Last active
September 15, 2021 17:54
-
-
Save mg979/b5bef1a64f7ce57fba45a83f6ea147d9 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
" ========================================================================/// | |
" Description: simple bookmarks system using uppercase marks and quickfix | |
" File: projectmarks.vim | |
" Author: Gianmaria Bajo <mg1979.git@gmail.com> | |
" Credits: https://www.reddit.com/r/vim/comments/pngb4j/what_is_the_best_way_to_manage_bookmarks_per/ | |
" License: MIT | |
" Created: mer 15 settembre 2021 17:00:32 | |
" Modified: mer 15 settembre 2021 17:00:32 | |
" ========================================================================/// | |
" GUARD {{{1 | |
if !exists('*bufadd') || exists('g:loaded_projectmarks') | |
finish | |
endif | |
let g:loaded_projectmarks = 1 | |
let s:save_cpo = &cpo | |
set cpo&vim | |
" }}} | |
""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" | |
" Command: ProjectMarks [!] | |
" | |
" Creates or updates a .projectmarks file, that stores uppercase marks from | |
" files belonging to the current root directory. | |
" When this file exists, it is updated on every BufWritePost, or after the user | |
" MarkChanged autocommand. | |
" | |
" After the command is run, the quickfix list is populated with the uppercase | |
" marks belonging to the project. | |
" | |
" If ProjectMarks is called with BANG, the .projectmarks file is deleted, and | |
" the project won't be tracked anymore. | |
" | |
""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" | |
command! -bang ProjectMarks if <bang>0 | silent! call delete('.projectmarks') | |
\| else | call s:update_projectmarks(1) | endif | |
" ----------------------------------------------------------------------------- | |
augroup projectmarks | |
au! | |
au BufEnter,WinEnter * if getcwd() != s:cwd | call s:set_marks() | endif | |
au BufWritePost * call s:update_projectmarks(0) | |
au User MarkChanged call s:update_projectmarks(0) | |
au VimEnter * call s:set_marks() | |
augroup END | |
" ----------------------------------------------------------------------------- | |
let s:cwd = getcwd() | |
let s:entry = { l, c, f -> {'line': l, 'col': c, 'file': f} } | |
" ----------------------------------------------------------------------------- | |
fun! s:set_marks() | |
let s:cwd = getcwd() | |
if !filereadable('.projectmarks') | |
return | |
endif | |
let dict = json_decode(join(readfile('.projectmarks'))) | |
for k in keys(dict) | |
let m = dict[k] | |
call setpos("'". k, [bufadd(m.file), m.line, m.col, 0]) | |
endfor | |
endfun | |
" ----------------------------------------------------------------------------- | |
fun! s:update_projectmarks(qf) | |
if !a:qf && !filereadable('.projectmarks') | |
return | |
endif | |
let s:cwd = getcwd() | |
let marks = filter(split(execute('marks'), '\n'), 'v:val =~ "^\\s*\\u"') | |
let dict = {} | |
for m in marks | |
let l = split(m) | |
let [m, l, c, pos] = [l[0], l[1], l[2], l[3:]] | |
if getpos("'" . m)[0] == bufnr() | |
" mark is in this file | |
let dict[m] = s:entry(l, c, expand('%:p')) | |
elseif filereadable(join(pos)) | |
" mark is in another file | |
if fnamemodify(join(pos), ':p') =~ getcwd() | |
let dict[m] = s:entry(l, c, join(pos)) | |
endif | |
endif | |
endfor | |
call writefile([json_encode(dict)], '.projectmarks') | |
if a:qf | |
let qflines = [] | |
for k in keys(dict) | |
let m = dict[k] | |
let qflines += [printf("%s:%s:%s:%s", m.file, m.line, m.col, 'Mark '.k)] | |
endfor | |
lgetexpr qflines | |
call setloclist(0, [], 'a', {'title': 'Project marks'}) | |
endif | |
endfun | |
""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" | |
" Restore previous external compatibility options {{{1 | |
let &cpo = s:save_cpo | |
unlet s:save_cpo | |
" vim: et sw=4 ts=4 sts=4 fdm=marker |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment