shithub: acme

Download patch

ref: e446d1aeea9bfd1f084ab5c7d6186b7dd4a3ceca
parent: db0b5711977ddcc2d5460479d4526a6d726fabdf
author: demyxology <spicycoldnoodles@gmail.com>
date: Sun Jan 19 16:09:58 EST 2025

Porting reverse search from p9p, doesnt work yet. shift+click not registering

--- a/acme.c
+++ b/acme.c
@@ -438,6 +438,7 @@
 	Mouse m;
 	char *act;
 	enum { MResize, MMouse, MPlumb, MWarnings, NMALT };
+	enum { Shift = 5 };
 	static Alt alts[NMALT+1];
 
 	threadsetname("mousethread");
@@ -560,6 +561,7 @@
 					wincommit(w, t);
 				else
 					textcommit(t, TRUE);
+				print("Got button %d\n", m.buttons);
 				if(m.buttons & 1){
 					textselect(t);
 					if(w)
@@ -573,9 +575,9 @@
 				}else if(m.buttons & 2){
 					if(textselect2(t, &q0, &q1, &argt))
 						execute(t, q0, q1, FALSE, argt);
-				}else if(m.buttons & 4){
+				}else if(m.buttons & (4|(4<<Shift))){
 					if(textselect3(t, &q0, &q1))
-						look3(t, q0, q1, FALSE);
+						look3(t, q0, q1, FALSE, (m.buttons&(4<<Shift))!=0);
 				}
 				if(w)
 					winunlock(w);
@@ -681,7 +683,7 @@
 					pids = p;
 				}
 			}else{
-				if(search(t, c->name, c->nname)){
+				if(search(t, c->name, c->nname, FALSE)){
 					textdelete(t, t->q0, t->q1, TRUE);
 					textsetselect(t, 0, 0);
 				}
--- a/addr.c
+++ b/addr.c
@@ -168,7 +168,7 @@
 }
 
 Range
-address(Mntdir *md, Text *t, Range lim, Range ar, void *a, uint q0, uint q1, int (*getc)(void*, uint),  int *evalp, uint *qp)
+address(Mntdir *md, Text *t, Range lim, Range ar, void *a, uint q0, uint q1, int (*getc)(void*, uint),  int *evalp, uint *qp, int reverse)
 {
 	int dir, size, npat;
 	int prevc, c, nc, n;
@@ -179,6 +179,8 @@
 	r = ar;
 	q = q0;
 	dir = None;
+	if(reverse)
+		dir = Back;
 	size = Line;
 	c = 0;
 	while(q < q1){
@@ -197,7 +199,7 @@
 			if(q>=q1 && t!=nil && t->file!=nil)	/* rhs defaults to $ */
 				r.q1 = t->file->nc;
 			else{
-				nr = address(md, t, lim, ar, a, q, q1, getc, evalp, &q);
+				nr = address(md, t, lim, ar, a, q, q1, getc, evalp, &q, FALSE);
 				r.q1 = nr.q1;
 			}
 			*qp = q;
--- a/dat.h
+++ b/dat.h
@@ -459,6 +459,7 @@
 	int	nname;
 	char	*bname;
 	int	jump;
+	int reverse;
 	union{
 		Text	*at;
 		Rune	*ar;
--- a/exec.c
+++ b/exec.c
@@ -275,6 +275,7 @@
 	Expand e;
 	char *a;
 
+    memset(&e, 0, sizeof e);
 	*rp = nil;
 	*nrp = 0;
 	if(argt == nil)
@@ -281,7 +282,7 @@
 		return nil;
 	a = nil;
 	textcommit(argt, TRUE);
-	if(expand(argt, argt->q0, argt->q1, &e)){
+	if(expand(argt, argt->q0, argt->q1, &e, FALSE)){
 		free(e.bname);
 		if(e.nname && dofile){
 			e.name = runerealloc(e.name, e.nname+1);
@@ -906,7 +907,7 @@
 	if(et && et->w){
 		t = &et->w->body;
 		if(narg > 0){
-			search(t, arg, narg);
+			search(t, arg, narg, FALSE);
 			return;
 		}
 		getarg(argt, FALSE, FALSE, &r, &n);
@@ -915,7 +916,7 @@
 			r = runemalloc(n);
 			bufread(t->file, t->q0, r, n);
 		}
-		search(t, r, n);
+		search(t, r, n, FALSE);
 		free(r);
 	}
 }
--- a/fns.h
+++ b/fns.h
@@ -57,8 +57,8 @@
 int	isspace(Rune);
 int	isalnum(Rune);
 void	execute(Text*, uint, uint, int, Text*);
-int	search(Text*, Rune*, uint);
-void	look3(Text*, uint, uint, int);
+int	search(Text*, Rune*, uint, int);
+void	look3(Text*, uint, uint, int, int);
 void	editcmd(Text*, Rune*, uint);
 uint	min(uint, uint);
 uint	max(uint, uint);
@@ -79,11 +79,11 @@
 void *emalloc(uint);
 void *erealloc(void*, uint);
 char	*estrdup(char*);
-Range		address(Mntdir*, Text*, Range, Range, void*, uint, uint, int (*)(void*, uint),  int*, uint*);
+Range		address(Mntdir*, Text*, Range, Range, void*, uint, uint, int (*)(void*, uint),  int*, uint*, int);
 int		rxexecute(Text*, Rune*, uint, uint, Rangeset*);
 int		rxbexecute(Text*, uint, Rangeset*);
 Window*	makenewwindow(Text *t);
-int	expand(Text*, uint, uint, Expand*);
+int	expand(Text*, uint, uint, Expand*, int);
 Rune*	skipbl(Rune*, int, int*);
 Rune*	findbl(Rune*, int, int*);
 char*	edittext(Window*, int, Rune*, int);
--- a/look.c
+++ b/look.c
@@ -16,7 +16,7 @@
 int	nuntitled;
 
 void
-look3(Text *t, uint q0, uint q1, int external)
+look3(Text *t, uint q0, uint q1, int external, int reverse)
 {
 	int n, c, f, expanded;
 	Text *ct;
@@ -30,7 +30,7 @@
 	ct = seltext;
 	if(ct == nil)
 		seltext = t;
-	expanded = expand(t, q0, q1, &e);
+	expanded = expand(t, q0, q1, &e, reverse);
 	if(!external && t->w!=nil && t->w->nopen[QWevent]>0){
 		/* send alphanumeric expansion to external client */
 		if(expanded == FALSE)
@@ -45,6 +45,8 @@
 		c = 'l';
 		if(t->what == Body)
 			c = 'L';
+		if(reverse)
+			c += 'R' - 'L';
 		n = q1-q0;
 		if(n <= EVENTSIZE){
 			r = runemalloc(n);
@@ -139,12 +141,17 @@
 		ct = &t->w->body;
 		if(t->w != ct->w)
 			winlock(ct->w, 'M');
-		if(t == ct)
-			textsetselect(ct, e.q1, e.q1);
+		if(t == ct) {
+			uint q;
+			q = e.q1;
+			if(reverse)
+				q = e.q0;
+			textsetselect(ct, q, q);
+		}
 		n = e.q1 - e.q0;
 		r = runemalloc(n);
 		bufread(t->file, e.q0, r, n);
-		if(search(ct, r, n) && e.jump)
+		if(search(ct, r, n, reverse) && e.jump)
 			moveto(mousectl, addpt(frptofchar(ct, ct->p0), Pt(4, ct->font->height-4)));
 		if(t->w != ct->w)
 			winunlock(ct->w);
@@ -177,6 +184,7 @@
 		warning(nil, "insanely long file name (%d bytes) in plumb message (%.32s...)\n", m->ndata, m->data);
 		return;
 	}
+	memset(&e, 0, sizeof e);
 	e.q0 = 0;
 	e.q1 = 0;
 	if(m->data[0] == '\0')
@@ -237,11 +245,11 @@
 }
 
 int
-search(Text *ct, Rune *r, uint n)
+search(Text *ct, Rune *r, uint n, int reverse)
 {
-	uint q, nb, maxn;
+	uint nb, maxn;
 	int around;
-	Rune *s, *b, *c;
+	Rune *s, *b;
 
 	if(n==0 || n>ct->file->nc)
 		return FALSE;
@@ -255,55 +263,111 @@
 	nb = 0;
 	b[nb] = 0;
 	around = 0;
-	q = ct->q1;
-	for(;;){
-		if(q >= ct->file->nc){
-			q = 0;
-			around = 1;
-			nb = 0;
-			b[nb] = 0;
-		}
-		if(nb > 0){
-			c = runestrchr(b, r[0]);
-			if(c == nil){
-				q += nb;
+	if(reverse){
+		uint q1;
+		q1 = ct->q0; // q1 is (past) end of text being searched.
+		for(;;){
+			if(q1 <= 0){
+				q1 = ct->file->nc;
+				around = 1;
 				nb = 0;
 				b[nb] = 0;
-				if(around && q>=ct->q1)
-					break;
-				continue;
 			}
-			q += (c-b);
-			nb -= (c-b);
-			b = c;
+			if(nb > 0){
+				Rune *c;
+				for(c=b+nb; c>b; c--)
+					if(c[-1] == r[n-1])
+						break;
+				if(c == b) {
+					q1 -= nb;
+					nb = 0;
+					b[nb] = 0;
+					if(around && q1 <= 0)
+						break;
+					continue;
+				}
+				q1 -= nb - (c - b);
+				nb = c - b;
+			}
+			/* reload if buffer covers neither string nor beginning of file */
+			if(nb<n && nb!=q1){
+				nb = q1;
+				if(nb >= maxn)
+					nb = maxn-1;
+				bufread(ct->file, q1-nb, s, nb);
+				b = s;
+				b[nb] = '\0';
+			}
+			if(runeeq(b+nb-n, n, r, n)==TRUE){
+				if(ct->w){
+					textshow(ct, q1-n, q1, 1);
+					winsettag(ct->w);
+				}else{
+					ct->q0 = q1-n;
+					ct->q1 = q1;
+				}
+				seltext = ct;
+				fbuffree(s);
+				return TRUE;
+			}
+			q1--;
+			nb--;
+			if(around && q1 <= 0)
+				break;
 		}
-		/* reload if buffer covers neither string nor rest of file */
-		if(nb<n && nb!=ct->file->nc-q){
-			nb = ct->file->nc-q;
-			if(nb >= maxn)
-				nb = maxn-1;
-			bufread(ct->file, q, s, nb);
-			b = s;
-			b[nb] = '\0';
-		}
-		/* this runeeq is fishy but the null at b[nb] makes it safe */
-		if(runeeq(b, n, r, n)==TRUE){
-			if(ct->w){
-				textshow(ct, q, q+n, 1);
-				winsettag(ct->w);
-			}else{
-				ct->q0 = q;
-				ct->q1 = q+n;
+	}else{
+		uint q;
+		q = ct->q1;
+		for(;;){
+			if(q >= ct->file->nc){
+				q = 0;
+				around = 1;
+				nb = 0;
+				b[nb] = 0;
 			}
-			seltext = ct;
-			fbuffree(s);
-			return TRUE;
+			if(nb > 0){
+				Rune *c;
+				c = runestrchr(b, r[0]);
+				if(c == nil){
+					q += nb;
+					nb = 0;
+					b[nb] = 0;
+					if(around && q>=ct->q1)
+						break;
+					continue;
+				}
+				q += (c-b);
+				nb -= (c-b);
+				b = c;
+			}
+			/* reload if buffer covers neither string nor rest of file */
+			if(nb<n && nb!=ct->file->nc-q){
+				nb = ct->file->nc-q;
+				if(nb >= maxn)
+					nb = maxn-1;
+				bufread(ct->file, q, s, nb);
+				b = s;
+				b[nb] = '\0';
+			}
+			/* this runeeq is fishy but the null at b[nb] makes it safe */
+			if(runeeq(b, n, r, n)==TRUE){
+				if(ct->w){
+					textshow(ct, q, q+n, 1);
+					winsettag(ct->w);
+				}else{
+					ct->q0 = q;
+					ct->q1 = q+n;
+				}
+				seltext = ct;
+				fbuffree(s);
+				return TRUE;
+			}
+			--nb;
+			b++;
+			q++;
+			if(around && q>=ct->q1)
+				break;
 		}
-		--nb;
-		b++;
-		q++;
-		if(around && q>=ct->q1)
-			break;
 	}
 	fbuffree(s);
 	return FALSE;
@@ -435,7 +499,7 @@
 }
 
 int
-expandfile(Text *t, uint q0, uint q1, Expand *e)
+expandfile(Text *t, uint q0, uint q1, Expand *e, int reverse)
 {
 	int i, n, nname, colon, eval;
 	uint amin, amax;
@@ -477,6 +541,11 @@
 						break;
 			}else
 				amax = t->file->nc;
+		if(colon != q0)
+			reverse = FALSE;
+	}else if(reverse){
+		if(textreadc(t, q0) != ':')
+			reverse = FALSE;
 	}
 	amin = amax;
 	e->q0 = q0;
@@ -539,8 +608,9 @@
 	e->nname = nname;
 	e->at = t;
 	e->a0 = amin+1;
+	e->reverse = reverse;
 	eval = FALSE;
-	address(nil, nil, (Range){-1,-1}, (Range){0, 0}, t, e->a0, amax, tgetc, &eval, (uint*)&e->a1);
+	address(nil, nil, (Range){-1,-1}, (Range){0, 0}, t, e->a0, amax, tgetc, &eval, (uint*)&e->a1, e->reverse);
 	return TRUE;
 
    Isntfile:
@@ -549,7 +619,7 @@
 }
 
 int
-expand(Text *t, uint q0, uint q1, Expand *e)
+expand(Text *t, uint q0, uint q1, Expand *e, int reverse)
 {
 	memset(e, 0, sizeof *e);
 	e->agetc = tgetc;
@@ -562,7 +632,7 @@
 			e->jump = FALSE;
 	}
 
-	if(expandfile(t, q0, q1, e))
+	if(expandfile(t, q0, q1, e, reverse))
 		return TRUE;
 
 	if(q0 == q1){
@@ -675,7 +745,7 @@
 		eval = FALSE;
 	else{
 		eval = TRUE;
-		r = address(nil, t, (Range){-1, -1}, (Range){t->q0, t->q1}, e->at, e->a0, e->a1, e->agetc, &eval, &dummy);
+		r = address(nil, t, (Range){-1, -1}, (Range){t->q0, t->q1}, e->at, e->a0, e->a1, e->agetc, &eval, &dummy, e->reverse);
 		if(eval == FALSE)
 			e->jump = FALSE;	/* don't jump if invalid address */
 	}
--- a/xfid.c
+++ b/xfid.c
@@ -455,7 +455,7 @@
 		t = &w->body;
 		wincommit(w, t);
 		eval = TRUE;
-		a = address(x->f->mntdir, t, w->limit, w->addr, r, 0, nr, rgetc, &eval, (uint*)&nb);
+		a = address(x->f->mntdir, t, w->limit, w->addr, r, 0, nr, rgetc, &eval, (uint*)&nb, FALSE);
 		free(r);
 		if(nb < nr){
 			respond(x, &fc, Ebadaddr);
@@ -863,8 +863,11 @@
 			break;
 		case 'l':
 		case 'L':
-			look3(t, q0, q1, TRUE);
+			look3(t, q0, q1, TRUE, FALSE);
 			break;
+		case 'r':
+		case 'R':
+			look3(t, q0, q1, TRUE, TRUE);
 		default:
 			qunlock(&row);
 			goto Rescue;