Vim シンプルなVimプラグインマネージャを書いた
既存のプラグインマネージャー使用した状態で自分の書くプラグインの修正に手間取ったり高機能すぎて何をしているのか把握できなかったり起動が遅くなったりしたのでシンプルなVimプラグインマネージャを書いた
あとプラグインの設定もプラグインマネージャにaddした直後に書きたかった
Linuxで複数ユーザーでいろいろとテストをしたいのでg:spm_repodirに共有ディレクトリを設定してレポジトリは一箇所に置いているがうまくいっている
自分が自分の書いたプラグインマネージャを使っている事を忘れるぐらいにはちゃんとしている
gvimのmru.vimでmenu.vim:120行あたりのhas("printer")のセクションで文句言うもんでコメントアウトしといたぐらい
Simple Plugin Manager で spm
概要
- クローンしてruntimepathに追加するだけ
- silient executeやvim#procで非同期など難しい事をしてないので全てが"見える"
動作確認
OS | APP | res |
---|---|---|
CentOS7.5 | Neovim 0.2.2 | ◯ |
macOS High Sierra | MacVim 8.0 | ◯ |
macOS High Sierra | Neovim 0.2.2 | ◯ |
Windows10 | KaoriYa Vim 8.0 | ◯ |
functions
function | action |
---|---|
call spm#clone(url) | urlを'git clone {url} {uri}'する {uri}はg:spm_repodirのディレクトリの位置+uri ~/.vim/repos/github.com/naoyuki1019/vim-spmみたいな |
call spm#clone() | vimrcに書いてある全てのURLを'git clone {url}'する |
call spm#pull(string) | clone済みのレポジトリを'git pull'する stringにnaoyukiと入れるとurlにnaoyukiを含むレポジトリをpullするか一つ一つconfirmが出る |
call spm#pull() | spm#clone(url)で設定されている全てのレポジトリを'git pull'する 一つ一つconfirmが出る |
call spm#status() | レポジトリのclone状況が確認できる |
spm#status()は新規レポジトリをcloneしたときもVimEnterで実行される
削除は?
削除は自分は必要ない
消す時は:!rm -rf xxxxx
でいい
Setting
add .vimrc
let g:spm_repodir = '~/.vim/repos' let s:spm_dir = '~/.vim/spm' if filereadable(fnamemodify(s:spm_dir,':p').'autoload/spm.vim') "{{{ execute 'set runtimepath+='.s:spm_dir "--------------------------------------------------------- " plugin 1 call spm#clone('https://github.com/Shougo/unite.vim') " plugin 1 settings let g:unite_enable_start_insert = 0 " plugin 2 call spm#clone('https://github.com/Shougo/neomru.vim') " plugin 2 settings let g:unite_source_file_mru_limit = 1000 " plugin 3 call spm#clone('https://github.com/thinca/vim-qfreplace') " plugin 3 settings let ...... " plugin 4 call spm#clone('https://github.com/tacroe/unite-mark') " plugin 4 settings let ...... .... ... .. . "--------------------------------------------------------- endif .... ... .. . filetype plugin indent on syntax enable
Github
ソースコードそのまま
scriptencoding utf-8 "/** " * @file spm.vim " * @author naoyuki onishi <naoyuki1019 at gmail.com> " * @version 1.0 " */ if exists("g:loaded_spm") finish endif let g:loaded_spm = 1 let s:save_cpo = &cpo set cpo&vim if has("win32") || has("win95") || has("win64") || has("win16") let s:is_win = 1 let s:ds = '\' else let s:is_win = 0 let s:ds = '/' endif if !exists('g:spm_repodir') let g:spm_repodir = fnamemodify(expand('<sfile>:p:h').'/../repos', ':p') endif let g:spm_dict = {} let s:loaded = 0 let s:clone_onload_list = [] let s:clone_list = [] augroup augroup#SPM autocmd! autocmd VimEnter * call s:VimEnter() augroup END function spm#status() let l:list = [] for [l:url, l:dict] in items(g:spm_dict) call add(l:list, l:url) endfor call sort(l:list) call s:show_clone_info(l:list) endfunction function s:VimEnter() let s:loaded = 1 call s:show_clone_info(s:clone_onload_list) endfunction function s:show_clone_info(list) "{{{ let l:list = a:list if 0 < len(a:list) let l:msg = [] call add(l:msg, '"--------------------------------------------------') call add(l:msg, '" Simple Plugin Manager') call add(l:msg, '" local: '.g:spm_repodir ) call add(l:msg, '"--------------------------------------------------') for l:url in a:list call add(l:msg, ' |') call add(l:msg, 'remote | '.l:url) call add(l:msg, 'message| '.g:spm_dict[l:url]['msg']) endfor call add(l:msg, ' |') if has('gui_running') && 1 == s:is_win call confirm(join(l:msg, "\n")) else echo join(l:msg, "\n") endif endif endfunction "}}} function! s:uri(url) let l:n = match(a:url, '://') let l:dir = a:url[l:n+3:] return substitute(l:dir, ':', '-', "g") endfunction function! s:fix_ds(path) let l:path = a:path let l:path = substitute(l:path, '\v\/{2,}', '/', 'g') if 1 == s:is_win let l:path = substitute(l:path, '\/', '\\', 'g') endif return l:path endfunction function! s:rm_tail_ds(dir) let l:dir = a:dir let l:len = strlen(a:dir) let l:tail = l:dir[l:len-1] if '/' == l:tail || '\' == l:tail let l:dir = l:dir[0:l:len-2] endif return l:dir endfunction function! s:add_tail_ds(dir) let l:dir = a:dir let l:len = strlen(a:dir) let l:tail = l:dir[l:len-1] if '/' != l:tail && '\' != l:tail let l:dir .= s:ds endif return l:dir endfunction function! spm#pull(...) "{{{ if 1 > a:0 let l:s = '.*' else let l:s = join(a:000, ' ') let l:s = substitute(l:s, '\v([^\.])\*', '\1.\*', 'g') let l:s = substitute(l:s, '\v([^\\])\.([^\*])', '\\.', 'g') let l:s = substitute(l:s, '\v\s{1,}', '.*', 'g') endif let l:unmatchall = 1 for [l:url, l:dict] in items(g:spm_dict) let l:n = match(l:url, l:s) if -1 < l:n let l:unmatchall = 0 let l:dir = fnamemodify(l:dict['dir'], ':p') if 1 == s:is_win let l:drive = l:dir[:stridx(l:dir, ':')] let l:execute = '!'.l:drive.' & cd '.shellescape(l:dir).' & git pull' else let l:execute = '!cd '.shellescape(l:dir).'; git pull' endif let l:conf = confirm('execute? ['.l:execute.']', "Yyes\nNno") if 1 != l:conf continue endif execute l:execute endif endfor if 1 == l:unmatchall call confirm('there was no match url') endif endfunction "}}} function! spm#clone(...) if 1 > a:0 let s:clone_list = [] for [l:url, l:dict] in items(g:spm_dict) call spm#clone(l:url) endfor call s:show_clone_info(s:clone_list) return endif let l:url = a:000[0] let l:dir = g:spm_repodir.'/'.s:uri(l:url) let l:dir = s:fix_ds(l:dir) let l:dir = fnamemodify(l:dir, ':p') let l:dir = s:rm_tail_ds(l:dir) let g:spm_dict[l:url] = { \'dir': l:dir, \'sts': 0, \'msg': '' \} call add(s:clone_list, l:url) if !isdirectory(s:add_tail_ds(g:spm_dict[l:url]['dir']).'.git') call add(s:clone_onload_list, l:url) let l:git_clone = s:git_clone(l:url, g:spm_dict[l:url]['dir']) if 0 != l:git_clone return endif else let g:spm_dict[l:url]['sts'] = 0 let g:spm_dict[l:url]['msg'] = 'installed' endif exec 'set runtimepath+='.g:spm_dict[l:url]['dir'] endfunction function! s:git_clone(url, dir) let l:escaped_url = shellescape(a:url) let l:escaped_dir = shellescape(s:rm_tail_ds(a:dir)) let l:execute = '!git clone '.l:escaped_url.' '.l:escaped_dir if 1 == s:loaded || ( 0 == s:loaded && !has('gui_running') && !has('nvim')) let l:conf = confirm('execute? ['.l:execute.']', "Yyes\nNno") if 1 != l:conf let g:spm_dict[a:url]['sts'] = 2 let g:spm_dict[a:url]['msg'] = 'clone: canceled' return 2 endif endif if has('gui_running') && 1 == s:is_win silent execute l:execute else execute l:execute endif if !isdirectory(s:add_tail_ds(a:dir).'.git') let g:spm_dict[a:url]['sts'] = 1 let g:spm_dict[a:url]['msg'] = 'clone: an error occurred. plz check url' if 1 == s:loaded call confirm('an error occurred. plz check url') endif return 1 endif let g:spm_dict[a:url]['sts'] = 0 let g:spm_dict[a:url]['msg'] = 'clone: success' return 0 endfunction let &cpo = s:save_cpo unlet s:save_cpo