Quantcast
Channel: Vimタグが付けられた新着記事 - Qiita
Viewing all 5608 articles
Browse latest View live

Vim を使い DarkPowerを得る

$
0
0

力がほしい

Vimを愛用し初めて1年半、そろそろが欲しいと思っていたところ。

Dein.vim

Dein.vim is a dark powered Vim/Neovim plugin manager.

良いものを発見。 まさにdark powerを得るチャンス。

※イメージ →

haya14busa さんのスライドより
https://docs.google.com/presentation/d/14pViuMI_X_PiNwQD8nuGRG72GUqSeKDqoJqjAZWS39U/edit#slide=id.g28fa7f227c_0_221

NeoBundleからDeinに乗り換える。
ついでに、Plugin整理やら追加やらをし、細かく解説していきます。

Deinを使う上での構成やら基本的なことはここを参照。

構成(~/以下)

  • .vimrc
  • .vim
    • rc
      • dein.toml
      • dein_lazy.toml

簡単な設定

白紙の.vimrcにこれを書いていきます。

setencoding=utf-8scriptencoding utf-8" 保存時の文字コードsetfileencoding=utf-8" 読み込み時の文字コードの自動判別. 左側が優先されるsetfileencodings=ucs-boms,utf-8,euc-jp,cp932" 改行コードの自動判別. 左側が優先されるsetfileformats=unix,dos,mac" □や○文字が崩れる問題を解決"setambiwidth=double"行数を表示するsetnumbersetbackspace=indent,eol,start"ヤンクした時にクリップボードにコピーするsetclipboard=unnamed,autoselect" タブ入力を複数の空白入力に置き換えるsetexpandtab" 画面上でタブ文字が占める幅settabstop=4" 連続した空白に対してタブキーやバックスペースキーでカーソルが動く幅setsofttabstop=4" 改行時に前の行のインデントを継続するsetautoindent" 改行時に前の行の構文をチェックし次の行のインデントを増減するsetsmartindent" smartindentで増減する幅"setshiftwidth=4" インクリメンタルサーチ. 1文字入力毎に検索を行うsetincsearch" 検索パターンに大文字小文字を区別しないsetignorecase" 検索パターンに大文字を含んでいたら大文字小文字を区別するsetsmartcase" 検索結果をハイライト"sethlsearch" 不可視文字を可視化(タブが「▸-」と表示される)setlistlistchars=tab:\▸\-" カーソルの左右移動で行末から次の行の行頭への移動が可能になるsetwhichwrap=b,s,h,l,<,>,[,],~" カーソルラインをハイライト"setcursorline

Plugins

初期設定

:.vimrc" dein.vim がなければ github から落としてくるif&runtimepath!~# '/dein.vim'if!isdirectory(s:dein_repo_dir)
    execute '!git clone https://github.com/Shougo/dein.vim' s:dein_repo_direndif
  execute 'set runtimepath^=' . fnamemodify(s:dein_repo_dir,':p')endif" 設定開始if dein#load_state(s:dein_dir)call dein#begin(s:dein_dir)  " プラグインリストを収めた TOML ファイル  " 予め TOML ファイル(後述)を用意しておくletg:rc_dir    = expand('~/.vim/rc')let s:toml      =g:rc_dir . '/dein.toml'let s:lazy_toml =g:rc_dir . '/dein_lazy.toml'  " TOML を読み込み、キャッシュしておくcall dein#load_toml(s:toml,      {'lazy': 0})call dein#load_toml(s:lazy_toml, {'lazy': 1})  " 設定終了call dein#end()call dein#save_state()endif" もし、未インストールものものがあったらインストールif dein#check_install()call dein#install()endif
:.dein.toml
# 基本は github.comのレポジトリーを指定するだけ
[[plugins]]
repo ='Shougo/dein.vim'

# git clone 後、実行すべきコマンドがある場合はこんな感じ
[[plugins]]
repo ='Shougo/vimproc.vim'
hook_post_update ='''if dein#util#_is_windows()let cmd ='tools\\update-dll-mingw'elseif dein#util#_is_cygwin()let cmd ='make -f make_cygwin.mak'elseif executable('gmake')let cmd ='gmake'elselet cmd ='make'endifletg:dein#plugin.build = cmd'''

これで準備完了!

vim-airline/vim-airline

:dein.toml
[[plugins]]
repo    ='vim-airline/vim-airline'
depends = ['vim-airline-themes']

[[plugins]]
repo ='vim-airline/vim-airline-themes'
:.vimrcletg:airline_theme ='molokai'

ステータスラインのテーマを変更する。

GitHub

tomasr/molokai

:dein.toml
[[plugins]]
repo ='tomasr/molokai'

コードの色をいい感じにしてくれる。
GitHub

スクリーンショット 2017-12-07 17.23.09.png

Shougo/vimfiler

:dein.toml
#vimfilerを使うために必要
[[plugins]]
repo ='Shougo/unite.vim'

#ディレクトリ表示
[[plugins]]
repo ='Shougo/vimfiler'

ディレクトリを表示し、移動が出来る。

https://github.com/Shougo/vimfiler.vim

:.vimrc:letg:vimfiler_as_default_explorer =1

をしておけばVim起動時に毎回起動する。

Townk/vim-autoclose

:dein.toml
[[plugins]]
repo ='Townk/vim-autoclose'

括弧補完
"を打つと ""に自動補完してくれる。
https://github.com/Townk/vim-autoclose

scrooloose/syntastic

:dein.toml
[[plugins]]
repo ='scrooloose/syntastic'

syntax のチェックをしてくれる。
エラーの箇所に >>が入るためわかりやすい。

https://github.com/vim-syntastic/syntastic

Yggdroot/indentLine

:dein.toml
[[plugins]]
repo ='Yggdroot/indentLine'
:.vimrcletg:indentLine_char ='¦'

インデントを可視化する

3__vim.png

https://github.com/Yggdroot/indentLine

bronson/vim-trailing-whitespace

:dein.toml
[[plugins]]
repo ='bronson/vim-trailing-whitespace'

末尾の全角と半角の空白文字を赤くハイライト
:FixWhitespace で全て削除できる。
vimwhite3.gif

https://github.com/bronson/vim-trailing-whitespace

tpope/vim-fugitive airblade/vim-gitgutter

:dein.toml
[[plugins]]
repo ='tpope/vim-fugitive'
[[plugins]]
repo ='airblade/vim-gitgutter'

git関連のプラグイン
gitの便利操作がvimで出来る
また、変更箇所に ~
追加箇所に +
削除箇所に -
と表示される。
お勧めは Gblame
誰のコミットかわかる。
vimgit.gif

vimgit2.gif

https://github.com/tpope/vim-fugitive
https://github.com/airblade/vim-gitgutter

junegunn/vim-easy-align

:dein.toml

[[plugins]]
repo ='junegunn/vim-easy-align'
:.vimrc"enterで整形設定に行くようにする
vmap <Enter><Plug>(EasyAlign)

細かい整形が出来るようなる
vimeasyalign2.gif

https://github.com/junegunn/vim-easy-align

整形箇所を選択→enter→ = → enter で整形される。
※ = 以外でも可能

ctrlpvim/ctrlp.vim

:dein.toml
[[plugins]]
repo ='ctrlpvim/ctrlp.vim'

ctrl+p でファイルあいまい検索ができる

https://github.com/ctrlpvim/ctrlp.vim
vimctrlp2.gif

vimctrlp3.gif

ctrl + tで新しいタブにてファイルを開ける。

Shougo/neocomplcache,neosnippet,neosnippet-snippets

:dein.toml
#入力補完
[[plugins]]
repo ='Shougo/neocomplcache'

# スニペットの補完機能
[[plugins]]
repo ='Shougo/neosnippet'

# スニペット集
[[plugins]]
repo ='Shougo/neosnippet-snippets'
.vimrc"====================neocomplcache====================" ~Disable AutoComplPop. neocomplcashe~letg:acp_enableAtStartup =0" Use neocomplcache.letg:neocomplcache_enable_at_startup =1" Use smartcase.letg:neocomplcache_enable_smart_case =1" Set minimum syntax keyword length.letg:neocomplcache_min_syntax_length =3letg:neocomplcache_lock_buffer_name_pattern ='\*ku\*'" Define dictionary.letg:neocomplcache_dictionary_filetype_lists = {
    \ 'default' : ''
    \ }" Plugin key-mappings.inoremap<expr><C-g>     neocomplcache#undo_completion()inoremap<expr><C-l>     neocomplcache#complete_common_string()" Recommended key-mappings." <CR>: close popup and save indent.inoremap<silent><CR><C-r>=<SID>my_cr_function()<CR>function! s:my_cr_function()return neocomplcache#smart_close_popup() . "\<CR>"endfunction" <TAB>: completion.inoremap<expr><TAB>  pumvisible() ? "\<C-n>" : "\<TAB>"" <C-h>, <BS>: close popup and delete backword char.inoremap<expr><C-h> neocomplcache#smart_close_popup()."\<C-h>"inoremap<expr><BS> neocomplcache#smart_close_popup()."\<C-h>"inoremap<expr><C-y>  neocomplcache#close_popup()inoremap<expr><C-e>  neocomplcache#cancel_popup()"~neocomplecas~"====================neosnippet====================" Plugin key-mappings." Note: It must be "imap" and "smap".  It uses <Plug> mappings.
imap <C-k><Plug>(neosnippet_expand_or_jump)smap<C-k><Plug>(neosnippet_expand_or_jump)
xmap <C-k><Plug>(neosnippet_expand_target)" SuperTab like snippets behavior." Note: It must be "imap" and "smap".  It uses <Plug> mappings.
imap <C-k><Plug>(neosnippet_expand_or_jump)"imap <expr><TAB>" \ pumvisible() ? "\<C-n>" :" \ neosnippet#expandable_or_jumpable() ?" \    "\<Plug>(neosnippet_expand_or_jump)" : "\<TAB>"smap<expr><TAB> neosnippet#expandable_or_jumpable() ?
\ "\<Plug>(neosnippet_expand_or_jump)" : "\<TAB>"" For conceal markers.if has('conceal')setconceallevel=2concealcursor=nivendif" ~ファイルタイプ毎 & gitリポジトリ毎にtagsの読み込みpathを変える~function! ReadTags(type)try
        execute "set tags=".$HOME."/dotfiles/tags_files/".
              \ system("cd " . expand('%:p:h') . "; basename `git rev-parse --show-toplevel` | tr -d '\n'").
              \ "/" . a:type . "_tags"catch
        execute "set tags=./tags/" . a:type . "_tags;"endtryendfunction

augroup TagsAutoCmd
    autocmd!
    autocmd BufEnter * :call ReadTags(&filetype)
augroup END

vimneo.gif

ctrl + kで次の入力するところに飛べる(便利だ・・・)

https://github.com/Shougo/neocomplcache.vim
https://github.com/Shougo/neosnippet.vim
https://github.com/Shougo/neosnippet-snippets

cohama/lexima.vim

dein.toml
[[plugins]]
repo ='cohama/lexima.vim'

閉じ括弧補完

https://github.com/cohama/lexima.vim

osyo-manga/vim-anzu

:dein.toml
[[plugins]]
repo ='osyo-manga/vim-anzu'
:.vimrc
nmap n<Plug>(anzu-n-with-echo)
nmap N <Plug>(anzu-N-with-echo)
nmap * <Plug>(anzu-star-with-echo)
nmap # <Plug>(anzu-sharp-with-echo)" clear status
nmap <Esc><Esc><Plug>(anzu-clear-search-status)" statuslinesetstatusline=%{anzu#search_status()}

検索結果の件数を表示

https://github.com/osyo-manga/vim-anzu

rhysd/clever-f.vim

:dein.toml
[[plugins]]
repo ='rhysd/clever-f.vim'

fで検索後移動できるようにする
ハイライトされるのがホント便利

https://github.com/rhysd/clever-f.vim

vim-operator-flashy

:dein.toml
[[plugins]]
repo ='kana/vim-operator-user'

[[plugins]]
repo ='haya14busa/vim-operator-flashy'
:.vimrc
map y<Plug>(operator-flashy)
nmap Y <Plug>(operator-flashy)$

コピーしたところが一瞬ハイライトされる

https://github.com/haya14busa/vim-operator-flashy

mattn/emmet-vim

[[plugins]]
repo = 'mattn/emmet-vim'
:.vimrcletg:user_emmet_leader_key='<C-t>'


vimhtml.gif

html補完

ctrl + t , で展開されるように設定

majutsushi/tagbar

[[plugins]]
repo ='majutsushi/tagbar'

vimtagbar.gif

tagbarがでて関数やclass一覧などがみえる。

まとめ

dein.toml

# 基本は github.comのレポジトリーを指定するだけ
[[plugins]]
repo ='Shougo/dein.vim'

# git clone 後、実行すべきコマンドがある場合はこんな感じ
[[plugins]]
repo ='Shougo/vimproc.vim'
hook_post_update ='''if dein#util#_is_windows()let cmd ='tools\\update-dll-mingw'elseif dein#util#_is_cygwin()let cmd ='make -f make_cygwin.mak'elseif executable('gmake')let cmd ='gmake'elselet cmd ='make'endifletg:dein#plugin.build = cmd'''
#ステータスラインのテーマ
[[plugins]]
repo    ='vim-airline/vim-airline'
depends = ['vim-airline-themes']

#ステータスラインのテーマ
[[plugins]]
repo ='vim-airline/vim-airline-themes'

#コードの色
[[plugins]]
repo ='tomasr/molokai'

#vimfilerを使うために必要
[[plugins]]
repo ='Shougo/unite.vim'

#ディレクトリ表示
[[plugins]]
repo ='Shougo/vimfiler'

#ディレクトリ表示
[[plugins]]
repo ='scrooloose/nerdtree'

#括弧補完
[[plugins]]
repo ='Townk/vim-autoclose'

#syntaxcheck
[[plugins]]
repo ='scrooloose/syntastic'

# インデントの可視化 上手く機能してない?
[[plugins]]
repo ='Yggdroot/indentLine'

# インデントの可視化
[[plugins]]
repo ='nathanaelkane/vim-indent-guides'

# 末尾の全角と半角の空白文字を赤くハイライト
[[plugins]]
repo ='bronson/vim-trailing-whitespace'

[[plugins]]
repo ='szw/vim-tags'

#gitの便利操作がvimで出来る Gblameなど
[[plugins]]
repo ='tpope/vim-fugitive'

#gitの変更箇所を左側に表示してくれる
[[plugins]]
repo ='airblade/vim-gitgutter'

#tagbarがでる関数一覧などが出る
[[plugins]]
repo ='majutsushi/tagbar'

#細かい整形が出来るようなる
[[plugins]]
repo ='junegunn/vim-easy-align'

#ctrl+pでファイルあいまい検索ができる
[[plugins]]
repo ='ctrlpvim/ctrlp.vim'

#入力補完
[[plugins]]
repo ='Shougo/neocomplcache'

# スニペットの補完機能
[[plugins]]
repo ='Shougo/neosnippet'

# スニペット集
[[plugins]]
repo ='Shougo/neosnippet-snippets'

#閉じ括弧補完
[[plugins]]
repo ='cohama/lexima.vim'

#検索結果の件数を表示
[[plugins]]
repo ='osyo-manga/vim-anzu'

#fで検索後移動できるようにする
[[plugins]]
repo ='rhysd/clever-f.vim'

[[plugins]]
repo ='kana/vim-operator-user'

#コピーしたところが一瞬ハイライトされる 入らなかった
[[plugins]]
repo ='haya14busa/vim-operator-flashy'

#html補完
[[plugins]]
repo ='mattn/emmet-vim'

.vimrc

setencoding=utf-8scriptencoding utf-8" 保存時の文字コードsetfileencoding=utf-8" 読み込み時の文字コードの自動判別. 左側が優先されるsetfileencodings=ucs-boms,utf-8,euc-jp,cp932" 改行コードの自動判別. 左側が優先されるsetfileformats=unix,dos,mac" □や○文字が崩れる問題を解決"setambiwidth=doublesetnumbersetbackspace=indent,eol,start"クリップボードにコピーするsetclipboard=unnamed,autoselect" タブ入力を複数の空白入力に置き換えるsetexpandtab" 画面上でタブ文字が占める幅settabstop=4" 連続した空白に対してタブキーやバックスペースキーでカーソルが動く幅setsofttabstop=4" 改行時に前の行のインデントを継続するsetautoindent" 改行時に前の行の構文をチェックし次の行のインデントを増減するsetsmartindent" smartindentで増減する幅"setshiftwidth=4" インクリメンタルサーチ. 1文字入力毎に検索を行うsetincsearch" 検索パターンに大文字小文字を区別しないsetignorecase" 検索パターンに大文字を含んでいたら大文字小文字を区別するsetsmartcase" 検索結果をハイライト"sethlsearch" 不可視文字を可視化(タブが「▸-」と表示される)setlistlistchars=tab:\▸\-" カーソルの左右移動で行末から次の行の行頭への移動が可能になるsetwhichwrap=b,s,h,l,<,>,[,],~" カーソルラインをハイライト"setcursorline" 行が折り返し表示されていた場合、行単位ではなく表示行単位でカーソルを移動するnnoremapj gjnnoremapk gknnoremap<down> gjnnoremap<up> gk" tagsジャンプの時に複数ある時は一覧表示"nnoremap <C-]> g<C-]>nnoremap<C-h> :vsp<CR> :exe("tjump ".expand('<cword>'))<CR>nnoremap<C-k> :split<CR> :exe("tjump ".expand('<cword>'))<CR>" 括弧の対応関係を一瞬表示するsetshowmatch
source $VIMRUNTIME/macros/matchit.vim" Vimの「%」を拡張する "" コマンドモードの補完setwildmenu" 保存するコマンド履歴の数  "sethistory=5000"=================dein================" プラグインが実際にインストールされるディレクトリlet s:dein_dir = expand('~/.cache/dein')" dein.vim 本体let s:dein_repo_dir = s:dein_dir . '/repos/github.com/Shougo/dein.vim'" dein.vim がなければ github から落としてくるif&runtimepath!~# '/dein.vim'if!isdirectory(s:dein_repo_dir)
    execute '!git clone https://github.com/Shougo/dein.vim' s:dein_repo_direndif
  execute 'set runtimepath^=' . fnamemodify(s:dein_repo_dir,':p')endif" 設定開始if dein#load_state(s:dein_dir)call dein#begin(s:dein_dir)  " プラグインリストを収めた TOML ファイル  " 予め TOML ファイル(後述)を用意しておくletg:rc_dir    = expand('~/.vim/rc')let s:toml      =g:rc_dir . '/dein.toml'let s:lazy_toml =g:rc_dir . '/dein_lazy.toml'  " TOML を読み込み、キャッシュしておくcall dein#load_toml(s:toml,      {'lazy': 0})call dein#load_toml(s:lazy_toml, {'lazy': 1})  " 設定終了call dein#end()call dein#save_state()endif" もし、未インストールものものがあったらインストールif dein#check_install()call dein#install()endif"色を付けるsyntaxoncolorscheme molokai"==============プラグイン関係の設定==============letg:airline_theme ='molokai'"====================gitgutter===================="変更箇所のハイライトletg:gitgutter_highlight_lines =0"====================junegunn/vim-easy-align===================="enterで整形設定に行くようにする
vmap <Enter><Plug>(EasyAlign)"====================neocomplcache====================" ~Disable AutoComplPop. neocomplcashe~letg:acp_enableAtStartup =0" Use neocomplcache.letg:neocomplcache_enable_at_startup =1" Use smartcase.letg:neocomplcache_enable_smart_case =1" Set minimum syntax keyword length.letg:neocomplcache_min_syntax_length =3letg:neocomplcache_lock_buffer_name_pattern ='\*ku\*'" Define dictionary.letg:neocomplcache_dictionary_filetype_lists = {
    \ 'default' : ''
    \ }" Plugin key-mappings.inoremap<expr><C-g>     neocomplcache#undo_completion()inoremap<expr><C-l>     neocomplcache#complete_common_string()" Recommended key-mappings." <CR>: close popup and save indent.inoremap<silent><CR><C-r>=<SID>my_cr_function()<CR>function! s:my_cr_function()return neocomplcache#smart_close_popup() . "\<CR>"endfunction" <TAB>: completion.inoremap<expr><TAB>  pumvisible() ? "\<C-n>" : "\<TAB>"" <C-h>, <BS>: close popup and delete backword char.inoremap<expr><C-h> neocomplcache#smart_close_popup()."\<C-h>"inoremap<expr><BS> neocomplcache#smart_close_popup()."\<C-h>"inoremap<expr><C-y>  neocomplcache#close_popup()inoremap<expr><C-e>  neocomplcache#cancel_popup()"~neocomplecas~"====================neosnippet====================" Plugin key-mappings." Note: It must be "imap" and "smap".  It uses <Plug> mappings.
imap <C-k><Plug>(neosnippet_expand_or_jump)smap<C-k><Plug>(neosnippet_expand_or_jump)
xmap <C-k><Plug>(neosnippet_expand_target)" SuperTab like snippets behavior." Note: It must be "imap" and "smap".  It uses <Plug> mappings.
imap <C-k><Plug>(neosnippet_expand_or_jump)"imap <expr><TAB>" \ pumvisible() ? "\<C-n>" :" \ neosnippet#expandable_or_jumpable() ?" \    "\<Plug>(neosnippet_expand_or_jump)" : "\<TAB>"smap<expr><TAB> neosnippet#expandable_or_jumpable() ?
\ "\<Plug>(neosnippet_expand_or_jump)" : "\<TAB>"" For conceal markers.if has('conceal')setconceallevel=2concealcursor=nivendif" ~ファイルタイプ毎 & gitリポジトリ毎にtagsの読み込みpathを変える~function! ReadTags(type)try
        execute "set tags=".$HOME."/dotfiles/tags_files/".
              \ system("cd " . expand('%:p:h') . "; basename `git rev-parse --show-toplevel` | tr -d '\n'").
              \ "/" . a:type . "_tags"catch
        execute "set tags=./tags/" . a:type . "_tags;"endtryendfunction

augroup TagsAutoCmd
    autocmd!
    autocmd BufEnter * :call ReadTags(&filetype)
augroup END"====================osyo-manga/vim-anzu====================" mapping
nmap n<Plug>(anzu-n-with-echo)
nmap N <Plug>(anzu-N-with-echo)
nmap * <Plug>(anzu-star-with-echo)
nmap # <Plug>(anzu-sharp-with-echo)" clear status
nmap <Esc><Esc><Plug>(anzu-clear-search-status)" statuslinesetstatusline=%{anzu#search_status()}" ====================indentLine====================letg:indentLine_char ='¦'"use ¦, ┆ or │"====================haya14busa/vim-operator-flashy====================
map y<Plug>(operator-flashy)
nmap Y <Plug>(operator-flashy)$"====================EmmetHmtl"====================letg:user_emmet_leader_key='<C-t>'

これで皆さんも Dark Powerを得れたのではないでしょうか?


リモートサーバでVimを使いたくない人が入れておくべきVSCodeの拡張機能 ~ EC2を例に ~

$
0
0

この記事はVisual Studio Code Advent Calendar 2017の10日目の記事です

早速ですが、皆さんはリモートサーバのファイルをいじる時、どんなエディタを使っていますか?

普段はIDEを使ってるけど、仕方なくVimで、、、という人も多いと思います(自分です)
Vimはいつか使いこなせるように、、、と思いつつ、まだまだコマンドとか覚えきれてないのが現実です、、、

しかし、1つの拡張機能と簡単な設定をするだけで、みんな大好きVSCodeでもファイルの編集をすることができます!

今回は、EC2インスタンス上のファイルをVSCodeで編集できるようにしてみましょう〜

最終的にできること

  • VSCode内のターミナルから、EC2インスタンスにsshで入り、
  • EC2上のファイルをローカルのVSCodeと同期し、そのまま編集、保存する
  • ローカルでの変更がEC2上のファイルにも反映されている!

必要なもの、設定

リモートサーバ側(EC2)

  • rmateのインストール
  • ポートを開ける
    • 今回はAWS上でのセキュリティグループの設定

ローカル側(VSCode)

  • Remote VSCode(VSCodeの拡張機能)のインストール
  • sshのconfigの設定
    • Remote VSCodeで指定したポートにsshで入るため

まずはローカル側の設定

あらかじめSSHのconfigを設定しておく

楽にリモート側へ入れるように、sshのcondigの設定をあらかじめしておく

~/.ssh/configで設定できます


Host hoge
  HostName hoge.jp //EC2インスタンスのグローバルIP
  User ec2-user
  IdentityFile ~/hoge //秘密鍵が置かれているところ
  IdentitiesOnly yes
  ForwardAgent yes
  RemoteForward 52698127.0.0.1:52698

最後の2行が大事。あとはよしなに。

VSCodeに拡張機能を入れる(Remote VSCode)

名前をそのまま検索して、インストールすればOK
設定を確認する(settings)

// Port number to use for connection.
    "remote.port": 52698,

// Launch the server on start up.
    "remote.onstartup": true

remote.onstartupはtrueでもfalseでもどちらでも良い
起動した時に、Remote VSCodeが立ち上がっているかどうか。

Remote VSCodeを立ち上げる

  • F1でcommand paletteを表示
  • Remote:Start serverでRemote VSCodeのサーバを起動

これでローカル側の準備は完了です!

次はリモートサーバ側の設定

セキュリティグループの設定

Remote VSCodeはポート52698を使用するので、あらかじめ開けておく(インバウンド、アウトバウンド両方)

  • タイプ:カスタムTCPルール
  • プロトコル:TCP
  • ポート範囲:52698
  • ソース:許可したいIPアドレス

みたいな感じでOK
このセキュリティグループをEC2インスタンスに設定しておく

インスタンスにログインし、rmateをインストールする

VSCodeの統合ターミナルから、以下のコマンドでリモートサーバへ入りましょう

ssh hoge

設定がうまくいってれば、これで入れればとりあえずOK

ダメだった場合は、ローカルで設定したsshのconfig、もしくはEC2インスタンスのセキュリティグループを見直しましょう

リモートに入れたら、パスが通ってるところに、rmateをインストールします

wget -O /usr/bin/rmate https://raw.github.com/aurora/rmate/master/rmate
chmod a+x /usr/bin/rmate

これで全ての準備がOK

実際にリモートサーバのファイルをローカルのVSCodeに同期してみる

VSCodeでいじりたいファイルを、以下のコマンドでローカルに持ってくることができる

rmate index.html

VSCodeにファイルが同期されれば、バッチグーです。

そのままファイルを編集、保存すると、リモート側のファイルも変更が加わっています
別のファイルを変更する際は、上記のコマンドで改めてVSCodeと同期しましょう

あとは開発を進めていくだけですね!

まとめ

  • Remote VScodeを使えば、リモートサーバでもVimを使わなくていい
  • 他のIDEでも似たような機能はあるので、色々調べてみましょう
  • でも本当はVimを使いこなせたほうがいい
  • Vimのコマンドをちゃんと覚えて、IDEに頼らないようにしましょう

参考資料

今年作ったプラグイン、使って良かったプラグイン

$
0
0

Vim2 Advent Calendar 2017の10日目の記事です!
9日目は @misato8310さんの Windowsでdein導入したい&&オレオレvimrcのお話でした。私もそのうち.vimrc晒すとかやってみようかな…!

今回、私は『今年作ったプラグイン、使って良かったプラグイン』という内容でお送りさせて頂きます。

作ったプラグイン

まずは作ったプラグインをご紹介します。
今年は初めて自分でVimプラグインを作って公開までできました。

CCSpellCheck.vim

Github
https://github.com/kmszk/CCSpellCheck.vim

これはスペルチェックプラグインです。
いつもコードレビューでTypoを指摘されていた私が、脱Typoを目指すためだけに作ったプラグインで、キャメルケースを考慮したスペルチェックができます。

利用イメージ:CaseをCeseとtypoした場合
ccs.png

内部的にはVimの機能だけで作られているため、Vimの本来のspellチェックや修正を使うことができます。処理的にはファイル内のキャメルケースの単語を抜き出し、正規表現で単語毎に分けてVimのspellの機能でチェックする形になります。

とりあえず、自分はこれでTypoが無くなり、コードレビューで指摘されることも無くなりました。なければ自作することができるのがVimの良いところですね。

Vimでキャメルケースのスペルチェックをするプラグインを作った 〜 CCSpellCheck.vim 〜

カラースキーム

Vimconf2017のcocoponさんの発表に影響を受けて、Vimのカラースキームを作ってみました。(※ただ、どちらも言語毎の調整まではしていません。)

skyhawk

skyhawk_ss.png

Vimconf2017のcocoponさんの発表ではicebergは『氷山』がテーマでしたが、今回自作したskyhawkはおおよそ下記のようなイメージで作成しました。

skyhawk2.jpg
※ 使用色は、空の青系統色(Statement、Identifier、Operator、Typeなど)、機体の色(この写真では山吹色?)(String、Booleanなど)、差し色のオレンジ(Special,Keywordなど)と黄色(SpecialCharなど)…そして色が足りなくなったので、地上の緑のイメージの緑系統色(Function)など。

skyknight

skyknightはskyhawkをベースにもう少し色を減らし、スッキリとした印象です。
skyknight_ss.png

※イメージ
300px-EF-10B_VMCJ-1.jpg
スッキリとした配色のデザインと、差し色の赤が特徴的だったので使っています。

最近は自分でもよくskyknightを使っています。

使って良かったプラグイン

今年入れて、個人的に人に勧めたくなるほど良かったプラグインは…

  • fzf (junegunn/fzf.vim)
  • junegunn/vim-easy-align
  • w0rp/ale (以前はvim-syntastic/syntasticを使用)
  • Shougo/deoplete.nvim (以前はいろいろ試していたが、満足できないものが多く…)

辺りですね。

fzf

https://github.com/junegunn/fzf
https://github.com/junegunn/fzf.vim

自分はzsh側でfzfを使っていて、Vimで呼ぶようにしているのですが、fzfの製作者からプラグインも提供されていて、多分これを使ってもほぼ同じかと思います。

Vimだけではなくzshでもかなりお世話になっています。というわけで自分はVimとzshでの使い方の記事も書いています。
https://qiita.com/kmszk/items/aa9920f07487559c0c7e#vim%E3%81%A7%E4%BD%BF%E3%81%86

Vimで選択的インターフェースとなるとUniteやCtrl-pになるかと思うのですが、fzfはgolangで書かれているので実行スピードとしては申し分なく、大きめのプロジェクトでもガツガツ候補を上げてもらえます。

自分はVimでは、ファイル検索、MRUのファイル選択、バッファのファイル選択辺りでよく使っています。
大体やりたいことはfzfのGithubのvimのページにまとまっています。
https://github.com/junegunn/fzf/wiki/Examples-(vim)

あと先週、fzfをつかってtagを検索して記述箇所を開くようなものを作ってみました。

.vimrc
" 呼び出し元let s:tags_file_full_path ='.tagファイルのパス'call s:fzf_tag(s:tags_file_full_path)" 呼び出し先function! s:fzf_tag(fzf_tags_file_full_path)let s:fzf_tags_file_full_path =a:fzf_tags_file_full_path    " https://stackoverflow.com/questions/11532157/unix-removing-duplicate-lines-without-sorting    " sort -u の代わりに awk '!x[$0]++' を使うことで行毎の処理を維持    " awk '!x[$1]++ {print $1}' は awk {'print $1'} | awk '!x[$0]++'と一緒 
    command! FZFTagList call fzf#run({
                \ 'source': "cat " . s:fzf_tags_file_full_path . " | awk '!x[$1]++ {print $1}' |  grep -v '^[!\(\=]'",
                \ 'sink': 'tag',
                \ 'down':    '40%'})endfunction

自分はこの関数の呼び出し元はPlugで管理しているszw/vim-tagsの記述のところにある為、tagファイルのパスをそこから引数で渡しています。

唐突に現れたawk '!x[$1]++ {print $1}'の部分ですが、やりたいことはつまるところawk {'print $1'} | sort -uです。sort -uではすべて読み込んでからsortし、結果を出力するためボトルネックになっていたところを、stackoverflowの受け売りでawkに書き換えてみたところ!x[$1]++sort -u相当のことをすることで行毎の処理を維持することができたという感じです。

途中のgrep -v '^[!\(\=]とかで要らなさそうなやつを適当に消しているのが自分の中でまだ消化不良感があります。(なんか他にもでてきそう…)

(※ shell部分はそのままではwindowsでは動かないかと思いますのでご了承を…!)

junegunn/vim-easy-align

https://github.com/junegunn/vim-easy-align

これは変数に代入をまとめて書いているブロックの『=』をきれいに揃えたりするときによく使います。

自分は ga*=とか覚えなさそうなので、選択した範囲をスペースを打つだけで整うようにしていて、とりあえず自分はこれで満足です。

" 選んだ範囲で整える
xmap <Space> <Plug>(EasyAlign)*<Space>
xmap ,  <Plug>(EasyAlign)*,
xmap = <Plug>(EasyAlign)*=

w0rp/ale

https://github.com/w0rp/ale

自分の場合、業務がPHP使用なのですが、phpmdやらphpcdやら通常の言語のチェック+αを走らせる目的で入れたような気がします。とにかくカバーしている言語も多く、速度的にも満足できます。

自分はairlineは重く感じるのでitchyny/lightline.vimを使っているのですが、maximbaz/lightline-aleを使うことによってステータスライン上にもエラー件数を出していたりします。

maximbaz/lightline-ale
https://github.com/maximbaz/lightline-ale

Shougo/deoplete.nvim

https://github.com/Shougo/deoplete.nvim

自分はMacでVim8を使っています。
名前にnvimとなってますが、vim8なら最近使えるようになりました。

業務がPHP使用なので型が明示的ではなく(-> なのでコメントで補足したりするとIDEが読んでくれたりします)、今までいろいろな補完のプラグインを使いましたが、検索が始まって返ってこないものや、欲しい結果が得られない物が多い中、deopleteは今のところ一番良い結果が帰ってきます。

vim8で対応されたのが11月の初めのほうで、まだまだ使い始めたばかりなので引き続き使わせていただきます。

まとめ

作ったもの&使ったものということで、ちょっと記事が長くなってしまいましたが、来年はもう少しよいプラグインが作りたいという抱負で行きたいです。

初心者でもわかるVim設定ファイルの読み方

$
0
0

エイチームライフスタイル アドベントカレンダー2017の11日目は、株式会社エイチームライフスタイルのWebエンジニア@matsu06が担当します。
今回は表題の通り、Vimの設定ファイルについて書いてみたいと思います。

対象者

  • Vimの操作にようやく慣れてきたかなという方

ゴール

  • Web上にある偉大な先人たちのVim設定ファイルについて、なんとなく読めるようになる

vimrcとは

Vimの設定はvimrcというファイルに記述して行いますが、このvimrcとは一体なにものでしょうか?
答えは、Vimが起動時に自動的に実行するvim scriptです。
設定をスクリプトで行うというとすごく難しそうですが、
新たにvim scriptをマスターする必要はなく、よく使うものは限られていますので、
今回はvimrcを記述する上でよく見かけるような気がする内容を説明させていただきます。

オプション

まずvimrcで一番見かけるのがオプションになると思います。
オプションの中にはローカルな値を持てるものがあり、
それらのオプションは特定のバッファやウィンドウ内に限定されたオプション値を持つことができます。
オプションを設定するには :setコマンドを用い、ローカルなオプションを設定するには:setlocal コマンドを用います。
なお、どのようなオプションがあるかは:help option-listで確認できます。

setlocal number "行番号を表示するオプション

また、&を接頭辞にすることで、オプションを変数のように扱えます。

let &tabstop = 4 "タブ幅をスペース4つ分にする

キーマッピング

キーマッピングには大きく分けてmapとnoremapがあり、

  • mapは再マッピングを行う
  • noremapは再マッピングを行わない

という違いがあります。
ぱっと見ただけだと使い分けが難しいと思いますが、いったんは

  • 他のキーマッピングでも使い回したいものはmapで定義
  • それ以外のものはnoremapで定義

と考えるのが良いと思います。
また、キーマッピングはそれぞれのモードで独立して定義でき、どのモードのキーマッピングかは最初の文字で判別可能です。

接頭辞ノーマルモードインサートモードビジュアルモード
なし-
n--
i--

上記の表の○となっている部分が定義されるモードになりますが、他にも多くのモード別のマッピングが存在します。

nnoremap + <C-a> "ノーマルモードの場合、+でインクリメントできるようにするできるようにする
nnoremap - <C-x> "ノーマルモードの場合、-でデクリメントできるようにするできるようにする

キーマッピングを確認したい場合は、以下のようなコマンドでそれぞれ確認できます。

"デフォルトのキーバインドの場合
:help index
"自分で設定したキーバインドの場合
:map " すべて確認
:imap " インサートモードだけ
:nmap " ノーマルモードだけ

なお、キーマッピングにはいくつかのオプションを使用することもできます。
代表的なものに<silent>があり、これは実行するコマンドがコマンドラインに表示されないようにするものです。

変数

設定ファイル内では変数が使用できますが、特に宣言は必要なく、次のようにletコマンドを用いれば、その場で変数を作成できます。
なお、存在しない変数を使おうとするとエラーになります。

let hoge = 'fuga'

また、変数は接頭辞によってスコープが決定することができ、以下のようなものが存在します。

接頭辞スコープ
g:グローバル
l:ローカル
b:バッファローカル
w:ウインドウローカル
t:タブローカル
s:スクリプトローカル
v:組み込み変数

接頭辞を省略した場合のスコープは、組み込み変数に存在する場合はv:、関数内の場合はl:、それ以外の場合はg:という順番に適用されます。

変数を削除する場合は、unletコマンドを用いると指定した変数を未定義にできますが、存在しないものを指定するとエラーになるので、その場合はunlet!コマンドを用います。

unlet! hogehoge "hogehogeという変数を削除(定義されていなくてもエラーにならない)

変数はさまざまなプラグインの設定や内部の制御に使用されています。
例えば、バージョン6以降のVimにはデフォルトでインストールされているmatchit.vimも、設定ファイルに以下の記述をすることで、設定を追加できます。(matchit.vimの詳細はここでは説明いたしません。)

"matchit.vimの有効化(「%」で対応する括弧に移動するためのプラグイン)
runtime macros/matchit.vim
"対応ペアの追加(ifとendif間を「%」で移動できるようにする)
let b:match_words = "if:endif"

自動実行

特定のタイミングで特定のコマンドを実行するように設定するには、autocmdコマンドを使います。
便利ですが、複雑なコマンドなので、基本的な使い方のみ説明します。

"~/.vimrcを保存したとき、自動で再読込する
autocmd sample BufWritePost~/.vimrc  so ~/.vimrc

上記のような記述は、以下のような意味になっています。

  • sampleはグループです。augroupコマンドにより、一括指定することもできます。グループについては下記で詳細を説明します。
  • BufWritePostはイベントの種類で、今回のものはファイルの保存後を指します。なお、カンマ区切りで複数のものを同時に指定できます。どのようなイベントがあるかは、:help {event}で確認できます。
  • ~/.vimrcの部分はパターンと呼ばれるもので、これに一致した場合のみ実行します。今回の場合はファイルの種類です。どういったパターンがあるかはイベントにより、パターンを使わないイベントもあるので、その場合は全てにマッチする*を指定します。
  • so ~/.vimrcは自動実行するコマンドの部分で、複雑なことをする場合は関数を定義しておき、それを指定することもできます。

グループについて

グループの設定は任意なのですが、autocmdを使用する際の注意する点として、
autocmdは上書きされずに実行された回数だけ定義されるというものがあります。
これを避けるため、autocmdはいったん削除してから再度定義するのが行儀が良いのですが、
その際、グループを指定し、削除することで想定していないautocmdを削除してしまうことを防ぐことができます。
削除するにはautocmd!というコマンドを用います。

augroup sample
  autocmd!"読込時、sampleグループのautocmdを削除する
  autocmd FileTyperubysetlocalnumber"削除対象
augroup END
autocmd sample FileTypevimsetlocalexpandtabshiftwidth=2"削除対象
augroup not_sample
  ... "sampleグループではないので、削除対象ではない
augroup END

おわりに

いかがでしたでしょうか。
Vimはとっつきにくい部分が多いですが、使いこなせば生産性が爆発的に向上します。
これまでに挑戦し、挫折してしまった方も、これを機にVimに再チャレンジしてみてください!
なお、現在私がメインで使っているエディタはVisual Studio Codeです。。。

エイチームライフスタイルアドベントカレンダー2017、明日はVimキーバンドを使いこなすデザイナー @themeaningof8さんがWebComponentsについて書いてくださるようです。お楽しみに!

初心者向け!3日でvim病になる方法

$
0
0

この記事は Advent Calendar 2017 vim2 の11日目の記事です

くぎゅう10と申します。

vim歴は半年。

vim知識は本当にまだまだですので
今回は超初心者向けの記事を投稿しようと思います。

ズバリ

「たったの3日でvim病になる方法」

です。

