jarun / nnn

n³ The unorthodox terminal file manager
BSD 2-Clause "Simplified" License
19.31k stars 762 forks source link

Having hooks #547

Closed sucrecacao closed 4 years ago

sucrecacao commented 4 years ago

Is your feature request related to a problem? Please describe.

I understand than nnn don't want to implement any kind of preview design. But having to press a key on every files to preview them can be annoying. Being able to hook a "preview script" on an given event ( in this case change of the current selected file ) could be very handy to preview file dynamically.

A clear and concise description of what the problem is.

Not being able to run a script on a hook, and having to press a key every time to run a script/plugin.

Describe the solution you'd like Follow the git / task warrior hook system:
having a hooks folder which contain hook file. a hook file start with "on-" followed by the hook type. For example:

on-change-current      # called everytime we change the current selected file
on-change-directory   # called when we enter a directory
on-exit                        # called when exiting nnn

A clear and concise description of what you want to happen.

When I press 'j' or 'k' in nnn and change the current selected file or dir, the script written in the file hooks/on-change-current is run with $1 being the new current selected file/dir.

jarun commented 4 years ago

When I press 'j' or 'k' in nnn and change the current selected file or dir, the script written in the file hooks/on-change-current is run with $1 being the new current selected file/dir.

We can't run a script on every keypress.

But having to press a key on every files to preview them can be annoying.

You can always open a directory of files in an image viewer like sxiv as thumbnails and browse them. nnn is not about image previews using different utilities and hacks for different kinds of files.

jarun commented 4 years ago

Some more details in the design notes: https://github.com/jarun/nnn/wiki#design

There are several good file managers which already do what you are looking for. Pick one of those.

sucrecacao commented 4 years ago

You can always open a directory of files in an image viewer like sxiv as thumbnails and browse them. nnn is not about image previews using different utilities and hacks for different kinds of files.

There are several good file managers which already do what you are looking for. Pick one of those.

Hooks is the requested feature, not previews. I just used it as an example.

I used preview has an example because it show how hooks could help user extend nnn to implement popular feature without changing its UNIX orthodoxies. Previews would be handled by external program.

We can't run a script on every keypress.

nnn won't run script on every keypress. It would run q script on certain event only if the user create a hook on that particular event.

jarun commented 4 years ago

It would run q script on certain event

which essentially means we will have to add checkpoints in several places and if enabled run the script as well.

jarun commented 4 years ago

Can you share some examples which are not achievable by plugins?

0xACE commented 4 years ago

Can you share some examples which are not achievable by plugins?

The idea I have had regarding this issue is: nnn piping output to a file-pipe where another program listens to it.

This would help with having a external program live preview the directory you are in to show thumbnails of images etc... or even have it open movie you are hovering over etc...

jarun commented 4 years ago

I get that but why do we need to keep writing to a pipe when we can open the directory in an external image viewer or image manager?

0xACE commented 4 years ago

Because this allows you to get a live preview in a actual viewer without having to invoking a secondary action.

For example I've set my media player to open up in the same instance when i open a file in nnn so that i can preview the video without having to change video etc (usually requiering you to close the previous window)... but this is only temporary until i get to spend time on nnn again...

I don't expect to have it on upstream but my intention is to have it on my personal build.

This would be more versatile than the current plugin system in some cases. You could implement your own plugin which gives you a live scrolling preview of the media file you are hovering over etc...

It's too much to put into words atm, but these are some of the plans/desires I've had.

jarun commented 4 years ago

Got it. Feel free to raise a PR within a macro. That way we can have it mainline and people like myself can continue mostly with non-multimedia stuff without having to compile this in.

0xACE commented 4 years ago

By the look of my current progress with nnn I wouldn't advise holding your breath waiting for it...

toddyamakawa commented 4 years ago

By the look of my current progress with nnn I wouldn't advise holding your breath waiting for it...

I took a quick look at the code and I don't understand where the "cd" happens. I would imagine somewhere there's one main place where the directory changes. Where does that piece of code live? Then in that function that's where the write to NNN_PIPE would take place, so in theory a lot of the pieces are already there.

