diff --git a/src/auto/configure b/src/auto/configure index 42f4784ddc..1049c0ceb3 100755 --- a/src/auto/configure +++ b/src/auto/configure @@ -5780,7 +5780,10 @@ $as_echo "$rubyhdrdir" >&6; } fi rubyldflags=`$vi_cv_path_ruby -r rbconfig -e 'print Config::CONFIG["LDFLAGS"]'` if test "X$rubyldflags" != "X"; then - LDFLAGS="$rubyldflags $LDFLAGS" + rubyldflags=`echo "$rubyldflags" | sed -e 's/-arch\ ppc//' -e 's/-arch\ i386//'` + if test "X$rubyldflags" != "X"; then + LDFLAGS="$rubyldflags $LDFLAGS" + fi fi RUBY_SRC="if_ruby.c" RUBY_OBJ="objects/if_ruby.o" diff --git a/src/configure.in b/src/configure.in index 66e214d1a6..821e5dc028 100644 --- a/src/configure.in +++ b/src/configure.in @@ -993,7 +993,13 @@ if test "$enable_rubyinterp" = "yes"; then fi rubyldflags=`$vi_cv_path_ruby -r rbconfig -e 'print Config::CONFIG[["LDFLAGS"]]'` if test "X$rubyldflags" != "X"; then - LDFLAGS="$rubyldflags $LDFLAGS" + dnl Ruby on Mac OS X 10.5 adds "-arch" flags but these should only + dnl be included if requested by passing --with-mac-arch to + dnl configure, so strip these flags first (if present) + rubyldflags=`echo "$rubyldflags" | sed -e 's/-arch\ ppc//' -e 's/-arch\ i386//'` + if test "X$rubyldflags" != "X"; then + LDFLAGS="$rubyldflags $LDFLAGS" + fi fi RUBY_SRC="if_ruby.c" RUBY_OBJ="objects/if_ruby.o" diff --git a/src/diff.c b/src/diff.c index 9537a65d79..f5ea0c6928 100644 --- a/src/diff.c +++ b/src/diff.c @@ -893,6 +893,7 @@ ex_diffpatch(eap) char_u *browseFile = NULL; int browse_flag = cmdmod.browse; #endif + struct stat st; #ifdef FEAT_BROWSE if (cmdmod.browse) @@ -999,44 +1000,51 @@ ex_diffpatch(eap) STRCAT(buf, ".rej"); mch_remove(buf); - if (curbuf->b_fname != NULL) + /* Only continue if the output file was created. */ + if (mch_stat((char *)tmp_new, &st) < 0 || st.st_size == 0) + EMSG(_("E816: Cannot read patch output")); + else { - newname = vim_strnsave(curbuf->b_fname, + if (curbuf->b_fname != NULL) + { + newname = vim_strnsave(curbuf->b_fname, (int)(STRLEN(curbuf->b_fname) + 4)); - if (newname != NULL) - STRCAT(newname, ".new"); - } + if (newname != NULL) + STRCAT(newname, ".new"); + } #ifdef FEAT_GUI - need_mouse_correct = TRUE; + need_mouse_correct = TRUE; #endif - /* don't use a new tab page, each tab page has its own diffs */ - cmdmod.tab = 0; + /* don't use a new tab page, each tab page has its own diffs */ + cmdmod.tab = 0; - if (win_split(0, (diff_flags & DIFF_VERTICAL) ? WSP_VERT : 0) != FAIL) - { - /* Pretend it was a ":split fname" command */ - eap->cmdidx = CMD_split; - eap->arg = tmp_new; - do_exedit(eap, old_curwin); - - if (curwin != old_curwin) /* split must have worked */ + if (win_split(0, (diff_flags & DIFF_VERTICAL) ? WSP_VERT : 0) != FAIL) { - /* Set 'diff', 'scrollbind' on and 'wrap' off. */ - diff_win_options(curwin, TRUE); - diff_win_options(old_curwin, TRUE); + /* Pretend it was a ":split fname" command */ + eap->cmdidx = CMD_split; + eap->arg = tmp_new; + do_exedit(eap, old_curwin); - if (newname != NULL) + /* check that split worked and editing tmp_new */ + if (curwin != old_curwin && win_valid(old_curwin)) { - /* do a ":file filename.new" on the patched buffer */ - eap->arg = newname; - ex_file(eap); + /* Set 'diff', 'scrollbind' on and 'wrap' off. */ + diff_win_options(curwin, TRUE); + diff_win_options(old_curwin, TRUE); + + if (newname != NULL) + { + /* do a ":file filename.new" on the patched buffer */ + eap->arg = newname; + ex_file(eap); #ifdef FEAT_AUTOCMD - /* Do filetype detection with the new name. */ - if (au_has_group((char_u *)"filetypedetect")) - do_cmdline_cmd((char_u *)":doau filetypedetect BufRead"); + /* Do filetype detection with the new name. */ + if (au_has_group((char_u *)"filetypedetect")) + do_cmdline_cmd((char_u *)":doau filetypedetect BufRead"); #endif + } } } } diff --git a/src/fileio.c b/src/fileio.c index 6421f7192d..43df094db9 100644 --- a/src/fileio.c +++ b/src/fileio.c @@ -121,6 +121,8 @@ struct bw_info char_u *bw_conv_buf; /* buffer for writing converted chars */ int bw_conv_buflen; /* size of bw_conv_buf */ int bw_conv_error; /* set for conversion error */ + linenr_T bw_conv_error_lnum; /* first line with error or zero */ + linenr_T bw_start_lnum; /* line number at start of buffer */ # ifdef USE_ICONV iconv_t bw_iconv_fd; /* descriptor for iconv() or -1 */ # endif @@ -132,7 +134,7 @@ static int buf_write_bytes __ARGS((struct bw_info *ip)); #ifdef FEAT_MBYTE static linenr_T readfile_linenr __ARGS((linenr_T linecnt, char_u *p, char_u *endp)); static int ucs2bytes __ARGS((unsigned c, char_u **pp, int flags)); -static int same_encoding __ARGS((char_u *a, char_u *b)); +static int need_conversion __ARGS((char_u *fenc)); static int get_fio_flags __ARGS((char_u *ptr)); static char_u *check_for_bom __ARGS((char_u *p, long size, int *lenp, int flags)); static int make_bom __ARGS((char_u *buf, char_u *name)); @@ -1041,13 +1043,12 @@ retry: } /* - * Conversion is required when the encoding of the file is different - * from 'encoding' or 'encoding' is UTF-16, UCS-2 or UCS-4 (requires - * conversion to UTF-8). + * Conversion may be required when the encoding of the file is different + * from 'encoding' or 'encoding' is UTF-16, UCS-2 or UCS-4. */ fio_flags = 0; - converted = (*fenc != NUL && !same_encoding(p_enc, fenc)); - if (converted || enc_unicode != 0) + converted = need_conversion(fenc); + if (converted) { /* "ucs-bom" means we need to check the first bytes of the file @@ -2924,6 +2925,7 @@ buf_write(buf, fname, sfname, start, end, eap, append, forceit, linenr_T lnum; long nchars; char_u *errmsg = NULL; + int errmsg_allocated = FALSE; char_u *errnum = NULL; char_u *buffer; char_u smallbuf[SMBUFSIZE]; @@ -2987,6 +2989,7 @@ buf_write(buf, fname, sfname, start, end, eap, append, forceit, /* must init bw_conv_buf and bw_iconv_fd before jumping to "fail" */ write_info.bw_conv_buf = NULL; write_info.bw_conv_error = FALSE; + write_info.bw_conv_error_lnum = 0; write_info.bw_restlen = 0; # ifdef USE_ICONV write_info.bw_iconv_fd = (iconv_t)-1; @@ -3965,10 +3968,9 @@ buf_write(buf, fname, sfname, start, end, eap, append, forceit, fenc = buf->b_p_fenc; /* - * The file needs to be converted when 'fileencoding' is set and - * 'fileencoding' differs from 'encoding'. + * Check if the file needs to be converted. */ - converted = (*fenc != NUL && !same_encoding(p_enc, fenc)); + converted = need_conversion(fenc); /* * Check if UTF-8 to UCS-2/4 or Latin1 conversion needs to be done. Or @@ -4243,6 +4245,7 @@ restore_backup: nchars += write_info.bw_len; } } + write_info.bw_start_lnum = start; #endif write_info.bw_len = bufsize; @@ -4278,6 +4281,9 @@ restore_backup: nchars += bufsize; s = buffer; len = 0; +#ifdef FEAT_MBYTE + write_info.bw_start_lnum = lnum; +#endif } /* write failed or last line has no EOL: stop here */ if (end == 0 @@ -4474,7 +4480,17 @@ restore_backup: { #ifdef FEAT_MBYTE if (write_info.bw_conv_error) - errmsg = (char_u *)_("E513: write error, conversion failed (make 'fenc' empty to override)"); + { + if (write_info.bw_conv_error_lnum == 0) + errmsg = (char_u *)_("E513: write error, conversion failed (make 'fenc' empty to override)"); + else + { + errmsg_allocated = TRUE; + errmsg = alloc(300); + vim_snprintf((char *)errmsg, 300, _("E513: write error, conversion failed in line %ld (make 'fenc' empty to override)"), + (long)write_info.bw_conv_error_lnum); + } + } else #endif if (got_int) @@ -4550,6 +4566,12 @@ restore_backup: { STRCAT(IObuff, _(" CONVERSION ERROR")); c = TRUE; + if (write_info.bw_conv_error_lnum != 0) + { + int l = STRLEN(IObuff); + vim_snprintf((char *)IObuff + l, IOSIZE - l, _(" in line %ld;"), + (long)write_info.bw_conv_error_lnum); + } } else if (notconverted) { @@ -4746,6 +4768,8 @@ nofail: } STRCAT(IObuff, errmsg); emsg(IObuff); + if (errmsg_allocated) + vim_free(errmsg); retval = FAIL; if (end == 0) @@ -5109,7 +5133,13 @@ buf_write_bytes(ip) c = buf[wlen]; } - ip->bw_conv_error |= ucs2bytes(c, &p, flags); + if (ucs2bytes(c, &p, flags) && !ip->bw_conv_error) + { + ip->bw_conv_error = TRUE; + ip->bw_conv_error_lnum = ip->bw_start_lnum; + } + if (c == NL) + ++ip->bw_start_lnum; } if (flags & FIO_LATIN1) len = (int)(p - buf); @@ -5390,6 +5420,7 @@ buf_write_bytes(ip) #ifdef FEAT_MBYTE /* * Convert a Unicode character to bytes. + * Return TRUE for an error, FALSE when it's OK. */ static int ucs2bytes(c, pp, flags) @@ -5473,20 +5504,37 @@ ucs2bytes(c, pp, flags) } /* - * Return TRUE if "a" and "b" are the same 'encoding'. - * Ignores difference between "ansi" and "latin1", "ucs-4" and "ucs-4be", etc. + * Return TRUE if file encoding "fenc" requires conversion from or to + * 'encoding'. */ static int -same_encoding(a, b) - char_u *a; - char_u *b; +need_conversion(fenc) + char_u *fenc; { - int f; + int same_encoding; + int enc_flags; + int fenc_flags; - if (STRCMP(a, b) == 0) - return TRUE; - f = get_fio_flags(a); - return (f != 0 && get_fio_flags(b) == f); + if (*fenc == NUL || STRCMP(p_enc, fenc) == 0) + same_encoding = TRUE; + else + { + /* Ignore difference between "ansi" and "latin1", "ucs-4" and + * "ucs-4be", etc. */ + enc_flags = get_fio_flags(p_enc); + fenc_flags = get_fio_flags(fenc); + same_encoding = (enc_flags != 0 && fenc_flags == enc_flags); + } + if (same_encoding) + { + /* Specified encoding matches with 'encoding'. This requires + * conversion when 'encoding' is Unicode but not UTF-8. */ + return enc_unicode != 0; + } + + /* Encodings differ. However, conversion is not needed when 'enc' is any + * Unicode encoding and the file is UTF-8. */ + return !(enc_utf8 && fenc_flags == FIO_UTF8); } /* @@ -8458,6 +8506,10 @@ aucmd_prepbuf(aco, buf) if (aucmd_win == NULL) win = curwin; } + if (win == NULL && aucmd_win_used) + /* Strange recursive autocommand, fall back to using the current + * window. Expect a few side effects... */ + win = curwin; aco->save_curwin = curwin; aco->save_curbuf = curbuf; @@ -8466,6 +8518,7 @@ aucmd_prepbuf(aco, buf) /* There is a window for "buf" in the current tab page, make it the * curwin. This is preferred, it has the least side effects (esp. if * "buf" is curbuf). */ + aco->use_aucmd_win = FALSE; curwin = win; } else @@ -8474,9 +8527,20 @@ 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. */ + aco->use_aucmd_win = TRUE; + aucmd_win_used = TRUE; aucmd_win->w_buffer = buf; ++buf->b_nwindows; win_init_empty(aucmd_win); /* set cursor and topline to safe values */ + vim_free(aucmd_win->w_localdir); + aucmd_win->w_localdir = NULL; + + /* Make sure w_localdir and globaldir are NULL to avoid a chdir() in + * win_enter_ext(). */ + aucmd_win->w_localdir = NULL; + aco->globaldir = globaldir; + globaldir = NULL; + #ifdef FEAT_WINDOWS /* Split the current window, put the aucmd_win in the upper half. @@ -8510,7 +8574,7 @@ aucmd_restbuf(aco) int dummy; #endif - if (aco->new_curwin == aucmd_win) + if (aco->use_aucmd_win) { --curbuf->b_nwindows; #ifdef FEAT_WINDOWS @@ -8537,6 +8601,7 @@ aucmd_restbuf(aco) /* Remove the window and frame from the tree of frames. */ (void)winframe_remove(curwin, &dummy, NULL); win_remove(curwin, NULL); + aucmd_win_used = FALSE; last_status(FALSE); /* may need to remove last status line */ restore_snapshot(SNAP_AUCMD_IDX, FALSE); (void)win_comp_pos(); /* recompute window positions */ @@ -8555,6 +8620,9 @@ aucmd_restbuf(aco) #endif curbuf = curwin->w_buffer; + vim_free(globaldir); + globaldir = aco->globaldir; + /* the buffer contents may have changed */ check_cursor(); if (curwin->w_topline > curbuf->b_ml.ml_line_count) @@ -8579,7 +8647,7 @@ aucmd_restbuf(aco) #endif { /* Restore the buffer which was previously edited by curwin, if - * it was chagned, we are still the same window and the buffer is + * it was changed, we are still the same window and the buffer is * valid. */ if (curwin == aco->new_curwin && curbuf != aco->new_curbuf diff --git a/src/globals.h b/src/globals.h index 33069360af..5211141f08 100644 --- a/src/globals.h +++ b/src/globals.h @@ -541,6 +541,7 @@ EXTERN win_T *curwin; /* currently active window */ #ifdef FEAT_AUTOCMD EXTERN win_T *aucmd_win; /* window used in aucmd_prepbuf() */ +EXTERN int aucmd_win_used INIT(= FALSE); /* aucmd_win is being used */ #endif /* diff --git a/src/gui.c b/src/gui.c index e0a8380d36..95727f965b 100644 --- a/src/gui.c +++ b/src/gui.c @@ -5029,6 +5029,19 @@ gui_do_findrepl(flags, find_text, repl_text, down) char_u *p; regmatch_T regmatch; int save_did_emsg = did_emsg; + static int busy = FALSE; + + /* When the screen is being updated we should not change buffers and + * windows structures, it may cause freed memory to be used. Also don't + * do this recursively (pressing "Find" quickly several times. */ + if (updating_screen || busy) + return FALSE; + + /* refuse replace when text cannot be changed */ + if ((type == FRD_REPLACE || type == FRD_REPLACEALL) && text_locked()) + return FALSE; + + busy = TRUE; ga_init2(&ga, 1, 100); if (type == FRD_REPLACEALL) @@ -5119,6 +5132,7 @@ gui_do_findrepl(flags, find_text, repl_text, down) } vim_free(ga.ga_data); + busy = FALSE; return (ga.ga_len > 0); } diff --git a/src/misc1.c b/src/misc1.c index f86a16781f..23a1c1e4ba 100644 --- a/src/misc1.c +++ b/src/misc1.c @@ -3276,6 +3276,7 @@ prompt_for_number(mouse_used) cmdline_row = msg_row - 1; need_wait_return = FALSE; msg_didany = FALSE; + msg_didout = FALSE; } else cmdline_row = save_cmdline_row; diff --git a/src/option.c b/src/option.c index d193172068..8bc2544f8f 100644 --- a/src/option.c +++ b/src/option.c @@ -409,8 +409,9 @@ struct vimoption #define P_NUM 0x02 /* the option is numeric */ #define P_STRING 0x04 /* the option is a string */ #define P_ALLOCED 0x08 /* the string option is in allocated memory, - must use vim_free() when assigning new - value. Not set if default is the same. */ + must use free_string_option() when + assigning new value. Not set if default is + the same. */ #define P_EXPAND 0x10 /* environment expansion. NOTE: P_EXPAND can never be used for local or hidden options! */ #define P_NODEFAULT 0x40 /* don't set to default value */ @@ -7275,6 +7276,14 @@ set_bool_option(opt_idx, varp, value, opt_flags) compatible_set(); } + /* 'list', 'number' */ + else if ((int *)varp == &curwin->w_p_list + || (int *)varp == &curwin->w_p_nu) + { + if (curwin->w_curswant != MAXCOL) + curwin->w_set_curswant = TRUE; + } + else if ((int *)varp == &curbuf->b_p_ro) { /* when 'readonly' is reset globally, also reset readonlymode */ @@ -7763,6 +7772,14 @@ set_bool_option(opt_idx, varp, value, opt_flags) curbuf->b_p_imsearch = B_IMODE_USE_INSERT; # endif } + if (curwin->w_curswant != MAXCOL) + curwin->w_set_curswant = TRUE; + } + + else if ((int *)varp == &p_arshape) + { + if (curwin->w_curswant != MAXCOL) + curwin->w_set_curswant = TRUE; } #endif @@ -7773,8 +7790,7 @@ set_bool_option(opt_idx, varp, value, opt_flags) options[opt_idx].flags |= P_WAS_SET; comp_col(); /* in case 'ruler' or 'showcmd' changed */ - if (curwin->w_curswant != MAXCOL) - curwin->w_set_curswant = TRUE; /* in case 'list' changed */ + check_redraw(options[opt_idx].flags); return NULL; @@ -9059,6 +9075,28 @@ free_termoptions() clear_termcodes(); } +/* + * Free the string for one term option, if it was allocated. + * Set the string to empty_option and clear allocated flag. + * "var" points to the option value. + */ + void +free_one_termoption(var) + char_u *var; +{ + struct vimoption *p; + + for (p = &options[0]; p->fullname != NULL; p++) + if (p->var == var) + { + if (p->flags & P_ALLOCED) + free_string_option(*(char_u **)(p->var)); + *(char_u **)(p->var) = empty_option; + p->flags &= ~P_ALLOCED; + break; + } +} + /* * Set the terminal option defaults to the current value. * Used after setting the terminal name. diff --git a/src/os_unix.c b/src/os_unix.c index 3bde72b823..61fc119612 100644 --- a/src/os_unix.c +++ b/src/os_unix.c @@ -1734,9 +1734,9 @@ get_x11_icon(test_only) if (oldicon == NULL && !test_only) { if (STRNCMP(T_NAME, "builtin_", 8) == 0) - oldicon = T_NAME + 8; + oldicon = vim_strsave(T_NAME + 8); else - oldicon = T_NAME; + oldicon = vim_strsave(T_NAME); } return retval; @@ -1939,9 +1939,9 @@ get_x11_icon(test_only) if (!test_only) { if (STRNCMP(T_NAME, "builtin_", 8) == 0) - oldicon = T_NAME + 8; + oldicon = vim_strsave(T_NAME + 8); else - oldicon = T_NAME; + oldicon = vim_strsave(T_NAME); } return FALSE; } diff --git a/src/proto/option.pro b/src/proto/option.pro index 39ee7be21a..9c58c3e9dc 100644 --- a/src/proto/option.pro +++ b/src/proto/option.pro @@ -29,6 +29,7 @@ int makeset __ARGS((FILE *fd, int opt_flags, int local_only)); int makefoldset __ARGS((FILE *fd)); void clear_termoptions __ARGS((void)); void free_termoptions __ARGS((void)); +void free_one_termoption __ARGS((char_u *var)); void set_term_defaults __ARGS((void)); void comp_col __ARGS((void)); char_u *get_equalprg __ARGS((void)); diff --git a/src/screen.c b/src/screen.c index abe721ed26..28fe238d26 100644 --- a/src/screen.c +++ b/src/screen.c @@ -7467,6 +7467,10 @@ retry: */ FOR_ALL_TAB_WINDOWS(tp, wp) win_free_lsize(wp); +#ifdef FEAT_AUTOCMD + if (aucmd_win != NULL) + win_free_lsize(aucmd_win); +#endif new_ScreenLines = (schar_T *)lalloc((long_u)( (Rows + 1) * Columns * sizeof(schar_T)), FALSE); @@ -7504,7 +7508,8 @@ retry: } } #ifdef FEAT_AUTOCMD - if (aucmd_win != NULL && win_alloc_lines(aucmd_win) == FAIL) + if (aucmd_win != NULL && aucmd_win->w_lines == NULL + && win_alloc_lines(aucmd_win) == FAIL) outofmem = TRUE; #endif #ifdef FEAT_WINDOWS diff --git a/src/spell.c b/src/spell.c index de74f61185..033c353bc0 100644 --- a/src/spell.c +++ b/src/spell.c @@ -10252,6 +10252,7 @@ spell_suggest(count) int limit; int selected = count; int badlen = 0; + int msg_scroll_save = msg_scroll; if (no_spell_checking(curwin)) return; @@ -10416,7 +10417,9 @@ spell_suggest(count) selected = prompt_for_number(&mouse_used); if (mouse_used) selected -= lines_left; - lines_left = Rows; /* avoid more prompt */ + lines_left = Rows; /* avoid more prompt */ + /* don't delay for 'smd' in normal_cmd() */ + msg_scroll = msg_scroll_save; } if (selected > 0 && selected <= sug.su_ga.ga_len && u_save_cursor() == OK) @@ -10441,7 +10444,8 @@ spell_suggest(count) } /* Replace the word. */ - p = alloc((unsigned)STRLEN(line) - stp->st_orglen + stp->st_wordlen + 1); + p = alloc((unsigned)STRLEN(line) - stp->st_orglen + + stp->st_wordlen + 1); if (p != NULL) { c = (int)(sug.su_badptr - line); diff --git a/src/structs.h b/src/structs.h index 417914c28d..5fdaf70377 100644 --- a/src/structs.h +++ b/src/structs.h @@ -2303,9 +2303,11 @@ typedef struct { buf_T *save_curbuf; /* saved curbuf */ #ifdef FEAT_AUTOCMD + int use_aucmd_win; /* using aucmd_win */ win_T *save_curwin; /* saved curwin */ win_T *new_curwin; /* new curwin */ buf_T *new_curbuf; /* new curbuf */ + char_u *globaldir; /* saved value of globaldir */ #endif } aco_save_T; diff --git a/src/term.c b/src/term.c index 48e557ffda..f607575b14 100644 --- a/src/term.c +++ b/src/term.c @@ -2881,7 +2881,7 @@ ttest(pairs) /* if 'Sb' and 'AB' are not defined, reset "Co" */ if (*T_CSB == NUL && *T_CAB == NUL) - T_CCO = empty_option; + free_one_termoption(T_CCO); /* Set 'weirdinvert' according to value of 't_xs' */ p_wiv = (*T_XS != NUL); diff --git a/src/version.c b/src/version.c index 3108d34b56..5eb236ab94 100644 --- a/src/version.c +++ b/src/version.c @@ -691,6 +691,28 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ +/**/ + 245, +/**/ + 244, +/**/ + 243, +/**/ + 242, +/**/ + 241, +/**/ + 240, +/**/ + 239, +/**/ + 238, +/**/ + 237, +/**/ + 236, +/**/ + 235, /**/ 234, /**/