Is there a fish way of doing zsh's noglob builtin?
From https://linux.die.net/man/1/zshmisc :
noglob
Filename generation (globbing) is not performed on any of the words.
zsh example:
$ ls /*
<lots of output>
$ noglob ls /*
ls: cannot access '/*': No such file or directory
$ ls "/*"
ls: cannot access '/*': No such file or directory
In fish, this works with quotes:
$ ls "/*"
ls: cannot access '/*': No such file or directory
Is it possible in fish to do the same thing without requiring quotes?
Original answer: Regarding noglob
behavior itself, I'm fairly certain the answer is "No", per this Github issue.
Edit/Update: But given the use-case you describe in the comments, there may be another way to avoid typing the quotes, albeit nowhere near as straightforward as noglob
.
For the sake of keeping this as simple as possible, I deviated slightly from your example in the comments. According to that example, you use noglob
in zsh to create an alias so that:
findf /path/*.ext
maps to find /path -name "*.ext"
I went with using a space to separate the path and the name into two distinct parameters:
findf /path *.ext
maps to find /path -name "*.ext"
Well, sort of - At least that's what you would type. The workaround in this case is to get fish to add the surrounding quotes for you automatically when you type an argument to findf
with a *
wildcard.
To do that, set up three functions (two of them are just one-liners), all in ~/.config/fish/functions
:
findf.fish:
function findf --description 'alias findf=find {path} -name {name}'
find $argv[1..-2] -name $argv[-1]
end
Pretty straightforward - Just passes the last argument to findf
as the -name
argument to find
.
Then the real workhorse. findf_binding.fish:
function findf_binding
commandline -i '*'
set -l tokens (commandline -bo)
if test (count $tokens) -gt 0
and [ $tokens[1] = "findf" ]
set -l currentToken (commandline -t)
if not contains "\"" (string split "" $currentToken)
set -l replaceToken "\""$currentToken"\""
set -l cursorPos (commandline --cursor)
commandline -t $replaceToken
commandline --cursor (math $cursorPos+1)
end
end
end
This basically boils down to "If *
is pressed, and the line starts with findf
, and argument with the *
isn't quoted already, then quote it and move the cursor after the *
."
Finally, bind the *
to the findf_binding
in fish_user_key_bindings.fish:
function fish_user_key_bindings
bind '*' findf_binding
end
Full disclosure - This is my first keybinding script in fish. It's a fish feature that I've been wanting to learn/try out for a while now, and I saw this as a good opportunity. As a result, though, there are undoubtedly some corner cases that I missed, and style or syntax improvements that could be made.
For instance, as a known limitation, if you ever want to use wildcards to match multiple paths (e.g. findf path* *.yaml
) this binding will erroneously add quotes to the path component as well.
But hopefully this gets you close to what you are looking for, or at least puts you on the right track to tweak it or write your own.