- [cd on quit](#cd-on-quit)
- [customize nlay](#customize-nlay)
- [copy file path to clipboard](#copy-file-path-to-clipboard)
- - [file copy. move. delete](#file-copy-move-delete)
+ - [file copy, move, delete](#file-copy-move-delete)
- [boost chdir prompt](#boost-chdir-prompt)
- [change file associations](#change-file-associations)
+ - [set idle timeout](#set-idle-timeout)
- [Why fork?](#why-fork)
- [Mentions](#mentions)
- [Developers](#developers)
- Change directory at exit (*easy* shell integration)
- Open any file in EDITOR (fallback vi) or PAGER (fallback less)
- Open current directory in a custom GUI file browser
+ - Terminal screensaver (default vlock, customizable) integration
- Unicode support
- Highly optimized code, minimal resource usage
^K | Invoke file name copier
^L | Force a redraw
? | Toggle help screen
- q | Quit
Q | Quit and change directory
+ q, ^Q | Quit
```
#### Filters
- [zathura](https://pwmt.org/projects/zathura/) - pdf
- vim - plain text
- gnome-search-tool - search
+ - vlock - terminal screensaver
- to add, remove recognized extensions in `nnn`, see [how to change file associations](#change-file-associations)
- If a file without any extension is a plain text file, it is opened in EDITOR (fallback vi)
- Set `NNN_FALLBACK_OPENER` as the fallback opener. E.g.:
nlay has provisions (disabled by default) to handle a specific file extension too. However, the extension should be recognized by `nnn` first.
+#### set idle timeout
+
+The terminal screensaver is disabled by default. To set the wait time in seconds, use environment variable `NNN_IDLE_TIMEOUT`.
+
### Why fork?
I chose to fork because:
static int idletimeout = 0; /* Screensaver timeout in seconds, 0 to disable */
static int showhidden = 0; /* Set to 1 to show hidden files by default */
static int showdetail = 0; /* Set to show additional file info */
-static char *idlecmd = "rain"; /* The screensaver program */
static struct assoc assocs[] = {
{ "\\.(c|cpp|h|log|md|py|sh|txt)$", "text" },
static struct key bindings[] = {
/* Quit */
{ 'q', SEL_QUIT, "", "" },
+ { CONTROL('Q'), SEL_QUIT, "", "" },
+ /* Change dir on quit */
{ 'Q', SEL_CDQUIT, "", "" },
/* Back */
{ KEY_BACKSPACE, SEL_BACK, "", "" },
#------------------ AUDIO -------------------
if [ "$2" == "audio" ]; then
app=mpv
- # To start mpv in a window enable audio_opts
- #audio_opts="--no-terminal --force-window"
+ # To start mpv in a window enable opts
+ #opts="--no-terminal --force-window"
#bg=">/dev/null 2>&1 &"
killall -9 $app >/dev/null 2>&1
fi
- eval $app $audio_opts "\"$1\"" $bg
+ eval $app $opts "\"$1\"" $bg
exit 0
fi
#------------------ VIDEO -------------------
if [ "$2" == "video" ]; then
app=mpv
- # To start mpv in a window enable video_opts
- #video_opts="--no-terminal --force-window"
+ # To start mpv in a window enable opts
+ #opts="--no-terminal --force-window"
#bg=">/dev/null 2>&1 &"
killall -9 $app >/dev/null 2>&1
fi
- eval $app $video_opts "\"$1\"" $bg
+ eval $app $opts "\"$1\"" $bg
exit 0
fi
#------------------ IMAGE -------------------
if [ "$2" == "image" ]; then
app=viewnior
- #image_opts=
+ #opts=
bg=">/dev/null 2>&1 &"
- eval $app $image_opts "\"$1\"" $bg
+ eval $app $opts "\"$1\"" $bg
exit 0
fi
#------------------- PDF --------------------
if [ "$2" == "pdf" ]; then
app=zathura
- #pdf_opts=
+ #opts=
bg=">/dev/null 2>&1 &"
- eval $app $pdf_opts "\"$1\"" $bg
+ eval $app $opts "\"$1\"" $bg
exit 0
fi
#---------------- PLAINTEXT -----------------
if [ "$2" == "text" ]; then
app=vim
- #txt_opts=
+ #opts=
#bg=">/dev/null 2>&1 &"
- eval $app $txt_opts "\"$1\"" $bg
+ eval $app $opts "\"$1\"" $bg
exit 0
fi
#----------------- SEARCH -------------------
if [ "$2" == "search" ]; then
app=gnome-search-tool
- #search_opts=
+ #opts=
bg=">/dev/null 2>&1 &"
- eval $app $search_opts --path "\"$1\"" $bg
+ eval $app $opts --path "\"$1\"" $bg
+ exit 0
+fi
+
+#--------------- SCREENSAVER ----------------
+if [ "$2" == "screensaver" ]; then
+ app=vlock
+ #opts=
+
+ #bg=">/dev/null 2>&1 &"
+
+ eval $app $opts $bg
exit 0
fi
Force a redraw
.It Ic \&?
Toggle help screen
-.It Ic q
-Quit
.It Ic Q
Quit and change directory
+.It Ic q, ^Q
+Quit
.El
.Pp
Backing up one directory level will set the cursor position at the
mime opener to use as a fallback when no association is set for a file
type. Custom associations are listed in the EXAMPLES section below.
.Pp
+\fBNNN_IDLE_TIMEOUT:\fR set idle timeout (in seconds) to invoke terminal
+screensaver.
+.Pp
\fBNNN_COPIER:\fR set to a clipboard copier script. For example, on Linux:
.Bd -literal
-------------------------------------
static int idle;
static char *opener;
static char *fb_opener;
+static char *nlay="nlay";
static char *player;
static char *copier;
static char *desktop_manager;
* - 0b1: draw a marker to indicate nnn spawned e.g., a shell
* - 0b10: do not wait in parent for child process e.g. DE file manager
* - 0b100: suppress stdout and stderr
+ * - 0b1000: restore default SIGINT handler
*/
static void
spawn(char *file, char *arg1, char *arg2, char *dir, unsigned char flag)
close(fd);
}
+ if (flag & 0b1000)
+ signal(SIGINT, SIG_DFL);
execlp(file, file, arg1, arg2, NULL);
_exit(1);
} else {
printprompt(ln);
break;
case CONTROL('L'):
- cur = oldcur;
- *ch = CONTROL('L');
+ cur = oldcur; // fallthrough
+ case CONTROL('Q'):
goto end;
default:
wln[len++] = (wchar_t)*ch;
^K | Invoke file name copier\n\
^L | Force a redraw\n\
? | Toggle help screen\n\
- q | Quit\n\
- Q | Quit and change directory\n\n\" | less");
+ Q | Quit and change directory\n\
+ q, ^Q | Quit\n\n\" | less");
return system(helpstr);
}
mime = getmime(dents[cur].name);
if (mime) {
exitcurses();
- if (player)
- spawn(player, newpath, mime, NULL, 0);
- else
- spawn("nlay", newpath, mime, NULL, 0);
+ spawn(player, newpath, mime, NULL, 0);
initcurses();
continue;
}
goto nochange;
case SEL_SEARCH:
exitcurses();
- if (player)
- spawn(player, path, "search", NULL, 0);
- else
- spawn("nlay", path, "search", NULL, 0);
+ spawn(player, path, "search", NULL, 0);
initcurses();
break;
case SEL_NEXT:
if (idletimeout != 0 && idle == idletimeout) {
idle = 0;
exitcurses();
- spawn(idlecmd, NULL, NULL, NULL, 0);
+ spawn(player, "", "screensaver", NULL, 8);
initcurses();
}
}
case 'v':
fprintf(stdout, "%s\n", VERSION);
return 0;
- case 'h':
+ case 'h': // fallthrough
default:
usage();
}
/* Get the default desktop mime opener, if set */
opener = getenv("NNN_OPENER");
+ /* Set player if not set already */
+ if (!player)
+ player = nlay;
+
/* Get the fallback desktop mime opener, if set */
fb_opener = getenv("NNN_FALLBACK_OPENER");
/* Get the desktop file browser, if set */
desktop_manager = getenv("NNN_DE_FILE_MANAGER");
+ /* Get screensaver wait time, if set; copier used as tmp var */
+ copier = getenv("NNN_IDLE_TIMEOUT");
+ if (copier)
+ idletimeout = abs(atoi(copier));
+
/* Get the default copier, if set */
copier = getenv("NNN_COPIER");