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=-1.0 required=5.0 tests=MAILING_LIST_MULTI, RCVD_IN_DNSWL_NONE autolearn=ham autolearn_force=no version=3.4.4 Received: (qmail 5459 invoked from network); 22 May 2020 22:25:10 -0000 Received: from ns1.primenet.com.au (HELO primenet.com.au) (203.24.36.2) by inbox.vuxu.org with ESMTPUTF8; 22 May 2020 22:25:10 -0000 Received: (qmail 11440 invoked by alias); 22 May 2020 22:25:04 -0000 Mailing-List: contact zsh-workers-help@zsh.org; run by ezmlm Precedence: bulk X-No-Archive: yes List-Id: Zsh Workers List List-Post: List-Help: List-Unsubscribe: X-Seq: 45897 Received: (qmail 29434 invoked by uid 1010); 22 May 2020 22:25:04 -0000 X-Qmail-Scanner-Diagnostics: from mail-ot1-f47.google.com by f.primenet.com.au (envelope-from , uid 7791) with qmail-scanner-2.11 (clamdscan: 0.102.3/25814. spamassassin: 3.4.4. Clear:RC:0(209.85.210.47):SA:0(-1.9/5.0):. Processed in 3.661149 secs); 22 May 2020 22:25:04 -0000 X-Envelope-From: schaefer@brasslantern.com X-Qmail-Scanner-Mime-Attachments: | X-Qmail-Scanner-Zip-Files: | Received-SPF: pass (ns1.primenet.com.au: SPF record at _netblocks.google.com designates 209.85.210.47 as permitted sender) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:mime-version:from:date:message-id:subject:to; bh=Q78ZlmsbAM4SBM2j5g9pYI10VEdw17YX5h2f1xoNwhM=; b=rilcWwfbC4ft5jJFFdN8mkgVgP9/ASzlFo0pxuEsksXZKQa9H63jtVsBMjZz3rcKHw pyyRVFtPw3hnFW5cbz8WEVzHS6T7vUNJ6lmnGRJ9O04KtRHA3UJmgchK/vLJVLxneslB j7KEQnZTlrcsFExUVTLI4DFtYQOTleWfgbAVirFOxYpV/b4HsGvJmZw+RIisjBYV8Qp2 DPZD9Xlenp5nFdySZD+Erdb1+lgFwY4M4YM2SBdPV611YBWuwnNpKmSxWMdQKJhgMmtz Lp7uUstqZl8hdKrXqbcSACHLt2gb5QVFuX9obv8sp/6X8nc/ZFEcVT6sC6kRmcgXBmPa vMeA== X-Gm-Message-State: AOAM530sKoIOklDalOTMKm3DkNMFcoYA8cEFTYQdDLpDe8DT6dy1962P i/sJwCeYzXh3DtRxPu3+lx3R3JdVd/o5NSCHBvPMy4FFc5e1Hw== X-Google-Smtp-Source: ABdhPJwW0vNPVkE5BjfP2Z978/UBAgxL0MVVTU2KRoJC8srd8naC4yI+Yp+nz4Vbp/o/ofmRUVVodSr39HvKAlyx37M= X-Received: by 2002:a9d:20e7:: with SMTP id x94mr13405445ota.260.1590186265612; Fri, 22 May 2020 15:24:25 -0700 (PDT) MIME-Version: 1.0 From: Bart Schaefer Date: Fri, 22 May 2020 15:24:14 -0700 Message-ID: Subject: Editing the history in the shell To: Zsh hackers list Content-Type: multipart/mixed; boundary="0000000000007d4bff05a64417ec" --0000000000007d4bff05a64417ec Content-Type: text/plain; charset="UTF-8" This is not quite a finished product yet (for one thing, no doc) but it demonstrates most of the interesting ideas. The patch implements "zed -h" which loads the history into vared and arranges to replace the existing history with that before it exits. This does NOT solve Markus' complaint about the history numbers, they increase by the number of entries output by the editor. It makes no attempt to account for various history options, so those may change the final result if they affect "print -s". It also handles "zed -h filename" which loads that file and saves it back again rather than alter the current shell history. There is a glitch currently that may lose the most recent line from the file when it is loaded (not when it is saved), which seems to be the fault of "fc -p". There are probably other bugs, I've tested only minimally. Some unanswered questions: 1) Should it be possible to edit empty events into the history? Currently empty lines are removed, but changing to IFS=$'\n\n' would preserve them (thanks Oliver for the idea) 2) Should "vared -h" be used? I'm inclined to say "no" because the behavior becomes a bit strange; the entire content of the variable is treated as one "history event" when navigating, i.e., if you move up from the top (oldest) history event, the whole history disappears and is replaced by the single newest event. 3) If the file for "zed -h filename" does not exist, should the editor be populated from the current shell history? Currently the editor starts empty. Patch both inlined and attached in case gmail garbles the lines. I followed the existing coding style of "zed", which is a little quirky. diff --git a/Functions/Misc/zed b/Functions/Misc/zed index 9eb4b2d..952e1a9 100644 --- a/Functions/Misc/zed +++ b/Functions/Misc/zed @@ -5,16 +5,18 @@ # Edit small files with the command line editor. # Use ^X^W to save (or ZZ in vicmd mode), ^C to abort. # Option -f: edit shell functions. (Also if called as fned.) +# Option -h: edit shell history. (Also if called as histed.) setopt localoptions noksharrays local var opts zed_file_name # We do not want timeout while we are editing a file -integer TMOUT=0 okargs=1 fun bind +integer TMOUT=0 okargs=1 fun hist bind local -a expand -zparseopts -D -A opts f b x: +zparseopts -D -A opts f h b x: fun=$+opts[-f] +hist=$+opts[-h] bind=$+opts[-b] if [[ $opts[-x] == <-> ]]; then expand=(-x $opts[-x]) @@ -24,12 +26,15 @@ elif (( $+opts[-x] )); then fi [[ $0 = fned ]] && fun=1 +[[ $0 = histed ]] && hist=1 (( bind )) && okargs=0 +(( hist && $# <= 2 )) && okargs=$# -if (( $# != okargs )); then +if (( $# != okargs || fun + hist > 1 )); then echo 'Usage: zed filename zed -f [ -x N ] function +zed -h [ filename [ size ] ] zed -b' >&2 return 1 fi @@ -133,6 +138,17 @@ if ((fun)) then }" fi vared -M zed -m zed-vicmd -i __zed_init var && eval function "$var" +elif ((hist)) then + [[ -n $1 ]] && { fc -p -a $1 ${2:-$({ wc -l <$1 } 2>/dev/null)} || return } + var=( "${(@Oav)history:gs/\\/\\\\}" ) + IFS=$'\n' vared -M zed -m zed-vicmd -i __zed_init var + if (( ? )); then + [[ -n $1 ]] && unset HISTFILE + else + hist=$HISTSIZE; HISTSIZE=0; fc -R /dev/null; HISTSIZE=$hist + for (( hist=1; hist <= $#var; hist++ )) print -s "$var[hist]" + [[ -n $1 ]] && SAVEHIST=$#var # Resets on function exit + fi else zed_file_name=$1 [[ -f $1 ]] && var="$(<$1)" --0000000000007d4bff05a64417ec Content-Type: text/plain; charset="US-ASCII"; name="zed-h.txt" Content-Disposition: attachment; filename="zed-h.txt" Content-Transfer-Encoding: base64 Content-ID: X-Attachment-Id: f_kairamzc0 ZGlmZiAtLWdpdCBhL0Z1bmN0aW9ucy9NaXNjL3plZCBiL0Z1bmN0aW9ucy9NaXNjL3plZAppbmRl eCA5ZWI0YjJkLi45NTJlMWE5IDEwMDY0NAotLS0gYS9GdW5jdGlvbnMvTWlzYy96ZWQKKysrIGIv RnVuY3Rpb25zL01pc2MvemVkCkBAIC01LDE2ICs1LDE4IEBACiAjIEVkaXQgc21hbGwgZmlsZXMg d2l0aCB0aGUgY29tbWFuZCBsaW5lIGVkaXRvci4KICMgVXNlIF5YXlcgdG8gc2F2ZSAob3IgWlog aW4gdmljbWQgbW9kZSksIF5DIHRvIGFib3J0LgogIyBPcHRpb24gLWY6IGVkaXQgc2hlbGwgZnVu Y3Rpb25zLiAgKEFsc28gaWYgY2FsbGVkIGFzIGZuZWQuKQorIyBPcHRpb24gLWg6IGVkaXQgc2hl bGwgaGlzdG9yeS4gIChBbHNvIGlmIGNhbGxlZCBhcyBoaXN0ZWQuKQogCiBzZXRvcHQgbG9jYWxv cHRpb25zIG5va3NoYXJyYXlzCiAKIGxvY2FsIHZhciBvcHRzIHplZF9maWxlX25hbWUKICMgV2Ug ZG8gbm90IHdhbnQgdGltZW91dCB3aGlsZSB3ZSBhcmUgZWRpdGluZyBhIGZpbGUKLWludGVnZXIg VE1PVVQ9MCBva2FyZ3M9MSBmdW4gYmluZAoraW50ZWdlciBUTU9VVD0wIG9rYXJncz0xIGZ1biBo aXN0IGJpbmQKIGxvY2FsIC1hIGV4cGFuZAogCi16cGFyc2VvcHRzIC1EIC1BIG9wdHMgZiBiIHg6 Cit6cGFyc2VvcHRzIC1EIC1BIG9wdHMgZiBoIGIgeDoKIGZ1bj0kK29wdHNbLWZdCitoaXN0PSQr b3B0c1staF0KIGJpbmQ9JCtvcHRzWy1iXQogaWYgW1sgJG9wdHNbLXhdID09IDwtPiBdXTsgdGhl bgogICBleHBhbmQ9KC14ICRvcHRzWy14XSkKQEAgLTI0LDEyICsyNiwxNSBAQCBlbGlmICgoICQr b3B0c1steF0gKSk7IHRoZW4KIGZpCiAKIFtbICQwID0gZm5lZCBdXSAmJiBmdW49MQorW1sgJDAg PSBoaXN0ZWQgXV0gJiYgaGlzdD0xCiAoKCBiaW5kICkpICYmIG9rYXJncz0wCisoKCBoaXN0ICYm ICQjIDw9IDIgKSkgJiYgb2thcmdzPSQjCiAKLWlmICgoICQjICE9IG9rYXJncyApKTsgdGhlbgor aWYgKCggJCMgIT0gb2thcmdzIHx8IGZ1biArIGhpc3QgPiAxICkpOyB0aGVuCiAgICAgZWNobyAn VXNhZ2U6CiB6ZWQgZmlsZW5hbWUKIHplZCAtZiBbIC14IE4gXSBmdW5jdGlvbgoremVkIC1oIFsg ZmlsZW5hbWUgWyBzaXplIF0gXQogemVkIC1iJyA+JjIKICAgICByZXR1cm4gMQogZmkKQEAgLTEz Myw2ICsxMzgsMTcgQEAgaWYgKChmdW4pKSB0aGVuCiB9IgogICBmaQogICB2YXJlZCAtTSB6ZWQg LW0gemVkLXZpY21kIC1pIF9femVkX2luaXQgdmFyICYmIGV2YWwgZnVuY3Rpb24gIiR2YXIiCitl bGlmICgoaGlzdCkpIHRoZW4KKyAgW1sgLW4gJDEgXV0gJiYgeyBmYyAtcCAtYSAkMSAkezI6LSQo eyB3YyAtbCA8JDEgfSAyPi9kZXYvbnVsbCl9IHx8IHJldHVybiB9CisgIHZhcj0oICIkeyhAT2F2 KWhpc3Rvcnk6Z3MvXFwvXFxcXH0iICkKKyAgSUZTPSQnXG4nIHZhcmVkIC1NIHplZCAtbSB6ZWQt dmljbWQgLWkgX196ZWRfaW5pdCB2YXIKKyAgaWYgKCggPyApKTsgdGhlbgorICAgIFtbIC1uICQx IF1dICYmIHVuc2V0IEhJU1RGSUxFCisgIGVsc2UKKyAgICBoaXN0PSRISVNUU0laRTsgSElTVFNJ WkU9MDsgZmMgLVIgL2Rldi9udWxsOyBISVNUU0laRT0kaGlzdAorICAgIGZvciAoKCBoaXN0PTE7 IGhpc3QgPD0gJCN2YXI7IGhpc3QrKyApKSBwcmludCAtcyAiJHZhcltoaXN0XSIKKyAgICBbWyAt biAkMSBdXSAmJiBTQVZFSElTVD0kI3ZhcgkjIFJlc2V0cyBvbiBmdW5jdGlvbiBleGl0CisgIGZp CiBlbHNlCiAgIHplZF9maWxlX25hbWU9JDEKICAgW1sgLWYgJDEgXV0gJiYgdmFyPSIkKDwkMSki Cg== --0000000000007d4bff05a64417ec--