Hi Bram,

2017/1/6 Fri 22:55:58 UTC+9 Bram Moolenaar wrote:
> Ken Takata wrote:
> 
> > 2016/9/9 Fri 0:30:00 UTC+9 Ken Takata wrote:
> > > 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.
> > 
> > I have updated the patch.  Now, it includes tests.
> > I think that the patch is ready to be included.
> 
> Looking at the documentation for the new options, I wonder if we really
> need three options.  One might argue that :grep and :make may have a
> different output, but then running :make  with two different compilers
> (e.g., in two windows or directories) also may require a different
> encoding.
> 
> And to make things more complicated, the :make command may run several
> tools with more than one encoding.  This would require adding the format
> in 'errorformat' and 'grepformat'.  That may be difficult to implement
> though.
> 
> Back to the original problem: When 'encoding' in Vim differs from the
> system encoding, the conversion is needed.  And that is just one
> encoding, thus we won't need three options.  Perhaps we can just use
> 'makeencoding' and use it for all commands.

Okay, updated.

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  734bd3d44352b50e1b6ecd570a831b0f54fd8b83

diff --git a/runtime/doc/options.txt b/runtime/doc/options.txt
--- a/runtime/doc/options.txt
+++ b/runtime/doc/options.txt
@@ -4971,6 +4971,25 @@ 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`, `:lmake`, `:grep`, `:lgrep`, `:grepadd`,
+	`:lgrepadd`, `:cfile`, `:cgetfile`, `:caddfile`, `:lfile`, `:lgetfile`,
+	and `:laddfile`.
+
+	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 error file differs from the
+			'encoding' option, you can use the 'makeencoding'
+			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 error file differs from the
+			'encoding' option, you can use the 'makeencoding'
+			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 error file differs from the
+			'encoding' option, you can use the 'makeencoding'
+			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 'makeencoding'
+			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 'makeencoding'
+			option to specify the encoding.
+
 							*:lgrepa* *:lgrepadd*
 :lgrepa[dd][!] [arguments]
 			Same as ":grepadd", except the location list for the
diff --git a/runtime/doc/quickref.txt b/runtime/doc/quickref.txt
--- a/runtime/doc/quickref.txt
+++ b/runtime/doc/quickref.txt
@@ -782,6 +782,7 @@ Short explanation of each option:		*opti
 'macatsui'		    Mac GUI: use ATSUI text drawing
 'magic'			    changes special characters in search patterns
 'makeef'	  'mef'     name of the errorfile for ":make"
+'makeencoding'	  'menc'    encoding of external make/grep commands
 'makeprg'	  'mp'	    program to use for the ":make" command
 'matchpairs'	  'mps'     pairs of characters that "%" can match
 'matchtime'	  'mat'     tenths of a second to show matching paren
diff --git a/src/Makefile b/src/Makefile
--- a/src/Makefile
+++ b/src/Makefile
@@ -2127,6 +2127,7 @@ test_arglist \
 	test_langmap \
 	test_largefile \
 	test_lispwords \
+	test_makeencoding \
 	test_man \
 	test_mapping \
 	test_marks \
diff --git a/src/buffer.c b/src/buffer.c
--- a/src/buffer.c
+++ b/src/buffer.c
@@ -2225,6 +2225,9 @@ 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_menc);
+#endif
 }
 
 /*
diff --git a/src/if_cscope.c b/src/if_cscope.c
--- a/src/if_cscope.c
+++ b/src/if_cscope.c
@@ -1242,7 +1242,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,16 @@ vim_main2(void)
      */
     if (params.edit_type == EDIT_QF)
     {
+	char_u	*enc = NULL;
+
+# ifdef FEAT_MBYTE
+	enc = 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
@@ -138,6 +138,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)
@@ -1800,6 +1803,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,
@@ -5558,6 +5570,9 @@ 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_menc);
+#endif
 }
 
 /*
@@ -6155,7 +6170,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_menc)
     {
 	if (gvarp == &p_fenc)
 	{
@@ -10232,6 +10248,11 @@ unset_global_local_option(char_u *name, 
 	    clear_string_option(&buf->b_p_lw);
 	    break;
 #endif
+#ifdef FEAT_MBYTE
+	case PV_MENC:
+	    clear_string_option(&buf->b_p_menc);
+	    break;
+#endif
     }
 }
 
@@ -10284,6 +10305,9 @@ 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_MENC: return (char_u *)&(curbuf->b_p_menc);
+#endif
 	}
 	return NULL; /* "cannot happen" */
     }
@@ -10357,6 +10381,10 @@ 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_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);
@@ -10957,6 +10985,9 @@ buf_copy_options(buf_T *buf, int flags)
 #ifdef FEAT_LISP
 	    buf->b_p_lw = empty_option;
 #endif
+#ifdef FEAT_MBYTE
+	    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
@@ -630,6 +630,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' */
@@ -1061,6 +1064,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
@@ -116,7 +116,7 @@ struct efm_S
 
 static efm_T	*fmt_start = NULL; /* cached across qf_parse_line() calls */
 
-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);
@@ -167,7 +167,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;
 
@@ -180,7 +181,7 @@ qf_init(
 
     return qf_init_ext(qi, efile, curbuf, NULL, errorformat, newlist,
 						    (linenr_T)0, (linenr_T)0,
-						    qf_title);
+						    qf_title, enc);
 }
 
 /*
@@ -498,6 +499,7 @@ typedef struct {
     buf_T	*buf;
     linenr_T	buflnum;
     linenr_T	lnumlast;
+    vimconv_T	*vc;
 } qfstate_T;
 
     static char_u *
@@ -713,6 +715,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;
 }
 
@@ -1105,10 +1131,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;
@@ -1119,7 +1146,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);
@@ -1286,6 +1320,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;
 }
@@ -3431,6 +3469,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;
@@ -3464,6 +3503,9 @@ ex_make(exarg_T *eap)
 # endif
     }
 #endif
+#ifdef FEAT_MBYTE
+    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)
@@ -3511,7 +3553,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
@@ -3850,6 +3892,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
@@ -3874,6 +3917,9 @@ ex_cfile(exarg_T *eap)
     if (au_name != NULL)
 	apply_autocmds(EVENT_QUICKFIXCMDPRE, au_name, NULL, FALSE, curbuf);
 #endif
+#ifdef FEAT_MBYTE
+    enc = (*curbuf->b_p_menc != NUL) ? curbuf->b_p_menc : p_menc;
+#endif
 #ifdef FEAT_BROWSE
     if (cmdmod.browse)
     {
@@ -3901,7 +3947,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))
     {
@@ -4927,7 +4973,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)
@@ -4995,7 +5041,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
@@ -2108,6 +2108,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 */
diff --git a/src/testdir/Make_all.mak b/src/testdir/Make_all.mak
--- a/src/testdir/Make_all.mak
+++ b/src/testdir/Make_all.mak
@@ -164,6 +164,7 @@ NEW_TESTS = test_arglist.res \
 	    test_job_fails.res \
 	    test_json.res \
 	    test_langmap.res \
+	    test_makeencoding.res \
 	    test_man.res \
 	    test_marks.res \
 	    test_matchadd_conceal.res \
diff --git a/src/testdir/test_makeencoding.py b/src/testdir/test_makeencoding.py
new file mode 100644
--- /dev/null
+++ b/src/testdir/test_makeencoding.py
@@ -0,0 +1,67 @@
+#!/usr/bin/python
+# -*- coding: utf-8 -*-
+
+# Test program for :make, :grep and :cgetfile.
+
+from __future__ import print_function, unicode_literals
+import locale
+import io
+import sys
+
+def set_output_encoding(enc=None):
+    """Set the encoding of stdout and stderr
+
+    arguments:
+      enc -- Encoding name.
+             If omitted, locale.getpreferredencoding() is used.
+    """
+    if enc is None:
+        enc = locale.getpreferredencoding()
+
+    def get_text_writer(fo, **kwargs):
+        kw = dict(kwargs)
+        kw.setdefault('errors', 'backslashreplace') # use \uXXXX style
+        kw.setdefault('closefd', False)
+
+        if sys.version_info[0] < 3:
+            # Work around for Python 2.x
+            # New line conversion isn't needed here. Done in somewhere else.
+            writer = io.open(fo.fileno(), mode='w', newline='', **kw)
+            write = writer.write    # save the original write() function
+            enc = locale.getpreferredencoding()
+            def convwrite(s):
+                if isinstance(s, bytes):
+                    write(s.decode(enc))    # convert to unistr
+                else:
+                    write(s)
+                try:
+                    writer.flush()  # needed on Windows
+                except IOError:
+                    pass
+            writer.write = convwrite
+        else:
+            writer = io.open(fo.fileno(), mode='w', **kw)
+        return writer
+
+    sys.stdout = get_text_writer(sys.stdout, encoding=enc)
+    sys.stderr = get_text_writer(sys.stderr, encoding=enc)
+
+
+def main():
+    enc = 'utf-8'
+    if len(sys.argv) > 1:
+        enc = sys.argv[1]
+    set_output_encoding(enc)
+
+    message_tbl = {
+            'utf-8': 'ÀÈÌÒÙ こんにちは 你好',
+            'latin1': 'ÀÈÌÒÙ',
+            'cp932': 'こんにちは',
+            'cp936': '你好',
+            }
+
+    print('Xfoobar.c(10) : %s (%s)' % (message_tbl[enc], enc))
+
+
+if __name__ == "__main__":
+    main()
diff --git a/src/testdir/test_makeencoding.vim b/src/testdir/test_makeencoding.vim
new file mode 100644
--- /dev/null
+++ b/src/testdir/test_makeencoding.vim
@@ -0,0 +1,106 @@
+" Tests for 'makeencoding'.
+if !has('multi_byte')
+  finish
+endif
+
+source shared.vim
+
+let s:python = PythonProg()
+if s:python == ''
+  " Can't run this test.
+  finish
+endif
+
+let s:script = 'test_makeencoding.py'
+
+let s:message_tbl = {
+      \ 'utf-8': 'ÀÈÌÒÙ こんにちは 你好',
+      \ 'latin1': 'ÀÈÌÒÙ',
+      \ 'cp932': 'こんにちは',
+      \ 'cp936': '你好',
+      \}
+
+
+" Tests for :cgetfile and :lgetfile.
+func Test_getfile()
+  set errorfile=Xerror.txt
+  set errorformat=%f(%l)\ :\ %m
+
+  " :cgetfile
+  for enc in keys(s:message_tbl)
+    let &makeencoding = enc
+    exec "silent !" . s:python . " " . s:script . " " . enc . " > " . &errorfile
+    cgetfile
+    copen
+    call assert_equal("Xfoobar.c|10| " . s:message_tbl[enc] . " (" . enc . ")",
+          \ getline('.'))
+    cclose
+  endfor
+
+  " :lgetfile
+  for enc in keys(s:message_tbl)
+    let &makeencoding = enc
+    exec "silent !" . s:python . " " . s:script . " " . enc . " > " . &errorfile
+    lgetfile
+    lopen
+    call assert_equal("Xfoobar.c|10| " . s:message_tbl[enc] . " (" . enc . ")",
+          \ getline('.'))
+    lclose
+  endfor
+
+  call delete(&errorfile)
+endfunc
+
+
+" Tests for :grep and :lgrep.
+func Test_grep()
+  let &grepprg = s:python
+  set grepformat=%f(%l)\ :\ %m
+
+  " :grep
+  for enc in keys(s:message_tbl)
+    let &makeencoding = enc
+    exec "silent grep! " . s:script . " " . enc
+    copen
+    call assert_equal("Xfoobar.c|10| " . s:message_tbl[enc] . " (" . enc . ")",
+          \ getline('.'))
+    cclose
+  endfor
+
+  " :lgrep
+  for enc in keys(s:message_tbl)
+    let &makeencoding = enc
+    exec "silent lgrep! " . s:script . " " . enc
+    lopen
+    call assert_equal("Xfoobar.c|10| " . s:message_tbl[enc] . " (" . enc . ")",
+          \ getline('.'))
+    lclose
+  endfor
+endfunc
+
+
+" Tests for :make and :lmake.
+func Test_make()
+  let &makeprg = s:python
+  set errorformat=%f(%l)\ :\ %m
+
+  " :make
+  for enc in keys(s:message_tbl)
+    let &makeencoding = enc
+    exec "silent make! " . s:script . " " . enc
+    copen
+    call assert_equal("Xfoobar.c|10| " . s:message_tbl[enc] . " (" . enc . ")",
+          \ getline('.'))
+    cclose
+  endfor
+
+  " :lmake
+  for enc in keys(s:message_tbl)
+    let &makeencoding = enc
+    exec "silent lmake! " . s:script . " " . enc
+    lopen
+    call assert_equal("Xfoobar.c|10| " . s:message_tbl[enc] . " (" . enc . ")",
+          \ getline('.'))
+    lclose
+  endfor
+endfunc

Raspunde prin e-mail lui