mirror of
https://github.com/fish-shell/fish-shell.git
synced 2026-06-12 14:51:16 -03:00
Change vi-mode tilde to toggle character case
This updates the behavior of tilde to match the behavior found in vim. In vim, tilde toggles the case of the character under the cursor and advances one character. In visual mode, the case of each selected character is toggled, the cursor position moves to the beginning of the selection, and the mode is changed to normal. In fish, tilde capitalizes the current letter and advances one word. There is no current tilde command for visual mode in fish. This patch adds the readline commands `togglecase-letter` and `togglecase-selection` to match the behavior of vim more closely. The only difference is that in visual mode, the cursor is not modified. Modifying the cursor in visual mode would require either moving it in `togglecase-selection`, which seems outside its scope or adding something like a `move-to-selection-start` readline command.
This commit is contained in:
committed by
Johannes Altmanninger
parent
93b86bbe63
commit
a3dfa21737
@@ -3219,6 +3219,72 @@ void reader_data_t::handle_readline_command(readline_cmd_t c, readline_loop_stat
|
||||
}
|
||||
break;
|
||||
}
|
||||
case rl::togglecase_char: {
|
||||
editable_line_t *el = active_edit_line();
|
||||
size_t buff_pos = el->position();
|
||||
|
||||
// Check that the cursor is on a character
|
||||
if (buff_pos < el->size()) {
|
||||
wchar_t chr = el->text().at(buff_pos);
|
||||
wcstring replacement;
|
||||
|
||||
// Toggle the case of the current character
|
||||
bool make_uppercase = iswlower(chr);
|
||||
if (make_uppercase) {
|
||||
chr = towupper(chr);
|
||||
} else {
|
||||
chr = tolower(chr);
|
||||
}
|
||||
|
||||
replacement.push_back(chr);
|
||||
el->replace_substring(buff_pos, (size_t)1, std::move(replacement));
|
||||
|
||||
// Restore the buffer position since replace_substring moves
|
||||
// the buffer position ahead of the replaced text.
|
||||
update_buff_pos(el, buff_pos);
|
||||
|
||||
command_line_changed(el);
|
||||
super_highlight_me_plenty();
|
||||
reader_repaint_needed();
|
||||
}
|
||||
break;
|
||||
}
|
||||
case rl::togglecase_selection: {
|
||||
editable_line_t *el = active_edit_line();
|
||||
|
||||
// Check that we have an active selection and get the bounds.
|
||||
size_t start, len;
|
||||
if (reader_get_selection(&start, &len)) {
|
||||
size_t buff_pos = el->position();
|
||||
wcstring replacement;
|
||||
|
||||
// Loop through the selected characters and toggle their case.
|
||||
for (size_t pos = start; pos < start + len && pos < el->size(); pos++) {
|
||||
wchar_t chr = el->text().at(pos);
|
||||
|
||||
// Toggle the case of the current character.
|
||||
bool make_uppercase = iswlower(chr);
|
||||
if (make_uppercase) {
|
||||
chr = towupper(chr);
|
||||
} else {
|
||||
chr = tolower(chr);
|
||||
}
|
||||
|
||||
replacement.push_back(chr);
|
||||
}
|
||||
|
||||
el->replace_substring(start, len, std::move(replacement));
|
||||
|
||||
// Restore the buffer position since replace_substring moves
|
||||
// the buffer position ahead of the replaced text.
|
||||
update_buff_pos(el, buff_pos);
|
||||
|
||||
command_line_changed(el);
|
||||
super_highlight_me_plenty();
|
||||
reader_repaint_needed();
|
||||
}
|
||||
break;
|
||||
}
|
||||
case rl::upcase_word:
|
||||
case rl::downcase_word:
|
||||
case rl::capitalize_word: {
|
||||
|
||||
Reference in New Issue
Block a user