diff --git a/nnn.1 b/nnn.1 index 2588b628..091a92af 100644 --- a/nnn.1 +++ b/nnn.1 @@ -31,12 +31,21 @@ efficient file manager that stays out of your way. .Nm opens the current working directory if .Ar PATH -is not specified. If the +is not specified. If .Ar PATH -doesn't exist, +is specified and it exists, .Nm -will prompt to create a new regular file. If the parent directory -is specified, it must exist and be accessible. +will open it. If the +.Ar PATH +doesn't exist and ends with a \fB/\fR, +.Nm +will attempt to create the directory tree and open it. Otherwise, +.Ar PATH +is considered a path to a regular file and +.Nm +attempts to create the complete directory tree to the file, open +the parent directory and prompt to create the new file in it with +the base filename. .Sh KEYBINDS .Pp Press diff --git a/src/nnn.c b/src/nnn.c index 0f64882c..597869ce 100644 --- a/src/nnn.c +++ b/src/nnn.c @@ -8571,7 +8571,9 @@ int main(int argc, char *argv[]) } else { /* Open a file */ arg = argv[optind]; DPRINTF_S(arg); - if (xstrlen(arg) > 7 && is_prefix(arg, "file://", 7)) + size_t len = xstrlen(arg); + + if (len > 7 && is_prefix(arg, "file://", 7)) arg = arg + 7; initpath = abspath(arg, NULL, NULL); DPRINTF_S(initpath); @@ -8592,16 +8594,23 @@ int main(int argc, char *argv[]) struct stat sb; if (stat(initpath, &sb) == -1) { - arg = xbasename(initpath); - if (arg != initpath) { /* We have a directory */ - if (!xdiraccess(xdirname(initpath))) { - xerror(); /* Fail non-existent/inaccessible directory */ + bool dir = (arg[len - 1] == '/'); + + if (!dir) { + arg = xbasename(initpath); + initpath = xdirname(initpath); + + pkey = CREATE_NEW_KEY; /* Override plugin key */ + g_state.initfile = 1; + } + if (dir || (arg != initpath)) { /* We have a directory */ + if (!xdiraccess(initpath) && !xmktree(initpath, TRUE)) { + xerror(); /* Fail if directory cannot be created */ return EXIT_FAILURE; } - *--arg = '/'; /* Restore the complete path */ + if (!dir) /* Restore the complete path */ + *--arg = '/'; } - pkey = CREATE_NEW_KEY; /* Override plugin key */ - g_state.initfile = 1; } else if (!S_ISDIR(sb.st_mode)) g_state.initfile = 1;