about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog37
-rw-r--r--Completion/Base/Utility/_arguments45
-rw-r--r--Doc/Zsh/builtins.yo3
-rw-r--r--Doc/Zsh/zle.yo29
-rw-r--r--Functions/VCS_Info/Backends/VCS_INFO_get_data_git7
-rw-r--r--Functions/Zle/bracketed-paste-url-magic42
-rw-r--r--Src/Zle/zle_main.c5
-rw-r--r--Src/Zle/zle_params.c24
-rw-r--r--Src/Zle/zle_thingy.c39
-rw-r--r--Src/exec.c2
-rw-r--r--Src/loop.c8
-rw-r--r--Src/text.c4
12 files changed, 204 insertions, 41 deletions
diff --git a/ChangeLog b/ChangeLog
index ea7bd2e98..b3a0a649f 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,40 @@
+2015-10-01  Mikael Magnusson  <mikachu@gmail.com>
+
+	* 36709: Doc/Zsh/zle.yo, Functions/Zle/bracketed-paste-url-magic,
+	Src/Zle/zle_main.c, Src/Zle/zle_params.c, Src/Zle/zle_thingy.c:
+	zle -f from inside widget to set flags and make yank start/end
+	zle params writable.
+
+	* 36692: Functions/Zle/bracketed-paste-url-magic: simpler
+	alternative for handling pasted urls
+
+2015-09-30  Barton E. Schaefer  <schaefer@zsh.org>
+
+	* users/20672: Src/text.c: missing "do" in gettext2() for "select"
+	
+	* 36707: Src/exec.c, Src/loop.c: distinguish ERR_RETURN value
+	of retflag so that execif() can ignore it in the test sublist
+
+	* cf. 36690: Doc/Zsh/builtins.yo: remove sentence fragment
+
+2015-09-30  Daniel Shahaf  <d.s@daniel.shahaf.name>
+
+	* 36725: Functions/VCS_Info/Backends/VCS_INFO_get_data_git:
+	vcs_info git: Compute %b correctly when "git am"-ing onto
+	detached heads.
+
+	* 36725: Functions/VCS_Info/Backends/VCS_INFO_get_data_git:
+	vcs_info git: Compute %b correctly when rebasing detached heads.
+
+	* 36725: Functions/VCS_Info/Backends/VCS_INFO_get_data_git:
+	vcs_info git: Compute %b correctly when merging to detached
+	heads.
+
+2015-09-30  Jun-ichi Takimoto <takimoto-j@kba.biglobe.ne.jp>
+
+	* 36697: Completion/Base/Utility/_arguments: handle options
+	of _arguments correctly
+
 2015-09-30  Peter Stephenson  <p.stephenson@samsung.com>
 
 	* Matthew Martin: 36693: Doc/Zsh/arith.yo: arithmetic rounds
diff --git a/Completion/Base/Utility/_arguments b/Completion/Base/Utility/_arguments
index 1f35e8d43..87fb20e6b 100644
--- a/Completion/Base/Utility/_arguments
+++ b/Completion/Base/Utility/_arguments
@@ -8,15 +8,33 @@ local oldcontext="$curcontext" hasopts rawret optarg singopt alwopt
 local setnormarg start rest
 local -a match mbegin mend
 
+subopts=()
+singopt=()
+while [[ "$1" = -([AMO]*|[CRSWnsw]) ]]; do
+  case "$1" in
+  -C)  usecc=yes; shift ;;
+  -O)  subopts=( "${(@P)2}" ); shift 2 ;;
+  -O*) subopts=( "${(@P)${1[3,-1]}}" ); shift ;;
+  -R)  rawret=yes; shift;;
+  -n)  setnormarg=yes; NORMARG=-1; shift;;
+  -w)  optarg=yes; shift;;
+  -W)  alwopt=arg; shift;;
+  -[Ss])  singopt+=( $1 ); shift;;
+  -[AM])  singopt+=( $1 $2 ); shift 2 ;;
+  -[AM]*) singopt+=( $1 ); shift ;;
+  esac
+done
+
+[[ $1 = ':' ]] && shift
+singopt+=( ':' )  # always end with ':' to indicate the end of options
+
+[[ "$PREFIX" = [-+] ]] && alwopt=arg
+
 long=$argv[(I)--]
 if (( long )); then
   local name tmp tmpargv
 
