To: vim-dev@vim.org Subject: Patch 6.2.313 Fcc: outbox From: Bram Moolenaar Mime-Version: 1.0 Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: 8bit ------------ Patch 6.2.313 Problem: When opening folds in a diff window, other diff windows no longer show the same text. Solution: Sync the folds in diff windows. Files: src/diff.c, src/fold.c, src/move.c, src/proto/diff.pro, src/proto/move.pro *** ../vim-6.2.312/src/diff.c Fri Feb 20 21:36:20 2004 --- src/diff.c Tue Mar 2 16:32:40 2004 *************** *** 2102,2105 **** --- 2102,2146 ---- return OK; } + + #if defined(FEAT_FOLDING) || defined(PROTO) + /* + * For line "lnum" in the current window find the equivalent lnum in window + * "wp", compensating for inserted/deleted lines. + */ + linenr_T + diff_lnum_win(lnum, wp) + linenr_T lnum; + win_T *wp; + { + diff_T *dp; + int idx; + int i; + + idx = diff_buf_idx(curbuf); + if (idx == DB_COUNT) /* safety check */ + return (linenr_T)0; + + if (diff_invalid) + ex_diffupdate(NULL); /* update after a big change */ + + /* search for a change that includes "lnum" in the list of diffblocks. */ + for (dp = first_diff; dp != NULL; dp = dp->df_next) + if (lnum <= dp->df_lnum[idx] + dp->df_count[idx]) + break; + + /* When after the last change, compute relative to the last line number. */ + if (dp == NULL) + return wp->w_buffer->b_ml.ml_line_count + - (curbuf->b_ml.ml_line_count - lnum); + + /* Find index for "wp". */ + i = diff_buf_idx(wp->w_buffer); + if (i == DB_COUNT) /* safety check */ + return (linenr_T)0; + + return lnum + (dp->df_lnum[i] - dp->df_lnum[idx]); + } + #endif + #endif /* FEAT_DIFF */ *** ../vim-6.2.312/src/fold.c Fri Feb 20 21:36:20 2004 --- src/fold.c Tue Mar 2 17:02:36 2004 *************** *** 43,54 **** --- 43,56 ---- #define MAX_LEVEL 20 /* maximum fold depth */ /* static functions {{{2 */ + static void newFoldLevelWin __ARGS((win_T *wp)); static int checkCloseRec __ARGS((garray_T *gap, linenr_T lnum, int level)); static int foldFind __ARGS((garray_T *gap, linenr_T lnum, fold_T **fpp)); static int foldLevelWin __ARGS((win_T *wp, linenr_T lnum)); static void checkupdate __ARGS((win_T *wp)); static void setFoldRepeat __ARGS((linenr_T lnum, long count, int open)); static linenr_T setManualFold __ARGS((linenr_T lnum, int opening, int recurse, int *donep)); + static linenr_T setManualFoldWin __ARGS((win_T *wp, linenr_T lnum, int opening, int recurse, int *donep)); static void foldOpenNested __ARGS((fold_T *fpr)); static void deleteFoldEntry __ARGS((garray_T *gap, int idx, int recursive)); static void foldMarkAdjustRecurse __ARGS((garray_T *gap, linenr_T line1, linenr_T line2, long amount, long amount_after)); *************** *** 486,506 **** void newFoldLevel() { fold_T *fp; int i; ! checkupdate(curwin); ! if (curwin->w_fold_manual) { /* Set all flags for the first level of folds to FD_LEVEL. Following * manual open/close will then change the flags to FD_OPEN or * FD_CLOSED for those folds that don't use 'foldlevel'. */ ! fp = (fold_T *)curwin->w_folds.ga_data; ! for (i = 0; i < curwin->w_folds.ga_len; ++i) fp[i].fd_flags = FD_LEVEL; ! curwin->w_fold_manual = FALSE; } ! changed_window_setting(); } /* foldCheckClose() {{{2 */ --- 488,534 ---- void newFoldLevel() { + newFoldLevelWin(curwin); + + #ifdef FEAT_DIFF + if (foldmethodIsDiff(curwin) && curwin->w_p_scb) + { + win_T *wp; + + /* + * Set the same foldlevel in other windows in diff mode. + */ + FOR_ALL_WINDOWS(wp) + { + if (wp != curwin && foldmethodIsDiff(wp) && wp->w_p_scb) + { + wp->w_p_fdl = curwin->w_p_fdl; + newFoldLevelWin(wp); + } + } + } + #endif + } + + static void + newFoldLevelWin(wp) + win_T *wp; + { fold_T *fp; int i; ! checkupdate(wp); ! if (wp->w_fold_manual) { /* Set all flags for the first level of folds to FD_LEVEL. Following * manual open/close will then change the flags to FD_OPEN or * FD_CLOSED for those folds that don't use 'foldlevel'. */ ! fp = (fold_T *)wp->w_folds.ga_data; ! for (i = 0; i < wp->w_folds.ga_len; ++i) fp[i].fd_flags = FD_LEVEL; ! wp->w_fold_manual = FALSE; } ! changed_window_setting_win(wp); } /* foldCheckClose() {{{2 */ *************** *** 1232,1246 **** /* setManualFold() {{{2 */ /* * Open or close the fold in the current window which contains "lnum". * "donep", when not NULL, points to flag that is set to DONE_FOLD when some * fold was found and to DONE_ACTION when some fold was opened or closed. * When "donep" is NULL give an error message when no fold was found for ! * "lnum". * Return the line number of the next line that could be closed. * It's only valid when "opening" is TRUE! */ static linenr_T ! setManualFold(lnum, opening, recurse, donep) linenr_T lnum; int opening; /* TRUE when opening, FALSE when closing */ int recurse; /* TRUE when closing/opening recursive */ --- 1260,1312 ---- /* setManualFold() {{{2 */ /* * Open or close the fold in the current window which contains "lnum". + * Also does this for other windows in diff mode when needed. + */ + static linenr_T + setManualFold(lnum, opening, recurse, donep) + linenr_T lnum; + int opening; /* TRUE when opening, FALSE when closing */ + int recurse; /* TRUE when closing/opening recursive */ + int *donep; + { + #ifdef FEAT_DIFF + if (foldmethodIsDiff(curwin) && curwin->w_p_scb) + { + win_T *wp; + linenr_T lnum; + + /* + * Do the same operation in other windows in diff mode. Calculate the + * line number from the diffs. + */ + FOR_ALL_WINDOWS(wp) + { + if (wp != curwin && foldmethodIsDiff(wp) && wp->w_p_scb) + { + lnum = diff_lnum_win(curwin->w_cursor.lnum, wp); + if (lnum != 0) + (void)setManualFoldWin(wp, lnum, opening, recurse, NULL); + } + } + } + #endif + + return setManualFoldWin(curwin, lnum, opening, recurse, donep); + } + + /* setManualFoldWin() {{{2 */ + /* + * Open or close the fold in window "wp" which contains "lnum". * "donep", when not NULL, points to flag that is set to DONE_FOLD when some * fold was found and to DONE_ACTION when some fold was opened or closed. * When "donep" is NULL give an error message when no fold was found for ! * "lnum", but only if "wp" is "curwin". * Return the line number of the next line that could be closed. * It's only valid when "opening" is TRUE! */ static linenr_T ! setManualFoldWin(wp, lnum, opening, recurse, donep) ! win_T *wp; linenr_T lnum; int opening; /* TRUE when opening, FALSE when closing */ int recurse; /* TRUE when closing/opening recursive */ *************** *** 1258,1269 **** linenr_T off = 0; int done = 0; ! checkupdate(curwin); /* * Find the fold, open or close it. */ ! gap = &curwin->w_folds; for (;;) { if (!foldFind(gap, lnum, &fp)) --- 1324,1335 ---- linenr_T off = 0; int done = 0; ! checkupdate(wp); /* * Find the fold, open or close it. */ ! gap = &wp->w_folds; for (;;) { if (!foldFind(gap, lnum, &fp)) *************** *** 1285,1291 **** if (use_level || fp->fd_flags == FD_LEVEL) { use_level = TRUE; ! if (level >= curwin->w_p_fdl) fp->fd_flags = FD_CLOSED; else fp->fd_flags = FD_OPEN; --- 1351,1357 ---- if (use_level || fp->fd_flags == FD_LEVEL) { use_level = TRUE; ! if (level >= wp->w_p_fdl) fp->fd_flags = FD_CLOSED; else fp->fd_flags = FD_OPEN; *************** *** 1331,1342 **** found->fd_flags = FD_CLOSED; done |= DONE_ACTION; } ! curwin->w_fold_manual = TRUE; if (done & DONE_ACTION) ! changed_window_setting(); done |= DONE_FOLD; } ! else if (donep == NULL) EMSG(_(e_nofold)); if (donep != NULL) --- 1397,1408 ---- found->fd_flags = FD_CLOSED; done |= DONE_ACTION; } ! wp->w_fold_manual = TRUE; if (done & DONE_ACTION) ! changed_window_setting_win(wp); done |= DONE_FOLD; } ! else if (donep == NULL && wp == curwin) EMSG(_(e_nofold)); if (donep != NULL) *** ../vim-6.2.312/src/move.c Fri Feb 20 21:36:20 2004 --- src/move.c Tue Mar 2 16:41:52 2004 *************** *** 467,476 **** void changed_window_setting() { ! curwin->w_lines_valid = 0; ! changed_line_abv_curs(); ! curwin->w_valid &= ~(VALID_BOTLINE|VALID_BOTLINE_AP|VALID_TOPLINE); ! redraw_later(NOT_VALID); } /* --- 467,483 ---- void changed_window_setting() { ! changed_window_setting_win(curwin); ! } ! ! void ! changed_window_setting_win(wp) ! win_T *wp; ! { ! wp->w_lines_valid = 0; ! changed_line_abv_curs_win(wp); ! wp->w_valid &= ~(VALID_BOTLINE|VALID_BOTLINE_AP|VALID_TOPLINE); ! redraw_win_later(wp, NOT_VALID); } /* *** ../vim-6.2.312/src/proto/diff.pro Sun Jun 1 12:26:06 2003 --- src/proto/diff.pro Tue Mar 2 16:54:08 2004 *************** *** 19,22 **** --- 19,23 ---- void ex_diffgetput __ARGS((exarg_T *eap)); int diff_mode_buf __ARGS((buf_T *buf)); int diff_move_to __ARGS((int dir, long count)); + linenr_T diff_lnum_win __ARGS((linenr_T lnum, win_T *wp)); /* vim: set ft=c : */ *** ../vim-6.2.312/src/proto/move.pro Sun Jun 1 12:26:16 2003 --- src/proto/move.pro Tue Mar 2 16:54:12 2004 *************** *** 4,9 **** --- 4,10 ---- void update_curswant __ARGS((void)); void check_cursor_moved __ARGS((win_T *wp)); void changed_window_setting __ARGS((void)); + void changed_window_setting_win __ARGS((win_T *wp)); void set_topline __ARGS((win_T *wp, linenr_T lnum)); void changed_cline_bef_curs __ARGS((void)); void changed_cline_bef_curs_win __ARGS((win_T *wp)); *** ../vim-6.2.312/src/version.c Wed Mar 3 19:23:14 2004 --- src/version.c Wed Mar 3 21:03:54 2004 *************** *** 639,640 **** --- 639,642 ---- { /* Add new patch number below this line */ + /**/ + 313, /**/ -- The Law of VIM: For each member b of the possible behaviour space B of program P, there exists a finite time t before which at least one user u in the total user space U of program P will request b becomes a member of the allowed behaviour space B' (B' <= B). In other words: Sooner or later everyone wants everything as an option. -- Vince Negri /// Bram Moolenaar -- Bram@Moolenaar.net -- http://www.Moolenaar.net \\\ /// Sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\ \\\ Project leader for A-A-P -- http://www.A-A-P.org /// \\\ Buy at Amazon and help AIDS victims -- http://ICCF.nl/click1.html ///