Hi,

2016/9/7 Wed 3:08:50 UTC+9 Bram Moolenaar wrote:
> Ken Takata wrote:
> 
> > 2016/8/23 Tue 20:00:50 UTC+9 Ken Takata wrote:
> > > Hi Bram,
> > > 
> > > 2016/8/22 Mon 2:29:28 UTC+9 Bram Moolenaar wrote:
> > > > Ken Takata wrote:
> > > > 
> > > > > > > > > I wrote a patch for the following todo item:
> > > > > > > > > 
> > > > > > > > > > Win32: When running ":make" and 'encoding' differs from the 
> > > > > > > > > > system locale, the
> > > > > > > > > > output should be converted.  Esp. when 'encoding' is 
> > > > > > > > > > "utf-8". (Yongwei Wu)
> > > > > > > > > > Should we use 'termencoding' for this?
> > > > > > > > > 
> > > > > > > > > I think using 'termencoding' for this is not so good.  
> > > > > > > > > Normally
> > > > > > > > > the encoding of a command output is the same as the encoding 
> > > > > > > > > of
> > > > > > > > > the terminal, but not always the same.  I hear that some 
> > > > > > > > > commands
> > > > > > > > > on Windows use utf-8 instead of the current codepage.  So I 
> > > > > > > > > added
> > > > > > > > > a new option 'cmdencoding' ('cenc').
> > > > > > > > > What do you think of this?
> > > > > > > > 
> > > > > > > > Seems reasonable.  It's not nice that it's yet another option.  
> > > > > > > > But in
> > > > > > > > case you know the compiler output is in a certain encoding it's 
> > > > > > > > the only
> > > > > > > > way to make it work.
> > > > > > > > 
> > > > > > > > Why they "char" value?  It's using the system locale, wouldn't 
> > > > > > > > "system"
> > > > > > > > be better?  Hmm, I don't see where "char" is recognized.
> > > > > > > 
> > > > > > > At least, GNU libiconv supports "char".
> > > > > > > 
> > > > > > > See: https://www.gnu.org/software/libiconv/
> > > > > > > | Locale dependent, in terms of `char' or `wchar_t' (with machine 
> > > > > > > dependent
> > > > > > > | endianness and alignment, and with OS and locale dependent 
> > > > > > > semantics)
> > > > > > > |     char, wchar_t
> > > > > > > |     The empty encoding name "" is equivalent to "char": it 
> > > > > > > denotes the locale
> > > > > > > |     dependent character encoding.
> > > > > > > 
> > > > > > > I don't know about other iconv implementations.
> > > > > > 
> > > > > > I found a few, but they all say that the name supported are system
> > > > > > dependent.  Perhaps someone can dig deeper?
> > > > > 
> > > > > I hear that the "char" encoding would be a GNU extension. So the 
> > > > > description
> > > > > in options.txt would be:
> > > > > 
> > > > >       This would be mostly useful when you use MS-Windows and set 
> > > > > 'encoding'
> > > > >       to "utf-8".  If GNU libiconv is available, setting 
> > > > > 'cmdencoding' to
> > > > >       "char" has the same effect as setting to the system locale 
> > > > > encoding.
> > > > >       Example: >
> > > > >               :set encoding=utf-8
> > > > >               :set cmdencoding=char   " system locale is used
> > > > > 
> > > > > On Japanese Windows, `set cenc=char` has the same effect as `set 
> > > > > cenc=cp932`.
> > > > > (I suppose the Vim 8.0 win32 installer will contain GNU libiconv.)
> > > > 
> > > > Looking at this patch, I think it also applies the conversion to
> > > > ":cbuffer".  That should not happen.  Also ":cexpr".
> > > 
> > > No, the conversion will not be applied to `:cbuffer` and `:cexpr`.
> > > As I wrote in the help, it will be applied to:
> > >   `:make`, `:lmake`, `:grep`, `:lgrep`, `:grepadd`, `:lgrepadd`,
> > >   `:cfile`, `:cgetfile`, `:caddfile`, `:lfile`, `:lgetfile`, and
> > >   `:laddfile`.
> > > (Oh, I didn't mention 'cenc' in each of them, only in `:make` and 
> > > `:lmake`.)
> > > 
> > > My patch only adds the conversion to the function qf_get_next_file_line()
> > > which is used only when reading from a file. (Note that `:make` and 
> > > `:grep`
> > > also use a file.)
> > > Hm, is it confusing that 'cmdencoding' also applies to `:[cl].*file`?
> > > 
> > > `:cbuffer` calls qf_get_next_buf_line(), I think.
> > > 
> > > 
> > > > In general, whether the conversion is needed depends on the command
> > > > used.  E.g. for :grep and :make it might be different.  Not sure how to
> > > > deal with that.
> > > 
> > > Do you mean `:grep` and `:make` should have different encoding options?
> > > Maybe a user can create wrapper commands which set 'cenc' before executing
> > > `:grep` or `:make`.
> > > Of course, it would be nice if Vim supports it natively, but I have no 
> > > idea
> > > how to implement it.
> > 
> > I'm thinking this issue again.
> > Maybe we can do this by adding an parameter for encoding to qf_init() in
> > quickfix.c. I think we can use three options instead of 'cenc':
> > 
> > 1. 'makeencoding', 'menc':
> >    Option for `:make` and `:lmake`.
> > 2. 'grepencoding', 'genc':
> >    Option for `:grep`, `:grepadd`, `:lgrep` and `:lgrepadd`.
> > 3. 'errfileencoding', 'eenc':
> >    Option for `:cfile`, `:cgetfile`, `:caddfile`, `:lfile`, `:lgetfile`,
> >    and `:laddfile`.
> > 
> > And I think these options should be global-local options.
> > What do you think?
> 
> That's a lot of new options, but it's probably needed.  An alternative
> is to make a comma separated list, but that's hard to use by plugins.
> e.g. if a plugin uses ":cfile" it probably wants to save, set and
> restore an option.
> 
> I would use 'menc' encoding for all commands when 'genc' and 'eenc' are
> empty.  On MS-Windows you probably want to set it to the system
> codepage.

I wrote a patch to implement this. Please check the attached patch.
I haven't add a test for this yet. It's not so easy.

Regards,
Ken Takata

-- 
-- 
You received this message from the "vim_dev" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php

--- 
You received this message because you are subscribed to the Google Groups 
"vim_dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
For more options, visit https://groups.google.com/d/optout.
# HG changeset patch
# Parent  35939ec273c1c3c8e010326023cfadcb27b2d66c

diff --git a/runtime/doc/options.txt b/runtime/doc/options.txt
--- a/runtime/doc/options.txt
+++ b/runtime/doc/options.txt
@@ -2784,6 +2784,19 @@ A jump table for the options with a shor
 	This option cannot be set from a |modeline| or in the |sandbox|, for
 	security reasons.
 
+					*'errfileencoding'* *'eenc'*
+'errfileencoding' 'eenc'
+			string	(default "")
+			global or local to buffer |global-local|
+			{only available when compiled with the |+multi_byte|
+			feature}
+			{not in Vi}
+	Encoding used for reading the error file.  When empty, the value of
+	'makeencoding' is used.
+	This is used for `:cfile`, `:cgetfile`, `:caddfile`, `:lfile`,
+	`:lgetfile` and `:laddfile`.
+	See also: 'makeencoding', 'grepencoding'
+
 			*'errorbells'* *'eb'* *'noerrorbells'* *'noeb'*
 'errorbells' 'eb'	boolean	(default off)
 			global
@@ -3467,6 +3480,17 @@ A jump table for the options with a shor
 
 	NOTE: This option is reset when 'compatible' is set.
 
+					*'grepencoding'* *'genc'*
+'grepencoding' 'genc'	string	(default "")
+			global or local to buffer |global-local|
+			{only available when compiled with the |+multi_byte|
+			feature}
+			{not in Vi}
+	Encoding used for reading the output of external grep commands.  When
+	empty, the value of 'makeencoding' is used.
+	This is used for `:grep`, `:lgrep`, `:grepadd` and `:lgrepadd`.
+	See also: 'makeencoding', 'errfileencoding'
+
 						*'grepformat'* *'gfm'*
 'grepformat' 'gfm'	string	(default "%f:%l:%m,%f:%l%m,%f  %l%m")
 			global
@@ -4968,6 +4992,26 @@ A jump table for the options with a shor
 	This option cannot be set from a |modeline| or in the |sandbox|, for
 	security reasons.
 
+					*'makeencoding'* *'menc'*
+'makeencoding' 'menc'	string	(default "")
+			global or local to buffer |global-local|
+			{only available when compiled with the |+multi_byte|
+			feature}
+			{not in Vi}
+	Encoding used for reading the output of external commands.  When empty,
+	encoding is not converted.
+	This is used for `:make` and `:lmake`.
+
+	This is also used as a default value for 'errfileencoding' and
+	'grepencoding' if they are empty.
+
+	This would be mostly useful when you use MS-Windows and set 'encoding'
+	to "utf-8".  If |+iconv| is enabled and GNU libiconv is used, setting
+	'makeencoding' to "char" has the same effect as setting to the system
+	locale encoding.  Example: >
+		:set encoding=utf-8
+		:set makeencoding=char	" system locale is used
+<
 						*'makeprg'* *'mp'*
 'makeprg' 'mp'		string	(default "make", VMS: "MMS")
 			global or local to buffer |global-local|
diff --git a/runtime/doc/quickfix.txt b/runtime/doc/quickfix.txt
--- a/runtime/doc/quickfix.txt
+++ b/runtime/doc/quickfix.txt
@@ -164,6 +164,9 @@ processing a quickfix or location list c
 			keep Vim running while compiling.  If you give the
 			name of the errorfile, the 'errorfile' option will
 			be set to [errorfile].  See |:cc| for [!].
+			If the encoding of the program output differs from the
+			'encoding' option, you can use the 'errfileencoding'
+			option to specify the encoding.
 
 							*:lf* *:lfile*
 :lf[ile][!] [errorfile]	Same as ":cfile", except the location list for the
@@ -175,6 +178,9 @@ processing a quickfix or location list c
 :cg[etfile] [errorfile]					*:cg* *:cgetfile*
 			Read the error file.  Just like ":cfile" but don't
 			jump to the first error.
+			If the encoding of the program output differs from the
+			'encoding' option, you can use the 'errfileencoding'
+			option to specify the encoding.
 
 
 :lg[etfile] [errorfile]					*:lg* *:lgetfile*
@@ -185,6 +191,9 @@ processing a quickfix or location list c
 :caddf[ile] [errorfile]	Read the error file and add the errors from the
 			errorfile to the current quickfix list. If a quickfix
 			list is not present, then a new list is created.
+			If the encoding of the program output differs from the
+			'encoding' option, you can use the 'errfileencoding'
+			option to specify the encoding.
 
 							*:laddf* *:laddfile*
 :laddf[ile] [errorfile]	Same as ":caddfile", except the location list for the
@@ -320,6 +329,7 @@ use this code: >
 	endfunction
 
 	au QuickfixCmdPost make call QfMakeConv()
+Another option is using 'makeencoding'.
 
 
 EXECUTE A COMMAND IN ALL THE BUFFERS IN QUICKFIX OR LOCATION LIST:
@@ -586,6 +596,9 @@ 4. Using :make						*:make_makeprg*
 			   like |:cnext| and |:cprevious|, see above.
 			This command does not accept a comment, any "
 			characters are considered part of the arguments.
+			If the encoding of the program output differs from the
+			'encoding' option, you can use the 'makeencoding'
+			option to specify the encoding.
 
 							*:lmak* *:lmake*
 :lmak[e][!] [arguments]
@@ -645,6 +658,7 @@ read the error messages: >
 	au QuickfixCmdPost make call QfMakeConv()
 
 (Example by Faque Cheng)
+Another option is using 'makeencoding'.
 
 ==============================================================================
 5. Using :vimgrep and :grep				*grep* *lid*
@@ -759,6 +773,9 @@ id-utils) in a similar way to its compil
 			When 'grepprg' is "internal" this works like
 			|:vimgrep|.  Note that the pattern needs to be
 			enclosed in separator characters then.
+			If the encoding of the program output differs from the
+			'encoding' option, you can use the 'grepencoding'
+			option to specify the encoding.
 
 							    *:lgr* *:lgrep*
 :lgr[ep][!] [arguments]	Same as ":grep", except the location list for the
@@ -783,6 +800,10 @@ id-utils) in a similar way to its compil
 				  \ | catch /E480:/
 				  \ | endtry"
 <
+			If the encoding of the program output differs from the
+			'encoding' option, you can use the 'grepencoding'
+			option to specify the encoding.
+
 							*:lgrepa* *:lgrepadd*
 :lgrepa[dd][!] [arguments]
 			Same as ":grepadd", except the location list for the
diff --git a/src/buffer.c b/src/buffer.c
--- a/src/buffer.c
+++ b/src/buffer.c
@@ -2211,6 +2211,11 @@ free_buf_options(
     clear_string_option(&buf->b_p_lw);
 #endif
     clear_string_option(&buf->b_p_bkc);
+#ifdef FEAT_MBYTE
+    clear_string_option(&buf->b_p_eenc);
+    clear_string_option(&buf->b_p_genc);
+    clear_string_option(&buf->b_p_menc);
+#endif
 }
 
 /*
diff --git a/src/if_cscope.c b/src/if_cscope.c
--- a/src/if_cscope.c
+++ b/src/if_cscope.c
@@ -1271,7 +1271,7 @@ cs_find_common(
 		wp = curwin;
 	    /* '-' starts a new error list */
 	    if (qf_init(wp, tmp, (char_u *)"%f%*\\t%l%*\\t%m",
-						  *qfpos == '-', cmdline) > 0)
+					  *qfpos == '-', cmdline, NULL) > 0)
 	    {
 # ifdef FEAT_WINDOWS
 		if (postponed_split != 0)
diff --git a/src/main.c b/src/main.c
--- a/src/main.c
+++ b/src/main.c
@@ -556,11 +556,17 @@ vim_main2(void)
      */
     if (params.edit_type == EDIT_QF)
     {
+	char_u	*enc = NULL;
+
+# ifdef FEAT_MBYTE
+	/* Use 'eenc' if it is set. Otherwise use 'menc'. */
+	enc = (*p_eenc != NUL) ? p_eenc : p_menc;
+# endif
 	if (params.use_ef != NULL)
 	    set_string_option_direct((char_u *)"ef", -1,
 					   params.use_ef, OPT_FREE, SID_CARG);
 	vim_snprintf((char *)IObuff, IOSIZE, "cfile %s", p_ef);
-	if (qf_init(NULL, p_ef, p_efm, TRUE, IObuff) < 0)
+	if (qf_init(NULL, p_ef, p_efm, TRUE, IObuff, enc) < 0)
 	{
 	    out_char('\n');
 	    mch_exit(3);
diff --git a/src/option.c b/src/option.c
--- a/src/option.c
+++ b/src/option.c
@@ -97,6 +97,9 @@
 # define PV_DEF		OPT_BOTH(OPT_BUF(BV_DEF))
 # define PV_INC		OPT_BOTH(OPT_BUF(BV_INC))
 #endif
+#ifdef FEAT_MBYTE
+# define PV_EENC	OPT_BOTH(OPT_BUF(BV_EENC))
+#endif
 #define PV_EOL		OPT_BUF(BV_EOL)
 #define PV_FIXEOL	OPT_BUF(BV_FIXEOL)
 #define PV_EP		OPT_BOTH(OPT_BUF(BV_EP))
@@ -116,6 +119,9 @@
 #ifdef FEAT_AUTOCMD
 # define PV_FT		OPT_BUF(BV_FT)
 #endif
+#ifdef FEAT_MBYTE
+# define PV_GENC	OPT_BOTH(OPT_BUF(BV_GENC))
+#endif
 #define PV_IMI		OPT_BUF(BV_IMI)
 #define PV_IMS		OPT_BUF(BV_IMS)
 #if defined(FEAT_CINDENT) && defined(FEAT_EVAL)
@@ -138,6 +144,9 @@
 # define PV_LISP	OPT_BUF(BV_LISP)
 # define PV_LW		OPT_BOTH(OPT_BUF(BV_LW))
 #endif
+#ifdef FEAT_MBYTE
+# define PV_MENC	OPT_BOTH(OPT_BUF(BV_MENC))
+#endif
 #define PV_MA		OPT_BUF(BV_MA)
 #define PV_ML		OPT_BUF(BV_ML)
 #define PV_MOD		OPT_BUF(BV_MOD)
@@ -1081,6 +1090,15 @@ static struct vimoption options[] =
     {"errorbells",  "eb",   P_BOOL|P_VI_DEF,
 			    (char_u *)&p_eb, PV_NONE,
 			    {(char_u *)FALSE, (char_u *)0L} SCRIPTID_INIT},
+    {"errfileencoding", "eenc", P_STRING|P_VI_DEF,
+#ifdef FEAT_MBYTE
+			    (char_u *)&p_eenc, PV_EENC,
+			    {(char_u *)"", (char_u *)0L}
+#else
+			    (char_u *)NULL, PV_NONE,
+			    {(char_u *)0L, (char_u *)0L}
+#endif
+			    SCRIPTID_INIT},
     {"errorfile",   "ef",   P_STRING|P_EXPAND|P_VI_DEF|P_SECURE,
 #ifdef FEAT_QUICKFIX
 			    (char_u *)&p_ef, PV_NONE,
@@ -1282,6 +1300,15 @@ static struct vimoption options[] =
 			    {(char_u *)NULL, (char_u *)0L}
 #endif
 			    SCRIPTID_INIT},
+    {"grepencoding","genc", P_STRING|P_VI_DEF,
+#ifdef FEAT_MBYTE
+			    (char_u *)&p_genc, PV_GENC,
+			    {(char_u *)"", (char_u *)0L}
+#else
+			    (char_u *)NULL, PV_NONE,
+			    {(char_u *)0L, (char_u *)0L}
+#endif
+			    SCRIPTID_INIT},
     {"grepprg",	    "gp",   P_STRING|P_EXPAND|P_VI_DEF|P_SECURE,
 #ifdef FEAT_QUICKFIX
 			    (char_u *)&p_gp, PV_GP,
@@ -1798,6 +1825,15 @@ static struct vimoption options[] =
 			    {(char_u *)NULL, (char_u *)0L}
 #endif
 			    SCRIPTID_INIT},
+    {"makeencoding","menc", P_STRING|P_VI_DEF,
+#ifdef FEAT_MBYTE
+			    (char_u *)&p_menc, PV_MENC,
+			    {(char_u *)"", (char_u *)0L}
+#else
+			    (char_u *)NULL, PV_NONE,
+			    {(char_u *)0L, (char_u *)0L}
+#endif
+			    SCRIPTID_INIT},
     {"makeprg",	    "mp",   P_STRING|P_EXPAND|P_VI_DEF|P_SECURE,
 #ifdef FEAT_QUICKFIX
 			    (char_u *)&p_mp, PV_MP,
@@ -5556,6 +5592,11 @@ check_buf_options(buf_T *buf)
     check_string_option(&buf->b_p_lw);
 #endif
     check_string_option(&buf->b_p_bkc);
+#ifdef FEAT_MBYTE
+    check_string_option(&buf->b_p_eenc);
+    check_string_option(&buf->b_p_genc);
+    check_string_option(&buf->b_p_menc);
+#endif
 }
 
 /*
@@ -6132,7 +6173,8 @@ did_set_string_option(
 
 #ifdef FEAT_MBYTE
     /* 'encoding' and 'fileencoding' */
-    else if (varp == &p_enc || gvarp == &p_fenc || varp == &p_tenc)
+    else if (varp == &p_enc || gvarp == &p_fenc || varp == &p_tenc
+		|| gvarp == &p_eenc || gvarp == &p_genc || gvarp == &p_menc)
     {
 	if (gvarp == &p_fenc)
 	{
@@ -10186,6 +10228,17 @@ unset_global_local_option(char_u *name, 
 	    clear_string_option(&buf->b_p_lw);
 	    break;
 #endif
+#ifdef FEAT_MBYTE
+	case PV_EENC:
+	    clear_string_option(&buf->b_p_eenc);
+	    break;
+	case PV_GENC:
+	    clear_string_option(&buf->b_p_genc);
+	    break;
+	case PV_MENC:
+	    clear_string_option(&buf->b_p_menc);
+	    break;
+#endif
     }
 }
 
@@ -10238,6 +10291,11 @@ get_varp_scope(struct vimoption *p, int 
 	    case PV_LW:   return (char_u *)&(curbuf->b_p_lw);
 #endif
 	    case PV_BKC:  return (char_u *)&(curbuf->b_p_bkc);
+#ifdef FEAT_MBYTE
+	    case PV_EENC: return (char_u *)&(curbuf->b_p_eenc);
+	    case PV_GENC: return (char_u *)&(curbuf->b_p_genc);
+	    case PV_MENC: return (char_u *)&(curbuf->b_p_menc);
+#endif
 	}
 	return NULL; /* "cannot happen" */
     }
@@ -10311,6 +10369,14 @@ get_varp(struct vimoption *p)
 	case PV_LW:	return *curbuf->b_p_lw != NUL
 				    ? (char_u *)&(curbuf->b_p_lw) : p->var;
 #endif
+#ifdef FEAT_MBYTE
+	case PV_EENC:	return *curbuf->b_p_eenc != NUL
+				    ? (char_u *)&(curbuf->b_p_eenc) : p->var;
+	case PV_GENC:	return *curbuf->b_p_genc != NUL
+				    ? (char_u *)&(curbuf->b_p_genc) : p->var;
+	case PV_MENC:	return *curbuf->b_p_menc != NUL
+				    ? (char_u *)&(curbuf->b_p_menc) : p->var;
+#endif
 
 #ifdef FEAT_ARABIC
 	case PV_ARAB:	return (char_u *)&(curwin->w_p_arab);
@@ -10899,6 +10965,11 @@ buf_copy_options(buf_T *buf, int flags)
 #ifdef FEAT_LISP
 	    buf->b_p_lw = empty_option;
 #endif
+#ifdef FEAT_MBYTE
+	    buf->b_p_eenc = empty_option;
+	    buf->b_p_genc = empty_option;
+	    buf->b_p_menc = empty_option;
+#endif
 
 	    /*
 	     * Don't copy the options set by ex_help(), use the saved values,
diff --git a/src/option.h b/src/option.h
--- a/src/option.h
+++ b/src/option.h
@@ -465,6 +465,9 @@ EXTERN char_u	*p_ead;		/* 'eadirection' 
 #endif
 EXTERN int	p_ea;		/* 'equalalways' */
 EXTERN char_u	*p_ep;		/* 'equalprg' */
+#ifdef FEAT_MBYTE
+EXTERN char_u	*p_eenc;	/* 'errfileencoding' */
+#endif
 EXTERN int	p_eb;		/* 'errorbells' */
 #ifdef FEAT_QUICKFIX
 EXTERN char_u	*p_ef;		/* 'errorfile' */
@@ -509,6 +512,9 @@ EXTERN char_u	*p_fp;		/* 'formatprg' */
 EXTERN int	p_fs;		/* 'fsync' */
 #endif
 EXTERN int	p_gd;		/* 'gdefault' */
+#ifdef FEAT_MBYTE
+EXTERN char_u	*p_genc;	/* 'grepencoding' */
+#endif
 #ifdef FEAT_PRINTER
 EXTERN char_u	*p_pdev;	/* 'printdevice' */
 # ifdef FEAT_POSTSCRIPT
@@ -630,6 +636,9 @@ EXTERN char_u	*p_luadll;	/* 'luadll' */
 EXTERN int	p_macatsui;	/* 'macatsui' */
 #endif
 EXTERN int	p_magic;	/* 'magic' */
+#ifdef FEAT_MBYTE
+EXTERN char_u	*p_menc;	/* 'makeencoding' */
+#endif
 #ifdef FEAT_QUICKFIX
 EXTERN char_u	*p_mef;		/* 'makeef' */
 EXTERN char_u	*p_mp;		/* 'makeprg' */
@@ -1024,6 +1033,9 @@ enum
     , BV_DEF
     , BV_INC
 #endif
+#ifdef FEAT_MBYTE
+    , BV_EENC
+#endif
     , BV_EOL
     , BV_FIXEOL
     , BV_EP
@@ -1039,6 +1051,9 @@ enum
 #ifdef FEAT_AUTOCMD
     , BV_FT
 #endif
+#ifdef FEAT_MBYTE
+    , BV_GENC
+#endif
     , BV_IMI
     , BV_IMS
 #if defined(FEAT_CINDENT) && defined(FEAT_EVAL)
@@ -1061,6 +1076,9 @@ enum
     , BV_LISP
     , BV_LW
 #endif
+#ifdef FEAT_MBYTE
+    , BV_MENC
+#endif
     , BV_MA
     , BV_ML
     , BV_MOD
diff --git a/src/proto/quickfix.pro b/src/proto/quickfix.pro
--- a/src/proto/quickfix.pro
+++ b/src/proto/quickfix.pro
@@ -1,5 +1,5 @@
 /* quickfix.c */
-int qf_init(win_T *wp, char_u *efile, char_u *errorformat, int newlist, char_u *qf_title);
+int qf_init(win_T *wp, char_u *efile, char_u *errorformat, int newlist, char_u *qf_title, char_u *enc);
 void qf_free_all(win_T *wp);
 void copy_loclist(win_T *from, win_T *to);
 void qf_jump(qf_info_T *qi, int dir, int errornr, int forceit);
diff --git a/src/quickfix.c b/src/quickfix.c
--- a/src/quickfix.c
+++ b/src/quickfix.c
@@ -114,7 +114,7 @@ struct efm_S
     int		    conthere;	/* %> used */
 };
 
-static int	qf_init_ext(qf_info_T *qi, char_u *efile, buf_T *buf, typval_T *tv, char_u *errorformat, int newlist, linenr_T lnumfirst, linenr_T lnumlast, char_u *qf_title);
+static int	qf_init_ext(qf_info_T *qi, char_u *efile, buf_T *buf, typval_T *tv, char_u *errorformat, int newlist, linenr_T lnumfirst, linenr_T lnumlast, char_u *qf_title, char_u *enc);
 static void	qf_store_title(qf_info_T *qi, char_u *title);
 static void	qf_new_list(qf_info_T *qi, char_u *qf_title);
 static void	ll_free_all(qf_info_T **pqi);
@@ -165,7 +165,8 @@ qf_init(
     char_u	    *efile,
     char_u	    *errorformat,
     int		    newlist,		/* TRUE: start a new error list */
-    char_u	    *qf_title)
+    char_u	    *qf_title,
+    char_u	    *enc)
 {
     qf_info_T	    *qi = &ql_info;
 
@@ -178,7 +179,7 @@ qf_init(
 
     return qf_init_ext(qi, efile, curbuf, NULL, errorformat, newlist,
 						    (linenr_T)0, (linenr_T)0,
-						    qf_title);
+						    qf_title, enc);
 }
 
 /*
@@ -495,6 +496,7 @@ typedef struct {
     buf_T	*buf;
     linenr_T	buflnum;
     linenr_T	lnumlast;
+    vimconv_T	*vc;
 } qfstate_T;
 
     static char_u *
@@ -710,6 +712,30 @@ qf_get_next_file_line(qfstate_T *state)
     else
 	state->linebuf = IObuff;
 
+#ifdef FEAT_MBYTE
+    /* Convert a line if it contains a non-ASCII character. */
+    if (state->vc->vc_type != CONV_NONE && has_non_ascii(state->linebuf)) {
+	char_u	*line;
+
+	line = string_convert(state->vc, state->linebuf, &state->linelen);
+	if (line != NULL)
+	{
+	    if (state->linelen < IOSIZE)
+	    {
+		STRCPY(state->linebuf, line);
+		vim_free(line);
+	    }
+	    else
+	    {
+		vim_free(state->growbuf);
+		state->linebuf = state->growbuf = line;
+		state->growbufsiz = state->linelen < LINE_MAXLEN
+						? state->linelen : LINE_MAXLEN;
+	    }
+	}
+    }
+#endif
+
     return QF_OK;
 }
 
