1
0
mirror of https://github.com/SpaceVim/SpaceVim.git synced 2025-02-13 20:07:58 +08:00
SpaceVim/bundle/bookmarks.vim/autoload/bookmarks.vim
2024-03-30 22:49:14 +08:00

231 lines
6.7 KiB
VimL

if exists('s:bookmarks')
finish
endif
let s:FILE = SpaceVim#api#import('file')
let s:NT = SpaceVim#api#import('notify')
let s:bookmarks = bookmarks#cache#read()
function! s:skip_current_buf() abort
if empty(bufname())
return v:true
elseif !empty(&buftype)
return v:true
endif
endfunction
function! bookmarks#on_leave_buffer() abort
if s:skip_current_buf()
return
endif
let file = s:FILE.unify_path(expand('%'), ':p')
if has_key(s:bookmarks, file)
let sign_lnum_map = bookmarks#sign#get_lnums(bufnr('%'))
let new_file_bms = {}
for lnum in keys(s:bookmarks[file])
let signid = s:bookmarks[file][lnum].signid
if has_key(sign_lnum_map, signid)
let new_lnum = sign_lnum_map[signid]
let new_file_bms[new_lnum] = s:bookmarks[file][lnum]
let new_file_bms[new_lnum].lnum = new_lnum
else
" the signid does not exist, maybe that line has been removed
if has_key(s:bookmarks[file][lnum], 'vtextid')
call bookmarks#vtext#delete(file, s:bookmarks[file][lnum].vtextid)
endif
endif
endfor
let s:bookmarks[file] = new_file_bms
call bookmarks#cache#write(s:bookmarks)
endif
endfunction
function! bookmarks#toggle() abort
if s:skip_current_buf()
return
endif
let file = s:FILE.unify_path(expand('%'), ':p')
let lnum = line('.')
if has_key(s:bookmarks, file) && has_key(s:bookmarks[file], lnum)
call bookmarks#delete(file, lnum)
else
call bookmarks#add(file, lnum, getline('.'))
endif
endfunction
function! s:has_annotation(file, lnum) abort
return has_key(s:bookmarks, a:file)
\ && has_key(s:bookmarks[a:file], a:lnum)
\ && has_key(s:bookmarks[a:file][a:lnum], 'annotation')
\ && !empty(s:bookmarks[a:file][a:lnum].annotation)
endfunction
function! bookmarks#annotate() abort
if s:skip_current_buf()
return
endif
let file = s:FILE.unify_path(expand('%'), ':p')
let lnum = line('.')
if s:has_annotation(file, lnum)
let default_annotation = s:bookmarks[file][lnum].annotation
let annotation = input({'prompt' : 'Annotation:', 'default' : default_annotation, 'cancelreturn' : ''})
if !empty(annotation)
call bookmarks#add(file, lnum, annotation, 1)
else
call s:NT.notify('canceled, no changes.')
endif
else
let annotation = input('Annotation:')
if !empty(annotation)
call bookmarks#add(file, lnum, annotation, 1)
else
call s:NT.notify('empty annotation, skipped!')
endif
endif
endfunction
function! bookmarks#get_all_bookmarks() abort
return deepcopy(s:bookmarks)
endfunction
function! bookmarks#add(file, lnum, text, ...) abort
call bookmarks#logger#info('add bookmarks:')
call bookmarks#logger#info(' file:' .. a:file)
call bookmarks#logger#info(' lnum:' .. a:lnum)
call bookmarks#logger#info(' text:' .. a:text)
call bookmarks#logger#info(' a:000:' .. string(a:000))
if !has_key(s:bookmarks, a:file)
let s:bookmarks[a:file] = {}
endif
if has_key(s:bookmarks[a:file], a:lnum) && has_key(s:bookmarks[a:file][a:lnum], 'vtextid')
call bookmarks#vtext#delete(a:file, s:bookmarks[a:file][a:lnum].vtextid)
endif
if has_key(s:bookmarks[a:file], a:lnum) && has_key(s:bookmarks[a:file][a:lnum], 'signid')
exe 'sign unplace ' . s:bookmarks[a:file][a:lnum].signid
endif
let s:bookmarks[a:file][a:lnum] = {
\ 'text' : a:text,
\ 'file' : a:file,
\ 'lnum' : a:lnum,
\ 'signid' : bookmarks#sign#add(a:file, a:lnum)
\ }
if get(a:000, 0, 0)
let s:bookmarks[a:file][a:lnum].vtextid = bookmarks#vtext#add(a:file, a:lnum, a:text)
let s:bookmarks[a:file][a:lnum].annotation = a:text
endif
call bookmarks#cache#write(s:bookmarks)
endfunction
function! bookmarks#delete(file, lnum) abort
if has_key(s:bookmarks, a:file) && has_key(s:bookmarks[a:file], a:lnum)
exe 'sign unplace ' . s:bookmarks[a:file][a:lnum].signid
if has_key(s:bookmarks[a:file][a:lnum], 'vtextid')
call bookmarks#vtext#delete(a:file, s:bookmarks[a:file][a:lnum].vtextid)
endif
unlet s:bookmarks[a:file][a:lnum]
if empty(s:bookmarks[a:file])
unlet s:bookmarks[a:file]
endif
call bookmarks#cache#write(s:bookmarks)
endif
endfunction
function! s:jump_to_bookmark(bookmark) abort
let file = s:FILE.unify_path(expand('%'), ':p')
if file !=# a:bookmark.file
exe 'e ' . a:bookmark.file
endif
exe a:bookmark.lnum
endfunction
function! bookmarks#next() abort
let file = s:FILE.unify_path(expand('%'), ':p')
if has_key(s:bookmarks, file) && !empty(keys(s:bookmarks[file]))
for lnum in sort(keys(s:bookmarks[file]))
if lnum > line('.')
call s:jump_to_bookmark(s:bookmarks[file][lnum])
return
endif
endfor
" if all bookmarks < line('.')
" jump to first bookmark
call s:jump_to_bookmark(s:bookmarks[file][keys(s:bookmarks[file])[0]])
else
call s:NT.notify('no bookmarks found')
endif
endfunction
function! bookmarks#previous() abort
let file = s:FILE.unify_path(expand('%'), ':p')
if has_key(s:bookmarks, file) && !empty(keys(s:bookmarks[file]))
for lnum in reverse(sort(keys(s:bookmarks[file])))
if lnum < line('.')
call s:jump_to_bookmark(s:bookmarks[file][lnum])
return
endif
endfor
" if all bookmarks > line('.')
" jump to first bookmark
call s:jump_to_bookmark(s:bookmarks[file][keys(s:bookmarks[file])[-1]])
else
call s:NT.notify('no bookmarks found')
endif
endfunction
function! bookmarks#showall() abort
let qf = []
for [f, nrs] in items(s:bookmarks)
for [nr, bm] in items(nrs)
call add(qf, {
\ 'filename' : f,
\ 'lnum' : nr,
\ 'text' : bm.text,
\ })
endfor
endfor
call setqflist([], 'r', {
\ 'title' : 'Bookmarks',
\ 'items' : qf,
\ })
botright copen
endfunction
function! bookmarks#on_enter_buffer() abort
if get(b:, 'bookmarks_init', v:false) || empty(bufname()) || !empty(&buftype)
return
endif
let file = s:FILE.unify_path(expand('%'), ':p')
if has_key(s:bookmarks, file)
for lnum in keys(s:bookmarks[file])
let s:bookmarks[file][lnum].signid = bookmarks#sign#add(file, lnum)
if has_key(s:bookmarks[file][lnum], 'annotation') && !empty(s:bookmarks[file][lnum].annotation)
call bookmarks#vtext#add(file, lnum, s:bookmarks[file][lnum].annotation)
endif
endfor
endif
let b:bookmarks_init = v:true
endfunction
function! bookmarks#clear() abort
let file = s:FILE.unify_path(expand('%'), ':p')
if has_key(s:bookmarks, file)
for lnum in keys(s:bookmarks[file])
call bookmarks#delete(file, lnum)
endfor
endif
call bookmarks#cache#write(s:bookmarks)
endfunction