commit dcc090a89810aeb037390c84616ca71c48823402
parent e2447723db2fc3bc0fb7363a56969c7b88835c5c
Author: Hayden Hamilton <hayden@haydenvh.com>
Date: Sat, 15 Feb 2020 09:00:04 +0000
Grub & vim stuff
Diffstat:
17 files changed, 3869 insertions(+), 0 deletions(-)
diff --git a/.config/vim/.netrwhist b/.config/vim/.netrwhist
@@ -0,0 +1,12 @@
+let g:netrw_dirhistmax =10
+let g:netrw_dirhistcnt =2
+let g:netrw_dirhist_2='/etc/bash'
+let g:netrw_dirhist_1='/etc/bash/bashrc.d'
+let g:netrw_dirhist_0='/home/hayden/.config/i3'
+let g:netrw_dirhist_9='/home/hayden'
+let g:netrw_dirhist_8='/'
+let g:netrw_dirhist_7='/home'
+let g:netrw_dirhist_6='/home/hayden'
+let g:netrw_dirhist_5='/home/hayden/work/website2/html/downloads/sent'
+let g:netrw_dirhist_4='/home/hayden/work/website2/bin/templates'
+let g:netrw_dirhist_3='/home/hayden/music/synth/eg/voyager'
diff --git a/.config/vim/autoload/goyo.vim b/.config/vim/autoload/goyo.vim
@@ -0,0 +1,447 @@
+" Copyright (c) 2015 Junegunn Choi
+"
+" MIT License
+"
+" Permission is hereby granted, free of charge, to any person obtaining
+" a copy of this software and associated documentation files (the
+" "Software"), to deal in the Software without restriction, including
+" without limitation the rights to use, copy, modify, merge, publish,
+" distribute, sublicense, and/or sell copies of the Software, and to
+" permit persons to whom the Software is furnished to do so, subject to
+" the following conditions:
+"
+" The above copyright notice and this permission notice shall be
+" included in all copies or substantial portions of the Software.
+"
+" THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+" EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+" MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+" NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+" LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+" OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+" WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+let s:cpo_save = &cpo
+set cpo&vim
+
+function! s:const(val, min, max)
+ return min([max([a:val, a:min]), a:max])
+endfunction
+
+function! s:get_color(group, attr)
+ return synIDattr(synIDtrans(hlID(a:group)), a:attr)
+endfunction
+
+function! s:set_color(group, attr, color)
+ let gui = has('gui_running') || has('termguicolors') && &termguicolors
+ execute printf('hi %s %s%s=%s', a:group, gui ? 'gui' : 'cterm', a:attr, a:color)
+endfunction
+
+function! s:blank(repel)
+ if bufwinnr(t:goyo_pads.r) <= bufwinnr(t:goyo_pads.l) + 1
+ \ || bufwinnr(t:goyo_pads.b) <= bufwinnr(t:goyo_pads.t) + 3
+ call s:goyo_off()
+ endif
+ execute 'wincmd' a:repel
+endfunction
+
+function! s:init_pad(command)
+ execute a:command
+
+ setlocal buftype=nofile bufhidden=wipe nomodifiable nobuflisted noswapfile
+ \ nonu nocursorline nocursorcolumn winfixwidth winfixheight statusline=\
+ if exists('&rnu')
+ setlocal nornu
+ endif
+ if exists('&colorcolumn')
+ setlocal colorcolumn=
+ endif
+ let bufnr = winbufnr(0)
+
+ execute winnr('#') . 'wincmd w'
+ return bufnr
+endfunction
+
+function! s:setup_pad(bufnr, vert, size, repel)
+ let win = bufwinnr(a:bufnr)
+ execute win . 'wincmd w'
+ execute (a:vert ? 'vertical ' : '') . 'resize ' . max([0, a:size])
+ augroup goyop
+ execute 'autocmd WinEnter,CursorMoved <buffer> nested call s:blank("'.a:repel.'")'
+ autocmd WinLeave <buffer> call s:hide_statusline()
+ augroup END
+
+ " To hide scrollbars of pad windows in GVim
+ let diff = winheight(0) - line('$') - (has('gui_running') ? 2 : 0)
+ if diff > 0
+ setlocal modifiable
+ call append(0, map(range(1, diff), '""'))
+ normal! gg
+ setlocal nomodifiable
+ endif
+ execute winnr('#') . 'wincmd w'
+endfunction
+
+function! s:resize_pads()
+ augroup goyop
+ autocmd!
+ augroup END
+
+ let t:goyo_dim.width = s:const(t:goyo_dim.width, 2, &columns)
+ let t:goyo_dim.height = s:const(t:goyo_dim.height, 2, &lines)
+
+ let vmargin = max([0, (&lines - t:goyo_dim.height) / 2 - 1])
+ let yoff = s:const(t:goyo_dim.yoff, - vmargin, vmargin)
+ let top = vmargin + yoff
+ let bot = vmargin - yoff - 1
+ call s:setup_pad(t:goyo_pads.t, 0, top, 'j')
+ call s:setup_pad(t:goyo_pads.b, 0, bot, 'k')
+
+ let nwidth = max([len(string(line('$'))) + 1, &numberwidth])
+ let width = t:goyo_dim.width + (&number ? nwidth : 0)
+ let hmargin = max([0, (&columns - width) / 2 - 1])
+ let xoff = s:const(t:goyo_dim.xoff, - hmargin, hmargin)
+ call s:setup_pad(t:goyo_pads.l, 1, hmargin + xoff, 'l')
+ call s:setup_pad(t:goyo_pads.r, 1, hmargin - xoff, 'h')
+endfunction
+
+function! s:tranquilize()
+ let bg = s:get_color('Normal', 'bg#')
+ for grp in ['NonText', 'FoldColumn', 'ColorColumn', 'VertSplit',
+ \ 'StatusLine', 'StatusLineNC', 'SignColumn']
+ " -1 on Vim / '' on GVim
+ if bg == -1 || empty(bg)
+ call s:set_color(grp, 'fg', get(g:, 'goyo_bg', 'black'))
+ call s:set_color(grp, 'bg', 'NONE')
+ else
+ call s:set_color(grp, 'fg', bg)
+ call s:set_color(grp, 'bg', bg)
+ endif
+ call s:set_color(grp, '', 'NONE')
+ endfor
+endfunction
+
+function! s:hide_statusline()
+ setlocal statusline=\
+endfunction
+
+function! s:hide_linenr()
+ if !get(g:, 'goyo_linenr', 0)
+ setlocal nonu
+ if exists('&rnu')
+ setlocal nornu
+ endif
+ endif
+ if exists('&colorcolumn')
+ setlocal colorcolumn=
+ endif
+endfunction
+
+function! s:maps_nop()
+ let mapped = filter(['R', 'H', 'J', 'K', 'L', '|', '_'],
+ \ "empty(maparg(\"\<c-w>\".v:val, 'n'))")
+ for c in mapped
+ execute 'nnoremap <c-w>'.escape(c, '|').' <nop>'
+ endfor
+ return mapped
+endfunction
+
+function! s:maps_resize()
+ let commands = {
+ \ '=': ':<c-u>let t:goyo_dim = <sid>parse_arg(t:goyo_dim_expr) <bar> call <sid>resize_pads()<cr>',
+ \ '>': ':<c-u>let t:goyo_dim.width = winwidth(0) + 2 * v:count1 <bar> call <sid>resize_pads()<cr>',
+ \ '<': ':<c-u>let t:goyo_dim.width = winwidth(0) - 2 * v:count1 <bar> call <sid>resize_pads()<cr>',
+ \ '+': ':<c-u>let t:goyo_dim.height += 2 * v:count1 <bar> call <sid>resize_pads()<cr>',
+ \ '-': ':<c-u>let t:goyo_dim.height -= 2 * v:count1 <bar> call <sid>resize_pads()<cr>'
+ \ }
+ let mapped = filter(keys(commands), "empty(maparg(\"\<c-w>\".v:val, 'n'))")
+ for c in mapped
+ execute 'nnoremap <silent> <c-w>'.c.' '.commands[c]
+ endfor
+ return mapped
+endfunction
+
+nnoremap <silent> <plug>(goyo-resize) :<c-u>call <sid>resize_pads()<cr>
+
+function! s:goyo_on(dim)
+ let dim = s:parse_arg(a:dim)
+ if empty(dim)
+ return
+ endif
+
+ let s:orig_tab = tabpagenr()
+ let settings =
+ \ { 'laststatus': &laststatus,
+ \ 'showtabline': &showtabline,
+ \ 'fillchars': &fillchars,
+ \ 'winminwidth': &winminwidth,
+ \ 'winwidth': &winwidth,
+ \ 'winminheight': &winminheight,
+ \ 'winheight': &winheight,
+ \ 'ruler': &ruler,
+ \ 'sidescroll': &sidescroll,
+ \ 'sidescrolloff': &sidescrolloff
+ \ }
+
+ " New tab
+ tab split
+
+ let t:goyo_master = winbufnr(0)
+ let t:goyo_dim = dim
+ let t:goyo_dim_expr = a:dim
+ let t:goyo_pads = {}
+ let t:goyo_revert = settings
+ let t:goyo_maps = extend(s:maps_nop(), s:maps_resize())
+ if has('gui_running')
+ let t:goyo_revert.guioptions = &guioptions
+ endif
+
+ " vim-gitgutter
+ let t:goyo_disabled_gitgutter = get(g:, 'gitgutter_enabled', 0)
+ if t:goyo_disabled_gitgutter
+ silent! GitGutterDisable
+ endif
+
+ " vim-signify
+ let t:goyo_disabled_signify = exists('b:sy') && b:sy.active
+ if t:goyo_disabled_signify
+ SignifyToggle
+ endif
+
+ " vim-airline
+ let t:goyo_disabled_airline = exists('#airline')
+ if t:goyo_disabled_airline
+ AirlineToggle
+ endif
+
+ " vim-powerline
+ let t:goyo_disabled_powerline = exists('#PowerlineMain')
+ if t:goyo_disabled_powerline
+ augroup PowerlineMain
+ autocmd!
+ augroup END
+ augroup! PowerlineMain
+ endif
+
+ " lightline.vim
+ let t:goyo_disabled_lightline = exists('#lightline')
+ if t:goyo_disabled_lightline
+ silent! call lightline#disable()
+ endif
+
+ call s:hide_linenr()
+ " Global options
+ let &winheight = max([&winminheight, 1])
+ set winminheight=1
+ set winheight=1
+ set winminwidth=1 winwidth=1
+ set laststatus=0
+ set showtabline=0
+ set noruler
+ set fillchars+=vert:\
+ set fillchars+=stl:\
+ set fillchars+=stlnc:\
+ set sidescroll=1
+ set sidescrolloff=0
+
+ " Hide left-hand scrollbars
+ if has('gui_running')
+ set guioptions-=l
+ set guioptions-=L
+ endif
+
+ let t:goyo_pads.l = s:init_pad('vertical topleft new')
+ let t:goyo_pads.r = s:init_pad('vertical botright new')
+ let t:goyo_pads.t = s:init_pad('topleft new')
+ let t:goyo_pads.b = s:init_pad('botright new')
+
+ call s:resize_pads()
+ call s:tranquilize()
+
+ augroup goyo
+ autocmd!
+ autocmd TabLeave * nested call s:goyo_off()
+ autocmd VimResized * call s:resize_pads()
+ autocmd ColorScheme * call s:tranquilize()
+ autocmd BufWinEnter * call s:hide_linenr() | call s:hide_statusline()
+ autocmd WinEnter,WinLeave * call s:hide_statusline()
+ if has('nvim')
+ autocmd TermClose * call feedkeys("\<plug>(goyo-resize)")
+ endif
+ augroup END
+
+ call s:hide_statusline()
+ if exists('g:goyo_callbacks[0]')
+ call g:goyo_callbacks[0]()
+ endif
+ if exists('#User#GoyoEnter')
+ doautocmd User GoyoEnter
+ endif
+endfunction
+
+function! s:goyo_off()
+ if !exists('#goyo')
+ return
+ endif
+
+ " Oops, not this tab
+ if !exists('t:goyo_revert')
+ return
+ endif
+
+ " Clear auto commands
+ augroup goyo
+ autocmd!
+ augroup END
+ augroup! goyo
+ augroup goyop
+ autocmd!
+ augroup END
+ augroup! goyop
+
+ for c in t:goyo_maps
+ execute 'nunmap <c-w>'.escape(c, '|')
+ endfor
+
+ let goyo_revert = t:goyo_revert
+ let goyo_disabled_gitgutter = t:goyo_disabled_gitgutter
+ let goyo_disabled_signify = t:goyo_disabled_signify
+ let goyo_disabled_airline = t:goyo_disabled_airline
+ let goyo_disabled_powerline = t:goyo_disabled_powerline
+ let goyo_disabled_lightline = t:goyo_disabled_lightline
+ let goyo_orig_buffer = t:goyo_master
+ let [line, col] = [line('.'), col('.')]
+
+ if tabpagenr() == 1
+ tabnew
+ normal! gt
+ bd
+ endif
+ tabclose
+ execute 'normal! '.s:orig_tab.'gt'
+ if winbufnr(0) == goyo_orig_buffer
+ " Doesn't work if window closed with `q`
+ execute printf('normal! %dG%d|', line, col)
+ endif
+
+ let wmw = remove(goyo_revert, 'winminwidth')
+ let ww = remove(goyo_revert, 'winwidth')
+ let &winwidth = ww
+ let &winminwidth = wmw
+ let wmh = remove(goyo_revert, 'winminheight')
+ let wh = remove(goyo_revert, 'winheight')
+ let &winheight = max([wmh, 1])
+ let &winminheight = wmh
+ let &winheight = wh
+
+ for [k, v] in items(goyo_revert)
+ execute printf('let &%s = %s', k, string(v))
+ endfor
+ execute 'colo '. get(g:, 'colors_name', 'default')
+
+ if goyo_disabled_gitgutter
+ silent! GitGutterEnable
+ endif
+
+ if goyo_disabled_signify
+ silent! if !b:sy.active
+ SignifyToggle
+ endif
+ endif
+
+ if goyo_disabled_airline && !exists('#airline')
+ AirlineToggle
+ " For some reason, Airline requires two refreshes to avoid display
+ " artifacts
+ silent! AirlineRefresh
+ silent! AirlineRefresh
+ endif
+
+ if goyo_disabled_powerline && !exists('#PowerlineMain')
+ doautocmd PowerlineStartup VimEnter
+ silent! PowerlineReloadColorscheme
+ endif
+
+ if goyo_disabled_lightline
+ silent! call lightline#enable()
+ endif
+
+ if exists('#Powerline')
+ doautocmd Powerline ColorScheme
+ endif
+
+ if exists('g:goyo_callbacks[1]')
+ call g:goyo_callbacks[1]()
+ endif
+ if exists('#User#GoyoLeave')
+ doautocmd User GoyoLeave
+ endif
+endfunction
+
+function! s:relsz(expr, limit)
+ if a:expr !~ '%$'
+ return str2nr(a:expr)
+ endif
+ return a:limit * str2nr(a:expr[:-2]) / 100
+endfunction
+
+function! s:parse_arg(arg)
+ if exists('g:goyo_height') || !exists('g:goyo_margin_top') && !exists('g:goyo_margin_bottom')
+ let height = s:relsz(get(g:, 'goyo_height', '85%'), &lines)
+ let yoff = 0
+ else
+ let top = max([0, s:relsz(get(g:, 'goyo_margin_top', 4), &lines)])
+ let bot = max([0, s:relsz(get(g:, 'goyo_margin_bottom', 4), &lines)])
+ let height = &lines - top - bot
+ let yoff = top - bot
+ endif
+
+ let dim = { 'width': s:relsz(get(g:, 'goyo_width', 80), &columns),
+ \ 'height': height,
+ \ 'xoff': 0,
+ \ 'yoff': yoff }
+ if empty(a:arg)
+ return dim
+ endif
+ let parts = matchlist(a:arg, '^\s*\([0-9]\+%\?\)\?\([+-][0-9]\+%\?\)\?\%(x\([0-9]\+%\?\)\?\([+-][0-9]\+%\?\)\?\)\?\s*$')
+ if empty(parts)
+ echohl WarningMsg
+ echo 'Invalid dimension expression: '.a:arg
+ echohl None
+ return {}
+ endif
+ if !empty(parts[1]) | let dim.width = s:relsz(parts[1], &columns) | endif
+ if !empty(parts[2]) | let dim.xoff = s:relsz(parts[2], &columns) | endif
+ if !empty(parts[3]) | let dim.height = s:relsz(parts[3], &lines) | endif
+ if !empty(parts[4]) | let dim.yoff = s:relsz(parts[4], &lines) | endif
+ return dim
+endfunction
+
+function! goyo#execute(bang, dim)
+ if a:bang
+ if exists('#goyo')
+ call s:goyo_off()
+ endif
+ else
+ if exists('#goyo') == 0
+ call s:goyo_on(a:dim)
+ elseif !empty(a:dim)
+ if winnr('$') < 5
+ call s:goyo_off()
+ return goyo#execute(a:bang, a:dim)
+ endif
+ let dim = s:parse_arg(a:dim)
+ if !empty(dim)
+ let t:goyo_dim = dim
+ let t:goyo_dim_expr = a:dim
+ call s:resize_pads()
+ endif
+ else
+ call s:goyo_off()
+ end
+ end
+endfunction
+
+let &cpo = s:cpo_save
+unlet s:cpo_save
+
diff --git a/.config/vim/autoload/magit/git.vim b/.config/vim/autoload/magit/git.vim
@@ -0,0 +1,348 @@
+function! magit#git#get_version()
+ if ( !exists("s:git_version") )
+ let s:git_version = matchlist(system(g:magit_git_cmd . " --version"),
+ \ 'git version \(\d\+\)\.\(\d\+\)\.\(\d\+\)\.\(\d\+\)\.\(g\x\+\)')[1:5]
+ endif
+ return s:git_version
+endfunction
+
+function! magit#git#is_version_sup_equal(major, minor, rev)
+ let git_ver = magit#git#get_version()
+ return ( ( a:major > git_ver[0] ) ||
+ \ (a:major >= git_ver[0] && a:minor > git_ver[1] ) ||
+ \ (a:major >= git_ver[0] && a:minor >= git_ver[1] && a:rev >= git_ver[2] )
+ \ )
+endfunction
+
+" magit#git#get_status: this function returns the git status output formated
+" into a List of Dict as
+" [ {staged', 'unstaged', 'filename'}, ... ]
+function! magit#git#get_status()
+ let file_list = []
+
+ " systemlist v7.4.248 problem again
+ " we can't use git status -z here, because system doesn't make the
+ " difference between NUL and NL. -status z terminate entries with NUL,
+ " instead of NF
+ let status_list=magit#sys#systemlist(g:magit_git_cmd . " status --porcelain")
+ for file_status_line in status_list
+ let line_match = matchlist(file_status_line, '\(.\)\(.\) \%(.\{-\} -> \)\?"\?\(.\{-\}\)"\?$')
+ let filename = line_match[3]
+ call add(file_list, { 'staged': line_match[1], 'unstaged': line_match[2], 'filename': filename })
+ endfor
+ return file_list
+endfunction
+
+function! magit#git#get_config(conf_name, default)
+ try
+ silent! let git_result=magit#utils#strip(
+ \ magit#sys#system(g:magit_git_cmd . " config --get " . a:conf_name))
+ catch 'shell_error'
+ return a:default
+ endtry
+ return git_result
+endfunction
+
+" magit#git#is_work_tree: this function check that path passed as parameter is
+" inside a git work tree
+" param[in] path: path to check
+" return: top work tree path if in a work tree, empty string otherwise
+function! magit#git#is_work_tree(path)
+ let dir = getcwd()
+ try
+ call magit#utils#chdir(a:path)
+ let top_dir=system(g:magit_git_cmd . " rev-parse --show-toplevel")
+ if ( executable("cygpath") )
+ let top_dir = magit#utils#strip(system("cygpath " . top_dir))
+ endif
+ if ( v:shell_error != 0 )
+ return ''
+ endif
+ return magit#utils#strip(top_dir) . "/"
+ finally
+ call magit#utils#chdir(dir)
+ endtry
+endfunction
+
+" magit#git#set_top_dir: this function set b:magit_top_dir and b:magit_git_dir
+" according to a path
+" param[in] path: path to set. This path must be in a git repository work tree
+function! magit#git#set_top_dir(path)
+ let dir = getcwd()
+ try
+ call magit#utils#chdir(a:path)
+ try
+ let top_dir=magit#utils#strip(
+ \ system(g:magit_git_cmd . " rev-parse --show-toplevel")) . "/"
+ let git_dir=magit#utils#strip(system(g:magit_git_cmd . " rev-parse --git-dir")) . "/"
+ if ( executable("cygpath") )
+ let top_dir = magit#utils#strip(system("cygpath " . top_dir))
+ let git_dir = magit#utils#strip(system("cygpath " . git_dir))
+ endif
+ catch 'shell_error'
+ call magit#sys#print_shell_error()
+ throw 'set_top_dir_error'
+ endtry
+ let b:magit_top_dir=top_dir
+ let b:magit_git_dir=git_dir
+ finally
+ call magit#utils#chdir(dir)
+ endtry
+endfunction
+
+" magit#git#top_dir: return the absolute path of current git worktree for the
+" current magit buffer
+" return top directory
+function! magit#git#top_dir()
+ if ( !exists("b:magit_top_dir") )
+ throw 'top_dir_not_set'
+ endif
+ return b:magit_top_dir
+endfunction
+
+" magit#git#git_dir: return the absolute path of current git worktree
+" return git directory
+function! magit#git#git_dir()
+ if ( !exists("b:magit_git_dir") )
+ throw 'git_dir_not_set'
+ endif
+ return b:magit_git_dir
+endfunction
+
+" magit#git#git_diff: helper function to get diff of a file
+" nota: when git fail (due to misformated patch for example), an error
+" message is raised.
+" WARNING: diff is generated without prefix. To apply this diff, git apply
+" must use the option -p0.
+" param[in] filemane: it must be quoted if it contains spaces
+" param[in] status: status of the file (see g:magit_git_status_code)
+" param[in] mode: can be staged or unstaged
+" return: two values
+" [0]: boolean, if true current file is binary
+" [1]: string array containing diff output
+function! magit#git#git_diff(filename, status, mode)
+ let dev_null = ( a:status == '?' ) ? "/dev/null " : ""
+ let staged_flag = ( a:mode == 'staged' ) ? "--staged" : ""
+ let git_cmd=g:magit_git_cmd . " diff --no-ext-diff " . staged_flag .
+ \ " --no-prefix --no-color -p -U" . b:magit_diff_context .
+ \ " -- " . dev_null . " " . a:filename
+
+ if ( a:status != '?' )
+ try
+ silent let diff_list=magit#sys#systemlist(git_cmd)
+ catch 'shell_error'
+ call magit#sys#print_shell_error()
+ throw 'diff error'
+ endtry
+ else
+ silent let diff_list=magit#sys#systemlist_noraise(git_cmd)
+ endif
+
+ if ( empty(diff_list) )
+ echohl WarningMsg
+ echom "diff command \"" . git_cmd . "\" returned nothing"
+ echohl None
+ throw 'diff error'
+ endif
+ return [
+ \ ( diff_list[-1] =~ "^Binary files .* differ$" && len(diff_list) <= 4 )
+ \, diff_list ]
+endfunction
+
+" magit#git#sub_check: this function checks if given submodule has modified or
+" untracked content
+" param[in] submodule: submodule path
+" param[in] check_level: can be modified or untracked
+function! magit#git#sub_check(submodule, check_level)
+ let ignore_flag = ( a:check_level == 'modified' ) ?
+ \ '--ignore-submodules=untracked' : ''
+ let git_cmd=g:magit_git_cmd . " status --porcelain " . ignore_flag . " " . a:submodule
+ return ( !empty(magit#sys#systemlist(git_cmd)) )
+endfunction
+
+" magit#git#git_sub_summary: helper function to get diff of a submodule
+" nota: when git fail (due to misformated patch for example), an error
+" message is raised.
+" param[in] filemane: it must be quoted if it contains spaces
+" param[in] mode: can be staged or unstaged
+function! magit#git#git_sub_summary(filename, mode)
+ let staged_flag = ( a:mode == 'staged' ) ? " --cached " : " --files "
+ let git_cmd=g:magit_git_cmd . " submodule summary " . staged_flag . " HEAD "
+ \ .a:filename
+ silent let diff_list=magit#sys#systemlist(git_cmd)
+ if ( empty(diff_list) )
+ if ( a:mode == 'unstaged' )
+ if ( magit#git#sub_check(a:filename, 'modified') )
+ return "modified content"
+ endif
+ if ( magit#git#sub_check(a:filename, 'untracked') )
+ return "untracked content"
+ endif
+ endif
+ echohl WarningMsg
+ echom "diff command \"" . git_cmd . "\" returned nothing"
+ echohl None
+ throw 'diff error'
+ endif
+ return diff_list
+endfunction
+
+" magit#git#git_add: helper function to add a whole file
+" nota: when git fail (due to misformated patch for example), an error
+" message is raised.
+" param[in] filemane: it must be quoted if it contains spaces
+function! magit#git#git_add(filename)
+ let git_cmd=g:magit_git_cmd . " add --no-ignore-removal -- " . a:filename
+ try
+ silent let git_result=magit#sys#system(git_cmd)
+ catch 'shell_error'
+ call magit#sys#print_shell_error()
+ throw 'add error'
+ endtry
+endfunction
+
+" magit#git#git_checkout: helper function to add a whole file
+" nota: when git fail (due to misformated patch for example), an error
+" message is raised.
+" param[in] filemane: it must be quoted if it contains spaces
+function! magit#git#git_checkout(filename)
+ let git_cmd=g:magit_git_cmd . " checkout -- " . a:filename
+ try
+ silent let git_result=magit#sys#system(git_cmd)
+ catch 'shell_error'
+ call magit#sys#print_shell_error()
+ throw 'checkout error'
+ endtry
+endfunction
+
+" magit#git#git_reset: helper function to add a whole file
+" nota: when git fail (due to misformated patch for example), an error
+" message is raised.
+" param[in] filemane: it must be quoted if it contains spaces
+function! magit#git#git_reset(filename)
+ let git_cmd=g:magit_git_cmd . " reset HEAD -- " . a:filename
+ try
+ silent let git_result=magit#sys#system(git_cmd)
+ catch 'shell_error'
+ call magit#sys#print_shell_error()
+ throw 'reset error'
+ endtry
+endfunction
+
+" magit#git#git_apply: helper function to stage a selection
+" nota: when git fail (due to misformated patch for example), an error
+" message is raised.
+" param[in] selection: the text to stage. It must be a patch, i.e. a diff
+" header plus one or more hunks
+" return: no
+function! magit#git#git_apply(header, selection)
+ let selection = magit#utils#flatten(a:header + a:selection)
+ if ( selection[-1] !~ '^$' )
+ let selection += [ '' ]
+ endif
+ let git_cmd=g:magit_git_cmd . " apply --recount --no-index --cached -p0 -"
+ try
+ silent let git_result=magit#sys#system(git_cmd, selection)
+ catch 'shell_error'
+ call magit#sys#print_shell_error()
+ echom "Tried to aply this"
+ echom string(selection)
+ throw 'apply error'
+ endtry
+endfunction
+
+" magit#git#git_unapply: helper function to unstage a selection
+" nota: when git fail (due to misformated patch for example), an error
+" message is raised.
+" param[in] selection: the text to stage. It must be a patch, i.e. a diff
+" header plus one or more hunks
+" return: no
+function! magit#git#git_unapply(header, selection, mode)
+ let cached_flag=''
+ if ( a:mode == 'staged' )
+ let cached_flag=' --cached '
+ endif
+ let selection = magit#utils#flatten(a:header + a:selection)
+ if ( selection[-1] !~ '^$' )
+ let selection += [ '' ]
+ endif
+ try
+ silent let git_result=magit#sys#system(
+ \ g:magit_git_cmd . " apply --recount --no-index -p0 --reverse " .
+ \ cached_flag . " - ", selection)
+ catch 'shell_error'
+ call magit#sys#print_shell_error()
+ echom "Tried to unaply this"
+ echom string(selection)
+ throw 'unapply error'
+ endtry
+endfunction
+
+" magit#git#submodule_status: helper function to return the submodule status
+" return submodule status
+function! magit#git#submodule_status()
+ return magit#sys#system(g:magit_git_cmd . " submodule status")
+endfunction
+
+" magit#git#get_branch_name: get the branch name given a reference
+" WARNING does not seem to work with SHA1
+" param[in] ref can be HEAD or a branch name
+" return branch name
+function! magit#git#get_branch_name(ref)
+ return magit#utils#strip(magit#sys#system(g:magit_git_cmd . " rev-parse --abbrev-ref " . a:ref))
+endfunction
+
+" magit#git#count_object: this function returns the output of git
+" count-objects, in a dict object
+" It contains the following information: count, size, in-pack, packs,
+" size-pack, prune-packable, garbage, size-garbage
+function! magit#git#count_object()
+ let count_object=magit#sys#systemlist(g:magit_git_cmd . " count-objects -v")
+ let refs={}
+ for line in count_object
+ let ref=split(line, ":")
+ let refs[ref[0]] = ref[1]
+ endfor
+ return refs
+endfunction
+
+" magit#git#check_repo: check the health of the repo
+" return 0 if everything is fine, 1 otherwise
+function! magit#git#check_repo()
+ try
+ let head_br=magit#git#get_branch_name("HEAD")
+ catch 'shell_error'
+ let count = magit#git#count_object()['count']
+ if ( count != 0 )
+ return 1
+ endif
+ endtry
+ return 0
+endfunction
+
+" magit#git#get_commit_subject: get the subject of a commit (first line)
+" param[in] ref: reference, can be SHA1, brnach name or HEAD
+" return commit subject
+function! magit#git#get_commit_subject(ref)
+ try
+ return magit#utils#strip(magit#sys#system(g:magit_git_cmd . " show " .
+ \" --no-prefix --no-patch --format=\"%s\" " . a:ref))
+ catch 'shell_error'
+ return ""
+ endtry
+endfunction
+
+" magit#git#get_remote_branch: get the branch name of the default remote, for
+" upstream and push
+" WARNING does not work with SHA1
+" param[in] ref: reference, can be HEAD or branch name
+" param[in] type: type of default remote: upstream or push
+" return the remote branch name, 'none' if it has not
+function! magit#git#get_remote_branch(ref, type)
+ try
+ return magit#utils#strip(magit#sys#system(
+ \ g:magit_git_cmd . " rev-parse --abbrev-ref=loose " . a:ref . "@{" . a:type . "}"))
+ catch 'shell_error'
+ return "none"
+ endtry
+endfunction
diff --git a/.config/vim/autoload/magit/helper.vim b/.config/vim/autoload/magit/helper.vim
@@ -0,0 +1,29 @@
+
+" magit#helper#get_filename: helper function to get the current filename, according to
+" cursor position
+" return: filename
+function! magit#helper#get_filename()
+ return substitute(getline(search(g:magit_file_re, "cbnW")), g:magit_file_re, '\2', '')
+endfunction
+
+" magit#helper#get_hunkheader_line_nb: helper function to get the current hunk
+" header line number, according to cursor position
+" return: hunk header line number
+function! magit#helper#get_hunkheader_line_nb()
+ return search(g:magit_hunk_re, "cbnW")
+endfunction
+
+" magit#utils#get_section: helper function to get the current section, according to
+" cursor position
+" return: section id, empty string if no section found
+function! magit#helper#get_section()
+ let section_line=getline(search(g:magit_section_re, "bnW"))
+ for [section_name, section_str] in items(g:magit_sections)
+ if ( section_line == section_str )
+ return section_name
+ endif
+ endfor
+ return ''
+endfunction
+
+
diff --git a/.config/vim/autoload/magit/mapping.vim b/.config/vim/autoload/magit/mapping.vim
@@ -0,0 +1,262 @@
+
+let g:magit_stage_file_mapping = get(g:, 'magit_stage_file_mapping', 'F' )
+let g:magit_stage_hunk_mapping = get(g:, 'magit_stage_hunk_mapping', 'S' )
+let g:magit_stage_line_mapping = get(g:, 'magit_stage_line_mapping', 'L' )
+let g:magit_mark_line_mapping = get(g:, 'magit_mark_line_mapping', 'M' )
+let g:magit_commit_mapping = get(g:, 'magit_commit_mapping', 'CC' )
+let g:magit_commit_amend_mapping = get(g:, 'magit_commit_amend_mapping', 'CA' )
+let g:magit_commit_fixup_mapping = get(g:, 'magit_commit_fixup_mapping', 'CF' )
+let g:magit_close_commit_mapping = get(g:, 'magit_close_commit_mapping', 'CU' )
+let g:magit_reload_mapping = get(g:, 'magit_reload_mapping', 'R' )
+let g:magit_edit_mapping = get(g:, 'magit_edit_mapping', 'E' )
+
+let g:magit_jump_next_hunk = get(g:, 'magit_jump_next_hunk', '<C-N>')
+let g:magit_jump_prev_hunk = get(g:, 'magit_jump_prev_hunk', '<C-P>')
+
+let g:magit_ignore_mapping = get(g:, 'magit_ignore_mapping', 'I' )
+let g:magit_discard_hunk_mapping = get(g:, 'magit_discard_hunk_mapping', 'DDD' )
+
+let g:magit_close_mapping = get(g:, 'magit_close_mapping', 'q' )
+let g:magit_toggle_help_mapping = get(g:, 'magit_toggle_help_mapping', '?' )
+
+let g:magit_diff_shrink = get(g:, 'magit_diff_shrink', '-' )
+let g:magit_diff_enlarge = get(g:, 'magit_diff_enlarge', '+' )
+let g:magit_diff_reset = get(g:, 'magit_diff_reset', '0' )
+
+let g:magit_folding_toggle_mapping = get(g:, 'magit_folding_toggle_mapping', [ '<CR>' ])
+let g:magit_folding_open_mapping = get(g:, 'magit_folding_open_mapping', [ 'zo', 'zO' ])
+let g:magit_folding_close_mapping = get(g:, 'magit_folding_close_mapping', [ 'zc', 'zC' ])
+
+" magit#open_close_folding_wrapper: wrapper function to
+" magit#open_close_folding. If line under cursor is not a cursor, execute
+" normal behavior
+" param[in] mapping: which has been set
+" param[in] visible : boolean, force visible value. If not set, toggle
+" visibility
+function! s:mg_open_close_folding_wrapper(mapping, ...)
+ if ( getline(".") =~ g:magit_file_re )
+ return call('magit#open_close_folding', a:000)
+ elseif ( foldlevel(line(".")) == 2 )
+ if ( foldclosed(line('.')) == -1 )
+ foldclose
+ else
+ foldopen
+ endif
+ else
+ silent! execute "silent! normal! " . a:mapping
+ endif
+endfunction
+
+" s:nmapping_wrapper: wrapper for normal mapping commands
+" it needs a wrapper because some mappings must only be enabled in some
+" sections. For example, wa want that 'S' mapping to be enabled in staged and
+" unstaged sections, but not in commit section.
+" param[in] mapping the key for the mapping (lhs)
+" param[in] function the function to call (rhs)
+" param[in] ... : optional, section, the regex of the sections where to enable the
+" mapping. If there is no section parameter or if the section parameter regex
+" match the current section, the rhs is called. Otherwise, the mapping is
+" applied to its original meaning.
+function! s:nmapping_wrapper(mapping, function, ...)
+ if ( a:0 == 0 || magit#helper#get_section() =~ a:1 )
+ execute "call " . a:function
+ else
+ " feedkeys(..., 'n') is prefered over execute normal!
+ " normal! does not enter in insert mode
+ call feedkeys(a:mapping, 'n')
+ endif
+endfunction
+
+" s:xmapping_wrapper: wrapper for visual mapping commands
+" it needs a wrapper because some mappings must only be enabled in some
+" sections. For example, wa want that 'S' mapping to be enabled in staged and
+" unstaged sections, but not in commit section.
+" param[in] mapping the key for the mapping (lhs)
+" param[in] function the function to call (rhs)
+" param[in] ... : optional, section, the regex of the sections where to enable the
+" mapping. If there is no section parameter or if the section parameter regex
+" match the current section, the rhs is called. Otherwise, the mapping is
+" applied to its original meaning.
+function! s:xmapping_wrapper(mapping, function, ...) range
+ if ( a:0 == 0 || magit#helper#get_section() =~ a:1 )
+ execute a:firstline . "," . a:lastline . "call " . a:function
+ else
+ " feedkeys(..., 'n') is prefered over execute normal!
+ " normal! does not enter in insert mode
+ call feedkeys(a:mapping, 'n')
+ endif
+endfunction
+" s:mg_set_mapping: helper function to setup the mapping
+" param[in] mode the mapping mode, one letter. Can be 'n', 'x', 'i', ...
+" param[in] mapping the key for the mapping (lhs)
+" param[in] function the function to call (rhs)
+" param[in] ... : optional, section, the regex of the section(s)
+function! s:mg_set_mapping(mode, mapping, function, ...)
+ if ( a:0 == 1 )
+ execute a:mode . "noremap <buffer><silent><nowait> "
+ \ . a:mapping .
+ \ " :call <SID>" . a:mode . "mapping_wrapper(\"" .
+ \ a:mapping . "\", \"" .
+ \ a:function . "\"" .
+ \ ", \'" . a:1 . "\'" .
+ \ ")<cr>"
+ else
+ execute a:mode . "noremap <buffer><silent><nowait> "
+ \ . a:mapping .
+ \ " :call " .
+ \ a:function . "<cr>"
+ endif
+endfunction
+
+function! magit#mapping#set_default()
+
+ call s:mg_set_mapping('n', g:magit_stage_hunk_mapping,
+ \"magit#stage_hunk(0)", '\<\%(un\)\?staged\>')
+ call s:mg_set_mapping('n', g:magit_stage_file_mapping,
+ \ "magit#stage_file()", '\<\%(un\)\?staged\>')
+ call s:mg_set_mapping('n', g:magit_discard_hunk_mapping,
+ \ "magit#stage_hunk(1)", '\<\%(un\)\?staged\>')
+ call s:mg_set_mapping('n', g:magit_stage_line_mapping,
+ \ "magit#stage_vselect()", '\<\%(un\)\?staged\>')
+ call s:mg_set_mapping('x', g:magit_stage_hunk_mapping,
+ \ "magit#stage_vselect()", '\<\%(un\)\?staged\>')
+ call s:mg_set_mapping('n', g:magit_mark_line_mapping,
+ \ "magit#mark_vselect()", '\<\%(un\)\?staged\>')
+ call s:mg_set_mapping('x', g:magit_mark_line_mapping,
+ \ "magit#mark_vselect()", '\<\%(un\)\?staged\>')
+
+ call s:mg_set_mapping('n', g:magit_ignore_mapping,
+ \ "magit#ignore_file()", '\<\%(un\)\?staged\>')
+ call s:mg_set_mapping('n', g:magit_edit_mapping,
+ \ "magit#jump_to()", '\<\%(un\)\?staged\>')
+
+ call s:mg_set_mapping('n', g:magit_reload_mapping,
+ \ "magit#update_buffer()")
+ call s:mg_set_mapping('n', g:magit_close_mapping,
+ \ "magit#close_magit()")
+ call s:mg_set_mapping('n', g:magit_diff_shrink,
+ \ "magit#update_diff('-')")
+ call s:mg_set_mapping('n', g:magit_diff_enlarge,
+ \ "magit#update_diff('+')")
+ call s:mg_set_mapping('n', g:magit_diff_reset,
+ \ "magit#update_diff('0')")
+ call s:mg_set_mapping('n', g:magit_toggle_help_mapping,
+ \ "magit#toggle_help()")
+
+ call s:mg_set_mapping('n', g:magit_commit_mapping,
+ \ "magit#commit_command('CC')")
+ call s:mg_set_mapping('n', g:magit_commit_amend_mapping,
+ \ "magit#commit_command('CA')")
+ call s:mg_set_mapping('n', g:magit_commit_fixup_mapping,
+ \ "magit#commit_command('CF')")
+ call s:mg_set_mapping('n', g:magit_close_commit_mapping,
+ \ "magit#close_commit()")
+
+ call s:mg_set_mapping('n', g:magit_jump_next_hunk,
+ \ "magit#jump_hunk('N')")
+ call s:mg_set_mapping('n', g:magit_jump_prev_hunk,
+ \ "magit#jump_hunk('P')")
+
+ for mapping in g:magit_folding_toggle_mapping
+ " trick to pass '<cr>' in a mapping command without being interpreted
+ let func_arg = ( mapping ==? "<cr>" ) ? '+' : mapping
+ execute "nnoremap <buffer><silent><nowait> " . mapping . " :call <SID>mg_open_close_folding_wrapper('" . func_arg . "')<return>"
+ endfor
+ for mapping in g:magit_folding_open_mapping
+ execute "nnoremap <buffer><silent><nowait> " . mapping . " :call <SID>mg_open_close_folding_wrapper('" . mapping . "', 1)<return>"
+ endfor
+ for mapping in g:magit_folding_close_mapping
+ execute "nnoremap <buffer><silent><nowait> " . mapping . " :call <SID>mg_open_close_folding_wrapper('" . mapping . "', 0)<return>"
+ endfor
+
+ " s:magit_inline_help: Dict containing inline help for each section
+ let s:magit_inline_help = {
+ \ 'staged': [
+\g:magit_stage_hunk_mapping
+\.' if cursor on filename header, unstage file',
+\' if cursor in hunk, unstage hunk',
+\' if visual selection in hunk (with v), unstage selection',
+\' if lines marked in hunk (with ' . g:magit_mark_line_mapping . '), unstage marked lines',
+\g:magit_stage_line_mapping
+\.' unstage the line under the cursor',
+\g:magit_mark_line_mapping
+\.' if cursor in hunk, mark line under cursor "to be unstaged"',
+\' if visual selection in hunk (with v), mark selected lines "to be unstaged"',
+\g:magit_stage_file_mapping
+\.' if cursor on filename header or hunk, unstage whole file',
+\g:magit_edit_mapping
+\.' edit, jump cursor to file containing this hunk',
+\g:magit_jump_next_hunk.','.g:magit_jump_prev_hunk
+\. ' move to Next/Previous hunk in magit buffer',
+\],
+ \ 'unstaged': [
+\g:magit_stage_hunk_mapping
+\.' if cursor on filename header, stage file',
+\' if cursor in hunk, stage hunk',
+\' if visual selection in hunk (with v), stage selection',
+\' if lines marked in hunk (with ' . g:magit_mark_line_mapping . '), stage marked lines',
+\g:magit_stage_line_mapping
+\.' stage the line under the cursor',
+\g:magit_mark_line_mapping
+\.' if cursor in hunk, mark line under cursor "to be staged"',
+\' if visual selection in hunk (with v), mark selected lines "to be staged"',
+\g:magit_stage_file_mapping
+\.' if cursor on filename header or hunk, stage whole file',
+\g:magit_edit_mapping
+\.' edit, jump cursor to file containing this hunk',
+\g:magit_jump_next_hunk.','.g:magit_jump_prev_hunk
+\. ' move to Next/Previous hunk in magit buffer',
+\g:magit_discard_hunk_mapping
+\. ' discard file changes (warning, changes will be lost)',
+\g:magit_ignore_mapping
+\.' add file in .gitgnore',
+\],
+ \ 'global': [
+\g:magit_sections['help'],
+\g:magit_folding_toggle_mapping[0]
+\. ' if cursor on filename header line, unhide diffs for this file',
+\g:magit_commit_mapping
+\. ' From stage mode: set commit mode in normal flavor',
+\' From commit mode: commit all staged changes with commit flavor',
+\' (normal or amend) with message in "Commit message" section',
+\g:magit_commit_amend_mapping
+\. ' From stage or commit mode: set commit mode in amend flavor, and',
+\' display "Commit message" section with previous commit message.',
+\g:magit_commit_fixup_mapping
+\. ' From stage mode: amend staged changes to previous commit without',
+\' modifying the previous commit message',
+\g:magit_close_commit_mapping
+\. ' commit undo, cancel and close current commit message',
+\g:magit_reload_mapping
+\.' refresh magit buffer',
+\g:magit_diff_shrink.','.g:magit_diff_enlarge.','.g:magit_diff_reset
+\. ' shrink,enlarge,reset diff context',
+\g:magit_close_mapping
+\.' close magit buffer',
+\g:magit_toggle_help_mapping
+\.' toggle help showing in magit buffer',
+\'======='
+\],
+\}
+endfunction
+
+" s:mg_get_inline_help_line_nb: this function returns the number of lines of
+" a given section, or 0 if help is disabled.
+" param[in] section: section identifier
+" return number of lines
+function! magit#mapping#get_section_help_line_nb(section)
+ return ( g:magit_show_help == 1 ) ?
+ \ len(s:magit_inline_help[a:section]) : 0
+endfunction
+
+" s:mg_section_help: this function writes in current buffer the inline help
+" for a given section, it does nothing if inline help is disabled.
+" WARNING: this function writes in file, it should only be called through
+" protected functions like magit#update_buffer
+" param[in] section: section identifier
+function! magit#mapping#get_section_help(section)
+ if ( g:magit_show_help == 1 )
+ silent put =s:magit_inline_help[a:section]
+ endif
+endfunction
+
diff --git a/.config/vim/autoload/magit/sign.vim b/.config/vim/autoload/magit/sign.vim
@@ -0,0 +1,116 @@
+" Got lot of stuf from vim-gitgutter
+" https://github.com/airblade/vim-gitgutter
+
+" Vim doesn't namespace sign ids so every plugin shares the same
+" namespace. Sign ids are simply integers so to avoid clashes with other
+" signs we guess at a clear run.
+"
+" Note also we currently never reset s:next_sign_id.
+let s:first_sign_id = 42000
+let s:next_sign_id = s:first_sign_id
+let s:dummy_sign_id = s:first_sign_id - 1
+" Remove-all-signs optimisation requires Vim 7.3.596+.
+let s:supports_star = v:version > 703 || (v:version == 703 && has("patch596"))
+
+function! magit#sign#remove_all(...)
+ if ( a:0 == 1 )
+ let pattern = a:1
+ else
+ let pattern = '^Magit.*'
+ endif
+ let signs = magit#sign#find_signs(pattern, 1, line('$'))
+ call magit#sign#remove_signs(signs)
+endfunction
+
+" magit#sign#remove_signs: unplace a list of signs
+" param[in] sign_ids: list of signs dict
+function! magit#sign#remove_signs(sign_ids)
+ let bufnr = magit#utils#bufnr()
+ for sign in values(a:sign_ids)
+ execute "sign unplace" sign.id
+ endfor
+endfunction
+
+function! magit#sign#add_sign(line, type, bufnr)
+ let id = <SID>get_next_sign_id()
+ execute ":sign place " . id .
+ \ " line=" . a:line . " name=" . s:magit_mark_signs[a:type] .
+ \ " buffer=" . a:bufnr
+ return id
+endfunction
+
+function! magit#sign#remove_sign(id)
+ execute ":sign unplace " . a:id
+endfunction
+
+" s:get_next_sign_id: helper function to increment sign ids
+function! s:get_next_sign_id()
+ let next_id = s:next_sign_id
+ let s:next_sign_id += 1
+ return next_id
+endfunction
+
+" magit#sign#find_signs: this function returns signs matching a pattern in a
+" range of lines
+" param[in] pattern: regex pattern to match
+" param[in] startline,endline: range of lines
+" FIXME: find since which version "sign place" is sorted
+function! magit#sign#find_signs(pattern, startline, endline)
+ let bufnr = magit#utils#bufnr()
+ " <line_number (string)>: {'id': <id (number)>, 'name': <name (string)>}
+ let found_signs = {}
+
+ redir => signs
+ silent execute "sign place buffer=" . bufnr
+ redir END
+
+ for sign_line in filter(split(signs, '\n'), 'v:val =~# "="')
+ " Typical sign line: line=88 id=1234 name=GitGutterLineAdded
+ " We assume splitting is faster than a regexp.
+ let components = split(sign_line)
+ let name = split(components[2], '=')[1]
+ let line_number = str2nr(split(components[0], '=')[1])
+ if ( name =~# a:pattern &&
+ \ line_number >= a:startline &&
+ \ line_number <= a:endline )
+ let id = str2nr(split(components[1], '=')[1])
+ let found_signs[line_number] = {'id': id, 'name': name}
+ endif
+ endfor
+ return found_signs
+endfunction
+
+" magit#sign#find_stage_signs: helper function to get marked lines for stage
+" param[in] startline,endline: range of lines
+" return Dict of marked lines
+function! magit#sign#find_stage_signs(startline, endline)
+ return magit#sign#find_signs(s:magit_mark_signs.M, a:startline, a:endline)
+endfunction
+
+" s:magit_mark_sign: string of the sign for lines to be staged
+let s:magit_mark_signs = {'M': 'MagitTBS', 'S': 'MagitBS', 'E': 'MagitBE'}
+
+" magit#sign#init: initializer function for signs
+function! magit#sign#init()
+ execute "sign define " . s:magit_mark_signs.M . " text=S> linehl=Visual"
+ execute "sign define " . s:magit_mark_signs.S
+ execute "sign define " . s:magit_mark_signs.E
+endfunction
+
+" magit#sign#toggle_signs: toggle marks for range of lines
+" marked lines are unmarked, non marked are marked
+" param[in] type; type of sign to toggle (see s:magit_mark_signs)
+" param[in] startline,endline: range of lines
+function! magit#sign#toggle_signs(type, startline, endline)
+ let bufnr = magit#utils#bufnr()
+ let current_signs = magit#sign#find_signs(s:magit_mark_signs[a:type], a:startline, a:endline)
+ let line = a:startline
+ while ( line <= a:endline )
+ if ( has_key(current_signs, line) == 0 )
+ call magit#sign#add_sign(line, a:type, bufnr)
+ else
+ call magit#sign#remove_sign(current_signs[line].id)
+ endif
+ let line += 1
+ endwhile
+endfunction
diff --git a/.config/vim/autoload/magit/state.vim b/.config/vim/autoload/magit/state.vim
@@ -0,0 +1,385 @@
+" magit#state#is_file_visible: file getter function
+" return if file is visible
+function! magit#state#is_file_visible() dict
+ return self.visible
+endfunction
+
+" magit#state#set_file_visible: file setter function
+" param[in] val: visible state to set to file
+function! magit#state#set_file_visible(val) dict
+ let self.visible = a:val
+endfunction
+
+" magit#state#toggle_file_visible: file setter function, toggle file visible
+" state
+function! magit#state#toggle_file_visible() dict
+ let self.visible = ( self.visible == 0 ) ? 1 : 0
+endfunction
+
+" magit#state#init_file_visible: init file visible status, among several conditions
+function! magit#state#init_file_visible() dict
+ if ( !self.new )
+ return self.is_visible()
+ else
+ if ( self.status == 'M' || b:magit_default_show_all_files > 1 )
+ call self.set_visible(b:magit_default_show_all_files)
+ endif
+ return self.is_visible()
+ endif
+endfunction
+
+" magit#state#is_file_dir: file getter function
+" return 1 if current file is a directory, 0 otherwise
+function! magit#state#is_file_dir() dict
+ return self.dir != 0
+endfunction
+
+" magit#state#must_be_added: file helper function
+" there are some conditions where files must be widely added (git add), not
+" 'diff applied' (git apply)
+" return 1 if file must
+function! magit#state#must_be_added() dict
+ return ( self.empty == 1 ||
+ \ self.symlink != '' ||
+ \ self.dir != 0 ||
+ \ self.binary == 1 ||
+ \ self.submodule == 1 )
+endfunction
+
+" magit#state#file_get_hunks: function accessor for hunks objects
+" return: List of List of hunks lines
+function! magit#state#file_get_hunks() dict
+ return self.diff.hunks
+endfunction
+
+" magit#state#file_get_flat_hunks: function accessor for hunks lines
+" return: all hunks lines of a file, including hunk headers
+function! magit#state#file_get_flat_hunks() dict
+ let hunks = self.diff.hunks
+ let lines = []
+ for hunk in hunks
+ call add(lines, hunk.header)
+ call add(lines, hunk.lines)
+ endfor
+ return lines
+endfunction
+
+" s:hunk_template: template for hunk object (nested in s:diff_template)
+" WARNING: this variable must be deepcopy()'ied
+let s:hunk_template = {
+\ 'header': '',
+\ 'line_pos': 0,
+\ 'lines': [],
+\ 'marks': [],
+\}
+
+" s:diff_template: template for diff object (nested in s:file_template)
+" WARNING: this variable must be deepcopy()'ied
+let s:diff_template = {
+\ 'len': 0,
+\ 'header': [],
+\ 'hunks': [s:hunk_template],
+\}
+
+" s:file_template: template for file object
+" WARNING: this variable must be deepcopy()'ied
+let s:file_template = {
+\ 'new': 1,
+\ 'exists': 0,
+\ 'visible': 0,
+\ 'filename': '',
+\ 'status': '',
+\ 'empty': 0,
+\ 'dir': 0,
+\ 'binary': 0,
+\ 'submodule': 0,
+\ 'symlink': '',
+\ 'diff': s:diff_template,
+\ 'line_pos': 0,
+\ 'is_dir': function("magit#state#is_file_dir"),
+\ 'is_visible': function("magit#state#is_file_visible"),
+\ 'set_visible': function("magit#state#set_file_visible"),
+\ 'init_visible': function("magit#state#init_file_visible"),
+\ 'toggle_visible': function("magit#state#toggle_file_visible"),
+\ 'must_be_added': function("magit#state#must_be_added"),
+\ 'get_header': function("magit#state#file_get_header"),
+\ 'get_hunks' : function("magit#state#file_get_hunks"),
+\ 'get_flat_hunks' : function("magit#state#file_get_flat_hunks"),
+\ 'get_filename_header' : function("magit#state#file_get_filename_header"),
+\}
+
+" magit#state#get_file: function accessor for file
+" param[in] mode: can be staged or unstaged
+" param[in] filename: filename to access
+" param[in] create: boolean. If 1, non existing file in Dict will be created.
+" if 0, 'file_doesnt_exists' exception will be thrown
+" return: Dict of file
+function! magit#state#get_file(mode, filename, ...) dict
+ let file_exists = has_key(self.dict[a:mode], a:filename)
+ let create = ( a:0 == 1 ) ? a:1 : 0
+ if ( file_exists == 0 && create == 1 )
+ let self.dict[a:mode][a:filename] = deepcopy(s:file_template)
+ let self.dict[a:mode][a:filename].filename = a:filename
+ elseif ( file_exists == 0 && create == 0 )
+ throw 'file_doesnt_exists'
+ endif
+ return self.dict[a:mode][a:filename]
+endfunction
+
+" magit#state#file_get_header: function accessor for diff header
+" param[in] mode: can be staged or unstaged
+" param[in] filename: header of filename to access
+" return: List of diff header lines
+function! magit#state#file_get_header() dict
+ return self.diff.header
+endfunction
+
+function! magit#state#file_get_filename_header() dict
+ if ( self.status == 'L' )
+ return g:magit_git_status_code.L . ': ' . self.filename . ' -> ' . self.symlink
+ else
+ return g:magit_git_status_code[self.status] . ': ' . self.filename
+ endif
+endfunction
+
+function! magit#state#check_max_lines(file) dict
+ let total_lines = self.nb_diff_lines + a:file.diff.len
+ if ( total_lines > g:magit_warning_max_lines && b:magit_warning_max_lines_answered == 0 )
+ echohl WarningMsg
+ let ret = input("There are " . total_lines . " diff lines to display. Do you want to display all diffs? y(es) / N(o) : ", "")
+ echohl None
+ let b:magit_warning_max_lines_answered = 1
+ if ( ret !~? '^y\%(e\%(s\)\?\)\?$' )
+ call a:file.set_visible(0)
+ let a:file.diff.len = 0
+ let b:magit_default_show_all_files = 0
+ return 1
+ endif
+ endif
+ return 0
+endfunction
+
+" magit#state#add_file: method to add a file with all its
+" properties (filename, exists, status, header and hunks)
+" param[in] mode: can be staged or unstaged
+" param[in] status: one character status code of the file (AMDRCU?)
+" param[in] filename: filename
+function! magit#state#add_file(mode, status, filename, depth) dict
+ let file = self.get_file(a:mode, a:filename, 1)
+ let file.exists = 1
+
+ let file.status = a:status
+ let file.depth = a:depth
+
+ " discard previous diff
+ let file.diff = deepcopy(s:diff_template)
+
+ if ( a:status == '?' && getftype(a:filename) == 'link' )
+ let file.status = 'L'
+ let file.symlink = resolve(a:filename)
+ let file.diff.hunks[0].header = 'New symbolic link file'
+ elseif ( magit#utils#is_submodule(a:filename))
+ let file.status = 'S'
+ let file.submodule = 1
+ if ( !file.is_visible() )
+ return
+ endif
+ let diff_list=magit#git#git_sub_summary(magit#utils#add_quotes(a:filename),
+ \ a:mode)
+ let file.diff.len = len(diff_list)
+
+ if ( self.check_max_lines(file) != 0 )
+ return
+ endif
+
+ let file.diff.hunks[0].header = ''
+ let file.diff.hunks[0].lines = diff_list
+ let self.nb_diff_lines += file.diff.len
+ elseif ( a:status == '?' && isdirectory(a:filename) == 1 )
+ let file.status = 'N'
+ let file.dir = 1
+ if ( !file.is_visible() )
+ return
+ endif
+ for subfile in magit#utils#ls_all(a:filename)
+ call self.add_file(a:mode, a:status, subfile, a:depth + 1)
+ endfor
+ elseif ( a:status == '?' && getfsize(a:filename) == 0 )
+ let file.status = 'E'
+ let file.empty = 1
+ let file.diff.hunks[0].header = 'New empty file'
+ else
+ if ( !file.init_visible() )
+ return
+ endif
+ let line = 0
+ " match(
+ let [ is_bin, diff_list ] =
+ \ magit#git#git_diff(magit#utils#add_quotes(a:filename),
+ \ a:status, a:mode)
+
+ if ( is_bin )
+ let file.binary = 1
+ let file.diff.hunks[0].header = 'Binary file'
+ if ( file.new )
+ call file.set_visible(0)
+ endif
+ return
+ endif
+
+ let file.diff.len = len(diff_list)
+
+ if ( self.check_max_lines(file) != 0 )
+ return
+ endif
+
+ while ( line < file.diff.len && diff_list[line] !~ "^@.*" )
+ call add(file.diff.header, diff_list[line])
+ let line += 1
+ endwhile
+
+ if ( line < file.diff.len )
+ let hunk = file.diff.hunks[0]
+ let hunk.header = diff_list[line]
+
+ for diff_line in diff_list[line+1 : -1]
+ if ( diff_line =~ "^@.*" )
+ let hunk = deepcopy(s:hunk_template)
+ call add(file.diff.hunks, hunk)
+ let hunk.header = diff_line
+ continue
+ endif
+ call add(hunk.lines, diff_line)
+ endfor
+ endif
+ let self.nb_diff_lines += file.diff.len
+ endif
+
+endfunction
+
+" magit#state#update: update self.dict
+" if a file does not exists anymore (because all its changes have been
+" committed, deleted, discarded), it is removed from g:mg_diff_dict
+" else, its diff is discarded and regenrated
+" what is resilient is its 'visible' parameter
+function! magit#state#update() dict
+ let self.nb_diff_lines = 0
+ for diff_dict_mode in values(self.dict)
+ for file in values(diff_dict_mode)
+ let file.exists = 0
+ let file.new = 0
+ " always discard previous diff
+ let file.diff = deepcopy(s:diff_template)
+ endfor
+ endfor
+
+ let dir = getcwd()
+ try
+ call magit#utils#chdir(magit#git#top_dir())
+ call magit#utils#refresh_submodule_list()
+ let status_list = magit#git#get_status()
+ for [mode, diff_dict_mode] in items(self.dict)
+ for file_status in status_list
+ let status=file_status[mode]
+
+ " untracked code apperas in staged column, we skip it
+ if ( status == ' ' || ( ( mode == 'staged' ) && status == '?' ) )
+ continue
+ endif
+ call self.add_file(mode, status, file_status.filename, 0)
+ endfor
+ endfor
+ finally
+ call magit#utils#chdir(dir)
+ endtry
+
+ " remove files that have changed their mode or been committed/deleted/discarded...
+ for diff_dict_mode in values(self.dict)
+ for [key, file] in items(diff_dict_mode)
+ if ( file.exists == 0 )
+ unlet diff_dict_mode[key]
+ endif
+ endfor
+ endfor
+endfunction
+
+" magit#state#set_files_visible: global dict setter function
+" update all files visible state
+" param[in] is_visible: boolean value to set to files
+function! magit#state#set_files_visible(is_visible) dict
+ for diff_dict_mode in values(self.dict)
+ for file in values(diff_dict_mode)
+ call file.set_visible(a:is_visible)
+ endfor
+ endfor
+endfunction
+
+" magit#state#get_files: global dict file objects getter function
+" param[in] mode: mode to select, can be 'staged' or 'unstaged'
+" return list of file objects belonging to mode
+function! magit#state#get_files(mode) dict
+ return self.dict[a:mode]
+endfunction
+
+" magit#state#get_files_nb: returns the number of files in a given section
+" param[in] mode: mode to select, can be 'staged' or 'unstaged'
+" return number of files of this section
+function! magit#state#get_files_nb(mode) dict
+ return len(self.dict[a:mode])
+endfunction
+
+" magit#state#get_files: global dict file objects (copy) getter function
+" param[in] mode: mode to select, can be 'staged' or 'unstaged'
+" return ordered list of file objects belonging to mode
+function! magit#state#get_files_ordered(mode) dict
+ let modified = []
+ let others = []
+ for filename in sort(keys(self.dict[a:mode]))
+ let file = self.get_file(a:mode, filename)
+ if ( file.status == 'M' )
+ call add(modified, file)
+ else
+ call add(others, file)
+ endif
+ endfor
+ return modified + others
+endfunction
+
+" magit#state#get_filenames: global dict filenames getter function
+" param[in] mode: mode to select, can be 'staged' or 'unstaged'
+" return ordered list of filename strings belonging to mode, modified files
+" first
+function! magit#state#get_filenames(mode) dict
+ let files = self.get_files_ordered(a:mode)
+ return map(copy(files), 'v:val.filename')
+endfunction
+
+
+" dict: structure containing all diffs
+" It is formatted as follow
+" {
+" 'staged': {
+" 'filename': s:file_template,
+" 'filename': s:file_template,
+" ...
+" },
+" 'unstaged': {
+" 'filename': s:file_template,
+" 'filename': s:file_template,
+" ...
+" },
+" }
+let magit#state#state = {
+ \ 'nb_diff_lines': 0,
+ \ 'get_file': function("magit#state#get_file"),
+ \ 'get_files': function("magit#state#get_files"),
+ \ 'get_files_nb': function("magit#state#get_files_nb"),
+ \ 'get_files_ordered': function("magit#state#get_files_ordered"),
+ \ 'get_filenames': function("magit#state#get_filenames"),
+ \ 'add_file': function("magit#state#add_file"),
+ \ 'set_files_visible': function("magit#state#set_files_visible"),
+ \ 'check_max_lines': function("magit#state#check_max_lines"),
+ \ 'update': function("magit#state#update"),
+ \ 'dict': { 'staged': {}, 'unstaged': {}},
+ \ }
+
diff --git a/.config/vim/autoload/magit/sys.vim b/.config/vim/autoload/magit/sys.vim
@@ -0,0 +1,119 @@
+" ======= system wrappers =======
+" Recent vim/neovim versions introduced a new handy function, systemlist:
+" > Same as |system()|, but returns a |List| with lines (parts of
+" > output separated by NL) with NULs transformed into NLs.
+" In the same time, they introduced the capabilty of system to take a list as
+" parameter
+" These two new behavior are emulated if not present.
+" Moreover, v:shell_error are detected and an exception is thrown if any.
+" Matching functions, without exception raising, are available. The problem is
+" that if an error is awaited, the exception thrown discards the return value.
+
+" s:system: magit#sys#system internal, with explicit catch shell error
+" parameter
+" param[in] ...: command + optional args
+" return: command output as a string
+function! s:magit_system(...)
+ let dir = getcwd()
+ try
+ call magit#utils#chdir(magit#git#top_dir())
+ " List as system() input is since v7.4.247, it is safe to check
+ " systemlist, which is sine v7.4.248
+ if exists('*systemlist')
+ return call('system', a:000)
+ else
+ if ( a:0 == 2 )
+ if ( type(a:2) == type([]) )
+ " ouch, this one is tough: input is very very sensitive, join
+ " MUST BE done with "\n", not '\n' !!
+ let arg=join(a:2, "\n")
+ else
+ let arg=a:2
+ endif
+ return system(a:1, arg)
+ else
+ return system(a:1)
+ endif
+ endif
+ finally
+ call magit#utils#chdir(dir)
+ endtry
+endfunction
+
+" s:systemlist: magit#sys#systemlist internal, with explicit catch shell
+" error parameter
+" param[in] catch: boolean, do we throw an exception in case of shell error
+" param[in] ...: command + optional args to execute, args can be List or String
+" return: command output as a list
+function! s:magit_systemlist(...)
+ let dir = getcwd()
+ try
+ call magit#utils#chdir(magit#git#top_dir())
+ " systemlist since v7.4.248
+ if exists('*systemlist')
+ return call('systemlist', a:000)
+ else
+ return split(call('s:magit_system', a:000), '\n')
+ endif
+ finally
+ call magit#utils#chdir(dir)
+ endtry
+endfunction
+
+" magit#sys#system: wrapper for system, which only takes String as input in vim,
+" although it can take String or List input in neovim.
+" INFO: temporarly change pwd to git top directory, then restore to previous
+" pwd at the end of function
+" param[in] ...: command + optional args
+" return: command output as a string
+" throw 'shell_error' in case of shell error
+function! magit#sys#system(...)
+ let ret = call('s:magit_system', a:000)
+ if ( v:shell_error != 0 )
+ let b:magit_shell_error = string(ret)
+ let b:magit_shell_cmd = string(a:000)
+ throw 'shell_error'
+ endif
+ return ret
+endfunction
+
+" magit#sys#systemlist: wrapper for systemlist, which only exists in neovim for
+" the moment.
+" INFO: temporarly change pwd to git top directory, then restore to previous
+" pwd at the end of function
+" param[in] ...: command + optional args to execute, args can be List or String
+" return: command output as a list
+" throw 'shell_error' in case of shell error
+function! magit#sys#systemlist(...)
+ let ret = call('s:magit_systemlist', a:000)
+ if ( v:shell_error != 0 )
+ let b:magit_shell_error = string(ret)
+ let b:magit_shell_cmd = string(a:000)
+ throw 'shell_error'
+ endif
+ return ret
+endfunction
+
+" magit#sys#system_noraise: magit#sys#system alias, without error
+" exception
+" param[in] ...: command + optional args
+" return: command output as a string
+function! magit#sys#system_noraise(...)
+ return call('s:magit_system', a:000)
+endfunction
+
+" magit#sys#systemlist_noraise: magit#sys#systemlist alias, without error
+" exception
+" param[in] ...: command + optional args to execute, args can be List or String
+" return: command output as a list
+function! magit#sys#systemlist_noraise(...)
+ return call('s:magit_systemlist', a:000)
+endfunction
+
+function! magit#sys#print_shell_error()
+ echohl WarningMsg
+ echom "Shell command error"
+ echom "Cmd: " . b:magit_shell_cmd
+ echom "Error msg: " . b:magit_shell_error
+ echohl None
+endfunction
diff --git a/.config/vim/autoload/magit/utils.vim b/.config/vim/autoload/magit/utils.vim
@@ -0,0 +1,180 @@
+
+" magit#utils#ls_all: list all files (including hidden ones) in a given path
+" return : list of filenames
+function! magit#utils#ls_all(path)
+ return split(globpath(a:path, '.[^.]*', 1) . "\n" .
+ \ globpath(a:path, '*', 1), '\n')
+endfunction
+
+let s:submodule_list = []
+" magit#utils#refresh_submodule_list: this function refresh the List s:submodule_list
+" magit#utils#is_submodule() is using s:submodule_list
+function! magit#utils#refresh_submodule_list()
+ let s:submodule_list = map(split(magit#git#submodule_status(), "\n"), 'split(v:val)[1]')
+endfunction
+
+" magit#utils#is_submodule search if dirname is in s:submodule_list
+" param[in] dirname: must end with /
+" INFO: must be called from top work tree
+function! magit#utils#is_submodule(dirname)
+ return ( index(s:submodule_list, a:dirname) != -1 )
+endfunction
+
+" magit#utils#chdir will change the directory respecting
+" local/tab-local/global directory settings.
+function! magit#utils#chdir(dir)
+ " This is a dirty hack to fix tcd breakages on neovim.
+ " Future work should be based on nvim API.
+ if exists(':tcd')
+ let chdir = haslocaldir() ? 'lcd' : haslocaldir(-1, 0) ? 'tcd' : 'cd'
+ else
+ let chdir = exists('*haslocaldir') && haslocaldir() ? 'lcd' : 'cd'
+ endif
+ execute chdir fnameescape(a:dir)
+endfunction
+
+" magit#utils#clear_undo: this function clear local undo history.
+" vimagit wants to clear undo history after each changes in vimagit buffer by
+" vimagit backend.
+" Use this function with caution: to be effective, the undo must be ack'ed
+" with a change. The hack is the line
+" exe "normal a \<BS>\<Esc>"
+" We move on first line to make this trick where it should be no folding
+function! magit#utils#clear_undo()
+ let old_undolevels = &l:undolevels
+ let cur_pos = line('.')
+ setlocal undolevels=-1
+ call cursor(1, 0)
+ exe "normal a \<BS>\<Esc>"
+ call cursor(cur_pos, 0)
+ let &l:undolevels = old_undolevels
+ unlet old_undolevels
+endfunction
+
+" magit#utils#underline: helper function to underline a string
+" param[in] title: string to underline
+" return a string composed of strlen(title) '='
+function! magit#utils#underline(title)
+ return substitute(a:title, ".", "=", "g")
+endfunction
+
+" magit#utils#strip: helper function to strip a string
+" WARNING: it only works with monoline string
+" param[in] string: string to strip
+" return: stripped string
+function! magit#utils#strip(string)
+ return substitute(a:string, '^\s*\(.\{-}\)\s*\n\=$', '\1', '')
+endfunction
+
+" magit#utils#strip_array: helper function to strip an array (remove empty rows
+" on both sides)
+" param[in] array: array to strop
+" return: stripped array
+function! magit#utils#strip_array(array)
+ let array_len = len(a:array)
+ let start = 0
+ while ( start < array_len && a:array[start] == '' )
+ let start += 1
+ endwhile
+ let end = array_len - 1
+ while ( end >= 0 && a:array[end] == '' )
+ let end -= 1
+ endwhile
+ return a:array[ start : end ]
+endfunction
+
+" magit#utils#join_list: helper function to concatente a list of strings with newlines
+" param[in] list: List to concat
+" return: concatenated list
+function! magit#utils#join_list(list)
+ return join(a:list, "\n") . "\n"
+endfunction
+
+" magit#utils#add_quotes: helper function to protect filename with quotes
+" return quoted filename
+function! magit#utils#add_quotes(filename)
+ return '"' . a:filename . '"'
+endfunction
+
+" magit#utils#remove_quotes: helper function to remove quotes aroudn filename
+" return unquoted filename
+function! magit#utils#remove_quotes(filename)
+ let ret=matchlist(a:filename, '"\([^"]*\)"')
+ if ( empty(ret) )
+ throw 'no quotes found: ' . a:filename
+ endif
+ return ret[1]
+endfunction
+
+" magit#utils#fatten: flat a nested list. it return a one dimensional list with
+" primary elements
+" https://gist.github.com/dahu/3322468
+" param[in] list: a List, can be nested or not
+" return: one dimensional list
+function! magit#utils#flatten(list)
+ let val = []
+ for elem in a:list
+ if type(elem) == type([])
+ call extend(val, magit#utils#flatten(elem))
+ else
+ call extend(val, [elem])
+ endif
+ unlet elem
+ endfor
+ return val
+endfunction
+
+" magit#utils#append_file: helper function to append to a file
+" Version working with file *possibly* containing trailing newline
+" param[in] file: filename to append
+" param[in] lines: List of lines to append
+function! magit#utils#append_file(file, lines)
+ let fcontents=[]
+ if ( filereadable(a:file) )
+ let fcontents=readfile(a:file, 'b')
+ endif
+ if !empty(fcontents) && empty(fcontents[-1])
+ call remove(fcontents, -1)
+ endif
+ call writefile(fcontents+a:lines, a:file, 'b')
+endfunction
+
+" s:bufnr: local variable to store current magit buffer id
+let s:bufnr = 0
+" magit#utils#setbufnr: function to set current magit buffer id
+" param[in] bufnr: current magit buffer id
+function! magit#utils#setbufnr(bufnr)
+ let s:bufnr = a:bufnr
+endfunction
+
+" magit#utils#bufnr: function to get current magit buffer id
+" return: current magit buffer id
+function! magit#utils#bufnr()
+ return s:bufnr
+endfunction
+
+" magit#utils#search_buffer_in_windows: search if a buffer is displayed in one
+" of opened windows
+" NOTE: windo command modify winnr('#'), if you want to use it, save it before
+" calling this function
+" param[in] filename: filename to search
+" return: window id, 0 if not found
+function! magit#utils#search_buffer_in_windows(filename)
+ let cur_win = winnr()
+ let last_win = winnr('#')
+ let files={}
+ windo if ( !empty(@%) ) | let files[@%] = winnr() | endif
+ execute last_win."wincmd w"
+ execute cur_win."wincmd w"
+ return ( has_key(files, buffer_name(a:filename)) ) ?
+ \files[buffer_name(a:filename)] : 0
+endfunction
+
+function! magit#utils#start_profile(...)
+ let prof_file = ( a:0 == 1 ) ? a:1 : "/tmp/vimagit.log"
+ profdel *
+ execute "profile start " . prof_file . " | profile pause"
+ profile file *
+ profile func *
+ profile continue
+endfunction
diff --git a/.config/vim/colors/.vimrc b/.config/vim/colors/.vimrc
diff --git a/.config/vim/common/magit_common.vim b/.config/vim/common/magit_common.vim
@@ -0,0 +1,62 @@
+" Section names
+" These are used to beautify the magit buffer and to help for some block
+" selection
+let g:magit_sections = {
+ \ 'info': 'Info',
+ \ 'help': 'Help',
+ \ 'staged': 'Staged changes',
+ \ 'unstaged': 'Unstaged changes',
+ \ 'commit': 'Commit message',
+ \ 'stash': 'Stash list'
+ \ }
+
+let g:magit_section_info = {
+ \ 'cur_repo': 'Repository:',
+ \ 'cur_head': 'Head:',
+ \ 'cur_upstream': 'Upstream:',
+ \ 'cur_push': 'Push:',
+ \ 'commit_mode': 'Commit mode:',
+ \ }
+
+let g:magit_git_status_code = {
+ \ 'M': 'modified',
+ \ 'A': 'added',
+ \ 'D': 'deleted',
+ \ 'R': 'renamed',
+ \ 'T': 'typechanged',
+ \ 'C': 'copied',
+ \ 'U': 'updated but unmerged',
+ \ '?': 'untracked',
+ \ '!': 'ignored',
+ \ 'E': 'empty',
+ \ 'L': 'symlink',
+ \ 'N': 'new dir',
+ \ 'S': 'submodule',
+ \ }
+
+let g:magit_commit_mode = {
+ \ 'CC': 'normal',
+ \ 'CA': 'amend',
+ \ }
+
+" Regular expressions used to select blocks
+let g:magit_file_re = '^\('
+for status_code in values(g:magit_git_status_code)
+ let g:magit_file_re .= status_code . '\|'
+endfor
+let g:magit_file_re .= 'unknown status\): \(.\{-\}\)\%( -> .*\)\?$'
+
+let g:magit_section_re = '^\('
+for section_name in values(g:magit_sections)
+ let g:magit_section_re .= section_name . '\|'
+endfor
+let g:magit_section_re .= 'unknown section\)$'
+
+let g:magit_diff_re = '^diff --git'
+let g:magit_end_diff_re = '^$'
+let g:magit_stash_re = '^stash@{\d\+}:'
+let g:magit_hunk_re = '^@@ -\(\d\+\),\?\(\d*\) +\(\d\+\),\?\(\d*\) @@'
+let g:magit_bin_re = '^Binary files '
+let g:magit_eof_re = '\%$'
+
+
diff --git a/.config/vim/plugin/deadkeys.vim b/.config/vim/plugin/deadkeys.vim
@@ -0,0 +1,253 @@
+let g:DeadKeysOn=0
+
+function! ToggleDeadKeys()
+ if !g:DeadKeysOn
+ call DeadKeys()
+ else
+ call DeadKeysOff()
+ endif
+endfunction
+
+function! DeadKeys()
+ echo "Dead Keys: On"
+ let g:DeadKeysOn=1
+ " grave accents
+ imap `a à
+ imap `e è
+ imap `i ì
+ imap `o ò
+ imap `u ù
+ imap `A À
+ imap `E È
+ imap `I Ì
+ imap `O Ò
+ imap `U Ù
+ imap `<space> `
+
+ " umlaut
+ imap "a ä
+ imap "e ë
+ imap "i ï
+ imap "o ö
+ imap "u ü
+ imap "A Ä
+ imap "E Ë
+ imap "I Ï
+ imap "O Ö
+ imap "U Ü
+ imap "<space> "
+
+ " macrons
+ imap :a ā
+ imap :e ē
+ imap :i ī
+ imap :o ō
+ imap :u ū
+ imap :A Ā
+ imap :E Ē
+ imap :I Ī
+ imap :O Ō
+ imap :U Ū
+
+ " acute accents
+ imap 'a á
+ imap 'A Á
+ imap 'C Ć
+ imap 'c ć
+ imap 'e é
+ imap 'E É
+ imap 'i í
+ imap 'I Í
+ imap 'N Ń
+ imap 'n ń
+ imap 'o ó
+ imap 'R Ŕ
+ imap 'r ŕ
+ imap 'S Ś
+ imap 's ś
+ imap 'O Ó
+ imap 'u ú
+ imap 'U Ú
+ imap '<space> '
+
+ " under dot
+ imap .D Ḍ
+ imap .d ḍ
+ imap .H Ḥ
+ imap .h ḥ
+ imap .L Ḹ
+ imap .l ḹ
+ imap .M Ṃ
+ imap .m ṃ
+ imap .N Ṇ
+ imap .n ṇ
+ imap .R Ṛ
+ imap .r ṛ
+ imap .G Ṝ
+ imap .g ṝ
+ imap .S Ṣ
+ imap .s ṣ
+ imap .T Ṭ
+ imap .t ṭ
+
+ " tilde
+ imap ~a ã
+ imap ~A Ã
+ imap ~e ẽ
+ imap ~E Ẽ
+ imap ~i ĩ
+ imap ~I Ĩ
+ imap ~o õ
+ imap ~O Õ
+ imap ~u ũ
+ imap ~U Ũ
+ imap ~n ñ
+ imap ~N Ñ
+
+ " caron
+ imap >A Ǎ
+ imap >a ǎ
+ imap >C Č
+ imap >c č
+ imap >E Ě
+ imap >e ě
+ imap >G Ǧ
+ imap >g ǧ
+ imap >I Ǐ
+ imap >i ǐ
+ imap >O Ǒ
+ imap >o ǒ
+ imap >R Ř
+ imap >r ř
+ imap >S Ṧ
+ imap >s ṧ
+ imap >U Ǔ
+ imap >u ǔ
+ imap >V Ǚ
+ imap >v ǚ
+ imap >Z Ž
+ imap >z ž
+
+endfunction "deadkeys()
+
+
+function! DeadKeysOff()
+ echo "Dead Keys: Off"
+ let g:DeadKeysOn=0
+
+ " unmapping graves
+ iunmap `a
+ iunmap `e
+ iunmap `i
+ iunmap `o
+ iunmap `u
+ iunmap `A
+ iunmap `E
+ iunmap `I
+ iunmap `O
+ iunmap `U
+ iunmap `<space>
+
+ " unmapping umlauts
+ iunmap "a
+ iunmap "e
+ iunmap "i
+ iunmap "o
+ iunmap "u
+ iunmap "A
+ iunmap "E
+ iunmap "I
+ iunmap "O
+ iunmap "U
+ iunmap "<space>
+
+ " unmapping macrons
+ iunmap :a
+ iunmap :e
+ iunmap :i
+ iunmap :o
+ iunmap :u
+ iunmap :A
+ iunmap :E
+ iunmap :I
+ iunmap :O
+ iunmap :U
+
+ " unmapping acutes
+ iunmap 'a
+ iunmap 'A
+ iunmap 'C
+ iunmap 'c
+ iunmap 'e
+ iunmap 'E
+ iunmap 'i
+ iunmap 'I
+ iunmap 'N
+ iunmap 'n
+ iunmap 'o
+ iunmap 'R
+ iunmap 'r
+ iunmap 'S
+ iunmap 's
+ iunmap 'O
+ iunmap 'u
+ iunmap 'U
+ iunmap '<space>
+ " under dot
+ iunmap .D
+ iunmap .d
+ iunmap .H
+ iunmap .h
+ iunmap .L
+ iunmap .l
+ iunmap .M
+ iunmap .m
+ iunmap .N
+ iunmap .n
+ iunmap .R
+ iunmap .r
+ iunmap .G
+ iunmap .g
+ iunmap .S
+ iunmap .s
+ iunmap .T
+ iunmap .t
+
+ "tilde
+ iunmap ~a
+ iunmap ~A
+ iunmap ~e
+ iunmap ~E
+ iunmap ~i
+ iunmap ~I
+ iunmap ~o
+ iunmap ~O
+ iunmap ~u
+ iunmap ~U
+ iunmap ~n
+
+ " caron
+ iunmap >A
+ iunmap >a
+ iunmap >C
+ iunmap >c
+ iunmap >E
+ iunmap >e
+ iunmap >G
+ iunmap >g
+ iunmap >I
+ iunmap >i
+ iunmap >O
+ iunmap >o
+ iunmap >R
+ iunmap >r
+ iunmap >S
+ iunmap >s
+ iunmap >U
+ iunmap >u
+ iunmap >V
+ iunmap >v
+ iunmap >Z
+ iunmap >z
+
+endfunction
diff --git a/.config/vim/plugin/goyo.vim b/.config/vim/plugin/goyo.vim
@@ -0,0 +1,24 @@
+" Copyright (c) 2015 Junegunn Choi
+"
+" MIT License
+"
+" Permission is hereby granted, free of charge, to any person obtaining
+" a copy of this software and associated documentation files (the
+" "Software"), to deal in the Software without restriction, including
+" without limitation the rights to use, copy, modify, merge, publish,
+" distribute, sublicense, and/or sell copies of the Software, and to
+" permit persons to whom the Software is furnished to do so, subject to
+" the following conditions:
+"
+" The above copyright notice and this permission notice shall be
+" included in all copies or substantial portions of the Software.
+"
+" THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+" EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+" MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+" NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+" LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+" OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+" WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+command! -nargs=? -bar -bang Goyo call goyo#execute(<bang>0, <q-args>)
diff --git a/.config/vim/plugin/ipa.vim b/.config/vim/plugin/ipa.vim
@@ -0,0 +1,186 @@
+let g:IPAOn=0
+
+function! ToggleIPA()
+ if !g:IPAOn
+ call IPA()
+ else
+ call IPAOff()
+ endif
+endfunction
+
+function! IPA()
+ echo "IPA macros activated"
+ let g:IPAOn=1
+ imap ,nn ɲ̊
+ imap ,gn ɲ
+ imap ,ng ŋ
+ imap ,' ʔ
+ imap ,sh ʃ
+ imap ,zh ʒ
+ imap ,xi ɕ
+ imap ,zi ʑ
+ imap ,ph ɸ
+ imap ,bh β
+ imap ,th θ
+ imap ,dh ð
+ imap ,cc ç
+ imap ,jj ʝ
+ imap ,gh ɣ
+ imap ,xx χ
+ imap ,fr ʁ
+ imap ,HH ħ
+ imap ,hh ɦ
+ imap ,vv ʋ
+ imap ,er ɹ
+ imap ,fl ɾ
+ imap ,bb ʙ
+ imap ,ih ɨ
+ imap ,ii ɪ
+ imap ,eu ɯ̽
+ imap ,uu ʊ
+ imap ,uh ə
+ imap ,eh ɛ
+ imap ,oe œ
+ imap ,au ɔ
+ imap ,ae æ
+ imap ,aa ɐ
+ imap ,OE ɶ
+ imap ,ah ɑ
+ imap ,ba ɒ
+endfunction
+
+function! IPAOff()
+ echo "IPA macros off."
+ let g:IPAOn=0
+ iunmap ,nn
+ iunmap ,gn
+ iunmap ,ng
+ iunmap ,'
+ iunmap ,sh
+ iunmap ,zh
+ iunmap ,xi
+ iunmap ,zi
+ iunmap ,ph
+ iunmap ,bh
+ iunmap ,th
+ iunmap ,dh
+ iunmap ,cc
+ iunmap ,jj
+ iunmap ,gh
+ iunmap ,xx
+ iunmap ,fr
+ iunmap ,HH
+ iunmap ,hh
+ iunmap ,vv
+ iunmap ,er
+ iunmap ,fl
+ iunmap ,bb
+ iunmap ,ih
+ iunmap ,ii
+ iunmap ,eu
+ iunmap ,uu
+ iunmap ,uh
+ iunmap ,eh
+ iunmap ,oe
+ iunmap ,au
+ iunmap ,ae
+ iunmap ,aa
+ iunmap ,OE
+ iunmap ,ah
+ iunmap ,ba
+endfunction
+
+" As of yet unimplemented:
+"b̪
+"t̼
+"d̼
+"ʈ
+"ɖ
+"ɟ
+"ɡ
+"ɢ
+"ʡ
+"ʂ
+"ʐ
+"θ̼
+"ð̼
+"θ̠
+"ð̠
+"ɹ̠̊
+"ɹ̠
+"ɻ
+"ʕ
+"ʢ
+"ʋ̥
+"ɹ̥
+"ɻ̊
+"ɻ
+"j̊
+"ɰ̊
+"ɰ
+"ʔ̞
+"ⱱ̟
+"ⱱ
+"ɾ̼
+"ɾ̥
+"ɽ̊
+"ɽ
+"ɢ̆
+"ʡ̮
+"ʙ̥
+"r̼
+"r̥
+"ɽ̊
+"ɽ
+"ʀ̥
+"ʀ
+"ʜ
+"ʢ
+"ɬ
+"ɮ
+"ɭ̊
+"ʎ̥
+"ʎ̝
+"ʟ̝̊
+"ʟ̝
+"l̥
+"ɭ̊
+"ɭ
+"ʎ̥
+"ʎ
+"ʟ̥
+"ʟ
+"ʟ̠
+"ɺ
+"ɺ̢
+"ʎ̮
+"ʟ̆
+"ʉ
+"ɯ
+"ʏ
+"ɪ̈
+"ʊ̈
+"ø
+"ɘ
+"ɵ
+"ɤ
+"e̞
+"ø̞
+"ɵ̞
+"ɤ̞
+"o̞
+"ɜ
+"ɞ
+"ʌ
+"ɞ̞
+"ä
+"ɒ̈
+"m̥
+"ɱ
+"n̼
+"n̥
+"ɳ̊
+"ɳ
+"ŋ̊
+"ɴ
+"p̪
diff --git a/.config/vim/plugin/magit.vim b/.config/vim/plugin/magit.vim
@@ -0,0 +1,1357 @@
+scriptencoding utf-8
+
+if exists('g:loaded_magit') || !executable('git') || &cp
+ finish
+endif
+let g:loaded_magit = 1
+
+let g:vimagit_version = [1, 7, 3]
+
+" Initialisation {{{
+
+" FIXME: find if there is a minimum vim version required
+" if v:version < 703
+" endif
+
+" source common file. variables in common file are shared with plugin and
+" syntax files
+let g:vimagit_path = fnameescape(resolve(expand('<sfile>:p:h')))
+execute 'source ' . g:vimagit_path . '/../common/magit_common.vim'
+
+" these mappings are broadly applied, for all vim buffers
+let g:magit_show_magit_mapping = get(g:, 'magit_show_magit_mapping', '<leader>M' )
+
+" user options
+let g:magit_enabled = get(g:, 'magit_enabled', 1)
+let g:magit_show_help = get(g:, 'magit_show_help', 0)
+let g:magit_default_show_all_files = get(g:, 'magit_default_show_all_files', 1)
+let g:magit_default_fold_level = get(g:, 'magit_default_fold_level', 1)
+let g:magit_auto_close = get(g:, 'magit_auto_close', 0)
+let g:magit_auto_foldopen = get(g:, 'magit_auto_foldopen', 1)
+let g:magit_default_sections = get(g:, 'magit_default_sections', ['info', 'global_help', 'commit', 'staged', 'unstaged'])
+let g:magit_discard_untracked_do_delete = get(g:, 'magit_discard_untracked_do_delete', 0)
+
+let g:magit_refresh_gutter = get(g:, 'magit_refresh_gutter' , 1)
+" Should deprecate the following
+let g:magit_refresh_gitgutter = get(g:, 'magit_refresh_gitgutter', 0)
+
+let g:magit_commit_title_limit = get(g:, 'magit_commit_title_limit', 50)
+
+let g:magit_scrolloff = get(g:, 'magit_scrolloff', 3)
+
+let g:magit_warning_max_lines = get(g:, 'magit_warning_max_lines', 10000)
+
+let g:magit_git_cmd = get(g:, 'magit_git_cmd' , "git")
+
+execute "nnoremap <silent> " . g:magit_show_magit_mapping . " :call magit#show_magit('v')<cr>"
+
+if (g:magit_refresh_gutter == 1 || g:magit_refresh_gitgutter == 1)
+ autocmd User VimagitUpdateFile
+ \ if ( exists("*gitgutter#process_buffer") ) |
+ \ call gitgutter#process_buffer(bufnr(g:magit_last_updated_buffer), 0) |
+ \ elseif ( exists("*sy#util#refresh_windows") ) |
+ \ call sy#util#refresh_windows() |
+ \ endif
+endif
+" }}}
+
+" s:mg_cut_str cut a string given a limit size
+" param[in] str string to cut
+" param[in] limit maximum number of column
+" return string cut on limit
+function! s:mg_cut_str(str, limit)
+ if ( len(a:str) < a:limit )
+ return a:str
+ elseif ( ( a:limit - 3 ) < 0 )
+ return ""
+ else
+ return printf("%.*s...", a:limit - 3, a:str)
+ endif
+endfunction
+
+" s:mg_get_info: this function writes in current buffer current git state
+" WARNING: this function writes in file, it should only be called through
+" protected functions like magit#update_buffer
+function! s:mg_get_info()
+ let align_w=12
+
+ let repo_line=printf("%-*s %s",
+ \ align_w,
+ \ g:magit_section_info.cur_repo,
+ \ magit#git#top_dir())
+
+ try
+ let head_br=magit#git#get_branch_name("HEAD")
+ catch 'shell_error'
+ let head_br="Empty repository"
+ endtry
+ let upstream_br=magit#git#get_remote_branch("HEAD", "upstream")
+ let push_br=magit#git#get_remote_branch("HEAD", "push")
+ let max_br_w = max([len(head_br), len(upstream_br), len(push_br)])
+
+ let limit=winwidth(0)-align_w-max_br_w-3
+ let head_msg=s:mg_cut_str(magit#git#get_commit_subject("HEAD"), limit)
+ let upstream_msg=s:mg_cut_str(magit#git#get_commit_subject(upstream_br), limit)
+ let push_msg=s:mg_cut_str(magit#git#get_commit_subject(push_br), limit)
+
+ let head_line=magit#utils#strip(printf("%-*s %-*s %s",
+ \ align_w, g:magit_section_info.cur_head,
+ \ max_br_w, head_br, head_msg))
+ let upstream_line=magit#utils#strip(printf("%-*s %-*s %s",
+ \ align_w, g:magit_section_info.cur_upstream,
+ \ max_br_w, upstream_br, upstream_msg))
+ let push_line=magit#utils#strip(printf("%-*s %-*s %s",
+ \ align_w, g:magit_section_info.cur_push,
+ \ max_br_w, push_br, push_msg))
+
+
+ silent put =g:magit_sections.info
+ silent put =magit#utils#underline(g:magit_sections.info)
+ silent put =''
+ silent put =repo_line
+ silent put =head_line
+ silent put =upstream_line
+ silent put =push_line
+
+ if ( b:magit_current_commit_mode != '' )
+ let commit_mode_line=printf("%-*s %s",
+ \ align_w, g:magit_section_info.commit_mode,
+ \ g:magit_commit_mode[b:magit_current_commit_mode])
+ silent put =commit_mode_line
+ endif
+ silent put =''
+ silent put ='Press ? to display help'
+ silent put =''
+ silent put =''
+endfunction
+
+" s:mg_display_files: display in current buffer files, filtered by some
+" parameters
+" param[in] mode: files mode, can be 'staged' or 'unstaged'
+" param[in] curdir: directory containing files (only needed for untracked
+" directory)
+" param[in] depth: current directory depth (only needed for untracked
+" directory)
+function! s:mg_display_files(mode, curdir, depth)
+
+ " FIXME: ouch, must store subdirs in more efficient way
+ for filename in b:state.get_filenames(a:mode)
+ let file = b:state.get_file(a:mode, filename, 0)
+ if ( file.depth != a:depth || filename !~ a:curdir . '.*' )
+ continue
+ endif
+ silent put =file.get_filename_header()
+ let file.line_pos = line('.')
+
+ if ( file.dir != 0 )
+ if ( file.visible == 1 )
+ call s:mg_display_files(a:mode, filename, a:depth + 1)
+ continue
+ endif
+ endif
+
+ if ( file.visible == 0 )
+ silent put =''
+ continue
+ endif
+ if ( file.exists == 0 )
+ echoerr "Error, " . filename . " should not exists"
+ endif
+ let hunks = file.get_hunks()
+ for hunk in hunks
+ if ( hunk.header != '' )
+ silent put =hunk.header
+ let hunk.line_pos = line('.')
+ endif
+ if ( !empty(hunk.lines) )
+ silent put =hunk.lines
+ endif
+ endfor
+ silent put =''
+ endfor
+endfunction
+
+" s:mg_get_staged_section: this function writes in current buffer all staged
+" or unstaged files, using b:state.dict information
+" WARNING: this function writes in file, it should only be called through
+" protected functions like magit#update_buffer
+" param[in] mode: 'staged' or 'unstaged'
+function! s:mg_get_staged_section(mode)
+ silent put =g:magit_sections[a:mode]
+ call magit#mapping#get_section_help(a:mode)
+ silent put =magit#utils#underline(g:magit_sections[a:mode])
+ silent put =''
+ call s:mg_display_files(a:mode, '', 0)
+ silent put =''
+endfunction
+
+" s:mg_get_stashes: this function write in current buffer all stashes
+" WARNING: this function writes in file, it should only be called through
+" protected functions like magit#update_buffer
+function! s:mg_get_stashes()
+ try
+ silent! let stash_list=magit#sys#systemlist(g:magit_git_cmd . " stash list")
+ catch 'shell_error'
+ call magit#sys#print_shell_error()
+ return
+ endtry
+
+ if (!empty(stash_list))
+ silent put =g:magit_sections.stash
+ silent put =magit#utils#underline(g:magit_sections.stash)
+ silent put =''
+
+ for stash in stash_list
+ let stash_id=substitute(stash, '^\(stash@{\d\+}\):.*$', '\1', '')
+ silent put =stash
+ silent! execute "read !git stash show -p " . stash_id
+ endfor
+ silent put =''
+ silent put =''
+ endif
+endfunction
+
+" b:magit_current_commit_msg: this variable store the current commit message,
+" saving it among refreshes (remember? the whole buffer is wiped at each
+" refresh).
+let b:magit_current_commit_msg = []
+
+" s:mg_get_commit_section: this function writes in current buffer the commit
+" section. It is a commit message, depending on b:magit_current_commit_mode
+" WARNING: this function writes in file, it should only be called through
+" protected functions like magit#update_buffer
+" param[in] b:magit_current_commit_mode: this function uses global commit mode
+" 'CC': prepare a brand new commit message
+" 'CA': get the last commit message
+function! s:mg_get_commit_section()
+ if ( b:magit_current_commit_mode != '' )
+ silent put =g:magit_sections.commit
+ silent put =magit#utils#underline(g:magit_sections.commit)
+
+ let git_dir=magit#git#git_dir()
+ " refresh the COMMIT_EDITMSG file
+ if ( b:magit_current_commit_mode == 'CC' )
+ silent! call magit#sys#system_noraise("GIT_EDITOR=/bin/false " .
+ \ g:magit_git_cmd . " -c commit.verbose=no commit -e 2> /dev/null")
+ elseif ( b:magit_current_commit_mode == 'CA' )
+ silent! call magit#sys#system_noraise("GIT_EDITOR=/bin/false " .
+ \ g:magit_git_cmd . " -c commit.verbose=no commit --amend -e 2> /dev/null")
+ endif
+ if ( !empty(b:magit_current_commit_msg) )
+ silent put =b:magit_current_commit_msg
+ elseif ( filereadable(git_dir . 'COMMIT_EDITMSG') )
+ let comment_char=magit#git#get_config("core.commentChar", '#')
+ let commit_msg=magit#utils#join_list(filter(readfile(git_dir . 'COMMIT_EDITMSG'), 'v:val !~ "^' . comment_char . '"'))
+ silent put =commit_msg
+ endif
+ silent put =''
+ silent put =''
+ endif
+endfunction
+
+" s:mg_search_block: helper function, to get start and end line of a block,
+" giving a start and multiple end pattern
+" a "pattern parameter" is a List:
+" @[0]: end pattern regex
+" @[1]: number of line to exclude above (negative), below (positive) or none (0)
+" param[in] start_pattern: start "pattern parameter", which will be search
+" backward (cursor position is set to end of line before searching, to find the
+" pattern if on the current line)
+" param[in] end_pattern: list of end "pattern parameter". Each pattern is
+" searched in order. It'll choose the match with the minimum line number
+" (smallest region search)
+" param[in] upperlimit_pattern: regex of upper limit. If start_pattern line is
+" inferior to upper_limit line, block is discarded
+" param[in]: end_pattern_on_cursor: boolean, if true end pattern is also
+" search on cursor position
+" return: [startline, endline]
+function! s:mg_search_block(start_pattern, end_pattern, upper_limit_pattern,
+ \ end_pattern_on_cursor)
+
+ let upper_limit=0
+ if ( a:upper_limit_pattern != "" )
+ let upper_limit=search(a:upper_limit_pattern, "cbnW")
+ endif
+
+ let start=search(a:start_pattern[0], "cbnW")
+ if ( start == 0 || start < upper_limit )
+ throw "out_of_block"
+ endif
+ let start+=a:start_pattern[1]
+
+ let end=0
+ let min=line('$')
+ for end_p in a:end_pattern
+ let curr_end=search(end_p[0], a:end_pattern_on_cursor ? "c" : "" . "nW")
+ if ( curr_end != 0 && curr_end <= min )
+ let end=curr_end + end_p[1]
+ let min=curr_end
+ endif
+ endfor
+ if ( end == 0 )
+ throw "out_of_block"
+ endif
+
+ return [start,end]
+endfunction
+
+" s:mg_get_commit_msg: get the commit meesgae currently in commit section
+" return a string containg the commit message
+" \param[in] out_of_block (optional): if set, will first move the cursor to
+" the commit block before getting content
+function! s:mg_get_commit_msg(...)
+ let commit_section_pat_start='^'.g:magit_sections.commit.'$'
+ " Get next section pattern with g:magit_default_sections order
+ let commit_position = match(g:magit_default_sections, 'commit')
+ if ( commit_position + 1 == len(g:magit_default_sections) )
+ let commit_section_pat_end='\%$'
+ else
+ let commit_section_pat_end='^'.g:magit_sections[g:magit_default_sections[commit_position+1]].'$'
+ endif
+
+ let commit_jump_line = 2
+ let out_of_block = a:0 == 1 ? a:1 : 0
+ if ( out_of_block )
+ let old_pos=line('.')
+ let commit_pos=search(commit_section_pat_start, "cw")
+ if ( commit_pos != 0 )
+ call cursor(commit_pos+1, 0)
+ endif
+ endif
+ try
+ let [start, end] = <SID>mg_search_block(
+ \ [commit_section_pat_start, commit_jump_line],
+ \ [ [commit_section_pat_end, -1] ], "", 1)
+ finally
+ if ( out_of_block && commit_pos != 0 )
+ call cursor(old_pos, 0)
+ endif
+ endtry
+ return magit#utils#strip_array(getline(start, end))
+endfunction
+
+" s:mg_git_commit: commit staged stuff with message prepared in commit section
+" param[in] mode: mode to commit
+" 'CF': don't use commit section, just amend previous commit with staged
+" stuff, without modifying message
+" 'CC': commit staged stuff with message in commit section to a brand new
+" commit
+" 'CA': commit staged stuff with message in commit section amending last
+" commit
+" return no
+function! s:mg_git_commit(mode) abort
+ if ( a:mode == 'CF' )
+ try
+ silent let git_result=magit#sys#system(g:magit_git_cmd .
+ \ " commit --amend -C HEAD")
+ catch 'shell_error'
+ call magit#sys#print_shell_error()
+ echoerr "Commit fix failed"
+ endtry
+ else
+ let commit_flag=""
+ if ( a:mode != 'CA' && empty( magit#get_staged_files() ) )
+ let choice = confirm(
+ \ "Do you really want to commit without any staged files?",
+ \ "&Yes\n&No", 2)
+ if ( choice != 1 )
+ return
+ else
+ let commit_flag.=" --allow-empty "
+ endif
+ endif
+
+ let commit_msg=s:mg_get_commit_msg()
+ if ( empty( commit_msg ) )
+ let choice = confirm(
+ \ "Do you really want to commit with an empty message?",
+ \ "&Yes\n&No", 2)
+ if ( choice != 1 )
+ return
+ else
+ let commit_flag.=" --allow-empty-message "
+ endif
+ endif
+
+ if ( a:mode == 'CA' )
+ let commit_flag.=" --amend "
+ endif
+ let commit_cmd=g:magit_git_cmd . " commit " . commit_flag .
+ \ " --file - "
+ try
+ silent! let git_result=magit#sys#system(commit_cmd, commit_msg)
+ catch 'shell_error'
+ call magit#sys#print_shell_error()
+ echoerr "Commit failed"
+ endtry
+ let b:magit_current_commit_mode=''
+ let b:magit_current_commit_msg=[]
+ endif
+ let b:magit_just_commited = 1
+endfunction
+
+" s:mg_select_file_block: select the whole diff file, relative to the current
+" cursor position
+" nota: if the cursor is not in a diff file when the function is called, this
+" function will fail
+" return: a List
+" @[0]: return value
+" @[1]: List of lines containing the patch for the whole file
+function! s:mg_select_file_block()
+ return <SID>mg_search_block(
+ \ [g:magit_file_re, 1],
+ \ [ [g:magit_end_diff_re, 0],
+ \ [g:magit_file_re, -1],
+ \ [g:magit_stash_re, -1],
+ \ [g:magit_section_re, -2],
+ \ [g:magit_bin_re, 0],
+ \ [g:magit_eof_re, 0 ]
+ \ ],
+ \ "",
+ \ 0)
+endfunction
+
+" s:mg_select_hunk_block: select a hunk, from the current cursor position
+" nota: if the cursor is not in a hunk when the function is called, this
+" function will fail
+" return: a List
+" @[0]: return value
+" @[1]: List of lines containing the hunk
+function! s:mg_select_hunk_block()
+ return <SID>mg_search_block(
+ \ [g:magit_hunk_re, 0],
+ \ [ [g:magit_hunk_re, -1],
+ \ [g:magit_end_diff_re, 0],
+ \ [g:magit_file_re, -1],
+ \ [g:magit_stash_re, -1],
+ \ [g:magit_section_re, -2],
+ \ [g:magit_eof_re, 0 ]
+ \ ],
+ \ g:magit_file_re,
+ \ 0)
+endfunction
+
+" s:mg_create_diff_from_select: craft the diff to apply from a selection
+" in a chunk
+" remarks: it works with full lines, and can not span over multiple chunks
+" param[in] select_lines: List containing all selected line numbers
+" return: List containing the diff to apply, including the chunk header (must
+" be applied with git apply --recount)
+function! s:mg_create_diff_from_select(select_lines)
+ let start_select_line = a:select_lines[0]
+ let end_select_line = a:select_lines[-1]
+ let [starthunk,endhunk] = <SID>mg_select_hunk_block()
+ if ( start_select_line < starthunk || end_select_line > endhunk )
+ throw 'out of hunk selection'
+ endif
+ let section=magit#helper#get_section()
+ let filename=magit#helper#get_filename()
+ let hunks = b:state.get_file(section, filename).get_hunks()
+ for hunk in hunks
+ if ( hunk.header == getline(starthunk) )
+ let current_hunk = hunk
+ break
+ endif
+ endfor
+ let selection = []
+ call add(selection, current_hunk.header)
+
+ let current_line = starthunk + 1
+ " when staging by visual selection, lines out of selection must be
+ " ignored. To do so, + lines are simply ignored, - lines are considered as
+ " untouched.
+ " For unstaging, - lines must be ignored and + lines considered untouched.
+ if ( section == 'unstaged' )
+ let remove_line_char = '+'
+ let replace_line_char = '-'
+ else
+ let remove_line_char = '-'
+ let replace_line_char = '+'
+ endif
+ for hunk_line in current_hunk.lines
+ if ( index(a:select_lines, current_line) != -1 )
+ call add(selection, getline(current_line))
+ elseif ( hunk_line =~ '^'.remove_line_char.'.*' )
+ " just ignore these lines
+ elseif ( hunk_line =~ '^'.replace_line_char.'.*' )
+ call add(selection, substitute(hunk_line,
+ \ '^'.replace_line_char.'\(.*\)$', ' \1', ''))
+ elseif ( hunk_line =~ '^ .*' )
+ call add(selection, hunk_line)
+ else
+ throw 'visual selection error: ' . hunk_line
+ endif
+ let current_line += 1
+ endfor
+ return selection
+endfunction
+
+" s:mg_mark_lines_in_hunk: this function toggle marks for selected lines in a
+" hunk.
+" if a hunk contains marked lines, only these lines will be (un)staged on next
+" (un)stage command
+" param[in] start_select_line,end_select_line: limits of the selection
+function! s:mg_mark_lines_in_hunk(start_select_line, end_select_line)
+ let [starthunk,endhunk] = <SID>mg_select_hunk_block()
+ if ( a:start_select_line < starthunk || a:end_select_line > endhunk )
+ throw 'out of hunk selection'
+ endif
+ return magit#sign#toggle_signs('M', a:start_select_line, a:end_select_line)
+endfunction
+
+" }}}
+
+" {{{ User functions and commands
+
+" magit#open_close_folding()
+" param[in] visible : boolean, force visible value. If not set, toggle
+" visibility
+function! magit#open_close_folding(...)
+ let list = matchlist(getline("."), g:magit_file_re)
+ if ( empty(list) )
+ throw 'non file header line: ' . getline(".")
+ endif
+ let filename = list[2]
+ let section=magit#helper#get_section()
+ " if first param is set, force visible to this value
+ " else, toggle value
+ let file = b:state.get_file(section, filename, 0)
+ if ( a:0 == 1 )
+ call file.set_visible(a:1)
+ else
+ call file.toggle_visible()
+ endif
+ call magit#update_buffer()
+endfunction
+
+let g:magit_last_updated_buffer = ''
+
+" s:mg_display_functions: Dict wrapping all display related functions
+" This Dict should be accessed through g:magit_default_sections
+let s:mg_display_functions = {
+ \ 'info': { 'fn': function("s:mg_get_info"), 'arg': []},
+ \ 'global_help': { 'fn': function("magit#mapping#get_section_help"), 'arg': ['global']},
+ \ 'commit': { 'fn': function("s:mg_get_commit_section"), 'arg': []},
+ \ 'staged': { 'fn': function("s:mg_get_staged_section"), 'arg': ['staged']},
+ \ 'unstaged': { 'fn': function("s:mg_get_staged_section"), 'arg': ['unstaged']},
+ \ 'stash': { 'fn': function("s:mg_get_stashes"), 'arg': []},
+\ }
+
+" magit#update_buffer: this function:
+" 1. checks that current buffer is the wanted one
+" 2. save window state (cursor position...)
+" 3. delete buffer
+" 4. fills with unstage stuff
+" 5. restore window state
+" param[in] updated file (optional): this filename is updated to absolute
+" path, set in g:magit_last_updated_buffer and the User autocmd
+" param[in] current section (optional)
+" param[in] current hunk id
+" when params 1 & 2 & 3 are set, it means
+" that a stage/unstage action occured. We try to smartly set the cursor
+" position after the refresh
+" - on current file on closest hunk if still contains hunks in current section
+" - else on next file if any
+" - else on previous file if any
+" - or cursor stay where it is
+" VimagitUpdateFile event is raised
+function! magit#update_buffer(...)
+ let buffer_name=bufname("%")
+ " (//|\\\\) is to handle old vim 7.4-0 fnameescape behavior on Windows
+ if ( buffer_name !~ "\\v^magit:(//|\\\\).*" )
+ echoerr "Not in magit buffer but in " . buffer_name
+ return
+ endif
+
+ if ( a:0 >= 1 )
+ let cur_filename = a:1
+ endif
+ if ( a:0 >= 2 )
+ let cur_section = a:2
+ endif
+ if ( a:0 >= 3 )
+ let cur_hunk_id = a:3
+ endif
+
+ if ( b:magit_current_commit_mode != '' )
+ try
+ let b:magit_current_commit_msg = s:mg_get_commit_msg(1)
+ catch /^out_of_block$/
+ let b:magit_current_commit_msg = []
+ endtry
+ call s:set_mode_write()
+ else
+ call s:set_mode_read()
+ endif
+ " FIXME: find a way to save folding state. According to help, this won't
+ " help:
+ " > This does not save fold information.
+ " Playing with foldenable around does not help.
+ " mkview does not help either.
+ let l:winview = winsaveview()
+
+ " remove all signs (needed as long as we wipe buffer)
+ call magit#sign#remove_all()
+
+ " remove folding while we are updating the buffer. writing to the buffer
+ " while the folding is enabled can be veryyyyy slow.
+ " One last strange thing is that, the first time the buffer is written, it
+ " is not slow at all. It is slow the second time, at first refresh (can be
+ " order of seconds). Then at third time (2nd refresh), it is fast again.
+ " refs:
+ " https://github.com/jreybert/vimagit/issues/170
+ " https://github.com/jreybert/vimagit/issues/36 (maybe)
+ setlocal foldmethod=manual
+ " delete buffer
+ silent! execute "silent :%delete _"
+
+ " be smart for the cursor position after refresh, if stage/unstaged
+ " occured
+ if ( a:0 >= 2 )
+ let filenames = b:state.get_filenames(cur_section)
+ let pos = match(filenames, cur_filename)
+ let next_filename = (pos < len(filenames) - 1) ? filenames[pos+1] : ''
+ let prev_filename = (pos > 0) ? filenames[pos-1] : ''
+ endif
+
+ call b:state.update()
+
+ if ( g:magit_auto_close == 1 &&
+ \ b:magit_just_commited == 1 &&
+ \ empty(b:state.get_filenames('staged')) &&
+ \ empty(b:state.get_filenames('unstaged')) )
+ let b:magit_just_commited = 0
+ call magit#close_magit()
+ return
+ endif
+
+ for section in g:magit_default_sections
+ try
+ let func = s:mg_display_functions[section]
+ catch
+ echohl WarningMsg
+ echom 'unknown section to display: ' . section
+ echom 'please check your redefinition of g:magit_default_sections'
+ echohl None
+ endtry
+ call call(func.fn, func.arg)
+ endfor
+
+ call winrestview(l:winview)
+
+ call magit#utils#clear_undo()
+
+ setlocal filetype=magit
+ setlocal foldmethod=syntax
+
+ if ( b:magit_current_commit_mode != '' && b:magit_commit_newly_open == 1 )
+ let commit_section_pat_start='^'.g:magit_sections.commit.'$'
+ silent! let section_line=search(commit_section_pat_start, "w")
+ silent! call cursor(section_line+2+magit#mapping#get_section_help_line_nb('commit'), 0)
+ if exists('#User#VimagitEnterCommit')
+ doautocmd User VimagitEnterCommit
+ endif
+ let b:magit_commit_newly_open = 0
+ endif
+
+ let g:magit_last_updated_buffer = ''
+ if ( a:0 >= 1 )
+ let abs_filename = magit#git#top_dir() . cur_filename
+ if ( bufexists(abs_filename) )
+ let g:magit_last_updated_buffer = abs_filename
+ if exists('#User#VimagitUpdateFile')
+ doautocmd User VimagitUpdateFile
+ endif
+ endif
+ endif
+
+ if exists('#User#VimagitRefresh')
+ doautocmd User VimagitRefresh
+ endif
+
+ if ( a:0 >= 3 )
+ if (b:state.get_files_nb(cur_section) > 0)
+ " if, in this order, current file, next file, previous file exists in
+ " current section, move cursor to it
+ let cur_file = 1
+ for fname in [cur_filename, next_filename, prev_filename]
+ try
+ let file = b:state.get_file(cur_section, fname)
+ if ( cur_file )
+ let hunk_id = max([0, min([len(file.get_hunks())-1, cur_hunk_id])])
+ let cur_file = 0
+ else
+ let hunk_id = 0
+ endif
+
+ if ( file.is_visible() )
+ call cursor(file.get_hunks()[hunk_id].line_pos, 0)
+ if ( g:magit_auto_foldopen )
+ foldopen
+ endif
+ else
+ call cursor(file.line_pos, 0)
+ endif
+ break
+ catch 'file_doesnt_exists'
+ endtry
+ endfor
+ else
+ " if current section is empty, move cursor to top to other section
+ if (cur_section == 'staged')
+ let cur_section = 'unstaged'
+ elseif (cur_section == 'unstaged')
+ let cur_section = 'staged'
+ endif
+ let section_line=search(g:magit_sections[cur_section], "bnw")
+ call cursor(section_line, 0)
+ endif
+ silent execute "normal! zt"
+ endif
+
+ if exists(':AirlineRefresh')
+ execute "AirlineRefresh"
+ endif
+
+endfunction
+
+" magit#toggle_help: toggle inline help showing in magit buffer
+function! magit#toggle_help()
+ let g:magit_show_help = ( g:magit_show_help == 0 ) ? 1 : 0
+ call magit#update_buffer()
+endfunction
+
+" magit#show_magit: prepare and show magit buffer
+" it also set local mappings to magit buffer
+" param[in] display:
+" 'v': vertical split
+" 'h': horizontal split
+" 'c': current buffer (should be used when opening vim in vimagit mode
+function! magit#show_magit(display, ...)
+ if ( &filetype == 'netrw' )
+ let cur_file = ""
+ let cur_file_path = b:netrw_curdir
+ else
+ let cur_file = expand("%:p")
+ let cur_file_path = isdirectory(cur_file) ? cur_file : fnamemodify(cur_file, ":h")
+ endif
+
+ let git_dir=''
+ let try_paths = [ cur_file_path, getcwd() ]
+ for path in try_paths
+ let git_dir=magit#git#is_work_tree(path)
+ if ( git_dir != '' )
+ break
+ endif
+ endfor
+
+ if ( git_dir == '' )
+ echohl ErrorMsg
+ echom "magit can not find any git repository"
+ echohl None
+ echom "make sure that current opened file or vim current directory points to a git repository"
+ echom "search paths:"
+ for path in try_paths
+ echom path
+ endfor
+ return
+ endif
+
+ let buffer_name=fnameescape('magit://' . git_dir)
+
+ let magit_win = magit#utils#search_buffer_in_windows(buffer_name)
+
+ if ( magit_win != 0 )
+ silent execute magit_win."wincmd w"
+ elseif ( a:display == 'v' )
+ silent execute "vnew " . buffer_name
+ " next is a workaround for vader, revert as soon as vader bug is fixed
+ " https://github.com/junegunn/vader.vim/issues/135
+ silent execute "buffer " . buffer_name
+ let b:magit_only = 0
+ elseif ( a:display == 'h' )
+ silent execute "new " . buffer_name
+ let b:magit_only = 0
+ elseif ( a:display == 'c' )
+ if ( !bufexists(buffer_name) )
+ if ( bufname("%") == "" )
+ silent keepalt enew
+ else
+ silent enew
+ endif
+ silent execute "file " . buffer_name
+ else
+ silent execute "buffer " . buffer_name
+ endif
+ let b:magit_only = 1
+ else
+ throw 'parameter_error'
+ endif
+
+ call magit#git#set_top_dir(git_dir)
+
+ let b:magit_default_show_all_files = g:magit_default_show_all_files
+ let b:magit_default_fold_level = g:magit_default_fold_level
+ let b:magit_warning_max_lines_answered = 0
+
+ if ( a:0 > 0 )
+ let b:magit_default_show_all_files = a:1
+ endif
+ if ( a:0 > 1 )
+ let b:magit_default_fold_level = a:2
+ endif
+
+ setlocal buftype=nofile
+ setlocal bufhidden=hide
+ setlocal noswapfile
+ setlocal foldmethod=syntax
+ setlocal foldnestmax=20
+ setlocal nobuflisted
+ setlocal nomodeline
+ let &l:foldlevel = b:magit_default_fold_level
+ setlocal filetype=magit
+ if ( g:magit_scrolloff != -1 )
+ if ( has("patch-8.1.0864") )
+ let &l:scrolloff = g:magit_scrolloff
+ else
+ let s:default_scrolloff=&scrolloff
+ " ugly hack, scrolloff is a global only option before patch 8.1.0864
+ execute "autocmd BufLeave " . buffer_name . " :set scrolloff=" . s:default_scrolloff
+ execute "autocmd BufEnter " . buffer_name . " :set scrolloff=" . g:magit_scrolloff
+ let &scrolloff = g:magit_scrolloff
+ endif
+ endif
+
+ augroup vimagit_buffer
+ autocmd!
+ " catch write command
+ execute "autocmd BufWriteCmd " . buffer_name . " :call magit#commit_command('CC')"
+
+ " let magit buffer in read mode when cursor is not in file, to avoid
+ " unfortunate commit with a :wall command out of magit buffer if a commit
+ " message is ongoing
+ execute "autocmd BufEnter " . buffer_name . "
+ \ :if ( exists('b:magit_current_commit_mode') &&
+ \ b:magit_current_commit_mode != '' ) |
+ \ call s:set_mode_write() |
+ \ endif"
+ execute "autocmd BufLeave " . buffer_name . "
+ \ :if ( exists('b:magit_current_commit_mode') &&
+ \ b:magit_current_commit_mode != '' ) |
+ \ call s:set_mode_read() |
+ \ endif"
+ augroup END
+
+ " s:magit_commit_mode: global variable which states in which commit mode we are
+ " values are:
+ " '': not in commit mode
+ " 'CC': normal commit mode, next commit command will create a new commit
+ " 'CA': amend commit mode, next commit command will ament current commit
+ " 'CF': fixup commit mode, it should not be a global state mode
+ let b:magit_current_commit_mode=''
+ let b:magit_commit_newly_open=0
+
+ let b:magit_diff_context=3
+
+ let b:magit_just_commited = 0
+
+ if ( magit#git#check_repo() != 0 )
+ echohl ErrorMsg
+ echom "git repository seems to be corrupted"
+ echohl None
+ echom "To be safe, vimagit ends now"
+ echom "Check your repository health with git fsck"
+ echom "If the result shows no problem, open an issue"
+ return
+ endif
+
+ let b:state = deepcopy(g:magit#state#state)
+ call magit#utils#setbufnr(bufnr(buffer_name))
+ call magit#sign#init()
+
+ call magit#mapping#set_default()
+
+ if exists('#User#VimagitBufferInit')
+ doautocmd User VimagitBufferInit
+ endif
+
+ call magit#update_buffer()
+
+ function! s:jump_first_file()
+ let unstaged_files = b:state.get_files_ordered('unstaged')
+ if ( !empty(unstaged_files) )
+ call cursor(unstaged_files[0].line_pos, 0)
+ else
+ let staged_files = b:state.get_files_ordered('staged')
+ if ( !empty(staged_files) )
+ call cursor(staged_files[0].line_pos, 0)
+ endif
+ endif
+ endfunction
+ " move cursor to (in priority order if not found):
+ " - current file unstaged
+ " - current file staged
+ " - first unstaged file
+ " - first stage file
+ let cur_filename = matchlist(cur_file, git_dir . '\(.*\)')
+ if ( !empty(cur_filename) )
+ let cur_file = cur_filename[1]
+ try
+ let file = b:state.get_file('unstaged', cur_file, 0)
+ call cursor(file.line_pos, 0)
+ catch 'file_doesnt_exists'
+ try
+ let file = b:state.get_file('staged', cur_file, 0)
+ call cursor(file.line_pos, 0)
+ catch 'file_doesnt_exists'
+ call s:jump_first_file()
+ endtry
+ endtry
+ else
+ call s:jump_first_file()
+ endif
+
+endfunction
+
+function! magit#close_magit()
+ if ( b:magit_only == 0 )
+ close
+ else
+ try
+ edit #
+ catch /^Vim\%((\a\+)\)\=:E\%(194\|499\)/
+ try
+ close
+ catch /^Vim\%((\a\+)\)\=:E444/
+ quit
+ endtry
+ endtry
+ endif
+endfunction
+
+function! s:mg_stage_closed_file(discard)
+ if ( getline(".") =~ g:magit_file_re )
+ let list = matchlist(getline("."), g:magit_file_re)
+ let filename = list[2]
+ let section=magit#helper#get_section()
+
+ let file = b:state.get_file(section, filename)
+ if ( file.is_visible() == 0 ||
+ \ file.is_dir() == 1 )
+ if ( a:discard == 0 )
+ if ( section == 'unstaged' )
+ call magit#git#git_add(magit#utils#add_quotes(filename))
+ elseif ( section == 'staged' )
+ call magit#git#git_reset(magit#utils#add_quotes(filename))
+ else
+ echoerr "Must be in \"" .
+ \ g:magit_sections.staged . "\" or \"" .
+ \ g:magit_sections.unstaged . "\" section"
+ endif
+ else
+ if ( section == 'unstaged' )
+ if ( file.status == '?' || file.must_be_added() )
+ if ( g:magit_discard_untracked_do_delete == 1 )
+ if ( delete(filename, "rf") != 0 )
+ echoerr "Can not delete \"" . filename . "\""
+ return
+ endif
+ else
+ echohl WarningMsg
+ echomsg "By default, vimagit won't discard "
+ \ "untracked file (which means delete this file)"
+ echomsg "You can force this behaviour, "
+ \ "setting g:magit_discard_untracked_do_delete=1"
+ echohl None
+ return
+ endif
+ else
+ call magit#git#git_checkout(magit#utils#add_quotes(filename))
+ endif
+ else
+ echohl WarningMsg
+ echomsg "Can not discard file in \"" .
+ \ g:magit_sections.staged . "\" section, "
+ \ "unstage file first."
+ echohl None
+ return
+ endif
+ endif
+
+ call magit#update_buffer(filename, section, 0)
+
+ return
+ endif
+ endif
+ throw "out_of_block"
+endfunction
+
+" magit#stage_block: this function (un)stage a block, according to parameter
+" INFO: in unstaged section, it stages the hunk, and in staged section, it
+" unstages the hunk
+" param[in] block_type: can be 'file' or 'hunk'
+" param[in] discard: boolean, if true, discard instead of (un)stage
+" return: no
+function! magit#stage_block(selection, discard) abort
+ let section=magit#helper#get_section()
+ let filename=magit#helper#get_filename()
+
+ let file = b:state.get_file(section, filename, 0)
+ let header = file.get_header()
+
+ " find current hunk position in file matching against current selection
+ " header
+ try
+ let hunk_id = match(map(deepcopy(file.get_hunks()), 'v:val.header'), "\\V" . a:selection[0])
+ catch /^Vim\%((\a\+)\)\=:E874/
+ echoerr "Escape issue with '" . a:selection[0] ."'"
+ return
+ endtry
+
+
+ if ( a:discard == 0 )
+ if ( section == 'unstaged' )
+ if ( file.must_be_added() )
+ call magit#git#git_add(magit#utils#add_quotes(filename))
+ else
+ call magit#git#git_apply(header, a:selection)
+ endif
+ elseif ( section == 'staged' )
+ if ( file.must_be_added() )
+ call magit#git#git_reset(magit#utils#add_quotes(filename))
+ else
+ call magit#git#git_unapply(header, a:selection, 'staged')
+ endif
+ else
+ echoerr "Must be in \"" .
+ \ g:magit_sections.staged . "\" or \"" .
+ \ g:magit_sections.unstaged . "\" section"
+ endif
+ else
+ if ( section == 'unstaged' )
+ if ( file.status == '?' || file.must_be_added() )
+ if ( g:magit_discard_untracked_do_delete == 1 )
+ if ( delete(filename, "rf") != 0 )
+ echoerr "Can not delete \"" . filename . "\""
+ return
+ endif
+ else
+ echohl WarningMsg
+ echomsg "By default, vimagit won't discard "
+ \ "untracked file (which means delete this file)"
+ echomsg "You can force this behaviour, "
+ \ "setting g:magit_discard_untracked_do_delete=1"
+ echohl None
+ return
+ endif
+ else
+ call magit#git#git_unapply(header, a:selection, 'unstaged')
+ endif
+ else
+ echoerr "Must be in \"" .
+ \ g:magit_sections.unstaged . "\" section"
+ endif
+ endif
+
+ call magit#update_buffer(filename, section, hunk_id)
+
+endfunction
+
+" magit#stage_file: this function (un)stage a whole file, from the current
+" cursor position
+" INFO: in unstaged section, it stages the file, and in staged section, it
+" unstages the file
+" return: no
+function! magit#stage_file()
+ try
+ call <SID>mg_stage_closed_file(0)
+ return
+ catch 'out_of_block'
+ try
+ let [start, end] = <SID>mg_select_file_block()
+ catch /^out_of_block$/
+ echohl ErrorMsg
+ echomsg "Error while staging."
+ echohl None
+ echomsg "Your cursor must be:"
+ echomsg " - on a file header line"
+ echomsg " - or on a hunk header line"
+ echomsg " - or within a hunk"
+ echomsg "If you repect one of previous points, please open a new issue:"
+ echomsg "https://github.com/jreybert/vimagit/issues/new"
+ return
+ endtry
+ let selection = getline(start, end)
+ endtry
+ return magit#stage_block(selection, 0)
+endfunction
+"
+" magit#stage_hunk: this function (un)stage/discard a hunk, from the current
+" cursor position
+" INFO: in unstaged section, it stages the hunk, and in staged section, it
+" unstages the hunk
+" param[in] discard:
+" - when set to 0, (un)stage
+" - when set to 1, discard
+" return: no
+function! magit#stage_hunk(discard)
+ try
+ call <SID>mg_stage_closed_file(a:discard)
+ return
+ catch 'out_of_block'
+ try
+ let [start,end] = <SID>mg_select_hunk_block()
+ catch 'out_of_block'
+ try
+ let [start,end] = <SID>mg_select_file_block()
+ catch /^out_of_block$/
+ echohl ErrorMsg
+ echomsg "Error while staging."
+ echohl None
+ echomsg "Your cursor must be:"
+ echomsg " - on a file header line"
+ echomsg " - or on a hunk header line"
+ echomsg " - or within a hunk"
+ echomsg "If you repect one of previous points, please open a new issue:"
+ echomsg "https://github.com/jreybert/vimagit/issues/new"
+ return
+ endtry
+ endtry
+ let marked_lines = magit#sign#find_stage_signs(start, end)
+ if ( empty(marked_lines) )
+ let selection = getline(start, end)
+ else
+ let selection = <SID>mg_create_diff_from_select(
+ \ map(keys(marked_lines), 'str2nr(v:val)'))
+ call magit#sign#remove_signs(marked_lines)
+ endif
+ endtry
+ return magit#stage_block(selection, a:discard)
+endfunction
+
+" magit#stage_vselect: this function (un)stage text being sectected in Visual
+" mode
+" remarks: it works with full lines, and can not span over multiple chunks
+" INFO: in unstaged section, it stages the file, and in staged section, it
+" unstages the file
+" return: no
+function! magit#stage_vselect() range
+ " func-range a:firstline a:lastline seems to work at least from vim 7.2
+ let lines = []
+ let curline = a:firstline
+ while ( curline <= a:lastline )
+ call add(lines, curline)
+ let curline += 1
+ endwhile
+ try
+ let selection = <SID>mg_create_diff_from_select(lines)
+ catch /^out_of_block$/
+ echohl ErrorMsg
+ echomsg "Error while staging a visual selection."
+ echohl None
+ echomsg "Visual selection staging has currently some limitations:"
+ echomsg " - selection must be limited within a single hunk"
+ echomsg " - only work for staging, not for unstaging"
+ echomsg "If you repect current limitations, please open a new issue:"
+ echomsg "https://github.com/jreybert/vimagit/issues/new"
+ return
+ endtry
+ return magit#stage_block(selection, 0)
+endfunction
+
+" magit#mark_vselect: wrapper function to mark selected lines (see
+" mg_mark_lines_in_hunk)
+function! magit#mark_vselect() range
+ return <SID>mg_mark_lines_in_hunk(a:firstline, a:lastline)
+endfunction
+
+" magit#ignore_file: this function add the file under cursor to .gitignore
+" FIXME: git diff adds some strange characters to end of line
+function! magit#ignore_file() abort
+ let ignore_file=magit#helper#get_filename()
+ call magit#utils#append_file(magit#git#top_dir() . ".gitignore",
+ \ [ ignore_file ] )
+ call magit#update_buffer()
+endfunction
+
+" set magit buffer in write mode
+function! s:set_mode_write()
+ setlocal buftype=acwrite
+endfunction
+
+" set magit buffer in read only mode
+function! s:set_mode_read()
+ setlocal buftype=nofile
+endfunction
+
+" magit#commit_command: entry function for commit mode
+" INFO: it has a different effect if current section is commit section or not
+" param[in] mode: commit mode
+" 'CF': do not set global b:magit_current_commit_mode, directly call magit#git_commit
+" 'CA'/'CF': if in commit section mode, call magit#git_commit, else just set
+" global state variable b:magit_current_commit_mode,
+function! magit#commit_command(mode)
+ if ( a:mode == 'CF' )
+ call <SID>mg_git_commit(a:mode)
+ else
+ let section=magit#helper#get_section()
+ if ( section == 'commit' &&
+\ !(b:magit_current_commit_mode == 'CC' && a:mode == 'CA' ) )
+ if ( b:magit_current_commit_mode == '' )
+ echoerr "Error, commit section should not be enabled"
+ return
+ endif
+ " when we do commit, it is prefered ot commit the way we prepared it
+ " (.i.e normal or amend), whatever we commit with CC or CA.
+ call <SID>mg_git_commit(b:magit_current_commit_mode)
+ if exists('#User#VimagitLeaveCommit')
+ doautocmd User VimagitLeaveCommit
+ endif
+ else
+ let b:magit_current_commit_mode=a:mode
+ let b:magit_commit_newly_open=1
+ call s:set_mode_write()
+ setlocal nomodified
+ endif
+ endif
+ call magit#update_buffer()
+endfunction
+
+" magit#close_commit: cancel for commit mode
+" close commit section if opened
+function! magit#close_commit()
+ if ( b:magit_current_commit_mode == '' )
+ return
+ endif
+
+ let git_dir=magit#git#git_dir()
+ let commit_editmsg=git_dir . 'COMMIT_EDITMSG'
+ if ( filereadable(commit_editmsg) )
+ let commit_msg=s:mg_get_commit_msg()
+ call writefile(commit_msg, commit_editmsg)
+ endif
+
+ let b:magit_current_commit_mode=''
+ let b:magit_current_commit_msg=[]
+ if exists('#User#VimagitLeaveCommit')
+ doautocmd User VimagitLeaveCommit
+ endif
+ call magit#update_buffer()
+endfunction
+
+" magit#jump_hunk: function to jump among hunks
+" it closes the current fold (if any), jump to next hunk and unfold it
+" param[in] dir: can be 'N' (for next) or 'P' (for previous)
+function! magit#jump_hunk(dir)
+ let back = ( a:dir == 'P' ) ? 'b' : ''
+ let line = search('\%(^@@ \|' . g:magit_file_re . '\)', back . 'wn')
+ if ( line != 0 )
+ if ( foldlevel(line('.')) == 2 )
+ try
+ foldclose
+ catch /^Vim\%((\a\+)\)\=:E490/
+ endtry
+ endif
+ call cursor(line, 0)
+
+ if ( foldlevel(line('.')) == 0 )
+ return
+ endif
+ " if current line if an header file of an open file, go next
+ if ( foldlevel(line('.')) == 1 )
+ let line = search('\%(^@@ \|' . g:magit_file_re . '\)', back . 'wn')
+ call cursor(line, 0)
+ endif
+ while ( foldclosed(line) != -1 )
+ try
+ foldopen
+ catch /^Vim\%((\a\+)\)\=:E490/
+ break
+ endtry
+ endwhile
+ silent execute "normal! zt"
+ endif
+endfunction
+
+" magit#get_staged_files: function returning an array with staged files names
+" return: an array with staged files names
+function! magit#get_staged_files()
+ return keys(b:state.dict.staged)
+endfunction
+
+" magit#get_staged_files: function returning an array with unstaged files
+" names
+" return: an array with unstaged files names
+function! magit#get_unstaged_files()
+ return keys(b:state.dict.unstaged)
+endfunction
+
+" magit#jump_to: function to move cursor to the file location of the current
+" hunk
+" if this file is already displayed in a window, jump to the window, if not,
+" jump to last window and open buffer, at the beginning of the hunk
+function! magit#jump_to()
+ let section=magit#helper#get_section()
+ let filename=fnameescape(magit#git#top_dir() . magit#helper#get_filename())
+ let header_line_nb=magit#helper#get_hunkheader_line_nb()
+
+ let line_in_file=substitute(getline(header_line_nb),
+ \ '^@@ -\d\+,\d\+ +\(\d\+\),\d\+ @@.*$', '\1', "")
+
+ " header_line_nb+2: +2 because we skip the header and the fist line
+ let hunk_extract=getline(header_line_nb+2, line('.'))
+ let line_in_hunk = len(filter(hunk_extract, 'v:val =~ "^[ +]"'))
+ let line_in_file += line_in_hunk
+
+ " winnr('#') is overwritten by magit#get_win()
+ let last_win = winnr('#')
+ let buf_win = magit#utils#search_buffer_in_windows(filename)
+ let buf_win = ( buf_win == 0 ) ? last_win : buf_win
+ if ( buf_win == 0 || winnr('$') == 1 )
+ rightbelow vnew
+ else
+ execute buf_win."wincmd w"
+ endif
+
+ try
+ execute "edit " . "+" . line_in_file . " " filename
+ catch
+ if ( v:exception == 'Vim:Interrupt' && buf_win == 0)
+ close
+ elseif ( v:exception != 'Vim(edit):E325: ATTENTION' )
+ throw v:exception
+ endif
+ endtry
+endfunction
+
+function! magit#update_diff(way)
+ if ( a:way == "+" )
+ let b:magit_diff_context+=1
+ elseif ( a:way == "0" )
+ let b:magit_diff_context=3
+ elseif ( b:magit_diff_context > 1 )
+ let b:magit_diff_context-=1
+ endif
+ call magit#update_buffer()
+endfunction
+
+function! magit#show_version()
+ return g:vimagit_version[0] . "." .
+ \ g:vimagit_version[1] . "." .
+ \ g:vimagit_version[2]
+endfunction
+
+function! magit#get_current_mode()
+ if ( b:magit_current_commit_mode == '' )
+ return "STAGING"
+ elseif ( b:magit_current_commit_mode == 'CC' )
+ return "COMMIT"
+ elseif ( b:magit_current_commit_mode == 'CA' )
+ return "AMEND"
+ endif
+endfunction
+
+command! Magit call magit#show_magit('v')
+command! MagitOnly call magit#show_magit('c')
+
+" }}}
diff --git a/.config/vim/plugin/prose.vim b/.config/vim/plugin/prose.vim
@@ -0,0 +1,38 @@
+let g:ProseOn=0
+
+function! ToggleProse()
+ if !g:ProseOn
+ call Prose()
+ else
+ call ProseOff()
+ endif
+endfunction
+
+function! Prose()
+ echo "Prose: On"
+ let g:ProseOn=1
+
+ noremap j gj
+ noremap k gk
+ noremap 0 g0
+ noremap $ g$
+ noremap A g$a
+ noremap I g0i
+ setlocal linebreak nonumber norelativenumber t_Co=0 foldcolumn=2
+ hi! link FoldColumn Normal
+
+endfunction
+
+function! ProseOff()
+ echo "Prose: Off"
+ let g:ProseOn=0
+
+ noremap j j
+ noremap k k
+ noremap 0 0
+ noremap $ $
+ noremap A A
+ noremap I I
+ setlocal nolinebreak number relativenumber t_Co=256 foldcolumn=0
+
+endfunction
diff --git a/.config/vim/syntax/magit.vim b/.config/vim/syntax/magit.vim
@@ -0,0 +1,51 @@
+if exists("b:current_syntax")
+ finish
+endif
+
+let s:vimagit_path = fnameescape(resolve(expand('<sfile>:p:h')))
+execute 'source ' . s:vimagit_path . '/../common/magit_common.vim'
+
+syn case match
+syn sync minlines=50
+
+syn include @diff syntax/diff.vim
+
+execute 'syn match titleEntry "' . g:magit_section_re . '\n\%(.*\n\)\{-}=\+"'
+hi def link titleEntry Comment
+
+execute 'syn region commitMsg start=/' . g:magit_sections.commit . '/ end=/\%(' . g:magit_section_re . '\)\@=/ contains=titleEntry'
+execute 'syn match commitMsgExceed "\%(=\+\n\+\_^.\{' . g:magit_commit_title_limit . '}\)\@<=.*$" contained containedin=commitMsg'
+hi def link commitMsgExceed Comment
+
+execute 'syn match stashEntry "' . g:magit_stash_re . '"'
+hi def link stashEntry String
+
+execute 'syn match fileEntry "' . g:magit_file_re . '"'
+hi def link fileEntry String
+
+execute 'syn region gitStash start=/' . g:magit_stash_re . '/ end=/\%(' .
+ \ g:magit_stash_re . '\)\@=/ contains=stashEntry fold'
+
+execute 'syn region gitFile start=/' . g:magit_file_re . '/ end=/\%(' .
+ \ g:magit_end_diff_re . '\)\@=/ contains=gitHunk,fileEntry fold'
+
+execute 'syn region gitHunk start=/' .
+ \ g:magit_hunk_re . '/ end=/\%(' . g:magit_end_diff_re . '\|' . g:magit_hunk_re
+ \ '\)\@=/ contains=@diff fold'
+
+execute 'syn match gitInfoRepo "\%(' . g:magit_section_info.cur_repo . '\)\@<=.*$" oneline'
+execute 'syn match gitInfoHead "\%(' . g:magit_section_info.cur_head . '\s*\)\@<=\S\+" oneline'
+execute 'syn match gitInfoUpstream "\%(' . g:magit_section_info.cur_upstream . '\s*\)\@<=\S\+" oneline'
+execute 'syn match gitInfoPush "\%(' . g:magit_section_info.cur_push . '\s*\)\@<=\S\+" oneline'
+execute 'syn match gitCommitMode "\%(' . g:magit_section_info.commit_mode . '\)\@<=.*$" oneline'
+"execute 'syn match gitInfoCommit "\%(' . g:magit_section_info.cur_commit . '\)\@<=.*$" contains=infoSha1 oneline'
+"syntax match infoSha1 containedin=gitInfoCommit "\x\{7,}"
+
+highlight default link gitInfoRepo Directory
+highlight default link gitInfoHead Identifier
+highlight default link gitInfoUpstream Identifier
+highlight default link gitInfoPush Identifier
+highlight default link gitCommitMode Special
+highlight default link infoSha1 Identifier
+
+let b:current_syntax = "magit"