Do not reparse %sh{...} strings

Automatic reparsing of %sh{...}, while convenient in many cases,
can be surprising as well, and can lead to security problems:

'echo %sh{ printf "foo\necho bar" }' runs 'echo foo', then 'echo bar'.
we make this danger explicit, and we fix the 'nop %sh{...}' pattern.

To reparse %sh{...} strings, they can be passed to evaluate-commands,
which has been fixed to work in every cases where %sh{...} reparsing
was used..
This commit is contained in:
Maxime Coste 2018-05-07 07:29:52 +10:00
parent 3b9818c10b
commit ec16969609
58 changed files with 170 additions and 191 deletions

View File

@ -2,7 +2,7 @@
## base16.kak by lenormf
##
%sh{
evaluate-commands %sh{
black_lighterer='rgb:383838'
black_lighter='rgb:2D2D2D'
black_light='rgb:1C1C1C'

View File

@ -1,6 +1,6 @@
# gruvbox theme
%sh{
evaluate-commands %sh{
gray="rgb:928374"
red="rgb:fb4934"
green="rgb:b8bb26"

View File

@ -1,6 +1,6 @@
# lucius theme
%sh{
evaluate-commands %sh{
# first we define the lucius colors as named colors
lucius_darker_grey="rgb:303030"
lucius_dark_grey="rgb:444444"

View File

@ -3,7 +3,7 @@
## a light theme inspired after https://github.com/hyspace/st2-reeder-theme
##
%sh{
evaluate-commands %sh{
white="rgb:f9f8f6"
white_light="rgb:f6f5f0"
black="rgb:383838"

View File

@ -1,6 +1,6 @@
# Solarized Dark
%sh{
evaluate-commands %sh{
base03='rgb:002b36'
base02='rgb:073642'
base01='rgb:586e75'

View File

@ -1,6 +1,6 @@
# Solarized Light
%sh{
evaluate-commands %sh{
base03='rgb:002b36'
base02='rgb:073642'
base01='rgb:586e75'

View File

@ -2,7 +2,7 @@
## Tomorrow-night, adapted by nicholastmosher
##
%sh{
evaluate-commands %sh{
foreground="rgb:c5c8c6"
background="rgb:272727"
selection="rgb:373b41"

View File

@ -1,6 +1,6 @@
# zenburn theme
%sh{
evaluate-commands %sh{
# define some named colors
zentext="rgb:cfcfcf"
zenselectionbg="rgb:3f7fcc"

View File

@ -55,7 +55,7 @@ The common pattern to do that is to use a fifo buffer:
[source,bash]
-----
%sh{
evaluate-commands %sh{
# Create a temporary fifo for communication
output=$(mktemp -d -t kak-temp-XXXXXXXX)/fifo
mkfifo ${output}
@ -113,7 +113,7 @@ decl str plugin_completions
hook global BufSetOption filetype=my_filetype %{
set -add buff completers option=plugin_completions
}
%sh{
evaluate-commands %sh{
# ask Kakoune to write current buffer to temporary file
filename=$(mktemp -t kak-temp.XXXXXXXX)
echo "set buffer plugin_filename '$filename'

View File

@ -5,6 +5,9 @@ released versions.
== Development version
* `%sh{...}` strings are not reparsed automatically anymore, they need
to go through an explicit `evaluate-commands`
* The `-allow-override` switch from `define-command` has been renamed
`-override`.

View File

@ -21,7 +21,7 @@ define-command -hidden autowrap-cursor %{ evaluate-commands -save-regs '/"|^@m'
} catch %{
## if we're adding characters in the middle of a sentence, use
## the `fmtcmd` command to wrap the entire paragraph
%sh{
evaluate-commands %sh{
if [ "${kak_opt_autowrap_format_paragraph}" = true ] \
&& [ -n "${kak_opt_autowrap_fmtcmd}" ]; then
format_cmd=$(printf %s "${kak_opt_autowrap_fmtcmd}" \

View File

@ -23,7 +23,7 @@ define-command -params ..1 \
-docstring %{ctags-search [<symbol>]: jump to a symbol's definition
If no symbol is passed then the current selection is used as symbol name} \
ctags-search \
%{ %sh{
%{ evaluate-commands %sh{
realpath() { ( path=$(readlink "$1"); cd "$(dirname "$1")"; printf "%s/%s\n" "$(pwd -P)" "$(basename "$1")" ) }
export tagname=${1:-${kak_selection}}
printf %s\\n "$kak_opt_ctagsfiles" | tr ':' '\n' |
@ -47,7 +47,7 @@ If no symbol is passed then the current selection is used as symbol name} \
define-command ctags-complete -docstring "Insert completion candidates for the current selection into the buffer's local variables" %{ evaluate-commands -draft %{
execute-keys <space>hb<a-k>^\w+$<ret>
%sh{ {
nop %sh{ {
compl=$(readtags -p "$kak_selection" | cut -f 1 | sort | uniq | sed -e 's/:/\\:/g' | sed -e 's/\n/:/g' )
compl="${kak_cursor_line}.${kak_cursor_column}+${#kak_selection}@${kak_timestamp}:${compl}"
printf %s\\n "set-option buffer=$kak_bufname ctags_completions '${compl}'" | kak -p ${kak_session}
@ -58,7 +58,7 @@ define-command ctags-funcinfo -docstring "Display ctags information about a sele
evaluate-commands -draft %{
try %{
execute-keys -no-hooks '[(;B<a-k>[a-zA-Z_]+\(<ret><a-;>'
%sh{
evaluate-commands %sh{
sigs=$(readtags -e ${kak_selection%?} | grep kind:f | sed -re 's/^(\S+).*((class|struct|namespace):(\S+))?.*signature:(.*)$/\5 [\4::\1]/')
if [ -n "$sigs" ]; then
printf %s\\n "evaluate-commands -client ${kak_client} %{info -anchor $kak_cursor_line.$kak_cursor_column -placement above '$sigs'}"
@ -81,7 +81,7 @@ declare-option -docstring "path to the directory in which the tags file will be
define-command ctags-generate -docstring 'Generate tag file asynchronously' %{
echo -markup "{Information}launching tag generation in the background"
%sh{ {
nop %sh{ (
while ! mkdir .tags.kaklock 2>/dev/null; do sleep 1; done
trap 'rmdir .tags.kaklock' EXIT
@ -93,11 +93,11 @@ define-command ctags-generate -docstring 'Generate tag file asynchronously' %{
fi
printf %s\\n "evaluate-commands -client $kak_client echo -markup '{Information}${msg}'" | kak -p ${kak_session}
} > /dev/null 2>&1 < /dev/null & }
) > /dev/null 2>&1 < /dev/null & }
}
define-command ctags-update-tags -docstring 'Update tags for the given file' %{
%sh{ {
nop %sh{ (
while ! mkdir .tags.kaklock 2>/dev/null; do sleep 1; done
trap 'rmdir .tags.kaklock' EXIT
@ -113,5 +113,5 @@ define-command ctags-update-tags -docstring 'Update tags for the given file' %{
fi
printf %s\\n "evaluate-commands -client $kak_client echo -markup '{Information}${msg}'" | kak -p ${kak_session}
} > /dev/null 2>&1 < /dev/null & }
) > /dev/null 2>&1 < /dev/null & }
}

View File

@ -37,7 +37,7 @@ add-highlighter shared/d/code regex "\b(this)\b\s*[^(]" 1:value
add-highlighter shared/d/code regex "((?:~|\b)this)\b\s*\(" 1:function
add-highlighter shared/d/code regex '#\s*line\b.*' 0:meta
%sh{
evaluate-commands %sh{
# Grammar
keywords="abstract|alias|align|asm|assert|auto|body|break|case|cast"

View File

@ -1,4 +1,4 @@
hook global BufOpenFile .* %{ %sh{
hook global BufOpenFile .* %{ evaluate-commands %sh{
if [ -z "${kak_opt_filetype}" ]; then
mime=$(file -b --mime-type "${kak_buffile}")
case "${mime}" in

View File

@ -25,7 +25,7 @@ add-highlighter shared/go/comment fill comment
add-highlighter shared/go/code regex %{-?([0-9]*\.(?!0[xX]))?\b([0-9]+|0[xX][0-9a-fA-F]+)\.?([eE][+-]?[0-9]+)?i?\b} 0:value
%sh{
evaluate-commands %sh{
# Grammar
keywords="break|default|func|interface|select|case|defer|go|map|struct"
keywords="${keywords}|chan|else|goto|package|switch|const|fallthrough|if|range|type"

View File

@ -9,7 +9,7 @@ declare-option -hidden int lint_error_count
declare-option -hidden int lint_warning_count
define-command lint -docstring 'Parse the current buffer with a linter' %{
%sh{
evaluate-commands %sh{
dir=$(mktemp -d "${TMPDIR:-/tmp}"/kak-lint.XXXXXXXX)
mkfifo "$dir"/fifo
printf '%s\n' "evaluate-commands -no-hooks write -sync $dir/buf"
@ -72,7 +72,7 @@ define-command lint -docstring 'Parse the current buffer with a linter' %{
define-command -hidden lint-show %{
update-option buffer lint_errors
%sh{
evaluate-commands %sh{
desc=$(printf '%s\n' "$kak_opt_lint_errors" | sed -e 's/\([^\\]\):/\1\n/g' | tail -n +2 |
sed -ne "/^$kak_cursor_line\.[^|]\+|.*/ { s/^[^|]\+|//g; s/'/\\\\'/g; s/\\\\:/:/g; p; }")
if [ -n "$desc" ]; then
@ -97,7 +97,7 @@ define-command lint-disable -docstring "Disable automatic diagnostics of the cod
define-command lint-next-error -docstring "Jump to the next line that contains an error" %{
update-option buffer lint_errors
%sh{
evaluate-commands %sh{
printf '%s\n' "$kak_opt_lint_errors" | sed -e 's/\([^\\]\):/\1\n/g' | tail -n +2 | {
while IFS='|' read -r candidate rest
do
@ -118,7 +118,7 @@ define-command lint-next-error -docstring "Jump to the next line that contains a
define-command lint-previous-error -docstring "Jump to the previous line that contains an error" %{
update-option buffer lint_errors
%sh{
evaluate-commands %sh{
printf '%s\n' "$kak_opt_lint_errors" | sed -e 's/\([^\\]\):/\1\n/g' | tail -n +2 | sort -t. -k1,1 -rn | {
while IFS='|' read -r candidate rest
do

View File

@ -27,7 +27,7 @@ add-highlighter shared/lua/code regex \b(and|break|do|else|elseif|end|false|for|
# Commands
# ‾‾‾‾‾‾‾‾
define-command lua-alternative-file -docstring 'Jump to the alternate file (implementation ↔ test)' %{ %sh{
define-command lua-alternative-file -docstring 'Jump to the alternate file (implementation ↔ test)' %{ evaluate-commands %sh{
case $kak_buffile in
*spec/*_spec.lua)
altfile=$(eval printf %s\\n $(printf %s\\n $kak_buffile | sed s+spec/+'*'/+';'s/_spec//))

View File

@ -11,7 +11,7 @@ hook global BufCreate .*[.](markdown|md|mkd) %{
# Highlighters
# ‾‾‾‾‾‾‾‾‾‾‾‾
%sh{
evaluate-commands %sh{
languages="
c cabal clojure coffee cpp css cucumber d diff dockerfile fish gas go
haml haskell html ini java javascript json julia kak kickstart latex

View File

@ -47,7 +47,7 @@ hook global WinSetOption filetype=(?!ocaml).* %{
# Macro
# ‾‾‾‾‾
%sh{
evaluate-commands %sh{
keywords=and:as:asr:assert:begin:class:constraint:do:done:downto:else:end:exception:external:false:for:fun:function:functor:if:in:include:inherit:initializer:land:lazy:let:lor:lsl:lsr:lxor:match:method:mod:module:mutable:new:nonrec:object:of:open:or:private:rec:sig:struct:then:to:true:try:type:val:virtual:when:while:with
echo "
add-highlighter shared/ocaml/code regex \b($(printf $keywords | tr : '|'))\b 0:keyword

View File

@ -22,7 +22,7 @@ add-highlighter shared/perl/double_string fill string
add-highlighter shared/perl/single_string fill string
add-highlighter shared/perl/comment fill comment
%sh{
evaluate-commands %sh{
# Grammar
keywords="else|lock|qw|elsif|lt|qx|eq|exp|ne|sub|for|no|my|not|tr|goto|and|foreach|or|break|exit|unless|cmp|ge|package|until|continue|gt|while|if|qq|xor|do|le|qr|return"
attributes="END|AUTOLOAD|BEGIN|CHECK|UNITCHECK|INIT|DESTROY"

View File

@ -49,7 +49,7 @@ add-highlighter shared/ruby/literal fill meta
add-highlighter shared/ruby/code regex \b([A-Za-z]\w*:(?!:))|([$@][A-Za-z]\w*)|((?<!:):(([A-Za-z]\w*[=?!]?)|(\[\]=?)))|([A-Z]\w*|^|\h)\K::(?=[A-Z]) 0:variable
%sh{
evaluate-commands %sh{
# Grammar
# Keywords are collected searching for keywords at
# https://github.com/ruby/ruby/blob/trunk/parse.y
@ -77,7 +77,7 @@ add-highlighter shared/ruby/code regex \b([A-Za-z]\w*:(?!:))|([$@][A-Za-z]\w*)|(
# Commands
# ‾‾‾‾‾‾‾‾
define-command ruby-alternative-file -docstring 'Jump to the alternate file (implementation ↔ test)' %{ %sh{
define-command ruby-alternative-file -docstring 'Jump to the alternate file (implementation ↔ test)' %{ evaluate-commands %sh{
case $kak_buffile in
*spec/*_spec.rb)
altfile=$(eval echo $(echo $kak_buffile | sed s+spec/+'*'/+';'s/_spec//))

View File

@ -1,19 +1,17 @@
# http://gnu.org/software/screen/
# ‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾
hook -group GNUscreen global KakBegin .* %{
%sh{
hook -group GNUscreen global KakBegin .* %sh{
[ -z "${STY}" ] && exit
echo "
alias global focus screen-focus
alias global new screen-new-vertical
"
}
}
define-command screen-new-vertical -params .. -command-completion -docstring "Split the current pane into two, left and right" %{
%sh{
nop %sh{
tty="$(ps -o tty ${kak_client_pid} | tail -n 1)"
screen -X eval \
'split -h' \
@ -25,7 +23,7 @@ define-command screen-new-vertical -params .. -command-completion -docstring "Sp
}
define-command screen-new-horizontal -params .. -command-completion -docstring "Split the current pane into two, top and bottom" %{
%sh{
nop %sh{
tty="$(ps -o tty ${kak_client_pid} | tail -n 1)"
screen -X eval \
'split -v' \
@ -37,7 +35,7 @@ define-command screen-new-horizontal -params .. -command-completion -docstring "
}
define-command screen-new-window -params .. -command-completion -docstring "Create a new window" %{
%sh{
nop %sh{
tty="$(ps -o tty ${kak_client_pid} | tail -n 1)"
screen -X screen kak -c "${kak_session}" -e "$*" < "/dev/$tty"
}
@ -46,7 +44,7 @@ define-command screen-new-window -params .. -command-completion -docstring "Crea
define-command -docstring %{screen-focus [<client>]: focus the given client
If no client is passed then the current one is used} \
-params ..1 -client-completion \
screen-focus %{ %sh{
screen-focus %{ evaluate-commands %sh{
if [ $# -eq 1 ]; then
printf %s\\n "
evaluate-commands -client '$1' focus

View File

@ -10,12 +10,12 @@ Formats of language supported:
- language code above followed by a dash or underscore with an ISO country code, e.g. 'en-US'} \
spell %{
try %{ add-highlighter window ranges 'spell_regions' }
%sh{
evaluate-commands %sh{
file=$(mktemp -d "${TMPDIR:-/tmp}"/kak-spell.XXXXXXXX)/buffer
printf 'eval -no-hooks write -sync %s\n' "${file}"
printf 'set-option buffer spell_tmp_file %s\n' "${file}"
}
%sh{
evaluate-commands %sh{
if [ $# -ge 1 ]; then
if [ ${#1} -ne 2 ] && [ ${#1} -ne 5 ]; then
echo "echo -markup '{Error}Invalid language code (examples of expected format: en, en_US, en-US)'"
@ -57,7 +57,7 @@ Formats of language supported:
}
}
define-command spell-next %{ %sh{
define-command spell-next %{ evaluate-commands %sh{
anchor_line="${kak_selection_desc%%.*}"
anchor_col="${kak_selection_desc%%,*}"
anchor_col="${anchor_col##*.}"
@ -101,7 +101,7 @@ define-command spell-next %{ %sh{
fi
} }
define-command spell-replace %{ %sh{
define-command spell-replace %{ evaluate-commands %sh{
if [ -n "$kak_opt_spell_lang" ]; then
options="-l '$kak_opt_spell_lang'"
fi

View File

@ -18,7 +18,7 @@ add-highlighter shared/ regions -default code sql \
comment '#' '$' '' \
comment '/\*' '\*/' ''
%sh{
evaluate-commands %sh{
# Keywords
keywords="ALTER|AS|ASC|AUTO_INCREMENT|CHECK|CONSTRAINT|CREATE|DATABASE|DEFAULT|DELETE|DESC|DISTINCT|DROP"
keywords="${keywords}|EXISTS|FOREIGN KEY|FROM|FULL JOIN|FULL OUTER JOIN|GROUP BY|HAVING|INDEX|INNER JOIN"

View File

@ -2,8 +2,7 @@
# ‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾
## The default behaviour for the `new` command is to open an horizontal pane in a tmux session
hook global KakBegin .* %{
%sh{
hook global KakBegin .* %sh{
if [ -n "$TMUX" ]; then
echo "
alias global focus tmux-focus
@ -11,11 +10,10 @@ hook global KakBegin .* %{
"
fi
}
}
## Temporarily override the default client creation command
define-command -hidden -params 1.. tmux-new-impl %{
%sh{
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'"
@ -43,7 +41,7 @@ define-command tmux-new-window -params .. -command-completion -docstring "Create
define-command -docstring %{tmux-focus [<client>]: focus the given client
If no client is passed then the current one is used} \
-params ..1 -client-completion \
tmux-focus %{ %sh{
tmux-focus %{ evaluate-commands %sh{
if [ $# -eq 1 ]; then
printf %s\\n "evaluate-commands -client '$1' focus"
elif [ -n "${kak_client_env_TMUX}" ]; then

View File

@ -16,7 +16,7 @@ A shell command is appended to the one set in this option at runtime} \
'xfce4-terminal -e ' ; do
terminal=${termcmd%% *}
if command -v $terminal >/dev/null 2>&1; then
printf %s\\n "'$termcmd'"
printf %s\\n "$termcmd"
exit
fi
done
@ -26,7 +26,7 @@ define-command -docstring %{x11-new [<command>]: create a new kak client for the
The optional arguments will be passed as arguments to the new client} \
-params .. \
-command-completion \
x11-new %{ %sh{
x11-new %{ evaluate-commands %sh{
if [ -z "${kak_opt_termcmd}" ]; then
echo "echo -markup '{Error}termcmd option is not set'"
exit
@ -38,7 +38,7 @@ The optional arguments will be passed as arguments to the new client} \
define-command -docstring %{x11-focus [<client>]: focus a given client's window
If no client is passed, then the current client is used} \
-params ..1 -client-completion \
x11-focus %{ %sh{
x11-focus %{ evaluate-commands %sh{
if [ $# -eq 1 ]; then
printf %s\\n "evaluate-commands -client '$1' focus"
else

View File

@ -127,7 +127,7 @@ define-command -hidden c-family-insert-on-newline %[ evaluate-commands -itersel
] ]
# Regions definition are the same between c++ and objective-c
%sh{
evaluate-commands %sh{
for ft in c cpp objc; do
if [ "${ft}" = "objc" ]; then
maybe_at='@?'
@ -155,7 +155,7 @@ define-command -hidden c-family-insert-on-newline %[ evaluate-commands -itersel
# c specific
add-highlighter shared/c/code regex %{\b-?(0x[0-9a-fA-F]+|\d+)[fdiu]?|'((\\.)?|[^'\\])'} 0:value
%sh{
evaluate-commands %sh{
# Grammar
keywords="asm break case continue default do else for goto if return
sizeof switch while"
@ -199,7 +199,7 @@ add-highlighter shared/cpp/code regex %{(?i)(?<!\.)\b0x([\da-f]('?[\da-f]+)*)?\.
# character literals (no multi-character literals)
add-highlighter shared/cpp/code regex %{(\b(u8|u|U|L)|\B)'((\\.)|[^'\\])'\B} 0:value
%sh{
evaluate-commands %sh{
# Grammar
keywords="alignas alignof and and_eq asm bitand bitor break case catch
compl const_cast continue decltype default delete do dynamic_cast
@ -231,7 +231,7 @@ add-highlighter shared/cpp/code regex %{(\b(u8|u|U|L)|\B)'((\\.)|[^'\\])'\B} 0:v
}
# c and c++ compiler macros
%sh{
evaluate-commands %sh{
builtin_macros="__cplusplus|__STDC_HOSTED__|__FILE__|__LINE__|__DATE__|__TIME__|__STDCPP_DEFAULT_NEW_ALIGNMENT__"
printf %s "
@ -243,7 +243,7 @@ add-highlighter shared/cpp/code regex %{(\b(u8|u|U|L)|\B)'((\\.)|[^'\\])'\B} 0:v
# objective-c specific
add-highlighter shared/objc/code regex %{\b-?\d+[fdiu]?|'((\\.)?|[^'\\])'} 0:value
%sh{
evaluate-commands %sh{
# Grammar
keywords="break case continue default do else for goto if return switch
while"
@ -314,7 +314,7 @@ Can be one of the following:
str c_include_guard_style "ifdef"
define-command -hidden c-family-insert-include-guards %{
%sh{
evaluate-commands %sh{
case "${kak_opt_c_include_guard_style}" in
ifdef)
echo 'execute-keys ggi<c-r>%<ret><esc>ggxs\.<ret>c_<esc><space>A_INCLUDED<esc>ggxyppI#ifndef<space><esc>jI#define<space><esc>jI#endif<space>//<space><esc>O<esc>'
@ -332,7 +332,7 @@ hook -group c-family-insert global BufNewFile .*\.(h|hh|hpp|hxx|H) c-family-inse
declare-option -docstring "colon separated list of path in which header files will be looked for" \
str-list alt_dirs ".:.."
define-command c-family-alternative-file -docstring "Jump to the alternate file (header/implementation)" %{ %sh{
define-command c-family-alternative-file -docstring "Jump to the alternate file (header/implementation)" %{ evaluate-commands %sh{
alt_dirs=$(printf %s\\n "${kak_opt_alt_dirs}" | tr ':' '\n')
file="${kak_buffile##*/}"
file_noext="${file%.*}"

View File

@ -111,7 +111,7 @@ hook global BufSetOption filetype=ruby %{
}
define-command comment-block -docstring '(un)comment selections using block comments' %{
%sh{
evaluate-commands %sh{
if [ -z "${kak_opt_comment_block_begin}" ] || [ -z "${kak_opt_comment_block_end}" ]; then
echo "fail \"The 'comment_block' options are empty, could not comment the selection\""
fi
@ -138,7 +138,7 @@ define-command comment-block -docstring '(un)comment selections using block comm
}
define-command comment-line -docstring '(un)comment selected lines using line comments' %{
%sh{
evaluate-commands %sh{
if [ -z "${kak_opt_comment_line}" ]; then
echo "fail \"The 'comment_line' option is empty, could not comment the line\""
fi

View File

@ -11,7 +11,7 @@ define-command -hidden -params 4 doc-render-regex %{
execute-keys \%s %arg{1} <ret>
execute-keys -draft s %arg{2} <ret> d
execute-keys "%arg{3}"
%sh{
evaluate-commands %sh{
ranges=$(echo "$kak_selections_desc" | sed -e "s/:/|$4:/g; s/\$/|$4/")
echo "update-option buffer doc_render_ranges"
echo "set-option -add buffer doc_render_ranges '$ranges'"
@ -54,7 +54,7 @@ define-command -hidden doc-parse-anchors %{
define-command doc-jump-to-anchor -params 1 %{
update-option buffer doc_anchors
%sh{
evaluate-commands %sh{
range=$(printf "%s" "$kak_opt_doc_anchors" | tr ':' '\n' | grep "$1" | head -n1)
if [ -n "$range" ]; then
printf '%s\n' "select '${range%|*}'; execute-keys vv"
@ -66,7 +66,7 @@ define-command doc-jump-to-anchor -params 1 %{
define-command doc-follow-link %{
update-option buffer doc_links
%sh{
evaluate-commands %sh{
printf "%s" "$kak_opt_doc_links" | awk -v RS=':' -v FS='[.,|#]' '
BEGIN {
l=ENVIRON["kak_cursor_line"];
@ -136,7 +136,7 @@ define-command -params 1..2 \
} \
doc -docstring %{doc <topic> [<keyword>]: open a buffer containing documentation about a given topic
An optional keyword argument can be passed to the function, which will be automatically selected in the documentation} %{
%sh{
evaluate-commands %sh{
readonly page="${kak_runtime}/doc/${1}.asciidoc"
if [ -f "${page}" ]; then
if [ $# -eq 2 ]; then

View File

@ -2,18 +2,18 @@ declare-option -docstring "shell command to which the contents of the current bu
str formatcmd
define-command format -docstring "Format the contents of the current buffer" %{ evaluate-commands -draft -no-hooks %{
%sh{
evaluate-commands %sh{
if [ -n "${kak_opt_formatcmd}" ]; then
path_file_tmp=$(mktemp "${TMPDIR:-/tmp}"/kak-formatter-XXXXXX)
printf %s\\n "
write -sync \"${path_file_tmp}\"
%sh{
evaluate-commands %sh{
readonly path_file_out=\$(mktemp \"${TMPDIR:-/tmp}\"/kak-formatter-XXXXXX)
if cat \"${path_file_tmp}\" | eval \"${kak_opt_formatcmd}\" > \"\${path_file_out}\"; then
printf '%s\\n' \"execute-keys \\%|cat<space>'\${path_file_out}'<ret>\"
printf '%s\\n' \"%sh{ rm -f '\${path_file_out}' }\"
printf '%s\\n' \"nop %sh{ rm -f '\${path_file_out}' }\"
else
printf '%s\\n' \"
evaluate-commands -client '${kak_client}' echo -markup '{Error}formatter returned an error (\$?)'

View File

@ -7,7 +7,7 @@ declare-option -hidden int grep_current_line 0
define-command -params .. -file-completion \
-docstring %{grep [<arguments>]: grep utility wrapper
All the optional arguments are forwarded to the grep utility} \
grep %{ %sh{
grep %{ evaluate-commands %sh{
output=$(mktemp -d "${TMPDIR:-/tmp}"/kak-grep.XXXXXXXX)/fifo
mkfifo ${output}
if [ $# -gt 0 ]; then

View File

@ -15,16 +15,16 @@ add-highlighter shared/ regions -default code kakrc \
comment (^|\h)\K# $ '' \
double_string %{(^|\h)\K"} %{(?<!\\)(\\\\)*"} '' \
single_string %{(^|\h)\K'} %{(?<!\\)(\\\\)*'} '' \
shell '(^|\h)\K%sh\{' '\}' '\{' \
shell '(^|\h)\K%sh\(' '\)' '\(' \
shell '(^|\h)\K%sh\[' '\]' '\[' \
shell '(^|\h)\K%sh<' '>' '<' \
shell '(^|\h)\K%?%sh\{' '\}' '\{' \
shell '(^|\h)\K%?%sh\(' '\)' '\(' \
shell '(^|\h)\K%?%sh\[' '\]' '\[' \
shell '(^|\h)\K%?%sh<' '>' '<' \
shell '(^|\h)\K-shell-(completion|candidates)\h+%\{' '\}' '\{' \
shell '(^|\h)\K-shell-(completion|candidates)\h+%\(' '\)' '\(' \
shell '(^|\h)\K-shell-(completion|candidates)\h+%\[' '\]' '\[' \
shell '(^|\h)\K-shell-(completion|candidates)\h+%<' '>' '<'
%sh{
evaluate-commands %sh{
# Grammar
keywords="edit write write-all kill quit write-quit write-all-quit map unmap alias unalias
buffer buffer-next buffer-previous delete-buffer add-highlighter remove-highlighter

View File

@ -10,7 +10,7 @@ declare-option -hidden int make_current_error_line
define-command -params .. \
-docstring %{make [<arguments>]: make utility wrapper
All the optional arguments are forwarded to the make utility} \
make %{ %sh{
make %{ evaluate-commands %sh{
output=$(mktemp -d "${TMPDIR:-/tmp}"/kak-make.XXXXXXXX)/fifo
mkfifo ${output}
( eval ${kak_opt_makecmd} "$@" > ${output} 2>&1 ) > /dev/null 2>&1 < /dev/null &

View File

@ -18,7 +18,7 @@ add-highlighter shared/makefile/evaluate-commands fill value
add-highlighter shared/makefile/content regex ^[\w.%-]+\h*:\s 0:variable
add-highlighter shared/makefile/content regex [+?:]= 0:operator
%sh{
evaluate-commands %sh{
# Grammar
keywords="ifeq|ifneq|ifdef|ifndef|else|endif|define|endef"

View File

@ -27,7 +27,7 @@ hook global WinSetOption filetype=(?!man).* %{
remove-hooks window man-hooks
}
define-command -hidden -params 2..3 man-impl %{ %sh{
define-command -hidden -params 2..3 man-impl %{ evaluate-commands %sh{
buffer_name="$1"
shift
manout=$(mktemp "${TMPDIR:-/tmp}"/kak-man-XXXXXX)
@ -57,7 +57,7 @@ define-command -params ..1 \
-docstring %{man [<page>]: manpage viewer wrapper
If no argument is passed to the command, the selection will be used as page
The page can be a word, or a word directly followed by a section number between parenthesis, e.g. kak(1)} \
man %{ %sh{
man %{ evaluate-commands %sh{
subject=${1-$kak_selection}
## The completion suggestions display the page number, strip them if present

View File

@ -41,7 +41,7 @@ add-highlighter shared/python/docstring/py-docstring/docstring fill string
add-highlighter shared/python/comment fill comment
%sh{
evaluate-commands %sh{
# Grammar
values="True|False|None|self|inf"
meta="import|from"

View File

@ -13,7 +13,7 @@ add-highlighter shared/sh/single_string fill string
add-highlighter shared/sh/comment fill comment
add-highlighter shared/sh/heredoc fill string
%sh{
evaluate-commands %sh{
# Grammar
keywords="alias|bind|builtin|caller|case|cd|command|coproc|declare|do|done"
keywords="${keywords}|echo|elif|else|enable|esac|exit|fi|for|function|help"

View File

@ -3,7 +3,7 @@ declare-option -docstring "remove backups once they've been restored" \
## Insert the content of the backup file into the current buffer, if a suitable one is found
define-command autorestore-restore-buffer -docstring "Restore the backup for the current file if it exists" %{
%sh{
evaluate-commands %sh{
buffer_basename="${kak_buffile##*/}"
buffer_dirname=$(dirname "${kak_buffile}")
@ -49,7 +49,7 @@ define-command autorestore-restore-buffer -docstring "Restore the backup for the
## Remove all the backups that have been created for the current buffer
define-command autorestore-purge-backups -docstring "Remove all the backups of the current buffer" %{
%sh{
evaluate-commands %sh{
[ ! -f "${kak_buffile}" ] && exit
buffer_basename="${kak_bufname##*/}"

View File

@ -10,7 +10,7 @@ define-command -params ..1 \
-docstring %{Parse the contents of the current buffer
The syntaxic errors detected during parsing are shown when auto-diagnostics are enabled} \
clang-parse %{
%sh{
evaluate-commands %sh{
dir=$(mktemp -d "${TMPDIR:-/tmp}"/kak-clang.XXXXXXXX)
mkfifo ${dir}/fifo
printf %s\\n "set-option buffer clang_tmp_dir ${dir}"
@ -18,7 +18,7 @@ The syntaxic errors detected during parsing are shown when auto-diagnostics are
}
# end the previous %sh{} so that its output gets interpreted by kakoune
# before launching the following as a background task.
%sh{
evaluate-commands %sh{
dir=${kak_opt_clang_tmp_dir}
printf %s\\n "evaluate-commands -draft %{
edit! -fifo ${dir}/fifo -debug *clang-output*
@ -106,7 +106,7 @@ define-command clang-complete -docstring "Complete the current selection" %{ cla
define-command -hidden clang-show-completion-info %[ try %[
evaluate-commands -draft %[
execute-keys <space>{( <a-k> ^\( <ret> b <a-k> \A\w+\z <ret>
%sh[
evaluate-commands %sh[
desc=$(printf %s\\n "${kak_opt_clang_completions}" | sed -e "{ s/\([^\\]\):/\1\n/g }" | sed -ne "/^${kak_selection}|/ { s/^[^|]\+|//; s/|.*$//; s/\\\:/:/g; p }")
if [ -n "$desc" ]; then
printf %s\\n "evaluate-commands -client $kak_client %{info -anchor ${kak_cursor_line}.${kak_cursor_column} -placement above %{${desc}}}"
@ -135,7 +135,7 @@ define-command clang-disable-autocomplete -docstring "Disable automatic clang co
define-command -hidden clang-show-error-info %{
update-option buffer clang_errors # Ensure we are up to date with buffer changes
%sh{
evaluate-commands %sh{
desc=$(printf %s\\n "${kak_opt_clang_errors}" |
sed -e "s/\([^\\]\):/\1\n/g" |
sed -ne "/^${kak_cursor_line}|.*/ { s/^[[:digit:]]\+|//g; s/'/\\\\'/g; s/\\\\:/:/g; p }")
@ -159,7 +159,7 @@ define-command clang-disable-diagnostics -docstring "Disable automatic error rep
define-command clang-diagnostics-next -docstring "Jump to the next line that contains an error" %{
update-option buffer clang_errors # Ensure we are up to date with buffer changes
%sh{
evaluate-commands %sh{
printf "%s\n" "${kak_opt_clang_errors}" | sed -e 's/\([^\\]\):/\1\n/g' | tail -n +2 | (
while IFS='|' read candidate rest; do
first_line=${first_line-$candidate}

View File

@ -18,7 +18,7 @@ add-highlighter shared/ regions -default code dockerfile \
string "'" "'" '' \
comment '#' $ ''
%sh{
evaluate-commands %sh{
# Grammar
keywords="ADD|ARG|CMD|COPY|ENTRYPOINT|ENV|EXPOSE|FROM|HEALTHCHECK|LABEL"
keywords="${keywords}|MAINTAINER|RUN|SHELL|STOPSIGNAL|USER|VOLUME|WORKDIR"

View File

@ -5,7 +5,7 @@ declare-option -hidden bool editorconfig_trim_trailing_whitespace false
define-command editorconfig-load -params ..1 -docstring "editorconfig-load [file]: set formatting behavior according to editorconfig" %{
remove-hooks buffer editorconfig-hooks
%sh{
evaluate-commands %sh{
command -v editorconfig >/dev/null 2>&1 || { echo 'echo -markup "{Error}editorconfig could not be found"'; exit 1; }
editorconfig "${1:-$kak_buffile}" | awk -F= -- '
/indent_style=/ { indent_style = $2 }
@ -39,7 +39,7 @@ define-command editorconfig-load -params ..1 -docstring "editorconfig-load [file
}
'
}
hook buffer BufWritePre %val{buffile} -group editorconfig-hooks %{ %sh{
hook buffer BufWritePre %val{buffile} -group editorconfig-hooks %{ evaluate-commands %sh{
if [ ${kak_opt_editorconfig_trim_trailing_whitespace} = "true" ]; then
printf %s\\n "try %{ execute-keys -draft %{ %s\h+$<ret>d } }"
fi

View File

@ -24,9 +24,9 @@ set-face global GitBlame default,magenta
set-face global GitDiffFlags default,black
define-command -params 1.. \
-docstring %sh{printf '%%{git [<arguments>]: git wrapping helper
-docstring %sh{printf 'git [<arguments>]: git wrapping helper
All the optional arguments are forwarded to the git utility
Available commands:\n add\n rm\n blame\n commit\n checkout\n diff\n hide-blame\n log\n show\n show-diff\n status\n update-diff}'} \
Available commands:\n add\n rm\n blame\n commit\n checkout\n diff\n hide-blame\n log\n show\n show-diff\n status\n update-diff'} \
-shell-candidates %{
if [ $kak_token_to_complete -eq 0 ]; then
printf "add\nrm\nblame\ncommit\ncheckout\ndiff\nhide-blame\nlog\nshow\nshow-diff\nstatus\nupdate-diff\n"
@ -38,7 +38,7 @@ Available commands:\n add\n rm\n blame\n commit\n checkout\n diff\n hide-
esac
fi
} \
git %{ %sh{
git %{ evaluate-commands %sh{
show_git_cmd_output() {
local filetype
case "$1" in
@ -166,7 +166,7 @@ Available commands:\n add\n rm\n blame\n commit\n checkout\n diff\n hide-
GIT_EDITOR='' EDITOR='' git commit "$@" > /dev/null 2>&1
msgfile="$(git rev-parse --git-dir)/COMMIT_EDITMSG"
printf %s "edit '$msgfile'
hook buffer BufWritePost '.*\Q$msgfile\E' %{ %sh{
hook buffer BufWritePost '.*\Q$msgfile\E' %{ evaluate-commands %sh{
if git commit -F '$msgfile' --cleanup=strip $* > /dev/null; then
printf %s 'evaluate-commands -client $kak_client echo -markup %{{Information}Commit succeeded}; delete-buffer'
else

View File

@ -5,7 +5,7 @@
# Needs the following tools in the path:
# - jq for json deserializaton
%sh{
evaluate-commands %sh{
for dep in gocode goimports gogetdoc jq; do
if ! command -v $dep > /dev/null 2>&1; then
echo "echo -debug %{Dependency unmet: $dep, please install it to use go-tools}"
@ -20,12 +20,12 @@ declare-option -hidden str go_complete_tmp_dir
declare-option -hidden completions gocode_completions
define-command go-complete -docstring "Complete the current selection with gocode" %{
%sh{
evaluate-commands %sh{
dir=$(mktemp -d "${TMPDIR:-/tmp}"/kak-go.XXXXXXXX)
printf %s\\n "set-option buffer go_complete_tmp_dir ${dir}"
printf %s\\n "evaluate-commands -no-hooks write ${dir}/buf"
}
%sh{
nop %sh{
dir=${kak_opt_go_complete_tmp_dir}
(
gocode_data=$(gocode -f=godit --in=${dir}/buf autocomplete ${kak_cursor_byte_offset})
@ -63,12 +63,12 @@ declare-option -hidden str go_format_tmp_dir
define-command -params ..1 go-format \
-docstring "go-format [-use-goimports]: custom formatter for go files" %{
%sh{
evaluate-commands %sh{
dir=$(mktemp -d "${TMPDIR:-/tmp}"/kak-go.XXXXXXXX)
printf %s\\n "set-option buffer go_format_tmp_dir ${dir}"
printf %s\\n "evaluate-commands -no-hooks write ${dir}/buf"
}
%sh{
evaluate-commands %sh{
dir=${kak_opt_go_format_tmp_dir}
if [ "$1" = "-use-goimports" ]; then
fmt_cmd="goimports -srcdir '${kak_buffile}'"
@ -94,12 +94,12 @@ declare-option -hidden str go_doc_tmp_dir
# FIXME text escaping
define-command -hidden -params 1..2 gogetdoc-cmd %{
%sh{
evaluate-commands %sh{
dir=$(mktemp -d "${TMPDIR:-/tmp}"/kak-go.XXXXXXXX)
printf %s\\n "set-option buffer go_doc_tmp_dir ${dir}"
printf %s\\n "evaluate-commands -no-hooks write ${dir}/buf"
}
%sh{
evaluate-commands %sh{
dir=${kak_opt_go_doc_tmp_dir}
(
printf %s\\n "${kak_buffile}" > ${dir}/modified
@ -172,7 +172,7 @@ define-command go-jump -docstring "Jump to the symbol definition" %{
gogetdoc-cmd "jump" 1
}
define-command go-share-selection -docstring "Share the selection using the Go Playground" %{ %sh{
define-command go-share-selection -docstring "Share the selection using the Go Playground" %{ evaluate-commands %sh{
snippet_id=$(printf %s\\n "${kak_selection}" | curl -s https://play.golang.org/share --data-binary @-)
printf "echo https://play.golang.org/p/%s" ${snippet_id}
} }

View File

@ -3,8 +3,7 @@
## The default behaviour for the `new` command is to open an vertical pane in
## an iTerm session if not in a tmux session.
hook global KakBegin .* %{
%sh{
hook global KakBegin .* %sh{
if [ "$TERM_PROGRAM" = "iTerm.app" ] && [ -z "$TMUX" ]; then
echo "
alias global new iterm-new-vertical
@ -12,10 +11,9 @@ hook global KakBegin .* %{
"
fi
}
}
define-command -hidden -params 1.. iterm-new-split-impl %{
%sh{
nop %sh{
direction="$1"
shift
if [ $# -gt 0 ]; then kakoune_params="-e \\\"$*\\\""; fi
@ -41,7 +39,7 @@ define-command -params .. -command-completion \
-docstring %{iterm-new-tab [<arguments>]: create a new tab
All optional arguments are forwarded to the new kak client} \
iterm-new-tab %{
%sh{
nop %sh{
if [ $# -gt 0 ]; then kakoune_params="-e \\\"$*\\\""; fi
cmd="env PATH='${PATH}' TMPDIR='${TMPDIR}' kak -c '${kak_session}' ${kakoune_params}"
osascript \
@ -57,7 +55,7 @@ define-command -params .. -command-completion \
-docstring %{iterm-new-window [<arguments>]: create a new window
All optional arguments are forwarded to the new kak client} \
iterm-new-window %{
%sh{
nop %sh{
if [ $# -gt 0 ]; then kakoune_params="-e \\\"$*\\\""; fi
cmd="env PATH='${PATH}' TMPDIR='${TMPDIR}' kak -c '${kak_session}' ${kakoune_params}"
osascript \
@ -70,7 +68,7 @@ All optional arguments are forwarded to the new kak client} \
define-command -params ..1 -client-completion \
-docstring %{iterm-focus [<client>]: focus the given client
If no client is passed then the current one is used} \
iterm-focus %{ %sh{
iterm-focus %{ evaluate-commands %sh{
if [ $# -eq 1 ]; then
printf %s\\n "evaluate-commands -client '$1' focus"
else

View File

@ -4,13 +4,13 @@ declare-option -docstring "colon separated list of path added to `python`'s $PYT
str-list jedi_python_path
define-command jedi-complete -docstring "Complete the current selection" %{
%sh{
evaluate-commands %sh{
dir=$(mktemp -d "${TMPDIR:-/tmp}"/kak-jedi.XXXXXXXX)
mkfifo ${dir}/fifo
printf %s\\n "set-option buffer jedi_tmp_dir ${dir}"
printf %s\\n "evaluate-commands -no-hooks write -sync ${dir}/buf"
}
%sh{
evaluate-commands %sh{
dir=${kak_opt_jedi_tmp_dir}
printf %s\\n "evaluate-commands -draft %{ edit! -fifo ${dir}/fifo *jedi-output* }"
(

View File

@ -11,7 +11,7 @@ declare-option -docstring "amount of lines that will be checked at the beginning
int modelines 5
define-command -hidden modeline-parse-impl %{
%sh{
evaluate-commands %sh{
# Translate a vim option into the corresponding kakoune one
translate_opt_vim() {
readonly key="$1"

View File

@ -30,7 +30,7 @@ add-highlighter shared/moon/code regex \b(and|break|catch|class|continue|do|else
# Commands
# ‾‾‾‾‾‾‾‾
define-command moon-alternative-file -docstring 'Jump to the alternate file (implementation ↔ test)' %{ %sh{
define-command moon-alternative-file -docstring 'Jump to the alternate file (implementation ↔ test)' %{ evaluate-commands %sh{
case $kak_buffile in
*spec/*_spec.moon)
altfile=$(eval printf %s\\n $(printf %s\\n $kak_buffile | sed s+spec/+'*'/+';'s/_spec//))

View File

@ -23,7 +23,7 @@ add-highlighter shared/nim/code regex \b(0[xXocCbB])?[\d_]+('[iIuUfFdD](8|16|32|
add-highlighter shared/nim/code regex \b\d+\.\d+\b 0:value
add-highlighter shared/nim/code regex %{'[^'\n]'} 0:string
%sh{
evaluate-commands %sh{
# Grammar
keywords="addr|and|as|asm|atomic|bind|block|break|case|cast|concept|const"
keywords="${keywords}|continue|converter|defer|discard|distinct|div|do|elif"

View File

@ -22,7 +22,7 @@ add-highlighter shared/pony/double_string fill string
add-highlighter shared/pony/comment fill comment
%sh{
evaluate-commands %sh{
# Grammar
values="true|false|None|this"
meta='use'

View File

@ -2,12 +2,12 @@ declare-option -hidden str racer_tmp_dir
declare-option -hidden completions racer_completions
define-command racer-complete -docstring "Complete the current selection with racer" %{
%sh{
evaluate-commands %sh{
dir=$(mktemp -d "${TMPDIR:-/tmp}"/kak-racer.XXXXXXXX)
printf %s\\n "set-option buffer racer_tmp_dir ${dir}"
printf %s\\n "evaluate-commands -no-hooks %{ write ${dir}/buf }"
}
%sh{
nop %sh{
dir=${kak_opt_racer_tmp_dir}
(
cursor="${kak_cursor_line} $((${kak_cursor_column} - 1))"
@ -95,12 +95,12 @@ define-command racer-disable-autocomplete -docstring "Disable racer completion"
}
define-command racer-go-definition -docstring "Jump to where the rust identifier below the cursor is defined" %{
%sh{
evaluate-commands %sh{
dir=$(mktemp -d "${TMPDIR:-/tmp}"/kak-racer.XXXXXXXX)
printf %s\\n "set-option buffer racer_tmp_dir ${dir}"
printf %s\\n "evaluate-commands -no-hooks %{ write ${dir}/buf }"
}
%sh{
evaluate-commands %sh{
dir=${kak_opt_racer_tmp_dir}
cursor="${kak_cursor_line} $((${kak_cursor_column} - 1))"
racer_data=$(racer --interface tab-text find-definition ${cursor} "${kak_buffile}" "${dir}/buf" | head -n 1)
@ -122,12 +122,12 @@ define-command racer-go-definition -docstring "Jump to where the rust identifier
}
define-command racer-show-doc -docstring "Show the documentation about the rust identifier below the cursor" %{
%sh{
evaluate-commands %sh{
dir=$(mktemp -d "${TMPDIR:-/tmp}"/kak-racer.XXXXXXXX)
printf %s\\n "set-option buffer racer_tmp_dir ${dir}"
printf %s\\n "evaluate-commands -no-hooks %{ write ${dir}/buf }"
}
%sh{
evaluate-commands %sh{
dir=${kak_opt_racer_tmp_dir}
cursor="${kak_cursor_line} ${kak_cursor_column}"
racer_data=$(racer --interface tab-text complete-with-snippet ${cursor} "${kak_buffile}" "${dir}/buf" | sed -n 2p )

View File

@ -3,7 +3,7 @@
define-command ranger-open-on-edit-directory \
-docstring 'Start the ranger file system explorer when trying to edit a directory' %{
hook global RuntimeError "\d+:\d+: '\w+' (.*): is a directory" %{ %sh{
hook global RuntimeError "\d+:\d+: '\w+' (.*): is a directory" %{ evaluate-commands %sh{
directory=$kak_hook_param_capture_1
echo ranger $directory
}}
@ -13,7 +13,7 @@ define-command \
-params .. -file-completion \
-docstring %{ranger [<arguments>]: open the file system explorer to select buffers to open
All the optional arguments are forwarded to the ranger utility} \
ranger %{ %sh{
ranger %{ evaluate-commands %sh{
if [ -n "${TMUX}" ]; then
tmux split-window -h \
ranger $@ --cmd " \

View File

@ -1,8 +1,7 @@
# http://tmux.github.io/
# ‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾
hook global KakBegin .* %{
%sh{
hook global KakBegin .* %sh{
if [ -n "$TMUX" ]; then
VERSION_TMUX=$(tmux -V | cut -d' ' -f2)
VERSION_TMUX=${VERSION_TMUX%%.*}
@ -21,10 +20,9 @@ hook global KakBegin .* %{
fi
fi
}
}
define-command -hidden -params 1..2 tmux-repl-impl %{
%sh{
evaluate-commands %sh{
if [ -z "$TMUX" ]; then
echo "echo -markup '{Error}This command is only available in a tmux session'"
exit
@ -68,7 +66,7 @@ define-command -hidden tmux-send-text -params 0..1 -docstring "tmux-send-text [t
}
}
define-command -hidden tmux-repl-disabled %{ %sh{
define-command -hidden tmux-repl-disabled %{ evaluate-commands %sh{
VERSION_TMUX=$(tmux -V)
printf %s "echo -markup %{{Error}The version of tmux is too old: got ${VERSION_TMUX}, expected >= 2.x}"
} }

View File

@ -3,7 +3,7 @@ define-command -docstring %{x11-repl [<arguments>]: create a new window for repl
All optional parameters are forwarded to the new window} \
-params .. \
-command-completion \
x11-repl %{ %sh{
x11-repl %{ evaluate-commands %sh{
if [ -z "${kak_opt_termcmd}" ]; then
echo "echo -markup '{Error}termcmd option is not set'"
exit

View File

@ -6,7 +6,7 @@ def -params 1 -docstring "colorscheme <name>: enable named colorscheme" \
printf %s\\n "${basename%.*}"
done | sort -u
} \
colorscheme %{ %sh{
colorscheme %{ evaluate-commands %sh{
find_colorscheme() {
find -L "${1}" -type f -name "${2}".kak | head -n 1
}
@ -25,7 +25,7 @@ def -params 1 -docstring "colorscheme <name>: enable named colorscheme" \
fi
}}
%sh{
evaluate-commands %sh{
autoload_directory() {
find -L "$1" -type f -name '*\.kak' \
-exec printf 'try %%{ source "%s" } catch %%{ echo -debug Autoload: could not load "%s" }\n' '{}' '{}' \;

View File

@ -171,6 +171,7 @@ Token parse_percent_token(Reader& reader, bool throw_on_unterminated)
{
kak_assert(*reader == '%');
++reader;
const auto type_start = reader.pos;
while (reader and iswalpha(*reader))
++reader;
@ -441,26 +442,10 @@ void CommandManager::execute(StringView command_line,
Context& context, const ShellContext& shell_context)
{
CommandParser parser(command_line);
struct ShellParser {
ShellParser(String&& str) : output{std::move(str)}, parser{output} {}
String output;
CommandParser parser;
};
Vector<ShellParser> shell_parser_stack;
auto next_token = [&] {
while (not shell_parser_stack.empty())
{
if (auto shell_token = shell_parser_stack.back().parser.read_token(true))
return shell_token;
shell_parser_stack.pop_back();
}
return parser.read_token(true);
};
BufferCoord command_coord;
Vector<String> params;
while (Optional<Token> token_opt = next_token())
Vector<String, MemoryDomain::Commands> params;
while (Optional<Token> token_opt = parser.read_token(true))
{
auto& token = *token_opt;
if (params.empty())
@ -471,9 +456,6 @@ void CommandManager::execute(StringView command_line,
execute_single_command(params, context, shell_context, command_coord);
params.clear();
}
// Shell expand are retokenized
else if (token.type == Token::Type::ShellExpand)
shell_parser_stack.emplace_back(expand_token(token, context, shell_context));
else if (token.type == Token::Type::ArgExpand and token.content == '@')
params.insert(params.end(), shell_context.params.begin(),
shell_context.params.end());

View File

@ -1702,14 +1702,14 @@ void context_wrap(const ParametersParser& parser, Context& context, Func func)
}
else
{
const bool transient = c.flags() & Context::Flags::Draft;
auto original_jump_list = transient ? Optional<JumpList>{} : c.jump_list();
auto jump = transient ? Optional<SelectionList>{} : c.selections();
const bool collapse_jumps = not (c.flags() & Context::Flags::Draft) and context.has_buffer();
auto original_jump_list = collapse_jumps ? c.jump_list() : Optional<JumpList>{};
auto jump = collapse_jumps ? c.selections() : Optional<SelectionList>{};
func(parser, c);
// If the jump list got mutated, collapse all jumps into a single one from original selections
if (not transient and c.jump_list() != *original_jump_list)
if (collapse_jumps and c.jump_list() != *original_jump_list)
{
original_jump_list->push(std::move(*jump));
if (c.jump_list() != *original_jump_list)

View File

@ -159,10 +159,11 @@ private:
struct ScopedEdition
{
ScopedEdition(Context& context)
: m_context(context), m_buffer(&context.buffer())
{ m_context.begin_edition(); }
: m_context{context},
m_buffer{context.has_buffer() ? &context.buffer() : nullptr}
{ if (m_buffer) m_context.begin_edition(); }
~ScopedEdition() { m_context.end_edition(); }
~ScopedEdition() { if (m_buffer) m_context.end_edition(); }
Context& context() const { return m_context; }
private:

View File

@ -52,7 +52,8 @@ static const char* startup_info =
" * faces are now scoped, set-face command takes an additional scope parameter\n"
" * <backtab> key is gone, use <s-tab> instead\n"
" === Kakoune v2018.04.13 Released ===\n"
" * define-command -allow-override switch has been renamed -override\n";
" * define-command -allow-override switch has been renamed -override\n"
" %sh{...} strings are not automatically reparsed anymore, use evaluate-commands %sh{...}\n";
struct startup_error : runtime_error
{