aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/cmd/acme/exec.c105
-rw-r--r--src/cmd/acme/look.c48
-rw-r--r--src/cmd/devdraw/cocoa-screen-metal.m15
3 files changed, 117 insertions, 51 deletions
diff --git a/src/cmd/acme/exec.c b/src/cmd/acme/exec.c
index 290e0514..bb2c93d6 100644
--- a/src/cmd/acme/exec.c
+++ b/src/cmd/acme/exec.c
@@ -695,42 +695,10 @@ checksha1(char *name, File *f, Dir *d)
}
}
-static uint
-trimspaces(Rune *r, uint *np, int eof)
-{
- uint i, w, nonspace, n;
- Rune c;
-
- nonspace = 0;
- w = 0;
- n = *np;
- for(i=0; i<n; i++) {
- c = r[i];
- if(c == '\n')
- w = nonspace;
- r[w++] = c;
- if(c != ' ' && c != '\t')
- nonspace = w;
- }
- if(nonspace > 0 && nonspace < w) {
- // Trailing spaces at end of buffer.
- // Tell caller to reread them with what follows,
- // so we can determine whether they need trimming.
- // Unless the trailing spaces are the entire buffer,
- // in which case let them through to avoid an infinite loop
- // if an entire buffer fills with spaces.
- // At EOF, just consume the spaces.
- if(!eof)
- *np = n - (w - nonspace);
- w = nonspace;
- }
- return w;
-}
-
void
putfile(File *f, int q0, int q1, Rune *namer, int nname)
{
- uint n, nn, m;
+ uint n, m;
Rune *r;
Biobuf *b;
char *s, *name;
@@ -757,6 +725,7 @@ putfile(File *f, int q0, int q1, Rune *namer, int nname)
goto Rescue1;
}
}
+
fd = create(name, OWRITE, 0666);
if(fd < 0){
warning(nil, "can't create file %s: %r\n", name);
@@ -785,14 +754,7 @@ putfile(File *f, int q0, int q1, Rune *namer, int nname)
if(n > BUFSIZE/UTFmax)
n = BUFSIZE/UTFmax;
bufread(&f->b, q, r, n);
- nn = n;
- // An attempt at automatically trimming trailing spaces.
- // Breaks programs that inspect body file and think it will match on-disk file
- // when window is clean. Should apply the changes to the actual window instead.
- // Later.
- if(0 && w->autoindent)
- nn = trimspaces(r, &n, q+n==q1);
- m = snprint(s, BUFSIZE+1, "%.*S", nn, r);
+ m = snprint(s, BUFSIZE+1, "%.*S", n, r);
sha1((uchar*)s, m, nil, h);
if(Bwrite(b, s, m) != m){
warning(nil, "can't write file %s: %r\n", name);
@@ -871,6 +833,65 @@ putfile(File *f, int q0, int q1, Rune *namer, int nname)
free(name);
}
+static void
+trimspaces(Text *et)
+{
+ File *f;
+ Rune *r;
+ Text *t;
+ uint q0, n, delstart;
+ int c, i, marked;
+
+ t = &et->w->body;
+ f = t->file;
+ marked = 0;
+
+ if(t->w!=nil && et->w!=t->w){
+ /* can this happen when t == &et->w->body? */
+ c = 'M';
+ if(et->w)
+ c = et->w->owner;
+ winlock(t->w, c);
+ }
+
+ r = fbufalloc();
+ q0 = f->b.nc;
+ delstart = q0; /* end of current space run, or 0 if no active run; = q0 to delete spaces before EOF */
+ while(q0 > 0) {
+ n = RBUFSIZE;
+ if(n > q0)
+ n = q0;
+ q0 -= n;
+ bufread(&f->b, q0, r, n);
+ for(i=n; ; i--) {
+ if(i == 0 || (r[i-1] != ' ' && r[i-1] != '\t')) {
+ // Found non-space or start of buffer. Delete active space run.
+ if(q0+i < delstart) {
+ if(!marked) {
+ marked = 1;
+ seq++;
+ filemark(f);
+ }
+ textdelete(t, q0+i, delstart, TRUE);
+ }
+ if(i == 0) {
+ /* keep run active into tail of next buffer */
+ if(delstart > 0)
+ delstart = q0;
+ break;
+ }
+ delstart = 0;
+ if(r[i-1] == '\n')
+ delstart = q0+i-1; /* delete spaces before this newline */
+ }
+ }
+ }
+ fbuffree(r);
+
+ if(t->w!=nil && et->w!=t->w)
+ winunlock(t->w);
+}
+
void
put(Text *et, Text *_0, Text *argt, int _1, int _2, Rune *arg, int narg)
{
@@ -893,6 +914,8 @@ put(Text *et, Text *_0, Text *argt, int _1, int _2, Rune *arg, int narg)
warning(nil, "no file name\n");
return;
}
+ if(w->autoindent)
+ trimspaces(et);
namer = bytetorune(name, &nname);
putfile(f, 0, f->b.nc, namer, nname);
xfidlog(w, "put");
diff --git a/src/cmd/acme/look.c b/src/cmd/acme/look.c
index cbbc71bf..44e23cca 100644
--- a/src/cmd/acme/look.c
+++ b/src/cmd/acme/look.c
@@ -30,7 +30,7 @@ plumbthread(void *v)
USED(v);
threadsetname("plumbproc");
-
+
/*
* Loop so that if plumber is restarted, acme need not be.
*/
@@ -46,7 +46,7 @@ plumbthread(void *v)
}
plumbeditfid = fid;
plumbsendfid = plumbopenfid("send", OWRITE|OCEXEC);
-
+
/*
* Relay messages.
*/
@@ -432,9 +432,9 @@ includename(Text *t, Rune *r, int n)
char buf[128];
Rune Lsysinclude[] = { '/', 's', 'y', 's', '/', 'i', 'n', 'c', 'l', 'u', 'd', 'e', 0 };
Rune Lusrinclude[] = { '/', 'u', 's', 'r', '/', 'i', 'n', 'c', 'l', 'u', 'd', 'e', 0 };
- Rune Lusrlocalinclude[] = { '/', 'u', 's', 'r', '/', 'l', 'o', 'c', 'a', 'l',
+ Rune Lusrlocalinclude[] = { '/', 'u', 's', 'r', '/', 'l', 'o', 'c', 'a', 'l',
'/', 'i', 'n', 'c', 'l', 'u', 'd', 'e', 0 };
- Rune Lusrlocalplan9include[] = { '/', 'u', 's', 'r', '/', 'l', 'o', 'c', 'a', 'l',
+ Rune Lusrlocalplan9include[] = { '/', 'u', 's', 'r', '/', 'l', 'o', 'c', 'a', 'l',
'/', 'p', 'l', 'a', 'n', '9', '/', 'i', 'n', 'c', 'l', 'u', 'd', 'e', 0 };
Runestr file;
int i;
@@ -443,7 +443,7 @@ includename(Text *t, Rune *r, int n)
sprint(buf, "/%s/include", objtype);
objdir = bytetorune(buf, &i);
objdir = runerealloc(objdir, i+1);
- objdir[i] = '\0';
+ objdir[i] = '\0';
}
w = t->w;
@@ -514,6 +514,19 @@ dirname(Text *t, Rune *r, int n)
return tmp;
}
+static int
+texthas(Text *t, uint q0, Rune *r)
+{
+ int i;
+
+ if((int)q0 < 0)
+ return FALSE;
+ for(i=0; r[i]; i++)
+ if(q0+i >= t->file->b.nc || textreadc(t, q0+i) != r[i])
+ return FALSE;
+ return TRUE;
+}
+
int
expandfile(Text *t, uint q0, uint q1, Expand *e)
{
@@ -522,12 +535,14 @@ expandfile(Text *t, uint q0, uint q1, Expand *e)
Rune *r, c;
Window *w;
Runestr rs;
+ Rune Lhttpcss[] = {'h', 't', 't', 'p', ':', '/', '/', 0};
+ Rune Lhttpscss[] = {'h', 't', 't', 'p', 's', ':', '/', '/', 0};
amax = q1;
if(q1 == q0){
colon = -1;
while(q1<t->file->b.nc && isfilec(c=textreadc(t, q1))){
- if(c == ':'){
+ if(c == ':' && !texthas(t, q1-4, Lhttpcss) && !texthas(t, q1-5, Lhttpscss)){
colon = q1;
break;
}
@@ -535,7 +550,7 @@ expandfile(Text *t, uint q0, uint q1, Expand *e)
}
while(q0>0 && (isfilec(c=textreadc(t, q0-1)) || isaddrc(c) || isregexc(c))){
q0--;
- if(colon<0 && c==':')
+ if(colon<0 && c==':' && !texthas(t, q0-4, Lhttpcss) && !texthas(t, q0-5, Lhttpscss))
colon = q0;
}
/*
@@ -565,8 +580,23 @@ expandfile(Text *t, uint q0, uint q1, Expand *e)
if(n == 0)
return FALSE;
/* see if it's a file name */
- r = runemalloc(n);
+ r = runemalloc(n+1);
bufread(&t->file->b, q0, r, n);
+ r[n] = 0;
+ /* is it a URL? look for http:// and https:// prefix */
+ if(runestrncmp(r, Lhttpcss, 7) == 0 || runestrncmp(r, Lhttpscss, 8) == 0){
+ // Avoid capturing end-of-sentence punctuation.
+ if(r[n-1] == '.') {
+ e->q1--;
+ n--;
+ }
+ e->name = r;
+ e->nname = n;
+ e->u.at = t;
+ e->a0 = e->q1;
+ e->a1 = e->q1;
+ return TRUE;
+ }
/* first, does it have bad chars? */
nname = -1;
for(i=0; i<n; i++){
@@ -728,7 +758,7 @@ openfile(Text *t, Expand *e)
/*
* Unrooted path in new window.
* This can happen if we type a pwd-relative path
- * in the topmost tag or the column tags.
+ * in the topmost tag or the column tags.
* Most of the time plumber takes care of these,
* but plumber might not be running or might not
* be configured to accept plumbed directories.
diff --git a/src/cmd/devdraw/cocoa-screen-metal.m b/src/cmd/devdraw/cocoa-screen-metal.m
index 09b34635..984ede03 100644
--- a/src/cmd/devdraw/cocoa-screen-metal.m
+++ b/src/cmd/devdraw/cocoa-screen-metal.m
@@ -212,12 +212,19 @@ threadmain(int argc, char **argv)
+ (void)callsetNeedsDisplayInRect:(NSValue *)v
{
NSRect r;
+ dispatch_time_t time;
r = [v rectValue];
LOG(@"callsetNeedsDisplayInRect(%g, %g, %g, %g)", r.origin.x, r.origin.y, r.size.width, r.size.height);
r = [win convertRectFromBacking:r];
LOG(@"setNeedsDisplayInRect(%g, %g, %g, %g)", r.origin.x, r.origin.y, r.size.width, r.size.height);
[layer setNeedsDisplayInRect:r];
+
+ time = dispatch_time(DISPATCH_TIME_NOW, 16 * NSEC_PER_MSEC);
+ dispatch_after(time, dispatch_get_main_queue(), ^(void){
+ [layer setNeedsDisplayInRect:r];
+ });
+
[myContent enlargeLastInputRect:r];
}
@@ -342,6 +349,13 @@ struct Cursors {
return YES;
}
+- (void)windowDidResize:(NSNotification *)notification
+{
+ if(![myContent inLiveResize] && img) {
+ resizeimg();
+ }
+}
+
- (void)windowDidBecomeKey:(id)arg
{
[myContent sendmouse:0];
@@ -1112,7 +1126,6 @@ resizewindow(Rectangle r)
s = [myContent convertSizeFromBacking:NSMakeSize(Dx(r), Dy(r))];
[win setContentSize:s];
- resizeimg();
});
}