junegunn / fzf

:cherry_blossom: A command-line fuzzy finder
https://junegunn.github.io/fzf/
MIT License
63.64k stars 2.36k forks source link

Feature request: Add an option to display date-time of fzf command history #1049

Open mgild opened 6 years ago

mgild commented 6 years ago

I would love to view the date and time in the fzf command history list, if possible, much like

fc -li

does

edubxb commented 6 years ago

Probably using the format defined in HISTTIMEFORMAT is the best approach.

I'm currently using this setting:

HISTTIMEFORMAT='%F %T '

mgild commented 6 years ago

It doesn't seem that HISTTIMEFORMAT effects fzf

junegunn commented 6 years ago

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.

deepredsky commented 6 years ago

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

alperyilmaz commented 6 years ago

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
socketbox commented 2 years ago

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.

toupeira commented 5 months ago

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:

cochon-git commented 4 months ago

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.

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/')"

hedgieinsocks commented 2 months ago

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\"/')"

LangLangBart commented 2 months ago

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

amigthea commented 1 month ago

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 :-)

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?

intelfx commented 1 month ago

@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.

LangLangBart commented 1 month ago

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 commented 1 month ago

@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 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 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
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