This commit is contained in:
Riley Bruins 2024-12-19 08:19:54 +01:00 committed by GitHub
commit d49e41d7ec
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
7 changed files with 243 additions and 44 deletions

View File

@ -2887,6 +2887,20 @@ nvim__ns_set({ns_id}, {opts}) *nvim__ns_set()*
============================================================================== ==============================================================================
Window Functions *api-window* Window Functions *api-window*
*nvim_win_add_fold()*
nvim_win_add_fold({window}, {start}, {end}, {opts})
Add a fold to the window from {start} to {end}.
All row arguments are 0-indexed, inclusive.
Only supported for |fold-manual| and |fold-marker|.
Parameters: ~
• {window} Window handle, or 0 for current window.
• {start} Start row of fold.
• {end} End row of fold.
• {opts} Optional parameters. Reserved for future use.
nvim_win_call({window}, {fun}) *nvim_win_call()* nvim_win_call({window}, {fun}) *nvim_win_call()*
Calls a function with window as temporary current window. Calls a function with window as temporary current window.
@ -2917,6 +2931,21 @@ nvim_win_close({window}, {force}) *nvim_win_close()*
unwritten changes can be closed. The buffer will become unwritten changes can be closed. The buffer will become
hidden, even if 'hidden' is not set. hidden, even if 'hidden' is not set.
*nvim_win_del_fold()*
nvim_win_del_fold({window}, {start}, {end}, {opts})
Delete a fold from the window from {start} to {end}.
All row arguments are 0-indexed, inclusive.
Only supported for |fold-manual| and |fold-marker|.
Parameters: ~
• {window} Window handle, or 0 for current window.
• {start} Start row of fold.
• {end} End row of fold.
• {opts} Optional parameters:
• recursive: Delete folds recursively
nvim_win_del_var({window}, {name}) *nvim_win_del_var()* nvim_win_del_var({window}, {name}) *nvim_win_del_var()*
Removes a window-scoped (w:) variable Removes a window-scoped (w:) variable
@ -2947,6 +2976,17 @@ nvim_win_get_cursor({window}) *nvim_win_get_cursor()*
See also: ~ See also: ~
• |getcurpos()| • |getcurpos()|
nvim_win_get_folds({window}, {opts}) *nvim_win_get_folds()*
Get fold information from the window.
All row arguments are 0-indexed, inclusive.
Parameters: ~
• {window} Window handle, or 0 for current window.
• {opts} Optional parameters:
• start_row: get folds from this row
• end_row: get folds up to this row
nvim_win_get_height({window}) *nvim_win_get_height()* nvim_win_get_height({window}) *nvim_win_get_height()*
Gets the window height Gets the window height

View File

