diff --git a/autoload/fern/scheme/file/mapping.vim b/autoload/fern/scheme/file/mapping.vim index 9d238175..89da4920 100644 --- a/autoload/fern/scheme/file/mapping.vim +++ b/autoload/fern/scheme/file/mapping.vim @@ -2,6 +2,7 @@ let s:Promise = vital#fern#import('Async.Promise') let s:Prompt = vital#fern#import('Prompt') function! fern#scheme#file#mapping#init(disable_default_mappings) abort + nnoremap (fern-action-new-path) :call call('new_path') nnoremap (fern-action-new-file) :call call('new_file') nnoremap (fern-action-new-dir) :call call('new_dir') nnoremap (fern-action-copy) :call call('copy') @@ -48,24 +49,26 @@ function! s:map_open_system(helper) abort \.finally({ -> Done() }) endfunction +function! s:map_new_path(helper) abort + let name = input( + \ "(Hint: Ends with '/' create a directory instead of a file)\nNew path: ", + \ '', + \ 'file', + \) + if empty(name) + return s:Promise.reject('Cancelled') + endif + return name[-1:] ==# '/' + \ ? s:new_dir(a:helper, name) + \ : s:new_file(a:helper, name) +endfunction + function! s:map_new_file(helper) abort let name = input('New file: ', '', 'file') if empty(name) return s:Promise.reject('Cancelled') endif - let node = a:helper.sync.get_cursor_node() - let node = node.status isnot# a:helper.STATUS_EXPANDED ? node.__owner : node - let path = fern#internal#filepath#to_slash(node._path) - let path = join([path, name], '/') - let path = fern#internal#filepath#from_slash(path) - let key = node.__key + [name] - let token = a:helper.fern.source.token - let previous = a:helper.sync.get_cursor_node() - return fern#scheme#file#shutil#mkfile(path, token) - \.then({ -> a:helper.async.reload_node(node.__key) }) - \.then({ -> a:helper.async.reveal_node(key) }) - \.then({ -> a:helper.async.redraw() }) - \.then({ -> a:helper.sync.focus_node(key, { 'previous': previous }) }) + return s:new_file(a:helper, name) endfunction function! s:map_new_dir(helper) abort @@ -73,19 +76,7 @@ function! s:map_new_dir(helper) abort if empty(name) return s:Promise.reject('Cancelled') endif - let node = a:helper.sync.get_cursor_node() - let node = node.status isnot# a:helper.STATUS_EXPANDED ? node.__owner : node - let path = fern#internal#filepath#to_slash(node._path) - let path = join([path, name], '/') - let path = fern#internal#filepath#from_slash(path) - let key = node.__key + [name] - let token = a:helper.fern.source.token - let previous = a:helper.sync.get_cursor_node() - return fern#scheme#file#shutil#mkdir(path, token) - \.then({ -> a:helper.async.reload_node(node.__key) }) - \.then({ -> a:helper.async.reveal_node(key) }) - \.then({ -> a:helper.async.redraw() }) - \.then({ -> a:helper.sync.focus_node(key, { 'previous': previous }) }) + return s:new_dir(a:helper, name) endfunction function! s:map_copy(helper) abort @@ -192,6 +183,38 @@ function! s:map_remove(helper) abort \.then({ -> a:helper.sync.echo(printf('%d items are removed', len(ps))) }) endfunction +function! s:new_file(helper, name) abort + let node = a:helper.sync.get_cursor_node() + let node = node.status isnot# a:helper.STATUS_EXPANDED ? node.__owner : node + let path = fern#internal#filepath#to_slash(node._path) + let path = join([path, a:name], '/') + let path = fern#internal#filepath#from_slash(path) + let key = node.__key + [a:name] + let token = a:helper.fern.source.token + let previous = a:helper.sync.get_cursor_node() + return fern#scheme#file#shutil#mkfile(path, token) + \.then({ -> a:helper.async.reload_node(node.__key) }) + \.then({ -> a:helper.async.reveal_node(key) }) + \.then({ -> a:helper.async.redraw() }) + \.then({ -> a:helper.sync.focus_node(key, { 'previous': previous }) }) +endfunction + +function! s:new_dir(helper, name) abort + let node = a:helper.sync.get_cursor_node() + let node = node.status isnot# a:helper.STATUS_EXPANDED ? node.__owner : node + let path = fern#internal#filepath#to_slash(node._path) + let path = join([path, a:name], '/') + let path = fern#internal#filepath#from_slash(path) + let key = node.__key + [a:name] + let token = a:helper.fern.source.token + let previous = a:helper.sync.get_cursor_node() + return fern#scheme#file#shutil#mkdir(path, token) + \.then({ -> a:helper.async.reload_node(node.__key) }) + \.then({ -> a:helper.async.reveal_node(key) }) + \.then({ -> a:helper.async.redraw() }) + \.then({ -> a:helper.sync.focus_node(key, { 'previous': previous }) }) +endfunction + let g:fern#scheme#file#mapping#mappings = get(g:, 'fern#scheme#file#mapping#mappings', [ \ 'cd', \ 'clipboard', diff --git a/doc/fern.txt b/doc/fern.txt index 7069b091..55a956e7 100644 --- a/doc/fern.txt +++ b/doc/fern.txt @@ -794,6 +794,13 @@ FILE *fern-mapping-file* The following mappings/actions are only available on file:// scheme. +*(fern-action-new-path)* + Open a prompt to ask a path and create a file/directory of the input + path from the path of a cursor node. + Any intermediate directories of the destination will be created. + If the path ends with "/", it creates a directory. Otherwise it + creates a file. + *(fern-action-new-file)* Open a prompt to ask a path and create a file of the input path from the path of a cursor node.