@@ -1100,10 +1126,11 @@ qf_init_ext(
     int		    newlist,		/* TRUE: start a new error list */
     linenr_T	    lnumfirst,		/* first line number to use */
     linenr_T	    lnumlast,		/* last line number to use */
-    char_u	    *qf_title)
+    char_u	    *qf_title,
+    char_u	    *enc)
 {
     qfstate_T	    state = {NULL, 0, NULL, 0, NULL, NULL, NULL, NULL,
-			     NULL, 0, 0};
+			     NULL, 0, 0, NULL};
     qffields_T	    fields = {NULL, NULL, 0, 0L, 0, FALSE, NULL, 0, 0, 0};
 #ifdef FEAT_WINDOWS
     qfline_T	    *old_last = NULL;
@@ -1113,7 +1140,14 @@ qf_init_ext(
     static char_u   *last_efm = NULL;
     int		    retval = -1;	/* default: return error flag */
     int		    status;
-
+#ifdef FEAT_MBYTE
+    vimconv_T	    vc;
+
+    vc.vc_type = CONV_NONE;
+    if (enc != NULL && *enc != NUL)
+	convert_setup(&vc, enc, p_enc);
+    state.vc = &vc;
+#endif
     fields.namebuf = alloc_id(CMDBUFFSIZE + 1, aid_qf_namebuf);
     fields.errmsglen = CMDBUFFSIZE + 1;
     fields.errmsg = alloc_id(fields.errmsglen, aid_qf_errmsg);
@@ -1276,6 +1310,10 @@ qf_init_end:
 #ifdef FEAT_WINDOWS
     qf_update_buffer(qi, old_last);
 #endif
+#ifdef FEAT_MBYTE
+    if (vc.vc_type != CONV_NONE)
+	convert_setup(&vc, NULL, NULL);
+#endif
 
     return retval;
 }
