본문 바로가기

C

C언어 개발 환경 구축 (1) - vim 에디터

개요

C언어를 학습하거나 개발하기 위한 기초적인 구성에 대해 설명하려한다. 앞으로 연재되는 포스트에서는 다음과 같은 것을 다룬다.

  • 에디터의 설정 - vim
  • 이식성 좋은 컴파일 빌더 - autotools
  • 자동완성 기능

개발 환경

  • Ubuntu 20.04

vim 플러그인 매니져 설치

많은 플러그인이 있지만 가볍고 설치가 빠른 vim-plug를 추천한다.

 

junegunn/vim-plug

:hibiscus: Minimalist Vim Plugin Manager. Contribute to junegunn/vim-plug development by creating an account on GitHub.

github.com

vim-plug 설치

curl -fLo ~/.vim/autoload/plug.vim --create-dirs \
    https://raw.githubusercontent.com/junegunn/vim-plug/master/plug.vim

shell에서 위의 명령을 실행

C 개발을 위한 추천 vim 플러그인

  • ctrlpvim/ctrlp.vim : Fuzzy search 지원 - 파일 탐색을 도와주는 플러그인
  • SirVer/ultisnips: snippet 입력을 도와주는 플러그인
  • honza/vim-snippets: 많이 쓰는 snippet을 모아둔 플러그인
  • vim-airline/vim-airline: 상태 표시창을 추가해주는 플러그인
  • vim-airline/vim-airline-themes: 상태 표시창의 테마 설정 플러그인
  • airblade/vim-gitgutter: git에서 변화된 라인을 +, - 와 같은 표식으로 표시해주는 플러그인
  • tpope/vim-fugitive: vim에서 git 명령을 사용하도록 지원하는 플러그인
  • Valloric/YouCompleteMe: 자동완성을 지원하는 플러그인
  • rdnetto/YCM-Generator: 자동완성 설정을 편하게 만들어주는 플러그인
  • ronakg/quickr-cscope.vim: cscope로 c 분석을 도와주는 플러그인
  • flazz/vim-colorschemes: colorscheme을 변경을 도와주는 플러그인
  • tomasr/molokai : dark mode에 어울리는 molokai 테마

.vimrc 설정

call plug#begin('~/.vim/plugged')

Plug 'ctrlpvim/ctrlp.vim'
Plug 'SirVer/ultisnips'
Plug 'honza/vim-snippets'
Plug 'vim-airline/vim-airline'
Plug 'vim-airline/vim-airline-themes'
Plug 'airblade/vim-gitgutter'
Plug 'tpope/vim-fugitive'
Plug 'Valloric/YouCompleteMe'
Plug 'rdnetto/YCM-Generator', { 'branch': 'stable' }
Plug 'flazz/vim-colorschemes'
Plug 'tomasr/molokai'

Plug 'majutsushi/tagbar'
Plug 'jiangmiao/auto-pairs'
Plug 'mattn/emmet-vim'
Plug 'tpope/vim-surround'
Plug 'scrooloose/nerdcommenter'
Plug 'ntpeters/vim-better-whitespace'
Plug 'terryma/vim-multiple-cursors'
Plug 'ronakg/quickr-cscope.vim'
Plug 'junegunn/vim-easy-align'
Plug 'derekwyatt/vim-fswitch'
Plug 'wellle/targets.vim'

call plug#end()

