diff options
author | Josh Rahm <joshuarahm@gmail.com> | 2023-11-29 21:52:58 +0000 |
---|---|---|
committer | Josh Rahm <joshuarahm@gmail.com> | 2023-11-29 21:52:58 +0000 |
commit | 931bffbda3668ddc609fc1da8f9eb576b170aa52 (patch) | |
tree | d8c1843a95da5ea0bb4acc09f7e37843d9995c86 /src/nvim/ex_session.c | |
parent | 142d9041391780ac15b89886a54015fdc5c73995 (diff) | |
parent | 4a8bf24ac690004aedf5540fa440e788459e5e34 (diff) | |
download | rneovim-931bffbda3668ddc609fc1da8f9eb576b170aa52.tar.gz rneovim-931bffbda3668ddc609fc1da8f9eb576b170aa52.tar.bz2 rneovim-931bffbda3668ddc609fc1da8f9eb576b170aa52.zip |
Merge remote-tracking branch 'upstream/master' into userreguserreg
Diffstat (limited to 'src/nvim/ex_session.c')
-rw-r--r-- | src/nvim/ex_session.c | 150 |
1 files changed, 54 insertions, 96 deletions
diff --git a/src/nvim/ex_session.c b/src/nvim/ex_session.c index 3de5e1db52..71c01922bc 100644 --- a/src/nvim/ex_session.c +++ b/src/nvim/ex_session.c @@ -1,21 +1,16 @@ -// This is an open source non-commercial project. Dear PVS-Studio, please check -// it. PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com - // Functions for creating a session file, i.e. implementing: // :mkexrc // :mkvimrc // :mkview // :mksession -#include <assert.h> #include <inttypes.h> -#include <limits.h> #include <stdbool.h> #include <stdio.h> #include <string.h> #include "nvim/arglist.h" -#include "nvim/ascii.h" +#include "nvim/ascii_defs.h" #include "nvim/buffer.h" #include "nvim/eval.h" #include "nvim/ex_cmds_defs.h" @@ -25,20 +20,22 @@ #include "nvim/file_search.h" #include "nvim/fileio.h" #include "nvim/fold.h" +#include "nvim/func_attr.h" #include "nvim/garray.h" #include "nvim/gettext.h" #include "nvim/globals.h" -#include "nvim/macros.h" +#include "nvim/macros_defs.h" #include "nvim/mapping.h" -#include "nvim/mark_defs.h" #include "nvim/memory.h" #include "nvim/message.h" #include "nvim/option.h" +#include "nvim/option_vars.h" +#include "nvim/os/fs.h" #include "nvim/os/os.h" #include "nvim/path.h" -#include "nvim/pos.h" +#include "nvim/pos_defs.h" #include "nvim/runtime.h" -#include "nvim/vim.h" +#include "nvim/vim_defs.h" #include "nvim/window.h" #ifdef INCLUDE_GENERATED_DECLARATIONS @@ -65,11 +62,9 @@ static int put_view_curpos(FILE *fd, const win_T *wp, char *spaces) static int ses_winsizes(FILE *fd, int restore_size, win_T *tab_firstwin) { - int n = 0; - win_T *wp; - if (restore_size && (ssop_flags & SSOP_WINSIZE)) { - for (wp = tab_firstwin; wp != NULL; wp = wp->w_next) { + int n = 0; + for (win_T *wp = tab_firstwin; wp != NULL; wp = wp->w_next) { if (!ses_do_win(wp)) { continue; } @@ -109,7 +104,6 @@ static int ses_winsizes(FILE *fd, int restore_size, win_T *tab_firstwin) /// @return FAIL when writing the commands to "fd" fails. static int ses_win_rec(FILE *fd, frame_T *fr) { - frame_T *frc; int count = 0; if (fr->fr_layout == FR_LEAF) { @@ -118,7 +112,7 @@ static int ses_win_rec(FILE *fd, frame_T *fr) // Find first frame that's not skipped and then create a window for // each following one (first frame is already there). - frc = ses_skipframe(fr->fr_child); + frame_T *frc = ses_skipframe(fr->fr_child); if (frc != NULL) { while ((frc = ses_skipframe(frc->fr_next)) != NULL) { // Make window as big as possible so that we have lots of room @@ -218,14 +212,13 @@ static int ses_do_win(win_T *wp) static int ses_arglist(FILE *fd, char *cmd, garray_T *gap, int fullname, unsigned *flagp) { char *buf = NULL; - char *s; if (fprintf(fd, "%s\n%s\n", cmd, "%argdel") < 0) { return FAIL; } for (int i = 0; i < gap->ga_len; i++) { // NULL file names are skipped (only happens when out of memory). - s = alist_name(&((aentry_T *)gap->ga_data)[i]); + char *s = alist_name(&((aentry_T *)gap->ga_data)[i]); if (s != NULL) { if (fullname) { buf = xmalloc(MAXPATHL); @@ -321,18 +314,14 @@ static int ses_put_fname(FILE *fd, char *name, unsigned *flagp) /// @param current_arg_idx current argument index of the window, use -1 if unknown static int put_view(FILE *fd, win_T *wp, int add_edit, unsigned *flagp, int current_arg_idx) { - win_T *save_curwin; int f; - int do_cursor; int did_next = false; // Always restore cursor position for ":mksession". For ":mkview" only // when 'viewoptions' contains "cursor". - do_cursor = (flagp == &ssop_flags || *flagp & SSOP_CURSOR); + int do_cursor = (flagp == &ssop_flags || *flagp & SSOP_CURSOR); - // // Local argument list. - // if (wp->w_alist == &global_alist) { PUTLINE_FAIL("argglobal"); } else { @@ -425,22 +414,18 @@ static int put_view(FILE *fd, win_T *wp, int add_edit, unsigned *flagp, int curr } } - // // Local mappings and abbreviations. - // if ((*flagp & (SSOP_OPTIONS | SSOP_LOCALOPTIONS)) && makemap(fd, wp->w_buffer) == FAIL) { return FAIL; } - // // Local options. Need to go to the window temporarily. // Store only local values when using ":mkview" and when ":mksession" is // used and 'sessionoptions' doesn't include "nvim/options". // Some folding options are always stored when "folds" is included, // otherwise the folds would not be restored correctly. - // - save_curwin = curwin; + win_T *save_curwin = curwin; curwin = wp; curbuf = curwin->w_buffer; if (*flagp & (SSOP_OPTIONS | SSOP_LOCALOPTIONS)) { @@ -457,9 +442,7 @@ static int put_view(FILE *fd, win_T *wp, int add_edit, unsigned *flagp, int curr return FAIL; } - // // Save Folds when 'buftype' is empty and for help files. - // if ((*flagp & SSOP_FOLDS) && wp->w_buffer->b_ffname != NULL && (bt_normal(wp->w_buffer) @@ -469,9 +452,7 @@ static int put_view(FILE *fd, win_T *wp, int add_edit, unsigned *flagp, int curr } } - // // Set the cursor after creating folds, since that moves the cursor. - // if (do_cursor) { // Restore the cursor line in the file and relatively in the // window. Don't use "G", it changes the jumplist. @@ -522,10 +503,8 @@ static int put_view(FILE *fd, win_T *wp, int add_edit, unsigned *flagp, int curr } } - // // Local directory, if the current flag is not view options or the "curdir" // option is included. - // if (wp->w_localdir != NULL && (flagp != &vop_flags || (*flagp & SSOP_CURDIR))) { if (fputs("lcd ", fd) < 0 @@ -551,12 +530,8 @@ static int put_view(FILE *fd, win_T *wp, int add_edit, unsigned *flagp, int curr static int makeopens(FILE *fd, char *dirnow) { int only_save_windows = true; - int nr; int restore_size = true; - win_T *wp; - char *sname; win_T *edited_win = NULL; - int tabnr; win_T *tab_firstwin; frame_T *tab_topframe; int cur_arg_idx = 0; @@ -581,13 +556,11 @@ static int makeopens(FILE *fd, char *dirnow) return FAIL; } - // // Now a :cd command to the session directory or the current directory - // if (ssop_flags & SSOP_SESDIR) { PUTLINE_FAIL("exe \"cd \" . escape(expand(\"<sfile>:p:h\"), ' ')"); } else if (ssop_flags & SSOP_CURDIR) { - sname = home_replace_save(NULL, globaldir != NULL ? globaldir : dirnow); + char *sname = home_replace_save(NULL, globaldir != NULL ? globaldir : dirnow); char *fname_esc = ses_escape_fname(sname, &ssop_flags); if (fprintf(fd, "cd %s\n", fname_esc) < 0) { xfree(fname_esc); @@ -633,7 +606,7 @@ static int makeopens(FILE *fd, char *dirnow) && buf->b_p_bl) { if (fprintf(fd, "badd +%" PRId64 " ", buf->b_wininfo == NULL - ? (int64_t)1L + ? 1 : (int64_t)buf->b_wininfo->wi_mark.mark.lnum) < 0 || ses_fname(fd, buf, &ssop_flags, true) == FAIL) { return FAIL; @@ -665,16 +638,10 @@ static int makeopens(FILE *fd, char *dirnow) restore_stal = true; } - // - // For each tab: - // - Put windows for each tab, when "tabpages" is in 'sessionoptions'. - // - Don't use goto_tabpage(), it may change CWD and trigger autocommands. - // - tab_firstwin = firstwin; // First window in tab page "tabnr". - tab_topframe = topframe; if ((ssop_flags & SSOP_TABPAGES)) { - // Similar to ses_win_rec() below, populate the tab pages first so - // later local options won't be copied to the new tabs. + // "tabpages" is in 'sessionoptions': Similar to ses_win_rec() below, + // populate the tab pages first so later local options won't be copied + // to the new tabs. FOR_ALL_TABS(tp) { // Use `bufhidden=wipe` to remove empty "placeholder" buffers once // they are not needed. This prevents creating extra buffers (see @@ -688,15 +655,17 @@ static int makeopens(FILE *fd, char *dirnow) return FAIL; } } - for (tabnr = 1;; tabnr++) { - tabpage_T *tp = find_tabpage(tabnr); - if (tp == NULL) { - break; // done all tab pages - } + // Assume "tabpages" is in 'sessionoptions'. If not then we only do + // "curtab" and bail out of the loop. + FOR_ALL_TABS(tp) { bool need_tabnext = false; int cnr = 1; + // May repeat putting Windows for each tab, when "tabpages" is in + // 'sessionoptions'. + // Don't use goto_tabpage(), it may change directory and trigger + // autocommands. if ((ssop_flags & SSOP_TABPAGES)) { if (tp == curtab) { tab_firstwin = firstwin; @@ -705,17 +674,19 @@ static int makeopens(FILE *fd, char *dirnow) tab_firstwin = tp->tp_firstwin; tab_topframe = tp->tp_topframe; } - if (tabnr > 1) { + if (tp != first_tabpage) { need_tabnext = true; } + } else { + tp = curtab; + tab_firstwin = firstwin; + tab_topframe = topframe; } - // // Before creating the window layout, try loading one file. If this // is aborted we don't end up with a number of useless windows. // This may have side effects! (e.g., compressed or network file). - // - for (wp = tab_firstwin; wp != NULL; wp = wp->w_next) { + for (win_T *wp = tab_firstwin; wp != NULL; wp = wp->w_next) { if (ses_do_win(wp) && wp->w_buffer->b_ffname != NULL && !bt_help(wp->w_buffer) @@ -753,12 +724,10 @@ static int makeopens(FILE *fd, char *dirnow) PUTLINE_FAIL("let &splitright = s:save_splitright"); } - // // Check if window sizes can be restored (no windows omitted). // Remember the window number of the current window after restoring. - // - nr = 0; - for (wp = tab_firstwin; wp != NULL; wp = wp->w_next) { + int nr = 0; + for (win_T *wp = tab_firstwin; wp != NULL; wp = wp->w_next) { if (ses_do_win(wp)) { nr++; } else { @@ -794,10 +763,20 @@ static int makeopens(FILE *fd, char *dirnow) return FAIL; } - // + // Restore the tab-local working directory if specified + // Do this before the windows, so that the window-local directory can + // override the tab-local directory. + if ((ssop_flags & SSOP_CURDIR) && tp->tp_localdir != NULL) { + if (fputs("tcd ", fd) < 0 + || ses_put_fname(fd, tp->tp_localdir, &ssop_flags) == FAIL + || put_eol(fd) == FAIL) { + return FAIL; + } + did_lcd = true; + } + // Restore the view of the window (options, file, cursor, etc.). - // - for (wp = tab_firstwin; wp != NULL; wp = wp->w_next) { + for (win_T *wp = tab_firstwin; wp != NULL; wp = wp->w_next) { if (!ses_do_win(wp)) { continue; } @@ -816,31 +795,17 @@ static int makeopens(FILE *fd, char *dirnow) // "tabedit". cur_arg_idx = next_arg_idx; - // // Restore cursor to the current window if it's not the first one. - // if (cnr > 1 && (fprintf(fd, "%dwincmd w\n", cnr) < 0)) { return FAIL; } - // // Restore window sizes again after jumping around in windows, because // the current window has a minimum size while others may not. - // if (nr > 1 && ses_winsizes(fd, restore_size, tab_firstwin) == FAIL) { return FAIL; } - // Take care of tab-local working directories if applicable - if (tp->tp_localdir) { - if (fputs("if exists(':tcd') == 2 | tcd ", fd) < 0 - || ses_put_fname(fd, tp->tp_localdir, &ssop_flags) == FAIL - || fputs(" | endif\n", fd) < 0) { - return FAIL; - } - did_lcd = true; - } - // Don't continue in another tab page when doing only the current one // or when at the last tab page. if (!(ssop_flags & SSOP_TABPAGES)) { @@ -857,9 +822,7 @@ static int makeopens(FILE *fd, char *dirnow) return FAIL; } - // // Wipe out an empty unnamed buffer we started in. - // if (fprintf(fd, "%s", "if exists('s:wipebuf') " "&& len(win_findbuf(s:wipebuf)) == 0 " @@ -891,9 +854,7 @@ static int makeopens(FILE *fd, char *dirnow) PUTLINE_FAIL("let &winminwidth = s:save_winminwidth"); } - // // Lastly, execute the x.vim file if it exists. - // if (fprintf(fd, "%s", "let s:sx = expand(\"<sfile>:p:r\").\"x.vim\"\n" "if filereadable(s:sx)\n" @@ -913,7 +874,7 @@ void ex_loadview(exarg_T *eap) return; } - if (do_source(fname, false, DOSO_NONE) == FAIL) { + if (do_source(fname, false, DOSO_NONE, NULL) == FAIL) { semsg(_(e_notopen), fname); } xfree(fname); @@ -926,12 +887,9 @@ void ex_loadview(exarg_T *eap) /// - SSOP_SLASH: filenames are written with "/" slash void ex_mkrc(exarg_T *eap) { - FILE *fd; - int failed = false; int view_session = false; // :mkview, :mksession int using_vdir = false; // using 'viewdir'? char *viewFile = NULL; - unsigned *flagp; if (eap->cmdidx == CMD_mksession || eap->cmdidx == CMD_mkview) { view_session = true; @@ -965,11 +923,13 @@ void ex_mkrc(exarg_T *eap) // When using 'viewdir' may have to create the directory. if (using_vdir && !os_isdir(p_vdir)) { - vim_mkdir_emsg((const char *)p_vdir, 0755); + vim_mkdir_emsg(p_vdir, 0755); } - fd = open_exfile(fname, eap->forceit, WRITEBIN); + FILE *fd = open_exfile(fname, eap->forceit, WRITEBIN); if (fd != NULL) { + int failed = false; + unsigned *flagp; if (eap->cmdidx == CMD_mkview) { flagp = &vop_flags; } else { @@ -1008,9 +968,8 @@ void ex_mkrc(exarg_T *eap) char *dirnow; // current directory dirnow = xmalloc(MAXPATHL); - // + // Change to session file's dir. - // if (os_dirname(dirnow, MAXPATHL) == FAIL || os_chdir(dirnow) != 0) { *dirnow = NUL; @@ -1084,7 +1043,7 @@ void ex_mkrc(exarg_T *eap) } /// @return the name of the view file for the current buffer. -static char *get_view_file(int c) +static char *get_view_file(char c) { if (curbuf->b_ffname == NULL) { emsg(_(e_noname)); @@ -1123,8 +1082,7 @@ static char *get_view_file(int c) } } *s++ = '='; - assert(c >= CHAR_MIN && c <= CHAR_MAX); - *s++ = (char)c; + *s++ = c; xstrlcpy(s, ".vim", 5); xfree(sname); |