-
-
Notifications
You must be signed in to change notification settings - Fork 2.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Rewrite command line parsing, add flags and expansions #12527
base: master
Are you sure you want to change the base?
Conversation
The prompt completion type alias is otherwise private. In child commits we will refactor some functions to return prompt completions, enabled by this small change.
This comment was marked as resolved.
This comment was marked as resolved.
Exciting PR. These are working for me on macOS: C-b = ":sh gh browse %{buffer_name}:%{cursor_line} -c=%sh{latest_pushed_commit}"
C-B = ":echo %sh{git blame --date=short -L %{cursor_line},+1 %{buffer_name} | sed -E 's/[0-9]+).*//' | sed 's/(//g'}" |
This comment was marked as resolved.
This comment was marked as resolved.
17de242
to
0507a5d
Compare
This comment was marked as resolved.
This comment was marked as resolved.
This comment was marked as resolved.
This comment was marked as resolved.
This comment was marked as resolved.
This comment was marked as resolved.
This comment was marked as resolved.
This comment was marked as resolved.
This comment was marked as resolved.
This comment was marked as resolved.
0507a5d
to
c7b1938
Compare
This comment was marked as resolved.
This comment was marked as resolved.
This comment was marked as resolved.
This comment was marked as resolved.
This comment was marked as resolved.
This comment was marked as resolved.
This comment was marked as resolved.
This comment was marked as resolved.
This comment was marked as resolved.
This comment was marked as resolved.
This comment was marked as resolved.
This comment was marked as resolved.
This comment was marked as resolved.
This comment was marked as resolved.
c7b1938
to
8462aef
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Some minor ideas here
When a variable is completed, we are left in this state:
What would be nice is if it automatically inserted the |
Ideally that would be covered by auto-pairs within the command line but that will take further changes to how completions work in the |
This is a full rewrite of the command line code which was parsed with `Shellwords` in the past. `Shellwords`'s escaping system was quite tricky to work with and prevented further improvements to the command line syntax like command flags (e.g. `--reverse`) and Kakoune-like expansions (`%sh{echo hello world}`). Ideally these features would be added after improving the parsing code but they both influence the design of the parser(s), their output types and the completion code so I feel it's best to land them together in one (admittedly outlandishly large) commit.
8462aef
to
78cb6b6
Compare
This change rewrites the command line parsing code (discarding
shellwords
) and adds command flags and expansions. Unfortunately these features are not really independent - each feature influences the design of the parsing and completion code - so I think it's best to add them all together.The syntax and design are roughly the same as what Kakoune is doing but with a few twists:
%sh{..}
expansions are recursive, enabling variables within shell commands like:noop %sh{gh browse "%{buffer_name}:%{cursor_line}" -c=%sh{git rev-parse HEAD}}
for example from Command expansion v2 #11164 (comment). In contrast, Kakoune exposes$kak_<val_name>
environment variables to the shell program.:toggle-option
for example to support toggling objects and arrays like:toggle rulers [10, 20] [30, 40]
: after the first arg everything is parsed as a JSON stream instead.The documentation in
book/src/commands.md
explains the quoting rules and how to use flags and expansions.Completion in the command mode prompt supports expansion names, variable names, and flags and it can be extended in the future for new expansions.
This PR focuses on the parsing and completion changes so it only adds one flag and a handful of variables. Other flags, variables or expansion kinds (for example
%config{key}
, the-mikedavis@dc57b11) should be very easy to add as follow-ups.The user-facing changes are:
:rsort
is removed, replaced with:sort -r
/:sort --reverse
. (breaking):sh
or:pipe
evaluate expansions but do not handle quotes. Aside from expansions the command line text is passed to the shell program as-is. (fixes sh command doesn't handle arguments with spaces #7453, fixes Remove escaping on shell commands #10549):set-option
and:toggle-option
now interpret the first argument according to normal rules but then use custom parsing for the rest of the input.:toggle-option
can now toggle object and array values likerulers
. (fixes Line numbers are now configurable via the gutters setting but apparently can't be changed with the :set command #2206, fixes :set-option cannot be used for structured options with spacing. #6171):echo
and:noop
. (:noop
enables a workflow like Adds a run-shell-command-no-output command #3247):open a\<tab>
in a directory with a filea b.txt
on Unix.)Review notes...
A good entrypoint looking at the new code is
Args::parse
. This is used when executing a command inhelix_term::commands::typed::execute_command
.Args
readsToken
s from theTokenizer
, according to a typable command's declaredSignature
, expanding them when you hit<ret>
in command mode.Signature
tellsArgs
how to parse the input: the range of positionals that should be expected, the command's flags and, optionally, after how many positionals the input should be consumed for further parsing within the command (Signature.raw_after
,Tokenizer::rest
).The completion code in
complete_command_args
(typed.rs
) is also worth a look to see how theToken
type is reused outside ofArgs::parse
.Tokenizer
closely follows Kakoune'sCommandParser
whileArgs
somewhat follows Kakoune'sParametersParser
.shellwords
has been discarded: the escaping rules were not very intuitive - generally backslash should be a convenience available to Unix and not at all required.Fixes #5828
Fixes #10993
Closes #11164