mirror of
https://github.com/fish-shell/fish-shell
synced 2024-11-10 07:04:29 +00:00
Add a fish_delta helper function
This helps figuring out which functions, completions and config you've overridden.
This commit is contained in:
parent
3ba1170ca5
commit
054f9baf88
3 changed files with 246 additions and 0 deletions
81
doc_src/cmds/fish_delta.rst
Normal file
81
doc_src/cmds/fish_delta.rst
Normal file
|
@ -0,0 +1,81 @@
|
|||
fish_delta - compare functions and completions to the default
|
||||
==============================================================
|
||||
|
||||
Synopsis
|
||||
--------
|
||||
|
||||
.. synopsis::
|
||||
|
||||
fish_delta name ...
|
||||
fish_delta [-f | --no-functions] [-c | --no-completions] [-C | --no-config] [-d | --no-diff] [-n | --new] [-V | --vendor=]
|
||||
fish_delta [-h | --help]
|
||||
|
||||
|
||||
Description
|
||||
-----------
|
||||
|
||||
The ``fish_delta`` function tells you, at a glance, which of your functions and completions differ from the set that fish ships.
|
||||
|
||||
It does this by going through the relevant variables (:envvar:`fish_function_path` for functions and :envvar:`fish_complete_path` for completions) and comparing the files against fish's default directories.
|
||||
|
||||
If any names are given, it will only compare files by those names (plus a ".fish" extension).
|
||||
|
||||
By default, it will also use ``diff`` to display the difference between the files. If ``diff`` is unavailable, it will skip it, but in that case it also cannot figure out if the files really differ.
|
||||
|
||||
The exit status is 1 if there was a difference and 2 for other errors, otherwise 0.
|
||||
|
||||
Options
|
||||
-------
|
||||
|
||||
The following options are available:
|
||||
|
||||
**-f** or **--no-functions**
|
||||
Stops checking functions
|
||||
|
||||
**-c** or **--no-completions**
|
||||
Stops checking completions
|
||||
|
||||
**-C** or **--no-config**
|
||||
Stops checking configuration files like config.fish or snippets in the conf.d directories.
|
||||
|
||||
**-d** or **--no-diff**
|
||||
Removes the diff display (this happens automatically if ``diff`` can't be found)
|
||||
|
||||
**-n** or **--new**
|
||||
Also prints new files (i.e. those that can't be found in fish's default directories).
|
||||
|
||||
**-Vvalue** or **--vendor=value**
|
||||
Determines how the vendor directories are counted. Valid values are:
|
||||
|
||||
- "default" - counts vendor files as belonging to the defaults. Any changes in other directories will be counted as changes over them. This is the default.
|
||||
- "user" - counts vendor files as belonging to the user files. Any changes in them will be counted as new or changed files.
|
||||
- "ignore" - ignores vendor directories. Files of the same name will be counted as "new" if no file of the same name in fish's default directories exists.
|
||||
|
||||
**-h** or **--help**
|
||||
Prints ``fish_delta``'s help (this).
|
||||
|
||||
Example
|
||||
-------
|
||||
|
||||
Running just::
|
||||
|
||||
fish_delta
|
||||
|
||||
will give you a list of all your changed functions and completions, including diffs (if you have the ``diff`` command).
|
||||
|
||||
It might look like this::
|
||||
|
||||
> fish_delta
|
||||
New: /home/alfa/.config/fish/functions/battery.fish
|
||||
Changed: /home/alfa/.config/fish/test/completions/cargo.fish
|
||||
--- /home/alfa/.config/fish/test/completions/cargo.fish 2022-09-02 12:57:55.579229959 +0200
|
||||
+++ /usr/share/fish/completions/cargo.fish 2022-09-25 17:51:53.000000000 +0200
|
||||
# the output of `diff` follows
|
||||
|
||||
The options are there to select which parts of the output you want. With ``--no-completions`` you can compare just functions, and with ``--no-diff`` you can turn off the ``diff`` display.
|
||||
|
||||
To only compare your ``fish_git_prompt``, you might use::
|
||||
|
||||
fish_delta --no-completions fish_git_prompt
|
||||
|
||||
which will only compare files called "fish_git_prompt.fish".
|
9
share/completions/fish_delta.fish
Normal file
9
share/completions/fish_delta.fish
Normal file
|
@ -0,0 +1,9 @@
|
|||
complete -c fish_delta -f -a '(path filter -rf -- $fish_function_path/*.fish $fish_complete_path/*.fish $__fish_vendor_confdirs/*.fish |
|
||||
path basename | path change-extension "") config'
|
||||
|
||||
complete -c fish_delta -s c -l no-completions -d 'Ignore completions'
|
||||
complete -c fish_delta -s f -l no-functions -d 'Ignore function files'
|
||||
complete -c fish_delta -s C -l no-config -d 'Ignore config files'
|
||||
complete -c fish_delta -s d -l no-diff -d 'Don\'t display the full diff'
|
||||
complete -c fish_delta -s n -l new -d 'Include new files'
|
||||
complete -c fish_delta -s V -l vendor -d 'Choose how to count vendor files' -xa 'ignore\t"Skip vendor files" user\t"Count vendor files as belonging to the user" default\t"Count vendor files as fish defaults"'
|
156
share/functions/fish_delta.fish
Normal file
156
share/functions/fish_delta.fish
Normal file
|
@ -0,0 +1,156 @@
|
|||
function fish_delta
|
||||
argparse h/help f/no-functions c/no-completions C/no-config d/no-diff n/new V/vendor= -- $argv
|
||||
|
||||
if set -q _flag_help
|
||||
__fish_print_help fish_delta
|
||||
return 0
|
||||
end
|
||||
|
||||
type -q diff
|
||||
or set -l _flag_d --no-diff
|
||||
|
||||
set -l vendormode default
|
||||
if set -ql _flag_vendor[1]
|
||||
if not contains -- $_flag_vendor[-1] default ignore user
|
||||
echo "Wrong vendor mode '$_flag_vendor[-1]'." >&2
|
||||
echo "Valid values are: default, ignore, new" >&2
|
||||
return 2
|
||||
end
|
||||
set vendormode $_flag_vendor[-1]
|
||||
end
|
||||
|
||||
# TODO: Do we want to keep the vendor dirs in here?
|
||||
set -l default_function_path $__fish_data_dir/functions
|
||||
test "$vendormode" = default && set -a default_function_path $__fish_vendor_functionsdirs
|
||||
|
||||
set -l default_complete_path $__fish_data_dir/completions
|
||||
test "$vendormode" = default && set -a default_completions_path $__fish_vendor_completionsdirs
|
||||
|
||||
set -l default_conf_path
|
||||
test "$vendormode" = default && set -a default_conf_path $__fish_vendor_confdirs
|
||||
|
||||
set -l user_function_path
|
||||
set -l user_complete_path
|
||||
set -l user_conf_path $__fish_config_dir/conf.d $__fish_sysconf_dir/conf.d
|
||||
test "$vendormode" = user && set -a user_conf_path $__fish_vendor_confdirs
|
||||
|
||||
for dir in $fish_function_path
|
||||
if contains -- $vendormode ignore default
|
||||
contains -- $dir $__fish_vendor_functionsdirs
|
||||
and continue
|
||||
end
|
||||
contains -- $dir $default_function_path
|
||||
or set -a user_function_path $dir
|
||||
end
|
||||
for dir in $fish_complete_path
|
||||
if contains -- $vendormode ignore default
|
||||
contains -- $dir $__fish_vendor_completionsdirs
|
||||
and continue
|
||||
end
|
||||
# We don't care about generated completions.
|
||||
# They shouldn't be compared at all.
|
||||
contains -- $dir $default_complete_path $__fish_user_data_dir/generated_completions
|
||||
or set -a user_complete_path $dir
|
||||
end
|
||||
|
||||
set -l vars
|
||||
not set -ql _flag_f[1]
|
||||
and set -a vars user_function_path default_function_path
|
||||
not set -ql _flag_c[1]
|
||||
and set -a vars user_complete_path default_complete_path
|
||||
not set -ql _flag_C[1]
|
||||
and set -a vars user_conf_path default_conf_path
|
||||
|
||||
if not set -q vars[1]
|
||||
echo No directories to check! >&2
|
||||
return 2
|
||||
end
|
||||
|
||||
set -l have_diff 0
|
||||
|
||||
if isatty stdout
|
||||
set -f colors "$(set_color normal)" "$(set_color brblue)" "$(set_color bryellow)" "$(set_color green)" "$(set_color red)"
|
||||
set -f pager less
|
||||
set -q PAGER
|
||||
and echo $PAGER | read -at pager
|
||||
if type -q less
|
||||
set -l lessopts isRF
|
||||
if test (less --version | string match -r 'less (\d+)')[2] -lt 530 2>/dev/null
|
||||
set lessopts "$lessopts"X
|
||||
end
|
||||
|
||||
not set -qx LESS
|
||||
and set -xf LESS $lessopts
|
||||
end
|
||||
else
|
||||
set -f colors "" "" "" "" ""
|
||||
set -f pager cat # cannot use a builtin here
|
||||
end
|
||||
|
||||
begin
|
||||
while set -q vars[1]
|
||||
set -l user_var $$vars[1]
|
||||
set -l default_var $$vars[2]
|
||||
set -l all_changed 0
|
||||
# We count config files as "changed" compared to /dev/null
|
||||
# because they are being run.
|
||||
test "$vars[1]" = user_conf_path
|
||||
and set all_changed 1
|
||||
set -e vars[..2]
|
||||
set -l files (path filter -rf -- $user_var/$argv.fish)
|
||||
set -q argv[1]
|
||||
or set files (path filter -rf -- $user_var/*)
|
||||
set -q files[1]
|
||||
and set have_diff 1
|
||||
|
||||
for file in $files
|
||||
set -l bn (path basename -- $file)
|
||||
set -l def (path filter -rf -- $default_var/$bn)[1]
|
||||
or begin
|
||||
if test $all_changed = 0
|
||||
set -ql _flag_n
|
||||
and printf (_ "%sNew%s: %s\n") $colors[2] $colors[1] $file
|
||||
continue
|
||||
else
|
||||
set def /dev/null
|
||||
end
|
||||
end
|
||||
|
||||
if type -q diff
|
||||
# We execute diff twice - once to figure out if it's changed,
|
||||
# so we can get nicer output.
|
||||
#
|
||||
if not diff -q -- $file $def >/dev/null 2>&1
|
||||
printf (_ "%sChanged%s: %s\n") $colors[3] $colors[1] $file
|
||||
not set -ql _flag_d[1]
|
||||
and diff -u -- $def $file
|
||||
else
|
||||
printf (_ "%sUnmodified%s: %s\n") $colors[4] $colors[1] $file
|
||||
end
|
||||
else
|
||||
# Without diff, we can't really tell if the contents are the same.
|
||||
printf (_ "%sPossibly changed%s: %s\n") $colors[3] $colors[1] $file
|
||||
end
|
||||
end
|
||||
end
|
||||
# config.fish is special - it's a single file, not a directory,
|
||||
# and it's not precedenced - *both* ~/.config/fish/config.fish and /etc/fish/config.fish
|
||||
# are executed.
|
||||
if not set -ql _flag_C[1]; and begin
|
||||
not set -q argv[1]
|
||||
or contains -- config $argv
|
||||
end
|
||||
for file in (path filter -rf -- $__fish_sysconf_dir/config.fish $__fish_config_dir/config.fish)
|
||||
# We count these as "changed" so they show up.
|
||||
printf (_ "%sChanged%s: %s\n") $colors[3] $colors[1] $file
|
||||
not set -ql _flag_d[1]
|
||||
and diff -u -- /dev/null $file
|
||||
end
|
||||
end
|
||||
# Instead of using diff's --color=always, just do the coloring ourselves.
|
||||
end | string replace -r -- '^(-.*)$' "$colors[5]\$1$colors[1]" |
|
||||
string replace -r -- '^(\+.*)$' "$colors[4]\$1$colors[1]" |
|
||||
$pager
|
||||
|
||||
return $have_diff
|
||||
end
|
Loading…
Reference in a new issue