Open mgild opened 6 years ago
Probably using the format defined in HISTTIMEFORMAT
is the best approach.
I'm currently using this setting:
HISTTIMEFORMAT='%F %T '
It doesn't seem that HISTTIMEFORMAT effects fzf
The problem with HISTTIMEFORMAT is that it makes history
command much slower. It's unacceptable to me.
> time HISTTIMEFORMAT='%Y/%m/%d %H:%M:%S:' history | wc -l
91125
real 0m3.220s
user 0m0.414s
sys 0m2.975s
> time HISTTIMEFORMAT= history | wc -l
91125
real 0m0.119s
user 0m0.053s
sys 0m0.130s
By the way, AFAIK, HISTTIMEFORMAT is a bash thing. Don't know what the equivalent is in zsh and how it performs.
In fish the equivalent is history --show-time='%h/%d - %H:%M:%S '
. its quite fast in fish. I just added the option to the history command in fzf-history-widget
function. I guess it would work in bash once you set the HISTTIMEFORMAT out of the box
Instead of using HISTTIMEFORMAT
I'm piping output of a custom command instead of history
command so that I have time info and larger history, and fzf
has no problem handling it. But, when I select a line, the time information is also pasted to command line. Is there a way to manipulate the pasted line? For example, how can I remove first 20 characters before pasting the line.
I see the following lines at the end of __fzf_history__()
but not sure if that's the correct place to change:
$(__fzfcmd) |
command grep '^ *[0-9]') &&
if [[ $- =~ H ]]; then
sed 's/^ *\([0-9]*\)\** .*/!\1/' <<< "$line"
else
sed 's/^ *\([0-9]*\)\** *//' <<< "$line"
fi
CTRL-R
toggles the sort order of search results between time and importance. This changes the last line (first line above the prompt) switching between +S
and -S
in my terminal.
Here's a version for Bash, it shows the timestamps in fzf
and strips them when inserting the history entry:
__fzf_history__() {
local output opts
opts="--height ${FZF_TMUX_HEIGHT:-40%} --bind=ctrl-z:ignore ${FZF_DEFAULT_OPTS-} --scheme=history ${FZF_CTRL_R_OPTS-} -n4.. +m +s --tac --ansi"
output=$( builtin history | FZF_DEFAULT_OPTS="$opts" $(__fzfcmd) --query "$READLINE_LINE" ) || return
READLINE_LINE=${output#*\[*\] }
if [[ -z "$READLINE_POINT" ]]; then
echo "$READLINE_LINE"
else
READLINE_POINT=0x7fffffff
fi
}
I'm using this with the following colored format:
HISTTIMEFORMAT=$( echo -ne "\e[0;35m[%Y-%m-%d \e[1;35m%T\e[0;35m]\e[0m " )
Which looks like this:
8953 [2024-03-23 16:22:44] history
+s --tac
disables sorting so the order is the same as when running history
. --ansi
is only needed if you use color codes.
You'll have to tweak two things for different formats:
-n4..
specifies which fields (separated by whitespace) should be searched, in my case I want to ignore the first 3 so only the commands are searched.READLINE_LINE=${output#*\[*\] }
strips the timestamps and history ID. How you do this depends on your format string, in my case I can just match on the square brackets (color codes are already stripped by fzf), and using #
(shortest match) makes sure I don't strip too much, if a command contains square brackets too.In fish the equivalent is
history --show-time='%h/%d - %H:%M:%S '
. its quite fast in fish. I just added the option to the history command infzf-history-widget
function.
In zsh the equivalent is fc -rlt '%h/%d - %H:%M:%S'
. its quite fast in zsh. I just added the option to the fc command in fzf-history-widget
function (in key-bindings.zsh
). Sorry I'm a bit late to the party :-)
Edit: Just remembered the documentation for the newer versions recommends 'eval'ing a pre-canned script emitted by the executable, so either use the old way or,,, eval "$(fzf --zsh | sed 's/fc -rl/fc -rlt %Y-%m-%d/')"
Edit: Just remembered the documentation for the newer versions recommends 'eval'ing a pre-canned script emitted by the executable, so either use the old way or,,, eval "$(fzf --zsh | sed 's/fc -rl/fc -rlt %Y-%m-%d/')"
Since I've got perl installed, the following dirty hack on the top of yours worked for me eval "$(fzf --zsh | sed -e '/zmodload/s/perl/perl_off/' -e '/selected/s/fc -rl/fc -rlt \"%Y-%m-%d %H:%M\"/')"
Neat solution! I recommend switching to the source <(fzf --zsh | sed …)
syntax, to avoid possible aliased commands being used. See #3794 for more details.
EDIT: fc -rlt "%Y-%m-%d %H:%M"
can be swapped for fc -rli
In zsh the equivalent is
fc -rlt '%h/%d - %H:%M:%S'
. its quite fast in zsh. I just added the option to the fc command infzf-history-widget
function (inkey-bindings.zsh
). Sorry I'm a bit late to the party :-)
I had a script that would replace fc -rl
with fc -Erl
everytime the file key-bindings.zsh was modified (like for an update) and that worked out for some time. Recently it stopped working and seems that an update (I'm on v0.53) borked it because I have this script on a server that runs fzf v0.45 and it still works perfectly.
I tried yours eval
, source
commands to no avail, anyone knows how could I fix this?
@amigthea There now seem to be two implementations of fzf-history-widget for zsh, the preferred one uses ${history[@]}
associative array with perl post-processing if both are available, and the non-preferred one uses fc
and awk post-processing.
I tried yours
eval
,source
commands to no avail, anyone knows how could I fix this?
Can you share your command? The workaround solution posted by @hedgieinsocks works well, and modifies the .zsh
keybind to use fc …
rather than … ${(kv)history[@]}
.
Alternatively, enable tracing of the fzf-history-widget
function and share the outcome of the commands below:
# Minimal zsh environment
command env -i HOME=$HOME TERM=$TERM USER=$USER PATH=$PATH zsh -f
fzf --version
source <(fzf --zsh | sed -e '/zmodload/s/perl/perl_off/' -e '/selected/s/fc -rl/fc -Erl/')
# Enable tracing for the function
typeset -fT fzf-history-widget
# Press Ctrl-R, then Enter
@amigthea There now seem to be two implementations of fzf-history-widget for zsh, the preferred one uses
${history[@]}
associative array with perl post-processing if both are available, and the non-preferred one usesfc
and awk post-processing.
I noticed that new if statement, so it's defaulting to the perl?
I tried yours
eval
,source
commands to no avail, anyone knows how could I fix this?Can you share your command? The workaround solution posted by @hedgieinsocks works well, and modifies the
.zsh
keybind to usefc …
rather than… ${(kv)history[@]}
.Alternatively, enable tracing of the
fzf-history-widget
function and share the outcome of the commands below:# Minimal zsh environment command env -i HOME=$HOME TERM=$TERM USER=$USER PATH=$PATH zsh -f fzf --version source <(fzf --zsh | sed -e '/zmodload/s/perl/perl_off/' -e '/selected/s/fc -rl/fc -Erl/') # Enable tracing for the function typeset -fT fzf-history-widget # Press Ctrl-R, then Enter
0.54.0 (9e92b6f1)
+fzf-history-widget:24> return 130
I confirm that sourcing that command display the date correctly
edit: how can I make that permanent between session?
thank you all <3
I would love to view the date and time in the fzf command history list, if possible, much like
does