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

[Windows] backslash characters are double escaped indiscriminately in field index expressions #3626

Closed
4 of 7 tasks
ibhagwan opened this issue Feb 13, 2024 · 3 comments
Closed
4 of 7 tasks
Labels

Comments

@ibhagwan
Copy link

  • I have read through the manual page (man fzf)
  • I have the latest version of fzf
  • I have searched through the existing issues

Info

  • OS
    • Linux
    • Mac OS X
    • Windows
    • Etc.

Problem / Steps to reproduce

While using fzf as a selector for rg I am unable to find a way to send special regex characters since every backslash is doubled, for example, consider the following command:

Only on Windows

break | fzf --ansi --disabled --bind="change:reload:rg --line-number --column --color=always {q}"

Now say I would like to search for open bracket which is a special regex character, I would need to pass \[ to rg, but typing \[ results in the error:

[Command failed: rg --line-number --column --color=always ^"\\[^"]

The escaping logic isn’t limited to {q}, this also happens with {+}, etc.

Another inconsistency I found is if you wish to pass ^ to rg this way you need double up the carets as it’s a special windows escape character, while this makes sense I believe it can be better handled on fzf’s side to provide consistency with other platforms.

During the porting of fzf-lua for windows I also encountered other windows escaping woes (and I also believe I have the solution) for which I’ll open new issues once I have easy reproduction steps.

@junegunn
Copy link
Owner

junegunn commented Mar 6, 2024

Thanks for the report. I'm not a Windows user so I'm basically clueless on the matter.

The escaping code is here:

func quoteEntry(entry string) string {
shell := os.Getenv("SHELL")
if len(shell) == 0 {
shell = "cmd"
}
if strings.Contains(shell, "cmd") {
// backslash escaping is done here for applications
// (see ripgrep test case in terminal_test.go#TestWindowsCommands)
escaped := strings.Replace(entry, `\`, `\\`, -1)
escaped = `"` + strings.Replace(escaped, `"`, `\"`, -1) + `"`
// caret is the escape character for cmd shell
r, _ := regexp.Compile(`[&|<>()@^%!"]`)
return r.ReplaceAllStringFunc(escaped, func(match string) string {
return "^" + match
})
} else if strings.Contains(shell, "pwsh") || strings.Contains(shell, "powershell") {
escaped := strings.Replace(entry, `"`, `\"`, -1)
return "'" + strings.Replace(escaped, "'", "''", -1) + "'"
} else {
return "'" + strings.Replace(entry, "'", "'\\''", -1) + "'"
}
}

and it was from #2641.

@ibhagwan
Copy link
Author

ibhagwan commented Mar 6, 2024

Thanks for the report. I'm not a Windows user so I'm basically clueless on the matter.

Gotcha, I ain’t a windows expert either (nor do I want to be lol) but I was somehow dragged into making fzf-lua support windows, while doing so I came up with what I believe is the correct escaping sequence for cmd.exe on windows, if this is of interest to you I can share my findings/reasoning/code.

As for this issue, it isn’t high priority as this only affects fzf-lua’s “native” commands (I.e. piping the shell command directly to fzf), the problem isn’t found in the non-native commands as I use a neovim headless wrapper to run the command inside which fixes the escaping with lua code.

@junegunn
Copy link
Owner

junegunn commented May 1, 2024

Fixed in 0.51.0.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants