mirror of
https://github.com/fish-shell/fish-shell.git
synced 2025-03-27 14:45:13 +08:00
commandline --selection-start
and --selection-end
implementation
Fixes #9197
This commit is contained in:
parent
dcf52dbba5
commit
e274ef6c0d
@ -26,6 +26,12 @@ The following options are available:
|
|||||||
If no argument is given, the current cursor position is printed, otherwise the argument is interpreted as the new cursor position.
|
If no argument is given, the current cursor position is printed, otherwise the argument is interpreted as the new cursor position.
|
||||||
If one of the options **-j**, **-p** or **-t** is given, the position is relative to the respective substring instead of the entire command line buffer.
|
If one of the options **-j**, **-p** or **-t** is given, the position is relative to the respective substring instead of the entire command line buffer.
|
||||||
|
|
||||||
|
**-B** or **--selection-start**
|
||||||
|
Get current position of the selection start in the buffer.
|
||||||
|
|
||||||
|
**-E** or **--selection-end**
|
||||||
|
Get current position of the selection end in the buffer.
|
||||||
|
|
||||||
**-f** or **--function**
|
**-f** or **--function**
|
||||||
Causes any additional arguments to be interpreted as input functions, and puts them into the queue, so that they will be read before any additional actual key presses are.
|
Causes any additional arguments to be interpreted as input functions, and puts them into the queue, so that they will be read before any additional actual key presses are.
|
||||||
This option cannot be combined with any other option.
|
This option cannot be combined with any other option.
|
||||||
|
@ -16,6 +16,8 @@ complete -c commandline -s o -l tokenize -d "Print each token on a separate line
|
|||||||
|
|
||||||
complete -c commandline -s I -l input -d "Specify command to operate on"
|
complete -c commandline -s I -l input -d "Specify command to operate on"
|
||||||
complete -c commandline -s C -l cursor -d "Set/get cursor position, not buffer contents"
|
complete -c commandline -s C -l cursor -d "Set/get cursor position, not buffer contents"
|
||||||
|
complete -c commandline -s B -l selection-start -d "Get current selection starting position"
|
||||||
|
complete -c commandline -s E -l selection-end -d "Get current selection ending position"
|
||||||
complete -c commandline -s L -l line -d "Print the line that the cursor is on"
|
complete -c commandline -s L -l line -d "Print the line that the cursor is on"
|
||||||
complete -c commandline -s S -l search-mode -d "Return true if performing a history search"
|
complete -c commandline -s S -l search-mode -d "Return true if performing a history search"
|
||||||
complete -c commandline -s P -l paging-mode -d "Return true if showing pager content"
|
complete -c commandline -s P -l paging-mode -d "Return true if showing pager content"
|
||||||
|
@ -142,6 +142,8 @@ maybe_t<int> builtin_commandline(parser_t &parser, io_streams_t &streams, const
|
|||||||
bool tokenize = false;
|
bool tokenize = false;
|
||||||
|
|
||||||
bool cursor_mode = false;
|
bool cursor_mode = false;
|
||||||
|
bool selection_start_mode = false;
|
||||||
|
bool selection_end_mode = false;
|
||||||
bool line_mode = false;
|
bool line_mode = false;
|
||||||
bool search_mode = false;
|
bool search_mode = false;
|
||||||
bool paging_mode = false;
|
bool paging_mode = false;
|
||||||
@ -152,7 +154,7 @@ maybe_t<int> builtin_commandline(parser_t &parser, io_streams_t &streams, const
|
|||||||
|
|
||||||
const auto &ld = parser.libdata();
|
const auto &ld = parser.libdata();
|
||||||
|
|
||||||
static const wchar_t *const short_options = L":abijpctforhI:CLSsP";
|
static const wchar_t *const short_options = L":abijpctforhI:CBELSsP";
|
||||||
static const struct woption long_options[] = {{L"append", no_argument, nullptr, 'a'},
|
static const struct woption long_options[] = {{L"append", no_argument, nullptr, 'a'},
|
||||||
{L"insert", no_argument, nullptr, 'i'},
|
{L"insert", no_argument, nullptr, 'i'},
|
||||||
{L"replace", no_argument, nullptr, 'r'},
|
{L"replace", no_argument, nullptr, 'r'},
|
||||||
@ -167,6 +169,8 @@ maybe_t<int> builtin_commandline(parser_t &parser, io_streams_t &streams, const
|
|||||||
{L"help", no_argument, nullptr, 'h'},
|
{L"help", no_argument, nullptr, 'h'},
|
||||||
{L"input", required_argument, nullptr, 'I'},
|
{L"input", required_argument, nullptr, 'I'},
|
||||||
{L"cursor", no_argument, nullptr, 'C'},
|
{L"cursor", no_argument, nullptr, 'C'},
|
||||||
|
{L"selection-start", no_argument, nullptr, 'B'},
|
||||||
|
{L"selection-end", no_argument, nullptr, 'E'},
|
||||||
{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'},
|
||||||
@ -227,6 +231,14 @@ maybe_t<int> builtin_commandline(parser_t &parser, io_streams_t &streams, const
|
|||||||
cursor_mode = true;
|
cursor_mode = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case 'B': {
|
||||||
|
selection_start_mode = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 'E': {
|
||||||
|
selection_end_mode = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
case 'L': {
|
case 'L': {
|
||||||
line_mode = true;
|
line_mode = true;
|
||||||
break;
|
break;
|
||||||
@ -274,7 +286,7 @@ maybe_t<int> builtin_commandline(parser_t &parser, io_streams_t &streams, const
|
|||||||
|
|
||||||
// Check for invalid switch combinations.
|
// Check for invalid switch combinations.
|
||||||
if (buffer_part || cut_at_cursor || append_mode || tokenize || cursor_mode || line_mode ||
|
if (buffer_part || cut_at_cursor || append_mode || tokenize || cursor_mode || line_mode ||
|
||||||
search_mode || paging_mode) {
|
search_mode || paging_mode || selection_start_mode || selection_end_mode) {
|
||||||
streams.err.append_format(BUILTIN_ERR_COMBO, argv[0]);
|
streams.err.append_format(BUILTIN_ERR_COMBO, argv[0]);
|
||||||
builtin_print_error_trailer(parser, streams.err, cmd);
|
builtin_print_error_trailer(parser, streams.err, cmd);
|
||||||
return STATUS_INVALID_ARGS;
|
return STATUS_INVALID_ARGS;
|
||||||
@ -324,6 +336,12 @@ maybe_t<int> builtin_commandline(parser_t &parser, io_streams_t &streams, const
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Check for invalid switch combinations.
|
// Check for invalid switch combinations.
|
||||||
|
if ((selection_start_mode || selection_end_mode) && (argc - w.woptind)) {
|
||||||
|
streams.err.append_format(BUILTIN_ERR_TOO_MANY_ARGUMENTS, argv[0]);
|
||||||
|
builtin_print_error_trailer(parser, streams.err, cmd);
|
||||||
|
return STATUS_INVALID_ARGS;
|
||||||
|
}
|
||||||
|
|
||||||
if ((search_mode || line_mode || cursor_mode || paging_mode) && (argc - w.woptind > 1)) {
|
if ((search_mode || line_mode || cursor_mode || paging_mode) && (argc - w.woptind > 1)) {
|
||||||
streams.err.append_format(BUILTIN_ERR_TOO_MANY_ARGUMENTS, argv[0]);
|
streams.err.append_format(BUILTIN_ERR_TOO_MANY_ARGUMENTS, argv[0]);
|
||||||
builtin_print_error_trailer(parser, streams.err, cmd);
|
builtin_print_error_trailer(parser, streams.err, cmd);
|
||||||
@ -379,6 +397,24 @@ maybe_t<int> builtin_commandline(parser_t &parser, io_streams_t &streams, const
|
|||||||
return (state.pager_mode && state.pager_fully_disclosed) ? 0 : 1;
|
return (state.pager_mode && state.pager_fully_disclosed) ? 0 : 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (selection_start_mode) {
|
||||||
|
if (!rstate.selection) {
|
||||||
|
return STATUS_CMD_ERROR;
|
||||||
|
}
|
||||||
|
source_offset_t start = rstate.selection->start;
|
||||||
|
streams.out.append_format(L"%lu\n", static_cast<unsigned long>(start));
|
||||||
|
return STATUS_CMD_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (selection_end_mode) {
|
||||||
|
if (!rstate.selection) {
|
||||||
|
return STATUS_CMD_ERROR;
|
||||||
|
}
|
||||||
|
source_offset_t end = rstate.selection->end();
|
||||||
|
streams.out.append_format(L"%lu\n", static_cast<unsigned long>(end));
|
||||||
|
return STATUS_CMD_OK;
|
||||||
|
}
|
||||||
|
|
||||||
// At this point we have (nearly) exhausted the options which always operate on the true command
|
// At this point we have (nearly) exhausted the options which always operate on the true command
|
||||||
// line. Now we respect the possibility of a transient command line due to evaluating a wrapped
|
// line. Now we respect the possibility of a transient command line due to evaluating a wrapped
|
||||||
// completion. Don't do this in cursor_mode: it makes no sense to move the cursor based on a
|
// completion. Don't do this in cursor_mode: it makes no sense to move the cursor based on a
|
||||||
|
Loading…
x
Reference in New Issue
Block a user