syntax on
set t_Co=256
set number                     " show line number
set relativenumber             " show relative line number
set cursorline                 " show cursor line
set cindent                    " according the C indenting rules
set autoindent                 " Copy indent from current line when starting a new line in insert mode
set smartindent                " When starting a new line '{', 'cinwords' '}'
set cino=(0,:0,t0              " Indent options
set enc=utf-8                  " Encoding vim inside
set fenc=utf-8                 " File encoding
set nocompatible               " Vi-compatible
set backspace=indent,eol,start " Backspace erase option
set hlsearch                   " Highlight all search pattern
set incsearch                  " While typing a search command, show where the pattern
set diffopt=vertical
set wildmenu                   " show wildmenu
set wildmode=list:longest,full " wildmenu option
set path+=./**
set list                       " show tabs endlie, blank
set listchars=tab:→\ ,extends:›,precedes:‹,nbsp:·,trail:·
set showbreak=\\               " [bonus]
set visualbell
set laststatus=2
set hidden                     " When off a buffer is unloaded when it is abandoned
set splitright
set splitbelow
set smarttab

" Color scheme
colorscheme molokai
hi MatchParen ctermfg=208 ctermbg=233 cterm=bold

augroup ctype
        autocmd!
        autocmd BufRead,BufNewFile *.h,*.c set filetype=c
augroup END

augroup filetype_c_cpp
        autocmd!
        autocmd FileType c,cpp setl ts=8 sw=8 sts=8
        autocmd FileType c,cpp :TagbarOpen
augroup END

augroup filetype_quickfix
        autocmd!
        autocmd FileType qf setl nonumber norelativenumber nocursorline
augroup END

augroup open_lastread
        autocmd!
        autocmd BufReadPost *
                \ if line("'\"") > 0 && line("'\"") <= line("$") |
                \   exe "normal g`\"" |
                \ endif
augroup END

" Make command
command -nargs=* Make wa | make <args> | cwindow 3

nnoremap <F5> :Make<CR>
nnoremap <F6> :Make check<CR>

let g:ycm_confirm_extra_conf           = 0
let g:ycm_auto_trigger                 = 1
let g:ycm_key_list_select_completion   = ['<C-j>', '<Down>']
let g:ycm_key_list_previous_completion = ['<C-k>', '<Up>']
let g:ycm_autoclose_preview_window_after_completion = 1

nnoremap <leader>gl :YcmCompleter GoToDeclaration <CR>
nnoremap <leader>gf :YcmCompleter GoToDefinition <CR>
nnoremap <leader>gg :YcmCompleter GoToDefinitionElseDeclaration <CR>

let g:UltiSnipsListSnippets        = "<C-g><Tab>"
let g:UltiSnipsExpandTrigger       = "<Tab>"
let g:UltiSnipsJumpForwardTrigger  = "<Tab>"
let g:UltiSnipsJumpBackwardTrigger = "<S-Tab>"
let g:UltiSnipsSnippetDirectories  = ['~/.vim/UltiSnips', 'UltiSnips']
let g:UltiSnipsEditSplit           = "vertical"

set wildignore+=*/tmp/*,*.so,*.swp,*.zip     " MacOSX/Linux
set wildignore+=*\\tmp\\*,*.swp,*.zip,*.exe  " Windows

let g:ctrlp_custom_ignore = {
        \ 'dir':  '\v[\/]\.(git|hg|svn)$',
        \ 'file': '\v\.(exe|so|dll)$',
        \ 'link': 'some_bad_symbolic_links',
\ }

let g:ctrlp_user_command = ['.git', 'cd %s && git ls-files -co --exclude-standard']

let g:airline#extensions#tabline#enabled = 1
let g:airline#extensions#tabline#buffer_nr_show = 1
let g:airline#extensions#tabline#formatter = 'unique_tail'
let g:airline_theme='molokai'
let g:airline_powerline_fonts = 1

let g:NERDSpaceDelims = 1
let g:NERDCompactSexyComs = 1
let g:NERDDefaultAlign = 'left'
let g:NERDCommentEmptyLines = 1
let g:NERDTrimTrailingWhitespace = 1
let g:NERDToggleCheckAllLines = 1
let g:NERDCreateDefaultMappings = 0
let g:NERDCustomDelimiters = {
        \ 'c': { 'leftAlt': '/*', 'rightAlt': '*/', 'left': '//' },
        \ 'cpp': { 'leftAlt': '/*', 'rightAlt': '*/', 'left': '//' }
\ }

nmap <Leader>; <plug>NERDCommenterToggle
vmap <Leader>; <plug>NERDCommenterToggle gv

function! LoadCscope()
        let db = findfile("cscope.out", ".;")
        if (!empty(db))
                let path = strpart(db, 0, match(db, "/cscope.out$"))
                set nocscopeverbose " suppress 'duplicate connection' error
                exe "cs add " . db . " " . path
                set cscopeverbose
                " else add the database pointed to by environment variable
        elseif $CSCOPE_DB != ""
                cs add $CSCOPE_DB
        endif
endfunction
au BufEnter /* call LoadCscope()

" Open QF when multiple matches.
let g:quickr_cscope_keymaps = 0

nmap <leader>cs <plug>(quickr_cscope_symbols)
nmap <leader>cg <plug>(quickr_cscope_global)
nmap <leader>cc <plug>(quickr_cscope_callers)
nmap <leader>cf <plug>(quickr_cscope_files)
nmap <leader>ci <plug>(quickr_cscope_includes)
nmap <leader>ct <plug>(quickr_cscope_text)
nmap <leader>ce <plug>(quickr_cscope_egrep)
nmap <leader>cd <plug>(quickr_cscope_functions)
nmap <leader>ca <plug>(quickr_cscope_assignments)

let g:AutoPairsFlyMode = 0
let g:AutoPairsShortcutBackInsert = '<M-b>'

개인의 입맛에 맞게 추가/수정하여 사용하도록 한다. 본인도 더 많은 플러그인과 설정들을 사용하지만 필수적이라고 생각되는 부분들만 뽑아 정리하였다.

플러그인 설치

vi 실행후 command mode에서 PlugInstall 실행

VI 실행시 아래와 같은 메시지가 출력 되는 이유는 YouCompleteMe 서버가 아직 설치되지 않아서 이다. 다음 항목에서 다룬다.

The ycmd server SHUT DOWN (restart with ':YcmRestartServer'). YC...M before using it. Follow the instructions in the documentation.

C 자동완성 기능 설치 - YouCompleteMe

YCM server는 CLANG을 이용하여 자동완성 기능을 지원한다. 이를 컴파일 하기위해서는 c++ 컴파일러와 python3-dev, cmake가 필요하다.

sudo apt install cpp cmake python3-dev

clang-completer 컴파일 및 설치

cd ~/.vim/plugged/YouCompleteMe/
./install.py --clang-completer

정상적으로 컴파일이 완료되었으면 C언어를 개발하기 위한 필수적인 개발환경은 구축되었다.

 

다음 포스트에서는 autotools를 이용한 builder 구성하는 것과 추천기능과 자동완성기능을 사용하는 방법에 대해 설명한다.