diff --git a/runtime/doc/autocmd.txt b/runtime/doc/autocmd.txt index 836f7d2128..14d64ed9b5 100644 --- a/runtime/doc/autocmd.txt +++ b/runtime/doc/autocmd.txt @@ -335,6 +335,8 @@ BufDelete Before deleting a buffer from the buffer list. NOTE: When this autocommand is executed, the current buffer "%" may be different from the buffer being deleted "" and "". + Don't change to another buffer, it will cause + problems. *BufEnter* BufEnter After entering a buffer. Useful for setting options for a file type. Also executed when @@ -397,6 +399,8 @@ BufUnload Before unloading a buffer. This is when the NOTE: When this autocommand is executed, the current buffer "%" may be different from the buffer being unloaded "". + Don't change to another buffer, it will cause + problems. *BufWinEnter* BufWinEnter After a buffer is displayed in a window. This can be when the buffer is loaded (after @@ -428,6 +432,8 @@ BufWipeout Before completely deleting a buffer. The NOTE: When this autocommand is executed, the current buffer "%" may be different from the buffer being deleted "". + Don't change to another buffer, it will cause + problems. *BufWrite* *BufWritePre* BufWrite or BufWritePre Before writing the whole buffer to a file. *BufWriteCmd* @@ -748,8 +754,10 @@ SwapExists Detected an existing swap file when starting 'a' abort, like hitting CTRL-C When set to an empty string the user will be asked, as if there was no SwapExists autocmd. - Note: Do not try to change the buffer, the - results are unpredictable. + *E812* + It is not allowed to change to another buffer, + change a buffer name or change directory + here. *Syntax* Syntax When the 'syntax' option has been set. The pattern is matched against the syntax name. diff --git a/runtime/doc/if_cscop.txt b/runtime/doc/if_cscop.txt index 94d3978203..3d98e4a185 100644 --- a/runtime/doc/if_cscop.txt +++ b/runtime/doc/if_cscop.txt @@ -355,13 +355,8 @@ cscope version for Win32 see: The DJGPP-built version from http://cscope.sourceforge.net is known to not work with Vim. -There are a couple of hard-coded limitations: - - 1. The maximum number of cscope connections allowed is 8. Do you - really need more? - - 2. Doing a |:tjump| when |:cstag| searches the tag files is not - configurable (e.g., you can't do a tselect instead). +Hard-coded limitation: doing a |:tjump| when |:cstag| searches the tag files +is not configurable (e.g., you can't do a tselect instead). ============================================================================== 6. Suggested usage *cscope-suggestions* diff --git a/runtime/doc/if_mzsch.txt b/runtime/doc/if_mzsch.txt index d225444198..ceecdba302 100644 --- a/runtime/doc/if_mzsch.txt +++ b/runtime/doc/if_mzsch.txt @@ -1,4 +1,4 @@ -*if_mzsch.txt* For Vim version 7.2. Last change: 2009 May 26 +*if_mzsch.txt* For Vim version 7.2. Last change: 2009 Jun 24 VIM REFERENCE MANUAL by Sergey Khorev @@ -231,7 +231,7 @@ Windows *mzscheme-window* (set-cursor (line . col) [window]) Set cursor position. ============================================================================== -5. Dynamic loading *mzscheme-dynamic* *E812* +5. Dynamic loading *mzscheme-dynamic* *E815* On MS-Windows the MzScheme libraries can be loaded dynamically. The |:version| output then includes |+mzscheme/dyn|. diff --git a/runtime/doc/various.txt b/runtime/doc/various.txt index 08cc5789e7..bbf345bf9b 100644 --- a/runtime/doc/various.txt +++ b/runtime/doc/various.txt @@ -511,6 +511,17 @@ N *+X11* Unix only: can restore window title |X11| messages though. Use ":silent" in the command itself to avoid that: ":silent menu .... :silent command". + *:uns* *:unsilent* +:uns[ilent] {command} Execute {command} not silently. Only makes a + difference when |:silent| was used to get to this + command. + Use this for giving a message even when |:silent| was + used. In this example |:silent| is used to avoid the + message about reading the file and |:unsilent| to be + able to list the first line of each file. > + :silent argdo unsilent echo expand('%') . ": " . getline(1) +< + *:verb* *:verbose* :[count]verb[ose] {command} Execute {command} with 'verbose' set to [count]. If diff --git a/src/edit.c b/src/edit.c index c1935c21cc..347571f478 100644 --- a/src/edit.c +++ b/src/edit.c @@ -114,6 +114,10 @@ static int compl_restarting = FALSE; /* don't insert match */ * FALSE the word to be completed must be located. */ static int compl_started = FALSE; +/* Set when doing something for completion that may call edit() recursively, + * which is not allowed. */ +static int compl_busy = FALSE; + static int compl_matches = 0; static char_u *compl_pattern = NULL; static int compl_direction = FORWARD; @@ -346,7 +350,7 @@ edit(cmdchar, startln, count) #ifdef FEAT_INS_EXPAND /* Don't allow recursive insert mode when busy with completion. */ - if (compl_started || pum_visible()) + if (compl_started || compl_busy || pum_visible()) { EMSG(_(e_secure)); return FALSE; @@ -1340,8 +1344,10 @@ doESCkey: goto normalchar; docomplete: + compl_busy = TRUE; if (ins_complete(c) == FAIL) compl_cont_status = 0; + compl_busy = FALSE; break; #endif /* FEAT_INS_EXPAND */ @@ -3172,6 +3178,7 @@ ins_compl_free() vim_free(match); } while (compl_curr_match != NULL && compl_curr_match != compl_first_match); compl_first_match = compl_curr_match = NULL; + compl_shown_match = NULL; } static void diff --git a/src/ex_cmds.c b/src/ex_cmds.c index fabb2e76a2..68627a578b 100644 --- a/src/ex_cmds.c +++ b/src/ex_cmds.c @@ -4013,6 +4013,9 @@ ex_change(eap) break; ml_delete(eap->line1, FALSE); } + + /* make sure the cursor is not beyond the end of the file now */ + check_cursor_lnum(); deleted_lines_mark(eap->line1, (long)(eap->line2 - lnum)); /* ":append" on the line above the deleted lines. */ diff --git a/src/ex_cmds.h b/src/ex_cmds.h index 313d3940be..2c58bf4747 100644 --- a/src/ex_cmds.h +++ b/src/ex_cmds.h @@ -995,6 +995,8 @@ EX(CMD_unmap, "unmap", ex_unmap, BANG|EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN), EX(CMD_unmenu, "unmenu", ex_menu, BANG|EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN), +EX(CMD_unsilent, "unsilent", ex_wrongmodifier, + NEEDARG|EXTRA|NOTRLCOM|SBOXOK|CMDWIN), EX(CMD_update, "update", ex_update, RANGE|WHOLEFOLD|BANG|FILE1|ARGOPT|DFLALL|TRLBAR), EX(CMD_vglobal, "vglobal", ex_global, diff --git a/src/ex_docmd.c b/src/ex_docmd.c index 9ff3536d12..066c6e8e40 100644 --- a/src/ex_docmd.c +++ b/src/ex_docmd.c @@ -1684,8 +1684,8 @@ do_one_cmd(cmdlinep, sourcing, char_u *errormsg = NULL; /* error message */ exarg_T ea; /* Ex command arguments */ long verbose_save = -1; - int save_msg_scroll = 0; - int did_silent = 0; + int save_msg_scroll = msg_scroll; + int save_msg_silent = -1; int did_esilent = 0; #ifdef HAVE_SANDBOX int did_sandbox = FALSE; @@ -1863,9 +1863,9 @@ do_one_cmd(cmdlinep, sourcing, } if (!checkforcmd(&ea.cmd, "silent", 3)) break; - ++did_silent; + if (save_msg_silent == -1) + save_msg_silent = msg_silent; ++msg_silent; - save_msg_scroll = msg_scroll; if (*ea.cmd == '!' && !vim_iswhite(ea.cmd[-1])) { /* ":silent!", but not "silent !cmd" */ @@ -1893,6 +1893,13 @@ do_one_cmd(cmdlinep, sourcing, #endif continue; + case 'u': if (!checkforcmd(&ea.cmd, "unsilent", 3)) + break; + if (save_msg_silent == -1) + save_msg_silent = msg_silent; + msg_silent = 0; + continue; + case 'v': if (checkforcmd(&ea.cmd, "vertical", 4)) { #ifdef FEAT_VERTSPLIT @@ -2691,13 +2698,12 @@ doend: cmdmod = save_cmdmod; - if (did_silent > 0) + if (save_msg_silent != -1) { /* messages could be enabled for a serious error, need to check if the * counters don't become negative */ - msg_silent -= did_silent; - if (msg_silent < 0) - msg_silent = 0; + if (!did_emsg) + msg_silent = save_msg_silent; emsg_silent -= did_esilent; if (emsg_silent < 0) emsg_silent = 0; @@ -2994,6 +3000,7 @@ static struct cmdmod {"silent", 3, FALSE}, {"tab", 3, TRUE}, {"topleft", 2, FALSE}, + {"unsilent", 3, FALSE}, {"verbose", 4, TRUE}, {"vertical", 4, FALSE}, }; @@ -7858,10 +7865,10 @@ ex_read(eap) if (*ml_get(lnum) == NUL && u_savedel(lnum, 1L) == OK) { ml_delete(lnum, FALSE); - deleted_lines_mark(lnum, 1L); if (curwin->w_cursor.lnum > 1 && curwin->w_cursor.lnum >= lnum) --curwin->w_cursor.lnum; + deleted_lines_mark(lnum, 1L); } } redraw_curbuf_later(VALID); @@ -7977,7 +7984,7 @@ ex_cd(eap) shorten_fnames(TRUE); /* Echo the new current directory if the command was typed. */ - if (KeyTyped) + if (KeyTyped || p_verbose >= 5) ex_pwd(eap); } vim_free(tofree); @@ -8706,6 +8713,8 @@ ex_mkrc(eap) } #ifdef FEAT_SESSION + /* Use the short file name until ":lcd" is used. We also don't use the + * short file name when 'acd' is set, that is checked later. */ did_lcd = FALSE; /* ":mkview" or ":mkview 9": generate file name with 'viewdir' */ @@ -10601,6 +10610,9 @@ ses_fname(fd, buf, flagp) if (buf->b_sfname != NULL && flagp == &ssop_flags && (ssop_flags & (SSOP_CURDIR | SSOP_SESDIR)) +#ifdef FEAT_AUTOCHDIR + && !p_acd +#endif && !did_lcd) name = buf->b_sfname; else diff --git a/src/ex_getln.c b/src/ex_getln.c index fb4e7728af..71b65db318 100644 --- a/src/ex_getln.c +++ b/src/ex_getln.c @@ -4877,14 +4877,14 @@ ExpandUserList(xp, num_file, file) /* Loop over the items in the list. */ for (li = retlist->lv_first; li != NULL; li = li->li_next) { - if (li->li_tv.v_type != VAR_STRING) - continue; /* Skip non-string items */ + if (li->li_tv.v_type != VAR_STRING || li->li_tv.vval.v_string == NULL) + continue; /* Skip non-string items and empty strings */ if (ga_grow(&ga, 1) == FAIL) break; ((char_u **)ga.ga_data)[ga.ga_len] = - vim_strsave(li->li_tv.vval.v_string); + vim_strsave(li->li_tv.vval.v_string); ++ga.ga_len; } list_unref(retlist); diff --git a/src/fileio.c b/src/fileio.c index 442327f082..6421f7192d 100644 --- a/src/fileio.c +++ b/src/fileio.c @@ -710,7 +710,8 @@ readfile(fname, sfname, from, lines_to_skip, lines_to_read, eap, flags) #endif #ifdef UNIX /* Set swap file protection bits after creating it. */ - if (swap_mode > 0 && curbuf->b_ml.ml_mfp->mf_fname != NULL) + if (swap_mode > 0 && curbuf->b_ml.ml_mfp != NULL + && curbuf->b_ml.ml_mfp->mf_fname != NULL) (void)mch_setperm(curbuf->b_ml.ml_mfp->mf_fname, (long)swap_mode); #endif } @@ -6641,7 +6642,10 @@ buf_check_timestamp(buf, focus) mesg = _("W16: Warning: Mode of file \"%s\" has changed since editing started"); mesg2 = _("See \":help W16\" for more info."); } - /* Else: only timestamp changed, ignored */ + else + /* Only timestamp changed, store it to avoid a warning + * in check_mtime() later. */ + buf->b_mtime_read = buf->b_mtime; } } } @@ -8470,25 +8474,23 @@ aucmd_prepbuf(aco, buf) * effects, insert it in a the current tab page. * Anything related to a window (e.g., setting folds) may have * unexpected results. */ - curwin = aucmd_win; - curwin->w_buffer = buf; + aucmd_win->w_buffer = buf; ++buf->b_nwindows; + win_init_empty(aucmd_win); /* set cursor and topline to safe values */ #ifdef FEAT_WINDOWS - /* Split the current window, put the aucmd_win in the upper half. */ + /* Split the current window, put the aucmd_win in the upper half. + * We don't want the BufEnter or WinEnter autocommands. */ + block_autocmds(); make_snapshot(SNAP_AUCMD_IDX); save_ea = p_ea; p_ea = FALSE; (void)win_split_ins(0, WSP_TOP, aucmd_win, 0); (void)win_comp_pos(); /* recompute window positions */ p_ea = save_ea; + unblock_autocmds(); #endif - /* set cursor and topline to safe values */ - curwin_init(); -#ifdef FEAT_VERTSPLIT - curwin->w_wincol = 0; - curwin->w_width = Columns; -#endif + curwin = aucmd_win; } curbuf = buf; aco->new_curwin = curwin; @@ -8513,7 +8515,8 @@ aucmd_restbuf(aco) --curbuf->b_nwindows; #ifdef FEAT_WINDOWS /* Find "aucmd_win", it can't be closed, but it may be in another tab - * page. */ + * page. Do not trigger autocommands here. */ + block_autocmds(); if (curwin != aucmd_win) { tabpage_T *tp; @@ -8537,6 +8540,7 @@ aucmd_restbuf(aco) last_status(FALSE); /* may need to remove last status line */ restore_snapshot(SNAP_AUCMD_IDX, FALSE); (void)win_comp_pos(); /* recompute window positions */ + unblock_autocmds(); if (win_valid(aco->save_curwin)) curwin = aco->save_curwin; diff --git a/src/getchar.c b/src/getchar.c index 0947f35feb..e050601cfc 100644 --- a/src/getchar.c +++ b/src/getchar.c @@ -1309,6 +1309,9 @@ save_typebuf() return OK; } +static int old_char = -1; /* character put back by vungetc() */ +static int old_mod_mask; /* mod_mask for ungotten character */ + #if defined(FEAT_EVAL) || defined(FEAT_EX_EXTRA) || defined(PROTO) /* @@ -1323,6 +1326,10 @@ save_typeahead(tp) if (!tp->typebuf_valid) typebuf = tp->save_typebuf; + tp->old_char = old_char; + tp->old_mod_mask = old_mod_mask; + old_char = -1; + tp->save_stuffbuff = stuffbuff; stuffbuff.bh_first.b_next = NULL; # ifdef USE_INPUT_BUF @@ -1344,6 +1351,9 @@ restore_typeahead(tp) typebuf = tp->save_typebuf; } + old_char = tp->old_char; + old_mod_mask = tp->old_mod_mask; + free_buff(&stuffbuff); stuffbuff = tp->save_stuffbuff; # ifdef USE_INPUT_BUF @@ -1499,9 +1509,6 @@ updatescript(c) #define KL_PART_KEY -1 /* keylen value for incomplete key-code */ #define KL_PART_MAP -2 /* keylen value for incomplete mapping */ -static int old_char = -1; /* character put back by vungetc() */ -static int old_mod_mask; /* mod_mask for ungotten character */ - /* * Get the next input character. * Can return a special key or a multi-byte character. diff --git a/src/gui.c b/src/gui.c index 9c35c57e77..e0a8380d36 100644 --- a/src/gui.c +++ b/src/gui.c @@ -975,7 +975,7 @@ gui_update_cursor(force, clear_selection) guicolor_T fg, bg; if ( -# ifdef HAVE_GTK2 +# if defined(HAVE_GTK2) && !defined(FEAT_HANGULIN) preedit_get_status() # else im_get_status() diff --git a/src/gui_gtk_x11.c b/src/gui_gtk_x11.c index 29ab9a7991..33fdaed485 100644 --- a/src/gui_gtk_x11.c +++ b/src/gui_gtk_x11.c @@ -6717,8 +6717,6 @@ clip_mch_request_selection(VimClipboard *cbd) { GdkAtom target; unsigned i; - int nbytes; - char_u *buffer; time_t start; for (i = 0; i < N_SELECTION_TARGETS; ++i) @@ -6746,22 +6744,7 @@ clip_mch_request_selection(VimClipboard *cbd) } /* Final fallback position - use the X CUT_BUFFER0 store */ - nbytes = 0; - buffer = (char_u *)XFetchBuffer(GDK_WINDOW_XDISPLAY(gui.mainwin->window), - &nbytes, 0); - if (nbytes > 0) - { - /* Got something */ - clip_yank_selection(MCHAR, buffer, (long)nbytes, cbd); - if (p_verbose > 0) - { - verbose_enter(); - smsg((char_u *)_("Used CUT_BUFFER0 instead of empty selection")); - verbose_leave(); - } - } - if (buffer != NULL) - XFree(buffer); + yank_cut_buffer0(GDK_WINDOW_XDISPLAY(gui.mainwin->window), cbd); } /* diff --git a/src/gui_photon.c b/src/gui_photon.c index a8ee1c4098..42b124281a 100644 --- a/src/gui_photon.c +++ b/src/gui_photon.c @@ -838,7 +838,12 @@ gui_ph_handle_window_open( static void gui_ph_draw_start( void ) { + PhGC_t *gc; + + gc = PgGetGC(); PgSetRegion( PtWidgetRid( PtFindDisjoint( gui.vimTextArea ) ) ); + PgClearClippingsCx( gc ); + PgClearTranslationCx( gc ); PtWidgetOffset( gui.vimTextArea, &gui_ph_raw_offset ); PhTranslatePoint( &gui_ph_raw_offset, PtWidgetPos( gui.vimTextArea, NULL ) ); @@ -2970,7 +2975,7 @@ gui_mch_init_font(char_u *vim_font_name, int fontset) if( vim_font_name == NULL ) { /* Default font */ - vim_font_name = "PC Term"; + vim_font_name = "PC Terminal"; } if( STRCMP( vim_font_name, "*" ) == 0 ) diff --git a/src/if_cscope.c b/src/if_cscope.c index c11fc2acbe..bd90eca876 100644 --- a/src/if_cscope.c +++ b/src/if_cscope.c @@ -46,7 +46,6 @@ static void cs_fill_results __ARGS((char *, int , int *, char ***, static int cs_find __ARGS((exarg_T *eap)); static int cs_find_common __ARGS((char *opt, char *pat, int, int, int)); static int cs_help __ARGS((exarg_T *eap)); -static void cs_init __ARGS((void)); static void clear_csinfo __ARGS((int i)); static int cs_insert_filelist __ARGS((char *, char *, char *, struct stat *)); @@ -66,7 +65,10 @@ static char * cs_resolve_file __ARGS((int, char *)); static int cs_show __ARGS((exarg_T *eap)); -static csinfo_T csinfo[CSCOPE_MAX_CONNECTIONS]; +static csinfo_T * csinfo = NULL; +static int csinfo_size = 0; /* number of items allocated in + csinfo[] */ + static int eap_arg_len; /* length of eap->arg, set in cs_lookup_cmd() */ static cscmd_T cs_cmds[] = @@ -144,23 +146,20 @@ get_cscope_name(xp, idx) } case EXP_CSCOPE_KILL: { - static char_u connection[2]; + static char connection[5]; /* ":cscope kill" accepts connection numbers or partial names of * the pathname of the cscope database as argument. Only complete * with connection numbers. -1 can also be used to kill all * connections. */ - for (i = 0, current_idx = 0; i < CSCOPE_MAX_CONNECTIONS; i++) + for (i = 0, current_idx = 0; i < csinfo_size; i++) { if (csinfo[i].fname == NULL) continue; if (current_idx++ == idx) { - /* Connection number fits in one character since - * CSCOPE_MAX_CONNECTIONS is < 10 */ - connection[0] = i + '0'; - connection[1] = NUL; - return connection; + vim_snprintf(connection, sizeof(connection), "%d", i); + return (char_u *)connection; } } return (current_idx == idx && idx > 0) ? (char_u *)"-1" : NULL; @@ -223,7 +222,6 @@ do_cscope_general(eap, make_split) { cscmd_T *cmdp; - cs_init(); if ((cmdp = cs_lookup_cmd(eap)) == NULL) { cs_help(eap); @@ -284,8 +282,6 @@ do_cstag(eap) { int ret = FALSE; - cs_init(); - if (*eap->arg == NUL) { (void)EMSG(_("E562: Usage: cstag ")); @@ -441,7 +437,7 @@ cs_connection(num, dbpath, ppath) if (num < 0 || num > 4 || (num > 0 && !dbpath)) return FALSE; - for (i = 0; i < CSCOPE_MAX_CONNECTIONS; i++) + for (i = 0; i < csinfo_size; i++) { if (!csinfo[i].fname) continue; @@ -684,7 +680,7 @@ cs_cnt_connections() short i; short cnt = 0; - for (i = 0; i < CSCOPE_MAX_CONNECTIONS; i++) + for (i = 0; i < csinfo_size; i++) { if (csinfo[i].fname != NULL) cnt++; @@ -1112,7 +1108,8 @@ cs_find_common(opt, pat, forceit, verbose, use_ll) { int i; char *cmd; - int nummatches[CSCOPE_MAX_CONNECTIONS], totmatches; + int *nummatches; + int totmatches; #ifdef FEAT_QUICKFIX char cmdletter; char *qfpos; @@ -1123,13 +1120,17 @@ cs_find_common(opt, pat, forceit, verbose, use_ll) if (cmd == NULL) return FALSE; + nummatches = (int *)alloc(sizeof(int)*csinfo_size); + if (nummatches == NULL) + return FALSE; + /* send query to all open connections, then count the total number * of matches so we can alloc matchesp all in one swell foop */ - for (i = 0; i < CSCOPE_MAX_CONNECTIONS; i++) + for (i = 0; i < csinfo_size; i++) nummatches[i] = 0; totmatches = 0; - for (i = 0; i < CSCOPE_MAX_CONNECTIONS; i++) + for (i = 0; i < csinfo_size; i++) { if (csinfo[i].fname == NULL || csinfo[i].to_fp == NULL) continue; @@ -1154,7 +1155,10 @@ cs_find_common(opt, pat, forceit, verbose, use_ll) char *buf; if (!verbose) + { + vim_free(nummatches); return FALSE; + } buf = (char *)alloc((unsigned)(strlen(opt) + strlen(pat) + strlen(nf))); if (buf == NULL) @@ -1165,6 +1169,7 @@ cs_find_common(opt, pat, forceit, verbose, use_ll) (void)EMSG(buf); vim_free(buf); } + vim_free(nummatches); return FALSE; } @@ -1217,6 +1222,7 @@ cs_find_common(opt, pat, forceit, verbose, use_ll) (void)EMSG(buf); vim_free(buf); } + vim_free(nummatches); return FALSE; } } @@ -1264,6 +1270,7 @@ cs_find_common(opt, pat, forceit, verbose, use_ll) } mch_remove(tmp); vim_free(tmp); + vim_free(nummatches); return TRUE; } else @@ -1275,6 +1282,7 @@ cs_find_common(opt, pat, forceit, verbose, use_ll) /* read output */ cs_fill_results((char *)pat, totmatches, nummatches, &matches, &contexts, &matched); + vim_free(nummatches); if (matches == NULL) return FALSE; @@ -1328,26 +1336,6 @@ cs_help(eap) } /* cs_help */ -/* - * PRIVATE: cs_init - * - * initialize cscope structure if not already - */ - static void -cs_init() -{ - short i; - static int init_already = FALSE; - - if (init_already) - return; - - for (i = 0; i < CSCOPE_MAX_CONNECTIONS; i++) - clear_csinfo(i); - - init_already = TRUE; -} /* cs_init */ - static void clear_csinfo(i) int i; @@ -1444,7 +1432,7 @@ cs_insert_filelist(fname, ppath, flags, sb) #endif i = -1; /* can be set to the index of an empty item in csinfo */ - for (j = 0; j < CSCOPE_MAX_CONNECTIONS; j++) + for (j = 0; j < csinfo_size; j++) { if (csinfo[j].fname != NULL #if defined(UNIX) @@ -1471,9 +1459,25 @@ cs_insert_filelist(fname, ppath, flags, sb) if (i == -1) { - if (p_csverbose) - (void)EMSG(_("E569: maximum number of cscope connections reached")); - return -1; + i = csinfo_size; + if (csinfo_size == 0) + { + /* First time allocation: allocate only 1 connection. It should + * be enough for most users. If more is needed, csinfo will be + * reallocated. */ + csinfo_size = 1; + csinfo = (csinfo_T *)alloc_clear(sizeof(csinfo_T)); + } + else + { + /* Reallocate space for more connections. */ + csinfo_size *= 2; + csinfo = vim_realloc(csinfo, sizeof(csinfo_T)*csinfo_size); + } + if (csinfo == NULL) + return -1; + for (j = csinfo_size/2; j < csinfo_size; j++) + clear_csinfo(j); } if ((csinfo[i].fname = (char *)alloc((unsigned)strlen(fname)+1)) == NULL) @@ -1580,15 +1584,14 @@ cs_kill(eap) /* It must be part of a name. We will try to find a match * within all the names in the csinfo data structure */ - for (i = 0; i < CSCOPE_MAX_CONNECTIONS; i++) + for (i = 0; i < csinfo_size; i++) { if (csinfo[i].fname != NULL && strstr(csinfo[i].fname, stok)) break; } } - if ((i >= CSCOPE_MAX_CONNECTIONS || i < -1 || csinfo[i].fname == NULL) - && i != -1) + if ((i != -1) && (i >= csinfo_size || i < -1 || csinfo[i].fname == NULL)) { if (p_csverbose) (void)EMSG2(_("E261: cscope connection %s not found"), stok); @@ -1597,7 +1600,7 @@ cs_kill(eap) { if (i == -1) { - for (i = 0; i < CSCOPE_MAX_CONNECTIONS; i++) + for (i = 0; i < csinfo_size; i++) { if (csinfo[i].fname) cs_kill_execute(i, csinfo[i].fname); @@ -1857,7 +1860,7 @@ cs_file_results(f, nummatches_a) if (buf == NULL) return; - for (i = 0; i < CSCOPE_MAX_CONNECTIONS; i++) + for (i = 0; i < csinfo_size; i++) { if (nummatches_a[i] < 1) continue; @@ -1929,7 +1932,7 @@ cs_fill_results(tagstr, totmatches, nummatches_a, matches_p, cntxts_p, matched) if ((cntxts = (char **)alloc(sizeof(char *) * totmatches)) == NULL) goto parse_out; - for (i = 0; i < CSCOPE_MAX_CONNECTIONS; i++) + for (i = 0; i < csinfo_size; i++) { if (nummatches_a[i] < 1) continue; @@ -2383,10 +2386,13 @@ cs_reset(eap) int i; char buf[20]; /* for sprintf " (#%d)" */ + if (csinfo_size == 0) + return CSCOPE_SUCCESS; + /* malloc our db and ppath list */ - dblist = (char **)alloc(CSCOPE_MAX_CONNECTIONS * sizeof(char *)); - pplist = (char **)alloc(CSCOPE_MAX_CONNECTIONS * sizeof(char *)); - fllist = (char **)alloc(CSCOPE_MAX_CONNECTIONS * sizeof(char *)); + dblist = (char **)alloc(csinfo_size * sizeof(char *)); + pplist = (char **)alloc(csinfo_size * sizeof(char *)); + fllist = (char **)alloc(csinfo_size * sizeof(char *)); if (dblist == NULL || pplist == NULL || fllist == NULL) { vim_free(dblist); @@ -2395,7 +2401,7 @@ cs_reset(eap) return CSCOPE_FAILURE; } - for (i = 0; i < CSCOPE_MAX_CONNECTIONS; i++) + for (i = 0; i < csinfo_size; i++) { dblist[i] = csinfo[i].fname; pplist[i] = csinfo[i].ppath; @@ -2405,7 +2411,7 @@ cs_reset(eap) } /* rebuild the cscope connection list */ - for (i = 0; i < CSCOPE_MAX_CONNECTIONS; i++) + for (i = 0; i < csinfo_size; i++) { if (dblist[i] != NULL) { @@ -2502,7 +2508,7 @@ cs_show(eap) MSG_PUTS_ATTR( _(" # pid database name prepend path\n"), hl_attr(HLF_T)); - for (i = 0; i < CSCOPE_MAX_CONNECTIONS; i++) + for (i = 0; i < csinfo_size; i++) { if (csinfo[i].fname == NULL) continue; @@ -2531,8 +2537,10 @@ cs_end() { int i; - for (i = 0; i < CSCOPE_MAX_CONNECTIONS; i++) + for (i = 0; i < csinfo_size; i++) cs_release_csp(i, TRUE); + vim_free(csinfo); + csinfo_size = 0; } #endif /* FEAT_CSCOPE */ diff --git a/src/if_cscope.h b/src/if_cscope.h index 89b69f7c72..5620eb3a2b 100644 --- a/src/if_cscope.h +++ b/src/if_cscope.h @@ -25,7 +25,6 @@ #define CSCOPE_SUCCESS 0 #define CSCOPE_FAILURE -1 -#define CSCOPE_MAX_CONNECTIONS 8 /* you actually need more? */ #define CSCOPE_DBFILE "cscope.out" #define CSCOPE_PROMPT ">> " diff --git a/src/if_mzsch.c b/src/if_mzsch.c index 017f8041ed..bc3dd6bf59 100644 --- a/src/if_mzsch.c +++ b/src/if_mzsch.c @@ -1040,7 +1040,7 @@ mzscheme_init(void) #ifdef DYNAMIC_MZSCHEME if (!mzscheme_enabled(TRUE)) { - EMSG(_("E812: Sorry, this command is disabled, the MzScheme libraries could not be loaded.")); + EMSG(_("E815: Sorry, this command is disabled, the MzScheme libraries could not be loaded.")); return -1; } #endif @@ -2169,9 +2169,9 @@ set_buffer_line(void *data, int argc, Scheme_Object **argv) curbuf = savebuf; raise_vim_exn(_("cannot delete line")); } - deleted_lines_mark((linenr_T)n, 1L); if (buf->buf == curwin->w_buffer) mz_fix_cursor(n, n + 1, -1); + deleted_lines_mark((linenr_T)n, 1L); curbuf = savebuf; @@ -2299,9 +2299,9 @@ set_buffer_line_list(void *data, int argc, Scheme_Object **argv) curbuf = savebuf; raise_vim_exn(_("cannot delete line")); } - deleted_lines_mark((linenr_T)lo, (long)old_len); if (buf->buf == curwin->w_buffer) mz_fix_cursor(lo, hi, -old_len); + deleted_lines_mark((linenr_T)lo, (long)old_len); } curbuf = savebuf; diff --git a/src/if_perl.xs b/src/if_perl.xs index d344938295..a589f8fd09 100644 --- a/src/if_perl.xs +++ b/src/if_perl.xs @@ -1233,9 +1233,8 @@ Delete(vimbuf, ...) if (u_savedel(lnum, 1) == OK) { ml_delete(lnum, 0); + check_cursor(); deleted_lines_mark(lnum, 1L); - if (aco.save_curbuf == curbuf) - check_cursor(); } /* restore curwin/curbuf and a few other things */ diff --git a/src/if_python.c b/src/if_python.c index ce9bb3eebe..e483bfc8a8 100644 --- a/src/if_python.c +++ b/src/if_python.c @@ -2497,9 +2497,9 @@ SetBufferLine(buf_T *buf, PyInt n, PyObject *line, PyInt *len_change) PyErr_SetVim(_("cannot delete line")); else { - deleted_lines_mark((linenr_T)n, 1L); if (buf == curwin->w_buffer) py_fix_cursor((linenr_T)n, (linenr_T)n + 1, (linenr_T)-1); + deleted_lines_mark((linenr_T)n, 1L); } curbuf = savebuf; @@ -2596,10 +2596,9 @@ SetBufferLineList(buf_T *buf, PyInt lo, PyInt hi, PyObject *list, PyInt *len_cha break; } } - deleted_lines_mark((linenr_T)lo, (long)i); - if (buf == curwin->w_buffer) py_fix_cursor((linenr_T)lo, (linenr_T)hi, (linenr_T)-n); + deleted_lines_mark((linenr_T)lo, (long)i); } curbuf = savebuf; diff --git a/src/message.c b/src/message.c index c0f661b09b..e29f5f8fec 100644 --- a/src/message.c +++ b/src/message.c @@ -107,7 +107,7 @@ msg(s) } #if defined(FEAT_EVAL) || defined(FEAT_X11) || defined(USE_XSMP) \ - || defined(PROTO) + || defined(FEAT_GUI_GTK) || defined(PROTO) /* * Like msg() but keep it silent when 'verbosefile' is set. */ diff --git a/src/misc1.c b/src/misc1.c index 2145124d11..39669b4c32 100644 --- a/src/misc1.c +++ b/src/misc1.c @@ -2345,12 +2345,13 @@ del_lines(nlines, undo) int undo; /* if TRUE, prepare for undo */ { long n; + linenr_T first = curwin->w_cursor.lnum; if (nlines <= 0) return; /* save the deleted lines for undo */ - if (undo && u_savedel(curwin->w_cursor.lnum, nlines) == FAIL) + if (undo && u_savedel(first, nlines) == FAIL) return; for (n = 0; n < nlines; ) @@ -2358,18 +2359,21 @@ del_lines(nlines, undo) if (curbuf->b_ml.ml_flags & ML_EMPTY) /* nothing to delete */ break; - ml_delete(curwin->w_cursor.lnum, TRUE); + ml_delete(first, TRUE); ++n; /* If we delete the last line in the file, stop */ - if (curwin->w_cursor.lnum > curbuf->b_ml.ml_line_count) + if (first > curbuf->b_ml.ml_line_count) break; } - /* adjust marks, mark the buffer as changed and prepare for displaying */ - deleted_lines_mark(curwin->w_cursor.lnum, n); + /* Correct the cursor position before calling deleted_lines_mark(), it may + * trigger a callback to display the cursor. */ curwin->w_cursor.col = 0; check_cursor_lnum(); + + /* adjust marks, mark the buffer as changed and prepare for displaying */ + deleted_lines_mark(first, n); } int @@ -2621,6 +2625,8 @@ deleted_lines(lnum, count) /* * Like deleted_lines(), but adjust marks first. + * Make sure the cursor is on a valid line before calling, a GUI callback may + * be triggered to display the cursor. */ void deleted_lines_mark(lnum, count) @@ -9193,7 +9199,7 @@ gen_expand_wildcards(num_pat, pat, num_file, file, flags) else if (vim_strpbrk(p, (char_u *)"$~") != NULL) { vim_free(p); - ga_clear(&ga); + ga_clear_strings(&ga); i = mch_expand_wildcards(num_pat, pat, num_file, file, flags); recursive = FALSE; diff --git a/src/netbeans.c b/src/netbeans.c index 47ca2fa2b2..030044b642 100644 --- a/src/netbeans.c +++ b/src/netbeans.c @@ -2644,7 +2644,7 @@ coloncmd(char *cmd, ...) va_list ap; va_start(ap, cmd); - vsprintf(buf, cmd, ap); + vim_vsnprintf(buf, sizeof(buf), cmd, ap, NULL); va_end(ap); nbdebug((" COLONCMD %s\n", buf)); diff --git a/src/ops.c b/src/ops.c index 3e595fd427..f75613def2 100644 --- a/src/ops.c +++ b/src/ops.c @@ -5591,6 +5591,29 @@ x11_export_final_selection() if (dpy != NULL && str != NULL && motion_type >= 0 && len < 1024*1024 && len > 0) { +#ifdef FEAT_MBYTE + /* The CUT_BUFFER0 is supposed to always contain latin1. Convert from + * 'enc' when it is a multi-byte encoding. When 'enc' is an 8-bit + * encoding conversion usually doesn't work, so keep the text as-is. + */ + if (has_mbyte) + { + char_u *conv_str = str; + vimconv_T vc; + + vc.vc_type = CONV_NONE; + if (convert_setup(&vc, p_enc, (char_u *)"latin1") == OK) + { + conv_str = string_convert(&vc, str, (int*)&len); + if (conv_str != NULL) + { + vim_free(str); + str = conv_str; + } + convert_setup(&vc, NULL, NULL); + } + } +#endif XStoreBuffer(dpy, (char *)str, (int)len, 0); XFlush(dpy); } diff --git a/src/os_mac.h b/src/os_mac.h index 7a54ee5c56..aadaed7766 100644 --- a/src/os_mac.h +++ b/src/os_mac.h @@ -268,9 +268,15 @@ */ #ifdef MACOS_X_UNIX -# define SIGPROTOARG (int) -# define SIGDEFARG(s) (s) int s; -# define SIGDUMMYARG 0 +# ifndef SIGPROTOARG +# define SIGPROTOARG (int) +# endif +# ifndef SIGDEFARG +# define SIGDEFARG(s) (s) int s UNUSED; +# endif +# ifndef SIGDUMMYARG +# define SIGDUMMYARG 0 +# endif # undef HAVE_AVAIL_MEM # ifndef HAVE_CONFIG_H # define RETSIGTYPE void diff --git a/src/proto/ui.pro b/src/proto/ui.pro index 8825b6a168..2bc0c31ec9 100644 --- a/src/proto/ui.pro +++ b/src/proto/ui.pro @@ -48,6 +48,7 @@ int check_row __ARGS((int row)); void open_app_context __ARGS((void)); void x11_setup_atoms __ARGS((Display *dpy)); void clip_x11_request_selection __ARGS((Widget myShell, Display *dpy, VimClipboard *cbd)); +void yank_cut_buffer0 __ARGS((Display *dpy, VimClipboard *cbd)); void clip_x11_lose_selection __ARGS((Widget myShell, VimClipboard *cbd)); int clip_x11_own_selection __ARGS((Widget myShell, VimClipboard *cbd)); void clip_x11_set_selection __ARGS((VimClipboard *cbd)); diff --git a/src/proto/window.pro b/src/proto/window.pro index 6bc5f7e9e2..7b019a780e 100644 --- a/src/proto/window.pro +++ b/src/proto/window.pro @@ -14,6 +14,7 @@ void win_free_all __ARGS((void)); win_T *winframe_remove __ARGS((win_T *win, int *dirp, tabpage_T *tp)); void close_others __ARGS((int message, int forceit)); void curwin_init __ARGS((void)); +void win_init_empty __ARGS((win_T *wp)); int win_alloc_first __ARGS((void)); void win_alloc_aucmd_win __ARGS((void)); void win_init_size __ARGS((void)); diff --git a/src/quickfix.c b/src/quickfix.c index 3c0ed203bb..5fc36bc5e0 100644 --- a/src/quickfix.c +++ b/src/quickfix.c @@ -3411,14 +3411,15 @@ load_dummy_buffer(fname) /* Init the options. */ buf_copy_options(newbuf, BCO_ENTER | BCO_NOHELP); - /* set curwin/curbuf to buf and save a few things */ - aucmd_prepbuf(&aco, newbuf); - - /* Need to set the filename for autocommands. */ - (void)setfname(curbuf, fname, NULL, FALSE); - - if (ml_open(curbuf) == OK) + /* need to open the memfile before putting the buffer in a window */ + if (ml_open(newbuf) == OK) { + /* set curwin/curbuf to buf and save a few things */ + aucmd_prepbuf(&aco, newbuf); + + /* Need to set the filename for autocommands. */ + (void)setfname(curbuf, fname, NULL, FALSE); + /* Create swap file now to avoid the ATTENTION message. */ check_need_swap(TRUE); @@ -3441,10 +3442,10 @@ load_dummy_buffer(fname) newbuf = curbuf; } } - } - /* restore curwin/curbuf and a few other things */ - aucmd_restbuf(&aco); + /* restore curwin/curbuf and a few other things */ + aucmd_restbuf(&aco); + } if (!buf_valid(newbuf)) return NULL; diff --git a/src/structs.h b/src/structs.h index eab41e1890..417914c28d 100644 --- a/src/structs.h +++ b/src/structs.h @@ -882,6 +882,8 @@ typedef struct { typebuf_T save_typebuf; int typebuf_valid; /* TRUE when save_typebuf valid */ + int old_char; + int old_mod_mask; struct buffheader save_stuffbuff; #ifdef USE_INPUT_BUF char_u *save_inputbuf; diff --git a/src/testdir/Makefile b/src/testdir/Makefile index b60bd4885a..50386ec775 100644 --- a/src/testdir/Makefile +++ b/src/testdir/Makefile @@ -4,9 +4,11 @@ VIMPROG = ../vim -# Uncomment this line for using valgrind. -# The output goes into a file "valgrind.$PID" (sorry, no test number). -# VALGRIND = valgrind --tool=memcheck --leak-check=yes --num-callers=15 --logfile=valgrind +# Uncomment this line to use valgrind for memory leaks and extra warnings. +# The output goes into a file "valgrind.testN" +# Vim should be compiled with EXITFREE to avoid false warnings. +# This will make testing about 10 times as slow. +# VALGRIND = valgrind --tool=memcheck --leak-check=yes --num-callers=15 --log-file=valgrind.$* SCRIPTS = test1.out test2.out test3.out test4.out test5.out test6.out \ test7.out test8.out test9.out test10.out test11.out \ diff --git a/src/ui.c b/src/ui.c index 9c5439986c..7ef95d62bb 100644 --- a/src/ui.c +++ b/src/ui.c @@ -2118,8 +2118,6 @@ clip_x11_request_selection(myShell, dpy, cbd) Atom type; static int success; int i; - int nbytes = 0; - char_u *buffer; time_t start_time; int timed_out = FALSE; @@ -2199,15 +2197,7 @@ clip_x11_request_selection(myShell, dpy, cbd) } /* Final fallback position - use the X CUT_BUFFER0 store */ - buffer = (char_u *)XFetchBuffer(dpy, &nbytes, 0); - if (nbytes > 0) - { - /* Got something */ - clip_yank_selection(MCHAR, buffer, (long)nbytes, cbd); - XFree((void *)buffer); - if (p_verbose > 0) - verb_msg((char_u *)_("Used CUT_BUFFER0 instead of empty selection")); - } + yank_cut_buffer0(dpy, cbd); } static Boolean clip_x11_convert_selection_cb __ARGS((Widget, Atom *, Atom *, Atom *, XtPointer *, long_u *, int *)); @@ -2383,6 +2373,60 @@ clip_x11_set_selection(cbd) } #endif +#if defined(FEAT_XCLIPBOARD) || defined(FEAT_GUI_X11) \ + || defined(FEAT_GUI_GTK) || defined(PROTO) +/* + * Get the contents of the X CUT_BUFFER0 and put it in "cbd". + */ + void +yank_cut_buffer0(dpy, cbd) + Display *dpy; + VimClipboard *cbd; +{ + int nbytes = 0; + char_u *buffer = (char_u *)XFetchBuffer(dpy, &nbytes, 0); + + if (nbytes > 0) + { +#ifdef FEAT_MBYTE + int done = FALSE; + + /* CUT_BUFFER0 is supposed to be always latin1. Convert to 'enc' when + * using a multi-byte encoding. Conversion between two 8-bit + * character sets usually fails and the text might actually be in + * 'enc' anyway. */ + if (has_mbyte) + { + char_u *conv_buf = buffer; + vimconv_T vc; + + vc.vc_type = CONV_NONE; + if (convert_setup(&vc, (char_u *)"latin1", p_enc) == OK) + { + conv_buf = string_convert(&vc, buffer, &nbytes); + if (conv_buf != NULL) + { + clip_yank_selection(MCHAR, conv_buf, (long)nbytes, cbd); + vim_free(conv_buf); + done = TRUE; + } + convert_setup(&vc, NULL, NULL); + } + } + if (!done) /* use the text without conversion */ +#endif + clip_yank_selection(MCHAR, buffer, (long)nbytes, cbd); + XFree((void *)buffer); + if (p_verbose > 0) + { + verbose_enter(); + verb_msg((char_u *)_("Used CUT_BUFFER0 instead of empty selection")); + verbose_leave(); + } + } +} +#endif + #if defined(FEAT_MOUSE) || defined(PROTO) /* diff --git a/src/version.c b/src/version.c index aad44cb005..8d777b7cc8 100644 --- a/src/version.c +++ b/src/version.c @@ -691,6 +691,44 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ +/**/ + 228, +/**/ + 227, +/**/ + 226, +/**/ + 225, +/**/ + 224, +/**/ + 223, +/**/ + 222, +/**/ + 221, +/**/ + 220, +/**/ + 219, +/**/ + 218, +/**/ + 217, +/**/ + 216, +/**/ + 215, +/**/ + 214, +/**/ + 213, +/**/ + 212, +/**/ + 211, +/**/ + 210, /**/ 209, /**/ diff --git a/src/window.c b/src/window.c index 0c3a7f3837..c1955ad700 100644 --- a/src/window.c +++ b/src/window.c @@ -2354,13 +2354,6 @@ win_free_mem(win, dirp, tp) frame_T *frp; win_T *wp; -#ifdef FEAT_FOLDING - clearFolding(win); -#endif - - /* reduce the reference count to the argument list. */ - alist_unlink(win->w_alist); - /* Remove the window and its frame from the tree of frames. */ frp = win->w_frame; wp = winframe_remove(win, dirp, tp); @@ -2386,9 +2379,6 @@ win_free_all() tabpage_close(TRUE); # endif - while (firstwin != NULL) - (void)win_free_mem(firstwin, &dummy, NULL); - # ifdef FEAT_AUTOCMD if (aucmd_win != NULL) { @@ -2396,6 +2386,9 @@ win_free_all() aucmd_win = NULL; } # endif + + while (firstwin != NULL) + (void)win_free_mem(firstwin, &dummy, NULL); } #endif @@ -3204,27 +3197,34 @@ close_others(message, forceit) void curwin_init() { - redraw_win_later(curwin, NOT_VALID); - curwin->w_lines_valid = 0; - curwin->w_cursor.lnum = 1; - curwin->w_curswant = curwin->w_cursor.col = 0; + win_init_empty(curwin); +} + + void +win_init_empty(wp) + win_T *wp; +{ + redraw_win_later(wp, NOT_VALID); + wp->w_lines_valid = 0; + wp->w_cursor.lnum = 1; + wp->w_curswant = wp->w_cursor.col = 0; #ifdef FEAT_VIRTUALEDIT - curwin->w_cursor.coladd = 0; + wp->w_cursor.coladd = 0; #endif - curwin->w_pcmark.lnum = 1; /* pcmark not cleared but set to line 1 */ - curwin->w_pcmark.col = 0; - curwin->w_prev_pcmark.lnum = 0; - curwin->w_prev_pcmark.col = 0; - curwin->w_topline = 1; + wp->w_pcmark.lnum = 1; /* pcmark not cleared but set to line 1 */ + wp->w_pcmark.col = 0; + wp->w_prev_pcmark.lnum = 0; + wp->w_prev_pcmark.col = 0; + wp->w_topline = 1; #ifdef FEAT_DIFF - curwin->w_topfill = 0; + wp->w_topfill = 0; #endif - curwin->w_botline = 2; + wp->w_botline = 2; #ifdef FEAT_FKMAP - if (curwin->w_p_rl) - curwin->w_farsi = W_CONV + W_R_L; + if (wp->w_p_rl) + wp->w_farsi = W_CONV + W_R_L; else - curwin->w_farsi = W_CONV; + wp->w_farsi = W_CONV; #endif } @@ -4325,6 +4325,13 @@ win_free(wp, tp) { int i; +#ifdef FEAT_FOLDING + clearFolding(wp); +#endif + + /* reduce the reference count to the argument list. */ + alist_unlink(wp->w_alist); + #ifdef FEAT_AUTOCMD /* Don't execute autocommands while the window is halfway being deleted. * gui_mch_destroy_scrollbar() may trigger a FocusGained event. */ @@ -4387,7 +4394,10 @@ win_free(wp, tp) } #endif /* FEAT_GUI */ - win_remove(wp, tp); +#ifdef FEAT_AUTOCMD + if (wp != aucmd_win) +#endif + win_remove(wp, tp); vim_free(wp); #ifdef FEAT_AUTOCMD