nnn Terminal File Manager

repository·master·Indexed 12 days ago

https://github.com/jarun/nnn

A highly optimized, tiny, and fast terminal file manager designed for productivity with minimal configuration. It features a User Patch Framework for enabling specific features during compilation, a robust plugin system for extending capabilities via executable scripts, and the ability to run arbitrary CLI commands as plugins using the NNN_PLUG environment variable.

Tokens
4.3K
Snippets
12
Records
17
Agent score
98%

What's inside nnn

  1. Core features of nnn

    master

    nnn is a fast, tiny, and highly portable terminal file manager. Key capabilities include:

    • Modes: Light (default), detail, disk usage analyzer (block/apparent), and file picker/plugin mode.
    • Navigation: Type-to-nav (turbo navigation), filtering (fuzzy, regex, and string), and context/tab management.
    • Search & Sort: Instant search-as-you-type with support for POSIX/PCRE2 regex. Sorting by name, time (access/change/mod), size, or extension.
    • Mimes & Previews: Built-in text/directory previewer, support for custom openers, and plugin-based previews for images, video, and audio.
    • File Operations: Batch renaming, creating/renaming/duplicating files and directories (including trees), and archive management (create, list, extract, mount).
    • Convenience: System clipboard integration, FreeDesktop trash integration, and ability to run plugins or custom commands via hotkeys.
  2. Basic navigation and shortcuts in nnn

    master

    You don't need to memorize all commands to use nnn. The following basic keys are sufficient for most tasks:

    • Arrows: Navigate through files and directories.
    • / : Initiate filtering/search.
    • q : Quit nnn.
    • Tab : Create and/or cycle through contexts (tabs/workspaces).
    • ? : List all available shortcuts.

    For more advanced navigation, nnn supports 'Type-to-nav' mode for rapid filtering and jumping to entries with visible relative offsets.

  3. Understand plugin access levels and environment variables

    master

    When nnn executes a plugin, it provides the following context:

    Arguments passed to the plugin script:

    1. $1: The hovered file's name.
    2. $2: The working directory (non-canonical, may differ from $PWD if symlinked).
    3. $3: The picker mode output file (- for stdout) if nnn is running as a file picker.

    Environment Variables set for the plugin:

    • NNN_PIPE: The path to the pipe used to send commands back to nnn (e.g., to change directories).
    • NNN_INCLUDE_HIDDEN: 1 if hidden files are active, 0 otherwise.
    • NNN_PREFER_SELECTION: 1 if the user prefers to use selection (via -u flag), 0 otherwise.
    • Special variables exported by nnn are also available.

    Plugins can also read the .selection file in the nnn config directory.

  4. Quickstart guide for nnn

    master

    To get started with nnn, follow these steps:

    1. Install nnn and any required dependencies.
    2. Open files: The desktop opener is used by default. Use the -e flag to open text files directly in the terminal.
    3. Shell Integration: Configure cd on quit and sync your subshell $PWD to nnn to ensure your shell stays in sync with your navigation.
    4. Plugins: Install plugins to extend functionality (e.g., live previews, disk mounting).
    5. Clipboard & Notifications: Use the -x flag to sync selections to the clipboard and show notifications when cp, mv, or rm operations complete.
    6. CLI-only environments: If you are in a strictly CLI environment, set the NNN_OPENER environment variable to nuke and use the -c option.
    7. Pro-tip: Replace your ls command with an alias for a better experience: alias ls='nnn -de'.
    alias ls='nnn -de'
  5. Apply user patches via make variables

    master

    The nnn User Patch Framework allows you to enable specific user-submitted features that are not part of the mainline version. Each patch is enabled during compilation by setting a specific make variable to 1.

    Available patches include:

    • O_COLEMAK: Key bindings for Colemak keyboard layout.
    • O_GITSTATUS: Adds a git status column to the detail view. Enables the -G command line flag in normal mode.
    • O_NAMEFIRST: Prints filenames first in the detail view and shows user/group columns when a directory contains different users/groups.
    • O_RESTOREPREVIEW: Adds a pipe to close and restore preview-tui for internal undetached edits (using the e key).

    To apply a patch, run make with the corresponding variable set to 1.

    make O_NAMEFIRST=1
  6. Run arbitrary CLI commands as plugins

    master

    You can assign keys to non-background CLI commands by prefixing the command with ! in the NNN_PLUG environment variable. This allows you to invoke standard shell commands using the ; prefix in nnn.

    Key Syntax Rules:

    • Use ! before the command to invoke it as a plugin.
    • Use "$nnn" (double quotes) to pass the hovered file safely.
    • Use single quotes for the NNN_PLUG export to prevent shell interpolation of $nnn.
    • Prefix with -! to disable directory refresh after the command executes.
    export NNN_PLUG='x:!chmod +x "$nnn";g:!git log;s:!smplayer "$nnn"'
  7. Configure plugin execution behavior (Skip confirmation, GUI, Paging, Floating windows)

    master

    When using ! to run commands as plugins, you can append specific suffixes to modify how they behave:

    SuffixActionNotes
    *Skip user confirmationSkips the Press Enter to continue prompt. Do not use with programs that run and exit (e.g., cat).
    &Run as GUI appRuns the command in the background. Incompatible with | and >
    |Page outputShows output of run-and-exit commands using a pager. Incompatible with & and >
    >Floating windowShows output in a floating window. Incompatible with &. Always refreshes the directory.

    Example Configuration:

    # Run smplayer without waiting for Enter, and run mousepad as a GUI app
    export NNN_PLUG='s:!smplayer "$nnn"*;m:-!&mousepad "$nnn"'
    export NNN_PLUG='s:!smplayer "$nnn"*;n:-!vim /home/vaio/Dropbox/Public/synced_note*'
    export NNN_PLUG='m:-!&mousepad "$nnn"'
    export NNN_PLUG='m:-!|mediainfo "$nnn";t:-!|tree -ps;l:-!|ls -lah --group-directories-first'
    export NNN_PLUG='m:!>mediainfo "$nnn";t:!>tree -ps;l:!>ls -lah --group-directories-first'
  8. Create a new nnn plugin

    master

    To create a plugin:

    1. Write a script (POSIX-compliant shell scripts are preferred).
    2. Make the file executable.
    3. Place it in the nnn plugin directory.
    4. (Optional) Add a hotkey in the NNN_PLUG environment variable for quick access.

    Best Practices:

    • Use ${XDG_CACHE_HOME:-$HOME/.cache}/nnn if your plugin needs to store data.
    • Document dependencies and author information within the plugin file.
    • Keep non-portable commands (like notify-send) commented out to ensure cross-platform compatibility.
  9. Install nnn plugins

    master

    Use the following command to install or update all available plugins. This command also performs a backup before updating.

    Plugins are installed to ${XDG_CONFIG_HOME:-$HOME/.config}/nnn/plugins}.

    sh -c "$(curl -Ls https://raw.githubusercontent.com/jarun/nnn/master/plugins/getplugs)"
  10. How to resolve patch conflicts

    master

    If you are developing or maintaining patches and encounter merge conflicts in the source code, follow these steps to resolve them and update the patch file:

    1. Generate conflict markers: Ensure you are on the latest master branch and run the make command with the --merge option for that specific patch. This will inject standard Git conflict markers (<<<<<<<) directly into the source file (e.g., src/nnn.c).
    2. Manual Resolution: Open the affected source file, resolve the conflicts around the markers, and save the file.
    3. Update the patch file: Use the following command sequence to capture your changes as a diff and append it to the existing patch file: git diff > patch.diff && sed -i -e "/^$/{r patch.diff" -e "q;}" patches/[patch_name]/mainline.diff

    Note: Replace [patch_name] with the actual directory name of the patch (e.g., restorepreview).

    # 1. Generate markers
    PATCH_OPTS="--merge" make O_RESTOREPREVIEW=1
    
    # 2. (Manually edit src/nnn.c to resolve <<<<<<< markers)
    
    # 3. Update the patch file
    git diff > patch.diff && sed -i -e "/^$/{r patch.diff" -e "q;}" patches/restorepreview/mainline.diff
  11. Skip directory refresh after running a plugin

    master

    By default, nnn refreshes the directory after a plugin runs to reflect changes. To prevent this automatic refresh, prefix the plugin name with a hyphen (-) in your NNN_PLUG configuration.

    export NNN_PLUG='p:-plugin'
  12. Configure plugin keybindings with NNN_PLUG

    master

    Assign specific keys to plugins using the NNN_PLUG environment variable. You can invoke a plugin by pressing the plugin shortcut (;) followed by the assigned key character.

    Syntax: key:plugin_name or key:subfolder/plugin_name.

    Usage Examples:

    • Single assignment: ;f runs finder.
    • Multiple assignments: ;f:finder;o:fzopen.
    • Subfolders: ;g:personal/convert2zoom looks for the plugin in the personal subfolder within the plugins directory.
    • Run at startup: Use the -P flag followed by the plugin key.

    Important Rules:

    • If you define the same key twice (e.g., b:boom;b:bulknew), only the first definition is used.
    • Keybinding definitions must be exactly 1 character; using more than 1 character will prevent nnn from starting.
    • To run an unassigned plugin, press <kbd>Enter</kbd> at the plugin prompt to enter the plugin directory.
    export NNN_PLUG='f:finder;o:fzopen;p:mocq;d:diffs;t:nmount;v:imgview'