# HG changeset patch # User vimboss # Date 1142717413 0 # Node ID fb913578cbf5dfbbef28d23922efdae4c63b5b74 # Parent c3f63ed316b621743f44a5ab6b9a5438b88feded updated for version 7.0228 diff --git a/runtime/optwin.vim b/runtime/optwin.vim --- a/runtime/optwin.vim +++ b/runtime/optwin.vim @@ -1,7 +1,7 @@ " These commands create the option window. " " Maintainer: Bram Moolenaar -" Last Change: 2006 Mar 16 +" Last Change: 2006 Mar 18 " If there already is an option window, jump to that one. if bufwinnr("option-window") > 0 @@ -435,6 +435,9 @@ call append("$", "winfixheight\tkeep the call append("$", "\t(local to window)") call BinOptionL("wfh") if has("vertsplit") +call append("$", "winfixwidth\tkeep the width of the window") +call append("$", "\t(local to window)") +call BinOptionL("wfw") call append("$", "winwidth\tminimal number of columns used for the current window") call append("$", " \tset wiw=" . &wiw) call append("$", "winminwidth\tminimal number of columns used for any window") diff --git a/src/getchar.c b/src/getchar.c --- a/src/getchar.c +++ b/src/getchar.c @@ -3273,7 +3273,7 @@ do_map(maptype, arg, mode, abbrev) { if (abbrev) { - if (hash != 0) /* there is only one abbreviation list */ + if (hash > 0) /* there is only one abbreviation list */ break; mpp = abbr_table; } @@ -3595,7 +3595,7 @@ map_clear_int(buf, mode, local, abbr) { if (abbr) { - if (hash) /* there is only one abbrlist */ + if (hash > 0) /* there is only one abbrlist */ break; #ifdef FEAT_LOCALMAP if (local) @@ -3734,9 +3734,10 @@ showmap(mp, local) * Also checks mappings local to the current buffer. */ int -map_to_exists(str, modechars) +map_to_exists(str, modechars, abbr) char_u *str; char_u *modechars; + int abbr; { int mode = 0; char_u *rhs; @@ -3758,7 +3759,7 @@ map_to_exists(str, modechars) if (vim_strchr(modechars, 'c') != NULL) mode |= CMDLINE; - retval = map_to_exists_mode(rhs, mode); + retval = map_to_exists_mode(rhs, mode, abbr); vim_free(buf); return retval; @@ -3770,9 +3771,10 @@ map_to_exists(str, modechars) * Also checks mappings local to the current buffer. */ int -map_to_exists_mode(rhs, mode) +map_to_exists_mode(rhs, mode, abbr) char_u *rhs; int mode; + int abbr; { mapblock_T *mp; int hash; @@ -3787,11 +3789,22 @@ map_to_exists_mode(rhs, mode) # endif for (hash = 0; hash < 256; ++hash) { + if (abbr) + { + if (hash > 0) /* there is only one abbr list */ + break; +#ifdef FEAT_LOCALMAP + if (expand_buffer) + mp = curbuf->b_first_abbr; + else +#endif + mp = first_abbr; + } # ifdef FEAT_LOCALMAP - if (expand_buffer) + else if (expand_buffer) mp = curbuf->b_maphash[hash]; +# endif else -# endif mp = maphash[hash]; for (; mp; mp = mp->m_next) { @@ -3954,7 +3967,7 @@ ExpandMappings(regmatch, num_file, file) { if (expand_isabbrev) { - if (hash) /* only one abbrev list */ + if (hash > 0) /* only one abbrev list */ break; /* for (hash) */ mp = first_abbr; } @@ -4255,7 +4268,7 @@ makemap(fd, buf) { if (abbr) { - if (hash) /* there is only one abbr list */ + if (hash > 0) /* there is only one abbr list */ break; #ifdef FEAT_LOCALMAP if (buf != NULL) @@ -4614,11 +4627,12 @@ check_map_keycodes() * NULL otherwise */ char_u * -check_map(keys, mode, exact, ign_mod) +check_map(keys, mode, exact, ign_mod, abbr) char_u *keys; int mode; int exact; /* require exact match */ int ign_mod; /* ignore preceding modifier */ + int abbr; /* do abbreviations */ { int hash; int len, minlen; @@ -4637,11 +4651,22 @@ check_map(keys, mode, exact, ign_mod) /* loop over all hash lists */ for (hash = 0; hash < 256; ++hash) { + if (abbr) + { + if (hash > 0) /* there is only one list. */ + break; #ifdef FEAT_LOCALMAP - if (local) + if (local) + mp = curbuf->b_first_abbr; + else +#endif + mp = first_abbr; + } +#ifdef FEAT_LOCALMAP + else if (local) mp = curbuf->b_maphash[hash]; +#endif else -#endif mp = maphash[hash]; for ( ; mp != NULL; mp = mp->m_next) { diff --git a/src/if_ruby.c b/src/if_ruby.c --- a/src/if_ruby.c +++ b/src/if_ruby.c @@ -1,7 +1,9 @@ /* vi:set ts=8 sts=4 sw=4: * * VIM - Vi IMproved by Bram Moolenaar - * Ruby interface by Shugo Maeda. + * + * Ruby interface by Shugo Maeda + * with improvements by SegPhault (Ryan Paul) * * Do ":help uganda" in Vim to read copying and usage conditions. * Do ":help credits" in Vim to see a list of people who contributed. @@ -567,7 +569,14 @@ static VALUE buffer_s_count() buf_T *b; int n = 0; - for (b = firstbuf; b; b = b->b_next) n++; + for (b = firstbuf; b != NULL; b = b->b_next) + { + /* Deleted buffers should not be counted + * SegPhault - 01/07/05 */ + if (b->b_p_bl) + n++; + } + return INT2NUM(n); } @@ -576,9 +585,17 @@ static VALUE buffer_s_aref(VALUE self, V buf_T *b; int n = NUM2INT(num); - for (b = firstbuf; b; b = b->b_next, --n) { - if (n == 0) + for (b = firstbuf; b != NULL; b = b->b_next) + { + /* Deleted buffers should not be counted + * SegPhault - 01/07/05 */ + if (!b->b_p_bl) + continue; + + if (n == 0) return buffer_new(b); + + n--; } return Qnil; } @@ -604,32 +621,35 @@ static VALUE buffer_count(VALUE self) return INT2NUM(buf->b_ml.ml_line_count); } -static VALUE buffer_aref(VALUE self, VALUE num) +static VALUE get_buffer_line(buf_T *buf, linenr_T n) { - buf_T *buf = get_buf(self); - long n = NUM2LONG(num); - - if (n > 0 && n <= buf->b_ml.ml_line_count) { + if (n > 0 && n <= buf->b_ml.ml_line_count) + { char *line = (char *)ml_get_buf(buf, n, FALSE); return line ? rb_str_new2(line) : Qnil; } - else { - rb_raise(rb_eIndexError, "index %d out of buffer", n); - return Qnil; /* For stop warning */ - } + rb_raise(rb_eIndexError, "index %d out of buffer", n); + return Qnil; /* For stop warning */ } -static VALUE buffer_aset(VALUE self, VALUE num, VALUE str) +static VALUE buffer_aref(VALUE self, VALUE num) { buf_T *buf = get_buf(self); + + if (buf != NULL) + return get_buffer_line(buf, (linenr_T)NUM2LONG(num)); + return Qnil; /* For stop warning */ +} + +static VALUE set_buffer_line(buf_T *buf, linenr_T n, VALUE str) +{ buf_T *savebuf = curbuf; char *line = STR2CSTR(str); - long n = NUM2LONG(num); if (n > 0 && n <= buf->b_ml.ml_line_count && line != NULL) { curbuf = buf; if (u_savesub(n) == OK) { - ml_replace(n, (char_u *) line, TRUE); + ml_replace(n, (char_u *)line, TRUE); changed(); #ifdef SYNTAX_HL syn_changed(n); /* recompute syntax hl. for this line */ @@ -645,6 +665,15 @@ static VALUE buffer_aset(VALUE self, VAL return str; } +static VALUE buffer_aset(VALUE self, VALUE num, VALUE str) +{ + buf_T *buf = get_buf(self); + + if (buf != NULL) + return set_buffer_line(buf, (linenr_T)NUM2LONG(num), str); + return str; +} + static VALUE buffer_delete(VALUE self, VALUE num) { buf_T *buf = get_buf(self); @@ -654,8 +683,12 @@ static VALUE buffer_delete(VALUE self, V if (n > 0 && n <= buf->b_ml.ml_line_count) { curbuf = buf; if (u_savedel(n, 1) == OK) { - mark_adjust(n, n, MAXLNUM, -1); ml_delete(n, 0); + + /* Changes to non-active buffers should properly refresh + * SegPhault - 01/09/05 */ + deleted_lines_mark(n, 1L); + changed(); } curbuf = savebuf; @@ -677,9 +710,13 @@ static VALUE buffer_append(VALUE self, V if (n >= 0 && n <= buf->b_ml.ml_line_count && line != NULL) { curbuf = buf; if (u_inssub(n + 1) == OK) { - mark_adjust(n + 1, MAXLNUM, 1L, 0L); ml_append(n, (char_u *) line, (colnr_T) 0, FALSE); - changed(); + + /* Changes to non-active buffers should properly refresh screen + * SegPhault - 12/20/04 */ + appended_lines_mark(n, 1L); + + changed(); } curbuf = savebuf; update_curbuf(NOT_VALID); @@ -720,6 +757,27 @@ static VALUE window_s_current() return window_new(curwin); } +/* + * Added line manipulation functions + * SegPhault - 03/07/05 + */ +static VALUE line_s_current() +{ + return get_buffer_line(curbuf, curwin->w_cursor.lnum); +} + +static VALUE set_current_line(VALUE str) +{ + return set_buffer_line(curbuf, curwin->w_cursor.lnum, str); +} + +static VALUE current_line_number() +{ + return INT2FIX((int)curwin->w_cursor.lnum); +} + + + static VALUE window_s_count() { #ifdef FEAT_WINDOWS @@ -877,6 +935,13 @@ static void ruby_vim_init(void) rb_define_method(cBuffer, "delete", buffer_delete, 1); rb_define_method(cBuffer, "append", buffer_append, 2); + /* Added line manipulation functions + * SegPhault - 03/07/05 */ + rb_define_method(cBuffer, "line_number", current_line_number, 0); + rb_define_method(cBuffer, "line", line_s_current, 0); + rb_define_method(cBuffer, "line=", set_current_line, 1); + + cVimWindow = rb_define_class_under(mVIM, "Window", rb_cObject); rb_define_singleton_method(cVimWindow, "current", window_s_current, 0); rb_define_singleton_method(cVimWindow, "count", window_s_count, 0); diff --git a/src/window.c b/src/window.c --- a/src/window.c +++ b/src/window.c @@ -36,8 +36,9 @@ static int frame_has_win __ARGS((frame_T static void frame_new_height __ARGS((frame_T *topfrp, int height, int topfirst, int wfh)); static int frame_fixed_height __ARGS((frame_T *frp)); #ifdef FEAT_VERTSPLIT +static int frame_fixed_width __ARGS((frame_T *frp)); static void frame_add_statusline __ARGS((frame_T *frp)); -static void frame_new_width __ARGS((frame_T *topfrp, int width, int leftfirst)); +static void frame_new_width __ARGS((frame_T *topfrp, int width, int leftfirst, int wfw)); static void frame_add_vsep __ARGS((frame_T *frp)); static int frame_minwidth __ARGS((frame_T *topfrp, win_T *next_curwin)); static void frame_fix_width __ARGS((win_T *wp)); @@ -723,6 +724,12 @@ win_split_ins(size, flags, newwin, dir) /* if it doesn't fit in the current window, need win_equal() */ if (oldwin->w_width - new_size - 1 < p_wmw) do_equal = TRUE; + + /* We don't like to take lines for the new window from a + * 'winfixwidth' window. Take them from a window to the left or right + * instead, if possible. */ + if (oldwin->w_p_wfw) + win_setwidth_win(oldwin->w_width + new_size, oldwin); } else #endif @@ -937,10 +944,11 @@ win_split_ins(size, flags, newwin, dir) frame_add_vsep(curfrp); /* Set width of neighbor frame */ frame_new_width(curfrp, curfrp->fr_width - - (new_size + ((flags & WSP_TOP) != 0)), flags & WSP_TOP); + - (new_size + ((flags & WSP_TOP) != 0)), flags & WSP_TOP, + FALSE); } else - oldwin->w_width -= new_size + 1; + win_new_width(oldwin, oldwin->w_width - (new_size + 1)); if (before) /* new window left of current one */ { wp->w_wincol = oldwin->w_wincol; @@ -1588,7 +1596,7 @@ win_equal_rec(next_curwin, current, topf frame_new_height(topfr, height, FALSE, FALSE); #ifdef FEAT_VERTSPLIT topfr->fr_win->w_wincol = col; - frame_new_width(topfr, width, FALSE); + frame_new_width(topfr, width, FALSE, FALSE); #endif redraw_all_later(CLEAR); } @@ -1610,8 +1618,13 @@ win_equal_rec(next_curwin, current, topf else extra_sep = 0; totwincount = (n + extra_sep) / (p_wmw + 1); - - /* Compute room available for windows other than "next_curwin" */ + has_next_curwin = frame_has_win(topfr, next_curwin); + + /* + * Compute width for "next_curwin" window and room available for + * other windows. + * "m" is the minimal width when counting p_wiw for "next_curwin". + */ m = frame_minwidth(topfr, next_curwin); room = width - m; if (room < 0) @@ -1619,18 +1632,56 @@ win_equal_rec(next_curwin, current, topf next_curwin_size = p_wiw + room; room = 0; } - else if (n == m) /* doesn't contain curwin */ - next_curwin_size = 0; else { - next_curwin_size = (room + p_wiw + (totwincount - 1) * p_wmw + next_curwin_size = -1; + for (fr = topfr->fr_child; fr != NULL; fr = fr->fr_next) + { + /* If 'winfixwidth' set keep the window width if + * possible. + * Watch out for this window being the next_curwin. */ + if (frame_fixed_width(fr)) + { + n = frame_minwidth(fr, NOWIN); + new_size = fr->fr_width; + if (frame_has_win(fr, next_curwin)) + { + room += p_wiw - p_wmw; + next_curwin_size = 0; + if (new_size < p_wiw) + new_size = p_wiw; + } + else + /* These windows don't use up room. */ + totwincount -= (n + (fr->fr_next == NULL + ? extra_sep : 0)) / (p_wmw + 1); + room -= new_size - n; + if (room < 0) + { + new_size += room; + room = 0; + } + fr->fr_newwidth = new_size; + } + } + if (next_curwin_size == -1) + { + if (!has_next_curwin) + next_curwin_size = 0; + else if (totwincount > 1 + && (room + (totwincount - 2)) + / (totwincount - 1) > p_wiw) + { + next_curwin_size = (room + p_wiw + totwincount * p_wmw + (totwincount - 1)) / totwincount; - if (next_curwin_size > p_wiw) - room -= next_curwin_size - p_wiw; - else - next_curwin_size = p_wiw; + room -= next_curwin_size - p_wiw; + } + else + next_curwin_size = p_wiw; + } } - if (n != m) + + if (has_next_curwin) --totwincount; /* don't count curwin */ } @@ -1643,6 +1694,11 @@ win_equal_rec(next_curwin, current, topf new_size = width; else if (dir == 'v') new_size = fr->fr_width; + else if (frame_fixed_width(fr)) + { + new_size = fr->fr_newwidth; + wincount = 0; /* doesn't count as a sizeable window */ + } else { /* Compute the maximum number of windows horiz. in "fr". */ @@ -1650,30 +1706,37 @@ win_equal_rec(next_curwin, current, topf wincount = (n + (fr->fr_next == NULL ? extra_sep : 0)) / (p_wmw + 1); m = frame_minwidth(fr, next_curwin); - if (n != m) /* don't count next_curwin */ + if (has_next_curwin) + hnc = frame_has_win(fr, next_curwin); + else + hnc = FALSE; + if (hnc) /* don't count next_curwin */ --wincount; - new_size = (wincount * room + ((unsigned)totwincount >> 1)) + if (totwincount == 0) + new_size = room; + else + new_size = (wincount * room + ((unsigned)totwincount >> 1)) / totwincount; - if (n != m) /* add next_curwin size */ + if (hnc) /* add next_curwin size */ { next_curwin_size -= p_wiw - (m - n); new_size += next_curwin_size; + room -= new_size - next_curwin_size; } + else + room -= new_size; + new_size += n; } - /* Skip frame that is full height when splitting or closing a + /* Skip frame that is full width when splitting or closing a * window, unless equalizing all frames. */ if (!current || dir != 'v' || topfr->fr_parent != NULL || (new_size != fr->fr_width) || frame_has_win(fr, next_curwin)) win_equal_rec(next_curwin, current, fr, dir, col, row, - new_size + n, height); - col += new_size + n; - width -= new_size + n; - if (n != m) /* contains curwin */ - room -= new_size - next_curwin_size; - else - room -= new_size; + new_size, height); + col += new_size; + width -= new_size; totwincount -= wincount; } } @@ -2172,7 +2235,7 @@ winframe_remove(win, dirp, tp) frame_T *frp, *frp2, *frp3; frame_T *frp_close = win->w_frame; win_T *wp; - int old_height = 0; + int old_size = 0; /* * If there is only one window there is nothing to remove. @@ -2199,18 +2262,27 @@ winframe_remove(win, dirp, tp) if (frp2->fr_win != NULL && (frp2->fr_next != NULL || frp2->fr_prev != NULL) && frp2->fr_win->w_p_wfh) - old_height = frp2->fr_win->w_height; + old_size = frp2->fr_win->w_height; frame_new_height(frp2, frp2->fr_height + frp_close->fr_height, frp2 == frp_close->fr_next ? TRUE : FALSE, FALSE); - if (old_height != 0) - win_setheight_win(old_height, frp2->fr_win); + if (old_size != 0) + win_setheight_win(old_size, frp2->fr_win); #ifdef FEAT_VERTSPLIT *dirp = 'v'; } else { + /* When 'winfixwidth' is set, remember its old size and restore + * it later (it's a simplistic solution...). Don't do this if the + * window will occupy the full width of the screen. */ + if (frp2->fr_win != NULL + && (frp2->fr_next != NULL || frp2->fr_prev != NULL) + && frp2->fr_win->w_p_wfw) + old_size = frp2->fr_win->w_width; frame_new_width(frp2, frp2->fr_width + frp_close->fr_width, - frp2 == frp_close->fr_next ? TRUE : FALSE); + frp2 == frp_close->fr_next ? TRUE : FALSE, FALSE); + if (old_size != 0) + win_setwidth_win(old_size, frp2->fr_win); *dirp = 'h'; } #endif @@ -2390,7 +2462,7 @@ frame_new_height(topfrp, height, topfirs while (frp != NULL); } #endif - else + else /* fr_layout == FR_COL */ { /* Complicated case: Resize a column of frames. Resize the bottom * frame first, frames above that when needed. */ @@ -2491,6 +2563,36 @@ frame_fixed_height(frp) #ifdef FEAT_VERTSPLIT /* + * Return TRUE if width of frame "frp" should not be changed because of + * the 'winfixwidth' option. + */ + static int +frame_fixed_width(frp) + frame_T *frp; +{ + /* frame with one window: fixed width if 'winfixwidth' set. */ + if (frp->fr_win != NULL) + return frp->fr_win->w_p_wfw; + + if (frp->fr_layout == FR_COL) + { + /* The frame is fixed width if one of the frames in the row is fixed + * width. */ + for (frp = frp->fr_child; frp != NULL; frp = frp->fr_next) + if (frame_fixed_width(frp)) + return TRUE; + return FALSE; + } + + /* frp->fr_layout == FR_ROW: The frame is fixed width if all of the + * frames in the row are fixed width. */ + for (frp = frp->fr_child; frp != NULL; frp = frp->fr_next) + if (!frame_fixed_width(frp)) + return FALSE; + return TRUE; +} + +/* * Add a status line to windows at the bottom of "frp". * Note: Does not check if there is room! */ @@ -2530,10 +2632,12 @@ frame_add_statusline(frp) * May remove separator line for windows at the right side (for win_close()). */ static void -frame_new_width(topfrp, width, leftfirst) +frame_new_width(topfrp, width, leftfirst, wfw) frame_T *topfrp; int width; int leftfirst; /* resize leftmost contained frame first */ + int wfw; /* obey 'winfixwidth' when there is a choice; + may cause the width not to be set */ { frame_T *frp; int extra_cols; @@ -2554,20 +2658,45 @@ frame_new_width(topfrp, width, leftfirst } else if (topfrp->fr_layout == FR_COL) { - /* All frames in this column get the same new width. */ - for (frp = topfrp->fr_child; frp != NULL; frp = frp->fr_next) - frame_new_width(frp, width, leftfirst); + do + { + /* All frames in this column get the same new width. */ + for (frp = topfrp->fr_child; frp != NULL; frp = frp->fr_next) + { + frame_new_width(frp, width, leftfirst, wfw); + if (frp->fr_width > width) + { + /* Could not fit the windows, make whole column wider. */ + width = frp->fr_width; + break; + } + } + } while (frp != NULL); } else /* fr_layout == FR_ROW */ { /* Complicated case: Resize a row of frames. Resize the rightmost * frame first, frames left of it when needed. */ - /* Find the rightmost frame of this row */ frp = topfrp->fr_child; + if (wfw) + /* Advance past frames with one window with 'wfw' set. */ + while (frame_fixed_width(frp)) + { + frp = frp->fr_next; + if (frp == NULL) + return; /* no frame without 'wfw', give up */ + } if (!leftfirst) + { + /* Find the rightmost frame of this row */ while (frp->fr_next != NULL) frp = frp->fr_next; + if (wfw) + /* Advance back for frames with one window with 'wfw' set. */ + while (frame_fixed_width(frp)) + frp = frp->fr_prev; + } extra_cols = width - topfrp->fr_width; if (extra_cols < 0) @@ -2579,23 +2708,35 @@ frame_new_width(topfrp, width, leftfirst if (frp->fr_width + extra_cols < w) { extra_cols += frp->fr_width - w; - frame_new_width(frp, w, leftfirst); + frame_new_width(frp, w, leftfirst, wfw); } else { - frame_new_width(frp, frp->fr_width + extra_cols, leftfirst); + frame_new_width(frp, frp->fr_width + extra_cols, + leftfirst, wfw); break; } if (leftfirst) - frp = frp->fr_next; + { + do + frp = frp->fr_next; + while (wfw && frp != NULL && frame_fixed_width(frp)); + } else - frp = frp->fr_prev; + { + do + frp = frp->fr_prev; + while (wfw && frp != NULL && frame_fixed_width(frp)); + } + /* Increase "width" if we could not reduce enough frames. */ + if (frp == NULL) + width -= extra_cols; } } else if (extra_cols > 0) { /* increase width of rightmost frame */ - frame_new_width(frp, frp->fr_width + extra_cols, leftfirst); + frame_new_width(frp, frp->fr_width + extra_cols, leftfirst, wfw); } } topfrp->fr_width = width; @@ -3689,7 +3830,7 @@ win_enter_ext(wp, undo_sync, curwin_inva #ifdef FEAT_VERTSPLIT /* set window width to desired minimal value */ - if (curwin->w_width < p_wiw) + if (curwin->w_width < p_wiw && !curwin->w_p_wfw) win_setwidth((int)p_wiw); #endif @@ -4012,7 +4153,8 @@ shell_new_rows() #ifdef FEAT_WINDOWS if (h < frame_minheight(topframe, NULL)) h = frame_minheight(topframe, NULL); - /* First try setting the heights of windows without 'winfixheight'. If + + /* First try setting the heights of windows with 'winfixheight'. If * that doesn't result in the right height, forget about that option. */ frame_new_height(topframe, h, FALSE, TRUE); if (topframe->fr_height != h) @@ -4045,7 +4187,13 @@ shell_new_columns() { if (firstwin == NULL) /* not initialized yet */ return; - frame_new_width(topframe, (int)Columns, FALSE); + + /* First try setting the widths of windows with 'winfixwidth'. If that + * doesn't result in the right width, forget about that option. */ + frame_new_width(topframe, (int)Columns, FALSE, TRUE); + if (topframe->fr_width != Columns) + frame_new_width(topframe, (int)Columns, FALSE, FALSE); + (void)win_comp_pos(); /* recompute w_winrow and w_wincol */ #if 0 /* Disabled: don't want making the screen smaller make a window larger. */ @@ -4480,6 +4628,7 @@ frame_setwidth(curfrp, width) int run; frame_T *frp; int w; + int room_reserved; /* If the width already is the desired value, nothing to do. */ if (curfrp->fr_width == width) @@ -4511,9 +4660,14 @@ frame_setwidth(curfrp, width) for (run = 1; run <= 2; ++run) { room = 0; + room_reserved = 0; for (frp = curfrp->fr_parent->fr_child; frp != NULL; frp = frp->fr_next) { + if (frp != curfrp + && frp->fr_win != NULL + && frp->fr_win->w_p_wfw) + room_reserved += frp->fr_width; room += frp->fr_width; if (frp != curfrp) room -= frame_minwidth(frp, NULL); @@ -4531,17 +4685,25 @@ frame_setwidth(curfrp, width) + frame_minwidth(curfrp->fr_parent, NOWIN) - (int)p_wmw - 1); } - /* * Compute the number of lines we will take from others frames (can be * negative!). */ take = width - curfrp->fr_width; + /* If there is not enough room, also reduce the width of a window + * with 'winfixwidth' set. */ + if (width > room - room_reserved) + room_reserved = room - width; + /* If there is only a 'winfixwidth' window and making the + * window smaller, need to make the other window narrower. */ + if (take < 0 && room - curfrp->fr_width < room_reserved) + room_reserved = 0; + /* * set the current frame to the new width */ - frame_new_width(curfrp, width, FALSE); + frame_new_width(curfrp, width, FALSE, FALSE); /* * First take lines from the frames right of the current frame. If @@ -4557,15 +4719,34 @@ frame_setwidth(curfrp, width) while (frp != NULL && take != 0) { w = frame_minwidth(frp, NULL); - if (frp->fr_width - take < w) + if (room_reserved > 0 + && frp->fr_win != NULL + && frp->fr_win->w_p_wfw) { - take -= frp->fr_width - w; - frame_new_width(frp, w, FALSE); + if (room_reserved >= frp->fr_width) + room_reserved -= frp->fr_width; + else + { + if (frp->fr_width - room_reserved > take) + room_reserved = frp->fr_width - take; + take -= frp->fr_width - room_reserved; + frame_new_width(frp, room_reserved, FALSE, FALSE); + room_reserved = 0; + } } else { - frame_new_width(frp, frp->fr_width - take, FALSE); - take = 0; + if (frp->fr_width - take < w) + { + take -= frp->fr_width - w; + frame_new_width(frp, w, FALSE, FALSE); + } + else + { + frame_new_width(frp, frp->fr_width - take, + FALSE, FALSE); + take = 0; + } } if (run == 0) frp = frp->fr_next; @@ -4811,7 +4992,7 @@ win_drag_vsep_line(dragwin, offset) return; /* grow frame fr by offset lines */ - frame_new_width(fr, fr->fr_width + offset, left); + frame_new_width(fr, fr->fr_width + offset, left, FALSE); /* shrink other frames: current and at the left or at the right */ if (left) @@ -4825,11 +5006,11 @@ win_drag_vsep_line(dragwin, offset) if (fr->fr_width - offset <= n) { offset -= fr->fr_width - n; - frame_new_width(fr, n, !left); + frame_new_width(fr, n, !left, FALSE); } else { - frame_new_width(fr, fr->fr_width - offset, !left); + frame_new_width(fr, fr->fr_width - offset, !left, FALSE); break; } if (left) @@ -5762,7 +5943,7 @@ restore_snapshot_rec(sn, fr) { frame_new_height(fr, fr->fr_height, FALSE, FALSE); # ifdef FEAT_VERTSPLIT - frame_new_width(fr, fr->fr_width, FALSE); + frame_new_width(fr, fr->fr_width, FALSE, FALSE); # endif wp = sn->fr_win; }