LoginSignup
86

More than 5 years have passed since last update.

VimでJavaScript開発環境を作成

Last updated at Posted at 2016-02-21

JavaScriptの勉強がてら開発環境を整備しました。
チップスは概要のみ掲載しているため、詳細は.vimrcを参照して下さい。

Plugin設定

ディレクトリ作成

$ mkdir -p \
    $HOME/.cache/eslint \
    $HOME/.vim/vim-ref/cache \
    $HOME/.vim/tags \
    $HOME/.vim/neosnippet.vim \
    $HOME/.vim/neocomplete.vim

Pluginインストール

Neobundle作者のShougoさんの新しいプラグイン管理プラグイン「dein.vim」を設定します。

.vimrc
" Cygwin
if has('win32') || has ('win64')
    set runtimepath^=$HOME\.vim runtimepath+=$HOME\.vim\after
endif
let s:deinDir    = ! exists('s:deinDir') ? $HOME . '/.vim/dein.vim' : s:deinDir
let &runtimepath = &runtimepath . ',' . s:deinDir . '/repos/github.com/Shougo/dein.vim'
" dein.vim {{{
if dein#load_state(s:deinDir)
    call dein#begin(s:deinDir)
    call dein#add('KazuakiM/neosnippet-snippets')
    call dein#add('KazuakiM/vim-qfstatusline')
    call dein#add('mojako/ref-sources.vim')
    call dein#add('pangloss/vim-javascript')
    call dein#add('Shougo/dein.vim')
    call dein#add('Shougo/neocomplete.vim')
    call dein#add('Shougo/neoinclude.vim')
    call dein#add('Shougo/neosnippet.vim')
    call dein#add('Shougo/vimproc.vim', {'build': 'make'})
    call dein#add('thinca/vim-quickrun')
    call dein#add('thinca/vim-ref')
    call dein#add('vim-scripts/taglist.vim')
    call dein#add('osyo-manga/shabadou.vim')
    call dein#add('osyo-manga/vim-watchdogs')
    call dein#add('mustardamus/jqapi', {'lazy':1})
    call dein#add('tokuhirom/jsref',   {'lazy':1})

    call dein#end()
    call dein#save_state()
endif
"}}}
filetype plugin indent on
syntax enable

syntax highlight

VimでES6のシンタックスハイライト - Qiita がイメージもあってよさ気です。綺麗だとその分もっさりするのでお好みで使用するのが良いと思います。

マニュアル設定

JavaScriptのマニュアルをネットワークを介さずに参照する設定をします。

.vimrc設定

.vimrc
" vim-ref {{{
inoremap <silent><C-k> <C-o>:call<Space>ref#K('normal')<CR><ESC>
nmap <silent>K <Plug>(ref-keyword)
let g:ref_no_default_key_mappings = 1
let g:ref_cache_dir               = $HOME . '/.vim/vim-ref/cache'
let g:ref_detect_filetype         = {
\    'css':        'phpmanual',
\    'html':       ['phpmanual',  'javascript', 'jquery'],
\    'javascript': ['javascript', 'jquery'],
\    'php':        ['phpmanual',  'javascript', 'jquery']
\}
let g:ref_javascript_doc_path = $HOME . '/.vim/dein.vim/repos/github.com/tokuhirom/jsref/htdocs'
let g:ref_jquery_doc_path     = $HOME . '/.vim/dein.vim/repos/github.com/mustardamus/jqapi'
let g:ref_phpmanual_path      = $HOME . '/.vim/vim-ref/php-chunked-xhtml'
let g:ref_use_cache           = 1
let g:ref_use_vimproc         = 1
"}}}

Universal Ctags設定

tagsファイルを適切に生成することでタグジャンプが可能となり、時間短縮が期待できます。

.ctags設定

正規表現の前にJavaScriptを勉強したてで、ケース漏れが多いかと思われます。
コメント頂けると幸いです。

.ctags
--exclude=*min.js
--recurse=yes
--langmap=JavaScript:.js.json.jsx.html

alias設定

.bashrc.local
#.bashrc.localみたいな感じでGitHub管理外でよしなに管理する
tagsJsCmd='ctags --languages=js  -f'
tagsVariable=''
tagsVariable="$tagsVariable cd $HOME/sample1; $tagsJsCmd $HOME/.vim/tags/sample1.tags $HOME/sample1;"
tagsVariable="$tagsVariable cd $HOME/sample2; $tagsJsCmd $HOME/.vim/tags/sample2.tags $HOME/sample2;"
tagsVariable="$tagsVariable cd;"
alias TAGS=$tagsVariable

.vimrc設定

.vimrc
" taglist.vim {{{
"MEMO:$ ctags --list-maps : ctags supported filetype.
"MEMO:$ ctags --list-kinds: ctags tlist setting.
nnoremap <Leader>t :<C-u>Tlist<CR>
let g:tlist_javascript_settings = 'js;o:object;f:function'
let g:tlist_php_settings        = 'php;c:class;f:function;d:constant'
let g:Tlist_Exit_OnlyWindow     = 1
let g:Tlist_Show_One_File       = 1
let g:Tlist_Use_Right_Window    = 1
let g:Tlist_WinWidth            = 25
"}}}

