The patch allows a-a-m-c to work for list of values in single word (e.g. as used by _values). This looks pretty straightforward and apparently does not have any side effects; comments? Index: Completion/Base/Utility/_values =================================================================== RCS file: /cvsroot/zsh/zsh/Completion/Base/Utility/_values,v retrieving revision 1.9 diff -u -p -r1.9 _values --- Completion/Base/Utility/_values 27 Feb 2007 20:44:01 -0000 1.9 +++ Completion/Base/Utility/_values 9 Jan 2009 17:44:46 -0000 @@ -12,6 +12,8 @@ if compvalues -i "$@"; then local noargs args opts descr action expl sep argsep subc test='*' local oldcontext="$curcontext" + compstate[list_in_word]=1 + compvalues -S argsep compvalues -s sep && [[ -n "$sep" ]] && test="[^${(q)sep}]#" Index: Doc/Zsh/compwid.yo =================================================================== RCS file: /cvsroot/zsh/zsh/Doc/Zsh/compwid.yo,v retrieving revision 1.45 diff -u -p -r1.45 compwid.yo --- Doc/Zsh/compwid.yo 18 Oct 2008 19:16:24 -0000 1.45 +++ Doc/Zsh/compwid.yo 9 Jan 2009 17:44:47 -0000 @@ -285,6 +285,13 @@ tt(messages) both kinds of explanation s will be set appropriately on entry to a completion widget and may be changed there. ) +vindex(list_in_word, compstate) +item(tt(list_in_word))( +This controls how accept-and-menu-complete widget handles suffix. If +set to tt(0) (default), suffix will be removed and replaced by space. +If set to tt(1), suffix is preserved so next match will be inserted +in the same word. +) vindex(list_lines, compstate) item(tt(list_lines))( This gives the number of lines that are needed to display the full Index: Src/Zle/compcore.c =================================================================== RCS file: /cvsroot/zsh/zsh/Src/Zle/compcore.c,v retrieving revision 1.98 diff -u -p -r1.98 compcore.c --- Src/Zle/compcore.c 26 Sep 2008 09:11:30 -0000 1.98 +++ Src/Zle/compcore.c 9 Jan 2009 17:44:47 -0000 @@ -325,6 +325,7 @@ do_completion(UNUSED(Hookdef dummy), Com comppatinsert = ztrdup("menu"); forcelist = 0; haspattern = 0; + complistinword = 0; complistmax = getiparam("LISTMAX"); zsfree(complastprompt); complastprompt = ztrdup(((isset(ALWAYSLASTPROMPT) && zmult == 1) || Index: Src/Zle/complete.c =================================================================== RCS file: /cvsroot/zsh/zsh/Src/Zle/complete.c,v retrieving revision 1.44 diff -u -p -r1.44 complete.c --- Src/Zle/complete.c 15 Nov 2008 21:27:46 -0000 1.44 +++ Src/Zle/complete.c 9 Jan 2009 17:44:47 -0000 @@ -38,6 +38,7 @@ zlong compcurrent, complistmax; /**/ zlong complistlines, + complistinword, compignored; /**/ @@ -1146,6 +1147,7 @@ static struct compparam compkparams[] = GSU(unambig_pos_gsu) }, { "insert_positions", PM_SCALAR | PM_READONLY, NULL, GSU(insert_pos_gsu) }, + { "list_in_word", PM_INTEGER, VAL(complistinword), NULL }, { "list_max", PM_INTEGER, VAL(complistmax), NULL }, { "last_prompt", PM_SCALAR, VAL(complastprompt), NULL }, { "to_end", PM_SCALAR, VAL(comptoend), NULL }, @@ -1596,7 +1598,7 @@ setup_(UNUSED(Module m)) compvared = compqstack = NULL; complastprefix = ztrdup(""); complastsuffix = ztrdup(""); - complistmax = 0; + complistmax = complistinword = 0; hascompmod = 1; return 0; Index: Src/Zle/compresult.c =================================================================== RCS file: /cvsroot/zsh/zsh/Src/Zle/compresult.c,v retrieving revision 1.75 diff -u -p -r1.75 compresult.c --- Src/Zle/compresult.c 7 May 2008 08:53:40 -0000 1.75 +++ Src/Zle/compresult.c 9 Jan 2009 17:44:48 -0000 @@ -1309,21 +1309,23 @@ accept_last(void) lastbrbeg->str[l] = ','; lastbrbeg->str[l + 1] = '\0'; } else { - int l; - zlemetacs = minfo.pos + minfo.len + minfo.insc; - iremovesuffix(' ', 1); - l = zlemetacs; - zlemetacs = minfo.pos + minfo.len + minfo.insc - (*(minfo.cur))->qisl; - if (zlemetacs < l) - foredel(l - zlemetacs, CUT_RAW); - else if (zlemetacs > zlemetall) - zlemetacs = zlemetall; - inststrlen(" ", 1, 1); + if (!complistinword) { + int l; + + iremovesuffix(' ', 1); + l = zlemetacs; + zlemetacs = minfo.pos + minfo.len + minfo.insc - (*(minfo.cur))- >qisl; + if (zlemetacs < l) + foredel(l - zlemetacs, CUT_RAW); + else if (zlemetacs > zlemetall) + zlemetacs = zlemetall; + inststrlen(" ", 1, 1); + } minfo.insc = minfo.len = 0; minfo.pos = zlemetacs; minfo.we = 1; - } + } if (!wasmeta) unmetafy_line();