Subject: lib/18103: libedit doesn't get word boundaries right in vi mode
To: None <gnats-bugs@gnats.netbsd.org>
From: None <dsl@l8s.co.uk>
List: netbsd-bugs
Date: 08/29/2002 14:18:25
>Number: 18103
>Category: lib
>Synopsis: libedit doesn't get word boundaries right in vi mode
>Confidential: no
>Severity: non-critical
>Priority: low
>Responsible: lib-bug-people
>State: open
>Class: sw-bug
>Submitter-Id: net
>Arrival-Date: Thu Aug 29 06:16:00 PDT 2002
>Closed-Date:
>Last-Modified:
>Originator: David Laight
>Release: NetBSD 1.6F
>Organization:
no
>Environment:
System: NetBSD snowdrop 1.6F NetBSD 1.6F (GENERIC) #161: Tue Aug 27 10:39:43 BST 2002
dsl@snowdrop:/oldroot/usr/bsd-current/src/sys/arch/i386/compile/GENERIC i386
Architecture: i386
Machine: i386
>Description:
libedit (used for command editing in sh) doesn't get the following
right:
1) c2w - miscounts words
2) E - treated as e
3) c2b - count ignored
>How-To-Repeat:
Play with sh after 'set -o vi'
>Fix:
Apply following changes
Index: chared.c
===================================================================
RCS file: /cvsroot/basesrc/lib/libedit/chared.c,v
retrieving revision 1.15
diff -u -r1.15 chared.c
--- chared.c 2002/03/18 16:00:50 1.15
+++ chared.c 2002/08/29 13:09:46
@@ -221,7 +221,7 @@
* vi historically deletes with cw only the word preserving the
* trailing whitespace! This is not what 'w' does..
*/
- if (el->el_chared.c_vcmd.action != (DELETE|INSERT))
+ if (n || el->el_chared.c_vcmd.action != (DELETE|INSERT))
while ((p < high) && isspace((unsigned char) *p))
p++;
}
@@ -238,26 +238,19 @@
* Find the previous word vi style
*/
protected char *
-cv_prev_word(EditLine *el, char *p, char *low, int n, int (*wtest)(int))
+cv_prev_word(char *p, char *low, int n, int (*wtest)(int))
{
int test;
+ p--;
while (n--) {
- p--;
- /*
- * vi historically deletes with cb only the word preserving the
- * leading whitespace! This is not what 'b' does..
- */
- if (el->el_chared.c_vcmd.action != (DELETE|INSERT))
- while ((p > low) && isspace((unsigned char) *p))
- p--;
+ while ((p > low) && isspace((unsigned char) *p))
+ p--;
test = (*wtest)((unsigned char) *p);
while ((p >= low) && (*wtest)((unsigned char) *p) == test)
p--;
- p++;
- while (isspace((unsigned char) *p))
- p++;
}
+ p++;
/* p now points where we want it */
if (p < low)
@@ -378,21 +371,19 @@
* Go to the end of this word according to vi
*/
protected char *
-cv__endword(char *p, char *high, int n)
+cv__endword(char *p, char *high, int n, int (*wtest)(int))
{
+ int test;
+
p++;
while (n--) {
while ((p < high) && isspace((unsigned char) *p))
p++;
- if (isalnum((unsigned char) *p))
- while ((p < high) && isalnum((unsigned char) *p))
- p++;
- else
- while ((p < high) && !(isspace((unsigned char) *p) ||
- isalnum((unsigned char) *p)))
- p++;
+ test = (*wtest)((unsigned char) *p);
+ while ((p < high) && (*wtest)((unsigned char) *p) == test)
+ p++;
}
p--;
return (p);
Index: chared.h
===================================================================
RCS file: /cvsroot/basesrc/lib/libedit/chared.h,v
retrieving revision 1.8
diff -u -r1.8 chared.h
--- chared.h 2002/03/18 16:00:51 1.8
+++ chared.h 2002/08/29 13:09:47
@@ -138,11 +138,11 @@
protected int cv__isword(int);
protected void cv_delfini(EditLine *);
-protected char *cv__endword(char *, char *, int);
+protected char *cv__endword(char *, char *, int, int (*)(int));
protected int ce__isword(int);
protected void cv_undo(EditLine *, int, size_t, char *);
protected char *cv_next_word(EditLine*, char *, char *, int, int (*)(int));
-protected char *cv_prev_word(EditLine*, char *, char *, int, int (*)(int));
+protected char *cv_prev_word(char *, char *, int, int (*)(int));
protected char *c__next_word(char *, char *, int, int (*)(int));
protected char *c__prev_word(char *, char *, int, int (*)(int));
protected void c_insert(EditLine *, int);
Index: vi.c
===================================================================
RCS file: /cvsroot/basesrc/lib/libedit/vi.c,v
retrieving revision 1.9
diff -u -r1.9 vi.c
--- vi.c 2002/03/18 16:01:01 1.9
+++ vi.c 2002/08/29 13:09:49
@@ -170,7 +170,7 @@
if (el->el_line.cursor == el->el_line.buffer)
return (CC_ERROR);
- el->el_line.cursor = cv_prev_word(el, el->el_line.cursor,
+ el->el_line.cursor = cv_prev_word(el->el_line.cursor,
el->el_line.buffer,
el->el_state.argument,
cv__isword);
@@ -185,7 +185,7 @@
/* vi_prev_word():
* Vi move to the previous word
- * [B]
+ * [b]
*/
protected el_action_t
/*ARGSUSED*/
@@ -195,7 +195,7 @@
if (el->el_line.cursor == el->el_line.buffer)
return (CC_ERROR);
- el->el_line.cursor = cv_prev_word(el, el->el_line.cursor,
+ el->el_line.cursor = cv_prev_word(el->el_line.cursor,
el->el_line.buffer,
el->el_state.argument,
ce__isword);
@@ -495,7 +495,7 @@
return (CC_ERROR);
el->el_line.cursor = cv__endword(el->el_line.cursor,
- el->el_line.lastchar, el->el_state.argument);
+ el->el_line.lastchar, el->el_state.argument, ce__isword);
if (el->el_chared.c_vcmd.action & DELETE) {
el->el_line.cursor++;
@@ -519,7 +519,7 @@
return (CC_ERROR);
el->el_line.cursor = cv__endword(el->el_line.cursor,
- el->el_line.lastchar, el->el_state.argument);
+ el->el_line.lastchar, el->el_state.argument, cv__isword);
if (el->el_chared.c_vcmd.action & DELETE) {
el->el_line.cursor++;
>Release-Note:
>Audit-Trail:
>Unformatted: