2012-06-05 12:24:42 +08:00
|
|
|
#
|
2016-05-09 06:57:56 +08:00
|
|
|
# Wrap the builtin history command to provide additional functionality.
|
2012-06-05 12:24:42 +08:00
|
|
|
#
|
2016-08-25 13:56:19 +08:00
|
|
|
function history --description "display or manipulate interactive command history"
|
2016-09-11 11:42:52 +08:00
|
|
|
set -l cmd history
|
2019-12-20 03:59:17 +08:00
|
|
|
set -l options --exclusive 'c,e,p' --exclusive 'S,D,M,V,X'
|
2020-03-10 02:36:12 +08:00
|
|
|
set -a options h/help c/contains e/exact p/prefix
|
|
|
|
set -a options C/case-sensitive R/reverse z/null 't/show-time=?' 'n#max'
|
2017-07-14 07:21:14 +08:00
|
|
|
# The following options are deprecated and will be removed in the next major release.
|
|
|
|
# Note that they do not have usable short flags.
|
2020-03-10 02:36:12 +08:00
|
|
|
set -a options S-search D-delete M-merge V-save X-clear
|
2017-07-14 07:21:14 +08:00
|
|
|
argparse -n $cmd $options -- $argv
|
|
|
|
or return
|
|
|
|
|
|
|
|
if set -q _flag_help
|
|
|
|
__fish_print_help history
|
|
|
|
return 0
|
|
|
|
end
|
|
|
|
|
2016-09-11 11:42:52 +08:00
|
|
|
set -l hist_cmd
|
|
|
|
set -l show_time
|
2017-09-15 06:44:17 +08:00
|
|
|
set -l max_count
|
2019-09-11 23:12:10 +08:00
|
|
|
set -l search_mode
|
2017-09-15 06:44:17 +08:00
|
|
|
set -q _flag_max
|
|
|
|
set max_count -n$_flag_max
|
2016-09-11 11:42:52 +08:00
|
|
|
|
2017-07-14 07:21:14 +08:00
|
|
|
set -q _flag_with_time
|
|
|
|
and set -l _flag_show_time $_flag_with_time
|
|
|
|
if set -q _flag_show_time[1]
|
|
|
|
set show_time --show-time=$_flag_show_time
|
|
|
|
else if set -q _flag_show_time
|
|
|
|
set show_time --show-time
|
2016-09-11 11:42:52 +08:00
|
|
|
end
|
2016-06-29 13:22:40 +08:00
|
|
|
|
2017-07-14 07:21:14 +08:00
|
|
|
set -q _flag_prefix
|
|
|
|
and set -l search_mode --prefix
|
|
|
|
set -q _flag_contains
|
|
|
|
and set -l search_mode --contains
|
|
|
|
set -q _flag_exact
|
|
|
|
and set -l search_mode --exact
|
|
|
|
|
|
|
|
if set -q _flag_delete
|
|
|
|
set hist_cmd delete
|
|
|
|
else if set -q _flag_save
|
|
|
|
set hist_cmd save
|
|
|
|
else if set -q _flag_clear
|
|
|
|
set hist_cmd clear
|
|
|
|
else if set -q _flag_search
|
|
|
|
set hist_cmd search
|
|
|
|
else if set -q _flag_merge
|
|
|
|
set hist_cmd merge
|
2021-10-18 10:27:46 +08:00
|
|
|
else if set -q _flag_clear-session
|
|
|
|
set hist_cmd clear-session
|
2016-07-14 13:33:50 +08:00
|
|
|
end
|
|
|
|
|
2016-09-11 11:42:52 +08:00
|
|
|
# If a history command has not already been specified check the first non-flag argument for a
|
|
|
|
# command. This allows the flags to appear before or after the subcommand.
|
|
|
|
if not set -q hist_cmd[1]
|
|
|
|
and set -q argv[1]
|
2024-04-13 18:21:51 +08:00
|
|
|
if contains $argv[1] search delete merge save clear clear-session append
|
2017-07-14 07:21:14 +08:00
|
|
|
set hist_cmd $argv[1]
|
|
|
|
set -e argv[1]
|
2016-09-11 11:42:52 +08:00
|
|
|
end
|
2016-06-29 13:22:40 +08:00
|
|
|
end
|
|
|
|
|
2016-09-11 11:42:52 +08:00
|
|
|
if not set -q hist_cmd[1]
|
|
|
|
set hist_cmd search # default to "search" if the user didn't specify a subcommand
|
|
|
|
end
|
|
|
|
|
|
|
|
switch $hist_cmd
|
|
|
|
case search # search the interactive command history
|
2016-07-14 13:33:50 +08:00
|
|
|
if isatty stdout
|
2023-10-28 16:31:24 +08:00
|
|
|
set -l pager (__fish_anypager)
|
|
|
|
and isatty stdout
|
|
|
|
or set pager cat
|
2018-11-20 20:10:09 +08:00
|
|
|
|
|
|
|
# If the user hasn't preconfigured less with the $LESS environment variable,
|
2021-07-23 01:19:33 +08:00
|
|
|
# we do so to have it behave like cat if output fits on one screen.
|
2021-09-17 07:30:33 +08:00
|
|
|
if not set -qx LESS
|
2024-11-22 01:27:10 +08:00
|
|
|
set -fx LESS --quit-if-one-screen
|
2021-09-17 07:30:33 +08:00
|
|
|
# Also set --no-init for less < v530, see #8157.
|
2022-10-19 00:05:16 +08:00
|
|
|
if type -q less; and test (less --version | string match -r 'less (\d+)')[2] -lt 530 2>/dev/null
|
2024-11-22 01:27:10 +08:00
|
|
|
set LESS $LESS --no-init
|
2021-09-17 07:30:33 +08:00
|
|
|
end
|
|
|
|
end
|
2018-11-20 20:10:09 +08:00
|
|
|
not set -qx LV # ask the pager lv not to strip colors
|
2024-11-22 01:27:10 +08:00
|
|
|
and set -fx LV -c
|
2018-11-20 20:10:09 +08:00
|
|
|
|
2018-12-12 17:47:17 +08:00
|
|
|
builtin history search $search_mode $show_time $max_count $_flag_case_sensitive $_flag_reverse $_flag_null -- $argv | $pager
|
2016-07-11 21:47:55 +08:00
|
|
|
else
|
2017-09-15 06:44:17 +08:00
|
|
|
builtin history search $search_mode $show_time $max_count $_flag_case_sensitive $_flag_reverse $_flag_null -- $argv
|
2016-07-11 21:47:55 +08:00
|
|
|
end
|
2016-05-09 07:27:15 +08:00
|
|
|
|
2016-09-11 11:42:52 +08:00
|
|
|
case delete # interactively delete history
|
2019-05-30 03:47:10 +08:00
|
|
|
set -l searchterm $argv
|
2016-07-14 13:33:50 +08:00
|
|
|
if not set -q argv[1]
|
2019-05-30 03:47:10 +08:00
|
|
|
read -P"Search term: " searchterm
|
2016-07-11 21:47:55 +08:00
|
|
|
end
|
2016-05-09 07:27:15 +08:00
|
|
|
|
2024-11-22 01:26:47 +08:00
|
|
|
if test "$search_mode" = --exact
|
2022-04-04 03:02:15 +08:00
|
|
|
builtin history delete $search_mode $_flag_case_sensitive -- $searchterm
|
2023-01-29 15:58:13 +08:00
|
|
|
builtin history save
|
2016-07-30 12:24:26 +08:00
|
|
|
return
|
|
|
|
end
|
|
|
|
|
2016-07-14 13:33:50 +08:00
|
|
|
# TODO: Fix this so that requesting history entries with a timestamp works:
|
2016-09-11 11:42:52 +08:00
|
|
|
# set -l found_items (builtin history search $search_mode $show_time -- $argv)
|
2016-10-17 11:33:33 +08:00
|
|
|
set -l found_items
|
2019-05-30 03:47:10 +08:00
|
|
|
set found_items (builtin history search $search_mode $_flag_case_sensitive --null -- $searchterm | string split0)
|
2016-07-14 13:33:50 +08:00
|
|
|
if set -q found_items[1]
|
|
|
|
set -l found_items_count (count $found_items)
|
2016-07-11 21:47:55 +08:00
|
|
|
for i in (seq $found_items_count)
|
2016-07-14 13:33:50 +08:00
|
|
|
printf "[%s] %s\n" $i $found_items[$i]
|
2016-07-11 21:47:55 +08:00
|
|
|
end
|
2023-06-10 21:23:29 +08:00
|
|
|
echo
|
2016-07-14 13:33:50 +08:00
|
|
|
echo "Enter nothing to cancel the delete, or"
|
2023-06-10 21:23:29 +08:00
|
|
|
echo "Enter one or more of the entry IDs or ranges like '5..12', separated by a space."
|
|
|
|
echo "For example '7 10..15 35 788..812'."
|
|
|
|
echo "Enter 'all' to delete all the matching entries."
|
|
|
|
echo
|
|
|
|
read --local --prompt "echo 'Delete which entries? '" choice
|
2016-07-14 13:33:50 +08:00
|
|
|
echo ''
|
2016-05-09 07:27:15 +08:00
|
|
|
|
2016-07-14 13:33:50 +08:00
|
|
|
if test -z "$choice"
|
|
|
|
printf "Cancelling the delete!\n"
|
|
|
|
return
|
|
|
|
end
|
2016-05-09 07:27:15 +08:00
|
|
|
|
2020-03-10 02:36:12 +08:00
|
|
|
if test "$choice" = all
|
2016-07-14 13:33:50 +08:00
|
|
|
printf "Deleting all matching entries!\n"
|
2016-10-12 09:59:45 +08:00
|
|
|
for item in $found_items
|
2016-09-24 11:12:15 +08:00
|
|
|
builtin history delete --exact --case-sensitive -- $item
|
2016-10-12 09:59:45 +08:00
|
|
|
end
|
2016-09-11 11:42:52 +08:00
|
|
|
builtin history save
|
2016-07-14 13:33:50 +08:00
|
|
|
return
|
|
|
|
end
|
2016-05-09 07:27:15 +08:00
|
|
|
|
2023-06-10 21:23:29 +08:00
|
|
|
set -l choices
|
2016-07-14 13:33:50 +08:00
|
|
|
for i in (string split " " -- $choice)
|
2023-06-10 21:23:29 +08:00
|
|
|
# Expand ranges like 577..580
|
|
|
|
if set -l inds (string match -rg '^([1-9][0-9]*)\.\.([1-9][0-9]*)' -- $i)
|
|
|
|
if test $inds[1] -gt $found_items_count
|
|
|
|
or test $inds[1] -gt $inds[2]
|
|
|
|
printf (_ "Ignoring invalid history entry ID \"%s\"\n") $i
|
|
|
|
continue
|
|
|
|
end
|
|
|
|
|
|
|
|
set -l indexes (seq $inds[1] 1 $inds[2])
|
|
|
|
if set -q indexes[1]
|
|
|
|
set -a choices $indexes
|
|
|
|
end
|
2016-07-11 21:47:55 +08:00
|
|
|
continue
|
|
|
|
end
|
2016-05-09 07:27:15 +08:00
|
|
|
|
2023-06-10 21:23:29 +08:00
|
|
|
if string match -qr '^[1-9][0-9]*$' -- $i
|
2024-01-04 22:33:00 +08:00
|
|
|
and test $i -le $found_items_count
|
2023-06-10 21:23:29 +08:00
|
|
|
set -a choices $i
|
|
|
|
else
|
|
|
|
printf (_ "Ignoring invalid history entry ID \"%s\"\n") $i
|
|
|
|
continue
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
if not set -q choices[1]
|
|
|
|
return 1
|
|
|
|
end
|
|
|
|
|
|
|
|
set choices (path sort -u -- $choices)
|
|
|
|
|
|
|
|
echo Deleting choices: $choices
|
|
|
|
for x in $choices
|
|
|
|
printf "Deleting history entry %s: \"%s\"\n" $x $found_items[$x]
|
|
|
|
builtin history delete --exact --case-sensitive -- "$found_items[$x]"
|
2016-05-09 07:27:15 +08:00
|
|
|
end
|
2016-09-11 11:42:52 +08:00
|
|
|
builtin history save
|
2016-07-11 21:47:55 +08:00
|
|
|
end
|
2016-07-14 13:33:50 +08:00
|
|
|
|
2016-09-11 11:42:52 +08:00
|
|
|
case save # save our interactive command history to the persistent history
|
|
|
|
builtin history save -- $argv
|
|
|
|
case merge # merge the persistent interactive command history with our history
|
|
|
|
builtin history merge -- $argv
|
|
|
|
case clear # clear the interactive command history
|
2016-09-10 08:15:23 +08:00
|
|
|
printf (_ "If you enter 'yes' your entire interactive command history will be erased\n")
|
|
|
|
read --local --prompt "echo 'Are you sure you want to clear history? (yes/no) '" choice
|
2020-03-10 02:36:12 +08:00
|
|
|
if test "$choice" = yes
|
2016-09-11 11:42:52 +08:00
|
|
|
builtin history clear -- $argv
|
2020-05-07 11:30:08 +08:00
|
|
|
and printf (_ "Command history cleared!\n")
|
2016-09-10 08:15:23 +08:00
|
|
|
else
|
|
|
|
printf (_ "You did not say 'yes' so I will not clear your command history\n")
|
2016-05-09 07:27:15 +08:00
|
|
|
end
|
2021-10-18 10:27:46 +08:00
|
|
|
case clear-session # clears only session
|
|
|
|
builtin history clear-session -- $argv
|
|
|
|
printf (_ "Command history for session cleared!\n")
|
2024-04-13 18:21:51 +08:00
|
|
|
case append
|
|
|
|
set -l newitem $argv
|
|
|
|
if not set -q argv[1]
|
|
|
|
read -P "Command: " newitem
|
|
|
|
end
|
|
|
|
|
|
|
|
builtin history append -- $newitem
|
2016-09-11 11:42:52 +08:00
|
|
|
case '*'
|
|
|
|
printf "%ls: unexpected subcommand '%ls'\n" $cmd $hist_cmd
|
|
|
|
return 2
|
2016-05-09 07:27:15 +08:00
|
|
|
end
|
2012-06-05 15:40:42 +08:00
|
|
|
end
|