Skip to content
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

fix(zsh): handle backtick trigger edge case #4090

Merged
merged 9 commits into from
Nov 14, 2024

Conversation

LangLangBart
Copy link
Contributor

@LangLangBart LangLangBart commented Nov 12, 2024

Description

If a single backtick is used as a trigger, the words array fails to populate
with the command elements.

The idea here is to temporarily alter the LBUFFER before calling
__fzf_extract_command by escaping the backtick.

The idea is to move the CURSOR before the trigger.

This approach seems a bit hacky, which is why this PR is marked as a draft.

Alternative A

Create a list of invalid triggers, since other characters have also been found
to cause the same issue:

Testing covered only ASCII values 32-126; others were excluded for simplicity.

Symbol Common Name ASCII Occurrences in Public Git Repos
& Ampersand 38 1
; Semicolon 59 ~25
[ Left Bracket 91 1
` Back-tick 96 ~20
| Pipe 124 0

If the user attempts to use one, display a message using zle -M [string] to
indicate the error. This places the string below the command line, prompting the
user to choose a different trigger character.

Alternative B

Fall back to the old extraction method if the words array is empty and the
LBUFFER is not empty, with the downside that it would only work for the first
command.

--- a/shell/completion.zsh
+++ b/shell/completion.zsh
@@ -123,9 +123,20 @@ __fzf_comprun() {
 # Extract the name of the command. e.g. ls; foo=1 ssh **<tab>
 __fzf_extract_command() {
+  local token tokens
   setopt localoptions noksh_arrays
-  # Control completion with the "compstate" parameter, insert and list noting
+  # Control completion with the "compstate" parameter, insert and list nothing
   compstate[insert]=
   compstate[list]=
   cmd_word="${words[1]}"
+  [[ -n $cmd_word ]] && return
+  tokens=(${(z)LBUFFER})
+  for token in $tokens; do
+    token=${(Q)token}
+    if [[ "$token" =~ [[:alnum:]] && ! "$token" =~ "=" ]]; then
+      cmd_word="$token"
+      return
+    fi
+  done
+  cmd_word="${tokens[1]}"
 }

@@ -341,5 +352,4 @@ fzf-completion() {
     # Make the 'cmd_word' global
     zle __fzf_extract_command || :
-    [[ -z "$cmd_word" ]] && return

     [ -z "$trigger"      ] && prefix=${tokens[-1]} || prefix=${tokens[-1]:0:-${#trigger}}

Alternative B might be the best option. If a user encounters an issue like the
one described in #1992, simply suggest using a different trigger?

@jefferickson
Copy link

I'd advocate for Alternative B as I've used the backtick as my trigger for 6+ years. The key is right next to the on an American layout and quite convenient.

Thank you!

It's just important that the cursor is in the 'command' part before the trigger; the actual position is not important.
@LangLangBart
Copy link
Contributor Author

For the current version, the CURSOR is moved before the trigger, as the
words array likely interprets any of the listed characters in the table above
as the start of a new command.

The approach would still extract the correct command.

More testing of these changes is needed.

An error occured when the trigger was assigned to '('
@LangLangBart LangLangBart marked this pull request as ready for review November 12, 2024 20:27
@LangLangBart
Copy link
Contributor Author

I'd advocate for Alternative B

That was also my intention, but temporarily moving the cursor before calling the
__fzf_extract_command completion widget seems to work well and ensures that
the user still gets the correct list of matches displayed in commands like below:

ls ; kill -9 `[TAB]

Please test the latest patch. The zsh version affects many users, and it's
important to avoid releasing with errors. Feedback will help ensure the fix
works well. Thanks!

source <(curl -fsSL https://raw.githubusercontent.com/LangLangBart/fzf/refs/heads/zsh_backtick/shell/completion.zsh)

@jefferickson
Copy link

Please test the latest patch.

The patch works for me and my backtick trigger! Thank you!

@junegunn
Copy link
Owner

junegunn commented Nov 14, 2024

I'm testing the latest revision, and I'm seeing this warning message.
image

Turns out I have setopt WARN_CREATE_GLOBAL in my .zshrc. Can we fix it? Or am I supposed to remove the setting from my config? From a confused bash user.

Having said that, the fix works as expected.

@LangLangBart
Copy link
Contributor Author

Turns out I have setopt WARN_CREATE_GLOBAL in my .zshrc. Can we fix it? Or am I supposed to remove the setting from my config? From a confused bash user.

Thanks for testing. I will add typeset -g cmd_word.

man zshoptions | less --pattern 'WARN_CREATE_GLOBAL'
WARN_CREATE_GLOBAL
  Print a warning message when a global parameter is created in  a
  function  by an assignment or in math context.  This often indi-
  cates that a parameter has  not  been  declared  local  when  it
  should  have  been.   Parameters explicitly declared global from
  within a function using typeset -g do not cause a warning.  Note
  that  there  is no warning when a local parameter is assigned to
  in a nested function, which may also indicate an error.
# see 'zshbuiltins'  for 'typeset'
man zshbuiltins

@junegunn
Copy link
Owner

Thanks, it all looks good to me, is there anything else you want to address?

@LangLangBart
Copy link
Contributor Author

Thanks, it all looks good to me, is there anything else you want to address?

I am finished. During testing, I found no other issues. I hope fzf users won't find any either.

The bugs (missing enhancement) reported from my zsh patches weren't created intentionally, and I am sorry you had to deal with so many releases.

@junegunn
Copy link
Owner

No problem at all, I really appreciate your help.

@junegunn junegunn merged commit 03d6ba7 into junegunn:master Nov 14, 2024
5 checks passed
@junegunn
Copy link
Owner

Merged thanks!

@jefferickson
Copy link

Thank you @LangLangBart ! Really appreciate the fast turn around and response to my report.

tmeijn pushed a commit to tmeijn/dotfiles that referenced this pull request Nov 22, 2024
This MR contains the following updates:

| Package | Update | Change |
|---|---|---|
| [junegunn/fzf](https://github.com/junegunn/fzf) | minor | `v0.55.0` -> `v0.56.3` |

MR created with the help of [el-capitano/tools/renovate-bot](https://gitlab.com/el-capitano/tools/renovate-bot).

**Proposed changes to behavior should be submitted there as MRs.**

---

### Release Notes

<details>
<summary>junegunn/fzf (junegunn/fzf)</summary>

### [`v0.56.3`](https://github.com/junegunn/fzf/releases/tag/v0.56.3): 0.56.3

[Compare Source](junegunn/fzf@v0.56.2...v0.56.3)

-   Bug fixes in zsh scripts
    -   fix(zsh): handle backtick trigger edge case ([#&#8203;4090](junegunn/fzf#4090))
    -   revert(zsh): remove 'fc -RI' call in the history widget ([#&#8203;4093](junegunn/fzf#4093))
    -   Thanks to [@&#8203;LangLangBart](https://github.com/LangLangBart) for the contributions

### [`v0.56.2`](https://github.com/junegunn/fzf/releases/tag/v0.56.2): 0.56.2

[Compare Source](junegunn/fzf@v0.56.1...v0.56.2)

-   Bug fixes
    -   Fixed abnormal scrolling behavior when `--wrap` is set ([#&#8203;4083](junegunn/fzf#4083))
    -   \[zsh] Fixed warning message when `ksh_arrays` is set ([#&#8203;4084](junegunn/fzf#4084))

### [`v0.56.1`](https://github.com/junegunn/fzf/releases/tag/v0.56.1): 0.56.1

[Compare Source](junegunn/fzf@v0.56.0...v0.56.1)

-   Bug fixes and improvements
    -   Fixed a race condition which would cause fzf to present stale results after `reload` ([#&#8203;4070](junegunn/fzf#4070))
    -   `page-up` and `page-down` actions now work correctly with multi-line items ([#&#8203;4069](junegunn/fzf#4069))
    -   `{n}` is allowed in `SCROLL` expression in `--preview-window` ([#&#8203;4079](junegunn/fzf#4079))
    -   \[zsh] Fixed regression in history loading with shared option ([#&#8203;4071](junegunn/fzf#4071))
    -   \[zsh] Better command extraction in zsh completion ([#&#8203;4082](junegunn/fzf#4082))
-   Thanks to [@&#8203;LangLangBart](https://github.com/LangLangBart), [@&#8203;jaydee-coder](https://github.com/jaydee-coder), [@&#8203;alex-huff](https://github.com/alex-huff), and [@&#8203;vejkse](https://github.com/vejkse) for the contributions

### [`v0.56.0`](https://github.com/junegunn/fzf/releases/tag/v0.56.0): 0.56.0

[Compare Source](junegunn/fzf@v0.55.0...v0.56.0)

-   Added `--gap[=N]` option to display empty lines between items.
    -   This can be useful to visually separate adjacent multi-line items.
        ```sh
        ```

### All bash functions, highlighted

      declare -f | perl -0777 -pe 's/^}\n/}\0/gm' |
        bat --plain --language bash --color always |
        fzf --read0 --ansi --reverse --multi --highlight-line --gap
      ```
      <img width="855" alt="image" src="https://github.com/user-attachments/assets/b3d2eaf2-bf44-4e3a-8d7b-9878629dd9be">
    - Or just to make the list easier to read. For single-line items, you probably want to set `--color gutter:-1` as well to hide the gutter.
      ```sh
      fzf --info inline-right --gap --color gutter:-1
      ```
      <img width="855" alt="image" src="https://github.com/user-attachments/assets/113757a1-ccfd-42a6-b946-83533f408e69">

-   Added `noinfo` option to `--preview-window` to hide the scroll indicator in the preview window
-   Bug fixes
    -   Thanks to [@&#8203;LangLangBart](https://github.com/LangLangBart), [@&#8203;akinomyoga](https://github.com/akinomyoga), and [@&#8203;charlievieth](https://github.com/charlievieth) for fixing the bugs

</details>

---

### Configuration

📅 **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined).

🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied.

♻ **Rebasing**: Whenever MR becomes conflicted, or you tick the rebase/retry checkbox.

🔕 **Ignore**: Close this MR and you won't be reminded about this update again.

---

 - [ ] <!-- rebase-check -->If you want to rebase/retry this MR, check this box

---

This MR has been generated by [Renovate Bot](https://github.com/renovatebot/renovate).
<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiIzNy40NDAuNyIsInVwZGF0ZWRJblZlciI6IjM3LjQ0MC43IiwidGFyZ2V0QnJhbmNoIjoibWFpbiIsImxhYmVscyI6WyJSZW5vdmF0ZSBCb3QiXX0=-->
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

0.56.1/2 breaks my FZF_COMPLETION_TRIGGER
3 participants