This commit is contained in:
Timofey Khoruzhii 2023-01-06 14:52:57 +03:00
commit 2bc0cea52b
3 changed files with 209 additions and 0 deletions

10
CMakeLists.txt Normal file
View file

@ -0,0 +1,10 @@
cmake_minimum_required(VERSION 3.14)
project(tmuxub)
set(CMAKE_CXX_STANDARD 17)
file(GLOB_RECURSE SOURCES_FILES src/*)
add_library(tmuxub ${SOURCES_FILES})
target_include_directories(tmuxub PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/include)

53
include/tmuxub/tmuxub.hpp Normal file
View file

@ -0,0 +1,53 @@
#pragma once
#include <filesystem>
#include <optional>
#include <string>
#if !defined(__linux__) && !defined(__APPLE__)
#error Only linux and Macos supported
#endif
namespace tmuxub {
class Tmux {
public:
Tmux(std::optional<std::filesystem::path> socket = std::nullopt) : socket_(socket) {}
bool HasSession(const std::string& name);
Tmux& ConnectToSession(const std::string& name);
Tmux& CreateOrConnect(const std::string& name);
Tmux& CreateSession(const std::string& name);
Tmux& LockSession();
Tmux& KillSession();
Tmux& CreateWindow(const std::string& window);
// | vertical, - horizontal, > move to next window, {cmd1 cmd2; cmd3}
// cmd3 in new batch, for example hotkey in nvim must send after nvim start
// . select current pane
//
// |-{ls}>|{pwd}
// +-------+-------+
// |ls | |
// | | |
// +---+---+ |
// |pwd| | |
// | | | |
// +---+---+-------+
Tmux& SplitWindow(const std::string& pattern);
private:
void ConnectToSession_(const std::string& name) {
session_ = name;
}
std::string GetCommandTmuxSocket() {
return std::string("tmux ") + (socket_ ? "-S " + std::string(socket_.value()) + " " : "");
}
private:
std::optional<std::filesystem::path> socket_;
std::optional<std::string> session_;
};
} // namespace tmuxub

146
src/tmuxub.cpp Normal file
View file

@ -0,0 +1,146 @@
#include <tmuxub/tmuxub.hpp>
#include <iostream>
namespace tmuxub {
bool Tmux::HasSession(const std::string& name) {
std::string command = GetCommandTmuxSocket() + "has-session -t " + name;
int x = system(command.data());
return x == 0;
}
Tmux& Tmux::ConnectToSession(const std::string& name) {
if (!HasSession(name)) {
throw std::logic_error("hasn't session " + name);
}
session_ = name;
LockSession();
return *this;
}
Tmux& Tmux::CreateOrConnect(const std::string& name) {
if (HasSession(name)) {
std::cout << "I find session, connect" << std::endl;
ConnectToSession_(name);
} else {
std::cout << "I not find session, create" << std::endl;
CreateSession(name);
}
return *this;
}
Tmux& Tmux::CreateSession(const std::string& name) {
std::string command = GetCommandTmuxSocket() + "new-session -d -s " + name;
if (system(command.data()) != 0) {
throw std::logic_error("couldn't create session");
}
session_ = name;
LockSession();
return *this;
}
Tmux& Tmux::LockSession() {
std::string command = GetCommandTmuxSocket() + "lock-session -t " + session_.value();
if (system(command.data()) != 0) {
throw std::logic_error("couldn't lock session");
}
return *this;
}
Tmux& Tmux::SplitWindow(const std::string& pattern) {
size_t number_pane = 0;
auto split_horizontal = [this, &number_pane]() {
std::string command =
GetCommandTmuxSocket() + "split-window -t " + "0." + std::to_string(number_pane);
std::cout << "split horizontal" << std::endl;
system(command.data());
};
auto split_vertical = [this, &number_pane]() {
std::string command =
GetCommandTmuxSocket() + "split-window -h -t " + "0." + std::to_string(number_pane);
std::cout << "split vertical" << std::endl;
system(command.data());
};
auto send_cmd = [this, &number_pane](const std::string& cmd) {
std::string command =
GetCommandTmuxSocket() + "send-keys -t " + "0." + std::to_string(number_pane) + " " + cmd;
std::cout << "CMD: " << command << std::endl;
system(command.data());
};
auto select_current_pane = [this, &number_pane](){
std::string command =
GetCommandTmuxSocket() + "select-pane -t " + "0." + std::to_string(number_pane);
std::cout << "select pane" << std::endl;
system(command.data());
};
bool is_cmd = false;
std::string cmd;
for (char x : pattern) {
if (is_cmd) {
if (x == '}') {
is_cmd = false;
send_cmd(cmd);
} else if (x == ';') {
send_cmd(cmd);
cmd.clear();
} else {
cmd += x;
}
continue;
}
switch (x) {
case '|':
split_vertical();
break;
case '-':
split_horizontal();
break;
case '>':
number_pane++;
break;
case '<':
if (number_pane == 0) {
throw std::logic_error("Number pane connot be less than zero");
}
number_pane--;
break;
case '{':
is_cmd = true;
cmd.clear();
break;
case '.':
select_current_pane();
break;
}
}
return *this;
}
Tmux& Tmux::KillSession() {
std::string command = std::string("tmux ") +
(socket_ ? "-S " + std::string(socket_.value()) + " " : "") +
"kill-session -t " + session_.value();
if (system(command.data()) != 0) {
throw std::logic_error("couldn't kill session");
}
return *this;
}
} // namespace tmuxub