summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorOliver Kiddle <opk@zsh.org>2014-11-17 22:50:34 +0100
committerOliver Kiddle <opk@zsh.org>2014-11-17 22:50:34 +0100
commit36878852efc1673aba445e7affe9c5c554c343d5 (patch)
tree729c1b26eaa97aa717729956ad40eef4fc976474
parent492b6cec28d70eb4ef34054f414dd1e80102e857 (diff)
downloadzsh-36878852efc1673aba445e7affe9c5c554c343d5.tar.gz
zsh-36878852efc1673aba445e7affe9c5c554c343d5.zip
33636: add support for a linewise visual selection mode
-rw-r--r--ChangeLog4
-rw-r--r--Src/Zle/iwidgets.list3
-rw-r--r--Src/Zle/zle_misc.c45
-rw-r--r--Src/Zle/zle_move.c19
-rw-r--r--Src/Zle/zle_refresh.c8
-rw-r--r--Src/Zle/zle_vi.c28
6 files changed, 96 insertions, 11 deletions
diff --git a/ChangeLog b/ChangeLog
index 7391f300c..e181b3852 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,9 @@
2014-11-17 Oliver Kiddle <opk@zsh.org>
+ * 33636: Src/Zle/iwidgets.list, Src/Zle/zle_misc.c,
+ Src/Zle/zle_move.c, Src/Zle/zle_refresh.c, Src/Zle/zle_vi.c:
+ add support for a linewise visual selection mode
+
* 33635: Src/Zle/iwidgets.list, Src/Zle/zle_misc.c,
Src/Zle/zle_move.c, Src/Zle/zle_refresh.c, Src/Zle/zle_vi.c:
adapt region to function as vim style visual selection mode
diff --git a/Src/Zle/iwidgets.list b/Src/Zle/iwidgets.list
index 23e5783f9..26182974a 100644
--- a/Src/Zle/iwidgets.list
+++ b/Src/Zle/iwidgets.list
@@ -184,7 +184,8 @@
"vi-yank", viyank, ZLE_LASTCOL
"vi-yank-eol", viyankeol, 0
"vi-yank-whole-line", viyankwholeline, 0
-"visual-mode", visualmode, ZLE_MENUCMP | ZLE_KEEPSUFFIX | ZLE_LASTCOL
+"visual-line-mode", visuallinemode, ZLE_MENUCMP | ZLE_LASTCOL
+"visual-mode", visualmode, ZLE_MENUCMP | ZLE_LASTCOL
"what-cursor-position", whatcursorposition, ZLE_MENUCMP | ZLE_KEEPSUFFIX | ZLE_LASTCOL
"where-is", whereis, ZLE_MENUCMP | ZLE_KEEPSUFFIX | ZLE_LASTCOL
"which-command", processcmd, ZLE_MENUCMP | ZLE_KEEPSUFFIX | ZLE_LASTCOL
diff --git a/Src/Zle/zle_misc.c b/Src/Zle/zle_misc.c
index 5996c485d..a220a6bc8 100644
--- a/Src/Zle/zle_misc.c
+++ b/Src/Zle/zle_misc.c
@@ -440,12 +440,44 @@ killline(char **args)
}
/**/
+void
+regionlines(int *start, int *end)
+{
+ int origcs = zlecs;
+
+ UNMETACHECK();
+ if (zlecs < mark) {
+ *start = findbol();
+ zlecs = (mark > zlell) ? zlell : mark;
+ *end = findeol();
+ } else {
+ *end = findeol();
+ zlecs = mark;
+ *start = findbol();
+ }
+ zlecs = origcs;
+}
+
+/**/
int
killregion(UNUSED(char **args))
{
if (mark > zlell)
mark = zlell;
- if (mark > zlecs)
+ if (region_active == 2) {
+ int a, b;
+ regionlines(&a, &b);
+ zlecs = a;
+ region_active = 0;
+ cut(zlecs, b - zlecs, CUT_RAW);
+ shiftchars(zlecs, b - zlecs);
+ if (zlell) {
+ if (zlecs == zlell)
+ DECCS();
+ foredel(1, 0);
+ vifirstnonblank(zlenoargs);
+ }
+ } else if (mark > zlecs)
forekill(mark - zlecs + invicmdmode(), CUT_RAW);
else {
if (invicmdmode())
@@ -1011,15 +1043,22 @@ quoteregion(UNUSED(char **args))
{
ZLE_STRING_T str;
size_t len;
+ int extra = invicmdmode();
if (mark > zlell)
mark = zlell;
- if (mark < zlecs) {
+ if (region_active == 2) {
+ int a, b;
+ regionlines(&a, &b);
+ zlecs = a;
+ mark = b;
+ extra = 0;
+ } else if (mark < zlecs) {
int tmp = mark;
mark = zlecs;
zlecs = tmp;
}
- str = (ZLE_STRING_T)hcalloc((len = mark - zlecs + invicmdmode()) *
+ str = (ZLE_STRING_T)hcalloc((len = mark - zlecs + extra) *
ZLE_CHAR_SIZE);
ZS_memcpy(str, zleline + zlecs, len);
foredel(len, CUT_RAW);
diff --git a/Src/Zle/zle_move.c b/Src/Zle/zle_move.c
index 7b6420c06..fad6b0a5f 100644
--- a/Src/Zle/zle_move.c
+++ b/Src/Zle/zle_move.c
@@ -527,6 +527,25 @@ visualmode(UNUSED(char **args))
/**/
int
+visuallinemode(UNUSED(char **args))
+{
+ switch (region_active) {
+ case 2:
+ region_active = 0;
+ break;
+ case 0:
+ mark = zlecs;
+ /* fall through */
+ case 1:
+ region_active = 2;
+ break;
+ }
+ return 0;
+}
+
+
+/**/
+int
vigotocolumn(UNUSED(char **args))
{
int x, y, n = zmult;
diff --git a/Src/Zle/zle_refresh.c b/Src/Zle/zle_refresh.c
index ebc6b494c..f0351ad15 100644
--- a/Src/Zle/zle_refresh.c
+++ b/Src/Zle/zle_refresh.c
@@ -1039,6 +1039,14 @@ zrefresh(void)
}
if (invicmdmode())
INCPOS(region_highlights[0].end);
+ if (region_active == 2) {
+ int origcs = zlecs;
+ zlecs = region_highlights[0].end;
+ region_highlights[0].end = findeol();
+ zlecs = region_highlights[0].start;
+ region_highlights[0].start = findbol();
+ zlecs = origcs;
+ }
} else {
region_highlights[0].start = region_highlights[0].end = -1;
}
diff --git a/Src/Zle/zle_vi.c b/Src/Zle/zle_vi.c
index 02877deee..3a4304ced 100644
--- a/Src/Zle/zle_vi.c
+++ b/Src/Zle/zle_vi.c
@@ -162,12 +162,14 @@ static int
getvirange(int wf)
{
int pos = zlecs, mpos = mark, ret = 0;
- int visual = region_active; /* don't trust movement cmd not to change it */
+ int visual = region_active; /* movement command might set it */
int mult1 = zmult, hist1 = histline;
Thingy k2;
if (visual) {
pos = mark;
+ vilinerange = (visual == 2);
+ region_active = 0;
} else {
virangeflag = 1;
@@ -256,10 +258,8 @@ getvirange(int wf)
pos = tmp;
}
- if (visual && invicmdmode()) {
- region_active = 0;
+ if (visual && invicmdmode())
INCPOS(pos);
- }
/* Was it a line-oriented move? If so, the command will have set *
* the vilinerange flag. In this case, entire lines are taken, *
@@ -463,7 +463,15 @@ visubstitute(UNUSED(char **args))
int
vichangeeol(UNUSED(char **args))
{
- forekill(findeol() - zlecs, CUT_RAW);
+ int a, b;
+ if (region_active) {
+ regionlines(&a, &b);
+ zlecs = a;
+ region_active = 0;
+ cut(zlecs, b - zlecs, CUT_RAW);
+ shiftchars(zlecs, b - zlecs);
+ } else
+ forekill(findeol() - zlecs, CUT_RAW);
startvitext(1);
return 0;
}
@@ -721,8 +729,11 @@ viindent(UNUSED(char **args))
{
int oldcs = zlecs, c2;
- /* get the range */
startvichange(1);
+ /* force line range */
+ if (region_active == 1)
+ region_active = 2;
+ /* get the range */
if ((c2 = getvirange(0)) == -1) {
vichgflag = 0;
return 1;
@@ -756,8 +767,11 @@ viunindent(UNUSED(char **args))
{
int oldcs = zlecs, c2;
- /* get the range */
startvichange(1);
+ /* force line range */
+ if (region_active == 1)
+ region_active = 2;
+ /* get the range */
if ((c2 = getvirange(0)) == -1) {
vichgflag = 0;
return 1;