@ -2341,6 +2341,18 @@ function vim.api.nvim_tabpage_set_var(tabpage, name, value) end
--- @param win integer Window handle, must already belong to {tabpage} --- @param win integer Window handle, must already belong to {tabpage}
function vim.api.nvim_tabpage_set_win(tabpage, win) end function vim.api.nvim_tabpage_set_win(tabpage, win) end
--- Add a fold to the window from {start} to {end}.
---
--- All row arguments are 0-indexed, inclusive.
---
--- Only supported for `fold-manual` and `fold-marker`.
---
--- @param window integer Window handle, or 0 for current window.
--- @param start integer Start row of fold.
--- @param end_ integer End row of fold.
--- @param opts vim.api.keyset.empty Optional parameters. Reserved for future use.
function vim.api.nvim_win_add_fold(window, start, end_, opts) end
--- Calls a function with window as temporary current window. --- Calls a function with window as temporary current window.
--- ---
--- ---
@ -2360,6 +2372,19 @@ function vim.api.nvim_win_call(window, fun) end
--- hidden, even if 'hidden' is not set. --- hidden, even if 'hidden' is not set.
function vim.api.nvim_win_close(window, force) end function vim.api.nvim_win_close(window, force) end
--- Delete a fold from the window from {start} to {end}.
---
--- All row arguments are 0-indexed, inclusive.
---
--- Only supported for `fold-manual` and `fold-marker`.
---
--- @param window integer Window handle, or 0 for current window.
--- @param start integer Start row of fold.
--- @param end_ integer End row of fold.
--- @param opts vim.api.keyset.win_del_fold Optional parameters:
--- - recursive: Delete folds recursively
function vim.api.nvim_win_del_fold(window, start, end_, opts) end
--- Removes a window-scoped (w:) variable --- Removes a window-scoped (w:) variable
--- ---
--- @param window integer Window handle, or 0 for current window --- @param window integer Window handle, or 0 for current window
@ -2392,6 +2417,17 @@ function vim.api.nvim_win_get_config(window) end
--- @return integer[] # (row, col) tuple --- @return integer[] # (row, col) tuple
function vim.api.nvim_win_get_cursor(window) end function vim.api.nvim_win_get_cursor(window) end
--- Get fold information from the window.
---
--- All row arguments are 0-indexed, inclusive.
---
--- @param window integer Window handle, or 0 for current window.
--- @param opts vim.api.keyset.empty Optional parameters:
--- - start_row: get folds from this row
--- - end_row: get folds up to this row
--- @return any[]
function vim.api.nvim_win_get_folds(window, opts) end
--- Gets the window height --- Gets the window height
--- ---
--- @param window integer Window handle, or 0 for current window --- @param window integer Window handle, or 0 for current window

View File

@ -308,6 +308,9 @@ error('Cannot require a meta file')
--- @field fixed? boolean --- @field fixed? boolean
--- @field hide? boolean --- @field hide? boolean
--- @class vim.api.keyset.win_del_fold
--- @field recursive? boolean
--- @class vim.api.keyset.win_text_height --- @class vim.api.keyset.win_text_height
--- @field start_row? integer --- @field start_row? integer
--- @field end_row? integer --- @field end_row? integer

View File

