"=============================================================================
" FILE: file_vimfiler_base.vim
" AUTHOR: Shougo Matsushita <Shougo.Matsu@gmail.com>
" License: MIT license {{{
" Permission is hereby granted, free of charge, to any person obtaining
" a copy of this software and associated documentation files (the
" "Software"), to deal in the Software without restriction, including
" without limitation the rights to use, copy, modify, merge, publish,
" distribute, sublicense, and/or sell copies of the Software, and to
" permit persons to whom the Software is furnished to do so, subject to
" the following conditions:
"
" The above copyright notice and this permission notice shall be included
" in all copies or substantial portions of the Software.
"
" THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
" OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
" MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
" IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
" CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
" TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
" SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
" }}}
"=============================================================================
let s:save_cpo = &cpo
set cpo&vim
" Global options definition. "{{{
call unite#util#set_default(
\ 'g:unite_kind_file_delete_file_command',
\ unite#util#is_windows() && !executable('rm') ? '' :
\ executable('trash-put') ? 'trash-put $srcs' :
\ executable('rmtrash') ? 'rmtrash $srcs' :
\ 'rm $srcs')
call unite#util#set_default(
\ 'g:unite_kind_file_delete_directory_command',
\ unite#util#is_windows() && !executable('rm') ? '' :
\ executable('trash-put') ? 'trash-put $srcs' :
\ executable('rmtrash') ? 'rmtrash $srcs' :
\ 'rm -r $srcs')
call unite#util#set_default(
\ 'g:unite_kind_file_copy_file_command',
\ unite#util#is_windows() && !executable('cp') ? '' :
\ 'cp -p $srcs $dest')
call unite#util#set_default(
\ 'g:unite_kind_file_copy_directory_command',
\ unite#util#is_windows() && !executable('cp') ? '' :
\ 'cp -p -r $srcs $dest')
call unite#util#set_default(
\ 'g:unite_kind_file_move_command',
\ unite#util#is_windows() && !executable('mv') ?
\ 'move /Y $srcs $dest' : 'mv $srcs $dest')
call unite#util#set_default('g:unite_kind_file_use_trashbox',
\ unite#util#is_windows() && unite#util#has_vimproc())
"}}}
function! unite#kinds#file_vimfiler_base#define() abort "{{{
return s:kind
endfunction"}}}
let s:System = unite#util#get_vital().import('System.File')
let s:kind = {
\ 'name' : 'file_vimfiler_base',
\ 'default_action' : 'open',
\ 'action_table' : {},
\ 'parents' : [],
\}
" Actions "{{{
" For vimfiler.
let s:kind.action_table.vimfiler__move = {
\ 'description' : 'move files',
\ 'is_quit' : 0,
\ 'is_invalidate_cache' : 1,
\ 'is_selectable' : 1,
\ 'is_listed' : 0,
\ }
function! s:kind.action_table.vimfiler__move.func(candidates) abort "{{{
if !unite#util#input_yesno('Really move files?')
echo 'Canceled.'
return
endif
let vimfiler_current_dir =
\ get(unite#get_context(), 'vimfiler__current_directory', '')
if vimfiler_current_dir == ''
let vimfiler_current_dir = getcwd()
endif
let current_dir = getcwd()
try
call unite#util#lcd(vimfiler_current_dir)
if g:unite_kind_file_move_command == ''
call unite#print_error('Please install mv.exe.')
return 1
endif
let context = unite#get_context()
let dest_dir = get(context, 'action__directory', '')
if dest_dir == ''
let dest_dir = unite#util#input_directory(
\ 'Input destination directory: ')
endif
if dest_dir == ''
return
elseif isdirectory(dest_dir) && dest_dir !~ '/$'
let dest_dir .= '/'
endif
let context.action__directory = dest_dir
let dest_drive = matchstr(dest_dir, '^\a\+\ze:')
let candidates = []
for candidate in a:candidates
let filename = candidate.action__path
if isdirectory(filename) && unite#util#is_windows()
\ && matchstr(filename, '^\a\+\ze:') !=? dest_drive
call s:move_to_other_drive(candidate, filename)
else
call add(candidates, candidate)
endif
endfor
if dest_dir =~ '^\h\w\+:'
" Use protocol move method.
let protocol = matchstr(dest_dir, '^\h\w\+')
call unite#sources#{protocol}#move_files(
\ dest_dir, candidates)
else
let filename = unite#kinds#file#do_action(
\ candidates, dest_dir, 'move')
call s:search_cursor(filename, dest_dir, a:candidates[-1])
endif
finally
call unite#util#lcd(current_dir)
endtry
endfunction"}}}
let s:kind.action_table.move =
\ deepcopy(s:kind.action_table.vimfiler__move)
let s:kind.action_table.move.is_listed = 1
function! s:kind.action_table.move.func(candidates) abort "{{{
return s:kind.action_table.vimfiler__move.func(a:candidates)
endfunction"}}}
let s:kind.action_table.vimfiler__copy = {
\ 'description' : 'copy files',
\ 'is_quit' : 0,
\ 'is_invalidate_cache' : 1,
\ 'is_selectable' : 1,
\ 'is_listed' : 0,
\ }
function! s:kind.action_table.vimfiler__copy.func(candidates) abort "{{{
let vimfiler_current_dir =
\ get(unite#get_context(), 'vimfiler__current_directory', '')
if vimfiler_current_dir == ''
let vimfiler_current_dir = getcwd()
endif
let current_dir = getcwd()
try
call unite#util#lcd(vimfiler_current_dir)
if g:unite_kind_file_copy_file_command == ''
\ || g:unite_kind_file_copy_directory_command == ''
call unite#print_error('Please install cp.exe.')
return 1
endif
let context = unite#get_context()
let dest_dir = get(context, 'action__directory', '')
if dest_dir == ''
let dest_dir = unite#util#input_directory(
\ 'Input destination directory: ')
endif
if dest_dir == ''
return
elseif isdirectory(dest_dir) && dest_dir !~ '/$'
let dest_dir .= '/'
endif
if dest_dir =~ '^\h\w\+:'
" Use protocol move method.
let protocol = matchstr(dest_dir, '^\h\w\+')
call unite#sources#{protocol}#copy_files(dest_dir, a:candidates)
else
let filename = unite#kinds#file#do_action(
\ a:candidates, dest_dir, 'copy')
call s:search_cursor(filename, dest_dir, a:candidates[-1])
endif
finally
call unite#util#lcd(current_dir)
endtry
endfunction"}}}
let s:kind.action_table.copy = deepcopy(s:kind.action_table.vimfiler__copy)
let s:kind.action_table.copy.is_listed = 1
function! s:kind.action_table.copy.func(candidates) abort "{{{
return s:kind.action_table.vimfiler__copy.func(a:candidates)
endfunction"}}}
let s:kind.action_table.vimfiler__delete = {
\ 'description' : 'delete files',
\ 'is_quit' : 0,
\ 'is_invalidate_cache' : 1,
\ 'is_selectable' : 1,
\ 'is_listed' : 0,
\ }
function! s:kind.action_table.vimfiler__delete.func(candidates) abort "{{{
if g:unite_kind_file_delete_file_command == ''
\ || g:unite_kind_file_delete_directory_command == ''
call unite#print_error('Please install rm.exe.')
return 1
endif
if !unite#util#input_yesno('Really force delete files?')
echo 'Canceled.'
return
endif
call unite#kinds#file#do_action(a:candidates, '', 'delete')
endfunction"}}}
let s:kind.action_table.vimfiler__rename = {
\ 'description' : 'rename files',
\ 'is_quit' : 0,
\ 'is_invalidate_cache' : 1,
\ 'is_listed' : 0,
\ }
function! s:kind.action_table.vimfiler__rename.func(candidate) abort "{{{
let vimfiler_current_dir =
\ get(unite#get_context(), 'vimfiler__current_directory', '')
if vimfiler_current_dir == ''
let vimfiler_current_dir = getcwd()
endif
let current_dir = getcwd()
try
call unite#util#lcd(vimfiler_current_dir)
let context = unite#get_context()
let filename = has_key(context, 'action__filename') ?
\ context.action__filename :
\ input(printf('New file name: %s -> ',
\ a:candidate.action__path), a:candidate.action__path)
if !has_key(context, 'action__filename')
redraw
endif
if filename != '' && filename !=# a:candidate.action__path
call unite#kinds#file#do_rename(a:candidate.action__path, filename)
call s:search_cursor(filename, '', {})
endif
finally
call unite#util#lcd(current_dir)
endtry
endfunction"}}}
let s:kind.action_table.vimfiler__newfile = {
\ 'description' : 'make this file',
\ 'is_quit' : 0,
\ 'is_invalidate_cache' : 1,
\ 'is_listed' : 0,
\ }
function! s:kind.action_table.vimfiler__newfile.func(candidate) abort "{{{
let vimfiler_current_dir =
\ get(unite#get_context(),
\ 'vimfiler__current_directory', '')
if vimfiler_current_dir == ''
let vimfiler_current_dir = getcwd()
endif
let current_dir = getcwd()
try
call unite#util#lcd(vimfiler_current_dir)
let filenames = input('New files name(comma separated): ',
\ '', 'file')
if filenames == ''
redraw
echo 'Canceled.'
return
endif
for filename in split(filenames, ',')
call unite#util#lcd(vimfiler_current_dir)
if filereadable(filename)
redraw
call unite#print_error(filename . ' is already exists.')
continue
endif
let dir = fnamemodify(filename, ':h')
if dir != '' && !isdirectory(dir) && !unite#util#is_sudo()
" Auto create directory.
call mkdir(dir, 'p')
endif
if filename !~ '/$'
let file = unite#sources#file#create_file_dict(filename, '')
let file.source = 'file'
call writefile([], filename)
endif
call s:search_cursor(filename, '', {})
endfor
finally
call unite#util#lcd(current_dir)
endtry
endfunction"}}}
let s:kind.action_table.unite__new_candidate =
\ deepcopy(s:kind.action_table.vimfiler__newfile)
let s:kind.action_table.vimfiler__shell = {
\ 'description' : 'popup shell',
\ 'is_listed' : 0,
\ }
function! s:kind.action_table.vimfiler__shell.func(candidate) abort "{{{
if !exists(':VimShellPop')
shell
return
endif
call vimshell#init#_start(
\ unite#helper#get_candidate_directory(a:candidate),
\ { 'popup' : 1, 'toggle' : 0 })
let files = unite#get_context().vimfiler__files
if !empty(files)
call setline(line('.'), getline('.') . ' ' . join(files))
call cursor(0, col('.')+1)
endif
endfunction"}}}
let s:kind.action_table.vimfiler__shellcmd = {
\ 'description' : 'execute shell command',
\ 'is_listed' : 0,
\ 'is_start' : 1,
\ }
function! s:kind.action_table.vimfiler__shellcmd.func(candidate) abort "{{{
let vimfiler_current_dir =
\ get(unite#get_context(), 'vimfiler__current_directory', '')
if vimfiler_current_dir == ''
let vimfiler_current_dir = getcwd()
endif
let current_dir = getcwd()
try
call unite#util#lcd(vimfiler_current_dir)
let command = unite#get_context().vimfiler__command
let output = split(unite#util#system(command), '\n\|\r\n')
if !empty(output)
call unite#start_script([['output', output]])
endif
finally
call unite#util#lcd(current_dir)
endtry
endfunction"}}}
let s:kind.action_table.vimfiler__mkdir = {
\ 'description' : 'make this directory and parents directory',
\ 'is_quit' : 0,
\ 'is_invalidate_cache' : 1,
\ 'is_listed' : 0,
\ 'is_selectable' : 1,
\ }
function! s:kind.action_table.vimfiler__mkdir.func(candidates) abort "{{{
let context = unite#get_context()
let vimfiler_current_dir = get(context, 'vimfiler__current_directory', '')
if vimfiler_current_dir == ''
let vimfiler_current_dir = getcwd()
endif
let current_dir = getcwd()
try
call unite#util#lcd(vimfiler_current_dir)
let dirnames = split(input(
\ 'New directory names(comma separated): ', '', 'dir'), ',')
redraw
if empty(dirnames)
echo 'Canceled.'
return
endif
for dirname in dirnames
let dirname = unite#util#substitute_path_separator(
\ fnamemodify(dirname, ':p'))
if filereadable(dirname) || isdirectory(dirname)
redraw
call unite#print_error(dirname . ' is already exists.')
continue
endif
call mkdir(dirname, 'p')
endfor
" Move marked files.
if !get(context, 'vimfiler__is_dummy', 1) && len(dirnames) == 1
call unite#sources#file#move_files(dirname, a:candidates)
endif
call s:search_cursor(dirname, '', {})
finally
call unite#util#lcd(current_dir)
endtry
endfunction"}}}
let s:kind.action_table.vimfiler__execute = {
\ 'description' : 'open files with associated program',
\ 'is_selectable' : 1,
\ 'is_listed' : 0,
\ }
function! s:kind.action_table.vimfiler__execute.func(candidates) abort "{{{
let vimfiler_current_dir =
\ get(unite#get_context(), 'vimfiler__current_directory', '')
if vimfiler_current_dir == ''
let vimfiler_current_dir = getcwd()
endif
let current_dir = getcwd()
try
call unite#util#lcd(vimfiler_current_dir)
for candidate in a:candidates
let path = candidate.action__path
if unite#util#is_windows() && path =~ '^//'
" substitute separator for UNC.
let path = substitute(path, '/', '\\', 'g')
endif
call s:System.open(path)
endfor
finally
call unite#util#lcd(current_dir)
endtry
endfunction"}}}
let s:kind.action_table.vimfiler__external_filer = {
\ 'description' : 'open file with external file explorer',
\ 'is_listed' : 0,
\ }
function! s:kind.action_table.vimfiler__external_filer.func(candidate) abort "{{{
let vimfiler_current_dir =
\ get(unite#get_context(), 'vimfiler__current_directory', '')
if vimfiler_current_dir == ''
let vimfiler_current_dir = getcwd()
endif
let current_dir = getcwd()
try
call unite#util#lcd(vimfiler_current_dir)
let path = a:candidate.action__path
if unite#util#is_windows()
let path = substitute(path, '/', '\\', 'g')
endif
let filer = ''
if unite#util#is_mac()
let filer = 'open -a Finder -R '
elseif unite#util#is_windows()
let filer = 'explorer /SELECT,'
elseif executable('nautilus')
" Note: Older nautilus does not support "-s" option...
let filer = 'nautilus '
if isdirectory(path)
" Use parent path
let path = fnamemodify(path, ':h')
endif
else
" Not supported
call s:System.open(fnamemodify(path, ':h'))
return
endif
if unite#util#is_windows()
let output = system(filer . '"' . path . '"')
else
let output = unite#util#system(filer . "'" . path . "' &")
endif
if output != ''
call unite#util#print_error(output)
endif
finally
call unite#util#lcd(current_dir)
endtry
endfunction"}}}
let s:kind.action_table.vimfiler__write = {
\ 'description' : 'save file',
\ 'is_listed' : 0,
\ }
function! s:kind.action_table.vimfiler__write.func(candidate) abort "{{{
let context = unite#get_context()
let lines = getline(context.vimfiler__line1, context.vimfiler__line2)
if context.vimfiler__eventname ==# 'FileAppendCmd'
" Append.
let lines = readfile(a:candidate.action__path) + lines
endif
call writefile(lines, a:candidate.action__path)
endfunction"}}}
"}}}
function! s:move_to_other_drive(candidate, filename) abort "{{{
" move command doesn't supported directory over drive move in Windows.
if g:unite_kind_file_copy_file_command == ''
\ || g:unite_kind_file_copy_directory_command == ''
call unite#print_error('Please install cp.exe.')
return 1
elseif g:unite_kind_file_delete_file_command == ''
\ || g:unite_kind_file_delete_directory_command == ''
call unite#print_error('Please install rm.exe.')
return 1
endif
if s:kind.action_table.vimfiler__copy.func([a:candidate])
call unite#print_error('Failed file move: ' . a:filename)
return 1
endif
if s:kind.action_table.vimfiler__delete.func([a:candidate])
call unite#print_error('Failed file delete: ' . a:filename)
return 1
endif
endfunction"}}}
function! s:search_cursor(filename, dest_dir, candidate) abort "{{{
if &filetype !=# 'vimfiler'
return
endif
if a:filename ==# a:dest_dir
\ && vimfiler#exists_another_vimfiler()
" Search from another vimfiler
call vimfiler#mappings#switch_another_vimfiler()
call vimfiler#view#_force_redraw_screen()
call vimfiler#mappings#search_cursor(
\ unite#util#substitute_path_separator(
\ a:dest_dir . a:candidate.vimfiler__filename))
call vimfiler#mappings#switch_another_vimfiler()
else
" Search current vimfiler
call vimfiler#view#_force_redraw_screen()
call vimfiler#mappings#search_cursor(
\ unite#util#substitute_path_separator(
\ fnamemodify(a:filename, ':p')))
endif
endfunction"}}}
let &cpo = s:save_cpo
unlet s:save_cpo
" vim: foldmethod=marker