Skip to content

Commit

Permalink
Merge pull request #1695 from contour-terminal/improvement/tabs
Browse files Browse the repository at this point in the history
Further improvements to tabs handling (add MoveTabToLeft / MoveTabToRight / MoveTabTo actions)
  • Loading branch information
christianparpart authored Jan 1, 2025
2 parents cd42389 + 8f56df6 commit 1083ac7
Show file tree
Hide file tree
Showing 10 changed files with 140 additions and 7 deletions.
4 changes: 4 additions & 0 deletions metainfo.xml
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,10 @@
<release version="0.6.2" urgency="medium" type="development">
<description>
<ul>
<li>Fixes `CreateTab` to sometimes spawn more than one tab (#1695)</li>
<li>Adds `MoveTabToLeft` and `MoveTabToRight` actions to move tabs around (#1695)</li>
<li>Adds `MoveTabTo` action to move tabs to a specific position (#1695)</li>
<li>Ensure inserting new tabs happens right next to the currently active tab (#1695)</li>
</ul>
</description>
</release>
Expand Down
3 changes: 3 additions & 0 deletions src/contour/Actions.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,9 @@ optional<Action> fromString(string const& name)
mapAction<actions::WriteScreen>("WriteScreen"),
mapAction<actions::CreateNewTab>("CreateNewTab"),
mapAction<actions::CloseTab>("CloseTab"),
mapAction<actions::MoveTabTo>("MoveTabTo"),
mapAction<actions::MoveTabToLeft>("MoveTabToLeft"),
mapAction<actions::MoveTabToRight>("MoveTabToRight"),
mapAction<actions::SwitchToTab>("SwitchToTab"),
mapAction<actions::SwitchToPreviousTab>("SwitchToPreviousTab"),
mapAction<actions::SwitchToTabLeft>("SwitchToTabLeft"),
Expand Down
32 changes: 32 additions & 0 deletions src/contour/Actions.h
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,9 @@ struct ViNormalMode{};
struct WriteScreen{ std::string chars; }; // "\033[2J\033[3J"
struct CreateNewTab{};
struct CloseTab{};
struct MoveTabTo{ int position; };
struct MoveTabToLeft{};
struct MoveTabToRight{};
struct SwitchToTab{ int position; };
struct SwitchToPreviousTab{};
struct SwitchToTabLeft{};
Expand Down Expand Up @@ -140,6 +143,9 @@ using Action = std::variant<CancelSelection,
WriteScreen,
CreateNewTab,
CloseTab,
MoveTabTo,
MoveTabToLeft,
MoveTabToRight,
SwitchToTab,
SwitchToPreviousTab,
SwitchToTabLeft,
Expand Down Expand Up @@ -259,6 +265,11 @@ namespace documentation
};
constexpr inline std::string_view CreateNewTab { "Creates a new tab in the terminal emulator." };
constexpr inline std::string_view CloseTab { "Closes current tab." };
constexpr inline std::string_view MoveTabTo {
"Moves current tab to the given position (starting at number 1)."
};
constexpr inline std::string_view MoveTabToLeft { "Moves current tab to the left." };
constexpr inline std::string_view MoveTabToRight { "Moves current tab to the right." };
constexpr inline std::string_view SwitchToTab {
"Switch to absolute tab position (starting at number 1)"
};
Expand Down Expand Up @@ -323,6 +334,9 @@ inline auto getDocumentation()
std::tuple { Action { WriteScreen {} }, documentation::WriteScreen },
std::tuple { Action { CreateNewTab {} }, documentation::CreateNewTab },
std::tuple { Action { CloseTab {} }, documentation::CloseTab },
std::tuple { Action { MoveTabTo {} }, documentation::MoveTabTo },
std::tuple { Action { MoveTabToLeft {} }, documentation::MoveTabToLeft },
std::tuple { Action { MoveTabToRight {} }, documentation::MoveTabToRight },
std::tuple { Action { SwitchToTab {} }, documentation::SwitchToTab },
std::tuple { Action { SwitchToPreviousTab {} }, documentation::SwitchToPreviousTab },
std::tuple { Action { SwitchToTabLeft {} }, documentation::SwitchToTabLeft },
Expand Down Expand Up @@ -397,12 +411,23 @@ DECLARE_ACTION_FMT(ViNormalMode)
DECLARE_ACTION_FMT(WriteScreen)
DECLARE_ACTION_FMT(CreateNewTab)
DECLARE_ACTION_FMT(CloseTab)
DECLARE_ACTION_FMT(MoveTabToLeft)
DECLARE_ACTION_FMT(MoveTabToRight)
DECLARE_ACTION_FMT(SwitchToPreviousTab)
DECLARE_ACTION_FMT(SwitchToTabLeft)
DECLARE_ACTION_FMT(SwitchToTabRight)
// }}}
#undef DECLARE_ACTION_FMT

template <>
struct std::formatter<contour::actions::MoveTabTo>: std::formatter<std::string>
{
auto format(contour::actions::MoveTabTo const& value, auto& ctx) const
{
return formatter<string>::format(std::format("MoveTabTo {{ position: {} }}", value.position), ctx);
}
};

template <>
struct std::formatter<contour::actions::SwitchToTab>: std::formatter<std::string>
{
Expand Down Expand Up @@ -476,9 +501,16 @@ struct std::formatter<contour::actions::Action>: std::formatter<std::string>
HANDLE_ACTION(ViNormalMode);
HANDLE_ACTION(CreateNewTab);
HANDLE_ACTION(CloseTab);
HANDLE_ACTION(MoveTabToLeft);
HANDLE_ACTION(MoveTabToRight);
HANDLE_ACTION(SwitchToPreviousTab);
HANDLE_ACTION(SwitchToTabLeft);
HANDLE_ACTION(SwitchToTabRight);
if (std::holds_alternative<contour::actions::MoveTabTo>(_action))
{
const auto action = std::get<contour::actions::MoveTabTo>(_action);
name = std::format("MoveTabTo, position: {}", action.position);
}
if (std::holds_alternative<contour::actions::SwitchToTab>(_action))
{
const auto action = std::get<contour::actions::SwitchToTab>(_action);
Expand Down
8 changes: 8 additions & 0 deletions src/contour/Config.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1827,6 +1827,14 @@ std::optional<actions::Action> YAMLConfigReader::parseAction(YAML::Node const& n
return std::nullopt;
}

if (holds_alternative<actions::MoveTabTo>(action))
{
if (auto position = node["position"]; position.IsScalar())
return actions::MoveTabTo { position.as<int>() };
else
return std::nullopt;
}

if (holds_alternative<actions::SwitchToTab>(action))
{
if (auto position = node["position"]; position.IsScalar())
Expand Down
3 changes: 3 additions & 0 deletions src/contour/ConfigDocumentation.h
Original file line number Diff line number Diff line change
Expand Up @@ -741,6 +741,8 @@ constexpr StringLiteral InputMappingsConfig {
"position.\n"
"{comment} - IncreaseFontSize Increases the font size by 1 pixel.\n"
"{comment} - IncreaseOpacity Increases the default-background opacity by 5%.\n"
"{comment} - MoveTabToLeft Moves the current tab to the left.\n"
"{comment} - MoveTabToRight Moves the current tab to the right.\n"
"{comment} - NewTerminal Spawns a new terminal at the current terminals current working "
"directory.\n"
"{comment} - NoSearchHighlight Disables current search highlighting, if anything is still "
Expand Down Expand Up @@ -783,6 +785,7 @@ constexpr StringLiteral InputMappingsConfig {
"{comment} - SendChars Writes given characters in `chars` member to the applications input.\n"
"{comment} - SwitchToTab Switches to the tab position, given by extra parameter \"position\".\n"
"{comment} The positions start at number 1.\n"
"{comment} - SwitchToPreviousTab Switches to the previously active tab.\n"
"{comment} - SwitchToTabLeft Switches to the tab left of the current tab.\n"
"{comment} - SwitchToTabRight Switches to the tab right of the current tab.\n"
"{comment} - CreateNewTab Creates a new tab.\n"
Expand Down
26 changes: 24 additions & 2 deletions src/contour/TerminalSession.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@

#include <algorithm>
#include <filesystem>
#include <format>
#include <fstream>
#include <limits>

Expand Down Expand Up @@ -185,7 +186,10 @@ namespace

} // namespace

TerminalSession::TerminalSession(unique_ptr<vtpty::Pty> pty, ContourGuiApp& app):
TerminalSession::TerminalSession(TerminalSessionManager* manager,
unique_ptr<vtpty::Pty> pty,
ContourGuiApp& app):
_manager { manager },
_id { createSessionId() },
_startTime { steady_clock::now() },
_config { app.config() },
Expand Down Expand Up @@ -1430,7 +1434,7 @@ bool TerminalSession::operator()(actions::WriteScreen const& event)

bool TerminalSession::operator()(actions::CreateNewTab)
{
emit createNewTab();
_manager->createSession();
return true;
}

Expand All @@ -1440,6 +1444,24 @@ bool TerminalSession::operator()(actions::CloseTab)
return true;
}

bool TerminalSession::operator()(actions::MoveTabTo event)
{
_manager->moveTabTo(event.position);
return true;
}

bool TerminalSession::operator()(actions::MoveTabToLeft)
{
_manager->moveTabToLeft(this);
return true;
}

bool TerminalSession::operator()(actions::MoveTabToRight)
{
_manager->moveTabToRight(this);
return true;
}

bool TerminalSession::operator()(actions::SwitchToTab const& event)
{
emit switchToTab(event.position);
Expand Down
7 changes: 6 additions & 1 deletion src/contour/TerminalSession.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ namespace display
}

class ContourGuiApp;
class TerminalSessionManager;

/**
* A set of user-facing activities that are guarded behind a permission-check wall.
Expand Down Expand Up @@ -215,7 +216,7 @@ class TerminalSession: public QAbstractItemModel, public vtbackend::Terminal::Ev
* @param pty a PTY object (can be process, networked, mockup, ...)
* @param display fronend display to render the terminal.
*/
TerminalSession(std::unique_ptr<vtpty::Pty> pty, ContourGuiApp& app);
TerminalSession(TerminalSessionManager* manager, std::unique_ptr<vtpty::Pty> pty, ContourGuiApp& app);
~TerminalSession() override;

int id() const noexcept { return _id; }
Expand Down Expand Up @@ -356,6 +357,9 @@ class TerminalSession: public QAbstractItemModel, public vtbackend::Terminal::Ev
bool operator()(actions::WriteScreen const& event);
bool operator()(actions::CreateNewTab);
bool operator()(actions::CloseTab);
bool operator()(actions::MoveTabTo);
bool operator()(actions::MoveTabToLeft);
bool operator()(actions::MoveTabToRight);
bool operator()(actions::SwitchToTab const& event);
bool operator()(actions::SwitchToPreviousTab);
bool operator()(actions::SwitchToTabLeft);
Expand Down Expand Up @@ -437,6 +441,7 @@ class TerminalSession: public QAbstractItemModel, public vtbackend::Terminal::Ev

// private data
//
TerminalSessionManager* _manager;
int _id;
std::chrono::steady_clock::time_point _startTime;
config::Config _config;
Expand Down
56 changes: 54 additions & 2 deletions src/contour/TerminalSessionManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -76,10 +76,14 @@ TerminalSession* TerminalSessionManager::createSessionInBackground()
}
#endif

auto* session = new TerminalSession(createPty(ptyPath), _app);
auto* session = new TerminalSession(this, createPty(ptyPath), _app);
managerLog()("Create new session with ID {} at index {}", session->id(), _sessions.size());

_sessions.push_back(session);
auto const currentSessionIterator = std::ranges::find(_sessions, _activeSession);
auto const insertPoint = currentSessionIterator != _sessions.end() ? std::next(currentSessionIterator)
: currentSessionIterator;

_sessions.insert(insertPoint, session);

connect(session, &TerminalSession::sessionClosed, [this, session]() { removeSession(*session); });

Expand Down Expand Up @@ -108,6 +112,9 @@ void TerminalSessionManager::setSession(size_t index)

TerminalSession* TerminalSessionManager::activateSession(TerminalSession* session, bool isNewSession)
{
if (!session)
return nullptr;

managerLog()(
"Activating session ID {} at index {}", session->id(), getSessionIndexOf(session).value_or(-1));

Expand Down Expand Up @@ -216,6 +223,51 @@ void TerminalSessionManager::closeTab()
removeSession(*_activeSession);
}

void TerminalSessionManager::moveTabTo(int position)
{
auto const currentIndexOpt = getSessionIndexOf(_activeSession);
if (!currentIndexOpt)
return;

if (position < 1 || position > static_cast<int>(_sessions.size()))
return;

auto const index = static_cast<size_t>(position - 1);

std::swap(_sessions[currentIndexOpt.value()], _sessions[index]);
updateStatusLine();
}

void TerminalSessionManager::moveTabToLeft(TerminalSession* session)
{
auto const maybeIndex = getSessionIndexOf(session);
if (!maybeIndex)
return;

auto const index = maybeIndex.value();

if (index > 0)
{
std::swap(_sessions[index], _sessions[index - 1]);
updateStatusLine();
}
}

void TerminalSessionManager::moveTabToRight(TerminalSession* session)
{
auto const maybeIndex = getSessionIndexOf(session);
if (!maybeIndex)
return;

auto const index = maybeIndex.value();

if (index + 1 < _sessions.size())
{
std::swap(_sessions[index], _sessions[index + 1]);
updateStatusLine();
}
}

void TerminalSessionManager::removeSession(TerminalSession& thatSession)
{
managerLog()("REMOVE SESSION: session: {}, _sessions.size(): {}", (void*) &thatSession, _sessions.size());
Expand Down
3 changes: 3 additions & 0 deletions src/contour/TerminalSessionManager.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,9 @@ class TerminalSessionManager: public QAbstractListModel
Q_INVOKABLE void switchToTabRight();
Q_INVOKABLE void switchToTab(int position);
Q_INVOKABLE void closeTab();
Q_INVOKABLE void moveTabTo(int position);
Q_INVOKABLE void moveTabToLeft(TerminalSession* session);
Q_INVOKABLE void moveTabToRight(TerminalSession* session);

void setSession(size_t index);

Expand Down
5 changes: 3 additions & 2 deletions src/contour/ui.template/Terminal.qml.in
Original file line number Diff line number Diff line change
Expand Up @@ -241,9 +241,10 @@ ContourTerminal
}

function delay(duration) { // In milliseconds
var timeStart = new Date().getTime();
var timeStart = new Date().getTime();
while (new Date().getTime() - timeStart < duration) {
}
// Do nothing
}
}


Expand Down

0 comments on commit 1083ac7

Please sign in to comment.