安装
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(' '.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