[prev in list] [next in list] [prev in thread] [next in thread]
List: busybox
Subject: Re: [PATCH 2/2] vi: handle autoindent in 'cc' command
From: Denys Vlasenko <vda.linux () googlemail ! com>
Date: 2022-06-26 17:56:17
Message-ID: CAK1hOcPXWqY1EqXm0g=nmookKwErbhFdJQp8Qa5iUf0NjAkK9w () mail ! gmail ! com
[Download RAW message or body]
Applied both, thanks
On Fri, Mar 18, 2022 at 12:31 PM Ron Yorston <rmy@pobox.com> wrote:
>
> When the 'cc' command is invoked with autoindent enabled it
> should use the indent of the first line being changed.
>
> The size of the indent has to be established before char_insert()
> is called as the lines being changed are deleted. Introduce a
> new global variable, newindent, to handle this. The indentcol
> global is now effectively a static variable in char_insert().
>
> function old new delta
> do_cmd 4247 4308 +61
> vi_main 416 422 +6
> char_insert 891 875 -16
> ------------------------------------------------------------------------------
> (add/remove: 0/0 grow/shrink: 2/1 up/down: 67/-16) Total: 51 bytes
>
> Signed-off-by: Ron Yorston <rmy@pobox.com>
> ---
> editors/vi.c | 71 ++++++++++++++++++++++++++++++++++------------------
> 1 file changed, 47 insertions(+), 24 deletions(-)
>
> diff --git a/editors/vi.c b/editors/vi.c
> index e63ca60d4..6edff0b5a 100644
> --- a/editors/vi.c
> +++ b/editors/vi.c
> @@ -380,7 +380,9 @@ struct globals {
> char *last_search_pattern; // last pattern from a '/' or '?' search
> #endif
> #if ENABLE_FEATURE_VI_SETOPTS
> - int indentcol; // column of recently autoindent, 0 or -1
> + int char_insert__indentcol; // column of recent autoindent or 0
> + int newindent; // autoindent value for 'O'/'cc' commands
> + // or -1 to use indent from previous line
> #endif
> smallint cmd_error;
>
> @@ -507,7 +509,8 @@ struct globals {
> #define ioq_start (G.ioq_start )
> #define dotcnt (G.dotcnt )
> #define last_search_pattern (G.last_search_pattern)
> -#define indentcol (G.indentcol )
> +#define char_insert__indentcol (G.char_insert__indentcol)
> +#define newindent (G.newindent )
> #define cmd_error (G.cmd_error )
>
> #define edit_file__cur_line (G.edit_file__cur_line)
> @@ -540,10 +543,11 @@ struct globals {
>
> #define INIT_G() do { \
> SET_PTR_TO_GLOBALS(xzalloc(sizeof(G))); \
> - last_modified_count = -1; \
> + last_modified_count--; \
> /* "" but has space for 2 chars: */ \
> IF_FEATURE_VI_SEARCH(last_search_pattern = xzalloc(2);) \
> tabstop = 8; \
> + IF_FEATURE_VI_SETOPTS(newindent--;) \
> } while (0)
>
> #if ENABLE_FEATURE_VI_CRASHME
> @@ -2112,6 +2116,7 @@ static size_t indent_len(char *p)
> static char *char_insert(char *p, char c, int undo) // insert the char c at 'p'
> {
> #if ENABLE_FEATURE_VI_SETOPTS
> +# define indentcol char_insert__indentcol
> size_t len;
> int col, ntab, nspc;
> #endif
> @@ -2140,7 +2145,8 @@ static char *char_insert(char *p, char c, int undo) // insert the char c at 'p'
> #if ENABLE_FEATURE_VI_SETOPTS
> if (autoindent) {
> len = indent_len(bol);
> - if (len && get_column(bol + len) == indentcol && bol[len] == '\n') {
> + col = get_column(bol + len);
> + if (len && col == indentcol && bol[len] == '\n') {
> // remove autoindent from otherwise empty line
> text_hole_delete(bol, bol + len - 1, undo);
> p = bol;
> @@ -2209,26 +2215,30 @@ static char *char_insert(char *p, char c, int undo) // insert the char c at 'p'
> showmatching(p - 1);
> }
> if (autoindent && c == '\n') { // auto indent the new line
> - // use indent of current/previous line
> - bol = indentcol < 0 ? p : prev_line(p);
> - len = indent_len(bol);
> - col = get_column(bol + len);
> -
> - if (len && col == indentcol) {
> - // previous line was empty except for autoindent
> - // move the indent to the current line
> - memmove(bol + 1, bol, len);
> - *bol = '\n';
> - return p;
> + if (newindent < 0) {
> + // use indent of previous line
> + bol = prev_line(p);
> + len = indent_len(bol);
> + col = get_column(bol + len);
> +
> + if (len && col == indentcol) {
> + // previous line was empty except for autoindent
> + // move the indent to the current line
> + memmove(bol + 1, bol, len);
> + *bol = '\n';
> + return p;
> + }
> + } else {
> + // for 'O'/'cc' commands add indent before newly inserted NL
> + if (p != end - 1) // but not for 'cc' at EOF
> + p--;
> + col = newindent;
> }
>
> - if (indentcol < 0)
> - p--; // open above, indent before newly inserted NL
> -
> - if (len) {
> + if (col) {
> // only record indent if in insert/replace mode or for
> - // the 'o'/'O' commands, which are switched to insert
> - // mode early.
> + // the 'o'/'O'/'cc' commands, which are switched to
> + // insert mode early.
> indentcol = cmd_mode != 0 ? col : 0;
> if (expandtab) {
> ntab = 0;
> @@ -2251,6 +2261,7 @@ static char *char_insert(char *p, char c, int undo) // insert the char c at 'p'
> }
> #if ENABLE_FEATURE_VI_SETOPTS
> indentcol = 0;
> +# undef indentcol
> #endif
> return p;
> }
> @@ -4219,6 +4230,9 @@ static void do_cmd(int c)
> case 'i': // i- insert before current char
> case KEYCODE_INSERT: // Cursor Key Insert
> dc_i:
> +#if ENABLE_FEATURE_VI_SETOPTS
> + newindent = -1;
> +#endif
> cmd_mode = 1; // start inserting
> undo_queue_commit(); // commit queue when cmd_mode changes
> break;
> @@ -4261,7 +4275,8 @@ static void do_cmd(int c)
> case 'O': // O- open an empty line above
> dot_begin();
> #if ENABLE_FEATURE_VI_SETOPTS
> - indentcol = -1;
> + // special case: use indent of current line
> + newindent = get_column(dot + indent_len(dot));
> #endif
> goto dc3;
> case 'o': // o- open an empty line below
> @@ -4384,14 +4399,22 @@ static void do_cmd(int c)
> if (buftype == WHOLE) {
> save_dot = p; // final cursor position is start of range
> p = begin_line(p);
> +#if ENABLE_FEATURE_VI_SETOPTS
> + if (c == 'c') // special case: use indent of current line
> + newindent = get_column(p + indent_len(p));
> +#endif
> q = end_line(q);
> }
> dot = yank_delete(p, q, buftype, yf, ALLOW_UNDO); // delete word
> if (buftype == WHOLE) {
> if (c == 'c') {
> +#if ENABLE_FEATURE_VI_SETOPTS
> + cmd_mode = 1; // switch to insert mode early
> +#endif
> dot = char_insert(dot, '\n', ALLOW_UNDO_CHAIN);
> - // on the last line of file don't move to prev line
> - if (dot != (end-1)) {
> + // on the last line of file don't move to prev line,
> + // handled in char_insert() if autoindent is enabled
> + if (dot != (end-1) && !autoindent) {
> dot_prev();
> }
> } else if (c == 'd') {
> --
> 2.35.1
>
> _______________________________________________
> busybox mailing list
> busybox@busybox.net
> http://lists.busybox.net/mailman/listinfo/busybox
_______________________________________________
busybox mailing list
busybox@busybox.net
http://lists.busybox.net/mailman/listinfo/busybox
[prev in list] [next in list] [prev in thread] [next in thread]
Configure |
About |
News |
Add a list |
Sponsored by KoreLogic