startify.vim 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211
  1. " Plugin: https://github.com/mhinz/vim-startify
  2. " Description: Start screen displaying recently used stuff.
  3. " Maintainer: Marco Hinz <http://github.com/mhinz>
  4. " Version: 1.5
  5. if exists('g:loaded_startify') || &cp
  6. finish
  7. endif
  8. let g:loaded_startify = 1
  9. " Init {{{1
  10. let g:startify_session_dir = resolve(expand(get(g:, 'startify_session_dir',
  11. \ has('win32') ? '$HOME\vimfiles\session' : '~/.vim/session')))
  12. augroup startify
  13. autocmd!
  14. autocmd VimEnter *
  15. \ if !argc() && (line2byte('$') == -1) && (v:progname =~? '^[gm]\=vim\%[\.exe]$') |
  16. \ call s:insane_in_the_membrane() |
  17. \ endif
  18. augroup END
  19. command! -nargs=? -bar -complete=customlist,startify#get_session_names SSave call startify#save_session(<f-args>)
  20. command! -nargs=? -bar -complete=customlist,startify#get_session_names SLoad call startify#load_session(<f-args>)
  21. command! -nargs=? -bar -complete=customlist,startify#get_session_names SDelete call startify#delete_session(<f-args>)
  22. command! -nargs=0 -bar Startify enew | call s:insane_in_the_membrane()
  23. " Function: s:insane_in_the_membrane {{{1
  24. function! s:insane_in_the_membrane() abort
  25. if !empty(v:servername) && exists('g:startify_skiplist_server')
  26. for servname in g:startify_skiplist_server
  27. if (servname == v:servername)
  28. return
  29. endif
  30. endfor
  31. endif
  32. setlocal nonumber noswapfile bufhidden=wipe
  33. if (v:version >= 703)
  34. setlocal norelativenumber
  35. endif
  36. setfiletype startify
  37. let special = get(g:, 'startify_enable_special', 1)
  38. let sep = startify#get_separator()
  39. let cnt = 0
  40. if special
  41. call append('$', ' [e] <empty buffer>')
  42. endif
  43. if get(g:, 'startify_show_files', 1) && !empty(v:oldfiles)
  44. let entries = {}
  45. let numfiles = get(g:, 'startify_show_files_number', 10)
  46. if special
  47. call append('$', '')
  48. endif
  49. for fname in v:oldfiles
  50. let expfname = resolve(fnamemodify(fname, ':p'))
  51. " filter duplicates, bookmarks and entries from the skiplist
  52. if has_key(entries, expfname) ||
  53. \ !filereadable(expfname) ||
  54. \ (exists('g:startify_skiplist') && startify#is_in_skiplist(expfname)) ||
  55. \ (exists('g:startify_bookmarks') && startify#is_bookmark(expfname))
  56. continue
  57. endif
  58. let entries[expfname] = 1
  59. let index = s:get_index_as_string(cnt)
  60. call append('$', ' ['. index .']'. repeat(' ', (3 - strlen(index))) . fname)
  61. execute 'nnoremap <buffer> '. index .' :edit '. startify#escape(fname) .' <bar> lcd %:h<cr>'
  62. let cnt += 1
  63. if (cnt == numfiles)
  64. break
  65. endif
  66. endfor
  67. endif
  68. let sfiles = split(globpath(g:startify_session_dir, '*'), '\n')
  69. if get(g:, 'startify_show_sessions', 1) && !empty(sfiles)
  70. call append('$', '')
  71. for i in range(len(sfiles))
  72. let idx = (i + cnt)
  73. let index = s:get_index_as_string(idx)
  74. call append('$', ' ['. index .']'. repeat(' ', (3 - strlen(index))) . fnamemodify(sfiles[i], ':t:r'))
  75. execute 'nnoremap <buffer> '. index .' :bd <bar> tabnew +source\ '. startify#escape(sfiles[i]) .' <bar> if (line2byte("$") == -1) <bar> close <bar> endif<cr>'
  76. endfor
  77. let cnt = idx
  78. endif
  79. if exists('g:startify_bookmarks')
  80. call append('$', '')
  81. for fname in g:startify_bookmarks
  82. let cnt += 1
  83. let index = s:get_index_as_string(cnt)
  84. call append('$', ' ['. index .']'. repeat(' ', (3 - strlen(index))) . fname)
  85. execute 'nnoremap <buffer> '. index .' :edit '. startify#escape(fname) .' <bar> lcd %:h<cr>'
  86. endfor
  87. endif
  88. if special
  89. call append('$', ['', ' [q] <quit>'])
  90. endif
  91. setlocal nomodifiable nomodified
  92. nnoremap <buffer><silent> e :enew<cr>
  93. nnoremap <buffer><silent> i :enew <bar> startinsert<cr>
  94. nnoremap <buffer><silent> <space> :call <SID>set_mark('B')<cr>
  95. nnoremap <buffer><silent> s :call <SID>set_mark('S')<cr>
  96. nnoremap <buffer><silent> v :call <SID>set_mark('V')<cr>
  97. nnoremap <buffer> <cr> :call <SID>open_buffers(expand('<cword>'))<cr>
  98. nnoremap <buffer> <2-LeftMouse> :execute 'normal '. matchstr(getline('.'), '\w\+')<cr>
  99. nnoremap <buffer> q
  100. \ :if (len(filter(range(0, bufnr('$')), 'buflisted(v:val)')) > 1) <bar>
  101. \ bd <bar>
  102. \ else <bar>
  103. \ quit <bar>
  104. \ endif<cr>
  105. if exists('g:startify_empty_buffer_key')
  106. execute 'nnoremap <buffer><silent> '. g:startify_empty_buffer_key .' :enew<cr>'
  107. endif
  108. autocmd! startify *
  109. autocmd startify CursorMoved <buffer> call s:set_cursor()
  110. autocmd startify BufLeave <buffer> autocmd! startify *
  111. call cursor(special ? 4 : 2, 5)
  112. endfunction
  113. " Function: s:open_buffers {{{1
  114. function! s:open_buffers(cword) abort
  115. if exists('s:marked') && !empty(s:marked)
  116. for i in range(len(s:marked))
  117. for val in values(s:marked)
  118. if val[0] == i
  119. if val[3] == 'S'
  120. execute 'split '. val[2]
  121. elseif val[3] == 'V'
  122. execute 'vsplit '. val[2]
  123. else
  124. execute 'edit '. val[2]
  125. endif
  126. continue
  127. endif
  128. endfor
  129. endfor
  130. else
  131. execute 'normal '. a:cword
  132. endif
  133. endfunction
  134. " Function: s:set_mark {{{1
  135. "
  136. " Markers are saved in the s:marked dict using the follow format:
  137. " - s:marked[0]: ID (for sorting)
  138. " - s:marked[1]: what the brackets contained before
  139. " - s:marked[2]: the actual path
  140. " - s:marked[3]: type (buffer, split, vsplit)
  141. "
  142. function! s:set_mark(type) abort
  143. if !exists('s:marked')
  144. let s:marked = {}
  145. let s:nmarked = 0
  146. endif
  147. " matches[1]: content between brackets
  148. " matches[2]: path
  149. let matches = matchlist(getline('.'), '\v\[(.*)\]\s+(.*)')
  150. if matches[2] =~ '\V<empty buffer>\|<quit>' || matches[2] =~ '^\w\+$'
  151. return
  152. endif
  153. setlocal modifiable
  154. if matches[1] =~ 'B\|S\|V'
  155. let s:nmarked -= 1
  156. execute 'normal! ci]'. remove(s:marked, line('.'))[1]
  157. else
  158. let s:marked[line('.')] = [s:nmarked, matches[1], matches[2], a:type]
  159. let s:nmarked += 1
  160. execute 'normal! ci]'. repeat(a:type, len(matches[1]))
  161. endif
  162. setlocal nomodifiable nomodified
  163. endfunction
  164. " Function: s:get_index_as_string {{{1
  165. function! s:get_index_as_string(idx) abort
  166. if exists('g:startify_custom_indices')
  167. let listlen = len(g:startify_custom_indices)
  168. return (a:idx < listlen) ? g:startify_custom_indices[a:idx] : string(a:idx - listlen)
  169. else
  170. return string(a:idx)
  171. endif
  172. endfunction
  173. " Function: s:set_cursor {{{1
  174. function! s:set_cursor() abort
  175. let s:line_old = exists('s:line_new') ? s:line_new : 5
  176. let s:line_new = line('.')
  177. if empty(getline(s:line_new))
  178. if (s:line_new > s:line_old)
  179. let s:line_new += 1
  180. call cursor(s:line_new, 5) " going down
  181. else
  182. let s:line_new -= 1
  183. call cursor((s:line_new < 2 ? 2 : s:line_new), 5) " going up
  184. endif
  185. else
  186. call cursor((s:line_new < 2 ? 2 : 0), 5) " hold cursor in column
  187. endif
  188. endfunction
  189. " vim: et sw=2 sts=2