BanditHijo.dev

Defx, Alternatif Vim File Explorer selain NERDTree

Created at: 2020-10-27
Author by: BanditHijo

Latar Belakang

Di Vim “world”, ada beberapa nama-nama plugin yang sudah tersohor di kalangan pengguna Vim. Dan biasanya menjadi plugin pilihan pertama oleh Vim user ketika baru bargabung dengan komunitas Vim. Tentu saja, yang menyebabkan hal tersebut adalah, karena biasanya di dalam tutorial, baik blog maupun vlog yang mereka lihat menginformasikan untuk memasang nama-nama plugin tersebut.

Salah satu plugin tersohor tersebut adalah NERDTree. NERDTree digunakan sebagai file explorer pengganti Netrw (default vim file explorer).

Saya pun, sejak awal menggunakan Vim, sudah menggunakan NERDTree, sampai-sampai saya tidak mengetahui bagaimana cara menggunakan Netrw.

Catatan kali ini tentang, proses migrasi saya dari NERDTree ke Defx.nvim.

Menurut yang tertulis di halaman GitHub README dari Defx, plugin ini diciptakan untuk menggantikan vimfiler yang sudah deprecated.

Penjelasan mengenai konsep dari Defx, dapat teman-teman baca di sini.

Requirement

neovim 0.4.x atau vim 8.2.x dengan python 3.6.x.

Instalasi

Saya menggunakan vim-plug sebagai plugin manager.

$HOME/.config/nvim/init.vim
1if has('nvim')
2 Plug 'Shougo/defx.nvim', { 'do': ':UpdateRemotePlugins' }
3else
4 Plug 'Shougo/defx.nvim'
5 Plug 'roxma/nvim-yarp'
6 Plug 'roxma/vim-hug-neovim-rpc'
7endif

Saya juga menambahkan 2 plugin tambahan untuk icon dan git status.

$HOME/.config/nvim/init.vim
1Plug 'kristijanhusak/defx-icons'
2Plug 'kristijanhusak/defx-git'

Konfigurasi Defx

Jangan kaget, kalau di halaman GitHub README tidak tersedia contoh-contoh konfigurasi.

Teman-teman dapat melihat contoh konfigurasi pada:

:help defx-examples

Namun, pada catatan kali ini, saya akan langsung memberikan konfigurasi yang saya pergunakan.

