ref: 51cd581eb268a1944653e119ddfcb989cb18ff47
parent: 685fce9942b9f9f877ba36db91bf8ef1e20f8254
author: glenda <glenda@cirno>
date: Fri Mar 21 19:27:36 EDT 2025
added history with shift up/down
--- a/dat.h
+++ b/dat.h
@@ -179,6 +179,13 @@
uchar maximized;
char *label;
char *dir;
+ Rune **history;
+ int *historylens;
+ int nhistory;
+ int maxhistory;
+ int histpos;
+ Rune *savedcmd;
+ int nsavedcmd;
};
void winctl(void*);
--- a/wind.c
+++ b/wind.c
@@ -12,6 +12,45 @@
#include "dat.h"
#include "fns.h"
+void
+waddhistory(Window *w, Rune *r, int nr)
+{
+ int i;
+ Rune *s;
+
+ if(nr <= 0)
+ return;
+
+ s = runemalloc(nr);
+ runemove(s, r, nr);
+
+ if(w->nhistory > 0 && nr == w->historylens[0] &&
+ memcmp(s, w->history[0], nr*sizeof(Rune)) == 0) {
+ free(s);
+ return;
+ }
+
+ if(w->nhistory == w->maxhistory) {
+ free(w->history[w->maxhistory-1]);
+ w->nhistory--;
+ }
+
+ if(w->history == nil) {
+ w->history = emalloc(w->maxhistory * sizeof(Rune*));
+ w->historylens = emalloc(w->maxhistory * sizeof(int));
+ }
+
+ for(i = w->nhistory; i > 0; i--) {
+ w->history[i] = w->history[i-1];
+ w->historylens[i] = w->historylens[i-1];
+ }
+
+ w->history[0] = s;
+ w->historylens[0] = nr;
+ w->nhistory++;
+ w->histpos = -1;
+}
+
Window*
wlookid(int id)
{
@@ -869,9 +908,75 @@
}
static void
+whistup(Window *w)
+{
+ uint p0, p1;
+
+ if(w->histpos == -1 && w->nhistory > 0) {
+ p0 = w->qh;
+ p1 = w->nr;
+
+ while(p0 > 0 && w->r[p0-1] != '\n')
+ p0--;
+
+ if(p1 > p0) {
+ w->nsavedcmd = p1 - p0;
+ w->savedcmd = runemalloc(w->nsavedcmd);
+ runemove(w->savedcmd, w->r + p0, w->nsavedcmd);
+ wdelete(w, p0, p1);
+ }
+
+ w->histpos = 0;
+ if(w->histpos < w->nhistory)
+ winsert(w, w->history[w->histpos], w->historylens[w->histpos], p0);
+ } else if(w->histpos+1 < w->nhistory) {
+ p0 = w->qh;
+ while(p0 > 0 && w->r[p0-1] != '\n')
+ p0--;
+
+ wdelete(w, p0, w->nr);
+
+ w->histpos++;
+ winsert(w, w->history[w->histpos], w->historylens[w->histpos], p0);
+ }
+}
+
+static void
+whistdown(Window *w)
+{
+ uint p0;
+
+ if(w->histpos > 0) {
+ p0 = w->qh;
+ while(p0 > 0 && w->r[p0-1] != '\n')
+ p0--;
+
+ wdelete(w, p0, w->nr);
+
+ w->histpos--;
+ winsert(w, w->history[w->histpos], w->historylens[w->histpos], p0);
+ } else if(w->histpos == 0) {
+ p0 = w->qh;
+ while(p0 > 0 && w->r[p0-1] != '\n')
+ p0--;
+
+ wdelete(w, p0, w->nr);
+
+ if(w->savedcmd != nil) {
+ winsert(w, w->savedcmd, w->nsavedcmd, p0);
+ free(w->savedcmd);
+ w->savedcmd = nil;
+ w->nsavedcmd = 0;
+ }
+
+ w->histpos = -1;
+ }
+}
+
+static void
wkeyctl(Window *w, Rune r)
{
- uint q0 ,q1;
+ uint q0 ,q1, p0;
int n, nb;
int *notefd;
@@ -892,6 +997,10 @@
if(!w->mouseopen)
switch(r){
case Kdown:
+ if(shiftdown) {
+ whistdown(w);
+ return;
+ }
n = shiftdown ? 1 : w->maxlines/3;
goto case_Down;
case Kscrollonedown:
@@ -906,8 +1015,12 @@
wsetorigin(w, q0, TRUE);
return;
case Kup:
- n = shiftdown ? 1 : w->maxlines/3;
- goto case_Up;
+ if(shiftdown) {
+ whistup(w);
+ return;
+ }
+ n = shiftdown ? 1 : w->maxlines/3;
+ goto case_Up;
case Kscrolloneup:
n = mousescrollsize(w->maxlines);
if(n <= 0)
@@ -1016,6 +1129,15 @@
q0 = w->q0;
q0 = winsert(w, &r, 1, q0);
wshow(w, q0+1);
+
+ if(r == '\n') {
+ p0 = q0;
+ while(p0 > 0 && w->r[p0-1] != '\n')
+ p0--;
+
+ if(q0 > p0)
+ waddhistory(w, w->r + p0, q0 - p0);
+ }
}
static Window *clickwin;
@@ -1277,6 +1399,13 @@
Rectangle r;
w = emalloc(sizeof(Window));
+ w->history = nil;
+ w->historylens = nil;
+ w->nhistory = 0;
+ w->maxhistory = 100;
+ w->histpos = -1;
+ w->savedcmd = nil;
+ w->nsavedcmd = 0;
w->screenr = i->r;
r = insetrect(i->r, Selborder+1);
w->i = i;
@@ -1362,6 +1491,14 @@
return 0;
if(i < 0)
error("negative ref count");
+ if(w->history) {
+ for(i = 0; i < w->nhistory; i++)
+ free(w->history[i]);
+ free(w->history);
+ free(w->historylens);
+ }
+ if(w->savedcmd)
+ free(w->savedcmd);
wclunk(w);
wsendctlmesg(w, Exited, ZR, nil);
return 1;