安裝
vim8要求安裝pynvim
用 vim 包管理工具安裝 defx
安裝些字體美化 defx 樹圖標,不知道要哪個,把有的 nerd 字體都裝了
修改了幾處默認快捷鍵:
h鍵:改為當光標在某個文件上時,按鍵后光標移動到其父目錄;當光標在目錄上時,若目錄在打開狀態,則關閉目錄,否則光標移動到其父目錄,一直到 defxtree的根目錄
pip install pynvim msgpack-python
call plug#begin('~/.vim/plugged') Plug 'git://github.com/Shougo/defx.nvim.git' Plug 'git://github.com/roxma/nvim-yarp.git' Plug 'git://github.com/roxma/vim-hug-neovim-rpc.git' Plug 'git://github.com/kristijanhusak/defx-icons.git' call plug#end()
$ sudo pacman -S nerd-fonts-roboto-mono nerd-fonts-terminus ttf-nerd-fonts-symbols-mono nerd-fonts-terminus
配置
安裝以后,defx 默認是沒有多少快捷鍵配置的, 所以根據defx的幫助文檔,把默認的快捷鍵設置代碼寫到 .vimrc 里,經過一些修改,目前我的配置文件是這樣的:"""""""""""""""""""""""""""""""""""""""""""""""""""""""""" """"" Defx配置 """""""""""""""""""""""""""""""""""""""""""""""""""""""""" let g:defx_icons_enable_syntax_highlight = 1 " 開關快捷鍵,【-search=`expand('%:p')`】表示打開defx樹后,光標自動放在當前buffer上 nmap <silent> ff :Defx -search=`expand('%:p')` -toggle <cr> "打開vim自動打開defx func! ArgFunc() abort let s:arg = argv(0) if isdirectory(s:arg) return s:arg else return fnamemodify(s:arg, ':h') endif endfunc "autocmd VimEnter * Defx `ArgFunc()` -no-focus -search=`expand('%:p')` " 設置defx樹的一些格式 call defx#custom#option('_', { \ 'columns': 'icons:indent:filename:size', \ 'winwidth': 30, \ 'split': 'vertical', \ 'direction': 'botright', \ 'show_ignored_files': 0, \ 'resume': 1, \ }) " Exit Vim if defxTree is the only window left. autocmd BufEnter * if tabpagenr('$') == 1 && winnr('$') == 1 && exists('b:defx') | \ quit | endif " 在打開多個tab的情況下,當前tab里只有一個buffer和nerd樹,當關閉buffer時,自動關閉當前標簽頁的nerd樹 autocmd BufEnter * if tabpagenr('$') > 1 && winnr('$') == 1 && exists('b:defx') | \ tabclose | endif " 在新tab頁打開文件 func! MyT(context) abort if isdirectory(get(a:context.targets, 0)) == 0 call defx#call_action('drop', 'tabe') endif endfunc " 給cd快捷鍵寫的 func! MyCD(context) abort if isdirectory(get(a:context.targets, 0)) execute 'cd' . get(a:context.targets, 0) else execute 'cd' . fnamemodify(defx#get_candidate().action__path, ':h') endif endfunc " 給 ter 快捷鍵寫的 func! MyTER(context) abort call MyCD(a:context) shell endfunc " 給復制或剪切選中的文件或目錄寫的 func! Mycopy_cut(mode) abort let s:Path = defx#get_selected_candidates() let s:Len = len(s:Path) let s:Path_list = [] let s:counter = 0 while s:counter < s:Len let s:P = s:Path[s:counter].action__path call add(s:Path_list, s:P) let s:counter = s:counter + 1 endwhile let s:MyCMD = ['!~/.vim/cut_copy.py'] + s:Path_list + [a:mode] execute join(s:MyCMD) endfunc " 給粘貼文件寫的 func! Mypaste() abort execute join(['!~/.vim/paste.py', defx#get_candidate().action__path]) endfunc " 所有快捷鍵在這里設置 autocmd FileType defx call s:defx_my_settings() function! s:defx_my_settings() abort nnoremap <silent><buffer><expr> <CR> defx#do_action('drop') nnoremap <silent><buffer><expr> t defx#do_action('call', 'MyT') nnoremap <silent><buffer><expr> yy defx#do_action('yank_path') nnoremap <silent><buffer><expr> dd defx#do_action('remove_trash') nnoremap <silent><buffer><expr> cc defx#do_action('copy') nnoremap <silent><buffer><expr> mm defx#do_action('move') nnoremap <silent><buffer><expr> pp defx#do_action('paste') nnoremap <silent><buffer><expr> CC Mycopy_cut('copy') . defx#do_action('clear_select_all') nnoremap <silent><buffer><expr> MM Mycopy_cut('cut') . defx#do_action('clear_select_all') nnoremap <silent><buffer><expr> PP Mypaste() nnoremap <silent><buffer><expr> N defx#do_action('new_file') nnoremap <silent><buffer><expr> M defx#do_action('new_multiple_files') nnoremap <silent><buffer><expr> R defx#do_action('rename') nnoremap <silent><buffer><expr> j line('.') == line('$') ? 'gg' : 'j' nnoremap <silent><buffer><expr> k line('.') == 1 ? 'G' : 'k' nnoremap <silent><buffer><expr> h \ defx#is_opened_tree() ? \ defx#do_action('close_tree', defx#get_candidate().action__path) : \ defx#do_action('search', fnamemodify(defx#get_candidate().action__path, ':h')) nnoremap <silent><buffer><expr> l defx#do_action('open_tree') nnoremap <silent><buffer><expr> o defx#do_action('open_directory') nnoremap <silent><buffer><expr> u defx#do_action('cd', ['..']) nnoremap <silent><buffer><expr> E defx#do_action('open', 'vsplit') nnoremap <silent><buffer><expr> P defx#do_action('preview') "nnoremap <silent><buffer><expr> d defx#do_action('new_directory') nnoremap <silent><buffer><expr> C defx#do_action('toggle_columns', 'mark:indent:icon:filename:type:size:time') nnoremap <silent><buffer><expr> S defx#do_action('toggle_sort', 'time') nnoremap <silent><buffer><expr> ! defx#do_action('execute_command') nnoremap <silent><buffer><expr> x defx#do_action('execute_system') nnoremap <silent><buffer><expr> cd defx#do_action('call', 'MyCD') nnoremap <silent><buffer><expr> ~ defx#do_action('cd') nnoremap <silent><buffer><expr> ter defx#do_action('call', 'MyTER') nnoremap <silent><buffer><expr> . defx#do_action('toggle_ignored_files') nnoremap <silent><buffer><expr> q defx#do_action('quit') nnoremap <silent><buffer><expr> <Space> defx#do_action('toggle_select') . 'j' nnoremap <silent><buffer><expr> * defx#do_action('toggle_select_all') nnoremap <silent><buffer><expr> m defx#do_action('clear_select_all') nnoremap <silent><buffer><expr> r defx#do_action('redraw') nnoremap <silent><buffer><expr> pr defx#do_action('print') 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) nnoremap <silent><buffer><expr> <2-LeftMouse> endfunction
u鍵:改為進入到defxtree根目錄的父目錄l鍵:改為只能打開或關閉目錄
o鍵:改為只能進入目錄,有點跟u鍵相反,按u鍵后,按o鍵可以恢復
cd鍵:把vim的工作目錄切換到光標所在的目錄,如果光標在文件上則切換到其父目錄
增加ter鍵:當光標在目錄上時,按ter 可以在此目錄上打開一個shell外殼,當光標在文件則在其父目錄打開
t鍵:在新標簽頁打開光標處的文件,
這里打開總是很慢,原因是有快捷鍵ter,這里在等待確認是否還會輸入er,可以改名解決,下面的space鍵也類似,可改為<space><space>
dd鍵:改成刪除文件至系統回收站,需要安裝send2trash默認有文件移動mm,復制cc,粘貼pp,因為有時用到不同的終端窗口之間移動文件,所以就新增加了以下幾個鍵:
CC鍵:復制選中的文件和目錄
MM鍵:剪切選中的文件和目錄
PP鍵:粘貼上述的文件和目錄到光標所在的位置,光標在目錄上則粘貼到此目錄內,光標在文件上,則粘貼到文件所在的目錄
其實,復制和粘貼就是調用用 ~/.vim/cut_copy.py把選中的文件和目錄的路徑寫到 ~/.vim/tmp_clipboard.txt 里,並標明要復制還是粘貼。
按PP鍵的時候才用 調用~/.vim/paste.py ,把文件和目錄移動到相應的位置。
這三個鍵要用到下面的兩個文件,要放到~/.vim 目錄下。
要增加權限
至此,defx就配置成比較順手的了,附上用到的兩個文件cut_copy.py
paste.py
參考:
chmod +x cut_copy.py paste.py
#!/usr/bin/python3 """ 調用方式: ~/.vim/cut_copy.py f1 f2 d1/ d2/ cut or copy 把相關的文件/目錄的絕對路徑寫到文件里保存 最后一個參數代表粘貼的時候是復制copy還是移動mv """ import sys argv = sys.argv with open('~/.vim/tmp_clipboard.txt', 'w') as f: f.write('\n'.join(argv[1:]))
#!/usr/bin/python3 """ 需要粘貼的文件路徑已經存放在文件~/.vim/tmp_clipboard.txt 文件最后一行表示要cut還是copy, 。 調用方法: ~/.vim/paste.py dst """ import os import sys import shutil
def clean_dst(one_path, dst): """ 當dst是一個目錄時,要把剪貼板上的文件和目錄都放到dst下面; 當dst是一個文件時,要把剪貼板上的文件和目錄都放到其父目錄下。 函數的功能就是清理dst,使得粘貼的時候不會發生文件存在異常。 """ dst = os.path.dirname(dst) if os.path.isfile(dst) else dst path = os.path.join(dst, os.path.basename(one_path)) if path == one_path: return None if os.path.exists(path): try: os.remove(path) except: shutil.rmtree(path) return path def paste(): """ 完成粘貼任務,如果同名目標已經存在,就覆蓋 """ dst = sys.argv[1].strip() FILE = "~/.vim/tmp_clipboard.txt" if os.path.exists(FILE): with open(FILE) as f: files = f.readlines() # 查看復制還是剪切 CUT = True if files[-1].strip() == 'cut' else False for f in files[: -1]: f = f.strip() if not f: continue dst_f = clean_dst(f, dst) if dst_f is None: # 粘貼到原位置 continue if CUT: shutil.move(f, dst_f) else: try: shutil.copy(f, dst_f) except: shutil.copytree(f, dst_f) assert len(sys.argv) == 2, '輸入dst' paste()
https://zhuanlan.zhihu.com/p/358828723