summaryrefslogtreecommitdiff
path: root/shell/key-bindings.zsh
diff options
context:
space:
mode:
authorKoichi Murase <myoga.murase@gmail.com>2025-06-04 13:11:00 +0900
committerJunegunn Choi <junegunn.c@gmail.com>2025-06-08 00:00:17 +0900
commit09194c24f275d9387b31e50b38cf7f3a94b1f0fa (patch)
treeb4a1502f35c6e919e48e8f6680cdcfa284dc372e /shell/key-bindings.zsh
parentec521e47aa9d8ee0b28801d11d737bf91c46bc43 (diff)
downloadfzf-09194c24f275d9387b31e50b38cf7f3a94b1f0fa.tar.gz
[bash,zsh] Work around a quirk of macOS awk
macOS awk is a variant of nawk, but it contains a unique patch for the UTF-8 support. However, this patch causes the problem. If the input contains any non-UTF-8 data, macOS awk stops processing and does not do anything, instead of ignoring the unrecognized data and continue the processing. However, the contents of the ssh configuration and /etc/hosts is not under the control of fzf, so we cannot fix the input when those files contain non-UTF-8 data. To work around this behavior, one can set the locale to LC_ALL=C to treat the input data with the plain 8-bit encoding.
Diffstat (limited to 'shell/key-bindings.zsh')
-rw-r--r--shell/key-bindings.zsh30
1 files changed, 28 insertions, 2 deletions
diff --git a/shell/key-bindings.zsh b/shell/key-bindings.zsh
index 9c4215e0..51defeab 100644
--- a/shell/key-bindings.zsh
+++ b/shell/key-bindings.zsh
@@ -46,6 +46,32 @@ __fzf_defaults() {
echo -E "${FZF_DEFAULT_OPTS-} $2"
}
+# This function performs `exec awk "$@"` safely by working around awk
+# compatibility issues.
+#
+# Note: To reduce an extra fork, this function performs "exec" so is expected
+# to be run as the last command in a subshell.
+#
+# Note: This function is included with {completion,key-bindings}.{bash,zsh} and
+# synchronized.
+__fzf_exec_awk() {
+ if [[ -z ${__fzf_awk-} ]]; then
+ __fzf_awk=awk
+
+ # choose the faster mawk if: it's installed && build date >= 20230322 &&
+ # version >= 1.3.4
+ local n x y z d
+ IFS=' .' read n x y z d <<< $(command mawk -W version 2> /dev/null)
+ [[ $n == mawk ]] && (( d >= 20230302 && (x * 1000 + y) * 1000 + z >= 1003004 )) && __fzf_awk=mawk
+ fi
+
+ # Note: macOS awk has a quirk that it stops processing at all when it sees
+ # any data not following UTF-8 in the input stream when the current LC_CTYPE
+ # specifies the UTF-8 encoding. To work around this quirk, one needs to
+ # specify LC_ALL=C to change the current encoding to the plain one.
+ LC_ALL=C exec "$__fzf_awk" "$@"
+}
+
# CTRL-T - Paste the selected file path(s) into the command line
__fzf_select() {
setopt localoptions pipefail no_aliases 2> /dev/null
@@ -117,13 +143,13 @@ fzf-history-widget() {
FZF_DEFAULT_OPTS=$(__fzf_defaults "" "-n2..,.. --scheme=history --bind=ctrl-r:toggle-sort --wrap-sign '\t↳ ' --highlight-line ${FZF_CTRL_R_OPTS-} --query=${(qqq)LBUFFER} +m --read0") \
FZF_DEFAULT_OPTS_FILE='' $(__fzfcmd))"
else
- selected="$(fc -rl 1 | awk '{ cmd=$0; sub(/^[ \t]*[0-9]+\**[ \t]+/, "", cmd); if (!seen[cmd]++) print $0 }' |
+ selected="$(fc -rl 1 | __fzf_exec_awk '{ cmd=$0; sub(/^[ \t]*[0-9]+\**[ \t]+/, "", cmd); if (!seen[cmd]++) print $0 }' |
FZF_DEFAULT_OPTS=$(__fzf_defaults "" "-n2..,.. --scheme=history --bind=ctrl-r:toggle-sort --wrap-sign '\t↳ ' --highlight-line ${FZF_CTRL_R_OPTS-} --query=${(qqq)LBUFFER} +m") \
FZF_DEFAULT_OPTS_FILE='' $(__fzfcmd))"
fi
local ret=$?
if [ -n "$selected" ]; then
- if [[ $(awk '{print $1; exit}' <<< "$selected") =~ ^[1-9][0-9]* ]]; then
+ if [[ $(__fzf_exec_awk '{print $1; exit}' <<< "$selected") =~ ^[1-9][0-9]* ]]; then
zle vi-fetch-history -n $MATCH
else # selected is a custom query, not from history
LBUFFER="$selected"