commit 2bc0cea52bd71bfda2b8a0a3213d1400d8b31481 Author: Timofey Khoruzhii Date: Fri Jan 6 14:52:57 2023 +0300 init prj diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..28dc303 --- /dev/null +++ b/CMakeLists.txt @@ -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) diff --git a/include/tmuxub/tmuxub.hpp b/include/tmuxub/tmuxub.hpp new file mode 100644 index 0000000..b88bdc2 --- /dev/null +++ b/include/tmuxub/tmuxub.hpp @@ -0,0 +1,53 @@ +#pragma once + +#include +#include +#include + +#if !defined(__linux__) && !defined(__APPLE__) +#error Only linux and Macos supported +#endif + +namespace tmuxub { +class Tmux { + public: + Tmux(std::optional 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 socket_; + std::optional session_; +}; +} // namespace tmuxub diff --git a/src/tmuxub.cpp b/src/tmuxub.cpp new file mode 100644 index 0000000..62849a5 --- /dev/null +++ b/src/tmuxub.cpp @@ -0,0 +1,146 @@ +#include +#include + +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