nnn: add cd on quit option

- add bash, zsh, fish, and nushell integration options
- add quitcd configuration for bash, zsh, fish, and nushell
This commit is contained in:
Giang Nguyen 2024-07-15 22:21:46 +07:00
parent 90ae324e2c
commit 838a50be87

View file

@ -104,6 +104,46 @@ in {
''; '';
default = { }; default = { };
}; };
enableBashIntegration = mkOption {
default = true;
type = types.bool;
description = ''
Whether to enable Bash integration.
'';
};
enableZshIntegration = mkOption {
default = true;
type = types.bool;
description = ''
Whether to enable Zsh integration.
'';
};
enableFishIntegration = mkOption {
default = true;
type = types.bool;
description = ''
Whether to enable Fish integration.
'';
};
enableNushellIntegration = mkOption {
default = true;
type = types.bool;
description = ''
Whether to enable Nushell integration.
'';
};
quitcd = mkOption {
default = false;
type = types.bool;
description = ''
Whether to enable cd on quit.
'';
};
}; };
}; };
@ -120,10 +160,127 @@ in {
--prefix NNN_PLUG : "${renderSettings cfg.plugins.mappings}" --prefix NNN_PLUG : "${renderSettings cfg.plugins.mappings}"
''; '';
}); });
quitcd = {
bash_sh_zsh = ''
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
}
}
'';
fish = ''
function n --wraps nnn --description 'support nnn quit and change directory'
# Block nesting of nnn in subshells
if test -n "$NNNLVL" -a "$NNNLVL" -ge 1
echo "nnn is already running"
return
end
# 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
set -x NNN_TMPFILE "$HOME/.config/nnn/.lastd"
end
# 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 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
end
end'';
nu = ''
# 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 replace --all --regex `^cd '|'$` ``
| str replace --all `'\''''` `'`
^rm -- $nnn_tmpfile
cd $path
}
}'';
};
in mkIf cfg.enable { in mkIf cfg.enable {
programs.nnn.finalPackage = nnnPackage; programs.nnn.finalPackage = nnnPackage;
home.packages = [ nnnPackage ]; home.packages = [ nnnPackage ];
xdg.configFile."nnn/plugins" = xdg.configFile."nnn/plugins" =
mkIf (cfg.plugins.src != null) { source = cfg.plugins.src; }; mkIf (cfg.plugins.src != null) { source = cfg.plugins.src; };
programs.bash.initExtra =
mkIf cfg.enableBashIntegration (mkAfter quitcd.bash_sh_zsh);
programs.zsh.initExtra =
mkIf cfg.enableZshIntegration (mkAfter quitcd.bash_sh_zsh);
programs.fish.interactiveShellInit =
mkIf cfg.enableFishIntegration (mkAfter quitcd.fish);
programs.nushell.extraConfig =
mkIf cfg.enableNushellIntegration (mkAfter quitcd.nu);
}; };
} }