Skip to content

Commit

Permalink
Restore cursor position based on concealed column
Browse files Browse the repository at this point in the history
  • Loading branch information
rbong committed Sep 3, 2024
1 parent 5ffa98a commit 6eacfe9
Show file tree
Hide file tree
Showing 3 changed files with 65 additions and 26 deletions.
10 changes: 5 additions & 5 deletions autoload/flog/floggraph/commit.vim
Original file line number Diff line number Diff line change
Expand Up @@ -142,16 +142,16 @@ function! flog#floggraph#commit#RestoreOffset(saved_win, saved_commit) abort

if l:line_offset == 0
let l:new_col = 0
let l:saved_vcol = a:saved_win.vcol
let l:saved_col = a:saved_win.concealcol

if l:saved_vcol == a:saved_commit.col
if l:saved_col == a:saved_commit.col
let l:new_col = flog#floggraph#commit#GetAtLine('.').col
elseif l:saved_vcol == a:saved_commit.format_col
elseif l:saved_col == a:saved_commit.format_col
let l:new_col = flog#floggraph#commit#GetAtLine('.').format_col
endif

if l:new_col > 0
call flog#win#SetVcol('.', l:new_col)
call flog#win#SetConcealCol('.', l:new_col)
endif

return [0, l:new_col]
Expand Down Expand Up @@ -190,7 +190,7 @@ function! flog#floggraph#commit#RestorePosition(saved_win, saved_commit) abort
" Restore parts of window position
call flog#win#RestoreTopline(a:saved_win)
if l:new_col == 0
call flog#win#RestoreVcol(a:saved_win)
call flog#win#RestoreConcealCol(a:saved_win)
endif

return a:saved_commit
Expand Down
6 changes: 3 additions & 3 deletions autoload/flog/floggraph/nav.vim
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ function! flog#floggraph#nav#JumpToCommit(hash, set_jump_mark = v:true, push_to_
let l:line = max([l:commit.line, 1])
let l:col = max([l:commit.col, 1])

call flog#win#SetVcol(l:line, l:col)
call flog#win#SetConcealCol(l:line, l:col)

call flog#floggraph#nav#HandlePostJump(l:pre_jump_info, a:set_jump_mark, a:push_to_jumplist)

Expand Down Expand Up @@ -264,7 +264,7 @@ endfunction
function! flog#floggraph#nav#JumpToCommitStart() abort
call flog#floggraph#buf#AssertFlogBuf()

let l:curr_col = flog#win#GetVcol('.')
let l:curr_col = flog#win#GetConcealCol('.')

let l:commit = flog#floggraph#commit#GetAtLine('.')
if empty(l:commit)
Expand All @@ -276,7 +276,7 @@ function! flog#floggraph#nav#JumpToCommitStart() abort
let l:new_col = l:commit.format_col
endif

call flog#win#SetVcol(l:commit.line, l:new_col)
call flog#win#SetConcealCol(l:commit.line, l:new_col)

return l:new_col
endfunction
Expand Down
75 changes: 57 additions & 18 deletions autoload/flog/win.vim
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,7 @@ function! flog#win#Save() abort
\ 'win_id': win_getid(),
\ 'bufnr': bufnr(),
\ 'view': winsaveview(),
\ 'vcol': flog#win#GetVcol('.'),
\ 'vcols': flog#win#GetVcol('$')
\ 'concealcol': flog#win#GetCols(line('.'), col('.'), -1).concealcol,
\ }
endfunction

Expand All @@ -31,7 +30,7 @@ function! flog#win#Restore(saved_win) abort

if flog#win#Is(a:saved_win)
call winrestview(a:saved_win.view)
call flog#win#RestoreVcol(a:saved_win)
call flog#win#RestoreConcealCol(a:saved_win)
endif

return l:new_win_id
Expand All @@ -51,27 +50,67 @@ function! flog#win#RestoreTopline(saved_win) abort
return l:topline
endfunction

function! flog#win#GetVcol(expr) abort
return virtcol(a:expr)
endfunction
function! flog#win#GetCols(lnum, target_col, target_concealcol) abort
let l:line = getline(a:lnum)

function! flog#win#SetVcol(line, vcol) abort
if exists('*setcursorcharpos')
return setcursorcharpos(a:line, a:vcol)
if len(l:line) == 0
return { 'col': 0, 'virtcol': 0, 'concealcol': 0 }
endif

let l:line = a:line
if type(a:line) == v:t_string
let l:line = line(a:line)
endif
let l:col = 1
let l:virtcol = 1
let l:concealcol = 1
let l:conceal_region = -1
let l:conceal_width = -1

let l:end_col = col([a:lnum, '$'])

while l:col <= l:end_col
if a:target_col >= 0 && a:target_col <= l:col && l:conceal_width != 0
break
endif
if a:target_concealcol >= 0 && a:target_concealcol <= l:concealcol && l:conceal_width != 0
break
endif

let l:width = len(strcharpart(l:line, l:virtcol - 1, 1))
if l:width <= 0
break
endif

let [l:is_concealed, l:conceal_ch, l:new_conceal_region] = synconcealed(a:lnum, l:col + 1)
let l:col += l:width
let l:virtcol += 1

if !l:is_concealed
let l:concealcol += 1
let l:conceal_region = -1
let l:conceal_width = -1
elseif l:new_conceal_region != l:conceal_region
let l:conceal_width = strwidth(l:conceal_ch)
let l:concealcol += l:conceal_width
let l:conceal_region = l:new_conceal_region
endif
endwhile

return { 'col': l:col, 'virtcol': l:virtcol, 'concealcol': l:concealcol }
endfunction

function! flog#win#GetConcealCol(expr) abort
let l:col = type(a:expr) == v:t_number ? a:expr : col(a:expr)
return flog#win#GetCols(line('.'), l:col, -1).concealcol
endfunction

return cursor(a:line, virtcol2col(win_getid(), l:line, a:vcol))
function! flog#win#SetConcealCol(line, concealcol) abort
let l:lnum = type(a:line) == v:t_number ? a:line : line(a:line)
let l:col = flog#win#GetCols(l:lnum, -1, a:concealcol).col
return cursor(l:lnum, l:col)
endfunction

function! flog#win#RestoreVcol(saved_win) abort
let l:vcol = a:saved_win.vcol
call flog#win#SetVcol('.', l:vcol)
return l:vcol
function! flog#win#RestoreConcealCol(saved_win) abort
let g:debug = a:saved_win
call flog#win#SetConcealCol('.', a:saved_win.concealcol)
return a:saved_win.concealcol
endfunction

function! flog#win#IsTabEmpty() abort
Expand Down

0 comments on commit 6eacfe9

Please sign in to comment.