".vimrc.localみたいな感じでGitHub管理外でよしなに管理する
augroup MyTagsAutoCmd
    autocmd!
    autocmd BufNewFile,BufRead $HOME/sample1/*.{js,json,html} setlocal tags=$HOME/.vim/tags/sample1.tags
    autocmd BufNewFile,BufRead $HOME/sample2/*.{js,json,html} setlocal tags=$HOME/.vim/tags/sample2.tags
augroup END

Syntaxチェック, lintチェック, 自動整形設定

はやりのESLintを導入します。

保存時の動作はESLintによる非同期のSyntaxチェックを実施、
Quickrunした場合には--fixオプションを付与した実行となり、自動整形が行われます。
ESLintのオプションなどはhelpを見て適当に設定したため、改良の余地はあるかと思われます。
(2016-02-24:追記start)
ESLintの設定を作りこむと若干Vimが遅くなったので、".eslintrc.js"と".eslintrc.limit.js"に分けました。
保存時は簡易版チェックで処理を行い、Quickrun時はフル版チェックで処理を行い、
"MyEslintFix()"実行時は--fixオプションを付与した実行となるようにしました。

.vimrc
" vim-qfstatusline {{{
function! MyStatuslineSyntax() abort "{{{
    let l:ret = qfstatusline#Update()
    if 0 < len(l:ret)
        if s:lineUpdate is# 0
            highlight StatusLine cterm=NONE gui=NONE ctermfg=Black guifg=Black ctermbg=Magenta guibg=Magenta
            let s:lineUpdate = 1
        endif
    elseif s:lineUpdate is# 1
        highlight StatusLine cterm=NONE gui=NONE ctermfg=Black guifg=Black ctermbg=Grey guibg=Grey
        let s:lineUpdate = 0
    endif
    return l:ret
endfunction "}}}

function! MyStatuslinePaste() abort "{{{
    if &paste is# 1
        return '(paste)'
    endif
    return ''
endfunction "}}}

let g:Qfstatusline#UpdateCmd = function('MyStatuslineSyntax')
set laststatus=2
set cmdheight=1
set statusline=\ %t\ %{MyStatuslinePaste()}\ %m\ %r\ %h\ %w\ %q\ %{MyStatuslineSyntax()}%=%l/%L\ \|\ %Y\ \|\ %{&fileformat}\ \|\ %{&fileencoding}\ 
"}}}

" vim-quickrun {{{
function! EslintFix() abort "{{{
    let l:quickrun_config_backup                  = g:quickrun_config['javascript']
    let g:quickrun_config['javascript']['cmdopt'] = l:quickrun_config_backup['cmdopt'] .' --config '. $HOME .'/.eslintrc.js --fix'
    let g:quickrun_config['javascript']['runner'] = 'system'

    QuickRun

    let g:quickrun_config['javascript'] = l:quickrun_config_backup
endfunction "}}}

nnoremap <Leader>run  :<C-u>QuickRun<CR>
nnoremap <Leader>es   :<C-u>call<Space>EslintFix()<CR>
let s:quickrun_config_javascript = {
\    'command':     'eslint',
\    'cmdopt':      '--cache --cache-location ' . s:envHome . '/.cache/eslint/.eslintcache --format compact --max-warnings 1 --no-color --no-ignore --quiet',
\    'errorformat': '%E%f: line %l\, col %c\, Error - %m,%W%f: line %l\, col %c\, Warning - %m,%-G%.%#',
\    'exec':        '%c %o %s:p'
\}
let g:quickrun_config = {
\    '_': {
\        'hook/close_buffer/enable_empty_data': 1,
\        'hook/close_buffer/enable_failure':    1,
\        'outputter':                           'multi:buffer:quickfix',
\        'outputter/buffer/close_on_empty':     1,
\        'outputter/buffer/split':              ':botright',
\        'runner':                              'vimproc',
\        'runner/vimproc/updatetime':           600
\    },
\    'javascript': {
\        'command':     s:quickrun_config_javascript['command'],
\        'cmdopt':      s:quickrun_config_javascript['cmdopt'] . ' --config ' . s:envHome . '/.eslintrc.js',
\        'errorformat': s:quickrun_config_javascript['errorformat'],
\        'exec':        s:quickrun_config_javascript['exec']
\    },
\    'javascript/watchdogs_checker': {
\        'type': 'watchdogs_checker/javascript'
\    },
\    'watchdogs_checker/_': {
\        'hook/close_quickfix/enable_exit':        1,
\        'hook/back_window/enable_exit':           0,
\        'hook/back_window/priority_exit':         1,
\        'hook/qfstatusline_update/enable_exit':   1,
\        'hook/qfstatusline_update/priority_exit': 2,
\        'outputter/quickfix/open_cmd':            ''
\    },
\    'watchdogs_checker/javascript': {
\        'command':     s:quickrun_config_javascript['command'],
\        'cmdopt':      s:quickrun_config_javascript['cmdopt'] . ' --config ' . s:envHome . '/.eslintrc.limit.js',
\        'errorformat': s:quickrun_config_javascript['errorformat'],
\        'exec':        s:quickrun_config_javascript['exec']
\    }
\}
unlet s:quickrun_config_javascript
"}}}

" shabadou.vim
" vim-watchdogs {{{
let g:watchdogs_check_BufWritePost_enable  = 1
let g:watchdogs_check_BufWritePost_enables = {'vim': 0}
let g:watchdogs_check_CursorHold_enable    = 1
let g:watchdogs_check_CursorHold_enables   = {'vim': 0}
"}}}

補完機能設定

Vim本体にも補完機能はありますが、ここではリッチな補完機能を活用したチップスの紹介をします。

補完するにあたり最も重要となるのはsnippetsになります。
snippetsはコーディング効率に直結する重要な設定のため、
私はベースとなるsnippetsをforkして自分用に最適化した物を使用しています。

.vimrc設定

.vimrc
" neosnippet-snippets
" neosnippet.vim
" neoinclude.vim
" neocomplete.vim {{{
imap <silent><expr><TAB> pumvisible() ? "\<C-n>" : neosnippet#expandable_or_jumpable() ? "\<Plug>(neosnippet_expand_or_jump)" : "\<TAB>"
" neosnippet.vim
smap <silent><expr><TAB>  neosnippet#expandable_or_jumpable() ? "\<Plug>(neosnippet_expand_or_jump)" : "\<TAB>"
nmap <silent><expr><TAB>  neosnippet#expandable_or_jumpable() ? "\<Plug>(neosnippet_expand_or_jump)" : "\<TAB>"
imap <silent><expr><C-x>  MyNeoCompleteCr()
imap <silent><expr><CR>   MyNeoCompleteCr()
nmap <silent><S-TAB> <ESC>a<C-r>=neosnippet#commands#_clear_markers()<CR>
inoremap <expr><C-h> neocomplete#smart_close_popup()."\<C-h>"
inoremap <expr><BS>  neocomplete#smart_close_popup()."\<C-h>"
"neocomplete.vim
let g:neocomplete#auto_completion_start_length = 3
let g:neocomplete#data_directory               = $HOME .'/.vim/neocomplete.vim'
let g:neocomplete#delimiter_patterns           = {
\    'javascript': ['.'],
\    'php':        ['->', '::', '\'],
\    'ruby':       ['::']
\}
let g:neocomplete#enable_at_startup         = 1
let g:neocomplete#enable_auto_close_preview = 1
let g:neocomplete#enable_auto_delimiter     = 1
let g:neocomplete#enable_auto_select        = 0
let g:neocomplete#enable_fuzzy_completion   = 0
let g:neocomplete#enable_smart_case         = 1
let g:neocomplete#keyword_patterns          = {'_': '\h\w*'}
let g:neocomplete#lock_buffer_name_pattern  = '\.log\|.*quickrun.*\|.jax'
let g:neocomplete#max_keyword_width         = 30
let g:neocomplete#max_list                  = 8
let g:neocomplete#min_keyword_length        = 3
let g:neocomplete#sources                   = {
\    '_':          ['neosnippet', 'file',               'buffer'],
\    'css':        ['neosnippet',         'dictionary', 'buffer'],
\    'html':       ['neosnippet', 'file', 'dictionary', 'buffer'],
\    'javascript': ['neosnippet', 'file', 'dictionary', 'buffer'],
\    'php':        ['neosnippet', 'file', 'dictionary', 'buffer']
\}
let g:neocomplete#sources#buffer#cache_limit_size  = 50000
let g:neocomplete#sources#buffer#disabled_pattern  = '\.log\|\.jax'
let g:neocomplete#sources#buffer#max_keyword_width = 30
let g:neocomplete#sources#dictionary#dictionaries  = {
\    '_':          '',
\    'css':        $HOME . '/.vim/dict/css.dict',
\    'html':       $HOME . '/.vim/dict/html.dict',
\    'javascript': $HOME . '/.vim/dict/javascript.dict',
\    'php':        $HOME . '/.vim/dict/php.dict'
\}
let g:neocomplete#use_vimproc = 1
"neoinclude.vim
let g:neoinclude#exts          = {'php': ['php', 'inc', 'tpl']}
let g:neoinclude#max_processes = 5
"neosnippet.vim
let g:neosnippet#data_directory                = $HOME . '/.vim/neosnippet.vim'
let g:neosnippet#disable_runtime_snippets      = {'_' : 1}
let g:neosnippet#enable_snipmate_compatibility = 1
let g:neosnippet#snippets_directory            = $HOME . '/.vim/dein.vim/repos/github.com/KazuakiM/neosnippet-snippets/neosnippets'
function! MyNeoCompleteCr() abort "{{{
    if pumvisible() is# 0
        return "\<CR>X\<C-h>"
    elseif neosnippet#expandable_or_jumpable()
        return "\<Plug>(neosnippet_expand_or_jump)"
    endif
    return "\<Left>\<Right>"
endfunction "}}}
"}}}

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
86