@@ -3419,6 +3457,7 @@ ex_make(exarg_T *eap)
 {
     char_u	*fname;
     char_u	*cmd;
+    char_u	*enc = NULL;
     unsigned	len;
     win_T	*wp = NULL;
     qf_info_T	*qi = &ql_info;
@@ -3453,6 +3492,18 @@ ex_make(exarg_T *eap)
 # endif
     }
 #endif
+#ifdef FEAT_MBYTE
+    if ((eap->cmdidx != CMD_make) && (eap->cmdidx != CMD_lmake))
+    {
+	/* Use 'genc' for grep commands if it is set. */
+	if (*curbuf->b_p_genc != NUL)
+	    enc = curbuf->b_p_genc;
+	else if (*p_genc != NUL)
+	    enc = p_genc;
+    }
+    if (enc == NULL)
+	enc = (*curbuf->b_p_menc != NUL) ? curbuf->b_p_menc : p_menc;
+#endif
 
     if (eap->cmdidx == CMD_lmake || eap->cmdidx == CMD_lgrep
 	|| eap->cmdidx == CMD_lgrepadd)
@@ -3500,7 +3551,7 @@ ex_make(exarg_T *eap)
 			    && eap->cmdidx != CMD_lmake) ? p_gefm : p_efm,
 					   (eap->cmdidx != CMD_grepadd
 					    && eap->cmdidx != CMD_lgrepadd),
