From 26561eea1da8cbce7869fb3ec27aeb37933c556f Mon Sep 17 00:00:00 2001
From: Philipp Jungkamp
Date: Sun, 4 Aug 2024 22:44:13 +0200
Subject: [PATCH 1/4] Add -echo argument to provide reliable quoting in shell
scripts
---
doc/kak.1 | 10 ++++++++++
src/main.cc | 8 ++++++++
2 files changed, 18 insertions(+)
diff --git a/doc/kak.1 b/doc/kak.1
index 37fab36bbf..a12dec232f 100644
--- a/doc/kak.1
+++ b/doc/kak.1
@@ -24,6 +24,10 @@
.Op Ar file ...
.
.Nm
+.Fl quote Sy raw|shell|kakoune
+.Op Ar string ...
+.
+.Nm
.Fl p Ar session_id
.
.Nm
@@ -151,6 +155,12 @@ Begin in
.Em readonly mode ,
all the buffers opened will not be written to disk.
.
+.It Fl quote Sy raw|shell|kakoune Op Ar string ...
+Escape one or more
+.Ar strings
+for interpolation into kakoune or shell scripts.
+Multiple strings will be escaped first and then joined with spaces inbetween.
+.
.It Sy + Ns Ar line Ns Oo Sy \&: Ns Ar column Oc | Sy +:
Specify a target line and column for the first file.
When the plus sign is followed by only a colon, then the cursor is sent
diff --git a/src/main.cc b/src/main.cc
index e86ffae3ba..1a0468e7e7 100644
--- a/src/main.cc
+++ b/src/main.cc
@@ -1103,6 +1103,7 @@ int main(int argc, char* argv[])
{ "debug", { ArgCompleter{}, "initial debug option value" } },
{ "version", { {}, "display kakoune version and exit" } },
{ "ro", { {}, "readonly mode" } },
+ { "quote", { ArgCompleter{}, "echo each argument with the given quoting (raw, kakoune, or shell)" } },
{ "help", { {}, "display a help message and quit" } } }
};
@@ -1153,6 +1154,13 @@ int main(int argc, char* argv[])
return 0;
}
+ if (auto quoting = parser.get_switch("quote"))
+ {
+ write_stdout(join(parser | transform(quoter(option_from_string(Meta::Type{}, *quoting))),
+ ' ', false));
+ return 0;
+ }
+
if (auto session = parser.get_switch("p"))
{
for (auto opt : { "c", "n", "s", "d", "e", "E", "ro" })
From 38e71f45add0176721a151b2b7d7603190ec81f0 Mon Sep 17 00:00:00 2001
From: Philipp Jungkamp
Date: Sun, 4 Aug 2024 23:48:24 +0200
Subject: [PATCH 2/4] menu.kak: Replace sed with kak -quote
---
rc/tools/menu.kak | 57 +++++++++++++++++++++++------------------------
1 file changed, 28 insertions(+), 29 deletions(-)
diff --git a/rc/tools/menu.kak b/rc/tools/menu.kak
index 4fd7dde4f5..453269a999 100644
--- a/rc/tools/menu.kak
+++ b/rc/tools/menu.kak
@@ -31,9 +31,6 @@ define-command menu -params 1.. -docstring %{
printf %s "$2"
exit
fi
- shellquote() {
- printf "'%s'" "$(printf %s "$1" | sed "s/'/'\\\\''/g; s/§/§§/g; $2")"
- }
cases=
select_cases=
completion=
@@ -43,43 +40,45 @@ define-command menu -params 1.. -docstring %{
command=$2
completion="${completion}${title}${nl}"
cases="${cases}
- ($(shellquote "$title" s/¶/¶¶/g))
- printf '%s\\n' $(shellquote "$command" s/¶/¶¶/g)
+ $(kak -quote shell -- "$title"))
+ printf '%s\\n' $(kak -quote shell -- "$command")
;;"
if $select_cmds; then
select_command=$3
select_cases="${select_cases}
- ($(shellquote "$title" s/¶/¶¶/g))
- printf '%s\\n' $(shellquote "$select_command" s/¶/¶¶/g)
+ $(kak -quote shell -- "$title"))
+ printf '%s\\n' $(kak -quote shell -- "$select_command")
;;"
fi
shift $stride
done
- printf "\
- prompt '' %%§
- evaluate-commands %%sh¶
- case \"\$kak_text\" in \
- %s
- (*) echo fail -- no such item: \"'\$(printf %%s \"\$kak_text\" | sed \"s/'/''/g\")'\" ;;
- esac
- ¶
- §" "$cases"
+
+ printf "%s" "prompt '' $(kak -quote kakoune -- "
+ evaluate-commands %sh$(kak -quote kakoune -- '
+ case "$kak_text" in
+ '"${cases}"'
+ *) echo fail -- no such item: "$(kak -quote kakoune -- "$kak_text")"
+ esac
+ ')
+ ")"
+
if $select_cmds; then
- printf " \
- -on-change %%§
- evaluate-commands %%sh¶
- case \"\$kak_text\" in \
- %s
- (*) : ;;
- esac
- ¶
- §" "$select_cases"
+ printf "%s" " -on-change $(kak -quote kakoune -- "
+ evaluate-commands %sh$(kak -quote kakoune -- '
+ case "$kak_text" in
+ '"$select_cases"'
+ *) : ;;
+ esac
+ ')
+ ")"
fi
+
if [ -n "$on_abort" ]; then
- printf " -on-abort '%s'" "$(printf %s "$on_abort" | sed "s/'/''/g")"
+ printf "%s" " -on-abort $(kak -quote kakoune -- "$on_abort")"
fi
- printf ' -menu -shell-script-candidates %%§
- printf %%s %s
- §\n' "$(shellquote "$completion")"
+
+ printf "%s\n" " -menu -shell-script-candidates $(kak -quote kakoune -- "
+ printf %s $(kak -quote shell -- "$completion")
+ ")"
}
}
From f9570947eb95d45bad427cf52e2af1e196087f54 Mon Sep 17 00:00:00 2001
From: Philipp Jungkamp
Date: Sun, 4 Aug 2024 23:50:00 +0200
Subject: [PATCH 3/4] git.kak: Replace sed with kak -quote
---
rc/tools/git.kak | 15 ++++++---------
1 file changed, 6 insertions(+), 9 deletions(-)
diff --git a/rc/tools/git.kak b/rc/tools/git.kak
index 68717fc798..677e6c3b46 100644
--- a/rc/tools/git.kak
+++ b/rc/tools/git.kak
@@ -148,9 +148,6 @@ define-command -params 1.. \
exit 1
}
}
- kakquote() {
- printf "%s" "$1" | sed "s/'/''/g; 1s/^/'/; \$s/\$/'/"
- }
show_git_cmd_output() {
local filetype
@@ -255,7 +252,7 @@ define-command -params 1.. \
n=$#
eval set -- "$(cat ${kak_response_fifo})" "$@"
if [ $# -eq $((n+1)) ]; then
- echo fail -- "$(kakquote "$1")"
+ echo fail -- "$(kak -quote kakoune -- "$1")"
exit
fi
commit=$1
@@ -266,15 +263,15 @@ define-command -params 1.. \
# Log commit and file name because they are only echoed briefly
# and not shown elsewhere (we don't have a :messages buffer).
message="Blaming $file as of $(git rev-parse --short $commit)"
- echo "echo -debug -- $(kakquote "$message")"
+ echo "echo -debug -- $(kak -quote kakoune -- "$message")"
on_close_fifo="
execute-keys -client ${kak_client} ${cursor_line}g${cursor_column}lh
evaluate-commands -client ${kak_client} %{
- set-option buffer git_blob $(kakquote "$commit:$file")
- git blame $(for arg; do kakquote "$arg"; printf " "; done)
+ set-option buffer git_blob $(kak -quote kakoune -- "$commit:$file")
+ git blame $(kak -quote kakoune -- "$@")
hook -once window NormalIdle .* %{
execute-keys vv
- echo -markup -- $(kakquote "{Information}{\\}$message. Press to jump to blamed commit")
+ echo -markup -- $(kak -quote kakoune -- "{Information}{\\}$message. Press to jump to blamed commit")
}
}
" show_git_cmd_output show "$commit:$file"
@@ -565,7 +562,7 @@ define-command -params 1.. \
'
eval set -- "$(cat ${kak_response_fifo})"
if [ $# -eq 1 ]; then
- echo fail -- "$(kakquote "$1")"
+ echo fail -- "$(kak -quote kakoune -- "$1")"
exit
fi
starting_commit=$1
From 714d3fddac774a810fe62cc16f8fde487e4387c1 Mon Sep 17 00:00:00 2001
From: Philipp Jungkamp
Date: Sun, 4 Aug 2024 23:50:30 +0200
Subject: [PATCH 4/4] modeline.kak: Replace sed with kak -quote
---
rc/detection/modeline.kak | 10 ++++------
1 file changed, 4 insertions(+), 6 deletions(-)
diff --git a/rc/detection/modeline.kak b/rc/detection/modeline.kak
index 6e067b1abd..166e89dc0d 100644
--- a/rc/detection/modeline.kak
+++ b/rc/detection/modeline.kak
@@ -12,8 +12,6 @@ declare-option -docstring "amount of lines that will be checked at the beginning
define-command -hidden modeline-parse-impl %{
evaluate-commands %sh{
- kakquote() { printf "%s" "$*" | sed "s/'/''/g; 1s/^/'/; \$s/\$/'/"; }
-
# Translate a vim option into the corresponding kakoune one
translate_opt_vim() {
local key="$1"
@@ -54,7 +52,7 @@ define-command -hidden modeline-parse-impl %{
return;;
esac
- printf 'set-option buffer %s %s\n' "${key}" "$(kakquote "${value}")"
+ printf 'set-option buffer %s %s\n' "${key}" "$(kak -quote kakoune -- "${value}")"
}
# Pass a few whitelisted options to kakoune directly
@@ -64,19 +62,19 @@ define-command -hidden modeline-parse-impl %{
case "${key}" in
scrolloff|tabstop|indentwidth|autowrap_column|eolformat|filetype|BOM|spell_lang);;
- *) printf 'echo -debug %s' "$(kakquote "Unsupported kakoune variable: ${key}")" \
+ *) printf 'echo -debug %s' "$(kak -quote kakoune -- "Unsupported kakoune variable: ${key}")" \
| kak -p "${kak_session}"
return;;
esac
- printf 'set-option buffer %s %s\n' "${key}" "$(kakquote "${value}")"
+ printf 'set-option buffer %s %s\n' "${key}" "$(kak -quote kakoune -- "${value}")"
}
case "${kak_selection}" in
*vi:*|*vim:*) type_selection="vim";;
*kak:*|*kakoune:*) type_selection="kakoune";;
*)
- printf 'fail %s\n' "$(kakquote "Unsupported modeline format: ${kak_selection}")"
+ printf 'fail %s\n' "$(kak -quote kakoune -- "Unsupported modeline format: ${kak_selection}")"
exit 1 ;;
esac