mirror of
https://github.com/jarun/nnn.git
synced 2024-11-28 05:41:31 +00:00
Create new files and dirs with parent (like mkdir -p)
This commit is contained in:
parent
9729b1f5a6
commit
3a9def25d8
|
@ -56,7 +56,7 @@ Add to that an awesome [Wiki](https://github.com/jarun/nnn/wiki)!
|
||||||
- Cross-dir file/all/range selection
|
- Cross-dir file/all/range selection
|
||||||
- Batch rename selection or dir entries
|
- Batch rename selection or dir entries
|
||||||
- Copy (as), move (as), delete, archive, link selection
|
- Copy (as), move (as), delete, archive, link selection
|
||||||
- Create, rename, duplicate files and dirs
|
- Create (with parents), rename, duplicate (anywhere) files and dirs
|
||||||
- Spawn a shell, run apps, run commands, execute file
|
- Spawn a shell, run apps, run commands, execute file
|
||||||
- Lock terminal (needs a locker)
|
- Lock terminal (needs a locker)
|
||||||
- Minimal deps, minimal config
|
- Minimal deps, minimal config
|
||||||
|
|
67
src/nnn.c
67
src/nnn.c
|
@ -1317,6 +1317,59 @@ static void xrm(char *path)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Create non-existent parents and a file or dir */
|
||||||
|
static bool xmkentryp(char* path, bool dir)
|
||||||
|
{
|
||||||
|
char* p = path;
|
||||||
|
char *slash = path;
|
||||||
|
|
||||||
|
if (!p || !*p)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
/* Skip the first '/' */
|
||||||
|
++p;
|
||||||
|
|
||||||
|
while (*p != '\0') {
|
||||||
|
if (*p == '/') {
|
||||||
|
slash = p;
|
||||||
|
*p = '\0';
|
||||||
|
} else {
|
||||||
|
++p;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Create folder from path to '\0' inserted at p */
|
||||||
|
if (mkdir(path, 0777) == -1 && errno != EEXIST) {
|
||||||
|
DPRINTF_S("mkdir1 fail");
|
||||||
|
DPRINTF_S(strerror(errno));
|
||||||
|
*slash = '/';
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Restore path */
|
||||||
|
*slash = '/';
|
||||||
|
++p;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dir) {
|
||||||
|
if(mkdir(path, 0777) == -1 && errno != EEXIST) {
|
||||||
|
DPRINTF_S("mkdir2 fail");
|
||||||
|
DPRINTF_S(strerror(errno));
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
int fd = open(path, O_CREAT, 0666);
|
||||||
|
if (fd == -1 && errno != EEXIST) {
|
||||||
|
DPRINTF_S("open fail");
|
||||||
|
DPRINTF_S(strerror(errno));
|
||||||
|
return FALSE;
|
||||||
|
} else
|
||||||
|
close(fd);
|
||||||
|
}
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
static uint lines_in_file(int fd, char *buf, size_t buflen)
|
static uint lines_in_file(int fd, char *buf, size_t buflen)
|
||||||
{
|
{
|
||||||
ssize_t len;
|
ssize_t len;
|
||||||
|
@ -4834,7 +4887,8 @@ nochange:
|
||||||
break;
|
break;
|
||||||
|
|
||||||
/* Allow only relative, same dir paths */
|
/* Allow only relative, same dir paths */
|
||||||
if (tmp[0] == '/' || xstrcmp(xbasename(tmp), tmp) != 0) {
|
if (tmp[0] == '/'
|
||||||
|
|| ((r != 'f' && r != 'd') && (xstrcmp(xbasename(tmp), tmp) != 0))) {
|
||||||
printwait(messages[STR_INPUT_ID], &presel);
|
printwait(messages[STR_INPUT_ID], &presel);
|
||||||
goto nochange;
|
goto nochange;
|
||||||
}
|
}
|
||||||
|
@ -4929,11 +4983,12 @@ nochange:
|
||||||
} else {
|
} else {
|
||||||
/* Check if it's a dir or file */
|
/* Check if it's a dir or file */
|
||||||
if (r == 'f') {
|
if (r == 'f') {
|
||||||
r = openat(fd, tmp, O_CREAT, 0666);
|
mkpath(path, tmp, newpath);
|
||||||
close(r);
|
r = xmkentryp(newpath, FALSE);
|
||||||
} else if (r == 'd')
|
} else if (r == 'd') {
|
||||||
r = mkdirat(fd, tmp, 0777);
|
mkpath(path, tmp, newpath);
|
||||||
else if (r == 's' || r == 'h') {
|
r = xmkentryp(newpath, TRUE);
|
||||||
|
} else if (r == 's' || r == 'h') {
|
||||||
if (tmp[0] == '@' && tmp[1] == '\0')
|
if (tmp[0] == '@' && tmp[1] == '\0')
|
||||||
tmp[0] = '\0';
|
tmp[0] = '\0';
|
||||||
r = xlink(tmp, path, newpath, &presel, r);
|
r = xlink(tmp, path, newpath, &presel, r);
|
||||||
|
|
Loading…
Reference in a new issue