mirror of
https://github.com/fish-shell/fish-shell
synced 2024-12-28 13:53:10 +00:00
commandline: Add --is-valid option (#8142)
* commandline: Add --is-valid option to query whether it's syntactically complete This means querying when the commandline is in a state that it could be executed. Because our `execute` bind function also inserts a newline if it isn't. One case that's not handled right now: `execute` also expands abbreviations, those can technically make the commandline invalid again. Unfortunately we have no real way to *check* without doing the replacement. Also since abbreviations are only available in command position when you _execute_ them the commandline will most likely be valid. This is enough to make transient prompts work: ```fish function reset-transient --on-event fish_postexec set -g TRANSIENT 0 end function maybe_execute if commandline --is-valid set -g TRANSIENT 1 commandline -f repaint else set -g TRANSIENT 0 end commandline -f execute end bind \r maybe_execute ``` and then in `fish_prompt` react to $TRANSIENT being set to 1.
This commit is contained in:
parent
8767f873eb
commit
c4593828f4
3 changed files with 38 additions and 0 deletions
|
@ -61,6 +61,7 @@ The following options output metadata about the commandline state:
|
||||||
|
|
||||||
- ``-P`` or ``--paging-mode`` evaluates to true if the commandline is showing pager contents, such as tab completions
|
- ``-P`` or ``--paging-mode`` evaluates to true if the commandline is showing pager contents, such as tab completions
|
||||||
|
|
||||||
|
- ``--is-valid`` returns true when the commandline is syntactically valid and complete. If it is, it would be executed when the ``execute`` bind function is called. If the commandline is incomplete, it returns 2, if it is erroneus, it returns 1.
|
||||||
|
|
||||||
Example
|
Example
|
||||||
-------
|
-------
|
||||||
|
|
|
@ -142,6 +142,7 @@ maybe_t<int> builtin_commandline(parser_t &parser, io_streams_t &streams, const
|
||||||
bool line_mode = false;
|
bool line_mode = false;
|
||||||
bool search_mode = false;
|
bool search_mode = false;
|
||||||
bool paging_mode = false;
|
bool paging_mode = false;
|
||||||
|
bool is_valid = false;
|
||||||
const wchar_t *begin = nullptr, *end = nullptr;
|
const wchar_t *begin = nullptr, *end = nullptr;
|
||||||
const wchar_t *override_buffer = nullptr;
|
const wchar_t *override_buffer = nullptr;
|
||||||
|
|
||||||
|
@ -165,6 +166,7 @@ maybe_t<int> builtin_commandline(parser_t &parser, io_streams_t &streams, const
|
||||||
{L"line", no_argument, nullptr, 'L'},
|
{L"line", no_argument, nullptr, 'L'},
|
||||||
{L"search-mode", no_argument, nullptr, 'S'},
|
{L"search-mode", no_argument, nullptr, 'S'},
|
||||||
{L"paging-mode", no_argument, nullptr, 'P'},
|
{L"paging-mode", no_argument, nullptr, 'P'},
|
||||||
|
{L"is-valid", no_argument, nullptr, 1},
|
||||||
{nullptr, 0, nullptr, 0}};
|
{nullptr, 0, nullptr, 0}};
|
||||||
|
|
||||||
int opt;
|
int opt;
|
||||||
|
@ -236,6 +238,10 @@ maybe_t<int> builtin_commandline(parser_t &parser, io_streams_t &streams, const
|
||||||
paging_mode = true;
|
paging_mode = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case 1: {
|
||||||
|
is_valid = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
case 'h': {
|
case 'h': {
|
||||||
builtin_print_help(parser, streams, cmd);
|
builtin_print_help(parser, streams, cmd);
|
||||||
return STATUS_CMD_OK;
|
return STATUS_CMD_OK;
|
||||||
|
@ -387,6 +393,18 @@ maybe_t<int> builtin_commandline(parser_t &parser, io_streams_t &streams, const
|
||||||
return STATUS_CMD_ERROR;
|
return STATUS_CMD_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (is_valid) {
|
||||||
|
if (!*current_buffer) return 1;
|
||||||
|
parser_test_error_bits_t res =
|
||||||
|
parse_util_detect_errors(current_buffer,
|
||||||
|
NULL,
|
||||||
|
true /* accept incomplete so we can tell the difference */);
|
||||||
|
if (res & PARSER_TEST_INCOMPLETE) {
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
return res & PARSER_TEST_ERROR ? STATUS_CMD_ERROR : STATUS_CMD_OK;
|
||||||
|
}
|
||||||
|
|
||||||
switch (buffer_part) {
|
switch (buffer_part) {
|
||||||
case STRING_MODE: {
|
case STRING_MODE: {
|
||||||
begin = current_buffer;
|
begin = current_buffer;
|
||||||
|
|
19
tests/checks/commandline.fish
Normal file
19
tests/checks/commandline.fish
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
#RUN: %fish %s
|
||||||
|
|
||||||
|
commandline --input "echo foo | bar" --is-valid
|
||||||
|
and echo Valid
|
||||||
|
# CHECK: Valid
|
||||||
|
|
||||||
|
commandline --input "echo foo | " --is-valid
|
||||||
|
or echo Invalid $status
|
||||||
|
# CHECK: Invalid 2
|
||||||
|
|
||||||
|
# TODO: This seems a bit awkward?
|
||||||
|
# The empty commandline is an error, not incomplete?
|
||||||
|
commandline --input '' --is-valid
|
||||||
|
or echo Invalid $status
|
||||||
|
# CHECK: Invalid 1
|
||||||
|
|
||||||
|
commandline --input 'echo $$' --is-valid
|
||||||
|
or echo Invalid $status
|
||||||
|
# CHECK: Invalid 1
|
Loading…
Reference in a new issue