reader: fix regressions when moving between lines

Fixes some regressions from 35ca42413 ("Simplify some parse_util functions").
The tmux tests are not beautiful but I find them easy to write.
Probably a pexpect test would also be enough here?
This commit is contained in:
Johannes Altmanninger 2021-08-01 17:41:56 +02:00
parent 2c420ef728
commit 3a375c2399
2 changed files with 46 additions and 9 deletions

View File

@ -54,8 +54,8 @@ int parse_util_lineno(const wcstring &str, size_t offset) {
int parse_util_get_line_from_offset(const wcstring &str, size_t pos) {
// Return the line pos is on, or -1 if it's after the end.
if (str.length() > pos) return -1;
return std::count(str.begin() + pos, str.end(), L'\n');
if (pos > str.length()) return -1;
return std::count(str.begin(), str.begin() + pos, L'\n');
}
size_t parse_util_get_offset_from_line(const wcstring &str, int line) {
@ -63,10 +63,11 @@ size_t parse_util_get_offset_from_line(const wcstring &str, int line) {
if (line < 0) return static_cast<size_t>(-1);
if (line == 0) return 0;
ssize_t i = 0;
while (auto pos = str.find(L'\n')) {
i++;
if (i == line) return pos + 1;
size_t pos = -1;
int count = 0;
while ((pos = str.find(L'\n', pos + 1)) != wcstring::npos) {
count++;
if (count == line) return pos + 1;
}
return static_cast<size_t>(-1);
}
@ -222,7 +223,6 @@ long parse_util_slice_length(const wchar_t *in) {
return -1;
}
int parse_util_locate_cmdsubst_range(const wcstring &str, size_t *inout_cursor_offset,
wcstring *out_contents, size_t *out_start, size_t *out_end,
bool accept_incomplete, bool *out_is_quoted) {
@ -1112,8 +1112,9 @@ static bool detect_errors_in_decorated_statement(const wcstring &buff_src,
const wcstring &com = dst.command.source(buff_src, storage);
if (com == L"$status") {
parse_error_offset_source_start(parse_errors, source_start);
errored = append_syntax_error(parse_errors, source_start,
_(L"$status is not valid as a command. See `help conditions`"));
errored =
append_syntax_error(parse_errors, source_start,
_(L"$status is not valid as a command. See `help conditions`"));
}
const wcstring &unexp_command = dst.command.source(buff_src, storage);

View File

@ -0,0 +1,36 @@
#RUN: %fish -C 'set -g fish %fish' %s
#REQUIRES: command -v tmux
set fish (builtin realpath $fish)
# Isolated tmux.
set -g tmpdir (mktemp -d)
# Don't CD elsewhere, because tmux socket file is relative to CWD. Using
# absolute path to socket file is prone to 'socket file name too long' error.
cd $tmpdir
set -g tmux tmux -S .tmux-socket -f /dev/null
set -g sleep sleep .1
set -q CI && set sleep sleep 1
$tmux new-session -x 80 -y 10 -d $fish -C '
# This is similar to "tests/interactive.config".
function fish_greeting; end
function fish_prompt; printf "prompt $status_generation> "; end
# No autosuggestion from older history.
set fish_history ""
'
$sleep # Let fish draw a prompt.
# Test moving around with up-or-search on a multi-line commandline.
$tmux send-keys 'echo 12' M-Enter 'echo ab' C-p 345 C-n cde
$sleep
$tmux capture-pane -p
# CHECK: prompt 0> echo 12345
# CHECK: echo abcde
$tmux kill-server
rm -r $tmpdir