shithub: mongrel

Download patch

ref: 09179e7f5084a223aa664bb53366ba47b106fe21
parent: 11c473e818fc3a0aa7ca096b5dac7dd0f124ac20
author: phil9 <telephil9@gmail.com>
date: Mon Mar 28 04:54:42 EDT 2022

add highlight rules to colour lines based on a regex pattern

	this does full line coloring based on a regexe pattern.
	For now, rules were added to color diff output.

--- a/text.c
+++ b/text.c
@@ -5,8 +5,26 @@
 #include <keyboard.h>
 #include <thread.h>
 #include <plumb.h>
+#include <regexp.h>
 #include "w.h"
 
+typedef struct Highlight Highlight;
+
+struct Highlight
+{
+	char *pattern;
+	ulong color;
+	Reprog *re;
+	Image *i;
+};
+
+Highlight hilights[] = {
+	{ "^--- a.*$", 0x458588ff, nil },
+	{ "^\\+\\+\\+ b.*$", 0x458588ff, nil },
+	{ "^-.+$",   0xcc241dFF, nil },
+	{ "^\\+.*$", 0x98971AFF, nil },
+};
+
 enum
 {
 	Scrollwidth = 12,
@@ -25,11 +43,23 @@
 };
 Menu menu2 = { menu2str };
 
+Image*
+findhilight(char *s)
+{
+	int i;
+
+	for(i = 0; i < nelem(hilights); i++)
+		if(regexec(hilights[i].re, s, nil, 0))
+			return hilights[i].i;
+	return nil;
+}
+
 void
 computelines(Text *t)
 {
-	int i, x, w, l, c;
+	int i, x, w, l, c, n;
 	Rune r;
+	char buf[4096] = {0};
 
 	t->lines[0] = 0;
 	t->nlines = 1;
@@ -40,6 +70,10 @@
 		if(r == '\n'){
 			if(i + c == t->ndata)
 				break;
+			n = i + c - t->lines[t->nlines - 1];
+			strncpy(buf, t->data + t->lines[t->nlines - 1], n);
+			buf[n] = 0;
+			t->high[t->nlines - 1] = findhilight(buf);
 			t->lines[t->nlines++] = i + c;
 			x = 0;
 		}else{
@@ -94,6 +128,8 @@
 void
 textinit(Text *t, Image *b, Rectangle r, Font *f, Image *cols[NCOLS])
 {
+	int i;
+
 	memset(t, 0, sizeof *t);
 	t->b = b;
 	t->font = f;
@@ -102,6 +138,10 @@
 	t->offset = 0;
 	textresize(t, r);
 	memmove(t->cols, cols, sizeof t->cols);
+	for(i = 0; i < nelem(hilights); i++){
+		hilights[i].re = regcomp(hilights[i].pattern);
+		hilights[i].i  = allocimage(display, Rect(0, 0, 1, 1), screen->chan, 1, hilights[i].color);
+	}
 }
 
 void
@@ -142,7 +182,7 @@
 void
 drawline(Text *t, int index)
 {
-	int i, s, e;
+	int i, s, e, sel;
 	Point p;
 	Rune r;
 	Image *fg, *bg;
@@ -154,8 +194,11 @@
 		e = t->lines[t->offset+index+1];
 	p = addpt(t->textr.min, Pt(0, index*font->height));
 	for(i = s; i < e; ){
-		fg = selected(t, i) ? t->cols[HTEXT] : t->cols[TEXT];
-		bg = selected(t, i) ? t->cols[HIGH]  : t->cols[BACK];
+		sel = selected(t, i);
+		fg = sel ? t->cols[HTEXT] : t->cols[TEXT];
+		bg = sel ? t->cols[HIGH]  : t->cols[BACK];
+		if(!sel && t->high[t->offset+index] != nil)
+			fg = t->high[t->offset+index];
 		i += chartorune(&r, &t->data[i]);
 		if(r == '\n')
 			if(s + 1 == e) /* empty line */
--- a/w.h
+++ b/w.h
@@ -28,6 +28,7 @@
 	char *data;
 	usize ndata;
 	usize lines[Maxlines];
+	Image *high[Maxlines];
 	int nlines;
 	int s0;
 	int s1;