-  if [[ long -eq 1 ]]; then
-    tmpargv=()
-  else
-    tmpargv=( "${(@)argv[1,long-1]}" )
-  fi
+  tmpargv=( "${(@)argv[1,long-1]}" )  # optspec's before --, if any
 
   name=${~words[1]}
   [[ "$name" = [^/]*/* ]] && name="$PWD/$name"
@@ -290,23 +308,6 @@ if (( long )); then
   set -- "$tmpargv[@]" "${(@P)name}"
 fi
 
-subopts=()
-singopt=()
-while [[ "$1" = -(O*|[CRWnsw]) ]]; do
-  case "$1" in
-  -C)  usecc=yes; shift ;;
-  -O)  subopts=( "${(@P)2}" ); shift 2 ;;
-  -O*) subopts=( "${(@P)${1[3,-1]}}" ); shift ;;
-  -R)  rawret=yes; shift;;
-  -n)  setnormarg=yes; NORMARG=-1; shift;;
-  -w)  optarg=yes; shift;;
-  -s)  singopt=(-s); shift;;
-  -W)  alwopt=arg; shift;;
-  esac
-done
-
-[[ "$PREFIX" = [-+] ]] && alwopt=arg
-
 zstyle -s ":completion:${curcontext}:options" auto-description autod
 
 if (( $# )) && comparguments -i "$autod" "$singopt[@]" "$@"; then
diff --git a/Doc/Zsh/builtins.yo b/Doc/Zsh/builtins.yo
index 97c337071..85d1742f0 100644
--- a/Doc/Zsh/builtins.yo
+++ b/Doc/Zsh/builtins.yo
@@ -174,8 +174,7 @@ pattern are loaded.
 
 With the tt(-w) flag, the var(name)s are taken as names of files compiled
 with the tt(zcompile) builtin, and all functions defined in them are
-marked for autoloading.  Note this does not otherwise change the search
-order for 
+marked for autoloading.
 
 The flags tt(-z) and tt(-k) mark the function to be autoloaded using the
 zsh or ksh style, as if the option tt(KSH_AUTOLOAD) were unset or were
diff --git a/Doc/Zsh/zle.yo b/Doc/Zsh/zle.yo
index 7d95eb377..05bb14829 100644
--- a/Doc/Zsh/zle.yo
+++ b/Doc/Zsh/zle.yo
@@ -404,6 +404,7 @@ xitem(tt(zle) tt(-l) [ tt(-L) | tt(-a) ] [ var(string) ... ])
 xitem(tt(zle) tt(-D) var(widget) ...)
 xitem(tt(zle) tt(-A) var(old-widget) var(new-widget))
 xitem(tt(zle) tt(-N) var(widget) [ var(function) ])
+xitem(tt(zle) tt(-f) var(flag) [ var(flag)... ])
 xitem(tt(zle) tt(-C) var(widget) var(completion-widget) var(function))
 xitem(tt(zle) tt(-R) [ tt(-c) ] [ var(display-string) ] [ var(string) ... ])
 xitem(tt(zle) tt(-M) var(string))
@@ -464,6 +465,21 @@ ifzman(the section `Widgets' below)\
 ifnzman(noderef(Zle Widgets))\
 .
 )
+item(tt(-f) var(flag) [ var(flag)... ])(
+Set various flags on the running widget.  Possible values for var(flag) are:
+
+tt(yank) for indicating that the widget has yanked text into the buffer.
+If the widget is wrapping an existing internal widget, no further
+action is necessary, but if it has inserted the text manually, then it
+should also take care to set tt(YANK_START) and tt(YANK_END) correctly.
+tt(yankbefore) does the same but is used when the yanked text appears
+after the cursor.
+
+tt(kill) for indicating that text has been killed into the cutbuffer.
+When repeatedly invoking a kill widget, text is appended to the cutbuffer
+instead of replacing it, but when wrapping such widgets, it is necessary
+to call `tt(zle -f kill)' to retain this effect.
+)
 cindex(completion widgets, creating)
 item(tt(-C) var(widget) var(completion-widget) var(function))(
 Create a user-defined completion widget named var(widget). The 
@@ -1011,11 +1027,14 @@ vindex(YANK_END)
 xitem(tt(YANK_ACTIVE) (integer))
 xitem(tt(YANK_START) (integer))
 item(tt(YANK_END) (integer))(
-These three parameters indicate whether text has just been yanked (pasted)
-into the buffer.  tt(YANK_START) and tt(YANK_END) are in the same units as
-tt(CURSOR), and are only valid when tt(YANK_ACTIVE) is non-zero.
-
-All three are read-only.
+tt(YANK_ACTIVE) indicates whether text has just been yanked (pasted)
+into the buffer.  tt(YANK_START) and tt(YANK_END) give the location of
+the pasted text and are in the same units as tt(CURSOR).  They are only
+valid for reading when tt(YANK_ACTIVE) is non-zero.  They can also be
+assigned by widgets that insert text in a yank-like fashion, for example
+wrappers of tt(bracketed-paste).  See also tt(zle -f).
+
+tt(YANK_ACTIVE) is read-only.
 )
 vindex(ZLE_STATE)
 item(tt(ZLE_STATE) (scalar))(
diff --git a/Functions/VCS_Info/Backends/VCS_INFO_get_data_git b/Functions/VCS_Info/Backends/VCS_INFO_get_data_git
index 8ecc7c7f7..8664d510e 100644
--- a/Functions/VCS_Info/Backends/VCS_INFO_get_data_git
+++ b/Functions/VCS_Info/Backends/VCS_INFO_get_data_git
@@ -87,13 +87,18 @@ VCS_INFO_git_getbranch () {
         gitbranch="$(${(z)gitsymref} 2> /dev/null)"
         [[ -z ${gitbranch} ]] && [[ -r ${actiondir}/head-name ]] \
             && gitbranch="$(< ${actiondir}/head-name)"
+        [[ -z ${gitbranch} ]] && gitbranch="$(< ${gitdir}/ORIG_HEAD)"
 
     elif [[ -f "${gitdir}/MERGE_HEAD" ]] ; then
         gitbranch="$(${(z)gitsymref} 2> /dev/null)"
-        [[ -z ${gitbranch} ]] && gitbranch="$(< ${gitdir}/MERGE_HEAD)"
+        [[ -z ${gitbranch} ]] && gitbranch="$(< ${gitdir}/ORIG_HEAD)"
 
     elif [[ -d "${gitdir}/rebase-merge" ]] ; then
         gitbranch="$(< ${gitdir}/rebase-merge/head-name)"
+        if [[ $gitbranch == 'detached HEAD' ]]; then
+            # get a sha1
+            gitbranch="$(< ${gitdir}/rebase-merge/orig-head)"
+        fi
 
     elif [[ -d "${gitdir}/.dotest-merge" ]] ; then
         gitbranch="$(< ${gitdir}/.dotest-merge/head-name)"
diff --git a/Functions/Zle/bracketed-paste-url-magic b/Functions/Zle/bracketed-paste-url-magic
new file mode 100644
index 000000000..e1bea60d6
--- /dev/null
+++ b/Functions/Zle/bracketed-paste-url-magic
@@ -0,0 +1,42 @@
+# bracketed-paste-url-magic quotes pasted urls automatically, if the
+# paste exactly starts with a url, eg no spaces or other characters precede it
+#
+# If the numeric argument is provided (eg, pressing alt-0 or alt-1 in emacs mode,
+# or just the number by itself in vi command mode), then override the url detection
+# and if it was 0, never quote, and if it was 1, always quote.
+#
+# To use this widget, put this in your startup files (eg, .zshrc)
+#
+# autoload -Uz bracketed-paste-url-magic
+# zle -N bracketed-paste bracketed-paste-url-magic
+#
+# You can customize which schemas are to be quoted by using
+#
+# zstyle :bracketed-paste-url-magic schema http https ftp
+#
+# The default can be seen just below.
+
+local -a schema
+zstyle -a :bracketed-paste-url-magic schema schema || schema=(http https ftp ftps file ssh sftp)
+
+local wantquote=${NUMERIC:-0}
+local content
+local start=$#LBUFFER
+
+zle .$WIDGET -N content
+
+if ! (( $wantquote )); then
+  if [[ $content = (${(~j:|:)schema})://* ]]; then
+    wantquote=1
+  fi
+fi
+
+if (( $wantquote )); then
+  content=${(q-)content}
+fi
+
+LBUFFER+=$content
+
+YANK_START=$start
+YANK_END=$#LBUFFER
+zle -f yank
diff --git a/Src/Zle/zle_main.c b/Src/Zle/zle_main.c
index 992f152df..593d636cc 100644
--- a/Src/Zle/zle_main.c
+++ b/Src/Zle/zle_main.c
@@ -1402,7 +1402,8 @@ execzlefunc(Thingy func, char **args, int set_bindk)
 	    opts[XTRACE] = oxt;
 	    sfcontext = osc;
 	    endparamscope();
-	    lastcmd = 0;
+	    lastcmd = w->flags;
+	    w->flags = 0;
 	    r = 1;
 	    redup(osi, 0);
 	}
@@ -1981,7 +1982,7 @@ zle_main_entry(int cmd, va_list ap)
 static struct builtin bintab[] = {
     BUILTIN("bindkey", 0, bin_bindkey, 0, -1, 0, "evaM:ldDANmrsLRp", NULL),
     BUILTIN("vared",   0, bin_vared,   1,  1, 0, "aAcef:hi:M:m:p:r:t:", NULL),
-    BUILTIN("zle",     0, bin_zle,     0, -1, 0, "aAcCDFgGIKlLmMNrRTUw", NULL),
+    BUILTIN("zle",     0, bin_zle,     0, -1, 0, "aAcCDfFgGIKlLmMNrRTUw", NULL),
 };
 
 /* The order of the entries in this table has to match the *HOOK
diff --git a/Src/Zle/zle_params.c b/Src/Zle/zle_params.c
index 000bc388c..b5bb288f1 100644
--- a/Src/Zle/zle_params.c
+++ b/Src/Zle/zle_params.c
@@ -98,9 +98,9 @@ static const struct gsu_integer undo_change_no_gsu =
 static const struct gsu_integer undo_limit_no_gsu =
 { get_undo_limit_change, set_undo_limit_change, zleunsetfn };
 static const struct gsu_integer yankstart_gsu =
-{ get_yankstart, NULL, zleunsetfn };
+{ get_yankstart, set_yankstart, zleunsetfn };
 static const struct gsu_integer yankend_gsu =
-{ get_yankend, NULL, zleunsetfn };
+{ get_yankend, set_yankend, zleunsetfn };
 static const struct gsu_integer yankactive_gsu =
 { get_yankactive, NULL, zleunsetfn };
 
@@ -149,8 +149,8 @@ static struct zleparam {
     { "WIDGET", PM_SCALAR | PM_READONLY, GSU(widget_gsu), NULL },
     { "WIDGETFUNC", PM_SCALAR | PM_READONLY, GSU(widgetfunc_gsu), NULL },
     { "WIDGETSTYLE", PM_SCALAR | PM_READONLY, GSU(widgetstyle_gsu), NULL },
-    { "YANK_START", PM_INTEGER | PM_READONLY, GSU(yankstart_gsu), NULL },
-    { "YANK_END", PM_INTEGER | PM_READONLY, GSU(yankend_gsu), NULL },
+    { "YANK_START", PM_INTEGER, GSU(yankstart_gsu), NULL },
+    { "YANK_END", PM_INTEGER, GSU(yankend_gsu), NULL },
     { "YANK_ACTIVE", PM_INTEGER | PM_READONLY, GSU(yankactive_gsu), NULL },
     { "ZLE_STATE", PM_SCALAR | PM_READONLY, GSU(zle_state_gsu), NULL },
     { NULL, 0, NULL, NULL }
@@ -503,7 +503,21 @@ get_yankend(UNUSED(Param pm))
 static zlong
 get_yankactive(UNUSED(Param pm))
 {
-    return lastcmd & ZLE_YANK;
+    return !!(lastcmd & ZLE_YANK) + !!(lastcmd & ZLE_YANKAFTER);
+}
+
+/**/
+static void
+set_yankstart(UNUSED(Param pm), zlong i)
+{
+    yankb = i;
+}
+
+/**/
+static void
+set_yankend(UNUSED(Param pm), zlong i)
+{
+    yanke = i;
 }
 
 /**/
diff --git a/Src/Zle/zle_thingy.c b/Src/Zle/zle_thingy.c
index da3a6d458..3963d7eaf 100644
--- a/Src/Zle/zle_thingy.c
+++ b/Src/Zle/zle_thingy.c
@@ -352,6 +352,7 @@ bin_zle(char *name, char **args, Options ops, UNUSED(int func))
 	{ 'U', bin_zle_unget, 1, 1 },
 	{ 'K', bin_zle_keymap, 1, 1 },
 	{ 'I', bin_zle_invalidate, 0, 0 },
+	{ 'f', bin_zle_flags, 1, -1 },
 	{ 'F', bin_zle_fd, 0, 2 },
 	{ 'T', bin_zle_transform, 0, 2},
 	{ 0,   bin_zle_call, 0, -1 },
@@ -625,6 +626,44 @@ bin_zle_complete(char *name, char **args, UNUSED(Options ops), UNUSED(char func)
 
 /**/
 static int
+bin_zle_flags(char *name, char **args, UNUSED(Options ops), UNUSED(char func))
+{
+    char **flag;
+
+    if (!zle_usable()) {
+	zwarnnam(name, "can only set flags from a widget");
+	return 1;
+    }
+
+    if (bindk) {
+	Widget w = bindk->widget;
+	if (w) {
+	    for (flag = args; *flag; flag++) {
+		if (!strcmp(*flag, "yank")) {
+		    w->flags |= ZLE_YANKAFTER;
+		} else if (!strcmp(*flag, "yankbefore"))
+		    w->flags |= ZLE_YANKBEFORE;
+		else if (!strcmp(*flag, "kill"))
+		    w->flags |= ZLE_KILL;
+		/*
+		 * These won't do anything yet, because of how execzlefunc
+		 * handles user widgets
+		} else if (!strcmp(*flag, "menucmp"))
+		    w->flags |= ZLE_MENUCMP;
+		else if (!strcmp(*flag, "linemove"))
+		    w->flags |= ZLE_LINEMOVE;
+		else if (!strcmp(*flag, "keepsuffix"))
+		    w->flags |= ZLE_KEEPSUFFIX;
+		*/
+		else
+		    zwarnnam(name, "invalid flag `%s' given to zle -f", *flag);
+	    }
+	}
+    }
+}
+
+/**/
+static int
 zle_usable()
 {
     return zleactive && !incompctlfunc && !incompfunc
diff --git a/Src/exec.c b/Src/exec.c
index da808d6f1..154bbb8db 100644
--- a/Src/exec.c
+++ b/Src/exec.c
@@ -1408,7 +1408,7 @@ sublist_done:
 			exit(lastval);
 		}
 		if (errreturn) {
-		    retflag = 1;
+		    retflag = 2;
 		    breaks = loops;
 		}
 	    }
diff --git a/Src/loop.c b/Src/loop.c
index 4def9b652..7d1528efe 100644
--- a/Src/loop.c
+++ b/Src/loop.c
@@ -552,8 +552,12 @@ execif(Estate state, int do_exec)
 	    run = 1;
 	    break;
 	}
-	if (retflag)
-	    break;
+	if (retflag) {
+	    if (retflag == 2)
+		retflag = 0; /* Never ERR_RETURN here */
+	    else
+		break;
+	}
 	s = 1;
 	state->pc = next;
     }
diff --git a/Src/text.c b/Src/text.c
index 7e65f43a4..9421d70ce 100644
--- a/Src/text.c
+++ b/Src/text.c
@@ -632,8 +632,10 @@ gettext2(Estate state)
 		    taddstr(" in ");
 		    taddlist(state, *state->pc++);
 		}
-		tindent++;
 		taddnl(0);
+		taddstr("do");
+		taddnl(0);
+		tindent++;
 		tpush(code, 1);
 	    } else {
 		dec_tindent();