$HOME/.config/nvim/init.vim
1if exists('g:plugs["defx.nvim"]')
2 autocmd FileType defx call s:defx_my_settings()
3 autocmd BufWritePost * call defx#redraw()
4 autocmd BufEnter * call s:open_defx_if_directory()
5
6 call defx#custom#option('_', {
7 \ 'winwidth' : 40,
8 \ 'split' : 'vertical',
9 \ 'direction' : 'topleft',
10 \ 'buffer_name' : 'defx',
11 \ 'columns' : 'git:indent:icons:filename',
12 \ 'show_ignored_files' : 0,
13 \ 'toggle' : 1,
14 \ 'resume' : 1,
15 \ 'auto_cd' : 1,
16 \ })
17
18 call defx#custom#column('icon', {
19 \ 'directory_icon' : ' ',
20 \ 'opened_icon' : ' ',
21 \ })
22
23 call defx#custom#column('filename', {
24 \ 'min_width': 40,
25 \ 'max_width': 1000,
26 \ })
27
28 " Open Defx when open a directory
29 function! s:open_defx_if_directory()
30 try
31 let l:full_path = expand(expand('%:p'))
32 catch
33 return
34 endtry
35
36 if isdirectory(l:full_path)
37 execute "Defx `expand('%:p')` | bd " . expand('%:r')
38 endif
39 endfunction
40
41 function! s:defx_my_settings() abort
42 " Define mappings
43 nnoremap <silent><buffer><expr> <CR> defx#is_directory() ? defx#do_action('open_or_close_tree') : defx#do_action('drop')
44 nnoremap <silent><buffer><expr> <2-LeftMouse>
45 \ defx#do_action('drop')
46 nnoremap <silent><buffer><expr> <2-RightMouse>
47 \ defx#do_action('open_or_close_tree')
48 nnoremap <silent><buffer><expr> c
49 \ defx#do_action('copy')
50 nnoremap <silent><buffer><expr> m
51 \ defx#do_action('move')
52 nnoremap <silent><buffer><expr> p
53 \ defx#do_action('paste')
54 nnoremap <silent><buffer><expr> V
55 \ defx#do_action('drop', 'vsplit')
56 nnoremap <silent><buffer><expr> S
57 \ defx#do_action('drop', 'split')
58 nnoremap <silent><buffer><expr> P
59 \ defx#do_action('open', 'pedit')
60 nnoremap <silent><buffer><expr> o
61 \ defx#do_action('open_or_close_tree')
62 nnoremap <silent><buffer><expr> K
63 \ defx#do_action('new_directory')
64 nnoremap <silent><buffer><expr> N
65 \ defx#do_action('new_file')
66 nnoremap <silent><buffer><expr> M
67 \ defx#do_action('new_multiple_files')
68 nnoremap <silent><buffer><expr> T
69 \ defx#do_action('toggle_sort', 'time')
70 nnoremap <silent><buffer><expr> d
71 \ defx#do_action('remove')
72 nnoremap <silent><buffer><expr> r
73 \ defx#do_action('rename')
74 nnoremap <silent><buffer><expr> !
75 \ defx#do_action('execute_command')
76 nnoremap <silent><buffer><expr> x
77 \ defx#do_action('execute_system')
78 nnoremap <silent><buffer><expr> yp
79 \ defx#do_action('yank_path')
80 nnoremap <silent><buffer><expr> .
81 \ defx#do_action('toggle_ignored_files')
82 nnoremap <silent><buffer><expr> ;
83 \ defx#do_action('repeat')
84 nnoremap <silent><buffer><expr> <Backspace>
85 \ defx#do_action('cd', ['..'])
86 nnoremap <silent><buffer><expr> ~
87 \ defx#do_action('cd')
88 nnoremap <silent><buffer><expr> q
89 \ defx#do_action('quit')
90 nnoremap <silent><buffer><expr> <Space>
91 \ defx#do_action('toggle_select') . 'j'
92 nnoremap <silent><buffer><expr> *
93 \ defx#do_action('toggle_select_all')
94 nnoremap <silent><buffer><expr> j
95 \ line('.') == line('$') ? 'gg' : 'j'
96 nnoremap <silent><buffer><expr> k
97 \ line('.') == 1 ? 'G' : 'k'
98 nnoremap <silent><buffer><expr> <C-r>
99 \ defx#do_action('redraw')
100 nnoremap <silent><buffer><expr> <C-g>
101 \ defx#do_action('print')
102 nnoremap <silent><buffer><expr> cd
103 \ defx#do_action('change_vim_cwd')
104 endfunction
105
106endif

Penjelasan

1autocmd FileType defx call s:defx_my_settings()

Baris di atas bertujuan untuk memanggil fungsi s:defx_my_settings apabila file type dari buffer yang dibuka bernilai defx.

1autocmd BufWritePost * call defx#redraw()

Baris di atas bertujuan untuk memanggil fungsi defx#redraw() apabila seluruh buffer sudah di-write ke file –mungkin maksudnya di-save.

1autocmd BufEnter * call s:open_defx_if_directory()

Baris di atas bertujuan untuk memanggil fungsi s:open_defx_if_directory() ketika vim dipanggil dengan atribut bernilai direktori misal: $ vim .config/nvim.

1call defx#custom#option('_', {
2 \ 'winwidth' : 40,
3 \ 'split' : 'vertical',
4 \ 'direction' : 'topleft',
5 \ 'buffer_name' : 'defx',
6 \ 'columns' : 'git:indent:icons:filename',
7 \ 'show_ignored_files' : 0,
8 \ 'toggle' : 1,
9 \ 'resume' : 1,
10 \ 'auto_cd' : 1,
11 \ })

Baris di atas bertujuan untuk mengkonfigurasi fungsi defx#custom#option().

Saya akan menjelaskan bagian-bagian yang sekiranya tidak dipahami,

winwidth, untuk membuat vertical split selebar 40px.

toggle, untuk mengaktifkan fitur toggling, apabila :Defx dipanggil.

columns, untuk mendefisikan apa saja isi (konten) dari column defx.

resume, untuk mengaktifkan fitur resume –artinya, abaila kita menutup buffer Defx dan membukanya kembali, Defx akan mengingat posisi terakhir cursor kita berada.

auto_cd, untuk mengaktifkan fungsi berganti direktori (change directory) ketika menafigasikan Defx untuk masuk atau keluar dari direktori. Catatan: hanya berfungsi apabila menggunakan fungsi defx#do_action('drop').

1call defx#custom#column('icon', {
2 \ 'directory_icon' : ' ',
3 \ 'opened_icon' : ' ',
4 \ })

Baris di atas berfungsi untuk menghilangkan tanda panah yang secara default disertakan oleh Defx. Hal ini saya lakukan karena saya menggunakan plugin defx-icons yang akan memberikan icon-icon pada setiap direktori dan file.

1call defx#custom#column('filename', {
2 \ 'min_width': 40,
3 \ 'max_width': 1000,
4 \ })

Baris di atas bertujuan untuk menghandle minimal & maximal lebar dari window pane agar filename tidak terpotong (truncated).

ini adalah judul yang sangat...panjang sekali.md
1function! s:open_defx_if_directory()
2 try
3 let l:full_path = expand(expand('%:p'))
4 catch
5 return
6 endtry
7
8 if isdirectory(l:full_path)
9 execute "Defx `expand('%:p')` | bd " . expand('%:r')
10 endif
11endfunction

Baris di atas bertujuan untuk mendefisikan fungsi s:open_defx_if_directory(). Fungsi ini digunakan untuk menghandle Defx agar terbuka ketika vim digunakan untuk membuka direktori –bukan file.

Catatan: masih terdapat banyak kekurangan pada fungsi ini.

1function! s:defx_my_settings() abort
2 ...
3endfunction

Baris di atas bertujuan untuk mendefinisikan keyboard mapping yang digunakan.

Kita dapat merubah-rubah sesuai preferensi pribadi masing-masing.

Konfigurasi Defx-icons

$HOME/.config/nvim/init.vim
1" defx-icons
2
3let g:defx_icons_enable_syntax_highlight = 1
4let g:defx_icons_column_length = 2
5let g:defx_icons_directory_icon = ''
6let g:defx_icons_mark_icon = ''
7let g:defx_icons_copy_icon = ''
8let g:defx_icons_move_icon = ''
9let g:defx_icons_parent_icon = ''
10let g:defx_icons_default_icon = ''
11let g:defx_icons_directory_symlink_icon = ''
12
13" Options below are applicable only when using 'tree' feature
14let g:defx_icons_draw_tree_structure = 1
15let g:defx_icons_root_opened_tree_icon = ''
16let g:defx_icons_nested_opened_tree_icon = ''
17let g:defx_icons_nested_closed_tree_icon = ''
18
19" Define the default higlight color for defx-icons
20hi default link DefxIconsMarkIcon Statement
21hi default link DefxIconsCopyIcon WarningMsg
22hi default link DefxIconsMoveIcon ErrorMsg
23hi default link DefxIconsDirectory Directory
24hi default link DefxIconsParentDirectory Directory
25hi default link DefxIconsSymlinkDirectory Directory
26hi default link DefxIconsOpenedTreeIcon Directory
27hi default link DefxIconsNestedTreeIcon Directory
28hi default link DefxIconsClosedTreeIcon Directory

Konfigurasi defx-git

$HOME/.config/nvim/init.vim
1" defx-git
2
3if exists('g:plugs["defx-git"]')
4 call defx#custom#column('git', 'column_length', 1)
5
6 call defx#custom#column('git', 'raw_mode', 0)
7
8 call defx#custom#column('git', 'indicators', {
9 \ 'Modified' : 'M',
10 \ 'Staged' : '+',
11 \ 'Untracked' : '*',
12 \ 'Renamed' : 'R',
13 \ 'Unmerged' : '=',
14 \ 'Ignored' : 'i',
15 \ 'Deleted' : 'X',
16 \ 'Unknown' : '?'
17 \ })
18
19 hi Defx_git_Untracked ctermfg=214 ctermbg=NONE
20 hi Defx_git_Ignored ctermfg=214 ctermbg=NONE
21 hi Defx_git_Unknown ctermfg=214 ctermbg=NONE
22 hi Defx_git_Renamed ctermfg=214 ctermbg=NONE
23 hi Defx_git_Modified ctermfg=214 ctermbg=NONE
24 hi Defx_git_Unmerged ctermfg=214 ctermbg=NONE
25 hi Defx_git_Deleted ctermfg=214 ctermbg=NONE
26 hi Defx_git_Staged ctermfg=214 ctermbg=NONE
27endif

Hasilnya

Gambar 1

Gambar 2

Kalau diperhatikan, kenapa status bar saya dapat berbeda ketika berada di buffer Defx?

Jawabannya ada di post setelah ini.

Credit

Terima kasih kepada Elianiva dan teh Tsara Fatma, untuk catatan di blognya.

Pesan Penulis

Sepertinya, segini dulu yang dapat saya tuliskan.

Untuk konfigurasi Defx milik saya yang lebih terbaru, dapat teman-teman kunjungi di sini.

Mudah-mudahan dapat bermanfaat.

Terima kasih.

(^_^)

Referensi

  1. github.com/crow-translate/crow-translate
    Diakses tanggal: 2020/10/27