Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Merged from the latest developing branch.

git-svn-id: https://vim.svn.sourceforge.net/svnroot/vim/trunk@1584 2a77ed30-b011-0410-a7ad-c7884a0aa172
  • Loading branch information...
commit 7faba72536a6d31df2b7a7ee883295dbfe066ba5 1 parent 54ca4fc
edyfox authored
View
114 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 @@ readfile(fname, sfname, from, lines_to_skip, lines_to_read, eap, flags)
}
/*
- * 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 @@ buf_write(buf, fname, sfname, start, end, eap, append, forceit,
nchars += write_info.bw_len;
}
}
+ write_info.bw_start_lnum = start;
#endif
write_info.bw_len = bufsize;
@@ -4278,6 +4281,9 @@ buf_write(buf, fname, sfname, start, end, eap, append, forceit,
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 @@ buf_write(buf, fname, sfname, start, end, eap, append, forceit,
{
#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 @@ buf_write(buf, fname, sfname, start, end, eap, append, forceit,
{
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 @@ buf_write(buf, fname, sfname, start, end, eap, append, forceit,
}
STRCAT(IObuff, errmsg);
emsg(IObuff);
+ if (errmsg_allocated)
+ vim_free(errmsg);
retval = FAIL;
if (end == 0)
@@ -5105,7 +5129,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);
@@ -5386,6 +5416,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)
@@ -5469,20 +5500,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);
}
/*
@@ -8420,6 +8468,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;
@@ -8428,6 +8480,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
@@ -8436,9 +8489,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.
@@ -8472,7 +8536,7 @@ aucmd_restbuf(aco)
int dummy;
#endif
- if (aco->new_curwin == aucmd_win)
+ if (aco->use_aucmd_win)
{
--curbuf->b_nwindows;
#ifdef FEAT_WINDOWS
@@ -8499,6 +8563,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 */
@@ -8517,6 +8582,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)
@@ -8541,7 +8609,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
View
1  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
/*
View
14 src/gui.c
@@ -5004,6 +5004,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)
@@ -5094,6 +5107,7 @@ gui_do_findrepl(flags, find_text, repl_text, down)
}
vim_free(ga.ga_data);
+ busy = FALSE;
return (ga.ga_len > 0);
}
View
19 src/option.c
@@ -7194,6 +7194,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 */
@@ -7645,6 +7653,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
@@ -7655,8 +7671,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;
View
7 src/screen.c
@@ -7467,6 +7467,10 @@ screenalloc(clear)
*/
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 @@ screenalloc(clear)
}
}
#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
View
2  src/structs.h
@@ -2288,9 +2288,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;
View
12 src/version.c
@@ -677,6 +677,18 @@ static char *(features[]) =
static int included_patches[] =
{ /* Add new patch number below this line */
/**/
+ 245,
+/**/
+ 244,
+/**/
+ 243,
+/**/
+ 242,
+/**/
+ 241,
+/**/
+ 240,
+/**/
239,
/**/
238,
Please sign in to comment.
Something went wrong with that request. Please try again.