diff options
author | Javier Lopez <graulopezjavier@gmail.com> | 2022-06-30 07:59:52 -0500 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-06-30 05:59:52 -0700 |
commit | 565f72b9689e0c440ff72c712a090224aaf7631b (patch) | |
tree | 425b6a00993aea16e9c3084711d3d6282fbc1f83 /src/nvim/buffer.c | |
parent | cb84f5ee530f0f32b92bed5b4ad41344e8b551aa (diff) | |
download | rneovim-565f72b9689e0c440ff72c712a090224aaf7631b.tar.gz rneovim-565f72b9689e0c440ff72c712a090224aaf7631b.tar.bz2 rneovim-565f72b9689e0c440ff72c712a090224aaf7631b.zip |
feat(marks): restore viewport on jump #15831
** Refactor
Previously most functions used to "get" a mark returned a position,
changed the line number and sometimes changed even the current buffer.
Now functions return a {x}fmark_T making calling context aware whether
the mark is in another buffer without arcane casting. A new function is
provided for switching to the mark buffer and returning a flag style
Enum to convey what happen in the movement. If the cursor changed, line,
columns, if it changed buffer, etc.
The function to get named mark was split into multiple functions.
- mark_get() -> fmark_T
- mark_get_global() -> xfmark_T
- mark_get_local() -> fmark_T
- mark_get_motion() -> fmark_T
- mark_get_visual() -> fmark_T
Functions that manage the changelist and jumplist were also modified to
return mark types.
- get_jumplist -> fmark_T
- get_changelist -> fmark_T
The refactor is also seen mainly on normal.c, where all the mark
movement has been siphoned through one function nv_gomark, while the
other functions handle getting the mark and setting their movement
flags. To handle whether context marks should be left, etc.
** Mark View
While doing the refactor the concept of a mark view was also
implemented:
The view of a mark currently implemented as the number of lines between
the mark position on creation and the window topline. This allows for
moving not only back to the position of a mark but having the window
look similar to when the mark was defined. This is done by carrying and
extra element in the fmark_T struct, which can be extended later to also
restore horizontal shift.
*** User space features
1. There's a new option, jumpoptions+=view enables the mark view restoring
automatically when using the jumplist, changelist, alternate-file and
mark motions. <C-O> <C-I> g; g, <C-^> '[mark] `[mark]
** Limitations
- The view information is not saved in shada.
- Calls to get_mark should copy the value in the pointer since we are
using pos_to_mark() to wrap and provide a homogeneous interfaces. This
was also a limitation in the previous state of things.
Diffstat (limited to 'src/nvim/buffer.c')
-rw-r--r-- | src/nvim/buffer.c | 37 |
1 files changed, 23 insertions, 14 deletions
diff --git a/src/nvim/buffer.c b/src/nvim/buffer.c index baecda8e3c..a2ecb69ac0 100644 --- a/src/nvim/buffer.c +++ b/src/nvim/buffer.c @@ -55,6 +55,7 @@ #include "nvim/main.h" #include "nvim/mapping.h" #include "nvim/mark.h" +#include "nvim/mark_defs.h" #include "nvim/mbyte.h" #include "nvim/memory.h" #include "nvim/message.h" @@ -1789,7 +1790,8 @@ buf_T *buflist_new(char_u *ffname_arg, char_u *sfname_arg, linenr_T lnum, int fl buf_copy_options(buf, BCO_ALWAYS); } - buf->b_wininfo->wi_fpos.lnum = lnum; + buf->b_wininfo->wi_mark = (fmark_T)INIT_FMARK; + buf->b_wininfo->wi_mark.mark.lnum = lnum; buf->b_wininfo->wi_win = curwin; hash_init(&buf->b_s.b_keywtab); @@ -1937,7 +1939,7 @@ int buflist_getfile(int n, linenr_T lnum, int options, int forceit) { buf_T *buf; win_T *wp = NULL; - pos_T *fpos; + fmark_T *fm = NULL; colnr_T col; buf = buflist_findnr(n); @@ -1963,11 +1965,13 @@ int buflist_getfile(int n, linenr_T lnum, int options, int forceit) return FAIL; } + bool restore_view = false; // altfpos may be changed by getfile(), get it now if (lnum == 0) { - fpos = buflist_findfpos(buf); - lnum = fpos->lnum; - col = fpos->col; + fm = buflist_findfmark(buf); + lnum = fm->mark.lnum; + col = fm->mark.col; + restore_view = true; } else { col = 0; } @@ -2011,6 +2015,9 @@ int buflist_getfile(int n, linenr_T lnum, int options, int forceit) curwin->w_cursor.coladd = 0; curwin->w_set_curswant = true; } + if (jop_flags & JOP_VIEW && restore_view) { + mark_view_restore(fm); + } return OK; } RedrawingDisabled--; @@ -2022,7 +2029,7 @@ void buflist_getfpos(void) { pos_T *fpos; - fpos = buflist_findfpos(curbuf); + fpos = &buflist_findfmark(curbuf)->mark; curwin->w_cursor.lnum = fpos->lnum; check_cursor_lnum(); @@ -2462,8 +2469,11 @@ void buflist_setfpos(buf_T *const buf, win_T *const win, linenr_T lnum, colnr_T } } if (lnum != 0) { - wip->wi_fpos.lnum = lnum; - wip->wi_fpos.col = col; + wip->wi_mark.mark.lnum = lnum; + wip->wi_mark.mark.col = col; + if (win != NULL) { + wip->wi_mark.view = mark_view_make(win->w_topline, wip->wi_mark.mark); + } } if (copy_options && win != NULL) { // Save the window-specific option values. @@ -2581,24 +2591,23 @@ void get_winopts(buf_T *buf) didset_window_options(curwin); } -/// Find the position (lnum and col) for the buffer 'buf' for the current -/// window. +/// Find the mark for the buffer 'buf' for the current window. /// /// @return a pointer to no_position if no position is found. -pos_T *buflist_findfpos(buf_T *buf) +fmark_T *buflist_findfmark(buf_T *buf) FUNC_ATTR_PURE { - static pos_T no_position = { 1, 0, 0 }; + static fmark_T no_position = { { 1, 0, 0 }, 0, 0, { 0 }, NULL }; wininfo_T *const wip = find_wininfo(buf, false, false); - return (wip == NULL) ? &no_position : &(wip->wi_fpos); + return (wip == NULL) ? &no_position : &(wip->wi_mark); } /// Find the lnum for the buffer 'buf' for the current window. linenr_T buflist_findlnum(buf_T *buf) FUNC_ATTR_PURE { - return buflist_findfpos(buf)->lnum; + return buflist_findfmark(buf)->mark.lnum; } /// List all known file names (for :files and :buffers command). |