mirror of
https://github.com/jarun/nnn.git
synced 2024-11-24 11:51:27 +00:00
Add an option to print hovered files to a FIFO (#548)
* Add an option to print hovered files to a FIFO This adds an env variable, `NNN_FIFO`, that can be set to a path that `nnn` will open/create as a FIFO, and where every hovered file's path is printed. This allows creating external perview/quick open plugins, ... It can be compiled out with the make variable `O_NOFIFO`. * Check filename ptr instead of full path (for FIFO) * Add documentation to use NNN_FIFO in plugins * Fix path sent to FIFO in empty dirs
This commit is contained in:
parent
b5de18c28f
commit
86e579799b
4
Makefile
4
Makefile
|
@ -57,6 +57,10 @@ ifeq ($(O_NOBATCH),1)
|
||||||
CPPFLAGS += -DNOBATCH
|
CPPFLAGS += -DNOBATCH
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
ifeq ($(O_NOFIFO),1)
|
||||||
|
CPPFLAGS += -DNOFIFO
|
||||||
|
endif
|
||||||
|
|
||||||
ifeq ($(shell $(PKG_CONFIG) ncursesw && echo 1),1)
|
ifeq ($(shell $(PKG_CONFIG) ncursesw && echo 1),1)
|
||||||
CFLAGS_CURSES ?= $(shell $(PKG_CONFIG) --cflags ncursesw)
|
CFLAGS_CURSES ?= $(shell $(PKG_CONFIG) --cflags ncursesw)
|
||||||
LDLIBS_CURSES ?= $(shell $(PKG_CONFIG) --libs ncursesw)
|
LDLIBS_CURSES ?= $(shell $(PKG_CONFIG) --libs ncursesw)
|
||||||
|
|
7
nnn.1
7
nnn.1
|
@ -423,6 +423,13 @@ separated by \fI;\fR:
|
||||||
.Pp
|
.Pp
|
||||||
\fBNNN_SEL:\fR absolute path to custom selection file.
|
\fBNNN_SEL:\fR absolute path to custom selection file.
|
||||||
.Pp
|
.Pp
|
||||||
|
\fBNNN_FIFO:\fR path of a named pipe to write current file path:
|
||||||
|
.Bd -literal
|
||||||
|
export NNN_FIFO='/tmp/nnn.fifo'
|
||||||
|
|
||||||
|
NOTE: If the FIFO file doesn't exist it will be created, but it will never be removed.
|
||||||
|
.Ed
|
||||||
|
.Pp
|
||||||
\fBnnn:\fR this is a special variable set to the hovered entry before executing
|
\fBnnn:\fR this is a special variable set to the hovered entry before executing
|
||||||
a command from the command prompt or spawning a shell.
|
a command from the command prompt or spawning a shell.
|
||||||
.Pp
|
.Pp
|
||||||
|
|
|
@ -190,7 +190,7 @@ Usage examples can be found in the Examples section below.
|
||||||
There are many plugins provided by `nnn` which can be used as examples. Here are a few simple selected examples.
|
There are many plugins provided by `nnn` which can be used as examples. Here are a few simple selected examples.
|
||||||
|
|
||||||
- Show the git log of changes to the particular file along with the code for a quick and easy review.
|
- Show the git log of changes to the particular file along with the code for a quick and easy review.
|
||||||
```sh
|
```sh
|
||||||
#!/usr/bin/env sh
|
#!/usr/bin/env sh
|
||||||
git log -p -- "$1"
|
git log -p -- "$1"
|
||||||
```
|
```
|
||||||
|
@ -220,6 +220,40 @@ There are many plugins provided by `nnn` which can be used as examples. Here are
|
||||||
printf "%s" "0c$dir" > "$NNN_PIPE"
|
printf "%s" "0c$dir" > "$NNN_PIPE"
|
||||||
```
|
```
|
||||||
|
|
||||||
|
#### Get notified on file hover
|
||||||
|
|
||||||
|
If `NNN_FIFO` is set, `nnn` will open it and write every hovered files.
|
||||||
|
This can be used in plugins, e.g. to implement file previews.
|
||||||
|
|
||||||
|
If a `NNN_FIFO` is set globally, each `nnn` instance will write to it, and a process reading from the pipe will get hovered path from every instance, interleaved.
|
||||||
|
|
||||||
|
If you want to prevent this and be sure to have a private pipe to one `nnn` instance, you can unlink (remove) the FIFO file.
|
||||||
|
If you opened the FIFO before and you have read from it (so that `nnn` have it opened too), you can still read from it while you don't close it.
|
||||||
|
But new `nnn` instances will recreate a new FIFO not linked to the previous one.
|
||||||
|
|
||||||
|
Don't forget to fork in the background to avoid blocking `nnn`.
|
||||||
|
|
||||||
|
Example (send every hovered file to X selection):
|
||||||
|
|
||||||
|
```sh
|
||||||
|
#!/usr/bin/env sh
|
||||||
|
if [ -z "$NNN_FIFO" ] ; then
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
while read FILE ; do
|
||||||
|
if [ -n "$NNN_FIFO" ] ; then
|
||||||
|
# If you want to remove the FIFO,
|
||||||
|
# don't do it before first read,
|
||||||
|
# nnn won't have it opened yet
|
||||||
|
rm "$NNN_FIFO"
|
||||||
|
NNN_FIFO=
|
||||||
|
fi
|
||||||
|
printf "%s" "$FILE" | xsel
|
||||||
|
done < "$NNN_FIFO" &
|
||||||
|
disown
|
||||||
|
```
|
||||||
|
|
||||||
## Contributing plugins
|
## Contributing plugins
|
||||||
|
|
||||||
1. Add informative sections like _Description_, _Notes_, _Dependencies_, _Shell_, _Author_ etc. in the plugin.
|
1. Add informative sections like _Description_, _Notes_, _Dependencies_, _Shell_, _Author_ etc. in the plugin.
|
||||||
|
|
63
src/nnn.c
63
src/nnn.c
|
@ -330,6 +330,9 @@ static context g_ctx[CTX_MAX] __attribute__ ((aligned));
|
||||||
|
|
||||||
static int ndents, cur, last, curscroll, last_curscroll, total_dents = ENTRY_INCR;
|
static int ndents, cur, last, curscroll, last_curscroll, total_dents = ENTRY_INCR;
|
||||||
static int nselected;
|
static int nselected;
|
||||||
|
#ifndef NOFIFO
|
||||||
|
static int fifofd = -1;
|
||||||
|
#endif
|
||||||
static uint idletimeout, selbufpos, lastappendpos, selbuflen;
|
static uint idletimeout, selbufpos, lastappendpos, selbuflen;
|
||||||
static ushort xlines, xcols;
|
static ushort xlines, xcols;
|
||||||
static ushort idle;
|
static ushort idle;
|
||||||
|
@ -350,6 +353,9 @@ static char *prefixpath;
|
||||||
static char *plugindir;
|
static char *plugindir;
|
||||||
static char *sessiondir;
|
static char *sessiondir;
|
||||||
static char *pnamebuf, *pselbuf;
|
static char *pnamebuf, *pselbuf;
|
||||||
|
#ifndef NOFIFO
|
||||||
|
static char *fifopath;
|
||||||
|
#endif
|
||||||
static ull *ihashbmp;
|
static ull *ihashbmp;
|
||||||
static struct entry *dents;
|
static struct entry *dents;
|
||||||
static blkcnt_t ent_blocks;
|
static blkcnt_t ent_blocks;
|
||||||
|
@ -4667,6 +4673,40 @@ static void populate(char *path, char *lastname)
|
||||||
last_curscroll = -1;
|
last_curscroll = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef NOFIFO
|
||||||
|
static void notify_fifo()
|
||||||
|
{
|
||||||
|
if (fifofd == -1) {
|
||||||
|
fifofd = open(fifopath, O_WRONLY|O_NONBLOCK);
|
||||||
|
if (fifofd == -1) {
|
||||||
|
if (errno != ENXIO)
|
||||||
|
/* Unexpected error, the FIFO file might have been removed */
|
||||||
|
/* We give up FIFO notification */
|
||||||
|
fifopath = NULL;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static char *name = NULL;
|
||||||
|
|
||||||
|
if (dents[cur].name == name)
|
||||||
|
return;
|
||||||
|
|
||||||
|
name = dents[cur].name;
|
||||||
|
|
||||||
|
char path[PATH_MAX];
|
||||||
|
size_t len = mkpath(g_ctx[cfg.curctx].c_path, ndents ? name : "", path);
|
||||||
|
|
||||||
|
path[len - 1] = '\n';
|
||||||
|
|
||||||
|
ssize_t ret = write(fifofd, path, len);
|
||||||
|
|
||||||
|
if (ret != (ssize_t)len && !(ret == -1 && (errno == EAGAIN || errno == EPIPE))) {
|
||||||
|
DPRINTF_S(strerror(errno));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
static void move_cursor(int target, int ignore_scrolloff)
|
static void move_cursor(int target, int ignore_scrolloff)
|
||||||
{
|
{
|
||||||
int onscreen = xlines - 4; /* Leave top 2 and bottom 2 lines */
|
int onscreen = xlines - 4; /* Leave top 2 and bottom 2 lines */
|
||||||
|
@ -4693,6 +4733,11 @@ static void move_cursor(int target, int ignore_scrolloff)
|
||||||
}
|
}
|
||||||
curscroll = MIN(curscroll, MIN(cur, ndents - onscreen));
|
curscroll = MIN(curscroll, MIN(cur, ndents - onscreen));
|
||||||
curscroll = MAX(curscroll, MAX(cur - (onscreen - 1), 0));
|
curscroll = MAX(curscroll, MAX(cur - (onscreen - 1), 0));
|
||||||
|
|
||||||
|
#ifndef NOFIFO
|
||||||
|
if (fifopath)
|
||||||
|
notify_fifo();
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
static void handle_screen_move(enum action sel)
|
static void handle_screen_move(enum action sel)
|
||||||
|
@ -7022,6 +7067,19 @@ int main(int argc, char *argv[])
|
||||||
|
|
||||||
DPRINTF_S(getenv("PWD"));
|
DPRINTF_S(getenv("PWD"));
|
||||||
|
|
||||||
|
#ifndef NOFIFO
|
||||||
|
/* Create fifo */
|
||||||
|
fifopath = getenv("NNN_FIFO");
|
||||||
|
if (fifopath) {
|
||||||
|
if (mkfifo(fifopath, 0600) != 0 && !(errno == EEXIST && access(fifopath, W_OK) == 0)) {
|
||||||
|
xerror();
|
||||||
|
return _FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
signal(SIGPIPE, SIG_IGN);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef LINUX_INOTIFY
|
#ifdef LINUX_INOTIFY
|
||||||
/* Initialize inotify */
|
/* Initialize inotify */
|
||||||
inotify_fd = inotify_init1(IN_NONBLOCK);
|
inotify_fd = inotify_init1(IN_NONBLOCK);
|
||||||
|
@ -7145,5 +7203,10 @@ int main(int argc, char *argv[])
|
||||||
haiku_close_nm(haiku_hnd);
|
haiku_close_nm(haiku_hnd);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifndef NOFIFO
|
||||||
|
if (fifofd != -1)
|
||||||
|
close(fifofd);
|
||||||
|
#endif
|
||||||
|
|
||||||
return opt;
|
return opt;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue