fish functions and user key bindings

This commit is contained in:
Noah Masur
2025-02-02 21:45:34 -05:00
parent 1226eafef2
commit 6f2b2a7694
24 changed files with 274 additions and 335 deletions

View File

@ -36,5 +36,12 @@ in
};
};
config.nmasur.presets.programs.fish.fish_user_key_bindings = # fish
''
# Ctrl-h
bind -M insert \ch '_atuin_search --filter-mode global'
bind -M default \ch '_atuin_search --filter-mode global'
'';
};
}

View File

@ -13,6 +13,7 @@ in
options.nmasur.presets.programs.bash.enable = lib.mkEnableOption "Bash shell";
config = lib.mkIf cfg.enable {
programs.bash = {
enable = true;
shellAliases = config.programs.fish.shellAliases;
@ -20,9 +21,5 @@ in
profileExtra = "";
};
programs.starship.enableBashIntegration = false;
programs.zoxide.enableBashIntegration = true;
programs.fzf.enableBashIntegration = true;
};
}

View File

@ -10,34 +10,35 @@ in
{
options.nmasur.presets.programs.fish.enable = lib.mkEnableOption "Fish shell";
options.nmasur.presets.programs.fish = {
enable = lib.mkEnableOption "Fish shell";
fish_user_key_bindings = lib.mkOption {
type = lib.types.lines;
description = "Text of fish_user_key_bindings function";
default = "";
};
};
config = lib.mkIf cfg.enable {
cfg.fish_user_key_bindings = # fish
''
# Shift-Enter (defined by terminal)
bind -M insert \x1F accept-autosuggestion
bind -M default \x1F accept-autosuggestion
'';
programs.fish = {
enable = true;
functions = {
commandline-git-commits = {
description = "Insert commit into commandline";
body = builtins.readFile ./functions/commandline-git-commits.fish;
};
copy = {
description = "Copy file contents into clipboard";
body = "cat $argv | pbcopy"; # Need to fix for non-macOS
};
edit = {
description = "Open a file in Vim";
body = builtins.readFile ./functions/edit.fish;
};
envs = {
description = "Evaluate a bash-like environment variables file";
body = ''set -gx (cat $argv | tr "=" " " | string split ' ')'';
};
fcd = {
description = "Jump to directory";
argumentNames = "directory";
body = builtins.readFile ./functions/fcd.fish;
};
fish_user_key_bindings = {
body = builtins.readFile ./functions/fish_user_key_bindings.fish;
};
@ -48,14 +49,6 @@ in
description = "Tidy up JSON using jq";
body = "pbpaste | jq '.' | pbcopy"; # Need to fix for non-macOS
};
recent = {
description = "Open a recent file in Vim";
body = builtins.readFile ./functions/recent.fish;
};
search-and-edit = {
description = "Search and open the relevant file in Vim";
body = builtins.readFile ./functions/search-and-edit.fish;
};
_which = {
description = "Identify the path to a program in the shell";
body = "command --search (string sub --start=2 $argv)";
@ -123,9 +116,5 @@ in
home.sessionVariables.fish_greeting = "";
programs.starship.enableFishIntegration = true;
programs.zoxide.enableFishIntegration = true;
programs.fzf.enableFishIntegration = true;
};
}

View File

@ -1,67 +0,0 @@
{
config,
pkgs,
lib,
...
}:
let
cfg = config.nmasur.presets.programs.fzf;
in
{
options.nmasur.presets.programs.fzf.enable = lib.mkEnableOption "Fzf fuzzy finder";
config = lib.mkIf cfg.enable {
programs.fzf.enable = true;
programs.fish = {
functions = {
projects = {
description = "Jump to a project";
body = ''
set projdir ( \
fd \
--search-path $HOME/dev \
--type directory \
--exact-depth 2 \
| ${pkgs.proximity-sort}/bin/proximity-sort $PWD \
| sed 's/\\/$//' \
| fzf --tiebreak=index \
)
and cd $projdir
and commandline -f execute
'';
};
};
shellAbbrs = {
lsf = "ls -lh | fzf";
};
};
# Global fzf configuration
home.sessionVariables =
let
fzfCommand = "fd --type file";
in
{
FZF_DEFAULT_COMMAND = fzfCommand;
FZF_CTRL_T_COMMAND = fzfCommand;
FZF_DEFAULT_OPTS = "-m --height 50% --border";
};
home.packages = [
(pkgs.writeShellApplication {
name = "jqr";
runtimeInputs = [
pkgs.jq
pkgs.fzf
];
text = builtins.readFile ./bash/scripts/jqr.sh;
})
];
};
}

View File

@ -0,0 +1,100 @@
{
config,
pkgs,
lib,
...
}:
let
cfg = config.nmasur.presets.programs.fzf;
in
{
options.nmasur.presets.programs.fzf.enable = lib.mkEnableOption "Fzf fuzzy finder";
config = lib.mkIf cfg.enable {
programs.fzf = {
enable = true;
enableFishIntegration = true;
enableBashIntegration = true;
};
programs.fish = {
functions = {
edit = {
description = "Open a file in Vim";
body = builtins.readFile ./fish/edit.fish;
};
fcd = {
description = "Jump to directory";
argumentNames = "directory";
body = builtins.readFile ./fish/fcd.fish;
};
projects = {
description = "Jump to a project";
body = # fish
''
set projdir ( \
fd \
--search-path $HOME/dev \
--type directory \
--exact-depth 2 \
| ${lib.getExe pkgs.proximity-sort} $PWD \
| sed 's/\\/$//' \
| fzf --tiebreak=index \
)
and cd $projdir
and commandline -f execute
'';
};
recent = {
description = "Open a recent file in Vim";
body = builtins.readFile ./edit/recent.fish;
};
search-and-edit = {
description = "Search and open the relevant file in Vim";
body = builtins.readFile ./edit/search-and-edit.fish;
};
};
shellAbbrs = {
lsf = "ls -lh | fzf";
};
};
config.nmasur.presets.programs.fish.fish_user_key_bindings = # fish
''
# Ctrl-o
bind -M insert \co edit
bind -M default \co edit
# Ctrl-s
bind -M insert \cs search-and-edit
bind -M default \cs search-and-edit
# Ctrl-a
bind -M insert \ca 'cd ~; and edit; and commandline -a "; cd -"; commandline -f execute'
bind -M default \ca 'cd ~; and edit; and commandline -a "; cd -"; commandline -f execute'
# Ctrl-e
bind -M insert \ce recent
bind -M default \ce recent
# Ctrl-f
bind -M insert \cf fcd
bind -M default \cf fcd
# Ctrl-p
bind -M insert \cp projects
bind -M default \cp projects
'';
# Global fzf configuration
home.sessionVariables =
let
fzfCommand = "${lib.getExe pkgs.fd} --type file";
in
{
FZF_DEFAULT_COMMAND = fzfCommand;
FZF_CTRL_T_COMMAND = fzfCommand;
FZF_DEFAULT_OPTS = "-m --height 50% --border";
};
};
}

View File

@ -0,0 +1,4 @@
set vimfile (fzf)
and set vimfile (echo $vimfile | tr -d '\r')
and commandline -r "vim \"$vimfile\""
and commandline -f execute

View File

@ -0,0 +1,10 @@
if test -z $directory
set directory "$HOME"
end
if ! test -d $directory
echo "Directory not found: $directory"
return 1
end
set jump (fd -t d . $directory | fzf)
and cd $jump $argv
and commandline -f execute

View File

@ -0,0 +1,4 @@
set vimfile (fd -t f --exec /usr/bin/stat -f "%m%t%N" | sort -nr | cut -f2 | fzf)
and set vimfile (echo $vimfile | tr -d '\r')
and commandline -r "vim $vimfile"
and commandline -f execute

View File

@ -0,0 +1,21 @@
set vimfile ( \
rg \
--color=always \
--line-number \
--no-heading \
--smart-case \
--iglob "!/Library/**" \
--iglob "!/System/**" \
--iglob "!Users/$HOME/Library/*" \
".*" \
| fzf --ansi \
--height "80%" \
--color "hl:-1:underline,hl+:-1:underline:reverse" \
--delimiter : \
--preview 'bat --color=always {1} --highlight-line {2}' \
--preview-window 'up,60%,border-bottom,+{2}+3/3,~3'
)
and set line_number (echo $vimfile | tr -d '\r' | cut -d':' -f2)
and set vimfile (echo $vimfile | tr -d '\r' | cut -d':' -f1)
and commandline -r "vim +$line_number \"$vimfile\""
and commandline -f execute

View File

@ -108,14 +108,14 @@ in
programs.fish.functions = {
git = {
body = builtins.readFile ./fish/functions/git.fish;
body = builtins.readFile ./fish/git.fish;
};
git-add-fuzzy = {
body = builtins.readFile ./fish/functions/git-add-fuzzy.fish;
body = builtins.readFile ./fish/git-add-fuzzy.fish;
};
git-fuzzy-branch = {
argumentNames = "header";
body = builtins.readFile ./fish/functions/git-fuzzy-branch.fish;
body = builtins.readFile ./fish/git-fuzzy-branch.fish;
};
git-checkout-fuzzy = {
body = ''
@ -149,18 +149,30 @@ in
'';
};
git-show-fuzzy = {
body = builtins.readFile ./fish/functions/git-show-fuzzy.fish;
body = builtins.readFile ./fish/git-show-fuzzy.fish;
};
git-commits = {
body = builtins.readFile ./fish/functions/git-commits.fish;
body = builtins.readFile ./fish/git-commits.fish;
};
commandline-git-commits = {
description = "Insert commit into commandline";
body = builtins.readFile ./fish/commandline-git-commits.fish;
};
git-history = {
body = builtins.readFile ./fish/functions/git-history.fish;
body = builtins.readFile ./fish/git-history.fish;
};
uncommitted = {
description = "Find uncommitted git repos";
body = builtins.readFile ./fish/functions/uncommitted.fish;
body = builtins.readFile ./fish/uncommitted.fish;
};
};
config.nmasur.presets.programs.fish.fish_user_key_bindings = # fish
''
# Ctrl-g
bind -M default \cg commandline-git-commits
bind -M insert \cg 'commandline -i (git rev-parse --show-toplevel 2>/dev/null || echo ".")'
'';
};
}

View File

@ -0,0 +1,6 @@
set commit (git-commits)
if [ $commit ]
commandline -i "$commit"
else
commandline -i HEAD
end

View File

@ -0,0 +1,14 @@
set gitfile (git status -s \
| fzf \
--height 50% \
-m \
--preview-window right:70% \
--layout reverse \
--preview 'set -l IFS; set gd (git diff --color=always (echo {} | awk \'{$1=$1};1\' | cut -d" " -f2)); if test "$gd"; echo "$gd"; else; bat --color=always (echo {} | awk \'{$1=$1};1\' | cut -d" " -f2); end')
and for gf in $gitfile
set gf (echo $gf \
| awk '{$1=$1};1' \
| cut -d' ' -f2 \
)
and git add $gf
end

View File

@ -0,0 +1,8 @@
set commitline (git log \
--pretty="format:%C(auto)%ar %h%d %s" \
| fzf \
--height 50% \
--preview 'git show --color=always (echo {} | cut -d" " -f4)' \
)
and set commit (echo $commitline | cut -d" " -f4)
and echo $commit

View File

@ -0,0 +1,10 @@
set -l current (git rev-parse --abbrev-ref HEAD | tr -d '\n')
set -l branch (git branch \
--format "%(refname:short)" \
| fzf \
--height 50% \
--header="On $current, $header" \
--preview-window right:70% \
--preview 'git log {} --color=always --pretty="format:%C(auto)%ar %h%d %s"' \
)
and echo $branch

View File

@ -0,0 +1,14 @@
if not count $argv >/dev/null
echo "Must provide filename."
return 1
end
set commitline ( git log \
--follow \
--pretty="format:%C(auto)%ar %h%d %s" \
-- ./$argv \
| fzf \
--height 100% \
--preview "git diff --color=always (echo {} | cut -d' ' -f4)^1..(echo {} | cut -d' ' -f4) -- ./$argv" \
)
and set commit (echo $commitline | cut -d" " -f4)
and echo $commit

View File

@ -0,0 +1,6 @@
set commitline (git log \
--pretty="format:%C(auto)%ar %h%d %s" \
| fzf \
)
and set commit (echo $commitline | cut -d" " -f4 )
and git show $commit

View File

@ -0,0 +1,37 @@
if contains f $argv
switch $argv[1]
case checkout
git-checkout-fuzzy
case add
git-add-fuzzy
case show
git-show-fuzzy
case merge
git-merge-fuzzy
case branch
if test "$argv[2]" = -d
git-delete-fuzzy
else if test "$argv[2]" = -D
git-force-delete-fuzzy
else
echo "Not a fuzzy option."
return 1
end
case reset
set commit (git-commits)
and if test "$argv[2]" = --hard
git reset --hard $commit
else
git reset $commit
end
case "*"
echo "No fuzzy option."
return 1
end
else
if count $argv >/dev/null
command git $argv
else
command git status -sb
end
end

View File

@ -0,0 +1,9 @@
echo "Searching git repos..." >&2
find "$HOME/dev" -type d -name '.git' | while read dir
set fullPath (dirname "$dir")
set relativePath (echo "$fullPath" | cut -d'/' -f5-)
if test -n (echo (git -C "$fullPath" status -s))
echo "$relativePath"
git -C "$fullPath" status -s
end
end

View File

@ -36,45 +36,60 @@ in
};
functions = {
nix-shell-run = {
body = ''
set program $argv[1]
if test (count $argv) -ge 2
commandline -r "nix run nixpkgs#$program -- $argv[2..-1]"
else
commandline -r "nix run nixpkgs#$program"
end
commandline -f execute
'';
body = # fish
''
set program $argv[1]
if test (count $argv) -ge 2
commandline -r "nix run nixpkgs#$program -- $argv[2..-1]"
else
commandline -r "nix run nixpkgs#$program"
end
commandline -f execute
'';
};
nix-fzf = {
body = ''
commandline -i (nix-instantiate --eval --json \
-E 'builtins.attrNames (import <nixpkgs> {})' \
| jq '.[]' -r | fzf)
commandline -f repaint
'';
body = # fish
''
commandline -i (nix-instantiate --eval --json \
-E 'builtins.attrNames (import <nixpkgs> {})' \
| ${lib.getExe pkgs.jq} '.[]' -r | ${lib.getExe pkgs.fzf})
commandline -f repaint
'';
};
rebuild-nixos = {
body = ''
git -C ${config.dotfilesPath} add --intent-to-add --all
echo "doas nixos-rebuild switch --flake ${config.dotfilesPath}#${config.networking.hostName}"
'';
body = # fish
''
git -C ${config.dotfilesPath} add --intent-to-add --all
echo "doas nixos-rebuild switch --flake ${config.dotfilesPath}#${config.networking.hostName}"
'';
};
rebuild-nixos-offline = {
body = ''
git -C ${config.dotfilesPath} add --intent-to-add --all
echo "doas nixos-rebuild switch --option substitute false --flake ${config.dotfilesPath}#${config.networking.hostName}"
'';
body = # fish
''
git -C ${config.dotfilesPath} add --intent-to-add --all
echo "doas nixos-rebuild switch --option substitute false --flake ${config.dotfilesPath}#${config.networking.hostName}"
'';
};
rebuild-home = {
body = ''
git -C ${config.dotfilesPath} add --intent-to-add --all
echo "${pkgs.home-manager}/bin/home-manager switch --flake ${config.dotfilesPath}#${config.networking.hostName}";
'';
body = # fish
''
git -C ${config.dotfilesPath} add --intent-to-add --all
echo "${lib.getExe pkgs.home-manager} switch --flake ${config.dotfilesPath}#${config.networking.hostName}";
'';
};
};
};
config.nmasur.presets.programs.fish.fish_user_key_bindings = # fish
''
# Ctrl-n
bind -M insert \cn 'commandline -r "nix shell nixpkgs#"'
bind -M default \cn 'commandline -r "nix shell nixpkgs#"'
# Ctrl-Shift-n (defined by terminal)
bind -M insert \x11F nix-fzf
bind -M default \x11F nix-fzf
'';
# Provides "command-not-found" options
programs.nix-index = {
enable = true;

View File

@ -14,65 +14,70 @@ in
options.nmasur.presets.programs.starship.enable = lib.mkEnableOption "Starship shell prompt";
config = lib.mkIf cfg.enable {
enable = true;
settings = {
add_newline = false; # Don't print new line at the start of the prompt
format = lib.concatStrings [
"$directory"
"$git_branch"
"$git_commit"
"$git_status"
"$hostname"
"$cmd_duration"
"$character"
];
right_format = "$nix_shell";
character = {
success_symbol = "[](bold green)";
error_symbol = "[](bold red)";
vicmd_symbol = "[](bold green)";
};
cmd_duration = {
min_time = 5000;
show_notifications = if pkgs.stdenv.isLinux then false else true;
min_time_to_notify = 30000;
format = "[$duration]($style) ";
};
directory = {
truncate_to_repo = true;
truncation_length = 100;
};
git_branch = {
format = "[$symbol$branch]($style)";
};
git_commit = {
format = "( @ [$hash]($style) )";
only_detached = false;
};
git_status = {
format = "([$all_status$ahead_behind]($style) )";
conflicted = "=";
ahead = "";
behind = "";
diverged = "";
untracked = "";
stashed = "";
modified = "";
staged = "+";
renamed = "»";
deleted = "";
style = "red";
};
hostname = {
ssh_only = true;
format = "on [$hostname](bold red) ";
};
nix_shell = {
format = "[$symbol $name]($style)";
symbol = "";
};
python = {
format = "[\${version}\\(\${virtualenv}\\)]($style)";
programs.starship = {
enable = true;
enableFishIntegration = true;
enableBashIntegration = true;
settings = {
add_newline = false; # Don't print new line at the start of the prompt
format = lib.concatStrings [
"$directory"
"$git_branch"
"$git_commit"
"$git_status"
"$hostname"
"$cmd_duration"
"$character"
];
right_format = "$nix_shell";
character = {
success_symbol = "[](bold green)";
error_symbol = "[](bold red)";
vicmd_symbol = "[](bold green)";
};
cmd_duration = {
min_time = 5000;
show_notifications = if pkgs.stdenv.isLinux then false else true;
min_time_to_notify = 30000;
format = "[$duration]($style) ";
};
directory = {
truncate_to_repo = true;
truncation_length = 100;
};
git_branch = {
format = "[$symbol$branch]($style)";
};
git_commit = {
format = "( @ [$hash]($style) )";
only_detached = false;
};
git_status = {
format = "([$all_status$ahead_behind]($style) )";
conflicted = "=";
ahead = "";
behind = "";
diverged = "";
untracked = "";
stashed = "";
modified = "";
staged = "+";
renamed = "»";
deleted = "";
style = "red";
};
hostname = {
ssh_only = true;
format = "on [$hostname](bold red) ";
};
nix_shell = {
format = "[$symbol $name]($style)";
symbol = "";
};
python = {
format = "[\${version}\\(\${virtualenv}\\)]($style)";
};
};
};

View File

@ -0,0 +1,25 @@
{
config,
pkgs,
lib,
...
}:
let
cfg = config.nmasur.presets.programs.zoxide;
in
{
options.nmasur.presets.programs.zoxide.enable = lib.mkEnableOption "zoxide smart cd replacement";
config = lib.mkIf cfg.enable {
programs.zoxide = {
enable = true;
enableFishIntegration = true;
enableBashIntegration = true;
};
};
}

View File

@ -33,7 +33,6 @@ in
pkgs.mpd # TUI slideshows
];
programs.zoxide.enable = lib.mkDefault true; # Shortcut jump command
programs.fish.shellAliases = {
"cd" = lib.mkDefault lib.getExe pkgs.zoxide;
"du" = lib.mkDefault lib.getExe pkgs.dua;
@ -53,6 +52,7 @@ in
ripgrep.enable = lib.mkDefault true;
prettyping.enable = lib.mkDefault true;
weather.enable = lib.mkDefault true;
zoxide.enable = lib.mkDefault true;
};
};