vim病とは、(http://d.hatena.ne.jp/keyword/vim%C9%C2)
vimの素晴らしさを理解しだした頃に発症する病気。以下のような症例が認められている

  • ホームポジションから手を動かしたくなくなる。マウスに手を動かすのは論外。
  • なんでもvimキーバインドにしたがる。
  • ほかのエディタでも手が勝手にvimキーバインドを叩いてしまう。

これらの症状は基本的に熟練のvimmerに発症する症状ですが、
それをなんとたった3日で病気になることができる手法です。

『クリスマスや年末年始を活用して新しくvimを使ってみようかな〜って』
思っている方はぜひ、以下の記事に目をお通し下さい!

1日目 ゲームで遊ぶ

vimは基本操作がクセありすぎです。

まずは基本のキー操作を身体に叩き込むことが大事なのは分かるんですが

ただただvimの真っ黒い画面を
目的もなくjjjjj、とかやってもぜんっぜん面白くないです。

死にます!

そこで先人の知恵。
vimを学べるゲームをやりましょう!

jkl;移動など基本操作はかなりばっちり覚えられます。

Vim Adventure (https://vim-adventures.com/)

スクリーンショット 2017-12-10 20.53.49.png

1〜2時間ほどのプレイで、jkl;移動が
かなり自然になると思います。

無課金でクリアできる範囲を終了したら、1日目は終了

2日目 無難にvim tutorial

Vim tutorial
ターミナルなどで vimtutorと叩くと始められる vimのチュートリアルです。

スクリーンショット 2017-12-10 21.16.17.png

vim tutorialの文章が良くできています。

Vim は、このチュートリアルで説明するには多すぎる程のコマンドを備えた非常に強力なエディターです。

「Viemmer特有の、vim自慢している時の得意げなニヤけ顔」
が良く伝わってきます。

「vimという素晴らしいエディタ選択をした君は実に懸命だ
このチュートリアルでvimの基本を身につける」と言わんばかり

1日目で一番難関である基本操作は終えてますので
かなりスムーズにvimが学習できるはずです。

チュートリアルを完走するころには

「あれ?vimってそんなに凄いの?」って、
vim可能性を感じ始めているでしょう。
(洗脳ともいいます)

3日目 哲学する

3日目の課題は哲学です。

images.png

真面目に言っています。

vim道は一日にして成らずということを知るのです。

ここまで基本操作を学習してくると、
なまじ基本を知ってしまった故に
vimって覚えることの多さにビビるんですよね。

覚えれば覚えるほど、ささっとこなせる小技も増えてくるし
確実に作業は楽しくなるのですが、やっぱ覚えること多すぎ。

プラグインとか入りだすと沼ですよ沼。

なので、3日目の課題は哲学です
これから半年修行してもいい、と思えるだけの
モチベーションが、自分にあるか、問いかけて下さい。

沼に入ってみる覚悟があるか、再度自答してみてください。

vimキーバインドの設計思想について調べてみて下さい。

Vimの素晴らしさを紹介している記事、動画をみてください。
Ci'キーの凄さに感動して下さい。

絶対にホームポジションから手を動かさないぞという、
vimmerの愛すべき「怠惰」を感じて下さい。

あなたにとっての「vimを一生使い続ける理由」を考えてみて下さい。

これらのモチベーションの質で

ちなみにぼくに取っての理由は単純で

「一生モノのエディタを使いこなしてる俺かっけー!」
みたいな、しょーもないのが目的だったりします。

エンジニアはどうせ一生エディタ使うので、
何か1つ、一生モノのエディタってものが欲しかったんですね。

3日後 

哲学で答えをだしても、答えをだせてなくても、
あなたはもうvimを「使える」ようになっています。

細かいキーバインドはまだまだ覚えてないでしょうけど、
普通のテキストエディタとしてなんとか使えなくもないレベルに達しているはずです。

そしてなにより、vim特有の「テキスト操作したときの快感」  みたいなものも
知ってしまったはずです。

背中がゾクゾクっときた人もいるかも知れませんね。

これで半年vim修行する

メールしながらvimの修行もできるならお得じゃね?

どうせなら仕事中もどんどん修行したいよね?

ネットで調べれはそういう情報がいくらでも出てきます。

vim病とは

vimの素晴らしさを理解しだした頃に発症する病気。以下のような症例が認められている。
- なんでもvimキーバインドにしたがる。
http://d.hatena.ne.jp/keyword/vim%C9%C2)

そう、あなたは立派にvimの可能性に気づいてしまいました。
残念ながら発症条件を満たしてしまいました。

vimキーバインドにしたがるという典型的な症状も確認できます。

完全にvim病です!お大事に!!

僕の.zshrcと.vimrcのおはなし

$
0
0

こんにちは。
締め切り15分前に書き始める系エンジニアのぐりです。

この記事は呉高専エンジニア勉強会 Advent Calendar 2017の11日目の記事です。
昨日の記事はether0x2caさんの学術論文のすゝめでした。
論文の種類、公開されているサイトとその紹介が書かれていて、論文読んでみようかなって思う記事でした。
Slackグループ作ったら是非参加したいですね。

さて、この記事は僕の.zshrc.vimrcのお話です。
それぞれのイチオシの設定とプラグインを紹介していきます。

.zshrc

oh-my-zsh

# Path to your oh-my-zsh installation.exportZSH=/Users/username/.oh-my-zsh

zshの設定の管理にはoh-my-zshを使ってます。
あんまり使いこなしてはないので特にここがいいとは言えません。
お好みで導入して下しあ。

Powerlevel9k

ZSH_THEME="powerlevel9k/powerlevel9k"POWERLEVEL9K_MODE='nerdfont-complete'POWERLEVEL9K_LEFT_PROMPT_ELEMENTS=(time dir vcs)POWERLEVEL9K_RIGHT_PROMPT_ELEMENTS=()POWERLEVEL9K_DISABLE_RPROMPT=truePOWERLEVEL9K_TIME_FORMAT="%D{%m\/%d %H:%M}"POWERLEVEL9K_TIME_FOREGROUND='white'POWERLEVEL9K_TIME_BACKGROUND='background'POWERLEVEL9K_PROMPT_ADD_NEWLINE=truePOWERLEVEL9K_PROMPT_ON_NEWLINE=truePOWERLEVEL9K_RPROMPT_ON_NEWLINE=falsePOWERLEVEL9K_MULTILINE_FIRST_PROMPT_PREFIX=""POWERLEVEL9K_MULTILINE_LAST_PROMPT_PREFIX="\u25B8 "POWERLEVEL9K_LEFT_SEGMENT_SEPARATOR=''POWERLEVEL9K_RIGHT_SEGMENT_SEPARATOR=''

見た目をちょっとイケてる感じにするのはpowerlevel9k
インストールが若干めんどくさいのが玉に瑕ですが、公式のドキュメントが充実してるのでつまずくことはないと思います。
みんなの作例がまとめてあるのでそれを見るのも面白です。
ちなみに僕のはこんな感じです。色々試しましたが、結局シンプルなのに落ち着きました。
Screen Shot 2017-12-11 at 1.49.23.png
lsがきれいになってるのはcolorlsのおかげです。若干表示されるまで時間がかかりますがおすすめです。

alias

aliasv="nvim"aliasg="git"aliasgp="g push"aliasls="colorls -a -sd"aliasvz="v ~/.zshrc"aliasn="nim c -r"aliassoen="source ./env.sh"aliassozh="source /Users/username/.zshrc"aliasbe="bundle exec"aliasrub="rubocop"aliasruba="rubocop --auto-correct"aliasrid="rails ridgepole:dry"aliasrida="rails ridgepole:apply"aliasr="rails"

お次はエイリアス。
よく使うものは最初の一文字でエイリアスをかけてます。

.vimrc

dein

" dein settings {{{" dein自体の自動インストールlet s:cache_home = empty($XDG_CACHE_HOME) ? expand('~/.cache') : $XDG_CACHE_HOMElet s:dein_dir = s:cache_home . '/dein'let s:dein_repo_dir = s:dein_dir . '/repos/github.com/Shougo/dein.vim'if!isdirectory(s:dein_repo_dir)call system('git clone https://github.com/Shougo/dein.vim ' . shellescape(s:dein_repo_dir))endiflet&runtimepath= s:dein_repo_dir .",". &runtimepath" プラグイン読み込み&キャッシュ作成let s:toml_file ='~/.dein.toml'let s:lazy_toml_file ='~/.dein_lazy.toml'if dein#load_state(s:dein_dir)call dein#begin(s:dein_dir)call dein#load_toml(s:toml_file)call dein#load_toml(s:lazy_toml_file, {'lazy': 1})call dein#end()call dein#save_state()endif" 不足プラグインの自動インストールif has('vim_starting')&& dein#check_install()call dein#install()endif

暗黒の力を与えられしプラグインマネージャー
その名もdein.vim

以下を参考(コピペ)にして設定しました。
別ファイルに読み込むプラグインをまとめて書いてます。
dein.vimによるプラグイン管理のマイベストプラクティス
NeoBundle から dein.vim に乗り換えたら爆速だった話

syntastic

" syntastic_mode_mapをactiveにするとバッファ保存時にsyntasticが走る" active_filetypesに、保存時にsyntasticを走らせるファイルタイプを指定するletg:syntastic_mode_map = { 'mode': 'passive','active_filetypes': ['ruby'] }letg:syntastic_ruby_checkers = ['rubocop']

rubyのスタイルガイドであるrubocopを、保存時に走らせる用に設定しました。
非同期なのでaleの方が良さげです。
参考
Rubocopをsyntasticを使ってVimから自動実行する

emmet-vmi

letg:user_emmet_settings = {
      \  'lang' : 'ja'
      \}

HTMLが爆速でかけるemmetのvim用プラグイン
emmet-vim

vim-easymotion

letg:EasyMotion_do_mapping =0"Disable default mappings
nmap <Leader>s <Plug>(easymotion-overwin-f2)

画面内の移動がめちゃくちゃ早くなるめちゃくちゃオススメなプラグイン
vim-easymotion。おすすめです。

NERDTree

map <C-n> :NERDTreeToggle<CR>let NERDTreeShowHidden=1

皆さんご存知NERDTree
まあこれの紹介はいいでしょう。

カラースキーマ

" set color schemeletg:hybrid_custom_term_colors =1

目に優しい感じのカラースキーマ
Screen Shot 2017-12-11 at 1.48.06.png

キーバインド

inoremap<C-j><Down>inoremap<C-k><Up>inoremap<C-h><Left>inoremap<C-l><Right>inoremap<C-f><Delete>inoremap<C-d><BS>inoremap<C-e><C-o>$inoremap<C-a><C-o><C-0>nnoremap<SPACE><Nop>
map <SPACE><leader>nnoremap<C-s> :%s/nnoremapj gjnnoremapk gknnoremap gj jnnoremap gk knnoremap s <Nop>nnoremapsj<C-w>jnnoremap sk <C-w>knnoremapsl<C-w>lnnoremapsh<C-w>hnnoremap ; :nnoremap : ;nnoremap<S-h><C-0>nnoremap<S-l> $nnoremap<CR> A<CR><ESC>nnoremap== gg=Gnnoremap<Leader>w :w<CR>nnoremap<Leader>q :wq<CR>

インサートモードでも移動や削除ができるようにしてたり、ペイン間の移動を楽にしてたりしてます。
個人的に一番役に立ったのはこれです。

nnoremap ; :nnoremap : ;

よく使う:をシフトキー無しで押せるようになってます。

以上です。
最後に全コード貼っておきますね。
.zshrc
.vimrc

zshでvimVim+Tabでエラーになる場合の対処法(zplug編)

$
0
0

zsh + zplug 環境で vimでファイル名補完をしようとして突然できなくなったときの対処法です。

ここ数週間で2回ハマったのでメモ :sob:

事象

vim ~/dotf # ここでTab補完しようとする_arguments:451: _vim_files: function definition file not found

解決方法

zplugのホームディレクトリにあるzcompdumpファイルを削除する。

rm -fr $ZPLUG_HOME/zcompdump
exec $SHELL -l

※ハマった内容

  • HOMEディレクトリにも.zcompdumpがあったので、消しても解決せず。
  • find / --name ".zcompdump"でも .がついているので、 ~/.zcompdumpしか見つからず。
  • ZPLUG_HOMEのデフォルトは~/.zplug
    • 自分の場合は、dotfileでHOMEを変更していたので rm -fr ~/.zplug/zcompdumpで解決せず。

参考

  • zplugを使用していない場合は、こちらが参考になります。

備考

そもそもこの事象が発生する要因って何ででしょうね :thinking:

行の抽出

$
0
0

手順

  1. /input
  2. :v//d

サンプル

https://getbootstrap.com/docs/4.0/components/forms/#form-row

<form><divclass="form-row"><divclass="col"><inputtype="text"class="form-control"placeholder="First name"></div><divclass="col"><inputtype="text"class="form-control"placeholder="Last name"></div></div></form>

<inputtype="text"class="form-control"placeholder="First name"><inputtype="text"class="form-control"placeholder="Last name">

【随時更新】若手エンジニアに試してほしい、開発スピードを上げるため工夫

$
0
0

Ateam Hikkoshi Samurai Inc. Advent Calendar 2017 12日目です。
本日はエイチーム引越し侍の新卒1年目、Webエンジニアの@ueki05が担当します。

みなさん、自身の開発スピードをなかなか上げれずにお困りではないでしょうか?
もしくは、回りに開発スピードを上げれずに困っている人はいませんか?
今回は自分が入社してから開発スピードを上げることに繋がった工夫をご紹介いたします。

※随時更新していきますので「これやると開発スピードあがるよ!」といったご意見やコンテンツをコメントいただけると嬉しいです!

導入

開発のスピードを上げる前に、まずは「開発」をフェーズ毎に分けてみます。
大枠は以下のようになるかと思います。

  1. 仕様決め
  2. コードを書く
  3. テスト・動作確認

私もそうなんですが、コードを書く以外のところでも結構時間を使います。
これら3つのフェーズをきちんと分けて考え、それぞれを効率化することが、開発全体のスピードアップに繋がると思います。

では実際に効率化に役立ったことをフェーズ毎に紹介し、全フェーズに共通することを最後にまとめていきます。

開発スピードを上げるために

仕様決め

必要なこと・不要なことをまとめる

「PCサイトは対応してたけどスマホサイト対応するの忘れてた。。。」
「これスマホサイトだけでよかったんだ、PCサイトも対応してしまった。。。」
私はこういう経験を何度かしています。
いまだにやってしまうことがあるのですが、これやっちゃうとすごく無駄な時間が増えてしまいます。

どの範囲まで開発をして、どの範囲はやらないのかを予め明確にしておくことが重要です。
これを確認しないと、無駄な開発に時間を使った挙句、戻しの対応もしないといけなかったり、逆に想定していなかった開発が後から増えて、直前の開発に追加の対応をしないといけなくなったりします。

仕様決めや確認の段階で、やること・やらないことを明確にしましょう。

色んな人に相談しすぎない

私の体験談になるのですが、例えばデザイナーのAさんにとある開発のデザインについて相談したとします。
開発が進んだので、もう一度Aさんに聞こうと思ったら不在で、そのときはデザイナーBさんに相談しました。
すると、Bさんから「xの色はもっと輝度の高い色にした方が目立つ」と言われて、自分でも納得してその変更を適用しました。
すると、今度はAさんから「そこは目立ちすぎない色にしたくて元の色に設定していたので、元の色に戻しましょう」となりました。

複数の人に相談すると、持っている前提条件が違ったりもしますし、各々で考える優先順位も違ったりします。
今回はデザイナーと一緒の例でしたが、これは別の職種でも同様に発生しますし、エンジニア内でも実装の良し悪しで議論することもあります。
議論すること自体は悪いことではないのですが、議論して100点のものを作ろうとすることは、60点のものを作ることよりかなり労力が必要です。
また、WebサービスだとABテストを回して結果が良かったら正式リリース、ダメだったら改善を試みて再度テストを回したりするので、一度60点のものを世に出してユーザーからのFBを得て改善した方が、自分たちの仮説だけで100点を目指すより随分早いし精度も高いと思います。

なので、開発スピードを優先したいのであれば、色んな人に相談しすぎないようにしてみるのも一つの手ではないかと思います。

コードを書く

開発言語の理解

かなり当然なことですが、おそらく開発スピードが遅い人はこれができていないと思います。
私自身、振り返るとできていませんでした。

現在仕事ではPHPで開発をしているのですが、学生時代からPHPでプログラムは書いていて、ハッカソンに出たり受託でサイト構築のお仕事をさせていただいていました。
そのときは0->1の開発ばかりやっていたので、言語の知識がそこまでなくても、やりたいことをググって、出てきたプログラムを上手く流用すれば目的が実現できていました。

それが運用しているサービスの改善となると、実際に動ているプログラムを理解して、改修箇所を探して、適切な処理を追加したり、適切な処理に修正したりしないといけないことがほとんどで、そうなるとググっても答えが出てきません。
そうなると頼りになるのはそのサービスのプログラム自体で、それを読み解かないといけないのですが、言語の知識が中途半端にしか理解できていないと、読み解くのにすごく時間がかかります。
なので、一度体系的に使っている開発言語の理解に着手してはいかがでしょうか。

最近だとProgateとかオススメです、すごくわかりやすいです。

フレームワークの理解

たいていのフレームワークにはチュートリアル的なコンテンツがあるので、それを一度終わらせましょう。
以下いくつか例を載せておきます。
※更新したいので皆さんがおつかいのフレームワークでチュートリアルをコメント頂けると嬉しいです。

ツールを使いこなす

エディタ

私の場合はVimを使いこなせることに勝手にあこがれを頂いているので、一旦Vimだけ書きます。
これ一通りできるようになればかなり早くなると思います。

※他のエディアをお使いの方、情報お待ちしております。

コマンド

こういうの少しずつ覚えていくと、着実に早くなります。

Chrome Developer Tools

Webエンジニアであれば、ChromeのDeveloper Toolsを使いこなせると爆速でデバックできそうです。
以下の記事はWindows用で書かれていますが、Macでも別のショートカットキーで同じことができます。

テスト・動作確認

テストすべきことを抜け漏れなく考える

いまだにやらかしているのが、改修範囲以外のテストを失念してしまうこと。
例えば、全ページ共通のコンテンツ(ヘッダーとかフッターとか)の改修で、特定のページAのときは表現を変えたいとする。
いざ特定のページAで表現を変えたときに、ページA 以外でも表現が変わっていないかを確認し忘れていることが未だにある。
これは仕様決めのときとも関わるのですが、いざリリースしてみて「ページA以外でも変更されてる。。。」とかなると二度手間なので、抜け漏れのないテストを心掛けましょう。

共通

システム仕様を理解する

これは開発全体のフェーズに効いてきますが、特に2番目の実際にコードを書くところに効いてくると思います。
開発を進めていくうちに覚えるという方もいらっしゃるのですが、私自身はなかなか理解が進まず困っています。

弊社でもドキュメントを残す等の色々な試みをしていますが、最近だと@kawanakashotaroさんにシステム仕様のクイズを作っていただいて重要なプログラムを追うようにしています。
自分一人で仕様を理解しようとしても、なにをどう理解したら良いのか分からなかったので、クイズにしてもらえただけで仕様理解が効率化できたように思います。

※皆さんはシステム仕様の理解をどのように進めていますか?ぜひコメントで教えてほしいです。

悩んだらすぐ人に聞く

これが本当に重要だと思います。
最初は自分で考えて改修箇所を探したり、実装を進めていくべきですが、わからないものはどうしたってわかりません。
手が止まったら詳しい人に聞きましょう。
その結果リリースが早くなるのであれば、それが正義で良いと思います。

最後に

Ateam Hikkoshi Samurai Inc. Advent Calendar 2017 12日目いかがでしたでしょうか。
明日はエイチーム引越し侍@ex_SOULさんがTDDに関する記事を書いてくれます(もしかしたら急遽変更するかも)。
お楽しみに。

追伸

株式会社エイチーム引越し侍では、一緒にサイト改善をしてくれるWebエンジニアを募集しています。エイチームグループのエンジニアとして働きたい!という方は是非、以下のリンクから応募してください。
皆様からのご応募、お待ちしております!!

エイチームグループ採用サイト(Web開発エンジニア職)

vim-go に unite/denite source を作って contribute した話

$
0
0

作って PR して入れてもらいました。そもそも vim-go にそんな機能あるの?という話から unite/denite source の作り方まで簡単に解説してみます。

まず完成形から。以下は denite での例を示しますが、unite でも見た目は一緒です。

Denite decls—— ディレクトリ(パッケージ)に含まれる関数と型を列挙します。
スクリーンショット 2017-12-11 20.11.16.png

尚、前提として Vim8(denite 使うなら Python3 も)を使ってるものとします。NeoVim でも多分動きますが僕は使ってないので試してません。

又、この記事では vim-go / unite / denite のインストール・設定については解説しません。以下のような優れた記事がありますのでそちらをご参照ください。

GoDecls / GoDeclsDirって知ってますか?

Show all function and type declarations for the current [file / dir].

と doc には書いてあります。要するに、ファイル・ディレクトリに含まれる関数と型を列挙してくれる機能です。元々これは ctrlp.vim使ってる人のための機能(最近 fzfサポートも入った)だったので、unite / denite派の僕には使えませんでした。

GoDecls—— ファイルに含まれる関数と型を列挙します。
スクリーンショット 2017-12-11 20.08.49.png
GoDeclsDir—— ディレクトリ(パッケージ)に含まれる関数と型を列挙します。
スクリーンショット 2017-12-11 20.09.01.png

もっとも、unite / denite には似た機能があります。outline source です。

Denite outline—— ファイルに含まれる関数と型を列挙します。
スクリーンショット 2017-12-11 20.11.04.png

GoDeclsと似てますね。これは ctagsコマンドを使って関数・型を列挙してくれるものです。普通の言語ならこれで十分なのですが、Go ではこれでは不足でして……なぜかというと、Go では関数・型の名前空間(パッケージ)がディレクトリ単位だからです。

ディレクトリ内のソース全部の関数・型を列挙したい!

今まで Go のソースを読んでるとき「このパッケージにこんな関数なかったっけ……」と思って探すには、ディレクトリ内で grep するしか方法がありませんでした(IDE 使ってる場合を除く)。vim-go の作者も同じ思いだったのでしょう。これを解決するため、便利ツールを作って解決してくれました。

motionは vim-go インストール時に行った :GoInstallBinariesコマンドでインストールされてます(やってますよね?)。適当なディレクトリでコマンドを叩くと、以下のような出力が取れます。

$ cd ~/.go/src/github.com/golang/appengine
$ motion -mode decls -include func,type -dir .{"mode": "decls","decls": [{"keyword": "func","ident": "TestValidGeoPoint","full": "func TestValidGeoPoint(t *testing.T)","filename": "appengine_test.go","line": 11,"col": 1},{"keyword": "func","ident": "BackgroundContext","full": "func BackgroundContext() context.Context","filename": "appengine_vm.go","line": 18,"col": 1},

...

JSON 以外に Vim 形式での出力も可能です。

$ motion -mode decls -include func,type -dir .{"mode": "decls", "decls": [{"keyword": "func", "ident": "IsTimeoutError", "full": "func IsTimeoutError(err error) bool", "filename": "timeout.go", "line": 10, "col": 1}, ...

ここまで出来てれば簡単ですね! このコマンドの出力を読み取って、いい感じに成形して表示すればいい訳です。

unite source の作り方

もうありとあらゆるところで解説されていることですから詳しく書くこともないでしょう。そもそも unite.vim 自体がすでに開発が終了してますからね。

Shougo/unite.vim: Unite and create user interfaces
Note: Active development on unite.vim has stopped. The only future changes will be bug fixes.

unite source を作るのに unite.vim のソースをいじる必要はありません。vim-go レポジトリの中で規定のパスにソースを置くだけです。完全なソースはリンク先を見ていただくとして要点だけ書いていきます。

source 属性の定義

unite source でまず必要なのは source の名前などを定義する辞書です。

let s:source = {
      \ 'name': 'decls'," ソースの名前
      \ 'description': 'GoDecls implementation for unite'," ソースの説明
      \ 'syntax': 'uniteSource__Decls'," 候補を列挙する際のシンタックスハイライト
      \ 'action_table': {},
      \ 'hooks': {},
      \ }

この中で nameだけが必須です。今回は候補を綺麗に色づけしたかったので syntaxも設定しています。

候補の列挙

そして source のキモとなるのが gather_candidates関数です。名前の通り、候補を列挙する関数です。

function! s:source.gather_candidates(args, context) abortletl:bin_path =go#path#CheckBinPath('motion')if empty(l:bin_path)return []endifletl:path= expand(get(a:args,0,'%:p:h'))if isdirectory(l:path)letl:mode='dir'elseif filereadable(l:path)letl:mode='file'elsereturn []endifletl:include= get(g:,'go_decls_includes','func,type')letl:command = printf('%s -format vim -mode decls -include %s -%s %s',l:bin_path,l:include,l:mode, shellescape(l:path))letl:candidates = []tryletl:result = eval(unite#util#system(l:command))letl:candidates = get(l:result,'decls', [])catchcall unite#print_source_error(['command returned invalid response.',v:exception], s:source.name)endtryreturn map(l:candidates,"{
        \ 'word': printf('%s :%d :%s', fnamemodify(v:val.filename,':~:.'),v:val.line,v:val.full),
        \ 'kind': 'jump_list',
        \ 'action__path': v:val.filename,
        \ 'action__line': v:val.line,
        \ 'action__col': v:val.col,
        \ }")endfunction

長いですが、大半は motionコマンドに渡すオプションを作成しています。大事なのは3点。

1. motionコマンドのパス

letl:bin_path =go#path#CheckBinPath('motion')

これは vim-go の便利関数で求められます。

2. コマンドの実行とエラー処理

tryletl:result = eval(unite#util#system(l:command))letl:candidates = get(l:result,'decls', [])catchcall unite#print_source_error(['command returned invalid response.',v:exception], s:source.name)endtry

実行には unite#util#system()、エラーを吐くときは unite#print_source_error()という便利関数を使いましょう。

3. 候補の作成

return map(l:candidates,"{
      \ 'word': printf('%s :%d :%s', fnamemodify(v:val.filename,':~:.'),v:val.line,v:val.full),
      \ 'kind': 'jump_list',
      \ 'action__path': v:val.filename,
      \ 'action__line': v:val.line,
      \ 'action__col': v:val.col,
      \ }")

各候補の情報を設定します。大体は見たまんまです。

項目説明
word画面に表示される文字列。
kind候補の“kind”(後述)。
action__path候補を開く際に使うパス。
action__lineファイルの中で候補が存在する行。
action__colファイルの中で候補が存在する桁。

kindがちょっと特殊ですね。これは名前の通り候補の「種別」を表すものです。「種別」はファイル、ディレクトリ、Vim のバッファー、URL などなどいろいろ用意されており、それぞれの種別によって取れる“action”が異なってきます。この辺はドキュメントが非常に詳しいので :h unite-kindsで読んでみてください。

今回はファイルの特定の場所に飛びたいだけですので jump_listという kind を使いました。

候補のシンタックスハイライト

実はここが一番大変でした。Vim のシンタックスハイライト機構は非常に多機能なのですが、正直言ってその記法は複雑怪奇です。今回説明する以外にも色んな機能がありますので詳細は :h syntaxを見てみてください。

unite では hooks.on_syntax()関数を定義し、その中で Vim のシンタックスハイライト関数を呼んで設定します。

function! s:source.hooks.on_syntax(args, context) abortsyntaxmatch uniteSource__Decls_Filepath /[^:]*\ze:/ contained containedin=uniteSource__Declssyntaxmatch uniteSource__Decls_Line /\d\+\ze :/ contained containedin=uniteSource__Declssyntaxmatch uniteSource__Decls_WholeFunction /\vfunc %(\([^)]+\) )?[^(]+/ contained containedin=uniteSource__Declssyntaxmatch uniteSource__Decls_Function /\S\+\ze(/ contained containedin=uniteSource__Decls_WholeFunctionsyntaxmatch uniteSource__Decls_WholeType /type \S\+/ contained containedin=uniteSource__Declssyntaxmatch uniteSource__Decls_Type /\v( )@<=\S+/ contained containedin=uniteSource__Decls_WholeType

各候補には予め uniteSource__(ソース名)という syntax region が設定されています。これを親として(containedin=uniteSource__Decls)、各パーツを正規表現で設定します。一部は孫 region まで作ってます。

highlight default link uniteSource__Decls_Filepath Commenthighlight default link uniteSource__Decls_Line LineNrhighlight default link uniteSource__Decls_Function Functionhighlight default link uniteSource__Decls_Type Type

各パーツに色を設定します。通常は新規の色を設定するのではなく、カラースキームと連携させた方が使い勝手がいいでしょう。highlight default linkは文字通り既存の色と“リンク”させてこれを実現してくれます。関数名には Functionの色を使ってくれる訳ですね。

syntaxmatch uniteSource__Decls_Separator /:/ contained containedin=uniteSource__Decls concealsyntaxmatch uniteSource__Decls_SeparatorFunction /func / contained containedin=uniteSource__Decls_WholeFunction concealsyntaxmatch uniteSource__Decls_SeparatorType /type / contained containedin=uniteSource__Decls_WholeType concealendfunction

最後に、画面から消したい文字列を conceal機能で隠します。funcとか自明ですからね。

denite source の作り方

今回の記事はそもそも denite の入門記事を書こうと思って始めたのですが、unite source と対比させた方が分かりやすいだろうと思いましてそっちを先に詳しく載せました。

denite source の一番の特徴は denite のそれです。つまり Python3 で書いてあるのです。そりゃ Vimscript も別に嫌いじゃないし、僕も denite のために Python3 触ったくらいなので特に思い入れもなかったんですが、unite source で散々苦労した後なので感慨もひとしおでした。denite source というか、Python3 のいいところは

  • 何でもできるし、道具も最初から揃ってる。
  • 開発を助けるツールがたくさんある。
  • 分からないことは Google 先生に聞けば一瞬で分かる。

に尽きます(特に最後)。やっぱりメジャーな言語はいいなあ……

更にこれは denite に限った特徴ですが、denite 本体が Python 3.5+ を必須として書かれています。今回のような拡張機能を書くときに古い環境のことを考えなくていいのはいいこと(?)です。

いい加減本題に入ります。denite も unite と同様、特定のパスにソースを置くとそれを実行時に読み込んでくれます。今回は vim-go の中のここにソースを置いています。

unite の時と同じく要点だけを書いていきましょう。

Source クラスの定義

classSource(Base):def__init__(self,vim):super().__init__(vim)self.name='decls'self.kind='file'

unite の時と比べるとずいぶん簡潔……というか分かりやすい。Vimscript ではクラスとかないのでいろいろ黒魔術が使われてましたからね……。

候補の列挙

これは gather_candidatesメソッドで行っています。やることは unite の時と同じですのでここも要点だけにしましょう。

defgather_candidates(self,context):bin_path=self.vim.call('go#path#CheckBinPath','motion')ifbin_path=='':return[]

Python3 から Vim のユーザー定義関数を呼び出す際は self.vim.call()メソッドを使います。ここでは unite の時と同じく motionコマンドのパスを検索しています。

expand=context['args'][0]ifcontext['args']else'%:p:h'target=self.vim.funcs.expand(expand)

Vim の関数のうち expand()のような Vim 本体の関数ならばショートカットが用意されています。self.vim.funcs.(関数名)()です。

try:cmd=subprocess.run(command,stdout=subprocess.PIPE,check=True)exceptsubprocess.CalledProcessErroraserr:denite.util.error(self.vim,'command returned invalid response: '+str(err))return[]txt=cmd.stdout.decode('utf-8')output=json.loads(txt,encoding='utf-8')

コマンドの出力結果(JSON)をデコードしています。denite.util.error()は denite に用意されたエラー出力関数です。

defmake_candidates(row):name=self.vim.funcs.fnamemodify(row['filename'],':~:.')return{'word':'{0} :{1} :{2}'.format(name,row['line'],row['full']),'action__path':row['filename'],'action__line':row['line'],'action__col':row['col'],}returnlist(map(make_candidates,output['decls']))

最後に候補を成形して終わり。unite の時と一緒なので特に説明は要らんと思いますが一つ、kindだけが抜けてますね。unite では jump_listとなっていた kind が denite では fileに変わっています。今回のソースではクラスのプロパティで self.kind = 'file'しちゃってますので、ここでは特に指定しなくて大丈夫です。

候補のシンタックスハイライト

DECLS_SYNTAX_HIGHLIGHT=[{'name':'FilePath','re':r'[^:]*\ze:','link':'Comment'},{'name':'Line','re':r'\d\+\ze :','link':'LineNr'},{'name':'WholeFunction','re':r'\vfunc %(\([^)]+\) )?[^(]+'},{'name':'Function','parent':'WholeFunction','re':r'\S\+\ze(','link':'Function'},{'name':'WholeType','re':r'type \S\+'},{'name':'Type','parent':'WholeType','re':r'\v( )@<=\S+','link':'Type'},{'name':'Separator','re':r':','conceal':True},{'name':'SeparatorFunction','parent':'WholeFunction','re':r'func ','conceal':True},{'name':'SeparatorType','parent':'WholeType','re':r'type ','conceal':True},]...defhighlight(self):forsyninDECLS_SYNTAX_HIGHLIGHT:containedin=self.syntax_namecontainedin+='_'+syn['parent']if'parent'insynelse''conceal=' conceal'if'conceal'insynelse''self.vim.command('syntax match {0}_{1} /{2}/ contained containedin={3}{4}'.format(self.syntax_name,syn['name'],syn['re'],containedin,conceal))if'link'insyn:self.vim.command('highlight default link {0}_{1} {2}'.format(self.syntax_name,syn['name'],syn['link']))

Vim の「関数」ではなく「ex コマンド」を呼び出す場合は self.vim.command()を使います。やってることは unite の時と一緒です。

ここだけは Python っぽく書いたら逆に見づらくなったかもしんない……。素直に self.vim.command()を羅列した方がいいのかも。


以上です。今回説明した基本だけ分かっとけば他のコマンド出力から source を作るのも簡単だと思いますので、皆さんもいろいろ試してみてください。

VimでPHPのコードをシュワルツ変換してソートする

$
0
0

(この記事はピクシブ株式会社 AdventCalendar 2017の12日目の記事です)

今回のあらすじ

どうおののかせたかを紹介します。

問題

pixivのURLルート定義は以下のような形になっています:1

lib/routes.php
functiongetUrlRouteMap(){$route_map=['/'=>['controller'=>'IndexController',],'/discovery'=>['controller'=>'DiscoveryController',],'/user/:user_id/series'=>['controller'=>'UserSeriesIndexController','params'=>['user_id'=>'int',],],...'/about.php'=>['controller'=>'AboutController',],'/bookmark.php'=>['controller'=>'BookmarkController',],...];return$route_map;}

見事に順番がバラバラです2。これでは後からコードを読んだ人には何処に何が書かれているか分からない状態で良くありませんし、新しい定義を追加する時にも判断に迷うので各自が好き勝手な場所に書き始めてどんどんカオスになっていきます。数が少なければまだしも、このルート定義の数は800個以上あるという……

というわけで 各ルート定義をURLの辞書順でソートするというのが今回の目的です。

回答

./sort-routes lib/routes.php
sort-routes
#!/bin/bash
vim -N -u NONE -i NONE -e -s -S "$0.vim""$@"
sort-routes.vim
/\$route_map = \[/
mark a
normal! %
mark b'a+1,'b-1g/'\/.*' => \[/.,/^ \{8}\],$/-1s/\n/XYZZY/'a+1,'b-1sort'a+1,'b-1 s/XYZZY/\r/gupdateqall!

解説

Vimでバッチ処理をする

vim -N -u NONE -i NONE -e -s -S "$0.vim""$@"

これはイディオムです。個々のオプションの意味は以下の通りです:

  • -N-u NONEするとvi互換モードになって色々と不便なので、それを避ける
  • -u NONEvimrcを読み込まない。自分の vimrcに依存したスクリプトだと他の人が実行できないので
  • -i NONEviminfoを読み込まない。レジスタの初期値が変動し得るのは避けたいし、上書きするのも避けたい
  • -e -s— バッチ処理中にバッファの状態を表示しない。この方が速い
  • -S {file}— Vim起動後に :source {file}が実行される

後はVim scriptで望みのバッチ処理を記述すればOKです。

「え? Vim scriptで……?」と怪訝に思うかも知れませんが、Vimはテキストエディタなのでその操作方法はテキスト処理に特化したDSLですし、Vim scriptは普段Vimを使う時に打つ :e foo:wの延長に過ぎないので、実際簡単です。

下準備: 頻繁に操作する範囲をメモしておく

/\$route_map = \[/
mark a
normal! %
mark b

全てのルート定義を頻繁に編集する事が分かっているので、以後の作業を楽にする為にその範囲をメモしておきます。

  1. /\$route_map = \[/— 正規表現にマッチする行(=全てのルート定義を包む [)までカーソルを移動し
  2. mark a— その行を後から 'aで参照できるようメモする
  3. normal! %[に対応する ] (=全てのルート定義を包む ])までカーソルを移動し
  4. mark b— その行を後から 'bで参照できるようメモする

具体的には以下の範囲がメモされます:

functiongetUrlRouteMap(){$route_map=[// 'a'/'=>[// ---.'controller'=>'IndexController',//    |-- 実際にソートしたい範囲],//    |...// ---'];// 'breturn$route_map;}

実際にソートしたい範囲は 'aより1行下かつ 'bより 1行上ですが、敢えて1行外側をメモしておきます。外側の行ならソートの過程で変化しないのですが、内側の行はソートの過程で増減します。内側の行をメモすると途中で行が消えて 'a'bで適切な範囲が指定できなくなるからです。

本題: VimでPHPのコードをシュワルツ変換してソートする

'a+1,'b-1g/'\/.*' => \[/.,/^ \{8}\],$/-1s/\n/XYZZY/'a+1,'b-1sort'a+1,'b-1 s/XYZZY/\r/g

Vimには sortコマンドがあるので、特定の範囲を行単位でソートするなら 'a,'b sortで済みます。ところが各ルート定義は複数行に渡っているので、このままだと sortでは太刀打ちできません。

でも

  1. 各ルート定義を1行に変換して
  2. sortして
  3. 各行をルート定義に逆変換する

とすればソート可能です。

各ルート定義を1行に変換する

'a+1,'b-1g/'\/.*' => \[/.,/^ \{8}\],$/-1s/\n/XYZZY/

{range}g/{pattern}/{command}

  1. {range}の範囲の中にある
  2. {pattern}にマッチする各行について
  3. {command}を実行する

事ができます。

なので、この長いコマンドは

  1. 'a+1,'b-1— ソートしたい範囲の中にある
  2. /'\/.*' => \[/— 各ルート定義の開始行について
  3. .,/^ \{8}\],$/-1s/\n/XYZZY/— 何か凄い事をする

という意味になります。

.,/^ \{8}\],$/-1s/\n/XYZZY/は一瞥しただけだと謎のコマンドですが、実態は {range}s/{pattern}/{replacement}/なので、単なる文字列置換です。具体的には

  1. .,/^ \{8}\],$/-1— カーソル行(=ルート定義の開始行)から正規表現にマッチする行の直前の行(=ルート定義の最後から2番目の行)について
  2. \n— 改行文字を
  3. XYZZY— 通常のソースコードには絶対に現れない文字列に置き換える3

となります。

実行結果は以下のようになります:

functiongetUrlRouteMap(){$route_map=['/'=>[XYZZY'controller'=>'IndexController',XYZZY],'/discovery'=>[XYZZY'controller'=>'DiscoveryController',XYZZY],'/user/:user_id/series'=>[XYZZY'controller'=>'UserSeriesIndexController',XYZZY'params'=>[XYZZY'user_id'=>'int',XYZZY],XYZZY],...'/about.php'=>[XYZZY'controller'=>'AboutController',XYZZY],'/bookmark.php'=>[XYZZY'controller'=>'BookmarkController',XYZZY],...];return$route_map;}

ソートする

'a+1,'b-1sort

これは見た通りですね。

実行結果は以下のようになります:

functiongetUrlRouteMap(){$route_map=['/'=>[XYZZY'controller'=>'IndexController',XYZZY],'/about.php'=>[XYZZY'controller'=>'AboutController',XYZZY],'/bookmark.php'=>[XYZZY'controller'=>'BookmarkController',XYZZY],'/discovery'=>[XYZZY'controller'=>'DiscoveryController',XYZZY],'/user/:user_id/series'=>[XYZZY'controller'=>'UserSeriesIndexController',XYZZY'params'=>[XYZZY'user_id'=>'int',XYZZY],XYZZY],...];return$route_map;}

各行をルート定義に逆変換する

'a+1,'b-1 s/XYZZY/\r/g

逆変換は gを駆使したややこしい行指定がしなくて良いので簡単です。

実行結果は以下のようになります:

functiongetUrlRouteMap(){$route_map=['/'=>['controller'=>'IndexController',],'/about.php'=>['controller'=>'AboutController',],'/bookmark.php'=>['controller'=>'BookmarkController',],'/discovery'=>['controller'=>'DiscoveryController',],'/user/:user_id/series'=>['controller'=>'UserSeriesIndexController','params'=>['user_id'=>'int',],],...];return$route_map;}

余談

実務で遭遇した例はもう一段ややこしく、一部のルート定義に対して以下のようにコメントが付いていました:

functiongetUrlRouteMap(){$route_map=[...// 旧URLのサポート用// TODO: #123 がマージされたらこれは消す'/discover'=>['redirect'=>'/discovery',],'/discovery'=>['controller'=>'DiscoveryController',],...];return$route_map;}

つまり、コメントも維持しつつソートをする必要があったという事です。

さらに、今回の記事の問題は氷山の一角に過ぎず、これに先立って

  • ルート定義は一部しか存在せず、残りは htdocs/*.phpが直接存在する状態だった。ルート定義を生成しつつ htdocs/*.phpを消す必要があった
  • htdocs/*.phpの中にコントローラークラスが記述されていた。ルート定義を生成する前に、クラス定義を別ファイルに分離する必要があった
  • 一部のコントローラークラスは名前が重複していた為、一意な名前に変更する必要があった
  • htdocs/*.phpの中身がベタなPHPスクリプトになっているものが少なからず存在していた。そういうものはコントローラークラスの体裁にまとめ直す必要があった

という楽しいリファクタリングが山盛りでした。もちろん全てVimで解決しました。

告知

ピクシブ株式会社では、このように大量のファイルを高速にリファクタリングするのが好きなエンジニア・アルバイトを募集しています。使用エディタは問いません。

明日は @RaggがRailsアプリのCSS設計の知見を披露してくれます。お楽しみに。


  1. これは記事の為に簡略化した擬似コードで、実際のものとは異なります。 

  2. 「URLルーターは無く htdocs/*.phpだけが有った」→「URLルーターが導入されて極一部のページは手動で移行した」→「残り全てのページは移行スクリプトを書いて処理した」という変遷を経た結果、順番がバラバラになっていました。 

  3. この記事ではコードとソート過程の分かり易さの為に XYZZYを使っています。実務では絶対に現れない文字として ^P (0x10) を使っていました。 

2018年に向けてNeoVim&dein.vimを整えた

$
0
0

こちらはフロムスクラッチ Advent Calendar 2017の4日目の記事です。

はじめに

  • 普段はIDEやAtomなどを全く使わず、VimでRubyやらJavaScriptを書いています。
  • 実践Vimを読んだものの、思考のスピードで編集できるほどのVim力はないです。

やりたいこと

  • literally the future of vim(直訳:文字通りvimの未来)と強気なNeovimを使ってみたい。
  • 2年前からメンテしていなくてぶっちゃけ重い.vimrcをキレイにしたい。
  • NeoBundleからとりあえずdein.vimに乗り換えた状態なので、使いこなしたい。具体的にはプラグインのTOML化を目指す。

環境

  • MacBook Pro(Retina, 13-inch, Early 2015)
  • macOS High Sierra Version 10.13.1
  • Homebrewは導入済み

NeoVimのインストール

まず最初にNeoVimをHomebrewを使ってインストールします。

$ brew install neovim$ nvim

neovim初起動.png
こんな感じでNeovimを起動することができました。

設定ファイルのパス

デフォルトだと~/.config/nvim/init.vimを読み込むようです。
僕はそういった類いのものはdotfilesでまとめて管理しているので、.zshrcに以下の記述を足しました。
こうすることで~/dotfiles/nvim/init.vimが設定ファイルになります。

.zshrc
exportXDG_CONFIG_HOME=$HOME/dotfiles

設定ファイルとの戦い

dein.vimリポジトリのgit clone

任意のディレクトリにdein.vimをgit cloneします。

$ mkdir -p ~/dotfiles/.vim/dein/repos/github.com/Shougo/dein.vim$ git clone git@github.com:Shougo/dein.vim.git \
    ~/.vim/dein/repos/github.com/Shougo/dein.vim

nvim/init.vimへの設定追加

ミニマルな設定をinit.vimに追加しました。

~/dotfiles/nvim/init.vim
" dein.vimによるプラグイン管理if&compatiblesetnocompatibleendif" dein.vimのclone先を指定するsetruntimepath+=~/dotfiles/.vim/dein/repos/github.com/Shougo/dein.vimcall dein#begin(expand('~/dotfiles/.vim/dein'))call dein#add('Shougo/dein.vim')call dein#add('Shougo/vimproc.vim', {'build': 'make'})" 補完、スニペットcall dein#add('Shougo/neocomplete.vim')call dein#add('Shougo/neosnippet')" その他必要なプラグインはこちらに追加するcall dein#end()

一度NeoVimを終了し、再度立ち上げてから:call dein#install()でプラグインのインストールができます。
ここまででdein.vimの導入は終了です。

プラグインのTOML化

プラグインをTOMLにして別ファイルで管理ができるようなので、こちらを試してみます。

~/dotfiles/nvim/init.vim
" dein.vimによるプラグイン管理if&compatiblesetnocompatibleendif" dein.vimのclone先を指定するsetruntimepath+=~/dotfiles/.vim/dein/repos/github.com/Shougo/dein.vimlet s:dein_dir = expand('~/dotfiles/.vim/dein')if dein#load_state(s:dein_dir)call dein#begin(s:dein_dir)call dein#load_toml(s:dein_dir . '/plugins.toml', {'lazy': 0})call dein#load_toml(s:dein_dir . '/lazy.toml', {'lazy': 1})call dein#end()call dein#save_state()endif

init.vimはこんな感じに書き換える。

~/dotfiles/.vim/dein/plugins.toml
[[plugins]]repo='Shougo/dein.vim'[[plugins]]# 非同期処理repo='Shougo/vimproc.vim'[[plugins]]# colorschemarepo='chriskempson/vim-tomorrow-theme'[[plugins]]# slimのハイライトrepo='slim-template/vim-slim'[[plugins]]# ES6のハイライトrepo='othree/yajs.vim'[[plugins]]# インデントを見やすくrepo='Yggdroot/indentLine'[[plugins]]# j,kによる移動を爆速にrepo='rhysd/accelerated-jk'
~/dotfiles/.vim/dein/lazy.toml
[[plugins]]# 補完repo='Shougo/neocomplete.vim'[[plugins]]# スニペットrepo='Shougo/neosnippet'[[plugins]]# スニペットrepo='Shougo/neosnippet-snippets'[[plugins]]# メソッドの定義元にジャンプrepo='szw/vim-tags'[[plugins]]# Rubyのend補完repo='tpope/vim-endwise'[[plugins]]# ローカル変数ハイライトrepo='todesking/ruby_hl_lvar.vim'

これでプラグイン管理が相当スッキリしました。
2年間放置していた.vimrcがかなりキレイになりました。

終わりに

  • NeoVim導入してみたけど、通常のVimと比べてすごい!!感動する!!という感じはない。
  • プラグインを色々入れては見るものの、普段からよく使っているものは少ないから定期的に整理したい。
  • .vimrc(init.vim)がかなり整理できたのが収穫。

CtagsでVimにタグジャンプ機能を追加する

$
0
0

ad_banner4.gif
このエントリーは、aratana Adventカレンダー13日目のエントリーです。

はじめまして!!
新卒一年目、Vim一年生の田村です。

前日は、@mt-kageさんの「はじめてのServerless ✕ Webpack ✕ TypeScript」というエントリーでした。
サーバーレスと聞いて、「サーバーはいらないけど、筋肉は必要」という迷言を思い出したのは私だけでしょうか。

私日々のコーディングは、Vimで行っており、操作や動作などで不満が出れば、解決しvimrcを育成しております。(vimrc Breederってやつです。聞いたこと無い

コードの処理を追っている中で、必ずと言ってもよいほど利用する定義元へのジャンプ
主要言語はだいたいプラグインを導入すればジャンプできますが、
マイナー言語のほとんどに、プラグインが作られておらず、定義元ジャンプができません。
grep使えばいいじゃんって声も聞こえて来そうですが、色々工程省ける定義元ジャンプのほうが(ry...
そこで、定義元ジャンプを使えるようにするCtagsを利用していきます。

やること

  • 標準で対応していない定義元ジャンプの設定
  • Vimで定義元ジャンプを実感!!
  • 楽するためのVim設定(関数とか書いてみる)

事前準備

  • Vim(まー標準で入っているでしょう)
  • Ctags(パッケージマネージャーなどで入れましょう)
  • ソースコードNaspSampleをダウンロード(DL直リンク
  • 解凍したNaspSampleディレクトリにいる状態 In 黒い画面
  • あ、対象は、Linux, Macとなっております(Windows翻訳できる方を除く)
  • ちょっとVimを触れる

ちなみに、Ctagsは

の2種類あります。

exuberant-ctagsの方は、更新が途絶えており、
universal-ctagsは、現在もメンテナンスされ続けています。
違いとしては、設定ファイルの場所とか、対応言語などです。
やっぱりオススメは、メンテナンスされているuniversal-ctagsですね。

Macなら、

exuberant-ctags
$ brew install ctags
universal-ctags
$ brew install --HEAD universal-ctags/universal-ctags/universal-ctags

universal-ctagsの主張が激しい。

事前vimrc

$HOME/.vimrcファイルに以下を追加設定しておいてください。
(文字コードを正しく認識して、動作不良を起こさないため)
※ 既に設定済みって方は不要です。

.vimrc
setfileformats=unix,dos,macsetfileencodings=utf-8,sjis

Ctagsというすごいやつ

Ctagsは、ソースファイルを解析してインデックスファイルを作成するプログラムです。
簡単に言い換えれば、関数や変数などの定義元へジャンプするためのファイルを作成するプログラムです。
標準でいくつかのプログラム言語に対応しています。

Ctagsを使ってみよう

実際に標準のCtagsを使ってみましょう!!
NaspSampleディレクトリで以下のコマンドを実行してから、
インデックスファイル(以後タグファイル)を作成できます。

bash
$ ctags -R -f .tags

.tagsファイルをエディタで開いて中身確認しても良いかも)

コマンド解説

  • ctagsctags実行。(そのまんま)
  • -Rは、現在ディレクトリから再帰的にファイルを解析していくオプション指定。 つまり、全ファイル見ますモード
  • -f .tags出力ファイル名を設定するオプション。(デフォルトは、tags

たった、これだけで便利な機能が使えるようになっちゃいます。

Vimでジャンプしてみる

では、先程作成したタグファイルを元にVimで定義元ジャンプを実感しましょう!!

やり方

  1. vim script/@ImgList.aspで該当ファイルをVimで開く
  2. :set tags=.tagsでタグファイルのパスを指定して
  3. 50gg OR 50Gで、50行へ飛ぶ
  4. 文字列rstにカーソルが乗った状態で、Ctrl-]でジャンプします。

定義元のdim rst:へ移動していると思います。
(そんなんgdでもいけるやんは、聞こえなかったことにします:thinking::ear:
正直このレベルでは、大したことないですね〜。

標準の限界

今回、ジャンプさせたい定義元を確認してみます。
script/@ImgList.aspファイルの28行(つまり、28gg OR 28G

script/@ImgList.asp
function OnDraw_Images(oNasp, vParam)

呼び出し元も確認してみます。
wwwroot/ImgList.aspの23行

wwwroot/ImgList.asp
    (#%Images|

です。ここで、OnDraw_Imagesを呼び出しています。
Vimを一回落としている場合は、
:set tags=.tagsをしましょう。

Imagesにカーソル合わせて、Ctrl-]でジャンプ!?

ん?なんかエラー出ていますね。
E426: tag not found: ImagesImagesというタグ無いですよって言われています。
Ctagsの標準では対応していないようですね。
では、Ctagsの設定をカスタマイズして飛べるようにしましょう!!

Ctagsカスタマイズ

Ctagsの設定ファイルを変更して、カスタマイズできます。
Ctagsの設定ファイルは、

  • exuberant-ctagsの場合は、$HOME/.ctags
  • universal-ctagsの場合は、$HOME/.ctags.d/configure.ctags

configure部分はなんでも良いっぽいです。

となっています。インストした方に合わせましょう。

考えられる解決方法は、

  1. OnDraw_Imagesをタグファイルへ登録
  2. ImagesOnDraw_Imagesを関連付ける

Ctags設定追加

では、設定ファイルに以下の一行を追加しましょう。

--regex-asp=/^[ \t]*(function)[ \t]+OnDraw_([a-zA-Z0-9_]+)/\2/r,ondraw/

この処理の意味をまとめると、

  • aspという言語に対してパターン追加
  • function OnDraw_hogehogeに一致する行をhogehogeとしてタグファイルに追加
  • ondrawというタグ種類で登録(識別子r

\2は、([a-zA-Z0-9_]+)を指しており、つまりhogehogeです。

これで、OnDraw_Imagesの箇所をタグファイルへ登録でき、Imagesで関連付け完了しました。

カスタマイズ後の確認

では、先程と同じことしてジャンプできるか確認してみましょう。

  1. ctags -R -f .tagsでタグファイル更新
  2. vim wwwroot/ImgList.asp
  3. :set tags=.tags
  4. 23ggで23行へ飛ぶ
  5. Images上でCtrl-]でジャンプ!!

パっと変わったと思いますパっと!!
ちなみに、Ctrl-tで元に戻れます。
Vimのタグジャンプは、スタックとして履歴残る感じなので、
Ctrl-]でpushして、Ctrl-tでpopする的な感じです。

無事ジャンプさせることができましたね!!
これを応用していけば、飛ばしたい場所に自由に飛べます。
IDEにも劣らぬジャンプ機能を手に入れることができました!!

ちなみに

インサートモードで、<Ctrl-x><Ctrl-]>を入力すると、タグリストの補完できます。
例えば、OnDrawまで入力した後に、<Ctrl-x><Ctrl-]>で、補完一覧がでてきます。
設定次第では、WordPressのアクションフック名の補完もできたりします。

問題点

ただ、いくつか面倒なところがありますね。。。

  • Vimを立ち上げる度に:set tags=.tags
  • ソースコードを変更する度に、タグファイル生成コマンド実行

さらに、極めつけには、ターミナル上でwwwrootへ移動した後、VimでImgList.aspを立ち上げ、同じようにすると、ジャンプ出来ません。
set tags=.ctagsと記入しているので、カレントディレクトリ直下の.tagsを探しており、wwwroot直下には、見つからないのでこのような現象になっています。こんなの使い物にならないじゃん!!

課題

とりあえず、現状の課題をまとめて見ました。

  • Vim立ち上げるたびset tags=.tags
  • タグファイルがあるディレクトリで、Vim立ち上げないとタグファイル読み込めない
  • ソース変更するたび、手動でインデックスファイル作り直し

では、これらすべて解決しましょう!

課題の解決

課題に対して一つずつ解決していきます!

vimrc設定

$HOME/.vimrcに記述すれば、Vim立ち上げ時に読み込まれるので、.vimrcに、set tags=.tagsを追加しましょう。

これで、立ち上げと一緒に実行されます。

が、しかし、カレントディレクトリにタグファイルがないといけません問題。

解決できそうな動作としては、
親ディレクトリを遡り.tagsがあるか探してから、あればそれを読み込む的な動作ができれば完璧ですね。
この動作は、Vimの標準でUpward searchあるので、それ使いましょう。
詳しくは、:h file-searchingの項目に書いてます。

以下の記述で、カレントディレクトリから、ホームディレクトリまで.tagsを探します。便利〜。

.vimrc
settags=.tags;$HOME

OR

.vimrc
settags=.tags;~

に変更しましょう。お好きな方で。

自動コマンド設定

次は、毎回タグファイル作るの面倒問題。
Vimには、指定イベントが行われたら自動的に実行されるコマンドを指定できる、
autocmdなるコマンドがあります。
これ使いましょう。

.vimrc
augroup ctags
  autocmd!
  autocmd BufWritePost * silent!ctags -R -f .tags
augroup END
  • augroupautocmd!は、簡単に説明すると、複数回autocmdが登録されるのを防ぐやつです。 詳しくは、おさらい autocmd/augroup
  • ファイル書き込み後にsilent !ctags -R -f .tags実行しますという意味
  • silentは、メッセージ出力させないよ。出力いらない。:spy:
  • !ctags -R -f .tags先頭にビックリマークで、外部プログラム実行するという意味

さらなる問題とその解決

これで、保存するたびインデックスファイル更新されるーっと思ったけど、
カレントディレクトリが変わったら、その直下に.tagsできちゃう問題発生。
これじゃ、ディレクトリ移動して保存するたびに.tags生まれちゃう!!

安心して作業できませんね。
読み込んでる.tagsファイルパスと同じ場所で生成できるようにしたいですね。

てことで関数作りました。

.vimrc
function! s:execute_ctags() abort  " 探すタグファイル名let tag_name ='.tags'  " ディレクトリを遡り、タグファイルを探し、パス取得let tags_path = findfile(tag_name,'.;')  " タグファイルパスが見つからなかった場合if tags_path ==# ''returnendif  " タグファイルのディレクトリパスを取得  " `:p:h`の部分は、:h filename-modifiersで確認let tags_dirpath = fnamemodify(tags_path,':p:h')  " 見つかったタグファイルのディレクトリに移動して、ctagsをバックグラウンド実行(エラー出力破棄)
  execute 'silent !cd' tags_dirpath '&& ctags -R -f' tag_name '2> /dev/null &'endfunction

これを、保存毎に実行するようにすれば良いので、
autocmd BufWritePost * call s:execute_ctags()
に変更します。
これで、快適にタグジャンプ生活を送れます。

現状のままだと、execute_ctags関数は、.ctags無かったら何もしないようになっています。
解決方法として、.ctagsが見つからなかった場合、

  • プロジェクトのルートに自動生成するようにする(.gitと同じ階層とか)
  • カレントディレクトリに生成するようにする(以降、生成したタグファイルを更新)

など、自分好みに改良していただければと思います。

.vimrc

.vimrc
setfileformats=unix,dos,macsetfileencodings=utf-8,sjissettags=.tags;$HOMEfunction! s:execute_ctags() abort  " 探すタグファイル名let tag_name ='.tags'  " ディレクトリを遡り、タグファイルを探し、パス取得let tags_path = findfile(tag_name,'.;')  " タグファイルパスが見つからなかった場合if tags_path ==# ''returnendif  " タグファイルのディレクトリパスを取得  " `:p:h`の部分は、:h filename-modifiersで確認let tags_dirpath = fnamemodify(tags_path,':p:h')  " 見つかったタグファイルのディレクトリに移動して、ctagsをバックグラウンド実行(エラー出力破棄)
  execute 'silent !cd' tags_dirpath '&& ctags -R -f' tag_name '2> /dev/null &'endfunction

augroup ctags
  autocmd!
  autocmd BufWritePost * call s:execute_ctags()
augroup END

ちなみに...

Tagbarというプラグインを入れると、右とかにタグ登録されたリストが表示され、選択することでその場所へ飛べます。

tagbar.png

つまり、CtagsとTagbarの設定をカスタマイズすることで、表示させたいリストを自分好みに変更することができるようになります。
CSSなら、セレクタ一覧とか。

さらに画像の左下に、現在カーソルがどこの関数に含まれるか表示させることもできます。
便利ですね。

最後に

思っていたよりもたくさん書いてしまいました。
CtagsとVimの素晴らしさを少しでも感じて頂けましたでしょうか。
Ctagsをカスタマイズして快適なVimジャンプライフを送りましょう。
これからも、さらにvimrcを育成していきます。

明日(14日目)のaratana Advent Calendar 2017のエントリーは、期待の新人@sakochiさんのエントリーです!お楽しみに!

vim-shiny という plugin を作った

$
0
0

はじめに

これはVim2 Advent Calendar 2017 13日目の記事です
前日の方に引き続き,自作vim pluginの紹介です.

VinConf2017 の感極まり駆動開発で,vim-shinyというプラグインを作成した.
今までに,いくつかプラグインを実装したことはあものの, そのほとんどが,syntax-highlightを行うためのもの (例えば,vim-jsx-pretty) だった.

そのため,あまりふさわしくないコードなどが含まれているかもしれない.

背景

Atomのpluginである,vim-mode-plus の紹介をVimConf2017でされているときに,視覚的にわかりやすいインタフェース,具体的には,モーションを活用してyankなどを行ったり,ペーストしたりした時に,フェードアニメーションが表示されるのはわかりやすいと感じた,
実用時にもわかりやすいし,デモのときなどもわかりやすい.
好みはあるが,Vimにもほしいという声は少なくないと思う.

また,Vimには,オペレーターに限ってこのようにハイライトする機能を提供しているプラグインはすでに存在していた.
(haya14busa/vim-operator-flashy)

今回は,vim-mode-plus と vim-operator-flashy を参考にしつつ,Vimをより視覚的にわかりやすくするためのプラグイン vim-shinyの実装を行った.

特徴

現在,vim-shinyが提供している機能を紹介する.

1つは,ペースト箇所のハイライトである.

  • ペースト時のハイライト

Paste demo

この機能は,'termguicolors'または,has('gui_running')のどちらかが有効なときに, g:vim_shiny_enable_fade_on_guiを有効することでフェードさせることができる.

Fade animation demo

  • ウィンドウ変更時のハイライト

change window demo

これは,colorcolumn を使って無理やり実装したので,あまり良くないと思う.
詳細は,次の章で触れる.

使い方

お好みのプラグインマネージャーで,本プラグインを導入した後に,vimrcに次の設定を追記..

nmap p<Plug>(shiny-p)
nmap P  <Plug>(shiny-P)
nmap gp<Plug>(shiny-gp)
nmap gP <Plug>(shiny-gP)

実装について

ペースト時のハイライト

いまは,色を決め打ちで決めているので,rgbaからカラーコード,カラーコードからrgbaに変換するような関数を実装し,指定されたhighlight groupの持っている色から,カラーコードを取得し,それをrgba に変換してalpha値を基準にフェード前後の色を自動で補完しても良いかもしれない.

実装は,結構原始的な実装方法をしており,(forループを回して,色を都度変更) 環境によってはハイライトが重かったりするかもしれない.

function! s:flash(patterns, group) abortleti=0forpina:patternsif getchar(1)breakendifcall s:Highlight.highlight('ShinyFlash' . i,a:group,p,1)leti+=1endforredrawcall s:clear(i)endfunction

部分的かつ一時的にハイライトする方法は,vim-operator-flashyを参考にした.
Vitalの外部拡張モジュールである,Coasterというものを使用した.

Coasterの作者さま,vim-operator-frashyの作者さま,ありがとうございました :bow:

ウィンドウ変更時のハイライト

少し前でも触れたが,ウィンドウ変更時のハイライトは 'colorcolumn'を利用している. 'colorcolumn'は,特定の列に hl-ColorColumnグループでハイライトするというものである.
通常,メールなど横幅に制限のある文章を書く時や,lintなどで1行にかける文字の量を制限しているときに活用する.

これを,1列目からWindow幅目までsetすることで,擬似的にマスクをかけたようにしている.

function! shiny#window#flash() abortforiin range(1, tabpagewinnr(tabpagenr(),'$'))let range =''ifi== winnr()letl:width =256letl:range =join(range(1,l:width),',')
      exec 'highlight! link ColorColumn ' . s:vim_shiny_hi_window_changecall setwinvar(i,'&colorcolumn', range)call s:clear()endifendforendfunction

tput コマンドで Window幅を取得しても良かったが,GUIのときどうなるか想像できなかったので,256と決め打ちにしている.

悩み

10p などをノーマルモードで押下したときのrange指定は対応したが,まだ ドットリピートに対応できていない.
ドットリピートができないのは結構致命的なので何らかの方法で実装したい.

プラグインでキーマッピングを提供したとき,それをドットリピートさせたいとき他の人はどうしてるのだろうか・・・?

他にも,undo や .で バッファの内容が増えることはよくあるだろう.
そのときに,どうにかしてハイライトしたいなーという思いがある.

両方,ドットリピートの話でややこしいのでまとめておく.

  • ペーストのマッピングを上書きしたあとでも .で繰り返しペーストさせたい
  • .によって何らかの文字列が挿入されたとき,その挿入された差分をハイライトさせたい

まとめ

  • vim-shinyというものを作った.
  • vim-mode-plusと比べるとハイライトしている箇所やハイライトのわかりやすさは現状劣っている.
  • 少しづつ良くしていきたい
    • ここ2ヶ月触れていないので,年末年始のまったりとした時間をつかって,これをいじって遊びたい.

�【2016年12月決定版】劇的に作業効率を上げるツール15選

$
0
0

はじめに

2016年も終盤に差し掛かってますが、皆さんに朗報があります:laughing:
下記のアプリをインストールして使いこなせるようになれば、2017年から本質的な仕事のみに集中することができるかと思います。

一度は考えたことがあるかもしれませんが、
自分の思考スピードとコンピューターの操作スピードを同じ速度にする 
ことで、思考の赴くままに成し遂げたいことができるようになるのではないでしょうか。
ぜひ、自分の思考スピードに追いつかせるようなコンピューター操作スキルを身につけましょう!

今回は、自分のMacBookProにインストールしているアプリの中で、
知らない人は使うべきだな〜と思ったアプリ10個Chrome拡張機能5つ独断と偏見で厳選して紹介します。
説明は極力省いてます。ですので、どんなことができるのかをまず知ってもらって良さそうであればググってください!

※「こっちの方がいいよ〜」などあれば、是非是非教えてください!!

背景

最近、社内でツールを共有したり、人のパソコンを設定する機会が増えてきたので、自分のパソコンに入っている便利ツールを公開することにしました。
この投稿により、少しでも多くの人に今年最後?の笑顔を届けられれば本望です笑

おすすめアプリ 10選 一覧

https://gyazo.com/175b67ee4bb5eb9d70d433ee93d63f71

説明app 名
作業効率向上Alfred
Windows単位での切り替えHyperSwitch
画面分割最適化Magnet
クリップボード履歴や定型文ClipMenu
Message系サービス一元管理Franz
タグ付けできるメモ帳Simplenote
プログラマ向けメモ帳Boostnote
画像加工・共有Skitch
To-Doリストとタスク管理Todoist
最大解像度設定QuickRes

おすすめChrome拡張機能 5選 一覧

https://gyazo.com/d2ea4723e0d35e9c9cdd0c6d36cb47cc

説明Google Chrome 拡張機能
マウスなしのブラウジングVimnium
Newspicks毎日無意識に読むNewsPicks公式ブラウザ
表示画面を下までpdf化Full Page Screen Capture
Webサイトのデザイン確認Search Preview
複数ページの一スクロール化Auto Pagerize

 おすすめアプリ10選

1. Alfred (作業効率向上)

https://gyazo.com/e8a5610727d23c403a94df646d2746dd

① 悩み

  • いつも特定のサイトを開くのに、chromeのタブをクリックしたりしながら辿らないといけないのは面倒くさい
  • keynoteやpdf、rubyファイルはFinderを開いて探さないと見つけられない

② 動作
https://gyazo.com/9748689dea6618e4b70e673302546e55

※ [engadget] -> [facebook] -> [github]を開きたい場合
※ よくわからないぐらい早いですが、実際こんなもんです。

③ 概要
事前に設定しておいたURLやFinder下のフォルダへ瞬時に飛ぶことができる

④ 設定例
1. スクリーンショットの瞬間共有Gyazoを開きたい場合は
[Alfredの起動] -> "gya" [Enter] # Gyazoの起動
2. pdf、pptやrubyファイルを一発で開きたい場合
[Alfredの起動] -> [Space] -> "ファイル名" [Enter]

⑤ 参考リンク


2. HyperSwitch (Windows単位での切り替え)

https://gyazo.com/8d9b1b6922d4e800da333f9d5d2d9951

① こんな悩みありませんか?

  • アプリ毎に移動する際は[Command] + [Tab]でやってるが、ブラウザ毎には移動ができない
  • 4つか5つのGoogle chromeのブラウザを開いており、移動をマウス操作でやっている

② 動作

Gyazo_-_yogokenのストックした投稿_-_Qiita.png

③ 概要
ブラウザ毎に画面を移動できる

④ 設定例
1. 移動
[Option] + [tab]

⑤ 参考リンク


3. Magnet (画面分割最適化)

https://gyazo.com/355abd3bf08567c1982b16f804a11872

① 悩み

  • 画面にブラウザだの、アプリだのが散在している
  • ワンコマンドで2 or 4アプリ同時に見れたらいいのになぁ〜

② 動作
https://gyazo.com/9f1b6dada1469b83bf8961b746cc71e4
※2分割

https://gyazo.com/b5fc51e43a7360c1efb9c4a17a110e72
※4分割

③ 概要
画面を2分割/4分割に瞬時に出来る

④ 設定例
1. 右半分、左半分
[Control] + [alt] + [← or →]
2. 四方向への配置
[Control] + [alt] + [j or k or i or u]
3. 全画面表示
[Control] + [alt] + [enter]

⑤ 参考リンク


4. ClipMenu (クリップボード履歴や定型文)

https://gyazo.com/5b1cd1a81812661731a0b077835bb989

① こんな悩みありませんか?

  • copy and pasteを連続してする場面で、以前コピーしたものを見たいけど上書きされてしまう。
  • フォーマットなど定型文をメモ帳に置いているが、正直探すのが大変。

② 動作
https://gyazo.com/5d19d3c518aedcdfd8096ea25e76ecbd

③ 概要
文をコピーした後に履歴に残し、すぐに使うことができる。
連続してコピーする作業、貼り付ける作業を分けて行うことができる。

④ 設定例
1. クリップメニューを表示
[Command] + [shift] + [v]

⑤ 参考リンク

-ダウンロード先


5. Franz (Message系サービス一元管理)

https://gyazo.com/b8c4958af5ad2ba2f6f72743c100fd3b

① 悩み

  • Facebookメッセンジャーだの、Slackだの、gmailだの、ブラウザやアプリがパソコンの画面を占領している。。。
  • Chat系アプリでいい感じに一元管理できるものがあればなぁ。。。

② 動作
https://gyazo.com/380540d673bfb30ace6bd2ac700ab6a5

https://gyazo.com/22284f19406cac2c4db136d8ed5d036e

③ 概要
Chat系アプリを一元管理できる。(LINEが入ってないのは残念。。。)

④ 設定例
1.トップにあるタブ移動
[Option] + [Command] + [← or →]

⑤ 参考リンク


6. Simplenote (タグ付けできるメモ帳)

https://gyazo.com/489b65bedbcba32fa6f1e11dfb6ea6ec

① 悩み

  • デフォルトのメモ帳を使っているが整理できていない
  • タブ機能があれば検索や必要な情報を探すのが早いのに。。。

② 動作

https://gyazo.com/ebb7f69b9e92cadc1918cff2e40d8845

③ 概要
タグをつけてメモを残せるため、種類ごとにメモを保存することができる

④ 設定例
1. 検索
[Command] + [Option] + [f]

⑤ 参考リンク


7. Boostnote (プログラマ向けメモ帳)

https://gyazo.com/4a3759d45a1ce3054ea6b2c6b32a7872

① 悩み

  • ソースコードをメモ帳にメモってるが、正直可読性が低くて困っている
  • マークダウンでかけるメモ帳があればいいのにな〜

② 動作

https://gyazo.com/b6859c1e5496520714dd1c376ec3d22a

③ 概要
マークダウンでメモが取れるため、rubyなどで書かれたコードをストックしたりすることができる。
タグ付けやカテゴリー別に分けられ、Simplenoteのマークダウン版だと思っていただければわかりやすいかと。

④ 参考リンク


8. Skitch (画像加工・共有)

https://gyazo.com/de21d390d0db7f70609d4ccb311b0869

① 悩み

  • 画像で送られてきたものに対して、その画面の特定の箇所に矢印でも引いてアドバイスしたい
  • 画像と文字をセットにした形で人に送りたい

② 動作
https://gyazo.com/4e83d8edab1d37ce07405fac699220c0

③ 概要
アップロードされた画像に対して、矢印や文言などを瞬時に追加でき、PDF化やコピーが簡単にできる

④ 参考リンク


9. Todoist (To-Doリストとタスク管理)

https://gyazo.com/f8445a62a6438a46e42763135830f267

① 悩み

  • Todo管理ツールいろいろあるけど、結局紙かメモアプリに書いている
  • 簡単に参照、追加、削除ができる機能だけあればいいのに。。。

② 動作
https://gyazo.com/6d0dae639087107133224c552839947a

③ 概要
ワンコマンドでタスクを追加でき、完了したものをすぐに削除できる

④ 設定例
1. 表示
[Control] + [t]
2. タスクの追加
[Control] + [u]

⑤ 参考リンク


10. Quickres (最大解像度設定)

https://gyazo.com/0087b69deea27dda2b39dab10e9d06bc

① 悩み

  • 画面の文字が小さくてももっと広範囲の箇所を見たい。。。
  • 解像度をデフォルトより高くしたい

② 動作

Cursor_と_applications_key.png

③ 概要
自由に画面の解像度を変更できる。
システム環境設定からは設定ができない特殊な解像度も選択できます。
特徴としては、Retina非搭載機能にも対応していることにより、擬似的な解像度の拡大ができてしまいます。

④ 参考リンク

 おすすめChrome拡張機能 5選

1. Vimnium (マウスなしのブラウジング)

https://gyazo.com/7fed84e0a6ea02500f333bdca49c1a7d

① 悩み

  • 次のページに遷移するときに、わざわざトラックパットでリンクを押すのが面倒だ
  • 下にスクロールするのをトラックパットでやってるが、キーボードから手が離れるのが嫌だ

② 動作
https://gyazo.com/5d6cf2c8196e50f0b4ce7ed91fe40861

※[i]→[k]→[i]、実際と同じ速さです。

③ 概要
マウスを使わなくても、ブラウザの移動ができるようになる。

④ 設定例
1. どのリンクをクリックするのかわかるようにアルファベットを表示させる
[i]
2. 上下にスクロール
[j]
[k]

⑤ 参考リンク


2. Newspicks (毎日無意識に読む NewsPicks公式ブラウザ)

https://gyazo.com/91cbeb297c4f6f42bd7bd96662045801

① 悩み

  • 毎日NewspicksのニュースサイトのURLを打って、記事を読んでいたがちょっと面倒くさい
  • Google Chromeで【Command + N】で新しいタブ開いたら見れたらいいな〜

② 動作
https://gyazo.com/0fc5a8fc2bf499b9a40799fa4d1d7fc0

③ 概要
【Command + N】で新たなタブを開く際に、Newspicksの記事が表紙されるため、
意識しなくても、ホットトピックが目に入ってくる。

④ 参考リンク


3. Full Page Screen Capture (表示画面を下までpdf化)

https://gyazo.com/c07c1382d2dc1fdd98cd16c868e1ef5f

① 悩み

  • 上下までスクロールしたデータ全体をpdfかして送信したい

② 動作
https://gyazo.com/4dfa77ac7ad1b2036018f964f9d33a4c

③ 概要
ブラウザの最上部から最下部まで、ワンクリックでpdf化することができる

④ 参考リンク


4. SearchPreview (Webサイトのデザイン確認)

https://gyazo.com/200b75bdd1e98fd22dcccaf2f069a3be

① 悩み

  • 調べ物をする際に、遷移先の雰囲気も一緒に知りたい

② 動作
https://gyazo.com/cc12b17c4ecdaa1339a13027e0efd06c

③ 概要
画像を文面の左側に表示してくれる

④ 参考リンク


5. Auto Pagerize (複数ページの一スクロール化)

https://gyazo.com/50183909bc8038b900259580ce4e8d97
① 悩み

  • google検索の下にあるこれを一々クリックするの面倒だな〜

https://gyazo.com/11edca0534975b3a12e45f254ce054d3

② 動作

https://gyazo.com/e4f8644c91a9a4170c63928668536261

③ 概要
スクロールしているうちに、自動的に次のページが表示されるようになる

④ 参考リンク


最後に

最後まで見て頂きありがとうございます。
15個中最低1つは新しいツールの発見があったのではないでしょうか?:laughing:

今回は簡単なツールの紹介なため詳細な利用方法に関して言及しませんでしたが、

優れたツールは感覚的にユーザーが操作できるようになっている
と個人的に思っているので、googleで調べたりすればすぐに使えるようになると思います!!:bowtie:

ぜひ、今年中に使いこなせるようになって、
2017年は飛躍的に成長する年にしましょう!!

では、良いお年を!!


Deniteのソースを作ろう

$
0
0

Deniteとは?

まずは軽くDeniteについて紹介します。
Vim8/Neovimのプラグインの一つです。
Uniteの後継プラグインです。
「ある一覧から特定のデータを検索してアクションを実行する」ことができます。

例えば標準機能である、「ファイル一覧からファイルを検索、選択して開く」です。
このファイル一覧のことをソースと言います。
Deniteはこのソースなどを自分で開発し追加することができます。
ここまではUniteもDeniteも同じですね。

UniteはVim scriptで実装されており、速度が出ないという問題がありました。また複雑化によりメンテが困難になったという話を聞いたことがあります。
そこでDeniteが生まれました。コア機能はPythonで実装されており、理論上Uniteより高速に動作するようになったようです。
またUniteは開発が終了しておりDeniteを使用することが勧められているようです。

Note: Active development on unite.vim has stopped. The only future changes will be bug fixes.
Please see Denite.nvim.

以下は有志で紹介されている外部プラグインの一覧です。
https://github.com/Shougo/unite.vim/wiki/unite-plugins
https://github.com/Shougo/denite.nvim/wiki/External-Sources
ここに記載されていないものもありますが、DeniteとUniteを比べるとDeniteは外部プラグインの開発がまだまだ進んでいません。

そこでDeniteのソースの開発方法を軽く説明しようと思います。

ソースの作り方

DeniteのソースはPython3で書きます。私はPythonについて然程詳しくありません。
なので今回はPythonについての説明などは省きます。
またDeniteのソースコード自体はあまり読んでいないので、曖昧な箇所があります。
確実でない箇所について「思います。」と表現していますので予めご了承ください。

ソースを作るにあたって

Deniteでは、
1. 何かの一覧を取得する
2. 検索・選択する
3. アクションを実行する

のが基本でした。まずは何の一覧を取得して、どういうアクションがしたいのか決めましょう。
今回はALEの結果を一覧として使いたいとします。
ALEは非同期にlintを走らせるプラグインです。
アクションはlintの警告などがあった箇所にジャンプするにします。
:Denite aleと実行したいのでソース名はaleとします。

調査

少し調べた結果、ALEの結果を取得するメソッドがale#engine#GetLoclistだということが分かりました。引数はバッファ番号でした。
結果にはバッファ番号、行番号、カラム、結果のテキスト、タイプなどが入っています。
検索対象は「結果のテキスト」にしてジャンプ先は「バッファ番号、行番号、カラム」としましょう。

また、このアクションをDeniteで実現するにはfile kindが良さそうという事が分かりました。(:help denite-kind-file)
kindについては後で簡単に説明します。

準備

:help denite-create-sourceを参考に作っていきます。
さてファイル構成を見てみましょう。

.
├── rplugin/
│   └── python3/
│   └── denite/
│   └── source/
│   └── ale.py
├── LICENSE
└── README.md

LICENSEやREADMEは必要に応じて配置してください。
rplugin/python3/denite/source/*.pyに開発したいソースのファイルを配置します。ale.pyがソースを定義しているファイルです。
ソース名と同一のファイル名にすると分かりやすいでしょう。

では、コーディング。

ソースにはBaseクラスがあり、これを継承する必要があります。
https://github.com/Shougo/denite.nvim/blob/1fd1217f928721255d7c671205e35a4b9e3d6d4f/rplugin/python3/denite/source/base.py
クラス名はSourceにすると自動で読み込んでくれるのでSourceにしました。

# -*- coding: utf-8 -*-from.baseimportBaseclassSource(Base):

__init__ / コンストラクタ

ソースの初期化メソッドになります。
ソースをDeniteに登録する時に呼ばれると思っています。

def__init__(self,vim):super().__init__(vim)self.name='ale'self.kind='file'

親のコンストラクタを呼ぶ必要があります。(デフォルト値の設定がされます)
またselfに設定して効果があるものに、name(必須), kind, syntax_name, max_candidatesなどがあります。
詳しくは:help denite-source-attribute-__init__の辺りを参照してください。

nameはソース名です。aleを設定しました。
これで:Denite aleと呼び出す事ができます。

kindにはkind名かKindクラスを指定します。kindを指定するとそのkindが持つactionを実行したりできます。デフォルトはbaseだったと思います。
kindもソースと同じ様に独自実装することができますが、今回は紹介しません。
詳しく知りたければ:help denite-create-kindを参照してください。

今回はALEの結果の一覧からファイルを開いて警告なりが出ている箇所にジャンプしたいので、fileを設定しました。file kindのデフォルトのアクションはopenです。
ファイルを開くという事になりますが、行やカラムを指定することで開いた後にジャンプすることも可能です。

on_init

ソースの初期化時に実行されます。Deniteコマンドが実行されたときに呼ばれると思います。
似たものにon_closeがあります。

defon_init(self,context):context['__bufnr']=str(self.vim.call('bufnr','%'))

contextはコンテキスト情報をディクショナリで保持しています。
主な情報として、input, args, candidates, eventなどがあります。
詳細は:help denite-notation-{context}を参照してください。

コマンド実行時のバッファ番号を取得したかったので、contextに保持させています。
尚、元々使われているkeyと被らないように__をprefixとして付けるようにしています。

gather_candidates / _convert

gather_candidatesは候補一覧を返すメソッドです。
候補一覧はリストで、リストの中身(候補情報)はディクショナリです。
ALEの情報を取得し、候補一覧に変換(_convert)し、それを返しています。

defgather_candidates(self,context):loclist=self.vim.call('ale#engine#GetLoclist',context['__bufnr'])return[self._convert(loc)forlocinloclist]def_convert(self,info):abbr='[%d:%d] %s'%(info['lnum'],info['col'],info['text'])return{'word':info['text'],'abbr':abbr,'action__path':self.vim.call('bufname',info['bufnr']),'action__line':info['lnum'],'action__col':info['col']}

候補情報にはword(必須), abbrが設定できます。
wordは表示・検索対象です。abbrを設定するとこちらを優先して表示します。
ただしabbrは検索対象にはなりません。
また、候補情報にはアクションに必要な情報を付加する事ができます。(action__xxx)
詳しくは:help denite-source-attribute-gather_candidates:help denite-candidate-attributesを参照してください。
調査済みのale#engine#GetLoclistvim.callで呼ぶ事で結果を取得できます。
このまま返してもDeniteがうまく処理できないので、_convertで候補情報に変換します。
最初はtextだけあればいいかと思っていたんですが、行・カラムの番号があると分かりやすいのでフォーマットしてabbrに設定しました。
ところでkindはfileでしたね。
:help denite-kind-fileに書いてありますが、action__pathが必須で、action__lineaction__colを指定することで、その箇所にジャンプすることができます。
ALEの結果情報から設定しています。

成果物

できあがったものはこちらです。

ale.py
# -*- coding: utf-8 -*-from.baseimportBaseclassSource(Base):def__init__(self,vim):super().__init__(vim)self.name='ale'self.kind='file'defon_init(self,context):context['__bufnr']=str(self.vim.call('bufnr','%'))defgather_candidates(self,context):loclist=self.vim.call('ale#engine#GetLoclist',context['__bufnr'])return[self._convert(loc)forlocinloclist]def_convert(self,info):abbr='[%d:%d] %s'%(info['lnum'],info['col'],info['text'])return{'word':info['text'],'abbr':abbr,'action__path':self.vim.call('bufname',info['bufnr']),'action__line':info['lnum'],'action__col':info['col']}

比較的簡単にできましたね。
という訳で、皆さんも何かDeniteのソースを作ってみましょう!
基本構成はUniteのソースと変わらないので、Uniteのソースを移植してみてもいいかもしれません。

全角入力のままノーマルモードに戻ってもすぐコマンド打てるよ: Vim

$
0
0

目的

何が何でも全角入力してノーマルモードに戻っても、IMEを切り替えるコマンドを押さずにすぐコマンド打ちたい

設定ファイル

FromEscapeToJapanese_eisuu.json
{"title":"Terminal等でESCあるいは^[で日本語入力を英数に","rules":[{"description":"TerminalまたはMacVimでESCあるいは^[を押したときに日本語入力を英数に切り替える。","manipulators":[{"type":"basic","from":{"key_code":"escape","modifiers":{"optional":["any"]}},"to":[{"key_code":"japanese_eisuu"},{"key_code":"escape"}],"conditions":[{"type":"frontmost_application_if","bundle_identifiers":["^com\\.apple\\.Terminal$","^org\\.vim\\.","^com\\.googlecode\\.iterm2$"]}]},{"type":"basic","from":{"key_code":"close_bracket","modifiers":{"mandatory":["left_control"]}},"to":[{"key_code":"japanese_eisuu"},{"key_code":"escape"}],"conditions":[{"type":"frontmost_application_if","bundle_identifiers":["^com\\.apple\\.Terminal$","^org\\.vim\\.","^com\\.googlecode\\.iterm2$"]}]}]}]}

手順

まずこれに沿ってください
しかし、リンク先の設定ファイルのままだと最新は動かなかったので、設定ファイルは上記のをコピペしてください
それだけです
https://qiita.com/takaeda/items/38ecf7d98d1a3ef99ef0

最後に

Karabinerよ、よくSierraにも対応してくれた。。。。!!!

VimでPHPの開発環境をサクッと整える

$
0
0

普段、複数の環境(例えば、PHPとRuby、PHPとgolangなど)で開発を行う場合、
IDEだとPHPStormや、RubyMineなど、各開発環境に応じてエディタを切り替えて利用することになり、
手間に感じることが多々あります。

ただし、Vimを使っていればこういったスイッチングコストはゼロでコーディングを行うことが可能です。

そこで、VimでPHPの開発を行う際に、プラグインを使わなくても、ちょっとだけ楽ができる設定をいくつかご紹介したいと思います。

インデントの設定をする

プロジェクトや言語によってコーディングルールのインデント幅が違ってきたりします。
毎度、設定するのは面倒なので、ファイルの拡張子によって自動で切り替えられるようにしておきます。

augroup vimrc-filetype
  autocmd!  " PHPだったらインデント幅が4で
  autocmd BufNewFile,BufRead *.php setfiletype=php
  autocmd FileType php setlocalexpandtabtabstop=4softtabstop=4shiftwidth=4  " Rubyだったらインデント幅は2にしたい
  autocmd BufNewFile,BufRead *.rb setfiletype=ruby
  autocmd BufNewFile,BufRead *.rubysetfiletype=ruby
  autocmd FileTyperubysetlocalexpandtabtabstop=2softtabstop=2shiftwidth=2
augroup END

PHP lintを使う

PHPのlintもphp7ccphanなど色々ありますが、ここではPHP標準の機能を使ってみます。
PHPでコマンドラインからシンタックスチェックを行うには下記のコマンドです。

$ php -l <filename>

ただし、これをコマンドラインから毎度叩くのは手間なので、下記のような設定をしておきます。

function! s:PHPLint()let s:result = system('php -l ' . bufname(""))let s:count = split(s:result,"\n")
  echo s:resultendfunction

augroup php-lint
  autocmd!
  autocmd BufWritePost *.php call<SID>PHPLint()
augroup END

こうすることで、カレントバッファを保存するタイミングでシンタックスチェックを行なってくれます。

universal-ctagsを使う

プロジェクトのサイズがそれなりになったり、フレームワークの仕様を確認したい場合など、
コードリーディングを行う場面は頻繁に訪れます。
universal-ctags1を使ってtagsファイルを作成しておけば、
クラス名や、メソッド名等でジャンプでき、コードリーディングが捗ります。
tagsファイルを生成するには下記のコマンドです。

$ ctags -R

ただし、これをコマンドラインから毎度叩くのは手間なので、下記のような設定をしておきます。

function! s:generateCtags()let s:options='/path/to/.ctags'"ctagsの設定ファイルへのパスlet s:command = [
    \'ctags',
    \'-f',
    \'/path/to/tags',"tagsファイルへのパス
  \]let s:command += s:optionscall job_start(s:command)endfunctionnnoremap<silent><Leader>gt :<C-u>call<SID>generateCtags()<CR>

これで任意のタイミングでtagsファイルを生成できます。
また、gitのフックを利用してclone時などに生成するようにしたりしておくと、さらに便利かもしれませんね。

こんな感じでVimなら、普段触れていない言語でも必要に応じて開発環境を気軽に整えることができるでしょう。


  1. 本家であるctagsは更新が滞っているようなので、最近はuniversal-ctagsの方を使っています。 

xargsで受け取った複数のファイル名をvimで開く(BSD系以外の場合)

$
0
0

TL;DR

シェルでfind、grep等をパイプしてxargsで受け取ってvimで開くには、
find . -type f -name hoge | xargs sh -c 'vim $* < /dev/tty'
とすれば良い。
これを毎回書くのは面倒なので、
alias xargsvim='xargs sh -c '\''vim $* < /dev/tty'\'''
とエイリアスを作っておくと
find . -type f -name hoge | xargsvim
と書けて便利。

背景

上記以外に言うべきことはほとんど無いのですが、背景を少し。
同じことを実現するために、素直に
find . -type f -name hoge | xargs vim
とすると、「Vim: Warning: Input is not from a terminal」という警告が出る上に、以降、ターミナルへの入力がおかしくなります。

仕方ないので
vim `find . -type f -name hoge`
とやっていたのですが、この方法だと途中でパスの補完が効かなかったり不便です。

そんな折に、こちらの記事を見つけました。
ファイル名をパイプで出力してvimで開く方法
(xargs vimでターミナルがおかしくなる理由も書いてありますので、興味のある人はぜひ読んでみてください)

find . -type f -name hoge | xargs -o vim
と、-oオプションを付けるだけでOKとのこと。
「おー、こういうのが欲しかったんだよ」思ったのですが、これはBSD系固有のオプションのようです。
https://linuxjm.osdn.jp/html/GNU_findutils/man1/xargs.1.html

という訳で、素直に環境に依存しない形式で、-oオプション相当のことを実現するエイリアスを作ればいい、という結論になりました。

Neovimと闇の力を手に入れる

$
0
0

経緯

今使っているvimプラグインの開発が止まったのでさすがに引っ越したい(そして闇:zap:の力を手に入れたい)
https://github.com/Shougo/neocomplete.vim
https://github.com/Shougo/neobundle.vim

やりたいこと

  • あまり時間をかけずに最低限使える状態でNeovimに移行
  • 雑な状態でもRailsの開発はできるようにしたい
  • 最低限、denite(ファイラ)、deoplete(補完)は使いたい

環境

$ sw_vers
ProductName:    Mac OS X
ProductVersion: 10.12.6
BuildVersion:   16G29

設定方法

.zshrc に ↓を追加

$ export XDG_CONFIG_HOME="$HOME/.config"

Neovimをinstall

$ brew install neovim

python3をinstall

$ brew install python3
$ pip3 install --upgrade neovim

dein.nvimをinstall

$ curl https://raw.githubusercontent.com/Shougo/dein.vim/master/bin/installer.sh > installer.sh
$ sh ./installer.sh {任意のディレクトリ}

設定を追加

~/.config/nvim/init.vimは Neovim版の .vimrc

~/.config/nvim/init.vim
" reset augroup
augroup MyAutoCmd
    autocmd!
augroup END

let $CACHE = empty($XDG_CACHE_HOME) ? expand('$HOME/.cache') : $XDG_CACHE_HOME
let $CONFIG = empty($XDG_CONFIG_HOME) ? expand('$HOME/.config') : $XDG_CONFIG_HOME
let $DATA = empty($XDG_DATA_HOME) ? expand('$HOME/.local/share') : $XDG_DATA_HOME

" {{{ dein
let s:dein_dir = expand('$DATA/dein')

if &runtimepath !~# '/dein.vim'
    let s:dein_repo_dir = s:dein_dir . '/repos/github.com/Shougo/dein.vim'

    " Auto Download
    if !isdirectory(s:dein_repo_dir)
        call system('git clone https://github.com/Shougo/dein.vim ' . shellescape(s:dein_repo_dir))
    endif

    execute 'set runtimepath^=' . s:dein_repo_dir
endif


" dein.vim settings

if dein#load_state(s:dein_dir)
    call dein#begin(s:dein_dir)

    let s:toml_dir = expand('$CONFIG/dein')

    call dein#load_toml(s:toml_dir . '/plugins.toml', {'lazy': 0})
    call dein#load_toml(s:toml_dir . '/lazy.toml', {'lazy': 1})

    call dein#end()
    call dein#save_state()
endif

if has('vim_starting') && dein#check_install()
    call dein#install()
endif
" }}}
nmap <silent> <C-e> :NERDTreeToggle<CR>

" denite
let g:denite_enable_start_insert=1
let g:denite_source_history_yank_enable =1
let g:denite_source_file_mru_limit = 200
nnoremap <C-t> :<C-u>Denite buffer<CR>
nnoremap <silent> ,ur :<C-u>Denite file_rec<CR>
nnoremap <silent> ,um :<C-u>Denite file_mru <CR>
nnoremap <silent> ,urc :<C-u>Denite file_rec:app/controllers/<CR><Space>
nnoremap <silent> ,urm :<C-u>Denite file_rec:app/models/ <CR><Space>
nnoremap <silent> ,urv :<C-u>Denite file_rec:app/views/ <CR><Space>
nnoremap <silent> ,urs :<C-u>Denite file_rec:app/assets/stylesheets/ <CR>
nnoremap <silent> ,urj :<C-u>Denite file_rec:app/assets/javascripts/ <CR>
~/.config/dein/plugins.toml
[[plugins]]repo='Shougo/dein.vim'[[plugins]]repo='w0ng/vim-hybrid'[[plugins]]repo='itchyny/lightline.vim'hook_add='''letg:lightline={'colorscheme':'wombat'}'''[[plugins]]repo='cespare/vim-toml'[[plugins]]repo='fatih/vim-go'[[plugins]]repo='scrooloose/nerdtree'[[plugins]]repo='Shougo/neosnippet-snippets'
dotfiles/.config/dein/lazy.toml
[[plugins]]repo='Shougo/denite.nvim'on_cmd='Denite'on_i=1hook_source='''calldenite#custom#map('insert', '<c-n>', '<denite:move_to_next_line>', 'noremap')calldenite#custom#map('insert', '<c-p>', '<denite:move_to_previous_line>', 'noremap')'''[[plugins]]# Plugin to easily access Most Recently Used (MRU) filesrepo='Shougo/neomru.vim'on_source='denite.nvim'on_path='.*'[[plugins]]# Yankrepo='Shougo/neoyank.vim'on_source='denite.nvim'on_event='TextYankPost'[[plugins]]repo='Shougo/deoplete.nvim'hook_source='''letg:deoplete#enable_at_startup = 1inoremap<expr><tab>pumvisible()?"\<C-n>":\neosnippet#expandable_or_jumpable() ?\"\<Plug>(neosnippet_expand_or_jump)":"\<tab>"'''on_i=1[[plugins]]repo='Shougo/neosnippet'hook_source='''imap<C-k><Plug>(neosnippet_expand_or_jump)smap<C-k><Plug>(neosnippet_expand_or_jump)xmap<C-k><Plug>(neosnippet_expand_target)ifhas('conceal')setconceallevel=2concealcursor=nivendif'''on_i=1on_ft=['snippet']depends=['neosnippet-snippets']

参考URL

https://github.com/Shougo/dein.vim
https://qiita.com/takezo/items/809d53ecd37c438bac9e

おわりに

とりあえず動く状態まで持って行きたかったので書き方とかおかしい場合はこっそり教えてもらえると助かります
年末あたりに開発環境をもっと改善したい

Viewing all 5608 articles
Browse latest View live


<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>