commit - 6f4a41c68c39970dab1d0e09393a57b6cc3f55d6
commit + e47d0a1e98d8a77f0196764d3f7e682715793e1d
blob - 93af258db9ac1bc1288059fad892cb0cfb7b96d0
blob + 8242da6936189f11d4bf36bba06dab06131dfaef
--- src/cmd/acme/dat.h
+++ src/cmd/acme/dat.h
uint textbacknl(Text*, uint, uint);
uint textbsinsert(Text*, uint, Rune*, uint, int, int*);
int textbswidth(Text*, Rune);
+int textclickhtmlmatch(Text*, uint*, uint*);
int textclickmatch(Text*, int, int, int, uint*);
void textclose(Text*);
void textcolumnate(Text*, Dirlist**, int);
blob - f330d4b809fb8fdaad7f3fc074673ba2f9943ff1
blob + f1fc7329520806ba9a43c91321ecd8ff0fddfb6f
--- src/cmd/acme/text.c
+++ src/cmd/acme/text.c
return;
}
}
+
+ if(textclickhtmlmatch(t, q0, q1))
+ return;
+
/* try filling out word to right */
while(*q1<t->file->b.nc && isalnum(textreadc(t, *q1)))
(*q1)++;
nest++;
}
return cl=='\n' && nest==1;
+}
+
+// Is the text starting at location q an html tag?
+// Return 1 for <a>, -1 for </a>, 0 for no tag or <a />.
+// Set *q1, if non-nil, to the location after the tag.
+static int
+ishtmlstart(Text *t, uint q, uint *q1)
+{
+ int c, c1, c2;
+
+ if(q+2 > t->file->b.nc)
+ return 0;
+ if(textreadc(t, q++) != '<')
+ return 0;
+ c = textreadc(t, q++);
+ c1 = c;
+ c2 = c;
+ while(c != '>') {
+ if(q >= t->file->b.nc)
+ return 0;
+ c2 = c;
+ c = textreadc(t, q++);
+ }
+ if(q1)
+ *q1 = q;
+ if(c1 == '/') // closing tag
+ return -1;
+ if(c2 == '/' || c2 == '!') // open + close tag or comment
+ return 0;
+ return 1;
+}
+
+// Is the text ending at location q an html tag?
+// Return 1 for <a>, -1 for </a>, 0 for no tag or <a />.
+// Set *q0, if non-nil, to the start of the tag.
+static int
+ishtmlend(Text *t, uint q, uint *q0)
+{
+ int c, c1, c2;
+
+ if(q < 2)
+ return 0;
+ if(textreadc(t, --q) != '>')
+ return 0;
+ c = textreadc(t, --q);
+ c1 = c;
+ c2 = c;
+ while(c != '<') {
+ if(q == 0)
+ return 0;
+ c1 = c;
+ c = textreadc(t, --q);
+ }
+ if(q0)
+ *q0 = q;
+ if(c1 == '/') // closing tag
+ return -1;
+ if(c2 == '/' || c2 == '!') // open + close tag or comment
+ return 0;
+ return 1;
}
+int
+textclickhtmlmatch(Text *t, uint *q0, uint *q1)
+{
+ int depth, n;
+ uint q, nq;
+
+ q = *q0;
+ // after opening tag? scan forward for closing tag
+ if(ishtmlend(t, q, nil) == 1) {
+ depth = 1;
+ while(q < t->file->b.nc) {
+ n = ishtmlstart(t, q, &nq);
+ if(n != 0) {
+ depth += n;
+ if(depth == 0) {
+ *q1 = q;
+ return 1;
+ }
+ q = nq;
+ continue;
+ }
+ q++;
+ }
+ }
+
+ // before closing tag? scan backward for opening tag
+ if(ishtmlstart(t, q, nil) == -1) {
+ depth = -1;
+ while(q > 0) {
+ n = ishtmlend(t, q, &nq);
+ if(n != 0) {
+ depth += n;
+ if(depth == 0) {
+ *q0 = q;
+ return 1;
+ }
+ q = nq;
+ continue;
+ }
+ q--;
+ }
+ }
+
+ return 0;
+}
+
uint
textbacknl(Text *t, uint p, uint n)
{