Skip to content

Commit c36464e

Browse files
authored
Merge pull request #138 from lambdalisue/new-path-action
Add "new-path" action
2 parents e75b4eb + 710e9f2 commit c36464e

File tree

2 files changed

+56
-26
lines changed

2 files changed

+56
-26
lines changed

autoload/fern/scheme/file/mapping.vim

Lines changed: 49 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ let s:Promise = vital#fern#import('Async.Promise')
22
let s:Prompt = vital#fern#import('Prompt')
33

44
function! fern#scheme#file#mapping#init(disable_default_mappings) abort
5+
nnoremap <buffer><silent> <Plug>(fern-action-new-path) :<C-u>call <SID>call('new_path')<CR>
56
nnoremap <buffer><silent> <Plug>(fern-action-new-file) :<C-u>call <SID>call('new_file')<CR>
67
nnoremap <buffer><silent> <Plug>(fern-action-new-dir) :<C-u>call <SID>call('new_dir')<CR>
78
nnoremap <buffer><silent> <Plug>(fern-action-copy) :<C-u>call <SID>call('copy')<CR>
@@ -48,44 +49,34 @@ function! s:map_open_system(helper) abort
4849
\.finally({ -> Done() })
4950
endfunction
5051

52+
function! s:map_new_path(helper) abort
53+
let name = input(
54+
\ "(Hint: Ends with '/' create a directory instead of a file)\nNew path: ",
55+
\ '',
56+
\ 'file',
57+
\)
58+
if empty(name)
59+
return s:Promise.reject('Cancelled')
60+
endif
61+
return name[-1:] ==# '/'
62+
\ ? s:new_dir(a:helper, name)
63+
\ : s:new_file(a:helper, name)
64+
endfunction
65+
5166
function! s:map_new_file(helper) abort
5267
let name = input('New file: ', '', 'file')
5368
if empty(name)
5469
return s:Promise.reject('Cancelled')
5570
endif
56-
let node = a:helper.sync.get_cursor_node()
57-
let node = node.status isnot# a:helper.STATUS_EXPANDED ? node.__owner : node
58-
let path = fern#internal#filepath#to_slash(node._path)
59-
let path = join([path, name], '/')
60-
let path = fern#internal#filepath#from_slash(path)
61-
let key = node.__key + [name]
62-
let token = a:helper.fern.source.token
63-
let previous = a:helper.sync.get_cursor_node()
64-
return fern#scheme#file#shutil#mkfile(path, token)
65-
\.then({ -> a:helper.async.reload_node(node.__key) })
66-
\.then({ -> a:helper.async.reveal_node(key) })
67-
\.then({ -> a:helper.async.redraw() })
68-
\.then({ -> a:helper.sync.focus_node(key, { 'previous': previous }) })
71+
return s:new_file(a:helper, name)
6972
endfunction
7073

7174
function! s:map_new_dir(helper) abort
7275
let name = input('New directory: ', '', 'dir')
7376
if empty(name)
7477
return s:Promise.reject('Cancelled')
7578
endif
76-
let node = a:helper.sync.get_cursor_node()
77-
let node = node.status isnot# a:helper.STATUS_EXPANDED ? node.__owner : node
78-
let path = fern#internal#filepath#to_slash(node._path)
79-
let path = join([path, name], '/')
80-
let path = fern#internal#filepath#from_slash(path)
81-
let key = node.__key + [name]
82-
let token = a:helper.fern.source.token
83-
let previous = a:helper.sync.get_cursor_node()
84-
return fern#scheme#file#shutil#mkdir(path, token)
85-
\.then({ -> a:helper.async.reload_node(node.__key) })
86-
\.then({ -> a:helper.async.reveal_node(key) })
87-
\.then({ -> a:helper.async.redraw() })
88-
\.then({ -> a:helper.sync.focus_node(key, { 'previous': previous }) })
79+
return s:new_dir(a:helper, name)
8980
endfunction
9081

9182
function! s:map_copy(helper) abort
@@ -192,6 +183,38 @@ function! s:map_remove(helper) abort
192183
\.then({ -> a:helper.sync.echo(printf('%d items are removed', len(ps))) })
193184
endfunction
194185

186+
function! s:new_file(helper, name) abort
187+
let node = a:helper.sync.get_cursor_node()
188+
let node = node.status isnot# a:helper.STATUS_EXPANDED ? node.__owner : node
189+
let path = fern#internal#filepath#to_slash(node._path)
190+
let path = join([path, a:name], '/')
191+
let path = fern#internal#filepath#from_slash(path)
192+
let key = node.__key + [a:name]
193+
let token = a:helper.fern.source.token
194+
let previous = a:helper.sync.get_cursor_node()
195+
return fern#scheme#file#shutil#mkfile(path, token)
196+
\.then({ -> a:helper.async.reload_node(node.__key) })
197+
\.then({ -> a:helper.async.reveal_node(key) })
198+
\.then({ -> a:helper.async.redraw() })
199+
\.then({ -> a:helper.sync.focus_node(key, { 'previous': previous }) })
200+
endfunction
201+
202+
function! s:new_dir(helper, name) abort
203+
let node = a:helper.sync.get_cursor_node()
204+
let node = node.status isnot# a:helper.STATUS_EXPANDED ? node.__owner : node
205+
let path = fern#internal#filepath#to_slash(node._path)
206+
let path = join([path, a:name], '/')
207+
let path = fern#internal#filepath#from_slash(path)
208+
let key = node.__key + [a:name]
209+
let token = a:helper.fern.source.token
210+
let previous = a:helper.sync.get_cursor_node()
211+
return fern#scheme#file#shutil#mkdir(path, token)
212+
\.then({ -> a:helper.async.reload_node(node.__key) })
213+
\.then({ -> a:helper.async.reveal_node(key) })
214+
\.then({ -> a:helper.async.redraw() })
215+
\.then({ -> a:helper.sync.focus_node(key, { 'previous': previous }) })
216+
endfunction
217+
195218
let g:fern#scheme#file#mapping#mappings = get(g:, 'fern#scheme#file#mapping#mappings', [
196219
\ 'cd',
197220
\ 'clipboard',

doc/fern.txt

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -794,6 +794,13 @@ FILE *fern-mapping-file*
794794

795795
The following mappings/actions are only available on file:// scheme.
796796

797+
*<Plug>(fern-action-new-path)*
798+
Open a prompt to ask a path and create a file/directory of the input
799+
path from the path of a cursor node.
800+
Any intermediate directories of the destination will be created.
801+
If the path ends with "/", it creates a directory. Otherwise it
802+
creates a file.
803+
797804
*<Plug>(fern-action-new-file)*
798805
Open a prompt to ask a path and create a file of the input path from
799806
the path of a cursor node.

0 commit comments

Comments
 (0)