paradigm / SkyBison

Vim plugin to expedite use of cmdline commands
73 stars 9 forks source link

On Windows, SkyBison can't differentiate between directories or filenames with escaped spaces #11

Closed jamessan closed 11 years ago

jamessan commented 11 years ago

If there are multiple directories with the same initial letter (e.g., foo1, foo2, foo3) in Vim's current working directory, :call SkyBison('e f') will treat the directories as one filename -- Press <CR> to select and run with "foo1\ foo2\ foo3\".

jamessan commented 11 years ago

This leads to the problem that a mapping like nnoremap <Leader>e 2:<C-u>call SkyBison('e ')<CR> will automatically open a non-existent file in this scenario.

paradigm commented 11 years ago

I'll look into it.

I'm able to reproduce it.

paradigm commented 11 years ago

I've managed to figure out exactly why that happens, but at the moment I'm not sure if there is a clean way to fix it.

The way SkyBison gets information out of Vim is via this line here:

https://github.com/paradigm/SkyBison/blob/master/plugin/skybison.vim#L176

Essentially all that does is run c_ctrl-a to fill the cmdline with completion options. All SkyBison gets back is a string - SkyBison has to figure out where different terms start and end. Vim is nice enough to escape whitespace within any given term, so I've been using this line to break it up (note the regex):

https://github.com/paradigm/SkyBison/blob/master/plugin/skybison.vim#L181

The problem is that, on Windows, c_ctrl-a will toss backspaces after directories as well. The string I'm getting from c_ctrl-a doesn't seem to differentiate between two terms, the first of which is a directory, and one term which includes an escaped space.

For example, if the present working directory contains:

The cmdline, after running :e <c-a>, will look like:

e dir1\ dir2\ file\ with\ spaces

Without additional information, there isn't a good way to parse that to get a meaningful difference between directories and file names with spaces in them.

To remedy this, we'll either need (1) to put logic in there specifically to handle file path stuff (which somewhat defeats the point behind SkyBison), or (2) find another way to get completion information out of Vim.

jamessan commented 11 years ago

If you do decide to distinguish between file completion and non-file completion, expand() should come in handy:

When {expr} does not start with '%', '#' or '<', it is expanded like a file name is expanded on the command line. 'suffixes' and 'wildignore' are used, unless the optional {nosuf} argument is given and it is non-zero.

From a quick test, :call expand('f*') gives the same info as :e f<C-a>, but as a list so you know what each item is.

Of course, even better would be if Vim exposed a way for a script to get what the current wildmode completions would be given the current command line (your option 2).

paradigm commented 11 years ago

SkyBison not only works with Vim's built-in completion, but also :help command-complete-custom. Would a custom command (with custom completion that reads from :call expand('f*')) be a viable option for you? Basically instead of calling SkyBison('e ') you'd just call SkyBison('E ') and everything would be all dandy. If that works for you, I'll be happy to write the custom command up for you.

jamessan commented 11 years ago

I'd rather get Vim fixed to provide proper introspection than require people to create user-commands that wrap any native command which completes paths. If/when that happens, then SkyBison would obviously not need any changes.

My suggestion at this point would be to either close this as not a problem SkyBison can solve or add something like SkyBisonPath('e ') which people can use for any command that does path completion. The theoretical SkyBisonPath at least means there's only one piece of code that needs to be written instead of one for every command that completes paths. The downside being that users can no longer just blindly use SkyBison().

paradigm commented 11 years ago

Sadly, not a problem SkyBison can cleanly solve at the moment. Hopefully Vim's backslash situation can be clarified or, preferably, Vim would support proper introspection.

paradigm commented 11 years ago

If Windows users don't mind using forward slashes to separate, we can probably fix this very cleanly by just setting (locally/temporarily) shellslash. This ensures Vim will append a forward slash at the end of a directory rather than a backslash, which will allow SkyBison to differentiate between directories and escaped whitespace. I'll have a patch up in a few.

paradigm commented 11 years ago

The latest commit seems to fix it. If you can confirm it looks good on your end I'll close the issue.

jamessan commented 11 years ago

:+1: