본문 바로가기
Linux/VIM

vim 파일 탐색 플러그인 fzf

by khd0801 2023. 4. 4.
반응형

 1.  FZF 이란?

fzf는 아주 강력한 파일 탐색 도구이다. 기존에는 vim에서 파일 탐색시 ctrlp를 사용하였지만 fzf를 설치한 이후로는 fzf만을 사용하여 vim 상태에서 파일을 검색한다.

fzf를 실행하고 파일을 찾기 위해 파일 이름을 적으면 아래 화면과 같이 유사 파일들의 목록을 표시하여 준다.

FZF 실행 화면

 

 2. .vimrc에 Plugin  추가

call vundle#begin()

   Plug 'junegunn/fzf', { 'do': { -> fzf#install() } }
   Plug 'junegunn/fzf.vim'

 

call vundle#end()

 

vim Plugin 사용방법

 

 3.  설정

fzf를 사용하기 위해서는 fzf를 설치해 줘야 된다. 쉘 상에서 sudo apt install fzf 명령어로 설치 할 수도 있고, 위 예시 처럼 Plugin에서 fzf를 추가한 다음 PluginInstall를 이용하여 설치하여도 된다. PluginInstall를 진행하면 fzf plugin을 설치하면서 fzf를 설치 하겠냐고 묻는데, 이때 y를 입력하면 설치가 된다.

 

아래 내용은 .vimrc에서 설정내용이다.

"-----------------------------------------------------------------------"
" fzf layout
"-----------------------------------------------------------------------"
" An action can be a reference to a function that processes selected lines
function! s:build_quickfix_list(lines)
  call setqflist(map(copy(a:lines), '{ "filename": v:val, "lnum": 1 }'))
  copen
  cc
endfunction

let g:fzf_action = {
  \ 'ctrl-q': function('s:build_quickfix_list'),
  \ 'ctrl-t': 'tab split',
  \ 'ctrl-x': 'split',
  \ 'ctrl-v': 'vsplit' }

"let g:fzf_layout = { 'window': { 'width': 0.9, 'height': 0.9,'yoffset':0.5,'xoffset': 0.5 } }

" - down / up / left / right
"let g:fzf_layout = { 'left': '50%' }

let $FZF_DEFAULT_OPTS = '--layout=reverse --inline-info'
let $FZF_DEFAULT_COMMAND="rg --files --hidden --glob '!.git/**'"

" Customize fzf colors to match your color scheme
" - fzf#wrap translates this to a set of `--color` options
let g:fzf_colors =
\ { 'fg':      ['fg', 'Normal'],
  \ 'bg':      ['bg', 'Normal'],
  \ 'hl':      ['fg', 'Comment'],
  \ 'fg+':     ['fg', 'CursorLine', 'CursorColumn', 'Normal'],
  \ 'bg+':     ['bg', 'CursorLine', 'CursorColumn'],
  \ 'hl+':     ['fg', 'Statement'],
  \ 'info':    ['fg', 'PreProc'],
  \ 'border':  ['fg', 'Ignore'],
  \ 'prompt':  ['fg', 'Conditional'],
  \ 'pointer': ['fg', 'Exception'],
  \ 'marker':  ['fg', 'Keyword'],
  \ 'spinner': ['fg', 'Label'],
  \ 'header':  ['fg', 'Comment'] }
  
command! -bang -nargs=? -complete=dir Files
    \ call fzf#vim#files(<q-args>, fzf#vim#with_preview({'options': ['--layout=reverse', '--info=inline']}), <bang>0)

5번째 줄 function!은 함수로서 endfunction까지가 해당 함수의 내용이다. 이 함수는 fzf로 실행된 목록 중에 mark로 선택된 리스트들을(tab 키로 선택 가능) 새버퍼를 열어 파일의 내용과 분활된 아래창에는 Quickfix List로 fzf에서 mark로 선택된 파일들의 목록이 보인다.(아래 QuickFix List 참고)

QuickFix List

11번째 줄 let g:fzf_action은 단축키의 등록이다. fzf window가 뜬 상태에서 "ctrl+q"를 누르면 앞에 설명한 5번째 줄의 funcion이 실행된다. "crtl-t"는 새 tab을 띄워 선택한 파일을 여는 것이고 "split", "vsplit"은 각각 가로와 세로 분활로 선택한 파일을 연다.

 

 

17번 째 줄은 필자는 쓰지 않아 주석으로 처리 했지만 해당 기능은 fzf의 window의 창 크기를 설정하는 옵션이다. 

 

 

20번 째 줄도 필자는 쓰지 않아 주석으로 처리 했지만 해당 기능은 fzf의 window를 창 아래에 나오게 할 것인지, 창 왼쪽 또는 오른쪽, 위에 나오게 할 것인지 위치와 크기를 정해주는 옵션이다.

 

 

22번 째 줄은 FZF 실행시 적용되는 옵션으로 '--layout=reverse'는 내가 찾는 파일의 목록을 위에서 아래로 표시하는 옵션이며 이 옵션을 해제하면 아래에서 위로 내가 찾는 파일과 근접한 파일들이 정렬되어 출력된다. 

'--inline-info' 옵션은 FZF 실행시 전체 파일 목록과, 내거 타이핑하여 검색된 목록 및 mark한 숫자 표시 search 입력란 옆에 출력하도록 하는 옵션이다. 이 옵션이 없으면 해당 표시는 search 입력란 밑에 표시된다. 

 

 

23번 째 줄은 rg 검색 옵션에 대한 옵션이다. fzf는 파일을 검색할 때 빠른 rg(ripgrep)를 사용하여 파일을 검색한다. 해당 내용은 파일들만 검색하는데 히든 파일 검색 허용과 .git 안의 내용들은 검색에서 제외하는 옵션이다.

 

 

27번 째 줄은 fzf의 컬러를 설정하는 옵션이다. :echo fzf#wrap()로 설정된 컬러 값 및 옵션 설정을 볼 수 있으며 자세한 내용은 아래 FZF Vim Integration 링크를 참조바란다.

 

 

마지막 42번 째 줄은 vim command 명령을 설정하는 것이다. command(명령) 모드에서 :Files 치면 FZF가 실행 되며, 실행된 FZF Window 옆에는 해당 파일의 미리보기가 나온다.

 

 

위에 설명한 기능들에 대한 사진은 아래에 있는  "5. 현재까지 설정이 적용된 vim 코드 뷰"를 참조 바란다.

 

 

추가적인 세부 옵션에 대한 내용은 아래 링크를 참조바란다.

 

fzf github 주소

주의사항

.vimrc 설정 내용에도 있듯이 vim을 통해 fzf를 쓰려면 rg가 설치되어 있어야 한다. rg는 ripgrep이란 프로그램으로 grep 을 대체할 수 있는 빠른 문자열 검색기이다. rg 설치는 아래와 같이 "sudo apt install ripgrep" 명령어로 설치가 가능하다.

 

$ sudo apt install ripgrep

Reading package lists... Done

Building dependency tree

Reading state information... Done

The following NEW packages will be installed:

  ripgrep

0 upgraded, 1 newly installed, 0 to remove and 22 not upgraded.

Need to get 1,173 kB of archives.

After this operation, 4,293 kB of additional disk space will be used.

Get:1 http://kr.archive.ubuntu.com/ubuntu focal-updates/universe amd64 ripgrep amd64 11.0.2-1ubuntu0.1 [1,173 kB]

Fetched 1,173 kB in 3s (406 kB/s)  

Selecting previously unselected package ripgrep.

(Reading database ... 216312 files and directories currently installed.)

Preparing to unpack .../ripgrep_11.0.2-1ubuntu0.1_amd64.deb ...

Unpacking ripgrep (11.0.2-1ubuntu0.1) ...

Setting up ripgrep (11.0.2-1ubuntu0.1) ...

Processing triggers for man-db (2.9.1-1) ...

$

 

 

 4. 현재까지의 설정이 적용된 .vimrc 내용

"-----------------------------------------------------------------------"
" Vundle 환경설정
"------------------------------------------------------------------------"
filetype off                   " required!
set shell=/bin/bash
set rtp+=~/.vim/bundle/Vundle.vim
call vundle#begin()
	" let Vundle manage Vundle
	" required!
	Plugin 'VundleVim/Vundle.vim'

	" vim 하단에 파일 정보 띄우기
	Plugin 'vim-airline/vim-airline'
	Plugin 'vim-airline/vim-airline-themes'
   
	"vim corlor/scheme 수정
	Plugin 'morhetz/gruvbox'
	
	" 파일 및 폴더 탐색
	Plugin 'ctrlpvim/ctrlp.vim'

	" vim 사용중 git 명령어 사용
	Plugin 'tpope/vim-fugitive'

	"vim 하단에 커서가 있는 함수나 변수의 정의 부분을 출력
	Plugin 'wesleyche/srcexpl'

	"명령어 자동완성 플러그인(inc + <C-a> : #include<>)
	Plugin 'SirVer/ultisnips'
	Plugin 'honza/vim-snippets'

	" [] {} 등 괄호 입력시 자동으로 닫아주는 플러그인
	Plugin 'jiangmiao/auto-pairs' 

	Plugin 'junegunn/fzf', { 'do': { -> fzf#install() } }
	Plugin 'junegunn/fzf.vim'

    " ...
call vundle#end()
filetype plugin indent on     " required!
	"
	" Brief help
	" :BundleList          - list configured bundles
	" :BundleInstall(!)    - install(update) bundles
	" :BundleSearch(!) foo - search(or refresh cache first) for foo
	" :BundleClean(!)      - confirm(or auto-approve) removal of unused bundles
	"
	" see :h vundle for more details or wiki for FAQ
	" NOTE: comments after Bundle command are not allowed..

"-----------------------------------------------------------------------"
"vim 환경설정
"-----------------------------------------------------------------------"

	" Vim 전용 기능 사용
	set nocompatible "Vim Using

	"파일 타입 설정
	set encoding=utf-8
	set fencs=utf-8,cp949,cp932,euc-jp,shift-jis,big5,ucs-2le,latin1

	" 명령어 기록 갯수
	set hi=1000

	" 백스페이스 사용
	set bs=indent,eol,start

	" 오른쪽 하단 커서 위치 항상 보이기
	set ru "same ruler

	" 줄번호 표시
	set nu

	" 줄 번호 표시 너비 설정
	set nuw=5

	" 탭 크기 설정
	set ts=4 "same tabstop
	set sw=4 "same shiftwidth
	set sts=0 "same softtabstop

	autocmd FileType make setlocal noexpandtab "Makefile은 tab 문법이기 때문에 스페이스 대체 안함.
	" 탭 >> 공백 변환 사용안함
	"set noet

	" 자동 줄바꿈 안함
	"set nowrap
	set linebreak
	set showbreak=+++\

	" 들여쓰기 설정
	set autoindent
	set cindent

	" 스마트 셋팅
	set smartcase
	set smarttab
	set smartindent

	" magic 기능 사용
	set magic

	" 이동 동작시 줄의 시작으로 자동 이동
	set sol

	" 비쥬얼 모드 동작 설정
	set sel=exclusive

	" 괄호짝 찾기에서 <> 도 찾도록 추가
	set mps+=<:>

	" 검색어 강조
	set hls

	" 검색시 파일 끝에서 되돌리기 안함
	set nows

	" 스마트한 대소문자 구별 기능 사용
	set scs

	"대소문자 구분(구분 없이 할 때 i 옵션 또는 ignorecase)
	set noignorecase

	" 항상 status 라인을 표시
	set ls=2

	"파일 형식에 따른 신택스 하이라이팅 켜기
	sy enable

	"괄호 매치
	set showmatch

	"마우스 자동
	set mouse=a

	"클립보드 복사
	"set clipboard=unnamed "use OS clipboard
	set clipboard=unnamedplus "use OS clipboard

	" 키워드 입력시 점진적 검색
	set incsearch
	set spell
"----------------------------------------------------------------------"
" AirLine
"----------------------------------------------------------------------"
set laststatus=2
let g:airline#extensions#tabline#enabled = 1 "버퍼 목록 켜기
let g:airline#extensions#tabline#left_sep = ' '
let g:airline#extensions#tabline#left_alt_sep = '|'
" 파일명만 출력
let g:airline#extensions#tabline#fnamemod = ':t'
let g:airline_highlighting_cache = 1

let g:airline_powerline_fonts = 1
let g:airline_theme= 'minimalist'
"let g:airline_section_y = ''
"let g:airline_section_warning= '' "마지막 status창 사용 안함
" 버퍼 목록 켜기
" 이 옵션은 버퍼를 수정한 직후 버퍼를 감춰지도록 한다.
" 이 방법으로 버퍼를 사용하려면 거의 필수다.
set hidden


"----------------------------------------------------------------------"
" gruvbox 설정
"----------------------------------------------------------------------"
set background=dark
let g:gruvbox_contrast_dark = 'soft'
"let g:gruvbox_contrast_light = 'soft'
"let g:gruvbox_transparent_bg = '1'
let g:gruvbox_italic = 1
"let g:gruvbox_underline=1
"let g:gruvbox_undercurl=1
"let g:gruvbox_termcolors=16
"let g:gruvbox_number_column='aqua'
"let g:gruvbox_sign_column='aqua'
"let g:gruvbox_color_column='aqua'

" Force to use underline for spell check results
augroup SpellUnderline
  autocmd!
  autocmd ColorScheme *
    \ highlight SpellBad
    \   cterm=Underline
    \   ctermfg=NONE
    \   ctermbg=NONE
    \   term=Reverse
    \   gui=Undercurl
    \   guisp=Red
  autocmd ColorScheme *
    \ highlight SpellCap
    \   cterm=Underline
    \   ctermfg=NONE
    \   ctermbg=NONE
    \   term=Reverse
    \   gui=Undercurl
    \   guisp=Red
  autocmd ColorScheme *
    \ highlight SpellLocal
    \   cterm=Underline
    \   ctermfg=NONE
    \   ctermbg=NONE
    \   term=Reverse
    \   gui=Undercurl
    \   guisp=Red
  autocmd ColorScheme *
    \ highlight SpellRare
    \   cterm=Underline
    \   ctermfg=NONE
    \   ctermbg=NONE
    \   term=Reverse
    \   gui=Undercurl
    \   guisp=Red
  augroup END
set termguicolors
colorscheme gruvbox


"----------------------------------------------------------------------"
" ctrlp.vim 설정(파일 탐색 속도 향상)
"----------------------------------------------------------------------"
set wildignore+=*/tmp/*,*.so,*.a,*.swp,*.zip,*.obj  " MacOSX/Linux
set wildignore+=*\\tmp\\*,*.swp,*.zip,*.exe  		" Windows

let g:ctrlp_custom_ignore = '\v[\/]\.(git|hg|svn)$'
let g:ctrlp_custom_ignore = {
  \ 'dir':  '\.git$\|public$\|log$\|tmp$\|vendor$',
  \ 'file': '\v\.(exe|so|dll|a)$',
  \ 'link': 'some_bad_symbolic_links'
\ }
let g:ctrlp_max_files = 10000
let g:ctrlp_max_depth = 30
let g:ctrlp_follow_symlinks = 1
"let g:ctrlp_user_command = ['.git', 'cd %s && git ls-files -co --exclude-standard']
"let g:ctrlp_use_readdir = 0
let g:ctrlp_root_markers = ['ctrlp-marker']

" <c-f>, <c-b> 모드 변환(MRU(Most Recently Used)내 검색, file 전체 검색, buffers내 검색)
" <c-d> path내 검색어가 포함되어 검색 또는 오직 파일내 검색어만 포함 검색 
" <c-r> 정규 표현식 모드 전환(검색어와 완전히 일치한 파일만 보여 줌)
" <c-j>, <c-k> 검색결과내 커서 위아래 이동
" <c-t>, <c-v>, <c-x> 파일을 새로운 tab으로 열거나 창을 분활하여 파일을 염.
" <c-n>, <n-p> 검색 history의 next/previous 문자열 선택
" <c-z>, <c-o> 검색된 결과물에 <c-z>로 마크를 하고 <c-o>로 오픈(멀티마크 가능) 
" <c-y> 검색입력어로 된 파일을 만든다. 파일 위치는 검색 폴더의 최상위 위치
" :help ctrlp-mappings 키 맵핑에 관한 설명


"-----------------------------------------------------------------------"
" Source Explorer 환경설정
"-----------------------------------------------------------------------"
nmap <F8> :SrcExplToggle<CR>            " F8 key = SrcExpl TOggle

let g:SrcExpl_winHeight = 12            " SrcExpl 윈도우 높이 지정
let g:SrcExpl_refreshTime = 100         " refreshing time = 100ms
let g:SrcExpl_jumpKey = "<ENTER>"       " 해당 definition으로 jump
let g:SrcExpl_gobackKey = "<SPACE>"     " back
let g:SrcExpl_pluginList = [
        \ "__Tag_List__",
        \ "_NERD_tree_",
        \ "Source_Explorer"
        \ ]

" // The color schemes used by Source Explorer. There are five color schemes
" // supported for now - Red, Cyan, Green, Yellow and Magenta. Source Explorer
" // will pick up one of them randomly when initialization.
let g:SrcExpl_colorSchemeList = [
        \ "Cyan",
    \ ]

" // Enable/Disable the local definition searching, and note that this is not
" // guaranteed to work, the Source Explorer doesn't check the syntax for now.
" // It only searches for a match with the keyword according to command 'gd'
let g:SrcExpl_searchLocalDef = 1

" // Workaround for Vim bug @https://goo.gl/TLPK4K as any plugins using autocmd for
" // BufReadPre might have conflicts with Source Explorer. e.g. YCM, Syntastic etc.
let g:SrcExpl_nestedAutoCmd = 1

" // Do not let the Source Explorer update the tags file when opening
let g:SrcExpl_isUpdateTags = 0

" // Use 'Exuberant Ctags' with '--sort=foldcase -R .' or '-L cscope.files' to
" // create/update the tags file
let g:SrcExpl_updateTagsCmd = "ctags --sort=foldcase -R ."

" // Set "<F12>" key for updating the tags file artificially
let g:SrcExpl_updateTagsKey = "<F12>"

" // Set "<F3>" key for displaying the previous definition in the jump list
let g:SrcExpl_prevDefKey = "<S-K>"

" // Set "<F4>" key for displaying the next definition in the jump list
let g:SrcExpl_nextDefKey = "<S-J>"


"-----------------------------------------------------------------------"
" ultisnips&vim-snippets Trigger Configuration
"-----------------------------------------------------------------------"
" Trigger configuration. You need to change this to something other than <tab>
" if you use one of the following:
" " - https://github.com/Valloric/YouCompleteMe
" " - https://github.com/nvim-lua/completion-nvim
let g:UltiSnipsExpandTrigger="<C-a>"
let g:UltiSnipsJumpForwardTrigger="<tab>"
let g:UltiSnipsJumpBackwardTrigger="<s-tab>"
" If you want :UltiSnipsEdit to split your window.
let g:UltiSnipsEditSplit="vertical"
" let g:UltiSnipsSnippetDirectories = ['~/.vim/UltiSnips']


"-----------------------------------------------------------------------"
" fzf layout
"-----------------------------------------------------------------------"
" An action can be a reference to a function that processes selected lines
function! s:build_quickfix_list(lines)
  call setqflist(map(copy(a:lines), '{ "filename": v:val, "lnum": 1 }'))
  copen
  cc
endfunction

let g:fzf_action = {
  \ 'ctrl-q': function('s:build_quickfix_list'),
  \ 'ctrl-t': 'tab split',
  \ 'ctrl-x': 'split',
  \ 'ctrl-v': 'vsplit' }

"let g:fzf_layout = { 'window': { 'width': 0.9, 'height': 0.9,'yoffset':0.5,'xoffset': 0.5 } }

" - down / up / left / right
"let g:fzf_layout = { 'left': '50%' }

let $FZF_DEFAULT_OPTS = '--layout=reverse --inline-info'
let $FZF_DEFAULT_COMMAND="rg --files --hidden --glob '!.git/**'"

" Customize fzf colors to match your color scheme
" - fzf#wrap translates this to a set of `--color` options
let g:fzf_colors =
\ { 'fg':      ['fg', 'Normal'],
  \ 'bg':      ['bg', 'Normal'],
  \ 'hl':      ['fg', 'Comment'],
  \ 'fg+':     ['fg', 'CursorLine', 'CursorColumn', 'Normal'],
  \ 'bg+':     ['bg', 'CursorLine', 'CursorColumn'],
  \ 'hl+':     ['fg', 'Statement'],
  \ 'info':    ['fg', 'PreProc'],
  \ 'border':  ['fg', 'Ignore'],
  \ 'prompt':  ['fg', 'Conditional'],
  \ 'pointer': ['fg', 'Exception'],
  \ 'marker':  ['fg', 'Keyword'],
  \ 'spinner': ['fg', 'Label'],
  \ 'header':  ['fg', 'Comment'] }
  
command! -bang -nargs=? -complete=dir Files
    \ call fzf#vim#files(<q-args>, fzf#vim#with_preview({'options': ['--layout=reverse', '--info=inline']}), <bang>0)

 

 

 5. 현재까지의 설정이 적용된 vim 코드 뷰

:FZF 명령을 실행하면 vim을 켠 위치로 부터 하위 폴더들의 파일을 검색한다. :FZF path/to/path 를 실행하면 내락 입력한 path/to/path 부터 하위 폴더의 모든 파일들을 검색한다.(ex : :FZF /home/root )

FZF 실행 명령 화면

 

FZF 실행 화면

 

test.h 파일을 검색하는 화면

 

Files 명령어 입력

 

Files 명령어 입력 실행 결과, fzf 파일 미리보기 실행

 

 

 

 

참고사항

vim에서 fzf로 검색시 위와 같이 팝업 상태의 Window 화면으로 보고싶다면 vim 8.2 버전 이상을 사용해야 된다.
vim 8.1 이하 버전은 새 Window 화면이 뜨지 않고 기존 화면 아래에 split 된 화면이 뜬다.
vim 8.2 설치 방법은 아래와 같다.

sudo add-apt-repository ppa:jonathonf/vim
sudo apt update
sudo apt install vim

 

반응형

댓글