mirror of
https://github.com/fish-shell/fish-shell
synced 2024-12-26 12:53:13 +00:00
Merge branch 'master' into documentation-update
Conflicts (fixed): doc_src/design.hdr
This commit is contained in:
commit
0e5ddfd9f5
6 changed files with 107 additions and 12 deletions
56
builtin.cpp
56
builtin.cpp
|
@ -2313,6 +2313,8 @@ static int builtin_read(parser_t &parser, wchar_t **argv)
|
||||||
const wchar_t *commandline = L"";
|
const wchar_t *commandline = L"";
|
||||||
int exit_res=STATUS_BUILTIN_OK;
|
int exit_res=STATUS_BUILTIN_OK;
|
||||||
const wchar_t *mode_name = READ_MODE_NAME;
|
const wchar_t *mode_name = READ_MODE_NAME;
|
||||||
|
int nchars=0;
|
||||||
|
wchar_t *end;
|
||||||
int shell = 0;
|
int shell = 0;
|
||||||
int array = 0;
|
int array = 0;
|
||||||
|
|
||||||
|
@ -2355,6 +2357,10 @@ static int builtin_read(parser_t &parser, wchar_t **argv)
|
||||||
L"mode-name", required_argument, 0, 'm'
|
L"mode-name", required_argument, 0, 'm'
|
||||||
}
|
}
|
||||||
,
|
,
|
||||||
|
{
|
||||||
|
L"nchars", required_argument, 0, 'n'
|
||||||
|
}
|
||||||
|
,
|
||||||
{
|
{
|
||||||
L"shell", no_argument, 0, 's'
|
L"shell", no_argument, 0, 's'
|
||||||
}
|
}
|
||||||
|
@ -2377,7 +2383,7 @@ static int builtin_read(parser_t &parser, wchar_t **argv)
|
||||||
|
|
||||||
int opt = wgetopt_long(argc,
|
int opt = wgetopt_long(argc,
|
||||||
argv,
|
argv,
|
||||||
L"xglUup:c:hm:sa",
|
L"xglUup:c:hm:n:sa",
|
||||||
long_options,
|
long_options,
|
||||||
&opt_index);
|
&opt_index);
|
||||||
if (opt == -1)
|
if (opt == -1)
|
||||||
|
@ -2428,6 +2434,32 @@ static int builtin_read(parser_t &parser, wchar_t **argv)
|
||||||
mode_name = woptarg;
|
mode_name = woptarg;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case L'n':
|
||||||
|
errno = 0;
|
||||||
|
nchars = fish_wcstoi(woptarg, &end, 10);
|
||||||
|
if (errno || *end != 0)
|
||||||
|
{
|
||||||
|
switch (errno)
|
||||||
|
{
|
||||||
|
case ERANGE:
|
||||||
|
append_format(stderr_buffer,
|
||||||
|
_(L"%ls: Argument '%ls' is out of range\n"),
|
||||||
|
argv[0],
|
||||||
|
woptarg);
|
||||||
|
builtin_print_help(parser, argv[0], stderr_buffer);
|
||||||
|
return STATUS_BUILTIN_ERROR;
|
||||||
|
|
||||||
|
default:
|
||||||
|
append_format(stderr_buffer,
|
||||||
|
_(L"%ls: Argument '%ls' must be an integer\n"),
|
||||||
|
argv[0],
|
||||||
|
woptarg);
|
||||||
|
builtin_print_help(parser, argv[0], stderr_buffer);
|
||||||
|
return STATUS_BUILTIN_ERROR;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
case 's':
|
case 's':
|
||||||
shell = 1;
|
shell = 1;
|
||||||
break;
|
break;
|
||||||
|
@ -2530,11 +2562,24 @@ static int builtin_read(parser_t &parser, wchar_t **argv)
|
||||||
proc_push_interactive(1);
|
proc_push_interactive(1);
|
||||||
|
|
||||||
event_fire_generic(L"fish_prompt");
|
event_fire_generic(L"fish_prompt");
|
||||||
line = reader_readline();
|
line = reader_readline(nchars);
|
||||||
proc_pop_interactive();
|
proc_pop_interactive();
|
||||||
if (line)
|
if (line)
|
||||||
{
|
{
|
||||||
buff = wcsdup(line);
|
if (0 < nchars && nchars < wcslen(line))
|
||||||
|
{
|
||||||
|
// line may be longer than nchars if a keybinding used `commandline -i`
|
||||||
|
// note: we're deliberately throwing away the tail of the commandline.
|
||||||
|
// It shouldn't be unread because it was produced with `commandline -i`,
|
||||||
|
// not typed.
|
||||||
|
buff = (wchar_t *)malloc(((size_t)nchars + 1) * sizeof(wchar_t));
|
||||||
|
wmemcpy(buff, line, (size_t)nchars);
|
||||||
|
buff[nchars] = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
buff = wcsdup(line);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -2594,6 +2639,11 @@ static int builtin_read(parser_t &parser, wchar_t **argv)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
sb.push_back(res);
|
sb.push_back(res);
|
||||||
|
|
||||||
|
if (0 < nchars && (size_t)nchars <= sb.size())
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sb.size() < 2 && eof)
|
if (sb.size() < 2 && eof)
|
||||||
|
|
|
@ -19,6 +19,8 @@ The following options are available:
|
||||||
|
|
||||||
- `-m NAME` or `--mode-name=NAME` specifies that the name NAME should be used to save/load the history file. If NAME is fish, the regular fish history will be available.
|
- `-m NAME` or `--mode-name=NAME` specifies that the name NAME should be used to save/load the history file. If NAME is fish, the regular fish history will be available.
|
||||||
|
|
||||||
|
- `-n NCHARS` or `--nchars=NCHARS` causes `read` to return after reading NCHARS characters rather than waiting for a complete line of input.
|
||||||
|
|
||||||
- `-p PROMPT_CMD` or `--prompt=PROMPT_CMD` uses the output of the shell command `PROMPT_CMD` as the prompt for the interactive mode. The default prompt command is <code>set_color green; echo read; set_color normal; echo "> "</code>.
|
- `-p PROMPT_CMD` or `--prompt=PROMPT_CMD` uses the output of the shell command `PROMPT_CMD` as the prompt for the interactive mode. The default prompt command is <code>set_color green; echo read; set_color normal; echo "> "</code>.
|
||||||
|
|
||||||
- `-s` or `--shell` enables syntax highlighting, tab completions and command termination suitable for entering shellscript code in the interactive mode.
|
- `-s` or `--shell` enables syntax highlighting, tab completions and command termination suitable for entering shellscript code in the interactive mode.
|
||||||
|
@ -35,6 +37,8 @@ The following options are available:
|
||||||
|
|
||||||
If `-a` or `--array` is provided, only one variable name is allowed and the tokens are stored as an array in this variable.
|
If `-a` or `--array` is provided, only one variable name is allowed and the tokens are stored as an array in this variable.
|
||||||
|
|
||||||
|
See the documentation for `set` for more details on the scoping rules for variables.
|
||||||
|
|
||||||
|
|
||||||
\subsection read-example Example
|
\subsection read-example Example
|
||||||
|
|
||||||
|
|
25
reader.cpp
25
reader.cpp
|
@ -2955,7 +2955,7 @@ static int read_i(void)
|
||||||
during evaluation.
|
during evaluation.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
const wchar_t *tmp = reader_readline();
|
const wchar_t *tmp = reader_readline(0);
|
||||||
|
|
||||||
if (data->end_loop)
|
if (data->end_loop)
|
||||||
{
|
{
|
||||||
|
@ -3044,7 +3044,7 @@ static wchar_t unescaped_quote(const wcstring &str, size_t pos)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
const wchar_t *reader_readline(void)
|
const wchar_t *reader_readline(int nchars)
|
||||||
{
|
{
|
||||||
wint_t c;
|
wint_t c;
|
||||||
int last_char=0;
|
int last_char=0;
|
||||||
|
@ -3084,6 +3084,13 @@ const wchar_t *reader_readline(void)
|
||||||
|
|
||||||
while (!finished && !data->end_loop)
|
while (!finished && !data->end_loop)
|
||||||
{
|
{
|
||||||
|
if (0 < nchars && (size_t)nchars <= data->command_line.size())
|
||||||
|
{
|
||||||
|
// we've already hit the specified character limit
|
||||||
|
finished = 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Sometimes strange input sequences seem to generate a zero
|
Sometimes strange input sequences seem to generate a zero
|
||||||
byte. I believe these simply mean a character was pressed
|
byte. I believe these simply mean a character was pressed
|
||||||
|
@ -3104,12 +3111,14 @@ const wchar_t *reader_readline(void)
|
||||||
{
|
{
|
||||||
|
|
||||||
wchar_t arr[READAHEAD_MAX+1];
|
wchar_t arr[READAHEAD_MAX+1];
|
||||||
int i;
|
size_t i;
|
||||||
|
size_t limit = 0 < nchars ? std::min((size_t)nchars - data->command_line.size(), (size_t)READAHEAD_MAX)
|
||||||
|
: READAHEAD_MAX;
|
||||||
|
|
||||||
memset(arr, 0, sizeof(arr));
|
memset(arr, 0, sizeof(arr));
|
||||||
arr[0] = c;
|
arr[0] = c;
|
||||||
|
|
||||||
for (i=1; i<READAHEAD_MAX; i++)
|
for (i = 1; i < limit; ++i)
|
||||||
{
|
{
|
||||||
|
|
||||||
if (!can_read(0))
|
if (!can_read(0))
|
||||||
|
@ -3120,7 +3129,7 @@ const wchar_t *reader_readline(void)
|
||||||
// only allow commands on the first key; otherwise, we might
|
// only allow commands on the first key; otherwise, we might
|
||||||
// have data we need to insert on the commandline that the
|
// have data we need to insert on the commandline that the
|
||||||
// commmand might need to be able to see.
|
// commmand might need to be able to see.
|
||||||
c = input_readch(i == 1);
|
c = input_readch(false);
|
||||||
if ((!wchar_private(c)) && (c>31) && (c != 127))
|
if ((!wchar_private(c)) && (c>31) && (c != 127))
|
||||||
{
|
{
|
||||||
arr[i]=c;
|
arr[i]=c;
|
||||||
|
@ -3137,6 +3146,12 @@ const wchar_t *reader_readline(void)
|
||||||
|
|
||||||
if (c != 0)
|
if (c != 0)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
if (0 < nchars && (size_t)nchars <= data->command_line.size())
|
||||||
|
{
|
||||||
|
c = R_NULL;
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If we get something other than a repaint, then stop coalescing them */
|
/* If we get something other than a repaint, then stop coalescing them */
|
||||||
|
|
10
reader.h
10
reader.h
|
@ -200,11 +200,13 @@ int reader_reading_interrupted();
|
||||||
bool reader_thread_job_is_stale();
|
bool reader_thread_job_is_stale();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Read one line of input. Before calling this function, reader_push()
|
Read one line of input. Before calling this function, reader_push() must have
|
||||||
must have been called in order to set up a valid reader
|
been called in order to set up a valid reader environment. If nchars > 0,
|
||||||
environment.
|
return after reading that many characters even if a full line has not yet
|
||||||
|
been read. Note: the returned value may be longer than nchars if a single
|
||||||
|
keypress resulted in multiple characters being inserted into the commandline.
|
||||||
*/
|
*/
|
||||||
const wchar_t *reader_readline();
|
const wchar_t *reader_readline(int nchars);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Push a new reader environment.
|
Push a new reader environment.
|
||||||
|
|
|
@ -75,3 +75,19 @@ print_vars ary
|
||||||
echo '' | read -la ary
|
echo '' | read -la ary
|
||||||
print_vars ary
|
print_vars ary
|
||||||
set -le IFS
|
set -le IFS
|
||||||
|
|
||||||
|
# read -n tests
|
||||||
|
|
||||||
|
echo
|
||||||
|
echo '# read -n tests'
|
||||||
|
echo 'testing' | read -n 3 foo
|
||||||
|
echo $foo
|
||||||
|
echo 'test' | read -n 10 foo
|
||||||
|
echo $foo
|
||||||
|
echo 'test' | read -n 0 foo
|
||||||
|
echo $foo
|
||||||
|
echo 'testing' | begin; read -n 3 foo; read -n 3 bar; end
|
||||||
|
echo $foo
|
||||||
|
echo $bar
|
||||||
|
echo 'test' | read -n 1 foo
|
||||||
|
echo $foo
|
||||||
|
|
|
@ -34,3 +34,11 @@ two
|
||||||
5 'h' 'e' 'l' 'l' 'o'
|
5 'h' 'e' 'l' 'l' 'o'
|
||||||
1 'h'
|
1 'h'
|
||||||
0
|
0
|
||||||
|
|
||||||
|
# read -n tests
|
||||||
|
tes
|
||||||
|
test
|
||||||
|
test
|
||||||
|
tes
|
||||||
|
tin
|
||||||
|
t
|
||||||
|
|
Loading…
Reference in a new issue