-					   *eap->cmdlinep);
+					   *eap->cmdlinep, enc);
     if (wp != NULL)
 	qi = GET_LOC_LIST(wp);
 #ifdef FEAT_AUTOCMD
@@ -3839,6 +3890,7 @@ ex_cnext(exarg_T *eap)
     void
 ex_cfile(exarg_T *eap)
 {
+    char_u	*enc = NULL;
     win_T	*wp = NULL;
     qf_info_T	*qi = &ql_info;
 #ifdef FEAT_AUTOCMD
@@ -3863,6 +3915,17 @@ ex_cfile(exarg_T *eap)
     if (au_name != NULL)
 	apply_autocmds(EVENT_QUICKFIXCMDPRE, au_name, NULL, FALSE, curbuf);
 #endif
+#ifdef FEAT_MBYTE
+    /* Use 'eenc' if it is set. Otherwise use 'menc'. */
+    if (*curbuf->b_p_eenc != NUL)
+	enc = curbuf->b_p_eenc;
+    else if (*p_eenc != NUL)
+	enc = p_eenc;
+    else if (*curbuf->b_p_menc != NUL)
+	enc = curbuf->b_p_menc;
+    else
+	enc = p_menc;
+#endif
 #ifdef FEAT_BROWSE
     if (cmdmod.browse)
     {
@@ -3890,7 +3953,7 @@ ex_cfile(exarg_T *eap)
      */
     if (qf_init(wp, p_ef, p_efm, (eap->cmdidx != CMD_caddfile
 				  && eap->cmdidx != CMD_laddfile),
-							   *eap->cmdlinep) > 0
+						       *eap->cmdlinep, enc) > 0
 				  && (eap->cmdidx == CMD_cfile
 					     || eap->cmdidx == CMD_lfile))
     {
@@ -4912,7 +4975,7 @@ ex_cbuffer(exarg_T *eap)
 			    (eap->cmdidx != CMD_caddbuffer
 			     && eap->cmdidx != CMD_laddbuffer),
 						   eap->line1, eap->line2,
-						   qf_title) > 0)
+						   qf_title, NULL) > 0)
 	    {
 #ifdef FEAT_AUTOCMD
 		if (au_name != NULL)
@@ -4981,7 +5044,8 @@ ex_cexpr(exarg_T *eap)
 	    if (qf_init_ext(qi, NULL, NULL, tv, p_efm,
 			    (eap->cmdidx != CMD_caddexpr
 			     && eap->cmdidx != CMD_laddexpr),
-				 (linenr_T)0, (linenr_T)0, *eap->cmdlinep) > 0)
+				 (linenr_T)0, (linenr_T)0, *eap->cmdlinep,
+				 NULL) > 0)
 	    {
 #ifdef FEAT_AUTOCMD
 		if (au_name != NULL)
diff --git a/src/structs.h b/src/structs.h
--- a/src/structs.h
+++ b/src/structs.h
@@ -2058,6 +2058,9 @@ struct file_buffer
     char_u	*b_p_cfu;	/* 'completefunc' */
     char_u	*b_p_ofu;	/* 'omnifunc' */
 #endif
+#ifdef FEAT_MBYTE
+    char_u	*b_p_eenc;	/* 'errfileencoding' */
+#endif
     int		b_p_eol;	/* 'endofline' */
     int		b_p_fixeol;	/* 'fixendofline' */
     int		b_p_et;		/* 'expandtab' */
@@ -2072,6 +2075,9 @@ struct file_buffer
 #endif
     char_u	*b_p_fo;	/* 'formatoptions' */
     char_u	*b_p_flp;	/* 'formatlistpat' */
+#ifdef FEAT_MBYTE
+    char_u	*b_p_genc;	/* 'grepencoding' */
+#endif
     int		b_p_inf;	/* 'infercase' */
     char_u	*b_p_isk;	/* 'iskeyword' */
 #ifdef FEAT_FIND_ID
@@ -2098,6 +2104,9 @@ struct file_buffer
 #ifdef FEAT_LISP
     int		b_p_lisp;	/* 'lisp' */
 #endif
+#ifdef FEAT_MBYTE
+    char_u	*b_p_menc;	/* 'makeencoding' */
+#endif
     char_u	*b_p_mps;	/* 'matchpairs' */
     int		b_p_ml;		/* 'modeline' */
     int		b_p_ml_nobin;	/* b_p_ml saved for binary mode */

Raspunde prin e-mail lui