Rework 'terminal' commands

* Arguments of the kakoune command are now preserved in the shell call
* Escaping logic is moved from 'new' to 'terminal'
This commit is contained in:
Olivier Perret 2018-12-21 18:14:28 +01:00
parent 02fa967476
commit 5146f7ba33
6 changed files with 125 additions and 62 deletions

View File

@ -4,11 +4,7 @@ The ''terminal'' alias is being used to determine the user''s preferred terminal
The optional arguments are passed as commands to the new client' \
%{
try %{
terminal %sh{
# double-up single-quotes
escaped=$(printf %s "$*" | sed -e "s|'|''|g")
printf "kak -c '%s' -e '%s'" "$kak_session" "$escaped"
}
terminal kak -c %val{session} -e "%arg{@}"
} catch %{
fail "The 'terminal' alias must be defined to use this command"
}

View File

@ -9,35 +9,46 @@ hook -group GNUscreen global KakBegin .* %sh{
"
}
define-command screen-terminal-impl -hidden -params 3 %{
define-command screen-terminal-impl -hidden -params 3.. %{
nop %sh{
tty="$(ps -o tty ${kak_client_pid} | tail -n 1)"
screen -X eval "$1" "$2"
screen -X screen sh -c "$3; screen -X remove" < "/dev/$tty"
shift 2
# see x11.kak for what this achieves
args=$(
for i in "$@"; do
if [ "$i" = '' ]; then
printf "'' "
else
printf %s "$i" | sed -e "s|'|'\\\\''|g; s|^|'|; s|$|' |"
fi
done
)
screen -X screen sh -c "${args} ; screen -X remove" < "/dev/$tty"
}
}
define-command screen-terminal-vertical -params 1 -shell-completion -docstring '
screen-terminal-vertical <program>: create a new terminal as a screen pane
define-command screen-terminal-vertical -params 1.. -shell-completion -docstring '
screen-terminal-vertical <program> [<arguments>] [<arguments>]: create a new terminal as a screen pane
The current pane is split into two, left and right
The shell program passed as argument will be executed in the new terminal' \
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 -shell-completion -docstring '
screen-terminal-horizontal <program>: create a new terminal as a screen pane
define-command screen-terminal-horizontal -params 1.. -shell-completion -docstring '
screen-terminal-horizontal <program> [<arguments>]: create a new terminal as a screen pane
The current pane is split into two, top and bottom
The shell program passed as argument will be executed in the new terminal' \
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 -shell-completion -docstring '
screen-terminal-window <program>: create a new terminal as a screen window
The shell program passed as argument will be executed in the new terminal' \
define-command screen-terminal-window -params 1.. -shell-completion -docstring '
screen-terminal-window <program> [<arguments>]: 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"
screen -X screen "$@" < "/dev/$tty"
}
}

View File

