junegunn / fzf

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

Key Bindings For Windows Muscle Memory #3821

Closed Gavin-Holt closed 1 month ago

Gavin-Holt commented 1 month ago

Checklist

Output of fzf --version

0.52.1 (6432f00)

OS

Shell

Problem / Steps to reproduce

Hi,

I am trying to change the default keybindings for fzf running in the Windows console. As I call fzf from many places I am hoping to use FZF_DEFAULT_OPTS or FZF_DEFAULT_OPTS_FILE, setting it from a batch file which defines my environment:

set FZF_DEFAULT_OPTS="--bind='ctrl-right:forward-word','ctrl-left:backward-word','ctrl-b:beginning-of-line','ctrl-y:kill-line','ctrl-delete:kill-word','ctrl-bspace:backward-kill-word'"

REM Or using a pointer to a file in the same directory 

set FZF_DEFAULT_OPTS_FILE=%~dp0fzf.rc

Q1. Would it be possible to open up some of these key combinations for binding? I note the current list of bindable keys (below) does not include ctrl-right, ctrl-left, ctrl-bspace - I get a polite error message.

Q2. What is the exact format of FZF_DEFAULT_OPTS_FILE?

# Example FZF_DEFAULT_OPTS_FILE - lines are automatically joined
--bind='ctrl-right:forward-word',
'ctrl-left:backward-word',
'ctrl-b:beginning-of-line',
'ctrl-y:kill-line',
'ctrl-delete:kill-word',
'ctrl-bspace:backward-kill-word'

or

# Example FZF_DEFAULT_OPTS_FILE - newlines must be escaped in bat files with ^
--bind='ctrl-right:forward-word',^
'ctrl-left:backward-word',^
'ctrl-b:beginning-of-line',^
'ctrl-y:kill-line',^
'ctrl-delete:kill-word',^
'ctrl-bspace:backward-kill-word'

Many thanks for this marvelous tool, I have used it to extend/enhance micro editor with great results - but I would like my fzf keybindings to match those within the micro editor.

Kind Regards Gavin Holt

Konfekt commented 1 month ago

Usually Windows global environment variables are set in a GUI, rapidee can help. If you don't mind using clink, you can add an envars.lua to the script folder containing, say,

os.setenv("FZF_DEFAULT_OPTS", '--bind=ctrl-l:accept --bind="ctrl-y:execute-silent(echo {..}|clip.exe)+abort"')

to yank the current line to the clipboard by ctrl-y.

Here's what I could hastily port over this way; maybe serves as inspiration:

FZF_DEFAULT_OPTS = " --info=inline --keep-right --exact"
 .. " --bind=ctrl-z:ignore"
 .. " --bind=ctrl-l:accept,ctrl-u:kill-line,change:top,alt-j:preview-page-down,alt-k:preview-page-up"
 .. ' --bind="ctrl-/:toggle-preview"'
 .. ' --bind="ctrl-y:execute-silent(echo {..}|clip.exe)+abort"'

os.setenv("FZF_DEFAULT_OPTS", FZF_DEFAULT_OPTS)

local function command_exists(exe_name)
  local f = io.popen("where " .. exe_name)
  local l = f:read("*a")
  f:close()
  return l ~= nil and l ~= ""
end

FZF_CTRL_T_OPTS = FZF_DEFAULT_OPTS .. ' --preview-window="up,60%,border-bottom,+{2}+3/3,~3"'
if command_exists('rga') then
  os.setenv('FZF_CTRL_T_OPTS', FZF_CTRL_T_OPTS .. ' --preview="rga --passthru -- `"`" {1}"')
elseif command_exists('bat') then
  os.setenv('FZF_CTRL_T_OPTS', FZF_CTRL_T_OPTS .. ' --preview="bat --color=always `"`" {1}"')
else
  os.setenv('FZF_CTRL_T_OPTS', FZF_CTRL_T_OPTS .. ' --preview="echo {}"')
end

os.setenv('FZF_ALT_C_OPTS', FZF_DEFAULT_OPTS .. ' --preview="tree.com /F {}"')

os.setenv("FZF_CTRL_R_OPTS", FZF_DEFAULT_OPTS
  .. ' --preview="echo {}" --preview-window=down:3:hidden:wrap'
  .. ' --bind="ctrl-/:toggle-preview"'
  .. ' --bind="ctrl-y:execute-silent(echo -n {2..}|clip.exe)+abort"'
  .. " --color=header:italic"
  .. ' --header="Press CTRL-Y to copy command into clipboard"')
junegunn commented 1 month ago

Q1. Would it be possible to open up some of these key combinations for binding?

Probably not. fzf is a terminal application, and most terminal emulators don't recognize CTRL-{left,enter,...} key chords. Maybe there are some terminal emulators that support them via some user configuration, but I don't want to confuse many users who don't use them.

Q2. What is the exact format of FZF_DEFAULT_OPTS_FILE?

Can I place text on separate lines?

Yes. New lines and spaces between options are ignored.

Is there a line comment prefix for annotations?

No. Just options. It's nothing more than $FZF_DEFAULT_OPTS stored in a file.

opts='

--header
"hello

world"
--border
--border-label
"goodbye"
'

FZF_DEFAULT_OPTS=$opts fzf

echo "$opts" > /tmp/opts
FZF_DEFAULT_OPTS_FILE=/tmp/opts fzf