@ -227,6 +227,11 @@ typedef struct {
Integer end_vcol; Integer end_vcol;
} Dict(win_text_height); } Dict(win_text_height);
typedef struct {
OptionalKeys is_set__win_del_fold_;
Boolean recursive;
} Dict(win_del_fold);
typedef struct { typedef struct {
OptionalKeys is_set__clear_autocmds_; OptionalKeys is_set__clear_autocmds_;
Buffer buffer; Buffer buffer;

View File

@ -4,6 +4,7 @@
#include <stdlib.h> #include <stdlib.h>
#include "nvim/api/keysets_defs.h" #include "nvim/api/keysets_defs.h"
#include "klib/kvec.h"
#include "nvim/api/private/defs.h" #include "nvim/api/private/defs.h"
#include "nvim/api/private/dispatch.h" #include "nvim/api/private/dispatch.h"
#include "nvim/api/private/helpers.h" #include "nvim/api/private/helpers.h"
@ -16,6 +17,7 @@
#include "nvim/errors.h" #include "nvim/errors.h"
#include "nvim/eval/window.h" #include "nvim/eval/window.h"
#include "nvim/ex_docmd.h" #include "nvim/ex_docmd.h"
#include "nvim/fold.h"
#include "nvim/gettext_defs.h" #include "nvim/gettext_defs.h"
#include "nvim/globals.h" #include "nvim/globals.h"
#include "nvim/lua/executor.h" #include "nvim/lua/executor.h"
@ -563,3 +565,114 @@ Dict nvim_win_text_height(Window window, Dict(win_text_height) *opts, Arena *are
PUT_C(rv, "fill", INTEGER_OBJ(fill)); PUT_C(rv, "fill", INTEGER_OBJ(fill));
return rv; return rv;
} }
/// Add a fold to the window from {start} to {end}.
///
/// All row arguments are 0-indexed, inclusive.
///
/// Only supported for |fold-manual| and |fold-marker|.
///
/// @param window Window handle, or 0 for current window.
/// @param start Start row of fold.
/// @param end End row of fold.
/// @param opts Optional parameters. Reserved for future use.
void nvim_win_add_fold(Window window, Integer start, Integer end, Dict(empty) *opts, Error *err)
FUNC_API_SINCE(11)
{
if (!foldManualAllowed(true)) {
return;
}
win_T *win = find_window_by_handle(window, err);
if (!win) {
return;
}
curwin->w_p_fen = true;
// Rows are zero-indexed.
pos_T start_pos = { start + 1, 1, 0 };
pos_T end_pos = { end + 1, 1, 0 };
foldCreate(win, start_pos, end_pos);
}
/// Delete a fold from the window from {start} to {end}.
///
/// All row arguments are 0-indexed, inclusive.
///
/// Only supported for |fold-manual| and |fold-marker|.
///
/// @param window Window handle, or 0 for current window.
/// @param start Start row of fold.
/// @param end End row of fold.
/// @param opts Optional parameters:
/// - recursive: Delete folds recursively
void nvim_win_del_fold(Window window, Integer start, Integer end, Dict(win_del_fold) *opts, Error *err)
FUNC_API_SINCE(11)
{
if (!foldManualAllowed(false)) {
return;
}
win_T *win = find_window_by_handle(window, err);
if (!win) {
return;
}
// Rows are zero-indexed.
deleteFold(win, start + 1, end + 1, opts->recursive, false);
}
/// Get fold information from the window.
///
/// All row arguments are 0-indexed, inclusive.
///
/// @param window Window handle, or 0 for current window.
/// @param opts Optional parameters:
/// - start_row: get folds from this row
/// - end_row: get folds up to this row
Array nvim_win_get_folds(Window window, Dict(empty) *opts, Arena *arena, Error *err)
FUNC_API_SINCE(11)
{
win_T *win = find_window_by_handle(window, err);
if (!win) {
goto cleanup;
}
garray_T *gap = &win->w_folds;
return folds_to_fold_dict(gap, arena, win, 0);
cleanup:
return (Array)ARRAY_DICT_INIT;
}
static Array folds_to_fold_dict(garray_T *folds, Arena *arena, win_T *wp, int parent_start) {
fold_T *fp = (fold_T *)folds->ga_data;
int fold_count = folds->ga_len;
Array rv = arena_array(arena, fold_count);
for (int i = 0; i < fold_count; i++) {
fold_T fold = fp[i];
// Nested fold positions are relative to the parent
int top = fold.fd_top + parent_start;
Dict fold_dict = arena_dict(arena, 4);
char *state;
switch (fold.fd_flags) {
case FD_CLOSED:
state = "closed";
break;
case FD_OPEN:
state = "open";
break;
case FD_LEVEL:
// BUG: Still does not update for e.g. open nested folds after "zM"
state = foldLevelWin(wp, top) >= wp->w_p_fdl ? "closed" : "open";
break;
}
PUT_C(fold_dict, "state", CSTR_TO_ARENA_OBJ(arena, state));
PUT_C(fold_dict, "start_row", INTEGER_OBJ(top - 1));
PUT_C(fold_dict, "end_row", INTEGER_OBJ(top + fold.fd_len - 2));
Array inner_folds = folds_to_fold_dict(&fold.fd_nested, arena, wp, top);
PUT_C(fold_dict, "children", ARRAY_OBJ(inner_folds));
ADD_C(rv, DICT_OBJ(fold_dict));
}
return rv;
}

View File

@ -55,49 +55,6 @@
#include "nvim/undo.h" #include "nvim/undo.h"
#include "nvim/vim_defs.h" #include "nvim/vim_defs.h"
// local declarations. {{{1
// typedef fold_T {{{2
// The toplevel folds for each window are stored in the w_folds growarray.
// Each toplevel fold can contain an array of second level folds in the
// fd_nested growarray.
// The info stored in both growarrays is the same: An array of fold_T.
typedef struct {
linenr_T fd_top; // first line of fold; for nested fold
// relative to parent
linenr_T fd_len; // number of lines in the fold
garray_T fd_nested; // array of nested folds
char fd_flags; // see below
TriState fd_small; // kTrue, kFalse, or kNone: fold smaller than
// 'foldminlines'; kNone applies to nested
// folds too
} fold_T;
enum {
FD_OPEN = 0, // fold is open (nested ones can be closed)
FD_CLOSED = 1, // fold is closed
FD_LEVEL = 2, // depends on 'foldlevel' (nested folds too)
};
#define MAX_LEVEL 20 // maximum fold depth
// Define "fline_T", passed to get fold level for a line. {{{2
typedef struct {
win_T *wp; // window
linenr_T lnum; // current line number
linenr_T off; // offset between lnum and real line number
linenr_T lnum_save; // line nr used by foldUpdateIEMSRecurse()
int lvl; // current level (-1 for undefined)
int lvl_next; // level used for next line
int start; // number of folds that are forced to start at
// this line.
int end; // level of fold that is forced to end below
// this line
int had_end; // level of fold that is forced to end above
// this line (copy of "end" of prev. line)
} fline_T;
// Flag is set when redrawing is needed. // Flag is set when redrawing is needed.
static bool fold_changed; static bool fold_changed;
@ -1086,7 +1043,7 @@ static bool foldFind(const garray_T *gap, linenr_T lnum, fold_T **fpp)
// foldLevelWin() {{{2 // foldLevelWin() {{{2
/// @return fold level at line number "lnum" in window "wp". /// @return fold level at line number "lnum" in window "wp".
static int foldLevelWin(win_T *wp, linenr_T lnum) int foldLevelWin(win_T *wp, linenr_T lnum)
{ {
fold_T *fp; fold_T *fp;
linenr_T lnum_rel = lnum; linenr_T lnum_rel = lnum;

View File

@ -12,6 +12,51 @@
EXTERN int disable_fold_update INIT( = 0); EXTERN int disable_fold_update INIT( = 0);
// local declarations. {{{1
// typedef fold_T {{{2
// The toplevel folds for each window are stored in the w_folds growarray.
// Each toplevel fold can contain an array of second level folds in the
// fd_nested growarray.
// The info stored in both growarrays is the same: An array of fold_T.
typedef struct {
linenr_T fd_top; // first line of fold; for nested fold
// relative to parent
linenr_T fd_len; // number of lines in the fold
garray_T fd_nested; // array of nested folds
char fd_flags; // see below
TriState fd_small; // kTrue, kFalse, or kNone: fold smaller than
// 'foldminlines'; kNone applies to nested
// folds too
} fold_T;
enum {
FD_OPEN = 0, // fold is open (nested ones can be closed)
FD_CLOSED = 1, // fold is closed
FD_LEVEL = 2, // depends on 'foldlevel' (nested folds too)
};
#define MAX_LEVEL 20 // maximum fold depth
// Define "fline_T", passed to get fold level for a line. {{{2
typedef struct {
win_T *wp; // window
linenr_T lnum; // current line number
linenr_T off; // offset between lnum and real line number
linenr_T lnum_save; // line nr used by foldUpdateIEMSRecurse()
int lvl; // current level (-1 for undefined)
int lvl_next; // level used for next line
int start; // number of folds that are forced to start at
// this line.
int end; // level of fold that is forced to end below
// this line
int had_end; // level of fold that is forced to end above
// this line (copy of "end" of prev. line)
} fline_T;
int foldLevelWin(win_T *wp, linenr_T lnum);
#ifdef INCLUDE_GENERATED_DECLARATIONS #ifdef INCLUDE_GENERATED_DECLARATIONS
# include "fold.h.generated.h" # include "fold.h.generated.h"
#endif #endif