From mboxrd@z Thu Jan 1 00:00:00 1970 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on inbox.vuxu.org X-Spam-Level: X-Spam-Status: No, score=-3.4 required=5.0 tests=DKIM_SIGNED,DKIM_VALID, DKIM_VALID_AU,MAILING_LIST_MULTI,RCVD_IN_DNSWL_MED,UNPARSEABLE_RELAY autolearn=ham autolearn_force=no version=3.4.4 Received: (qmail 27977 invoked from network); 21 Apr 2021 21:27:43 -0000 Received: from zero.zsh.org (2a02:898:31:0:48:4558:7a:7368) by inbox.vuxu.org with ESMTPUTF8; 21 Apr 2021 21:27:43 -0000 ARC-Seal: i=1; cv=none; a=rsa-sha256; d=zsh.org; s=rsa-20200801; t=1619040463; b=UvN4wsY9XHCQwxzifKQKUAlBmMLLQdS65elmZkHtc+YiWEJpcAHwBdH4fca3T4Dg8FiJFgO1fb 5aIjdgDoJX/pOrVka/w8rIDJToevNbvrqCpZOn02Pxnz64rmLqUbmbM/GEYiY7eLXxWaGj6uAY KZkjofNbS9CZiCcxnE6zADXn7GISzrunhOPo5G80PFBjxMTmYSMexyh6u5ATdrRXoH2Uns+UP7 lUqEVc/Z9Q4klTCLPg2TK5wfYDe1CcjdNsvuUhKvif7Tq3jsJf+3jAEFyMdYwhwNpGEbnjN/AM cm3IsNGpmolYfbb+SGE6xw9QjSW+iSDbF/kNdA2C51N1mA==; ARC-Authentication-Results: i=1; zsh.org; iprev=pass (out1-smtp.messagingengine.com) smtp.remote-ip=66.111.4.25; dkim=pass header.d=daniel.shahaf.name header.s=fm3 header.a=rsa-sha256; dkim=pass header.d=messagingengine.com header.s=fm2 header.a=rsa-sha256; dmarc=none header.from=daniel.shahaf.name; arc=none ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed; d=zsh.org; s=rsa-20200801; t=1619040463; bh=ln4m6BPG/5Ip2PdGQ2la7kBzh5ciS8WuLQaBgGAb2e8=; h=List-Archive:List-Owner:List-Post:List-Unsubscribe:List-Subscribe:List-Help: List-Id:Sender:In-Reply-To:Content-Transfer-Encoding:Content-Type: MIME-Version:References:Message-ID:Subject:Cc:To:From:Date:DKIM-Signature: DKIM-Signature:DKIM-Signature; b=U5peou1Of9sr6hWhT15Zu21BgeHlHRKVDH70vOjgS5qzZvvwFuNQ39tdrG2iGjqobeVTTXoGR3 FbAu2NJY3ocp9rK18F7QYAAUtRyWDO7FlOoy9IK44m+p6qYB2xOgxQ7K64gXBIcreDNp3zrZ/+ 5r6x2kvNRUP9ZNcjAM3Oj6JvksqAP8WBW8VRjehlTqnJLYHC3uh7qO2stZLjWD/EkTygq0Jk+b 5VLQVyfPIwnFHga4am4wR07Hm4dO9kLGv7Xu+jQyEIMsPZD0UHHAwasS1VVQ5oD+BNOfs3jUS4 k7D53Y5fMaPis89knfclxll/NxhDPlcumR/DLeO1KRsj1w==; DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=zsh.org; s=rsa-20200801; h=List-Archive:List-Owner:List-Post:List-Unsubscribe: List-Subscribe:List-Help:List-Id:Sender:In-Reply-To:Content-Transfer-Encoding :Content-Type:MIME-Version:References:Message-ID:Subject:Cc:To:From:Date: Reply-To:Content-ID:Content-Description:Resent-Date:Resent-From:Resent-Sender :Resent-To:Resent-Cc:Resent-Message-ID; bh=gNgikSuw685jNDhhIWq70PPmIWdF8+BlVC+zCgl6Sek=; b=pwNOfkV2VF/575086LO6S0MHxX PeWbuTN4tegD7TCb9tpo4yw15Zr1TWk1IQATyYYLH/ZJS4qFHqAXjBZoATYiysNcS9YPBFkF8QnmI vBEItGEJI7uQsXgkeyz2C23M+RjRUW/9Tm6Q57L6tyBSLnfvuLfKF4SMxyB+1KBUG2cxap82U/FAx V8WO9sCjIHvwGLzEtsihf93G1Xhq1RsOKOnGB2Sg3ed0I/vhmjY1SHoJH/sIpn4deQkp4QuIRsSCW YZ72OyeIhFBU9fJzUlOHp6kONX8bijIMzCLvRQ3OkyNYr8bSiSOSElrk2Nog013v6RoTB0mIAKxMr FkZx9AQA==; Received: from authenticated user by zero.zsh.org with local id 1lZKNq-0002pX-J7; Wed, 21 Apr 2021 21:27:42 +0000 Authentication-Results: zsh.org; iprev=pass (out1-smtp.messagingengine.com) smtp.remote-ip=66.111.4.25; dkim=pass header.d=daniel.shahaf.name header.s=fm3 header.a=rsa-sha256; dkim=pass header.d=messagingengine.com header.s=fm2 header.a=rsa-sha256; dmarc=none header.from=daniel.shahaf.name; arc=none Received: from out1-smtp.messagingengine.com ([66.111.4.25]:33055) by zero.zsh.org with esmtps (TLS1.3:TLS_AES_256_GCM_SHA384:256) id 1lZKNW-0002a3-Bm; Wed, 21 Apr 2021 21:27:23 +0000 Received: from compute3.internal (compute3.nyi.internal [10.202.2.43]) by mailout.nyi.internal (Postfix) with ESMTP id E10035C0124; Wed, 21 Apr 2021 17:27:20 -0400 (EDT) Received: from mailfrontend2 ([10.202.2.163]) by compute3.internal (MEProxy); Wed, 21 Apr 2021 17:27:20 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= daniel.shahaf.name; h=date:from:to:cc:subject:message-id :references:mime-version:content-type:content-transfer-encoding :in-reply-to; s=fm3; bh=gNgikSuw685jNDhhIWq70PPmIWdF8+BlVC+zCgl6 Sek=; b=usSmoyL1RcrKlbee6g/qYUxYw+Hhxpkk50ZsmW7STDLqUWRz5B6pngw1 4E5/+GLO+iM5Z8dZ4RpSkUSEbMC4jaOYHr7mFpCq4umN6FMlSmX5OH7QCeMfpl1+ rQNo9/D5gKtlCURYIG+Ds5xtX7PgmoKwjC53w6ZAWuxmxer/WJl9l8aUZaw+MnTx ZJNIhkt/XfWLyvZt+r1V+fifJeeW0SVou++gtxLyI95mZK9tLEordfOWY4aFuRZZ pVePpazLOXDHuOEeSoyxWF4Wt5mwChVVu71CmMQvXB7XUtIO3H6leHCps5evEWg5 PWcEWGCAZFGuJddNwlWpU1jiJ7gEkg== DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= messagingengine.com; h=cc:content-transfer-encoding:content-type :date:from:in-reply-to:message-id:mime-version:references :subject:to:x-me-proxy:x-me-proxy:x-me-sender:x-me-sender :x-sasl-enc; s=fm2; bh=gNgikSuw685jNDhhIWq70PPmIWdF8+BlVC+zCgl6S ek=; b=a21MHV7B6ODVwWixXr7dztXAA7vTQLErjYN7bJ87idFn2HjUT4aNs46iC J5sntW1E6A+zpOnWEXFhiSblnLGW84BcUSRHXt8479J3edHY11L4LxvoXLwhFB9Z m+F3fWbXvoAumx6IY04vLwnUyGikMZRaIl5IB43J+FLO27d69VftOd0Fp/nd40uN JHRMgEnqfwP/rfQuUTt9d2yekGN1lKPAEkTEg03hqVRMF4FLUmTs/HcJh4zXTXmI JnllJR4SAY3G7Qen0JYRy+6a4vEkWz33bMrUUyX3FcnOZ5rasG/j094REKe49EAX HCs5OvCZNFvLXXOP9xZGE2Nrkyxfg== X-ME-Sender: X-ME-Proxy-Cause: gggruggvucftvghtrhhoucdtuddrgeduledrvddtkedgudeifecutefuodetggdotefrod ftvfcurfhrohhfihhlvgemucfhrghsthforghilhdpqfgfvfdpuffrtefokffrpgfnqfgh necuuegrihhlohhuthemuceftddtnecusecvtfgvtghiphhivghnthhsucdlqddutddtmd enucfjughrpeffhffvuffkfhggtggugfgjfgesthektddttderudenucfhrhhomhepffgr nhhivghlucfuhhgrhhgrfhcuoegurdhssegurghnihgvlhdrshhhrghhrghfrdhnrghmvg eqnecuggftrfgrthhtvghrnhepgfelhedtffeuhfegueelfeffjeegtddtleehvddvueei hfevgfdvgffhvedvkeetnecukfhppedutdelrdeiiedrieefrddvfedtnecuvehluhhsth gvrhfuihiivgeptdenucfrrghrrghmpehmrghilhhfrhhomhepugdrshesuggrnhhivghl rdhshhgrhhgrfhdrnhgrmhgv X-ME-Proxy: Received: from tarpaulin.shahaf.local2 (bzq-109-66-63-230.red.bezeqint.net [109.66.63.230]) by mail.messagingengine.com (Postfix) with ESMTPA id 3B03B108005B; Wed, 21 Apr 2021 17:27:20 -0400 (EDT) Received: by tarpaulin.shahaf.local2 (Postfix, from userid 1005) id 4FQYY13P9Wz3Mt; Wed, 21 Apr 2021 21:27:17 +0000 (UTC) Date: Wed, 21 Apr 2021 21:27:17 +0000 From: Daniel Shahaf To: Marlon Richert Cc: Zsh hackers list Subject: Re: [PATCH] Add execute-command() widget function (was Re: [RFC][PATCH] Add change-directory() widget function) Message-ID: <20210421212717.GE21343@tarpaulin.shahaf.local2> References: <95CDA630-4EE5-4003-8D9C-CCCB9A47F109@gmail.com> <4D587C0C-EB5F-4A58-A0AE-D45E43F432CD@gmail.com> MIME-Version: 1.0 Content-Type: text/plain; charset=iso-8859-1 Content-Disposition: inline Content-Transfer-Encoding: 8bit In-Reply-To: User-Agent: Mutt/1.10.1 (2018-07-13) X-Seq: 48647 Archived-At: X-Loop: zsh-workers@zsh.org Errors-To: zsh-workers-owner@zsh.org Precedence: list Precedence: bulk Sender: zsh-workers-request@zsh.org X-no-archive: yes List-Id: List-Help: List-Subscribe: List-Unsubscribe: List-Post: List-Owner: List-Archive: [ Aside: does anyone use zyodl.vim? I see I have some local mods and not sure how much to prioritize cleaning them up and pushing them. ] Marlon Richert wrote on Wed, Apr 21, 2021 at 14:37:28 +0300: > Thank you both (Bart & Daniel) for your input. I added better safeguards against the non-PS1 cases, rewrote the function to be more generic and added comments. New patch attached. Again, please wrap long lines in your prose. This is the third time you are being asked to do so. > Subject: [PATCH] Add execute-command() widget function > > +++ Doc/Zsh/contrib.yo > @@ -2502,6 +2502,32 @@ arguments: > > example(zstyle :zle:edit-command-line editor gvim -f) > ) > +tindex(execute-command) > +item(tt(execute-command))( +1 on the generalization with respect to the previous iteration. > +This function lets you implement widgets that can execute arbitrary commands > +without losing the current command line, in a fashion similar to the > +tt(run-help) and tt(which-command) widgets (see > +ifzman(the subsection Miscellaneous in zmanref(zshzle))\ The title "Miscellaneous" deserves markup and/or punctuation, not merely capitalization. Good catch on retaining the line continuation. > +ifnzman(noderef(Miscellaneous))). More precisely, it s/it/it:|it+DASH()-/ ? > +enumeration( > +myeit() pushes the buffer onto the buffer stack, > +myeit() executes the supplied arguments, then > +myeit() lets the ZLE pop the buffer off the top of the buffer stack and load > + it into the editing buffer. Should the precise implementation be documented here? If the implementation strategy is seen as an API promise, it would be more difficult to change it later. Describing what the function actually _does_ (as distinguished from what sort of context it's typically used in) is of course relevant; cf. [workers/45152, fifth hunk]. «myeit()» is defined in Etc/FAQ.yo and isn't a standard yodl macro, so it'll just cause a compile error here. Yes, it's not ideal that the documentation isn't all written in the same dialect. > +) > + > +You can use this, for example, to create key bindings that let you instantly > +change directories, even while in the middle of typing another command: > + > +example(autoload -Uz execute-command > +setopt autopushd pushdminus pushdsilent AUTO_PUSHD is set but not used. As to PUSHD_MINUS and PUSHD_SILENT, it would be better to give an example doesn't change them from their default values. That's again 45149, which I mentioned just yesterday. > +zle -N cd-upward ; cd-upward() { execute-command cd .. } > +zle -N cd-backward; cd-backward() { execute-command pushd -1 } > +zle -N cd-forward ; cd-forward() { execute-command pushd +0 } s/()/+LPAR()+RPAR()/ so they don't look like yodl macros (and potentially throw build-time warnings). (For Vim users, the custom ftplugin sets up concealing which does the reverse replacement while editing.) Use a «--» guard on the second one, for forward compatibility with future --options to execute-command? In general, commands are either passed as a single string and then parsed by a shell, or are passed as an array and then kept this way until execve(3) time. Here, the implementation uses «BUFFER="$*"» but the command is passed as an array; this breaks that pattern. Either the commands should be passed as a single string, or the assignment to BUFFER should be changed so stuff like «execute-command print -l 'foo bar'» would work as intended. Contrast with _call_program, which doesn't follow that pattern, and indeed «_call_program print-foo-bar print -l 'foo bar'» is wrong and, I suspect, not uncommon. Consider adding index entries for cd-upward, cd-backward, cd-forward here. > +bindkey '^[^[[A' cd-upward; bindkey '^[^[OA' cd-upward -1 on using random escape sequences without any explanation of what they do and how to find them out. Can the symbolic names of these escape sequences be used here? At least . % for k v in "${(@kv)terminfo}" ; [[ $v == (*\[A*|*OA*) ]] && echo $k cuu1 kcuu1 . if we don't have anything more human-readable than those. (I think this was discussed somewhere in the "default zshrc" thread so I won't elaborate here.) > +bindkey '^[-' cd-backward > +bindkey '^[=' cd-forward) What makes it safe to assume the reader will know what to press to invoke these? There are no relevant matches of «alt» (as a whole word) in the manual. > +) > tindex(expand-absolute-path) > item(tt(expand-absolute-path))( > Expand the file name under the cursor to an absolute path, resolving > diff --git a/Functions/Zle/execute-command b/Functions/Zle/execute-command > new file mode 100644 > index 000000000..04fccf176 > --- /dev/null > +++ b/Functions/Zle/execute-command > @@ -0,0 +1,54 @@ > +# This function lets you implement widgets that can execute arbitrary commands > +# without losing the current command line, in a fashion similar to the > +# 'run-help' and 'which-command' widgets. You can use this, for example, to > +# create key bindings that let you instantly change directories, even while in > +# the middle of typing another command: > +# > +# autoload -Uz execute-command > +# setopt autopushd pushdminus pushdsilent > +# zle -N cd-upward ; cd-upward() { execute-command cd .. } > +# zle -N cd-backward; cd-backward() { execute-command pushd -1 } > +# zle -N cd-forward ; cd-forward() { execute-command pushd +0 } > +# bindkey '^[^[[A' cd-upward; bindkey '^[^[OA' cd-upward > +# bindkey '^[-' cd-backward > +# bindkey '^[=' cd-forward DRY. This information is in the manual, so it isn't needed here. > +# > + > +case $CONTEXT in > + ( start ) # PS1 My $EDITOR thanks your use of balanced parentheses. > + ;; > + ( cont ) # PS2 > + # Add a one-time hook that will re-run this widget at the top-level prompt. > + autoload -Uz add-zle-hook-widget > + local hook=line-init > + local func=:$hook:$WIDGET > + eval "$func() { Concerned about namespace collisions here. > + # Make sure we don't run twice. > + add-zle-hook-widget -d $hook $func > + > + # Don't leave anything behind. > + zle -D $func > + unfunction $func > + > + zle $WIDGET > + }" Use ${(q)} as needed. > + add-zle-hook-widget $hook $func > + > + # Move the entire current multiline construct into the editor buffer. This > + # function is then aborted and we return to the top-level prompt, which > + # triggers the hook above. > + zle .push-line-or-edit > + return # Not actually necessary, but for clarity's sake How is it not necessary? If control flow continued past the «esac», code would be executed. > + ;; > + ( * ) > + # We don't want this to be used in a select loop or in vared. If the user presses the bound key at the select prompt or in vared, why should the library function disregard that? Shouldn't this behaviour be changed? Or failing that, documented? > + return 1 > + ;; > +esac > + > +# Push the current buffer onto the buffer stack and clear the buffer. The ZLE > +# will auto-restore it at the next top-level prompt. > +zle .push-line > + > +BUFFER="$*" > +zle .accept-line > -- > 2.31.1 > > >