Add a complete-command command to configure command completion
This makes it possible to change command completion in hooks and paves the way to more flexibility in how custom commands can be completed
This commit is contained in:
parent
b915e4e11b
commit
7061001728
|
@ -3,6 +3,10 @@
|
||||||
This changelog contains major and/or breaking changes to Kakoune between
|
This changelog contains major and/or breaking changes to Kakoune between
|
||||||
released versions.
|
released versions.
|
||||||
|
|
||||||
|
== Development version
|
||||||
|
|
||||||
|
* `complete-command` (See <<commands#configuring-command-completion,`:doc commands configuring-command-completion`>>
|
||||||
|
|
||||||
== Kakoune 2021.11.07
|
== Kakoune 2021.11.07
|
||||||
|
|
||||||
* Support for curly and separately colored underlines (undocumented in 2021.10.28)
|
* Support for curly and separately colored underlines (undocumented in 2021.10.28)
|
||||||
|
|
|
@ -180,6 +180,11 @@ of the file onto the filesystem
|
||||||
define a new alias named *name* in *scope*
|
define a new alias named *name* in *scope*
|
||||||
(See <<aliases,Using aliases>> and <<scopes#,`:doc scopes`>>)
|
(See <<aliases,Using aliases>> and <<scopes#,`:doc scopes`>>)
|
||||||
|
|
||||||
|
*complete-command* [<switches>] <name> <type> [<param>]::
|
||||||
|
*alias* compl +
|
||||||
|
configure how a command completion works
|
||||||
|
(See <<configuring-command-completion,Configuring command completion>>)
|
||||||
|
|
||||||
*unalias* <scope> <name> [<command>]::
|
*unalias* <scope> <name> [<command>]::
|
||||||
remove an alias if its current value is the same as the one passed
|
remove an alias if its current value is the same as the one passed
|
||||||
as an optional parameter, remove it unconditionally otherwise
|
as an optional parameter, remove it unconditionally otherwise
|
||||||
|
@ -473,25 +478,59 @@ New commands can be defined using the *define-command* command:
|
||||||
define the documentation string for the command
|
define the documentation string for the command
|
||||||
|
|
||||||
*-menu*:::
|
*-menu*:::
|
||||||
the suggestions generated by the completion options are the only
|
|
||||||
permitted parameters.
|
|
||||||
|
|
||||||
*-file-completion*:::
|
*-file-completion*:::
|
||||||
try file completion on any parameter passed to this command
|
|
||||||
|
|
||||||
*-client-completion*:::
|
*-client-completion*:::
|
||||||
try client name completion on any parameter passed to this command
|
|
||||||
|
|
||||||
*-buffer-completion*:::
|
*-buffer-completion*:::
|
||||||
try buffer name completion on any parameter passed to this command
|
|
||||||
|
|
||||||
*-command-completion*:::
|
*-command-completion*:::
|
||||||
try command completion on any parameter passed to this command
|
|
||||||
|
|
||||||
*-shell-completion*:::
|
*-shell-completion*:::
|
||||||
try shell command completion on any parameter passed to this command
|
|
||||||
|
|
||||||
*-shell-script-completion*:::
|
*-shell-script-completion*:::
|
||||||
|
*-shell-script-candidates*:::
|
||||||
|
old-style command completion specification, function as-if
|
||||||
|
the switch and its eventual parameter was passed to the
|
||||||
|
*complete-command* command
|
||||||
|
(See <<configuring-command-completion,Configuring command completion>>)
|
||||||
|
|
||||||
|
The use of those switches is discouraged in favor of the
|
||||||
|
*complete-command* command.
|
||||||
|
|
||||||
|
Using shell expansion allows defining complex commands or accessing
|
||||||
|
Kakoune's state:
|
||||||
|
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
# create a directory for current buffer if it does not exist
|
||||||
|
define-command mkdir %{ nop %sh{ mkdir -p $(dirname $kak_buffile) } }
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
|
||||||
|
== Configuring command completion
|
||||||
|
|
||||||
|
Command completion can be configured with the *complete-command* command:
|
||||||
|
|
||||||
|
*complete-command* [<switches>] <command_name> <completion_type> [<parameter>]::
|
||||||
|
*switches* can be:
|
||||||
|
|
||||||
|
*-menu*:::
|
||||||
|
the suggestions generated by the completion options are the only
|
||||||
|
permitted parameters. Kakoune will autoselect the best completion
|
||||||
|
candidate on command validation.
|
||||||
|
|
||||||
|
*completion_type* can be:
|
||||||
|
|
||||||
|
*file-completion*:::
|
||||||
|
try file completion on any parameter passed to the command
|
||||||
|
|
||||||
|
*client-completion*:::
|
||||||
|
try client name completion on any parameter passed to the command
|
||||||
|
|
||||||
|
*buffer-completion*:::
|
||||||
|
try buffer name completion on any parameter passed to the command
|
||||||
|
|
||||||
|
*command-completion*:::
|
||||||
|
try command completion on any parameter passed to the command
|
||||||
|
|
||||||
|
*shell-completion*:::
|
||||||
|
try shell command completion on any parameter passed to the command
|
||||||
|
|
||||||
|
*shell-script-completion*:::
|
||||||
following string is a shell command which takes parameters as
|
following string is a shell command which takes parameters as
|
||||||
positional params and outputs one completion candidate per line.
|
positional params and outputs one completion candidate per line.
|
||||||
The provided shell command will run after each keypress.
|
The provided shell command will run after each keypress.
|
||||||
|
@ -507,14 +546,14 @@ New commands can be defined using the *define-command* command:
|
||||||
Position of the cursor inside the token being completed, in bytes
|
Position of the cursor inside the token being completed, in bytes
|
||||||
from token start.
|
from token start.
|
||||||
|
|
||||||
*-shell-script-candidates*:::
|
*shell-script-candidates*:::
|
||||||
following string is a shell command which takes parameters as
|
following string is a shell script which takes parameters as
|
||||||
positional params and outputs one completion candidate per line.
|
positional params and outputs one completion candidate per line.
|
||||||
The provided shell command will run once at the beginning of each
|
The provided shell script will run once at the beginning of each
|
||||||
completion session, candidates are cached and then used by kakoune
|
completion session, candidates are cached and then used by kakoune
|
||||||
internal fuzzy engine.
|
internal fuzzy engine.
|
||||||
|
|
||||||
During the execution of the shell command, the following env vars are
|
During the execution of the shell script, the following env vars are
|
||||||
available:
|
available:
|
||||||
|
|
||||||
*$kak_token_to_complete*::::
|
*$kak_token_to_complete*::::
|
||||||
|
@ -522,14 +561,6 @@ New commands can be defined using the *define-command* command:
|
||||||
Note that unlike the Unix `argv` tradition,
|
Note that unlike the Unix `argv` tradition,
|
||||||
0 is the first argument, not the command name itself.
|
0 is the first argument, not the command name itself.
|
||||||
|
|
||||||
Using shell expansion allows defining complex commands or accessing
|
|
||||||
Kakoune's state:
|
|
||||||
|
|
||||||
---------------------------------------------------------------------
|
|
||||||
# create a directory for current buffer if it does not exist
|
|
||||||
define-command mkdir %{ nop %sh{ mkdir -p $(dirname $kak_buffile) } }
|
|
||||||
---------------------------------------------------------------------
|
|
||||||
|
|
||||||
== Aliases
|
== Aliases
|
||||||
|
|
||||||
With `:alias`, commands can be given additional names.
|
With `:alias`, commands can be given additional names.
|
||||||
|
|
|
@ -19,14 +19,14 @@ add-highlighter shared/diff/ regex "^\+[^\n]*\n" 0:green,default
|
||||||
add-highlighter shared/diff/ regex "^-[^\n]*\n" 0:red,default
|
add-highlighter shared/diff/ regex "^-[^\n]*\n" 0:red,default
|
||||||
add-highlighter shared/diff/ regex "^@@[^\n]*@@" 0:cyan,default
|
add-highlighter shared/diff/ regex "^@@[^\n]*@@" 0:cyan,default
|
||||||
|
|
||||||
define-command diff-jump \
|
define-command diff-jump -params .. -docstring %{
|
||||||
-docstring %{diff-jump [<switches>] [<directory>]: edit the diff's source file at the cursor position.
|
diff-jump [<switches>] [<directory>]: edit the diff's source file at the cursor position.
|
||||||
Paths are resolved relative to <directory>, or the current working directory if unspecified.
|
Paths are resolved relative to <directory>, or the current working directory if unspecified.
|
||||||
|
|
||||||
Switches:
|
Switches:
|
||||||
- jump to the old file instead of the new file
|
- jump to the old file instead of the new file
|
||||||
-<num> strip <num> leading directory components, like -p<num> in patch(1). Defaults to 1 if there is a 'diff' line (as printed by 'diff -r'), or 0 otherwise.} \
|
-<num> strip <num> leading directory components, like -p<num> in patch(1). Defaults to 1 if there is a 'diff' line (as printed by 'diff -r'), or 0 otherwise.
|
||||||
-params .. -file-completion %{
|
} %{
|
||||||
evaluate-commands -draft -save-regs c %{
|
evaluate-commands -draft -save-regs c %{
|
||||||
# Save the column because we will move the cursor.
|
# Save the column because we will move the cursor.
|
||||||
set-register c %val{cursor_column}
|
set-register c %val{cursor_column}
|
||||||
|
@ -146,6 +146,7 @@ Switches:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
complete-command diff-jump file
|
||||||
|
|
||||||
§
|
§
|
||||||
|
|
||||||
|
|
|
@ -56,7 +56,7 @@ add-highlighter shared/kakrc/shell8 region -recurse '<' '(^|\h)\K-shell-script-
|
||||||
evaluate-commands %sh{
|
evaluate-commands %sh{
|
||||||
# Grammar
|
# Grammar
|
||||||
keywords="add-highlighter alias arrange-buffers buffer buffer-next buffer-previous catch
|
keywords="add-highlighter alias arrange-buffers buffer buffer-next buffer-previous catch
|
||||||
change-directory colorscheme debug declare-option declare-user-mode define-command
|
change-directory colorscheme debug declare-option declare-user-mode define-command complete-command
|
||||||
delete-buffer delete-buffer! echo edit edit! enter-user-mode evaluate-commands execute-keys
|
delete-buffer delete-buffer! echo edit edit! enter-user-mode evaluate-commands execute-keys
|
||||||
fail hook info kill kill! map menu nop on-key prompt provide-module quit quit!
|
fail hook info kill kill! map menu nop on-key prompt provide-module quit quit!
|
||||||
remove-highlighter remove-hooks rename-buffer rename-client rename-session require-module
|
remove-highlighter remove-hooks rename-buffer rename-client rename-session require-module
|
||||||
|
|
|
@ -4,7 +4,7 @@ declare-option -docstring "name of the client in which utilities display informa
|
||||||
str toolsclient
|
str toolsclient
|
||||||
declare-option -hidden int grep_current_line 0
|
declare-option -hidden int grep_current_line 0
|
||||||
|
|
||||||
define-command -params .. -file-completion -docstring %{
|
define-command -params .. -docstring %{
|
||||||
grep [<arguments>]: grep utility wrapper
|
grep [<arguments>]: grep utility wrapper
|
||||||
All optional arguments are forwarded to the grep utility
|
All optional arguments are forwarded to the grep utility
|
||||||
} grep %{ evaluate-commands %sh{
|
} grep %{ evaluate-commands %sh{
|
||||||
|
@ -23,6 +23,7 @@ define-command -params .. -file-completion -docstring %{
|
||||||
hook -always -once buffer BufCloseFifo .* %{ nop %sh{ rm -r $(dirname ${output}) } }
|
hook -always -once buffer BufCloseFifo .* %{ nop %sh{ rm -r $(dirname ${output}) } }
|
||||||
}"
|
}"
|
||||||
}}
|
}}
|
||||||
|
complete-command grep file
|
||||||
|
|
||||||
hook -group grep-highlight global WinSetOption filetype=grep %{
|
hook -group grep-highlight global WinSetOption filetype=grep %{
|
||||||
add-highlighter window/grep group
|
add-highlighter window/grep group
|
||||||
|
|
|
@ -36,22 +36,25 @@ define-command -hidden -params 2.. iterm-terminal-split-impl %{
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
define-command iterm-terminal-vertical -params 1.. -shell-completion -docstring '
|
define-command iterm-terminal-vertical -params 1.. -docstring '
|
||||||
iterm-terminal-vertical <program> [<arguments>]: create a new terminal as an iterm pane
|
iterm-terminal-vertical <program> [<arguments>]: create a new terminal as an iterm pane
|
||||||
The current pane is split into two, left and right
|
The current pane is split into two, left and right
|
||||||
The 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{@}
|
iterm-terminal-split-impl 'vertically' %arg{@}
|
||||||
}
|
}
|
||||||
define-command iterm-terminal-horizontal -params 1.. -shell-completion -docstring '
|
complete-command iterm-terminal-vertical shell
|
||||||
|
|
||||||
|
define-command iterm-terminal-horizontal -params 1.. -docstring '
|
||||||
iterm-terminal-horizontal <program> [<arguments>]: create a new terminal as an iterm pane
|
iterm-terminal-horizontal <program> [<arguments>]: create a new terminal as an iterm pane
|
||||||
The current pane is split into two, top and bottom
|
The current pane is split into two, top and bottom
|
||||||
The 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{@}
|
iterm-terminal-split-impl 'horizontally' %arg{@}
|
||||||
}
|
}
|
||||||
|
complete-command iterm-terminal-horizontal shell
|
||||||
|
|
||||||
define-command iterm-terminal-tab -params 1.. -shell-completion -docstring '
|
define-command iterm-terminal-tab -params 1.. -docstring '
|
||||||
iterm-terminal-tab <program> [<arguments>]: create a new terminal as an iterm tab
|
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'\
|
The program passed as argument will be executed in the new terminal'\
|
||||||
%{
|
%{
|
||||||
|
@ -76,8 +79,9 @@ The program passed as argument will be executed in the new terminal'\
|
||||||
-e "end tell" >/dev/null
|
-e "end tell" >/dev/null
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
complete-command iterm-terminal-tab shell
|
||||||
|
|
||||||
define-command iterm-terminal-window -params 1.. -shell-completion -docstring '
|
define-command iterm-terminal-window -params 1.. -docstring '
|
||||||
iterm-terminal-window <program> [<arguments>]: create a new terminal as an iterm window
|
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'\
|
The program passed as argument will be executed in the new terminal'\
|
||||||
%{
|
%{
|
||||||
|
@ -100,8 +104,9 @@ The program passed as argument will be executed in the new terminal'\
|
||||||
-e "end tell" >/dev/null
|
-e "end tell" >/dev/null
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
complete-command iterm-terminal-window shell
|
||||||
|
|
||||||
define-command iterm-focus -params ..1 -client-completion -docstring '
|
define-command iterm-focus -params ..1 -docstring '
|
||||||
iterm-focus [<client>]: focus the given client
|
iterm-focus [<client>]: focus the given client
|
||||||
If no client is passed then the current one is used' \
|
If no client is passed then the current one is used' \
|
||||||
%{
|
%{
|
||||||
|
@ -131,6 +136,7 @@ If no client is passed then the current one is used' \
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
complete-command iterm-focus client
|
||||||
|
|
||||||
alias global focus iterm-focus
|
alias global focus iterm-focus
|
||||||
alias global terminal iterm-terminal-vertical
|
alias global terminal iterm-terminal-vertical
|
||||||
|
|
|
@ -10,7 +10,7 @@ evaluate-commands %sh{
|
||||||
|
|
||||||
declare-option -docstring %{window type that kitty creates on new and repl calls (window|os-window)} str kitty_window_type window
|
declare-option -docstring %{window type that kitty creates on new and repl calls (window|os-window)} str kitty_window_type window
|
||||||
|
|
||||||
define-command kitty-terminal -params 1.. -shell-completion -docstring '
|
define-command kitty-terminal -params 1.. -docstring '
|
||||||
kitty-terminal <program> [<arguments>]: create a new terminal as a kitty window
|
kitty-terminal <program> [<arguments>]: create a new terminal as a kitty window
|
||||||
The program passed as argument will be executed in the new terminal' \
|
The program passed as argument will be executed in the new terminal' \
|
||||||
%{
|
%{
|
||||||
|
@ -28,8 +28,9 @@ The program passed as argument will be executed in the new terminal' \
|
||||||
kitty @ $listen launch --no-response --type="$kak_opt_kitty_window_type" --cwd="$PWD" $match "$@"
|
kitty @ $listen launch --no-response --type="$kak_opt_kitty_window_type" --cwd="$PWD" $match "$@"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
complete-command kitty-terminal shell
|
||||||
|
|
||||||
define-command kitty-terminal-tab -params 1.. -shell-completion -docstring '
|
define-command kitty-terminal-tab -params 1.. -docstring '
|
||||||
kitty-terminal-tab <program> [<arguments>]: create a new terminal as kitty tab
|
kitty-terminal-tab <program> [<arguments>]: create a new terminal as kitty tab
|
||||||
The program passed as argument will be executed in the new terminal' \
|
The program passed as argument will be executed in the new terminal' \
|
||||||
%{
|
%{
|
||||||
|
@ -47,8 +48,9 @@ The program passed as argument will be executed in the new terminal' \
|
||||||
kitty @ $listen launch --no-response --type=tab --cwd="$PWD" $match "$@"
|
kitty @ $listen launch --no-response --type=tab --cwd="$PWD" $match "$@"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
complete-command kitty-terminal-tab shell
|
||||||
|
|
||||||
define-command kitty-focus -params ..1 -client-completion -docstring '
|
define-command kitty-focus -params ..1 -docstring '
|
||||||
kitty-focus [<client>]: focus the given client
|
kitty-focus [<client>]: focus the given client
|
||||||
If no client is passed then the current one is used' \
|
If no client is passed then the current one is used' \
|
||||||
%{
|
%{
|
||||||
|
@ -70,6 +72,7 @@ If no client is passed then the current one is used' \
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
complete-command kitty-focus client
|
||||||
|
|
||||||
alias global terminal kitty-terminal
|
alias global terminal kitty-terminal
|
||||||
alias global terminal-tab kitty-terminal-tab
|
alias global terminal-tab kitty-terminal-tab
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
define-command new -params .. -command-completion -docstring '
|
define-command new -params .. -docstring '
|
||||||
new [<commands>]: create a new Kakoune client
|
new [<commands>]: create a new Kakoune client
|
||||||
The ''terminal'' alias is being used to determine the user''s preferred terminal emulator
|
The ''terminal'' alias is being used to determine the user''s preferred terminal emulator
|
||||||
The optional arguments are passed as commands to the new client' \
|
The optional arguments are passed as commands to the new client' \
|
||||||
|
@ -6,3 +6,4 @@ The optional arguments are passed as commands to the new client' \
|
||||||
terminal kak -c %val{session} -e "%arg{@}"
|
terminal kak -c %val{session} -e "%arg{@}"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
complete-command new command
|
||||||
|
|
|
@ -12,7 +12,6 @@ define-command -docstring %{
|
||||||
All optional parameters are forwarded to the new terminal window
|
All optional parameters are forwarded to the new terminal window
|
||||||
} \
|
} \
|
||||||
-params .. \
|
-params .. \
|
||||||
-shell-completion \
|
|
||||||
dtach-repl %{ terminal sh -c %{
|
dtach-repl %{ terminal sh -c %{
|
||||||
file="$(mktemp -u -t kak_dtach_repl.XXXXX)"
|
file="$(mktemp -u -t kak_dtach_repl.XXXXX)"
|
||||||
trap 'rm -f "${file}"' EXIT
|
trap 'rm -f "${file}"' EXIT
|
||||||
|
@ -22,6 +21,7 @@ define-command -docstring %{
|
||||||
dtach -c "${file}" -E sh -c "${@:-$SHELL}" || "${@:-$SHELL}"
|
dtach -c "${file}" -E sh -c "${@:-$SHELL}" || "${@:-$SHELL}"
|
||||||
} -- %val{client} %val{session} %arg{@}
|
} -- %val{client} %val{session} %arg{@}
|
||||||
}
|
}
|
||||||
|
complete-command dtach-repl shell
|
||||||
|
|
||||||
define-command dtach-send-text -params 0..1 -docstring %{
|
define-command dtach-send-text -params 0..1 -docstring %{
|
||||||
dtach-send-text [text]: Send text to the REPL.
|
dtach-send-text [text]: Send text to the REPL.
|
||||||
|
|
|
@ -4,7 +4,7 @@ hook global ModuleLoaded kitty %{
|
||||||
|
|
||||||
provide-module kitty-repl %{
|
provide-module kitty-repl %{
|
||||||
|
|
||||||
define-command -params .. -shell-completion \
|
define-command -params .. \
|
||||||
-docstring %{
|
-docstring %{
|
||||||
kitty-repl [<arguments>]: Create a new window for repl interaction.
|
kitty-repl [<arguments>]: Create a new window for repl interaction.
|
||||||
|
|
||||||
|
@ -31,6 +31,7 @@ define-command -params .. -shell-completion \
|
||||||
kitty @ $listen launch --no-response --keep-focus --type="$kak_opt_kitty_window_type" --title=kak_repl_window --cwd="$PWD" $match $cmd
|
kitty @ $listen launch --no-response --keep-focus --type="$kak_opt_kitty_window_type" --title=kak_repl_window --cwd="$PWD" $match $cmd
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
complete-command kitty-repl shell
|
||||||
|
|
||||||
define-command -hidden -params 0..1 \
|
define-command -hidden -params 0..1 \
|
||||||
-docstring %{
|
-docstring %{
|
||||||
|
|
|
@ -23,17 +23,20 @@ define-command -hidden -params 1.. tmux-repl-impl %{
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
define-command tmux-repl-vertical -params 0.. -command-completion -docstring "Create a new vertical pane for repl interaction" %{
|
define-command tmux-repl-vertical -params 0.. -docstring "Create a new vertical pane for repl interaction" %{
|
||||||
tmux-repl-impl 'split-window -v' %arg{@}
|
tmux-repl-impl 'split-window -v' %arg{@}
|
||||||
}
|
}
|
||||||
|
complete-command tmux-repl-vertical command
|
||||||
|
|
||||||
define-command tmux-repl-horizontal -params 0.. -command-completion -docstring "Create a new horizontal pane for repl interaction" %{
|
define-command tmux-repl-horizontal -params 0.. -docstring "Create a new horizontal pane for repl interaction" %{
|
||||||
tmux-repl-impl 'split-window -h' %arg{@}
|
tmux-repl-impl 'split-window -h' %arg{@}
|
||||||
}
|
}
|
||||||
|
complete-command tmux-repl-horizontal command
|
||||||
|
|
||||||
define-command tmux-repl-window -params 0.. -command-completion -docstring "Create a new window for repl interaction" %{
|
define-command tmux-repl-window -params 0.. -docstring "Create a new window for repl interaction" %{
|
||||||
tmux-repl-impl 'new-window' %arg{@}
|
tmux-repl-impl 'new-window' %arg{@}
|
||||||
}
|
}
|
||||||
|
complete-command tmux-repl-window command
|
||||||
|
|
||||||
define-command -params 0..1 tmux-repl-set-pane -docstring %{
|
define-command -params 0..1 tmux-repl-set-pane -docstring %{
|
||||||
tmux-repl-set-pane [pane number]: Set an existing tmux pane for repl interaction
|
tmux-repl-set-pane [pane number]: Set an existing tmux pane for repl interaction
|
||||||
|
|
|
@ -11,7 +11,6 @@ define-command -docstring %{
|
||||||
All optional parameters are forwarded to the new window
|
All optional parameters are forwarded to the new window
|
||||||
} \
|
} \
|
||||||
-params .. \
|
-params .. \
|
||||||
-shell-completion \
|
|
||||||
x11-repl %{ x11-terminal sh -c %{
|
x11-repl %{ x11-terminal sh -c %{
|
||||||
winid="${WINDOWID:-$(xdotool search --pid ${PPID} | tail -1)}"
|
winid="${WINDOWID:-$(xdotool search --pid ${PPID} | tail -1)}"
|
||||||
printf "evaluate-commands -try-client $1 \
|
printf "evaluate-commands -try-client $1 \
|
||||||
|
@ -20,6 +19,7 @@ define-command -docstring %{
|
||||||
[ "$1" ] && "$@" || "$SHELL"
|
[ "$1" ] && "$@" || "$SHELL"
|
||||||
} -- %val{client} %val{session} %arg{@}
|
} -- %val{client} %val{session} %arg{@}
|
||||||
}
|
}
|
||||||
|
complete-command x11-repl shell
|
||||||
|
|
||||||
define-command x11-send-text -params 0..1 -docstring %{
|
define-command x11-send-text -params 0..1 -docstring %{
|
||||||
x11-send-text [text]: Send text to the REPL window.
|
x11-send-text [text]: Send text to the REPL window.
|
||||||
|
|
|
@ -28,21 +28,25 @@ define-command screen-terminal-impl -hidden -params 3.. %{
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
define-command screen-terminal-vertical -params 1.. -shell-completion -docstring '
|
define-command screen-terminal-vertical -params 1.. -docstring '
|
||||||
screen-terminal-vertical <program> [<arguments>] [<arguments>]: create a new terminal as a screen pane
|
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 current pane is split into two, left and right
|
||||||
The 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{@}
|
screen-terminal-impl 'split -v' 'focus right' %arg{@}
|
||||||
}
|
}
|
||||||
define-command screen-terminal-horizontal -params 1.. -shell-completion -docstring '
|
complete-command screen-terminal-vertical shell
|
||||||
|
|
||||||
|
define-command screen-terminal-horizontal -params 1.. -docstring '
|
||||||
screen-terminal-horizontal <program> [<arguments>]: create a new terminal as a screen pane
|
screen-terminal-horizontal <program> [<arguments>]: create a new terminal as a screen pane
|
||||||
The current pane is split into two, top and bottom
|
The current pane is split into two, top and bottom
|
||||||
The 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{@}
|
screen-terminal-impl 'split -h' 'focus down' %arg{@}
|
||||||
}
|
}
|
||||||
define-command screen-terminal-window -params 1.. -shell-completion -docstring '
|
complete-command screen-terminal-horizontal shell
|
||||||
|
|
||||||
|
define-command screen-terminal-window -params 1.. -docstring '
|
||||||
screen-terminal-window <program> [<arguments>]: create a new terminal as a screen window
|
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' \
|
The program passed as argument will be executed in the new terminal' \
|
||||||
%{
|
%{
|
||||||
|
@ -51,8 +55,9 @@ The program passed as argument will be executed in the new terminal' \
|
||||||
screen -X screen "$@" < "/dev/$tty"
|
screen -X screen "$@" < "/dev/$tty"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
complete-command screen-terminal-window shell
|
||||||
|
|
||||||
define-command screen-focus -params ..1 -client-completion -docstring '
|
define-command screen-focus -params ..1 -docstring '
|
||||||
screen-focus [<client>]: focus the given client
|
screen-focus [<client>]: focus the given client
|
||||||
If no client is passed then the current one is used' \
|
If no client is passed then the current one is used' \
|
||||||
%{
|
%{
|
||||||
|
@ -67,6 +72,7 @@ If no client is passed then the current one is used' \
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
complete-command screen-focus client
|
||||||
|
|
||||||
alias global focus screen-focus
|
alias global focus screen-focus
|
||||||
alias global terminal screen-terminal-vertical
|
alias global terminal screen-terminal-vertical
|
||||||
|
|
|
@ -30,28 +30,33 @@ define-command -hidden -params 2.. tmux-terminal-impl %{
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
define-command tmux-terminal-vertical -params 1.. -shell-completion -docstring '
|
define-command tmux-terminal-vertical -params 1.. -docstring '
|
||||||
tmux-terminal-vertical <program> [<arguments>]: create a new terminal as a tmux pane
|
tmux-terminal-vertical <program> [<arguments>]: create a new terminal as a tmux pane
|
||||||
The current pane is split into two, top and bottom
|
The current pane is split into two, top and bottom
|
||||||
The 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{@}
|
tmux-terminal-impl 'split-window -v' %arg{@}
|
||||||
}
|
}
|
||||||
define-command tmux-terminal-horizontal -params 1.. -shell-completion -docstring '
|
complete-command tmux-terminal-vertical shell
|
||||||
|
|
||||||
|
define-command tmux-terminal-horizontal -params 1.. -docstring '
|
||||||
tmux-terminal-horizontal <program> [<arguments>]: create a new terminal as a tmux pane
|
tmux-terminal-horizontal <program> [<arguments>]: create a new terminal as a tmux pane
|
||||||
The current pane is split into two, left and right
|
The current pane is split into two, left and right
|
||||||
The 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{@}
|
tmux-terminal-impl 'split-window -h' %arg{@}
|
||||||
}
|
}
|
||||||
define-command tmux-terminal-window -params 1.. -shell-completion -docstring '
|
complete-command tmux-terminal-horizontal shell
|
||||||
|
|
||||||
|
define-command tmux-terminal-window -params 1.. -docstring '
|
||||||
tmux-terminal-window <program> [<arguments>] [<arguments>]: create a new terminal as a tmux window
|
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' \
|
The program passed as argument will be executed in the new terminal' \
|
||||||
%{
|
%{
|
||||||
tmux-terminal-impl 'new-window' %arg{@}
|
tmux-terminal-impl 'new-window' %arg{@}
|
||||||
}
|
}
|
||||||
|
complete-command tmux-terminal-window shell
|
||||||
|
|
||||||
define-command tmux-focus -params ..1 -client-completion -docstring '
|
define-command tmux-focus -params ..1 -docstring '
|
||||||
tmux-focus [<client>]: focus the given client
|
tmux-focus [<client>]: focus the given client
|
||||||
If no client is passed then the current one is used' \
|
If no client is passed then the current one is used' \
|
||||||
%{
|
%{
|
||||||
|
@ -66,6 +71,7 @@ If no client is passed then the current one is used' \
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
complete-command tmux-focus client
|
||||||
|
|
||||||
## The default behaviour for the `new` command is to open an horizontal pane in a tmux session
|
## The default behaviour for the `new` command is to open an horizontal pane in a tmux session
|
||||||
alias global focus tmux-focus
|
alias global focus tmux-focus
|
||||||
|
|
|
@ -28,7 +28,7 @@ A shell command is appended to the one set in this option at runtime} \
|
||||||
done
|
done
|
||||||
}
|
}
|
||||||
|
|
||||||
define-command wayland-terminal -params 1.. -shell-completion -docstring '
|
define-command wayland-terminal -params 1.. -docstring '
|
||||||
wayland-terminal <program> [<arguments>]: create a new terminal as a Wayland window
|
wayland-terminal <program> [<arguments>]: create a new terminal as a Wayland window
|
||||||
The program passed as argument will be executed in the new terminal' \
|
The program passed as argument will be executed in the new terminal' \
|
||||||
%{
|
%{
|
||||||
|
@ -43,13 +43,15 @@ The program passed as argument will be executed in the new terminal' \
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
complete-command wayland-terminal shell
|
||||||
|
|
||||||
define-command wayland-focus -params ..1 -client-completion -docstring '
|
define-command wayland-focus -params ..1 -docstring '
|
||||||
wayland-focus [<kakoune_client>]: focus a given client''s window
|
wayland-focus [<kakoune_client>]: focus a given client''s window
|
||||||
If no client is passed, then the current client is used' \
|
If no client is passed, then the current client is used' \
|
||||||
%{
|
%{
|
||||||
fail There is no way to focus another window on Wayland
|
fail There is no way to focus another window on Wayland
|
||||||
}
|
}
|
||||||
|
complete-command wayland-focus client
|
||||||
|
|
||||||
alias global focus wayland-focus
|
alias global focus wayland-focus
|
||||||
alias global terminal wayland-terminal
|
alias global terminal wayland-terminal
|
||||||
|
|
|
@ -33,7 +33,7 @@ A shell command is appended to the one set in this option at runtime} \
|
||||||
done
|
done
|
||||||
}
|
}
|
||||||
|
|
||||||
define-command x11-terminal -params 1.. -shell-completion -docstring '
|
define-command x11-terminal -params 1.. -docstring '
|
||||||
x11-terminal <program> [<arguments>]: create a new terminal as an X11 window
|
x11-terminal <program> [<arguments>]: create a new terminal as an X11 window
|
||||||
The program passed as argument will be executed in the new terminal' \
|
The program passed as argument will be executed in the new terminal' \
|
||||||
%{
|
%{
|
||||||
|
@ -48,8 +48,9 @@ The program passed as argument will be executed in the new terminal' \
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
complete-command x11-terminal shell
|
||||||
|
|
||||||
define-command x11-focus -params ..1 -client-completion -docstring '
|
define-command x11-focus -params ..1 -docstring '
|
||||||
x11-focus [<kakoune_client>]: focus a given client''s window
|
x11-focus [<kakoune_client>]: focus a given client''s window
|
||||||
If no client is passed, then the current client is used' \
|
If no client is passed, then the current client is used' \
|
||||||
%{
|
%{
|
||||||
|
@ -62,6 +63,7 @@ If no client is passed, then the current client is used' \
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
complete-command x11-focus client
|
||||||
|
|
||||||
alias global focus x11-focus
|
alias global focus x11-focus
|
||||||
alias global terminal x11-terminal
|
alias global terminal x11-terminal
|
||||||
|
|
|
@ -41,6 +41,15 @@ void CommandManager::register_command(String command_name,
|
||||||
std::move(completer) };
|
std::move(completer) };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CommandManager::set_command_completer(StringView command_name, CommandCompleter completer)
|
||||||
|
{
|
||||||
|
auto it = m_commands.find(command_name);
|
||||||
|
if (it == m_commands.end())
|
||||||
|
throw runtime_error(format("no such command '{}'", command_name));
|
||||||
|
|
||||||
|
it->value.completer = std::move(completer);
|
||||||
|
}
|
||||||
|
|
||||||
bool CommandManager::module_defined(StringView module_name) const
|
bool CommandManager::module_defined(StringView module_name) const
|
||||||
{
|
{
|
||||||
return m_modules.find(module_name) != m_modules.end();
|
return m_modules.find(module_name) != m_modules.end();
|
||||||
|
|
|
@ -112,6 +112,8 @@ public:
|
||||||
CommandHelper helper = CommandHelper(),
|
CommandHelper helper = CommandHelper(),
|
||||||
CommandCompleter completer = CommandCompleter());
|
CommandCompleter completer = CommandCompleter());
|
||||||
|
|
||||||
|
void set_command_completer(StringView command_name, CommandCompleter completer);
|
||||||
|
|
||||||
Completions complete_command_name(const Context& context, StringView query) const;
|
Completions complete_command_name(const Context& context, StringView query) const;
|
||||||
|
|
||||||
void clear_last_complete_command() { m_last_complete_command = String{}; }
|
void clear_last_complete_command() { m_last_complete_command = String{}; }
|
||||||
|
|
169
src/commands.cc
169
src/commands.cc
|
@ -1159,6 +1159,82 @@ Vector<String> params_to_shell(const ParametersParser& parser)
|
||||||
return vars;
|
return vars;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CommandCompleter make_command_completer(StringView type, StringView param, Completions::Flags completions_flags)
|
||||||
|
{
|
||||||
|
if (type == "file")
|
||||||
|
{
|
||||||
|
return [=](const Context& context, CompletionFlags flags,
|
||||||
|
CommandParameters params,
|
||||||
|
size_t token_to_complete, ByteCount pos_in_token) {
|
||||||
|
const String& prefix = params[token_to_complete];
|
||||||
|
const auto& ignored_files = context.options()["ignored_files"].get<Regex>();
|
||||||
|
return Completions{0_byte, pos_in_token,
|
||||||
|
complete_filename(prefix, ignored_files,
|
||||||
|
pos_in_token, FilenameFlags::Expand),
|
||||||
|
completions_flags};
|
||||||
|
};
|
||||||
|
}
|
||||||
|
else if (type == "client")
|
||||||
|
{
|
||||||
|
return [=](const Context& context, CompletionFlags flags,
|
||||||
|
CommandParameters params,
|
||||||
|
size_t token_to_complete, ByteCount pos_in_token)
|
||||||
|
{
|
||||||
|
const String& prefix = params[token_to_complete];
|
||||||
|
auto& cm = ClientManager::instance();
|
||||||
|
return Completions{0_byte, pos_in_token,
|
||||||
|
cm.complete_client_name(prefix, pos_in_token),
|
||||||
|
completions_flags};
|
||||||
|
};
|
||||||
|
}
|
||||||
|
else if (type == "buffer")
|
||||||
|
{
|
||||||
|
return [=](const Context& context, CompletionFlags flags,
|
||||||
|
CommandParameters params,
|
||||||
|
size_t token_to_complete, ByteCount pos_in_token)
|
||||||
|
{
|
||||||
|
return add_flags(complete_buffer_name<false>, completions_flags)(
|
||||||
|
context, flags, params[token_to_complete], pos_in_token);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
else if (type == "shell-script")
|
||||||
|
{
|
||||||
|
if (param.empty())
|
||||||
|
throw runtime_error("shell-script requires a shell script parameter");
|
||||||
|
|
||||||
|
return ShellScriptCompleter{param.str(), completions_flags};
|
||||||
|
}
|
||||||
|
else if (type == "shell-script-candidates")
|
||||||
|
{
|
||||||
|
if (param.empty())
|
||||||
|
throw runtime_error("shell-script-candidates requires a shell script parameter");
|
||||||
|
|
||||||
|
return ShellCandidatesCompleter{param.str(), completions_flags};
|
||||||
|
}
|
||||||
|
else if (type == "command")
|
||||||
|
{
|
||||||
|
return [](const Context& context, CompletionFlags flags,
|
||||||
|
CommandParameters params,
|
||||||
|
size_t token_to_complete, ByteCount pos_in_token)
|
||||||
|
{
|
||||||
|
return CommandManager::instance().complete(
|
||||||
|
context, flags, params, token_to_complete, pos_in_token);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
else if (type == "shell")
|
||||||
|
{
|
||||||
|
return [=](const Context& context, CompletionFlags flags,
|
||||||
|
CommandParameters params,
|
||||||
|
size_t token_to_complete, ByteCount pos_in_token)
|
||||||
|
{
|
||||||
|
return add_flags(shell_complete, completions_flags)(
|
||||||
|
context, flags, params[token_to_complete], pos_in_token);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
else
|
||||||
|
throw runtime_error(format("invalid command completion type '{}'", type));
|
||||||
|
}
|
||||||
|
|
||||||
void define_command(const ParametersParser& parser, Context& context, const ShellContext&)
|
void define_command(const ParametersParser& parser, Context& context, const ShellContext&)
|
||||||
{
|
{
|
||||||
const String& cmd_name = parser[0];
|
const String& cmd_name = parser[0];
|
||||||
|
@ -1211,75 +1287,22 @@ void define_command(const ParametersParser& parser, Context& context, const Shel
|
||||||
}
|
}
|
||||||
|
|
||||||
CommandCompleter completer;
|
CommandCompleter completer;
|
||||||
if (parser.get_switch("file-completion"))
|
for (StringView completion_switch : {"file-completion", "client-completion", "buffer-completion",
|
||||||
|
"shell-script-completion", "shell-script-candidates",
|
||||||
|
"command-completion", "shell-completion"})
|
||||||
{
|
{
|
||||||
completer = [=](const Context& context, CompletionFlags flags,
|
if (auto param = parser.get_switch(completion_switch))
|
||||||
CommandParameters params,
|
|
||||||
size_t token_to_complete, ByteCount pos_in_token)
|
|
||||||
{
|
{
|
||||||
const String& prefix = params[token_to_complete];
|
constexpr StringView suffix = "-completion";
|
||||||
const auto& ignored_files = context.options()["ignored_files"].get<Regex>();
|
if (completion_switch.ends_with(suffix))
|
||||||
return Completions{0_byte, pos_in_token,
|
completion_switch = completion_switch.substr(0, completion_switch.length() - suffix.length());
|
||||||
complete_filename(prefix, ignored_files,
|
completer = make_command_completer(completion_switch, *param, completions_flags);
|
||||||
pos_in_token, FilenameFlags::Expand),
|
break;
|
||||||
completions_flags};
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
else if (parser.get_switch("client-completion"))
|
|
||||||
{
|
|
||||||
completer = [=](const Context& context, CompletionFlags flags,
|
|
||||||
CommandParameters params,
|
|
||||||
size_t token_to_complete, ByteCount pos_in_token)
|
|
||||||
{
|
|
||||||
const String& prefix = params[token_to_complete];
|
|
||||||
auto& cm = ClientManager::instance();
|
|
||||||
return Completions{0_byte, pos_in_token,
|
|
||||||
cm.complete_client_name(prefix, pos_in_token),
|
|
||||||
completions_flags};
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
else if (parser.get_switch("buffer-completion"))
|
|
||||||
{
|
|
||||||
completer = [=](const Context& context, CompletionFlags flags,
|
|
||||||
CommandParameters params,
|
|
||||||
size_t token_to_complete, ByteCount pos_in_token)
|
|
||||||
{
|
|
||||||
return add_flags(complete_buffer_name<false>, completions_flags)(
|
|
||||||
context, flags, params[token_to_complete], pos_in_token);
|
|
||||||
};
|
|
||||||
}
|
|
||||||
else if (auto shell_script = parser.get_switch("shell-script-completion"))
|
|
||||||
{
|
|
||||||
completer = ShellScriptCompleter{shell_script->str(), completions_flags};
|
|
||||||
}
|
|
||||||
else if (auto shell_script = parser.get_switch("shell-script-candidates"))
|
|
||||||
{
|
|
||||||
completer = ShellCandidatesCompleter{shell_script->str(), completions_flags};
|
|
||||||
}
|
|
||||||
else if (parser.get_switch("command-completion"))
|
|
||||||
{
|
|
||||||
completer = [](const Context& context, CompletionFlags flags,
|
|
||||||
CommandParameters params,
|
|
||||||
size_t token_to_complete, ByteCount pos_in_token)
|
|
||||||
{
|
|
||||||
return CommandManager::instance().complete(
|
|
||||||
context, flags, params, token_to_complete, pos_in_token);
|
|
||||||
};
|
|
||||||
}
|
|
||||||
else if (parser.get_switch("shell-completion"))
|
|
||||||
{
|
|
||||||
completer = [=](const Context& context, CompletionFlags flags,
|
|
||||||
CommandParameters params,
|
|
||||||
size_t token_to_complete, ByteCount pos_in_token)
|
|
||||||
{
|
|
||||||
return add_flags(shell_complete, completions_flags)(
|
|
||||||
context, flags, params[token_to_complete], pos_in_token);
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
auto docstring = trim_indent(parser.get_switch("docstring").value_or(StringView{}));
|
auto docstring = trim_indent(parser.get_switch("docstring").value_or(StringView{}));
|
||||||
|
|
||||||
cm.register_command(cmd_name, cmd, docstring, desc, flags, CommandHelper{}, completer);
|
cm.register_command(cmd_name, cmd, docstring, desc, flags, CommandHelper{}, std::move(completer));
|
||||||
}
|
}
|
||||||
|
|
||||||
const CommandDesc define_command_cmd = {
|
const CommandDesc define_command_cmd = {
|
||||||
|
@ -1354,6 +1377,25 @@ const CommandDesc unalias_cmd = {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const CommandDesc complete_command_cmd = {
|
||||||
|
"complete-command",
|
||||||
|
"compl",
|
||||||
|
"complete-command [<switches>] <name> <type> [<param>]\n"
|
||||||
|
"define command completion",
|
||||||
|
ParameterDesc{
|
||||||
|
{ { "menu", { false, "treat completions as the only valid inputs" } }, },
|
||||||
|
ParameterDesc::Flags::None, 2, 3},
|
||||||
|
CommandFlags::None,
|
||||||
|
CommandHelper{},
|
||||||
|
make_completer(complete_command_name),
|
||||||
|
[](const ParametersParser& parser, Context& context, const ShellContext&)
|
||||||
|
{
|
||||||
|
const Completions::Flags flags = parser.get_switch("menu") ? Completions::Flags::Menu : Completions::Flags::None;
|
||||||
|
CommandCompleter completer = make_command_completer(parser[1], parser.positional_count() >= 3 ? parser[2] : StringView{}, flags);
|
||||||
|
CommandManager::instance().set_command_completer(parser[0], std::move(completer));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
const CommandDesc echo_cmd = {
|
const CommandDesc echo_cmd = {
|
||||||
"echo",
|
"echo",
|
||||||
nullptr,
|
nullptr,
|
||||||
|
@ -2719,6 +2761,7 @@ void register_commands()
|
||||||
register_command(remove_hook_cmd);
|
register_command(remove_hook_cmd);
|
||||||
register_command(trigger_user_hook_cmd);
|
register_command(trigger_user_hook_cmd);
|
||||||
register_command(define_command_cmd);
|
register_command(define_command_cmd);
|
||||||
|
register_command(complete_command_cmd);
|
||||||
register_command(alias_cmd);
|
register_command(alias_cmd);
|
||||||
register_command(unalias_cmd);
|
register_command(unalias_cmd);
|
||||||
register_command(echo_cmd);
|
register_command(echo_cmd);
|
||||||
|
|
|
@ -46,6 +46,7 @@ struct {
|
||||||
} constexpr version_notes[] = { {
|
} constexpr version_notes[] = { {
|
||||||
0,
|
0,
|
||||||
"» pipe commands do not append final end-of-lines anymore\n"
|
"» pipe commands do not append final end-of-lines anymore\n"
|
||||||
|
"» {+u}complete-command{} to configure command completion\n"
|
||||||
}, {
|
}, {
|
||||||
20211107,
|
20211107,
|
||||||
"» colored and curly underlines support (undocumented in 20210828)\n"
|
"» colored and curly underlines support (undocumented in 20210828)\n"
|
||||||
|
|
|
@ -67,6 +67,9 @@ public:
|
||||||
[[gnu::always_inline]]
|
[[gnu::always_inline]]
|
||||||
bool empty() const { return type().length() == 0_byte; }
|
bool empty() const { return type().length() == 0_byte; }
|
||||||
|
|
||||||
|
bool starts_with(StringView str) const;
|
||||||
|
bool ends_with(StringView str) const;
|
||||||
|
|
||||||
ByteCount byte_count_to(CharCount count) const
|
ByteCount byte_count_to(CharCount count) const
|
||||||
{ return utf8::advance(begin(), end(), count) - begin(); }
|
{ return utf8::advance(begin(), end(), count) - begin(); }
|
||||||
|
|
||||||
|
@ -306,6 +309,22 @@ inline StringView StringOps<Type, CharType>::substr(ColumnCount from, ColumnCoun
|
||||||
return StringView{ beg, utf8::advance(beg, end(), length) };
|
return StringView{ beg, utf8::advance(beg, end(), length) };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<typename Type, typename CharType>
|
||||||
|
inline bool StringOps<Type, CharType>::starts_with(StringView str) const
|
||||||
|
{
|
||||||
|
if (type().length() < str.length())
|
||||||
|
return false;
|
||||||
|
return substr(0, str.length()) == str;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename Type, typename CharType>
|
||||||
|
inline bool StringOps<Type, CharType>::ends_with(StringView str) const
|
||||||
|
{
|
||||||
|
if (type().length() < str.length())
|
||||||
|
return false;
|
||||||
|
return substr(type().length() - str.length()) == str;
|
||||||
|
}
|
||||||
|
|
||||||
inline String& operator+=(String& lhs, StringView rhs)
|
inline String& operator+=(String& lhs, StringView rhs)
|
||||||
{
|
{
|
||||||
lhs.append(rhs.data(), rhs.length());
|
lhs.append(rhs.data(), rhs.length());
|
||||||
|
|
|
@ -396,6 +396,16 @@ UnitTest test_string{[]()
|
||||||
{
|
{
|
||||||
kak_assert(String("youpi ") + "matin" == "youpi matin");
|
kak_assert(String("youpi ") + "matin" == "youpi matin");
|
||||||
|
|
||||||
|
kak_assert(StringView{"youpi"}.starts_with(""));
|
||||||
|
kak_assert(StringView{"youpi"}.starts_with("you"));
|
||||||
|
kak_assert(StringView{"youpi"}.starts_with("youpi"));
|
||||||
|
kak_assert(not StringView{"youpi"}.starts_with("youpi!"));
|
||||||
|
|
||||||
|
kak_assert(StringView{"youpi"}.ends_with(""));
|
||||||
|
kak_assert(StringView{"youpi"}.ends_with("pi"));
|
||||||
|
kak_assert(StringView{"youpi"}.ends_with("youpi"));
|
||||||
|
kak_assert(not StringView{"youpi"}.ends_with("oup"));
|
||||||
|
|
||||||
auto wrapped = "wrap this paragraph\n respecting whitespaces and much_too_long_words" | wrap_at(16) | gather<Vector>();
|
auto wrapped = "wrap this paragraph\n respecting whitespaces and much_too_long_words" | wrap_at(16) | gather<Vector>();
|
||||||
kak_assert(wrapped.size() == 6);
|
kak_assert(wrapped.size() == 6);
|
||||||
kak_assert(wrapped[0] == "wrap this");
|
kak_assert(wrapped[0] == "wrap this");
|
||||||
|
|
Loading…
Reference in New Issue
Block a user