@ -11,7 +11,7 @@ hook global KakBegin .* %sh{
fi
}
define-command -hidden -params 2 tmux-terminal-impl %{
define-command -hidden -params 2.. tmux-terminal-impl %{
evaluate-commands %sh{
tmux=${kak_client_env_TMUX:-$TMUX}
if [ -z "$tmux" ]; then
@ -19,29 +19,32 @@ define-command -hidden -params 2 tmux-terminal-impl %{
exit
fi
tmux_args="$1"
TMUX=$tmux tmux $tmux_args env TMPDIR="$TMPDIR" sh -c "$2" < /dev/null > /dev/null 2>&1 &
shift
# ideally we should escape single ';' to stop tmux from interpreting it as a new command
# but that's probably too rare to care
TMUX=$tmux tmux $tmux_args env TMPDIR="$TMPDIR" "$@" < /dev/null > /dev/null 2>&1 &
}
}
define-command tmux-terminal-vertical -params 1 -shell-completion -docstring '
tmux-terminal-vertical <program>: create a new terminal as a tmux pane
define-command tmux-terminal-vertical -params 1.. -shell-completion -docstring '
tmux-terminal-vertical <program> [<arguments>]: create a new terminal as a tmux pane
The current pane is split into two, top and bottom
The shell program passed as argument will be executed in the new terminal' \
The program passed as argument will be executed in the new terminal' \
%{
tmux-terminal-impl 'split-window -v' %arg{1}
tmux-terminal-impl 'split-window -v' %arg{@}
}
define-command tmux-terminal-horizontal -params 1 -shell-completion -docstring '
tmux-terminal-horizontal <program>: create a new terminal as a tmux pane
define-command tmux-terminal-horizontal -params 1.. -shell-completion -docstring '
tmux-terminal-horizontal <program> [<arguments>]: create a new terminal as a tmux pane
The current pane is split into two, left and right
The shell program passed as argument will be executed in the new terminal' \
The program passed as argument will be executed in the new terminal' \
%{
tmux-terminal-impl 'split-window -h' %arg{1}
tmux-terminal-impl 'split-window -h' %arg{@}
}
define-command tmux-terminal-window -params 1 -shell-completion -docstring '
tmux-terminal-window <program> [<arguments>]: create a new terminal as a tmux window
The shell program passed as argument will be executed in the new terminal' \
define-command tmux-terminal-window -params 1.. -shell-completion -docstring '
tmux-terminal-window <program> [<arguments>] [<arguments>]: 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{1}
tmux-terminal-impl 'new-window' %arg{@}
}
define-command tmux-focus -params ..1 -client-completion -docstring '

View File

@ -22,16 +22,36 @@ A shell command is appended to the one set in this option at runtime} \
done
}
define-command x11-terminal -params 1 -shell-completion -docstring '
x11-terminal <program>: create a new terminal as an x11 window
The shell program passed as argument will be executed in the new terminal' \
define-command x11-terminal -params 1.. -shell-completion -docstring '
x11-terminal <program> [<arguments>]: 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 "fail 'termcmd option is not set'"
exit
fi
setsid ${kak_opt_termcmd} "$1" < /dev/null > /dev/null 2>&1 &
# join arguments into a single string, in which they're delimited
# by single quotes, and with single quotes inside transformed to '\''
# so that sh -c "$args" will re-split the arguments properly
# example:
# $1 = ab
# $2 = foo bar
# $3 =
# $4 = foo'bar
# $args = 'ab' 'foo bar' '' 'foo'\''bar'
# would be nicer to do in a single sed/awk call but that's difficult
args=$(
for i in "$@"; do
# special case to preserve empty variables as sed won't touch these
if [ "$i" = '' ]; then
printf "'' "
else
printf %s "$i" | sed -e "s|'|'\\\\''|g; s|^|'|; s|$|' |"
fi
done
)
setsid ${kak_opt_termcmd} "$args" < /dev/null > /dev/null 2>&1 &
}
}

View File

