Add support for `g:obsession_prepend`
Closed this issue · 3 comments
Would you be willing to extend vim-obsession and add a g:obsession_prepend
-variable; in addition to g:obsession_append
?
My use-case is: Keep global marks for a project in the session-file.
I've made a change in my copy of vim-obsession, where I'm using a funcref
that's used to call-back a function in my config. The callback-function returns a list of lines - related to restoring my global marks - which are added (by vim-obsession) to the top of the session-file; so that they don't interfere with badd
and other commands.
Here's the change in obsession.vim
, that I'm currently using:
diff --git a/plugin/obsession.vim b/plugin/obsession.vim
index e36729d..ec7426f 100644
--- a/plugin/obsession.vim
+++ b/plugin/obsession.vim
@@ -77,6 +77,21 @@ function! s:persist() abort
let body = readfile(tmp)
call insert(body, 'let g:this_session = v:this_session', -3)
call insert(body, 'let g:this_obsession = v:this_session', -3)
+ if type(get(g:, 'obsession_prepend')) == type([])
+ for l:Item in g:obsession_prepend
+ if type(l:Item) == v:t_string
+ call insert(body, l:Item)
+ elseif type(l:Item) == v:t_list
+ for l:line in reverse(l:Item)
+ call insert(body, l:line)
+ endfor
+ elseif type(l:Item) == v:t_func
+ for l:line in reverse(l:Item())
+ call insert(body, l:line)
+ endfor
+ endif
+ endfor
+ endif
if type(get(g:, 'obsession_append')) == type([])
for line in g:obsession_append
call insert(body, line, -3)
I'm not aware of a better way to restore global marks, other than editing a marked file, reapplying the cursor-position and then setting the mark!?
Here's the code - from my config - that gets called, by passing a funcref
via the g:obsession_prepend
-variable:
function! s:get_global_mark_lines() abort
let l:marked_files = {}
let l:ordered_files = []
for l:mark_item in getmarklist()
let l:mark = l:mark_item.mark
if l:mark !~# "^'[A-Z]$"
" ignore non-global marks
continue
else
" remove the "'"-prefix from the mark
let l:mark = substitute(l:mark, "'", "", "")
endif
let l:file = l:mark_item.file
let l:pos = l:mark_item.pos
let l:line_number = l:pos[1]
let l:column = l:pos[2]
if has_key(l:marked_files, l:file)
" use existing list of marks, from an already discovered marked file
let l:list = l:marked_files[l:file]
else
" create a new list of marks, for a newly discovered marked file
let l:list = []
let l:marked_files[l:file] = l:list
call add(l:list, "badd +" . l:line_number . " " . fnameescape(l:file))
call add(l:list, "keepjumps edit " . fnameescape(l:file)) " edit file
call add(l:ordered_files, l:file) " keep the order of the files
endif
call add(l:list, l:line_number) " go to line
call add(l:list, "normal! " . l:column . "|") " go to column
call add(l:list, "normal! m" . l:mark) " set mark
endfor
let l:lines = []
call add(l:lines, "delmarks A-Z") " delete marks in the range A to Z
for l:file in l:ordered_files
let l:list = l:marked_files[l:file]
call add(l:lines, l:list)
call add(l:lines, "bdelete " . fnameescape(l:file)) " don't interfere with badd
endfor
return flatten(l:lines)
endfunction
let g:obsession_prepend = [funcref("s:get_global_mark_lines")]
I'm using:
NVIM v0.10.0
Build type: Release
LuaJIT 2.1.1713773202
For my use-case, I needed the lines to be inserted after the cd
-command and before the badd
-commands; inside the session-file.
diff --git a/plugin/obsession.vim b/plugin/obsession.vim
index e36729d..851f2b4 100644
--- a/plugin/obsession.vim
+++ b/plugin/obsession.vim
@@ -77,6 +77,28 @@ function! s:persist() abort
let body = readfile(tmp)
call insert(body, 'let g:this_session = v:this_session', -3)
call insert(body, 'let g:this_obsession = v:this_session', -3)
+ if type(get(g:, 'obsession_prepend')) == type([])
+ let l:idx = 0
+ for l:i in range(0, len(body) - 1)
+ if match(body[l:i], "if &shortmess =\\~ 'A'") == 0
+ let l:idx = l:i + 5 " place after the `shortmess` if-else-block
+ break
+ endif
+ endfor
+ for l:Item in g:obsession_prepend
+ if type(l:Item) == v:t_string
+ call insert(body, l:Item, l:idx)
+ elseif type(l:Item) == v:t_list
+ for l:line in reverse(l:Item)
+ call insert(body, l:line, l:idx)
+ endfor
+ elseif type(l:Item) == v:t_func
+ for l:line in reverse(l:Item())
+ call insert(body, l:line, l:idx)
+ endfor
+ endif
+ endfor
+ endif
if type(get(g:, 'obsession_append')) == type([])
for line in g:obsession_append
call insert(body, line, -3)
I figured, I could trigger my function on the Obsession
-event.
Thank you, for this!
function! s:save_global_marks() abort
" ... code from https://github.com/tpope/vim-obsession/issues/81#issue-2272389561
let l:body = readfile(g:this_obsession)
let l:idx = 0
for l:i in range(0, len(l:body) - 1)
if match(l:body[l:i], "if &shortmess =\\~ 'A'") == 0
let l:idx = l:i + 5 " place after the `shortmess` if-else-block
break
endif
endfor
for l:line in reverse(flatten(l:lines))
call insert(l:body, l:line, l:idx)
endfor
call writefile(l:body, g:this_obsession)
endfunction
augroup my_obsession
autocmd!
autocmd User Obsession call s:save_global_marks()
augroup END
That's probably a more robust solution. g:obsession_append
is designed for static inclusions. For something like global marks you'd need to compute them each time, which is kind of awkward.