mirror of
https://github.com/fish-shell/fish-shell.git
synced 2026-06-30 23:51:15 -03:00
Improve newline behavior of kill-whole-line
Previously, `kill-whole-line` kills the line and its following newline. This is insufficient when we are on the last line, because it would not actually clear the line. The cursor would stay on the line, which is not the correct behavior for bindings like `dd`. Also, `cc` in vi-mode used `kill-whole-line`, which is not correct because it should not remove any newlines. We have to introduce another special input function (`kill-inner-line`) to fix this.
This commit is contained in:
committed by
ridiculousfish
parent
025acfe45a
commit
cf620c829b
@@ -1479,6 +1479,7 @@ static bool command_ends_paging(readline_cmd_t c, bool focused_on_search_field)
|
||||
case rl::yank_pop:
|
||||
case rl::backward_kill_line:
|
||||
case rl::kill_whole_line:
|
||||
case rl::kill_inner_line:
|
||||
case rl::kill_word:
|
||||
case rl::kill_bigword:
|
||||
case rl::backward_kill_word:
|
||||
@@ -3295,9 +3296,10 @@ void reader_data_t::handle_readline_command(readline_cmd_t c, readline_loop_stat
|
||||
kill(el, begin - buff, len, KILL_PREPEND, rls.last_cmd != rl::backward_kill_line);
|
||||
break;
|
||||
}
|
||||
case rl::kill_whole_line: {
|
||||
// We match the emacs behavior here: "kills the entire line including the following
|
||||
// newline".
|
||||
case rl::kill_whole_line: // We match the emacs behavior here: "kills the entire line
|
||||
// including the following newline".
|
||||
case rl::kill_inner_line: // Do not kill the following newline
|
||||
{
|
||||
editable_line_t *el = active_edit_line();
|
||||
const wchar_t *buff = el->text().c_str();
|
||||
|
||||
@@ -3312,16 +3314,27 @@ void reader_data_t::handle_readline_command(readline_cmd_t c, readline_loop_stat
|
||||
|
||||
// Push end forwards to just past the next newline, or just past the last char.
|
||||
size_t end = el->position();
|
||||
while (buff[end] != L'\0') {
|
||||
end++;
|
||||
if (buff[end - 1] == L'\n') {
|
||||
for (;; end++) {
|
||||
if (buff[end] == L'\0') {
|
||||
if (c == rl::kill_whole_line && begin > 0) {
|
||||
// We are on the last line. Delete the newline in the beginning to clear
|
||||
// this line.
|
||||
begin--;
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (buff[end] == L'\n') {
|
||||
if (c == rl::kill_whole_line) {
|
||||
end++;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
assert(end >= begin);
|
||||
|
||||
if (end > begin) {
|
||||
kill(el, begin, end - begin, KILL_APPEND, rls.last_cmd != rl::kill_whole_line);
|
||||
kill(el, begin, end - begin, KILL_APPEND, rls.last_cmd != c);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user