From: adr <adr@sdf.org>
To: 9fans@9fans.net
Subject: [9fans] Acme: support spaces in file|dir names
Date: Mon, 20 Feb 2023 16:06:50 +0000 (UTC) [thread overview]
Message-ID: <5032d5dd-7583-64f5-b3ab-284d2c4c8290@sdf.org> (raw)
[-- Attachment #1: Type: text/plain, Size: 7049 bytes --]
Hi,
this patch adds code from p9p to support spaces in file or dir
names. I use the 9front version because it has been mantained, but
there are more fixes in p9p to be imported.
adr
diff -Nur /n/9front/sys/src/cmd/acme/fns.h /sys/src/cmd/acme/fns.h
--- /n/9front/sys/src/cmd/acme/fns.h Mon Jul 11 20:01:08 2022
+++ /sys/src/cmd/acme/fns.h Mon Feb 20 15:23:42 2023
@@ -90,6 +90,7 @@
void flushwarnings(void);
long nlcount(Text*, long, long, long*);
long nlcounttopos(Text*, long, long, long);
+Rune* parsetag(Window*, int, int*);
#define runemalloc(a) (Rune*)emalloc((a)*sizeof(Rune))
#define runerealloc(a, b) (Rune*)erealloc((a), (b)*sizeof(Rune))
diff -Nur /n/9front/sys/src/cmd/acme/look.c /sys/src/cmd/acme/look.c
--- /n/9front/sys/src/cmd/acme/look.c Mon Jul 11 20:01:08 2022
+++ /sys/src/cmd/acme/look.c Mon Feb 20 15:47:24 2023
@@ -397,9 +397,9 @@
Runestr
dirname(Text *t, Rune *r, int n)
{
- Rune *b, c;
- uint m, nt;
- int slash;
+ Rune *b;
+ uint nt;
+ int slash, i;
Runestr tmp;
b = nil;
@@ -410,15 +410,13 @@
goto Rescue;
if(n>=1 && r[0]=='/')
goto Rescue;
- b = runemalloc(nt+n+1);
- bufread(t->w->tag.file, 0, b, nt);
+ b = parsetag(t->w, n, &i);
slash = -1;
- for(m=0; m<nt; m++){
- c = b[m];
- if(c == '/')
- slash = m;
- if(c==' ' || c=='\t')
+ for(i--; i >= 0; i--){
+ if(b[i] == '/'){
+ slash = i;
break;
+ }
}
if(slash < 0)
goto Rescue;
@@ -502,7 +500,7 @@
if(nname == -1)
nname = n;
for(i=0; i<nname; i++)
- if(!isfilec(r[i]))
+ if(!isfilec(r[i]) && r[i] != ' ')
goto Isntfile;
/*
* See if it's a file name in <>, and turn that into an include
diff -Nur /n/9front/sys/src/cmd/acme/wind.c /sys/src/cmd/acme/wind.c
--- /n/9front/sys/src/cmd/acme/wind.c Mon Jul 11 20:01:08 2022
+++ /sys/src/cmd/acme/wind.c Mon Feb 20 15:20:37 2023
@@ -109,14 +109,26 @@
return rr - r;
}
+int
+delrunepos(Window *w)
+{
+ Rune *r;
+ int i;
+
+ r = parsetag(w, 0, &i);
+ free(r);
+ i += 2;
+ if(i >= w->tag.file->nc)
+ return -1;
+ return i;
+}
+
void
movetodel(Window *w)
{
int n;
-
- n = tagrunepos(w, delcmd);
- free(delcmd);
- delcmd = nil;
+
+ n = delrunepos(w);
if(n < 0)
return;
moveto(mousectl, addpt(frptofchar(&w->tag, n), Pt(4, w->tag.font->height-4)));
@@ -141,7 +153,7 @@
if(!w->tagexpand) {
/* use just as many lines as needed to show the Del */
- n = tagrunepos(w, delcmd);
+ n = delrunepos(w);
if(n < 0)
return 1;
p = subpt(frptofchar(&w->tag, n), w->tag.r.min);
@@ -412,11 +424,7 @@
/* w must be committed */
n = w->tag.file->nc;
- r = runemalloc(n);
- bufread(w->tag.file, 0, r, n);
- for(i=0; i<n; i++)
- if(r[i]==' ' || r[i]=='\t')
- break;
+ r = parsetag(w, 0, &i);
for(; i<n; i++)
if(r[i] == '|')
break;
@@ -433,6 +441,38 @@
textsetselect(&w->tag, w->tag.q0, w->tag.q1);
}
+Rune*
+parsetag(Window *w, int extra, int *len)
+{
+ static Rune Ldelsnarf[] = { ' ', 'D', 'e', 'l', ' ', 'S', 'n', 'a', 'r', 'f', 0 };
+ static Rune Lspacepipe[] = { ' ', '|', 0 };
+ static Rune Ltabpipe[] = { '\t', '|', 0 };
+ int i;
+ Rune *r, *p, *pipe;
+
+ r = runemalloc(w->tag.file->nc+extra+1);
+ bufread(w->tag.file, 0, r, w->tag.file->nc);
+ r[w->tag.file->nc] = '\0';
+
+ /*
+ * " |" or "\t|" ends left half of tag
+ * If we find " Del Snarf" in the left half of the tag
+ * (before the pipe), that ends the file name.
+ */
+ pipe = runestrstr(r, Lspacepipe);
+ if((p = runestrstr(r, Ltabpipe)) != nil && (pipe == nil || p < pipe))
+ pipe = p;
+ if((p = runestrstr(r, Ldelsnarf)) != nil && (pipe == nil || p < pipe))
+ i = p - r;
+ else {
+ for(i=0; i<w->tag.file->nc; i++)
+ if(r[i]==' ' || r[i]=='\t')
+ break;
+ }
+ *len = i;
+ return r;
+}
+
void
winsettag1(Window *w)
{
@@ -445,12 +485,7 @@
/* there are races that get us here with stuff in the tag cache, so we take extra care to sync it */
if(w->tag.ncache!=0 || w->tag.file->mod)
wincommit(w, &w->tag); /* check file name; also guarantees we can modify tag contents */
- old = runemalloc(w->tag.file->nc+1);
- bufread(w->tag.file, 0, old, w->tag.file->nc);
- old[w->tag.file->nc] = '\0';
- for(i=0; i<w->tag.file->nc; i++)
- if(old[i]==' ' || old[i]=='\t')
- break;
+ old = parsetag(w, 0, &i);
if(runeeq(old, i, w->body.file->name, w->body.file->nname) == FALSE){
textdelete(&w->tag, 0, i, TRUE);
textinsert(&w->tag, 0, w->body.file->name, w->body.file->nname, TRUE);
@@ -458,7 +493,6 @@
old = runemalloc(w->tag.file->nc+1);
bufread(w->tag.file, 0, old, w->tag.file->nc);
old[w->tag.file->nc] = '\0';
- w->tagsafe = FALSE;
}
new = runemalloc(w->body.file->nname+100);
i = 0;
@@ -572,11 +606,7 @@
textcommit(f->text[i], FALSE); /* no-op for t */
if(t->what == Body)
return;
- r = runemalloc(w->tag.file->nc);
- bufread(w->tag.file, 0, r, w->tag.file->nc);
- for(i=0; i<w->tag.file->nc; i++)
- if(r[i]==' ' || r[i]=='\t')
- break;
+ r = parsetag(w, 0, &i);
if(runeeq(r, i, w->body.file->name, w->body.file->nname) == FALSE){
seq++;
filemark(w->body.file);
@@ -611,11 +641,11 @@
r = runerealloc(r, n+1);
r[n] = 0;
}
+ free(a);
if((d->qid.type&QTDIR) == 0){
free(d);
warning(nil, "%s: not a directory\n", a);
free(r);
- free(a);
return;
}
free(a);
------------------------------------------
9fans: 9fans
Permalink: https://9fans.topicbox.com/groups/9fans/Tc1d9d9ca3a94e285-M502a002b31fde997a5913efb
Delivery options: https://9fans.topicbox.com/groups/9fans/subscription
[-- Attachment #2: Type: text/plain, Size: 5251 bytes --]
diff -Nur /n/9front/sys/src/cmd/acme/fns.h /sys/src/cmd/acme/fns.h
--- /n/9front/sys/src/cmd/acme/fns.h Mon Jul 11 20:01:08 2022
+++ /sys/src/cmd/acme/fns.h Mon Feb 20 15:23:42 2023
@@ -90,6 +90,7 @@
void flushwarnings(void);
long nlcount(Text*, long, long, long*);
long nlcounttopos(Text*, long, long, long);
+Rune* parsetag(Window*, int, int*);
#define runemalloc(a) (Rune*)emalloc((a)*sizeof(Rune))
#define runerealloc(a, b) (Rune*)erealloc((a), (b)*sizeof(Rune))
diff -Nur /n/9front/sys/src/cmd/acme/look.c /sys/src/cmd/acme/look.c
--- /n/9front/sys/src/cmd/acme/look.c Mon Jul 11 20:01:08 2022
+++ /sys/src/cmd/acme/look.c Mon Feb 20 15:47:24 2023
@@ -397,9 +397,9 @@
Runestr
dirname(Text *t, Rune *r, int n)
{
- Rune *b, c;
- uint m, nt;
- int slash;
+ Rune *b;
+ uint nt;
+ int slash, i;
Runestr tmp;
b = nil;
@@ -410,15 +410,13 @@
goto Rescue;
if(n>=1 && r[0]=='/')
goto Rescue;
- b = runemalloc(nt+n+1);
- bufread(t->w->tag.file, 0, b, nt);
+ b = parsetag(t->w, n, &i);
slash = -1;
- for(m=0; m<nt; m++){
- c = b[m];
- if(c == '/')
- slash = m;
- if(c==' ' || c=='\t')
+ for(i--; i >= 0; i--){
+ if(b[i] == '/'){
+ slash = i;
break;
+ }
}
if(slash < 0)
goto Rescue;
@@ -502,7 +500,7 @@
if(nname == -1)
nname = n;
for(i=0; i<nname; i++)
- if(!isfilec(r[i]))
+ if(!isfilec(r[i]) && r[i] != ' ')
goto Isntfile;
/*
* See if it's a file name in <>, and turn that into an include
diff -Nur /n/9front/sys/src/cmd/acme/wind.c /sys/src/cmd/acme/wind.c
--- /n/9front/sys/src/cmd/acme/wind.c Mon Jul 11 20:01:08 2022
+++ /sys/src/cmd/acme/wind.c Mon Feb 20 15:20:37 2023
@@ -109,14 +109,26 @@
return rr - r;
}
+int
+delrunepos(Window *w)
+{
+ Rune *r;
+ int i;
+
+ r = parsetag(w, 0, &i);
+ free(r);
+ i += 2;
+ if(i >= w->tag.file->nc)
+ return -1;
+ return i;
+}
+
void
movetodel(Window *w)
{
int n;
-
- n = tagrunepos(w, delcmd);
- free(delcmd);
- delcmd = nil;
+
+ n = delrunepos(w);
if(n < 0)
return;
moveto(mousectl, addpt(frptofchar(&w->tag, n), Pt(4, w->tag.font->height-4)));
@@ -141,7 +153,7 @@
if(!w->tagexpand) {
/* use just as many lines as needed to show the Del */
- n = tagrunepos(w, delcmd);
+ n = delrunepos(w);
if(n < 0)
return 1;
p = subpt(frptofchar(&w->tag, n), w->tag.r.min);
@@ -412,11 +424,7 @@
/* w must be committed */
n = w->tag.file->nc;
- r = runemalloc(n);
- bufread(w->tag.file, 0, r, n);
- for(i=0; i<n; i++)
- if(r[i]==' ' || r[i]=='\t')
- break;
+ r = parsetag(w, 0, &i);
for(; i<n; i++)
if(r[i] == '|')
break;
@@ -433,6 +441,38 @@
textsetselect(&w->tag, w->tag.q0, w->tag.q1);
}
+Rune*
+parsetag(Window *w, int extra, int *len)
+{
+ static Rune Ldelsnarf[] = { ' ', 'D', 'e', 'l', ' ', 'S', 'n', 'a', 'r', 'f', 0 };
+ static Rune Lspacepipe[] = { ' ', '|', 0 };
+ static Rune Ltabpipe[] = { '\t', '|', 0 };
+ int i;
+ Rune *r, *p, *pipe;
+
+ r = runemalloc(w->tag.file->nc+extra+1);
+ bufread(w->tag.file, 0, r, w->tag.file->nc);
+ r[w->tag.file->nc] = '\0';
+
+ /*
+ * " |" or "\t|" ends left half of tag
+ * If we find " Del Snarf" in the left half of the tag
+ * (before the pipe), that ends the file name.
+ */
+ pipe = runestrstr(r, Lspacepipe);
+ if((p = runestrstr(r, Ltabpipe)) != nil && (pipe == nil || p < pipe))
+ pipe = p;
+ if((p = runestrstr(r, Ldelsnarf)) != nil && (pipe == nil || p < pipe))
+ i = p - r;
+ else {
+ for(i=0; i<w->tag.file->nc; i++)
+ if(r[i]==' ' || r[i]=='\t')
+ break;
+ }
+ *len = i;
+ return r;
+}
+
void
winsettag1(Window *w)
{
@@ -445,12 +485,7 @@
/* there are races that get us here with stuff in the tag cache, so we take extra care to sync it */
if(w->tag.ncache!=0 || w->tag.file->mod)
wincommit(w, &w->tag); /* check file name; also guarantees we can modify tag contents */
- old = runemalloc(w->tag.file->nc+1);
- bufread(w->tag.file, 0, old, w->tag.file->nc);
- old[w->tag.file->nc] = '\0';
- for(i=0; i<w->tag.file->nc; i++)
- if(old[i]==' ' || old[i]=='\t')
- break;
+ old = parsetag(w, 0, &i);
if(runeeq(old, i, w->body.file->name, w->body.file->nname) == FALSE){
textdelete(&w->tag, 0, i, TRUE);
textinsert(&w->tag, 0, w->body.file->name, w->body.file->nname, TRUE);
@@ -458,7 +493,6 @@
old = runemalloc(w->tag.file->nc+1);
bufread(w->tag.file, 0, old, w->tag.file->nc);
old[w->tag.file->nc] = '\0';
- w->tagsafe = FALSE;
}
new = runemalloc(w->body.file->nname+100);
i = 0;
@@ -572,11 +606,7 @@
textcommit(f->text[i], FALSE); /* no-op for t */
if(t->what == Body)
return;
- r = runemalloc(w->tag.file->nc);
- bufread(w->tag.file, 0, r, w->tag.file->nc);
- for(i=0; i<w->tag.file->nc; i++)
- if(r[i]==' ' || r[i]=='\t')
- break;
+ r = parsetag(w, 0, &i);
if(runeeq(r, i, w->body.file->name, w->body.file->nname) == FALSE){
seq++;
filemark(w->body.file);
@@ -611,11 +641,11 @@
r = runerealloc(r, n+1);
r[n] = 0;
}
+ free(a);
if((d->qid.type&QTDIR) == 0){
free(d);
warning(nil, "%s: not a directory\n", a);
free(r);
- free(a);
return;
}
free(a);
next reply other threads:[~2023-02-20 16:07 UTC|newest]
Thread overview: 5+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-02-20 16:06 adr [this message]
2023-02-20 17:23 ` hiro
2023-02-20 18:05 ` adr
2023-02-20 19:27 ` hiro
2023-02-24 20:21 ` Nicola Girardi
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=5032d5dd-7583-64f5-b3ab-284d2c4c8290@sdf.org \
--to=adr@sdf.org \
--cc=9fans@9fans.net \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).