@ -11,12 +11,25 @@ hook global KakBegin .* %sh{
fi
}
define-command -hidden -params 2 iterm-terminal-split-impl %{
define-command -hidden -params 2.. iterm-terminal-split-impl %{
nop %sh{
# replace ' with '\\'' in the command
escaped=$(printf %s "$2" | sed -e "s|'|'\\\\\\\\''|g")
direction="$1"
cmd="env PATH='${PATH}' TMPDIR='${TMPDIR}' sh -c '$escaped'"
shift
# join the arguments as one string for the shell execution (see x11.kak)
args=$(
for i in "$@"; do
if [ "$i" = '' ]; then
printf "'' "
else
printf %s "$i" | sed -e "s|'|'\\\\''|g; s|^|'|; s|$|' |"
fi
done
)
# go through another round of escaping for osascript
# \ -> \\
# " -> \"
escaped=$(printf %s "$args" | sed -e 's|\|\\\\|g; s|"|\\"|g')
cmd="env PATH='${PATH}' TMPDIR='${TMPDIR}' $escaped"
osascript \
-e "tell application \"iTerm\"" \
-e " tell current session of current window" \
@ -26,28 +39,38 @@ define-command -hidden -params 2 iterm-terminal-split-impl %{
}
}
define-command iterm-terminal-vertical -params 1 -shell-completion -docstring '
iterm-terminal-vertical <program>: create a new terminal as an iterm pane
define-command iterm-terminal-vertical -params 1.. -shell-completion -docstring '
iterm-terminal-vertical <program> [<arguments>]: create a new terminal as an iterm pane
The current pane is split into two, top and bottom
The shell program passed as argument will be executed in the new terminal'\
The program passed as argument will be executed in the new terminal'\
%{
iterm-terminal-split-impl 'vertically' %arg{1}
}
define-command iterm-terminal-horizontal -params 1 -shell-completion -docstring '
iterm-terminal-horizontal <program>: create a new terminal as an iterm pane
define-command iterm-terminal-horizontal -params 1.. -shell-completion -docstring '
iterm-terminal-horizontal <program> [<arguments>]: create a new terminal as an iterm pane
The current pane is split into two, left and right
The shell program passed as argument will be executed in the new terminal'\
The program passed as argument will be executed in the new terminal'\
%{
iterm-terminal-split-impl 'horizontally' %arg{1}
}
define-command iterm-terminal-tab -params 1 -shell-completion -docstring '
iterm-terminal-tab <program>: create a new terminal as an iterm tab
The shell program passed as argument will be executed in the new terminal'\
define-command iterm-terminal-tab -params 1.. -shell-completion -docstring '
iterm-terminal-tab <program> [<arguments>]: create a new terminal as an iterm tab
The program passed as argument will be executed in the new terminal'\
%{
nop %sh{
escaped=$(printf %s "$1" | sed -e "s|'|'\\\\\\\\''|g")
cmd="env PATH='${PATH}' TMPDIR='${TMPDIR}' sh -c '$escaped'"
# see above
args=$(
for i in "$@"; do
if [ "$i" = '' ]; then
printf "'' "
else
printf %s "$i" | sed -e "s|'|'\\\\''|g; s|^|'|; s|$|' |"
fi
done
)
escaped=$(printf %s "$args" | sed -e 's|\|\\\\|g; s|"|\\"|g')
cmd="env PATH='${PATH}' TMPDIR='${TMPDIR}' $escaped"
osascript \
-e "tell application \"iTerm\"" \
-e " tell current window" \
@ -58,12 +81,22 @@ The shell program passed as argument will be executed in the new terminal'\
}
define-command iterm-terminal-window -params 1 -shell-completion -docstring '
iterm-terminal-window <program>: create a new terminal as an iterm window
The shell program passed as argument will be executed in the new terminal'\
iterm-terminal-window <program> [<arguments>]: create a new terminal as an iterm window
The program passed as argument will be executed in the new terminal'\
%{
nop %sh{
escaped=$(printf %s "$1" | sed -e "s|'|'\\\\\\\\''|g")
cmd="env PATH='${PATH}' TMPDIR='${TMPDIR}' sh -c '$escaped'"
# see above
args=$(
for i in "$@"; do
if [ "$i" = '' ]; then
printf "'' "
else
printf %s "$i" | sed -e "s|'|'\\\\''|g; s|^|'|; s|$|' |"
fi
done
)
escaped=$(printf %s "$args" | sed -e 's|\|\\\\|g; s|"|\\"|g')
cmd="env PATH='${PATH}' TMPDIR='${TMPDIR}' $escaped"
osascript \
-e "tell application \"iTerm\"" \
-e " create window with default profile command \"${cmd}\"" \

View File

@ -12,21 +12,21 @@ hook -group kitty-hooks global KakBegin .* %sh{
fi
}
define-command kitty-terminal -params 1 -shell-completion -docstring '
kitty-terminal <program>: create a new terminal as a kitty window
The shell program passed as argument will be executed in the new terminal' \
define-command kitty-terminal -params 1.. -shell-completion -docstring '
kitty-terminal <program> [<arguments>]: 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 "$1"
kitty @ new-window --no-response --window-type $kak_opt_kitty_window_type "$@"
}
}
define-command kitty-terminal-tab -params 1 -shell-completion -docstring '
kitty-terminal-tab <program>: create a new terminal as kitty tab
The shell program passed as argument will be executed in the new terminal' \
define-command kitty-terminal-tab -params 1.. -shell-completion -docstring '
kitty-terminal-tab <program> [<arguments>]: 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 "$1"
kitty @ new-window --no-response --new-tab "$@"
}
}