Zsh Mailing List Archive
Messages sorted by:
Reverse Date,
Date,
Thread,
Author
PATCH: visual line mode
- X-seq: zsh-workers 33636
- From: Oliver Kiddle <okiddle@xxxxxxxxxxx>
- To: Zsh workers <zsh-workers@xxxxxxx>
- Subject: PATCH: visual line mode
- Date: Fri, 07 Nov 2014 16:48:18 +0100
- Dkim-signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.co.uk; s=s2048; t=1415375299; bh=xm0R/CzdjAxOdNATA4V/4JLUMwVhk+jEuZij0asgyig=; h=From:To:Subject:Date:From:Subject; b=PpDFwPJbwhluFEk8f5pJNvMgVcCQVOzIrT9xi1o6YaEwgfPZ5yeSNQtIenD+XO4jqDJZZxswL0YTS/TX0GeCB3HUaEs1xKVyUWrWLw8FGfc9CQ0svW5pJNZAkRWKMTdHISe4mjYGzrJUU5W3e9OrX13OOfOHtx5cbDCJZh/kgrNO1KS81nVIRTXAD2ouCUC9fqGogZwdgCPoSkLM1AUDbyphWyzXeQ/P58SYx4+/k0TveY6K1xVPZl4PZ6rz/pHp+aP6ktQfwhLbTO9U5LNVfzxGjXfY/2awZSDWJOErDKJIreqWRYXH6oNnoy7lEAnAiEMYTwAzY/swZvKlqDVIrA==
- Domainkey-signature: a=rsa-sha1; q=dns; c=nofws; s=s2048; d=yahoo.co.uk; b=ANL3GsvLKlWMlBA0rmuDpNU6xPYdtVN3ncP+J87S/9JRJwfleC5DkH8bcRS3Ae1OUqSlZx00LceAM7ZEbEtgnXKH05ik3q0ensjoHnGtOZqQa+kyqB6fknhH4LZxfAFyJuIYd08irkdUKbGFVIH0S9GOlwuLcHbCZQtJfi9T6PE13zf/hQ9gOsjnbXjl5uLZy35LhxPG8C33ze8R6ubQrPNutzRs5AGKqPKfsaI26mrpjPq4mnD6lm2UTSwQqLstxuSMhwFhmglHuiKv7cMRVSlpEVKWF1nLdIRNAtWG1jx9xysbylo3G3HjAOfKESy85pk5xaFmDVzJpwcrAW86RA==;
- List-help: <mailto:zsh-workers-help@zsh.org>
- List-id: Zsh Workers List <zsh-workers.zsh.org>
- List-post: <mailto:zsh-workers@zsh.org>
- Mailing-list: contact zsh-workers-help@xxxxxxx; run by ezmlm
This adds a linewise visual mode.
This uses a value of 2 for region_active which is exposed to the shell
function widgets via REGION_ACTIVE.
A visual-line-mode widget is added. We might need another one to just
set region_active to 0 which would be bound to escape in the visual
keymap.
There are also a few widgets: vichangeeol, viindent and viunindent that
should work linewise even for a character-wise selection.
There's an existing old bug with blank lines: dd on a blank line doesn't
work. It works in 3.0.8 but not in 4.2.1.
Oliver
diff --git a/Src/Zle/iwidgets.list b/Src/Zle/iwidgets.list
index f5ff0a4..1dc0c9a 100644
--- a/Src/Zle/iwidgets.list
+++ b/Src/Zle/iwidgets.list
@@ -179,7 +179,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 d1bd5a1..5ee9f5a 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())
@@ -958,15 +990,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 7b6420c..fad6b0a 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 ebc6b49..f0351ad 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 ba13de3..a07ed61 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;
@@ -262,10 +264,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, *
@@ -469,7 +469,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;
}
@@ -727,8 +735,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;
@@ -758,8 +769,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;
Messages sorted by:
Reverse Date,
Date,
Thread,
Author