Compare commits

...

894 Commits

Author SHA1 Message Date
Arun e27d059552
Merge pull request #1881 from N-R-K/colemak-collision
fix collision in colemak patch
2024-05-18 05:43:44 +05:30
NRK 4f3662cf88 fix collision in colemak patch
Closes: https://github.com/jarun/nnn/issues/1876
2024-05-11 11:46:11 +00:00
Arun 9e95578c22
Merge pull request #1879 from N-R-K/use_stdio
use buffered io to reduce syscalls
2024-05-10 17:33:32 +05:30
NRK 78b9677abd use buffered io to reduce syscalls 2024-05-10 08:37:21 +00:00
Arun Prakash Jana 55137600e0
Fix #1877: use dprintf() instead of write() 2024-05-06 19:05:46 +05:30
Arun Prakash Jana be6988d1c8
Fix #1877: malloc: error pointer being freed was not allocated 2024-05-05 18:40:52 +05:30
Arun Prakash Jana 191e77ec5d
Fix CI error 2024-04-28 20:37:53 +05:30
Arun Prakash Jana 46b5255814
Add comma 2024-04-28 20:25:08 +05:30
Arun 2fb7490bf0
Merge pull request #1834 from TheUtopian/master
preview-tabbed: show sxiv/nsxiv in thumbnail mode when watching Pictures folder
2024-04-28 18:16:36 +05:30
Arun d61c983dd0
Merge pull request #1872 from N-R-K/manpage_sort
clarify au and du in manpage
2024-04-24 18:12:53 +05:30
NRK e60be2eaa2 silence new clang-tidy warnings 2024-04-24 07:31:15 +00:00
NRK 72ee94ed6e clarify au and du in manpage
Closes: https://github.com/jarun/nnn/issues/1855
Closes: https://github.com/jarun/nnn/issues/1290
Closes: https://github.com/jarun/nnn/discussions/1750
2024-04-24 06:16:00 +00:00
Oktay Imanzade b20886a29c
preview-tabbed: show (n)sxiv in thumbnail mode when watching "Pictures" directory 2024-04-18 20:18:24 +04:00
Arun ad04944bdf
Merge pull request #1865 from flipflop133/patch-1
preview-tui: add svg support
2024-04-08 18:04:00 +05:30
François Bechet 133c0d329b preview-tui: add full svg support 2024-04-08 13:55:21 +02:00
Arun 5853ac8e48
Merge pull request #1864 from horrad/master
Fix file creation on OpenBSD
2024-04-05 23:31:08 +05:30
Martin Ziemer 28d993a8e8 Fix file creation on OpenBSD
On OpenBSD at least one of O_RDONLY, O_WRONLY or O_RDWR is needed to open a file.

In creating a new file none of those is set, which leads to an EINVAL error ("invalid argument").

Since the new file is only created and never read, I chose to use O_WRONLY.
2024-04-04 15:57:36 +02:00
Arun 22aa1455a6
Merge pull request #1861 from KlzXS/makefile_icons
Prevent multiple icons options being selected at the same time
2024-03-30 01:33:20 +05:30
KlzXS 7806d5d371
Prevent multiple icons options being selected at the same time 2024-03-28 18:20:21 +01:00
Arun 5456ba4582
Merge pull request #1830 from c79cea05/master
nuke: use sort -V
2024-03-05 23:31:45 +05:30
c79cea05 297b85492f nuke: use sort -V 2024-02-23 09:21:15 +09:00
Arun Prakash Jana f71b1309a9
Fix deletion prompt when rm is used 2024-02-18 06:32:49 +05:30
Arun eb66598145
Merge pull request #1821 from KlzXS/cpmvrm_dashes
Added dashes to progress versions of cp and mv
2024-02-16 19:17:39 +05:30
KlzXS 3d6777920a
Add -- to mvg and cpg which were missed 2024-02-13 18:49:02 +01:00
Arun 4a9587a5e6
Merge pull request #1820 from KlzXS/cpmvrm_dashes
Add -- to cp, mv and rm
2024-02-13 19:45:38 +05:30
KlzXS b392dd3723
Added -- to all instances of cp, mv or rm dealing with user provided paths 2024-02-13 14:32:42 +01:00
Arun 0f62c6258a
Merge pull request #1806 from BeyondMagic/master
quitcd: fix old bug and feat. for modular export for nushell
2024-02-12 22:24:53 +05:30
João F. (BeyondMagic/koetemagie) 2a442ec30c quitcd: fix bugs and feat. for modular export and selective quit 2024-02-10 18:59:26 -03:00
Michel DHOOGE 5b05c8b9b1
fix: use a more generic way to print NUL with awk
Only gawk undestands the \0 syntax
feat(mimelist): use `mimetype` for better type detection
docs(mimelist): add author & dependencies
2024-02-09 23:14:58 +05:30
90 eb3888cb09
Add option to `rm -rf` irrespective of trash setting 2024-02-09 23:14:56 +05:30
Arun Prakash Jana 94aeaccdbd
Fix #1765: detect and ignore false mouse click 2024-02-09 23:14:49 +05:30
NRK 0738f39cf0 show relative line numbering when jumping
Co-authored-by: Darukutsu <darupeter@pm.me>
Closes: https://github.com/jarun/nnn/pull/1804
Closes: https://github.com/jarun/nnn/discussions/1708
2024-02-03 09:53:11 +00:00
Antonio Mancera Gamez e76d7bbf1d
Changed exa from grid to tree view (preview-tui) (#1803)
* Changed exa from grid to tree view (preview-tui)

* Update plugins/preview-tui

Change also eza

Co-authored-by: blissful <blissful@sunsetglow.net>

* Changed maximum depth in exa and eza

* Added fifo_pager to exa and eza

---------

Co-authored-by: blissful <blissful@sunsetglow.net>
2024-02-02 21:11:18 +05:30
Arun f2a8648861
Merge pull request #1783 from 7ocb/alternative-setenv-pwd-3
Setting PWD: set on use case, not on browse
2023-12-15 06:07:44 +05:30
Arun 82f9e544f2
Merge pull request #1782 from BeyondMagic/master
fix nushell quitcd script: remove deprecated keywords
2023-12-15 06:06:09 +05:30
me 3d2caf861d Setting PWD: set on use case, not on browse
This moves setting PWD environment variable closer to the places where child process (that needs PWD correctly set) is started instead of start it on browse.
2023-12-14 11:03:38 +03:00
João F. (BeyondMagic/koetemagie) eb775914af fix nu quitcd: remove deprecated keywords 2023-12-13 21:18:29 -03:00
Arun 5595d93d29
Merge pull request #1778 from 7ocb/set-PWD-to-current-path
Set PWD environment variable
2023-12-08 19:38:46 +05:30
Arun bb650eb9dd
Merge pull request #1775 from JefeDavis/master
feat(preview-tui): allow image previews inside tmux on kitty terminal
2023-12-08 18:21:29 +05:30
me ab718387c2 Set PWD environment variable
This is to make spawned shells and processes to see "logical" path.
2023-12-04 14:09:37 +03:00
Jeff Davis 3849430ebc feat(preview-tui): allow image previews inside tmux on kitty terminal
Signed-off-by: Jeff Davis <mr.jefedavis@gmail.com>
2023-12-03 00:51:27 -05:00
Arun f2a909dafd
Merge pull request #1770 from 7ocb/pass-path-to-abspath
When handling SEL_NEW pass `path` to `abspath` call
2023-11-25 18:36:52 +05:30
Arun 404eed5fc7
Merge pull request #1773 from 7ocb/handle-link-by-readlink-not-realpath-mk2
When handling bookmark, use readlink, not realpath
2023-11-25 18:34:01 +05:30
me 9aaf9491ad When handling bookmark, use readlink, not realpath
This is to cd to path as it pointed by symlink, not to it's real path. Bookmarked directory may itself contain symlinks in path, which should be respected.

For example: if directory is physically in /mnt/storage/some and it's symlinked to ~/some and directory ~/some/dir added to bookmarks, it's expected that when following bookmark directory will be changed to ~/some/dir (as in bookmark's link) not to /mnt/storage/some/dir (as dir real path).
2023-11-22 20:41:49 +03:00
Arun 485079d3ec
Merge pull request #1769 from N-R-K/fix-helpstr
fix buffer overflow on certain platforms
2023-11-21 22:11:12 +05:30
me bca441e00f When handling SEL_NEW pass `path` to `abspath` call
If `path` is not provided to `abspath`, later will do `getcwd`, and it's result will differ from `path`. This causes problem that when creating directory inside path reached with symlink, subsequent call to get_cwd_entry does not recognize newly created path as subpath of current path, thus not selecting newly created element.
2023-11-21 19:26:20 +03:00
NRK 60eabb6170 silence ci warning 2023-11-21 20:50:45 +06:00
NRK 3665541dac fix buffer overflow on certain platforms
the size of g_buf depends on PATH_MAX and NAME_MAX which on certain
platforms (such as mac) might not be big enough to decode the help
string. use an explicit buffer with proper size instead.

Closes: https://github.com/jarun/nnn/issues/1768
2023-11-21 19:32:00 +06:00
Arun 744a7554ef
Merge pull request #1762 from azuline/sortctx
restore sort function pointers when restoring cfg
2023-11-19 13:39:24 +05:30
blissful c0b3cc8689
factor out a `setcfg` function for setting the cfg global 2023-11-18 16:34:17 -05:00
blissful 703d349389
restore sort function pointers when restoring cfg 2023-11-17 17:45:06 -05:00
Arun Prakash Jana 9259170afd Add example: run cmd as plugin to change directory 2023-11-18 01:00:03 +05:30
Arun 2f22afcacc
Merge pull request #1755 from cronyakatsuki/alacritty
preview-tabbed: Add alacritty as xembed client for text-based preview
2023-11-17 19:08:03 +05:30
luukvbaal 4009e211f3
Merge pull request #1749 from abhinav3398/master
preview-tui: tmux sixel support for img, gif & vid preview
preview-tui: mpv kitty backend and better previewer handling
2023-11-16 15:50:08 +01:00
Luuk van Baal 3160442f0c
preview-tui: mpv kitty backend and better previewer handling 2023-11-16 15:40:03 +01:00
Abhinav Lakhani 9ff81ca1f9 preview-tui: tmux sixel support for img, gif & vid preview 2023-11-12 14:40:31 -07:00
CronyAkatsuki 8e8289373a
Add alacritty as xembed client for text-based preview 2023-11-03 12:08:09 +00:00
Arun 1051d7213d
Merge pull request #1747 from luukvbaal/master
Preview-tui avoid early exit after SIGWINCH
2023-10-18 06:53:33 +05:30
Luuk van Baal f8f6d6a482
Preview-tui avoid early exit after SIGWINCH 2023-10-11 01:20:44 +02:00
Arun 7f63bef4d6
Merge pull request #1744 from s-hamann/fix-colemak-patch
Fix colemak patch
2023-10-08 17:33:02 +05:30
black bfb46159a1
Fix colemak patch 2023-10-08 09:28:58 +02:00
Arun f3397d5ea4
Merge pull request #1741 from N-R-K/rm-colemak-dh
rm colemak-dh
2023-09-30 22:12:55 +05:30
NRK 336ec8be5d rm colemak-dh
one colemak patch ought to be enough.

Closes: https://github.com/jarun/nnn/issues/1735
2023-09-30 22:25:23 +06:00
J-Kappes afe84862ff
fix nu quitcd: switched quotes (#1737)
Closes: https://github.com/jarun/nnn/issues/1736
2023-09-30 16:19:01 +00:00
Arun 3176eaa85c
Merge pull request #1732 from N-R-K/pr-clang-tidy
Fix CI
2023-09-23 13:54:39 +05:30
NRK 4d5e29c3dd fix CI 2023-09-23 12:26:58 +06:00
NRK 6d6fc3419e split clang-tidy checks into multiple lines
makes it more readable and more easily editable. also produces better
diff when editing.
2023-09-23 12:26:29 +06:00
Arun Prakash Jana 9b921761b6
Update CI name 2023-09-23 08:21:20 +05:30
Arun 09bf8fe469
Merge pull request #1729 from azuline/eza
Add support for eza as a replacement for exa
2023-09-21 09:39:44 +05:30
blissful 3b3ad9ccc6
Add support for eza as a replacement for exa 2023-09-20 15:50:58 -04:00
Arun Prakash Jana dd07aeb703
Fix patch build errors 2023-09-20 23:41:54 +05:30
Arun Prakash Jana 9c7c7284c0
Option `-N` to use native prompt
This is useful for situations where the executable is compiled with
readline support but the user wants to use the native prompt. Often
this happens because packagers build without readline disabled.
2023-09-20 23:02:04 +05:30
Arun ba439084c5
Merge pull request #1728 from Xerillic/master
wallpaper plugin: remove unneeded code
2023-09-20 17:51:22 +05:30
Xerillic 06d8da9052 wallpaper plugin: remove unneeded code 2023-09-13 19:53:55 -04:00
Arun ed59aa2ac3
Merge pull request #1727 from Xerillic/master
wallpaper plugin: add ability to set wallpaper for specific monitors
2023-09-13 22:44:55 +05:30
umaranis a06af824ee
plugins for integration with MacOS clipboard 2023-09-13 18:01:35 +05:30
Xerillic 66447d52a7 wallpaper plugin: add ability to set wallpaper for specific monitors using nitrogen 2023-09-12 20:58:37 -04:00
Syed Umar Anis 547508aa78
fzhist plugin: add support for zsh history #1721 (#1722)
* fzhist plugin: add support for zsh history

* fzhist plugin: check $HISTFILE for history file location

* fzhist plugin: remove extra trailing spaces
2023-09-07 18:03:01 +05:30
Arun Prakash Jana d72ab3497a
Use CircleCI parallelism 2023-08-27 18:58:15 +05:30
Arun Prakash Jana 2472554e9a
Use identifiable CircleCI test name 2023-08-27 18:08:27 +05:30
Arun Prakash Jana 785dd3ddf1
Update Haiku nnn.rdef 2023-08-27 10:09:11 +05:30
Arun Prakash Jana 33126ee813
Prepare for release v4.9 Elixir 2023-08-27 09:55:13 +05:30
Arun d8c1c99e45
Merge pull request #1719 from umaranis/master
Update finder plugin find command with default path #1718
2023-08-27 09:12:40 +05:30
Syed Umar Anis b28f209c84
Update finder plugin find command with default path #1718 2023-08-27 10:00:12 +10:00
Arun 1ba85825c5
Merge pull request #1711 from quantonganh/dup-first-char-macOS
Double-width icons can cause duplicated first characters in the filename on macOS
2023-08-20 17:59:30 +05:30
Arun 66f636de13
Merge pull request #1712 from Rahlir/plugin-fzopen-fix
Fix bug in fzopen when selection is canceled
2023-08-17 05:09:19 +05:30
Tadeas Uhlir e500179188 Fix bug in fzopen when selection is canceled 2023-08-12 17:45:14 +02:00
Quan Tong d220c50773 Double-width icons can cause duplicated first characters in the filename on macOS 2023-08-11 06:54:15 +07:00
Arun Prakash Jana 186f9d01ea
Move to Ubuntu 22.04 on Circle CI 2023-08-07 06:16:34 +05:30
Arun Prakash Jana 693ba757c0
Fix #1704 - Show only selected file name if sel is preferred 2023-08-05 23:53:01 +05:30
Arun Prakash Jana 3539e5c1b1
Update help 2023-07-28 20:52:21 +05:30
Arun d65a095d9b
Merge pull request #1698 from ANtlord/young-files
Jump to the next young file
2023-07-28 20:39:29 +05:30
ANtlord dedf0554e5 Jump to the next young file
Forward jumping to the next young file is implemented. The starting
position from which the next young file is searched is the next
position. If no young file has been found, the search starts from the
beginning. It stops at the initial position where the search has
started.
2023-07-25 08:17:21 +06:00
Arun b835cfcc2a
Merge pull request #1686 from Anomalocaridid/nmount-replace-pmount
nmount: make `pmount` optional
2023-07-16 00:20:50 +05:30
Anomalocaridid 80bbf76b5b nmount: add support for luks volumes for udisksctl 2023-07-09 19:57:57 -04:00
Anomalocaridid 5723023491 nmount: update dependencies in plugins/README.md 2023-07-08 19:55:10 -04:00
Anomalocaridid 280068c5da nmount: make pmount optional 2023-07-08 19:55:07 -04:00
Arun 53e4fec75b
Merge pull request #1679 from N-R-K/ifdef_fixes
Remove some unnecessary ifdefs
2023-07-04 20:21:43 +05:30
NRK db8b61866b define _FILE_OFFSET_BITS 64 unconditionally
according to the manpage, it won't have any effect on 64bit system
anyways. and musl always uses 64bit so this macro doesn't have any
effect there either.
2023-07-01 08:56:18 +06:00
Arun 26d5b5c614
Merge pull request #1668 from N-R-K/better_compress
better and faster string compression
2023-06-16 12:14:02 +05:30
Arun 899fd5b4cf
Merge pull request #1673 from JingMatrix/master
Add djvu icon
2023-06-16 12:12:41 +05:30
JingMatrix e6ce7a614e Add djvu icon
Use paperclip as icon since it is used by DjVuLibre.
2023-06-15 16:56:51 +02:00
NRK 5e3ee08e64 fix failing colemak patches 2023-06-15 08:57:48 +06:00
NRK 4c2ce0a84d better helpstring compression
this avoids multiple printf calls and instead decodes the buffer
natively. using %NN instead of %-NNc also saves two bytes per run.
helpstr is also made `static` to avoid unnecessary stack allocation.
2023-06-15 08:49:30 +06:00
Arun 0dfc6881b4
Merge pull request #1672 from luukvbaal/preview-tui
Preview-tui add -C to NNN_PAGER
2023-06-14 16:20:15 +05:30
Luuk van Baal 05990dc9e5
Preview-tui add -C to NNN_PAGER
This makes it so that when the paged text is fewer lines than the preview pane, it is placed at the top instead of at the bottom
2023-06-14 09:24:23 +02:00
Arun fb6e7403cf
Merge pull request #1658 from N-R-K/chmod_fix
fix: properly update mode after xchmod
2023-05-27 04:44:56 +05:30
NRK b2b830e69d fix: properly update mode after xchmod
xchmod now returns the new mode through a pointer, no need to assume all
executable bits were toggled.

Closes: https://github.com/jarun/nnn/issues/1657
2023-05-26 19:31:00 +06:00
Arun 4149a2619d
Merge pull request #1655 from mistersmee/gitstatus-nerd
patches/gitstatus: Fix nerd fonts broken by 3.0.0 update
2023-05-22 18:08:39 +05:30
Aseem Athale aed2725cb3 patches/gitstatus: Fix nerd fonts broken by 3.0.0 update
Signed-off-by: Aseem Athale <athaleaseem@gmail.com>
2023-05-22 14:22:13 +05:30
Arun 04d9f6738d
Merge pull request #1650 from leo-arch/master
Fix crash when PWD is set to empty string
2023-05-19 01:57:34 +05:30
Arun e013a867da
Merge pull request #1651 from N-R-K/cp_mv
make the cp/mv modification more robust
2023-05-19 01:56:53 +05:30
Arun ed58e07a98
Merge pull request #1646 from Delgan/patch-2
Fix some broken table links in docs
2023-05-19 01:53:48 +05:30
NRK 16899bda53 make the cp/mv modification more robust
this makes it so that if the cp/mv commands are changed the in the
future, it will continue to work reliably instead of having hardcoded
indexes to modify the array.

the `#ifdef __linux__` is also removed, compilers should be smart enough
to see that PROGRESS_{CP,MV} are unused (on non-linux systems) and
optimize it out.
2023-05-15 11:29:47 +06:00
Arun 4c0305f11c
Merge pull request #1648 from N-R-K/g3_debug
Makefile: use -g3 for debug builds
2023-05-15 06:38:03 +05:30
leo-arch 4babedc3e4
Fix crash when PWD is set to empty string
nnn crashes when PWD is set to empty string: `PWD="" nnn`
2023-05-14 20:12:04 +00:00
NRK ddcf331205 Makefile: use -g3 for debug builds
-g3 builds additional information such as macro definition and so on.
2023-05-14 22:13:44 +06:00
Delgan bd4a4454fe
Fix some broken table links in docs 2023-05-13 17:25:59 +02:00
Arun aaf60b93d7
Merge pull request #1645 from Delgan/patch-1
Add "$NNN_TERMINAL_ARGS" for "preview-tui" plugin
2023-05-12 22:03:22 +05:30
Arun 145ea41490
Merge pull request #1644 from jaspwr/master
Update Haskell icon colour
2023-05-12 22:02:52 +05:30
Arun 29779acc57
Merge pull request #1643 from UnleashedMarf/iconlookup-fix
Fix syntax-error in .iconlookup
2023-05-12 21:07:29 +05:30
Delgan a7262eb4ee Allow $NNN_TERMINAL additional arguments for "preview-tui" plugin
This can be used to start terminal with a custom title and prevent focus switch with i3 window manager.
2023-05-12 15:53:45 +02:00
Jasper fb3a648756 Update Haskell icon color 2023-05-12 15:19:04 +10:00
UnleashedMarf 9be3ee9abf
Fix another typo
Co-authored-by: luukvbaal <luukvbaal@gmail.com>
2023-05-11 19:44:17 +02:00
UnleashedMarf d873eb393d
Fix syntax-error in .iconlookup
Fixed syntax-error that prevented .iconlookup from executing.
2023-05-11 18:58:11 +02:00
Arun Prakash Jana efd5bc9db1 Update docs 2023-05-06 17:56:21 +05:30
Arun 737ebaa9ef
Merge pull request #1639 from atomcult/posix-quitcd
quitcd.bash_zsh: make POSIX compliant; minor fixes and style changes
2023-05-06 08:34:31 +05:30
J. Brock 95183fbef8 quitcd.bash_zsh: make POSIX compliant; minor fixes and style changes
This commit makes the following changes to quitcd.bash_zsh:
- POSIX compliance and an according rename of the script
- Enforces consistent if-then statements and indentation
- Minor comment fixes

Signed-off-by: J. Brock <joseph.brock@protonmail.com>
2023-05-05 14:42:13 -04:00
Arun fe96bd6bc7
Merge pull request #1638 from luukvbaal/nerdfix
Update nerd-font icons to v3
2023-05-05 05:36:27 +05:30
Luuk van Baal 20e944f5e5
Update nerd-font icons to v3
This is an upstream breaking change.
Update your font to the latest version if you see missing icons.
2023-05-05 01:01:43 +02:00
Arun Prakash Jana 5d81aeb477 Filter adjustment when opening context from plugin
- Clear filter only when a plugin is selected manually.
  Plugin dir should be unfiltered when opened.
- Plugins invoked by keys don't require clearing filter
  of original context. If a new context is opened using
  the plugin, it will be unfiltered by default. If the
  same context is re-used (when all the contexts are in
  use) the filter should be cleared so the the new path
  is opened unfiltered.
2023-04-29 21:53:49 +05:30
Arun 8fd1822ca6
Merge pull request #1633 from N-R-K/assert_fix
icons-hash: replace assert with handmade version
2023-04-23 21:01:27 +05:30
NRK 20725b0b4d icons-hash: replace assert with handmade version
since 2fc9d51, the hash-table generator inherits environmental
CFLAGS and so we shouldn't disallow setting -DNDEBUG.

fixes: https://github.com/jarun/nnn/issues/1632
2023-04-22 17:08:00 +06:00
Arun 6a8d74a43a
Merge pull request #1630 from musjj/preview-tui-escape
feat(preview-tui): handle quoting in `start_preview` more robustly
2023-04-22 03:02:37 +05:30
Luuk van Baal d3b5d0e49d
perf(preview-tui): replace env for loop with parameter expansion 2023-04-21 10:39:10 +02:00
musjj 432b0755d3 feat(preview-tui): handle quoting in start_preview more robustly
This commit makes the script more resistant to naughty filenames.
The script now depends on bash for the following features:
- Arrays
Correctly creating and passing argument lists is now simple
- Parameter transformation
`${parameter@Q}` makes it easy to correctly quote a string so that it
can be safely re-evaluated by the interpreter later.

On iTerm, the shell command used to render the preview is now passed to
osascript via a named pipe: `$FIFO_OSASCRIPT`. By not embedding the
shell command directly, we now no longer need to worry about osascript's
quoting rules. It's not perfect, because $SHELL and $TMPDIR might
contain naughty characters, but it's quite unlikely to happen.
2023-04-19 08:20:41 +07:00
Arun 621dbba02e
Merge pull request #1628 from spfanning/patch-1
Support wezterm split size percentage in preview-tui
2023-04-14 18:54:22 +05:30
spfanning 63891578d7
Support wezterm split size percentage 2023-04-13 15:50:31 -05:00
Arun Prakash Jana 8a1dce888a
config option to specify archive mounter utility 2023-04-14 01:47:50 +05:30
Arun Prakash Jana 9319b638e7
Revert variety 2023-04-13 19:10:07 +05:30
Arun Prakash Jana 6dd8cf8b4d
Happy Birthday nnn!
Prepare for release v4.8 Spritz!
2023-04-13 18:37:42 +05:30
Arun 18b5371d08
Merge pull request #1621 from kianmeng/fix-typos
Fix typos
2023-04-04 21:06:08 +05:30
Kian-Meng Ang 3d1bc6e8e5 Fix typos
Found via `codespell -L noice,nd,fils,numer,caf,iterm`
2023-04-03 12:49:03 +08:00
Arun 79007074f7
Merge pull request #1619 from yoshiyoshyosh/icon-jxl
add jpeg xl icon
2023-03-29 22:09:52 +05:30
yosh 98d3b2135d add jxl icon 2023-03-28 11:44:38 -04:00
Arun a3759abd4e
Merge pull request #1616 from N-R-K/quitcd
add shell_escape() to properly escape filenames fed to shell
2023-03-28 04:28:04 +05:30
NRK 57882ffab7 add shell_escape() to properly escape filenames fed to shell
Fixes: https://github.com/jarun/nnn/issues/1615
2023-03-22 10:09:39 +06:00
Arun Prakash Jana c4678e3116 Update issue templates
Signed-off-by: Arun Prakash Jana <engineerarun@gmail.com>
2023-03-15 04:21:17 +05:30
Arun 03ae86cca4
Merge pull request #1598 from N-R-K/tilde_handling
More correct tilde handling
2023-03-10 18:15:16 +05:30
Arun 15e55f5e18
Merge pull request #1606 from mmai/patch-2
Fix paths in nushell quitcd script
2023-03-08 20:26:05 +05:30
Arun 2af79c9ad2
Merge pull request #1604 from irhl/patch-1
plugins/wallpaper: update link
2023-03-08 20:18:13 +05:30
Henri Bourcereau eaffd311d4
Fix paths in nushell quitcd script
This set the correct path to the temp nnn file when XDG_CONFIG_HOME is set. It fixes https://github.com/jarun/nnn/discussions/1605
2023-03-07 15:40:10 +01:00
NRK 003228afba add some critical comments 2023-03-05 18:43:08 +06:00
birik 8b8e3eb522
plugins/wallpaper: update link 2023-03-05 09:07:04 +00:00
Arun 9656c809d2
Merge pull request #1602 from mmai/patch-1
Create quitcd script for nushell
2023-03-02 05:09:23 +05:30
Henri Bourcereau 69882b3bff
Create quitcd script for nushell 2023-02-28 16:26:36 +01:00
NRK 3a30211e6c handle tilde more strictly in mkpath and abspath
otherwise, if a file is named "~" it will get incorrectly expanded into
$HOME and disaster can happen.
2023-02-26 18:13:26 +06:00
Arun 2a38132012
Merge pull request #1597 from amalgame21/master
Add old 1997-2003 .doc and .xls preview support
2023-02-26 07:33:57 +05:30
NRK 8dbd9da0cc convert_tilde: return whether the conversion was done or not 2023-02-25 21:15:55 +06:00
NRK a59a91c312 handle tilde more correctly
closes: https://github.com/jarun/nnn/issues/1596
2023-02-25 21:15:46 +06:00
amalgame21 1dc4c96139
Add old 1997-2003 .doc and .xls support 2023-02-25 09:52:33 +00:00
Arun 9503703517
Merge pull request #1593 from luukvbaal/preview-tui
Preview-tui hide terminated/broken pipe messages
2023-02-20 19:42:15 +05:30
Luuk van Baal 675e50c941
Preview-tui hide terminated/broken pipe messages
Fix #1583, close #1591
2023-02-19 21:55:07 +01:00
Arun a4745272db
Merge pull request #1592 from N-R-K/nmv_tmp_cleanup
nmv: ensure the tmpfile is cleaned up in all cases
2023-02-19 22:27:36 +05:30
Jacob Moena 2dc7f19be0
Added patch for colemak keyboard layout. Existing renamed to colemak-dh (#1587)
* Added patch for colemak keyboard layout. Existing renamed

to colemak-dh

* Missed two spots of O_COLEMAK

* Update check-patches.sh
2023-02-19 17:22:32 +01:00
NRK bc6a09475d nmv: ensure the tmpfile is cleaned up in all cases
currently, there's a couple exit paths where the tmpfile doesn't get
cleaned up.
2023-02-19 21:14:53 +06:00
Arun Prakash Jana b874da395c
Update copyright year 2023-02-19 08:28:20 +05:30
Arun b49cc28d80
Merge pull request #1589 from N-R-K/prefer_sel
fix shellcheck issues
2023-02-17 21:00:44 +05:30
NRK 8c23c3da4e fix shellcheck issues 2023-02-17 20:12:07 +06:00
Arun f1c85b977a
Merge pull request #1588 from N-R-K/prefer_sel
nmv: prefer selection if -u is active
2023-02-17 19:30:59 +05:30
NRK 4867fa2bc7 plugin-helper: add nnn_use_selection() 2023-02-17 19:54:36 +06:00
NRK 9cc4b66868 export NNN_PREFER_SELECTION to all plugins 2023-02-17 19:24:45 +06:00
NRK 8ad5c87107 nmv: prefer selection if -u is active
the rename plugin always asks for "selection vs current" even when -u
flag is active. pass it to the plugin via `NNN_PREFER_SELECTION` so that
there's less distracting prompts.
2023-02-17 19:22:46 +06:00
Arun 9357825b34
Merge pull request #1586 from luukvbaal/preview-tui
Preview-tui restore current working directory
2023-02-17 18:42:50 +05:30
Luuk van Baal fc26493602
Preview-tui restore current working directory 2023-02-17 03:02:01 +01:00
Arun ade477e705
Merge pull request #1585 from luukvbaal/preview-tui
Preview-tui hide wezterm split-pane output
2023-02-17 07:18:35 +05:30
Luuk van Baal 08d2ba0b5d
Preview-tui hide wezterm split-pane output 2023-02-17 01:45:17 +01:00
Arun Prakash Jana bbfb16db42
Update readme 2023-02-13 01:05:36 +05:30
Arun d7bfe38728
Merge pull request #1580 from luukvbaal/preview-tui
Preview-tui!: refactor environment variables
2023-02-12 07:58:58 +05:30
Luuk van Baal 80c07741e5
Preview-tui!: refactor environment variables
Problem:    List of environment variables is copied for each previewer.
            Environment variable names are too general.
Solution:   Parameterize environment variable flags with static list of
            variables. Prepend user-facing variables with `NNN_`.
2023-02-11 03:09:56 +01:00
Arun 3739aab578
Merge pull request #1578 from kuntau/wezterm-preview-support
feat(preview-tui): add `wezterm` support
2023-02-04 07:04:24 +05:30
Nizamuddin Sulieman 70204a2d0f
Update plugins/preview-tui
use `$WEZTERM_PANE` instead, since `$WEZTERM_UNIX_SOCKET` is not set on Linux

Co-authored-by: luukvbaal <31730729+luukvbaal@users.noreply.github.com>
2023-02-04 07:36:57 +08:00
Nizamuddin Sulieman 1ad6d30a36 feat(preview-tui): use built in `iTerm2` image protocol if
`NNN_PREVIEW_IMGPROG` is not specified. Add some notes.
2023-02-02 18:25:39 +08:00
Nizamuddin Sulieman 0ac8b7aa54 feat(preview-tui): add `wezterm` support 2023-02-02 16:14:56 +08:00
Arun Prakash Jana 58b77411c8
Optimize listed selection size calculation 2023-01-31 18:36:26 +05:30
Arun d0631707fc
Merge pull request #1576 from greenfoo/add_chafa
preview-tui: add chafa and PREFERRED_IMAGE_VIEWER env variable
2023-01-30 18:37:42 +05:30
Fernando Ramos c4c720a59a preview-tui: add chafa and PREFERRED_IMAGE_VIEWER env variable 2023-01-30 08:24:44 +01:00
Arun 326e76b9d0
Merge pull request #1575 from luukvbaal/colemak
Update colemak patch
2023-01-30 06:49:00 +05:30
Luuk van Baal 778d6617b1
Update colemak patch 2023-01-29 23:05:49 +01:00
Arun Prakash Jana 33827109d5
Show total size of non-filtered selected files in a directory. 2023-01-30 00:14:54 +05:30
Arun Prakash Jana 4f95796ede
Run cmd as plugin now supported exported variables 2023-01-28 10:01:46 +05:30
Arun Prakash Jana b80e047d50
Set defaults for some multiple choice prompts
Archive options: listing
Create new options: create file
Open with options: command type GUI
2023-01-28 09:50:58 +05:30
Arun Prakash Jana ad4ecb19cb
Simplify paged and GUI commands run as plugin 2023-01-28 09:16:06 +05:30
Arun Prakash Jana 03e0531e81
Place "$nnn" in double quotes in man page examples 2023-01-28 08:31:25 +05:30
Arun 786ecf9fc2
Merge pull request #1571 from KlzXS/plugin_simplification
Simplify the command as plugin codepath
2023-01-28 08:23:24 +05:30
Arun 1a5a7da8eb
Merge pull request #1570 from KlzXS/general_simplification
Second attempt at #1566
2023-01-28 08:22:52 +05:30
Arun d4575e99c8
Merge pull request #1573 from N-R-K/fix_chksum
plugins/chksum: use exit instead of return
2023-01-27 21:03:45 +05:30
NRK ca8fcf454a plugins/chksum: use exit instead of return
From https://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#tag_18_24:

| The return utility shall cause the shell to stop executing the current
| function or dot script. If the shell is not currently executing a
| function or dot script, the results are unspecified.

Closes: https://github.com/jarun/nnn/issues/1572
2023-01-26 01:21:40 +06:00
KlzXS 867726d870
Add debug message for bad call 2023-01-25 18:56:48 +01:00
KlzXS 7abfb77a13
Update signatures 2023-01-25 17:37:31 +01:00
KlzXS 827e84a56f
Simplify commands as plugins
Remove restrictions on $nnn

Update the plugin README
2023-01-25 17:33:15 +01:00
KlzXS 8d21e5e832
Revert using UTIL_SH_EXEC 2023-01-25 17:26:14 +01:00
Arun Prakash Jana 6b94911bc9 Revert "Simplify get_output()"
This reverts commit 6c23fdfd5f.
2023-01-16 00:19:03 +05:30
Arun Prakash Jana 653cab9dff Revert "Give better names to variables"
This reverts commit 1a2f783b75.
2023-01-16 00:18:52 +05:30
Arun Prakash Jana f9295780ef Revert "Make CI happy"
This reverts commit 8a1e32d9eb.
2023-01-16 00:18:41 +05:30
Arun Prakash Jana cac5b9ba33 Revert "Concatenate arguments to pass to `sh`"
This reverts commit 428c652d36.
2023-01-16 00:18:19 +05:30
Arun Prakash Jana df05f593de Revert "Paging is achieved through shell command now"
This reverts commit 243301603e.
2023-01-16 00:15:54 +05:30
Arun Prakash Jana 243301603e
Paging is achieved through shell command now 2023-01-15 11:46:03 +05:30
Arun f9281c8eab
Merge pull request #1566 from KlzXS/general_simplification
General simplification
2023-01-15 11:16:01 +05:30
Arun 428c652d36
Concatenate arguments to pass to `sh`
Co-authored-by: KlzXS <klzx+github@klzx.cf>
Co-authored-by: Arun Prakash Jana <engineerarun@gmail.com>
2023-01-15 10:59:36 +05:30
KlzXS 8a1e32d9eb
Make CI happy 2023-01-14 23:18:22 +01:00
KlzXS 1a2f783b75
Give better names to variables 2023-01-14 22:31:16 +01:00
KlzXS 6c23fdfd5f
Simplify get_output() 2023-01-14 22:11:10 +01:00
Arun fef3c673cd
Merge pull request #1565 from N-R-K/discussion_template
issue-template: add a section for opening a discussion
2023-01-14 18:35:59 +05:30
NRK 1887cd1a77 issue-template: add a section for opening a discussion
this should give the section more visibility.
2023-01-14 18:48:11 +06:00
Arun 12aedd521d
Merge pull request #1563 from N-R-K/macos_ci
attempt at fixing macos CI
2023-01-10 20:59:49 +05:30
NRK cf68675478 attempt at fixing macos CI 2023-01-10 14:19:00 +06:00
Arun 2b6fb3f388
Merge pull request #1559 from leovilok/tabbed-wayland-warn
preview-tabbed: warn & prevent running on Wayland
2023-01-08 06:32:50 +05:30
Léo Villeveygoux dac5fb0af9 preview-tabbed: warn & prevent running on Wayland 2023-01-07 23:19:28 +01:00
Arun Prakash Jana 789449a464 Update bug template 2023-01-06 04:24:38 +05:30
Arun fa62b08243
Merge pull request #1555 from N-R-K/icons_fix_ub
icons-hash: fix bitwise rotation
2023-01-03 04:38:26 +05:30
Arun Prakash Jana dd214c50f3
Update plugin docs and examples 2023-01-03 04:37:07 +05:30
NRK fb5b2e5e64 icons-hash: fix bitwise rotation
in case the rotation is 0, `v >> (32 - r)` would end up doing a 32 right
shift which is equal to the width of `v` and thus undefined behavior.

ref: https://blog.regehr.org/archives/1063
2023-01-03 02:20:21 +06:00
Raffaele Mancuso c9b384f009
[kdeconnect] Various improvements (#1551)
- Support multiple devices paired and available at the same time
- Filter out non-regular files
2023-01-02 22:23:47 +05:30
N-R-K 2000ed5080
icons-hash: misc improvements (#1553)
* icons-hash: take total probe count into account as well

* icons-hash: use a better PRNG

the older method was using a multiplicative congruential generator (MCG)
which doesn't work too well especially with just 32 bits of state.

change it to a PCG instead with 64 bits of state (and 32 bits of output)
which should give better results.

and since we should get better rng - the search iteration has been
halved as well to save some build time.

* icons-hash: use an xor-rotate hash function

* icons-hash: fix some compiler warnings
2023-01-02 22:23:18 +05:30
8B411 a51437ff16
Miscellaneous improvements to nmount plugin (#1547)
* plugins/nmount: keep `while` & `do` on one line for consistency

* plugins/nmount: sync only that device, which user wants to unmount

* plugins/nmount: replace all instances of `$dev` with `/dev/$dev`

* plugins/nmount: add `--no-user-interaction` option to `udisksctl`

Otherwise the user will be asked for authentication each time he wants
to unmount, say, HDD, since `udisksctl` will try to power it off.

* plugins/nmount: try to mount only existing block devices

* plugins/nmount: do not invoke `lsblk` immediately after mounting

Sometimes `lsblk` fails to provide mountpoint in such a short time frame.

* plugins/nmount: simplify pipe

* plugins/nmount: keep `echo` arguments in a single pair of quotes

* plugins/nmount: report mountpoint only if mounting was successful
2022-12-21 23:14:28 +05:30
Arun Prakash Jana e236bd0b3a
Add Discussions link to README. 2022-12-18 21:30:23 +05:30
Raffaele Mancuso 1b5cfbca3d
kdeconnect: misc improvements (#1543)
- Work with multiple connected devices by sending files to the first
  device
- Support multi-files selection
- Support sending hovered file in case no file is selected

Co-authored-by: NRK <nrk@disroot.org>
Co-authored-by: Arun Prakash Jana <engineerarun@gmail.com>
2022-12-18 21:29:52 +05:30
Arun Prakash Jana 1688b07d0e
Update readme 2022-12-16 19:54:53 +05:30
Arun 4d54490433
Merge pull request #1542 from KlzXS/archive_script
Remove unnecessary parameter from `archive_selection()`
2022-12-13 18:40:42 +05:30
KlzXS 87627a6e08
Remove unnecessary parameter from `archive_selection()` 2022-12-12 16:13:35 +01:00
Arun Prakash Jana 17ed380b57
Optimize link creation 2022-12-12 18:03:11 +05:30
Arun Prakash Jana 38d7090e64
Clear selection if all links are generated 2022-12-12 16:15:06 +05:30
Arun Prakash Jana 824e7a2c18
Show errno on link creation failure 2022-12-12 15:57:20 +05:30
Arun Prakash Jana 2e84716e76
Restore check to prevent overwriting hovered file when archiving 2022-12-12 14:45:04 +05:30
Arun Prakash Jana e8bc59a816
Improve archive, rename, new workflows
1. hover on entry created in cwd
2. check user input doesn't end with /
3. check user input len < PATH_MAX
4. support creation in ~ directory
5. handle filter mode after creation
6. ensure absolute path len < PATH_MAX
2022-12-12 10:19:53 +05:30
Arun Prakash Jana 32a6a63f44
Improve archive creation handling 2022-12-12 02:43:23 +05:30
Arun Prakash Jana cf46da60d9
Fix memory leak 2022-12-12 00:17:28 +05:30
Arun Prakash Jana 1a04e813be
Update docs 2022-12-11 10:53:16 +05:30
Arun Prakash Jana 02dec98bf8
Use built-in 2022-12-11 03:42:34 +05:30
Arun Prakash Jana 608fbb4ad7
Fix length calculation 2022-12-11 03:01:19 +05:30
Arun Prakash Jana d4c3e52f2f
Attmept to create PATH if PATH is non-existent 2022-12-11 00:03:24 +05:30
Arun Prakash Jana 93de728eab
Create files in less permissive mode 2022-12-10 22:02:22 +05:30
Arun Prakash Jana c9dbae0586
Fix build break 2022-12-10 21:43:42 +05:30
Arun Prakash Jana b6bfc740ce
Fix signed and unsigned comparison 2022-12-10 21:39:44 +05:30
Arun Prakash Jana 28ea6e0f36
Allow creating a new file on startup
An accessibe parent directory must exist to allow creation
2022-12-10 21:39:36 +05:30
Arun Prakash Jana 2a673b4eb1
Allow overwriting regular files on new empty file creation 2022-12-10 19:28:58 +05:30
Arun Prakash Jana cd145b982d
Update ToDo link 2022-12-03 07:26:26 +05:30
Arun Prakash Jana 92a0158f93
Update README 2022-11-26 09:36:07 +05:30
Arun Prakash Jana 0c234060bf
Add correct check for Wayland in clipboard plugins 2022-11-26 09:33:59 +05:30
Arun 07c5590db3
Merge pull request #1531 from sjmulder/pr/cflags
Respect CFLAGS and LDFLAGS when building generator
2022-11-25 22:24:31 +05:30
Sijmen J. Mulder 2fc9d518d1 Respect CFLAGS and LDFLAGS when building generator 2022-11-25 16:40:17 +01:00
Arun Prakash Jana 1de825b5bb
Fix #1529: fix improper piping 2022-11-25 19:48:45 +05:30
Arun Prakash Jana fbf9279973
Set rdef to development 2022-11-24 11:24:10 +05:30
Arun Prakash Jana 7330e6642b
Prepare for release v4.7 Cuba libre 2022-11-24 10:58:21 +05:30
Darukutsu 4bb7ffcd4a
plugins/upload: handle selection using ffsend 2022-11-18 21:17:02 +05:30
Arun 3359b8f7cd
Merge pull request #1516 from lgtm-migrator/codeql
Add CodeQL workflow for GitHub code scanning
2022-11-09 23:10:30 +05:30
LGTM Migrator 66fd131f2d
Add CodeQL workflow for GitHub code scanning 2022-11-09 15:46:24 +00:00
Arun a1477c2668
Merge pull request #1512 from Darukutsu/pull-requests
plugins/wallpaper: support wayland and fix indentation
2022-11-02 18:34:44 +05:30
NRK f13b527a93 plugins/wallpaper: update description 2022-11-02 05:27:57 +06:00
NRK 83c4c880cc plugins/wallpaper: fix indentation 2022-11-01 23:03:14 +06:00
daru e7abf87c54
Update wallpaper 2022-11-01 17:05:57 +01:00
Darukutsu e80ba2e44a fix plugins/wallpaper support for wayland 2022-11-01 16:40:25 +01:00
Arun 2a4231ea89
Merge pull request #1511 from N-R-K/icons_clarify
Misc icon changes
2022-10-26 17:26:32 +05:30
NRK 985f6537ce add ksh, ttf and otf icons
Co-authored-by: Tanner Babcock <babkock@protonmail.com>
2022-10-26 15:08:27 +06:00
NRK 080a061969 icons.h: fix alignment 2022-10-26 14:55:20 +06:00
NRK ff27d9ee14 clarify the goal of the default icon set 2022-10-26 14:54:07 +06:00
nblock b511506fa3
imgview: handle arguments as strings (#1509)
* imgview: handle arguments as strings

Avoids the following synax errors:
line 34: [: : integer expression expected
line 49: [: : integer expression expected

* imgview: use meaningful strings as arguments

Co-authored-by: Florian Preinstorfer <florian@nblock.org>
Co-authored-by: Luuk van Baal <luukvbaal@gmail.com>
2022-10-21 14:16:06 +02:00
Arun f89ba77516
Merge pull request #1506 from N-R-K/nsxiv_link
update nsxiv upstream link
2022-10-12 20:23:21 +05:30
Arun 0c4180f2d8
Merge pull request #1507 from N-R-K/prompt_prefill
prefill the prompt when there's a single target
2022-10-12 06:04:20 +05:30
NRK e5074ebc83 prefill the prompt when there's a single target
Fixes: #1505 #1282 #1345
2022-10-12 00:48:33 +06:00
NRK b00700ce4d fix nsxiv upstream link
main repo is hosted on codeberg, github is only a mirror.
2022-10-11 22:00:42 +06:00
Dean G 38b7282050
Add Rust icons (#1502) 2022-10-05 11:38:48 +00:00
Arun 31b83ef1f0
Merge pull request #1501 from luukvbaal/patches
Fix gitstatus patch git command
2022-10-01 21:15:48 +05:30
Luuk van Baal bc4233767a
Fix git pathspec for gitstatus patch 2022-10-01 17:06:30 +02:00
Arun Prakash Jana 59eed597c2
Fix #1498: count broken when selection is updated outside nnn 2022-09-28 00:30:26 +05:30
Arun Prakash Jana de3ad1b146
Fix build break 2022-09-19 21:36:04 +05:30
Christian Rackerseder c24ede2d4a
Fix #1486: update macOS instructions for chksum plugin 2022-09-19 20:10:51 +05:30
Arun Prakash Jana 0907895865
Add macOS instruction 2022-09-17 21:43:46 +05:30
Arun 1cefc326e3
Merge pull request #1491 from PatrickF1/patch-1
slightly improve n.fish
2022-09-16 23:28:59 +05:30
Patrick a7ce7bb36c
wrap in quotes just in case 2022-09-15 19:57:25 -07:00
Patrick c9c74dd753
make one single invocation to test 2022-09-15 18:24:04 -07:00
Patrick 3dac035819
slightly improve and optimize n.fish
The expr is redundant because `test -ge` treats strings as numbers already.
2022-09-15 17:11:34 -07:00
Arun f6edcc41b9
Merge pull request #1485 from pataquets/detect-key-collision-text
Detect key collisions: make clear everywhere that it exits afterwards.
2022-09-13 06:32:39 +05:30
pataquets 78019a758e Detect key collisions: make clear everywhere that it exits afterwards. 2022-09-12 23:04:54 +02:00
Arun 23f8c37094
Merge pull request #1480 from luukvbaal/master
Show selected items in rm msg
2022-09-09 00:40:35 +05:30
Luuk van Baal 4f57e0df37
Show selected items in rm msg
Close https://github.com/jarun/nnn/issues/1479
2022-09-08 20:07:34 +02:00
Arun Prakash Jana f56a8caf65
Use correct data type for key collision detection 2022-08-23 19:00:45 +05:30
Arun 340ba19098
Merge pull request #1461 from N-R-K/xstrdup_memcpy
xstrdup: use memcpy
2022-08-16 19:07:21 +05:30
NRK f8ee991254 xstrdup: use memcpy
the length is already known, so memcpy should be faster than xstrsncpy.
2022-08-16 19:31:18 +06:00
Arun d49ddd1331
Merge pull request #1457 from N-R-K/alignas
use standard C11 alignas
2022-08-11 16:16:31 +05:30
NRK 29a5992dee use standard C11 alignas
nnn source code already uses C11, which introduced `_Alignas` [^0] as a
standardized alternative to __attribute__((aligned)).

there are no other usage of `__attribute__` in the nnn source code, so
in theory this should make things more portable across compilers.

also removes an unnecessary usage of `alloca()` with an aligned constant
sized buffer instead.

[^0]: https://en.cppreference.com/w/c/language/_Alignas
2022-08-11 11:31:35 +06:00
Arun ad62463b48
Merge pull request #1456 from luukvbaal/preview-tui
Preview-tui fix image_preview stdout
2022-08-07 21:30:23 +05:30
Luuk van Baal 95e1d56ee4
Preview-tui fix image_preview stdout 2022-08-07 16:40:12 +02:00
Arun Prakash Jana a335f94d05
Update docs 2022-08-06 11:23:10 +05:30
Arun Prakash Jana a937bc0a4c
Update ToDo list link 2022-08-05 05:46:25 +05:30
Arun 92873352e0
Merge pull request #1453 from N-R-K/fix_manpage
fix outdated manpage
2022-08-04 21:45:20 +05:30
NRK e57bb26295 fix outdated manpage
Closes: https://github.com/jarun/nnn/issues/1452
2022-08-04 21:38:38 +06:00
Arun 7086d030f0
Merge pull request #1451 from KlzXS/list_mode_read
Improved chunk allocation logic
2022-08-03 21:27:47 +05:30
KlzXS 65dec55e23
Improved chunk allocation logic
Found memory deallocation edge case

Update and move chunk limit check

Generalize maximum size of input

Remove hard-coded values

Remove superfluous check before free

Let the kernel deal with extra data

Handle signals while reading

Conform to the manpage

Make CI happy

use `size_t` instead of `ssize_t`

`ssize_t` was used just so `--i` when `i` was zero would become -1
instead of SIZE_MAX. for looping through something in reverse order, the
"goes-to" operator (`-->`) can be used instead which doesn't require `i`
to be signed anymore.

remove useless blank line

use a normal loop

don't see any reason why freeing in reverse order would've been needed.

Co-authored-by: N-R-K <nrk@disroot.org>
2022-08-03 17:38:19 +02:00
Arun Prakash Jana ab9d8bee89
Fix #1449: ^N not working 2022-08-01 23:41:04 +05:30
Arun Prakash Jana 926c4014b3
Update colemak patch 2022-07-31 19:40:50 +05:30
Arun Prakash Jana a7ebc7858a
Key 'J' to jump to entry number or relative offset 2022-07-31 18:54:47 +05:30
Arun Prakash Jana e8acae3274
Continue listing when max files/size is exceeded 2022-07-31 12:49:42 +05:30
Arun Prakash Jana 21eebbb003
File list mode changes
- support listing maximum 16K files
- check if target directory exists before directory tree creation
  in most of the cases many files will be under the same directory
- make frequently used function 'inline'
2022-07-31 11:11:32 +05:30
Arun Prakash Jana f530b2ca18
Let ffmpegthumbnailer use embedded image metadata 2022-07-30 21:44:00 +05:30
Arun Prakash Jana e298f7eeaf
Update patches 2022-07-30 10:32:32 +05:30
Arun Prakash Jana e73b57c78a
Option -B to use bsdtar as archive tool 2022-07-29 22:35:43 +05:30
Arun Prakash Jana 49a0d9d02c
Fix typo 2022-07-29 22:18:34 +05:30
Arun Prakash Jana b76cea3a34 Revert "Patch #1386: make bsdtar the default archive handler"
This reverts commit e104b749be.
2022-07-29 22:14:00 +05:30
Arun Prakash Jana 83825a7d11
Fix rm prompt
Esc - cancels the search
y/Y - adds the force option
n/N/any other key - prompts for every file
2022-07-28 19:38:55 +05:30
Arun Prakash Jana 22db656b8d Update gitignore file 2022-07-28 18:38:54 +05:30
Arun 07c1e8e655
Merge pull request #1440 from N-R-K/fix_emoji_tar
fix emoji tar command
2022-07-26 21:09:59 +05:30
NRK 61e1356fbd fix emoji tar command
Fixes: https://github.com/jarun/nnn/pull/1356#discussion_r930094949
2022-07-26 21:37:38 +06:00
N-R-K f618b78866
Makefile: more robust generated header tracking (#1439)
give each generated header it's own unique file so that it's not
possible to try and build `O_EMOJI=1` with the generated header for
`O_NERD=1`.
2022-07-26 20:26:49 +05:30
Arun Prakash Jana f2a38b0e22
Update Haiku file 2022-07-26 20:20:04 +05:30
Arun Prakash Jana 0988268a61
Prepare for release v4.6 Absinthe 2022-07-26 19:28:44 +05:30
Tharindu Abeydeera 98287158aa
Add Elixir icon (#1437)
* Added icons for erlang, elixir and lockfile

* Lockfile icon updated

* Added colors for Erlang and elixir

* Added few more color variations and configured colors and file
extensions

* remove erlang and lock, use 1 color for elixir

Co-authored-by: Tharindu Abeydeera <tharindu.a@vizuamatix.com>
Co-authored-by: NRK <nrk@disroot.org>
2022-07-25 19:40:00 +05:30
Arun e2e1d80d58
Merge pull request #1438 from N-R-K/icons_cleanup
icons-hash: comments and cleanups
2022-07-25 19:19:25 +05:30
NRK e6b6466c49 icons-hash: comments and cleanups
adds some comments, references and cleanups. no change in functionality.
2022-07-25 18:34:36 +06:00
Arun Prakash Jana f415924c7e
Remove redundant spaces 2022-07-24 20:07:27 +05:30
Arun Prakash Jana ab0dc52c49
Add example to quick find in subtree and nuke 2022-07-24 16:20:54 +05:30
Arun f829afe60b
Merge pull request #1436 from N-R-K/icon_compaction
icons: use a compact array
2022-07-24 16:14:52 +05:30
NRK fe9c1bbb3a icons: use a compact array
a lot of the extension use the same icon. this can be exploited via
having an array with all the unique icons and then storing a single byte
index into the unique array.

when using `O_EMOJI` this results in around ~1.7KiB drop in the total
table size. `O_NERD` and `O_ICONS` get roughly ~0.5KiB savings.
2022-07-24 16:24:11 +06:00
NRK 63a254951d icons-hash: some minor cleanups 2022-07-24 16:24:11 +06:00
Arun aab5ab53a5
Merge pull request #1435 from N-R-K/icons_update
Update some icons and colors
2022-07-24 15:40:18 +05:30
NRK 12f5faa10d icons: replace double-width icons 2022-07-24 16:06:14 +06:00
NRK f1932967e2 icons: use COLOR_C for go files 2022-07-24 16:06:14 +06:00
Arun Prakash Jana 197717ce68
Enable hidden when opening a hidden file 2022-07-23 09:33:11 +05:30
Arun 117025c1a4
Merge pull request #1432 from N-R-K/icon_rework_squashed
Revise and optimize icons handling
2022-07-22 22:37:25 +05:30
Arun 0381db1875
Merge pull request #1431 from luukvbaal/preview-tui
Preview-tui improvements
2022-07-22 22:33:16 +05:30
NRK e98d9288d2 some cleanups and comments 2022-07-22 21:33:35 +06:00
NRK c3a42f0d92 make clang-tidy happy 2022-07-22 17:31:55 +06:00
NRK 3b09fd1c75 Revise and optimize icons handling
This pretty much reworks the entire icon system. Some notable changes:

* The extensions are put into a statically generated hash-table instead
  of a sorted array. We use Robin-Hood insertion to reduce the max probe
  length. Currently we need to probe only 2 slots for `O_EMOJI` and only
  3 for `O_NERD`/`O_ICONS`.
* I've opted not to use a perfect-hash since the perfect hashes
  generated by [`gperf`](https://www.gnu.org/software/gperf) used some
  huge lookup table. The hash function also wasn't as minimal as I'd
  like.
* Colors are now using X-Macros. This should speed up startup since we
  don't have to search `icons_ext` linearly to find unique colors.
* The hash-table generator outputs a more space optimized `struct
  icon_pair` using a char array instead of char pointer. This brings
  down the binary size from `145KiB` when using `O_NERD` down to
  `137KiB`.
* Some unnecessary duplication and indirection has been reduced by using
  the `ICON_STR()` macro.
2022-07-22 17:08:42 +06:00
Luuk van Baal 3fb9cc1e5a
Preview-tui improvements 2022-07-22 10:49:13 +02:00
Arun Prakash Jana d95755cce1
Use unget_wch() 2022-07-21 17:51:20 +05:30
Arun Prakash Jana 12b5416b2c
Fix #1428: handle unicode keybinds 2022-07-20 20:09:34 +05:30
Arun Prakash Jana a937265833
Reduce get_wch() array length and initialization. 2022-07-20 18:49:24 +05:30
Anomalocaridid f2c7495f50
escape call to `nnn` so `nnn` can be used as an alias to `n` 2022-07-18 18:28:18 +05:30
Arun Prakash Jana b0580905f2
Add Makefile target shellcheck 2022-07-18 18:28:16 +05:30
Arun Prakash Jana b75a22f72d
Minor improvements 2022-07-18 18:28:16 +05:30
Arun Prakash Jana b752744ca0
Show volume used information in help 2022-07-18 18:28:16 +05:30
Arun Prakash Jana db7cb4da1e
Fix double order chars on filter case match change 2022-07-18 18:28:15 +05:30
Luuk van Baal 910763441d
Fix checkpatches duplicate make 2022-07-18 18:28:15 +05:30
Arun Prakash Jana b658f324c2
Update README 2022-07-10 21:36:56 +05:30
Arun Prakash Jana 3f4efbefe4
Remove redundant check
sdfdf
2022-07-10 11:00:56 +05:30
Arun c09ac1c174
Merge pull request #1421 from luukvbaal/patches
Add colemak patch
2022-07-09 17:20:46 +05:30
Luuk van Baal a3cef1611d
Add colemak patch 2022-07-09 13:42:38 +02:00
Arun f4116a5f42
Merge pull request #1420 from CinnamonJui/patch-1
Update plugin name in Configuration section
2022-07-08 20:57:35 +05:30
Jie a7f243beed
Update plugin name in Configuration section
As the plugin was renamed from 'mocplay' to 'mocq' in 4dcefcc4d4
2022-07-08 23:25:40 +08:00
Arun Prakash Jana 8520fe5a0a
Udpate ToDO list 2022-07-01 22:28:21 +05:30
Arun a998938b9d
Merge pull request #1413 from N-R-K/patches_ci
make it easy to check for failing patches locally
2022-07-01 07:45:00 +05:30
NRK fd69fc2dca make it easy to check for failing patches locally
adds a script `check-patches.sh` to check for patch failures and also
adds a make target `checkpatches` which will invoke the check-patches
script.
2022-07-01 05:47:23 +06:00
NRK 7121a6fe43
Fix build break 2022-06-30 22:26:17 +05:30
happy wang dc2cfe78cd
add z.lua to autojump 2022-06-30 22:26:12 +05:30
Arun 96cfd3a41a
Merge pull request #1412 from N-R-K/misc_cleanups
Misc cleanups
2022-06-30 00:51:43 +05:30
NRK 0df6eebea0 fix breaking patches 2022-06-30 01:04:25 +06:00
NRK 744e9aaf70 initialize to zero instead of using memset
reduces some unncessary code. and when initializing larger objects,
compilers (gcc and clang at least) typically tend to compile it down to
a memset anyways.
2022-06-30 00:27:00 +06:00
NRK 1d347b1ce9 cfg: use designated initializer
anything not explicitly initialized will be implicitly initialized to
zero. this makes things more robust since comments are not checked by
the compiler and can be incorrect.
2022-06-30 00:26:36 +06:00
NRK 2df0cbd08b fix incorrect comment
xextension() uses xmemrchr to find '.'
2022-06-30 00:25:44 +06:00
Arun b9a1f1747f
Merge pull request #1411 from luukvbaal/preview-tui
Account for ueberzug offset in preview-tui
2022-06-29 20:59:14 +05:30
Luuk van Baal 0ab9189bc5
Account for ueberzug offset in preview-tui 2022-06-29 12:33:11 +02:00
Arun Prakash Jana 52f4ee5aee
Fix build break 2022-06-28 23:17:23 +05:30
Arun 5ace352d2c
Merge pull request #1409 from luukvbaal/preview-tui
Scale up kitty previews
2022-06-28 16:55:22 +05:30
Luuk van Baal 3e84c275ba
Scale up kitty previews 2022-06-28 12:43:35 +02:00
Arun Prakash Jana 89bd541562
Add new emoji for C files 2022-06-25 20:07:43 +05:30
Arun Prakash Jana 02d48a9144
New icons for audio and video 2022-06-25 19:59:13 +05:30
Arun c69067b502
Merge pull request #1406 from N-R-K/realpath
account for realpath failure and update link
2022-06-20 21:48:20 +05:30
NRK af5cdca043 README: update my name and link 2022-06-20 22:06:23 +06:00
NRK eb66cb5d11 account for realpath failure
realpath may fail, in which case fallback to mkpath.
2022-06-20 21:49:41 +06:00
Arun Prakash Jana 6c197f5f02
Update plugin doc 2022-06-16 23:40:05 +05:30
Arun Prakash Jana 2130e1b33a
Use the term auto-advance instead of auto-jump
There's no jump.
2022-06-15 20:04:56 +05:30
Arun Prakash Jana 0c626d49a6 Revert "Add bookmarknav patch"
This reverts commit fbd6f69f25.
2022-06-14 17:43:50 +05:30
Arun Prakash Jana d898d174f5
Fix docs, allow `/` to enable filter inside bookmarks 2022-06-14 17:36:17 +05:30
Arun Prakash Jana 581e629c20
Enable automatic dir entry on unique filer match 2022-06-14 13:49:41 +05:30
Arun Prakash Jana 56f96c3d0a
Enable filtering in plugins/bookmarks dirs
Enable auto-dir entry on filter mode
2022-06-14 13:10:54 +05:30
Arun Prakash Jana 51f2fde0e6
Revert #1398: Go to prev dir on bookmark key repeat
Reasons:

1. `b` is not a special key and will be interpreted as a filter
2. with this change pressing the standard `-` inside a symlinked
   bookmark takes back to the bookmarks directory. This deviates
   from the regular bookmarks behaviour.
2022-06-14 12:51:42 +05:30
Arun 40f75e9c38
Merge pull request #1402 from luukvbaal/selbm
Fix false positive selbm
2022-06-13 17:21:02 +05:30
Luuk van Baal 5b5a62bb0d
Fix false positive selbm 2022-06-13 04:07:40 +02:00
Arun Prakash Jana 1b31f5cf9b
Fix patch doc 2022-06-12 07:56:21 +05:30
Arun Prakash Jana 783ea754f7
Use a more visible color 2022-06-12 07:55:23 +05:30
Arun c02605a907
Merge pull request #1401 from luukvbaal/master
Add bookmarknav patch
2022-06-12 07:31:06 +05:30
Luuk van Baal fbd6f69f25
Add bookmarknav patch 2022-06-11 19:44:44 +02:00
Arun Prakash Jana 19b2ea324a
Skip redundant getutil() call 2022-06-11 21:32:16 +05:30
Arun Prakash Jana 03fc3b99c5
Add informative comment 2022-06-11 21:25:03 +05:30
Arun Prakash Jana e104b749be
Patch #1386: make bsdtar the default archive handler 2022-06-11 15:09:40 +05:30
Arun Prakash Jana 8fb7feb61c
Add new icon colors for mp4 and flac formats 2022-06-11 07:34:59 +05:30
Arun Prakash Jana 49f21ae013
Fix segfault when last dir is not set 2022-06-11 06:05:57 +05:30
Göran Gustafsson 4baee859f8
Go to last dir on bookmark key repeat 2022-06-10 21:18:02 +05:30
Arun Prakash Jana de004d944e
Fix #1385: document internal files in 'plugins' dir 2022-06-10 21:00:06 +05:30
Arun 4784587024
Merge pull request #1394 from luukvbaal/explorer
Disable e on explorer mode
2022-06-09 02:26:27 +05:30
Luuk van Baal 6fc8f63c0d
Disable e on explorer mode 2022-06-08 21:01:03 +02:00
Arun 88306e2d9c
Merge pull request #1391 from ggustafsson/feat/usage-stdout-fix
Print usage info to stdout instead of stderr
2022-06-08 02:54:27 +05:30
Arun 4c6c06b743
Merge pull request #1389 from ggustafsson/feat/bsd-stat-x-fix
Use -x flag with BSD stat
2022-06-08 01:38:53 +05:30
Göran Gustafsson 5023abe2df Print usage info to stdout instead of stderr 2022-06-07 20:33:05 +02:00
Göran Gustafsson 93db9bb2be Use -x flag with BSD stat 2022-06-05 22:13:23 +02:00
Arun 46a5092eee
Merge pull request #1384 from N-R-K/fix_sizeof
fix incorrect usage of sizeof
2022-06-02 21:44:52 +05:30
NRK 5ae3891ee5 fix incorrect usage of sizeof
`sizeof(cmd)` here would give the sizeof a char pointer, not the sizeof
the cp/mv array.
2022-06-02 15:44:31 +06:00
Arun 01ab453cff
Merge pull request #1380 from luukvbaal/master
Update patch conflict instructions/workflow
2022-05-31 16:36:23 +05:30
Luuk van Baal 3072aa7891
Update patch conflict instructions/workflow 2022-05-31 11:07:31 +02:00
Arun 0499998e2a
Merge pull request #1379 from luukvbaal/master
Move patch ci to ubuntu
2022-05-30 23:29:46 +05:30
Luuk van Baal bb604bdf1d
Move patch ci to ubuntu 2022-05-30 19:45:28 +02:00
Arun Prakash Jana a70ad9c480
Update doc 2022-05-30 22:31:24 +05:30
Arun Prakash Jana 10e2d37d0f Revert "Enter type-to-nav for bookmarks dir"
This reverts commit 8cdeddeb4a.
2022-05-30 22:20:45 +05:30
Arun Prakash Jana 85be28c019 Revert "Fix reverting filtermode on empty directory"
This reverts commit 4337214f50.
2022-05-30 22:19:41 +05:30
Arun d859e81444
Merge pull request #1377 from luukvbaal/patches
Add patch conflict instructions
2022-05-30 22:12:30 +05:30
Arun 33ec6dece4
Merge pull request #1376 from N-R-K/patches_ci
Improve patches ci
2022-05-30 22:11:43 +05:30
Luuk van Baal 4c974f286c
Add patch conflict instructions 2022-05-30 14:43:59 +02:00
N-R-K 1e98e2e126 improve patch conflict ci script
goes through all different combinations automatically and makes adding
another patch easier by simply putting the name into the patches array.
2022-05-30 17:43:41 +06:00
Arun f8b8e77be9
Merge pull request #1375 from luukvbaal/master
Add patch conflict workflow
2022-05-30 06:22:23 +05:30
Luuk van Baal 0095948d8d
Add patch conflict workflow 2022-05-30 01:01:46 +02:00
Arun Prakash Jana d618922177
Get rid of rundir 2022-05-29 22:32:54 +05:30
Arun Prakash Jana 4337214f50
Fix reverting filtermode on empty directory 2022-05-29 20:17:55 +05:30
Arun Prakash Jana 31a273fdd0
Fix build break 2022-05-29 20:09:33 +05:30
Arun c2a2a9dee7
Merge pull request #1373 from luukvbaal/bmnav
Enter type-to-nav for bookmarks dir
2022-05-29 19:37:33 +05:30
Luuk van Baal 8cdeddeb4a
Enter type-to-nav for bookmarks dir 2022-05-29 13:55:15 +02:00
Arun 772fd30fa0
Merge pull request #1372 from luukvbaal/patches
Fix restorepreview patch conflict
2022-05-29 14:12:44 +05:30
Luuk van Baal ae36d30b66
Fix restorepreview patch conflict 2022-05-29 01:32:07 +02:00
Arun Prakash Jana 14e80c3872
Update docs 2022-05-28 23:59:11 +05:30
Arun Prakash Jana 8175571952
Clear runtime states 2022-05-28 23:30:56 +05:30
Arun Prakash Jana 3a50be93fd
Fix #1369: limit symlinked bookmarks to bookmarks dir 2022-05-28 23:14:07 +05:30
Arun Prakash Jana ec7692bb9e
Update man page. 2022-05-28 06:20:57 +05:30
Arun e4c2cb9fd4
Merge pull request #1371 from dnbz/master
Fix a broken link in CONTRIBUTING.md
2022-05-28 05:57:18 +05:30
Arun Prakash Jana 8d83af811f
Fix #1369: open target of symlinked bookmark 2022-05-28 05:54:55 +05:30
Dan Baz ef5d90f4bb
Fix a broken link in CONTRIBUTING.md 2022-05-28 00:17:15 +00:00
Arun Prakash Jana ec076f5886
FIx alignment 2022-05-26 02:36:59 +05:30
Arun 81f96ecc1e
Merge pull request #1366 from jarun/preview-tui-kitty
Improve preview-tui kitty documentation
2022-05-23 21:14:36 +05:30
luukvbaal ed7afd2dd1
Improve preview-tui kitty documentation 2022-05-23 17:25:19 +02:00
Arun ab8505efa4
Merge pull request #1364 from cain-dev/patch-1
Reference dependency needed for kitty preview
2022-05-14 06:36:07 +05:30
cain-dev b3f16e7671
Reference dependency needed for kitty preview 2022-05-13 16:41:42 -03:00
Arun Prakash Jana f6783c2065
Emoji changes 2022-05-13 04:44:27 +05:30
Arun a3fbda02d7
Merge pull request #1363 from N-R-K/alloc_check
check for some alloc failures
2022-05-12 18:05:53 +05:30
NRK ba72fca69a check for some alloc failures 2022-05-12 18:26:48 +06:00
Arun e1e47f909f
Merge pull request #1361 from N-R-K/headers_makefile
add headers as make dependancy
2022-05-12 16:36:11 +05:30
NRK 6f332e5260 add headers as make dependancy 2022-05-12 00:32:10 +06:00
Arun Prakash Jana c23125ba50
Change some emojis 2022-05-11 21:40:23 +05:30
Arun Prakash Jana 0a67c5d657
Use correct Emojis for arrows 2022-05-11 01:54:54 +05:30
Arun Prakash Jana af94c7704f
Remove redundant Emojis 2022-05-11 00:56:25 +05:30
Desmond Kabus b45be9bc5b
Add build option EMOJI for Unicode emoji as file icons 2022-05-10 20:31:11 +05:30
Arun Prakash Jana 18a6a010cf
Fix #1355: interpret suffix `$nnn` when paging 2022-05-10 19:46:19 +05:30
Patrick 4ddd048feb
.cbcp plugin: output a more useful error message 2022-04-30 14:44:11 +05:30
Arun Prakash Jana fd998b3045
Post-release formalities. 2022-04-26 19:03:04 +05:30
Arun Prakash Jana 3f58f6111c Prepare for release v4.5 Cachaça 2022-04-26 18:34:24 +05:30
Arun 4366247441
Merge pull request #1347 from luukvbaal/patches
Fix patch conflicts and rebase
2022-04-26 18:33:05 +05:30
Luuk van Baal 7793cb8b5c
Fix patch conflicts and rebase 2022-04-26 14:54:27 +02:00
Arun Prakash Jana cc965d1c2d
Use bold forward arrowhead for current 2022-04-26 04:26:01 +05:30
Arun Prakash Jana dc16ca2340
Add 2 spaces after icons for better visibility 2022-04-26 03:59:12 +05:30
Arun Prakash Jana 6b9f8f3666
Fix #1345: allow symlink name '@' in single file case 2022-04-20 20:20:25 +05:30
Arun 15243186c5
Merge pull request #1344 from SlIdE42/patch-1
quitcd script for Elvish shell > 0.17.0
2022-04-17 17:05:26 +05:30
SlIdE42 0812c7afac
quitcd script for Elvish shell > 0.17.0 2022-04-17 13:29:51 +02:00
Arun Prakash Jana be4460c1da
Handle broken window if started in type-to-nav 2022-04-16 18:48:52 +05:30
Arun Prakash Jana eb42f7a948
Bind ^J with toggle auto-jump on open 2022-04-16 18:04:09 +05:30
Arun Prakash Jana 2c5cb4c5aa
Replace ^J with + to (un)select
^J has been reported as out of place several times.
As `+` is used as the seleciton marker, it makes more sense.
2022-04-16 17:04:53 +05:30
Arun a555a7d122
Merge pull request #1342 from N-R-K/use_elements
consistently use ELEMENTS macro
2022-04-14 06:26:16 +05:30
NRK d0bf2abb37 consistently use ELEMENTS macro
+ some small white-space fixes
2022-04-12 22:30:22 +06:00
Arun 59cf883437
Merge pull request #1338 from JingMatrix/fix-gsconnect
Allow gsconnect to handle multiple devices
2022-04-09 16:56:30 +05:30
JingMatrix 5bc75ef4fd Allow gsconnect to handle multiple devices
When gsconnect is connected to multiple devices, the original
script won't work. Now the code will share files to all devices.
2022-04-09 11:42:31 +02:00
Arun bb875cd5e7
Merge pull request #1337 from pcapriotti/pcapriotti/quit-on-cd-docs
Clarify docs in the quit-on-cd wrapper
2022-04-07 06:26:12 +05:30
Paolo Capriotti 4220f4e2eb Clarify docs in the quit-on-cd wrapper 2022-04-06 17:28:12 +02:00
Arun Prakash Jana d66492ac10 Show reverse timestamp for young entries
Show timestamps for entries modified/created within 5 minutes in
reverse.

Signed-off-by: Arun Prakash Jana <engineerarun@gmail.com>
2022-04-02 10:15:14 +05:30
Arun Prakash Jana 88e9122c79
opener improvements
- show file name
- open hovered if none selected
- open and exit if only one file selected
- code improvements
2022-04-01 09:00:51 +05:30
Arun Prakash Jana 5745597fd5
Fix #1333: plugin openall to open selection 2022-03-31 19:29:30 +05:30
Arun 0a7742089a
Merge pull request #1331 from JingMatrix/master
Preview for djvu files
2022-03-26 04:02:44 +05:30
JingMatrix 0a59005acd Preview for djvu files 2022-03-25 17:21:11 +01:00
Arun 81226db24e
Merge pull request #1330 from N-R-K/prompt_clearsel
native prompt: clear selection on successful operation
2022-03-24 03:05:47 +05:30
NRK 72ecf6c4b8 native prompt: clear selection on successful operation
have been using the %j substitution for a bit now, it's quite nice :)
but it's also quite annoying when doing something like

	mv "%j" ./

in this case, the files have been moved but the selection is incorrectly
points to them.

when there's a successful operation made on the selection via the native
prompt, it makes sense to clear the selection.
2022-03-24 00:23:38 +06:00
Arun 675016eb55
Merge pull request #1329 from N-R-K/avoid_malloc
avoid unnessary heap allocation
2022-03-23 21:03:31 +05:30
NRK 9be6c1a5e2 avoid unnessary heap allocation
the binary size shouldn't change since it'll most likely go into the bss
section.
2022-03-22 17:50:54 +06:00
Arun Prakash Jana d38841d5f3
Support n/N to cancel forced rm 2022-03-13 12:37:50 +05:30
Arun 136549b1ba
Merge pull request #1321 from N-R-K/preview_tui_debug
preview-tui: make debugging easier
2022-03-10 22:52:46 +05:30
NRK c3534bd7e0 preview-tui: make debugging easier
i've noticed that there's a non-trival amount of issues user face
related to preview-tui. allowing all the null redirection to be easily
switched on/off can make debugging much easier, both for the users and
for us.
2022-03-09 01:48:13 +06:00
Arun Prakash Jana 57d212c3ca
Fix entry order 2022-02-27 02:06:24 +05:30
Arun Prakash Jana 66639c6053
Fix #1312 2022-02-27 01:44:30 +05:30
Arun b718d6d305
Merge pull request #1314 from Darukutsu/master
Added a user-script/plugin to send selected files using GSConnect.
2022-02-23 21:11:22 +05:30
Arun 994bc80e82
Merge pull request #1315 from N-R-K/include-hidden
export NNN_INCLUDE_HIDDEN to plugins
2022-02-23 21:08:12 +05:30
daru 633a9ca8e1 Update plugins/gsconnect
Co-authored-by: N-R-K <79544946+N-R-K@users.noreply.github.com>
2022-02-22 22:19:44 +06:00
daru d1de515532 Update plugins/gsconnect
Co-authored-by: N-R-K <79544946+N-R-K@users.noreply.github.com>
2022-02-22 22:19:44 +06:00
Darukutsu cd2445607b workaround with xargs -0
added hover over file to send
2022-02-22 22:19:44 +06:00
Darukutsu 83b6d6aff7 Added a user-script/plugin to send selected files using GSConnect. 2022-02-22 22:19:44 +06:00
NRK 2fedc92efc export NNN_INCLUDE_HIDDEN to plugins
Closes: https://github.com/jarun/nnn/issues/1308
2022-02-22 17:40:44 +06:00
Arun Prakash Jana 953643b9f1
Fix condition 2022-02-21 02:01:03 +05:30
Arun 816680ed01
Merge pull request #1313 from N-R-K/dragon_name
dragdrop: use "dragon-drop" if it exists
2022-02-20 14:22:34 +05:30
NRK a8e9d279ac dragdrop: use "dragon-drop" if it exists
to avoid name conflict some distros renamed dragon to `dragon-drop`
https://github.com/mwh/dragon/issues/17#issuecomment-889878960
2022-02-20 14:41:37 +06:00
Arun cb410e25d8
Merge pull request #1307 from N-R-K/fd_leak
don't leak inotify_fd to plugins
2022-02-15 19:48:53 +05:30
NRK 799b8fd378 don't leak inotify_fd to plugins
Closes: https://github.com/jarun/nnn/issues/1291

Co-authored-by: Daniel Eklöf <daniel@ekloef.se>
2022-02-15 19:05:58 +06:00
Arun 30bd6a4e33
Merge pull request #1306 from KlzXS/nmv_trash
Respect NNN_TRASH in .nmv
2022-02-14 07:17:49 +05:30
KlzXS 184f134c9e
Respect NNN_TRASH in .nmv 2022-02-13 10:37:21 +01:00
Arun Prakash Jana 23b54ba0cf
Open previous active context on context quit 2022-02-06 00:23:45 +05:30
Arun 866612bfda
Merge pull request #1302 from N-R-K/makefile_rebuild
rebuild if Makefile changes
2022-02-04 08:57:40 +05:30
NRK ff1c1eb2e1 rebuild if Makefile changes 2022-02-03 22:20:55 +06:00
Arun fbb2172627
Merge pull request #1300 from N-R-K/rsynccp_fix
[rsynccp & fzcd]: avoid using non-portable xargs flag
2022-02-01 18:28:41 +05:30
NRK 24db74fd7b fzcd: avoid using non-portable xargs flag 2022-02-01 18:00:20 +06:00
NRK ffd0468f67 rsynccp: avoid using non-portable flags
Closes: https://github.com/jarun/nnn/issues/1299
2022-02-01 16:29:40 +06:00
Arun Prakash Jana e67587204b
Update ToDo list link 2022-01-23 20:55:16 +05:30
Arun Prakash Jana aa2147f3ef
make option O_NOSORT to disable sort on dir load 2022-01-23 10:52:33 +05:30
Arun Prakash Jana e140e34483
Disable filterinfo if file details enabled 2022-01-22 21:06:57 +05:30
Arun Prakash Jana fe4ea8a029
Update copyright date 2022-01-22 16:02:51 +05:30
Arun bfa2d4fce5
Merge pull request #1289 from luukvbaal/preview-tui
Preview-tui support windows terminal split
2022-01-18 00:22:11 +05:30
Luuk van Baal ecad3e0524
Preview-tui support windows terminal split
Co-authored-by: WanderLanz
2022-01-17 14:20:27 +01:00
Arun b8b0bab426
Merge pull request #1288 from Anomalocaridid/fix-nuke-imv
add support for imv when named imv in nuke
2022-01-09 16:16:37 +05:30
Arun 9c6ce560f1
Merge pull request #1287 from lawnowner/master
Remove trailing blanks to assure .desktop suffix for xdg-mime.
2022-01-09 16:15:52 +05:30
Anomalocaridid efa960d022 add support for imv when named imv in nuke 2022-01-08 16:21:49 -05:00
lwnctd 49aa4dabf1 Remove trailing blanks to assure .desktop suffix for xdg-mime. 2022-01-08 05:34:20 +03:00
Arun 2eadf35fa0
Merge pull request #1277 from N-R-K/webp_icon
add webp icon
2021-12-26 17:33:46 +05:30
NRK 04181084c0 add webp icon 2021-12-26 14:43:18 +06:00
Arun dcf3a35cd5
Merge pull request #1276 from N-R-K/bookmark_doc
add bookmark section to the manpage
2021-12-26 11:56:53 +05:30
NRK e2b856904d add bookmark section to the manpage 2021-12-26 11:07:18 +06:00
Arun Prakash Jana 693df568e0 Document symlinked bookmarks in the manpage 2021-12-26 09:58:34 +05:30
Arun 3368a7905b
Merge pull request #1275 from N-R-K/pedantic_cleanups
Pedantic cleanups
2021-12-25 22:36:13 +05:30
NRK 02d6feb9b9 check bound before making access 2021-12-25 12:47:48 +06:00
NRK 1608c8763f avoid having function with unspecified arguments 2021-12-25 12:47:33 +06:00
NRK 78c0d54400 avoid doing arithmetic on void pointer 2021-12-25 12:47:24 +06:00
Arun e44f8d3fcc
Merge pull request #1270 from N-R-K/doc_improvement
Make the manpage more clear
2021-12-25 08:17:45 +05:30
Arun 282266705e
Merge branch 'master' into doc_improvement 2021-12-25 08:17:34 +05:30
Patrick fe0608116a
introduce new plugin for jumping git root 2021-12-25 08:13:43 +05:30
Arun Prakash Jana 0fb7a25612
Use terms consistent with man page in docs 2021-12-25 08:13:41 +05:30
Arun Prakash Jana b69f838fb8
Update bug report template 2021-12-25 08:13:40 +05:30
Luuk van Baal beafeaaea2
Preview-tui fix gif conversion 2021-12-25 08:13:40 +05:30
Luuk van Baal a3d660b673
Preview-tui fix gif whitespace name 2021-12-25 08:13:39 +05:30
NRK ac86fbed0f
add icon for opus files 2021-12-25 08:13:39 +05:30
Luuk van Baal 48bcc929e8
Restorepreview when launching subshell 2021-12-25 08:13:39 +05:30
Luuk van Baal 06bf4f5dce
Replace restorepreview workaround 2021-12-25 08:13:38 +05:30
KlzXS 3be2dd8390
Remove -E from sed in plugins 2021-12-25 08:13:35 +05:30
NRK ce58aab6b2 slight reword 2021-12-25 08:39:29 +06:00
NRK 62f1004836 upadte the source code according to the docs 2021-12-25 08:37:28 +06:00
NRK d215a9c61d -A doc: change auto-select to auto-enter 2021-12-25 08:35:23 +06:00
NRK c234c05b3d clarify '+' keybinding in type-to-nav mode 2021-12-25 08:35:23 +06:00
NRK f7298efa99 reword 'select' -> 'selection' 2021-12-25 08:35:23 +06:00
NRK 9a26739132 fix plugin requirement 2021-12-25 08:35:23 +06:00
NRK 23edf571a7 make the manpage more clear
some of the terms used in the manpage aren't exactly obvious, especially
to a new user. this is an attempt at making the manual more clear and
remove any potential confusion.

here's a couple issues i've noticed where users were confused due to non
clear manpage description:

https://github.com/jarun/nnn/issues/1268
https://github.com/jarun/nnn/issues/1269
https://github.com/jarun/nnn/issues/1209
2021-12-25 08:35:23 +06:00
Arun Prakash Jana 892e4c0082
Use terms consistent with man page in docs 2021-12-25 08:02:27 +05:30
Arun Prakash Jana bd6e7e8147
Update bug report template 2021-12-20 11:56:54 +05:30
Arun ecfe819a73
Merge pull request #1267 from luukvbaal/preview-tui
Preview-tui fix gif conversion
2021-12-20 10:16:23 +05:30
Luuk van Baal b851b58e83
Preview-tui fix gif conversion 2021-12-20 02:39:10 +01:00
Arun 2c31615256
Merge pull request #1263 from luukvbaal/preview-tui
Preview-tui fix gif whitespace name
2021-12-19 03:13:25 +05:30
Luuk van Baal 95f709f86a
Preview-tui fix gif whitespace name 2021-12-18 22:34:24 +01:00
Arun a1b15eb766
Merge pull request #1258 from N-R-K/opus_icon
add icon for opus files
2021-12-17 17:46:59 +05:30
Arun 48e478bb90
Merge pull request #1257 from luukvbaal/patches
Restorepreview patch improvements
2021-12-17 17:46:33 +05:30
Luuk van Baal 8ba43edffc
Restorepreview when launching subshell 2021-12-17 12:41:29 +01:00
NRK 7aef60a9d5 add icon for opus files 2021-12-15 00:45:58 +06:00
Luuk van Baal e0c1ed273f
Replace restorepreview workaround 2021-12-14 17:16:56 +01:00
Arun 40b2250209
Merge pull request #1247 from KlzXS/posix_sed
Remove -E from sed in plugins
2021-11-28 06:45:30 +05:30
Arun eb62775852
Merge pull request #1248 from yeetologist/master
Fix zsh auto-completion typo
2021-11-27 15:43:27 +05:30
yeetologist c147414bc7 Fix zsh auto-completion typo 2021-11-27 11:57:45 +07:00
Arun Prakash Jana 1e8b8d14ff
Remove redundant line 2021-11-27 09:48:21 +05:30
KlzXS 8f2e17303e
Remove -E from sed in plugins 2021-11-26 10:33:11 +01:00
Arun 1bc234b0eb
Merge pull request #1244 from N-R-K/malloc_size
fix the malloc size in get_archive_cmd
2021-11-24 22:48:02 +05:30
NRK bd8faa2dd8 use patterns[] for archive command string 2021-11-24 22:34:22 +06:00
NRK 578e6d1aaa use a macro for the format string
this makes things slightly more robust as changing the string inside the
macro would automatically change the malloc size.
2021-11-24 22:06:05 +06:00
NRK f7091f78e5 fix the malloc size in get_archive_cmd
since the tr hack was removed in deead97, the format string is no longer
70 chars. also removes unnecessary malloc casting.
2021-11-24 21:53:11 +06:00
Arun c87b67e073
Merge pull request #1243 from omar-polo/sed-misc
misc sed tweaks
2021-11-24 18:25:13 +05:30
Omar Polo fb3d3ab0ef define SED only if not already defined
This allows packagers to set a custom path for sed (gsed may be simply
called `gsed' or `gnu-sed' or ...)
2021-11-24 11:44:50 +01:00
Omar Polo deead97e23 drop unnecessary ifdef __linux__
since nnn requires gsed anyway, why don't use it?
Probably forgot in #1210
2021-11-24 11:40:59 +01:00
Arun Prakash Jana 8ec2fe7f81
Set Haiku variety to dev 2021-11-23 18:58:43 +05:30
Arun Prakash Jana 65eddfe7b9
Prepare for release v4.4 Tequila 2021-11-23 18:33:45 +05:30
Arun 2f986253e4
Merge pull request #1241 from luukvbaal/master
Guard open_with getreadline for picker
2021-11-23 18:17:13 +05:30
Luuk van Baal 1a6d54515b Guard open_with getreadline with for picker
fix luukvbaal/nnn.nvim#25
2021-11-23 13:11:42 +01:00
Arun 256f0d008f
Merge pull request #1240 from KlzXS/percent_j
Enforce %J only at the end of command
2021-11-16 22:38:32 +05:30
KlzXS ca9b5e04c7
Enforce %J only at the end of command
Also removes double shell
2021-11-16 00:44:44 +01:00
Arun f3df0816d9
Merge pull request #1239 from tonijarjour/patch-1
n/sxiv play gifs automatically from tabbed
2021-11-15 19:06:54 +05:30
Toni Jarjour 8755a3c0cf
n/sxiv play gifs automatically from tabbed 2021-11-14 20:56:32 -05:00
Arun Prakash Jana f66183937d
More frequent interrupt handling during du
The check is done when traversing directories in preorder i.e before the files
inside are enumerated. Postorder traversal is unwinding, so mostly we are done
with the calculation and finishing off the thread.
2021-11-15 01:11:46 +05:30
Arun 6178be7e06
Merge pull request #1235 from luukvbaal/preview-tui
Preview-tui pass pts device in env variable
2021-11-13 01:00:26 +05:30
Luuk van Baal 84bfbcf4e7 Preview-tui pass pts device in env variable 2021-11-12 13:57:27 +01:00
Arun 9cb0a13ffe
Merge pull request #1234 from luukvbaal/preview-tui
Preview-tui ensure pts device for tput in subshell
2021-11-12 07:59:10 +05:30
Luuk van Baal e94f90c89a Preview-tui ensure pts device for tput in subshell 2021-11-11 17:35:10 +01:00
Arun 8b7feff4b6
Merge pull request #1232 from KlzXS/nmv_list_env
Env variable should be not set, not set to 0
2021-11-11 06:06:37 +05:30
Arun bd7f127ad9
Merge pull request #1231 from luukvbaal/preview-tui
Preview-tui workaround for ncurses tput regression
2021-11-11 06:05:35 +05:30
Arun fec0479da3
Merge pull request #1230 from N-R-K/nsxiv_support
add nsxiv support to nuke, preview-tabbed and imgview
2021-11-11 06:00:23 +05:30
KlzXS 875a4d8c23
-n exists for a reason 2021-11-10 21:56:51 +01:00
KlzXS a300e3267f
Env variable should be not set, not set to 0 2021-11-10 21:51:05 +01:00
Luuk van Baal 0d657b47b9 Preview-tui workaround for ncurses tput regression 2021-11-10 19:22:41 +01:00
NRK 39a3cc5309 add nsxiv support to nuke, preview-tabbed and imgview
`nuke` and `preview-tabbed` works as expected. I would assume `imgview`
should work as expected as well since `nsxiv` (at the moment at least)
is a drop-in replacement for sxiv, but I haven't tested it.

Closes: https://github.com/jarun/nnn/issues/1229
2021-11-10 22:46:45 +06:00
Arun c9b9c14481
Merge pull request #1227 from luukvbaal/patches
Fix restorepreview patch conflict
2021-11-09 15:35:01 +00:00
Arun 182ac51b8d
Merge pull request #1226 from luukvbaal/preview-tui
Proper fix for preview-tui zombie-pane
2021-11-09 15:34:28 +00:00
Luuk van Baal 66dfa60465 Fix restorepreview patch conflict 2021-11-09 14:52:45 +01:00
Luuk van Baal 26f380f154 Proper fix for preview-tui zombie-pane 2021-11-09 14:33:52 +01:00
KlzXS 48415c5e1c
Revert "malloc() mem those persist through program runtime"
This reverts commit b84ad2d552.
2021-11-08 15:08:12 +01:00
Arun 1508874b5a
Merge pull request #1224 from KlzXS/nmv_list_current
Updated .nmv to support current when NNN_LIST
2021-11-08 13:34:39 +00:00
Arun e686b94f7e
Merge pull request #1223 from akrifari/fix-invisible-description
Fix invisible description
2021-11-08 13:33:20 +00:00
KlzXS 22096ee0cd
Updated .nmv to support current when NNN_LIST
NNN_LIST now should pass listroo
2021-11-07 22:08:43 +01:00
Krisan Alifari eff4bd6e67 Fix invisible description 2021-11-07 13:00:06 +07:00
Arun f854b3c748
Merge pull request #1220 from luukvbaal/patches
Add nerd icons to gitstatus patch
2021-11-06 06:12:13 +05:30
Luuk van Baal 1621c0303b Add nerd icons to gitstatus patch 2021-11-05 17:01:56 +01:00
Arun Prakash Jana b84ad2d552
malloc() mem those persist through program runtime
At exit, the OS should reclaim all the memory, so no explicit free() required.
2021-11-05 07:59:40 +05:30
Arun Prakash Jana 07a47db8fe
Update ToDO list link 2021-11-04 20:50:32 +05:30
Arun Prakash Jana e2c4445d74
Fix build break 2021-11-03 09:01:26 +05:30
KlzXS eb769c0de5
Resolve symlinks one level for .nmv when in list mode 2021-11-03 08:37:08 +05:30
Terminator X b56e488f1c
Merge pull request #1217 from N-R-K/nuke
nuke: port sxiv-rifle performance improvement over
2021-11-02 10:16:17 +05:30
NRK 5e6c62cd8e nuke: port sxiv-rifle performance improvement over
this commit is mostly porting over some recent performance improvements
from `sxiv-rifle`: https://github.com/ranger/ranger/pull/2411

there's one "bug-fix" in this commit. currently a file named "afilejpeg"
would be matched due to the `-iregex` in listimages. this commit changes
that so only extensions would match, so for example "afile.jpeg" would
match but not "afilejpeg".

As for performance, there's a couple things this commit does:

* store the result of listimages into a tmp file instead of calling that
  function twice, this is probably the biggest performance improvement.
  especially when loading large directories.

* abspath now sets the var abs_target instead of calling printf. since
  abspath is only called from load_dir, we can go one step further and
  inline it. but i haven't done that since the function might be useful
  later on.

* avoid call to dirname and use parameter subsitution instead inside
  `listimages`

* use grep instead of `-iregex`, it's POSIX compliant and can be faster.

i've tested this out with sxiv and everything seems to be working as
expected.
2021-11-02 10:13:45 +06:00
Terminator X b5f5b2f55c
Merge pull request #1216 from CantoroMC/master
[icons nerdfont] added gpg icon
2021-11-01 17:34:59 +05:30
Marco Cantoro da03016c79 [icons nerdfont] added gpg icon 2021-11-01 11:39:33 +01:00
Terminator X bcae254ff2
Merge pull request #1215 from N-R-K/fzopen_fix
plugin: fzopen: print full path for picker mode
2021-11-01 13:53:48 +05:30
NRK 65ae3abc24 quickfix 2021-11-01 14:15:49 +06:00
NRK d2dff487e0 use $PWD 2021-11-01 14:13:21 +06:00
NRK afb7a6e9c1 check if $entry is fullpath or not 2021-11-01 14:05:18 +06:00
NRK a47376ee04 plugin: fzopen: print full path for picker mode
Closes: https://github.com/mcchrish/nnn.vim/issues/133
2021-11-01 13:28:49 +06:00
Arun Prakash Jana bdbd182c65
Handle plugin selection early 2021-11-01 12:54:47 +05:30
Arun Prakash Jana cffcd655e9
Minor code refactor 2021-10-30 12:26:31 +05:30
Arun Prakash Jana 2a87694e6a
Do not reorder pre-ordered directory on refresh 2021-10-30 12:07:45 +05:30
Arun Prakash Jana 473cd271b5
Position cursor in correct place for long names 2021-10-29 21:27:02 +05:30
Arun Prakash Jana 8efcc24e0e
Fix #1213: scroll long strings in prompts 2021-10-29 19:41:56 +05:30
Arun Prakash Jana aa8baa3d91
Update docs 2021-10-29 05:23:14 +05:30
Avimitin 254fd9b7a3
patch/docs: correct the git status build flag (#1212)
The git status build flag is missing a letter 'T'.

Signed-off-by: Avimitin <avimitin@gmail.com>
2021-10-28 14:11:49 +02:00
Terminator X 684a8c7b99
Merge pull request #1210 from alexDarcy/master
FreeBSD: use gsed instead of sed
2021-10-28 16:06:49 +05:30
Alexis Praga e3e4159e11 BSDs and Solaris: use gsed instead of sed 2021-10-28 11:38:35 +02:00
Arun Prakash Jana 856896f55d
Update comment 2021-10-27 03:57:23 +05:30
Terminator X b72090c9a3
Merge pull request #1208 from luukvbaal/preview-tui
Fix preview-tui without -a
2021-10-23 19:24:57 +05:30
Arun Prakash Jana 4d864d438f
Update help 2021-10-23 19:21:22 +05:30
Luuk van Baal de017b7aa2 Fix preview-tui without -a 2021-10-23 15:50:29 +02:00
Arun Prakash Jana f4f78276e2
Disable verbose xargs, change nativ eprompt to "nnn]" 2021-10-23 03:47:53 +05:30
Terminator X b411dfe1ba
Merge pull request #1202 from KlzXS/cmd_selection
Added %s and %S for using selection in shell
2021-10-23 03:01:07 +05:30
KlzXS 7857b7bc5a
Fix off-by-one 2021-10-22 21:06:26 +02:00
KlzXS 1022340aa1
Revert searching for a leading space
%j and %J will be replaced by a file path. File paths should be quoted to ensure proper interpretation by the shell
2021-10-22 20:28:33 +02:00
KlzXS 73ef170da7
Replace %s and %S with %j and %J
Those two conversions aren't used by any printf and scanf functions so there will no longer be any erroneous rewrites

Style fixes
2021-10-22 19:58:50 +02:00
Terminator X 0c0afd4799
Merge pull request #1207 from luukvbaal/master
Clear selection for send_to_explorer
2021-10-22 22:04:49 +05:30
Luuk van Baal fa9067afd4 Clear selection for send_to_explorer 2021-10-22 18:26:45 +02:00
Arun Prakash Jana cb5aefa59a
Remove option -w: always place HW cursor on current entry 2021-10-22 06:45:42 +05:30
Arun Prakash Jana 00c73512b9 Revert "fix: no mouse support inside vim terminal"
This reverts commit dd7c13dd77.

Single/double mouse click breaks on xfce4-terminal and xterm on Ubuntu 20.04
2021-10-22 00:30:11 +05:30
Luuk van Baal 2801832c4d
Selection and mouse support for explorer/picker 2021-10-21 23:58:35 +05:30
Terminator X 5f76b69c36
Merge pull request #1204 from N-R-K/mouse_ev
fix: no mouse support inside vim terminal
2021-10-21 18:23:57 +05:30
NRK dd7c13dd77 fix: no mouse support inside vim terminal
we need to signal mouse event by printing these escape codes. the X10
escape code seems to be legacy format only used as fallback incase SGR
extended coordinates aren't supported.
2021-10-21 18:21:59 +06:00
Terminator X f3e027c283
Merge pull request #1203 from luukvbaal/patches
Resolve gitstatus patch conflict
2021-10-21 17:11:14 +05:30
Luuk van Baal a0fcd78df2 Resolve gitstatus patch conflict 2021-10-21 13:39:09 +02:00
KlzXS bc69c968be
Added %s and %S for using selection in shell 2021-10-20 19:28:15 +02:00
Arun Prakash Jana 53fbab1f44
Prefer inline for single liner 2021-10-20 20:29:15 +05:30
Arun Prakash Jana 24b71bcf1f
Picker mode: don't pick on Enter if selection exists 2021-10-19 18:50:11 +05:30
Arun Prakash Jana 12fa5344cf
Fix #1201: accept link name for single target
When creating new sym/hard link, accept link name if
the current file is being linked or 1 file selected.
2021-10-19 15:35:57 +05:30
Arun Prakash Jana d5d559ae7f
Update docs 2021-10-19 00:44:33 +05:30
Arun Prakash Jana acfec62a13 Add example to copy image to clipboard (#1199) 2021-10-18 02:49:36 +05:30
Terminator X 4dc70f4a3f
Merge pull request #1198 from stelgenhof/master
Add 'font' mime-type registry check for preview-tui plugin
2021-10-17 17:51:29 +05:30
Arun Prakash Jana a06ff83c22
Add option -i to show file information on hover 2021-10-17 12:01:01 +05:30
Sacha Telgenhof 44b983f71e Added the media registry 'font' for mime types part of it.
Signed-off-by: Sacha Telgenhof <me@sachatelgenhof.com>
2021-10-17 14:34:09 +09:00
Arun Prakash Jana 9c36f0df34
Get rid of clearinfoln() 2021-10-17 05:00:35 +05:30
Arun Prakash Jana 3490a959be
make var O_FILEINFO to show file info on hover 2021-10-16 22:48:01 +05:30
Arun Prakash Jana c611720cba
Update version 2021-10-15 12:45:58 +05:30
Arun Prakash Jana be549f330a
Update docs 2021-10-15 03:05:21 +05:30
An Phung e20cfd67a1
Support OSX iterm2 in preview-tui by using split pane (#1196) 2021-10-14 22:07:11 +02:00
Arun Prakash Jana 3091a6f240
Update link to ToDo list 2021-10-10 11:45:49 +05:30
Arun Prakash Jana 3acbc65adb
Fix build break 2021-10-09 19:37:45 +05:30
Terminator X 98585153cc
Merge pull request #1191 from luukvbaal/patches
Fix gitstatus regression and restorepreview conflict
2021-10-09 19:11:03 +05:30
Terminator X 57bae766ea
Merge pull request #1192 from jarun/luukvbaal-readme
Add nnn.nvim to README
2021-10-09 18:57:21 +05:30
luukvbaal e9dbadd465
Add nnn.nvim to README 2021-10-09 14:40:22 +02:00
Luuk van Baal 17bf7c97f6 Fix gitstatus regression/restore preview conflict 2021-10-09 02:36:22 +02:00
Terminator X 1020f37320
Merge pull request #1190 from luukvbaal/sessionfix
Save session after browse()
2021-10-07 08:59:34 +05:30
Luuk van Baal 151312eb37 Save session after browse() 2021-10-07 02:57:55 +02:00
Terminator X 2435263052
Merge pull request #1186 from KlzXS/recursive_batch_rename
Added recursive capabilities to .nmv
2021-10-04 20:32:14 +05:30
Terminator X 831b434021
Merge pull request #1189 from luukvbaal/preview-tui
Remove preview-tui winch tmux workaround
2021-10-04 20:30:49 +05:30
Luuk van Baal c48691fe3d Change preview-tui winch workaround 2021-10-04 00:12:48 +02:00
KlzXS b492dfd7ca
Added recursive capabilities to .nmv 2021-10-03 11:42:02 +02:00
Terminator X fa7c19c409
Merge pull request #1183 from N-R-K/disable_e
Disable e on picker mode
2021-09-30 19:50:40 +05:30
NRK 8a1a5db92a Disable e on picker mode
Mainly so that pressing 'e' due to muscle memory on nnn.vim doesn't nest
a new editor instance inside the embedded vim terminal.

However invoking nnn with picker mode implies that the intention is to
pick file(s), there shouldn't be any business trying to edit things on
the fly. And if editing a file while in picker mode is desirable, then
'l' can be used for that instead.
2021-09-30 19:54:22 +06:00
Arun Prakash Jana 7477bd15bb
Update docs 2021-09-30 07:26:40 +05:30
Arun Prakash Jana 74b779abc9
Update docs 2021-09-30 03:17:02 +05:30
Arun Prakash Jana 2f6c180433
Improve docs in cd on quit scripts 2021-09-29 19:16:58 +05:30
Arun Prakash Jana 79b3688e49
Revert Haiku rdef 2021-09-29 16:22:01 +05:30
Terminator X d772223e1f
Merge pull request #1182 from luukvbaal/patches
Fix gitstatus and rebase patches
2021-09-29 15:43:43 +05:30
Luuk van Baal 541b936bcf Fix gitstatus and rebase patches 2021-09-29 11:33:19 +02:00
Arun Prakash Jana e74aa95e3f
Prepare for release v4.3 Martini 2021-09-29 14:37:45 +05:30
Arun Prakash Jana fc86152fa2
Fix compilation warning 2021-09-29 14:28:16 +05:30
Terminator X 1723aeb470
Merge pull request #1180 from MaxGyver83/master
autojump plugin: Support jethrokuan/z (port of z for fish)
2021-09-27 05:38:12 +05:30
Max Schillinger 1c9ecd781c
Combine assignment of $_Z_DATA, $Z_DATA or $HOME/.z
Co-authored-by: luukvbaal <31730729+luukvbaal@users.noreply.github.com>
2021-09-26 23:17:51 +02:00
Max Schillinger f39ee39a36 autojump plugin: Support jethrokuan/z (port of z for fish) 2021-09-26 21:54:01 +02:00
Arun Prakash Jana 046d676a73 Fix broken GUI cmd run as plugin case 2021-09-25 23:55:25 +05:30
Terminator X f3e0f23718
Merge pull request #1177 from luukvbaal/preview-tui
Preview without convert
2021-09-24 17:54:41 +05:30
Luuk van Baal 07c8089eaf Preview without convert 2021-09-24 12:12:13 +02:00
Terminator X 2c82c77a05
Merge pull request #1174 from luukvbaal/restorepreview
Improve restorepreview race conditions
2021-09-23 13:12:15 +05:30
Luuk van Baal 52d8aa0945 Improve restorepreview race conditions 2021-09-22 17:15:35 +02:00
Terminator X a447c12866
Merge pull request #1173 from luukvbaal/previewpatch
Add restorepreview patch
2021-09-22 09:08:32 +05:30
Luuk van Baal d96a7bc2b7 Add restorepreview patch 2021-09-22 04:13:57 +02:00
Arun Prakash Jana ffe472ac32 Revert "Close previewer when opening file (#1171)"
This reverts commit 532532704e.
2021-09-22 05:46:45 +05:30
CantoroMC bfc493c753
Support for nerdfont sty,cls and bib(tex filetypes) (#1169)
I've extended the use of nerdfont icon for tex to other common tex extensions.
I don't know how to do the same for icons-in-terminal.
Additionally, since the list is growing I have alphabetize the list of common
icons, used in icons-nerdfont.h.
2021-09-21 10:23:18 +05:30
luukvbaal 532532704e
Close previewer when opening file (#1171) 2021-09-21 10:18:51 +05:30
CantoroMC 2a6cc41972
add provided but unused ruby icon (#1167) 2021-09-19 10:13:07 +05:30
Terminator X 5bf9b52beb
Update FUNDING.yml 2021-09-19 06:55:51 +05:30
Arun Prakash Jana aea97cf3a7
More checks 2021-09-09 23:17:22 +05:30
Arun Prakash Jana 27e1eb54c4
Fix #1162: run commands as plugin through shell 2021-09-09 19:38:41 +05:30
Arun Prakash Jana e7aec90889 Add early check 2021-09-09 18:05:51 +05:30
Jakob Beckmann 7f84fbc8a0
Added theme support for bat in preview-tui plugin (#1141) 2021-09-09 18:02:06 +05:30
Arun Prakash Jana 9df7e5f03e
Reformat checks 2021-09-09 09:06:09 +05:30
Arun Prakash Jana 359d7bc29c
Directory-specific sort order 2021-09-09 01:46:22 +05:30
Arun Prakash Jana fa7cef2df7
The shell interprets "$nnn" now 2021-09-05 18:19:30 +05:30
Assaf Ben-Amitai d34741107a
fix jump cd to use seperate params (#1156) 2021-09-05 05:20:31 +05:30
Assaf Ben-Amitai 7de52ff890
plugin autojump: on jump - read entire line (#1155) 2021-09-05 02:01:41 +05:30
Arun Prakash Jana 51829c8027
Reformat copy current current file name 2021-09-04 08:06:29 +05:30
Arun Prakash Jana 49be2cfcd1
Fix #1153: sync hidden on batch rename 2021-09-04 07:23:02 +05:30
Arun Prakash Jana ab0ab2b5f4
Use a meaningful macro 2021-09-04 07:21:59 +05:30
Daniel Eklöf 0556ac14ec
[draft] signal CWD change to terminal via OSC-7 (#1148)
* Signal CWD change to terminal via OSC-7

Closes #1147

* Make OSC-7 emission gated by NOX11

* Use newpath variable in gethostname()

Use dynamic memory for hostname
2021-08-30 20:14:05 +05:30
Terminator X 64c2c68bd0
Merge pull request #1146 from luanrivello/patch-1
Fix kitty listen_on example
2021-08-29 20:16:40 +05:30
Luan Belem Rivello f9cf6dad48
Fix kitty listen_on example 2021-08-28 20:14:35 -03:00
Arun Prakash Jana c974690482
Fix build break 2021-08-25 20:14:55 +05:30
Arun Prakash Jana 742759f32d Exports special variables before running plugins 2021-08-25 16:32:45 +05:30
Terminator X ad968b88da
Merge pull request #1143 from joelazar/master
fix fzhist plugin - get fish_history from the right place
2021-08-25 16:25:20 +05:30
joelazar dba6eeb431 fix fzhist plugin - get fish_history from the right place 2021-08-25 10:36:10 +02:00
Arun Prakash Jana 55fc0c500b
Retain original context hovered file when selecting from plugin dir 2021-08-25 01:32:40 +05:30
Arun Prakash Jana a62dbf093a
Fix NULL file name handling 2021-08-25 00:47:52 +05:30
Arun Prakash Jana 900513710f
More special variables at prompt/shell
$dN: directory path open in context N
$fN: file path hovered in context N
2021-08-24 23:34:40 +05:30
Arun Prakash Jana 6243de06f4
Update help page logo 2021-08-23 11:02:53 +05:30
Arun Prakash Jana e11cbc289a
Add a cool ASCII art to help screen 2021-08-23 04:38:54 +05:30
elder-n00b e4813f06c1
MacOSX legacy (#1138)
* Branched v4.2
Added workaround for Mac OS X < 10.12.0
(Only tested on 10.11.6, lower versions may need more workaround)

* Added *.dSYM to .gitignore

* Added comments for the macosx detection in Makefile

* Fixed indentation, formatting and missing newline at eof

* Moved includes inside include guard

Co-authored-by: elder-n00b <elder-n00b@yandex.com>
2021-08-22 12:17:27 +05:30
Arun Prakash Jana 6c5eab5e55 Jump back last dir from plugin dir with - 2021-08-19 08:45:07 +05:30
luukvbaal ad6b6bd3df
Icon changes .iconlookup (#1136) 2021-08-18 23:16:29 +05:30
CantoroMC a65055fc32
change and add some icons-nerdfont (#1135) 2021-08-18 19:23:53 +05:30
Arun Prakash Jana 6c3a3dbc15
Update README 2021-08-18 00:27:09 +05:30
CantoroMC 43da9a9c46
icon for zsh, nix, and matlab files(nerdfonts), lua color to lua file (#1132)
* icon for nix and matlab files(nerdfonts), lua color to lua file

* Update .iconlookup

* Update icons-nerdfont.h

* Update icons.h

Co-authored-by: luukvbaal <31730729+luukvbaal@users.noreply.github.com>
2021-08-17 20:41:42 +02:00
Arun Prakash Jana 78ea6702f7
Key B to add bookmarks on the fly 2021-08-17 20:53:54 +05:30
Terminator X 0aed67f329
Merge pull request #1131 from luukvbaal/patchfix
Fix gitstatus pathspec errors
2021-08-17 17:49:34 +05:30
Luuk van Baal 82d1510213 Fix gitstatus pathspec errors 2021-08-17 14:01:24 +02:00
Arun Prakash Jana 983d689a05
Disable auto-marking 2021-08-17 15:06:09 +05:30
0xACE 9d4330e382
Decide string length at compile time (#1130)
I run into many premature optimizations in our codebase which are
unnecessary.

In this particular case `strlen()` is optimized at compile time even at
`-O0` with `gcc`.

I would value higher code quality than dealing with these things in our
future endeavours. If this is accepted I may supply some more
readability patches.
2021-08-17 10:26:33 +05:30
Arun Prakash Jana 86648ab391
Fix length 2021-08-17 01:03:28 +05:30
Arun Prakash Jana 46294e9f3d
Add bookmarks directory support 2021-08-16 20:16:56 +05:30
Terminator X 840fb75208
Merge pull request #1129 from luukvbaal/patchfix
Fix namefirst patch conflict
2021-08-16 18:39:03 +05:30
Luuk van Baal b5750c9e38 Fix finder typo 2021-08-16 12:47:02 +02:00
Luuk van Baal 2b45c1be55 Fix patch conflict 2021-08-16 12:45:44 +02:00
Luuk van Baal b7c6fede5f
Add finder history/bookmarks 2021-08-15 22:07:20 +05:30
Arun Prakash Jana 943a7c13ac
Fix broken statusbar when symlink name exceeds max cols 2021-08-15 22:07:18 +05:30
Arun Prakash Jana 7cbc79a5fc
Remove repetitive code 2021-08-14 19:27:24 +05:30
Arun Prakash Jana 0b07b77e85
Update Quickstart 2021-08-14 12:43:18 +05:30
Arun Prakash Jana e4c1abb6b8
Save full filter in session to restore correctly 2021-08-12 23:15:15 +05:30
Arun Prakash Jana bf2b8d8c84
Decouple statusbar redraw 2021-08-12 22:09:06 +05:30
Arun Prakash Jana fc00faf7d0
Do not modify $PWD 2021-08-12 10:46:12 +05:30
Arun Prakash Jana 42061b0399
Fail operations if selection file is empty 2021-08-12 00:20:13 +05:30
Arun Prakash Jana b2c99b9e4e
Update docs 2021-08-12 00:01:01 +05:30
Arun Prakash Jana 06e2676421
Sync operation on selection among nnn instances 2021-08-11 21:53:42 +05:30
Arun Prakash Jana 97ac88dec2
Try to get current dir from PWD first 2021-08-10 22:34:18 +05:30
Arun Prakash Jana e146ad0d7a
Use a different function 2021-08-10 07:06:20 +05:30
Arun Prakash Jana 59d90aa2ce
Do not resolve symlinks in argument PATH 2021-08-10 06:48:21 +05:30
Arun Prakash Jana 1df63a78e4
Do not resolve symlinks in bookmarks 2021-08-09 01:13:54 +05:30
Arun Prakash Jana db1efba256
Update ToDo list link 2021-08-08 20:19:46 +05:30
Arun Prakash Jana 49ee5b21e7
Do not end selection mode before prompt/shell 2021-08-08 20:15:20 +05:30
Arun Prakash Jana 62a0486480 Do not end selection mode before invoking plugin 2021-08-08 18:31:29 +05:30
Terminator X 2c32f24073
Merge pull request #1121 from sikmir/haiku
Update Haiku Makefile
2021-08-08 18:07:51 +05:30
Nikolay Korotkiy f8aaf3b34c
Update Haiku Makefile 2021-08-08 15:32:39 +03:00
Arun Prakash Jana 7d17cf3f63
List open locations from active contexts in help 2021-08-07 23:55:51 +05:30
Arun Prakash Jana 87380732dc
make option O_MATCHFLTR to disable filters without match 2021-08-05 22:15:02 +05:30
Terminator X 1d5efa7074
Merge pull request #1119 from N-R-K/NOSSN
fix misleading comment in Makefile
2021-07-29 23:28:10 +05:30
NRK 5fcd3d1198 fix misleading comment in Makefile
reading the source code, setting NOSSN to 1 _disables_ session support,
not enable it.
2021-07-29 15:33:19 +06:00
Arun Prakash Jana b54f771a44
Fix #1117: Revert "Ignore filter key if no results"
This reverts commit 3ef50f06f8.
2021-07-29 03:34:06 +05:30
Terminator X 23a806864f
Merge pull request #1118 from N-R-K/xdgdefault
xdgdefault: make dmenu case-insensitive, fix style
2021-07-28 14:33:49 +05:30
NRK f3c29fe81a xdgdefault: make dmenu case-insensitive, fix style
Most *.desktop entries have same name as their application name so this
is not an issue most of the time. However in the case of Neovim, the
application name is "Neovim" while the desktop entry is "nvim.desktop"

Since dmenu is case sensitive by default this means that searching
"neovim" will not show any results since the N is not capitalized and
the desktop entry name is "nvim"

fzf doesn't have this issue since its case-insensitive/fuzzy by
default. Making dmenu case-insensitive solves this.

Also fix the indentation to be consistent with the rest of the script.
2021-07-28 12:30:30 +06:00
Arun Prakash Jana 88e38f1efc
Eliminate redundant stat() 2021-07-27 23:04:23 +05:30
Arun Prakash Jana 6ba0a8357f
redraw() is heavy and distracting 2021-07-26 06:19:56 +05:30
Arun Prakash Jana 8cebc69e71
Fix build break 2021-07-25 07:20:43 +05:30
Arun Prakash Jana f6856f61f7
Allow specifying output file in NNN_TMPFILE for cd on quit 2021-07-25 07:03:09 +05:30
Arun Prakash Jana f1dbb9622d Open controlling terminal only as stdin 2021-07-24 22:22:17 +05:30
Terminator X 0db988b9b2
Merge pull request #1114 from jcromero/patch-1
Fix wrong exclamation mark char description
2021-07-24 15:48:36 +05:30
jcromero 258a5846f7
Fix wrong exclamation mark char description 2021-07-24 11:54:27 +02:00
Arun Prakash Jana d80fdf335b
Check if file is already selected before appending in picker mode 2021-07-24 01:51:20 +05:30
Arun Prakash Jana e2545f9596
Truncate output file before writing in picker mode 2021-07-24 01:25:28 +05:30
Arun Prakash Jana 25fab4cb2e
Open controlling terminal for input when run in a script 2021-07-23 23:46:20 +05:30
N-R-K 3a98dfb0b0
xdgdefault plugin: add dmenu support (#1112)
* xdgdefault plugin: add dmenu support

use fzf if available. otherwise, if available, use dmenu.
should be possible to use rofi as well, but i don't use rofi nor do i
have it installed for testing.

* xdgdefault plugin: add GUI flag

* update xdgdefault requirement
2021-07-23 17:06:19 +05:30
Arun Prakash Jana 0150c69844
Update plugin docs 2021-07-22 20:11:07 +05:30
Arun Prakash Jana b561772ada
Remove dated documentation 2021-07-21 23:43:59 +05:30
Arun Prakash Jana ad163fb574
Revert variety in Haiku Makefile 2021-07-21 17:56:46 +05:30
Arun Prakash Jana bc5b39d54c
Prepare for release v4.2 Mojito 2021-07-21 17:45:39 +05:30
Arun Prakash Jana 14663b964b
Add option to specify arguments to exec 2021-07-21 11:54:40 +05:30
Arun Prakash Jana 3f07a8ca76
Press TAB to insert current file name at prompt 2021-07-21 11:24:46 +05:30
Jonathan Rash 4b4355c733
Added execute fallback to nuke 2021-07-21 10:28:33 +05:30
Arun Prakash Jana 7b31a356d2
Minor update 2021-07-20 23:31:40 +05:30
Arun Prakash Jana 9972c4bdb0
Fix #1110: sanitize path from plugin 2021-07-19 03:57:53 +05:30
Arun Prakash Jana c470143113
Clear filter early before running plugin 2021-07-19 01:52:44 +05:30
Arun Prakash Jana 3b5800fc7a
Selection-specific scratch buffer 2021-07-18 11:45:50 +05:30
Arun Prakash Jana 29a7a25445
Free allocated memory 2021-07-18 02:51:09 +05:30
Arun Prakash Jana 6f14190e6d
Plugin suedit - preserve environment 2021-07-17 22:00:38 +05:30
Arun Prakash Jana d54bc230f6
fzopen - add option to open files in nuke 2021-07-17 21:04:53 +05:30
Arun Prakash Jana e31f71285d
Merge plugin fzz into autojump 2021-07-17 20:02:22 +05:30
Arun Prakash Jana 1e182a1fe5
Remember the last command executed at prompt 2021-07-17 16:30:45 +05:30
Arun Prakash Jana f7aa4ed324
Add macro for prompt 2021-07-17 13:09:33 +05:30
Arun Prakash Jana 0ef34a930c
Use a simpler macro 2021-07-17 13:05:37 +05:30
Arun Prakash Jana 07b627a725
Fix unused variable warning 2021-07-17 04:46:35 +05:30
Arun Prakash Jana a911b3044a
Code reformat 2021-07-16 21:19:17 +05:30
Arun Prakash Jana 26f44f0dfc
Fix selection in / 2021-07-16 11:09:20 +05:30
Arun Prakash Jana fa0f9ddc93
Remove from selection when hovered entry is deleted 2021-07-16 04:44:01 +05:30
Arun Prakash Jana 3ef50f06f8
Ignore filter key if no results 2021-07-16 02:22:01 +05:30
Arun Prakash Jana d40dbfd69a
Do not apply filter if directory is empty 2021-07-16 01:54:15 +05:30
Arun Prakash Jana 8af773eb0d
Allocate PATH_MAX aligned memory size 2021-07-16 01:19:09 +05:30
Arun Prakash Jana 8ad807d4a9
Optimize repeat copy of same prefix 2021-07-15 23:43:07 +05:30
Arun Prakash Jana 4ec87e3021
Optimize bulk selection 2021-07-15 21:21:54 +05:30
Arun Prakash Jana 0159c08602
Invert optimization: allocate in a go 2021-07-15 18:59:00 +05:30
Arun Prakash Jana 064f5ea998
Show msg for both invert and select all 2021-07-15 11:45:32 +05:30
Arun Prakash Jana 9526fb7612
Optimize invert further 2021-07-15 02:06:11 +05:30
Arun Prakash Jana 61d8a29d84
In-place invert optimization 2021-07-14 21:04:02 +05:30
Arun Prakash Jana cef9bd289f
Update docs 2021-07-14 02:44:38 +05:30
Arun Prakash Jana b3ef30a8ba
Update add to and invert selection logic 2021-07-13 21:46:18 +05:30
Arun Prakash Jana 96f2dfa8a5
Scan for selection status on redraw() 2021-07-13 01:30:23 +05:30
Arun Prakash Jana 60f310160a
Remove redundant macro 2021-07-12 02:54:00 +05:30
Arun Prakash Jana baca4693ec
Remove redundant prompt 2021-07-12 01:22:39 +05:30
Terminator X e94ac0b91b
Merge pull request #1106 from KlzXS/persistent_selection
Use selbufpos instead of selbuflen
2021-07-11 23:58:58 +05:30
KlzXS b5d1a1b036
Use selbufpos instead of selbuflen 2021-07-11 20:16:28 +02:00
KlzXS c0dceb18c6
Persistent selection (#1086)
* Add persistsel

* Fix Makefile spacing

* Update Haiku Makefile

* Do a double pass on inversion

* Split single and double pass for easier testing

Removed lastappendpos

Eliminate suffix matches

* Check if dir is in selection before searching for files

Fix double pass

* Switch to mainline

Optimize memory moving

Handle large selection in invertsel()

Going forward with 2pass

* Update Makefiles

* Fix style

* Move forward declarations

* Remove edit selection in inversion

Replace buf with g_buf to fix CI

Fix CI

* Style changes

* Comment the code

* Style fixes

* Fix infinite loop

* Fix crash on empty invert

* Fix off-by-one-in-two-places

Off-by-twice?

* Adopt changes from master

* Only check directory if entry in it is selected

* Better organization

* Wrong variable

* Tiny optimizations

* Style fixes and updated man page

* Update man page

* Remember where we found directory path in selection

Add in progress message on invert
2021-07-10 07:30:02 +05:30
Arun Prakash Jana d9db6b045c
Fix #1102: suppress clang unused variable warnings 2021-07-10 02:08:48 +05:30
Arun Prakash Jana 5f5ee10e94
Fix #1101: confirm trashing files 2021-07-09 21:00:46 +05:30
Arun Prakash Jana facdc5fdeb
Fix #1098: clear selmode on last deselect 2021-07-06 23:25:49 +05:30
Piña Colada 1269dd2695
Merge pull request #1095 from luukvbaal/patches
Remove gitstatus libgit2 dependency
2021-07-06 17:48:25 +05:30
Luuk van Baal ddf845be88 Remove gitstatus libgit2 dependency 2021-07-06 02:01:19 +02:00
Piña Colada c482cf54f0
Merge pull request #1094 from jarun/preview-tui
Allow tmux inside kitty without KITTY_LISTEN_ON set
2021-07-05 22:29:03 +05:30
Luuk van Baal 4abced6142 Allow tmux inside kitty without KITTY_LISTEN_ON set 2021-07-05 15:40:18 +02:00
Piña Colada 77c16ac143
Merge pull request #1091 from luukvbaal/adjust_cols
Move adjust_cols and no else braces
2021-07-03 05:24:23 +05:30
Luuk van Baal 36ddbac10a Move ajust cols and no else braces 2021-07-03 00:50:51 +02:00
Arun Prakash Jana d4a4c72e00
Fix off_t to uint_t comparison warning
The man page says:

"blkcnt_t and off_t shall be signed integer types."

https://man7.org/linux/man-pages/man0/sys_types.h.0p.html
2021-07-02 20:34:02 +05:30
Piña Colada a7aae40069
Merge pull request #1090 from luukvbaal/imgview
Imgview fix ucollage directory
2021-07-01 14:56:53 +05:30
Luuk van Baal fe07ae35f2 Imgview fix ucollage directory 2021-07-01 11:24:49 +02:00
Piña Colada a7603ba1f2
Merge pull request #1084 from luukvbaal/imgview
Imgview open hovered image and reuse NNN_PREVIEWDIR
2021-07-01 14:36:07 +05:30
Luuk van Baal a199156cae Imgview hovered image/thumbnail dir 2021-07-01 02:26:47 +02:00
Piña Colada ce8b9fdb2f
Merge pull request #1088 from 1bman/1bman-patch-1
fix icons.h typo
2021-06-30 19:51:50 +05:30
1bman 99bd80137d
fix icons.h typo
fixed some typo
2021-06-30 14:25:01 +05:30
Piña Colada 2fda5c78e0
Merge pull request #1087 from KlzXS/debug
Fix debug line number
2021-06-29 23:59:30 +05:30
KlzXS c39e54b288
Fix debug line number 2021-06-29 19:49:59 +02:00
Arun Prakash Jana 1729a10ef4
Try to unmount hovered local dir 2021-06-28 00:16:32 +05:30
Arun Prakash Jana 96fb61a6a2
Reformat help 2021-06-27 21:26:37 +05:30
Piña Colada 15b60a80ad
Merge pull request #1082 from tonijarjour/patch-1
Make sxiv play gifs automatically
2021-06-27 20:54:42 +05:30
Arun Prakash Jana 04a806dc09
Reformat help 2021-06-27 20:53:13 +05:30
Toni Jarjour 1607200a75
Make sxiv play gifs automatically 2021-06-27 11:11:39 -04:00
Arun Prakash Jana 63ef6d7340
Update docs 2021-06-25 23:57:28 +05:30
Arun Prakash Jana 73a175cc39
Update readme 2021-06-25 00:06:15 +05:30
Arun Prakash Jana d1df9343c6
Remove redundant param 2021-06-23 23:42:10 +05:30
Arun Prakash Jana e7f73d95ce
Fix memory leak 2021-06-22 20:51:23 +05:30
Arun Prakash Jana eae60c3048
Simplify mkpath() 2021-06-22 20:27:07 +05:30
KlzXS 20e0c49292
Replace fd dependency with find (#1078) 2021-06-21 04:59:50 +05:30
Arun Prakash Jana 7ce5bbcdf7
Break long macros 2021-06-20 22:16:09 +05:30
Arun Prakash Jana 94c399e2cf
One notify FIFO mode at a time 2021-06-20 21:42:44 +05:30
Arun Prakash Jana d9f988e7ed
Fix patch break 2021-06-20 21:25:22 +05:30
Arun Prakash Jana 983babc5f6
Improve alignment 2021-06-20 20:48:06 +05:30
Arun Prakash Jana c597f3be9b
Add range check 2021-06-20 19:20:10 +05:30
Arun Prakash Jana 0e8819fea8
Fix alignments 2021-06-20 15:45:03 +05:30
Arun Prakash Jana 2ffb0f7c79
Fix patch break 2021-06-20 14:29:07 +05:30
Arun Prakash Jana 556941c2b2
Alphabetically order internal states 2021-06-20 14:23:13 +05:30
Arun Prakash Jana 4f297fa147
Shared previewer and explorer 2021-06-20 13:58:33 +05:30
Arun Prakash Jana 9f86015c16
Print version to stdout 2021-06-20 10:25:40 +05:30
Arun Prakash Jana c0ed6d1d04
Fix compilation error when FIFO is disabled 2021-06-19 21:04:21 +05:30
Arun Prakash Jana b626cfa00f
Use macro in all places 2021-06-19 20:36:16 +05:30
Arun Prakash Jana 3e91c2c977
Use easily identifiable type 2021-06-19 18:39:35 +05:30
Arun Prakash Jana 8f3785f2e5
Restore statusbar after unmounting remote/archive 2021-06-19 17:23:28 +05:30
Arun Prakash Jana d5359f0455
Fix created archive not highlighted 2021-06-19 15:16:24 +05:30
Arun Prakash Jana 17bb0cfb52
Default to CWD for atool 2021-06-19 14:31:04 +05:30
Arun Prakash Jana e8f0c53287
Do not open current dir in nez context when extracting archive 2021-06-19 13:00:50 +05:30
Arun Prakash Jana 96cbb4ff84
Fix #1076: show file name in archive extract prompt 2021-06-19 11:21:42 +05:30
Arun Prakash Jana 35aa864554
Fix returns 2021-06-19 01:48:14 +05:30
Arun Prakash Jana 825effb264
Fix broken window due to double spawn 2021-06-18 20:44:44 +05:30
Michael Lan b2e7f7794c
Refactor fifo code and add explorer (#1075)
* Refactor fifo code and add explorer

* add explorer option and flag

* notify explorer fifo on selection

* close explorer fifo file descriptor

* Try to create explorer fifo if doesn't exist

This doesn't quite work

* Allow uncreated fifos

* delete persistence fifo on cleanup

with correct formatting

Co-authored-by: luukvbaal <31730729+luukvbaal@users.noreply.github.com>

* Work correctly with NOFIFO

* Refactor variable names

* fix

* Use -X flag for explorer mode

* Update manpage with explorer mode

Co-authored-by: luukvbaal <31730729+luukvbaal@users.noreply.github.com>
2021-06-18 05:38:28 +05:30
luukvbaal 02b5b15001
Update gitstatus patch (#1074) 2021-06-18 05:02:44 +05:30
Arun Prakash Jana 640a56e1cc
sigwinch test 2021-06-18 04:36:28 +05:30
Arun Prakash Jana 239c7e7970 Revert "Remove redundant old state handlers"
This reverts commit 1590103ab7.
2021-06-17 00:31:26 +05:30
Arun Prakash Jana 0b99247774
Update docs 2021-06-16 23:44:24 +05:30
Arun Prakash Jana 1590103ab7
Remove redundant old state handlers 2021-06-16 00:17:01 +05:30
Arun Prakash Jana 3db1dfd17f
Get rid of file stream functions 2021-06-15 20:52:59 +05:30
Arun Prakash Jana 0884ad4af9
Code reformat, use basic IO functions 2021-06-15 20:18:19 +05:30
Arun Prakash Jana 745a30ccb5
Use raw functions instead of file functions 2021-06-15 15:28:53 +05:30
Arun Prakash Jana a007fe8493
Fix #1072: use internal tmp file to page output 2021-06-15 14:38:08 +05:30
Arun Prakash Jana 4c66a8c0c3
Remove redundant newline 2021-06-14 22:12:55 +05:30
Arun Prakash Jana 3834d75d77
Extract archive to, mount remove/archive in smart context 2021-06-14 00:16:49 +05:30
Arun Prakash Jana e256353fbf
Support archive "extract to..." 2021-06-13 14:38:37 +05:30
Arun Prakash Jana 54258749e1
Update docs 2021-06-13 10:38:12 +05:30
Arun Prakash Jana 361521b769
Fix patch incompatibility 2021-06-13 09:04:49 +05:30
Arun Prakash Jana 16a15fc976
Remove option from auto-complete 2021-06-13 02:03:47 +05:30
Arun Prakash Jana 06c5b17c02
Config NNN_HELP to show output of a program on top of help page 2021-06-13 01:22:36 +05:30
Arun Prakash Jana 8c116eea2c
Use netbsd-curses v0.3.2 2021-06-13 00:36:45 +05:30
Arun Prakash Jana f4f6919c02
Fix #1067: handle SIGWINCH the ncurses way
Ref: https://invisible-island.net/ncurses/ncurses-intro.html#xterm
2021-06-13 00:16:43 +05:30
Anna Arad 4f977ff269
Add force-tty capability to spawn and set pagers to it (#1070)
Co-authored-by: Anna Arad <annagram@shards.me>
2021-06-12 23:02:48 +05:30
Arun Prakash Jana 0dd76e7aec
Drop unreliable popen() call [e.g. fails if filename has "] 2021-06-12 22:44:15 +05:30
Arun Prakash Jana 69926a8eff
Simplify show_stats() 2021-06-12 21:33:26 +05:30
Arun Prakash Jana 9a124ae935
Initialize local array to NULL 2021-06-12 19:41:34 +05:30
Arun Prakash Jana 145ca91df2
Attempt to fix #1067: hook into ncurses to resize on KEY_RESIZE 2021-06-12 16:59:19 +05:30
Arun Prakash Jana e537c22281
Use standard descriptor names 2021-06-11 23:35:57 +05:30
Piña Colada 8238410d4c
Merge pull request #1066 from kevinsjoberg/remove-fzf-options
Remove opinionated options
2021-06-11 19:34:32 +05:30
Kevin Sjöberg 8fc18fb9d6 Remove opinionated options 2021-06-11 15:48:29 +02:00
Kevin Sjöberg f443768260
Support opening regular text files on macOS 2021-06-11 15:35:03 +05:30
Arun Prakash Jana cbbac4728b
Checkpatch fixes 2021-06-10 00:31:17 +05:30
Arun Prakash Jana 54b2eb51d5
Use static global 2021-06-08 20:50:09 +05:30
Arun Prakash Jana 46b48cf71c
Update examples 2021-06-07 01:18:34 +05:30
Arun Prakash Jana 6d2d901a91
Update docs 2021-06-06 23:35:15 +05:30
Arun Prakash Jana 51ac3d02c9
Remove redundant examples 2021-06-06 22:16:24 +05:30
Arun Prakash Jana 15eed29227
NNN_PLUG: use `|` to page run-and-exit cmd output 2021-06-06 21:51:30 +05:30
Arun Prakash Jana 3b6938f782
Fix alignment 2021-06-06 18:58:13 +05:30
Arun Prakash Jana f24b82a750
NNN_PLUG: use & as run-gui-cmd-as-plugin symbol (earlier |) 2021-06-06 18:48:14 +05:30
Arun Prakash Jana 9de941306c
NNN_PLUG: use ! as run-cmd-as-plugin symbol (earlier _) 2021-06-06 18:37:49 +05:30
Arun Prakash Jana 5e34181bb3
Add another useful plugin example 2021-06-06 17:35:05 +05:30
Arun Prakash Jana d87414eb61
Plugin fzcd - decouple from selection 2021-06-06 17:07:23 +05:30
Arun Prakash Jana 488fe6b941
Plugin cleanup 2: one-liners with paged output
- remove `mediainf`
- remove `uidgid`
- remove `hexview`
- remove `pdfview`
2021-06-06 13:56:09 +05:30
Arun Prakash Jana fb6ca79197
Plugin cleanup 1
- rename `wall` to `wallpaper`
- remove `upgrade` - packaging is on OBS now
- remove `treeview` - needs minor preview-tui tweak
- remove `picker` - `nnn -p -` does the same
2021-06-06 10:44:10 +05:30
Piña Colada 29bce804be
Merge pull request #1055 from luukvbaal/patches
Add gitstatus patch -G flag
2021-06-05 20:00:09 +05:30
Luuk van Baal 7edf14139b Add gitstatus patch -G flag 2021-06-05 16:21:01 +02:00
Arun Prakash Jana e1a9aa0aa5
Mention patch framework 2021-06-05 04:54:15 +05:30
Piña Colada b8851bdf16
Merge pull request #1054 from luukvbaal/preview-tui
Preview-tui single previewpid file
2021-06-05 04:27:58 +05:30
Luuk van Baal c9c0be32a8 Preview-tui single previewpid file 2021-06-05 00:35:54 +02:00
Piña Colada 4637a5a84d
Merge pull request #1053 from luukvbaal/preview-tui
Suppress pgrep output
2021-06-04 21:24:27 +05:30
Luuk van Baal 0fff92b396 Supress pgrep output 2021-06-04 17:04:01 +02:00
Piña Colada 7b32e3bae0
Merge pull request #1052 from luukvbaal/preview-tui
Fix preview-tui zombie
2021-06-04 20:25:48 +05:30
Luuk van Baal 5533f152bd Fix preview-tui zombie 2021-06-04 16:43:59 +02:00
Piña Colada f681a5b3f1
Merge pull request #1051 from luukvbaal/preview-tui
Fix preview-tui job control
2021-06-04 07:43:59 +05:30
Luuk van Baal 99e039d504 Fix preview-tui job control 2021-06-04 04:10:35 +02:00
Arun Prakash Jana f03b5dd4a9
Add mention 2021-06-03 23:28:07 +05:30
Arun Prakash Jana 2df1e64127
Post-release formalities 2021-06-03 22:54:12 +05:30
98 changed files with 5995 additions and 3604 deletions

View File

@ -3,10 +3,11 @@ version: 2
jobs:
compile:
docker:
- image: ubuntu:20.04
- image: ubuntu:22.04
working_directory: ~/nnn
environment:
CI_FORCE_TEST: 1
parallelism: 4
steps:
- run:
command: |
@ -14,24 +15,14 @@ jobs:
DEBIAN_FRONTEND="noninteractive" TZ="America/New_York" apt-get -y install tzdata
apt install -y --no-install-recommends software-properties-common wget gpg-agent shellcheck
apt install -y --no-install-recommends git make pkg-config libncurses-dev libreadline-dev
apt install -y --no-install-recommends gcc-7 gcc-8 gcc-9 gcc-10
apt install -y --no-install-recommends clang-6.0 clang-7 clang-8 clang-9 clang-10 clang-11 clang-tidy-11
apt install -y --no-install-recommends gcc-9 gcc-10 gcc-11 gcc-12
apt install -y --no-install-recommends clang-11 clang-12 clang-13 clang-14 clang-15 clang-tidy-15
- checkout
- run:
command: |
export CFLAGS=-Werror
make clean
echo
echo "########## gcc-7 ##########"
CC=gcc-7 make strip
ls -l nnn
make clean
echo
echo "########## gcc-8 ##########"
CC=gcc-8 make strip
ls -l nnn
make clean
echo
echo "########## gcc-9 ##########"
CC=gcc-9 make strip
ls -l nnn
@ -42,28 +33,13 @@ jobs:
ls -l nnn
make clean
echo
echo "########## clang-6 ##########"
CC=clang-6.0 make strip
echo "########## gcc-11 ##########"
CC=gcc-11 make strip
ls -l nnn
make clean
echo
echo "########## clang-7 ##########"
CC=clang-7 make strip
ls -l nnn
make clean
echo
echo "########## clang-8 ##########"
CC=clang-8 make strip
ls -l nnn
make clean
echo
echo "########## clang-9 ##########"
CC=clang-9 make strip
ls -l nnn
make clean
echo
echo "########## clang-10 ##########"
CC=clang-10 make strip
echo "########## gcc-12 ##########"
CC=gcc-12 make strip
ls -l nnn
make clean
echo
@ -72,10 +48,25 @@ jobs:
ls -l nnn
make clean
echo
echo "########## clang-tidy-10 ##########"
clang-tidy-11 src/* -- -I/usr/include -I/usr/include/ncursesw
echo "########## clang-12 ##########"
CC=clang-12 make strip
ls -l nnn
make clean
echo
echo "########## clang-13 ##########"
CC=clang-13 make strip
ls -l nnn
make clean
echo
echo "########## clang-14 ##########"
CC=clang-14 make strip
ls -l nnn
make clean
echo
echo "########## clang-tidy-15 ##########"
clang-tidy-15 src/* -- -I/usr/include -I/usr/include/ncursesw
echo "########## shellcheck ##########"
find plugins/ -type f -not -name "*.md" -exec shellcheck -e SC1090,SC2230 {} +
find plugins/ -type f ! \( -name "*.md" -o -name "*-mac" \) -exec shellcheck {} +
package-and-publish:
machine: true
@ -101,13 +92,13 @@ jobs:
- run:
name: "publish to GitHub"
command: |
go get github.com/tcnksm/ghr
go install github.com/tcnksm/ghr@latest
ghr -t ${GITHUB_API_TOKEN} -u ${CIRCLE_PROJECT_USERNAME} -r ${CIRCLE_PROJECT_REPONAME} -c ${CIRCLE_SHA1} -replace ${CIRCLE_TAG} ./dist/
workflows:
version: 2
test:
CircleCI:
jobs: &all-tests
- compile

2
.github/FUNDING.yml vendored
View File

@ -1,3 +1,3 @@
# These are supported funding model platforms
custom: https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=RMLTQ76JSXJ4Q
github: jarun

View File

@ -36,6 +36,7 @@ If we need more information and there is no communication from the bug reporter
- [ ] Custom desktop opener (if applicable):
- [ ] Program options used:
- [ ] Configuration options set:
- [ ] Plugins are installed
- [ ] Issue exists on `nnn` master
#### Exact steps to reproduce the issue

4
.github/ISSUE_TEMPLATE/config.yml vendored Normal file
View File

@ -0,0 +1,4 @@
contact_links:
- name: Idea, Enhancement, Question, Support
url: https://github.com/jarun/nnn/discussions
about: If you have a question, need support or want to discuss new ideas then please open a discussion thread.

View File

@ -1,29 +0,0 @@
---
name: Feature request
about: Suggest an idea for this project
title: ''
labels: enhancement
assignees: ''
---
**Is your feature request related to a problem? Please describe.**
A clear and concise description of what the problem is.
**Describe the solution you'd like**
A clear and concise description of what you want to happen.
**Describe alternatives you've considered**
A clear and concise description of any alternative solutions or features you've
considered.
**Additional context**
Add any other context or screenshots about the feature request here.
**Consider contributing**
Please consider contributing the feature back to `nnn`.
Feel free to discuss in the ToDo list thread. We are more than happy to help.

View File

@ -1,4 +1,4 @@
name: ci
name: GitHubCI
on:
push:
@ -27,11 +27,23 @@ jobs:
env:
CC: clang
run: |
brew update
brew install llvm
# see: https://github.com/actions/setup-python/issues/577
brew update || true
brew install llvm || true
brew unlink python@3.11 && brew link python@3.11
export PATH="/usr/local/opt/llvm/bin:$PATH"
export PATH="/opt/homebrew/opt/llvm/bin:$PATH"
export CFLAGS="$CFLAGS -Werror"
make clean
make
make clean
clang-tidy src/* -- -I/usr/include
ubuntu-patches:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Compile patches with gcc
env:
CC: gcc
run: |
make checkpatches

42
.github/workflows/codeql.yml vendored Normal file
View File

@ -0,0 +1,42 @@
name: "CodeQL"
on:
push:
branches: [ "master" ]
pull_request:
branches: [ "master" ]
schedule:
- cron: "11 23 * * 3"
jobs:
analyze:
name: Analyze
runs-on: ubuntu-latest
permissions:
actions: read
contents: read
security-events: write
strategy:
fail-fast: false
matrix:
language: [ cpp, python ]
steps:
- name: Checkout
uses: actions/checkout@v3
- name: Initialize CodeQL
uses: github/codeql-action/init@v2
with:
languages: ${{ matrix.language }}
queries: +security-and-quality
- name: Autobuild
uses: github/codeql-action/autobuild@v2
if: ${{ matrix.language == 'cpp' || matrix.language == 'python' }}
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v2
with:
category: "/language:${{ matrix.language }}"

3
.gitignore vendored
View File

@ -1,2 +1,5 @@
*.o
*.dSYM
nnn
src/icons-generated*.h
src/icons-hash-gen

234
CHANGELOG
View File

@ -1,3 +1,235 @@
nnn v4.9 Elixir
2023-08-27
- config option `NNN_ARCHMNT` to specify archive mounter utility
- key <kbd>^y</kbd> to jump to next young file
- filter adjustment when opening context from plugin
- properly update mode after `chmod`
- pre-fill selected file name to create link if sel is preferred over hovered
- fix crash when `PWD` is empty
- make `quitcd.bash_zsh` POSIX-compliant
- `nmount` - support `udiskctl` as default
- `preview-tui` - support wezterm split size percentage
- `preview-tui` - move to bash for environment manipulation through arrays
- `fzopen` - handle empty selection
- `finder` - use default path to find
- add icons for `djvu` files
- support Nerd Fonts v3.0.0 and above (older versions are broken by v3.0.0)
-------------------------------------------------------------------------------
nnn v4.8 Spritz
2023-04-13
- show total size (key <kbd>S</kbd>) of non-filtered selection in a directory
- fix tilde (~) handling in file name
- plugin `.nmv` now respects `-u` flag
- env var `$NNN_PREFER_SELECTION` exported to all plugins
- support for wezterm in `preview-tui`
- create new file or directory (tree) on startup
- run command as plugin now supports exported variables
- use `"$nnn"` anywhere when running command as plugin
- set defaults for some prompts on <kbd>Enter</kbd>
- improve archive, rename and create new workflows
- optimize link creation
- allow overwriting regular files on new empty file creation
- add patch for colemak keyboard (existing renamed to colemak-dh)
- add correct check for Wayland in clipboard plugins
- add quitcd script for nushell
- plugin `kdeconnect` - send multiple files
- plugin `preview-tui`: add `chafa` as preferred image viewer, multiple fixes
- plugin `nmount` - misc. improvements
- add icon for jxl files
-------------------------------------------------------------------------------
nnn v4.7 Cuba libre
2022-11-24
- fix <kbd>^N</kbd> not working sometimes (#1449)
- fix file remove confirmation prompt
- bring back `atool` as the default archive handler
- add option `-B` to use `bsdtar` as the archive utility
- find and list mode improvements
ntinue even if max paths/data size limit is exceeded
eed improvements
pport listing maximum 16K paths of 64 MiB of data
- key <kbd>J</kbd> to jump to an entry or relative offset from current entry
- prefill the hard link creation prompt when there's a single target (#1507)
- documented workaround for docker container crash (#1407, #1476)
- plugin `imgview`: handle arguments as strings (#1509)
- plugin `wallpaper`: support Wayland (#1512)
- plugin `upload`: handle selection using `ffsend` (#1523)
- add Rust icons (#1502)
-------------------------------------------------------------------------------
nnn v4.6 Absinthe
2022-07-26
- icon handling overhaul (#1432, #1436)
- better performance, memory usage and reduced binary size
- emoji support for supporting distros and terminals (#1346)
- open the target directory of symlinked bookmarks (#1353)
- enable show hidden when a hidden file is passed as argument
- add Colemak-DH layout keybinds to patch framework (#1421)
- set `bsdtar` as the default archive utility
- support 4 byte unicode keybinds (#1428)
- enable directory auto-enter during filter operation (`-A` to disable)
- enable filter prompt inside the bookmark/plugin dirs
- show volume usage information in help
- add new icon colors for mp4 and flac files
- use `stat -x` for file details on *BSD and macOS (#1389)
- interpret suffix `$nnn` when paging (#1355)
- disable key <kbd>e</kbd> (edit file) in explorer mode (#1394)
- fix double order chars on filter case match change
- `.cbcp`: more verbose message on paste without a selection
- plugin `preview-tui`: scale-up kitty previews
- plugin `preview-tui`: account for ueberzug offset
- plugin `preview-tui`: support `SPLIT_SIZE` for preview pane (#1431)
- plugin `autojump`: support z.lua
- new Makefile target `shellcheck` to verify plugins
-------------------------------------------------------------------------------
nnn v4.5 Cachaça
2022-04-26
- disable filter info if file details (option `-i`) enabled
- open previous active context on context quit
- switch <kbd>^J</kbd> and <kbd>+</kbd> functionality:
- <kbd>+</kbd>: toggle file selection
- <kbd>^J</kbd>: toggle auto-jump on file open
- allow symlink creation with name `@` to a single file (#1345)
- clear selection on successful operation at native prompt with "%j" (#1330)
- reverse timestamps of entries modified/created within 5 minutes
- avoid using non-portable `xargs` flags on macOS (#1299)
- quitcd script for Elvish shell > 0.17.0 (#1344)
- plugin `openall` to open selected files together (#1333)
- plugin `gitroot` to jump to git root directory from a subtree
- plugin `gsconnect` to send the selected files to Android using gsconnect
- icon for opus and webp files
- `preview-tui` - fix gif conversion and whitespace name
- `preview-tui` - add support for windows terminal split
- `preview-tui` - djvu file previews
- `nuke` - add support for `imv` when named _imv_
- `gsconnect` - support connection to multiple devices
- export `NNN_INCLUDE_HIDDEN` to plugins (#1308)
- respect `NNN_TRASH` in `.nmv` (#1306)
- add GNU sed as a dependency with support for env var `SED`
- use bold `>` to point at current entry in detail mode
- add 2 spaces after icons for better visibility
- documentation refresh
- make option `O_NOSORT` to load directories unsorted on entry
-------------------------------------------------------------------------------
nnn v4.4 Tequila
2021-11-23
- support macOS iterm2 in plugin preview-tui (#1196)
- use selection at native command prompt with `%j` and `%J`
- docs - https://github.com/jarun/nnn/wiki/concepts#special-variables
- scroll strings longer than columns in rename/new prompts (#1213, #279)
- batch rename symlink targets in listing mode (#1214)
- option for recursive rename in plugin .nmv (#1186)
- more frequent checks for cancellation during du (#1236)
- picker mode: enable auto-proceed
- picker mode: don't pick hovered file on <kbd>Enter</kbd> if selection exists
- picker mode: fix issue in plugin `fzopen` when used to pick files
- send file to explorer FIFO on double left click instead of opening it
- new neovim plugin [nnn.nvim](https://github.com/luukvbaal/nnn.nvim)
- nvim-only, featuring explorer mode (`-F` flag)
- explorer mode for [nnn.vim](https://github.com/mcchrish/nnn.vim#explorer)
- remove option `-w`: always place HW cursor on current entry
- accept link name when linking a single target (#1201)
- option `-i` to show current file information in info bar
- force GNU sed on *BSD and Solaris
- add `nsxiv` support to nuke, preview-tabbed and imgview (#1230)
- fix preview-tui without `-a` (#1208)
- pass `pts` in env var for preview-tui to use in `tput` (#1235)
- disable editing file in picker mode (#1183)
- save session in picker mode (#1190)
- use nerd icons for gitstatus patch (#1220)
-------------------------------------------------------------------------------
nnn v4.3 Martini
2021-09-29
- cool ASCII art logo in the help screen
- add `bookmarks` directory for flexible symlinked bookmarks
- new key <kbd>B</kbd> to add a symlinked bookmark for current dir
- special variables `$dN`, `$fN` available for plugins/prompt/shell to access
dir/hovered file in each context
- config `NNN_ORDER` to set directory-specific ordering
- show/hide hidden files as per context state in plugin based batch rename
- retain search filter history for plugin `finder`
- sync multiple instances of `nnn` after operation on selection
- signal CWD change to terminal via OSC-7 (#1147)
- save complete per-context filter when saving sessions
- disable symlink resolution for paths in `NNN_BMS` and arg `PATH`
- do not end selection mode on running plugins/prompt/shell
- plugin `bookmarks` replaced by symlinked bookmarks support
- list open locations in active contexts in help page
- make option `O_MATCHFLTR` to discard filter key if no match
- configurable `NNN_TMPFILE` to _cd on quit_
- disable auto marking directories (use <kbd>-</kbd>)
- picker mode improvements
- open tty for input if `STDIN` is non-tty
- truncate output file before writing
- do not double select a file on <kbd>Enter</kbd>
- legacy macOS (< 10.12.0) support
- no redraw during du calculation, show processed dir name
- plugin `xdgdefault`: add dmenu support
- user patch `restorepreview`: close/restore `preview-tui` for internal edits
-------------------------------------------------------------------------------
nnn v4.2 Mojito
2021-07-21
- `NNN_PLUG` indicator symbol interpretation has **changed**:
- `!` - _run-cmd-as-plugin_ (earlier `_`)
- `&` - _run-gui-cmd-as-plugin_ (earlier `|`)
- `|` (new) - page noninteractive _run-cmd-as-plugin_ output
- persistent selection markers (#1086)
- option _extract to..._ for archives
- mount remote and mount/extract archive to a smart context
- confirm file trashing to avoid accidental press of <kbd>x</kbd> (#1101)
- insert the last command executed at prompt on <kbd>Up</kbd> or <kbd>Down</kbd>
- insert the current file name at empty prompt on <kbd>TAB</kbd>
- handle redraw issue on missed `KEY_RESIZE` (#1067)
- add force-tty capability to spawn and set pagers to it (#1064)
- clear selection mode on deselecting last selected file (#1098)
- remove selected hovered entry from selection on deletion
- disable filtering in empty directories
- ignore last pressed filter character when no matches
- fix broken screen on resize while paging (#1072)
- fix archive not hovered on creation
- remove libgit2 dependency in `gitstatus` patch (#1095)
- add `-G` flag for `gitstatus` patch
- option `-X` for explorer (persistent picker) mode
- option `-F` decommissioned in favour of config `NNN_HELP`
- `-F` redefined to multiplex `NNN_FIFO` to preview or explore
- support paging noninterative _run-cmd-as-plugin_ output
- `nuke` - add option to execute binaries (#1111)
- plugin `fzopen` - call `open` on macOS, add option to use `nuke`
- plugin `fzcd` will not modify selection
- plugin `suedit` - preserve environment
- several `preview-tui` fixes
- plugin `wall` renamed to `wallpaper`
- remove plugin `fzz` - merged into plugin `autojump`
- remove plugin `upgrade` - packaging is on OBS now
- remove plugin `treeview` - needs minor `preview-tui` tweak
- remove plugin `picker` - `nnn -p -` does the same
- remove plugin `pdfview` - needs simple change in `pdfread`
- remove plugin `uidgid` - use program option `-U`
- remove plugins `mediainf`, `hexview` - simple one-liners
-------------------------------------------------------------------------------
nnn v4.1.1 Sake
2021-06-03
@ -281,7 +513,7 @@ nnn v3.1
- hover and connect by dir name (within config dir)
- move to next entry on current file delete
- on single file copy/move, select the copied/moved file
- option `-f` to to use readline history file (off by default)
- option `-f` to use readline history file (off by default)
- use `s` in status bar to indicate selection in progress
- make var `O_NOMOUSE` to disable mouse support
- do not store `NNN_TRASH` and `-Q` in config/session

View File

@ -2,7 +2,7 @@ BSD 2-Clause License
Copyright (c) 2014-2016, Lazaros Koromilas <lostd@2f30.org>
Copyright (c) 2014-2016, Dimitris Papastamos <sin@2f30.org>
Copyright (c) 2016-2021, Arun Prakash Jana <engineerarun@gmail.com>
Copyright (c) 2016-2023, Arun Prakash Jana <engineerarun@gmail.com>
All rights reserved.
Redistribution and use in source and binary forms, with or without

130
Makefile
View File

@ -21,19 +21,22 @@ O_NOFIFO := 0 # no FIFO previewer support
O_CTX8 := 0 # enable 8 contexts
O_ICONS := 0 # support icons-in-terminal
O_NERD := 0 # support icons-nerdfont
O_EMOJI := 0 # support emoji
O_QSORT := 0 # use Alexey Tourbin's QSORT implementation
O_BENCH := 0 # benchmark mode (stops at first user input)
O_NOSSN := 0 # enable session support
O_NOSSN := 0 # disable session support
O_NOUG := 0 # disable user, group name in status bar
O_NOX11 := 0 # disable X11 integration
O_MATCHFLTR := 0 # allow filters without matches
O_NOSORT := 0 # disable sorting entries on dir load
# User patches
O_COLEMAK := 0 # change key bindings to colemak compatible layout
O_GITSTATUS := 0 # add git status to detail view
O_NAMEFIRST := 0 # print file name first, add uid and guid to detail view
O_RESTOREPREVIEW := 0 # add preview pipe to close and restore preview pane
ifeq ($(strip $(O_GITSTATUS)),1)
LDLIBS += -lgit2
endif
T_ICONS := 0 # test if multiple icons options are set and fail
# convert targets to flags for backwards compatibility
ifneq ($(filter debug,$(MAKECMDGOALS)),)
@ -49,7 +52,7 @@ endif
ifeq ($(strip $(O_DEBUG)),1)
CPPFLAGS += -DDEBUG
CFLAGS += -g
CFLAGS += -g3
endif
ifeq ($(strip $(O_NORL)),1)
@ -70,6 +73,8 @@ ifeq ($(strip $(O_NOLC)),1)
$(info *** Ignoring O_NOLC since O_ICONS is set ***)
else ifeq ($(strip $(O_NERD)),1)
$(info *** Ignoring O_NOLC since O_NERD is set ***)
else ifeq ($(strip $(O_EMOJI)),1)
$(info *** Ignoring O_NOLC since O_EMOJI is set ***)
else
CPPFLAGS += -DNOLC
endif
@ -92,11 +97,30 @@ ifeq ($(strip $(O_CTX8)),1)
endif
ifeq ($(strip $(O_ICONS)),1)
CPPFLAGS += -DICONS
ICONS_INCLUDE = icons-generated-icons-in-term.h
CPPFLAGS += -DICONS_IN_TERM -DICONS_INCLUDE=\"$(ICONS_INCLUDE)\"
ifeq ($(strip $(T_ICONS)),1)
$(error Choose only one system for icons (O_ICONS, O_NERD or O_EMOJI))
endif
T_ICONS := 1
endif
ifeq ($(strip $(O_NERD)),1)
CPPFLAGS += -DNERD
ICONS_INCLUDE = icons-generated-nerd.h
CPPFLAGS += -DNERD -DICONS_INCLUDE=\"$(ICONS_INCLUDE)\"
ifeq ($(strip $(T_ICONS)),1)
$(error Choose only one system for icons (O_ICONS, O_NERD or O_EMOJI))
endif
T_ICONS := 1
endif
ifeq ($(strip $(O_EMOJI)),1)
ICONS_INCLUDE = icons-generated-emoji.h
CPPFLAGS += -DEMOJI -DICONS_INCLUDE=\"$(ICONS_INCLUDE)\"
ifeq ($(strip $(T_ICONS)),1)
$(error Choose only one system for icons (O_ICONS, O_NERD or O_EMOJI))
endif
T_ICONS := 1
endif
ifeq ($(strip $(O_QSORT)),1)
@ -119,6 +143,14 @@ ifeq ($(strip $(O_NOX11)),1)
CPPFLAGS += -DNOX11
endif
ifeq ($(strip $(O_MATCHFLTR)),1)
CPPFLAGS += -DMATCHFLTR
endif
ifeq ($(strip $(O_NOSORT)),1)
CPPFLAGS += -DNOSORT
endif
ifeq ($(shell $(PKG_CONFIG) ncursesw && echo 1),1)
CFLAGS_CURSES ?= $(shell $(PKG_CONFIG) --cflags ncursesw)
LDLIBS_CURSES ?= $(shell $(PKG_CONFIG) --libs ncursesw)
@ -149,14 +181,47 @@ DESKTOPFILE = misc/desktop/nnn.desktop
LOGOSVG = misc/logo/logo.svg
LOGO64X64 = misc/logo/logo-64x64.png
COLEMAK = patches/colemak
GITSTATUS = patches/gitstatus
NAMEFIRST = patches/namefirst
RESTOREPREVIEW = patches/restorepreview
# test if we are on Mac OS X and get X.Y.Z OS version with system binary /usr/bin/sw_vers
MACOS_VERSION := $(strip $(shell command -v sw_vers >/dev/null && [ "`sw_vers -productName`" = "Mac OS X" ] && sw_vers -productVersion))
# if Mac OS X detected, test if its version is below 10.12.0 relying on "sort -c" returning "disorder" message if the input is not sorted
ifneq ($(MACOS_VERSION),)
MACOS_BELOW_1012 := $(if $(strip $(shell printf '10.12.0\n%s' "$(MACOS_VERSION)" | sort -ct. -k1,1n -k2,2n -k3,3n 2>&1)),1)
endif
# if Mac OS X version is below 10.12.0, compile in the replacement clock_gettime and define MACOS_BELOW_1012 so that it's included in nnn.c
ifneq ($(MACOS_BELOW_1012),)
GETTIME_C = misc/macos-legacy/mach_gettime.c
GETTIME_H = misc/macos-legacy/mach_gettime.h
SRC += $(GETTIME_C)
HEADERS += $(GETTIME_H)
CPPFLAGS += -DMACOS_BELOW_1012
endif
ifeq ($(strip $(O_DEBUG)),1)
HEADERS += src/dbg.h
endif
ifeq ($(strip $(O_QSORT)),1)
HEADERS += src/qsort.h
endif
ifeq ($(strip $(O_EMOJI)),1)
HEADERS += src/icons.h src/$(ICONS_INCLUDE)
endif
ifeq ($(strip $(O_NERD)),1)
HEADERS += src/icons.h src/$(ICONS_INCLUDE)
endif
ifeq ($(strip $(O_ICONS)),1)
HEADERS += src/icons.h src/$(ICONS_INCLUDE) src/icons-in-terminal.h
endif
all: $(BIN)
$(BIN): $(SRC) $(HEADERS)
$(BIN): $(SRC) $(HEADERS) Makefile
@$(MAKE) --silent prepatch
$(CC) $(CPPFLAGS) $(CFLAGS) $(LDFLAGS) -o $@ $< $(LDLIBS)
$(CC) $(CPPFLAGS) $(CFLAGS) $(LDFLAGS) -o $@ $(GETTIME_C) $< $(LDLIBS)
@$(MAKE) --silent postpatch
# targets for backwards compatibility
@ -164,6 +229,10 @@ debug: $(BIN)
norl: $(BIN)
nolc: $(BIN)
src/$(ICONS_INCLUDE): src/icons-hash.c src/icons.h src/icons-in-terminal.h
$(CC) $(CPPFLAGS) $(CFLAGS) $(LDFLAGS) -DICONS_GENERATE -o src/icons-hash-gen src/icons-hash.c
./src/icons-hash-gen > $@
install-desktop: $(DESKTOPFILE)
$(INSTALL) -m 0755 -d $(DESTDIR)$(DESKTOPPREFIX)
$(INSTALL) -m 0644 $(DESKTOPFILE) $(DESTDIR)$(DESKTOPPREFIX)
@ -204,12 +273,18 @@ static:
# static binary with patched nerd font support
make O_STATIC=1 O_NERD=1 strip
mv $(BIN) $(BIN)-nerd-static
# static binary with emoji support
make O_STATIC=1 O_EMOJI=1 strip
mv $(BIN) $(BIN)-emoji-static
musl:
cp misc/musl/musl-static-ubuntu.sh .
./musl-static-ubuntu.sh 1
rm ./musl-static-ubuntu.sh
shellcheck:
find ./plugins/ -type f -not -name "*.md" -exec shellcheck {} +
dist:
mkdir -p nnn-$(VERSION)
$(CP) -r $(DISTFILES) nnn-$(VERSION)
@ -221,7 +296,7 @@ sign:
gpg --detach-sign --yes nnn-$(VERSION).tar.gz
rm -f nnn-$(VERSION).tar.gz
upload-local: sign static musl-static
upload-local: sign static musl
$(eval ID=$(shell curl -s 'https://api.github.com/repos/jarun/nnn/releases/tags/v$(VERSION)' | jq .id))
# upload sign file
curl -XPOST 'https://uploads.github.com/repos/jarun/nnn/releases/$(ID)/assets?name=nnn-$(VERSION).tar.gz.sig' \
@ -231,6 +306,7 @@ upload-local: sign static musl-static
upx -qqq $(BIN)-static
upx -qqq $(BIN)-icons-static
upx -qqq $(BIN)-nerd-static
upx -qqq $(BIN)-emoji-static
# upload static binary
tar -zcf $(BIN)-static-$(VERSION).x86_64.tar.gz $(BIN)-static
curl -XPOST 'https://uploads.github.com/repos/jarun/nnn/releases/$(ID)/assets?name=$(BIN)-static-$(VERSION).x86_64.tar.gz' \
@ -246,6 +322,11 @@ upload-local: sign static musl-static
curl -XPOST 'https://uploads.github.com/repos/jarun/nnn/releases/$(ID)/assets?name=$(BIN)-nerd-static-$(VERSION).x86_64.tar.gz' \
-H 'Authorization: token $(NNN_SIG_UPLOAD_TOKEN)' -H 'Content-Type: application/x-sharedlib' \
--upload-file $(BIN)-nerd-static-$(VERSION).x86_64.tar.gz
# upload emoji compiled static binary
tar -zcf $(BIN)-emoji-static-$(VERSION).x86_64.tar.gz $(BIN)-emoji-static
curl -XPOST 'https://uploads.github.com/repos/jarun/nnn/releases/$(ID)/assets?name=$(BIN)-emoji-static-$(VERSION).x86_64.tar.gz' \
-H 'Authorization: token $(NNN_SIG_UPLOAD_TOKEN)' -H 'Content-Type: application/x-sharedlib' \
--upload-file $(BIN)-emoji-static-$(VERSION).x86_64.tar.gz
# upload musl static binary
tar -zcf $(BIN)-musl-static-$(VERSION).x86_64.tar.gz $(BIN)-musl-static
curl -XPOST 'https://uploads.github.com/repos/jarun/nnn/releases/$(ID)/assets?name=$(BIN)-musl-static-$(VERSION).x86_64.tar.gz' \
@ -253,26 +334,41 @@ upload-local: sign static musl-static
--upload-file $(BIN)-musl-static-$(VERSION).x86_64.tar.gz
clean:
$(RM) -f $(BIN) nnn-$(VERSION).tar.gz *.sig $(BIN)-static $(BIN)-static-$(VERSION).x86_64.tar.gz $(BIN)-icons-static $(BIN)-icons-static-$(VERSION).x86_64.tar.gz $(BIN)-nerd-static $(BIN)-nerd-static-$(VERSION).x86_64.tar.gz
$(RM) -f $(BIN) nnn-$(VERSION).tar.gz *.sig $(BIN)-static $(BIN)-static-$(VERSION).x86_64.tar.gz $(BIN)-icons-static $(BIN)-icons-static-$(VERSION).x86_64.tar.gz $(BIN)-nerd-static $(BIN)-nerd-static-$(VERSION).x86_64.tar.gz $(BIN)-emoji-static $(BIN)-emoji-static-$(VERSION).x86_64.tar.gz $(BIN)-musl-static $(BIN)-musl-static-$(VERSION).x86_64.tar.gz src/icons-hash-gen src/icons-generated-*.h
checkpatches:
./patches/check-patches.sh
prepatch:
ifeq ($(strip $(O_NAMEFIRST)),1)
patch --forward --strip=1 --input=$(NAMEFIRST)/mainline.diff
patch --forward $(PATCH_OPTS) --strip=1 --input=$(NAMEFIRST)/mainline.diff
ifeq ($(strip $(O_GITSTATUS)),1)
patch --forward --strip=1 --input=$(GITSTATUS)/namefirst.diff
patch --forward $(PATCH_OPTS) --strip=1 --input=$(GITSTATUS)/namefirst.diff
endif
else ifeq ($(strip $(O_GITSTATUS)),1)
patch --forward --strip=1 --input=$(GITSTATUS)/mainline.diff
patch --forward $(PATCH_OPTS) --strip=1 --input=$(GITSTATUS)/mainline.diff
endif
ifeq ($(strip $(O_RESTOREPREVIEW)),1)
patch --forward $(PATCH_OPTS) --strip=1 --input=$(RESTOREPREVIEW)/mainline.diff
endif
ifeq ($(strip $(O_COLEMAK)),1)
patch --forward $(PATCH_OPTS) --strip=1 --input=$(COLEMAK)/mainline.diff
endif
postpatch:
ifeq ($(strip $(O_NAMEFIRST)),1)
ifeq ($(strip $(O_GITSTATUS)),1)
patch --reverse --strip=1 --input=$(GITSTATUS)/namefirst.diff
patch --reverse $(PATCH_OPTS) --strip=1 --input=$(GITSTATUS)/namefirst.diff
endif
patch --reverse --strip=1 --input=$(NAMEFIRST)/mainline.diff
patch --reverse $(PATCH_OPTS) --strip=1 --input=$(NAMEFIRST)/mainline.diff
else ifeq ($(strip $(O_GITSTATUS)),1)
patch --reverse --strip=1 --input=$(GITSTATUS)/mainline.diff
patch --reverse $(PATCH_OPTS) --strip=1 --input=$(GITSTATUS)/mainline.diff
endif
ifeq ($(strip $(O_RESTOREPREVIEW)),1)
patch --reverse $(PATCH_OPTS) --strip=1 --input=$(RESTOREPREVIEW)/mainline.diff
endif
ifeq ($(strip $(O_COLEMAK)),1)
patch --reverse $(PATCH_OPTS) --strip=1 --input=$(COLEMAK)/mainline.diff
endif
skip: ;

View File

@ -15,26 +15,26 @@
href="https://github.com/jarun/nnn#features">Features</a>] [<a
href="https://github.com/jarun/nnn#quickstart">Quickstart</a>] [<a
href="https://github.com/jarun/nnn/tree/master/plugins#nnn-plugins">Plugins</a>] [<a
href="https://github.com/jarun/nnn/wiki">Documentation</a>]</h3>
href="https://github.com/jarun/nnn/wiki">Wiki</a>]</h3>
`nnn` (_n³_) is a full-featured terminal file manager. It's tiny and nearly 0-config with an [incredible speed](https://github.com/jarun/nnn/wiki/Performance).
`nnn` (_n³_) is a full-featured terminal file manager. It's tiny, nearly 0-config and [incredibly fast](https://github.com/jarun/nnn/wiki/Performance).
It is designed to be unobtrusive with smart workflows to match the trains of thought.
`nnn` can analyze disk usage, batch rename, launch apps and pick files. The plugin repository has tons of plugins to extend the capabilities further e.g. [preview](https://github.com/jarun/nnn/wiki/Live-previews), (un)mount disks, find & list, file/dir diff, upload files.
`nnn` can analyze disk usage, batch rename, launch apps and pick files. The plugin repository has tons of plugins to extend the capabilities further e.g. [live previews](https://github.com/jarun/nnn/wiki/Live-previews), (un)mount disks, find & list, file/dir diff, upload files. A [patch framework](https://github.com/jarun/nnn/tree/master/patches) hosts sizable user-submitted patches which are subjective in nature.
There are 2 independent (neo)vim plugins - [nnn.vim](https://github.com/mcchrish/nnn.vim) and [vim-floaterm nnn wrapper](https://github.com/voldikss/vim-floaterm#nnn).
Independent (neo)vim plugins - [nnn.vim](https://github.com/mcchrish/nnn.vim), [vim-floaterm nnn wrapper](https://github.com/voldikss/vim-floaterm#nnn) and [nnn.nvim](https://github.com/luukvbaal/nnn.nvim) (neovim exclusive).
It runs smoothly on the Pi, [Termux](https://www.youtube.com/embed/AbaauM7gUJw) (Android), Linux, macOS, BSD, Haiku, Cygwin, WSL, across DEs and GUI utilities or a strictly CLI environment.
Runs on the Pi, [Termux](https://www.youtube.com/embed/AbaauM7gUJw) (Android), Linux, macOS, BSD, Haiku, Cygwin, WSL, across DEs or a strictly CLI env.
[_(there's more)_](https://github.com/jarun/nnn/wiki/Basic-use-cases#the_nnn-magic)
<p align="center">
<a href="https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=RMLTQ76JSXJ4Q"><img src="https://img.shields.io/badge/donate-@PayPal-1eb0fc.svg" alt="Donate via PayPal!" /></a>
</p>
## Features
- Quality
- Privacy-aware (no unconfirmed user data collection)
- POSIX-compliant, follows Linux kernel coding style
- Highly optimized, static analysis integrated code
- Frugal
- Typically needs less than 3.5MB resident memory
- Works with 8 colors (and xterm 256 colors)
@ -51,24 +51,21 @@ It runs smoothly on the Pi, [Termux](https://www.youtube.com/embed/AbaauM7gUJw)
- No config file, minimal config with sensible defaults
- Plugin to backup configuration
- Widely available on many packagers
- Touch enabled, comfortable on handhelds too!
- Touch enabled, handheld-friendly shortcuts
- Unicode support
- Quality
- Privacy-aware (no unconfirmed user data collection)
- POSIX-compliant, follows Linux kernel coding style
- Highly optimized, static analysis integrated code
- Modes
- Light (default), detail
- Disk usage analyzer (block/apparent)
- File picker, (neo)vim plugin
- Navigation
- *Type-to-nav* mode with dir auto-select
- Filter with automatic dir entry on unique match
- *Type-to-nav* (turbo navigation/always filter) mode
- Contexts (_aka_ tabs/workspaces) with custom colors
- Sessions, bookmarks with hotkeys; mark and visit a dir
- Sessions, bookmarks, mark and visit a dir
- Remote mounts (needs `sshfs`, `rclone`)
- Familiar shortcuts (arrows, <kbd>~</kbd>, <kbd>-</kbd>, <kbd>@</kbd>), quick look-up
- `cd` on quit (*easy* shell integration)
- Auto-advance on opening files
- Proceed to next file on file open and selection
- Search
- Instant filtering with *search-as-you-type*
- Regex (POSIX/PCRE) and string (default) filters
@ -78,41 +75,42 @@ It runs smoothly on the Pi, [Termux](https://www.youtube.com/embed/AbaauM7gUJw)
- Case-insensitive version (_aka_ natural) sort
- By name, access/change/mod (default) time, size, extn
- Reverse sort
- Directory-specific ordering
- Mimes
- Preview hovered files in FIFO-based previewer
- Open with desktop opener or specify a custom opener
- File-specific colors (or minimal _dirs in context color_)
- Icons (customize and compile-in)
- Icons and Emojis support (customize and compile-in)
- Plugin for image, video and audio thumbnails
- Create, list, extract, mount (FUSE based) archives
- Create, list, extract (to), mount (FUSE based) archives
- Option to open all text files in `$EDITOR`
- Information
- Detailed file information
- Media information plugin
- Convenience
- Detailed file stats and mime information
- Run plugins and custom commands with hotkeys
- FreeDesktop compliant trash utility integration
- Cross-dir file/all/range selection
- Create (with parents), rename, duplicate files and dirs
- Create new file or directory (tree) on startup
- Batch renamer for selection or dir
- List input stream of file paths from stdin or plugin
- Copy (as), move (as), delete, archive, link selection
- Dir updates, notification on `cp`, `mv`, `rm` completion
- Copy file paths to system clipboard on select
- Launch apps, run commands, spawn a shell, toggle exe
- Access hovered file as `$nnn` at prompt or spawned shell
- Access context paths/files at prompt or spawned shell
- Lock terminal after configurable idle timeout
- Capture and show output of a program in help screen
- Basic support for screen readers and braille displays
## Quickstart
1. [Install](https://github.com/jarun/nnn/wiki/Usage) `nnn` and any dependencies you need. All files are opened with the desktop opener by default.
2. Add option `-e` to your alias to open text files in `$VISUAL`/`$EDITOR`/ `vi`. [Open detached](https://github.com/jarun/nnn/wiki/Basic-use-cases#detached-text) if you wish.
1. [Install](https://github.com/jarun/nnn/wiki/Usage) `nnn` and the dependencies you need.
2. The desktop opener is default. Use `-e` to open text files in the terminal. Optionally [open detached](https://github.com/jarun/nnn/wiki/Basic-use-cases#detached-text).
3. Configure [`cd` on quit](https://github.com/jarun/nnn/wiki/Basic-use-cases#configure-cd-on-quit).
4. [Sync subshell `$PWD`](https://github.com/jarun/nnn/wiki/Basic-use-cases#sync-subshell-pwd) to `nnn`.
5. [Install plugins](https://github.com/jarun/nnn/tree/master/plugins#installation).
6. Use `-x` to sync selection to system clipboard, show notis on `cp`, `mv`, `rm` completion and set xterm title.
7. For a CLI-only environment, customize and use plugin [`nuke`](https://github.com/jarun/nnn/blob/master/plugins/nuke) with option `-c` (overrides `-e`).
6. Use `-x` to sync selection to clipboard, show notis on `cp`, `mv`, `rm` and set xterm title.
7. For a CLI-only environment, set [`NNN_OPENER`](https://github.com/jarun/nnn/wiki/Usage#configuration) to [`nuke`](https://github.com/jarun/nnn/blob/master/plugins/nuke). Use option `-c`.
8. Bid `ls` goodbye! `alias ls='nnn -de'` :sunglasses:
9. Visit the [Live previews](https://github.com/jarun/nnn/wiki/Live-previews) and [Troubleshooting](https://github.com/jarun/nnn/wiki/Troubleshooting) Wiki pages.
@ -144,7 +142,9 @@ Don't memorize! Arrows, <kbd>/</kbd>, <kbd>q</kbd> suffice. <kbd>Tab</kbd> creat
- LinuxLinks [[1](https://www.linuxlinks.com/nnn-fast-and-flexible-file-manager/)] [[2](https://www.linuxlinks.com/bestconsolefilemanagers/)] [[3](https://www.linuxlinks.com/excellent-system-tools-nnn-portable-terminal-file-manager/)]
- [Linux Magazine; FOSSPicks](https://www.linux-magazine.com/Issues/2017/205/FOSSPicks/(offset)/15)
- [Make Tech Easier](https://www.maketecheasier.com/nnn-file-manager-terminal/)
- [Opensource.com](https://opensource.com/article/22/12/linux-file-manager-nnn)
- [Open Source For You](https://www.opensourceforu.com/2019/12/nnn-this-feature-rich-terminal-file-manager-will-enhance-your-productivity/)
- [PCLinuxOS Magazine Issue June 2021](https://pclosmag.com/html/Issues/202106/page08.html)
- [Suckless Rocks](https://suckless.org/rocks/)
- [Ubuntu Full Circle Magazine Issue 135; Review: nnn](https://fullcirclemagazine.org/issue-135/)
- [Using and Administering Linux: Volume 2: Zero to SysAdmin: Advanced Topics](https://books.google.com/books?id=MqjDDwAAQBAJ&pg=PA32)
@ -152,12 +152,14 @@ Don't memorize! Arrows, <kbd>/</kbd>, <kbd>q</kbd> suffice. <kbd>Tab</kbd> creat
## Developers
- [Arun Prakash Jana](https://github.com/jarun) (Copyright © 2016-2021)
- [Arun Prakash Jana](https://github.com/jarun) (Copyright © 2016-2023)
- [0xACE](https://github.com/0xACE)
- [Anna Arad](https://github.com/annagrram)
- [KlzXS](https://github.com/KlzXS)
- [Léo Villeveygoux](https://github.com/leovilok)
- [Luuk van Baal](https://github.com/luukvbaal)
- [NRK](https://codeberg.org/NRK)
- [Sijmen J. Mulder](https://github.com/sjmulder)
- and other contributors
Visit the [ToDo list](https://github.com/jarun/nnn/issues/1040) to contribute or see the features in progress.
Visit the [Tracker](https://github.com/jarun/nnn/issues/1546) thread for a list of features in progress and anything up for grabs. Feel free to [discuss](https://github.com/jarun/nnn/discussions) new ideas or enhancement requests.

View File

@ -1,13 +1,18 @@
# Contributing
Contributions to nnn are welcome! There's always an open issue with the current ToDo list, which contains the proposed features for the next release you can get your hands on. Any small changes or ideas should go in there, rather than in a separate issue.
Before suggesting changes, please read a bit about [the design principles nnn follows](https://github.com/jarun/nnn/wiki#design), and make sure you aren't breaking any of them.
Before suggesting changes, please read a bit about [the design principles nnn follows](https://github.com/jarun/nnn/wiki/concepts#design), and make sure you aren't breaking any of them.
Feel free to join the [Discussions](https://github.com/jarun/nnn/discussions). We highly recommended a discussion before raising a PR.
## Coding standard
`nnn` follows the Linux kernel coding style closely. The C source code uses TABs and the plugins use 4 spaces for indentation.
CI runs `shellcheck` on plugins. Please watch out for any failures if you are modifying/adding a plugin.
- Code changes should not break the patch framework. Please run `make checkpatches` to ensure.
- Run `make shellcheck` if adding/modifying plugins.
CI runs patch framework sanity test and `shellcheck`. Please watch out for any failures after raising the PR.
## Resources
The [wiki](https://github.com/jarun/nnn/wiki/Developer-guides) has some resources for developers you might be interested in: building, debugging...

View File

@ -15,6 +15,7 @@ _nnn ()
-a
-A
-b
-B
-c
-C
-d
@ -22,9 +23,9 @@ _nnn ()
-e
-E
-f
-F
-g
-H
-i
-J
-K
-l
@ -42,7 +43,6 @@ _nnn ()
-u
-U
-V
-w
-x
-h
)

View File

@ -12,8 +12,9 @@ else
end
complete -c nnn -s a -d 'auto-create NNN_FIFO'
complete -c nnn -s A -d 'disable dir auto-select'
complete -c nnn -s A -d 'disable dir auto-enter'
complete -c nnn -s b -r -d 'bookmark key to open' -x -a '(echo $NNN_BMS | awk -F: -v RS=\; \'{print $1"\t"$2}\')'
complete -c nnn -s B -d 'use bsdtar for archives'
complete -c nnn -s c -d 'cli-only opener'
complete -c nnn -s C -d 'color by context'
complete -c nnn -s d -d 'start in detail mode'
@ -21,11 +22,11 @@ complete -c nnn -s D -d 'dirs in context color'
complete -c nnn -s e -d 'open text files in $VISUAL/$EDITOR/vi'
complete -c nnn -s E -d 'use EDITOR for undetached edits'
complete -c nnn -s f -d 'use readline history file'
complete -c nnn -s F -d 'show fortune'
complete -c nnn -s g -d 'regex filters'
complete -c nnn -s H -d 'show hidden files'
complete -c nnn -s J -d 'no auto-proceed on select'
complete -c nnn -s K -d 'detect key collision'
complete -c nnn -s i -d 'show current file info'
complete -c nnn -s J -d 'no auto-advance on selection'
complete -c nnn -s K -d 'detect key collision and exit'
complete -c nnn -s l -r -d 'lines to move per scroll'
complete -c nnn -s n -d 'start in type-to-nav mode'
complete -c nnn -s o -d 'open files only on Enter'
@ -41,6 +42,5 @@ complete -c nnn -s T -r -d 'a d e r s t v'
complete -c nnn -s u -d 'use selection (no prompt)'
complete -c nnn -s U -d 'show user and group'
complete -c nnn -s V -d 'show program version and exit'
complete -c nnn -s w -d 'hardware cursor mode'
complete -c nnn -s x -d 'notis, sel to system clipboard, xterm title'
complete -c nnn -s h -d 'show program help'

View File

@ -10,8 +10,9 @@ setopt localoptions noshwordsplit noksharrays
local -a args
args=(
'(-a)-a[auto-create NNN_FIFO]'
'(-A)-A[disable dir auto-select]'
'(-A)-A[disable dir auto-enter]'
'(-b)-b[bookmark key to open]:key char'
'(-B)-B[use bsdtar for archives]'
'(-c)-c[cli-only opener]'
'(-C)-C[color by context]'
'(-d)-d[start in detail mode]'
@ -19,16 +20,16 @@ args=(
'(-e)-e[open text files in $VISUAL/$EDITOR/vi]'
'(-E)-E[use EDITOR for undetached edits]'
'(-f)-f[use readline history file]'
'(-F)-F[show fortune]'
'(-g)-g[regex filters]'
'(-H)-H[show hidden files]'
'(-J)-J[no auto-proceed on select]'
'(-K)-K[detect key collision]'
'(-i)-i[show current file info]'
'(-J)-J[no auto-advance on selection]'
'(-K)-K[detect key collision and exit]'
'(-l)-l[lines to move per scroll]:val'
'(-n)-n[start in type-to-nav mode]'
'(-o)-o[open files only on Enter]'
'(-p)-p[copy selection to file]:file name'
'(-P)-P[plugin key to runn]:key char'
'(-P)-P[plugin key to run]:key char'
'(-Q)-Q[disable quit confirmation]'
'(-r)-r[show cp, mv progress (Linux-only)]'
'(-R)-R[disable rollover at edges]'
@ -39,7 +40,6 @@ args=(
'(-u)-u[use selection (no prompt)]'
'(-U)-U[show user and group]'
'(-V)-V[show program version and exit]'
'(-w)-C[hardware cursor mode]'
'(-x)-x[notis, sel to system clipboard, xterm title]'
'(-h)-h[show program help]'
'*:filename:_files'

View File

@ -21,9 +21,10 @@ O_ICONS := 0 # support icons-in-terminal
O_NERD := 0 # support icons-nerdfont
O_QSORT := 0 # use Alexey Tourbin's QSORT implementation
O_BENCH := 0 # benchmark mode (stops at first user input)
O_NOSSN := 0 # enable session support
O_NOSSN := 0 # disable session support
O_NOUG := 0 # disable user, group name in status bar
O_NOX11 := 0 # disable X11 integration
O_MATCHFLTR := 0 # allow filters without matches
# User patches
O_GITSTATUS := 0 # add git status to detail view
@ -118,6 +119,10 @@ ifeq ($(strip $(O_NOX11)),1)
CPPFLAGS += -DNOX11
endif
ifeq ($(strip $(O_MATCHFLTR)),1)
CPPFLAGS += -DMATCHFLTR
endif
ifeq ($(shell $(PKG_CONFIG) ncursesw && echo 1),1)
CFLAGS_CURSES ?= $(shell $(PKG_CONFIG) --cflags ncursesw)
LDLIBS_CURSES ?= $(shell $(PKG_CONFIG) --libs ncursesw)
@ -129,7 +134,7 @@ else
endif
ifeq ($(shell uname -s), Haiku)
LDLIBS_HAIKU ?= -lstdc++ -lbe
LDLIBS_HAIKU ?= -lstdc++ -lgnu -lbe
SRC_HAIKU ?= misc/haiku/nm.cpp
OBJS_HAIKU ?= misc/haiku/nm.o
endif

View File

@ -12,7 +12,7 @@ Cygwin, WSL, Haiku and works seamlessly with DEs and GUI utilities.
Visit the Wiki for concepts, program usage, how-tos and troubleshooting."
HOMEPAGE="https://github.com/jarun/nnn"
COPYRIGHT="2016-2021 Arun Prakash Jana"
COPYRIGHT="2016-2023 Arun Prakash Jana"
LICENSE="BSD (2-clause)"
REVISION="1"
SOURCE_URI="git://github.com/jarun/nnn.git"

View File

@ -9,10 +9,10 @@ resource app_signature "application/x-vnd.Jarun-nnn";
resource app_version {
major = 4,
middle = 1,
minor = 1,
middle = 9,
minor = 0,
variety = B_APPV_FINAL,
variety = B_APPV_DEVELOPMENT,
internal = 0,
short_info = "nnn",

View File

@ -0,0 +1,42 @@
#include "mach_gettime.h"
#include <mach/mach_time.h>
#define MT_NANO (+1.0E-9)
#define MT_GIGA UINT64_C(1000000000)
// TODO create a list of timers,
static double mt_timebase = 0.0;
static uint64_t mt_timestart = 0;
int clock_gettime(clockid_t clk_id, struct timespec *tp)
{
kern_return_t retval = KERN_SUCCESS;
if (clk_id == TIMER_ABSTIME) {
if (!mt_timestart) { // only one timer, initialized on the first call to the TIMER
mach_timebase_info_data_t tb;
mach_timebase_info(&tb);
mt_timebase = tb.numer;
mt_timebase /= tb.denom;
mt_timestart = mach_absolute_time();
}
double diff = (mach_absolute_time() - mt_timestart) * mt_timebase;
tp->tv_sec = diff * MT_NANO;
tp->tv_nsec = diff - (tp->tv_sec * MT_GIGA);
} else { // other clk_ids are mapped to the corresponding mach clock_service
clock_serv_t cclock;
mach_timespec_t mts;
host_get_clock_service(mach_host_self(), clk_id, &cclock);
retval = clock_get_time(cclock, &mts);
mach_port_deallocate(mach_task_self(), cclock);
tp->tv_sec = mts.tv_sec;
tp->tv_nsec = mts.tv_nsec;
}
return retval;
}
/* Copyright (c) 2015-2018 Alf Watt - Open Source - https://opensource.org/licenses/MIT */

View File

@ -0,0 +1,28 @@
#ifndef mach_time_h
#define mach_time_h
#include <sys/types.h>
#include <sys/_types/_timespec.h>
#include <mach/mach.h>
#include <mach/clock.h>
/* The opengroup spec isn't clear on the mapping from REALTIME to CALENDAR
being appropriate or not.
http://pubs.opengroup.org/onlinepubs/009695299/basedefs/time.h.html */
// XXX only supports a single timer
#define TIMER_ABSTIME -1
#define CLOCK_REALTIME CALENDAR_CLOCK
#define CLOCK_MONOTONIC SYSTEM_CLOCK
typedef int clockid_t;
/* the mach kernel uses struct mach_timespec, so struct timespec
is loaded from <sys/_types/_timespec.h> for compatibility */
// struct timespec { time_t tv_sec; long tv_nsec; };
int clock_gettime(clockid_t clk_id, struct timespec *tp);
#endif
/* Copyright (c) 2015-2018 Alf Watt - Open Source - https://opensource.org/licenses/MIT */

View File

@ -33,14 +33,14 @@ sudo apt install -y --no-install-recommends musl musl-dev musl-tools
# Enter the library dir
cd netbsd-curses
# Get the last known good commit before cursor stuck issue is introduced
git checkout f1fa19a1f36a25d0971b3d08449303e6af6f3da5
# Get the last known working version
git checkout v0.3.2
# Compile the static netbsd-curses libraries
if [ ! -d "./libs" ]; then
mkdir libs
else
rm -vf libs/*
rm -vf -- libs/*
fi
make CC=musl-gcc CFLAGS=-O3 LDFLAGS=-static all-static -j$(($(nproc)+1))
cp -v libcurses/libcurses.a libterminfo/libterminfo.a libs/
@ -57,7 +57,7 @@ make CC=musl-gcc CFLAGS=-O3 LDFLAGS=-static -j$(($(nproc)+1))
# Compile nnn
cd ..
[ -e "./netbsd-curses" ] || rm "$BIN"
[ -e "./netbsd-curses" ] || rm -- "$BIN"
musl-gcc -O3 -DNORL -DNOMOUSE -std=c11 -Wall -Wextra -Wshadow -I./netbsd-curses/libcurses -I./musl-fts -o "$BIN" src/nnn.c -Wl,-Bsymbolic-functions -lpthread -L./netbsd-curses/libs -lcurses -lterminfo -static -L./musl-fts/.libs -lfts
strip "$BIN"

View File

@ -0,0 +1,30 @@
n ()
{
# Block nesting of nnn in subshells
[ "${NNNLVL:-0}" -eq 0 ] || {
echo "nnn is already running"
return
}
# The behaviour is set to cd on quit (nnn checks if NNN_TMPFILE is set)
# If NNN_TMPFILE is set to a custom path, it must be exported for nnn to
# see. To cd on quit only on ^G, remove the "export" and make sure not to
# use a custom path, i.e. set NNN_TMPFILE *exactly* as follows:
# NNN_TMPFILE="${XDG_CONFIG_HOME:-$HOME/.config}/nnn/.lastd"
export NNN_TMPFILE="${XDG_CONFIG_HOME:-$HOME/.config}/nnn/.lastd"
# Unmask ^Q (, ^V etc.) (if required, see `stty -a`) to Quit nnn
# stty start undef
# stty stop undef
# stty lwrap undef
# stty lnext undef
# The command builtin allows one to alias nnn to n, if desired, without
# making an infinitely recursive alias
command nnn "$@"
[ ! -f "$NNN_TMPFILE" ] || {
. "$NNN_TMPFILE"
rm -f -- "$NNN_TMPFILE" > /dev/null
}
}

View File

@ -1,27 +0,0 @@
n ()
{
# Block nesting of nnn in subshells
if [ -n $NNNLVL ] && [ "${NNNLVL:-0}" -ge 1 ]; then
echo "nnn is already running"
return
fi
# The default behaviour is to cd on quit (nnn checks if NNN_TMPFILE is set)
# To cd on quit only on ^G, remove the "export" as in:
# NNN_TMPFILE="${XDG_CONFIG_HOME:-$HOME/.config}/nnn/.lastd"
# NOTE: NNN_TMPFILE is fixed, should not be modified
export NNN_TMPFILE="${XDG_CONFIG_HOME:-$HOME/.config}/nnn/.lastd"
# Unmask ^Q (, ^V etc.) (if required, see `stty -a`) to Quit nnn
# stty start undef
# stty stop undef
# stty lwrap undef
# stty lnext undef
nnn "$@"
if [ -f "$NNN_TMPFILE" ]; then
. "$NNN_TMPFILE"
rm -f "$NNN_TMPFILE" > /dev/null
fi
}

View File

@ -1,8 +1,9 @@
# NOTE: set NNN_TMPFILE correctly if you use 'XDG_CONFIG_HOME'
# The default behaviour is to cd on quit (nnn checks if NNN_TMPFILE is set)
# To cd on quit only on ^G, export NNN_TMPFILE after the call to nnn
# NOTE: NNN_TMPFILE is fixed, should not be modified
# The behaviour is set to cd on quit (nnn checks if NNN_TMPFILE is set)
# If NNN_TMPFILE is set to a custom path, it must be exported for nnn to see.
# To cd on quit only on ^G, set NNN_TMPFILE after the nnn invocation, and make
# sure not to use a custom path.
set NNN_TMPFILE=~/.config/nnn/.lastd
# Unmask ^Q (, ^V etc.) (if required, see `stty -a`) to Quit nnn
@ -11,4 +12,6 @@ set NNN_TMPFILE=~/.config/nnn/.lastd
# stty lwrap undef
# stty lnext undef
alias n 'nnn; source "$NNN_TMPFILE"; rm -f "$NNN_TMPFILE"'
# The backslash allows one to alias n to nnn if desired without making an
# infinitely recursive alias
alias n '\nnn; source "$NNN_TMPFILE"; rm -f -- "$NNN_TMPFILE"'

41
misc/quitcd/quitcd.elv Normal file
View File

@ -0,0 +1,41 @@
# Append this file to ~/.elvish/rc.elv (Elvish > 0.17.0)
use path
fn n {|@a|
# Block nesting of nnn in subshells
if (has-env NNNLVL) {
try {
if (>= $E:NNNLVL 1) {
echo "nnn is already running"
return
}
} catch e {
nop
}
}
# The behaviour is set to cd on quit (nnn checks if NNN_TMPFILE is set)
# If NNN_TMPFILE is set to a custom path, it must be exported for nnn to
# see.
if (has-env XDG_CONFIG_HOME) {
set-env NNN_TMPFILE $E:XDG_CONFIG_HOME/nnn/.lastd
} else {
set-env NNN_TMPFILE $E:HOME/.config/nnn/.lastd
}
# Unmask ^Q (, ^V etc.) (if required, see `stty -a`) to Quit nnn
# stty start undef
# stty stop undef
# stty lwrap undef
# stty lnext undef
# The e: prefix allows one to alias n to nnn if desired without making an
# infinitely recursive alias
e:nnn $@a
if (path:is-regular $E:NNN_TMPFILE) {
eval (slurp < $E:NNN_TMPFILE)
rm -- $E:NNN_TMPFILE
}
}

View File

@ -4,17 +4,15 @@
function n --wraps nnn --description 'support nnn quit and change directory'
# Block nesting of nnn in subshells
if test -n "$NNNLVL"
if [ (expr $NNNLVL + 0) -ge 1 ]
echo "nnn is already running"
return
end
if test -n "$NNNLVL" -a "$NNNLVL" -ge 1
echo "nnn is already running"
return
end
# The default behaviour is to cd on quit (nnn checks if NNN_TMPFILE is set)
# To cd on quit only on ^G, remove the "-x" as in:
# set NNN_TMPFILE "$XDG_CONFIG_HOME/nnn/.lastd"
# NOTE: NNN_TMPFILE is fixed, should not be modified
# The behaviour is set to cd on quit (nnn checks if NNN_TMPFILE is set)
# If NNN_TMPFILE is set to a custom path, it must be exported for nnn to
# see. To cd on quit only on ^G, remove the "-x" from both lines below,
# without changing the paths.
if test -n "$XDG_CONFIG_HOME"
set -x NNN_TMPFILE "$XDG_CONFIG_HOME/nnn/.lastd"
else
@ -27,10 +25,12 @@ function n --wraps nnn --description 'support nnn quit and change directory'
# stty lwrap undef
# stty lnext undef
nnn $argv
# The command function allows one to alias this function to `nnn` without
# making an infinitely recursive alias
command nnn $argv
if test -e $NNN_TMPFILE
source $NNN_TMPFILE
rm $NNN_TMPFILE
rm -- $NNN_TMPFILE
end
end

37
misc/quitcd/quitcd.nu Normal file
View File

@ -0,0 +1,37 @@
# Run nnn with dynamic changing directory to the environment.
#
# $env.XDG_CONFIG_HOME sets the home folder for `nnn` folder and its $env.NNN_TMPFILE variable.
# See manual NNN(1) for more information.
#
# Import module using `use quitcd.nu n` to have `n` command in your context.
export def --env n [
...args : string # Extra flags to launch nnn with.
--selective = false # Change directory only when exiting via ^G.
] -> nothing {
# The behaviour is set to cd on quit (nnn checks if $env.NNN_TMPFILE is set).
# Hard-coded to its respective behaviour in `nnn` source-code.
let nnn_tmpfile = $env
| default '~/.config/' 'XDG_CONFIG_HOME'
| get 'XDG_CONFIG_HOME'
| path join 'nnn/.lastd'
| path expand
# Launch nnn. Add desired flags after `^nnn`, ex: `^nnn -eda ...$args`,
# or make an alias `alias n = n -eda`.
if $selective {
^nnn ...$args
} else {
NNN_TMPFILE=$nnn_tmpfile ^nnn ...$args
}
if ($nnn_tmpfile | path exists) {
# Remove <cd '> from the first part of the string and the last single quote <'>.
# Fix post-processing of nnn's given path that escapes its single quotes with POSIX syntax.
let path = open $nnn_tmpfile | str substring 4..-1 | str replace --all `'\''` `'`
^rm -- $nnn_tmpfile
cd $path
}
}

244
nnn.1
View File

@ -1,4 +1,4 @@
.Dd Jun 03, 2021
.Dd Aug 27, 2023
.Dt NNN 1
.Os
.Sh NAME
@ -6,8 +6,10 @@
.Nd The unorthodox terminal file manager.
.Sh SYNOPSIS
.Nm
.Op Ar -aAcCdDeEfFgHJKlnQrRSuUVwxh
.Op Ar -aAcCdDeEfgHJKnQrRSuUVxh
.Op Ar -b key
.Op Ar -F val
.Op Ar -l val
.Op Ar -p file
.Op Ar -P key
.Op Ar -s name
@ -21,15 +23,29 @@ is a performance-optimized, feature-packed fork of noice
.Em http://git.2f30.org/noice/
with seamless desktop integration, simplified navigation,
.Em type-to-nav
mode with auto select, disk usage analyzer mode, bookmarks,
mode with dir auto-enter, disk usage analyzer mode, bookmarks,
contexts, application launcher, familiar navigation shortcuts,
subshell spawning and much more. It remains a simple and
efficient file manager that stays out of your way.
.Pp
.Nm
opens the current working directory by default if
opens the current working directory if
.Ar PATH
is not specified.
is not specified. If
.Ar PATH
is specified and it exists,
.Nm
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
@ -43,14 +59,17 @@ to see the list of keybinds.
supports the following options:
.Pp
.Fl a
auto-setup temporary NNN_FIFO (described in ENVIRONMENT section)
auto-setup temporary \fBNNN_FIFO\fR (described in \fIENVIRONMENT\fR section)
.Pp
.Fl A
disable directory auto-select in type-to-nav mode
disable directory auto-enter on unique filter match
.Pp
.Fl "b key"
specify bookmark key to open
.Pp
.Fl B
use bsdtar for archives (default: atool)
.Pp
.Fl c
indicates that the opener is a cli-only opener (overrides -e)
.Pp
@ -72,8 +91,9 @@ supports the following options:
.Fl f
use readline history file
.Pp
.Fl F
show fortune in help and settings screen
.Fl "F val"
fifo notification mode
0: notify as previewer, 1: notify as explorer
.Pp
.Fl g
use regex filters instead of substring match
@ -81,11 +101,15 @@ supports the following options:
.Fl H
show hidden files
.Pp
.Fl i
show current file information in info bar (may be slow)
.Pp
.Fl J
disable auto-proceed on select
disable auto-advance on selection
(eg. selecting an entry will no longer move cursor to the next entry)
.Pp
.Fl K
test for keybind collision
test for keybind collision and exit
.Pp
.Fl "l val"
number of lines to move per mouse wheel scroll
@ -107,10 +131,11 @@ supports the following options:
.Pp
.Fl r
show cp, mv progress
(Linux-only, needs advcpmv; '^T' shows the progress on BSD/macOS)
(Linux-only, needs \fIadvcpmv\fR; '^T' shows the progress on BSD/macOS)
.Pp
.Fl R
disable rollover at edges
disable rollover at edges (eg. pressing \fIdown\fR while on the last
entry will no longer move cursor to the first entry and vice\-versa)
.Pp
.Fl "s name"
load a session by name
@ -123,7 +148,8 @@ supports the following options:
.Pp
.Fl "T key"
sort order
keys: 'a'u / 'd'u / 'e'xtension / 'r'everse / 's'ize / 't'ime / 'v'ersion
keys: 'a'pparent disk usage / 'd'isk usage / 'e'xtension / 'r'everse / 's'ize / 't'ime / 'v'ersion
capitalize to reverse (except 'r')
.Pp
.Fl u
use selection if available, don't prompt to choose between selection and hovered entry
@ -134,12 +160,9 @@ supports the following options:
.Fl V
show version and exit
.Pp
.Fl w
place hardware cursor on hovered entry
.Pp
.Fl x
show notis on selection cp, mv, rm completion
copy path to system clipboard on select
show notifications on selection cp, mv, rm completion (requires \fI.ntfy\fR plugin)
copy path to system clipboard on selection (requires \fI.cbcp\fR plugin)
show xterm title (if non-picker mode)
.Pp
.Fl h
@ -195,6 +218,10 @@ Filters are strings (or regex patterns) to find matching entries in the current
directory instantly (\fIsearch-as-you-type\fR). Matches are case-insensitive by
default. The last filter in each context is persisted at runtime or in saved
sessions.
.br
When there's a unique match and it's a directory,
.Nm
auto enters the directory. Use the relevant program option to disable this.
.Pp
Special keys at filter prompt:
.Bd -literal
@ -203,7 +230,7 @@ Special keys at filter prompt:
-------- + ---------------------------------------
^char | Usual keybind functionality
Esc | Exit filter prompt but skip dir refresh
Alt+Esc | Exit filter prompt and refresh dir
Alt+Esc | Unfilter, quit context
-------- + ---------------------------------------
.Ed
.Pp
@ -222,6 +249,20 @@ Special keys at \fBempty filter prompt\fR:
------ + ---------------------------------------
.Ed
.Pp
Common regex use cases:
.Pp
(1) To list all matches starting with the filter expression,
start the expression with a '^' (caret) symbol.
.br
(2) Type '\\.mkv' to list all MKV files.
.br
(3) Use '.*' to match any character (\fIsort of\fR fuzzy search).
.br
(4) Exclude filenames having 'nnn' (compiled with PCRE lib): '^(?!nnn)'
.Pp
In the \fBtype-to-nav\fR mode directories are opened in filter
mode, allowing continuous navigation.
.Pp
Additional special keys at \fBempty filter prompt\fR
in \fBtype-to-nav\fR mode:
.Bd -literal
@ -229,7 +270,7 @@ in \fBtype-to-nav\fR mode:
Key | Function
------ + ------------------------
' | Go to first non-dir file
+ | Toggle auto-advance
+ | Toggle file selection
, | Mark CWD
- | Go to last visited dir
. | Show hidden files
@ -242,25 +283,6 @@ in \fBtype-to-nav\fR mode:
~ | Go HOME
------ + ------------------------
.Ed
.Pp
Common regex use cases:
.Pp
(1) To list all matches starting with the filter expression,
start the expression with a '^' (caret) symbol.
.br
(2) Type '\\.mkv' to list all MKV files.
.br
(3) Use '.*' to match any character (\fIsort of\fR fuzzy search).
.br
(4) Exclude filenames having 'nnn' (compiled with PCRE lib): '^(?!nnn)'
.Pp
In the \fItype-to-nav\fR mode directories are opened in filter
mode, allowing continuous navigation.
.br
When there's a unique match and it's a directory,
.Nm
auto selects the directory and enters it in this mode. Use the relevant
program option to disable this behaviour.
.Sh SELECTION
.Nm
allows file selection across directories and contexts!
@ -283,25 +305,23 @@ instances. Selection from multiple instances are not merged. The last instance
writing to the file overwrites earlier contents. If you have 2 instances of
.Nm
\fIopen\fR in 2 panes of a terminal multiplexer, you can select in one pane and
use the selection in the other pane.
use the selection in the other pane. The selection gets cleared in the
.Nm
instance where the selection was made on mv/rm (but not on cp).
.Pp
.Nm
clears the selection after an operation with the selection. Plugins are allowed
to define the behaviour individually.
clears the selection after a successful operation with the selection. Plugins
are allowed to define the behaviour individually.
.Pp
To edit the selection use the _edit selection_ key. Editing doesn't end the
selection mode. You can add more files to the selection and edit the list
again. If no file is selected in the current session, this option attempts
to list the selection file.
.Pp
.Nm
doesn't match directory entries for selected files after a redraw or after the
user navigates away from the directory. An attempt to do so will increase
memory consumption and processing significantly as
.Nm
allows selection across directories. So the selection marks are cleared. The
selection can still be edited in the same instance.
.Pp
To edit the selection use the _edit selection_ key. Use this key to remove a
file from selection after you navigate away from its directory or to remove
duplicates. Editing doesn't end the selection mode. You can add more files to
the selection and edit the list again. If no file is selected in the current
session, this option attempts to list the selection file.
can show the total size of non-filtered selected files listed in a
directory. For directories, only the size of the directory is added by
default. To add the size of the contents of a directory, switch to du mode.
.Sh FIND AND LIST
There are two ways to search and list:
.Pp
@ -311,7 +331,7 @@ There are two ways to search and list:
.Pp
File paths must be NUL-separated ('\\0'). Paths and can be relative to the
current directory or absolute. Invalid paths in the input are ignored. Input
limit is 65,536 paths or 256 MiB of data.
processing limit is 16,384 paths or 64 MiB (max_paths x max_path_len) of data.
.Pp
To list the input stream, start
.Nm
@ -333,7 +353,7 @@ Handy bash/zsh shell function to list files by mime-type in current directory:
list ()
{
find . -maxdepth 1 | file -if- | grep "$1" | awk -F: '{printf "%s\0", $1}' | nnn
find . -maxdepth 1 | file -if- | grep "$1" | awk -F: '{printf "%s%c", $1, 0}' | nnn
}
.Ed
.Pp
@ -346,6 +366,24 @@ file. Press '-' to return to the listing dir. Press 'Enter' to open the symlink.
.Pp
Listing input stream can be scripted. It can be extended to pick (option -p)
selected entries from the listed results.
.Sh BOOKMARKS
There are 2 ways (can be used together) to manage bookmarks.
.Pp
(1) Bookmark keys: See \fBNNN_BMS\fR under \fIENVIORNMENT\fR section on how to set
bookmark keys.
The select bookmark key \fIb\fR lists all the bookmark keys set in \fBNNN_BMS\fR
in the bookmarks prompt.
.Pp
(2) Symlinked bookmarks: A symlinked bookmark to the current directory can
be created with the \fIB\fR key (or manually under ~/.config/nnn/bookmarks).
Pressing 'Enter' at the bookmarks prompt takes to this directory.
If \fBNNN_BMS\fR is not set, the select bookmark key directly opens it.
.Pp
On entering a bookmark, the directory where the select bookmark key was
pressed is set as the previous directory. Press '-' to return to it.
.Pp
.Sh UNITS
The minimum file size unit is byte (B). The rest are K, M, G, T, P, E, Z, Y
(powers of 1024), same as the default units in \fIls\fR.
@ -369,9 +407,11 @@ used. A single combination of arguments is supported for SHELL and PAGER.
\fBNNN_BMS:\fR bookmark string as \fIkey_char:location\fR pairs
separated by \fI;\fR:
.Bd -literal
export NNN_BMS="d:$HOME/Documents;u:/home/user/Cam Uploads;D:$HOME/Downloads/"
export NNN_BMS="d:$HOME/Docs;u:/home/user/Cam Uploads;D:$HOME/Downloads/"
.Ed
.Pp
These bookmarks are listed in the help and config screen (key ?).
.Pp
\fBNNN_PLUG:\fR directly executable plugins as \fIkey_char:plugin\fR pairs
separated by \fI;\fR:
.Bd -literal
@ -382,50 +422,72 @@ separated by \fI;\fR:
2. Alternatively, combine with \fIAlt\fR (i.e. \fIAlt+key\fR).
3. To skip directory refresh after running a plugin, prefix with \fB-\fR.
export NNN_PLUG='m:-mediainf'
export NNN_PLUG='p:-plugin'
.Ed
.Pp
To assign keys to arbitrary non-background non-shell-interpreted cli
commands and invoke like plugins, add \fI_\fR (underscore) before the
command.
To assign keys to arbitrary non-background cli commands and invoke like
plugins, add \fB!\fR before the command.
.Bd -literal
export NNN_PLUG='x:_chmod +x $nnn;g:_git log;s:_smplayer $nnn'
export NNN_PLUG='x:!chmod +x "$nnn";g:!git log;s:!smplayer "$nnn"'
To pick and run an unassigned plugin, press \fBEnter\fR at the plugin prompt.
To run a plugin at startup, use the option `-P` followed by the plugin key.
NOTES:
1. Use single quotes for $NNN_PLUG so $nnn is not interpreted
2. $nnn should be the last argument (IF used)
3. (Again) add \fB_\fR before the command
1. Place $nnn (or exported variables) in double quotes (\fB"$nnn"\fR)
2. Use single quotes for $NNN_PLUG so "$nnn" is not interpreted
3. (Again) add \fB!\fR before the command
4. To disable directory refresh after running a \fIcommand as plugin\fR,
prefix with \fB-_\fR
prefix with \fB-!\fR
5. To skip user confirmation after command execution, suffix with \fB*\fR
Note: Do not use \fB*\fR with programs those run and exit e.g. cat
export NNN_PLUG='y:-_sync*'
export NNN_PLUG='y:-!sync*'
6. To run a \fIGUI app as plugin\fR, add a \fB|\fR after \fB_\fR
6. To run a \fIGUI app as plugin\fR, add a \fB&\fR after \fB!\fR.
export NNN_PLUG='m:-_|mousepad $nnn'
export NNN_PLUG='m:-!&mousepad "$nnn"'
7. To show the output of run-and-exit commands which do not need user input,
add \fB|\fR (pipe) after \fB!\fR
Note: This option is incompatible with \fB&\fR (terminal output is masked
for GUI programs) and ignores \fB*\fR (output is already paged for user).
export NNN_PLUG='m:-!|mediainfo "$nnn";t:-!|tree -ps;l:-!|ls -lah --group-directories-first'
EXAMPLES:
----------------------------------- + -------------------------------------------------
Key:Command | Description
----------------------------------- + -------------------------------------------------
g:-_git diff | Show git diff
k:-_fuser -kiv $nnn* | Interactively kill process(es) using hovered file
l:-_git log | Show git log
n:-_vi /home/user/Dropbox/dir/note* | Take quick notes in a synced file/dir of notes
p:-_less -iR $nnn* | Page through hovered file in less
s:-_|smplayer -minigui $nnn | Play hovered media file, even unfinished download
x:_chmod +x $nnn | Make the hovered file executable
y:-_sync* | Flush cached writes
----------------------------------- + -------------------------------------------------
------------------------------------ + -------------------------------------------------
Key:Command | Description
------------------------------------ + -------------------------------------------------
c:!convert "$nnn" png:- | xclip | Copy image to clipboard
-sel clipboard -t image/png* |
C:!cp -rv "$nnn" "$nnn".cp* | Create a copy of the hovered file
e:-!sudo -E vim "$nnn"* | Edit file as root in vim
g:-!git diff | Show git diff
h:-!hx "$nnn"* | Open hovered file in hx hex editor
k:-!fuser -kiv "$nnn"* | Interactively kill process(es) using hovered file
l:-!git log | Show git log
n:-!vi /home/user/Dropbox/dir/note* | Take quick notes in a synced file/dir of notes
p:-!less -iR "$nnn"* | Page through hovered file in less
s:-!&smplayer -minigui "$nnn" | Play hovered media file, even unfinished download
x:!chmod +x "$nnn" | Make the hovered file executable
y:-!sync* | Flush cached writes
------------------------------------ + -------------------------------------------------
Online docs: https://github.com/jarun/nnn/tree/master/plugins
.Ed
.Pp
\fBNNN_ORDER:\fR directory-specific sort key.
.Bd -literal
export NNN_ORDER='t:/home/user/Downloads;S:/tmp'
NOTE: Sort keys can be a/d/e/r/s/t/v (see program option -T).
Capitalize to reverse (except 'r').
Path must be absolute.
Timestamps for entries modified/created within 5 minutes are shown in reverse.
.Ed
.Pp
\fBNNN_COLORS:\fR string of color numbers for each context, e.g.:
.Bd -literal
# 8 color numbers:
@ -478,6 +540,11 @@ separated by \fI;\fR:
NOTE: Non-default formats may require a third-party utility.
.Ed
.Pp
\fBNNN_ARCHMNT:\fR optional archive mounter utility (default: archivemount).
.Bd -literal
export NNN_ARCHIVE='fuse-archive'
.Ed
.Pp
\fBNNN_SSHFS:\fR specify custom sshfs command with options:
.Bd -literal
export NNN_SSHFS='sshfs -o reconnect,idmap=user,cache_timeout=3600'
@ -499,6 +566,9 @@ separated by \fI;\fR:
.Ed
.Pp
\fBNNN_SEL:\fR absolute path to custom selection file.
.Bd -literal
export NNN_SEL='/tmp/.sel'
.Ed
.Pp
\fBNNN_FIFO:\fR path of a named pipe to write the hovered file path:
.Bd -literal
@ -518,6 +588,16 @@ separated by \fI;\fR:
export NNN_LOCKER='cmatrix'
.Ed
.Pp
\fBNNN_TMPFILE:\fR \fIalways\fR cd on quit and write the command in the file specified.
.Bd -literal
export NNN_TMPFILE='/tmp/.lastd'
.Ed
.Pp
\fBNNN_HELP:\fR run a program and show the output on top of the program help page.
.Bd -literal
export NNN_HELP='fortune'
.Ed
.Pp
\fBNNN_MCLICK:\fR key emulated by a middle mouse click.
.Bd -literal
export NNN_MCLICK='^R'

View File

@ -2,14 +2,29 @@
This directory contains sizable user submitted patches that were rejected from mainline as they tend to be more subjective in nature.
The patches will be adapted on each release when necessary (v4.1 onwards). Each patch can be applied through its respective make variable during compilation. In case inter-patch merge conflicts occur, a compatability patch is provided and will automatically be applied.
The patches will be adapted on each release when necessary (v4.1 onwards). Each patch can be applied through its respective make variable during compilation. In case inter-patch merge conflicts occur, a compatibility patch is provided and will automatically be applied.
## List of patches
| Patch (a-z) | Description | Make var |
| --- | --- | --- |
| gitstatus | Add git status column to the detail view. Requires [libgit2](https://github.com/libgit2/libgit2). | `O_GISTATUS` |
| colemak | Key bindings for Colemak keyboard layout | `O_COLEMAK` |
| gitstatus | Add git status column to the detail view. Provides command line flag `-G` to show column in normal mode. | `O_GITSTATUS` |
| namefirst | Print filenames first in the detail view. Print user/group columns when a directory contains different users/groups. | `O_NAMEFIRST` |
| restorepreview | Add pipe to close and restore [`preview-tui`](https://github.com/jarun/nnn/blob/master/plugins/preview-tui) for internal undetached edits (<kbd>e</kbd> key)| `O_RESTOREPREVIEW` |
To apply a patch, use the corresponding make variable, e.g.:
make O_NAMEFIRST=1
When contributing/adding a new patch, make sure to add the make variable to the patches array in `./misc/test/check-patches.sh` as well so that patch failures can be easily tested.
## Resolving patch conflicts
Patch conflicts can be checked locally by running `make checkpatches` or by running `./patches/check-patches.sh` manually.
Whenever patch conflicts occur on the latest master, pull requests resolving them are welcome. Let's say a conflict occurs in the `restorepreview` patch. The best way to resolve this conflict would be something along the lines of:
- Ensure you're on latest master and run `PATCH_OPTS="--merge" make O_RESTOREPREVIEW=1`. This will generate the conflict markers in `src/nnn.c`.
- Next edit `src/nnn.c`, resolve the conflicts around the conflict markers(`<<<<<<<`), and save.
- Then run `git diff > patch.diff && sed -i -e "/^$/{r patch.diff" -e "q;}" patches/restorepreview/mainline.diff` to update the patch.

29
patches/check-patches.sh Executable file
View File

@ -0,0 +1,29 @@
#!/bin/bash
#
# Usage: ./misc/test/check-patches.sh
#
# Bash script that checks for any of the patches failing to apply.
# Read patches/README.md for more information.
export PATCH_OPTS="--merge"
patches=("O_COLEMAK" "O_GITSTATUS" "O_NAMEFIRST" "O_RESTOREPREVIEW")
z=$(( 1 << ${#patches[@]} ))
pid=$$
ret=0
trap 'ret=1' SIGUSR1
for ((n=1; n < z; ++n)); do
for ((i=0; i < ${#patches[@]}; ++i)); do
printf "%s=%d " "${patches[$i]}" "$(( (n & (1 << i)) != 0 ))"
done | tee "/dev/stderr" | (
make clean -s
if ! xargs make 2>&1; then
echo "[FAILED]" >&2
kill -SIGUSR1 "$pid"
else
echo "[SUCCESS]" >&2
fi
git restore src
) >/dev/null
done
exit "$ret"

View File

@ -0,0 +1,134 @@
diff --git a/src/nnn.c b/src/nnn.c
index d7c53166..bb7ff3e8 100644
--- a/src/nnn.c
+++ b/src/nnn.c
@@ -5149,12 +5149,12 @@ static void show_help(const char *path)
"2(___n))\n"
"0\n"
"1NAVIGATION\n"
- "9Up k Up%16PgUp ^U Page up\n"
- "9Dn j Down%14PgDn ^D Page down\n"
+ "9Up e Up%16PgUp ^U Page up\n"
+ "9Dn n Down%14PgDn ^D Page down\n"
"9Lt h Parent%12~ ` @ - ~, /, start, prev\n"
- "5Ret Rt l Open%20' First file/match\n"
- "9g ^A Top%21J Jump to entry/offset\n"
- "9G ^E End%20^J Toggle auto-advance on open\n"
+ "5Ret Rt i Open%20' First file/match\n"
+ "9g ^E Top%21J Jump to entry/offset\n"
+ "9G ^N End%20^J Toggle auto-advance on open\n"
"8B (,) Book(mark)%11b ^/ Select bookmark\n"
"a1-4 Context%11(Sh)Tab Cycle/new context\n"
"62Esc ^Q Quit%19^y Next young\n"
@@ -5162,27 +5162,27 @@ static void show_help(const char *path)
"cq Quit context\n"
"0\n"
"1FILTER & PROMPT\n"
- "c/ Filter%17^N Toggle type-to-nav\n"
+ "c/ Filter%17^K Toggle type-to-nav\n"
"aEsc Exit prompt%12^L Toggle last filter\n"
"c. Toggle hidden%05Alt+Esc Unfilter, quit context\n"
"0\n"
"1FILES\n"
- "9o ^O Open with%15n Create new/link\n"
+ "9o ^O Open with%15c Create new/link\n"
"9f ^F File stats%14d Detail mode toggle\n"
"b^R Rename/dup%14r Batch rename\n"
- "cz Archive%17e Edit file\n"
+ "cz Archive%17y Edit file\n"
"c* Toggle exe%14> Export list\n"
"6Space + (Un)select%12m-m Select range/clear\n"
"ca Select all%14A Invert sel\n"
"9p ^P Copy here%12w ^W Cp/mv sel as\n"
- "9v ^V Move here%15E Edit sel list\n"
+ "9v ^V Move here%15l Edit sel list\n"
"9x ^X Delete or trash%09S Listed sel size\n"
"cX Delete (rm -rf)%07Esc Send to FIFO\n"
"0\n"
"1MISC\n"
"8Alt ; Select plugin%11= Launch app\n"
"9! ^] Shell%19] Cmd prompt\n"
- "cc Connect remote%10u Unmount remote/archive\n"
+ "cC Connect remote%10u Unmount remote/archive\n"
"9t ^T Sort toggles%12s Manage session\n"
"cT Set time type%110 Lock\n"
"b^L Redraw%18? Help, conf\n"
diff --git a/src/nnn.h b/src/nnn.h
index bd500244..43b7fa22 100644
--- a/src/nnn.h
+++ b/src/nnn.h
@@ -139,12 +139,12 @@ static struct key bindings[] = {
{ '\r', SEL_OPEN },
/* Pure navigate inside */
{ KEY_RIGHT, SEL_NAV_IN },
- { 'l', SEL_NAV_IN },
+ { 'i', SEL_NAV_IN },
/* Next */
- { 'j', SEL_NEXT },
+ { 'n', SEL_NEXT },
{ KEY_DOWN, SEL_NEXT },
/* Previous */
- { 'k', SEL_PREV },
+ { 'e', SEL_PREV },
{ KEY_UP, SEL_PREV },
/* Page down */
{ KEY_NPAGE, SEL_PGDN },
@@ -157,11 +157,11 @@ static struct key bindings[] = {
/* First entry */
{ KEY_HOME, SEL_HOME },
{ 'g', SEL_HOME },
- { CONTROL('A'), SEL_HOME },
+ { CONTROL('E'), SEL_HOME },
/* Last entry */
{ KEY_END, SEL_END },
{ 'G', SEL_END },
- { CONTROL('E'), SEL_END },
+ { CONTROL('N'), SEL_END },
/* Go to first file */
{ '\'', SEL_FIRST },
/* Jump to an entry number/offset */
@@ -179,7 +179,7 @@ static struct key bindings[] = {
{ 'b', SEL_BMOPEN },
{ CONTROL('_'), SEL_BMOPEN },
/* Connect to server over SSHFS */
- { 'c', SEL_REMOTE },
+ { 'C', SEL_REMOTE },
/* Cycle contexts in forward direction */
{ '\t', SEL_CYCLE },
/* Cycle contexts in reverse direction */
@@ -202,7 +202,7 @@ static struct key bindings[] = {
/* Filter */
{ '/', SEL_FLTR },
/* Toggle filter mode */
- { CONTROL('N'), SEL_MFLTR },
+ { CONTROL('K'), SEL_MFLTR },
/* Toggle hide .dot files */
{ '.', SEL_HIDDEN },
/* Detailed listing */
@@ -229,7 +229,7 @@ static struct key bindings[] = {
/* Invert selection in current dir */
{ 'A', SEL_SELINV },
/* List, edit selection */
- { 'E', SEL_SELEDIT },
+ { 'l', SEL_SELEDIT },
/* Copy from selection buffer */
{ 'p', SEL_CP },
{ CONTROL('P'), SEL_CP },
@@ -247,7 +247,7 @@ static struct key bindings[] = {
{ 'o', SEL_OPENWITH },
{ CONTROL('O'), SEL_OPENWITH },
/* Create a new file */
- { 'n', SEL_NEW },
+ { 'c', SEL_NEW },
/* Show rename prompt */
{ CONTROL('R'), SEL_RENAME },
/* Rename contents of current dir */
@@ -259,7 +259,7 @@ static struct key bindings[] = {
/* Toggle auto-advance on file open */
{ CONTROL('J'), SEL_AUTONEXT },
/* Edit in EDITOR */
- { 'e', SEL_EDIT },
+ { 'y', SEL_EDIT },
/* Run a plugin */
{ ';', SEL_PLUGIN },
/* Show total size of listed selection */

View File

@ -1,224 +1,223 @@
# Description: Add git status column to detail mode.
# Description: Add git status column to detail mode. Provides additional
# command line flag -G which will render the git status
# column also in normal mode. Vim plugin users may consider
# adding the -G flag to their command override.
#
# Dependencies: libgit2
#
# Authors: @crides, Luuk van Baal
# Authors: Luuk van Baal
diff --git a/src/nnn.c b/src/nnn.c
index d83d7f6..7940077 100644
index 83ecdb90..4397944a 100644
--- a/src/nnn.c
+++ b/src/nnn.c
@@ -105,6 +105,7 @@
#include <wchar.h>
#include <pwd.h>
#include <grp.h>
+#include <git2.h>
@@ -270,6 +270,25 @@
#define VFS_USED 1
#define VFS_SIZE 2
#if !defined(alloca) && defined(__GNUC__)
/*
@@ -244,6 +245,16 @@ typedef unsigned int uint_t;
+/* Git icons */
+#ifdef NERD
+#define GIT_ADD ""
+#define GIT_DEL ""
+#define GIT_IGN ""
+#define GIT_MOD ""
+#define GIT_NEW ""
+#define GIT_NON "-"
+#define GIT_UPD "󰚰"
+#else
+#define GIT_ADD "A"
+#define GIT_DEL "D"
+#define GIT_IGN "!"
+#define GIT_MOD "M"
+#define GIT_NEW "?"
+#define GIT_NON "-"
+#define GIT_UPD "U"
+#endif
+
/* TYPE DEFINITIONS */
typedef unsigned int uint_t;
typedef unsigned char uchar_t;
typedef unsigned short ushort_t;
typedef unsigned long long ulong_t;
+typedef enum {
+ GIT_COLUMN_STATUS_UNMOD = 0,
+ GIT_COLUMN_STATUS_NEW,
+ GIT_COLUMN_STATUS_MODIFIED,
+ GIT_COLUMN_STATUS_DELETED,
+ GIT_COLUMN_STATUS_RENAMED,
+ GIT_COLUMN_STATUS_TYPE_CHANGE,
+ GIT_COLUMN_STATUS_IGNORED,
+ GIT_COLUMN_STATUS_CONFLICTED,
+} git_column_status_t;
/* STRUCTURES */
@@ -263,6 +274,8 @@ typedef struct entry {
@@ -294,6 +313,7 @@ typedef struct entry {
uid_t uid; /* 4 bytes */
gid_t gid; /* 4 bytes */
#endif
+ git_column_status_t status_indexed;
+ git_column_status_t status_staged;
+ char git_status[2][5];
} *pEntry;
/* Key-value pairs from env */
@@ -362,7 +375,18 @@ typedef struct {
/* Selection marker */
@@ -349,6 +369,7 @@ typedef struct {
uint_t cliopener : 1; /* All-CLI app opener */
uint_t waitedit : 1; /* For ops that can't be detached, used EDITOR */
uint_t rollover : 1; /* Roll over at edges */
+ uint_t normalgit : 1; /* Show git status in normal mode */
} settings;
/* Non-persistent program-internal states (alphabeical order) */
@@ -400,7 +421,17 @@ typedef struct {
} session_header_t;
#endif
+typedef struct {
+ char *path;
+ git_status_t status;
+} simple_git_status_t;
+
+typedef struct {
+ simple_git_status_t *statuses;
+ size_t len;
+} simple_git_statuses_t;
+ char status[2];
+ char path[PATH_MAX];
+} git_status_t;
+
/* GLOBALS */
+simple_git_statuses_t git_statuses;
+struct {
+ bool show;
+ size_t len;
+ git_status_t *statuses;
+} git_statuses;
/* Configuration, contexts */
static settings cfg = {
@@ -3464,6 +3488,80 @@ static char *get_kv_val(kv *kvarr, char *buf, int key, uchar_t max, uchar_t id)
return NULL;
@@ -3796,6 +3827,47 @@ static int get_kv_key(kv *kvarr, char *val, uchar_t max, uchar_t id)
return -1;
}
+static git_column_status_t git_get_indexed_status(const uint32_t status) {
+ if (status & GIT_STATUS_INDEX_NEW) return GIT_COLUMN_STATUS_NEW;
+ if (status & GIT_STATUS_INDEX_MODIFIED) return GIT_COLUMN_STATUS_MODIFIED;
+ if (status & GIT_STATUS_INDEX_DELETED) return GIT_COLUMN_STATUS_DELETED;
+ if (status & GIT_STATUS_INDEX_RENAMED) return GIT_COLUMN_STATUS_RENAMED;
+ if (status & GIT_STATUS_INDEX_TYPECHANGE) return GIT_COLUMN_STATUS_TYPE_CHANGE;
+ return GIT_COLUMN_STATUS_UNMOD;
+}
+static size_t get_git_statuses(const char *path)
+{
+ static char gst[] = "git -c core.quotePath= status -s --no-renames --ignored=matching -unormal . 2>/dev/null";
+ FILE *fp = popen(gst, "r");
+ char status[PATH_MAX];
+ size_t pathindex, i = -1;
+ git_statuses.show = FALSE;
+
+static git_column_status_t git_get_staged_status(const uint32_t status) {
+ if (status & GIT_STATUS_WT_NEW) return GIT_COLUMN_STATUS_NEW;
+ if (status & GIT_STATUS_WT_MODIFIED) return GIT_COLUMN_STATUS_MODIFIED;
+ if (status & GIT_STATUS_WT_DELETED) return GIT_COLUMN_STATUS_DELETED;
+ if (status & GIT_STATUS_WT_RENAMED) return GIT_COLUMN_STATUS_RENAMED;
+ if (status & GIT_STATUS_WT_TYPECHANGE) return GIT_COLUMN_STATUS_TYPE_CHANGE;
+ if (status & GIT_STATUS_IGNORED) return GIT_COLUMN_STATUS_IGNORED;
+ if (status & GIT_STATUS_CONFLICTED) return GIT_COLUMN_STATUS_CONFLICTED;
+ return GIT_COLUMN_STATUS_UNMOD;
+}
+
+static void print_gitstatus(git_column_status_t status) {
+ switch (status) {
+ case GIT_COLUMN_STATUS_UNMOD: addch('-' | 0); break;
+ case GIT_COLUMN_STATUS_NEW: addch('N' | (g_state.oldcolor ? COLOR_PAIR(1) : COLOR_PAIR(C_EXE))); break;
+ case GIT_COLUMN_STATUS_MODIFIED: addch('M' | (g_state.oldcolor ? COLOR_PAIR(1) : COLOR_PAIR(4))); break;
+ case GIT_COLUMN_STATUS_DELETED: addch('D' | (g_state.oldcolor ? COLOR_PAIR(1) : COLOR_PAIR(C_UND))); break;
+ case GIT_COLUMN_STATUS_RENAMED: addch('R' | (g_state.oldcolor ? COLOR_PAIR(1) : COLOR_PAIR(C_CHR))); break;
+ case GIT_COLUMN_STATUS_TYPE_CHANGE: addch('T' | (g_state.oldcolor ? COLOR_PAIR(1) : COLOR_PAIR(C_HRD))); break;
+ case GIT_COLUMN_STATUS_IGNORED: addch('I' | 0); break;
+ case GIT_COLUMN_STATUS_CONFLICTED: addch('U' | (g_state.oldcolor ? COLOR_PAIR(1) : COLOR_PAIR(C_UND))); break;
+ while (fgets(status, PATH_MAX, fp)) {
+ pathindex = (status[3] == '"') ? 4 : 3;
+ if (!cfg.showhidden && status[pathindex] == '.')
+ continue;
+ status[xstrlen(status) - pathindex + 2] = '\0';
+ git_statuses.statuses = xrealloc(git_statuses.statuses, sizeof(git_status_t) * (++i + 1));
+ git_statuses.statuses[i].status[0] = status[0];
+ git_statuses.statuses[i].status[1] = status[1];
+ mkpath(path, status + pathindex, git_statuses.statuses[i].path);
+ }
+
+ pclose(fp);
+ return (i + 1);
+}
+
+static simple_git_statuses_t statuses_from_path(const char *path) {
+ git_repository *repo;
+ git_buf ret = { .ptr = NULL, .asize = 0, .size = 0 };
+ simple_git_statuses_t statuses = { .statuses = NULL, .len = 0 };
+ git_repository_discover(&ret, path, false, NULL);
+ git_repository_open(&repo, ret.ptr);
+ git_buf_dispose(&ret);
+
+ if (repo) {
+ char buf[PATH_MAX];
+ const char *workdir = git_repository_workdir(repo);
+ git_status_list *status_list;
+
+ git_status_list_new(&status_list, repo, NULL);
+ statuses.len = git_status_list_entrycount(status_list);
+ statuses.statuses = malloc(statuses.len * sizeof(simple_git_status_t));
+
+ for (size_t i = 0; i < statuses.len; ++i) {
+ const git_status_entry *status_ent = git_status_byindex(status_list, i);
+ const char *entry_path = status_ent->head_to_index ? status_ent->head_to_index->old_file.path
+ : status_ent->index_to_workdir->old_file.path;
+
+ xstrsncpy(buf, workdir, xstrlen(workdir));
+ statuses.statuses[i].path = abspath(entry_path, buf);
+ statuses.statuses[i].status = status_ent->status;
+ }
+
+ git_status_list_free(status_list);
+ git_repository_free(repo);
+static void set_git_status(char status[][5], uint_t nr)
+{
+ for (int j = 0; j < 2; j++) {
+ if (status[j][0] == '-')
+ switch (git_statuses.statuses[nr].status[j]) {
+ case ' ': xstrsncpy(status[j], GIT_NON, 4); break;
+ case 'M': xstrsncpy(status[j], GIT_MOD, 4); break;
+ case 'A': xstrsncpy(status[j], GIT_ADD, 4); break;
+ case '?': xstrsncpy(status[j], GIT_NEW, 4); break;
+ case '!': xstrsncpy(status[j], GIT_IGN, 4); break;
+ case 'D': xstrsncpy(status[j], GIT_DEL, 4); break;
+ case 'U': xstrsncpy(status[j], GIT_UPD, 4); break;
+ }
+ }
+ return statuses;
+}
+
+static void git_statuses_free(void) {
+ for (size_t i = 0; i < git_statuses.len; ++i)
+ free(git_statuses.statuses[i].path);
+
+ free(git_statuses.statuses);
+ git_statuses.len = 0;
+ if (git_statuses.statuses[nr].status[1] != '!')
+ git_statuses.show = TRUE;
+}
+
static void resetdircolor(int flags)
{
/* Directories are always shown on top, clear the color when moving to first file */
@@ -3794,6 +3892,11 @@ static void printent(const struct entry *ent, uint_t namecols, bool sel)
@@ -4123,6 +4195,10 @@ static void printent(const struct entry *ent, uint_t namecols, bool sel)
if (attrs)
attroff(attrs);
uchar_t color_pair = get_color_pair_name_ind(ent, &ind, &attrs);
+ if (git_statuses.show && (cfg.showdetail || cfg.normalgit))
+ printw("%*s%s%s", (cfg.normalgit && !cfg.showdetail) ? 1 : 0, "",
+ ent->git_status[0], ent->git_status[1]);
+
+ if (git_statuses.len) {
+ print_gitstatus(ent->status_indexed);
+ print_gitstatus(ent->status_staged);
+ }
}
addch((ent->flags & FILE_SELECTED) ? '+' | A_REVERSE | A_BOLD : ' ');
attrs = 0;
@@ -5119,6 +5222,10 @@ static int dentfill(char *path, struct entry **ppdents)
if (g_state.oldcolor)
@@ -5592,6 +5668,11 @@ static int dentfill(char *path, struct entry **ppdents)
attron(COLOR_PAIR(cfg.curctx + 1));
}
+ if (git_statuses.len)
+ git_statuses_free();
+ git_statuses = statuses_from_path(path);
+ char linkpath[PATH_MAX];
+ if ((git_statuses.len = get_git_statuses(path)))
+ if (!realpath(path, linkpath))
+ printwarn(NULL);
+
#if _POSIX_C_SOURCE >= 200112L
posix_fadvise(fd, 0, 0, POSIX_FADV_SEQUENTIAL);
#endif
@@ -5316,6 +5423,25 @@ static int dentfill(char *path, struct entry **ppdents)
@@ -5792,6 +5873,29 @@ static int dentfill(char *path, struct entry **ppdents)
#endif
}
+ if (git_statuses.len) {
+ uint merged_status = 0;
+ char *dentpath = abspath(dentp->name, path);
+ char dentpath[PATH_MAX];
+ size_t pathlen = mkpath(linkpath, dentp->name, dentpath);
+ dentp->git_status[0][0] = dentp->git_status[1][0] = '-';
+ dentp->git_status[0][1] = dentp->git_status[1][1] = '\0';
+
+ for (size_t i = 0; i < git_statuses.len; ++i) {
+ if (dentp->flags & DIR_OR_LINK_TO_DIR) {
+ size_t dentlen = xstrlen(dentpath);
+ if (dentp->flags & DIR_OR_DIRLNK) {
+ char prefix[PATH_MAX];
+ memccpy(prefix, dentpath, '\0', PATH_MAX);
+ prefix[pathlen - 1] = '/';
+
+ if ((dentlen <= xstrlen(git_statuses.statuses[i].path)) && is_prefix(git_statuses.statuses[i].path, dentpath, dentlen))
+ merged_status |= git_statuses.statuses[i].status;
+ } else if (!xstrcmp(git_statuses.statuses[i].path, dentpath))
+ merged_status |= git_statuses.statuses[i].status;
+ for (size_t i = 0; i < git_statuses.len; ++i)
+ if (is_prefix(git_statuses.statuses[i].path, prefix, pathlen))
+ set_git_status(dentp->git_status, i);
+ } else {
+ for (size_t i = 0; i < git_statuses.len; ++i)
+ if (!xstrcmp(git_statuses.statuses[i].path, dentpath)) {
+ set_git_status(dentp->git_status, i);
+ break;
+ }
+ }
+
+ dentp->status_indexed = git_get_indexed_status(merged_status);
+ dentp->status_staged = git_get_staged_status(merged_status);
+ free(dentpath);
+ }
+
++ndents;
} while ((dp = readdir(dirp)));
@@ -5834,11 +5960,11 @@ static int adjust_cols(int n)
@@ -6361,11 +6465,12 @@ static int adjust_cols(int n)
#endif
if (cfg.showdetail) {
/* Fallback to light mode if less than 35 columns */
- if (n < 36)
+ if (n < 38)
cfg.showdetail ^= 1;
else {
/* 2 more accounted for below */
else /* 2 more accounted for below */
- n -= 32;
+ n -= 34;
}
}
- }
+ n -= (git_statuses.show ? 34 : 32);
+ } else if (cfg.normalgit && git_statuses.show)
+ n -= 3;
@@ -7712,6 +7838,8 @@ static void cleanup(void)
/* 2 columns for preceding space and indicator */
return (n - 2);
@@ -8143,6 +8248,7 @@ static void usage(void)
" -F val fifo mode [0:preview 1:explore]\n"
#endif
" -g regex filters\n"
+ " -G always show git status\n"
" -H show hidden files\n"
" -i show current file info\n"
" -J no auto-advance on selection\n"
@@ -8282,6 +8388,7 @@ static void cleanup(void)
fflush(stdout);
}
#endif
+ git_statuses_free();
+ git_libgit2_shutdown();
+ free(git_statuses.statuses);
free(selpath);
free(plgpath);
free(cfgpath);
@@ -7907,6 +8035,7 @@ int main(int argc, char *argv[])
return EXIT_FAILURE;
@@ -8326,7 +8433,7 @@ int main(int argc, char *argv[])
atexit(cleanup);
+ git_libgit2_init();
/* Check if we are in path list mode */
if (!isatty(STDIN_FILENO)) {
while ((opt = (env_opts_id > 0
? env_opts[--env_opts_id]
- : getopt(argc, argv, "aAb:BcCdDeEfF:gHiJKl:nNop:P:QrRs:St:T:uUVxh"))) != -1) {
+ : getopt(argc, argv, "aAb:BcCdDeEfF:gGHiJKl:nNop:P:QrRs:St:T:uUVxh"))) != -1) {
switch (opt) {
#ifndef NOFIFO
case 'a':
@@ -8380,6 +8487,9 @@ int main(int argc, char *argv[])
cfg.regex = 1;
filterfn = &visible_re;
break;
+ case 'G':
+ cfg.normalgit = 1;
+ break;
case 'H':
cfg.showhidden = 1;
break;

View File

@ -1,220 +1,226 @@
# Description: Add git status column to detail mode.
# Description: Add git status column to detail mode. Provides additional
# command line flag -G which will render the git status
# column also in normal mode. Vim plugin users may consider
# adding the -G flag to their command override.
# Compatibility patch for the namefirst patch.
#
# Dependencies: libgit2
#
# Authors: @crides, Luuk van Baal
# Authors: Luuk van Baal
diff --git a/src/nnn.c b/src/nnn.c
index 9b55d5d..240ace2 100644
index 88538787..d4af7c43 100644
--- a/src/nnn.c
+++ b/src/nnn.c
@@ -105,6 +105,7 @@
#include <wchar.h>
#include <pwd.h>
#include <grp.h>
+#include <git2.h>
@@ -270,6 +270,25 @@
#define VFS_USED 1
#define VFS_SIZE 2
#if !defined(alloca) && defined(__GNUC__)
/*
@@ -244,6 +245,16 @@ typedef unsigned int uint_t;
+/* Git icons */
+#ifdef NERD
+#define GIT_ADD ""
+#define GIT_DEL ""
+#define GIT_IGN ""
+#define GIT_MOD ""
+#define GIT_NEW ""
+#define GIT_NON "-"
+#define GIT_UPD "󰚰"
+#else
+#define GIT_ADD "A"
+#define GIT_DEL "D"
+#define GIT_IGN "!"
+#define GIT_MOD "M"
+#define GIT_NEW "?"
+#define GIT_NON "-"
+#define GIT_UPD "U"
+#endif
+
/* TYPE DEFINITIONS */
typedef unsigned int uint_t;
typedef unsigned char uchar_t;
typedef unsigned short ushort_t;
typedef unsigned long long ulong_t;
+typedef enum {
+ GIT_COLUMN_STATUS_UNMOD = 0,
+ GIT_COLUMN_STATUS_NEW,
+ GIT_COLUMN_STATUS_MODIFIED,
+ GIT_COLUMN_STATUS_DELETED,
+ GIT_COLUMN_STATUS_RENAMED,
+ GIT_COLUMN_STATUS_TYPE_CHANGE,
+ GIT_COLUMN_STATUS_IGNORED,
+ GIT_COLUMN_STATUS_CONFLICTED,
+} git_column_status_t;
/* STRUCTURES */
@@ -262,6 +273,8 @@ typedef struct entry {
#ifndef NOUG
@@ -294,6 +313,7 @@ typedef struct entry {
uid_t uid; /* 4 bytes */
gid_t gid; /* 4 bytes */
+ git_column_status_t status_indexed;
+ git_column_status_t status_staged;
#endif
+ char git_status[2][5];
} *pEntry;
@@ -366,7 +379,18 @@ static struct {
/* Selection marker */
@@ -349,6 +369,7 @@ typedef struct {
uint_t cliopener : 1; /* All-CLI app opener */
uint_t waitedit : 1; /* For ops that can't be detached, used EDITOR */
uint_t rollover : 1; /* Roll over at edges */
+ uint_t normalgit : 1; /* Show git status in normal mode */
} settings;
/* Non-persistent program-internal states (alphabeical order) */
@@ -404,7 +425,17 @@ static struct {
ushort_t maxnameln, maxsizeln, maxuidln, maxgidln, maxentln, uidln, gidln, printguid;
} dtls;
+typedef struct {
+ char *path;
+ git_status_t status;
+} simple_git_status_t;
+
+typedef struct {
+ simple_git_status_t *statuses;
+ size_t len;
+} simple_git_statuses_t;
+ char status[2];
+ char path[PATH_MAX];
+} git_status_t;
+
/* GLOBALS */
+simple_git_statuses_t git_statuses;
+struct {
+ bool show;
+ size_t len;
+ git_status_t *statuses;
+} git_statuses;
/* Configuration, contexts */
static settings cfg = {
@@ -3472,6 +3496,79 @@ static char *get_kv_val(kv *kvarr, char *buf, int key, uchar_t max, uchar_t id)
return NULL;
@@ -3804,6 +3835,47 @@ static int get_kv_key(kv *kvarr, char *val, uchar_t max, uchar_t id)
return -1;
}
+static git_column_status_t git_get_indexed_status(const uint32_t status) {
+ if (status & GIT_STATUS_INDEX_NEW) return GIT_COLUMN_STATUS_NEW;
+ if (status & GIT_STATUS_INDEX_MODIFIED) return GIT_COLUMN_STATUS_MODIFIED;
+ if (status & GIT_STATUS_INDEX_DELETED) return GIT_COLUMN_STATUS_DELETED;
+ if (status & GIT_STATUS_INDEX_RENAMED) return GIT_COLUMN_STATUS_RENAMED;
+ if (status & GIT_STATUS_INDEX_TYPECHANGE) return GIT_COLUMN_STATUS_TYPE_CHANGE;
+ return GIT_COLUMN_STATUS_UNMOD;
+}
+static size_t get_git_statuses(const char *path)
+{
+ static char gst[] = "git -c core.quotePath= status -s --no-renames --ignored=matching -unormal . 2>/dev/null";
+ FILE *fp = popen(gst, "r");
+ char status[PATH_MAX];
+ size_t pathindex, i = -1;
+ git_statuses.show = FALSE;
+
+static git_column_status_t git_get_staged_status(const uint32_t status) {
+ if (status & GIT_STATUS_WT_NEW) return GIT_COLUMN_STATUS_NEW;
+ if (status & GIT_STATUS_WT_MODIFIED) return GIT_COLUMN_STATUS_MODIFIED;
+ if (status & GIT_STATUS_WT_DELETED) return GIT_COLUMN_STATUS_DELETED;
+ if (status & GIT_STATUS_WT_RENAMED) return GIT_COLUMN_STATUS_RENAMED;
+ if (status & GIT_STATUS_WT_TYPECHANGE) return GIT_COLUMN_STATUS_TYPE_CHANGE;
+ if (status & GIT_STATUS_IGNORED) return GIT_COLUMN_STATUS_IGNORED;
+ if (status & GIT_STATUS_CONFLICTED) return GIT_COLUMN_STATUS_CONFLICTED;
+ return GIT_COLUMN_STATUS_UNMOD;
+}
+
+static void print_gitstatus(git_column_status_t status) {
+ switch (status) {
+ case GIT_COLUMN_STATUS_UNMOD: addch('-' | 0); break;
+ case GIT_COLUMN_STATUS_NEW: addch('N' | (g_state.oldcolor ? COLOR_PAIR(1) : COLOR_PAIR(C_EXE))); break;
+ case GIT_COLUMN_STATUS_MODIFIED: addch('M' | (g_state.oldcolor ? COLOR_PAIR(1) : COLOR_PAIR(4))); break;
+ case GIT_COLUMN_STATUS_DELETED: addch('D' | (g_state.oldcolor ? COLOR_PAIR(1) : COLOR_PAIR(C_UND))); break;
+ case GIT_COLUMN_STATUS_RENAMED: addch('R' | (g_state.oldcolor ? COLOR_PAIR(1) : COLOR_PAIR(C_CHR))); break;
+ case GIT_COLUMN_STATUS_TYPE_CHANGE: addch('T' | (g_state.oldcolor ? COLOR_PAIR(1) : COLOR_PAIR(C_HRD))); break;
+ case GIT_COLUMN_STATUS_IGNORED: addch('I' | 0); break;
+ case GIT_COLUMN_STATUS_CONFLICTED: addch('U' | (g_state.oldcolor ? COLOR_PAIR(1) : COLOR_PAIR(C_UND))); break;
+ while (fgets(status, PATH_MAX, fp)) {
+ pathindex = (status[3] == '"') ? 4 : 3;
+ if (!cfg.showhidden && status[pathindex] == '.')
+ continue;
+ status[xstrlen(status) - pathindex + 2] = '\0';
+ git_statuses.statuses = xrealloc(git_statuses.statuses, sizeof(git_status_t) * (++i + 1));
+ git_statuses.statuses[i].status[0] = status[0];
+ git_statuses.statuses[i].status[1] = status[1];
+ mkpath(path, status + pathindex, git_statuses.statuses[i].path);
+ }
+
+ pclose(fp);
+ return (i + 1);
+}
+
+static simple_git_statuses_t statuses_from_path(const char *path) {
+ git_repository *repo;
+ git_buf ret = { .ptr = NULL, .asize = 0, .size = 0 };
+ simple_git_statuses_t statuses = { .statuses = NULL, .len = 0 };
+ git_repository_discover(&ret, path, false, NULL);
+ git_repository_open(&repo, ret.ptr);
+ git_buf_dispose(&ret);
+
+ if (repo) {
+ char buf[PATH_MAX];
+ const char *workdir = git_repository_workdir(repo);
+ git_status_list *status_list;
+
+ git_status_list_new(&status_list, repo, NULL);
+ statuses.len = git_status_list_entrycount(status_list);
+ statuses.statuses = malloc(statuses.len * sizeof(simple_git_status_t));
+
+ for (size_t i = 0; i < statuses.len; ++i) {
+ const git_status_entry *status_ent = git_status_byindex(status_list, i);
+ const char *entry_path = status_ent->head_to_index ? status_ent->head_to_index->old_file.path
+ : status_ent->index_to_workdir->old_file.path;
+
+ xstrsncpy(buf, workdir, xstrlen(workdir));
+ statuses.statuses[i].path = abspath(entry_path, buf);
+ statuses.statuses[i].status = status_ent->status;
+ }
+
+ git_status_list_free(status_list);
+ git_repository_free(repo);
+static void set_git_status(char status[][5], uint_t nr)
+{
+ for (int j = 0; j < 2; j++) {
+ if (status[j][0] == '-')
+ switch (git_statuses.statuses[nr].status[j]) {
+ case ' ': xstrsncpy(status[j], GIT_NON, 4); break;
+ case 'M': xstrsncpy(status[j], GIT_MOD, 4); break;
+ case 'A': xstrsncpy(status[j], GIT_ADD, 4); break;
+ case '?': xstrsncpy(status[j], GIT_NEW, 4); break;
+ case '!': xstrsncpy(status[j], GIT_IGN, 4); break;
+ case 'D': xstrsncpy(status[j], GIT_DEL, 4); break;
+ case 'U': xstrsncpy(status[j], GIT_UPD, 4); break;
+ }
+ }
+ return statuses;
+}
+
+static void git_statuses_free(void) {
+ for (size_t i = 0; i < git_statuses.len; ++i)
+ free(git_statuses.statuses[i].path);
+
+ free(git_statuses.statuses);
+ if (git_statuses.statuses[nr].status[1] != '!')
+ git_statuses.show = TRUE;
+}
+
static void resetdircolor(int flags)
{
/* Directories are always shown on top, clear the color when moving to first file */
@@ -3783,6 +3880,12 @@ static void printent(const struct entry *ent, uint_t namecols, bool sel)
@@ -4104,6 +4176,9 @@ static void printent(const struct entry *ent, uint_t namecols, bool sel)
int attrs = 0, namelen;
uchar_t color_pair = get_color_pair_name_ind(ent, &ind, &attrs);
+ if (git_statuses.show && (cfg.showdetail || cfg.normalgit))
+ printw(" %s%s", ent->git_status[0], ent->git_status[1]);
+
addch((ent->flags & FILE_SELECTED) ? '+' | A_REVERSE | A_BOLD : ' ');
+ if (cfg.showdetail && git_statuses.len) {
+ print_gitstatus(ent->status_indexed);
+ print_gitstatus(ent->status_staged);
+ addch(' ');
+ }
+
if (g_state.oldcolor)
resetdircolor(ent->flags);
else {
@@ -5125,6 +5228,10 @@ static int dentfill(char *path, struct entry **ppdents)
@@ -5598,6 +5673,11 @@ static int dentfill(char *path, struct entry **ppdents)
attron(COLOR_PAIR(cfg.curctx + 1));
}
+ if (git_statuses.len)
+ git_statuses_free();
+ git_statuses = statuses_from_path(path);
+ char linkpath[PATH_MAX];
+ if ((git_statuses.len = get_git_statuses(path)))
+ if (!realpath(path, linkpath))
+ printwarn(NULL);
+
#if _POSIX_C_SOURCE >= 200112L
posix_fadvise(fd, 0, 0, POSIX_FADV_SEQUENTIAL);
#endif
@@ -5322,6 +5429,25 @@ static int dentfill(char *path, struct entry **ppdents)
@@ -5798,6 +5878,29 @@ static int dentfill(char *path, struct entry **ppdents)
#endif
}
+ if (git_statuses.len) {
+ uint merged_status = 0;
+ char *dentpath = abspath(dentp->name, path);
+ char dentpath[PATH_MAX];
+ size_t pathlen = mkpath(linkpath, dentp->name, dentpath);
+ dentp->git_status[0][0] = dentp->git_status[1][0] = '-';
+ dentp->git_status[0][1] = dentp->git_status[1][1] = '\0';
+
+ for (size_t i = 0; i < git_statuses.len; ++i) {
+ if (dentp->flags & DIR_OR_LINK_TO_DIR) {
+ size_t dentlen = xstrlen(dentpath);
+ if (dentp->flags & DIR_OR_DIRLNK) {
+ char prefix[PATH_MAX];
+ memccpy(prefix, dentpath, '\0', PATH_MAX);
+ prefix[pathlen - 1] = '/';
+
+ if ((dentlen <= xstrlen(git_statuses.statuses[i].path)) && is_prefix(git_statuses.statuses[i].path, dentpath, dentlen))
+ merged_status |= git_statuses.statuses[i].status;
+ } else if (!xstrcmp(git_statuses.statuses[i].path, dentpath))
+ merged_status |= git_statuses.statuses[i].status;
+ for (size_t i = 0; i < git_statuses.len; ++i)
+ if (is_prefix(git_statuses.statuses[i].path, prefix, pathlen))
+ set_git_status(dentp->git_status, i);
+ } else {
+ for (size_t i = 0; i < git_statuses.len; ++i)
+ if (!xstrcmp(git_statuses.statuses[i].path, dentpath)) {
+ set_git_status(dentp->git_status, i);
+ break;
+ }
+ }
+
+ dentp->status_indexed = git_get_indexed_status(merged_status);
+ dentp->status_staged = git_get_staged_status(merged_status);
+ free(dentpath);
+ }
+
++ndents;
} while ((dp = readdir(dirp)));
@@ -5972,7 +6098,7 @@ static void redraw(char *path)
@@ -6362,7 +6465,8 @@ static int adjust_cols(int n)
cfg.showdetail ^= 1;
else /* 2 more accounted for below */
n -= (dtls.maxentln - 2 - dtls.maxnameln);
- }
+ } else if (cfg.normalgit && git_statuses.show)
+ n -= 3;
/* 2 columns for preceding space and indicator */
return (n - 2);
@@ -6517,7 +6621,7 @@ static void redraw(char *path)
}
#endif
}
- dtls.maxentln = dtls.maxnameln + dtls.maxsizeln + (dtls.printguid ? (dtls.maxuidln + dtls.maxgidln + 29) : 26);
+ dtls.maxentln = dtls.maxnameln + dtls.maxsizeln + (dtls.printguid ? (dtls.maxuidln + dtls.maxgidln + 3) : 0) + (git_statuses.show ? 29 : 26);
}
- dtls.maxentln = dtls.maxnameln + dtls.maxsizeln + (dtls.printguid ? (dtls.maxuidln + dtls.maxgidln) : 0) + (g_state.uidgid ? 26 : 23);
+ dtls.maxentln = dtls.maxnameln + dtls.maxsizeln + (dtls.printguid ? (dtls.maxuidln + dtls.maxgidln) : 0) + (g_state.uidgid ? 29 : 26);
ncols = adjust_cols(ncols);
@@ -7714,6 +7840,8 @@ static void cleanup(void)
@@ -8153,6 +8257,7 @@ static void usage(void)
" -F val fifo mode [0:preview 1:explore]\n"
#endif
" -g regex filters\n"
+ " -G always show git status\n"
" -H show hidden files\n"
" -i show current file info\n"
" -J no auto-advance on selection\n"
@@ -8292,6 +8397,7 @@ static void cleanup(void)
fflush(stdout);
}
#endif
+ git_statuses_free();
+ git_libgit2_shutdown();
+ free(git_statuses.statuses);
free(selpath);
free(plgpath);
free(cfgpath);
@@ -7909,6 +8037,7 @@ int main(int argc, char *argv[])
return EXIT_FAILURE;
@@ -8336,7 +8442,7 @@ int main(int argc, char *argv[])
atexit(cleanup);
+ git_libgit2_init();
/* Check if we are in path list mode */
if (!isatty(STDIN_FILENO)) {
while ((opt = (env_opts_id > 0
? env_opts[--env_opts_id]
- : getopt(argc, argv, "aAb:BcCdDeEfF:gHiJKl:nNop:P:QrRs:St:T:uUVxh"))) != -1) {
+ : getopt(argc, argv, "aAb:BcCdDeEfF:gGHiJKl:nNop:P:QrRs:St:T:uUVxh"))) != -1) {
switch (opt) {
#ifndef NOFIFO
case 'a':
@@ -8390,6 +8496,9 @@ int main(int argc, char *argv[])
cfg.regex = 1;
filterfn = &visible_re;
break;
+ case 'G':
+ cfg.normalgit = 1;
+ break;
case 'H':
cfg.showhidden = 1;
break;

View File

@ -4,47 +4,47 @@
# Author: Luuk van Baal
diff --git a/src/nnn.c b/src/nnn.c
index d83d7f6..22402fa 100644
index f8a2c58..9802a1f 100644
--- a/src/nnn.c
+++ b/src/nnn.c
@@ -362,6 +362,10 @@ typedef struct {
@@ -394,6 +394,10 @@ typedef struct {
} session_header_t;
#endif
+static struct {
+ ushort_t maxnameln, maxsizeln, maxuidln, maxgidln, maxentln, uidln, gidln, printguid;
+} dtls;
+
/* GLOBALS */
/* Configuration, contexts */
@@ -1038,10 +1042,12 @@ static char *getpwname(uid_t uid)
static char *namecache = NULL;
@@ -1070,10 +1074,12 @@ static char *getpwname(uid_t uid)
static char *namecache;
if (uidcache != uid) {
+ if (dtls.maxuidln && !dtls.printguid) dtls.printguid = 1;
struct passwd *pw = getpwuid(uid);
uidcache = uid;
namecache = pw ? pw->pw_name : NULL;
+ dtls.uidln = xstrlen(namecache ? namecache : xitoa(uid));
}
return namecache ? namecache : xitoa(uid);
@@ -1053,10 +1059,12 @@ static char *getgrname(gid_t gid)
static char *grpcache = NULL;
@@ -1085,10 +1091,12 @@ static char *getgrname(gid_t gid)
static char *grpcache;
if (gidcache != gid) {
+ if (dtls.maxgidln && !dtls.printguid) dtls.printguid = 1;
struct group *gr = getgrgid(gid);
gidcache = gid;
grpcache = gr ? gr->gr_name : NULL;
+ dtls.gidln = xstrlen(grpcache ? grpcache : xitoa(gid));
}
return grpcache ? grpcache : xitoa(gid);
@@ -3479,14 +3487,13 @@ static void resetdircolor(int flags)
@@ -3834,14 +3842,13 @@ static void resetdircolor(int flags)
* Max supported str length: NAME_MAX;
*/
#ifdef NOLC
@ -62,18 +62,18 @@ index d83d7f6..22402fa 100644
{
wchar_t * const wbuf = (wchar_t *)g_buf;
wchar_t *buf = wbuf;
@@ -3510,7 +3517,7 @@ static wchar_t *unescape(const char *str, uint_t maxcols)
@@ -3866,7 +3873,7 @@ static wchar_t *unescape(const char *str, uint_t maxcols)
++buf;
}
- return wbuf;
+ return len;
}
static off_t get_size(off_t size, off_t *pval, uint_t comp)
@@ -3771,33 +3778,7 @@ static uchar_t get_color_pair_name_ind(const struct entry *ent, char *pind, int
static void printent(const struct entry *ent, uint_t namecols, bool sel)
static off_t get_size(off_t size, off_t *pval, int comp)
@@ -4228,38 +4235,13 @@ static void printent(int pdents_index, uint_t namecols, bool sel)
{
const struct entry *ent = &pdents[pdents_index];
char ind = '\0';
- int attrs;
-
@ -90,7 +90,7 @@ index d83d7f6..22402fa 100644
- attron(attrs);
-
- /* Print details */
- print_time(&ent->sec);
- print_time(&ent->sec, ent->flags);
-
- printw("%s%9s ", perms, (type == S_IFREG || type == S_IFDIR)
- ? coolsize(cfg.blkorder ? (blkcnt_t)ent->blocks << blk_shift : ent->size)
@ -99,16 +99,21 @@ index d83d7f6..22402fa 100644
- if (attrs)
- attroff(attrs);
- }
-
+ int attrs = 0, namelen;
if (g_state.showlines) {
ptrdiff_t rel_num = pdents_index - cur;
printw(rel_num == 0 ? "%4td" : "%+4td", rel_num);
}
- attrs = 0;
-
+ int attrs = 0, namelen;
uchar_t color_pair = get_color_pair_name_ind(ent, &ind, &attrs);
addch((ent->flags & FILE_SELECTED) ? '+' | A_REVERSE | A_BOLD : ' ');
@@ -3822,15 +3803,40 @@ static void printent(const struct entry *ent, uint_t namecols, bool sel)
@@ -4284,15 +4266,40 @@ static void printent(int pdents_index, uint_t namecols, bool sel)
++namecols;
#ifndef NOLC
- addwstr(unescape(ent->name, namecols));
+ addwstr((namelen = unescape(ent->name, namecols), (wchar_t *)g_buf));
@ -116,7 +121,7 @@ index d83d7f6..22402fa 100644
- addstr(unescape(ent->name, MIN(namecols, ent->nlen) + 1));
+ addstr((namelen = unescape(ent->name, MIN(namecols, ent->nlen) + 1), (char *)g_buf));
#endif
- if (attrs)
+ if (!sel && attrs)
attroff(attrs);
@ -130,10 +135,10 @@ index d83d7f6..22402fa 100644
+
+ if (attrs)
+ attron(attrs);
+ if (!g_state.oldcolor && (type == S_IFDIR || (type == S_IFLNK && ent->flags & DIR_OR_LINK_TO_DIR)))
+ if (!g_state.oldcolor && (type == S_IFDIR || (type == S_IFLNK && ent->flags & DIR_OR_DIRLNK)))
+ attroff(A_BOLD);
+ size_t sizelen = (type == S_IFREG || type == S_IFDIR) ? xstrlen(size = coolsize(cfg.blkorder ? ent->blocks << blk_shift : ent->size)) : 1;
+ printw("%*c%*s%s%s", 1 + MIN(namecols, dtls.maxnameln + (size_t)(ind ? 0 : 1)) - namelen, ' ',
+ int sizelen = (type == S_IFREG || type == S_IFDIR) ? xstrlen(size = coolsize(cfg.blkorder ? ent->blocks << blk_shift : ent->size)) : 1;
+ printw("%*c%*s%s%s", 1 + MIN(namecols, dtls.maxnameln + (uint_t)(ind ? 0 : 1)) - namelen, ' ',
+ dtls.maxsizeln - sizelen, "", size ? size : (type = (uchar_t)get_detail_ind(ent->mode), (char *)&type), " ");
+#ifndef NOUG
+ if (g_state.uidgid && dtls.printguid) {
@ -143,65 +148,59 @@ index d83d7f6..22402fa 100644
+ }
+#endif
+ addstr(perms);
+ print_time(&ent->sec);
+ print_time(&ent->sec, ent->flags);
+ }
+ if (attrs)
+ attroff(attrs);
}
static void savecurctx(settings *curcfg, char *path, char *curname, int nextctx)
@@ -5814,18 +5820,6 @@ static void statusbar(char *path)
tocursor();
/**
@@ -6527,26 +6534,19 @@ static void statusbar(char *path)
tocursor();
}
-static inline void markhovered(void)
-{
- if (cfg.showdetail && ndents) { /* Reversed block for hovered entry */
- if (cfg.showdetail && ndents) { /* Bold forward arrowhead */
- tocursor();
-#ifdef ICONS_ENABLED
- addstr(MD_ARROW_FORWARD);
-#else
- addch(' ' | A_REVERSE);
-#endif
- addch('>' | A_BOLD);
- }
-}
-
static int adjust_cols(int n)
{
/* Calculate the number of cols available to print entry name */
@@ -5833,13 +5827,10 @@ static int adjust_cols(int n)
n -= (g_state.oldcolor ? 0 : 1 + xstrlen(ICON_PADDING_LEFT) + xstrlen(ICON_PADDING_RIGHT));
#ifdef ICONS_ENABLED
n -= (g_state.oldcolor ? 0 : ICON_SIZE + ICON_PADDING_LEFT_LEN + ICON_PADDING_RIGHT_LEN);
#endif
+
if (cfg.showdetail) {
- /* Fallback to light mode if less than 35 columns */
/* Fallback to light mode if less than 35 columns */
- if (n < 36)
+ if (n < (dtls.maxentln + 1 - dtls.maxnameln))
cfg.showdetail ^= 1;
- else {
- /* 2 more accounted for below */
else /* 2 more accounted for below */
- n -= 32;
- }
+ else
+ n -= (dtls.maxentln - 2 - dtls.maxnameln);
}
/* 2 columns for preceding space and indicator */
@@ -5877,8 +5868,6 @@ static void draw_line(char *path, int ncols)
@@ -6412,8 +6411,6 @@ static void draw_line(int ncols)
/* Must reset e.g. no files in dir */
if (dir)
attroff(COLOR_PAIR(cfg.curctx + 1) | A_BOLD);
- markhovered();
-
statusbar(path);
- markhovered();
}
@@ -5970,6 +5959,21 @@ static void redraw(char *path)
attroff(A_UNDERLINE | COLOR_PAIR(cfg.curctx + 1));
static void redraw(char *path)
@@ -6521,6 +6518,21 @@ static void redraw(char *path)
onscreen = MIN(onscreen + curscroll, ndents);
+ if (cfg.showdetail) {
+ ushort_t lenbuf = dtls.maxnameln = dtls.maxsizeln = dtls.maxuidln = dtls.maxgidln = dtls.printguid = 0;
+ for (i = curscroll; i < ndents && i < curscroll + onscreen; ++i) {
+ ushort_t lenbuf = dtls.maxnameln = dtls.maxsizeln = dtls.maxuidln = dtls.maxgidln = dtls.printguid = 0;
+ for (i = curscroll; i < onscreen; ++i) {
+ if ((lenbuf = pdents[i].nlen - 1) > dtls.maxnameln) dtls.maxnameln = lenbuf;
+ if ((lenbuf = xstrlen(coolsize(cfg.blkorder ? pdents[i].blocks << blk_shift : pdents[i].size))) > dtls.maxsizeln) dtls.maxsizeln = lenbuf;
+#ifndef NOUG
@ -211,18 +210,18 @@ index d83d7f6..22402fa 100644
+ }
+#endif
+ }
+ dtls.maxentln = dtls.maxnameln + dtls.maxsizeln + (dtls.printguid ? (dtls.maxuidln + dtls.maxgidln + 29) : 26);
+ }
+ dtls.maxentln = dtls.maxnameln + dtls.maxsizeln + (dtls.printguid ? (dtls.maxuidln + dtls.maxgidln) : 0) + (g_state.uidgid ? 26 : 23);
+
ncols = adjust_cols(ncols);
/* Go to first entry */
@@ -6011,8 +6015,6 @@ static void redraw(char *path)
int len = scanselforpath(path, FALSE);
@@ -6551,7 +6563,7 @@ static void redraw(char *path)
#endif
}
- markhovered();
-
statusbar(path);
+ statusbar(path);
}
static bool cdprep(char *lastdir, char *lastname, char *path, char *newpath)

View File

@ -0,0 +1,269 @@
# Description: Adds preview pipe to enable closing and re-opening the preview
# pane when running an undetached editor. If you are using vim
# you might experience incorrectly resized window. Consider adding
# the following to your vimrc:
# autocmd VimEnter * :silent exec "!kill -s WINCH $PPID"
#
# Authors: Luuk van Baal
diff --git a/src/nnn.c b/src/nnn.c
index 0388b23c..66d3316a 100644
--- a/src/nnn.c
+++ b/src/nnn.c
@@ -391,7 +391,8 @@ typedef struct {
uint_t usebsdtar : 1; /* Use bsdtar as default archive utility */
uint_t xprompt : 1; /* Use native prompt instead of readline prompt */
uint_t showlines : 1; /* Show line numbers */
- uint_t reserved : 3; /* Adjust when adding/removing a field */
+ uint_t previewer : 1; /* Run state of previewer */
+ uint_t reserved : 2; /* Adjust when adding/removing a field */
} runstate;
/* Contexts or workspaces */
@@ -516,6 +517,9 @@ alignas(max_align_t) static char g_tmpfpath[TMP_LEN_MAX];
/* Buffer to store plugins control pipe location */
alignas(max_align_t) static char g_pipepath[TMP_LEN_MAX];
+/* Buffer to store preview plugins control pipe location */
+static char g_ppipepath[TMP_LEN_MAX] __attribute__ ((aligned));
+
/* Non-persistent runtime states */
static runstate g_state;
@@ -696,12 +700,13 @@ static const char * const messages[] = {
#define NNN_FCOLORS 5
#define NNNLVL 6
#define NNN_PIPE 7
-#define NNN_MCLICK 8
-#define NNN_SEL 9
-#define NNN_ARCHIVE 10
-#define NNN_ORDER 11
-#define NNN_HELP 12 /* strings end here */
-#define NNN_TRASH 13 /* flags begin here */
+#define NNN_PPIPE 8
+#define NNN_MCLICK 9
+#define NNN_SEL 10
+#define NNN_ARCHIVE 11
+#define NNN_ORDER 12
+#define NNN_HELP 13 /* strings end here */
+#define NNN_TRASH 14 /* flags begin here */
static const char * const env_cfg[] = {
"NNN_OPTS",
@@ -712,6 +717,7 @@ static const char * const env_cfg[] = {
"NNN_FCOLORS",
"NNNLVL",
"NNN_PIPE",
+ "NNN_PPIPE",
"NNN_MCLICK",
"NNN_SEL",
"NNN_ARCHIVE",
@@ -850,7 +856,7 @@ static int set_sort_flags(int r);
static void statusbar(char *path);
static bool get_output(char *file, char *arg1, char *arg2, int fdout, bool page);
#ifndef NOFIFO
-static void notify_fifo(bool force);
+static void notify_fifo(bool force, bool closepreview);
#endif
/* Functions */
@@ -3140,7 +3146,7 @@ try_quit:
} else {
#ifndef NOFIFO
if (!g_state.fifomode)
- notify_fifo(TRUE); /* Send hovered path to NNN_FIFO */
+ notify_fifo(TRUE, FALSE); /* Send hovered path to NNN_FIFO */
#endif
escaped = TRUE;
settimeout();
@@ -5258,15 +5264,20 @@ static void run_cmd_as_plugin(const char *file, uchar_t flags)
static bool plctrl_init(void)
{
- size_t len;
+ size_t len, lenbuf;
+ pid_t pid = getpid();
/* g_tmpfpath is used to generate tmp file names */
g_tmpfpath[tmpfplen - 1] = '\0';
- len = xstrsncpy(g_pipepath, g_tmpfpath, TMP_LEN_MAX);
+ len = lenbuf = xstrsncpy(g_pipepath, g_tmpfpath, TMP_LEN_MAX);
g_pipepath[len - 1] = '/';
- len = xstrsncpy(g_pipepath + len, "nnn-pipe.", TMP_LEN_MAX - len) + len;
- xstrsncpy(g_pipepath + len - 1, xitoa(getpid()), TMP_LEN_MAX - len);
+ xstrsncpy(g_ppipepath, g_pipepath, TMP_LEN_MAX);
+ len += xstrsncpy(g_pipepath + len, "nnn-pipe.", TMP_LEN_MAX - len);
+ xstrsncpy(g_pipepath + len - 1, xitoa(pid), TMP_LEN_MAX - len);
+ len = xstrsncpy(g_ppipepath + lenbuf, "nnn-ppipe.", TMP_LEN_MAX - lenbuf) + lenbuf;
+ xstrsncpy(g_ppipepath + len - 1, xitoa(pid), TMP_LEN_MAX - len);
setenv(env_cfg[NNN_PIPE], g_pipepath, TRUE);
+ setenv(env_cfg[NNN_PPIPE], g_ppipepath, TRUE);
return EXIT_SUCCESS;
}
@@ -5295,6 +5306,21 @@ static ssize_t read_nointr(int fd, void *buf, size_t count)
return len;
}
+void *previewpipe(void *arg __attribute__ ((unused)))
+{
+ int fd, buf;
+
+ mkfifo(g_ppipepath, 0600);
+ fd = open(g_ppipepath, O_RDONLY);
+
+ if (read(fd, &buf, 1) == 1)
+ g_state.previewer = buf;
+
+ close(fd);
+ unlink(g_ppipepath);
+ return NULL;
+}
+
static char *readpipe(int fd, char *ctxnum, char **path)
{
char ctx, *nextpath = NULL;
@@ -5979,7 +6005,7 @@ static void populate(char *path, char *lastname)
}
#ifndef NOFIFO
-static void notify_fifo(bool force)
+static void notify_fifo(bool force, bool closepreview)
{
if (!fifopath)
return;
@@ -5995,6 +6021,12 @@ static void notify_fifo(bool force)
}
}
+ if (closepreview) {
+ if (write(fifofd, "close\n", 6) != 6)
+ xerror();
+ return;
+ }
+
static struct entry lastentry;
if (!force && !memcmp(&lastentry, &pdents[cur], sizeof(struct entry))) // NOLINT
@@ -6027,7 +6059,7 @@ static void send_to_explorer(int *presel)
if (fd > 1)
close(fd);
} else
- notify_fifo(TRUE); /* Send opened path to NNN_FIFO */
+ notify_fifo(TRUE, FALSE); /* Send opened path to NNN_FIFO */
}
#endif
@@ -6060,7 +6092,7 @@ static void move_cursor(int target, int ignore_scrolloff)
#ifndef NOFIFO
if (!g_state.fifomode)
- notify_fifo(FALSE); /* Send hovered path to NNN_FIFO */
+ notify_fifo(FALSE, FALSE); /* Send hovered path to NNN_FIFO */
#endif
}
@@ -6733,7 +6765,7 @@ static bool browse(char *ipath, const char *session, int pkey)
pEntry pent;
enum action sel;
struct stat sb;
- int r = -1, presel, selstartid = 0, selendid = 0;
+ int r = -1, presel, selstartid = 0, selendid = 0, previewkey = 0;
const uchar_t opener_flags = (cfg.cliopener ? F_CLI : (F_NOTRACE | F_NOSTDIN | F_NOWAIT));
bool watch = FALSE, cd = TRUE;
ino_t inode = 0;
@@ -6991,7 +7023,7 @@ nochange:
move_cursor(r, 1);
#ifndef NOFIFO
else if ((event.bstate == BUTTON1_PRESSED) && !g_state.fifomode)
- notify_fifo(TRUE); /* Send clicked path to NNN_FIFO */
+ notify_fifo(TRUE, FALSE); /* Send clicked path to NNN_FIFO */
#endif
/* Handle right click selection */
if (event.bstate == BUTTON3_PRESSED) {
@@ -7153,7 +7185,14 @@ nochange:
&& strstr(g_buf, "text")
#endif
) {
+ if (g_state.previewer)
+ notify_fifo(FALSE, TRUE);
spawn(editor, newpath, NULL, NULL, F_CLI);
+ if (g_state.previewer) {
+ pkey = previewkey;
+ goto run_plugin;
+ }
+
if (cfg.filtermode) {
presel = FILTER;
clearfilter();
@@ -7471,8 +7510,14 @@ nochange:
copycurname();
goto nochange;
case SEL_EDIT:
+ if (g_state.previewer)
+ notify_fifo(FALSE, TRUE);
if (!(g_state.picker || g_state.fifomode))
spawn(editor, newpath, NULL, NULL, F_CLI);
+ if (g_state.previewer) {
+ pkey = previewkey;
+ goto run_plugin;
+ }
continue;
default: /* SEL_LOCK */
lock_terminal();
@@ -7860,6 +7905,7 @@ nochange:
cd = FALSE;
goto begin;
}
+run_plugin:
case SEL_PLUGIN:
/* Check if directory is accessible */
if (!xdiraccess(plgpath)) {
@@ -7885,6 +7931,12 @@ nochange:
goto nochange;
}
+ if (xstrcmp(tmp, "preview-tui") == 0) {
+ previewkey = r;
+ pthread_t tid;
+ pthread_create(&tid, NULL, previewpipe, NULL);
+ }
+
if (tmp[0] == '-' && tmp[1]) {
++tmp;
r = FALSE; /* Do not refresh dir after completion */
@@ -7943,7 +7995,13 @@ nochange:
case SEL_SHELL: // fallthrough
case SEL_LAUNCH: // fallthrough
case SEL_PROMPT:
+ if (g_state.previewer)
+ notify_fifo(FALSE, TRUE);
r = handle_cmd(sel, path, newpath);
+ if (g_state.previewer) {
+ pkey = previewkey;
+ goto run_plugin;
+ }
/* Continue in type-to-nav mode, if enabled */
if (cfg.filtermode)
@@ -8492,8 +8550,10 @@ static void cleanup(void)
if (g_state.autofifo)
unlink(fifopath);
#endif
- if (g_state.pluginit)
+ if (g_state.pluginit){
unlink(g_pipepath);
+ unlink(g_ppipepath);
+ }
#ifdef DEBUG
disabledbg();
#endif
@@ -9020,7 +9080,7 @@ int main(int argc, char *argv[])
#ifndef NOFIFO
if (!g_state.fifomode)
- notify_fifo(FALSE);
+ notify_fifo(FALSE, TRUE);
if (fifofd != -1)
close(fifofd);
#endif

View File

@ -22,8 +22,12 @@
IFS="$(printf '%b_' '\n')"; IFS="${IFS%_}" # protect trailing \n
selection=${NNN_SEL:-${XDG_CONFIG_HOME:-$HOME/.config}/nnn/.selection}
[ -s "$selection" ] || { echo "plugin .cbcp error: empty selection" >&2 ; exit 1; }
if type xsel >/dev/null 2>&1; then
if [ "$XDG_SESSION_TYPE" = "wayland" ]; then
# Wayland
tr '\0' '\n' < "$selection" | wl-copy
elif type xsel >/dev/null 2>&1; then
# Linux
tr '\0' '\n' < "$selection" | xsel -bi
elif type xclip >/dev/null 2>&1; then
@ -41,9 +45,6 @@ elif type clip.exe >/dev/null 2>&1; then
elif type clip >/dev/null 2>&1; then
# Cygwin
tr '\0' '\n' < "$selection" | clip
elif type wl-copy >/dev/null 2>&1; then
# Wayland
tr '\0' '\n' < "$selection" | wl-copy
elif type clipboard >/dev/null 2>&1; then
# Haiku
tr '\0' '\n' < "$selection" | clipboard --stdin

View File

@ -29,6 +29,7 @@ awk 'BEGIN {
color_docs=202 #color_docs=173 #color_docs="208;135;112"
color_archive=209 #color_archive=179 #color_archive="235;203;139"
color_c=81 #color_c=150 #color_c="163;190;140"
color_elixir=104 #color_elixir=109 #color_elixir="143;188;187"
color_java=32 #color_java=139 #color_java="180;142;173"
color_js=47 #color_js=109 #color_js="143;188;187"
color_react=39 #color_react=111 #color_react="129;161;193"
@ -39,53 +40,58 @@ awk 'BEGIN {
color_fsharp=31 #color_fsharp=179 #color_fsharp="180;142;173"
color_ruby=160 #color_ruby=150 #color_ruby="163;190;140"
color_scala=196 #color_scala=139 #color_scala="143;188;187"
color_shell=47 #color_shell=109 #color_shell="143;188;187"
color_vim=28 #color_vim=109 #color_vim="143;188;187"
# icons[][1] contains icon and icons[][2] contains color
icons["directory"][1] = ""; icons["directory"][2] = color_default
icons["file"][1] = ""; icons["file"][2] = color_default
icons["file"][1] = "󰈔"; icons["file"][2] = color_default
icons["exec"][1] = ""; icons["exec"][2] = color_default
icons["manual"][1] = ""; icons["manual"][2] = color_docs
icons["pipe"][1] = ""; icons["pipe"][2] = color_default
icons["socket"][1] = ""; icons["socket"][2] = color_default
icons["manual"][1] = "󱓷"; icons["manual"][2] = color_docs
icons["pipe"][1] = "󰟥"; icons["pipe"][2] = color_default
icons["socket"][1] = "󰟩"; icons["socket"][2] = color_default
icons["door"][1] = "➡"; icons["door"][2] = color_default
# top level and common icons
icons[".git"][1] = ""; icons[".git"][2] = color_default
icons["desktop"][1] = ""; icons["desktop"][2] = color_default
icons["briefcase"][1] = ""; icons["briefcase"][2] = color_default
icons["document"][1] = ""; icons["document"][2] = color_default
icons["downloads"][1] = ""; icons["downloads"][2] = color_default
icons["music"][1] = ""; icons["music"][2] = color_default
icons["musicfile"][1] = ""; icons["musicfile"][2] = color_audio
icons["pictures"][1] = ""; icons["pictures"][2] = color_default
icons["picturefile"][1] = ""; icons["picturefile"][2] = color_image
icons["desktop"][1] = "󰟀"; icons["desktop"][2] = color_default
icons["briefcase"][1] = "󰃖"; icons["briefcase"][2] = color_default
icons["document"][1] = "󰃖"; icons["document"][2] = color_default
icons["downloads"][1] = "󰃘"; icons["downloads"][2] = color_default
icons["music"][1] = "󱍙"; icons["music"][2] = color_default
icons["musicfile"][1] = "󰎈"; icons["musicfile"][2] = color_audio
icons["pictures"][1] = "󰉔"; icons["pictures"][2] = color_default
icons["picturefile"][1] = "󰈟"; icons["picturefile"][2] = color_image
icons["public"][1] = ""; icons["public"][2] = color_default
icons["templates"][1] = ""; icons["templates"][2] = color_default
icons["videos"][1] = ""; icons["videos"][2] = color_default
icons["videofile"][1] = ""; icons["videofile"][2] = color_video
icons["changelog"][1] = ""; icons["changelog"][2] = color_docs
icons["templates"][1] = "󰗇"; icons["templates"][2] = color_default
icons["videos"][1] = "󰈰"; icons["videos"][2] = color_default
icons["videofile"][1] = "󰈫"; icons["videofile"][2] = color_video
icons["changelog"][1] = "󰋚"; icons["changelog"][2] = color_docs
icons["configure"][1] = ""; icons["configure"][2] = color_default
icons["license"][1] = ""; icons["license"][2] = color_docs
icons["makefile"][1] = ""; icons["makefile"][2] = color_default
icons["archive"][1] = ""; icons["archive"][2] = color_archive
icons["script"][1] = ""; icons["script"][2] = color_default
icons["license"][1] = "󰈙"; icons["license"][2] = color_docs
icons["makefile"][1] = "󰆍"; icons["makefile"][2] = color_default
icons["archive"][1] = "󰀼"; icons["archive"][2] = color_archive
icons["rust"][1] = ""; icons["rust"][2] = color_default
icons["script"][1] = ""; icons["script"][2] = color_shell
icons["subtitle"][1] = "󰅺"; icons["subtitle"][2] = color_default
icons["cplusplus"][1] = ""; icons["cplusplus"][2] = color_c
icons["java"][1] = ""; icons["java"][2] = color_java
icons["clojure"][1] = ""; icons["clojure"][2] = color_default
icons["js"][1] = ""; icons["js"][2] = color_js
icons["linux"][1] = ""; icons["linux"][2] = color_default
icons["js"][1] = "󰌞"; icons["js"][2] = color_js
icons["linux"][1] = "󰌽"; icons["linux"][2] = color_default
icons["elixir"][1] = ""; icons["elixir"][2] = color_fsharp
icons["fsharp"][1] = ""; icons["fsharp"][2] = color_fsharp
icons["ruby"][1] = ""; icons["ruby"][2] = color_ruby
icons["c"][1] = ""; icons["c"][2] = color_c
icons["chess"][1] = ""; icons["chess"][2] = color_default
icons["chess"][1] = "󰄺"; icons["chess"][2] = color_default
icons["haskell"][1] = ""; icons["haskell"][2] = color_vim
icons["html"][1] = ""; icons["html"][2] = color_default
icons["font"][1] = ""; icons["font"][2] = color_default
icons["html"][1] = "󰌝"; icons["html"][2] = color_default
icons["react"][1] = ""; icons["react"][2] = color_react
icons["python"][1] = ""; icons["python"][2] = color_python
icons["database"][1] = ""; icons["database"][2] = color_default
icons["worddoc"][1] = ""; icons["worddoc"][2] = color_document
icons["playlist"][1] = ""; icons["playlist"][2] = color_audio
icons["database"][1] = "󰆼"; icons["database"][2] = color_default
icons["worddoc"][1] = "󰈬"; icons["worddoc"][2] = color_document
icons["playlist"][1] = "󱍙"; icons["playlist"][2] = color_audio
icons["opticaldisk"][1] = ""; icons["opticaldisk"][2] = color_archive
# numbers
@ -107,6 +113,7 @@ awk 'BEGIN {
# c
icons["cplusplus"][1] = icons["cplusplus"][1]; icons["cplusplus"][2] = icons["cplusplus"][2]
icons["cabal"][1] = icons["haskell"][1]; icons["cab"][2] = icons["haskell"][2]
icons["cab"][1] = icons["archive"][1]; icons["cab"][2] = icons["archive"][2]
icons["cbr"][1] = icons["archive"][1]; icons["cbr"][2] = icons["archive"][2]
icons["cbz"][1] = icons["archive"][1]; icons["cbz"][2] = icons["archive"][2]
@ -120,7 +127,7 @@ awk 'BEGIN {
icons["conf"][1] = icons["configure"][1]; icons["conf"][2] = icons["configure"][2]
icons["cpio"][1] = icons["archive"][1]; icons["cpio"][2] = icons["archive"][2]
icons["cpp"][1] = icons["cplusplus"][1]; icons["cpp"][2] = icons["cplusplus"][2]
icons["css"][1] = ""; icons["css"][2] = color_css
icons["css"][1] = ""; icons["css"][2] = color_css
icons["cue"][1] = icons["playlist"][1]; icons["cue"][2] = icons["playlist"][2]
icons["cvs"][1] = icons["configure"][1]; icons["cvs"][2] = icons["configure"][2]
icons["cxx"][1] = icons["cplusplus"][1]; icons["cxx"][2] = icons["cplusplus"][2]
@ -138,6 +145,9 @@ awk 'BEGIN {
icons["elf"][1] = icons["linux"][1]; icons["elf"][2] = icons["linux"][2]
icons["epub"][1] = icons["manual"][1]; icons["epub"][2] = icons["manual"][2]
icons["exe"][1] = icons["exec"][1]; icons["exe"][2] = icons["exec"][2]
icons["ex"][1] = icons["elixir"][1]; icons["ex"][2] = icons["elixir"][2]
icons["eex"][1] = icons["elixir"][1]; icons["eex"][2] = icons["elixir"][2]
icons["exs"][1] = icons["elixir"][1]; icons["exs"][2] = icons["elixir"][2]
# f
icons["fsharp"][1] = icons["fsharp"][1]; icons["fsharp"][2] = icons["fsharp"][2]
@ -152,7 +162,7 @@ awk 'BEGIN {
# g
icons["gem"][1] = icons["ruby"][1]; icons["gem"][2] = icons["ruby"][2]
icons["gif"][1] = icons["picturefile"][1]; icons["gif"][2] = icons["picturefile"][2]
icons["go"][1] = ""; icons["go"][2] = color_default
icons["go"][1] = "󰟓"; icons["go"][2] = color_default
icons["gz"][1] = icons["archive"][1]; icons["gz"][2] = icons["archive"][2]
icons["gzip"][1] = icons["archive"][1]; icons["gzip"][2] = icons["archive"][2]
@ -165,12 +175,14 @@ awk 'BEGIN {
icons["htpasswd"][1] = icons["configure"][1]; icons["htpasswd"][2] = icons["configure"][2]
icons["htm"][1] = icons["html"][1]; icons["htm"][2] = icons["html"][2]
icons["hxx"][1] = icons["cplusplus"][1]; icons["hxx"][2] = icons["cplusplus"][2]
icons["heex"][1] = icons["elixir"][1]; icons["heex"][2] = icons["elixir"][2]
# i
icons["ico"][1] = icons["picturefile"][1]; icons["ico"][2] = icons["picturefile"][2]
icons["img"][1] = icons["opticaldisk"][1]; icons["img"][2] = icons["opticaldisk"][2]
icons["ini"][1] = icons["configure"][1]; icons["ini"][2] = icons["configure"][2]
icons["iso"][1] = icons["opticaldisk"][1]; icons["iso"][2] = icons["opticaldisk"][2]
icons["isub"][1] = icons["subtitle"][1]; icons["isub"][2] = icons["subtitle"][2]
# j
icons["jar"][1] = icons["java"][1]; icons["jar"][2] = icons["java"][2]
@ -178,22 +190,26 @@ awk 'BEGIN {
icons["jl"][1] = icons["configure"][1]; icons["jl"][2] = icons["configure"][2]
icons["jpeg"][1] = icons["picturefile"][1]; icons["jpeg"][2] = icons["picturefile"][2]
icons["jpg"][1] = icons["picturefile"][1]; icons["jpg"][2] = icons["picturefile"][2]
icons["json"][1] = ""; icons["json"][2] = color_js
icons["json"][1] = ""; icons["json"][2] = color_js
icons["jsx"][1] = icons["react"][1]; icons["jsx"][2] = icons["react"][2]
icons["jxl"][1] = icons["picturefile"][1]; icons["jxl"][2] = icons["picturefile"][2]
# k
icons["ksh"][1] = icons["font"][1]; icons["ksf"][2] = icons["font"][2]
# l
icons["lha"][1] = icons["archive"][1]; icons["lha"][2] = icons["archive"][2]
icons["lhs"][1] = icons["haskell"][1]; icons["lhs"][2] = icons["haskell"][2]
icons["ilog"][1] = icons["document"][1]; icons["ilog"][2] = icons["document"][2]
icons["lua"][1] = ""; icons["lua"][2] = color_default
icons["lua"][1] = ""; icons["lua"][2] = color_lua
icons["lzh"][1] = icons["archive"][1]; icons["lzh"][2] = icons["archive"][2]
icons["lzma"][1] = icons["archive"][1]; icons["lzma"][2] = icons["archive"][2]
# m
icons["m"][1] = "󰠞"; icons["mat"][2] = color_c
icons["m4a"][1] = icons["musicfile"][1]; icons["m4a"][2] = icons["musicfile"][2]
icons["m4v"][1] = icons["videofile"][1]; icons["m4v"][2] = icons["videofile"][2]
icons["mat"][1] = ""; icons["mat"][2] = color_c
icons["markdown"][1] = ""; icons["markdown"][2] = color_docs
icons["md"][1] = ""; icons["md"][2] = color_docs
icons["mk"][1] = icons["makefile"][1]; icons["mk"][2] = icons["makefile"][2]
@ -203,25 +219,27 @@ awk 'BEGIN {
icons["mp4"][1] = icons["videofile"][1]; icons["mp4"][2] = icons["videofile"][2]
icons["mpeg"][1] = icons["videofile"][1]; icons["mpeg"][2] = icons["videofile"][2]
icons["mpg"][1] = icons["videofile"][1]; icons["mpg"][2] = icons["videofile"][2]
icons["msi"][1] = ""; icons["msi"][2] = color_default
icons["msi"][1] = "󰍲"; icons["msi"][2] = color_default
# n
icons["nix"][1] = ""; icons["nix"][2] = color_fsharp
# o
icons["o"][1] = icons["manual"][1]; icons["o"][2] = icons["manual"][2]
icons["ogg"][1] = icons["musicfile"][1]; icons["ogg"][2] = icons["musicfile"][2]
icons["odownload"][1] = icons["download"][1]; icons["odownload"][2] = icons["download"][2]
icons["otf"][1] = icons["font"][1]; icons["otf"][2] = icons["font"][2]
icons["out"][1] = icons["linux"][1]; icons["out"][2] = icons["linux"][2]
# p
icons["part"][1] = icons["download"][1]; icons["part"][2] = icons["download"][2]
icons["patch"][1] = icons["diff"][1]; icons["patch"][2] = icons["diff"][2]
icons["pdf"][1] = ""; icons["pdf"][2] = color_docs
icons["pdf"][1] = "󰈦"; icons["pdf"][2] = color_docs
icons["pgn"][1] = icons["chess"][1]; icons["pgn"][2] = icons["chess"][2]
icons["php"][1] = ""; icons["php"][2] = color_default
icons["png"][1] = icons["picturefile"][1]; icons["png"][2] = icons["picturefile"][2]
icons["ppt"][1] = ""; icons["ppt"][2] = color_default
icons["pptx"][1] = ""; icons["pptx"][2] = color_default
icons["ppt"][1] = "󰈧"; icons["ppt"][2] = color_default
icons["pptx"][1] = "󰈧"; icons["pptx"][2] = color_default
icons["psb"][1] = ""; icons["psb"][2] = color_default
icons["psd"][1] = ""; icons["psd"][2] = color_default
icons["py"][1] = icons["python"][1]; icons["py"][2] = icons["python"][2]
@ -234,10 +252,10 @@ awk 'BEGIN {
# r
icons["rar"][1] = icons["archive"][1]; icons["rar"][2] = icons["archive"][2]
icons["rc"][1] = icons["configure"][1]; icons["rc"][2] = icons["configure"][2]
icons["rom"][1] = ""; icons["rom"][2] = color_default
icons["rom"][1] = "󰊖"; icons["rom"][2] = color_default
icons["rpm"][1] = icons["archive"][1]; icons["rpm"][2] = icons["archive"][2]
icons["rss"][1] = ""; icons["rss"][2] = color_default
icons["rtf"][1] = ""; icons["rtf"][2] = color_default
icons["rss"][1] = ""; icons["rss"][2] = color_default
icons["rtf"][1] = "󰈦"; icons["rtf"][2] = color_default
# s
icons["sass"][1] = ""; icons["sass"][2] = color_css
@ -248,18 +266,18 @@ awk 'BEGIN {
icons["slim"][1] = icons["script"][1]; icons["slim"][2] = icons["script"][2]
icons["sln"][1] = ""; icons["sln"][2] = color_default
icons["sql"][1] = icons["database"][1]; icons["sql"][2] = icons["database"][2]
icons["srt"][1] = ""; icons["srt"][2] = color_default
icons["isub"][1] = ""; icons["isub"][2] = color_default
icons["srt"][1] = icons["subtitle"][1]; icons["srt"][2] = icons["subtitle"][2]
icons["svg"][1] = icons["picturefile"][1]; icons["svg"][2] = icons["picturefile"][2]
# t
icons["tar"][1] = icons["archive"][1]; icons["tar"][2] = icons["archive"][2]
icons["tex"][1] = ""; icons["tex"][2] = color_default
icons["tex"][1] = "󰙩"; icons["tex"][2] = color_default
icons["tgz"][1] = icons["archive"][1]; icons["tgz"][2] = icons["archive"][2]
icons["ts"][1] = ""; icons["ts"][2] = color_js
icons["tsx"][1] = icons["react"][1]; icons["tsx"][2] = icons["react"][2]
icons["txt"][1] = icons["document"][1]; icons["txt"][2] = icons["document"][2]
icons["txz"][1] = icons["archive"][1]; icons["txz"][2] = icons["archive"][2]
icons["ttf"][1] = icons["font"][1]; icons["ttf"][2] = icons["font"][2]
# u
@ -267,7 +285,7 @@ awk 'BEGIN {
icons["vid"][1] = icons["videofile"][1]; icons["vid"][2] = icons["videofile"][2]
icons["vim"][1] = ""; icons["vim"][2] = color_vim
icons["vimrc"][1] = ""; icons["vimrc"][2] = color_vim
icons["vtt"][1] = ""; icons["vtt"][2] = color_default
icons["vtt"][1] = icons["subtitle"][1]; icons["vtt"][2] = icons["subtitle"][2]
# w
icons["wav"][1] = icons["musicfile"][1]; icons["wav"][2] = icons["musicfile"][2]
icons["webm"][1] = icons["videofile"][1]; icons["webm"][2] = icons["videofile"][2]
@ -278,8 +296,8 @@ awk 'BEGIN {
icons["xbps"][1] = icons["archive"][1]; icons["xbps"][2] = color_archive
icons["xcf"][1] = icons["picturefile"][1]; icons["xcf"][2] = color_image
icons["xhtml"][1] = icons["html"][1]; icons["xhtml"][2] = icons["html"][2]
icons["xls"][1] = ""; icons["xls"][2] = color_default
icons["xlsx"][1] = ""; icons["xlsx"][2] = color_default
icons["xls"][1] = "󰈛"; icons["xls"][2] = color_default
icons["xlsx"][1] = "󰈛"; icons["xlsx"][2] = color_default
icons["xml"][1] = icons["html"][1]; icons["xml"][2] = icons["html"][2]
icons["xz"][1] = icons["archive"][1]; icons["xz"][2] = icons["archive"][2]
@ -288,6 +306,8 @@ awk 'BEGIN {
icons["yml"][1] = icons["configure"][1]; icons["yml"][2] = icons["configure"][2]
# z
icons["zip"][1] = icons["archive"][1]; icons["zip"][2] = icons["archive"][2]
icons["zsh"][1] = icons["script"][1]; icons["zsh"][2] = icons["script"][2]
icons["zst"][1] = icons["archive"][1]; icons["zst"][2] = icons["archive"][2]
FS = "."
limit = ENVIRON["limit"]

View File

@ -5,6 +5,7 @@
# Note: nnn auto-detects and invokes this plugin if available
# Whitespace is used as delimiter for read.
# The plugin doesn't support filenames with leading or trailing whitespace
# To use NNN_LIST your shell must support readlink(1)
#
# Capabilities:
# 1. Basic file rename
@ -16,42 +17,63 @@
# Shell: bash
# Author: KlzXS
# shellcheck disable=SC1090,SC1091
. "$(dirname "$0")"/.nnn-plugin-helper
EDITOR="${EDITOR:-vi}"
TMPDIR="${TMPDIR:-/tmp}"
INCLUDE_HIDDEN="${INCLUDE_HIDDEN:-0}"
NNN_INCLUDE_HIDDEN="${NNN_INCLUDE_HIDDEN:-0}"
VERBOSE="${VERBOSE:-0}"
RECURSIVE="${RECURSIVE:-0}"
case "$NNN_TRASH" in
1)
RM_UTIL="trash-put" ;;
2)
RM_UTIL="gio trash" ;;
*)
RM_UTIL="rm -ri --" ;;
esac
selection=${NNN_SEL:-${XDG_CONFIG_HOME:-$HOME/.config}/nnn/.selection}
exit_status=0
dst_file=$(mktemp "$TMPDIR/.nnnXXXXXX")
if [ -s "$selection" ]; then
printf "Rename 'c'urrent / 's'election? "
read -r resp
if ! [ "$resp" = "c" ] && ! [ "$resp" = "s" ]; then
exit 1
fi
fi
if [ "$resp" = "s" ]; then
if nnn_use_selection "Rename"; then
# shellcheck disable=SC2154
arr=$(tr '\0' '\n' < "$selection")
else
if [ "$INCLUDE_HIDDEN" -eq 0 ]; then
arr=$(find . ! -name . -prune ! -name ".*" -print | sort)
else
arr=$(find . ! -name . -prune -print | sort)
findcmd="find . ! -name ."
if [ "$RECURSIVE" -eq 0 ]; then
findcmd="$findcmd -prune"
fi
if [ "$NNN_INCLUDE_HIDDEN" -eq 0 ]; then
findcmd="$findcmd ! -name \".*\""
fi
if [ -z "$NNN_LIST" ]; then
findcmd="$findcmd -print"
else
findcmd="$findcmd -printf "'"'"$NNN_LIST/%P\n"'"'
fi
arr=$(eval "$findcmd" | sort)
fi
lines=$(printf "%s\n" "$arr" | wc -l)
width=${#lines}
dst_file=$(mktemp "$TMPDIR/.nnnXXXXXX")
trap 'rm -f -- "$dst_file"' EXIT
printf "%s" "$arr" | awk '{printf("%'"${width}"'d %s\n", NR, $0)}' > "$dst_file"
items=("~")
while IFS='' read -r line; do
if [ -n "$NNN_LIST" ]; then
line=$(readlink "$line" || printf "%s" "$line")
fi
items+=("$line");
done < <(printf "%s\n" "$arr")
@ -100,7 +122,7 @@ while read -r num name; do
tmp="$tmp~$c"
done
if mv "$name" "$tmp"; then
if mv -- "$name" "$tmp"; then
if [ "$VERBOSE" -ne 0 ]; then
printf "'%s' -> '%s'\n" "$name" "$tmp"
fi
@ -120,7 +142,7 @@ while read -r num name; do
if [ ! -d "$dir" ] && ! mkdir -p "$dir"; then
printf "%s: failed to create directory tree %s\n" "$0" "$dir" > /dev/stderr
exit_status=1
elif ! mv -i "$src" "$name"; then
elif ! mv -i -- "$src" "$name"; then
printf "%s: failed to rename %s to %s: %s\n" "$0" "$name" "$tmp" "$!" > /dev/stderr
exit_status=1
else
@ -146,8 +168,7 @@ done <"$dst_file"
unset "items[0]"
for item in "${items[@]}"; do
rm -ri "$item"
$RM_UTIL "$item"
done
rm "$dst_file"
exit $exit_status

View File

@ -12,6 +12,9 @@ export selection
CUR_CTX=0
export CUR_CTX
NNN_PREFER_SELECTION="${NNN_PREFER_SELECTION:-0}"
export NNN_PREFER_SELECTION
## Ask nnn to switch to directory $1 in context $2.
## If $2 is not provided, the function asks explicitly.
nnn_cd () {
@ -36,3 +39,23 @@ cmd_exists () {
type "$1" > /dev/null 2>&1
echo $?
}
nnn_use_selection() {
if ! [ -s "$selection" ]; then
return 1
fi
if [ "$NNN_PREFER_SELECTION" -eq 1 ]; then
return 0
else
[ -n "$1" ] && printf "%s " "$1"
printf "(s)election/(c)urrent? [default=c] "
read -r resp__
if [ "$resp__" = "s" ]; then
return 0
else
return 1
fi
fi
}

View File

@ -13,47 +13,46 @@ Plugins extend the capabilities of `nnn`. They are _executable_ scripts (or bina
| Plugin (a-z) | Description [Clears selection<sup>1</sup>] | Lang | Dependencies |
| --- | --- | --- | --- |
| [autojump](autojump) | Navigate to dir/path | sh | [jump](https://github.com/gsamokovarov/jump)/autojump/zoxide |
| [bookmarks](bookmarks) | Use named bookmarks managed with symlinks | sh | fzf |
| [autojump](autojump) | Navigate to dir/path | sh | [jump](https://github.com/gsamokovarov/jump)/autojump/<br>zoxide/z/[z.lua](https://github.com/skywind3000/z.lua) |
| [boom](boom) | Play random music from dir | sh | [moc](http://moc.daper.net/) |
| [bulknew](bulknew) | Create multiple files/dirs at once | bash | sed, xargs, mktemp |
| [cbcopy-mac](cbcopy-mac) | Copy the hovered file to MacOS clipboard | applescript | macos |
| [cbpaste-mac](cbpaste-mac) | Pastes files from MacOS clipboard into currect directory | macos |
| [cdpath](cdpath) | `cd` to the directory from `CDPATH` | sh | fzf |
| [chksum](chksum) | Create and verify checksums [✓] | sh | md5sum,<br>sha256sum |
| [cmusq](cmusq) | Queue/play files/dirs in cmus player [✓] | sh | cmus, pgrep |
| [diffs](diffs) | Diff for selection (limited to 2 for directories) [✓] | sh | vimdiff, mktemp |
| [dragdrop](dragdrop) | Drag/drop files from/into nnn | sh | [dragon](https://github.com/mwh/dragon) |
| [dups](dups) | List non-empty duplicate files in current dir | bash | find, md5sum,<br>sort uniq xargs |
| [finder](finder) | Run custom find command and list | sh | - |
| [finder](finder) | Run custom find command (**stored in histfile**) and list | sh | - |
| [fixname](fixname) | Clean filename to be more shell-friendly [✓] | bash | sed |
| [fzcd](fzcd) | Fuzzy search multiple dirs (or `$PWD`) and visit file [✓] | sh | fzf, (fd) |
| [fzcd](fzcd) | Fuzzy search multiple dirs (or `$PWD`) and visit file | sh | fzf, (find) |
| [fzhist](fzhist) | Fuzzy-select a cmd from history, edit in `$EDITOR` and run | sh | fzf, mktemp |
| [fzopen](fzopen) | Fuzzy find file(s) in subtree to edit/open/pick | sh | fzf, xdg-open |
| [fzopen](fzopen) | Fuzzy find file(s) in subtree to edit/open/pick | sh | fzf, xdg-open/open |
| [fzplug](fzplug) | Fuzzy find, preview and run other plugins | sh | fzf |
| [fzz](fzz) | Change to any directory in the z database with fzf | sh | fzf, z |
| [getplugs](getplugs) | Update plugins to installed `nnn` version | sh | curl |
| [gpg\*](gpg\*) | Encrypt/decrypt files using GPG [✓] | sh | gpg |
| [gitroot](gitroot) | Cd to the root of current git repo | sh | git |
| [gpge](gpge) | Encrypt/decrypt files using GPG [✓] | sh | gpg |
| [gutenread](gutenread) | Browse, download, read from Project Gutenberg | sh | curl, unzip, w3m<br>[epr](https://github.com/wustho/epr) (optional) |
| [hexview](hexview) | View a file in hex in `$PAGER` | sh | [hx](https://github.com/krpors/hx)/xxd |
| [imgresize](imgresize) | Resize images in dir to screen resolution | sh | [imgp](https://github.com/jarun/imgp) |
| [gsconnect](gsconnect) | GNOME's implementation of kdeconnect [✓] | sh | gsconnect |
| [imgresize](imgresize) | Batch resize images in dir to screen resolution | sh | [imgp](https://github.com/jarun/imgp) |
| [imgur](imgur) | Upload an image to imgur (from [imgur-screenshot](https://github.com/jomo/imgur-screenshot)) | bash | - |
| [imgview](imgview) | View (thumbnail)images, set wallpaper, [rename](https://github.com/jarun/nnn/wiki/Basic-use-cases#browse-rename-images) and [more](https://wiki.archlinux.org/index.php/Sxiv#Assigning_keyboard_shortcuts)| sh | [imv](https://github.com/eXeC64/imv)/[sxiv](https://github.com/muennich/sxiv)/[viu](https://github.com/atanunq/viu)/<br>[ucollage](https://github.com/ckardaris/ucollage)/[catimg](https://github.com/posva/catimg)/[lsix](https://github.com/hackerb9/lsix)|
| [imgview](imgview) | View (thumbnail)images, set wallpaper, [rename](https://github.com/jarun/nnn/wiki/Basic-use-cases#browse-rename-images) and [more](https://wiki.archlinux.org/index.php/Sxiv#Assigning_keyboard_shortcuts)| sh | _see in-file docs_ |
| [ipinfo](ipinfo) | Fetch external IP address and whois information | sh | curl, whois |
| [kdeconnect](kdeconnect) | Send selected files to an Android device [✓] | sh | kdeconnect-cli |
| [launch](launch) | GUI application launcher | sh | fzf |
| [mediainf](mediainf) | Show media information | sh | mediainfo |
| [mimelist](mimelist) | List files by mime in subtree | sh | - |
| [mimelist](mimelist) | List files by mime in subtree | sh | file/mimetype |
| [moclyrics](moclyrics) | Show lyrics of the track playing in moc | sh | [ddgr](https://github.com/jarun/ddgr), [moc](http://moc.daper.net/) |
| [mocq](mocq) | Queue/play selection/dir/file in moc [✓] | sh | [moc](http://moc.daper.net/) |
| [mp3conv](mp3conv) | Extract audio from multimedia as mp3 | sh | ffmpeg |
| [mtpmount](mtpmount) | Toggle mount of MTP device (eg. Android) | sh | gvfs-mtp |
| [nbak](nbak) | Backs up `nnn` config | sh | tar, awk, mktemp |
| [nmount](nmount) | Toggle mount status of a device as normal user | sh | pmount, udisks2 |
| [nmount](nmount) | Toggle mount status of a device as normal user | sh | pmount (optional), udisks2 |
| [nuke](nuke) | Sample file opener (CLI-only by default) | sh | _see in-file docs_ |
| [oldbigfile](oldbigfile) | List large files by access time | sh | find, sort |
| [openall](openall) | Open selected files together or one by one [✓] | bash | - |
| [organize](organize) | Auto-organize files in directories by file type [✓] | sh | file |
| [pdfread](pdfread) | Read a PDF or text file aloud | sh | pdftotext, mpv,<br>pico2wave |
| [pdfview](pdfview) | View PDF file in `$PAGER` | sh | pdftotext/<br>mupdf-tools |
| [picker](picker) | Pick files and list one per line (to pipe) | sh | nnn |
| [preview-tabbed](preview-tabbed) | Preview files with Tabbed/xembed | bash | _see in-file docs_ |
| [preview-tui](preview-tui) | Preview with Tmux/kitty/[QuickLook](https://github.com/QL-Win/QuickLook)/xterm/`$TERMINAL` | sh | _see in-file docs_ |
| [pskill](pskill) | Fuzzy list by name and kill process or zombie | sh | fzf, ps, sudo/doas |
@ -63,25 +62,40 @@ Plugins extend the capabilities of `nnn`. They are _executable_ scripts (or bina
| [splitjoin](splitjoin) | Split file or join selection [✓] | sh | split, cat |
| [suedit](suedit) | Edit file using superuser permissions | sh | sudoedit/sudo/doas |
| [togglex](togglex) | Toggle executable mode for selection [✓] | sh | chmod |
| [treeview](treeview) | Informative tree output in `$EDITOR` | sh | tree |
| [uidgid](uidgid) | List user and group of all files in dir | sh | ls, less |
| [umounttree](umounttree) | Unmount a remote mountpoint from within | sh | fusermount |
| [upgrade](upgrade) | Upgrade nnn manually on Debian 9 Stretch | sh | curl |
| [upload](upload) | Upload to Firefox Send or ix.io (text) or file.io (bin) | sh | [ffsend](https://github.com/timvisee/ffsend), curl, jq, tr |
| [wall](wall) | Set wallpaper or change colorscheme | sh | nitrogen/pywal |
| [wallpaper](wallpaper) | Set wallpaper or change colorscheme | sh | nitrogen/pywal |
| [x2sel](x2sel) | Copy file list from system clipboard to selection | sh | _see in-file docs_ |
| [xdgdefault](xdgdefault) | Set the default app for the hovered file type | sh | xdg-utils, fzf |
| [xdgdefault](xdgdefault) | Set the default app for the hovered file type | sh | xdg-utils, fzf/dmenu |
Note:
Notes:
1. A plugin has to explicitly request `nnn` to clear the selection e.g. after operating on the selected files.
2. Files starting with a dot in the `plugins` directory are internal files and should not be used as plugins.
### Table of contents
- [Installation](#installation)
- [Configuration](#configuration)
- [Skip directory refresh after running a plugin](#skip-directory-refresh-after-running-a-plugin--)
- [Running commands as plugin](#running-commands-as-plugin-)
- [Skip user confirmation after command execution](#skip-user-confirmation-after-command-execution-)
- [Run a GUI app as plugin](#run-a-gui-app-as-plugin-)
- [Page non-interactive command output](#page-non-interactive-command-output-)
- [Some useful key-command examples](#some-useful-key-command-examples)
- [Access level of plugins](#access-level-of-plugins)
- [Create your own plugins](#create-your-own-plugins)
- [Send data to `nnn`](#send-data-to-nnn)
- [Get notified on file hover](#get-notified-on-file-hover)
- [Examples](#examples)
- [Contributing plugins](#contributing-plugins)
## Installation
The following command installs or updates (after backup) all plugins:
```sh
curl -Ls https://raw.githubusercontent.com/jarun/nnn/master/plugins/getplugs | sh
sh -c "$(curl -Ls https://raw.githubusercontent.com/jarun/nnn/master/plugins/getplugs)"
```
Plugins are installed to `${XDG_CONFIG_HOME:-$HOME/.config}/nnn/plugins`.
@ -91,7 +105,7 @@ Plugins are installed to `${XDG_CONFIG_HOME:-$HOME/.config}/nnn/plugins`.
Set environment variable `NNN_PLUG` to assign keybinds and invoke plugins directly using the plugin shortcut (<kbd>;</kbd>) followed by the assigned key character. E.g., with the below config:
```sh
export NNN_PLUG='f:finder;o:fzopen;p:mocplay;d:diffs;t:nmount;v:imgview'
export NNN_PLUG='f:finder;o:fzopen;p:mocq;d:diffs;t:nmount;v:imgview'
```
plugin `finder` can be invoked with the keybind <kbd>;f</kbd>, `fzopen` can be run with <kbd>;o</kbd> and so on... The key vs. plugin pairs are shown in the help and config screen.
@ -107,79 +121,88 @@ If the plugins list gets too long, try breaking them up into sections:
```
NNN_PLUG_PERSONAL='g:personal/convert2zoom;p:personal/echo'
NNN_PLUG_WORK='j:work/prettyjson;d:work/foobar'
NNN_PLUG_INLINE='e:_go run $nnn*'
NNN_PLUG_DEFAULT='1:bookmarks;2:ipinfo;p:preview-tui;o:fzz;b:nbak'
NNN_PLUG_INLINE='e:!go run "$nnn"*'
NNN_PLUG_DEFAULT='1:ipinfo;p:preview-tui;o:fzz;b:nbak'
NNN_PLUG="$NNN_PLUG_PERSONAL;$NNN_PLUG_WORK;$NNN_PLUG_DEFAULT;$NNN_PLUG_INLINE"
export NNN_PLUG
```
Note:
- `'g:personal/convert2zoom'` will look in the personal sub-folder inside the plugin folder.
- `'b:boom;b:bookmarks` will result in only the first definition of *b* (`b:boom`) being used.
- `'b:boom;b:bulknew` will result in only the first definition of *b* (`b:boom`) being used.
- A keybinding definition of more than 1 character will prevent nnn from starting.
#### Skip directory refresh after running a plugin
#### Skip directory refresh after running a plugin [`-`]
`nnn` refreshes the directory after running a plugin to reflect any changes by the plugin. To disable this (say while running the `mediainf` plugin on some filtered files), add a `-` before the plugin name:
`nnn` refreshes the directory after running a plugin to reflect any changes by the plugin. To disable this add a `-` before the plugin name:
```sh
export NNN_PLUG='m:-mediainf'
export NNN_PLUG='p:-plugin'
```
Now `nnn` will not refresh the directory after running the `mediainf` plugin.
## Running commands as plugin [`!`]
## Running commands as plugin
To assign keys to arbitrary non-background, non-shell-interpreted cli commands and invoke like plugins, add `_` (underscore) before the command.
For example:
To assign keys to arbitrary non-background cli commands and invoke like plugins, add `!` before the command.
```sh
export NNN_PLUG='x:_chmod +x $nnn;g:_git log;s:_smplayer $nnn'
export NNN_PLUG='x:!chmod +x "$nnn";g:!git log;s:!smplayer "$nnn"'
```
Now <kbd>;x</kbd> can be used to make a file executable, <kbd>;g</kbd> can be used to the git log of a git project directory, <kbd>;s</kbd> can be used to preview a partially downloaded media file.
#### Skip user confirmation after command execution
#### Skip user confirmation after command execution [`*`]
`nnn` waits for user confirmation (the prompt `Press Enter to continue`) after it executes a command as plugin (unlike plugins which can add a `read` to wait). To skip this, add a `*` after the command. For example:
`nnn` waits for user confirmation (the prompt `Press Enter to continue`) after it executes a command as plugin (unlike plugins which can add a `read` to wait). To skip this, add a `*` after the command.
```sh
export NNN_PLUG='s:_smplayer $nnn*;n:-_vim /home/vaio/Dropbox/Public/synced_note*'
export NNN_PLUG='s:!smplayer "$nnn"*;n:-!vim /home/vaio/Dropbox/Public/synced_note*'
```
Now there will be no prompt after <kbd>;s</kbd> and <kbd>;n</kbd>.
Note: Do not use `*` with programs those run and exit e.g. cat.
Note: Do not use `*` with programs that run and exit e.g. cat.
#### Run GUI app as plugin
#### Run a GUI app as plugin [`&`]
To run a GUI app as plugin, add a `|` after `_`. For example:
To run a GUI app as plugin, add a `&` after `!`.
```sh
export NNN_PLUG='m:-_|mousepad $nnn'
export NNN_PLUG='m:-!&mousepad "$nnn"'
```
Notes:
#### Page non-interactive command output [`|`]
1. Use single quotes for `$NNN_PLUG` so `$nnn` is not interpreted
2. `$nnn` should be the last argument (IF used)
3. (_Again_) add `_` before the command
4. To disable directory refresh after running a _command as plugin_, prefix with `-_`
To show the output of run-and-exit commands which do not need user input, add `|` (pipe) after `!`.
```sh
export NNN_PLUG='m:-!|mediainfo "$nnn";t:-!|tree -ps;l:-!|ls -lah --group-directories-first'
```
This option is incompatible with `&` (terminal output is masked for GUI programs) and ignores `*` (output is already paged for user).
Notes:
1. Place `$nnn` (or exported variables) in double quotes (**`"$nnn"`**)
2. Use single quotes for `$NNN_PLUG` so `"$nnn"` is not interpreted
3. (_Again_) add `!` before the command
4. To disable directory refresh after running a _command as plugin_, prefix with `-!`
#### Some useful key-command examples
| Key:Command | Description |
|---|---|
| `g:-_git diff` | Show git diff |
| `k:-_fuser -kiv $nnn*` | Interactively kill process(es) using hovered file |
| `l:-_git log` | Show git log |
| `n:-_vi /home/user/Dropbox/dir/note*` | Take quick notes in a synced file/dir of notes |
| `p:-_less -iR $nnn*` | Page through hovered file in less |
| `s:-_\|smplayer -minigui $nnn` | Play hovered media file, even unfinished download |
| `x:_chmod +x $nnn` | Make the hovered file executable |
| `y:-_sync*` | Flush cached writes |
| `c:!convert "$nnn" png:- \| xclip -sel clipboard -t image/png*` | Copy image to clipboard |
| `C:!cp -rv "$nnn" "$nnn".cp` | Create a copy of the hovered file |
| `e:-!sudo -E vim "$nnn"*` | Edit file as root in vim |
| `g:-!git diff` | Show git diff |
| `h:-!hx "$nnn"*` | Open hovered file in [hx](https://github.com/krpors/hx) hex editor |
| `k:-!fuser -kiv "$nnn"*` | Interactively kill process(es) using hovered file |
| `l:-!git log` | Show git log |
| `n:-!vi /home/user/Dropbox/dir/note*` | Take quick notes in a synced file/dir of notes |
| `p:-!less -iR "$nnn"*` | Page through hovered file in less |
| `s:-!&smplayer -minigui "$nnn"` | Play hovered media file, even unfinished download |
| `x:!chmod +x "$nnn"` | Make the hovered file executable |
| `y:-!sync*` | Flush cached writes |
## Access level of plugins
@ -190,6 +213,9 @@ When `nnn` executes a plugin, it does the following:
2. `$2`: The working directory (might differ from `$PWD` in case of symlinked paths; non-canonical).
3. `$3`: The picker mode output file (`-` for stdout) if `nnn` is executed as a file picker.
- Sets the environment variable `NNN_PIPE` used to control `nnn` active directory.
- Sets the environment variable `NNN_INCLUDE_HIDDEN` to `1` if hidden files are active, `0` otherwise.
- Sets the environment variable `NNN_PREFER_SELECTION` to `1` if user prefers to use selection (see nnn's `-u` flag), `0` otherwise.
- Exports the [special variables](https://github.com/jarun/nnn/wiki/Concepts#special-variables).
Plugins can also read the `.selection` file in the config directory.
@ -197,7 +223,7 @@ Plugins can also read the `.selection` file in the config directory.
Plugins can be written in any scripting language. However, POSIX-compliant shell scripts runnable in `sh` are preferred.
Make the file executable and drop it in the plugin install directory. Optionally add a hotkey in `$NNN_PLUG` for frequent usage.
**Make the file executable**. Drop it in the plugin directory. Optionally add a hotkey in `$NNN_PLUG` for frequent usage.
#### Send data to `nnn`
`nnn` provides a mechanism for plugins to send data to `nnn` to control its active directory or invoke the list mode.
@ -207,6 +233,7 @@ The plugin should write a single string in the format `(<->)<ctxcode><opcode><da
The optional `-` at the **beginning of the stream** instructs `nnn` to clear the selection.
In cases where the data transfer to `nnn` has to happen while the selection file is being read (e.g. in a loop), the plugin should
create a tmp copy of the selection file, inform `nnn` to clear the selection and then do the subsequent processing with the tmp file.
A paged [`|`] or GUI [`&`] cmd run as plugin cannot clear selection.
The `ctxcode` indicates the context to change the active directory of.
@ -228,8 +255,6 @@ For convenience, we provided a helper script named `.nnn-plugin-helper` and a fu
If a context is not provided, it is asked for explicitly. To skip this and choose the current context, set the `CUR_CTX` variable in `.nnn-plugin-helper` (or in the specific plugin after sourcing `.nnn-plugin-helper`) to 1.
Usage examples can be found in the Examples section below.
If a plugin doesn't send any data back to `nnn` and there's a selection, the selection is cleared.
#### 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 and external scripts, e.g. to implement file previews.
@ -238,87 +263,121 @@ Don't forget to fork in the background to avoid blocking `nnn`.
For more details on configuration and usage of the preview plugins, visit [Live Previews](https://github.com/jarun/nnn/wiki/Live-previews).
#### Examples
## 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.
```sh
#!/usr/bin/env sh
git log -p -- "$1"
```
#### Show the git log of changes to the particular file along with the code for a quick and easy review.
- Change to directory in clipboard using helper script
```sh
#!/usr/bin/env sh
. $(dirname $0)/.nnn-plugin-helper
```sh
#!/usr/bin/env sh
nnn_cd "$(xsel -ob)"
```
git log -p -- "$1"
```
- Change directory to the location of a link using helper script with specific context (current)
```sh
#!/usr/bin/env sh
. $(dirname $0)/.nnn-plugin-helper
#### Change to directory in clipboard using helper script
nnn_cd "$(dirname $(readlink -fn $1))" 0
```
```sh
#!/usr/bin/env sh
- Change to arbitrary directory without helper script
```sh
#!/usr/bin/env sh
printf "cd to: "
read -r dir
. $(dirname $0)/.nnn-plugin-helper
printf "%s" "0c$dir" > "$NNN_PIPE"
```
nnn_cd "$(xsel -ob)"
```
- Send every hovered file to X selection
```sh
#!/usr/bin/env sh
if [ -z "$NNN_FIFO" ] ; then
exit 1
fi
#### Change directory to the location of a link using helper script with specific context (current)
while read FILE ; do
printf "%s" "$FILE" | xsel
done < "$NNN_FIFO" &
disown
```
```sh
#!/usr/bin/env sh
- Quick find (using `fd`)
```sh
#!/usr/bin/env sh
. $(dirname $0)/.nnn-plugin-helper
. "$(dirname "$0")"/.nnn-plugin-helper
nnn_cd "$(dirname $(readlink -fn $1))" 0
```
printf "pattern: "
read -r pattern
#### Change to arbitrary directory without helper script
if [ -n "$pattern" ]; then
printf "%s" "+l" > "$NNN_PIPE"
eval "fd -HI $pattern -0" > "$NNN_PIPE"
fi
```
```sh
#!/usr/bin/env sh
- Quick grep (using `rg`)
```sh
#!/usr/bin/env sh
printf "cd to: "
read -r dir
. "$(dirname "$0")"/.nnn-plugin-helper
printf "%s" "0c$dir" > "$NNN_PIPE"
```
printf "pattern: "
read -r pattern
#### Send every hovered file to X selection
if [ -n "$pattern" ]; then
printf "%s" "+l" > "$NNN_PIPE"
eval "rg -l0 --hidden -S $pattern" > "$NNN_PIPE"
fi
```
```sh
#!/usr/bin/env sh
if [ -z "$NNN_FIFO" ] ; then
exit 1
fi
while read FILE ; do
printf "%s" "$FILE" | xsel
done < "$NNN_FIFO" &
disown
```
#### Quick `find` the first match in subtree and open in `nuke`
```sh
#!/usr/bin/env sh
NUKE="${XDG_CONFIG_HOME:-$HOME/.config}/nnn/plugins/nuke"
printf "file name: "
read -r pattern
entry=$(find . -type f -iname "$pattern" -print -quit 2>/dev/null)
if [ -n "$entry" ]; then
"$NUKE" "$entry"
fi
```
#### Quick find (using `fd`)
```sh
#!/usr/bin/env sh
. "$(dirname "$0")"/.nnn-plugin-helper
printf "pattern: "
read -r pattern
if [ -n "$pattern" ]; then
printf "%s" "+l" > "$NNN_PIPE"
eval "fd -HI $pattern -0" > "$NNN_PIPE"
fi
```
#### Quick grep (using `rg`)
```sh
#!/usr/bin/env sh
. "$(dirname "$0")"/.nnn-plugin-helper
printf "pattern: "
read -r pattern
if [ -n "$pattern" ]; then
printf "%s" "+l" > "$NNN_PIPE"
eval "rg -l0 --hidden -S $pattern" > "$NNN_PIPE"
fi
```
#### Change directory
NNN_PLUG='c:!read -r to && [ -n "$to" ] && printf "0c%s" "${to}" > "$NNN_PIPE"*'
## Contributing plugins
1. Add informative sections like _Description_, _Notes_, _Dependencies_, _Shell_, _Author_ etc. in the plugin.
2. Add an entry in the table above.
2. Add an entry in the table above. Note that the list is alphabetically ordered by plugin name.
3. Keep non-portable commands (like `notify-send`) commented so users from any other OS/DE aren't surprised.
4. The plugin file should be executable.
5. If your plugin stores data, use `${XDG_CACHE_HOME:-$HOME/.cache}/nnn`. Document it _in-file_.

View File

@ -1,16 +1,21 @@
#!/usr/bin/env sh
# Description: Navigate to directory using jump/autojump/zoxide
# Description: Navigate to directory using jump/autojump/zoxide/z
#
# Dependencies:
# - jump - https://github.com/gsamokovarov/jump
# - OR autojump - https://github.com/wting/autojump
# - OR zoxide - https://github.com/ajeetdsouza/zoxide
# - OR z - https://github.com/rupa/z (z requires fzf)
# - OR z (fish) - https://github.com/jethrokuan/z (z requires fzf)
# - OR z.lua - https://github.com/skywind3000/z.lua (z.lua can enhanced with fzf)
#
# Note: The dependencies STORE NAVIGATION PATTERNS
#
# to make z.lua work, you need to set $NNN_ZLUA to the path of script z.lua
#
# Shell: POSIX compliant
# Authors: Marty Buchaus, Dave Snider, Tim Adler
# Authors: Marty Buchaus, Dave Snider, Tim Adler, Nick Waywood
if [ ! -p "$NNN_PIPE" ]; then
printf 'ERROR: NNN_PIPE is not set!'
@ -20,8 +25,9 @@ fi
if type jump >/dev/null 2>&1; then
printf "jump to : "
read -r dir
odir="$(jump cd "$dir")"
IFS= read -r line
# shellcheck disable=SC2086
odir="$(jump cd ${line})"
printf "%s" "0c$odir" > "$NNN_PIPE"
elif type autojump >/dev/null 2>&1; then
printf "jump to : "
@ -38,7 +44,31 @@ elif type zoxide >/dev/null 2>&1; then
odir="$(zoxide query -- "$dir")"
printf "%s" "0c$odir" > "$NNN_PIPE"
fi
elif type lua >/dev/null 2>&1 && [ -n "$NNN_ZLUA" ]; then
printf "jump to : "
read -r line
if type fzf >/dev/null 2>&1; then
odir="$(lua "$NNN_ZLUA" -l "$line" | fzf --nth 2.. --reverse --inline-info --tac +s -e --height 35%)"
printf "%s" "0c$(echo "$odir" | awk '{print $2}')" > "$NNN_PIPE"
else
odir="$(lua "$NNN_ZLUA" -e "$line")"
printf "%s" "0c$odir" > "$NNN_PIPE"
fi
else
printf "No supported autojump script found. (jump/autojump/zoxide are supported)"
read -r _
# rupa/z uses $_Z_DATA, jethrokuan/z (=port of z for fish) uses $Z_DATA
datafile="${_Z_DATA:-${Z_DATA:-$HOME/.z}}"
if type fzf >/dev/null 2>&1 && [ -f "$datafile" ]; then
# Read the data from z's file instead of calling
# z so the data doesn't need to be processed twice
sel=$(awk -F "|" '{print $1}' "$datafile" | fzf | awk '{$1=$1};1')
# NOTE: Uncomment this line and comment out the line above if
# you want to see the weightings of the dir's in the fzf pane
# sel=$(awk -F "|" '{printf "%s %s\n", $2, $1}' "$datafile" | fzf | sed 's/^[0-9,.]* *//' | awk '{$1=$1};1')
printf "%s" "0c$sel" > "$NNN_PIPE"
else
printf "No supported autojump script [jump/autojump/zoxide/z (needs fzf)] found"
read -r _
fi
fi

View File

@ -1,60 +0,0 @@
#!/usr/bin/env sh
# Description: Use named bookmarks using symlinks
#
# Dependencies: fzf
#
# Usage:
# 1. Create a $BOOKMARKS_DIR directory
# By default, $BOOKMARKS_DIR is set to: ${XDG_CACHE_HOME:-$HOME/.cache}/nnn/bookmarks
# 2. Create symlinks to directories
# `cd $BOOKMARKS_DIR`
# `ln -s /path/to/useful/directory bookmark_name`
# `ln -s $XDG_CONFIG_HOME/nnn/plugins nnn_plugins"
# `ln -s /path/to/documents docs`
# `ln -s /path/to/media media`
# `ln -s /path/to/movies movies`
#
# Bonus tip: Add `$BOOKMARKS_DIR` to your `$CDPATH`
# https://linux.101hacks.com/cd-command/cdpath/
#
# TODO:
# - Remove `fzf` dependency
#
# Shell: POSIX compliant
# Author: Todd Yamakawa
if [ -z "$BOOKMARKS_DIR" ]; then
BOOKMARKS_DIR="${XDG_CACHE_HOME:-$HOME/.cache}/nnn/bookmarks"
fi
# Check if NNN_PIPE is set
if [ -z "$NNN_PIPE" ]; then
printf 'ERROR: NNN_PIPE is not set!'
read -r _
exit 2
fi
# Get all directory symlinks
get_links() {
for entry in "$1"/*; do
# Skip unless directory symlink
[ -h "$entry" ] || continue
[ -d "$entry" ] || continue
printf "%20s -> %s\n" "$(basename "$entry")" "$(readlink -f "$entry")"
done | fzf |
awk 'END {
if (length($1) == 0) { print "'"$PWD"'" }
else { print "'"$BOOKMARKS_DIR"'/"$1 }
}'
}
# Choose symlink with fzf
cddir="$(get_links "$BOOKMARKS_DIR")"
# Writing result to NNN_PIPE will change nnn's active directory
# https://github.com/jarun/nnn/tree/master/plugins#send-data-to-nnn
context=0
printf "%s" "${context}c$(readlink -f "$cddir")" > "$NNN_PIPE"

View File

@ -9,7 +9,7 @@
# Shell: POSIX compliant
# Author: Arun Prakash Jana
GUIPLAYER="${GUIPLAYER}"
GUIPLAYER="${GUIPLAYER:-""}"
NUMTRACKS="${NUMTRACKS:-100}"
if [ -n "$GUIPLAYER" ]; then

View File

@ -29,4 +29,4 @@ $EDITOR "$tmpfile"
sed "/^\//d" "$tmpfile" | xargs -n1 -I{} sh -c "$cmd"
rm "$tmpfile"
rm -- "$tmpfile"

16
plugins/cbcopy-mac Executable file
View File

@ -0,0 +1,16 @@
#!/usr/bin/osascript
# Description: Copy the hovered file to MacOS clipboard.
#
# Note: Supports only MacOS
#
# Shell: POSIX compliant
# Author: Syed Umar Anis
on run args
set filePath to (second item of args & "/" & first item of args)
tell application "Finder"
set the clipboard to (filePath as POSIX file)
end tell
end

24
plugins/cbpaste-mac Executable file
View File

@ -0,0 +1,24 @@
#!/usr/bin/env sh
# shellcheck disable=all
# Description: Paste the clipboard files into the current directory.
# Only works if clipboard contents are files.
#
# Note: Supports only MacOS
#
# Shell: POSIX compliant
# Author: Syed Umar Anis
fs=($( osascript -e "use framework \"Foundation\"
property this : a reference to the current application
property NSPasteboard : a reference to NSPasteboard of this
property NSURL : a reference to NSURL of this
property pb : a reference to NSPasteboard's generalPasteboard
property text item delimiters : linefeed
pb's readObjectsForClasses:[NSURL] options:[]
(result's valueForKey:\"path\") as list as text" ))
cp -R -- "${fs[@]}" "$2/"

View File

@ -2,7 +2,7 @@
# Description: 'cd' to the directory from CDPATH
#
# Details: If the CDPATH environmet variable is not set, the default value of
# Details: If the CDPATH environment variable is not set, the default value of
# ${XDG_CONFIG_HOME:-$HOME/.config}/nnn/bookmarks will be used.
# You can create this directory and fill it with symbolic links to your
# favorite directories. It's a good idea to add it to CDPATH so that it
@ -16,6 +16,7 @@
# Shell: POSIX compliant
# Author: Yuri Kloubakov
# shellcheck disable=SC1090,SC1091
. "$(dirname "$0")"/.nnn-plugin-helper
# Get a list of (symbolic links to) directories for every element of CDPATH

View File

@ -2,6 +2,9 @@
# Description: Create and verify checksums
#
# Note: On macOS, install the relevant checksum packages from Homebrew with:
# brew install coreutils
#
# Details:
# - selection: it will generate one file with the checksums and filenames
# (and with paths if they are in another directory)
@ -58,7 +61,7 @@ elif [ -n "$1" ]; then
if echo "$1" | grep -q \.${chks}$; then
${chks}sum -c < "$1"
read -r _
return
exit
fi
done
checksum_type

View File

@ -25,7 +25,7 @@ dirdiff() {
ls -A1 "$1" > "$dir1"
ls -A1 "$2" > "$dir2"
$diffcmd "$dir1" "$dir2"
rm "$dir1" "$dir2"
rm -- "$dir1" "$dir2"
}
if [ -s "$selection" ]; then

View File

@ -19,6 +19,8 @@ resp=f
all=
if type dragon-drag-and-drop >/dev/null 2>&1; then
dnd="dragon-drag-and-drop"
elif type dragon-drop >/dev/null 2>&1; then
dnd="dragon-drop"
else
dnd="dragon"
fi

View File

@ -28,17 +28,17 @@ printf "\
" > "$tmpfile"
# shellcheck disable=SC2016
find . -size +0 -type f -printf "%${size_digits}s %p\n" | sort -rn | uniq -w"${size_digits}" -D | sed -E '
s/^ {,12}([0-9]{,12}) (.*)$/printf "%s %s\\n" "$(md5sum "\2")" "d\1"/
' | tr '\n' '\0' | xargs -0 -n1 sh -c | sort | { uniq -w32 --all-repeated=separate; echo; } | sed -nE '
find . -size +0 -type f -printf "%${size_digits}s %p\n" | sort -rn | uniq -w"${size_digits}" -D | sed -e '
s/^ \{0,12\}\([0-9]\{0,12\}\) \(.*\)$/printf "%s %s\\n" "$(md5sum "\2")" "d\1"/
' | tr '\n' '\0' | xargs -0 -n1 sh -c | sort | { uniq -w32 --all-repeated=separate; echo; } | sed -ne '
h
s/^(.{32}).* d([0-9]*)$/## md5sum: \1 size: \2 bytes/p
s/^\(.\{32\}\).* d\([0-9]*\)$/## md5sum: \1 size: \2 bytes/p
g
:loop
N
/.*\n$/!b loop
p' | sed -E 's/^.{32} (.*) d[0-9]*$/\1/' >> "$tmpfile"
p' | sed -e 's/^.\{32\} \(.*\) d[0-9]*$/\1/' >> "$tmpfile"
"$EDITOR" "$tmpfile"
@ -46,7 +46,7 @@ printf "Remove commented files? (yes/no) [default=n]: "
read -r commented
if [ "$commented" = "y" ]; then
sedcmd="/^(##|[^#]).*/d; /^$/d; s/^# *(.*)$/\1/"
sedcmd="/^##.*/d; /^[^#].*/d; /^$/d; s/^# *\(.*\)$/\1/"
else
printf "Press any key to exit"
read -r _
@ -58,13 +58,13 @@ read -r force
if [ "$force" = "f" ]; then
#shellcheck disable=SC2016
sed -E "$sedcmd" "$tmpfile" | tr '\n' '\0' | xargs -0 -r sh -c 'rm -f "$0" "$@" </dev/tty'
sed -e "$sedcmd" "$tmpfile" | tr '\n' '\0' | xargs -0 -r sh -c 'rm -f -- "$0" "$@" </dev/tty'
else
#shellcheck disable=SC2016
sed -E "$sedcmd" "$tmpfile" | tr '\n' '\0' | xargs -0 -r sh -c 'rm -i "$0" "$@" </dev/tty'
sed -e "$sedcmd" "$tmpfile" | tr '\n' '\0' | xargs -0 -r sh -c 'rm -i -- "$0" "$@" </dev/tty'
fi
rm "$tmpfile"
rm -- "$tmpfile"
printf "Press any key to exit"
read -r _

View File

@ -1,28 +1,89 @@
#!/usr/bin/env sh
#!/usr/bin/env bash
# Description: Run custom search and list results in smart context
#
# Note: To enable multi select in fzf, export the following:
# - export FZF_DEFAULT_OPTS='--bind ctrl-a:select-all,ctrl-d:deselect-all,ctrl-t:toggle'
# Note: This plugin retains search history
#
# Shell: POSIX compliant
# Author: Arun Prakash Jana
# Usage:
# Run plugin and enter e.g. "-size +10M" to list files in current
# directory larger than 10M. By default entered expressions are
# interpreted as arguments to find. Results have to be NUL
# terminated which is done by default for find. Alternatively one
# can prepend a '$' to run a custom search program such as fd or
# ripgrep. Entered expressions will be saved in history file to
# be listed as bookmarks and and can be entered by index and edited.
#
# Shell: Bash
# Author: Arun Prakash Jana, Luuk van Baal
TMPDIR="${TMPDIR:-/tmp}"
NNN_FINDHIST="${NNN_FINDHIST:-${XDG_CONFIG_HOME:-$HOME/.config}/nnn/finderbms}"
NNN_FINDHISTLEN="${NNN_FINDHISTLEN:-10000}"
. "$(dirname "$0")"/.nnn-plugin-helper
printexamples() {
printf -- "-maxdepth 1 -name pattern
-maxdepth 1 -size +100M
\$fd -0 pattern
\$fd -0 -d 2 -S +100M
\$grep -rlZ pattern
\$rg -l0 pattern
\$fzf -m | tr '\\\n' '\\\0'\n"
}
printf "Examples:\n"
printf " find . -name \"pattern*\" -print0\n"
printf " fd pattern -0\n"
printf " find -maxdepth 1 -size +100M -print0\n"
printf " fd -d 2 -S +100M -0\n"
printf " grep -rlZ pattern\n"
printf " rg -l0 pattern\n"
printf " fzf -m | tr %s %s\n\n" "'\n'" "'\0'"
printexprs() {
for ((i = "$1"; i < ${#fexprs[@]}; i++)); do
printf '%s\t%s\n' "$((i + 1))" "${fexprs[$i]}"
done
}
printf "cmd: "
read -r cmd
mapexpr() {
if [ "$fexpr" -eq "$fexpr" ] 2>/dev/null; then
fexpr=${fexprs[$((fexpr - 1))]}
read -r -e -p "Search expression: " -i "$fexpr" fexpr
else
return 1
fi
}
if [ -n "$cmd" ]; then
printf "%s" "+l" > "$NNN_PIPE"
eval "$cmd" > "$NNN_PIPE"
readexpr() {
case "$fexpr" in
h) clear
printf "Examples:\n"
mapfile -t fexprs < <(printexamples)
printexprs 0
read -r -p "Search expression or index: " fexpr
mapexpr
[ -n "$fexpr" ] && readexpr ;;
\$*) cmd="${fexpr:1}" ;;
*) mapexpr && readexpr
cmd="find . $fexpr -print0" ;;
esac
}
clear
[ -f "$NNN_FINDHIST" ] || printexamples > "$NNN_FINDHIST"
mapfile -t fexprs < <(sort "$NNN_FINDHIST" | uniq -c | sort -nr | head -n5 |\
awk '{for (i=2; i<NF; i++) printf $i " "; print $NF}')
printf "Most used search expressions:\n"
printexprs 0
mapfile -t -O"$i" fexprs < <(tac "$NNN_FINDHIST" | awk '!a[$0]++' | head -n5)
printf "Most recently used search expressions:\n"
printexprs "$i"
read -r -p "Search expression or index (h for help): " fexpr
mapexpr
if [ -n "$fexpr" ]; then
printf "+l" > "$NNN_PIPE"
while :; do
readexpr
eval "$cmd" > "$NNN_PIPE" && break
read -r -e -p "Search expression: " -i "$fexpr" fexpr
done
if [ -n "$fexpr" ]; then
tail -n"$NNN_FINDHISTLEN" "$NNN_FINDHIST" > "$TMPDIR/finderbms"
printf "%s\n" "$fexpr" >> "$TMPDIR/finderbms"
mv -- "$TMPDIR/finderbms" "$NNN_FINDHIST"
fi
fi

View File

@ -65,7 +65,7 @@ for i in "${targets[@]}"; do
if [ -e "$(cleanup "$i")" ]; then
tmp='_'
fi
mv "$i" "$tmp$(cleanup "$i")";
mv -- "$i" "$tmp$(cleanup "$i")";
fi
done

View File

@ -2,7 +2,7 @@
# Description: Fuzzy search multiple locations read-in from a path-list file
# (or $PWD) and open the selected file's dir in a smart context.
# Dependencies: fzf, fd (only for multi-location search)
# Dependencies: fzf, find (only for multi-location search)
#
# Details: Paths in list file should be newline-separated absolute paths.
# Paths can be file paths; the script will scan the parent dirs.
@ -17,33 +17,26 @@
# - pick the (file)paths in picker mode to path-list file
# - OR, edit selection in nnn and save as path-list file
#
# The plugin clears nnn selection as the user can be tempted to delete
# duplicate files after finding copies and remove selection by mistake.
#
# Shell: POSIX compliant
# Author: Anna Arad, Arun Prakash Jana
# Author: Anna Arad, Arun Prakash Jana, KlzXS
IFS="$(printf '\n\r')"
# shellcheck disable=SC1090,SC1091
. "$(dirname "$0")"/.nnn-plugin-helper
CTX=+
LIST="$LIST"
LIST="${LIST:-""}"
if ! type fzf >/dev/null 2>&1; then
printf "fzf missing"
read -r _
exit 1
exit 1
fi
if [ -n "$1" ] && [ "$(file -b --mime-type "$1")" = 'text/plain' ] && [ -e "$(head -1 "$1")" ]; then
LIST="$1"
elif ! [ -s "$LIST" ]; then
# Clear selection
if [ -p "$NNN_PIPE" ]; then
printf "-" >"$NNN_PIPE"
fi
sel=$(fzf)
# Show only the file and parent dir
# sel=$(fzf --delimiter / --with-nth=-2,-1 --tiebreak=begin --info=hidden)
@ -52,7 +45,7 @@ elif ! [ -s "$LIST" ]; then
fi
if [ -n "$LIST" ]; then
if type fd >/dev/null 2>&1; then
if type find >/dev/null 2>&1; then
tmpfile=$(mktemp /tmp/abc-script.XXXXXX)
while IFS= read -r path; do
@ -63,18 +56,15 @@ if [ -n "$LIST" ]; then
fi
done < "$LIST"
# Clear selection
if [ -p "$NNN_PIPE" ]; then
printf "-" >"$NNN_PIPE"
fi
sel=$(xargs -d '\n' < "$tmpfile" -I{} find {} -type f -printf "%H//%P\n" | sed '/.*\/\/\(\..*\|.*\/\..*\)/d; s:/\+:/:g' | fzf --delimiter / --tiebreak=begin --info=hidden)
# Alternative for 'fd'
# sel=$(xargs -d '\n' < "$tmpfile" fd . | fzf --delimiter / --tiebreak=begin --info=hidden)
sel=$(xargs -d '\n' -a "$tmpfile" fd -H . | fzf --delimiter / --tiebreak=begin --info=hidden)
rm "$tmpfile"
rm -- "$tmpfile"
else
printf "fd missing"
printf "find missing"
read -r _
exit 1
exit 1
fi
fi

View File

@ -3,7 +3,9 @@
# Description: Fuzzy find a command from history,
# edit in $EDITOR and run as a command
#
# Note: Supports only bash and fish history
# Note: Supports only bash, zsh and fish history
#
# TODO: For zsh there's also $ZDOTDIR which might need to be checked as well for the -z $HISTFILE && -n $ZDOTDIR case.
#
# Shell: POSIX compliant
# Author: Arun Prakash Jana
@ -17,10 +19,21 @@ fi
shellname="$(basename "$SHELL")"
if [ "$shellname" = "bash" ]; then
hist_file="$HOME/.bash_history"
if [ -f "$HISTFILE" ]; then
hist_file="$HISTFILE"
else
hist_file="$HOME/.bash_history"
fi
entry="$("$fuzzy" < "$hist_file")"
elif [ "$shellname" = "zsh" ]; then
if [ -f "$HISTFILE" ]; then
hist_file="$HISTFILE"
else
hist_file="$HOME/.zsh_history"
fi
entry="$("$fuzzy" < "$hist_file")"
elif [ "$shellname" = "fish" ]; then
hist_file="$HOME/.config/fish/fish_history"
hist_file="$HOME/.local/share/fish/fish_history"
entry="$(grep "\- cmd: " "$hist_file" | cut -c 8- | "$fuzzy")"
fi
@ -33,7 +46,7 @@ if [ -n "$entry" ]; then
$SHELL -c "$(cat "$tmpfile")"
fi
rm "$tmpfile"
rm -- "$tmpfile"
printf "Press any key to exit"
read -r _

View File

@ -12,11 +12,15 @@
# Leaves untouched if no file is picked.
# Works with single/multiple files selected.
#
# Dependencies: fd/find, fzf/skim, xdg-open
# Dependencies: fd/find, fzf/skim, xdg-open/open (on macOS)
#
# Shell: POSIX compliant
# Author: Arun Prakash Jana
NUKE="${XDG_CONFIG_HOME:-$HOME/.config}/nnn/plugins/nuke"
USE_NUKE=0
# shellcheck disable=SC1090,SC1091
. "$(dirname "$0")"/.nnn-plugin-helper
if type fzf >/dev/null 2>&1; then
@ -26,7 +30,7 @@ if type fzf >/dev/null 2>&1; then
else
[ -z "$cmd" ] && cmd="find . -type f 2>/dev/null"
fi
entry="$(eval "$cmd" | fzf -m --delimiter / --nth=-1 --tiebreak=begin --info=hidden)"
entry="$(eval "$cmd" | fzf -m)"
# To show only the file name
# entry=$(find . -type f 2>/dev/null | fzf --delimiter / --with-nth=-1 --tiebreak=begin --info=hidden)
elif type sk >/dev/null 2>&1; then
@ -38,10 +42,14 @@ fi
# Check for picker mode
if [ "$3" ]; then
if [ "$entry" ]; then
case "$entry" in
/*) fullpath="$entry" ;;
*) fullpath="$PWD/$entry" ;;
esac
if [ "-" = "$3" ]; then
printf "%s\n" "$entry"
printf "%s\n" "$fullpath"
else
printf "%s\n" "$entry" > "$3"
printf "%s\n" "$fullpath" > "$3"
fi
# Tell `nnn` to clear its internal selection
@ -51,15 +59,27 @@ if [ "$3" ]; then
exit 0
fi
# Open the file (works for a single file only)
case "$(file -biL "$entry")" in
*text*)
"${VISUAL:-$EDITOR}" "$entry" ;;
*)
if uname | grep -q "Darwin"; then
open "$entry" >/dev/null 2>&1
else
xdg-open "$entry" >/dev/null 2>&1
fi
;;
esac
if [ "$entry" ]; then
if [ "$USE_NUKE" -ne 0 ]; then
"$NUKE" "$entry"
exit 0
fi
# Open the file (works for a single file only)
cmd_file=""
cmd_open=""
if uname | grep -q "Darwin"; then
cmd_file="file -bIL"
cmd_open="open"
else
cmd_file="file -biL"
cmd_open="xdg-open"
fi
case "$($cmd_file "$entry")" in
*text*)
"${VISUAL:-$EDITOR}" "$entry" ;;
*)
$cmd_open "$entry" >/dev/null 2>&1 ;;
esac
fi

View File

@ -1,26 +0,0 @@
#!/usr/bin/env sh
# Description: cd to any dir in the z database using an fzf pane
#
# Shell: POSIX compliant
# Author: Nick Waywood
. "$(dirname "$0")"/.nnn-plugin-helper
if type fzf >/dev/null 2>&1; then
fuzzy=fzf
else
exit 1
fi
datafile="${_Z_DATA:-$HOME/.z}"
if [ -f "$datafile" ]; then
# I read the data from z's file instead of calling the z command so that the data doesn't need to be processed twice
sel=$(awk -F "|" '{print $1}' "$datafile" | "$fuzzy" | awk '{$1=$1};1')
# NOTE: Uncomment this line and comment out the line above if you want to see the weightings of the dir's in the fzf pane
# sel=$(awk -F "|" '{printf "%s %s\n", $2, $1}' "$datafile" | "$fuzzy" | sed 's/^[0-9,.]* *//' | awk '{$1=$1};1')
else
exit 1
fi
printf "%s" "0c$sel" > "$NNN_PIPE"

View File

@ -24,7 +24,7 @@ prompt () {
if [ "$operation" = "m" ]; then
op="merge"
elif [ "$operation" = "o" ]; then
op="cp -vRf"
op="cp -vRf --"
else
op="true"
fi
@ -62,7 +62,7 @@ for f in $(find . -maxdepth 1 \( ! -iname "." ! -iname "*.md" \)); do
$op "$f" ../../plugins/
fi
else
cp -vRf "$f" ../../plugins/
cp -vRf -- "$f" ../../plugins/
fi
done
cd ../.. || exit 1

15
plugins/gitroot Executable file
View File

@ -0,0 +1,15 @@
#!/usr/bin/env sh
# Description: cd to the top level of the current git repository in the current context
# Dependencies: git
# Shell: sh
# Author: https://github.com/PatrickF1
root="$(git rev-parse --show-toplevel 2>/dev/null)"
if [ -n "$root" ]; then
printf "%s" "0c$root" > "$NNN_PIPE"
else
printf "Not in a git repository"
read -r _
exit 1
fi

View File

@ -10,7 +10,8 @@
# Shell: POSIX compliant
# Author: KlzXS
selection=${NNN_SEL:-${XDG_CONFIG_HOME:-$HOME/.config}/nnn/.selection}
# shellcheck disable=SC1090,SC1091
. "$(dirname "$0")"/.nnn-plugin-helper
printf "(s)ymmetric, (a)symmetric? [default=a] "
read -r symmetry
@ -18,12 +19,12 @@ read -r symmetry
if [ "$symmetry" = "s" ]; then
gpg --symmetric "$1"
else
printf "(s)election/(c)urrent? [default=c] "
read -r resp
if [ "$resp" = "s" ]; then
if nnn_use_selection; then
clear_sel=1
# shellcheck disable=SC2154
files=$(tr '\0' '\n' < "$selection")
else
clear_sel=0
files=$1
fi
@ -37,8 +38,8 @@ else
printf "%s" "$files" | xargs -n1 gpg --encrypt --recipient "$recipient"
# Clear selection
if [ "$resp" = "s" ] && [ -p "$NNN_PIPE" ]; then
printf "-" > "$NNN_PIPE"
fi
# Clear selection
if [ "$clear_sel" -eq 1 ] && [ -p "$NNN_PIPE" ]; then
printf "-" > "$NNN_PIPE"
fi
fi

21
plugins/gsconnect Executable file
View File

@ -0,0 +1,21 @@
#!/usr/bin/env sh
#set -x
# Description: Send the selected (or hovered) files to your Android device using gsconnect daemon.js.
# GSConnect must be configured on the Android device and the PC.
#
# Shell: POSIX compliant
# Author: Darukutsu
selection=${NNN_SEL:-${XDG_CONFIG_HOME:-$HOME/.config}/nnn/.selection}
gsconnect=$HOME/.local/share/gnome-shell/extensions/gsconnect@andyholmes.github.io/service/daemon.js
ids=$($gsconnect -l)
for id in $ids; do
if [ -s "$selection" ]; then
xargs -0 < "$selection" -I{} "$gsconnect" -d "$id" --share-file="{}"
# Clear selection
printf "-" > "$NNN_PIPE"
else
"$gsconnect" -d "$id" --share-file="$2/$1"
fi
done

View File

@ -18,11 +18,11 @@
# Shell: POSIX compliant
# Author: Arun Prakash Jana
EBOOK_ID="${EBOOK_ID}"
EBOOK_ID="${EBOOK_ID:-""}"
DIR="${XDG_CACHE_HOME:-$HOME/.cache}/nnn/gutenbooks/$EBOOK_ID"
BROWSE_LINK="https://www.gutenberg.org/ebooks/search/?sort_order=downloads"
BROWSER="${BROWSER:-w3m}"
READER="${READER}"
READER="${READER:-""}"
if [ -n "$EBOOK_ID" ]; then
if [ ! -e "$DIR" ]; then

View File

@ -1,16 +0,0 @@
#!/usr/bin/env sh
# Description: View a file in hex
#
# Dependencies: hx (https://github.com/krpors/hx)/xxd and $PAGER
#
# Shell: POSIX compliant
# Author: Arun Prakash Jana
if [ -n "$1" ]; then
if type hx >/dev/null 2>&1; then
hx "$1"
else
xxd "$1" | $PAGER
fi
fi

View File

@ -28,7 +28,7 @@
##########################################################################
# https://github.com/jomo/imgur-screenshot
# https://imgur.com/tools
# https://help.imgur.com/hc/en-us/articles/209592766-Tools-for-Imgur
#
# Slightly modified for `nnn` integration
#
@ -112,6 +112,7 @@ check_update="true"
settings_path="${HOME}/.config/imgur-screenshot/settings.conf"
if [ -f "${settings_path}" ]; then
# shellcheck disable=SC1090
source "${settings_path}"
fi
@ -204,6 +205,7 @@ function load_access_token() {
token_expire_time=0
# check for saved access_token and its expiration date
if [ -f "${credentials_file}" ]; then
# shellcheck disable=SC1090
source "${credentials_file}"
fi
current_time="$(date +%s)"
@ -581,7 +583,7 @@ for upload_file in "${upload_files[@]}"; do
# delete file if configured
if [ "${keep_file}" = "false" ] && [ -z "${1}" ]; then
echo "Deleting temp file ${file_dir}/${img_file}"
rm -rf "${img_file}"
rm -rf -- "${img_file}"
fi
echo ""

View File

@ -1,12 +1,12 @@
#!/usr/bin/env sh
# Description: Open hovered or current directory in image viewer.
# Supported image viewers open in thumbnail mode when
# the hovered entry is a directory.
# Generates media thumbnails with optional dependencies.
#
# Dependencies:
# - imv (https://github.com/eXeC64/imv) or,
# - sxiv (https://github.com/muennich/sxiv) or,
# - nsxiv (https://codeberg.org/nsxiv/nsxiv) or,
# - ucollage (https://github.com/ckardaris/ucollage) or,
# - lsix (https://github.com/hackerb9/lsix), or
# - viu (https://github.com/atanunq/viu), or
@ -16,8 +16,10 @@
#
# Shell: POSIX compliant
# Author: Arun Prakash Jana, Luuk van Baal
target="$(readlink -f "$1")"
#
# Consider setting NNN_PREVIEWDIR to $XDG_CACHE_HOME/nnn/previews
# if you want to keep media thumbnails on disk between reboots.
NNN_PREVIEWDIR="${NNN_PREVIEWDIR:-${TMPDIR:-/tmp}/nnn/previews}"
exit_prompt() {
[ -n "$1" ] && printf "%s\n" "$1"
@ -27,91 +29,85 @@ exit_prompt() {
exit
}
nthumb_cleanup() {
[ -n "$!" ] && while [ -e /proc/"$!" ]; do sleep 1; done
if [ -f "$target" ]; then
rm -r "$(dirname "$target")"/.nthumbs
elif [ -d "$target" ]; then
rm -r "$target"/.nthumbs
fi &
}
make_thumbs() {
if [ -d "$target" ]; then
[ "$1" -eq 4 ] && exit_prompt "$3 can only display a single image"
cd "$target" || exit_prompt
fi
if mkdir .nthumbs >/dev/null; then
thumbs=1
else
exit_prompt
fi
if [ "$1" -eq 4 ]; then
mime="$(file -bL --mime-type -- "$2")"
mkdir -p "$NNN_PREVIEWDIR$dir" || return
if [ "$1" = "viu" ] || [ "$1" = "catimg" ]; then
[ -d "$target" ] && exit_prompt "$1 can only display a single image"
mime="$(file -bL --mime-type -- "$target")"
case "$mime" in
audio/*) ffmpeg -i "$2" ".nthumbs/${2%%.*}.jpg" -y >/dev/null 2>&1
ret=".nthumbs/${2%%.*}.jpg" ;;
video/*) ffmpegthumbnailer -i "$2" -o .nthumbs/"${2%%.*}".jpg 2> /dev/null
ret=".nthumbs/${2%%.*}.jpg" ;;
*) ret="$2" ;;
audio/*) ffmpeg -i "$target" "$NNN_PREVIEWDIR$target.jpg" -y >/dev/null 2>&1
ret="$NNN_PREVIEWDIR/$target.jpg" ;;
video/*) ffmpegthumbnailer -i "$target" -o "$NNN_PREVIEWDIR$target.jpg" 2> /dev/null
ret="$NNN_PREVIEWDIR/$target.jpg" ;;
*) ret="$target" ;;
esac
fi
for file in *; do
case "$(file -bL --mime-type -- "$file")" in
audio/*) [ "$1" -ne 0 ] && ffmpeg -i "$file" ".nthumbs/${file%%.*}.jpg" -y >/dev/null 2>&1 ;;
video/*) [ "$1" -ne 1 ] && ffmpegthumbnailer -i "$file" -o .nthumbs/"${file%%.*}".jpg 2> /dev/null ;;
esac
for file in "$dir"/*; do
if [ ! -f "$NNN_PREVIEWDIR$file.jpg" ]; then
case "$(file -bL --mime-type -- "$file")" in
audio/*) [ "$1" != "sxiv" ] &&
ffmpeg -i "$file" "$NNN_PREVIEWDIR$file.jpg" -y >/dev/null 2>&1 ;;
video/*) [ "$1" != "ucollage" ] &&
ffmpegthumbnailer -i "$file" -o "$NNN_PREVIEWDIR$file.jpg" 2> /dev/null ;;
esac
fi
done
for file in "$NNN_PREVIEWDIR$dir"/*; do
filename="$(basename "$file" .jpg)"
[ ! -e "$dir/$filename" ] && rm -- "$file" 2>/dev/null
done
}
view_files() {
find . .nthumbs -maxdepth 1 -type f -print0 | xargs -0 "$@" --
listimages() {
find -L "$dir" "$NNN_PREVIEWDIR$dir" -maxdepth 1 -type f -print0 2>/dev/null | sort -z
}
view_files() {
[ -f "$target" ] && count="-n $(listimages | grep -a -m 1 -ZznF "$target" | cut -d: -f1)"
case "$1" in
nsxiv) listimages | xargs -0 nsxiv -a "${count:--t}" -- ;;
sxiv) listimages | xargs -0 sxiv -a "${count:--t}" -- ;;
imv*) listimages | xargs -0 "$1" "${count:-}" -- ;;
esac
}
target="$(readlink -f "$1")"
[ -d "$target" ] && dir="$target" || dir="${target%/*}"
if uname | grep -q "Darwin"; then
[ -f "$1" ] && open "$1" >/dev/null 2>&1 &
elif type lsix >/dev/null 2>&1; then
if [ -d "$target" ]; then
cd "$target" || exit_prompt
fi
make_thumbs ""
make_thumbs lsix
clear
lsix
cd .nthumbs && lsix
nthumb_cleanup
cd "$NNN_PREVIEWDIR$dir" && lsix
exit_prompt
elif type ucollage >/dev/null 2>&1; then
make_thumbs 1
if ! UCOLLAGE_EXPAND_DIRS=1 ucollage . .nthumbs; then
nthumb_cleanup && exit_prompt
fi
nthumb_cleanup
exit
type ffmpeg >/dev/null 2>&1 && make_thumbs ucollage
UCOLLAGE_EXPAND_DIRS=1 ucollage "$dir" "$NNN_PREVIEWDIR$dir" || exit_prompt
elif type sxiv >/dev/null 2>&1; then
make_thumbs 0
if [ -f "$target" ]; then
view_files sxiv >/dev/null 2>&1 &
elif [ -d "$target" ]; then
view_files sxiv -aqt >/dev/null 2>&1 &
fi
type ffmpegthumbnailer >/dev/null 2>&1 && make_thumbs sxiv
view_files sxiv >/dev/null 2>&1 &
elif type nsxiv >/dev/null 2>&1; then
type ffmpegthumbnailer >/dev/null 2>&1 && make_thumbs sxiv
view_files nsxiv >/dev/null 2>&1 &
elif type imv >/dev/null 2>&1; then
make_thumbs 3
make_thumbs imv
view_files imv >/dev/null 2>&1 &
elif type imvr >/dev/null 2>&1; then
make_thumbs 3
make_thumbs imv
view_files imvr >/dev/null 2>&1 &
elif type viu >/dev/null 2>&1; then
clear
make_thumbs 4 "$1" viu
make_thumbs viu
viu -n "$ret"
nthumb_cleanup
exit_prompt
elif type catimg >/dev/null 2>&1; then
make_thumbs 4 "$1" catimg
make_thumbs catimg
catimg "$ret"
nthumb_cleanup
exit_prompt
else
exit_prompt "Please install sxiv/imv/viu/catimg/lsix."
exit_prompt "Please install sxiv/nsxiv/imv/viu/catimg/lsix."
fi
[ "$thumbs" -ne 0 ] && nthumb_cleanup &

View File

@ -1,24 +1,66 @@
#!/usr/bin/env sh
# Description: Send the selected files to your Android device using kdeconnect-cli.
# Description: Send files or folders to your Android device using kdeconnect-cli.
# kdeconnect must be configured on the Android device and the PC.
#
# Usage:
# - Hover over a file or a folder and call the plugin.
# - Alternatively, select the files and folders you would like to send, and activate the plugin.
#
# Shell: POSIX compliant
# Author: juacq97
# Author: juacq97, raffaem, N-R-K
# If you want system notification, put this equal to 1
notify=0
note() {
if [ $notify = 1 ]; then
notify-send -a "Kdeconnect" "$1"
else
echo "[Kdeconnect] $1"
fi
}
# kdeconnect doesn't cope with non-files
filter_files() {
xargs -0 -I{} sh -c '
if [ -f "{}" ]; then
printf "%s\0" "{}";
else
printf "Error: not a regular file: %s\n" "{}" >&2;
fi;'
}
send() {
filter_files | xargs -0 -I{} kdeconnect-cli --name "$devname" --share {}
note "Files sent"
}
# Select paired device
names=$(kdeconnect-cli --list-available --name-only 2>/dev/null)
if [ -z "$names" ]; then
note "No devices paired and available"
exit
fi
ndevs=$(printf "%s" "$names" | awk 'END{print NR}')
if [ "$ndevs" -eq 1 ]; then
devname="$names"
else
printf "%s" "$names" | awk '{ print NR ". " $0 }'
printf "Pick a device: "
read -r pick
if [ -n "$pick" ] && [ "$pick" -eq "$pick" ]; then
devname=$(printf '%s' "$names" | awk "NR==$pick")
fi
fi
selection=${NNN_SEL:-${XDG_CONFIG_HOME:-$HOME/.config}/nnn/.selection}
id=$(kdeconnect-cli -a --id-only | awk '{print $1}')
if [ -s "$selection" ]; then
kdeconnect-cli -d "$id" --share "$(cat "$selection")"
# If you want a system notification, uncomment the next 3 lines.
#notify-send -a "Kdeconnect" "Sending $(cat "$selection")"
#else
#notify-send -a "Kdeconnect" "No file selected"
# Clear selection
if [ -p "$NNN_PIPE" ]; then
printf "-" > "$NNN_PIPE"
fi
send < "$selection"
[ -p "$NNN_PIPE" ] && printf "-" > "$NNN_PIPE" # clear selection
elif [ -n "$1" ]; then
printf "%s" "$1" | send
else
note "No selection and no hovered file"
fi

View File

@ -1,13 +0,0 @@
#!/usr/bin/env sh
# Description: Show media information of a file in pager
#
# Dependencies: mediainfo
#
# Shell: POSIX compliant
# Author: Arun Prakash Jana
if [ -n "$1" ] && [ -f "$1" ]; then
mediainfo "$1" | $PAGER
# exiftool "$1" | $PAGER
fi

View File

@ -2,13 +2,22 @@
# Description: Find and list files by mime type in smart context
#
# Dependencies:
# - file
# - mimetype (optional, PERL File MimeInfo)
#
# Shell: POSIX compliant
# Author: Arun Prakash Jana
# Author: Arun Prakash Jana, Michel DHOOGE
# shellcheck disable=SC1090,SC1091
. "$(dirname "$0")"/.nnn-plugin-helper
printf "mime (e.g., video/audio/image): "
read -r mime
printf "%s" "+l" > "$NNN_PIPE"
find . | file -if- | grep "$mime" | awk -F: '{printf "%s\0", $1}' > "$NNN_PIPE"
if type mimetype >/dev/null 2>&1; then
find . | mimetype -f - | grep "$mime" | awk -F: '{printf "%s%c", $1, 0}' > "$NNN_PIPE"
else
find . | file -if- | grep "$mime" | awk -F: '{printf "%s%c", $1, 0}' > "$NNN_PIPE"
fi

View File

@ -34,7 +34,7 @@ fi
cd "$tempdir/$outdir" || exit 1
# Backing up config dir content
cp -r "$configdir" . || exit 1
cp -r -- "$configdir" . || exit 1
# Environment config
env | sed "s/'/'\\\\''/" |\
@ -72,4 +72,4 @@ printf "Saving as '%s' ... " "$workdir/$outfile"
tar caf "$workdir/$outfile" "$outdir" && echo "Done" || echo "Failed"
cd "$workdir" && rm -rf "$tempdir"
cd "$workdir" && rm -rf -- "$tempdir"

View File

@ -4,7 +4,7 @@
# If the device is not mounted, it will be mounted.
# If the device is mounted, it will be unmounted and powered down.
#
# Dependencies: lsblk, pmount
# Dependencies: lsblk, pmount (optional), udisks2
#
# Usage: Runs `lsblk` on 'l', exits on 'Return`.
#
@ -13,7 +13,7 @@
# macOS: "diskutil list"
# BSD: "geom disk list"
# - The script uses udisksctl (from udisks2) to power down devices. This is also Linux-specific.
# Users on non-Linux platforms can comment it and use an alterntive to power-down disks.
# Users on non-Linux platforms can comment it and use an alternative to power-down disks.
#
# Shell: POSIX compliant
# Author: Arun Prakash Jana
@ -26,26 +26,59 @@ printf "\nEnsure you aren't still in the mounted device.\n"
printf "%s" "$prompt"
read -r dev
while [ -n "$dev" ]
do
while [ -n "$dev" ]; do
if [ "$dev" = "l" ]; then
lsblk
elif [ "$dev" = "q" ]; then
exit
else
if grep -qs "$dev " /proc/mounts; then
sync
if pumount "$dev"
then
echo "$dev" unmounted.
if udisksctl power-off -b /dev/"$dev"
then
echo "$dev" ejected.
# LUKS volumes mounted with udisksctl appear differently than with pmount
if grep -qs "$dev " /proc/mounts || [ -n "$(lsblk -n "/dev/$dev" -o MOUNTPOINT)" ]; then
sync "$(lsblk -n "/dev/$dev" -o MOUNTPOINT | sed "/^$/d")"
if type pumount >/dev/null 2>&1; then
pumount "/dev/$dev"
exit_code="$?"
else
# Unlike pmount, udisksctl does not transparently handle LUKS volumes
# We need to manually get the unlocked device, unmount it, and then lock the volume
if lsblk -n "/dev/$dev" -o FSTYPE | grep "crypto_LUKS" >/dev/null; then
dev_map="$(udisksctl info -b /dev/"$dev" | grep "CleartextDevice" | grep -o "dm_2d[[:digit:]]*" | sed "s/_2d/-/")"
udisksctl unmount -b "/dev/$dev_map" --no-user-interaction >/dev/null
exit_code="$?"
udisksctl lock -b "/dev/$dev" --no-user-interaction >/dev/null
else
udisksctl unmount -b "/dev/$dev" --no-user-interaction >/dev/null
exit_code="$?"
fi
fi
if [ $exit_code -eq 0 ]; then
echo "/dev/$dev unmounted."
if udisksctl power-off -b "/dev/$dev" --no-user-interaction; then
echo "/dev/$dev ejected."
fi
fi
elif [ -b "/dev/$dev" ]; then
if type pmount >/dev/null 2>&1; then
pmount "/dev/$dev"
exit_code="$?"
else
# Unlike pmount, udisksctl does not transparently handle LUKS volumes
# We need to manually get the unlocked device and mount that instead of the volume itself
if [ "$(lsblk "/dev/$dev" -n -o FSTYPE)" = "crypto_LUKS" ]; then
dev_map=$(udisksctl unlock -b "/dev/$dev" --no-user-interaction | grep -o "dm-[[:digit:]]*")
udisksctl mount -b "/dev/$dev_map" --no-user-interaction >/dev/null
exit_code="$?"
else
udisksctl mount -b "/dev/$dev" --no-user-interaction >/dev/null
exit_code="$?"
fi
fi
if [ $exit_code -eq 0 ]; then
sleep 1
echo "/dev/$dev mounted to $(lsblk -n "/dev/$dev" -o MOUNTPOINT | sed "/^$/d")."
fi
else
pmount "$dev"
echo "$dev" mounted to "$(lsblk -n /dev/"$dev" | rev | cut -d' ' -f1 | rev)".
echo "/dev/$dev does not exist or is not a block device."
fi
fi

View File

@ -21,9 +21,10 @@
# Guards against accidentally opening mime types like executables, shared libs etc.
#
# Tries to play 'file' (1st argument) in the following order:
# i. by extension
# ii. by mime (image, video, audio, pdf)
# iii. by mime (other file types)
# 1. by extension
# 2. by mime (image, video, audio, pdf)
# 3. by mime (other file types)
# 4. by mime (prompt and run executables)
#
# Modification tips:
# 1. Invokes CLI utilities by default. Set GUI to 1 to enable GUI apps.
@ -50,7 +51,7 @@
# htm|html|xhtml: w3m, lynx, elinks
# json: jq, python (json.tool module)
# Multimedia by mime:
# image/*: imv/sxiv (GUI), viu (https://github.com/atanunq/viu), img2txt, exiftool
# image/*: imv/sxiv/nsxiv (GUI), viu (https://github.com/atanunq/viu), img2txt, exiftool
# video/*: smplayer, mpv (GUI), ffmpegthumbnailer, mediainfo, exiftool
# audio/*: mocq (nnn plugin using MOC), mpv, media_client (Haiku), mediainfo, exiftool
# application/pdf: zathura (GUI), pdftotext, mutool, exiftool
@ -63,8 +64,9 @@
# 1. Adapt, test and enable all mimes
# 2. Clean-up the unnecessary exit codes
# set to 1 to enable GUI apps
# set to 1 to enable GUI apps and/or BIN execution
GUI="${GUI:-0}"
BIN="${BIN:-0}"
set -euf -o noclobber -o noglob -o nounset
IFS="$(printf '%b_' '\n')"; IFS="${IFS%_}" # protect trailing \n
@ -257,27 +259,32 @@ handle_extension() {
esac
}
# sets the variable abs_target, this should be faster than calling printf
abspath() {
case "$1" in
/*) printf "%s\n" "$1";;
*) printf "%s\n" "$PWD/$1";;
/*) abs_target="$1";;
*) abs_target="$PWD/$1";;
esac
}
# storing the result to a tmp file is faster than calling listimages twice
listimages() {
find -L "$(dirname "$target")" -maxdepth 1 -type f -iregex \
'.*\(jpe?g\|bmp\|webp\|ico\|svg\|png\|gif\)$' -print0 | sort -z
find -L "///${1%/*}" -maxdepth 1 -type f -print0 |
grep -izZE '\.(jpe?g|png|gif|webp|tiff|bmp|ico|svg)$' |
sort -zV | tee "$tmp"
}
load_dir() {
target="$(abspath "$2")"
count="$(listimages | grep -a -m 1 -ZznF "$target" | cut -d: -f1)"
abspath "$2"
tmp="${TMPDIR:-/tmp}/nuke_$$"
trap 'rm -f -- "$tmp"' EXIT
count="$(listimages "$abs_target" | grep -a -m 1 -ZznF "$abs_target" | cut -d: -f1)"
if [ -n "$count" ]; then
if [ "$GUI" -ne 0 ]; then
listimages | xargs -0 nohup "$1" -n "$count" --
xargs -0 nohup "$1" -n "$count" -- < "$tmp"
else
listimages | xargs -0 "$1" -n "$count" --
xargs -0 "$1" -n "$count" -- < "$tmp"
fi
else
shift
@ -311,12 +318,18 @@ handle_multimedia() {
if is_mac; then
nohup open "${FPATH}" >/dev/null 2>&1 &
exit 0
elif type imv >/dev/null 2>&1; then
load_dir imv "${FPATH}" >/dev/null 2>&1 &
exit 0
elif type imvr >/dev/null 2>&1; then
load_dir imvr "${FPATH}" >/dev/null 2>&1 &
exit 0
elif type sxiv >/dev/null 2>&1; then
load_dir sxiv "${FPATH}" >/dev/null 2>&1 &
exit 0
elif type nsxiv >/dev/null 2>&1; then
load_dir nsxiv "${FPATH}" >/dev/null 2>&1 &
exit 0
fi
elif type viu >/dev/null 2>&1; then
viu -n "${FPATH}" | eval "$PAGER"
@ -389,7 +402,7 @@ handle_multimedia() {
# "${FPATH}";
# then
# convert -- "${preview_png}" "${IMAGE_CACHE_PATH}" \
# && rm "${preview_png}" \
# && rm -- "${preview_png}" \
# && exit 6
# else
# exit 1
@ -513,10 +526,29 @@ handle_blocked() {
esac
}
handle_bin() {
case "${MIMETYPE}" in
application/x-executable|application/x-shellscript)
clear
echo '-------- Executable File --------' && file --dereference --brief -- "${FPATH}"
printf "Run executable (y/N/'a'rgs)? "
read -r answer
case "$answer" in
[Yy]* ) exec "${FPATH}";;
[Aa]* )
printf "args: "
read -r args
exec "${FPATH}" "$args";;
[Nn]* ) exit;;
esac
esac
}
MIMETYPE="$( file -bL --mime-type -- "${FPATH}" )"
handle_extension
handle_multimedia "${MIMETYPE}"
handle_mime "${MIMETYPE}"
[ "$BIN" -ne 0 ] && [ -x "${FPATH}" ] && handle_bin
handle_blocked "${MIMETYPE}"
handle_fallback

49
plugins/openall Executable file
View File

@ -0,0 +1,49 @@
#!/usr/bin/env bash
# Description: Open selected files in nuke one by one or in oneshot
#
# Notes: 1. Opens the hovered file if the selection is empty
# 2. nuke is the default, set OPENER below for custom
# 3. Opener is invoked once for each file in a loop
# 4. Keep pressing "Enter" to open files one by one
#
# Shell: bash
# Author: Arun Prakash Jana
sel=${NNN_SEL:-${XDG_CONFIG_HOME:-$HOME/.config}/nnn/.selection}
OPENER="${XDG_CONFIG_HOME:-$HOME/.config}/nnn/plugins/nuke"
if [ -s "$sel" ]; then
targets=()
while IFS= read -r -d '' entry || [ -n "$entry" ]; do
targets+=( "$entry" )
done < "$sel"
elements=${#targets[@]}
if (( elements == 1 )); then
# If there's only one file selected, open without prompts
"$OPENER" "${targets[0]}"
else
printf "open [A]ll? "
read -r all
for ((index=0; index <= ${#targets[@]}; index++)); do
"$OPENER" "${targets[index]}"
if [ "$all" != "A" ] && (( index+1 < elements )); then
printf "press Enter to open '%s'\n" "${targets[index+1]}"
read -r -s -n 1 key
if [[ $key != "" ]]; then
break
fi
fi
done
fi
# Clear selection
if [ -s "$sel" ] && [ -p "$NNN_PIPE" ]; then
printf "-" > "$NNN_PIPE"
fi
elif [ -n "$1" ]; then
"$OPENER" "$1"
fi

View File

@ -13,36 +13,36 @@ organize() {
case "$(file -biL "$1")" in
*video*)
[ ! -d "Videos" ] && mkdir "Videos"
mv "$1" "Videos/$1"
mv -- "$1" "Videos/$1"
printf "Moved %s to Videos\n" "$1" ;;
*audio*) [ ! -d "Audio" ] && mkdir "Audio"
mv "$1" "Audio/$1"
mv -- "$1" "Audio/$1"
printf "Moved %s to Audio\n" "$1" ;;
*image*)
[ ! -d "Images" ] && mkdir "Images"
mv "$1" "Images/$1"
mv -- "$1" "Images/$1"
printf "Moved %s to Images\n" "$1" ;;
*pdf*|*document*|*epub*|*djvu*|*cb*)
[ ! -d "Documents" ] && mkdir "Documents"
mv "$1" "Documents/$1"
mv -- "$1" "Documents/$1"
printf "Moved %s to Documents\n" "$1" ;;
*text*)
[ ! -d "Plaintext" ] && mkdir "Plaintext"
mv "$1" "Plaintext/$1"
mv -- "$1" "Plaintext/$1"
printf "Moved %s to Plaintext\n" "$1" ;;
*tar*|*xz*|*compress*|*7z*|*rar*|*zip*)
[ ! -d "Archives" ] && mkdir "Archives"
mv "$1" "Archives/$1"
mv -- "$1" "Archives/$1"
printf "Moved %s to Archives\n" "$1" ;;
*binary*)
[ ! -d "Binaries" ] && mkdir "Binaries"
mv "$1" "Binaries/$1"
mv -- "$1" "Binaries/$1"
printf "Moved %s to Binaries\n" "$1" ;;
esac
}

View File

@ -15,7 +15,7 @@ if [ -n "$1" ]; then
pico2wave -w "$tmpf".wav -l en-GB "$(tr '\n' ' ' < "$tmpf".txt)"
rm "$tmpf".txt
rm -- "$tmpf".txt
else
pico2wave -w "$tmpf".wav -l en-GB "$(tr '\n' ' ' < "$1")"
fi
@ -26,5 +26,5 @@ if [ -n "$1" ]; then
# flat read but better quality
# play -qV0 "$tmpf".wav treble 2 gain -l 2
rm "$tmpf".wav
rm -- "$tmpf".wav
fi

View File

@ -1,24 +0,0 @@
#!/usr/bin/env sh
# Description: View a PDF file in pager
#
# Notes:
# - $PAGER must be 'less -R' or 'most'
# - To use mutool, uncomment the relevant lines and comment the pdftotext line
#
# Shell: POSIX compliant
# Author: Arun Prakash Jana
if [ -n "$1" ]; then
if [ "$(head -c 4 "$1")" = "%PDF" ]; then
# Convert using pdftotext
pdftotext -nopgbrk -layout "$1" - | sed 's/\xe2\x80\x8b//g' | $PAGER
# Convert using mutool
# file=`basename "$1"`
# txt=/tmp/"$file".txt
# mutool convert -o "$txt" "$1"
# eval $PAGER $txt
# rm "$txt"
fi
fi

View File

@ -1,26 +0,0 @@
#!/usr/bin/env sh
# Description: Pick files and pipe the newline-separated list to another utility
#
# Usage:
# Copy this file in your $PATH, make it executable and preferably name it to picker.
# Run commands like:
# ls -l `picker`
# cd `picker`
# vimdiff `picker`
# or, in fish shell:
# ls -l (picker)
# cd (picker)
# vimdiff (picker)
#
# Note: This use case is limited to picking files, other functionality may not work as expected.
#
# Shell: POSIX compliant
# Author: Arun Prakash Jana
nnn -p /tmp/picked
if [ -f /tmp/picked ]; then
tr '\0' '\n' < /tmp/picked
rm /tmp/picked
fi

View File

@ -4,12 +4,13 @@
#
# Dependencies:
# - tabbed (https://tools.suckless.org/tabbed): xembed host
# - xterm (or urxvt or st) : xembed client for text-based preview
# - xterm (or urxvt or st or alacritty) : xembed client for text-based preview
# - mpv (https://mpv.io): xembed client for video/audio
# - sxiv (https://github.com/muennich/sxiv): xembed client for images
# - sxiv (https://github.com/muennich/sxiv) or,
# - nsxiv (https://codeberg.org/nsxiv/nsxiv) : xembed client for images
# - zathura (https://pwmt.org/projects/zathura): xembed client for PDF
# - nnn's nuke plugin for text preview and fallback
# nuke is a fallback for 'mpv', 'sxiv', and 'zathura', but has its
# nuke is a fallback for 'mpv', 'sxiv'/'nsxiv', and 'zathura', but has its
# own dependencies, see the script for more information
# - vim (or any editor/pager really)
# - file
@ -26,6 +27,7 @@
# 1. This plugin needs a "NNN_FIFO" to work. See man.
# 2. If the same NNN_FIFO is used in multiple nnn instances, there will be one
# common preview window. With different FIFO paths, they will be independent.
# 3. This plugin only works on X, not on Wayland.
#
# How it works:
# We use `tabbed` [1] as a xembed [2] host, to have a single window
@ -35,7 +37,7 @@
# provided for `urxvt` and `st`). For graphic preview this can be trickier,
# but a few popular viewers are xembed-able, we use:
# - `mpv`: multimedia player, for video/audio preview
# - `sxiv`: image viewer
# - `sxiv`/`nsxiv`: image viewer
# - `zathura`: PDF viewer
# - but we always fallback to `nuke` plugin
#
@ -50,6 +52,10 @@ XDOTOOL_TIMEOUT=2
PAGER=${PAGER:-"vim -R"}
NUKE="${XDG_CONFIG_HOME:-$HOME/.config}/nnn/plugins/nuke"
if [ -n "$WAYLAND_DISPLAY" ] ; then
echo "Wayland is not supported in preview-tabbed, this plugin could freeze your session!" >&2
exit 1
fi
if type xterm >/dev/null 2>&1 ; then
TERMINAL="xterm -into"
@ -57,10 +63,15 @@ elif type urxvt >/dev/null 2>&1 ; then
TERMINAL="urxvt -embed"
elif type st >/dev/null 2>&1 ; then
TERMINAL="st -w"
elif type alacritty >/dev/null 2>&1 ; then
TERMINAL="alacritty --embed"
else
echo "No xembed term found" >&2
fi
if type xdg-user-dir >/dev/null 2>&1 ; then
PICTURES_DIR=$(xdg-user-dir PICTURES)
fi
term_nuke () {
# $1 -> $XID, $2 -> $FILE
@ -84,7 +95,7 @@ start_tabbed () {
read -r XID < "$FIFO"
rm "$FIFO"
rm -- "$FIFO"
}
get_viewer_pid () {
@ -154,7 +165,9 @@ previewer_loop () {
;;
image/*)
if type sxiv >/dev/null 2>&1 ; then
sxiv -e "$XID" "$FILE" &
sxiv -ae "$XID" "$FILE" &
elif type nsxiv >/dev/null 2>&1 ; then
nsxiv -ae "$XID" "$FILE" &
else
term_nuke "$XID" "$FILE"
fi
@ -167,7 +180,17 @@ previewer_loop () {
fi
;;
inode/directory)
$TERMINAL "$XID" -e nnn "$FILE" &
if [[ -n $PICTURES_DIR && "$FILE" == "$PICTURES_DIR"* ]] ; then
if type sxiv >/dev/null 2>&1 ; then
sxiv -te "$XID" "$FILE" &
elif type nsxiv >/dev/null 2>&1 ; then
nsxiv -te "$XID" "$FILE" &
else
$TERMINAL "$XID" -e nnn "$FILE" &
fi
else
$TERMINAL "$XID" -e nnn "$FILE" &
fi
;;
text/*)
if [ -x "$NUKE" ] ; then

View File

@ -1,17 +1,19 @@
#!/usr/bin/env sh
#!/usr/bin/env bash
# Description: Terminal based file previewer
#
# Note: This plugin needs a "NNN_FIFO" to work. See man.
#
# Dependencies:
# - Supports 4 independent methods to preview with:
# - Supports 6 independent methods to preview with:
# - tmux (>=3.0), or
# - kitty with allow_remote_control and listen_on set in kitty.conf, or
# - QuickLook on WSL (https://github.com/QL-Win/QuickLook)
# - $TERMINAL set to a terminal (it's xterm by default).
# - less or $PAGER
# - tree or exa or ls
# - wezterm (https://wezfurlong.org/wezterm), or
# - QuickLook on WSL (https://github.com/QL-Win/QuickLook), or
# - Windows Terminal (https://github.com/Microsoft/Terminal | https://aka.ms/terminal) with WSL, or
# - $NNN_TERMINAL set to a terminal (it's xterm by default).
# - less or $NNN_PAGER
# - tree or exa/eza or (GNU) ls
# - mediainfo or file
# - mktemp
# - unzip
@ -19,24 +21,30 @@
# - man
# - optional: bsdtar or atool for additional archive preview
# - optional: bat for code syntax highlighting
# - optional: ueberzug, kitty terminal, viu or catimg for images
# - optional: convert(ImageMagick) for playing gif preview
# - optional: ueberzug, kitty terminal, wezterm terminal, img2sixel, viu, catimg or chafa for images
# - optional: convert(ImageMagick) for playing gif preview (mandatory for kitty image previews)
# - optional: mpv for gif and video
# Also requires a terminal supporting the sixel (https://www.arewesixelyet.com/)
# or kitty (https://sw.kovidgoyal.net/kitty/graphics-protocol) video_output backends.
# Requires tmux compiled with `./configure --enable-sixel` if used.
# - optional: ffmpegthumbnailer for video thumbnails (https://github.com/dirkvdb/ffmpegthumbnailer)
# - optional: ffmpeg for audio thumbnails
# - optional: libreoffce for opendocument/officedocument preview
# - optional: pdftoppm(poppler) for pdf thumbnails
# - optional: gnome-epub-thumbnailer for epub thumbnails (https://gitlab.gnome.org/GNOME/gnome-epub-thumbnailer)
# - optional: fontpreview for font preview (https://github.com/sdushantha/fontpreview)
# - optional: djvulibre for djvu
# - optional: glow or lowdown for markdown
# - optional: w3m or lynx or elinks for html
# - optional: set/export ICONLOOKUP as 1 to enable file icons in front of directory previews with .iconlookup
# Icons and colors are configureable in .iconlookup
# - optional: set/export NNN_ICONLOOKUP as 1 to enable file icons in front of directory previews with .iconlookup
# Icons and colors are configurable in .iconlookup
# - optional: scope.sh file viewer from ranger.
# 1. drop scope.sh executable in $PATH
# 2. set/export $USE_SCOPE as 1
# 2. set/export $NNN_SCOPE as 1
# - optional: pistol file viewer (https://github.com/doronbehar/pistol).
# 1. install pistol
# 2. set/export $USE_PISTOL as 1
# 2. set/export $NNN_PISTOL as 1
# - optional: librsvg for rsvg-convert
#
# Usage:
# You need to set a NNN_FIFO path and a key for the plugin with NNN_PLUG,
@ -56,134 +64,204 @@
#
# The previews will be shown in a tmux split. If that isn't possible, it
# will try to use a kitty terminal split. And as a final fallback, a
# different terminal window will be used ($TERMINAL).
# different terminal window will be used ($NNN_TERMINAL).
#
# Tmux and kitty users can configure $SPLIT to either "h" or "v" to set a
# 'h'orizontal split or a 'v'ertical split (as in, the line that splits the
# windows will be horizontal or vertical).
# Kitty users need something similar to the following in their kitty.conf:
# - `allow_remote_control yes`
# - `listen_on unix:$TMPDIR/kitty`
# - `enabled_layouts splits` (optional)
# With ImageMagick installed, this terminal can use the icat kitten to display images.
# Refer to kitty documentation for further details.
#
# Kitty users need `allow_remote_control` set to `yes`, and `listen_on` set
# to e.g. "$TMPDIR/kitty". To customize the window split, `enabled_layouts`
# has to be set to `all` or `splits` (the former is the default value).
# This terminal is also able to show images without extra dependencies.
# Users with both tmux and kitty can leverage image previews inside tmux with kitty's icat kitten
# - setup kitty as stated above
# - tmux >= v3.3a required
# - add the following to your tmux.conf:
# - `set -g allow-passthrough on`
#
# Shell: POSIX compliant
# Authors: Todd Yamakawa, Léo Villeveygoux, @Recidiviste, Mario Ortiz Manero, Luuk van Baal
# Wezterm should work out of the box. If `NNN_PREVIEWIMGPROG` is not specified it will use
# built in iTerm2 image protocol.
#
# Note that GNU ls is used for its `--group-directories-first` flag.
# On MacOS this may be installed with `brew install coreutils`, or the flag can be removed.
# iTerm2 users are recommended to use viu to view images without getting pixelated.
#
# Windows Terminal users can set "Profile termination behavior" under "Profile > Advanced" settings
# to automatically close pane on quit when exit code is 0.
#
# When specifying a different terminal, additional arguments are supported. In particular, you can
# append a specific title to the terminal and set it to "nofocus" in your WM config.
# E.g for alacritty and i3, you can set $NNN_TERMINAL to 'alacritty --title preview-tui' and add
# 'no_focus [title="preview-tui"]' to your i3 config file.
#
# Shell: Bash (for environment manipulation through arrays)
# Authors: Todd Yamakawa, Léo Villeveygoux, @Recidiviste, Mario Ortiz Manero, Luuk van Baal, @WanderLanz, @flipflop133
#SPLIT="$SPLIT" # you can set a permanent split here
#TERMINAL="$TERMINAL" # same goes for the terminal
USE_SCOPE="${USE_SCOPE:-0}"
USE_PISTOL="${USE_PISTOL:-0}"
ICONLOOKUP="${ICONLOOKUP:-0}"
PAGER="${PAGER:-less -P?n -R}"
TMPDIR="${TMPDIR:-/tmp}"
BAT_STYLE="${BAT_STYLE:-numbers}"
# Consider setting NNN_PREVIEWDIR to $XDG_CACHE_HOME/nnn/previews if you want to keep previews on disk between reboots
NNN_PREVIEWDIR="${NNN_PREVIEWDIR:-$TMPDIR/nnn/previews}"
NNN_PREVIEWWIDTH="${NNN_PREVIEWWIDTH:-1920}"
NNN_PREVIEWHEIGHT="${NNN_PREVIEWHEIGHT:-1080}"
NNN_PARENT="${NNN_FIFO#*.}"
FIFOPID="$TMPDIR/nnn-preview-tui-fifopid.$NNN_PARENT"
PAGERPID="$TMPDIR/nnn-preview-tui-pagerpid.$NNN_PARENT"
IMGPID="$TMPDIR/nnn-preview-tui-imgpid.$NNN_PARENT"
CURSEL="$TMPDIR/nnn-preview-tui-selection.$NNN_PARENT"
FIFO_UEBERZUG="$TMPDIR/nnn-preview-tui-ueberzug-fifo.$NNN_PARENT"
# Configurable environment variables:
NNN_SPLIT=${NNN_SPLIT:-} # permanent split direction
NNN_TERMINAL=${NNN_TERMINAL:-} # external terminal to be used
NNN_SPLITSIZE=${NNN_SPLITSIZE:-50} # previewer split size percentage
TMPDIR=${TMPDIR:-/tmp} # location of temporary files
ENVVARS=(
"NNN_SCOPE=${NNN_SCOPE:-0}" # use scope
"NNN_PISTOL=${NNN_PISTOL:-0}" # use pistol
"NNN_ICONLOOKUP=${NNN_ICONLOOKUP:-0}" # use .iconlookup
"NNN_PAGER=${NNN_PAGER:-less -P?n -R -C}" # pager options
"NNN_BATTHEME=${NNN_BATTHEME:-ansi}" # bat theme
"NNN_BATSTYLE=${NNN_BATSTYLE:-numbers}" # bat style
"NNN_PREVIEWWIDTH=${NNN_PREVIEWWIDTH:-1920}" # width of generated preview images
"NNN_PREVIEWHEIGHT=${NNN_PREVIEWHEIGHT:-1080}" # height of generated preview images
"NNN_PREVIEWDIR=${NNN_PREVIEWDIR:-$TMPDIR/nnn/previews}" # location of generated preview images
"NNN_PREVIEWIMGPROG=${NNN_PREVIEWIMGPROG:-}" # program used to preview images
"NNN_PREVIEWVIDEO=${NNN_PREVIEWVIDEO:-}" # mpv backend used to preview video
)
# Non-configurable environment variables
NNN_PARENT=${NNN_FIFO#*.}
[ "$NNN_PARENT" -eq "$NNN_PARENT" ] 2>/dev/null || NNN_PARENT="" # Make empty if non-numeric
ENVVARS+=(
"PWD=$PWD"
"PATH=$PATH"
"NNN_FIFO=$NNN_FIFO"
"FIFOPID=$TMPDIR/nnn-preview-tui-fifopid.$NNN_PARENT"
"FIFOPATH=$TMPDIR/nnn-preview-tui-fifo.$NNN_PARENT"
"PREVIEWPID=$TMPDIR/nnn-preview-tui-previewpid.$NNN_PARENT"
"CURSEL=$TMPDIR/nnn-preview-tui-selection.$NNN_PARENT"
"FIFO_UEBERZUG=$TMPDIR/nnn-preview-tui-ueberzug-fifo.$NNN_PARENT"
"POSOFFSET=$TMPDIR/nnn-preview-tui-posoffset"
)
trap '' PIPE
exists() { type "$1" >/dev/null 2>&1 ;}
pkill() { command pkill "$@" >/dev/null 2>&1 ;}
prompt() { clear; printf "%b" "$@"; cfg=$(stty -g); stty raw -echo; head -c 1; stty "$cfg" ;}
pidkill() {
if [ -f "$1" ]; then
PID="$(cat "$1" 2>/dev/null)" || return 1
kill "$PID" >/dev/null 2>&1
RET=$?
wait "$PID" 2>/dev/null
return $RET
fi
return 1
}
start_preview() {
[ "$PAGER" = "most" ] && PAGER="less -R"
if [ -e "${TMUX%%,*}" ] && tmux -V | grep -q '[ -][3456789]\.'; then
TERMINAL=tmux
NNN_TERMINAL=tmux
exists mpv && tmux display -p '#{client_termfeatures}' | grep -q 'sixel' && ENVVARS+=("NNN_PREVIEWVIDEO=sixel")
elif [ -n "$KITTY_LISTEN_ON" ]; then
TERMINAL=kitty
NNN_TERMINAL=kitty
exists mpv && ENVVARS+=("NNN_PREVIEWVIDEO=kitty")
elif [ -n "$WEZTERM_PANE" ]; then
NNN_TERMINAL=wezterm
exists mpv && ENVVARS+=("NNN_PREVIEWVIDEO=kitty")
elif [ -z "$NNN_TERMINAL" ] && [ "$TERM_PROGRAM" = "iTerm.app" ]; then
NNN_TERMINAL=iterm
exists mpv && ENVVARS+=("NNN_PREVIEWVIDEO=sixel")
elif [ -n "$WT_SESSION" ]; then
NNN_TERMINAL=winterm
else
TERMINAL="${TERMINAL:-xterm}"
NNN_TERMINAL="${NNN_TERMINAL:-xterm}"
fi
if [ -z "$SPLIT" ] && [ $(($(tput lines) * 2)) -gt "$(tput cols)" ]; then
SPLIT='h'
elif [ "$SPLIT" != 'h' ]; then
SPLIT='v'
if [ -z "$NNN_SPLIT" ] && [ $(($(tput lines) * 2)) -gt "$(tput cols)" ]; then
NNN_SPLIT='h'
elif [ "$NNN_SPLIT" != 'h' ]; then
NNN_SPLIT='v'
fi
case "$TERMINAL" in
ENVVARS+=("NNN_TERMINAL=$NNN_TERMINAL" "NNN_SPLIT=$NNN_SPLIT" "QLPATH=$2" "PREVIEW_MODE=1")
case "$NNN_TERMINAL" in
iterm|winterm) # has to run in separate shell command: escape
ENVVARS=("${ENVVARS[@]/#/\\\"}")
ENVVARS=("${ENVVARS[@]/%/\\\"}")
command="$SHELL -c 'env ${ENVVARS[*]} \\\"$0\\\" \\\"$1\\\"'" ;;
esac
case "$NNN_TERMINAL" in
tmux) # tmux splits are inverted
if [ "$SPLIT" = "v" ]; then DSPLIT="h"; else DSPLIT="v"; fi
tmux split-window -e "NNN_FIFO=$NNN_FIFO" -e "PREVIEW_MODE=1" -e "PAGER=$PAGER" \
-e "USE_SCOPE=$USE_SCOPE" -e "SPLIT=$SPLIT" -e "USE_PISTOL=$USE_PISTOL" \
-e "BAT_STYLE=$BAT_STYLE" -e "PAGERPID=$PAGERPID" -e "FIFOPID=$FIFOPID" \
-e "IMGPID=$IMGPID" -e "CURSEL=$CURSEL" -e "TMPDIR=$TMPDIR" \
-e "ICONLOOKUP=$ICONLOOKUP" -e "NNN_PREVIEWDIR=$NNN_PREVIEWDIR" \
-e "NNN_PREVIEWWIDTH=$NNN_PREVIEWWIDTH" -e "NNN_PREVIEWHEIGHT=$NNN_PREVIEWHEIGHT" \
-e "FIFO_UEBERZUG=$FIFO_UEBERZUG" -e "QLPATH=$2" -d"$DSPLIT" "$0" "$1" ;;
ENVVARS=("${ENVVARS[@]/#/-e}")
if [ "$NNN_SPLIT" = "v" ]; then split="h"; else split="v"; fi
tmux split-window -l"$NNN_SPLITSIZE"% "${ENVVARS[@]}" -d"$split" -p"$NNN_SPLITSIZE" "$0" "$1" ;;
kitty) # Setting the layout for the new window. It will be restored after the script ends.
ENVVARS=("${ENVVARS[@]/#/--env=}")
kitty @ goto-layout splits
# Trying to use kitty's integrated window management as the split window. All
# environmental variables that will be used in the new window must be explicitly passed.
kitty @ launch --no-response --title "nnn preview" --keep-focus \
--cwd "$PWD" --env "PATH=$PATH" --env "NNN_FIFO=$NNN_FIFO" \
--env "PREVIEW_MODE=1" --env "PAGER=$PAGER" --env "TMPDIR=$TMPDIR" \
--env "USE_SCOPE=$USE_SCOPE" --env "SPLIT=$SPLIT" --env "TERMINAL=$TERMINAL"\
--env "USE_PISTOL=$USE_PISTOL" --env "BAT_STYLE=$BAT_STYLE" --env "FIFOPID=$FIFOPID" \
--env "PAGERPID=$PAGERPID" --env "IMGPID=$IMGPID" --env "FIFO_UEBERZUG=$FIFO_UEBERZUG" \
--env "ICONLOOKUP=$ICONLOOKUP" --env "NNN_PREVIEWDIR=$NNN_PREVIEWDIR" \
--env "NNN_PREVIEWWIDTH=$NNN_PREVIEWWIDTH" --env "NNN_PREVIEWHEIGHT=$NNN_PREVIEWHEIGHT" \
--env "CURSEL=$CURSEL" --location "${SPLIT}split" "$0" "$1" ;;
# Trying to use kitty's integrated window management as the split window.
kitty @ launch --no-response --title "preview-tui" --keep-focus \
--cwd "$PWD" "${ENVVARS[@]}" --location "${NNN_SPLIT}split" "$0" "$1" ;;
wezterm)
export "${ENVVARS[@]}"
if [ "$NNN_SPLIT" = "v" ]; then split="--horizontal"; else split="--bottom"; fi
wezterm cli split-pane --cwd "$PWD" $split --percent "$NNN_SPLITSIZE" "$0" "$1" >/dev/null
wezterm cli activate-pane-direction Prev ;;
iterm)
if [ "$NNN_SPLIT" = "h" ]; then split="horizontally"; else split="vertically"; fi
osascript <<-EOF
tell application "iTerm"
tell current session of current window
split $split with default profile command "$command"
end tell
end tell
EOF
;;
winterm)
if [ "$NNN_SPLIT" = "h" ]; then split="H"; else split="V"; fi
wt -w 0 sp -$split -s"0.$NNN_SPLITSIZE" "$command" \; -w 0 mf previous 2>/dev/null ;;
*) if [ -n "$2" ]; then
QUICKLOOK=1 QLPATH="$2" PREVIEW_MODE=1 "$0" "$1" &
env "${ENVVARS[@]}" QUICKLOOK=1 "$0" "$1" &
else
PAGERPID="$PAGERPID" IMGPID="$IMGPID" CURSEL="$CURSEL" PREVIEW_MODE=1 \
FIFOPID="$FIFOPID" FIFO_UEBERZUG="$FIFO_UEBERZUG" $TERMINAL -e "$0" "$1" &
# shellcheck disable=SC2086 # (allow arguments)
env "${ENVVARS[@]}" $NNN_TERMINAL -e "$0" "$1" &
fi ;;
esac
} >/dev/null 2>&1
}
toggle_preview() {
export "${ENVVARS[@]}"
if exists QuickLook.exe; then
QLPATH="QuickLook.exe"
elif exists Bridge.exe; then
QLPATH="Bridge.exe"
fi
if pkill -P "$(cat "$FIFOPID")"; then
if pidkill "$FIFOPID"; then
[ -p "$NNN_PPIPE" ] && printf "0" > "$NNN_PPIPE"
pidkill "$PREVIEWPID"
pkill -f "tail --follow $FIFO_UEBERZUG"
if [ -n "$QLPATH" ] && stat "$1"; then
f="$(wslpath -w "$1")" && "$QLPATH" "$f" &
fi
else
[ -p "$NNN_PPIPE" ] && printf "1" > "$NNN_PPIPE"
start_preview "$1" "$QLPATH"
fi
} >/dev/null 2>&1
exists() {
type "$1" >/dev/null
}
fifo_pager() {
cmd="$1"
shift
# We use a FIFO to access $PAGER PID in jobs control
tmpfifopath="$TMPDIR/nnn-preview-tui-fifo.$$"
mkfifo "$tmpfifopath" || return
# We use a FIFO to access $NNN_PAGER PID in jobs control
mkfifo "$FIFOPATH" || return
$PAGER < "$tmpfifopath" &
printf "%s" "$!" > "$PAGERPID"
$NNN_PAGER < "$FIFOPATH" &
printf "%s" "$!" > "$PREVIEWPID"
(
exec > "$tmpfifopath"
exec > "$FIFOPATH"
if [ "$cmd" = "pager" ]; then
if exists bat; then
bat --terminal-width="$(tput cols)" --decorations=always --color=always \
--paging=never --style="$BAT_STYLE" "$@" &
bat --terminal-width="$cols" --decorations=always --color=always \
--paging=never --style="$NNN_BATSTYLE" --theme="$NNN_BATTHEME" "$@" &
else
$PAGER "$@" &
$NNN_PAGER "$@" &
fi
else
"$cmd" "$@" &
fi
)
rm "$tmpfifopath"
} 2>/dev/null
rm -- "$FIFOPATH"
}
# Binary file: show file info inside the pager
print_bin_info() {
@ -193,17 +271,18 @@ print_bin_info() {
else
file -b "$1"
fi
} 2>/dev/null
}
handle_mime() {
case "$2" in
image/jpeg) image_preview "$cols" "$lines" "$1" ;;
image/gif) generate_preview "$cols" "$lines" "$1" "gif" ;;
image/vnd.djvu) generate_preview "$cols" "$lines" "$1" "djvu" ;;
image/*) generate_preview "$cols" "$lines" "$1" "image" ;;
video/*) generate_preview "$cols" "$lines" "$1" "video" ;;
audio/*) generate_preview "$cols" "$lines" "$1" "audio" ;;
application/font*|application/*opentype) generate_preview "$cols" "$lines" "$1" "font" ;;
*/*office*|*/*document*) generate_preview "$cols" "$lines" "$1" "office" ;;
application/font*|application/*opentype|font/*) generate_preview "$cols" "$lines" "$1" "font" ;;
*/*office*|*/*document*|*/*msword|*/*ms-excel) generate_preview "$cols" "$lines" "$1" "office" ;;
application/zip) fifo_pager unzip -l "$1" ;;
text/troff)
if exists man; then
@ -255,13 +334,13 @@ handle_ext() {
preview_file() {
clear
# Trying to use pistol if it's available.
if [ "$USE_PISTOL" -ne 0 ] && exists pistol; then
if [ "$NNN_PISTOL" -ne 0 ] && exists pistol; then
fifo_pager pistol "$1"
return
fi
# Trying to use scope.sh if it's available.
if [ "$USE_SCOPE" -ne 0 ] && exists scope.sh; then
if [ "$NNN_SCOPE" -ne 0 ] && exists scope.sh; then
fifo_pager scope.sh "$1" "$cols" "$lines" "$(mktemp -d)" "True"
return
fi
@ -283,27 +362,33 @@ preview_file() {
# Otherwise, falling back to the defaults.
if [ -d "$1" ]; then
cd "$1" || return
if [ "$ICONLOOKUP" -ne 0 ] && [ -f "$(dirname "$0")"/.iconlookup ]; then
[ "$SPLIT" = v ] && BSTR="\n"
if [ "$NNN_ICONLOOKUP" -ne 0 ] && [ -f "$(dirname "$0")"/.iconlookup ]; then
[ "$NNN_SPLIT" = v ] && BSTR="\n"
# shellcheck disable=SC2012
ls -F --group-directories-first | head -n "$((lines - 3))" | "$(dirname "$0")"/.iconlookup -l "$cols" -B "$BSTR" -b " "
elif exists tree; then
fifo_pager tree --filelimit "$(find . -maxdepth 1 | wc -l)" -L 3 -C -F --dirsfirst --noreport
elif exists exa; then
exa -G --group-directories-first --colour=always
fifo_pager exa -T --group-directories-first --colour=always -L 3
elif exists eza; then # eza is a community fork of exa (exa is unmaintained)
fifo_pager eza -T --group-directories-first --colour=always -L 3
else
fifo_pager ls -F --group-directories-first --color=always
fi
cd ..
elif [ "${encoding#*)}" = "binary" ]; then
handle_mime "$1" "$mimetype" "$ext" "bin"
else
handle_mime "$1" "$mimetype" "$ext"
fi
} 2>/dev/null
}
generate_preview() {
if [ -n "$QLPATH" ] && stat "$3"; then
f="$(wslpath -w "$3")" && "$QLPATH" "$f" &
elif [ -n "$NNN_PREVIEWVIDEO" ] && [[ "$4" == +(gif|video) ]]; then
[ "$4" = "video" ] && args=(--start=10% --length=4) || args=()
video_preview "$1" "$2" "$3" "${args[@]}" && return
elif [ ! -f "$NNN_PREVIEWDIR/$3.jpg" ] || [ -n "$(find -L "$3" -newer "$NNN_PREVIEWDIR/$3.jpg")" ]; then
mkdir -p "$NNN_PREVIEWDIR/${3%/*}"
case $4 in
@ -311,56 +396,91 @@ generate_preview() {
epub) gnome-epub-thumbnailer "$3" "$NNN_PREVIEWDIR/$3.jpg" ;;
font) fontpreview -i "$3" -o "$NNN_PREVIEWDIR/$3.jpg" ;;
gif) if [ -p "$FIFO_UEBERZUG" ] && exists convert; then
frameprefix="$NNN_PREVIEWDIR/$3/${3##*/}"
if [ ! -d "$NNN_PREVIEWDIR/$3" ]; then
mkdir -p "$NNN_PREVIEWDIR/$3"
convert -coalesce -resize "$NNN_PREVIEWWIDTH"x"$NNN_PREVIEWHEIGHT"\> "$3" "$NNN_PREVIEWDIR/$3/${3##*/}.jpg"
convert -coalesce -resize "$NNN_PREVIEWWIDTH"x"$NNN_PREVIEWHEIGHT"\> "$3" "$frameprefix.jpg" ||
MAGICK_TMPDIR="/tmp" convert -coalesce -resize "$NNN_PREVIEWWIDTH"x"$NNN_PREVIEWHEIGHT"\> "$3" "$frameprefix.jpg"
fi
while true; do
for frame in $(find "$NNN_PREVIEWDIR/$3"/*.jpg | sort -V); do
image_preview "$1" "$2" "$frame"
sleep 0.1
done
done &
printf "%s" "$!" > "$IMGPID"
return
else
image_preview "$1" "$2" "$3"
frames=$(($(find "$NNN_PREVIEWDIR/$3" | wc -l) - 2))
[ $frames -lt 0 ] && return
while true; do
for i in $(seq 0 $frames); do
image_preview "$1" "$2" "$frameprefix-$i.jpg"
sleep 0.1
done
done &
printf "%s" "$!" > "$PREVIEWPID"
return
elif [ -n "$NNN_PREVIEWVIDEO" ]; then
video_preview "$1" "$2" "$3" && return
else
image_preview "$1" "$2" "$3" && return
fi ;;
image) convert "$3" -flatten -resize "$NNN_PREVIEWWIDTH"x"$NNN_PREVIEWHEIGHT"\> "$NNN_PREVIEWDIR/$3.jpg" ;;
image) if exists rsvg-convert && [[ "${3##*.}" == "svg" ]]; then
rsvg-convert -a -w "$NNN_PREVIEWWIDTH" -h "$NNN_PREVIEWHEIGHT" -f png -o "$NNN_PREVIEWDIR/$3.png" "$3"
elif exists convert; then
convert "$3" -flatten -resize "$NNN_PREVIEWWIDTH"x"$NNN_PREVIEWHEIGHT"\> "$NNN_PREVIEWDIR/$3.jpg"
else
image_preview "$1" "$2" "$3" && return
fi ;;
office) libreoffice --convert-to jpg "$3" --outdir "$NNN_PREVIEWDIR/${3%/*}"
filename="$(printf "%s" "${3##*/}" | cut -d. -f1)"
mv "$NNN_PREVIEWDIR/${3%/*}/$filename.jpg" "$NNN_PREVIEWDIR/$3.jpg" ;;
mv -- "$NNN_PREVIEWDIR/${3%/*}/$filename.jpg" "$NNN_PREVIEWDIR/$3.jpg" ;;
pdf) pdftoppm -jpeg -f 1 -singlefile "$3" "$NNN_PREVIEWDIR/$3" ;;
video) ffmpegthumbnailer -s0 -i "$3" -o "$NNN_PREVIEWDIR/$3.jpg" || rm "$NNN_PREVIEWDIR/$3.jpg" ;;
djvu) ddjvu -format=ppm -page=1 "$3" "$NNN_PREVIEWDIR/$3.jpg" ;;
video) video_preview "$1" "$2" "$3" && return ;;
esac
fi >/dev/null
fi
if [ -f "$NNN_PREVIEWDIR/$3.jpg" ]; then
image_preview "$1" "$2" "$NNN_PREVIEWDIR/$3.jpg"
elif [[ "${3##*.}" == "svg" ]] && [ -f "$NNN_PREVIEWDIR/$3.png" ]; then
image_preview "$1" "$2" "$NNN_PREVIEWDIR/$3.png"
else
fifo_pager print_bin_info "$3"
fi
} 2>/dev/null
} >/dev/null 2>&1
image_preview() {
clear
if [ "$TERMINAL" = "kitty" ]; then
# Kitty terminal users can use the native image preview method
kitty +kitten icat --silent --place "$1"x"$2"@0x0 --transfer-mode=stream --stdin=no "$3" &
elif exists ueberzug; then
exec >/dev/tty
if [ "$NNN_TERMINAL" = "kitty" ] && [[ "$NNN_PREVIEWIMGPROG" == +(|icat) ]]; then
kitty +kitten icat --silent --scale-up --place "$1"x"$2"@0x0 --transfer-mode=stream --stdin=no "$3" &
elif [ "$NNN_TERMINAL" = "tmux" ] && [[ -n "$KITTY_LISTEN_ON" ]] && [[ "$NNN_PREVIEWIMGPROG" == +(|icat) ]]; then
kitty +kitten icat --silent --scale-up --place "$(($1 - 1))x$(($2 - 1))"@0x0 --transfer-mode=memory --stdin=no "$3" &
elif [ "$NNN_TERMINAL" = "wezterm" ] && [[ "$NNN_PREVIEWIMGPROG" == +(|imgcat) ]]; then
wezterm imgcat "$3" &
elif exists ueberzug && [[ "$NNN_PREVIEWIMGPROG" == +(|ueberzug) ]]; then
ueberzug_layer "$1" "$2" "$3" && return
elif exists catimg; then
elif exists catimg && [[ "$NNN_PREVIEWIMGPROG" == +(|catimg) ]]; then
catimg "$3" &
elif exists viu; then
elif exists viu && [[ "$NNN_PREVIEWIMGPROG" == +(|viu) ]]; then
viu -t "$3" &
elif exists chafa && [[ "$NNN_PREVIEWIMGPROG" == +(|chafa) ]]; then
chafa "$3" &
elif exists img2sixel && [[ "$NNN_PREVIEWIMGPROG" == +(|img2sixel) ]]; then
img2sixel -g "$3" &
else
fifo_pager print_bin_info "$3" && return
fi
printf "%s" "$!" > "$IMGPID"
} 2>/dev/null
printf "%s" "$!" > "$PREVIEWPID"
}
video_preview() {
clear
exec >/dev/tty
if [ -n "$NNN_PREVIEWVIDEO" ]; then
mpv --no-config --really-quiet --vo="$NNN_PREVIEWVIDEO" --profile=sw-fast --loop-file --no-audio "$4" "$3" &
else
ffmpegthumbnailer -m -s0 -i "$3" -o "$NNN_PREVIEWDIR/$3.jpg" || rm -- "$NNN_PREVIEWDIR/$3.jpg" &
fi
printf "%s" "$!" > "$PREVIEWPID"
}
ueberzug_layer() {
printf '{"action": "add", "identifier": "nnn_ueberzug", "x": 0, "y": 0, "width": "%d", "height": "%d", "scaler": "fit_contain", "path": "%s"}\n' "$1" "$2" "$3" > "$FIFO_UEBERZUG"
[ -f "$POSOFFSET" ] && read -r x y < "$POSOFFSET"
printf '{"action": "add", "identifier": "nnn_ueberzug", "x": %d, "y": %d, "width": "%d", "height": "%d", "scaler": "fit_contain", "path": "%s"}\n'\
"${x:-0}" "${y:-0}" "$1" "$2" "$3" > "$FIFO_UEBERZUG"
}
ueberzug_remove() {
@ -369,48 +489,49 @@ ueberzug_remove() {
winch_handler() {
clear
kill "$(cat "$IMGPID")" "$(cat "$PAGERPID")"
pidkill "$PREVIEWPID"
if [ -p "$FIFO_UEBERZUG" ]; then
pkill -P "$$"
pkill -f "tail --follow $FIFO_UEBERZUG"
tail --follow "$FIFO_UEBERZUG" | ueberzug layer --silent --parser json &
fi
cat "$CURSEL" > "$NNN_FIFO"
preview_file "$(cat "$CURSEL")"
preview_fifo &
wait "$!"
} 2>/dev/null
}
preview_fifo() {
printf "%s" "$$" > "$FIFOPID"
while read -r selection; do
kill "$(cat "$IMGPID")" "$(cat "$PAGERPID")"
[ -p "$FIFO_UEBERZUG" ] && ueberzug_remove
preview_file "$selection"
printf "%s" "$selection" > "$CURSEL"
if [ -n "$selection" ]; then
pidkill "$PREVIEWPID"
[ -p "$FIFO_UEBERZUG" ] && ueberzug_remove
[ "$selection" = "close" ] && break
preview_file "$selection"
printf "%s" "$selection" > "$CURSEL"
fi
done < "$NNN_FIFO"
} 2>/dev/null
sleep 0.1 # make sure potential preview by winch_handler is killed
pkill -P "$$"
}
if [ "$PREVIEW_MODE" ]; then
if [ "$TERMINAL" != "kitty" ] && exists ueberzug; then
if [ "$PREVIEW_MODE" -eq 1 ] 2>/dev/null; then
if exists ueberzug && [ "$NNN_TERMINAL" != "kitty" ] && [[ "$NNN_PREVIEWIMGPROG" == +(|ueberzug) ]]; then
mkfifo "$FIFO_UEBERZUG"
tail --follow "$FIFO_UEBERZUG" | ueberzug layer --silent --parser json &
fi
printf "%s" "$PWD/$1" > "$CURSEL"
preview_file "$PWD/$1"
preview_fifo &
preview_fifo & WAITPID=$!
printf "%s" "$!" > "$FIFOPID"
printf "%s" "$PWD/$1" > "$CURSEL"
trap 'winch_handler' WINCH
trap 'rm "$PAGERPID" "$IMGPID" "$CURSEL" "$FIFO_UEBERZUG" "$FIFOPID" 2>/dev/null' INT HUP EXIT
wait "$!" 2>/dev/null
trap 'rm -- "$PREVIEWPID" "$CURSEL" "$FIFO_UEBERZUG" "$FIFOPID" "$POSOFFSET" 2>/dev/null' INT HUP EXIT
while kill -s 0 $WAITPID; do
wait $WAITPID 2>/dev/null
done
exit 0
else
if [ ! -r "$NNN_FIFO" ]; then
clear
printf "No FIFO available! (\$NNN_FIFO='%s')\nPlease read Usage in preview-tui." "$NNN_FIFO"
cfg=$(stty -g); stty raw -echo; head -c 1; stty "$cfg"
elif [ "$KITTY_WINDOW_ID" ] && [ -z "$KITTY_LISTEN_ON" ]; then
clear
printf "\$KITTY_LISTEN_ON not set!\nPlease read Usage in preview-tui."
cfg=$(stty -g); stty raw -echo; head -c 1; stty "$cfg"
prompt "No FIFO available! (\$NNN_FIFO='$NNN_FIFO')\nPlease read Usage in '$0'."
elif [ "$KITTY_WINDOW_ID" ] && [ -z "$TMUX" ] && [ -z "$KITTY_LISTEN_ON" ]; then
prompt "\$KITTY_LISTEN_ON not set!\nPlease read Usage in '$0'."
else
toggle_preview "$1" &
fi

View File

@ -1,6 +1,6 @@
#!/usr/bin/env sh
# Description: Batch rename selection or current directory with qmv
# Description: Batch rename selection or current directory with qmv or vidir
#
# Notes:
# - Try to mimic current batch rename functionality but with correct

View File

@ -15,10 +15,10 @@ sel=${NNN_SEL:-${XDG_CONFIG_HOME:-$HOME/.config}/nnn/.selection}
# Choose one of these two schemes by commenting
# more verbose
xargs -0 -a "$sel" -I % rsync -ah --progress % "$PWD"
xargs -0 -I % rsync -ah --progress % "$PWD" < "$sel"
# less verbose
# xargs -0 -a "$sel" -I % rsync -ah --info=progress2 % "$PWD"
# xargs -0 -I % rsync -ah --info=progress2 % "$PWD" < "$sel"
# Clear selection
if [ -p "$NNN_PIPE" ]; then

View File

@ -26,7 +26,7 @@ if [ "$resp" = "j" ]; then
for entry in $arr
do
if [ -d "$entry" ]; then
echo "cant join directories"
echo "can't join directories"
exit
fi
done

View File

@ -8,9 +8,9 @@
EDITOR="${EDITOR:-vim}"
if type sudo >/dev/null 2>&1; then
sudo "$EDITOR" "$1"
sudo -E "$EDITOR" "$1"
elif type sudoedit >/dev/null 2>&1; then
sudoedit "$1"
sudoedit -E "$1"
elif type doas >/dev/null 2>&1; then
doas "$EDITOR" "$1"
fi

View File

@ -1,8 +0,0 @@
#!/usr/bin/env sh
# Description: Show tree output in $EDITOR
#
# Shell: POSIX compliant
# Author: Arun Prakash Jana
tree -ps | $EDITOR -

View File

@ -1,12 +0,0 @@
#!/usr/bin/env sh
# Description: list uid and gid of files
#
# Note: To list UID and GID of all users in a pretty format, run:
# cut -d':' -f1,3,4,5 < /etc/passwd | column -ts ":"
#
# Shell: POSIX compliant
# Authors: Arun Prakash Jana, superDuperCyberTechno
# shellcheck disable=SC2012
ls -lah --group-directories-first | less

View File

@ -1,25 +0,0 @@
#!/usr/bin/env sh
# Description: Check and update to latest version of nnn manually on Debian 9 Stretch
#
# Note: This script installs a package, should be issued with admin privilege
#
# Shell: POSIX compliant
# Author: Arun Prakash Jana
cur="$(nnn -v)"
new="$(curl -s "https://github.com/jarun/nnn/releases/latest" | grep -Eo "[0-9]+\.[0-9]+")"
if [ "$cur" = "$new" ]; then
echo 'Already at latest version'
exit 0
fi
# get the package
curl -Ls -O "https://github.com/jarun/nnn/releases/download/v$new/nnn_$new-1_debian9.amd64.deb"
# install it
sudo dpkg -i nnn_"$new"-1_debian9.amd64.deb
# remove the file
rm -rf nnn_"$new"-1_debian9.amd64.deb

View File

@ -1,6 +1,8 @@
#!/usr/bin/env sh
# Description: Upload to Firefox Send if ffsend is found, else
# Description: Selections are uploaded using Firefox Send
# For single files:
# Upload to Firefox Send if ffsend is found, else
# Paste contents of a text a file http://ix.io
# Upload a binary file to file.io
#
@ -11,20 +13,33 @@
# Shell: POSIX compliant
# Author: Arun Prakash Jana
if [ -n "$1" ] && [ -s "$1" ]; then
selection=${NNN_SEL:-${XDG_CONFIG_HOME:-$HOME/.config}/nnn/.selection}
if [ -s "$selection" ]; then
if type ffsend >/dev/null 2>&1; then
ffsend -fiq u "$1"
elif [ "$(mimetype --output-format %m "$1" | awk -F '/' '{print $1}')" = "text" ]; then
curl -F "f:1=@$1" ix.io
# File name will be randomized foo.tar
xargs -0 < "$selection" ffsend u
else
# Upload the file, show the download link and wait till user presses any key
curl -s -F "file=@$1" https://file.io/?expires=1w | jq '.link' | tr -d '"'
# To write download link to "$1".loc and exit
# curl -s -F "file=@$1" https://file.io/?expires=1w -o `basename "$1"`.loc
printf "ffsend is required to upload selection."
fi
# Clear selection
printf "-" > "$NNN_PIPE"
else
printf "empty file!"
if [ -n "$1" ] && [ -s "$1" ]; then
if type ffsend >/dev/null 2>&1; then
ffsend -fiq u "$1"
elif [ "$(mimetype --output-format %m "$1" | awk -F '/' '{print $1}')" = "text" ]; then
curl -F "f:1=@$1" ix.io
else
# Upload the file, show the download link and wait till user presses any key
curl -s -F "file=@$1" https://file.io/?expires=1w | jq '.link' | tr -d '"'
# To write download link to "$1".loc and exit
# curl -s -F "file=@$1" https://file.io/?expires=1w -o `basename "$1"`.loc
fi
else
printf "empty file!"
fi
fi
read -r _

View File

@ -1,26 +0,0 @@
#!/usr/bin/env sh
# Description: Set the selected image as wallpaper using nitrogen or pywal.
#
# Usage: Hover on an image and run the script to set it as wallpaper.
#
# Shell: POSIX compliant
# Author: juacq97
if [ -n "$1" ]; then
if [ "$(file --mime-type "$1" | awk '{print $NF}' | awk -F '/' '{print $1}')" = "image" ]; then
if type nitrogen >/dev/null 2>&1; then
nitrogen --set-zoom-fill --save "$1"
elif type wal >/dev/null 2>&1; then
wal -i "$1"
else
printf "nitrogen ir pywal missing"
read -r _
fi
# If you want a system notification, uncomment the next 3 lines.
# notify-send -a "nnn" "Wallpaper changed!"
# else
# notify-send -a "nnn" "No image selected"
fi
fi

45
plugins/wallpaper Executable file
View File

@ -0,0 +1,45 @@
#!/usr/bin/env sh
# Description: Set the selected image as wallpaper.
# Uses nitrogen or pywal on X11, swww on wayland.
#
# Usage: Hover on an image and run the script to set it as wallpaper.
#
# Shell: POSIX compliant
# Author: juacq97
resp=
if [ -n "$1" ]; then
if [ "$(file --mime-type "$1" | awk '{print $NF}' | awk -F '/' '{print $1}')" = "image" ]; then
if [ "$XDG_SESSION_TYPE" = "x11" ]; then
if type nitrogen >/dev/null 2>&1; then
printf "Set to full desktop or a specific monitors? [0, 1, etc. Defaults to full.]"
read -r resp
if [ "$resp" != "" ]; then
nitrogen --set-zoom-fill --save "$1" --head="$resp"
else
nitrogen --set-zoom-fill --save "$1"
fi
elif type wal >/dev/null 2>&1; then
wal -i "$1"
else
printf "nitrogen or pywal missing"
read -r _
fi
else
if type swww >/dev/null 2>&1; then
swww img "$1"
else
printf "swww missing"
read -r _
fi
fi
# If you want a system notification, uncomment the next 3 lines.
# notify-send -a "nnn" "Wallpaper changed!"
# else
# notify-send -a "nnn" "No image selected"
fi
fi

View File

@ -23,7 +23,10 @@ IFS="$(printf '%b_' '\n')"; IFS="${IFS%_}" # protect trailing \n
selection=${NNN_SEL:-${XDG_CONFIG_HOME:-$HOME/.config}/nnn/.selection}
getclip () {
if type xsel >/dev/null 2>&1; then
if [ "$XDG_SESSION_TYPE" = "wayland" ]; then
# Wayland
wl-paste
elif type xsel >/dev/null 2>&1; then
# Linux
xsel -bo
elif type xclip >/dev/null 2>&1; then
@ -41,9 +44,6 @@ getclip () {
elif [ -r /dev/clipboard ] ; then
# Cygwin
cat /dev/clipboard
elif type wl-paste >/dev/null 2>&1; then
# Wayland
wl-paste
elif type clipboard >/dev/null 2>&1; then
# Haiku
clipboard --print

View File

@ -5,12 +5,21 @@
# defaults if unset, as specified in XDG Base Directory Specification
# - http://specifications.freedesktop.org/basedir-spec/.
#
# Dependencies: xdg-utils, fzf
# Dependencies: xdg-utils, fzf or dmenu (GUI)
#
# Shell: POSIX compliant
# Author: lwnctd
if [ -z "$1" ] || ! command -v fzf > /dev/null 2>& 1; then
# set to 1 to enable GUI apps
GUI="${GUI:-0}"
if [ "$GUI" -ne 0 ] && command -v dmenu > /dev/null 2>& 1; then
menu="dmenu -i -l 7"
elif command -v fzf > /dev/null 2>& 1; then
menu="fzf -e --tiebreak=begin"
fi
if [ -z "$1" ] || [ -z "$menu" ] > /dev/null 2>& 1; then
exit 1
fi
@ -33,12 +42,12 @@ done
app=$(find "$@" -iname '*.desktop' -exec grep '^Name=' {} + \
| sort -u -t ':' -k 1,1 \
| sed -E 's;.+/(.+desktop):Name=(.+);\2:\1;' \
| sed -e 's;..*/\(..*desktop\):Name=\(..*\);\2:\1;' \
| sort -t ':' -k 1,1 \
| column -t -s ':' -o "$(printf '\t')" \
| fzf -e --tiebreak=begin \
| $menu \
| cut -f 2)
if [ -n "$app" ]; then
xdg-mime default "$app" "$ftype"
xdg-mime default "${app%%[[:blank:]]*}" "$ftype"
fi

View File

@ -1,5 +1,35 @@
---
Checks: 'clang-diagnostic-*,clang-analyzer-*,readability-*,modernize-*,bugprone-*,misc-*,-misc-unused-parameters,google-runtime-int,-llvm-header-guard,fuchsia-restrict-system-includes,-clang-analyzer-valist.Uninitialized,-clang-analyzer-security.insecureAPI.DeprecatedOrUnsafeBufferHandling,-clang-analyzer-security.insecureAPI.rand,-clang-analyzer-alpha.*,-readability-magic-numbers,-readability-braces-around-statements,-readability-function-cognitive-complexity,-readability-isolate-declaration,-bugprone-narrowing-conversions,-bugprone-reserved-identifier'
Checks: >
clang-diagnostic-*,
clang-analyzer-*,
readability-*,
modernize-*,
bugprone-*,
misc-*,
google-runtime-int,
fuchsia-restrict-system-includes,
-misc-unused-parameters,
-misc-include-cleaner,
-llvm-header-guard,
-clang-analyzer-valist.Uninitialized,
-clang-analyzer-security.insecureAPI.DeprecatedOrUnsafeBufferHandling,
-clang-analyzer-security.insecureAPI.rand,
-clang-analyzer-alpha.*,
-modernize-macro-to-enum,
-readability-magic-numbers,
-readability-braces-around-statements,
-readability-function-cognitive-complexity,
-readability-identifier-length,
-readability-isolate-declaration,
-readability-suspicious-call-argument,
-readability-avoid-nested-conditional-operator,
-bugprone-easily-swappable-parameters,
-bugprone-narrowing-conversions,
-bugprone-reserved-identifier,
-bugprone-switch-missing-default-case,
-bugprone-inc-dec-in-conditions,
-bugprone-multi-level-implicit-pointer-conversion,
WarningsAsErrors: '*'
HeaderFilterRegex: '.*(?<!lookup3.c)$'
FormatStyle: 'file'
@ -11,5 +41,5 @@ CheckOptions:
- key: fuchsia-restrict-system-includes.Includes
value: '*,-stdint.h,-stdbool.h'
- key: readability-function-size.StatementThreshold
value: '900'
value: '950'
...

View File

@ -3,7 +3,7 @@
*
* Copyright (C) 2014-2016, Lazaros Koromilas <lostd@2f30.org>
* Copyright (C) 2014-2016, Dimitris Papastamos <sin@2f30.org>
* Copyright (C) 2016-2021, Arun Prakash Jana <engineerarun@gmail.com>
* Copyright (C) 2016-2023, Arun Prakash Jana <engineerarun@gmail.com>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -79,10 +79,10 @@ static void disabledbg(void)
#define STRINGIFY(x) #x
#define TOSTRING(x) STRINGIFY(x)
#define DPRINTF_D(x) xprintf(DEBUG_FD, "ln " TOSTRING(__line__) ": " #x "=%d\n", x)
#define DPRINTF_U(x) xprintf(DEBUG_FD, "ln " TOSTRING(__line__) ": " #x "=%u\n", x)
#define DPRINTF_S(x) xprintf(DEBUG_FD, "ln " TOSTRING(__line__) ": " #x "=%s\n", x)
#define DPRINTF_P(x) xprintf(DEBUG_FD, "ln " TOSTRING(__line__) ": " #x "=%p\n", x)
#define DPRINTF_D(x) xprintf(DEBUG_FD, "ln " TOSTRING(__LINE__) ": " #x "=%d\n", x)
#define DPRINTF_U(x) xprintf(DEBUG_FD, "ln " TOSTRING(__LINE__) ": " #x "=%u\n", x)
#define DPRINTF_S(x) xprintf(DEBUG_FD, "ln " TOSTRING(__LINE__) ": " #x "=%s\n", x)
#define DPRINTF_P(x) xprintf(DEBUG_FD, "ln " TOSTRING(__LINE__) ": " #x "=%p\n", x)
#else
#define DPRINTF_D(x)
#define DPRINTF_U(x)

291
src/icons-hash.c Normal file
View File

@ -0,0 +1,291 @@
/*
* simple program which outputs a hash-table of `icons_ext` with low collusion.
* the hash function is case-insensitive, it also doesn't hash beyond the
* length of the longest extension.
*/
#include <stddef.h>
#include <stdint.h>
#include <inttypes.h>
#define GOLDEN_RATIO_32 UINT32_C(2654442313) /* golden ratio for 32bits: (2^32) / 1.61803 */
#define GOLDEN_RATIO_64 UINT64_C(0x9E3793492EEDC3F7)
#define ICONS_TABLE_SIZE 8 /* size in bits. 8 = 256 */
#ifndef TOUPPER
#define TOUPPER(ch) (((ch) >= 'a' && (ch) <= 'z') ? ((ch) - 'a' + 'A') : (ch))
#endif
/* all of this is just for the static hash-table generation. only the hash
* function gets included in `nnn` binary.
*/
#ifdef ICONS_GENERATE
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <limits.h>
#include "icons.h"
/* like assert, but always sticks around during generation. */
#define ENSURE(X) do { \
if (!(X)) { \
fprintf(stderr, "%s:%d: `%s`\n", __FILE__, __LINE__, #X); \
abort(); \
} \
} while (0)
#define ARRLEN(X) (sizeof(X) / sizeof((X)[0]))
#define MAX(A, B) ((A) > (B) ? (A) : (B))
#define HGEN_ITERARATION (1ul << 13)
#define ICONS_PROBE_MAX_ALLOWED 6
#define ICONS_MATCH_MAX (512)
#if 0 /* for logging some interesting info to stderr */
#define log(...) fprintf(stderr, "[INFO]: " __VA_ARGS__)
#else
#define log(...) ((void)0)
#endif
static uint32_t icon_ext_hash(const char *s);
/* change ICONS_TABLE_SIZE to increase the size of the table */
static struct icon_pair table[1u << ICONS_TABLE_SIZE];
static uint8_t seen[ARRLEN(table)];
/* arbitrarily picked starting position. change if needed.
* but ensure they're above 1 and prefer prime numbers.
*/
static uint32_t hash_start = 7;
static uint32_t hash_mul = 251; /* unused as of now */
/*
* use robin-hood insertion to reduce the max probe length
*/
static void
rh_insert(const struct icon_pair item, uint32_t idx, uint32_t n)
{
ENSURE(n != 0);
for (uint32_t tries = 0; tries < ARRLEN(table); ++tries, ++n) {
if (seen[idx] < n) {
struct icon_pair tmp_item = table[idx];
uint32_t tmp_n = seen[idx];
ENSURE(n < (uint8_t)-1);
table[idx] = item;
seen[idx] = n;
if (tmp_n != 0) /* the slot we inserted to wasn't empty */
rh_insert(tmp_item, idx, tmp_n);
return;
}
idx = (idx + 1) % ARRLEN(table);
}
ENSURE(0 && "unreachable");
}
enum { PROBE_MAX, PROBE_TOTAL, PROBE_CNT };
static unsigned int *
table_populate(unsigned int p[static PROBE_CNT])
{
memset(seen, 0x0, sizeof seen);
memset(table, 0x0, sizeof table);
for (size_t i = 0; i < ARRLEN(icons_ext); ++i) {
if (icons_ext[i].icon[0] == '\0') /* skip empty entries */
continue;
uint32_t h = icon_ext_hash(icons_ext[i].match);
rh_insert(icons_ext[i], h, 1);
}
p[PROBE_MAX] = p[PROBE_TOTAL] = 0;
for (size_t i = 0; i < ARRLEN(seen); ++i) {
p[PROBE_MAX] = MAX(p[PROBE_MAX], seen[i]);
p[PROBE_TOTAL] += seen[i];
}
return p;
}
/* permuted congruential generator */
static uint32_t
pcg(uint64_t *state)
{
uint64_t oldstate = *state;
*state *= GOLDEN_RATIO_64;
uint32_t r = (oldstate >> 59);
uint32_t v = (oldstate ^ (oldstate >> 18)) >> 27;
return (v >> (-r & 31)) | (v << r);
}
int
main(void)
{
ENSURE(ARRLEN(icons_ext) <= ARRLEN(table));
ENSURE(ICONS_TABLE_SIZE < 16);
ENSURE(1u << ICONS_TABLE_SIZE == ARRLEN(table));
ENSURE((GOLDEN_RATIO_32 & 1) == 1); /* must be odd */
ENSURE((GOLDEN_RATIO_64 & 1) == 1); /* must be odd */
ENSURE(hash_start > 1);
ENSURE(hash_mul > 1);
/* ensure power of 2 hashtable size which allows compiler to optimize
* away mod (`%`) operations
*/
ENSURE((ARRLEN(table) & (ARRLEN(table) - 1)) == 0);
unsigned int max_probe = (unsigned)-1;
uint32_t best_hash_start = 0, best_hash_mul = 0, best_total_probe = 9999;
uint64_t hash_start_rng = hash_start, hash_mul_rng = hash_mul;
for (size_t i = 0; i < HGEN_ITERARATION; ++i) {
unsigned *p = table_populate((unsigned [PROBE_CNT]){0});
if (p[PROBE_MAX] < max_probe ||
(p[PROBE_MAX] == max_probe && p[PROBE_TOTAL] < best_total_probe))
{
max_probe = p[PROBE_MAX];
best_total_probe = p[PROBE_TOTAL];
best_hash_start = hash_start;
best_hash_mul = hash_mul;
}
hash_start = pcg(&hash_start_rng);
hash_mul = pcg(&hash_mul_rng);
}
ENSURE(max_probe < ICONS_PROBE_MAX_ALLOWED);
hash_start = best_hash_start;
hash_mul = best_hash_mul;
{
unsigned *p = table_populate((unsigned [PROBE_CNT]){0});
ENSURE(p[PROBE_MAX] == max_probe);
ENSURE(p[PROBE_TOTAL] == best_total_probe);
}
/* sanity check */
double nitems = 0;
unsigned int total_probe = 0;
for (size_t i = 0; i < ARRLEN(icons_ext); ++i) {
if (icons_ext[i].icon[0] == 0)
continue;
uint32_t found = 0, h = icon_ext_hash(icons_ext[i].match);
for (uint32_t k = 0; k < max_probe; ++k) {
uint32_t z = (h + k) % ARRLEN(table);
++total_probe;
if (table[z].match && strcasecmp(icons_ext[i].match, table[z].match) == 0) {
found = 1;
break;
}
}
ENSURE(found);
++nitems;
}
ENSURE(total_probe == best_total_probe);
size_t match_max = 0, icon_max = 0;
for (size_t i = 0; i < ARRLEN(icons_name); ++i) {
match_max = MAX(match_max, strlen(icons_name[i].match) + 1);
icon_max = MAX(icon_max, strlen(icons_name[i].icon) + 1);
}
for (size_t i = 0; i < ARRLEN(icons_ext); ++i) {
match_max = MAX(match_max, strlen(icons_ext[i].match) + 1);
icon_max = MAX(icon_max, strlen(icons_ext[i].icon) + 1);
}
icon_max = MAX(icon_max, strlen(dir_icon.icon) + 1);
icon_max = MAX(icon_max, strlen(exec_icon.icon) + 1);
icon_max = MAX(icon_max, strlen(file_icon.icon) + 1);
ENSURE(icon_max < ICONS_MATCH_MAX);
const char *uniq[ARRLEN(icons_ext)] = {0};
size_t uniq_head = 0;
for (size_t i = 0; i < ARRLEN(icons_ext); ++i) {
if (icons_ext[i].icon[0] == 0)
continue;
int isuniq = 1;
for (size_t k = 0; k < uniq_head; ++k) {
if (strcasecmp(uniq[k], icons_ext[i].icon) == 0) {
isuniq = 0;
break;
}
}
if (isuniq) {
ENSURE(uniq_head < ARRLEN(uniq));
uniq[uniq_head++] = icons_ext[i].icon;
}
}
ENSURE(uniq_head < (unsigned char)-1);
log("load-factor: %.2f (%u/%zu)\n", (nitems * 100.0) / (double)ARRLEN(table),
(unsigned int)nitems, ARRLEN(table));
log("max_probe : %6u\n", max_probe);
log("total_probe: %6u\n", total_probe);
log("uniq icons : %6zu\n", uniq_head);
log("no-compact : %6zu bytes\n", ARRLEN(table) * icon_max);
log("compaction : %6zu bytes\n", uniq_head * icon_max + ARRLEN(table));
log("hash_start : %6" PRIu32 "\n", hash_start);
log("hash_mul : %6" PRIu32 "\n", hash_mul);
printf("#ifndef INCLUDE_ICONS_GENERATED\n");
printf("#define INCLUDE_ICONS_GENERATED\n\n");
printf("/*\n * NOTE: This file is automatically generated.\n");
printf(" * DO NOT EDIT THIS FILE DIRECTLY.\n");
printf(" * Use `icons.h` to customize icons\n */\n\n");
printf("#define hash_start UINT32_C(%" PRIu32 ")\n", hash_start);
printf("#define hash_mul UINT32_C(%" PRIu32 ")\n\n", hash_mul);
printf("#define ICONS_PROBE_MAX %uu\n", max_probe);
printf("#define ICONS_MATCH_MAX %zuu\n\n", match_max);
printf("#define ICONS_STR_MAX %zuu\n\n", icon_max);
printf("struct icon_pair { const char match[ICONS_MATCH_MAX]; "
"const char icon[ICONS_STR_MAX]; unsigned char color; };\n\n");
printf("static const char icons_ext_uniq[%zu][ICONS_STR_MAX] = {\n", uniq_head);
for (size_t i = 0; i < uniq_head; ++i)
printf("\t\"%s\",\n", uniq[i]);
printf("};\n\n");
printf("static const struct {\n\tconst char match[ICONS_MATCH_MAX];\n"
"\tunsigned char idx;\n\tunsigned char color;\n} icons_ext[%zu] = {\n",
ARRLEN(table));
for (size_t i = 0; i < ARRLEN(table); ++i) {
if (table[i].icon == NULL || table[i].icon[0] == '\0') /* skip empty entries */
continue;
size_t k;
for (k = 0; k < uniq_head; ++k) {
if (strcasecmp(table[i].icon, uniq[k]) == 0)
break;
}
ENSURE(k < uniq_head);
printf("\t[%3zu] = {\"%s\", %zu, %hhu },\n",
i, table[i].match, k, table[i].color);
}
printf("};\n\n");
printf("#endif /* INCLUDE_ICONS_GENERATED */\n");
}
#else
#define ENSURE(X) ((void)0)
#endif /* ICONS_GENERATE */
#if defined(ICONS_GENERATE) || defined(ICONS_ENABLED)
static uint32_t
icon_ext_hash(const char *str)
{
uint32_t i, hash = hash_start;
enum { wsz = sizeof hash * CHAR_BIT, z = wsz - ICONS_TABLE_SIZE, r = 5 };
/* just an xor-rotate hash. in general, this is a horrible hash
* function but for our specific input it works fine while being
* computationally cheap.
*/
for (i = 0; i < ICONS_MATCH_MAX && str[i] != '\0'; ++i) {
hash ^= TOUPPER((unsigned char)str[i]);
hash = (hash >> (wsz - r)) | (hash << r);
}
/* finalizer: https://probablydance.com/2018/06/16 */
hash ^= (hash >> z);
hash *= GOLDEN_RATIO_32;
hash >>= z;
ENSURE(hash < ARRLEN(table));
return hash;
}
#endif

View File

@ -1,261 +0,0 @@
#ifndef ICONS_NERDFONT
#define ICONS_NERDFONT
// You can find hex codes for nerd fonts here
// https://www.nerdfonts.com/cheat-sheet
// Arrows
#define MD_ARROW_UPWARD "\uf55c"
#define MD_ARROW_FORWARD "\uf553"
#define MD_ARROW_DOWNWARD "\uf544"
// Generics
#define ICON_DIRECTORY "\ue5ff"
#define ICON_FILE "\uf713"
#define ICON_EXEC "\uf144"
#define ICON_MANUAL "\uf5bd"
// Top level and common icons
#define ICON_GIT "\ue5fb"
#define ICON_DESKTOP "\ufcbe"
#define ICON_BRIEFCASE "\uf5d5"
#define ICON_DOCUMENT "\uf718"
#define ICON_DOWNLOADS "\uf5d7"
#define ICON_MUSIC "\uf832"
#define ICON_MUSICFILE "\uf886"
#define ICON_PICTURES "\uf753"
#define ICON_PICTUREFILE "\uf71e"
#define ICON_PUBLIC "\ue5ff"
#define ICON_TEMPLATES "\ufac6"
#define ICON_VIDEOS "\uf72f"
#define ICON_VIDEOFILE "\ufcdc"
#define ICON_CHANGELOG "\uf7d9"
#define ICON_CONFIGURE "\uf423"
#define ICON_LICENSE "\uf718"
#define ICON_MAKEFILE "\uf68c"
#define ICON_ARCHIVE "\uf53b"
#define ICON_SCRIPT "\ue795"
#define ICON_CPLUSPLUS "\ue61d"
#define ICON_JAVA "\ue738"
#define ICON_CLOJURE "\ue76a"
#define ICON_JAVASCRIPT "\ue74e"
#define ICON_LINUX "\uf83c"
#define ICON_FSHARP "\ue7a7"
#define ICON_RUBY "\ue23e"
#define ICON_C "\ue61e"
#define ICON_CHESS "\uf639"
#define ICON_HASKELL "\ue777"
#define ICON_HTML "\uf72d"
#define ICON_REACT "\ue625"
#define ICON_PYTHON "\ue235"
#define ICON_DATABASE "\uf6b7"
#define ICON_WORDDOC "\uf72b"
#define ICON_PLAYLIST "\uf910"
#define ICON_OPTICALDISK "\ue271"
/* Numbers */
#define ICON_EXT_1 ICON_MANUAL
#define ICON_EXT_7Z ICON_ARCHIVE
/* A */
#define ICON_EXT_A ICON_MANUAL
#define ICON_EXT_APK ICON_ARCHIVE
#define ICON_EXT_ASM ICON_FILE
#define ICON_EXT_AUP ICON_MUSICFILE
#define ICON_EXT_AVI ICON_VIDEOFILE
/* B */
#define ICON_EXT_BAT ICON_SCRIPT
#define ICON_EXT_BIN "\uf471"
#define ICON_EXT_BMP ICON_PICTUREFILE
#define ICON_EXT_BZ2 ICON_ARCHIVE
/* C */
#define ICON_EXT_C ICON_C
#define ICON_EXT_CPLUSPLUS ICON_CPLUSPLUS
#define ICON_EXT_CAB ICON_ARCHIVE
#define ICON_EXT_CBR ICON_ARCHIVE
#define ICON_EXT_CBZ ICON_ARCHIVE
#define ICON_EXT_CC ICON_CPLUSPLUS
#define ICON_EXT_CLASS ICON_JAVA
#define ICON_EXT_CLJ ICON_CLOJURE
#define ICON_EXT_CLJC ICON_CLOJURE
#define ICON_EXT_CLJS ICON_CLOJURE
#define ICON_EXT_CMAKE ICON_MAKEFILE
#define ICON_EXT_COFFEE "\ue751"
#define ICON_EXT_CONF ICON_CONFIGURE
#define ICON_EXT_CPIO ICON_ARCHIVE
#define ICON_EXT_CPP ICON_CPLUSPLUS
#define ICON_EXT_CSS "\ue614"
#define ICON_EXT_CUE ICON_PLAYLIST
#define ICON_EXT_CVS ICON_CONFIGURE
#define ICON_EXT_CXX ICON_CPLUSPLUS
/* D */
#define ICON_EXT_DB ICON_DATABASE
#define ICON_EXT_DEB "\ue77d"
#define ICON_EXT_DIFF "\uf440"
#define ICON_EXT_DLL ICON_SCRIPT
#define ICON_EXT_DOC ICON_WORDDOC
#define ICON_EXT_DOCX ICON_WORDDOC
/* E */
#define ICON_EXT_EJS ICON_JAVASCRIPT
#define ICON_EXT_ELF ICON_LINUX
#define ICON_EXT_EPUB ICON_MANUAL
#define ICON_EXT_EXE ICON_EXEC
/* F */
#define ICON_EXT_FEN ICON_CHESS
#define ICON_EXT_FSHARP ICON_FSHARP
#define ICON_EXT_FLAC ICON_MUSICFILE
#define ICON_EXT_FLV ICON_VIDEOFILE
#define ICON_EXT_FS ICON_FSHARP
#define ICON_EXT_FSI ICON_FSHARP
#define ICON_EXT_FSSCRIPT ICON_FSHARP
#define ICON_EXT_FSX ICON_FSHARP
/* G */
#define ICON_EXT_GEM ICON_RUBY
#define ICON_EXT_GIF ICON_PICTUREFILE
#define ICON_EXT_GO "\ufcd1"
#define ICON_EXT_GZ ICON_ARCHIVE
#define ICON_EXT_GZIP ICON_ARCHIVE
/* H */
#define ICON_EXT_H ICON_C
#define ICON_EXT_HH ICON_CPLUSPLUS
#define ICON_EXT_HPP ICON_CPLUSPLUS
#define ICON_EXT_HS ICON_HASKELL
#define ICON_EXT_HTACCESS ICON_CONFIGURE
#define ICON_EXT_HTPASSWD ICON_CONFIGURE
#define ICON_EXT_HTM ICON_HTML
#define ICON_EXT_HTML ICON_HTML
#define ICON_EXT_HXX ICON_CPLUSPLUS
/* I */
#define ICON_EXT_ICO ICON_PICTUREFILE
#define ICON_EXT_IMG ICON_OPTICALDISK
#define ICON_EXT_INI ICON_CONFIGURE
#define ICON_EXT_ISO ICON_OPTICALDISK
/* J */
#define ICON_EXT_JAR ICON_JAVA
#define ICON_EXT_JAVA ICON_JAVA
#define ICON_EXT_JL ICON_CONFIGURE
#define ICON_EXT_JPEG ICON_PICTUREFILE
#define ICON_EXT_JPG ICON_PICTUREFILE
#define ICON_EXT_JS ICON_JAVASCRIPT
#define ICON_EXT_JSON "\ufb25"
#define ICON_EXT_JSX ICON_REACT
/* K */
/* L */
#define ICON_EXT_LHA ICON_ARCHIVE
#define ICON_EXT_LHS ICON_HASKELL
#define ICON_EXT_LOG ICON_DOCUMENT
#define ICON_EXT_LUA "\ue620"
#define ICON_EXT_LZH ICON_ARCHIVE
#define ICON_EXT_LZMA ICON_ARCHIVE
/* M */
#define ICON_EXT_M4A ICON_MUSICFILE
#define ICON_EXT_M4V ICON_VIDEOFILE
#define ICON_EXT_MD "\ue609"
#define ICON_EXT_MK ICON_MAKEFILE
#define ICON_EXT_MKV ICON_VIDEOFILE
#define ICON_EXT_MOV ICON_VIDEOFILE
#define ICON_EXT_MP3 ICON_MUSICFILE
#define ICON_EXT_MP4 ICON_VIDEOFILE
#define ICON_EXT_MPEG ICON_VIDEOFILE
#define ICON_EXT_MPG ICON_VIDEOFILE
#define ICON_EXT_MSI "\uf871"
/* N */
/* O */
#define ICON_EXT_O ICON_MANUAL
#define ICON_EXT_OGG ICON_MUSICFILE
#define ICON_EXT_ODOWNLOAD ICON_DOWNLOADS
#define ICON_EXT_OUT ICON_LINUX
/* P */
#define ICON_EXT_PART ICON_DOWNLOADS
#define ICON_EXT_PATCH "\uf440"
#define ICON_EXT_PDF "\uf724"
#define ICON_EXT_PGN ICON_CHESS
#define ICON_EXT_PHP "\ue73d"
#define ICON_EXT_PNG ICON_PICTUREFILE
#define ICON_EXT_PPT "\uf726"
#define ICON_EXT_PPTX "\uf726"
#define ICON_EXT_PSB "\ue7b8"
#define ICON_EXT_PSD "\ue7b8"
#define ICON_EXT_PY ICON_PYTHON
#define ICON_EXT_PYC ICON_PYTHON
#define ICON_EXT_PYD ICON_PYTHON
#define ICON_EXT_PYO ICON_PYTHON
/* Q */
/* R */
#define ICON_EXT_RAR ICON_ARCHIVE
#define ICON_EXT_RC ICON_CONFIGURE
#define ICON_EXT_ROM "\uf795"
#define ICON_EXT_RPM ICON_ARCHIVE
#define ICON_EXT_RSS "\uf96b"
#define ICON_EXT_RTF "\uf724"
/* S */
#define ICON_EXT_SASS "\ue603"
#define ICON_EXT_SCSS "\ue603"
#define ICON_EXT_SO ICON_MANUAL
#define ICON_EXT_SCALA "\ue737"
#define ICON_EXT_SH ICON_SCRIPT
#define ICON_EXT_SLIM ICON_SCRIPT
#define ICON_EXT_SLN "\ue70c"
#define ICON_EXT_SQL ICON_DATABASE
#define ICON_EXT_SRT "\uf679"
#define ICON_EXT_SUB "\uf679"
#define ICON_EXT_SVG ICON_PICTUREFILE
/* T */
#define ICON_EXT_TAR ICON_ARCHIVE
#define ICON_EXT_TEX "\uf6fc"
#define ICON_EXT_TGZ ICON_ARCHIVE
#define ICON_EXT_TS "\ue628"
#define ICON_EXT_TSX ICON_REACT
#define ICON_EXT_TXT ICON_DOCUMENT
#define ICON_EXT_TXZ ICON_ARCHIVE
/* U */
/* V */
#define ICON_EXT_VID ICON_VIDEOFILE
#define ICON_EXT_VIM "\ue62b"
#define ICON_EXT_VIMRC "\ue62b"
/* W */
#define ICON_EXT_WAV ICON_MUSICFILE
#define ICON_EXT_WEBM ICON_VIDEOFILE
#define ICON_EXT_WMA ICON_VIDEOFILE
#define ICON_EXT_WMV ICON_VIDEOFILE
/* X */
#define ICON_EXT_XBPS ICON_ARCHIVE
#define ICON_EXT_XCF ICON_PICTUREFILE
#define ICON_EXT_XHTML ICON_HTML
#define ICON_EXT_XLS "\uf71a"
#define ICON_EXT_XLSX "\uf71a"
#define ICON_EXT_XML ICON_HTML
#define ICON_EXT_XZ ICON_ARCHIVE
/* Y */
#define ICON_EXT_YAML ICON_CONFIGURE
#define ICON_EXT_YML ICON_CONFIGURE
/* Z */
#define ICON_EXT_ZIP ICON_ARCHIVE
#endif // ICONS_NERDFONT

View File

@ -1,513 +1,445 @@
#pragma once
#ifndef INCLUDE_ICONS_H
#define INCLUDE_ICONS_H
#if defined(ICONS)
#include "icons-in-terminal.h"
#if defined(ICONS_GENERATE) || defined(ICONS_ENABLED)
/*
* 1st arg = ICONS_IN_TERM
*
* 2nd arg = NERD ICONS
* You can find hex codes for nerd fonts here: https://www.nerdfonts.com/cheat-sheet
*
* 3rd arg = EMOJIS
* You can find a list of emoji here: https://unicode.org/Public/emoji/5.0/emoji-test.txt
*
* Any entry with empty icon gets removed by the hash-table generator
*/
#if defined(ICONS_IN_TERM)
#define ICON_STR(I, N, E) I
#include "icons-in-terminal.h"
#elif defined(NERD)
#include "icons-nerdfont.h"
#define ICON_STR(I, N, E) N
#elif defined(EMOJI)
#define ICON_STR(I, N, E) E
#endif
struct icon_pair {
const char *match;
const char *icon;
/*
* Hex xterm 256 color code, 0 to follow file specific (if any)
* Codes: https://jonasjacek.github.io/colors/
* Spectrum sorted: https://upload.wikimedia.org/wikipedia/commons/1/15/Xterm_256color_chart.svg
*/
const unsigned char color;
};
/*
* Define a string to be printed before and after the icon
* Adjust if the icons are not printed properly
*/
#if defined(EMOJI)
/*
* NOTE: As some emojis take up two cells, all of the emoji icons must
* be of width 2. Therefore, right pad single-width emoji with a space.
*/
#define ICON_SIZE 2
#define ICON_PADDING_RIGHT " "
#else
#define ICON_SIZE 1
#define ICON_PADDING_RIGHT " "
#endif
#define ICON_PADDING_LEFT ""
#define ICON_PADDING_RIGHT " "
#define ICON_PADDING_LEFT_LEN (sizeof ICON_PADDING_LEFT - 1)
#define ICON_PADDING_RIGHT_LEN (sizeof ICON_PADDING_RIGHT - 1)
/* ARROWS */
#define ICON_ARROW_UP ICON_STR(MD_ARROW_UPWARD, "󰁝", "⬆")
#define ICON_ARROW_FORWARD ICON_STR(MD_ARROW_FORWARD, "󰁔", "➡")
#define ICON_ARROW_DOWN ICON_STR(MD_ARROW_DOWNWARD, "󰁅", "⬇")
/* GENERIC */
#define ICON_DIRECTORY ICON_STR(FA_FOLDER, "", "📂")
#define ICON_FILE ICON_STR(FA_FILE, "󰈔", "📃")
#define ICON_EXEC ICON_STR(FA_COG, "", "⚙️ ")
/* Top level and common icons */
#define ICON_ARCHIVE ICON_STR(FA_FILE_ARCHIVE_O, "󰀼", "📦")
#define ICON_BRIEFCASE ICON_STR(FA_BRIEFCASE, "󰃖", "💼")
#define ICON_C ICON_STR(MFIZZ_C, "", "🇨 ")
#define ICON_CHANGELOG ICON_STR(FA_HISTORY, "󰋚", "🔺")
#define ICON_CHESS ICON_STR("", "󰄺", "")
#define ICON_CLOJURE ICON_STR(MFIZZ_CLOJURE, "", "")
#define ICON_CONFIGURE ICON_STR(FILE_CONFIG, "", "🔧")
#define ICON_CPLUSPLUS ICON_STR(MFIZZ_CPLUSPLUS, "", ICON_C)
#define ICON_DATABASE ICON_STR(MFIZZ_DATABASE_ALT2, "󰆼", "🗃️ ")
#define ICON_DESKTOP ICON_STR(FA_DESKTOP, "󰟀", "🖥️ ")
#define ICON_DJVU ICON_STR(FA_PAPERCLIP, "", "📎")
#define ICON_DOCUMENT ICON_STR(FA_FILE_TEXT_O, "󰈙", "🗒 ")
#define ICON_DOWNLOADS ICON_STR(FA_DOWNLOAD, "󰃘", "📥")
#define ICON_ELIXIR ICON_STR(MFIZZ_ELIXIR, "", "💧")
#define ICON_ENCRYPT ICON_STR("", "󰌆", "🔒")
#define ICON_FSHARP ICON_STR(DEV_FSHARP, "", "")
#define ICON_FONT ICON_STR(FILE_FONT, "", "")
#define ICON_GIT ICON_STR(FA_GIT, "", "🌱")
#define ICON_HASKELL ICON_STR("", "", "")
#define ICON_HTML ICON_STR(FA_FILE_CODE_O, "󰌝", "")
#define ICON_JAVA ICON_STR(MFIZZ_JAVA, "", "☕")
#define ICON_JAVASCRIPT ICON_STR(FA_FILE_CODE_O, "󰌞", "")
#define ICON_LICENSE ICON_STR(FA_COPYRIGHT, "󰈙", "⚖️ ")
#define ICON_LINUX ICON_STR(FA_LINUX, "󰌽", "🐧")
#define ICON_MAKEFILE ICON_STR(FILE_CMAKE, "󰆍", "🛠 ")
#define ICON_MANUAL ICON_STR(FILE_MANPAGE, "󱓷", "❓")
#define ICON_MS_EXCEL ICON_STR(FILE_EXCEL, "󰈛", ICON_WORDDOC)
#define ICON_MUSIC ICON_STR(FA_MUSIC, "󱍙", "🎧")
#define ICON_MUSICFILE ICON_STR(FA_FILE_AUDIO_O, "󰎈", ICON_MUSIC)
#define ICON_OPTICALDISK ICON_STR(LINEA_MUSIC_CD, "", "💿")
#define ICON_PDF ICON_STR(FA_FILE_PDF_O, "󰈦", "📕")
#define ICON_PHOTOSHOP ICON_STR(DEV_PHOTOSHOP, "", ICON_PICTUREFILE)
#define ICON_PICTUREFILE ICON_STR(FA_FILE_IMAGE_O, "󰈟", ICON_PICTURES)
#define ICON_PICTURES ICON_STR(MD_CAMERA_ALT, "󰉔", "🎨")
#define ICON_PLAYLIST ICON_STR(ICON_MUSICFILE, "󱍙", "")
#define ICON_POWERPOINT ICON_STR(FILE_POWERPOINT, "󰈧", "📊")
#define ICON_PUBLIC ICON_STR(FA_INBOX, "", "👀")
#define ICON_PYTHON ICON_STR(MFIZZ_PYTHON, "", "🐍")
#define ICON_REACT ICON_STR(FILE_JSX, "", ICON_JAVASCRIPT)
#define ICON_RUBY ICON_STR(MFIZZ_RUBY, "", "💎")
#define ICON_RUST ICON_STR(DEV_RUST, "", "")
#define ICON_SASS ICON_STR("", "", "")
#define ICON_SCRIPT ICON_STR(MFIZZ_SCRIPT, "", "📜")
#define ICON_SUBTITLE ICON_STR(FA_COMMENTS_O, "󰅺", "💬")
#define ICON_TEMPLATES ICON_STR(FA_PAPERCLIP, "󰗇", "📎")
#define ICON_TEX ICON_STR(FILE_TEX, "󰙩", ICON_DOCUMENT)
#define ICON_VIDEOFILE ICON_STR(FA_FILE_MOVIE_O, "󰈫", ICON_VIDEOS)
#define ICON_VIDEOS ICON_STR(FA_FILM, "󰈰", "🎞 ")
#define ICON_VIM ICON_STR(DEV_VIM, "", "")
#define ICON_WORDDOC ICON_STR(FILE_WORD, "󰈬", "📘")
#define ICON_EXT_ASM ICON_STR(FILE_NASM, "", "")
#define ICON_EXT_BIN ICON_STR(OCT_FILE_BINARY, "", "📓")
#define ICON_EXT_COFFEE ICON_STR(MFIZZ_COFFEE_BEAN, "", "")
#define ICON_EXT_CSS ICON_STR(MFIZZ_CSS3, "", "🦋")
#define ICON_EXT_DEB ICON_STR(MFIZZ_DEBIAN, "", ICON_LINUX)
#define ICON_EXT_DIFF ICON_STR(FILE_DIFF, "", "📋")
#define ICON_EXT_GO ICON_STR(MFIZZ_GO, "󰟓", "")
#define ICON_EXT_JSON ICON_STR(ICON_JAVASCRIPT, "", ICON_JAVASCRIPT)
#define ICON_EXT_LUA ICON_STR(FILE_LUA, "", "🌘")
#define ICON_EXT_M ICON_STR("", "󰠞", "📊")
#define ICON_EXT_MAT ICON_STR("", "", "")
#define ICON_EXT_MD ICON_STR(DEV_MARKDOWN, "", "📝")
#define ICON_EXT_MSI ICON_STR(FA_WINDOWS, "󰍲", "🪟")
#define ICON_EXT_NIX ICON_STR("", "", "")
#define ICON_EXT_PATCH ICON_STR(FILE_PATCH, "", "🩹")
#define ICON_EXT_PHP ICON_STR(MFIZZ_PHP, "", "🌐")
#define ICON_EXT_ROM ICON_STR(FA_LOCK, "󰊖", "")
#define ICON_EXT_RSS ICON_STR(FA_RSS_SQUARE, "", "📡")
#define ICON_EXT_RTF ICON_STR(ICON_PDF, "󰈦", ICON_PDF)
#define ICON_EXT_SCALA ICON_STR(MFIZZ_SCALA, "", "")
#define ICON_EXT_SLN ICON_STR(DEV_VISUALSTUDIO, "", "")
#define ICON_EXT_TS ICON_STR(FILE_TS, "", "")
#define COLOR_VIDEO 93 /* Purple */
#define COLOR_AUDIO 220 /* Gold1 */
#define COLOR_IMAGE 82 /* Chartreuse2 */
#define COLOR_DOCS 202 /* OrangeRed1 */
#define COLOR_ARCHIVE 209 /* Salmon1 */
#define COLOR_C 81 /* SteelBlue1 */
#define COLOR_JAVA 32 /* DeepSkyBlue3 */
#define COLOR_JAVASCRIPT 47 /* SpringGreen2 */
#define COLOR_REACT 39 /* DeepSkyBlue1 */
#define COLOR_CSS 199 /* DeepPink1 */
#define COLOR_PYTHON 227 /* LightGoldenrod1 */
#define COLOR_LUA 19 /* LightGoldenrod1 */
#define COLOR_DOCUMENT 15 /* WHITE */
#define COLOR_FSHARP 31 /* DeepSkyBlue3 */
#define COLOR_RUBY 160 /* Red3 */
#define COLOR_SCALA 196 /* Red1 */
#define COLOR_VIM 28 /* Green4 */
/*
* Using symbols defined in icons-in-terminal.h, or even using icons-in-terminal is not necessary.
* You can use whatever pathched font you like. You just have to put the desired icon as a string.
* If you are using icons-in-terminal the creator recommends that you do use the symbols in the generated header.
* Hex xterm 256 color code, 0 to follow file specific (if any)
* Codes: https://jonasjacek.github.io/colors/
* Spectrum sorted: https://upload.wikimedia.org/wikipedia/commons/1/15/Xterm_256color_chart.svg
* Color names: https://www.ditig.com/256-colors-cheat-sheet
*/
#define COLOR_LIST \
COLOR_X(COLOR_VIDEO, 45) /* Turquoise2 */ \
COLOR_X(COLOR_VIDEO1, 226) /* Yellow1 */ \
COLOR_X(COLOR_AUDIO, 220) /* Gold1 */ \
COLOR_X(COLOR_AUDIO1, 205) /* HotPink */ \
COLOR_X(COLOR_IMAGE, 82) /* Chartreuse2 */ \
COLOR_X(COLOR_DOCS, 202) /* OrangeRed1 */ \
COLOR_X(COLOR_ARCHIVE, 209) /* Salmon1 */ \
COLOR_X(COLOR_C, 81) /* SteelBlue1 */ \
COLOR_X(COLOR_JAVA, 32) /* DeepSkyBlue3 */ \
COLOR_X(COLOR_JAVASCRIPT, 47) /* SpringGreen2 */ \
COLOR_X(COLOR_REACT, 39) /* DeepSkyBlue1 */ \
COLOR_X(COLOR_CSS, 199) /* DeepPink1 */ \
COLOR_X(COLOR_PYTHON, 227) /* LightGoldenrod1 */ \
COLOR_X(COLOR_LUA, 19) /* Blue3 */ \
COLOR_X(COLOR_DOCUMENT, 15) /* White */ \
COLOR_X(COLOR_FSHARP, 31) /* DeepSkyBlue3 */ \
COLOR_X(COLOR_RUBY, 160) /* Red3 */ \
COLOR_X(COLOR_SCALA, 196) /* Red1 */ \
COLOR_X(COLOR_SHELL, 47) /* SpringGreen2 */ \
COLOR_X(COLOR_VIM, 28) /* Green4 */ \
COLOR_X(COLOR_ELIXIR, 104) /* MediumPurple */ \
#if defined(ICONS)
static const struct icon_pair dir_icon = {"", FA_FOLDER, 0};
static const struct icon_pair file_icon = {"", FA_FILE_O, 0};
static const struct icon_pair exec_icon = {"", FA_COG, 0};
#elif defined(NERD)
static const struct icon_pair dir_icon = {"", ICON_DIRECTORY, 0};
static const struct icon_pair file_icon = {"", ICON_FILE, 0};
static const struct icon_pair exec_icon = {"", ICON_EXEC, 0};
/* X-Macro: https://en.wikipedia.org/wiki/X_Macro */
#define COLOR_X(N, V) N = (V),
enum { COLOR_LIST };
#undef COLOR_X
#define COLOR_X(N, V) N,
static const unsigned char init_colors[] = { COLOR_LIST };
#undef COLOR_X
#ifdef ICONS_GENERATE
/* temporary struct using `char *`. the hash-table generator will
* output a more optimized version which uses `char[]` instead reducing
* indirection and the total binary size.
*/
struct icon_pair { const char *match; const char *icon; unsigned char color; };
#endif
/* All entries are case-insensitive */
struct icon { const char *icon; unsigned char color; };
static const struct icon dir_icon = {ICON_DIRECTORY, 0};
static const struct icon file_icon = {ICON_FILE, 0};
static const struct icon exec_icon = {ICON_EXEC, 0};
static const struct icon_pair icons_name[] = {
#if defined(ICONS)
{".git", FA_GIT, 0},
{"Desktop", FA_DESKTOP, 0},
{"Documents", FA_BRIEFCASE, 0},
{"Downloads", FA_DOWNLOAD, 0},
{"Music", FA_MUSIC, 0},
{"Pictures", MD_CAMERA_ALT, 0},
{"Public", FA_INBOX, 0},
{"Templates", FA_PAPERCLIP, 0},
{"Videos", FA_FILM, 0},
{"CHANGELOG", FA_HISTORY, COLOR_DOCS},
{"configure", FILE_CONFIG, 0},
{"License", FA_COPYRIGHT, COLOR_DOCS},
{"Makefile", FILE_CMAKE, 0},
#elif defined(NERD)
{".git", ICON_GIT, 0},
{"Desktop", ICON_DESKTOP, 0},
{"Documents", ICON_BRIEFCASE, 0},
{"Downloads", ICON_DOWNLOADS, 0},
{"Music", ICON_MUSIC, 0},
{"Pictures", ICON_PICTURES, 0},
{"Public", ICON_PUBLIC, 0},
{"Templates", ICON_TEMPLATES, 0},
{"Videos", ICON_VIDEOS, 0},
{"CHANGELOG", ICON_CHANGELOG, COLOR_DOCS},
{"configure", ICON_CONFIGURE, 0},
{"License", ICON_LICENSE, COLOR_DOCS},
{"Makefile", ICON_MAKEFILE, 0},
#endif
{".git", ICON_GIT, 0},
{"Desktop", ICON_DESKTOP, 0},
{"Documents", ICON_BRIEFCASE, 0},
{"Downloads", ICON_DOWNLOADS, 0},
{"Music", ICON_MUSIC, 0},
{"Pictures", ICON_PICTURES, 0},
{"Public", ICON_PUBLIC, 0},
{"Templates", ICON_TEMPLATES, 0},
{"Videos", ICON_VIDEOS, 0},
{"CHANGELOG", ICON_CHANGELOG, COLOR_DOCS},
{"configure", ICON_CONFIGURE, 0},
{"License", ICON_LICENSE, COLOR_DOCS},
{"Makefile", ICON_MAKEFILE, 0},
};
#ifdef ICONS_GENERATE
/*
* New entries should bu added such that the first character of the extension is in the correct group .
* This is done for performance reason so that the correct icon can be found faster.
* All entries are case-insensitive
* The goal here is to provide a small set of default values. We don't try to
* provide icons for everything under the sun because keeping a _huge_ table of
* icons would: increase binary size, increase memory usage, decrease performance.
*
* Users are free to customize this *locally* as they see fit. Only open a
* pull-request if you think your changes are aligned with the goal described
* above.
*/
static const struct icon_pair icons_ext[] = {
#if defined(ICONS)
static const struct icon_pair icons_ext[] = { /* All entries are case-insensitive */
/* Numbers */
{"1", FILE_MANPAGE, COLOR_DOCS},
{"7z", FA_FILE_ARCHIVE_O, COLOR_ARCHIVE},
{"1", ICON_MANUAL, COLOR_DOCS},
{"7z", ICON_ARCHIVE, COLOR_ARCHIVE},
/* A */
{"a", FILE_MANPAGE, 0},
{"apk", FA_FILE_ARCHIVE_O, COLOR_ARCHIVE},
{"asm", FILE_NASM, 0},
{"aup", FA_FILE_AUDIO_O, COLOR_AUDIO},
{"avi", FA_FILE_MOVIE_O, COLOR_VIDEO},
{"a", ICON_MANUAL, 0},
{"apk", ICON_ARCHIVE, COLOR_ARCHIVE},
{"asm", ICON_EXT_ASM, 0},
{"aup", ICON_MUSICFILE, COLOR_AUDIO},
{"avi", ICON_VIDEOFILE, COLOR_VIDEO},
/* B */
{"bat", MFIZZ_SCRIPT, 0},
{"bin", OCT_FILE_BINARY, 0},
{"bmp", FA_FILE_IMAGE_O, COLOR_IMAGE},
{"bz2", FA_FILE_ARCHIVE_O, COLOR_ARCHIVE},
{"bat", ICON_SCRIPT, 0},
{"bib", ICON_TEX, 0},
{"bin", ICON_EXT_BIN, 0},
{"bmp", ICON_PICTUREFILE, COLOR_IMAGE},
{"bz2", ICON_ARCHIVE, COLOR_ARCHIVE},
/* C */
{"c", MFIZZ_C, 0},
{"c++", MFIZZ_CPLUSPLUS, 0},
{"cab", FA_FILE_ARCHIVE_O, COLOR_ARCHIVE},
{"cbr", FA_FILE_ARCHIVE_O, COLOR_ARCHIVE},
{"cbz", FA_FILE_ARCHIVE_O, COLOR_ARCHIVE},
{"cc", MFIZZ_CPLUSPLUS, 0},
{"class", MFIZZ_JAVA, 0},
{"clj", MFIZZ_CLOJURE, 0},
{"cljc", MFIZZ_CLOJURE, 0},
{"cljs", MFIZZ_CLOJURE, 0},
{"cmake", FILE_CMAKE, 0},
{"coffee", MFIZZ_COFFEE_BEAN, 0},
{"conf", FA_COGS, 0},
{"cpio", FA_FILE_ARCHIVE_O, COLOR_ARCHIVE},
{"cpp", MFIZZ_CPLUSPLUS, 0},
{"css", MFIZZ_CSS3, 0},
{"cue", FA_FILE_AUDIO_O, COLOR_AUDIO},
{"cvs", FA_COGS, 0},
{"cxx", MFIZZ_CPLUSPLUS, 0},
/* C */
{"c", ICON_C, COLOR_C},
{"c++", ICON_CPLUSPLUS, COLOR_C},
{"cabal", ICON_HASKELL, COLOR_VIDEO},
{"cab", ICON_ARCHIVE, COLOR_ARCHIVE},
{"cbr", ICON_ARCHIVE, COLOR_ARCHIVE},
{"cbz", ICON_ARCHIVE, COLOR_ARCHIVE},
{"cc", ICON_CPLUSPLUS, COLOR_C},
{"class", ICON_JAVA, COLOR_JAVA},
{"clj", ICON_CLOJURE, 0},
{"cljc", ICON_CLOJURE, 0},
{"cljs", ICON_CLOJURE, 0},
{"cls", ICON_TEX, 0},
{"cmake", ICON_MAKEFILE, 0},
{"coffee", ICON_EXT_COFFEE, 0},
{"conf", ICON_CONFIGURE, 0},
{"cpio", ICON_ARCHIVE, COLOR_ARCHIVE},
{"cpp", ICON_CPLUSPLUS, COLOR_C},
{"css", ICON_EXT_CSS, COLOR_CSS},
{"cue", ICON_PLAYLIST, COLOR_AUDIO},
{"cvs", ICON_CONFIGURE, 0},
{"cxx", ICON_CPLUSPLUS, COLOR_C},
/* D */
{"db", MFIZZ_DATABASE_ALT2, 0},
{"deb", MFIZZ_DEBIAN, COLOR_ARCHIVE},
{"diff", FILE_DIFF, 0},
{"dll", FILE_MANPAGE, 0},
{"doc", FILE_WORD, 0},
{"docx", FILE_WORD, 0},
{"db", ICON_DATABASE, 0},
{"deb", ICON_EXT_DEB, COLOR_ARCHIVE},
{"diff", ICON_EXT_DIFF, 0},
{"dll", ICON_SCRIPT, 0},
{"djvu", ICON_DJVU, COLOR_DOCS},
{"doc", ICON_WORDDOC, COLOR_DOCUMENT},
{"docx", ICON_WORDDOC, COLOR_DOCUMENT},
/* E */
{"ejs", FA_FILE_CODE_O, 0},
{"elf", FA_LINUX, 0},
{"epub", FA_FILE_PDF_O, COLOR_DOCS},
{"exe", FA_WINDOWS, 0},
/* E */
{"ejs", ICON_JAVASCRIPT, COLOR_JAVASCRIPT},
{"elf", ICON_LINUX, 0},
{"epub", ICON_PDF, COLOR_DOCS},
{"exe", ICON_EXEC, 0},
{"ex", ICON_ELIXIR, COLOR_ELIXIR},
{"eex", ICON_ELIXIR, COLOR_ELIXIR},
{"exs", ICON_ELIXIR, COLOR_ELIXIR},
/* F */
{"f#", DEV_FSHARP, 0},
{"flac", FA_FILE_AUDIO_O, COLOR_AUDIO},
{"flv", FA_FILE_MOVIE_O, COLOR_VIDEO},
{"fs", DEV_FSHARP, 0},
{"fsi", DEV_FSHARP, 0},
{"fsscript", DEV_FSHARP, 0},
{"fsx", DEV_FSHARP, 0},
{"f#", ICON_FSHARP, COLOR_FSHARP},
{"fen", ICON_CHESS, 0},
{"flac", ICON_MUSICFILE, COLOR_AUDIO1},
{"flv", ICON_VIDEOFILE, COLOR_VIDEO},
{"fs", ICON_FSHARP, COLOR_FSHARP},
{"fsi", ICON_FSHARP, COLOR_FSHARP},
{"fsscript", ICON_FSHARP, COLOR_FSHARP},
{"fsx", ICON_FSHARP, COLOR_FSHARP},
/* G */
{"gem", FA_FILE_ARCHIVE_O, 0},
{"gif", FA_FILE_IMAGE_O, COLOR_IMAGE},
{"go", MFIZZ_GO, 0},
{"gz", FA_FILE_ARCHIVE_O, COLOR_ARCHIVE},
{"gzip", FA_FILE_ARCHIVE_O, COLOR_ARCHIVE},
{"gem", ICON_RUBY, COLOR_RUBY},
{"gif", ICON_PICTUREFILE, COLOR_IMAGE},
{"go", ICON_EXT_GO, COLOR_C},
{"gpg", ICON_ENCRYPT, COLOR_ARCHIVE},
{"gz", ICON_ARCHIVE, COLOR_ARCHIVE},
{"gzip", ICON_ARCHIVE, COLOR_ARCHIVE},
/* H */
{"h", MFIZZ_C, 0},
{"hh", MFIZZ_CPLUSPLUS, 0},
{"htaccess", FA_COGS, 0},
{"htpasswd", FA_COGS, 0},
{"htm", FA_FILE_CODE_O, 0},
{"html", FA_FILE_CODE_O, 0},
{"hxx", MFIZZ_CPLUSPLUS, 0},
{"h", ICON_C, COLOR_C},
{"hh", ICON_CPLUSPLUS, COLOR_C},
{"hpp", ICON_CPLUSPLUS, COLOR_C},
{"hs", ICON_HASKELL, COLOR_ELIXIR},
{"htaccess", ICON_CONFIGURE, 0},
{"htpasswd", ICON_CONFIGURE, 0},
{"htm", ICON_HTML, 0},
{"html", ICON_HTML, 0},
{"hxx", ICON_CPLUSPLUS, COLOR_C},
{"heex", ICON_ELIXIR, COLOR_ELIXIR},
/* I */
{"ico", FA_FILE_IMAGE_O, COLOR_IMAGE},
{"img", LINEA_MUSIC_CD, COLOR_ARCHIVE},
{"ini", FA_COGS, 0},
{"iso", LINEA_MUSIC_CD, COLOR_ARCHIVE},
{"ico", ICON_PICTUREFILE, COLOR_IMAGE},
{"ini", ICON_CONFIGURE, 0},
{"img", ICON_OPTICALDISK, COLOR_ARCHIVE},
{"iso", ICON_OPTICALDISK, COLOR_ARCHIVE},
/* J */
{"jar", MFIZZ_JAVA, 0},
{"java", MFIZZ_JAVA, 0},
{"jl", FA_COGS, 0},
{"jpeg", FA_FILE_IMAGE_O, COLOR_IMAGE},
{"jpg", FA_FILE_IMAGE_O, COLOR_IMAGE},
{"js", DEV_JAVASCRIPT_BADGE, 0},
{"json", MFIZZ_JAVASCRIPT, 0},
{"jsx", FILE_JSX, 0},
{"jar", ICON_JAVA, COLOR_JAVA},
{"java", ICON_JAVA, COLOR_JAVA},
{"jl", ICON_CONFIGURE, 0},
{"jpeg", ICON_PICTUREFILE, COLOR_IMAGE},
{"jpg", ICON_PICTUREFILE, COLOR_IMAGE},
{"js", ICON_JAVASCRIPT, COLOR_JAVASCRIPT},
{"json", ICON_EXT_JSON, COLOR_JAVASCRIPT},
{"jsx", ICON_REACT, COLOR_REACT},
{"jxl", ICON_PICTUREFILE, COLOR_IMAGE},
/* K */
{"ksh", ICON_SCRIPT, COLOR_SHELL},
/* L */
{"lha", FA_FILE_ARCHIVE_O, COLOR_ARCHIVE},
{"log", FA_FILE_TEXT_O, 0},
{"lua", FILE_LUA, 0},
{"lzh", FA_FILE_ARCHIVE_O, COLOR_ARCHIVE},
{"lzma", FA_FILE_ARCHIVE_O, COLOR_ARCHIVE},
{"lha", ICON_ARCHIVE, COLOR_ARCHIVE},
{"lhs", ICON_HASKELL, COLOR_VIM},
{"log", ICON_DOCUMENT, 0},
{"lua", ICON_EXT_LUA, COLOR_LUA},
{"lzh", ICON_ARCHIVE, COLOR_ARCHIVE},
{"lzma", ICON_ARCHIVE, COLOR_ARCHIVE},
/* M */
{"m4a", FA_FILE_AUDIO_O, COLOR_AUDIO},
{"m4v", FA_FILE_MOVIE_O, COLOR_VIDEO},
{"markdown", DEV_MARKDOWN, COLOR_DOCS},
{"md", DEV_MARKDOWN, COLOR_DOCS},
{"mk", FILE_CMAKE, 0},
{"mkv", FA_FILE_MOVIE_O, COLOR_VIDEO},
{"mov", FA_FILE_MOVIE_O, COLOR_VIDEO},
{"mp3", FA_FILE_AUDIO_O, COLOR_AUDIO},
{"mp4", FA_FILE_MOVIE_O, COLOR_VIDEO},
{"mpeg", FA_FILE_MOVIE_O, COLOR_VIDEO},
{"mpg", FA_FILE_MOVIE_O, COLOR_VIDEO},
{"msi", FA_WINDOWS, 0},
{"m", ICON_EXT_M, COLOR_C},
{"m4a", ICON_MUSICFILE, COLOR_AUDIO},
{"m4v", ICON_VIDEOFILE, COLOR_VIDEO},
{"markdown", ICON_EXT_MD, COLOR_DOCS},
{"mat", ICON_EXT_MAT, COLOR_C},
{"md", ICON_EXT_MD, COLOR_DOCS},
{"mk", ICON_MAKEFILE, 0},
{"mkv", ICON_VIDEOFILE, COLOR_VIDEO},
{"mov", ICON_VIDEOFILE, COLOR_VIDEO},
{"mp3", ICON_MUSICFILE, COLOR_AUDIO},
{"mp4", ICON_VIDEOFILE, COLOR_VIDEO1},
{"mpeg", ICON_VIDEOFILE, COLOR_VIDEO},
{"mpg", ICON_VIDEOFILE, COLOR_VIDEO},
{"msi", ICON_EXT_MSI, 0},
/* N */
{"nix", ICON_EXT_NIX, COLOR_FSHARP},
/* O */
{"o", FILE_MANPAGE, 0},
{"ogg", FA_FILE_AUDIO_O, COLOR_AUDIO},
{"opdownload", FA_DOWNLOAD, 0},
{"out", FA_LINUX, 0},
{"o", ICON_MANUAL, 0},
{"ogg", ICON_MUSICFILE, COLOR_AUDIO},
{"opus", ICON_MUSICFILE, COLOR_AUDIO},
{"opdownload", ICON_DOWNLOADS, 0},
{"otf", ICON_FONT, 0},
{"out", ICON_LINUX, 0},
/* P */
{"part", FA_DOWNLOAD, 0},
{"patch", FILE_PATCH, 0},
{"pdf", FA_FILE_PDF_O, COLOR_DOCS},
{"php", MFIZZ_PHP, 0},
{"png", FA_FILE_IMAGE_O, COLOR_IMAGE},
{"ppt", FILE_POWERPOINT, 0},
{"pptx", FILE_POWERPOINT, 0},
{"psb", DEV_PHOTOSHOP, 0},
{"psd", DEV_PHOTOSHOP, 0},
{"py", MFIZZ_PYTHON, 0},
{"pyc", MFIZZ_PYTHON, 0},
{"pyd", MFIZZ_PYTHON, 0},
{"pyo", MFIZZ_PYTHON, 0},
{"part", ICON_DOWNLOADS, 0},
{"patch", ICON_EXT_PATCH, 0},
{"pdf", ICON_PDF, COLOR_DOCS},
{"pgn", ICON_CHESS, 0},
{"php", ICON_EXT_PHP, 0},
{"png", ICON_PICTUREFILE, COLOR_IMAGE},
{"ppt", ICON_POWERPOINT, 0},
{"pptx", ICON_POWERPOINT, 0},
{"psb", ICON_PHOTOSHOP, 0},
{"psd", ICON_PHOTOSHOP, 0},
{"py", ICON_PYTHON, COLOR_PYTHON},
{"pyc", ICON_PYTHON, COLOR_PYTHON},
{"pyd", ICON_PYTHON, COLOR_PYTHON},
{"pyo", ICON_PYTHON, COLOR_PYTHON},
/* Q */
/* R */
{"rar", FA_FILE_ARCHIVE_O, COLOR_ARCHIVE},
{"rc", FA_COGS, 0},
{"rom", FA_LOCK, 0},
{"rpm", FA_FILE_ARCHIVE_O, COLOR_ARCHIVE},
{"rss", FA_RSS_SQUARE, 0},
{"rtf", FA_FILE_PDF_O, 0},
{"rar", ICON_ARCHIVE, COLOR_ARCHIVE},
{"rb", ICON_RUBY, COLOR_RUBY},
{"rc", ICON_CONFIGURE, 0},
{"rom", ICON_EXT_ROM, 0},
{"rpm", ICON_ARCHIVE, COLOR_ARCHIVE},
{"rs", ICON_RUST, COLOR_DOCS},
{"rss", ICON_EXT_RSS, 0},
{"rtf", ICON_EXT_RTF, 0},
/* S */
{"so", FILE_MANPAGE, 0},
{"scala", MFIZZ_SCALA, 0},
{"sh", MFIZZ_SCRIPT, 0},
{"slim", FA_FILE_CODE_O, 0},
{"sln", DEV_VISUALSTUDIO, 0},
{"sql", MFIZZ_MYSQL, 0},
{"srt", FA_COMMENTS_O, 0},
{"sub", FA_COMMENTS_O, 0},
{"svg", FA_FILE_IMAGE_O, COLOR_IMAGE},
{"sass", ICON_SASS, COLOR_CSS},
{"scss", ICON_SASS, COLOR_CSS},
{"so", ICON_MANUAL, 0},
{"scala", ICON_EXT_SCALA, COLOR_SCALA},
{"sh", ICON_SCRIPT, COLOR_SHELL},
{"slim", ICON_SCRIPT, COLOR_DOCUMENT},
{"sln", ICON_EXT_SLN, 0},
{"sql", ICON_DATABASE, 0},
{"srt", ICON_SUBTITLE, 0},
{"sty", ICON_TEX, 0},
{"sub", ICON_SUBTITLE, 0},
{"svg", ICON_PICTUREFILE, COLOR_IMAGE},
/* T */
{"tar", FA_FILE_ARCHIVE_O, COLOR_ARCHIVE},
{"tex", FILE_TEX, 0},
{"tgz", FA_FILE_ARCHIVE_O, COLOR_ARCHIVE},
{"ts", FILE_TS, 0},
{"tsx", FILE_TSX, 0},
{"txt", FA_FILE_TEXT_O, 0},
{"txz", FA_FILE_ARCHIVE_O, COLOR_ARCHIVE},
{"tar", ICON_ARCHIVE, COLOR_ARCHIVE},
{"tex", ICON_TEX, 0},
{"tgz", ICON_ARCHIVE, COLOR_ARCHIVE},
{"ts", ICON_EXT_TS, COLOR_JAVASCRIPT},
{"tsx", ICON_REACT, COLOR_REACT},
{"txt", ICON_DOCUMENT, COLOR_DOCUMENT},
{"txz", ICON_ARCHIVE, COLOR_ARCHIVE},
{"ttf", ICON_FONT, 0},
/* U */
/* V */
{"vid", FA_FILE_MOVIE_O, COLOR_VIDEO},
{"vim", DEV_VIM, 0},
{"vimrc", DEV_VIM, 0},
{"vtt", FA_COMMENTS_O, 0},
{"vid", ICON_VIDEOFILE, COLOR_VIDEO},
{"vim", ICON_VIM, COLOR_VIM},
{"vimrc", ICON_VIM, COLOR_VIM},
{"vtt", ICON_SUBTITLE, 0},
/* W */
{"wav", FA_FILE_AUDIO_O, COLOR_AUDIO},
{"webm", FA_FILE_MOVIE_O, COLOR_VIDEO},
{"wma", FA_FILE_AUDIO_O, COLOR_AUDIO},
{"wmv", FA_FILE_MOVIE_O, COLOR_VIDEO},
{"wav", ICON_MUSICFILE, COLOR_AUDIO},
{"webm", ICON_VIDEOFILE, COLOR_VIDEO},
{"webp", ICON_PICTUREFILE, COLOR_IMAGE},
{"wma", ICON_VIDEOFILE, COLOR_AUDIO},
{"wmv", ICON_VIDEOFILE, COLOR_VIDEO},
/* X */
{"xbps", FA_FILE_ARCHIVE_O, COLOR_ARCHIVE},
{"xcf", FA_FILE_IMAGE_O, COLOR_IMAGE},
{"xhtml", FA_FILE_CODE_O, 0},
{"xls", FILE_EXCEL, 0},
{"xlsx", FILE_EXCEL, 0},
{"xml", FA_FILE_CODE_O, 0},
{"xz", FA_FILE_ARCHIVE_O, COLOR_ARCHIVE},
{"xbps", ICON_ARCHIVE, COLOR_ARCHIVE},
{"xcf", ICON_PICTUREFILE, COLOR_IMAGE},
{"xhtml", ICON_HTML, 0},
{"xls", ICON_MS_EXCEL, 0},
{"xlsx", ICON_MS_EXCEL, 0},
{"xml", ICON_HTML, 0},
{"xz", ICON_ARCHIVE, COLOR_ARCHIVE},
/* Y */
{"yaml", FA_COGS, 0},
{"yml", FA_COGS, 0},
{"yaml", ICON_CONFIGURE, COLOR_DOCUMENT},
{"yml", ICON_CONFIGURE, COLOR_DOCUMENT},
/* Z */
{"zip", FA_FILE_ARCHIVE_O, COLOR_ARCHIVE},
{"zip", ICON_ARCHIVE, COLOR_ARCHIVE},
{"zsh", ICON_SCRIPT, COLOR_SHELL},
{"zst", ICON_ARCHIVE, COLOR_ARCHIVE},
/* Other */
#elif defined(NERD)
/* Numbers */
{"1", ICON_EXT_1, COLOR_DOCS},
{"7z", ICON_EXT_7Z, COLOR_ARCHIVE},
/* A */
{"a", ICON_EXT_A, 0},
{"apk", ICON_EXT_APK, COLOR_ARCHIVE},
{"asm", ICON_EXT_ASM, 0},
{"aup", ICON_EXT_AUP, COLOR_AUDIO},
{"avi", ICON_EXT_AVI, COLOR_VIDEO},
/* B */
{"bat", ICON_EXT_BAT, 0},
{"bin", ICON_EXT_BIN, 0},
{"bmp", ICON_EXT_BMP, COLOR_IMAGE},
{"bz2", ICON_EXT_BZ2, COLOR_ARCHIVE},
/* C */
{"c", ICON_EXT_C, COLOR_C},
{"c++", ICON_EXT_CPLUSPLUS, COLOR_C},
{"cab", ICON_EXT_CAB, COLOR_ARCHIVE},
{"cbr", ICON_EXT_CBR, COLOR_ARCHIVE},
{"cbz", ICON_EXT_CBZ, COLOR_ARCHIVE},
{"cc", ICON_EXT_CC, COLOR_C},
{"class", ICON_EXT_CLASS, COLOR_JAVA},
{"clj", ICON_EXT_CLJ, 0},
{"cljc", ICON_EXT_CLJC, 0},
{"cljs", ICON_EXT_CLJS, 0},
{"cmake", ICON_EXT_CMAKE, 0},
{"coffee", ICON_EXT_COFFEE, 0},
{"conf", ICON_EXT_CONF, 0},
{"cpio", ICON_EXT_CPIO, COLOR_ARCHIVE},
{"cpp", ICON_EXT_CPP, 0},
{"css", ICON_EXT_CSS, COLOR_CSS},
{"cue", ICON_EXT_CUE, COLOR_AUDIO},
{"cvs", ICON_EXT_CVS, 0},
{"cxx", ICON_EXT_CXX, COLOR_C},
/* D */
{"db", ICON_EXT_DB, 0},
{"deb", ICON_EXT_DEB, COLOR_ARCHIVE},
{"diff", ICON_EXT_DIFF, 0},
{"dll", ICON_EXT_DLL, 0},
{"doc", ICON_EXT_DOC, COLOR_DOCUMENT},
{"docx", ICON_EXT_DOCX, COLOR_DOCUMENT},
/* E */
{"ejs", ICON_EXT_EJS, COLOR_JAVASCRIPT},
{"elf", ICON_EXT_ELF, 0},
{"epub", ICON_EXT_EPUB, COLOR_DOCS},
{"exe", ICON_EXT_EXE, 0},
/* F */
{"f#", ICON_EXT_FSHARP, COLOR_FSHARP},
{"fen", ICON_EXT_FEN, 0},
{"flac", ICON_EXT_FLAC, COLOR_AUDIO},
{"flv", ICON_EXT_FLV, COLOR_VIDEO},
{"fs", ICON_EXT_FS, COLOR_FSHARP},
{"fsi", ICON_EXT_FSI, COLOR_FSHARP},
{"fsscript", ICON_EXT_FSSCRIPT, COLOR_FSHARP},
{"fsx", ICON_EXT_FSX, COLOR_FSHARP},
/* G */
{"gem", ICON_EXT_GEM, COLOR_RUBY},
{"gif", ICON_EXT_GIF, COLOR_IMAGE},
{"go", ICON_EXT_GO, 0},
{"gz", ICON_EXT_GZ, COLOR_ARCHIVE},
{"gzip", ICON_EXT_GZIP, COLOR_ARCHIVE},
/* H */
{"h", ICON_EXT_H, COLOR_C},
{"hh", ICON_EXT_HH, COLOR_C},
{"hpp", ICON_EXT_HPP, COLOR_C},
{"hs", ICON_EXT_HS, COLOR_VIM},
{"htaccess", ICON_EXT_HTACCESS, 0},
{"htpasswd", ICON_EXT_HTPASSWD, 0},
{"htm", ICON_EXT_HTM, 0},
{"html", ICON_EXT_HTML, 0},
{"hxx", ICON_EXT_HXX, COLOR_C},
/* I */
{"ico", ICON_EXT_ICO, COLOR_IMAGE},
{"img", ICON_EXT_IMG, COLOR_ARCHIVE},
{"ini", ICON_EXT_INI, 0},
{"iso", ICON_EXT_ISO, COLOR_ARCHIVE},
/* J */
{"jar", ICON_EXT_JAR, COLOR_JAVA},
{"java", ICON_EXT_JAVA, COLOR_JAVA},
{"jl", ICON_EXT_JL, 0},
{"jpeg", ICON_EXT_JPEG, COLOR_IMAGE},
{"jpg", ICON_EXT_JPG, COLOR_IMAGE},
{"js", ICON_EXT_JS, COLOR_JAVASCRIPT},
{"json", ICON_EXT_JSON, COLOR_JAVASCRIPT},
{"jsx", ICON_EXT_JSX, COLOR_REACT},
/* K */
/* L */
{"lha", ICON_EXT_LHA, COLOR_ARCHIVE},
{"lhs", ICON_EXT_LHS, COLOR_VIM},
{"log", ICON_EXT_LOG, 0},
{"lua", ICON_EXT_LUA, 0},
{"lzh", ICON_EXT_LZH, COLOR_ARCHIVE},
{"lzma", ICON_EXT_LZMA, COLOR_ARCHIVE},
/* M */
{"m4a", ICON_EXT_M4A, COLOR_AUDIO},
{"m4v", ICON_EXT_M4V, COLOR_VIDEO},
{"markdown", ICON_EXT_MD, COLOR_DOCS},
{"md", ICON_EXT_MD, COLOR_DOCS},
{"mk", ICON_EXT_MK, 0},
{"mkv", ICON_EXT_MKV, COLOR_VIDEO},
{"mov", ICON_EXT_MOV, COLOR_VIDEO},
{"mp3", ICON_EXT_MP3, COLOR_AUDIO},
{"mp4", ICON_EXT_MP4, COLOR_VIDEO},
{"mpeg", ICON_EXT_MPEG, COLOR_VIDEO},
{"mpg", ICON_EXT_MPG, COLOR_VIDEO},
{"msi", ICON_EXT_MSI, 0},
/* N */
/* O */
{"o", ICON_EXT_O, 0},
{"ogg", ICON_EXT_OGG, COLOR_AUDIO},
{"opdownload", ICON_EXT_ODOWNLOAD, 0},
{"out", ICON_EXT_OUT, 0},
/* P */
{"part", ICON_EXT_PART, 0},
{"patch", ICON_EXT_PATCH, 0},
{"pdf", ICON_EXT_PDF, COLOR_DOCS},
{"pgn", ICON_EXT_PGN, 0},
{"php", ICON_EXT_PHP, 0},
{"png", ICON_EXT_PNG, COLOR_IMAGE},
{"ppt", ICON_EXT_PPT, 0},
{"pptx", ICON_EXT_PPTX, 0},
{"psb", ICON_EXT_PSB, 0},
{"psd", ICON_EXT_PSD, 0},
{"py", ICON_EXT_PY, COLOR_PYTHON},
{"pyc", ICON_EXT_PYC, COLOR_PYTHON},
{"pyd", ICON_EXT_PYD, COLOR_PYTHON},
{"pyo", ICON_EXT_PYO, COLOR_PYTHON},
/* Q */
/* R */
{"rar", ICON_EXT_RAR, COLOR_ARCHIVE},
{"rc", ICON_EXT_RC, 0},
{"rom", ICON_EXT_ROM, 0},
{"rpm", ICON_EXT_RPM, COLOR_ARCHIVE},
{"rss", ICON_EXT_RSS, 0},
{"rtf", ICON_EXT_RTF, 0},
/* S */
{"sass", ICON_EXT_SASS, COLOR_CSS},
{"scss", ICON_EXT_SCSS, COLOR_CSS},
{"so", ICON_EXT_SO, 0},
{"scala", ICON_EXT_SCALA, COLOR_SCALA},
{"sh", ICON_EXT_SH, 0},
{"slim", ICON_EXT_SLIM, COLOR_DOCUMENT},
{"sln", ICON_EXT_SLN, 0},
{"sql", ICON_EXT_SQL, 0},
{"srt", ICON_EXT_SRT, 0},
{"sub", ICON_EXT_SUB, 0},
{"svg", ICON_EXT_SVG, COLOR_IMAGE},
/* T */
{"tar", ICON_EXT_TAR, COLOR_ARCHIVE},
{"tex", ICON_EXT_TEX, 0},
{"tgz", ICON_EXT_TGZ, COLOR_ARCHIVE},
{"ts", ICON_EXT_TS, COLOR_JAVASCRIPT},
{"tsx", ICON_EXT_TSX, COLOR_REACT},
{"txt", ICON_EXT_TXT, COLOR_DOCUMENT},
{"txz", ICON_EXT_TXZ, COLOR_ARCHIVE},
/* U */
/* V */
{"vid", ICON_EXT_VID, COLOR_VIDEO},
{"vim", ICON_EXT_VIM, COLOR_VIM},
{"vimrc", ICON_EXT_VIMRC, COLOR_VIM},
{"vtt", ICON_EXT_SRT, 0},
/* W */
{"wav", ICON_EXT_WAV, COLOR_AUDIO},
{"webm", ICON_EXT_WEBM, COLOR_VIDEO},
{"wma", ICON_EXT_WMA, COLOR_AUDIO},
{"wmv", ICON_EXT_WMV, COLOR_VIDEO},
/* X */
{"xbps", ICON_EXT_XBPS, COLOR_ARCHIVE},
{"xcf", ICON_EXT_XCF, COLOR_IMAGE},
{"xhtml", ICON_EXT_XHTML, 0},
{"xls", ICON_EXT_XLS, 0},
{"xlsx", ICON_EXT_XLSX, 0},
{"xml", ICON_EXT_XML, 0},
{"xz", ICON_EXT_XZ, COLOR_ARCHIVE},
/* Y */
{"yaml", ICON_EXT_YAML, COLOR_DOCUMENT},
{"yml", ICON_EXT_YML, COLOR_DOCUMENT},
/* Z */
{"zip", ICON_EXT_ZIP, COLOR_ARCHIVE},
/* Other */
#endif
};
#endif
#endif /* defined(ICONS_GENERATE) || defined(ICONS_ENABLED) */
#endif /* INCLUDE_ICONS_H */

3725
src/nnn.c

File diff suppressed because it is too large Load Diff

View File

@ -3,7 +3,7 @@
*
* Copyright (C) 2014-2016, Lazaros Koromilas <lostd@2f30.org>
* Copyright (C) 2014-2016, Dimitris Papastamos <sin@2f30.org>
* Copyright (C) 2016-2021, Arun Prakash Jana <engineerarun@gmail.com>
* Copyright (C) 2016-2023, Arun Prakash Jana <engineerarun@gmail.com>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -31,6 +31,7 @@
#pragma once
#include <curses.h>
#include <wchar.h>
#define CONTROL(c) ((c) & 0x1f)
@ -56,11 +57,13 @@ enum action {
SEL_HOME,
SEL_END,
SEL_FIRST,
SEL_JUMP,
SEL_YOUNG,
SEL_CDHOME,
SEL_CDBEGIN,
SEL_CDLAST,
SEL_CDROOT,
SEL_BOOKMARK,
SEL_BMOPEN,
SEL_REMOTE,
SEL_CYCLE,
SEL_CYCLER,
@ -75,6 +78,7 @@ enum action {
SEL_CTX8,
#endif
SEL_MARK,
SEL_BMARK,
SEL_FLTR,
SEL_MFLTR,
SEL_HIDDEN,
@ -92,7 +96,8 @@ enum action {
SEL_CP,
SEL_MV,
SEL_CPMVAS,
SEL_RM,
SEL_TRASH,
SEL_RM_ONLY,
SEL_OPENWITH,
SEL_NEW,
SEL_RENAME,
@ -102,9 +107,10 @@ enum action {
SEL_AUTONEXT,
SEL_EDIT,
SEL_PLUGIN,
SEL_SELSIZE,
SEL_SHELL,
SEL_LAUNCH,
SEL_RUNCMD,
SEL_PROMPT,
SEL_LOCK,
SEL_SESSIONS,
SEL_EXPORT,
@ -120,7 +126,7 @@ enum action {
/* Associate a pressed key to an action */
struct key {
int sym; /* Key pressed */
wint_t sym; /* Key pressed */
enum action act; /* Action */
};
@ -158,6 +164,9 @@ static struct key bindings[] = {
{ CONTROL('E'), SEL_END },
/* Go to first file */
{ '\'', SEL_FIRST },
/* Jump to an entry number/offset */
{ 'J', SEL_JUMP },
{ CONTROL('Y'), SEL_YOUNG },
/* HOME */
{ '~', SEL_CDHOME },
/* Initial directory */
@ -167,8 +176,8 @@ static struct key bindings[] = {
/* Go to / */
{ '`', SEL_CDROOT },
/* Leader key */
{ 'b', SEL_BOOKMARK },
{ CONTROL('_'), SEL_BOOKMARK },
{ 'b', SEL_BMOPEN },
{ CONTROL('_'), SEL_BMOPEN },
/* Connect to server over SSHFS */
{ 'c', SEL_REMOTE },
/* Cycle contexts in forward direction */
@ -188,6 +197,8 @@ static struct key bindings[] = {
#endif
/* Mark a path to visit later */
{ ',', SEL_MARK },
/* Create a bookmark */
{ 'B', SEL_BMARK },
/* Filter */
{ '/', SEL_FLTR },
/* Toggle filter mode */
@ -209,8 +220,8 @@ static struct key bindings[] = {
/* Redraw window */
{ CONTROL('L'), SEL_REDRAW },
/* Select current file path */
{ CONTROL('J'), SEL_SEL },
{ ' ', SEL_SEL },
{ '+', SEL_SEL },
/* Toggle select multiple files */
{ 'm', SEL_SELMUL },
/* Select all files in current dir */
@ -229,8 +240,9 @@ static struct key bindings[] = {
{ 'w', SEL_CPMVAS },
{ CONTROL('W'), SEL_CPMVAS },
/* Delete from selection buffer */
{ 'x', SEL_RM },
{ CONTROL('X'), SEL_RM },
{ 'x', SEL_TRASH },
{ CONTROL('X'), SEL_TRASH },
{ 'X', SEL_RM_ONLY },
/* Open in a custom application */
{ 'o', SEL_OPENWITH },
{ CONTROL('O'), SEL_OPENWITH },
@ -244,19 +256,21 @@ static struct key bindings[] = {
{ 'u', SEL_UMOUNT },
/* Show help */
{ '?', SEL_HELP },
/* Quit a context */
{ '+', SEL_AUTONEXT },
/* Toggle auto-advance on file open */
{ CONTROL('J'), SEL_AUTONEXT },
/* Edit in EDITOR */
{ 'e', SEL_EDIT },
/* Run a plugin */
{ ';', SEL_PLUGIN },
/* Show total size of listed selection */
{ 'S', SEL_SELSIZE },
/* Run command */
{ '!', SEL_SHELL },
{ CONTROL(']'), SEL_SHELL },
/* Launcher */
{ '=', SEL_LAUNCH },
/* Run a command */
{ ']', SEL_RUNCMD },
/* Show command prompt */
{ ']', SEL_PROMPT },
/* Lock screen */
{ '0', SEL_LOCK },
/* Manage sessions */