leovilok commented 4 years ago

@0xACE @toddyamakawa See #548 (And I have a shell script around somewhere, which would allow implementing basic preview using this feature)

jarun commented 4 years ago

@sucrecacao this is being implemented at PR #548.

When it's in, can you share a working example of preview on hover in progress?

sucrecacao commented 4 years ago

Wow Nice ! this is an amazing improvement that is very helpful for previewing files.

But I think the discussion has deviate to another subject that is previewing, while my initial goal was to implements hooks ( which could also solve the previewing problem).

Can you share some examples which are not achievable by plugins?

None of the hooks can be achievable via plugins. But all plugin can be called by hooks. You can see hooks has a way to "trigger" plugin automatically on specific nnn event, without having to press any keystroke.

An example in python/pseudo-code ( my C is not that good) to git pull automatically when entering specific directory .

In nnn.c place this where in the change to a new directory happen: ( with dir_name a variable containing the name directory we just entered. )

if exists.path.exists('~/.config/nnn/hooks/on-change-directory.sh'):
    subprocess.call(['~/.config/nnn/hooks/on-change-directory.sh', dir_name])

in on-change-directory.sh

$dir_name=$1
if [ $dir_name == 'my_cool_project' ]; then
    git pull origin master &
fi
jarun commented 4 years ago

@leovilok is this what we are trying to achieve?

jarun commented 4 years ago

OK. I got it from @leovilok's screencast.

leovilok commented 4 years ago

I didn't implement the hook system, just a FIFO (pipe) where evey file hovered in nnn is printed. With this system, it's trivial to build some hooks:

HOOKDIR="~/.config/nnn-hooks"
DIR=""
while read FILE ; do
    NEWDIR="$(dirname "$FILE")"
    if [ "$NEWDIR" != "$DIR" ] ; then
        "$HOOKDIR"/on-change-directory.sh "$NEWDIR"
        DIR="$NEWDIR"
    fi
    "$HOOKDIR"/on-change-current.sh "$FILE"
done < "$NNN_FIFO"
"$HOOKDIR"/on-exit.sh
leovilok commented 4 years ago

@sucrecacao you could clean this up and make it a plugin, but it would need to fork in the background.

0xACE commented 4 years ago

Technically he could get the directory by looking at the dirname of the hovered file

leovilok commented 4 years ago

@0xACE that's what my example does, see above.

toddyamakawa commented 4 years ago

I didn't implement the hook system, just a FIFO (pipe) where evey file hovered in nnn is printed. With this system, it's trivial to build some hooks:

This is even better than what I wanted. I would have been happy with a directory change, but now with the full path to every file the possibilities are endless. Thank you @leovilok!

jarun commented 4 years ago

Fixed at #548.

sucrecacao commented 4 years ago

Thanks @leovilok and @jarun I just see one issue when the user launch multiple instance of nnn. Only the first one is writing to the FIFO file. One solution could be to pass the FIFO path as an argument: nnn --fifo /tmp/nnn.fifo

0xACE commented 4 years ago

@sucrecacao see https://github.com/jarun/nnn/pull/548#issuecomment-623241260

also that thread brings up this topic and a proposed method of usage. It's a bit sidewards but, meh, in the end it works just the same... Just rm "$NNN_FIFO" after you have read from it.

leovilok commented 4 years ago

@sucrecacao

I just see one issue when the user launch multiple instance of nnn. Only the first one is writing to the FIFO file.

No. If you launch multiple instances of nnn with the same path in NNN_FIFO, they will all write to the same FIFO, and the reader will get path from both instances.

One solution could be to pass the FIFO path as an argument: nnn --fifo /tmp/nnn.fifo

You can achieve the same by running nnn that way:

NNN_FIFO=/tmp/fifo1 nnn
...
NNN_FIFO=/tmp/fifo2 nnn
leovilok commented 4 years ago

See also (as @0xACE mentionnend) the method described here: https://github.com/jarun/nnn/tree/master/plugins#get-notified-on-file-hover And the last example of the next section.