From 88f4e24d4c42de1072898cd0e26e3d43c7de448c Mon Sep 17 00:00:00 2001 From: Oliver Kiddle Date: Mon, 8 Dec 2014 17:23:23 +0100 Subject: 33924: allow vi line/characterwise mode to be forced --- ChangeLog | 6 ++++++ Doc/Zsh/zle.yo | 8 ++++++-- Src/Zle/iwidgets.list | 2 +- Src/Zle/zle.h | 2 ++ Src/Zle/zle_move.c | 12 ++++++++++++ Src/Zle/zle_vi.c | 13 +++++++++++-- Test/X02zlevi.ztst | 21 +++++++++++++++++++++ 7 files changed, 59 insertions(+), 5 deletions(-) diff --git a/ChangeLog b/ChangeLog index fd6a49f22..b8af2130c 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2014-12-08 Oliver Kiddle + + * 33924: Doc/Zsh/zle.yo, Src/Zle/iwidgets.list, Src/Zle/zle.h, + Src/Zle/zle_move.c, Src/Zle/zle_vi.c, Test/X02zlevi.ztst: + allow vi line/characterwise mode to be forced + 2014-12-08 Peter Stephenson * 33927: Completion/Unix/Command/_nm: .elf files and diff --git a/Doc/Zsh/zle.yo b/Doc/Zsh/zle.yo index 3693ec9d5..f95264232 100644 --- a/Doc/Zsh/zle.yo +++ b/Doc/Zsh/zle.yo @@ -2301,12 +2301,16 @@ If repeated, redo the modification. tindex(visual-mode) item(tt(visual-mode) (unbound) (v) (unbound))( Toggle vim-style visual selection mode. If line-wise visual mode is -currently enabled then it is changed to being character-wise. +currently enabled then it is changed to being character-wise. If used +following an operator, it forces the subsequent movement command to be +treated as a character-wise movement. ) tindex(visual-line-mode) item(tt(visual-line-mode) (unbound) (V) (unbound))( Toggle vim-style line-wise visual selection mode. If character-wise -visual mode is currently enabled then it is changed to being line-wise. +visual mode is currently enabled then it is changed to being line-wise. If used +following an operator, it forces the subsequent movement command to be +treated as a line-wise movement. ) tindex(what-cursor-position) item(tt(what-cursor-position) (^X=) (unbound) (unbound))( diff --git a/Src/Zle/iwidgets.list b/Src/Zle/iwidgets.list index 1a664e5e8..40750221e 100644 --- a/Src/Zle/iwidgets.list +++ b/Src/Zle/iwidgets.list @@ -156,7 +156,7 @@ "vi-forward-word-end", viforwardwordend, 0 "vi-goto-column", vigotocolumn, 0 "vi-goto-mark", vigotomark, 0 -"vi-goto-mark-line", vigotomarkline, 0 +"vi-goto-mark-line", vigotomarkline, ZLE_LINEMOVE "vi-history-search-backward", vihistorysearchbackward, 0 "vi-history-search-forward", vihistorysearchforward, 0 "vi-indent", viindent, ZLE_LASTCOL diff --git a/Src/Zle/zle.h b/Src/Zle/zle.h index 8a85ee342..a46b52ded 100644 --- a/Src/Zle/zle.h +++ b/Src/Zle/zle.h @@ -243,6 +243,8 @@ struct modifier { #define MOD_VIAPP (1<<3) /* appending to the vi cut buffer */ #define MOD_NEG (1<<4) /* last command was negate argument */ #define MOD_NULL (1<<5) /* throw away text for the vi cut buffer */ +#define MOD_CHAR (1<<6) /* force character-wise movement */ +#define MOD_LINE (1<<7) /* force line-wise movement */ /* current modifier status */ diff --git a/Src/Zle/zle_move.c b/Src/Zle/zle_move.c index 939cfb1d0..d751c4333 100644 --- a/Src/Zle/zle_move.c +++ b/Src/Zle/zle_move.c @@ -511,6 +511,12 @@ exchangepointandmark(UNUSED(char **args)) int visualmode(UNUSED(char **args)) { + if (virangeflag) { + prefixflag = 1; + zmod.flags &= ~MOD_LINE; + zmod.flags |= MOD_CHAR; + return 0; + } switch (region_active) { case 1: region_active = 0; @@ -529,6 +535,12 @@ visualmode(UNUSED(char **args)) int visuallinemode(UNUSED(char **args)) { + if (virangeflag) { + prefixflag = 1; + zmod.flags &= ~MOD_CHAR; + zmod.flags |= MOD_LINE; + return 0; + } switch (region_active) { case 2: region_active = 0; diff --git a/Src/Zle/zle_vi.c b/Src/Zle/zle_vi.c index 249e38f15..1a11ca7d5 100644 --- a/Src/Zle/zle_vi.c +++ b/Src/Zle/zle_vi.c @@ -259,15 +259,24 @@ getvirange(int wf) /* Was it a line-oriented move? If so, the command will have set * * the vilinerange flag. In this case, entire lines are taken, * * rather than just the sequence of characters delimited by pos * - * and zlecs. The terminating newline is left out of the range, * + * and zlecs. The terminating newline is left out of the range, * * which the real command must deal with appropriately. At this * * point we just need to make the range encompass entire lines. */ - if(vilinerange) { + vilinerange = (zmod.flags & MOD_LINE) || + (vilinerange && !(zmod.flags & MOD_CHAR)); + if (vilinerange) { int newcs = findbol(); lastcol = zlecs - newcs; zlecs = pos; pos = findeol(); zlecs = newcs; + } else if (!visual) { + /* for a character-wise move don't include a newline at the * + * end of the range */ + int prev = pos; + DECPOS(prev); + if (zleline[prev] == ZWC('\n')) + pos = prev; } return pos; } diff --git a/Test/X02zlevi.ztst b/Test/X02zlevi.ztst index 4f2f3193d..7bb35d52f 100644 --- a/Test/X02zlevi.ztst +++ b/Test/X02zlevi.ztst @@ -287,6 +287,27 @@ >BUFFER: one wo >CURSOR: 2 + zletest $'keepnot\eo unwanted\ekhhcvj ' +0:force character-wise change to join lines +>BUFFER: keep wanted +>CURSOR: 5 + + zletest $'}\eOkeep{del\eF{dvj' +0:character-wise delete to beginning of line leaves the newline' +>BUFFER: keep +>} +>CURSOR: 3 + + zletest $'keep\eOdel\edVh' +0:force line-wise delete of line +>BUFFER: keep +>CURSOR: 0 + + zletest $'one two three\eFwdVawaX' +0:line-wise force of a text object +>BUFFER: X +>CURSOR: 1 + zletest $'one two\evbcx' 0:change selection >BUFFER: one x -- cgit 1.4.1