ref: aac2549d724f05d5b5dcce35c6f3e29a936f8cd1
parent: bcac03391b9eec054bfb6911ac8e1e504c91889b
author: phil9 <telephil9@gmail.com>
date: Tue Dec 27 11:37:30 EST 2022
implement delete command
--- a/a.h
+++ b/a.h
@@ -116,8 +116,10 @@
Dir dirmodelgetdir(Dirmodel*, int);
long dirmodelcount(Dirmodel*);
void dirmodelreload(Dirmodel*);
+void dirmodelreloadifsame(Dirmodel*, Dirmodel*);
void dirmodelcd(Dirmodel*, char*);
void dirmodelfilter(Dirmodel*, char*);
+long dirmodelmarklist(Dirmodel*, Dir**);
Dirpanel* mkdirpanel(Dirmodel*);
void dirpanelsetrect(Dirpanel*, Rectangle);
@@ -148,7 +150,12 @@
int match(char*, char*);
int message(int, const char*, Mousectl*, Keyboardctl*);
+void errormessage(char*, Mousectl*, Keyboardctl*);
+int mkdir(char*, char*);
+int rm(char*, Dir);
+int rmdir(char*);
+
Rectangle boundsrect(Rectangle);
Image* ealloccolor(ulong);
void* emalloc(ulong);
@@ -156,7 +163,6 @@
char* slurp(char*);
char* homedir(void);
char* abspath(char*, char*);
-int mkdir(char*, char*);
enum
{
--- a/dirmodel.c
+++ b/dirmodel.c
@@ -48,6 +48,13 @@
}
void
+dirmodelreloadifsame(Dirmodel *m, Dirmodel *o)
+{
+ if(strcmp(m->path, o->path) == 0)
+ dirmodelreload(o);
+}
+
+void
dirmodelcd(Dirmodel *m, char *p)
{
char newpath[1024] = {0};
@@ -134,4 +141,31 @@
memset(m->sel, 0, m->ndirs * sizeof(uchar));
m->filter = strdup(p);
sendul(m->c, 1);
+}
+
+long
+dirmodelmarklist(Dirmodel *m, Dir **d)
+{
+ int i, j;
+ long n, ndirs;
+ Dir *dirs;
+
+ n = 0;
+ ndirs = m->ndirs;
+ dirs = m->dirs;
+ if(m->filter){
+ ndirs = m->fndirs;
+ dirs = m->fdirs;
+ }
+ for(i = 0; i < ndirs; i++)
+ n += m->sel[i];
+ if(n == 0)
+ return 0;
+ *d = emalloc(n*sizeof(Dir));
+ j = 0;
+ for(i = 0; i < ndirs; i++){
+ if(m->sel[i])
+ (*d)[j++] = dirs[i];
+ }
+ return n;
}
--- a/dirviewcmd.c
+++ b/dirviewcmd.c
@@ -58,7 +58,7 @@
{
Dirpanel *p;
Dir d, null;
- char errbuf[64+ERRMAX], opath[1024] = {0}, buf[255] = {0};
+ char opath[1024] = {0}, buf[255] = {0};
int n;
p = dirviewcurrentpanel(dview);
@@ -65,7 +65,7 @@
if(strcmp(p->model->path, dirviewotherpanel(dview)->model->path) == 0){
d = dirmodelgetdir(p->model, dirpanelselectedindex(p));
if(d.qid.type&QTDIR){
- message(Derror, "cannot rename directories.", mc, kc);
+ errormessage("cannot rename directories.", mc, kc);
return;
}
snprint(buf, sizeof buf, d.name);
@@ -77,8 +77,7 @@
nulldir(&null);
null.name = buf;
if(dirwstat(opath, &null) < 0){
- snprint(errbuf, sizeof errbuf, "rename failed: %r");
- message(Derror, errbuf, mc, kc);
+ errormessage("rename failed: %r", mc, kc);
}else{
dirmodelreload(p->model);
dirmodelreload(dirviewotherpanel(dview)->model);
@@ -85,7 +84,7 @@
}
return;
}
-};
+}
static void
cmdmkdir(void)
@@ -97,16 +96,51 @@
if(enter("new dir:", buf, sizeof buf, mc, kc, nil) <= 0)
return;
if(mkdir(p->model->path, buf) < 0){
- fprint(2, "mkdir: %r\n");
+ errormessage("directory creation failed: %r", mc, kc);
return;
}
dirmodelreload(p->model);
+ dirmodelreloadifsame(p->model, dirviewotherpanel(dview)->model);
}
static void
cmddelete(void)
{
- fprint(2, "TODO: delete\n");
+ Dirpanel *p;
+ Dir *md, d;
+ char buf[1024] = {0}, *path;
+ long nd;
+ int n;
+
+ p = dirviewcurrentpanel(dview);
+ path = p->model->path;
+ nd = dirmodelmarklist(p->model, &md);
+ if(nd != 0){
+ snprint(buf, sizeof buf, "delete %ld files/directories ?", nd);
+ if(message(Dconfirm, buf, mc, kc) == Bno)
+ return;
+ for(n = 0; n < nd; n++){
+ d = md[n];
+ if(rm(path, d) < 0){
+ errormessage("delete failed: %r", mc, kc);
+ return;
+ }
+ }
+ }else{
+ n = dirpanelselectedindex(p);
+ if(n == 0 && !p->model->isroot) /* up dir */
+ return;
+ d = dirmodelgetdir(p->model, n);
+ snprint(buf, sizeof buf, "delete %s '%s' ?", (d.qid.type&QTDIR) ? "directory" : "file", d.name);
+ if(message(Dconfirm, buf, mc, kc) == Bno)
+ return;
+ if(rm(path, d) < 0){
+ errormessage("delete failed: %r", mc, kc);
+ return;
+ }
+ }
+ dirmodelreload(p->model);
+ dirmodelreloadifsame(p->model, dirviewotherpanel(dview)->model);
}
static void
--- /dev/null
+++ b/fops.c
@@ -1,0 +1,63 @@
+#include "a.h"
+
+int
+mkdir(char *wd, char *name)
+{
+ char *p;
+ int fd;
+
+ p = abspath(wd, name);
+ if(access(p, 0) >= 0){
+ werrstr("directory already exists");
+ free(p);
+ return -1;
+ }
+ fd = create(p, OREAD, DMDIR|0755);
+ if(fd < 0){
+ free(p);
+ return -1;
+ }
+ free(p);
+ close(fd);
+ return 0;
+}
+
+int
+rmdir(char *path)
+{
+ Dir *dirs;
+ int i, fd, ndirs;
+
+ fd = open(path, OREAD);
+ if(fd < 0)
+ return -1;
+ ndirs = dirreadall(fd, &dirs);
+ close(fd);
+ if(ndirs < 0)
+ return -1;
+ for(i = 0; i < ndirs; i++){
+ if(rm(path, dirs[i]) < 0){
+ free(dirs);
+ return -1;
+ }
+ }
+ free(dirs);
+ if(remove(path) < 0)
+ return -1;
+ return 0;
+}
+
+int
+rm(char *path, Dir d)
+{
+ char buf[1024] = {0};
+ int rc;
+
+ snprint(buf, sizeof buf, "%s/%s", path, d.name);
+ if(d.qid.type&QTDIR){
+ rc = rmdir(buf);
+ }else{
+ rc = remove(buf);
+ }
+ return rc;
+}
--- a/message.c
+++ b/message.c
@@ -136,3 +136,12 @@
flushimage(display, 1);
return rc;
}
+
+void
+errormessage(char *msg, Mousectl *mc, Keyboardctl *kc)
+{
+ char errbuf[64+ERRMAX] = {0};
+
+ snprint(errbuf, sizeof errbuf, msg);
+ message(Derror, msg, mc, kc);
+}
--- a/mkfile
+++ b/mkfile
@@ -15,6 +15,7 @@
text.$O \
message.$O \
glob.$O \
+ fops.$O \
utils.$O
</sys/src/cmd/mkone
--- a/utils.c
+++ b/utils.c
@@ -99,25 +99,3 @@
cleanname(s);
return s;
}
-
-int
-mkdir(char *wd, char *name)
-{
- char *p;
- int fd;
-
- p = abspath(wd, name);
- if(access(p, 0) >= 0){
- werrstr("directory already exists");
- free(p);
- return -1;
- }
- fd = create(p, OREAD, DMDIR|0755);
- if(fd < 0){
- free(p);
- return -1;
- }
- free(p);
- close(fd);
- return 0;
-}