-
-
Notifications
You must be signed in to change notification settings - Fork 2.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
I need help to remove entries from history #3522
Comments
@amigthea Have you seen #2800, or perhaps this discussion? Neither does what you want right out of the box, but might give you some ideas. I am interested in creating something similar for myself - the ability to, from within If I'm successful I'll try to share my implementation here. Or if you beat me to it, perhaps you could do the same? |
thank you for joining @cohml |
Here is a tool I just found which may help a lot: https://github.com/marlonrichert/zsh-hist Please check back in with your implementation if you get something working! |
The idea of removing entries based on their number may not be as straightforward as it seems, given that a history entry can span multiple lines, or can have blank lines. Consequently, the line number you see may not be a reliable indicator to work with. In bash, it appears much simpler to use
loading the history with There are limited options that you can assign to It's generally safer and more efficient to use built-in zsh features like a Footnotes |
thank you for your contribution @LangLangBart |
Additional to the marlonrichert's plugin, I use this as follows albeit it is not exactly what you want since it is assigned to a different key instead of reusing the fzf-delete-history-widget() {
local selected num
setopt localoptions noglobsubst noposixbuiltins pipefail no_aliases 2> /dev/null
local selected=( $(fc -rl 1 | awk '{ cmd=$0; sub(/^[ \t]*[0-9]+\**[ \t]+/, "", cmd); if (!seen[cmd]++) print $0 }' |
FZF_DEFAULT_OPTS="--height ${FZF_TMUX_HEIGHT:-40%} ${FZF_DEFAULT_OPTS-} -n2..,.. --bind=ctrl-r:toggle-sort,ctrl-z:ignore ${FZF_CTRL_R_OPTS-} --query=${(qqq)LBUFFER} +m --multi --bind 'enter:become(echo {+1})'" $(__fzfcmd)) )
local ret=$?
if [ -n "$selected[*]" ]; then
hist delete $selected[*]
fi
zle reset-prompt
return $ret
}
zle -N fzf-delete-history-widget
bindkey -M emacs '^H' fzf-delete-history-widget
bindkey -M vicmd '^H' fzf-delete-history-widget
bindkey -M viins '^H' fzf-delete-history-widget
|
The dedicated widget by The only issue I've noticed is that when you run a command in other shells and then return to your fzf-delete-history-widget() {
local selected num
setopt localoptions noglobsubst noposixbuiltins pipefail no_aliases 2> /dev/null
+ fc -pa $HISTFILE
local selected=( $(fc -rl 1 | awk '{ cmd=$0; sub(/^[ \t]*[0-9]+\**[ \t]+/, "", cmd); if (!seen[cmd]++) print $0 }' |
FZF_DEFAULT_OPTS="--height ${FZF_TMUX_HEIGHT:-40%} ${FZF_DEFAULT_OPTS-} -n2..,.. --bind=ctrl-r:toggle-sort,ctrl-z:ignore ${FZF_CTRL_R_OPTS-} --query=${(qqq)LBUFFER} +m --multi --bind 'enter:become(echo {+1})'" $(__fzfcmd)) )
local ret=$? One might consider closing this issue, as there is no actual bug in |
setting |
Open one terminal, let's call it However, if you examine your The issue lies in this line: The real problem arises when you don't use The deletion is done by adding all commands to be removed to the You can try this in your shell. The session history will contain the HISTORY_IGNORE=(echo 5)
echo 5
# 5
history -1
# 5985 echo 5
tail -3 $HISTFILE
# HISTORY_IGNORE=(echo 5)
# history -1
# tail -3 $HISTFILE Footnotes |
Adding entries to the The following allows you to delete a selected entry from your history file using the ⌃ Control + D key. Important Ensure your environment variable 'HISTFILE' is assigned and exported, e.g. export FZF_CTRL_R_OPTS="$(
cat <<'FZF_FTW'
--bind "ctrl-d:execute-silent(zsh -ic 'fc -pa $HISTFILE; for i in {+1}; do ignore+=( \"${(b)history[$i]}\" );done;HISTORY_IGNORE=\"(${(j:|:)ignore})\";fc -W')+reload:fc -pa $HISTFILE; fc -rl 1 |
awk '{ cmd=$0; sub(/^[ \t]*[0-9]+\**[ \t]+/, \"\", cmd); if (!seen[cmd]++) print $0 }'"
--bind "start:reload:fc -pa $HISTFILE; fc -rl 1 |
awk '{ cmd=$0; sub(/^[ \t]*[0-9]+\**[ \t]+/, \"\", cmd); if (!seen[cmd]++) print $0 }'"
--header 'enter select · ^d remove'
--height 70%
--preview-window 'hidden:down:border-top:wrap:<70(hidden)'
--prompt ' Global History > '
--with-nth 2..
FZF_FTW
)" Colored versionThis version does the same as above, but colorize the lines with # The awk command removes duplicates, and aligns numbers from left to right.
# This alignment is necessary for the 'bat' function to colorize the output correctly while
# maintaining proper field index expression.
export FZF_CTRL_R_OPTS="$(
cat <<'FZF_FTW'
--ansi
--bind "ctrl-d:execute-silent(zsh -ic 'fc -pa $HISTFILE; for i in {+1}; do ignore+=( \"${(b)history[$i]}\" );done;
HISTORY_IGNORE=\"(${(j:|:)ignore})\";fc -W')+reload:fc -pa $HISTFILE; fc -rl 1 |
awk '{ cmd=$0; sub(/^[ \t]*[0-9]+\**[ \t]+/, \"\", cmd); if (!seen[cmd]++) {printf \"%-10s\", $1; $1=\"\"; print $0} }' |
bat --color=always --plain --language sh"
--bind "start:reload:fc -pa $HISTFILE; fc -rl 1 |
awk '{ cmd=$0; sub(/^[ \t]*[0-9]+\**[ \t]+/, \"\", cmd); if (!seen[cmd]++) {printf \"%-10s\", $1; $1=\"\"; print $0} }' |
bat --color=always --plain --language sh"
--header 'enter select · ^d remove'
--height 70%
--preview-window 'hidden:down:border-top:wrap:<70(hidden)'
--preview 'bat --color=always --plain --language sh <<<{2..}'
--prompt ' Global History > '
--with-nth 2..
FZF_FTW
)" The reason you can only select one is because the Line 102 in 8d20f3d
UPDATE: Caution Assigning values to the deletion functionhist_delete_fzf() {
local +h HISTORY_IGNORE=
local -a ignore
fc -pa "$HISTFILE"
selection=$(fc -rl 1 |
awk '{ cmd=$0; sub(/^[ \t]*[0-9]+\**[ \t]+/, "", cmd); if (!seen[cmd]++) print $0}' |
fzf --bind 'enter:become:echo {+f1}')
if [ -n "$selection" ]; then
while IFS= read -r line; do ignore+=("${(b)history[$line]}"); done < "$selection"
HISTORY_IGNORE="(${(j:|:)ignore})"
# Write history excluding lines that match `$HISTORY_IGNORE` and read new history.
fc -W && fc -p "$HISTFILE"
else
echo "nothing deleted from history"
fi
} UPDATE2: |
This thread has suddenly become a work of art. You all are absolute legends! Especially @LangLangBart, whose beautifully formatted comments are a joy to read. Anyway, one semi-involved followup question: My knowledge of zsh syntax and function isn't very deep. What exactly is happening in these complex keybindings (copied from an earlier message)? --bind "ctrl-d:execute-silent(zsh -ic 'fc -pa $HISTFILE; for i in {+1}; do ignore+=( \"${(b)history[$i]}\" );done;HISTORY_IGNORE=\"(${(j:|:)ignore})\";fc -W')+reload:fc -pa $HISTFILE; fc -rl 1 |
awk '{ cmd=$0; sub(/^[ \t]*[0-9]+\**[ \t]+/, \"\", cmd); if (!seen[cmd]++) print $0 }'"
--bind "start:reload:fc -pa $HISTFILE; fc -rl 1 |
awk '{ cmd=$0; sub(/^[ \t]*[0-9]+\**[ \t]+/, \"\", cmd); if (!seen[cmd]++) print $0 }'" If anyone would be kind enough to explain clause by clause what is happening in each, that would be immensely helpful in helping others customize these keybindings to their taste. Many thanks in advance. |
Tip Quick ways to find the meaning of something in for i in $manpath; do find $i -name 'zsh*' | xargs grep -l HISTORY_IGNORE; done
# /usr/share/man/man1/zshparam.1
man zshparam
# … Footnotes |
Is there any bash version of this? |
Made this into a ZSH plugin for anyone to use https://github.com/p1r473/zsh-hist-delete-fzf/ I encourage someone to try and do this with zsh-hist as I cant figure it out |
man fzf
)Info
Problem / Steps to reproduce
For some days now, I'm trying to implement a shortcut into the CTRL-R function, unfortunately to no avail. What I'm trying to achieve is the ability to remove commands from history (enabling multiselection too), within the fzf view; refreshing the fzf results once done.
This is the farthest I could go:
~/.zshrc
export FZF_CTRL_R_OPTS="--bind=\"ctrl-d:execute-silent(awk '{print \$1}' {+f1..} | while read -r linenum; do sed -i "\${linenum}d" "$HISTFILE"; done),ctrl-d:+refresh-preview\" --header \"CTRL-D to remove command from history\""
it can successfully delete the highlighted command from history file but:
/usr/share/fzf/key-bindings.zsh
but it still remove the first selected element only)ctrl-d:+reload(command here)
?Thank you, amazing piece of software
The text was updated successfully, but these errors were encountered: