Created
July 1, 2015 21:42
-
-
Save zchee/c314e63ae8b6bea50bb4 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
" NeoBundle | |
" | |
if has('vim_starting') | |
set runtimepath+=~/.nvim/bundle/neobundle.vim/ | |
endif | |
call neobundle#begin(expand('~/.nvim/bundle')) | |
NeoBundleFetch 'Shougo/neobundle.vim' | |
" Completion | |
NeoBundle 'Shougo/deoplete.nvim' | |
NeoBundle 'Shougo/neco-vim' | |
" NeoBundle 'Shougo/neosnippet.vim' | |
" NeoBundle 'SirVer/ultisnips' | |
" Helper | |
NeoBundle 'benekastah/neomake' | |
NeoBundle 'scrooloose/syntastic' | |
NeoBundle 'Shougo/unite.vim' | |
NeoBundle 'Shougo/vimproc.vim', { 'build' : { 'mac' : 'make -f make_mac.mak' } } | |
NeoBundle 'mattn/gist-vim', { 'depends': 'mattn/webapi-vim' } | |
NeoBundle 'mattn/ctrlp-gist', { 'autoload': { 'commands': ['Gist'], } } | |
NeoBundleLazy 'lambdalisue/vim-gita', { 'autoload': { 'commands': ['Gita'], } } | |
NeoBundle 'chrisbra/Colorizer', { 'autoload': { 'commands': ['Colorizer'], } } | |
NeoBundleLazy 'thinca/vim-quickrun', { 'autoload': { 'commands': ['QuickRun'], } } | |
" NeoBundle 'Shougo/vimshell.vim' | |
" NeoBundle 'tpope/vim-fugitive' | |
" NeoBundle 'nixprime/cpsm' | |
" File | |
NeoBundle 'ctrlpvim/ctrlp.vim' | |
NeoBundle 'justinmk/vim-dirvish' | |
NeoBundle 'scrooloose/nerdtree' | |
"NeoBundle 'Shougo/vimfiler.vim' | |
" Edit | |
NeoBundle 'majutsushi/tagbar' | |
NeoBundle 'jiangmiao/auto-pairs' | |
NeoBundle 'terryma/vim-multiple-cursors' | |
NeoBundle 'Align' | |
" NeoBundle 'ConradIrwin/vim-bracketed-paste' | |
" View¬ | |
NeoBundle 'trusktr/seti.vim' | |
NeoBundle 'airblade/vim-gitgutter' | |
NeoBundle 'guns/xterm-color-table.vim' | |
NeoBundle 'powerline/powerline', {'rtp': 'powerline/bindings/vim/'} | |
" Syntax¬ | |
NeoBundleLazy 'fatih/vim-go', { "autoload": { "filetypes": ['go'] } } | |
NeoBundleLazy 'Blackrush/vim-gocode', { "autoload": { "filetypes": ['go'] } } | |
NeoBundleLazy 'dgryski/vim-godef', { "autoload": { "filetypes": ['go'] } } | |
NeoBundleLazy 'docker/docker', { 'rtp': '/contrib/syntax/vim', "autoload": { "filetypes": ['Dockerfile'] } } | |
NeoBundle 'ThomasAdam/tmux', { 'rtp': '/examples' } | |
" NeoBundle 'scrooloose/syntastic' | |
call neobundle#end() | |
filetype plugin indent on | |
NeoBundleCheck | |
" | |
" Set | |
" | |
syntax on | |
colorscheme seti | |
filetype on | |
filetype indent on | |
" set t_Co=256 | |
set backspace=indent,eol,start | |
set undodir=~/.vim/cache/undo | |
set noswapfile | |
set nobackup | |
set noshowcmd | |
set undofile | |
set encoding=utf-8 | |
set autochdir | |
set expandtab | |
set autoindent " nvim set by default | |
set cindent | |
set cmdheight=1 | |
set wildmenu " nvim set by default | |
set wildmode=longest:full,full | |
set showmatch | |
set title | |
set titlelen=90 | |
set scrolloff=5 | |
set wrap | |
set nowrapscan | |
set smartindent | |
set smarttab " nvim set by default | |
set tabstop=2 | |
set shiftwidth=2 | |
set nohlsearch " nvim set by default | |
set incsearch " nvim set by default | |
set ignorecase | |
set smartcase | |
set list | |
set listchars=tab:▸\ | |
" set completeopt=menu,preview | |
set laststatus=2 | |
set statusline=[%n]\ %<%F\ \ \ [%M%R%H%W%Y]\ \ %=\ %l/%c\ \ %p%% | |
set noerrorbells | |
set ruler | |
set showmode | |
set cursorline | |
set esckeys | |
set showtabline=2 | |
set dir=~/tmp | |
set clipboard+=unnamedplus | |
set helplang=ja,en | |
" http://stackoverflow.com/questions/630884/opening-vim-help-in-a-vertical-split-window | |
autocmd FileType help wincmd L | |
set tags+=./.tags " nvim set by default | |
set number norelativenumber | |
set guicursor=n-v-c:block-blinkon0-nCursor,o:hor50,i-ci:hor15,r-cr:hor30,sm:block | |
" Move cursor too lazy when vim+tmux+iterm? | |
" from lingr | |
" set regexpengine=2 | |
set nolazyredraw | |
set nocursorcolumn | |
set nocursorline | |
syntax sync minlines=256 | |
syntax sync maxlines=500 | |
" https://gist.github.com/zchee/6c4bdae654e2dda09a97 | |
set timeout | |
set ttimeout | |
set timeoutlen=300 | |
set ttimeoutlen=0 | |
" http://itchyny.hatenablog.com/entry/20130624/1372059268 | |
" set notimeout | |
" set ttimeout | |
" set timeoutlen=100 | |
" | |
" Neovim configuration | |
" | |
" Python | |
" let g:python_host_prog = '/usr/bin/python' | |
let g:python3_host_prog = '/usr/local/bin/python3' | |
python3 import sys | |
python3 print(sys.modules['__main__'].__dict__ is globals()) | |
py3 print("Hello") | |
python3 from powerline.vim import powerline_setup | |
python3 powerline_setup() | |
python3 del powerline_setup" | |
" TERM config | |
let $TERM='xterm' | |
" let $NVIM_LISTEN_ADDRESS='127.0.0.1:6666 | |
let $NVIM_LISTEN_ADDRESS='/tmp/nvim' | |
" Enable shape cursor on insert mode | |
let $NVIM_TUI_ENABLE_CURSOR_SHAPE=1 | |
" Enable true color in text interfaces | |
let $NVIM_TUI_ENABLE_TRUE_COLOR=1 | |
if exists(':terminal') | |
let g:terminal_color = 'xterm' | |
" allow terminal buffer size to be very large | |
let g:terminal_scrollback_buffer_size = 100000 | |
" map esc to exit to normal mode in terminal too | |
tnoremap <Esc><Esc> <C-\><C-n> | |
" Jump and Create splits easily | |
tnoremap <A-h> <C-\><C-n><C-w>h | |
tnoremap <A-j> <C-\><C-n><C-w>j | |
tnoremap <A-k> <C-\><C-n><C-w>k | |
tnoremap <A-l> <C-\><C-n><C-w>l | |
tnoremap <A-c> <C-\><C-n><C-w>c | |
nnoremap <A-h> <C-w>h | |
nnoremap <A-j> <C-w>j | |
nnoremap <A-k> <C-w>k | |
nnoremap <A-l> <C-w>l | |
nnoremap <A-c> <C-w>c | |
tnoremap <A-d>t <C-\><C-n>:vsp \| term://bash -l<CR> | |
tnoremap <A-d> <C-\><C-n>:vsp<CR> | |
tnoremap <A-s-d>t <C-\><C-n>:sp \| term://bash -l<CR> | |
tnoremap <A-s-d> <C-\><C-n>:sp<CR> | |
nnoremap <A-d>t <ESC>:vsp \| term bash -l<CR> | |
nnoremap <A-d> <ESC>:vsp<CR> | |
nnoremap <A-s-d>t <ESC>:sp \| term bash -l<CR> | |
nnoremap <A-s-d> <ESC>:sp<CR> | |
" Into insert mode when entering the terminal | |
augroup Terminal | |
au! | |
au TermOpen * let g:last_terminal_job_id = b:terminal_job_id | |
au WinEnter term://* startinsert | |
augroup END | |
endif | |
" Temporary plugin | |
" Multiline search | |
" http://vim.wikia.com/wiki/Search_across_multiple_lines | |
" Search for the ... arguments separated with whitespace (if no '!'), | |
" or with non-word characters (if '!' added to command). | |
function! SearchMultiLine(bang, ...) | |
if a:0 > 0 | |
let sep = (a:bang) ? '\_W\+' : '\_s\+' | |
let @/ = join(a:000, sep) | |
endif | |
endfunction | |
command! -bang -nargs=* -complete=tag S call SearchMultiLine(<bang>0, <f-args>)|normal! /<C-R>/<CR> | |
" https://github.com/neovim/neovim/blob/master/runtime/vimrc_example.vim | |
" When editing a file, always jump to the last known cursor position. Don't | |
" do it when the position is invalid or when inside an event handler | |
" Also don't do it when the mark is in the first line, that is the default | |
" position when opening a file. | |
autocmd BufReadPost * | |
\ if line("'\"") > 1 && line("'\"") <= line("$") | | |
\ execute "normal! g`\"" | | |
\ endif | |
if !exists(":DiffOrig") | |
command DiffOrig vert new | set buftype=nofile | read ++edit # | 0d_ | diffthis | |
\ | wincmd p | diffthis | |
endif | |
" Trim whitespace when write buffer | |
autocmd BufWritePre * :%s/\s\+$//ge | |
" quickrun-outputter | |
" http://d.hatena.ne.jp/osyo-manga/20120725/1343218270 | |
function! s:vsqf_funcname(line) | |
let funcname = matchstr(a:line, 'function.*<SNR>\d*_\zs.*\ze,') | |
return empty(funcname) ? matchstr(a:line, 'function \zs.*\ze,') : funcname | |
endfunction | |
function! s:vsqf_lnum(filelines, line) | |
let funcname = s:vsqf_funcname(a:line) | |
let lnum = matchstr(a:line, '.*行 \zs\d*\ze') | |
if empty(lnum) | |
return -1 | |
else | |
return (empty(funcname) ? 0 : match(a:filelines, 'function.*'.funcname.'\s*(') + 1) + lnum | |
endif | |
endfunction | |
function! s:make_vim_script_qflist(filename, errors) | |
let filelines = readfile(a:filename) | |
let errors = a:errors | |
let bufnr = bufnr(a:filename) | |
return map(a:errors, '{ | |
\ "bufnr" : bufnr, | |
\ "lnum" : s:vsqf_lnum(filelines, v:val), | |
\ "text" : v:val, | |
\}') | |
endfunction | |
let s:outputter = quickrun#outputter#buffered#new() | |
let s:outputter.name = "quickfix_vim_script" | |
let s:outputter.kind = "outputter" | |
function! s:outputter.finish(session) | |
let messages = self._result | |
let file = a:session.config.srcfile | |
let qflist= s:make_vim_script_qflist(file, split(messages, "\n")) | |
call setqflist(qflist, 'r') | |
copen | |
for winnr in range(1, winnr('$')) | |
if getwinvar(winnr, '&buftype') ==# 'quickfix' | |
call setwinvar(winnr, 'quickfix_title', 'quickrun: ' . | |
\ join(a:session.commands, ' && ')) | |
break | |
endif | |
endfor | |
endfunction | |
call quickrun#module#register(s:outputter, 1) | |
unlet s:outputter | |
" example | |
" :QuickRun -outputter quickfix_vim_script | |
" | |
" Syntax | |
" | |
augroup filetypedetect | |
" autocmd BufRead,BufNewFile .tmux.conf*,tmux.conf* set filetype=tmux | |
autocmd BufRead,BufNewFile *dockerfile set filetype=Dockerfile | |
autocmd BufRead,BufNewFile Dockerfile* set filetype=Dockerfile | |
"syntax include @Bash Dockerfile | |
augroup END | |
" Highlight color | |
" Neovim default highlight color | |
" https://github.com/neovim/neovim/blob/master/src/nvim/syntax.c#L5753-L5846 | |
" highlight TermCursor guibg=#FF5BFF guifg=#FEFEFE gui=reverse " Not works | |
" highlight TermCursorNC guibg=#FF5BFF guifg=#FEFEFE gui=reverse " Not works | |
highlight Pmenu guibg=#282a2b guifg=NONE gui=bold | |
highlight PmenuSel guibg=#4f99d3 guifg=#FEFEFE gui=bold | |
highlight PmenuSbar guibg=#101213 guifg=NONE gui=bold | |
highlight PmenuThumb guibg=#383a3a guifg=NONE gui=bold | |
highlight EndOfBuffer guibg=#151718 guifg=NONE gui=NONE | |
" highlight Question guibg=#202123 gui=bold | |
autocmd BufNewFile,BufRead *.css,*.html,*.htm :ColorHighlight! | |
let g:colorizer_syntax = 1 | |
" | |
" Plugin settings | |
" | |
" deoplete.vim | |
set omnifunc=syntaxcomplete#Complete | |
let g:deoplete#enable_at_startup = 1 | |
set completeopt+=noinsert | |
let g:deoplete#enable_ignore_case = 'ignorecase' | |
" https://github.com/Shougo/neocomplete.vim/blob/master/autoload/neocomplete/sources/omni.vim | |
let g:deoplete#omni_patterns = {} | |
let g:deoplete#omni_patterns.html = '<[^>]*' | |
let g:deoplete#omni_patterns.xml = '<[^>]*' | |
let g:deoplete#omni_patterns.md = '<[^>]*' | |
let g:deoplete#omni_patterns.css = '^\s\+\w\+\|\w\+[):;]\?\s\+\w*\|[@!]' | |
let g:deoplete#omni_patterns.scss = '^\s\+\w\+\|\w\+[):;]\?\s\+\w*\|[@!]' | |
let g:deoplete#omni_patterns.sass = '^\s\+\w\+\|\w\+[):;]\?\s\+\w*\|[@!]' | |
let g:deoplete#omni_patterns.javascript = '[^. \t]\.\%(\h\w*\)\?' | |
let g:deoplete#omni_patterns.c = '[^.[:digit:] *\t]\%(\.\|->\)\w*' | |
let g:deoplete#omni_patterns.cpp = '[^.[:digit:] *\t]\%(\.\|->\)\w*\|\h\w*::\w*' | |
let g:deoplete#omni_patterns.go = '[^.[:digit:] *\t]\.\w*' | |
let g:deoplete#omni_patterns.ruby = ['[^. *\t]\.\w*', '\h\w*::'] | |
" let g:deoplete#omni_patterns.python = '[^. \t]\.\w*' | |
let g:deoplete#omni_patterns.python = ['[^. *\t]\.\h\w*\','\h\w*::'] | |
let g:deoplete#omni_patterns.python3 = ['[^. *\t]\.\h\w*\','\h\w*::'] | |
autocmd CmdwinEnter * let b:deoplete_sources = ['buffer'] | |
imap <Nul> <C-Space> | |
inoremap <expr><C-Space> deoplete#mappings#manual_complete() | |
inoremap <expr><BS> deoplete#mappings#smart_close_popup()."\<C-h>" | |
" the_platinum_searcher | |
if executable('pt') | |
let g:unite_source_grep_command = 'pt' | |
let g:unite_source_grep_default_opts = '--nogroup --nocolor' | |
let g:unite_source_grep_recursive_opt = '' | |
let g:unite_source_grep_encoding = 'utf-8' | |
endif | |
" Neomake | |
autocmd! BufEnter * Neomake | |
" CtrlP file viewer by mattn/files(go) | |
let g:ctrlp_user_command = 'files -p -A %s' | |
" Golang | |
let g:go_highlight_functions = 1 | |
let g:go_highlight_methods = 1 | |
let g:go_highlight_structs = 1 | |
let g:go_highlight_operators = 1 | |
let g:go_highlight_build_constraints = 1 | |
let g:go_highlight_extra_types = 1 | |
let g:go_snippet_engine = "neosnippet" | |
let g:gofmt_command = 'goimports' | |
let g:godef_split=3 | |
autocmd BufWritePost *.go silent! !ctags -R & | |
autocmd BufEnter,BufRead,BufNewFile *go set shiftwidth=4 tabstop=4 noexpandtab | |
set rtp+=$GOPATH/src/github.com/nsf/gocode/vim | |
set rtp+=$GOPATH/src/github.com/golang/lint/misc/vim | |
" Switch horizontal and vertical open | |
autocmd FileType go nmap <Leader>gv <Plug>(go-doc) | |
autocmd FileType go nmap <Leader>gd <Plug>(go-doc-vertical) | |
autocmd FileType go nmap <Leader>i <Plug>(go-info) | |
autocmd FileType go nmap <Leader>s <Plug>(go-implements) | |
autocmd FileType go nmap <Leader>g <Plug>(go-doc-vertical) | |
" Python | |
" tagbar | |
let g:tagbar_type_go = { | |
\ 'ctagstype' : 'go', | |
\ 'kinds' : [ | |
\ 'p:package', | |
\ 'i:imports:1', | |
\ 'c:constants', | |
\ 'v:variables', | |
\ 't:types', | |
\ 'n:interfaces', | |
\ 'w:fields', | |
\ 'e:embedded', | |
\ 'm:methods', | |
\ 'r:constructor', | |
\ 'f:functions' | |
\ ], | |
\ 'sro' : '.', | |
\ 'kind2scope' : { | |
\ 't' : 'ctype', | |
\ 'n' : 'ntype' | |
\ }, | |
\ 'scope2kind' : { | |
\ 'ctype' : 't', | |
\ 'ntype' : 'n' | |
\ }, | |
\ 'ctagsbin' : 'gotags', | |
\ 'ctagsargs' : '-sort -silent' | |
\ } | |
" gist-vim | |
let g:gist_clip_command = 'pbcopy' | |
let g:gist_detect_filetype = 1 | |
let g:gist_browser_command = 'chromium %URL% &' | |
let g:gist_show_privates = 1 | |
let g:gist_get_multiplefile = 1 | |
" gitgutter | |
let g:gitgutter_enabled = 1 | |
let g:gitgutter_signs = 0 | |
let g:gitgutter_sign_column_always = 1 | |
let g:gitgutter_realtime = 1 | |
let g:gitgutter_eager = 1 | |
let g:gitgutter_enabled = 1 | |
" NERDTree | |
let NERDTreeHijackNetrw=0 | |
let NERDTreeMinimalUI=1 | |
let NERDTreeShowHidden=1 | |
autocmd BufEnter * lcd %:p:h | |
" auto-pairs | |
let g:AutoPairsFlyMode = 1 | |
let g:AutoPairsShortcutBackInsert = '<M-b>' | |
" dirvish | |
" let g:dirvish_relative_paths = 1 | |
augroup my_dirvish_events | |
au! | |
au User DirvishEnter let b:dirvish.showhidden = 1 | |
augroup END | |
" powerline/powerline | |
" python from powerline.vim import setup as powerline_setup | |
" python powerline_setup() | |
" python del powerline_setup python powerline_setup() | |
" set rtp+={repository_root}/powerline/bindings/vim | |
" YouCompleteMe | |
" autocmd FileType go nnoremap <buffer> <silent> ,g :YcmCompleter GoTo<CR> | |
" autocmd FileType c nnoremap <buffer> <silent> ,g :YcmCompleter GoTo<CR> | |
" let g:acp_enableAtStartup = 0 | |
" let g:ycm_min_num_of_chars_for_completion = 1 | |
" let g:ycm_complete_in_comments = 1 | |
" let g:ycm_collect_identifiers_from_comments_and_strings = 1 | |
" let g:ycm_collect_identifiers_from_tags_files = 1 | |
" let g:ycm_seed_identifiers_with_syntax = 1 | |
" let g:ycm_add_preview_to_completeopt = 1 | |
" let g:ycm_autoclose_preview_window_after_completion = 1 | |
" let g:ycm_autoclose_preview_window_after_insertion = 1 | |
" let g:ycm_confirm_extra_conf = 1 | |
" let g:ycm_global_ycm_extra_conf = '~/.ycm_extra_conf.py' | |
" FZF | |
" set rtp+=$HOME/.zsh/.fzf | |
" let g:fzf_action = { | |
" \ 'ctrl-m': 'e', | |
" \ 'ctrl-t': 'tabedit', | |
" \ 'alt-j': 'botright split', | |
" \ 'alt-k': 'topleft split', | |
" \ 'alt-h': 'vertical topleft split', | |
" \ 'alt-l': 'vertical botright split' } | |
" | |
" Keymap | |
" Prefix key | |
" | |
nnoremap <Space> <Nop> | |
" Dvorak Leftside | |
nnoremap , <Nop> | |
nnoremap e <Nop> | |
nnoremap e <Nop> | |
" Dvorak Rightside | |
nnoremap t <Nop> | |
nnoremap s <Nop> | |
" Global | |
map <C-n> :NERDTreeToggle<CR> | |
map . , | |
map , . | |
" | |
" Normal | |
" | |
" Swap semicolon and colon is move to Karabiner | |
" Don't use Ex mode, use Q for formatting | |
noremap Q gq | |
" manage windows | |
nnoremap qs :<C-u>split<CR> | |
nnoremap qv :<C-w>vsplit<CR> | |
nnoremap qt :<C-u>tabnew<CR> | |
nnoremap qn gt | |
nnoremap qp gT | |
nnoremap qw <C-w>w | |
nnoremap qj <C-w>j | |
nnoremap qk <C-w>k | |
nnoremap ql <C-w>l | |
nnoremap qh <C-w>h | |
" Misc | |
nnoremap <silent> ,g :call GodefUnderCursor()<CR> | |
nnoremap <silent> ,hi :nohlsearch<CR> | |
nnoremap <silent> ,sh :VimShell<CR> | |
nnoremap <silent> ,zsh :VimShellInteractive zsh<CR> | |
nnoremap <silent> ,pry :VimShellInteractive pry<CR> | |
nnoremap <silent> ,b :CtrlPBuffer<CR> | |
nnoremap <silent> ,u :<C-u>Unite grep:. -buffer-name=search-buffer<CR> | |
nnoremap <silent> ,n :call ToggleRelativeNumber()<CR> | |
function! ToggleRelativeNumber() | |
if(&relativenumber == 1) && (&number == 1) | |
set nonumber | |
set norelativenumber | |
elseif(&number == 1) | |
set number | |
set relativenumber | |
else | |
set norelativenumber | |
set number | |
endif | |
endfunc | |
" | |
" Visual | |
" | |
" Swap semicolon and colon is move to Karabiner | |
" http://vim-jp.org/blog/2015/06/30/visual-ctrl-a-ctrl-x.html | |
vnoremap <C-a> <C-a>gv | |
vnoremap <C-x> <C-x>gv | |
" | |
" Insert | |
" | |
inoremap <silent> jj <ESC> | |
inoremap <C-U> <C-G>u<C-U> | |
" https://github.com/neovim/neovim/issues/2701 | |
set <F37>=x27<M-BS> | |
inoremap <F37> <C-W> | |
" Command line | |
cnoremap <C-y> yank | |
cnoremap <C-p> put | |
" cnoremap <C-v> v | |
" | |
" Map Leader | |
" | |
let mapleader = "\<Space>" | |
nnoremap <Leader>w :w<CR> | |
nnoremap <Leader>q :wq<CR> | |
nnoremap <Leader>r :w<CR>:source %<CR> | |
nnoremap <Leader>h :<C-u>help<Space> | |
nmap <silent> <Leader>t :TagbarToggle<CR> | |
vmap <Leader>y "+y | |
vmap <Leader>d "+d | |
nmap <Leader>p "+p | |
nmap <Leader>P "+P | |
vmap <Leader>p "+p | |
vmap <Leader>P "+P | |
" XTerm arrow key control sequences issue on iTerm | |
" http://apple.stackexchange.com/questions/3369/why-dont-my-arrow-keys-work-in-vim-under-iterm | |
" Input sequences code by Ctrl-V + Arrow key | |
nnoremap <silent> x27<Left> h | |
nnoremap <silent> x27<Down> j | |
nnoremap <silent> x27<Up> k | |
nnoremap <silent> x27<Right> l | |
tnoremap <silent> x27<Left> h | |
tnoremap <silent> x27<Down> j | |
tnoremap <silent> x27<Up> k | |
tnoremap <silent> x27<Right> l | |
" for the future vim reading club. | |
"_人人人人人人人人人人人人人人人人人人人_ | |
"> ここまで読んだらお前は死ぬ by mattn < | |
" ̄YYYYYYYYYYYYYYYYYYY ̄ | |
" Debug autocmd | |
" set verbose=9 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment