mirror of
https://github.com/fish-shell/fish-shell.git
synced 2026-06-06 00:41:15 -03:00
builtins commandline/complete: allow handling commandline before reader initialization
Commands like "commandline foo" silently fail, and "complete -C" fails with a weird "option requires an argument" error. I think at least the first one can be useful in edge cases, e.g. to test code that does not separate the `commandline` input and output (#11570), and to set fish's initial commandline, see the next commit. I don't think there are super strong reasons to allow these, but if the existing state is merely due to "no one has ever thought of doing this", then we should try changing it. For consistency, also allow "complete -C". I guess an argument for that is that it's weird to make a command behave differently in non-interactive shells. For now, keep the historical behavior of disabling access to the command line in non-interactive shells. If we find a good reason for allowing that (which seems unlikely), we can. Ref: https://github.com/fish-shell/fish-shell/pull/11570#discussion_r2144544053 Co-authored-by: Johannes Altmanninger <aclopte@gmail.com>
This commit is contained in:
committed by
Johannes Altmanninger
parent
4d67ca7c58
commit
32c36aa5f8
@@ -636,19 +636,16 @@ pub fn commandline(parser: &Parser, streams: &mut IoStreams, args: &mut [&wstr])
|
||||
transient = parser.libdata().transient_commandline.clone().unwrap();
|
||||
current_buffer = &transient;
|
||||
current_cursor_pos = transient.len();
|
||||
} else if rstate.initialized {
|
||||
} else if is_interactive_session() {
|
||||
current_buffer = &rstate.text;
|
||||
current_cursor_pos = rstate.cursor_pos;
|
||||
} else {
|
||||
// There is no command line, either because we are not interactive, or because we are
|
||||
// interactive and are still reading init files (in which case we silently ignore this).
|
||||
if !is_interactive_session() {
|
||||
streams.err.append(cmd);
|
||||
streams
|
||||
.err
|
||||
.append(L!(": Can not set commandline in non-interactive mode\n"));
|
||||
builtin_print_error_trailer(parser, streams.err, cmd);
|
||||
}
|
||||
// There is no command line because we are not interactive.
|
||||
streams.err.append(cmd);
|
||||
streams
|
||||
.err
|
||||
.append(L!(": Can not set commandline in non-interactive mode\n"));
|
||||
builtin_print_error_trailer(parser, streams.err, cmd);
|
||||
return Err(STATUS_CMD_ERROR);
|
||||
}
|
||||
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
use crate::parse_constants::ParseErrorList;
|
||||
use crate::parse_util::parse_util_detect_errors_in_argument_list;
|
||||
use crate::parse_util::{parse_util_detect_errors, parse_util_token_extent};
|
||||
use crate::proc::is_interactive_session;
|
||||
use crate::reader::{commandline_get_state, completion_apply_to_command_line};
|
||||
use crate::wcstringutil::string_suffixes_string;
|
||||
use crate::{
|
||||
@@ -465,11 +466,12 @@ pub fn complete(parser: &Parser, streams: &mut IoStreams, argv: &mut [&wstr]) ->
|
||||
None => {
|
||||
// No argument given, try to use the current commandline.
|
||||
let commandline_state = commandline_get_state(true);
|
||||
if !commandline_state.initialized {
|
||||
// This corresponds to using 'complete -C' in non-interactive mode.
|
||||
// See #2361 .
|
||||
builtin_missing_argument(parser, streams, cmd, L!("-C"), true);
|
||||
return Err(STATUS_INVALID_ARGS);
|
||||
if !is_interactive_session() {
|
||||
streams.err.append(cmd);
|
||||
streams
|
||||
.err
|
||||
.append(L!(": Can not get commandline in non-interactive mode\n"));
|
||||
return Err(STATUS_CMD_ERROR);
|
||||
}
|
||||
commandline_state.text
|
||||
}
|
||||
|
||||
@@ -400,8 +400,6 @@ pub struct CommandlineState {
|
||||
pub search_field: Option<(WString, usize)>,
|
||||
/// pager is visible and search is active
|
||||
pub search_mode: bool,
|
||||
/// if false, the reader has not yet been entered
|
||||
pub initialized: bool,
|
||||
}
|
||||
|
||||
impl CommandlineState {
|
||||
@@ -415,7 +413,6 @@ const fn new() -> Self {
|
||||
pager_fully_disclosed: false,
|
||||
search_field: None,
|
||||
search_mode: false,
|
||||
initialized: false,
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1370,7 +1367,6 @@ fn update_commandline_state(&self) {
|
||||
});
|
||||
}
|
||||
snapshot.search_mode = self.history_search.active();
|
||||
snapshot.initialized = true;
|
||||
}
|
||||
|
||||
/// Apply any changes from the reader snapshot. This is called after running fish script,
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
#RUN: %fish %s
|
||||
|
||||
set -g fish (status fish-path)
|
||||
|
||||
commandline --input "echo foo | bar" --is-valid
|
||||
and echo Valid
|
||||
# CHECK: Valid
|
||||
@@ -50,3 +52,16 @@ commandline --input "echo > {a,b}" --tokens-expanded
|
||||
commandline --input "echo {arg1,arg2} <in >out" --tokens-raw
|
||||
# CHECK: echo
|
||||
# CHECK: {arg1,arg2}
|
||||
|
||||
$fish -ic '
|
||||
commandline hello
|
||||
commandline
|
||||
commandline -i world
|
||||
commandline
|
||||
commandline --cursor 5
|
||||
commandline -i " "
|
||||
commandline
|
||||
'
|
||||
# CHECK: hello
|
||||
# CHECK: helloworld
|
||||
# CHECK: hello world
|
||||
|
||||
Reference in New Issue
Block a user