mirror of
https://github.com/neovim/neovim.git
synced 2025-09-15 07:48:18 +00:00
ex_getln: Fixes for some problems with getexmodeline()
Problems with line-input editing commands in Ex mode ('nvim -e' or 'Q' in normal mode): CTRL_U: Only after the next keystroke the complete line change is shown if the indentation was not 0. : asdfCTRL_U CTRL_T: Memory reallocation with ga_grows() before a memmove(), but pointers into the memory are not updated. :set sw=40 :CTRL_T ... Should complain about a memory error. CTRL_D: Trying to reduce an indentation of 0. :set sw=1 :CTRL_D Segfault Helped-by: Scott Prager <splinterofchaos@gmail.com>
This commit is contained in:

committed by
Justin M. Keyes

parent
e692930af2
commit
2493b6fefc
@@ -1781,24 +1781,29 @@ getexmodeline (
|
|||||||
msg_col = startcol;
|
msg_col = startcol;
|
||||||
msg_clr_eos();
|
msg_clr_eos();
|
||||||
line_ga.ga_len = 0;
|
line_ga.ga_len = 0;
|
||||||
continue;
|
goto redraw;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int num_spaces;
|
||||||
if (c1 == Ctrl_T) {
|
if (c1 == Ctrl_T) {
|
||||||
int sw = get_sw_value(curbuf);
|
int sw = get_sw_value(curbuf);
|
||||||
|
|
||||||
p = (char_u *)line_ga.ga_data;
|
p = (char_u *)line_ga.ga_data;
|
||||||
p[line_ga.ga_len] = NUL;
|
p[line_ga.ga_len] = NUL;
|
||||||
indent = get_indent_str(p, 8, FALSE);
|
indent = get_indent_str(p, 8, FALSE);
|
||||||
indent += sw - indent % sw;
|
num_spaces = sw - indent % sw;
|
||||||
|
indent += num_spaces;
|
||||||
add_indent:
|
add_indent:
|
||||||
while (get_indent_str(p, 8, FALSE) < indent) {
|
if (num_spaces > 0) {
|
||||||
|
ga_grow(&line_ga, num_spaces + 1);
|
||||||
|
p = (char_u *)line_ga.ga_data;
|
||||||
char_u *s = skipwhite(p);
|
char_u *s = skipwhite(p);
|
||||||
|
|
||||||
ga_grow(&line_ga, 1);
|
// Insert spaces after leading whitespaces.
|
||||||
memmove(s + 1, s, line_ga.ga_len - (s - p) + 1);
|
memmove(s + num_spaces, s, line_ga.ga_len - (s - p) + 1);
|
||||||
*s = ' ';
|
memset(s, ' ', num_spaces);
|
||||||
++line_ga.ga_len;
|
|
||||||
|
line_ga.ga_len += num_spaces;
|
||||||
}
|
}
|
||||||
redraw:
|
redraw:
|
||||||
/* redraw the line */
|
/* redraw the line */
|
||||||
@@ -1835,15 +1840,25 @@ redraw:
|
|||||||
} else {
|
} else {
|
||||||
p[line_ga.ga_len] = NUL;
|
p[line_ga.ga_len] = NUL;
|
||||||
indent = get_indent_str(p, 8, FALSE);
|
indent = get_indent_str(p, 8, FALSE);
|
||||||
|
if (indent == 0) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
--indent;
|
--indent;
|
||||||
indent -= indent % get_sw_value(curbuf);
|
indent -= indent % get_sw_value(curbuf);
|
||||||
}
|
}
|
||||||
while (get_indent_str(p, 8, FALSE) > indent) {
|
|
||||||
char_u *s = skipwhite(p);
|
|
||||||
|
|
||||||
memmove(s - 1, s, line_ga.ga_len - (s - p) + 1);
|
// reduce the line's indentation
|
||||||
--line_ga.ga_len;
|
char_u *from = skipwhite(p);
|
||||||
|
char_u *to = from;
|
||||||
|
int old_indent;
|
||||||
|
while ((old_indent = get_indent_str(p, 8, FALSE)) > indent) {
|
||||||
|
*--to = NUL;
|
||||||
}
|
}
|
||||||
|
memmove(to, from, line_ga.ga_len - (from - p) + 1);
|
||||||
|
line_ga.ga_len -= from - to;
|
||||||
|
|
||||||
|
// Removed to much indentation, fix it before redrawing.
|
||||||
|
num_spaces = indent - old_indent;
|
||||||
goto add_indent;
|
goto add_indent;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user