From c8403624a74348ba3537ded640cba8d0c746568e Mon Sep 17 00:00:00 2001 From: Olivier Perret Date: Sun, 2 Dec 2018 13:59:45 +0100 Subject: [PATCH] Expose a 'terminal' command for the various windowing systems It allows plugins to create generic terminal using the user's preferred windowing system For example, it can be used to run fzf, gdb or simply a shell. * 'new' commands are refactored to simply use the 'terminal' one * style and docstrings has been unified * all windowing systems go through "sh -c" for consistency purposes, even if unnecessary --- rc/base/screen.kak | 89 ++++++++++++++++++++++++++++++---------------- rc/base/tmux.kak | 75 ++++++++++++++++++++++++++------------ rc/base/x11.kak | 40 +++++++++++++-------- rc/extra/kitty.kak | 79 ++++++++++++++++++++++++++-------------- 4 files changed, 188 insertions(+), 95 deletions(-) diff --git a/rc/base/screen.kak b/rc/base/screen.kak index 66a8db5de..4d13c3756 100644 --- a/rc/base/screen.kak +++ b/rc/base/screen.kak @@ -6,44 +6,70 @@ hook -group GNUscreen global KakBegin .* %sh{ echo " alias global focus screen-focus alias global new screen-new-vertical + alias global terminal screen-terminal-vertical " } -define-command screen-new-vertical -params .. -command-completion -docstring "Split the current pane into two, left and right" %{ - nop %sh{ - tty="$(ps -o tty ${kak_client_pid} | tail -n 1)" - screen -X eval \ - 'split -h' \ - 'focus down' \ - "screen sh -c 'kak -c \"${kak_session}\" -e \"$*\" ; - screen -X remove'" \ - < "/dev/$tty" - } -} - -define-command screen-new-horizontal -params .. -command-completion -docstring "Split the current pane into two, top and bottom" %{ - nop %sh{ - tty="$(ps -o tty ${kak_client_pid} | tail -n 1)" - screen -X eval \ - 'split -v' \ - 'focus right' \ - "screen sh -c 'kak -c \"${kak_session}\" -e \"$*\" ; - screen -X remove'" \ - < "/dev/$tty" - } -} - -define-command screen-new-window -params .. -command-completion -docstring "Create a new window" %{ +define-command screen-terminal-impl -hidden -params 3.. -command-completion %{ nop %sh{ tty="$(ps -o tty ${kak_client_pid} | tail -n 1)" - screen -X screen kak -c "${kak_session}" -e "$*" < "/dev/$tty" + screen -X eval "$1" "$2" + shift 2 + cmd=$(printf %s "$*") + screen -X screen sh -c "${cmd}; screen -X remove" < "/dev/$tty" } } -define-command -docstring %{screen-focus []: focus the given client -If no client is passed then the current one is used} \ - -params ..1 -client-completion \ - screen-focus %{ evaluate-commands %sh{ +define-command screen-terminal-vertical -params 1.. -command-completion -docstring ' +screen-terminal-vertical []: create a new terminal as a screen pane +The current pane is split into two, left and right +The program passed as argument will be executed in the new terminal' \ +%{ + screen-terminal-impl 'split -v' 'focus right' %arg{@} +} +define-command screen-terminal-horizontal -params 1.. -command-completion -docstring ' +screen-terminal-horizontal []: create a new terminal as a screen pane +The current pane is split into two, top and bottom +The program passed as argument will be executed in the new terminal' \ +%{ + screen-terminal-impl 'split -h' 'focus down' %arg{@} +} +define-command screen-terminal-window -params 1.. -command-completion -docstring ' +screen-terminal-window []: create a new terminal as a screen window +The program passed as argument will be executed in the new terminal' \ +%{ + nop %sh{ + tty="$(ps -o tty ${kak_client_pid} | tail -n 1)" + screen -X screen sh -c "$*" < "/dev/$tty" + } +} + +define-command screen-new-vertical -params .. -command-completion -docstring ' +screen-new-vertical []: create a new kakoune client as a screen pane +The current pane is split into two, left and right +The optional arguments are passed as commands to the new client' \ +%{ + screen-terminal-vertical "kak -c '%val{session}' -e '%arg{@}'" +} +define-command screen-new-horizontal -params .. -command-completion -docstring ' +screen-new-horizontal []: create a new kakoune client as a screen pane +The current pane is split into two, top and bottom +The optional arguments are passed as commands to the new client' \ +%{ + screen-terminal-horizontal "kak -c '%val{session}' -e '%arg{@}'" +} +define-command screen-new-window -params .. -command-completion -docstring ' +screen-new-window []: create a new kakoune client as a screen window +The optional arguments are passed as commands to the new client' \ +%{ + screen-terminal-window "kak -c '%val{session}' -e '%arg{@}'" +} + +define-command screen-focus -params ..1 -client-completion -docstring ' +screen-focus []: focus the given client +If no client is passed then the current one is used' \ +%{ + evaluate-commands %sh{ if [ $# -eq 1 ]; then printf %s\\n " evaluate-commands -client '$1' focus @@ -52,4 +78,5 @@ If no client is passed then the current one is used} \ tty="$(ps -o tty ${kak_client_pid} | tail -n 1)" screen -X select "${kak_client_env_WINDOW}" < "/dev/$tty" fi -} } + } +} diff --git a/rc/base/tmux.kak b/rc/base/tmux.kak index 3a17669d4..c587cdb92 100644 --- a/rc/base/tmux.kak +++ b/rc/base/tmux.kak @@ -7,44 +7,75 @@ hook global KakBegin .* %sh{ echo " alias global focus tmux-focus alias global new tmux-new-horizontal + alias global terminal tmux-terminal-horizontal " fi } -## Temporarily override the default client creation command -define-command -hidden -params 1.. tmux-new-impl %{ +define-command -hidden -params 2.. tmux-terminal-impl %{ evaluate-commands %sh{ tmux=${kak_client_env_TMUX:-$TMUX} if [ -z "$tmux" ]; then - echo "echo -markup '{Error}This command is only available in a tmux session'" + echo "fail 'This command is only available in a tmux session'" exit fi tmux_args="$1" shift - if [ $# -ne 0 ]; then kakoune_params="-e '$@'"; fi - TMUX=$tmux tmux $tmux_args "env TMPDIR='${TMPDIR}' kak -c ${kak_session} ${kakoune_params}" < /dev/null > /dev/null 2>&1 & + TMUX=$tmux tmux $tmux_args env TMPDIR="$TMPDIR" sh -c "$*" < /dev/null > /dev/null 2>&1 & } } -define-command tmux-new-vertical -params .. -command-completion -docstring "Split the current pane into two, top and bottom" %{ - tmux-new-impl 'split-window -v' %arg{@} +define-command tmux-terminal-vertical -params 1.. -shell-completion -docstring ' +tmux-terminal-vertical []: create a new terminal as a tmux pane +The current pane is split into two, top and bottom +The program passed as argument will be executed in the new terminal' \ +%{ + tmux-terminal-impl 'split-window -v' %arg{@} +} +define-command tmux-terminal-horizontal -params 1.. -shell-completion -docstring ' +tmux-terminal-horizontal []: create a new terminal as a tmux pane +The current pane is split into two, left and right +The program passed as argument will be executed in the new terminal' \ +%{ + tmux-terminal-impl 'split-window -h' %arg{@} +} +define-command tmux-terminal-window -params 1.. -shell-completion -docstring ' +tmux-terminal-window []: create a new terminal as a tmux window +The program passed as argument will be executed in the new terminal' \ +%{ + tmux-terminal-impl 'new-window' %arg{@} } -define-command tmux-new-horizontal -params .. -command-completion -docstring "Split the current pane into two, left and right" %{ - tmux-new-impl 'split-window -h' %arg{@} +define-command tmux-new-vertical -params .. -command-completion -docstring ' +tmux-new-vertical []: create a new kakoune client as a tmux pane +The current pane is split into two, top and bottom +The optional arguments are passed as commands to the new client' \ +%{ + tmux-terminal-vertical "kak -c %val{session} -e '%arg{@}'" +} +define-command tmux-new-horizontal -params .. -command-completion -docstring ' +tmux-new-horizontal []: create a new kakoune client as a tmux pane +The current pane is split into two, left and right +The optional arguments are passed as commands to the new client' \ +%{ + tmux-terminal-horizontal "kak -c %val{session} -e '%arg{@}'" +} +define-command tmux-new-window -params .. -command-completion -docstring ' +tmux-new-window []: create a new kakoune client as a tmux window +The optional arguments are passed as commands to the new client' \ +%{ + tmux-terminal-window "kak -c %val{session} -e '%arg{@}'" } -define-command tmux-new-window -params .. -command-completion -docstring "Create a new window" %{ - tmux-new-impl 'new-window' %arg{@} +define-command tmux-focus -params ..1 -client-completion -docstring ' +tmux-focus []: focus the given client +If no client is passed then the current one is used' \ +%{ + evaluate-commands %sh{ + if [ $# -eq 1 ]; then + printf "evaluate-commands -client '%s' focus" "$1" + elif [ -n "${kak_client_env_TMUX}" ]; then + TMUX="${kak_client_env_TMUX}" tmux select-pane -t "${kak_client_env_TMUX_PANE}" > /dev/null + fi + } } - -define-command -docstring %{tmux-focus []: focus the given client -If no client is passed then the current one is used} \ - -params ..1 -client-completion \ - tmux-focus %{ evaluate-commands %sh{ - if [ $# -eq 1 ]; then - printf %s\\n "evaluate-commands -client '$1' focus" - elif [ -n "${kak_client_env_TMUX}" ]; then - TMUX="${kak_client_env_TMUX}" tmux select-pane -t "${kak_client_env_TMUX_PANE}" > /dev/null - fi -} } diff --git a/rc/base/x11.kak b/rc/base/x11.kak index 1c4f6df68..9d5ee82e2 100644 --- a/rc/base/x11.kak +++ b/rc/base/x11.kak @@ -22,29 +22,39 @@ A shell command is appended to the one set in this option at runtime} \ done } -define-command -docstring %{x11-new []: create a new kak client for the current session -The optional arguments will be passed as arguments to the new client} \ - -params .. \ - -command-completion \ - x11-new %{ evaluate-commands %sh{ +define-command x11-terminal -params 1.. -shell-completion -docstring ' +x11-terminal []: create a new terminal as an x11 window +The program passed as argument will be executed in the new terminal' \ +%{ + evaluate-commands %sh{ if [ -z "${kak_opt_termcmd}" ]; then - echo "echo -markup '{Error}termcmd option is not set'" + echo "fail 'termcmd option is not set'" exit fi - if [ $# -ne 0 ]; then kakoune_params="-e '$@'"; fi - setsid ${kak_opt_termcmd} "kak -c ${kak_session} ${kakoune_params}" < /dev/null > /dev/null 2>&1 & -}} + setsid ${kak_opt_termcmd} "$*" < /dev/null > /dev/null 2>&1 & + } +} -define-command -docstring %{x11-focus []: focus a given client's window -If no client is passed, then the current client is used} \ - -params ..1 -client-completion \ - x11-focus %{ evaluate-commands %sh{ +define-command x11-new -params .. -command-completion -docstring ' +x11-new []: create a new kakoune client as an x11 window +The optional arguments are passed as commands to the new client' \ +%{ + x11-terminal "kak -c %val{session} -e '%arg{@}'" +} + +define-command x11-focus -params ..1 -client-completion -docstring ' +x11-focus []: focus a given client''s window +If no client is passed, then the current client is used' \ +%{ + evaluate-commands %sh{ if [ $# -eq 1 ]; then - printf %s\\n "evaluate-commands -client '$1' focus" + printf "evaluate-commands -client '%s' focus" "$1" else xdotool windowactivate $kak_client_env_WINDOWID > /dev/null fi -} } + } +} alias global focus x11-focus alias global new x11-new +alias global terminal x11-terminal diff --git a/rc/extra/kitty.kak b/rc/extra/kitty.kak index 8a640d3ed..c85333123 100644 --- a/rc/extra/kitty.kak +++ b/rc/extra/kitty.kak @@ -5,6 +5,8 @@ hook -group kitty-hooks global KakBegin .* %sh{ echo " alias global new kitty-new alias global new-tab kitty-new-tab + alias global terminal kitty-terminal + alias global terminal-tab kitty-terminal-tab alias global focus kitty-focus alias global repl kitty-repl alias global send-text kitty-send-text @@ -12,42 +14,65 @@ hook -group kitty-hooks global KakBegin .* %sh{ fi } -define-command -docstring %{kitty-new []: create a new kak client for the current session -Optional arguments are passed as arguments to the new client} \ - -params .. \ - -command-completion \ - kitty-new %{ nop %sh{ - kitty @ new-window --no-response --window-type $kak_opt_kitty_window_type "$(command -v kak 2>/dev/null)" -c "${kak_session}" -e "$*" -}} +define-command kitty-terminal -params 1.. -shell-completion -docstring ' +kitty-terminal []: create a new terminal as a kitty window +The program passed as argument will be executed in the new terminal' \ +%{ + nop %sh{ + kitty @ new-window --no-response --window-type $kak_opt_kitty_window_type sh -c "$*" + } +} -define-command -docstring %{kitty-new-tab []: create a new tab -All optional arguments are forwarded to the new kak client} \ - -params .. \ - -command-completion \ - kitty-new-tab %{ nop %sh{ - kitty @ new-window --no-response --new-tab "$(command -v kak 2>/dev/null)" -c "${kak_session}" -e "$*" -}} +define-command kitty-new -params .. -command-completion -docstring ' +kitty-new []: create a new kakoune client as a kitty window +The optional arguments are passed as commands to the new client' \ +%{ + kitty-terminal "kak -c %val{session} -e '%arg{@}'" +} -define-command -params ..1 -client-completion \ - -docstring %{kitty-focus []: focus the given client -If no client is passed then the current one is used} \ - kitty-focus %{ evaluate-commands %sh{ +define-command kitty-terminal-tab -params 1.. -shell-completion -docstring ' +kitty-terminal-tab []: create a new terminal as kitty tab +The program passed as argument will be executed in the new terminal' \ +%{ + nop %sh{ + kitty @ new-window --no-response --new-tab sh -c "$*" + } +} + +define-command kitty-new-tab -params .. -command-completion -docstring ' +kitty-new-tab []: create a new terminal as kitty tab +The optional arguments are passed as commands to the new client' \ +%{ + kitty-terminal-tab "kak -c %val{session} -e '%arg{@}'" +} + +define-command kitty-focus -params ..1 -client-completion -docstring ' +kitty-focus []: focus the given client +If no client is passed then the current one is used' \ +%{ + evaluate-commands %sh{ if [ $# -eq 1 ]; then - printf %s\\n "evaluate-commands -client '$1' focus" + printf "evaluate-commands -client '%s' focus" "$1" else kitty @ focus-tab --no-response -m=id:$kak_client_env_KITTY_WINDOW_ID kitty @ focus-window --no-response -m=id:$kak_client_env_KITTY_WINDOW_ID fi -}} + } +} -define-command -docstring %{kitty-repl []: create a new window for repl interaction -All optional parameters are forwarded to the new window} \ - -params .. \ - -shell-completion \ - kitty-repl %{ evaluate-commands %sh{ - if [ $# -eq 0 ]; then cmd="${SHELL:-/bin/sh}"; else cmd="$*"; fi +define-command kitty-repl -params .. -shell-completion -docstring ' +kitty-repl []: create a new window for repl interaction +All optional parameters are forwarded to the new window' \ +%{ + nop %sh{ + if [ $# -eq 0 ]; then + cmd="${SHELL:-/bin/sh}" + else + cmd="$*" + fi kitty @ new-window --no-response --window-type $kak_opt_kitty_window_type --title kak_repl_window --cwd "$PWD" $cmd < /dev/null > /dev/null 2>&1 & -}} + } +} define-command kitty-send-text -docstring "send the selected text to the repl window" %{ nop %sh{