mirror of
https://github.com/SpaceVim/SpaceVim.git
synced 2025-01-23 13:50:05 +08:00
341 lines
11 KiB
VimL
341 lines
11 KiB
VimL
"=============================================================================
|
|
" defx.vim --- defx configuration
|
|
" Copyright (c) 2016-2023 Wang Shidong & Contributors
|
|
" Author: Wang Shidong < wsdjeg@outlook.com >
|
|
" URL: https://spacevim.org
|
|
" License: GPLv3
|
|
"=============================================================================
|
|
scriptencoding utf-8
|
|
|
|
|
|
let s:SYS = SpaceVim#api#import('system')
|
|
let s:FILE = SpaceVim#api#import('file')
|
|
let s:VCOP = SpaceVim#api#import('vim#compatible')
|
|
let s:WIN = SpaceVim#api#import('vim#window')
|
|
|
|
if g:spacevim_filetree_direction ==# 'right'
|
|
let s:direction = 'rightbelow'
|
|
else
|
|
let s:direction = 'leftabove'
|
|
endif
|
|
|
|
function! s:setcolum() abort
|
|
if g:_spacevim_enable_filetree_filetypeicon && !g:_spacevim_enable_filetree_gitstatus
|
|
return 'indent:icons:filename:type'
|
|
elseif !g:_spacevim_enable_filetree_filetypeicon && g:_spacevim_enable_filetree_gitstatus
|
|
return 'indent:git:filename:type'
|
|
elseif g:_spacevim_enable_filetree_filetypeicon && g:_spacevim_enable_filetree_gitstatus
|
|
return 'indent:git:icons:filename:type'
|
|
else
|
|
return 'mark:indent:icon:filename:type'
|
|
endif
|
|
endfunction
|
|
|
|
call defx#custom#option('_', {
|
|
\ 'columns': s:setcolum(),
|
|
\ 'winwidth': g:spacevim_sidebar_width,
|
|
\ 'split': 'vertical',
|
|
\ 'direction': s:direction,
|
|
\ 'show_ignored_files': g:_spacevim_filetree_show_hidden_files,
|
|
\ 'buffer_name': '',
|
|
\ 'toggle': 1,
|
|
\ 'resume': 1
|
|
\ })
|
|
|
|
call defx#custom#column('mark', {
|
|
\ 'readonly_icon': '',
|
|
\ 'selected_icon': '',
|
|
\ })
|
|
|
|
call defx#custom#column('icon', {
|
|
\ 'directory_icon': '▶',
|
|
\ 'opened_icon': '▼',
|
|
\ 'root_icon': ' ',
|
|
\ })
|
|
|
|
call defx#custom#column('filename', {
|
|
\ 'max_width': -90,
|
|
\ })
|
|
|
|
augroup vfinit
|
|
au!
|
|
autocmd FileType defx call s:defx_init()
|
|
" auto close last defx windows
|
|
autocmd BufEnter * nested if
|
|
\ (!has('vim_starting') && s:WIN.win_count() == 1 && g:_spacevim_autoclose_filetree
|
|
\ && &filetype ==# 'defx') |
|
|
\ call s:close_last_vimfiler_windows() | endif
|
|
augroup END
|
|
|
|
" in this function, we should check if shell terminal still exists,
|
|
" then close the terminal job before close vimfiler
|
|
function! s:close_last_vimfiler_windows() abort
|
|
call SpaceVim#layers#shell#close_terminal()
|
|
q
|
|
endfunction
|
|
|
|
function! s:defx_init()
|
|
setl nonumber
|
|
setl norelativenumber
|
|
setl listchars=
|
|
setl nofoldenable
|
|
setl foldmethod=manual
|
|
|
|
" disable this mappings
|
|
nnoremap <silent><buffer> <3-LeftMouse> <Nop>
|
|
nnoremap <silent><buffer> <4-LeftMouse> <Nop>
|
|
nnoremap <silent><buffer> <LeftMouse> <LeftMouse><Home>
|
|
|
|
silent! nunmap <buffer> <Space>
|
|
silent! nunmap <buffer> <C-l>
|
|
silent! nunmap <buffer> <C-j>
|
|
silent! nunmap <buffer> E
|
|
silent! nunmap <buffer> gr
|
|
silent! nunmap <buffer> gf
|
|
silent! nunmap <buffer> -
|
|
silent! nunmap <buffer> s
|
|
|
|
" nnoremap <silent><buffer><expr> st vimfiler#do_action('tabswitch')
|
|
" nnoremap <silent><buffer> yY :<C-u>call <SID>copy_to_system_clipboard()<CR>
|
|
nnoremap <silent><buffer><expr> '
|
|
\ defx#do_action('toggle_select') . 'j'
|
|
" TODO: we need an action to clear all selections
|
|
nnoremap <silent><buffer><expr> V
|
|
\ defx#do_action('toggle_select_all')
|
|
" nmap <buffer> v <Plug>(vimfiler_quick_look)
|
|
" nmap <buffer> p <Plug>(vimfiler_preview_file)
|
|
" nmap <buffer> i <Plug>(vimfiler_switch_to_history_directory)
|
|
|
|
" Define mappings
|
|
nnoremap <silent><buffer><expr> gx
|
|
\ defx#do_action('execute_system')
|
|
nnoremap <silent><buffer><expr> c
|
|
\ defx#do_action('copy')
|
|
nnoremap <silent><buffer><expr> q
|
|
\ defx#do_action('quit')
|
|
nnoremap <silent><buffer><expr> m
|
|
\ defx#do_action('move')
|
|
nnoremap <silent><buffer><expr> P
|
|
\ defx#do_action('paste')
|
|
nnoremap <silent><buffer><expr> h defx#do_action('call', g:defx_config_sid . 'DefxSmartH')
|
|
nnoremap <silent><buffer><expr> <Left> defx#do_action('call', g:defx_config_sid . 'DefxSmartH')
|
|
nnoremap <silent><buffer><expr> l defx#do_action('call', g:defx_config_sid . 'DefxSmartL')
|
|
nnoremap <silent><buffer><expr> <Right> defx#do_action('call', g:defx_config_sid . 'DefxSmartL')
|
|
nnoremap <silent><buffer><expr> o defx#do_action('call', g:defx_config_sid . 'DefxSmartL')
|
|
nnoremap <silent><buffer><expr> <Cr>
|
|
\ defx#is_directory() ?
|
|
\ defx#do_action('open_directory') : defx#do_action('drop')
|
|
nnoremap <silent><buffer><expr> <2-LeftMouse>
|
|
\ defx#is_directory() ?
|
|
\ (
|
|
\ defx#is_opened_tree() ?
|
|
\ defx#do_action('close_tree') :
|
|
\ defx#do_action('open_tree')
|
|
\ )
|
|
\ : defx#do_action('drop')
|
|
nnoremap <silent><buffer><expr> sg
|
|
\ defx#do_action('drop', 'vsplit')
|
|
nnoremap <silent><buffer><expr> sv
|
|
\ defx#do_action('drop', 'split')
|
|
nnoremap <silent><buffer><expr> st
|
|
\ defx#do_action('drop', 'tabedit')
|
|
nnoremap <silent><buffer><expr> p defx#do_action('call', g:defx_config_sid . 'DefxPreview')
|
|
nnoremap <silent><buffer><expr> K
|
|
\ defx#do_action('new_directory')
|
|
nnoremap <silent><buffer><expr> N
|
|
\ defx#do_action('new_file')
|
|
nnoremap <silent><buffer><expr> d
|
|
\ defx#do_action('remove')
|
|
nnoremap <silent><buffer><expr> r
|
|
\ defx#do_action('rename')
|
|
nnoremap <silent><buffer><expr> yy defx#do_action('call', g:defx_config_sid . 'DefxYarkPath')
|
|
nnoremap <silent><buffer><expr> yY defx#do_action('call', g:defx_config_sid . 'DefxCopyFile')
|
|
nnoremap <silent><buffer><expr> P defx#do_action('call', g:defx_config_sid . 'DefxPasteFile')
|
|
nnoremap <silent><buffer><expr> .
|
|
\ defx#do_action('toggle_ignored_files')
|
|
nnoremap <silent><buffer><expr> <C-f>
|
|
\ defx#do_action('change_filtered_files')
|
|
nnoremap <silent><buffer><expr> ~
|
|
\ defx#do_action('cd')
|
|
nnoremap <silent><buffer><expr> j
|
|
\ line('.') == line('$') ? 'gg' : 'j'
|
|
nnoremap <silent><buffer><expr> k
|
|
\ line('.') == 1 ? 'G' : 'k'
|
|
nnoremap <silent><buffer><expr> <C-r>
|
|
\ defx#do_action('redraw')
|
|
nnoremap <silent><buffer><expr> <C-g>
|
|
\ defx#do_action('print')
|
|
nnoremap <silent><buffer> <Home> :call cursor(2, 1)<cr>
|
|
nnoremap <silent><buffer> <End> :call cursor(line('$'), 1)<cr>
|
|
nnoremap <silent><buffer><expr> <C-Home>
|
|
\ defx#do_action('cd', SpaceVim#plugins#projectmanager#current_root())
|
|
nnoremap <silent><buffer><expr> > defx#do_action('resize',
|
|
\ defx#get_context().winwidth + 10)
|
|
nnoremap <silent><buffer><expr> < defx#do_action('resize',
|
|
\ defx#get_context().winwidth - 10)
|
|
doautocmd User DefxInit
|
|
endf
|
|
|
|
" in this function we should vim-choosewin if possible
|
|
function! s:DefxSmartL(_)
|
|
if defx#is_directory()
|
|
call defx#call_action('open_tree')
|
|
normal! j
|
|
else
|
|
let filepath = defx#get_candidate()['action__path']
|
|
if tabpagewinnr(tabpagenr(), '$') >= 3 " if there are more than 2 normal windows
|
|
if exists(':ChooseWin') == 2
|
|
ChooseWin
|
|
else
|
|
let input = input('ChooseWin No./Cancel(n): ')
|
|
if input ==# 'n' | return | endif
|
|
if input == winnr() | return | endif
|
|
exec input . 'wincmd w'
|
|
endif
|
|
exec 'e' filepath
|
|
else
|
|
exec 'wincmd w'
|
|
exec 'e' filepath
|
|
endif
|
|
endif
|
|
endfunction
|
|
|
|
function! s:DefxPreview(_) abort
|
|
if s:preview_windows_opened()
|
|
pclose
|
|
else
|
|
if !defx#is_directory()
|
|
let filepath = defx#get_candidate()['action__path']
|
|
exe 'topleft pedit ' . filepath
|
|
endif
|
|
endif
|
|
endfunction
|
|
|
|
fun! s:preview_windows_opened()
|
|
for nr in range(1, winnr('$'))
|
|
if getwinvar(nr, "&pvw") == 1
|
|
" found a preview
|
|
return 1
|
|
endif
|
|
endfor
|
|
return 0
|
|
endfun
|
|
|
|
function! s:DefxSmartH(_)
|
|
" if cursor line is first line, or in empty dir
|
|
if line('.') ==# 1 || line('$') ==# 1
|
|
return defx#call_action('cd', ['..'])
|
|
endif
|
|
|
|
" candidate is opend tree?
|
|
if defx#is_opened_tree()
|
|
return defx#call_action('close_tree')
|
|
endif
|
|
|
|
" parent is root?
|
|
let s:candidate = defx#get_candidate()
|
|
let s:parent = fnamemodify(s:candidate['action__path'], s:candidate['is_directory'] ? ':p:h:h' : ':p:h')
|
|
let sep = s:SYS.isWindows ? '\\' : '/'
|
|
if s:trim_right(s:parent, sep) == s:trim_right(b:defx.paths[0], sep)
|
|
return defx#call_action('cd', ['..'])
|
|
endif
|
|
|
|
" move to parent.
|
|
call defx#call_action('search', s:parent)
|
|
|
|
" if you want close_tree immediately, enable below line.
|
|
call defx#call_action('close_tree')
|
|
endfunction
|
|
|
|
function! s:DefxYarkPath(_) abort
|
|
let candidate = defx#get_candidate()
|
|
let @+ = candidate['action__path']
|
|
echo 'yanked path: ' . @+
|
|
endfunction
|
|
|
|
|
|
let s:copyed_file_path = ''
|
|
|
|
function! s:DefxCopyFile(_) abort
|
|
if !executable('xclip-copyfile') && !s:SYS.isWindows
|
|
echohl WarningMsg
|
|
echo 'you need to have xclip-copyfile in your PATH'
|
|
echohl NONE
|
|
return
|
|
endif
|
|
let candidate = defx#get_candidate()
|
|
let filename = candidate['action__path']
|
|
|
|
if executable('xclip-copyfile')
|
|
call s:VCOP.systemlist(['xclip-copyfile', filename])
|
|
if v:shell_error
|
|
echohl WarningMsg
|
|
echo 'failed to copy file!'
|
|
echohl NONE
|
|
else
|
|
echo 'Yanked:' . filename
|
|
endif
|
|
elseif s:SYS.isWindows
|
|
let s:copyed_file_path = filename
|
|
echo 'Yanked:' . filename
|
|
endif
|
|
endfunction
|
|
|
|
function! s:DefxPasteFile(_) abort
|
|
if !executable('xclip-pastefile') && !s:SYS.isWindows
|
|
echohl WarningMsg
|
|
echo 'you need to have xclip-copyfile in your PATH'
|
|
echohl NONE
|
|
return
|
|
endif
|
|
let candidate = defx#get_candidate()
|
|
let path = candidate['action__path']
|
|
if !isdirectory(path)
|
|
let path = fnamemodify(path, ':p:h')
|
|
endif
|
|
|
|
" If you have xclip-pastefile in your PATH.
|
|
" this command will be run on action directory
|
|
" support paste file which is copied outside of vim.
|
|
if executable('xclip-pastefile')
|
|
let old_wd = getcwd()
|
|
if old_wd == path
|
|
call s:VCOP.systemlist(['xclip-pastefile'])
|
|
else
|
|
noautocmd exe 'cd' fnameescape(path)
|
|
call s:VCOP.systemlist(['xclip-pastefile'])
|
|
noautocmd exe 'cd' fnameescape(old_wd)
|
|
endif
|
|
return
|
|
endif
|
|
|
|
if s:SYS.isWindows && !empty(s:copyed_file_path)
|
|
" in windows, use copy command for paste file.
|
|
let destination = path . s:FILE.separator . fnamemodify(s:copyed_file_path, ':t')
|
|
let cmd = 'cmd /c copy ' . shellescape(s:copyed_file_path) . ' ' . shellescape(destination)
|
|
call s:VCOP.systemlist(cmd)
|
|
elseif !s:SYS.isWindows && !empty(s:copyed_file_path)
|
|
" in Linux or MacOS, use cp command for paste file.
|
|
let destination = path . s:FILE.separator . fnamemodify(s:copyed_file_path, ':t')
|
|
let cmd = 'cp -r ' . shellescape(s:copyed_file_path) . ' ' . shellescape(destination)
|
|
call s:VCOP.systemlist(cmd)
|
|
endif
|
|
if v:shell_error
|
|
echohl WarningMsg
|
|
echo 'failed to paste file!'
|
|
echohl NONE
|
|
else
|
|
echo 'Pasted:' . destination
|
|
endif
|
|
endfunction
|
|
|
|
function! s:trim_right(str, trim)
|
|
return substitute(a:str, printf('%s$', a:trim), '', 'g')
|
|
endfunction
|
|
|
|
function! s:SID_PREFIX() abort
|
|
return matchstr(expand('<sfile>'),
|
|
\ '<SNR>\d\+_\zeSID_PREFIX$')
|
|
endfunction
|
|
let g:defx_config_sid = s:SID_PREFIX()
|