ToDo list
Closed this issue Β· 56 comments
Rolled from #483.
Ready for next release
- an official logo
- previews
- config
NNN_FIFO
to write hovered file paths a previewer can read - plugin
preview-tabbed
: tabbed/xembed based file previewer - plugin
preview-tui
: simple TUI file previewer in tmux/xterm - plugin
preview-kitty
: preview using kitty terminal's capabilities - live preview configuration example
- config
- find & list
- send list of files from (cmd run as) plugin to
nnn
- plugin
finder
: find/fd/fzf/grep/ripgrep/fzf (in subtree) and list innnn
- Right or l on symlink in list dir takes to target file
- send list of files from (cmd run as) plugin to
- persistent session option
-S
[for disk usage, runnnn -T d
(see help)] - hover on the file when a file path is passed as positional argument
- go to first file or match with ' (followed by ' or char)
- config
NNN_SEL
to specify custom selection file - config
NNN_LOCKER
to specify locker program - dim file details in detail mode
- call
chdir()
on directory change - option
-l
: number of lines to move on mouse scroll - graphical keybind map
- let
NNN_COLORS
overrideNO_COLOR
- plugins
- option
-P
: run plugin by key at start - run plugins with Alt+key
- allow
NNN_PIPE
usage by commands run as plugin - input format to
NNN_PIPE
:<ctxcode><opcode><data>
(see plugins doc) - set
ctxcode
to+
for smart context usage (next inactive, else current) getplugs
to fetch plugins by installed version ofnnn
- plugin
mimelist
: list files by mime type in subtree - plugin
bookmarks
: named bookmarks using symlinks - plugin
nbak
: backupnnn
config nuke
adds lowdown as alternative markdown viewer- several plugin improvements
- option
- fix broken screen on resize (see #520)
- fix broken version sort (see #550)
- fix list and pipe modes not working together
- fix multiple issues with listing files
- fix
@
shown in detail mode for symlink to dir - fix listing files directly under
/
- move to
-std=c11
Proposed features and tasks (up for grabs)
- a plugin for GPG based encryption
- make the context-specific code generic, support up to 8 contexts (@0xACE)
- support pre-defined filters like bookmarks
- a video exploring
nnn
plugins - move hardware cursor to selected item (see #534)
Anything else which would add value (please discuss in this thread).
Feature Request
Hi, thank you so much for this wonderful command line tool. Is there any plan to enhance fzopen
plugin? Something like adding $FZF_DEFAULT_COMMAND
so it can be used to exclude some directories that were specified inside $FZF_DEFAULT_COMMAND
such as .git
, node_modules
, etc. Because currently find
command tries to indexing all files and directories.
Line 13 in a8da997
Let me know what you think. Feel free to send a PR
Yes sure, please raise a PR.
Got a question:
Shouldn't both FZF_DEFAULT_COMMAND and FZF_DEFAULT_OPTS work if they are defined?
Not at this moment. It only reads $FZF_DEFAULT_OPTS
Note: both already defined
Shouldn't that be fixed in fzf instead of the plugin?
It works if I run outside fzopen
(zsh, bash, vim, etc) but the problem comes in when I try to search inside fzopen
. I think the problem because find
command that is using in this plugin
I see. See if it can be fixed.
Is the -c parameter limited to nuke ?
If I have: xdg-mime query default image/jpeg -> chromium.desktop, nnn -c will open images in chromium. Do I need to have NNN_OPENER specified ?
Is the -c parameter limited to nuke ?
No, you can use it with any custom cli opener.
Yes, you'll have to specify the path to the custom opener in NNN_OPENER
.
Hmm maybe I'm doing something wrong. I've attached a short screen recording.
-
In the image you are running
nnn
, so the image will open usingxdg-open
. -
To open using
nuke
or any other opener, you have to- set
NNN_OPENER
- use
nnn -c
- set
-
If you want to use
xdg-open
, usexdg-mime
to set the default app for images to something likegpicview
.
I set the NNN_OPENER env var using that alias I made for nnn. It's in the upper right terminal.
I'm probably confused about how the -c parameter works. Does nnn actually have a way to control if a file will be opened in something that is not cli ?
In your case:
NNN_OPENER=xdg-open
means you want to open files in xdg-open
.
Then you have:
xdg-mime query default image/jpeg
chromium.desktop
So images will open in chromium. What is your expectation?
If you do NOT want to open images using chromium see this: https://unix.stackexchange.com/a/59088/164910
I'm probably confused about how the -c parameter works.
If you want to set xdg-open
as opener you do NOT have to use -c
.
Does nnn actually have a way to control if a file will be opened in something that is not cli ?
There's no issue with nnn
here. You have set xdg-open
as your opener and the images are set to open in chromium. That's the expected result. Check the link I shared above to set the application to open images from chromium to something else.
What application do you want to open images in?
Forgive me but what is the use case for "-c" if some file will open in a graphical application regardless if the NNN_OPENER is set or not ?
I honestly expected nnn -c to just not open a image in chromium because chromium is a graphical application.
if some file will open in a graphical application regardless if the NNN_OPENER is set or not
Your opener is xdg-open
, which is a graphical opener, and that decides which application will open your images (in this case, chromium). Using -c
in nnn
doesn't change the behaviour of your opener. The option -c
cannot change a graphical opener to cli opener.
What open -c
does is - it blocks when it spawns the opener. This is useful when you want to edit a file in the cli (nnn
has to wait otherwise your editor e.g. will never show). Without the -c
option nnn
doesn't open for the opener to exit.
Yes, xdg-open
does behave like a cli opener in the virtual terminal environment and chooses cli applications. But it detects a virtual terminal using environment variables etc. In your case you are in a desktop environment. So xdg-open
will open files using regular GUI desktop apps (like chromium). Any option in nnn
cannot change that.
Using
-c
innnn
doesn't change the behaviour of your opener.
I see. Thank you. What does it actually do ? Because in the man page it says this:
opener opens files in cli utilities only (overrides -e)
EDIT: Saw your edit. Thanks again.
I added more details in my earlier answer.
opener opens files in cli utilities only (overrides -e)
It doesn't mean that the option forces opener to open files in CLI utilities only. It means that when the user sets this flag he is indicating to nnn
that the opener opens files in CLI apps only.
Anyway, I see why it's confusing. I will update it.
Firstly, can you elaborate on this feature?
support pre-defined filters like bookmarks
I wrote myself a plugin that seems to work pretty well:
https://github.com/toddyamakawa/bin/blob/master/nnn-bookmarks
If my plugin looks like something thatβs usable and what you envisioned, I could write it in such a way that it removes the fzf
dependency.
I have a lot of ideas for features that I think could be useful:
- When a plugin gets run, if it has a non-zero exit code I think that
nnn
should display the output for the user. This would make writing and debugging plugins a lot easier. - Speaking of plugins, instead of putting all the plugins in the
~/.config/nnn/plugins
directory, I think it would be great ifnnn
instead searched$PATH
for anynnn-
commands. That way I could specify mynnn-bookmarks
command by setting the environment variable tob:bookmarks
- I think
nnn
should always open a pipe, and every time the directory is changed, it writes the directory to the pipe. This would enable another process to watch the pipe and react to those changes, e.g. another tmux pane that displays things about the directorynnn
is currently in. This would enable us to write some really cool plugins.
Firstly, can you elaborate on this feature?
This is for pre-defined filters a user can set like NNN_BMS or NNN_PLUG and apply. The implementation should follow the current ones.
I wrote myself a plugin that seems to work pretty well
Can you please explain what it does? And in which workflow would it replace fzf?
if it has a non-zero exit code I think that nnn should display the output for the user
That would be very useful indeed.
I think it would be great if nnn instead searched
- we want to have a distinct repo
- it also makes listing the plugins easy
- it's not possible to remember shortcuts for all plugins
- we can't search $PATH for all plugins and list them in a custom view
- it also doesn't need
sudo
permissions to install (of course you can extend $PATH but still... we now provide static binary)
I think nnn should always open a pipe, and every time the directory is changed, it writes the directory to the pipe.
That's a lot of disk writes unless your /tmp is tmpfs (maybe we could have a keybind to do that explicitly?).
@toddyamakawa can you also take a look at my request at #520 (comment)?
Firstly, can you elaborate on this feature?
This is for pre-defined filters a user can set like NNN_BMS or NNN_PLUG and apply. The implementation should follow the current ones.
Ah, I misunderstood what the feature does. I do not have a predefined filter.
I wrote myself a plugin that seems to work pretty well
Can you please explain what it does? And in which workflow would it replace fzf?
I have a bunch of symlinks I use in my $HOME/.links
directory (although if I turned it into a plugin I would probably change that to $HOME/.config/nnn/bookmarks
or something). My plugin will cd
into one of the symlinks by using fzf
. This effectively gets over the limit on the number of bookmarks a user can have and it allows you to "name" the bookmarks.
I think it would be great if nnn instead searched
we want to have a distinct repo
it also makes listing the plugins easy
- it's not possible to remember shortcuts for all plugins
- we can't search $PATH for all plugins and list them in a custom view
it also doesn't need
sudo
permissions to install (of course you can extend $PATH but still... we now provide static binary)
I personally think that $PATH
feels more like the *nix way. e.g. if you add a git-<CMD>
command to $PATH
, then run git <CMD>
, then git
will automatically search for the command and run it. nnn
is one of those tools that doesn't need a config file because it uses environment variables. This would bring it one step closer to getting rid of the need for a specific config directory. I think a lot of power users probably already have their own bin
directories that they extend $PATH
with.
Does nnn
currently display all plugins somewhere or is it just mapped plugins? There are definitely ways to list all the plugins if it's needed, but it definitely isn't pretty, and will definitely be harder in C.
echo "$PATH" | tr ':' '\n' | xargs -I % bash -c 'ls -l %/nnn-*' 2>/dev/null
I think nnn should always open a pipe, and every time the directory is changed, it writes the directory to the pipe.
That's a lot of disk writes unless your /tmp is tmpfs (maybe we could have a keybind to do that explicitly?).
Good point, I didn't think about that. I guess it would be better to map a key binding or a flag.
I have a bunch of symlinks
Why not create a file with the paths?
Also, on a side note, there are no limits to bookmarks in v3.1.
I would probably change that to $HOME/.config/nnn/bookmarks or something
Plugin gutenbook
uses DIR="${XDG_CACHE_HOME:-$HOME/.cache}/nnn/gutenbooks/$EBOOK_ID"
feels more like the *nix way
We can't drop the listing plugins feature. And this also affects run-cmd-as-plugin, now when we have such a command ls
can also mean nnn-ls
. I do not want to parse the cmd
token and do this. I think we are much more organized with what we have today. The last thing I ever want is to parse PATH, touch the filesystem in the core file manager.
Also, we do not run commands with nnn
like we do with git. I would like to keep this clean. That's the reason we also don't invoke 5 different utilities in 5 different languages with 5 different params to show images for 5 different mimes in 5 ways for for 5 different terminals, you see. ;)
This would bring it one step closer to getting rid of the need for a specific config directory.
Not having a config file and not having a config dir are different. We still need to store sessions, selection file and so on...
Does nnn currently display all plugins somewhere or is it just mapped plugins?
It does. ;
-> Enter
.
I have a bunch of symlinks
Why not create a file with the paths?
I guess my plugin on the surface looks like a duplicate of the fzz
plugin. There are two good things about symlinks:
- It has a name.
name -> directory
- I use directories with a bunch of symlinks in my $CDPATH.
Also, on a side note, there are no limits to bookmarks in v3.1.
I think the one limitation with the built-in bookmarks is you have to remember which letter is mapped to which bookmark or you have to look it up first with ?
. If you have 30+
bookmarks and you haven't used some of them in a while, then using fzf
would make it easier.
ls
can also meannnn-ls
.
The mappings would be different though. nnn-ls
would be l:ls
and ls
would be l:_ls
Does nnn currently display all plugins somewhere or is it just mapped plugins?
It does.
;
->Enter
.
Good to know. Thanks!
Anyways, I understand everything you're saying. nnn
has a really cool paradigm in the way that it was developed. It's very easy to use and configure, and (once you figure it out) very easy to extend with plugins.
It does feel like having a config directory sort of conflicts with not having a config file and that setting things with environment variables sort of conflicts with having a config directory, but everything does work really well together.
It has a name. name -> directory
Have entries in the file as: name -> path
And then parse the file output in fzf to show only the first column.
I am insisting on text as it is much easy to configure and edit and only 1 additional file on the disk.
then using fzf would make it easier
Yes, I am OK with adding a plugin that works as the fallback. And we won't have z dep either. I would love it if we could get rid of the fzf dep too.
The mappings would be different though. nnn-ls would be l:ls and ls would be l:_ls
Let's not have this. We are well-provisioned with the current mechanism.
It does feel like having a config directory sort of conflicts with not having a config file and that setting things with environment variables sort of conflicts with having a config directory
The config file isn't there because we don't want to load and read a file from disk every time we start. There's no such issue with dirs.
Also, see my dev-room note on the backup thing. We can do those because we are well organised. Maybe we should have the bookmark file in config dir so that also gets backed up without any additional effort.
But to do that, we need to get the plugin work without fzf or have a way to handle if fzf is not installed.
It has a name. name -> directory
Have entries in the file as: name -> path
And then parse the file output in fzf to show only the first column.
I am insisting on text as it is much easy to configure and edit and only 1 additional file on the disk.
name -> path
was an oversimplification since each symlink is a file, which gives additional information like timestamps and group permissions for additional things to filter on. Plus it's impossible to have a syntax error since it's not all in a file.
then using fzf would make it easier
Yes, I am OK with adding a plugin that works as the fallback. And we won't have z dep either. I would love it if we could get rid of the fzf dep too.
I've never looked at z
. Does it just use a text file in the home directory? If so, it should be trivial to rewrite fzz
to not have an fzf
or z
dependency if we use the select
command.
The config file isn't there because we don't want to load and read a file from disk every time we start. There's no such issue with dirs.
I didn't even think about that. Thanks for the explanation
In the current state, is possible to write a plugin to display file icons using a patched font?
In the current state, is possible to write a plugin to display file icons using a patched font?
And why do we need to do that in nnn
?
@RibalGZ we do not want to make nnn
a copy of another file manager with tons of fancy features. nnn
provides string/regex filters, sort by extension which are dead simple to use and much more effective in finding the file you want. How does showing an icon or a different color help in finding an executable in /bin
?
The main goal of nnn
still remains to be text-based and simple.
In the current state, is possible to write a plugin to display file icons using a patched font?
And why do we need to do that in
nnn
?
Again, it's related to being able to determine information in more ways than just reading file names...
Now i don't find icons necessary, but thumbnails help a lot with pictures... but I guess a image browser fits better for this goal, considering we are in the terminal...
So really: it's not exactly necessary in nnn
's case...
@RibalGZ I asked in the private dev-discussion thread:
Could
nnn
spew out the conents it's listing to the script in this case?
This would allow a seperate script to run along side nnn
and let you list information per line...
Didn't receive an answer, but I may add it on my local copy in the future as I find this useful, as it allows you to virtually add extra columns to nnn
as you wish.
Could nnn spew out the conents it's listing to the script in this case?
I missed this. That would be too much data written on each hover. Yes, it's probably better to maintain in a fork if you fin it useful. You can refer to the code for handling SEL_EXPORT
.
@RibalGZ I checked the feasibility. It would need a regex match per file. Too heavy for nnn
standards.
And why do we need to do that in
nnn
?
we do not want to make nnn a copy of another file manager with tons of fancy features.
We don't need to do that in nnn
, and I don't know if other file managers do it either.
I just wondered if something like that could be achieved via plugins in the current state of the project.
@RibalGZ I checked the feasibility. It would need a regex match per file. Too heavy for nnn standards.
I agree, thank you!
What about adding support for specifying custom colors for file entry according to the file name ? Using something like export NNN_FILECOLORS="*mp4:1;*jpg:2;Makefile:4"
What about adding support for specifying custom colors for file entry according to the file name ? Using something like
export NNN_FILECOLORS="*mp4:1;*jpg:2;Makefile:4"
As jarun described, the method of detecting it would increase the complexity of nnn
's codebase. And would come at cost of nnn
's performance.
Have you tried filtering by search? or sorting by file extension? te
?
(as I was writing this)
Wait a minute, we already have te
... Maybe it shouldn't be that hard to implement after all. I don't have interest in this problem, but look at cfg.extnorder
and change printent()
according to your needs.
@0xACE is right. We would like to avoid a regex/string compare per file, which color codes would warrant. You'll have to understand that nnn
's priority is performance on low end devices like the Pi and low-end Android devices. Even making it optional means an additional check per file or separate print functions (which would increase binary size).
Sort by extension is a specific case. As @0xACE has suggested, feel free to patch.
This is intentional. Tells you the exact file name and looks better.
That is a pleasantly nice setup you have @gyvess (referring to the ricing)
diff --git a/src/nnn.c b/src/nnn.c
index 49127b8..ff50bf3 100644
--- a/src/nnn.c
+++ b/src/nnn.c
@@ -3285,11 +3285,11 @@ static void printent(const struct entry *ent, uint namecols, bool sel)
#else
addstr(unescape(ent->name, MIN(namecols, ent->nlen) + 1));
#endif
+ if (ind)
+ addch(ind);
if (attrs)
attroff(attrs);
- if (ind)
- addch(ind);
addch('\n');
}
@@ -3374,10 +3374,10 @@ static void printent_long(const struct entry *ent, uint namecols, bool sel)
#else
addstr(unescape(ent->name, MIN(namecols, ent->nlen) + 1));
#endif
- if (attrs)
- attroff(attrs);
if (ind2)
addch(ind2);
+ if (attrs)
+ attroff(attrs);
addch('\n');
}
This should fix the /
highlight part (I didn't test, I'm shooting from the hips atm)
diff --git a/src/nnn.c b/src/nnn.c
index 49127b8..a83f51d 100644
--- a/src/nnn.c
+++ b/src/nnn.c
@@ -3276,10 +3276,10 @@ static void printent(const struct entry *ent, uint namecols, bool sel)
/* Directories are always shown on top */
resetdircolor(ent->flags);
- addch((ent->flags & FILE_SELECTED) ? '+' : ' ');
if (attrs)
attron(attrs);
+ addch((ent->flags & FILE_SELECTED) ? '+' : ' ');
#ifndef NOLOCALE
addwstr(unescape(ent->name, namecols));
#else
@@ -3304,10 +3304,10 @@ static void printent_long(const struct entry *ent, uint namecols, bool sel)
/* Directories are always shown on top */
resetdircolor(ent->flags);
- addch((ent->flags & FILE_SELECTED) ? '+' : ' ');
if (attrs)
attron(attrs);
+ addch((ent->flags & FILE_SELECTED) ? '+' : ' ');
/* Timestamp */
print_time(&ent->t);
And that should do the same for the +
selection marker.
Again I didn't test these, have fun.
@0xACE what is the problem with not highlighting the / and the prefix space?
No problem whatsoever, it was poor wording from me. imho. I was trying to be quick with writing my post... It grinds down to personal taste and behavior.
Imho tough: there is no other user experience where /
is excluded...
Tbh, this "issue" is of such minor cause that it is not worth delving into, unless it's considered a problem by others.
So for now let it rest. We both know it is easily reversible. I'll back you up in the public branch, if this becomes a problem
Thanks, I thought I broke something in user experience. Highlighting the file name seemed logical.
I have a feature request / request for help (perhaps this is already possible with plugins, but I haven't been able to achieve it yet).
I use "picker" (-p
) mode from my editor to navigate between files. I'd like to be able to control the file that nnn has selected when I start it. For example, I've got files fileA
through fileC
in my folder, I'm currently editing fileB
. I'd like to start nnn with fileB
selected (as opposed to the usual case which would start with fileA
) so if I want to navigate to fileC
it's just 1 file away.
It's sort of like a reverse NNN_FIFO
or writable $nnn variable. Is this already possible or a valid feature? Thanks.
Edit: I'm sure it works differently, but the same as how navigating up to the parent directory puts the cursor on the directory that you were just in - I'd like to do that but with files too.
@joshaw your answer is sessions. Have a saved session with that file hovered and use -s session_name
to start with that session.
Thank you! I'll try using sessions. I'm guessing it would work to dynamically create the session file in ~/.config/nnn/sessions
and load it with -s
, simple!
Yes, we try our best to keep the workflows simple for users however complex they are internally.
Is there any documentation on the session file format? I can't find any and am currently just getting either a segfault or "failed" flashing up and the session file has no effect. Thanks for your help
You don't need to know the session file format or create one manually. You need to save a session when you are running nnn
.
The documentation is available in the man page as well as in the wiki - https://github.com/jarun/nnn/wiki#sessions
I'd like to start from an artbitrary file though, so can't create a session file beforehand. I can pass the directory so that nnn starts in the right folder, but I'd like to start at the right file as well. My workflow is
$EDITOR some/folder/fileB
- I want to move to
some/folder/fileC
- Press a key to start nnn, which runs
nnn -p - some/folder
- Select the file and the output is used to change to that file.
That works very well, I'd just like to be able to start nnn with the cursor on fileB, or whichever other file I happen to be editing at the time.
https://github.com/jarun/nnn/blob/master/src/nnn.c#L3520-L3528
I guess this is the format you are looking for.
@joshaw At present if you pass a file path to nnn
it would just open that file and exit.
I've pushed a sample implementation at commit 5688692 to select the file if the file path is passed.
@0xACE We do not need to modify session handling for this. When a session is saved it will store the path and hovered file correctly which works as it should.
The commit above breaks our current behaviour where we open the file directly using opener if the path points to a file and nnn
exits. However, now nnn
will stay open with the file hovered.
@0xACE @KlzXS @leovilok do you guys think this new behaviour is acceptable? Consider the scenario where a file is opened from the browser and nnn
is set as the default file manager.
I think it makes sense if nnn
highlights the file if it has been given one in the path...
I like this new behaviour better. I think that it's out of the scope of nnn
to open the file directly.
OK. Then it stays!