diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/eval.c | 35 | ||||
-rw-r--r-- | src/ex_cmds.c | 14 | ||||
-rw-r--r-- | src/ex_cmds.h | 4 | ||||
-rw-r--r-- | src/ex_cmds2.c | 2 | ||||
-rw-r--r-- | src/globals.h | 9 | ||||
-rw-r--r-- | src/main.c | 102 | ||||
-rw-r--r-- | src/misc1.c | 4 | ||||
-rw-r--r-- | src/misc2.c | 10 | ||||
-rw-r--r-- | src/proto/window.pro | 2 | ||||
-rw-r--r-- | src/screen.c | 21 | ||||
-rw-r--r-- | src/search.c | 2 | ||||
-rw-r--r-- | src/structs.h | 70 | ||||
-rw-r--r-- | src/version.h | 4 |
13 files changed, 210 insertions, 69 deletions
diff --git a/src/eval.c b/src/eval.c index d29f1a4f1..8c7049be3 100644 --- a/src/eval.c +++ b/src/eval.c @@ -17258,6 +17258,7 @@ ex_function(eap) char_u *name = NULL; char_u *p; char_u *arg; + char_u *line_arg = NULL; garray_T newargs; garray_T newlines; int varargs = FALSE; @@ -17531,7 +17532,11 @@ ex_function(eap) break; } - if (*p != NUL && *p != '"' && *p != '\n' && !eap->skip && !did_emsg) + /* When there is a line break use what follows for the function body. + * Makes 'exe "func Test()\n...\nendfunc"' work. */ + if (*p == '\n') + line_arg = p + 1; + else if (*p != NUL && *p != '"' && !eap->skip && !did_emsg) EMSG(_(e_trailing)); /* @@ -17563,7 +17568,20 @@ ex_function(eap) { msg_scroll = TRUE; need_wait_return = FALSE; - if (eap->getline == NULL) + if (line_arg != NULL) + { + /* Use eap->arg, split up in parts by line breaks. */ + theline = line_arg; + p = vim_strchr(theline, '\n'); + if (p == NULL) + line_arg += STRLEN(line_arg); + else + { + *p = NUL; + line_arg = p + 1; + } + } + else if (eap->getline == NULL) theline = getcmdline(':', 0L, indent); else theline = eap->getline(':', eap->cookie, indent); @@ -17594,7 +17612,8 @@ ex_function(eap) /* Check for "endfunction". */ if (checkforcmd(&p, "endfunction", 4) && nesting-- == 0) { - vim_free(theline); + if (line_arg == NULL) + vim_free(theline); break; } @@ -17660,7 +17679,8 @@ ex_function(eap) /* Add the line to the function. */ if (ga_grow(&newlines, 1) == FAIL) { - vim_free(theline); + if (line_arg == NULL) + vim_free(theline); goto erret; } @@ -17670,12 +17690,17 @@ ex_function(eap) p = vim_strsave(theline); if (p != NULL) { - vim_free(theline); + if (line_arg == NULL) + vim_free(theline); theline = p; } ((char_u **)(newlines.ga_data))[newlines.ga_len] = theline; newlines.ga_len++; + + /* Check for end of eap->arg. */ + if (line_arg != NULL && *line_arg == NUL) + line_arg = NULL; } /* Don't define the function when skipping commands or when an error was diff --git a/src/ex_cmds.c b/src/ex_cmds.c index dff491a37..c6cdc5a50 100644 --- a/src/ex_cmds.c +++ b/src/ex_cmds.c @@ -1811,15 +1811,18 @@ write_viminfo(file, forceit) /* Use mch_open() to be able to use O_NOFOLLOW and set file * protection: - * Unix: same as original file, but strip s-bit. + * Unix: same as original file, but strip s-bit. Reset umask to + * avoid it getting in the way. * Others: r&w for user only. */ #ifdef UNIX + umask_save = umask(0); fd = mch_open((char *)tempname, O_CREAT|O_EXTRA|O_EXCL|O_WRONLY|O_NOFOLLOW, (int)((st_old.st_mode & 0777) | 0600)); + (void)umask(umask_save); #else fd = mch_open((char *)tempname, - O_CREAT|O_EXTRA|O_EXCL|O_WRONLY|O_NOFOLLOW, 0600); + O_CREAT|O_EXTRA|O_EXCL|O_WRONLY|O_NOFOLLOW, 0600); #endif if (fd < 0) fp_out = NULL; @@ -3504,8 +3507,11 @@ do_ecmd(fnum, ffname, sfname, eap, newlnum, flags) /* Tell the diff stuff that this buffer is new and/or needs updating. * Also needed when re-editing the same buffer, because unloading will * have removed it as a diff buffer. */ - diff_new_buffer(); - diff_invalidate(); + if (curwin->w_p_diff) + { + diff_buf_add(curbuf); + diff_invalidate(curbuf); + } #endif if (command == NULL) diff --git a/src/ex_cmds.h b/src/ex_cmds.h index 6571ccef3..d505bff37 100644 --- a/src/ex_cmds.h +++ b/src/ex_cmds.h @@ -880,11 +880,13 @@ EX(CMD_tags, "tags", do_tags, EX(CMD_tab, "tab", ex_tab, RANGE|NOTADR|COUNT|TRLBAR), EX(CMD_tabclose, "tabclose", ex_tabclose, - BANG|TRLBAR|CMDWIN), + RANGE|NOTADR|COUNT|BANG|TRLBAR|CMDWIN), EX(CMD_tabedit, "tabedit", ex_tabedit, BANG|FILE1|RANGE|NOTADR|EDITCMD|ARGOPT|TRLBAR), EX(CMD_tabfind, "tabfind", ex_tabedit, BANG|FILE1|RANGE|NOTADR|EDITCMD|ARGOPT|TRLBAR), +EX(CMD_tabonly, "tabonly", ex_tabonly, + TRLBAR|CMDWIN), EX(CMD_tabs, "tabs", ex_tabs, TRLBAR|CMDWIN), EX(CMD_tcl, "tcl", ex_tcl, diff --git a/src/ex_cmds2.c b/src/ex_cmds2.c index 0e671c8af..b2a9327f1 100644 --- a/src/ex_cmds2.c +++ b/src/ex_cmds2.c @@ -2232,7 +2232,7 @@ ex_listdo(eap) if (!win_valid(win)) break; win_goto(win); - win = win->w_next; + win = curwin->w_next; } #endif else if (eap->cmdidx == CMD_bufdo) diff --git a/src/globals.h b/src/globals.h index c6409b96b..0cea5c28b 100644 --- a/src/globals.h +++ b/src/globals.h @@ -507,11 +507,12 @@ EXTERN frame_T *topframe; /* top of the window frame tree */ #ifdef FEAT_WINDOWS /* - * Tab pages are nothing more than alternative topframes. "first_tabpage" - * points to the first one in the list, "topframe" is the current one. + * Tab pages are alternative topframes. "first_tabpage" points to the first + * one in the list, "curtab" is the current one. */ -EXTERN tabpage_T *first_tabpage; -EXTERN int redraw_tabpage INIT(= FALSE); /* redraw tab pages line */ +EXTERN tabpage_T *first_tabpage; +EXTERN tabpage_T *curtab; +EXTERN int redraw_tabline INIT(= FALSE); /* need to redraw tabline */ #endif /* diff --git a/src/main.c b/src/main.c index 1a71be908..31c6f6fba 100644 --- a/src/main.c +++ b/src/main.c @@ -32,6 +32,11 @@ /* Maximum number of commands from + or -c arguments. */ #define MAX_ARG_CMDS 10 +/* values for "window_layout" */ +#define WIN_HOR 1 /* "-o" horizontally split windows */ +#define WIN_VER 2 /* "-O" vertically split windows */ +#define WIN_TABS 3 /* "-p" windows on tab pages */ + /* Struct for various parameters passed between main() and other functions. */ typedef struct { @@ -65,7 +70,7 @@ typedef struct #endif #ifdef FEAT_WINDOWS int window_count; /* number of windows to use */ - int vert_windows; /* "-O" used instead of "-o" */ + int window_layout; /* 0, WIN_HOR, WIN_VER or WIN_TABS */ #endif #ifdef FEAT_CLIENTSERVER @@ -189,7 +194,6 @@ main #endif #ifdef FEAT_WINDOWS params.window_count = -1; - params.vert_windows = MAYBE; #endif #ifdef FEAT_TCL @@ -416,8 +420,8 @@ main { if (params.window_count == -1) params.window_count = 0; /* open up to 3 windows */ - if (params.vert_windows == MAYBE) - params.vert_windows = TRUE; /* use vertical split */ + if (params.window_layout == 0) + params.window_layout = WIN_VER; /* use vertical split */ } #endif @@ -1738,12 +1742,21 @@ command_line_scan(parmp) parmp->no_swap_file = TRUE; break; + case 'p': /* "-p[N]" open N tab pages */ +#ifdef FEAT_WINDOWS + /* default is 0: open window for each file */ + parmp->window_count = get_number_arg((char_u *)argv[0], + &argv_idx, 0); + parmp->window_layout = WIN_TABS; +#endif + break; + case 'o': /* "-o[N]" open N horizontal split windows */ #ifdef FEAT_WINDOWS /* default is 0: open window for each file */ parmp->window_count = get_number_arg((char_u *)argv[0], &argv_idx, 0); - parmp->vert_windows = FALSE; + parmp->window_layout = WIN_HOR; #endif break; @@ -1752,7 +1765,7 @@ command_line_scan(parmp) /* default is 0: open window for each file */ parmp->window_count = get_number_arg((char_u *)argv[0], &argv_idx, 0); - parmp->vert_windows = TRUE; + parmp->window_layout = WIN_VER; #endif break; @@ -2235,6 +2248,9 @@ create_windows(parmp) mparm_T *parmp; { #ifdef FEAT_WINDOWS + int rewind; + int done = 0; + /* * Create the number of windows that was requested. */ @@ -2246,12 +2262,17 @@ create_windows(parmp) { /* Don't change the windows if there was a command in .vimrc that * already split some windows */ - if (parmp->vert_windows == MAYBE) - parmp->vert_windows = FALSE; - if (firstwin->w_next == NULL) + if (parmp->window_layout == 0) + parmp->window_layout = WIN_HOR; + if (parmp->window_layout == WIN_TABS) + { + parmp->window_count = make_tabpages(parmp->window_count); + TIME_MSG("making tab pages"); + } + else if (firstwin->w_next == NULL) { parmp->window_count = make_windows(parmp->window_count, - parmp->vert_windows); + parmp->window_layout == WIN_VER); TIME_MSG("making windows"); } else @@ -2284,9 +2305,30 @@ create_windows(parmp) ++autocmd_no_leave; #endif #ifdef FEAT_WINDOWS - for (curwin = firstwin; curwin != NULL; curwin = W_NEXT(curwin)) -#endif + rewind = TRUE; + while (done++ < 1000) { + if (rewind) + { + if (parmp->window_layout == WIN_TABS) + goto_tabpage(1); + else + curwin = firstwin; + } + else if (parmp->window_layout == WIN_TABS) + { + if (curtab->tp_next == NULL) + break; + goto_tabpage(0); + } + else + { + if (curwin->w_next == NULL) + break; + curwin = curwin->w_next; + } + rewind = FALSE; +#endif curbuf = curwin->w_buffer; if (curbuf->b_ml.ml_mfp == NULL) { @@ -2306,7 +2348,7 @@ create_windows(parmp) check_swap_exists_action(); #endif #ifdef FEAT_AUTOCMD - curwin = firstwin; /* start again */ + rewind = TRUE; /* start again */ #endif } #ifdef FEAT_WINDOWS @@ -2316,16 +2358,19 @@ create_windows(parmp) (void)vgetc(); /* only break the file loading, not the rest */ break; } -#endif } -#ifdef FEAT_AUTOCMD - --autocmd_no_enter; - --autocmd_no_leave; #endif #ifdef FEAT_WINDOWS - curwin = firstwin; + if (parmp->window_layout == WIN_TABS) + goto_tabpage(1); + else + curwin = firstwin; curbuf = curwin->w_buffer; #endif +#ifdef FEAT_AUTOCMD + --autocmd_no_enter; + --autocmd_no_leave; +#endif } } @@ -2351,9 +2396,18 @@ edit_buffers(parmp) arg_idx = 1; for (i = 1; i < parmp->window_count; ++i) { - if (curwin->w_next == NULL) /* just checking */ - break; - win_enter(curwin->w_next, FALSE); + if (parmp->window_layout == WIN_TABS) + { + if (curtab->tp_next == NULL) /* just checking */ + break; + goto_tabpage(0); + } + else + { + if (curwin->w_next == NULL) /* just checking */ + break; + win_enter(curwin->w_next, FALSE); + } /* Only open the file if there is no file in this window yet (that can * happen when .vimrc contains ":sall") */ @@ -2375,6 +2429,9 @@ edit_buffers(parmp) break; } } + + if (parmp->window_layout == WIN_TABS) + goto_tabpage(1); # ifdef FEAT_AUTOCMD --autocmd_no_enter; # endif @@ -2383,7 +2440,7 @@ edit_buffers(parmp) --autocmd_no_leave; # endif TIME_MSG("editing files in windows"); - if (parmp->window_count > 1) + if (parmp->window_count > 1 && parmp->window_layout != WIN_TABS) win_equal(curwin, FALSE, 'b'); /* adjust heights */ } #endif /* FEAT_WINDOWS */ @@ -2825,6 +2882,7 @@ usage() main_msg(_("-U <gvimrc>\t\tUse <gvimrc> instead of any .gvimrc")); #endif main_msg(_("--noplugin\t\tDon't load plugin scripts")); + main_msg(_("-p[N]\t\tOpen N tab pages (default: one for each file)")); main_msg(_("-o[N]\t\tOpen N windows (default: one for each file)")); main_msg(_("-O[N]\t\tLike -o but split vertically")); main_msg(_("+\t\t\tStart at end of file")); diff --git a/src/misc1.c b/src/misc1.c index fc56c913a..bcc43dafb 100644 --- a/src/misc1.c +++ b/src/misc1.c @@ -2458,7 +2458,7 @@ changed() ml_setflags(curbuf); #ifdef FEAT_WINDOWS check_status(curbuf); - redraw_tabpage = TRUE; + redraw_tabline = TRUE; #endif #ifdef FEAT_TITLE need_maketitle = TRUE; /* set window title later */ @@ -2848,7 +2848,7 @@ unchanged(buf, ff) save_file_ff(buf); #ifdef FEAT_WINDOWS check_status(buf); - redraw_tabpage = TRUE; + redraw_tabline = TRUE; #endif #ifdef FEAT_TITLE need_maketitle = TRUE; /* set window title later */ diff --git a/src/misc2.c b/src/misc2.c index 2ff4d5c58..680202f1c 100644 --- a/src/misc2.c +++ b/src/misc2.c @@ -962,6 +962,12 @@ free_all_mem() ++autocmd_block; /* don't want to trigger autocommands here */ +#ifdef FEAT_WINDOWS + /* close all tabs and windows */ + do_cmdline_cmd((char_u *)"tabonly!"); + do_cmdline_cmd((char_u *)"only!"); +#endif + # if defined(FEAT_SYN_HL) /* Free all spell info. */ spell_free_all(); @@ -1012,7 +1018,7 @@ free_all_mem() free_tag_stuff(); free_cd_dir(); set_expr_line(NULL); - diff_clear(); + diff_clear(curtab); clear_sb_text(); /* free any scrollback text */ /* Free some global vars. */ @@ -2792,7 +2798,7 @@ set_fileformat(t, opt_flags) #ifdef FEAT_WINDOWS /* This may cause the buffer to become (un)modified. */ check_status(curbuf); - redraw_tabpage = TRUE; + redraw_tabline = TRUE; #endif #ifdef FEAT_TITLE need_maketitle = TRUE; /* set window title later */ diff --git a/src/proto/window.pro b/src/proto/window.pro index ae6aa636f..7fa357270 100644 --- a/src/proto/window.pro +++ b/src/proto/window.pro @@ -7,7 +7,6 @@ int make_windows __ARGS((int count, int vertical)); void win_move_after __ARGS((win_T *win1, win_T *win2)); void win_equal __ARGS((win_T *next_curwin, int current, int dir)); void close_windows __ARGS((buf_T *buf, int keep_curwin)); -int last_window __ARGS((void)); void win_close __ARGS((win_T *win, int free_buf)); void win_close_othertab __ARGS((win_T *win, int free_buf, tabpage_T *tp)); void win_free_all __ARGS((void)); @@ -16,6 +15,7 @@ void win_init __ARGS((win_T *wp)); int win_alloc_first __ARGS((void)); void win_init_size __ARGS((void)); int win_new_tabpage __ARGS((void)); +int make_tabpages __ARGS((int maxcount)); int valid_tabpage __ARGS((tabpage_T *tpc)); tabpage_T *find_tabpage __ARGS((int n)); void goto_tabpage __ARGS((int n)); diff --git a/src/screen.c b/src/screen.c index f9ed5e17e..928b1b01b 100644 --- a/src/screen.c +++ b/src/screen.c @@ -394,7 +394,7 @@ update_screen(type) } redraw_cmdline = TRUE; #ifdef FEAT_WINDOWS - redraw_tabpage = TRUE; + redraw_tabline = TRUE; #endif } msg_scrolled = 0; @@ -476,7 +476,7 @@ update_screen(type) #ifdef FEAT_WINDOWS /* Redraw the tab pages line if needed. */ - if (redraw_tabpage || type >= NOT_VALID) + if (redraw_tabline || type >= NOT_VALID) draw_tabpage(); #endif @@ -706,7 +706,7 @@ updateWindow(wp) #ifdef FEAT_WINDOWS /* When the screen was cleared redraw the tab pages line. */ - if (redraw_tabpage) + if (redraw_tabline) draw_tabpage(); if (wp->w_redr_status @@ -4965,7 +4965,7 @@ redraw_statuslines() for (wp = firstwin; wp; wp = wp->w_next) if (wp->w_redr_status) win_redr_status(wp); - if (redraw_tabpage) + if (redraw_tabline) draw_tabpage(); } #endif @@ -7084,7 +7084,7 @@ screenclear2() win_rest_invalid(firstwin); redraw_cmdline = TRUE; #ifdef FEAT_WINDOWS - redraw_tabpage = TRUE; + redraw_tabline = TRUE; #endif if (must_redraw == CLEAR) /* no need to clear again */ must_redraw = NOT_VALID; @@ -8463,7 +8463,7 @@ draw_tabpage() tabpage_T *tp; int tabwidth; int col = 0; - int scol; + int scol = 0; int had_current = FALSE; int attr; win_T *wp; @@ -8475,8 +8475,9 @@ draw_tabpage() int attr_sel = hl_attr(HLF_TPS); int attr_nosel = hl_attr(HLF_TP); int attr_fill = hl_attr(HLF_TPF); + char_u *p; - redraw_tabpage = FALSE; + redraw_tabline = FALSE; if (tabpageline_height() < 1) return; @@ -8548,11 +8549,15 @@ draw_tabpage() MAXPATHL, TRUE); trans_characters(NameBuff, MAXPATHL); len = STRLEN(NameBuff); + p = NameBuff; if (len > scol - col + tabwidth - 1) /* TODO: multi-byte chars */ + { + p += len - (scol - col + tabwidth - 1); len = scol - col + tabwidth - 1; + } if (len > 0) { - screen_puts_len(NameBuff, len, 0, col, attr); + screen_puts_len(p, len, 0, col, attr); col += len; } screen_putchar(' ', 0, col++, attr); diff --git a/src/search.c b/src/search.c index 5531fb6c0..d50634465 100644 --- a/src/search.c +++ b/src/search.c @@ -4938,7 +4938,7 @@ search_line: #if defined(FEAT_WINDOWS) && defined(FEAT_QUICKFIX) if (g_do_tagpreview != 0 - && curwin != curwin_save && win_valid(curwin_save)) + && curwin != curwin_save && win_valid(curwin_save)) { /* Return cursor to where we were */ validate_cursor(); diff --git a/src/structs.h b/src/structs.h index 6153099e6..fac17856d 100644 --- a/src/structs.h +++ b/src/structs.h @@ -1526,6 +1526,60 @@ struct file_buffer }; + +#ifdef FEAT_DIFF +/* + * Stuff for diff mode. + */ +# define DB_COUNT 4 /* up to four buffers can be diff'ed */ + +/* + * Each diffblock defines where a block of lines starts in each of the buffers + * and how many lines it occupies in that buffer. When the lines are missing + * in the buffer the df_count[] is zero. This is all counted in + * buffer lines. + * There is always at least one unchanged line in between the diffs. + * Otherwise it would have been included in the diff above or below it. + * df_lnum[] + df_count[] is the lnum below the change. When in one buffer + * lines have been inserted, in the other buffer df_lnum[] is the line below + * the insertion and df_count[] is zero. When appending lines at the end of + * the buffer, df_lnum[] is one beyond the end! + * This is using a linked list, because the number of differences is expected + * to be reasonable small. The list is sorted on lnum. + */ +typedef struct diffblock_S diff_T; +struct diffblock_S +{ + diff_T *df_next; + linenr_T df_lnum[DB_COUNT]; /* line number in buffer */ + linenr_T df_count[DB_COUNT]; /* nr of inserted/changed lines */ +}; +#endif + +/* + * Tab pages point to the top frame of each tab page. + * Note: Most values are NOT valid for the current tab page! Use "curwin", + * "firstwin", etc. for that. "tp_topframe" is always valid and can be + * compared against "topframe" to find the current tab page. + */ +typedef struct tabpage_S tabpage_T; +struct tabpage_S +{ + tabpage_T *tp_next; /* next tabpage or NULL */ + frame_T *tp_topframe; /* topframe for the windows */ + win_T *tp_curwin; /* current window in this Tab page */ + win_T *tp_prevwin; /* previous window in this Tab page */ + win_T *tp_firstwin; /* first window in this Tab page */ + win_T *tp_lastwin; /* last window in this Tab page */ + long tp_old_Rows; /* Rows when Tab page was left */ + long tp_old_Columns; /* Columns when Tab page was left */ +#ifdef FEAT_DIFF + diff_T *tp_first_diff; + buf_T *(tp_diffbuf[DB_COUNT]); + int tp_diff_invalid; /* list of diffs is outdated */ +#endif +}; + /* * Structure to cache info for displayed lines in w_lines[]. * Each logical line has one entry. @@ -1550,22 +1604,6 @@ typedef struct w_line } wline_T; /* - * Tab pages point to the top frame of each tab page. - */ -typedef struct tabpage_S tabpage_T; -struct tabpage_S -{ - tabpage_T *tp_next; /* next tabpage or NULL */ - frame_T *tp_topframe; /* topframe for the windows */ - win_T *tp_curwin; /* current window in this Tab page */ - win_T *tp_prevwin; /* previous window in this Tab page */ - win_T *tp_firstwin; /* first window in this Tab page */ - win_T *tp_lastwin; /* last window in this Tab page */ - long tp_old_Rows; /* Rows when Tab page was left */ - long tp_old_Columns; /* Columns when Tab page was left */ -}; - -/* * Windows are kept in a tree of frames. Each frame has a column (FR_COL) * or row (FR_ROW) layout or is a leaf, which has a window. */ diff --git a/src/version.h b/src/version.h index b00a9a1c0..80a3f61a4 100644 --- a/src/version.h +++ b/src/version.h @@ -36,5 +36,5 @@ #define VIM_VERSION_NODOT "vim70aa" #define VIM_VERSION_SHORT "7.0aa" #define VIM_VERSION_MEDIUM "7.0aa ALPHA" -#define VIM_VERSION_LONG "VIM - Vi IMproved 7.0aa ALPHA (2006 Feb 16)" -#define VIM_VERSION_LONG_DATE "VIM - Vi IMproved 7.0aa ALPHA (2006 Feb 16, compiled " +#define VIM_VERSION_LONG "VIM - Vi IMproved 7.0aa ALPHA (2006 Feb 17)" +#define VIM_VERSION_LONG_DATE "VIM - Vi IMproved 7.0aa ALPHA (2006 Feb 17, compiled " |