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」を設定します。
" 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設定
" 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を勉強したてで、ケース漏れが多いかと思われます。
コメント頂けると幸いです。
--exclude=*min.js
--recurse=yes
--langmap=JavaScript:.js.json.jsx.html
alias設定
#.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設定
" 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オプションを付与した実行となるようにしました。
" 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設定
" 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 "}}}
"}}}