vim-fern icon indicating copy to clipboard operation
vim-fern copied to clipboard

Ability to create multiple files and / or directories in 1 command

Open nickjj opened this issue 4 years ago • 14 comments

I find myself creating directories and files using Fern because it's handy, but I noticed that you can't create more than 1 file or directory at a time in a way that produces an expected result.

For example if you create a new path and enter in a/ b/ you end up with a/b (B is nested in A) instead of a/ b/ (they are their own independent directories). The expected outcome would be what you'd get if you used mkdir or touch directly.

To get around this I find myself running :!mkdir a/ b/ in Vim directly which works but this also means a lot more typing (especially if it's a nested directory in a project) and also reloading Fern to pick up the changes.

nickjj avatar Feb 23 '21 15:02 nickjj

For example if you create a new path and enter in a/ b/ you end up with a/b (B is nested in A) instead of a/ b/ (they are their own independent directories). The expected outcome would be what you'd get if you used mkdir or touch directly.

No. It's a bit incorrect. Fern creates a/ b/ rather than a/b/ for a/ b/ thus users get the result as-is. I didn't designed the feature to mimic the behavior of mkdir or touch.

I understand your want but I cannot image a good interface which consistent with the current one (I'm not going to apply breaking changes for this.) Does anyone have ideas?

lambdalisue avatar Feb 23 '21 18:02 lambdalisue

No. It's a bit incorrect. Fern creates a/ b/ rather than a/b/ for a/ b/ thus users get the result as-is.

Oh my machine (Ubuntu 20.04 LTS) with the latest version of Fern as of today if I run fern-action-new-path and type a/ b/ it will create this directory structure:

$ ls -laR

.:
total 80
drwxr-xr-x   3 nick nick  4096 Feb 23 13:44 .
drwxrwxrwt 210 root root 69632 Feb 23 13:45 ..
drwxr-xr-x   3 nick nick  4096 Feb 23 13:44 a

./a:
total 12
drwxr-xr-x 2 nick nick 4096 Feb 23 13:44 ' b'
drwxr-xr-x 3 nick nick 4096 Feb 23 13:44  .
drwxr-xr-x 3 nick nick 4096 Feb 23 13:44  ..

'./a/ b':
total 8
drwxr-xr-x 2 nick nick 4096 Feb 23 13:44 .
drwxr-xr-x 3 nick nick 4096 Feb 23 13:44 ..

And inside of Fern it creates a nested b/ inside of a/.

nickjj avatar Feb 23 '21 18:02 nickjj

I... don't really get what you mean. It seems the result you pasted is what exactly I expect.

I expect the following when you run fern-action-new-path with a/_b/ (assume _ is a whitespace)

  • a directory
  • _b directory in the above a directory (assume _ is a whitespace)

Is my expectation correct in your machine?

lambdalisue avatar Feb 23 '21 21:02 lambdalisue

Yep that is what happens. I misread your initial reply because I missed the empty whitespace reference (good idea with using _).

nickjj avatar Feb 26 '21 13:02 nickjj

Ok, then fern worked as it designed.

Let's get back to the original. Do you (or anyone) have interface idea for creating multiple files/directories. Or are you satisfied with the current design while it create a file/directory as it designed?

lambdalisue avatar Feb 27 '21 08:02 lambdalisue

It's a tricky one. It would be kind of neat if it worked like mkdir or touch where you can pass in a space separated list of paths, and if you happen to want a space in your path then you would quote it. This way you have the same interface to create 1 or many paths.

It could get complicated tho because then there's maybe doing things like touch a/b/{hello,world}, but I think this could be pretty easily avoided in Fern by invoking the create path action on the b directory in this case so the need for {} goes away.

nickjj avatar Feb 27 '21 11:02 nickjj

I'm sorry but I'm not going to apply breaking changes for this while most of people satisfied with the current interface.

lambdalisue avatar Feb 27 '21 12:02 lambdalisue

I find this feature could be handy for cpp devs. We regularly need to touch some_class.{h,cpp} but currently two fern-action-new-files are required. I made a quick and dirty workaround for this.

function! s:fern_exec(cmd) abort
    let node = fern#helper#new().sync.get_cursor_node()
    if l:node['status'] == g:fern#STATUS_NONE
        let node = l:node['__owner']
    endif
    let path = l:node['_path']
    let orig_path = getcwd()
    exec 'lcd ' . l:path
    execute '!' . a:cmd
    exec 'lcd ' . l:orig_path
endfunction
command! -complete=shellcmd -nargs=+ FernExec call s:fern_exec(<q-args>)
command! -complete=shellcmd -nargs=+ FernExecIn FernDo -stay :FernExec <args>

Usage: FernExecIn touch some_class.{h,cpp} should do what you expect.

cairijun avatar Apr 15 '21 08:04 cairijun

We regularly need to touch some_class.{h,cpp} but currently two fern-action-new-files are required.

Thanks, I didn't have that point 👍 Now I understand that the feature is convenient for some users. (it doesn't mean that I'm going to implement that feature thought.)

lambdalisue avatar Apr 15 '21 09:04 lambdalisue

Ah, well, I need to think about Windows... I'm sure that mkdir or touch doesn't work on Windows and I don't think it's good idea to parse the argument in fern to detect some_class.{h,cpp} or something like that while Vim script is horribly slow and it's not powerful enough to parse sh-like expressions.

lambdalisue avatar Apr 15 '21 09:04 lambdalisue

I'm not sure how all Windows users use Vim but I am on Windows here and use terminal Vim within WSL which has access to all Unix commands. Is Fern coded today in such a way that it works with GUI Vim running in Windows?

nickjj avatar Apr 15 '21 09:04 nickjj

Is Fern coded today in such a way that it works with GUI Vim running in Windows?

I know some users are using fern on gVim in Windows.

I believe that supporting Windows is quite important feature of fern while tons of Vim plugins doesn't work well on Windows. (I, personally, doesn't use Windows though.)

lambdalisue avatar Apr 15 '21 09:04 lambdalisue

Well, brace expansion in vim is not portable even in the Unix world. AFAIK it won't work on busybox. A portable solution might need a tedious vimscript implementation (which doesn't seem worth it), or some external dependency (which might be better to put in a seperated plugin):

  • lua: https://github.com/fbriere/mpv-scripts/blob/master/scripts/brace-expand.lua
  • python: https://github.com/trendels/braceexpand

cairijun avatar Apr 15 '21 09:04 cairijun

Well, brace expansion in vim is not portable even in the Unix world. AFAIK it won't work on busybox. A portable solution might need a tedious vimscript implementation (which doesn't seem worth it), or some external dependency (which might be better to put in a seperated plugin):

Well, I agree that perfect portability does not worth while I think nobody expect fern works on busybox or so on. However, I think Windows is one of quite common environment thus I think it worth to support it.

lambdalisue avatar Apr 15 '21 18:04 lambdalisue