From 7c4102a49711e638eb15268fdcca9847a4b285c8 Mon Sep 17 00:00:00 2001 From: alex <61123283+unfortunatelyalex@users.noreply.github.com> Date: Wed, 22 May 2024 22:17:23 +0200 Subject: [PATCH] Add files via upload --- plugins/zsh-syntax-highlighting/COPYING.md | 23 + plugins/zsh-syntax-highlighting/HACKING.md | 99 ++ plugins/zsh-syntax-highlighting/Makefile | 64 ++ plugins/zsh-syntax-highlighting/README.md | 97 ++ plugins/zsh-syntax-highlighting/changelog.md | 920 ++++++++++++++++++ .../images/after1-smaller.png | Bin 0 -> 2517 bytes .../zsh-syntax-highlighting/images/after1.png | Bin 0 -> 5842 bytes .../images/after2-smaller.png | Bin 0 -> 4386 bytes .../zsh-syntax-highlighting/images/after2.png | Bin 0 -> 10228 bytes .../images/after3-smaller.png | Bin 0 -> 1673 bytes .../zsh-syntax-highlighting/images/after3.png | Bin 0 -> 3427 bytes .../images/after4-smaller.png | Bin 0 -> 3224 bytes .../images/before1-smaller.png | Bin 0 -> 1589 bytes .../images/before1.png | Bin 0 -> 2636 bytes .../images/before2-smaller.png | Bin 0 -> 2605 bytes .../images/before2.png | Bin 0 -> 2614 bytes .../images/before3-smaller.png | Bin 0 -> 763 bytes .../images/before3.png | Bin 0 -> 1461 bytes .../images/before4-smaller.png | Bin 0 -> 2987 bytes .../images/preview-smaller.png | Bin 0 -> 5982 bytes .../images/preview.png | Bin 0 -> 14650 bytes plugins/zsh-syntax-highlighting/release.md | 21 + .../zsh-syntax-highlighting/tests/README.md | 124 +++ .../tests/edit-failed-tests | 40 + .../tests/generate.zsh | 117 +++ .../tests/tap-colorizer.zsh | 71 ++ .../zsh-syntax-highlighting/tests/tap-filter | 47 + .../tests/test-highlighting.zsh | 291 ++++++ .../tests/test-perfs.zsh | 103 ++ .../tests/test-zprof.zsh | 78 ++ .../zsh-syntax-highlighting.plugin.zsh | 2 + .../zsh-syntax-highlighting.zsh | 587 +++++++++++ 32 files changed, 2684 insertions(+) create mode 100644 plugins/zsh-syntax-highlighting/COPYING.md create mode 100644 plugins/zsh-syntax-highlighting/HACKING.md create mode 100644 plugins/zsh-syntax-highlighting/Makefile create mode 100644 plugins/zsh-syntax-highlighting/README.md create mode 100644 plugins/zsh-syntax-highlighting/changelog.md create mode 100644 plugins/zsh-syntax-highlighting/images/after1-smaller.png create mode 100644 plugins/zsh-syntax-highlighting/images/after1.png create mode 100644 plugins/zsh-syntax-highlighting/images/after2-smaller.png create mode 100644 plugins/zsh-syntax-highlighting/images/after2.png create mode 100644 plugins/zsh-syntax-highlighting/images/after3-smaller.png create mode 100644 plugins/zsh-syntax-highlighting/images/after3.png create mode 100644 plugins/zsh-syntax-highlighting/images/after4-smaller.png create mode 100644 plugins/zsh-syntax-highlighting/images/before1-smaller.png create mode 100644 plugins/zsh-syntax-highlighting/images/before1.png create mode 100644 plugins/zsh-syntax-highlighting/images/before2-smaller.png create mode 100644 plugins/zsh-syntax-highlighting/images/before2.png create mode 100644 plugins/zsh-syntax-highlighting/images/before3-smaller.png create mode 100644 plugins/zsh-syntax-highlighting/images/before3.png create mode 100644 plugins/zsh-syntax-highlighting/images/before4-smaller.png create mode 100644 plugins/zsh-syntax-highlighting/images/preview-smaller.png create mode 100644 plugins/zsh-syntax-highlighting/images/preview.png create mode 100644 plugins/zsh-syntax-highlighting/release.md create mode 100644 plugins/zsh-syntax-highlighting/tests/README.md create mode 100644 plugins/zsh-syntax-highlighting/tests/edit-failed-tests create mode 100644 plugins/zsh-syntax-highlighting/tests/generate.zsh create mode 100644 plugins/zsh-syntax-highlighting/tests/tap-colorizer.zsh create mode 100644 plugins/zsh-syntax-highlighting/tests/tap-filter create mode 100644 plugins/zsh-syntax-highlighting/tests/test-highlighting.zsh create mode 100644 plugins/zsh-syntax-highlighting/tests/test-perfs.zsh create mode 100644 plugins/zsh-syntax-highlighting/tests/test-zprof.zsh create mode 100644 plugins/zsh-syntax-highlighting/zsh-syntax-highlighting.plugin.zsh create mode 100644 plugins/zsh-syntax-highlighting/zsh-syntax-highlighting.zsh diff --git a/plugins/zsh-syntax-highlighting/COPYING.md b/plugins/zsh-syntax-highlighting/COPYING.md new file mode 100644 index 000000000..cacbcbee0 --- /dev/null +++ b/plugins/zsh-syntax-highlighting/COPYING.md @@ -0,0 +1,23 @@ +Copyright (c) 2010-2020 zsh-syntax-highlighting contributors +All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, are permitted +provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, this list of conditions + and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright notice, this list of + conditions and the following disclaimer in the documentation and/or other materials provided + with the distribution. + * Neither the name of the zsh-syntax-highlighting contributors nor the names of its contributors + may be used to endorse or promote products derived from this software without specific prior + written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR +IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND +FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER +IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT +OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/plugins/zsh-syntax-highlighting/HACKING.md b/plugins/zsh-syntax-highlighting/HACKING.md new file mode 100644 index 000000000..ddd39a4e3 --- /dev/null +++ b/plugins/zsh-syntax-highlighting/HACKING.md @@ -0,0 +1,99 @@ +Hacking on zsh-syntax-highlighting itself +========================================= + +This document includes information for people working on z-sy-h itself: on the +core driver (`zsh-syntax-highlighting.zsh`), on the highlighters in the +distribution, and on the test suite. It does not target third-party +highlighter authors (although they may find it an interesting read). + +The `main` highlighter +---------------------- + +The following function `pz` is useful when working on the `main` highlighting: + +```zsh +pq() { + (( $#argv )) || return 0 + print -r -l -- ${(qqqq)argv} +} +pz() { + local arg + for arg; do + pq ${(z)arg} + done +} +``` + +It prints, for each argument, its token breakdown, similar to how the main +loop of the `main` highlighter sees it. + +Testing the `brackets` highlighter +---------------------------------- + +Since the test harness empties `ZSH_HIGHLIGHT_STYLES` and the `brackets` +highlighter interrogates `ZSH_HIGHLIGHT_STYLES` to determine how to highlight, +tests must set the `bracket-level-#` keys themselves. For example: + +```zsh +ZSH_HIGHLIGHT_STYLES[bracket-level-1]= +ZSH_HIGHLIGHT_STYLES[bracket-level-2]= + +BUFFER='echo ({x})' + +expected_region_highlight=( + "6 6 bracket-level-1" # ( + "7 7 bracket-level-2" # { + "9 9 bracket-level-2" # } + "10 10 bracket-level-1" # ) +) +``` + +Testing the `pattern` and `regexp` highlighters +----------------------------------------------- + +Because the `pattern` and `regexp` highlighters modifies `region_highlight` +directly instead of using `_zsh_highlight_add_highlight`, the test harness +cannot get the `ZSH_HIGHLIGHT_STYLES` keys. Therefore, when writing tests, use +the style itself as third word (cf. the +[documentation for `expected_region_highlight`](docs/highlighters.md)). For example: + +```zsh +ZSH_HIGHLIGHT_PATTERNS+=('rm -rf *' 'fg=white,bold,bg=red') + +BUFFER='rm -rf /' + +expected_region_highlight=( + "1 8 fg=white,bold,bg=red" # rm -rf / +) +``` + +Memos and commas +---------------- + +We append to `region_highlight` as follows: + + +```zsh +region_highlight+=("$start $end $spec, memo=zsh-syntax-highlighting") +``` + +That comma is required to cause zsh 5.8 and older to ignore the memo without +ignoring the `$spec`. It's a hack, but given that no further 5.8.x patch +releases are planned, it's been deemed acceptable. See issue #418 and the +cross-referenced issues. + + +Miscellany +---------- + +If you work on the driver (`zsh-syntax-highlighting.zsh`), you may find the following zstyle useful: + +```zsh +zstyle ':completion:*:*:*:*:globbed-files' ignored-patterns {'*/',}zsh-syntax-highlighting.plugin.zsh +``` + +IRC channel +----------- + +We're on #zsh-syntax-highlighting on Libera.Chat. + diff --git a/plugins/zsh-syntax-highlighting/Makefile b/plugins/zsh-syntax-highlighting/Makefile new file mode 100644 index 000000000..bbc1d4391 --- /dev/null +++ b/plugins/zsh-syntax-highlighting/Makefile @@ -0,0 +1,64 @@ +NAME=zsh-syntax-highlighting + +INSTALL?=install -c +PREFIX?=/usr/local +SHARE_DIR?=$(DESTDIR)$(PREFIX)/share/$(NAME) +DOC_DIR?=$(DESTDIR)$(PREFIX)/share/doc/$(NAME) +ZSH?=zsh # zsh binary to run tests with + +all: + cd docs && \ + cp highlighters.md all.md && \ + printf '\n\nIndividual highlighters documentation\n=====================================' >> all.md && \ + for doc in highlighters/*.md; do printf '\n\n'; cat "$$doc"; done >> all.md + +install: all + $(INSTALL) -d $(SHARE_DIR) + $(INSTALL) -d $(DOC_DIR) + cp .version zsh-syntax-highlighting.zsh $(SHARE_DIR) + cp COPYING.md README.md changelog.md $(DOC_DIR) + sed -e '1s/ .*//' -e '/^\[build-status-[a-z]*\]: /d' < README.md > $(DOC_DIR)/README.md + if [ x"true" = x"`git rev-parse --is-inside-work-tree 2>/dev/null`" ]; then \ + git rev-parse HEAD; \ + else \ + cat .revision-hash; \ + fi > $(SHARE_DIR)/.revision-hash + : +# The [ -e ] check below is to because sh evaluates this with (the moral +# equivalent of) NONOMATCH in effect, and highlighters/*.zsh has no matches. + for dirname in highlighters highlighters/*/ ; do \ + $(INSTALL) -d $(SHARE_DIR)/"$$dirname"; \ + for fname in "$$dirname"/*.zsh ; do [ -e "$$fname" ] && cp "$$fname" $(SHARE_DIR)"/$$dirname"; done; \ + done + cp -R docs/* $(DOC_DIR) + +clean: + rm -f docs/all.md + +test: + @$(ZSH) -fc 'echo ZSH_PATCHLEVEL=$$ZSH_PATCHLEVEL' + @result=0; \ + for test in highlighters/*; do \ + if [ -d $$test/test-data ]; then \ + echo "Running test $${test##*/}"; \ + env -i QUIET=$$QUIET $${TERM:+"TERM=$$TERM"} $(ZSH) -f tests/test-highlighting.zsh "$${test##*/}"; \ + : $$(( result |= $$? )); \ + fi \ + done; \ + exit $$result + +quiet-test: + $(MAKE) test QUIET=y + +perf: + @result=0; \ + for test in highlighters/*; do \ + if [ -d $$test/test-data ]; then \ + echo "Running test $${test##*/}"; \ + $(ZSH) -f tests/test-perfs.zsh "$${test##*/}"; \ + : $$(( result |= $$? )); \ + fi \ + done; \ + exit $$result + +.PHONY: all install clean test perf diff --git a/plugins/zsh-syntax-highlighting/README.md b/plugins/zsh-syntax-highlighting/README.md new file mode 100644 index 000000000..4768b3dd9 --- /dev/null +++ b/plugins/zsh-syntax-highlighting/README.md @@ -0,0 +1,97 @@ +zsh-syntax-highlighting [![Build Status][build-status-image]][build-status] +======================= + +**[Fish shell][fish]-like syntax highlighting for [Zsh][zsh].** + +*Requirements: zsh 4.3.11+.* + +[fish]: https://fishshell.com/ +[zsh]: https://www.zsh.org/ + +This package provides syntax highlighting for the shell zsh. It enables +highlighting of commands whilst they are typed at a zsh prompt into an +interactive terminal. This helps in reviewing commands before running +them, particularly in catching syntax errors. + +Some examples: + +Before: [![Screenshot #1.1](images/before1-smaller.png)](images/before1.png) +
+After:  [![Screenshot #1.2](images/after1-smaller.png)](images/after1.png) + +Before: [![Screenshot #2.1](images/before2-smaller.png)](images/before2.png) +
+After:  [![Screenshot #2.2](images/after2-smaller.png)](images/after2.png) + +Before: [![Screenshot #3.1](images/before3-smaller.png)](images/before3.png) +
+After:  [![Screenshot #3.2](images/after3-smaller.png)](images/after3.png) + +Before: [![Screenshot #4.1](images/before4-smaller.png)](images/before4-smaller.png) +
+After:  [![Screenshot #4.2](images/after4-smaller.png)](images/after4-smaller.png) + + + +How to install +-------------- + +See [INSTALL.md](INSTALL.md). + + +FAQ +--- + +### Why must `zsh-syntax-highlighting.zsh` be sourced at the end of the `.zshrc` file? + +zsh-syntax-highlighting works by hooking into the Zsh Line Editor (ZLE) and +computing syntax highlighting for the command-line buffer as it stands at the +time z-sy-h's hook is invoked. + +In zsh 5.2 and older, +`zsh-syntax-highlighting.zsh` hooks into ZLE by wrapping ZLE widgets. It must +be sourced after all custom widgets have been created (i.e., after all `zle -N` +calls and after running `compinit`) in order to be able to wrap all of them. +Widgets created after z-sy-h is sourced will work, but will not update the +syntax highlighting. + +In zsh newer than 5.8 (not including 5.8 itself), +zsh-syntax-highlighting uses the `add-zle-hook-widget` facility to install +a `zle-line-pre-redraw` hook. Hooks are run in order of registration, +therefore, z-sy-h must be sourced (and register its hook) after anything else +that adds hooks that modify the command-line buffer. + +### Does syntax highlighting work during incremental history search? + +Highlighting the command line during an incremental history search (by default bound to +to Ctrl+R in zsh's emacs keymap) requires zsh 5.4 or newer. + +Under zsh versions older than 5.4, the zsh-default [underlining][zshzle-Character-Highlighting] +of the matched portion of the buffer remains available, but zsh-syntax-highlighting's +additional highlighting is unavailable. (Those versions of zsh do not provide +enough information to allow computing the highlighting correctly.) + +See issues [#288][i288] and [#415][i415] for details. + +[zshzle-Character-Highlighting]: https://zsh.sourceforge.io/Doc/Release/Zsh-Line-Editor.html#Character-Highlighting +[i288]: https://github.com/zsh-users/zsh-syntax-highlighting/pull/288 +[i415]: https://github.com/zsh-users/zsh-syntax-highlighting/pull/415 + +### How are new releases announced? + +There is currently no "push" announcements channel. However, the following +alternatives exist: + +- GitHub's RSS feed of releases: https://github.com/zsh-users/zsh-syntax-highlighting/releases.atom +- An anitya entry: https://release-monitoring.org/project/7552/ + + +How to tweak +------------ + +Syntax highlighting is done by pluggable highlighter scripts. See the +[documentation on highlighters](docs/highlighters.md) for details and +configuration settings. + +[build-status]: https://github.com/zsh-users/zsh-syntax-highlighting/actions +[build-status-image]: https://github.com/zsh-users/zsh-syntax-highlighting/workflows/Tests/badge.svg diff --git a/plugins/zsh-syntax-highlighting/changelog.md b/plugins/zsh-syntax-highlighting/changelog.md new file mode 100644 index 000000000..8ee508892 --- /dev/null +++ b/plugins/zsh-syntax-highlighting/changelog.md @@ -0,0 +1,920 @@ +# Changes in HEAD + + +- Highlight `&>` `>&|` `>&!` `&>|` and `&>!` as redirection. + [#942] + + +# Changes in 0.8.0 + +This is a stable bugfix and feature release. Major new features and changes include: + + +## Changes fixed as part of the switch to zle-line-pre-redraw + +The changes in this section were fixed by switching to a `zle-line-pre-redraw`-based +implementation. + +Note: The new implementation will only be used on future zsh releases, +numbered 5.8.1.1 and newer, due to interoperability issues with other plugins +(issues #418 and #579). The underlying zsh feature has been available since +zsh 5.3. + +Whilst under development, the new implementation was known as the +"feature/redrawhook" topic branch. + +- Fixed: Highlighting not triggered after popping a buffer from the buffer stack + (using the `push-line` widget, default binding: `M-q`) + [#40] + +- Fixed: Invoking completion when there were no matches removed highlighting + [#90, #470] + +- Fixed: Two successive deletes followed by a yank only yanked the latest + delete, rather than both of them + [#150, #151, #160; cf. #183] + +- Presumed fixed: Completing `$(xsel)` results in an error message from `xsel`, + with pre-2017 versions of `xsel`. (For 2017 vintage and newer, see the issue + for details.) + [#154] + +- Fixed: When the standard `bracketed-paste-magic` widget is in use, pastes were slow + [#295] + +- Fixed: No way to prevent a widget from being wrapped + [#324] + +- Fixed: No highlighting while cycling menu completion + [#375] + +- Fixed: Does not coexist with the `IGNORE_EOF` option + [#377] + +- Fixed: The `undefined-key` widget was wrapped + [#421] + +- Fixed: Does not coexist with the standard `surround` family of widgets + [#520] + +- Fixed: First completed filename doesn't get `path` highlighting + [#632] + + +## Other changes + +- Add issue #712 to the previous release's changelog (hereinafter). + +- Fix highlighting when using an alias twice inside another alias + [#769, #775] + +- Remove lint warning for `env` followed by a pipe + [#797] + +- Recognize `proxychains` as a precommand + [#814, #914] + +- Honor shwordsplit when expanding parameters + [#687, #818] + +- Skip highlighting when keys are still pending in more cases + [#835] + +- Recognize `grc` as a precommand + +- Recognize `torsocks` and `torift` as precommands + [#898] + +- Recognize `cpulimit` as a precommand + [#897] + +- Recognize `ktrace` as a precommand + + +# Changes in 0.8.0-alpha1-pre-redrawhook + +## Notice about an improbable-but-not-impossible forward incompatibility + +Everyone can probably skip this section. + +The `master` branch of zsh-syntax-highlighting uses a zsh feature that has not +yet appeared in a zsh release: the `memo=` feature, added to zsh in commit +zsh-5.8-172-gdd6e702ee (after zsh 5.8, before zsh 5.9). In the unlikely event +that this zsh feature should change in an incompatible way before the next +stable zsh release, set `zsh_highlight__memo_feature=0` in your .zshrc files to +disable use of the new feature. + +z-sy-h dogfoods the new, unreleased zsh feature because that feature was +added to zsh at z-sy-h's initiative. The new feature is used in the fix +to issue #418. + + +## Incompatible changes: + +- An unsuccessful completion (a ⮀ Tab press that doesn't change the + command line) no longer causes highlighting to be lost. Visual feedback can + alternatively be achieved by setting the `format` zstyle under the `warnings` + tag, for example, + + zstyle ':completion:*:warnings' format '%F{red}No matches%f' + + Refer to the [description of the `format` style in `zshcompsys(1)`] + [zshcompsys-Standard-Styles-format]. + + (#90, part of #245 (feature/redrawhook)) + +[zshcompsys-Standard-Styles]: https://zsh.sourceforge.io/Doc/Release/Completion-System.html#Standard-Styles +[zshcompsys-Standard-Styles-format]: https://zsh.sourceforge.io/Doc/Release/Completion-System.html#index-format_002c-completion-style + + + +## Other changes: + +- Document `$ZSH_HIGHLIGHT_MAXLENGTH`. + [#698] + +- Optimize highlighting unquoted words (words that are not in single quotes, double quotes, backticks, or dollar-single-quotes) + [#730] + +- Redirection operators (e.g., `<` and `>`) are now highlighted by default + [#646] + +- Propertly terminate `noglob` scope in try/always blocks + [#577] + +- Don't error out when `KSH_ARRAYS` is set in the calling scope + [#622, #689] + +- Literal semicolons in array assignments (`foo=( bar ; baz )`) are now + highlighted as errors. + [3ca93f864fb6] + +- Command separators in array assignments (`foo=( bar | baz )`) are now + highlighted as errors. + [#651, 81267ca3130c] + +- Support parameter elision in command position (e.g., `$foo ls` where `$foo` is unset or empty) + [#667] + +- Don't consider the filename in `sudo -e /path/to/file` to be a command position + [#678] + +- Don't look up absolute directory names in $cdpath + [2cc2583f8f12, part of #669] + +- Fix `exec 2>&1;` being highlighted as an error. + [#676] + +- Fix `: $(<*)` being highlighted as globbing. + [#582] + +- Fix `cat < *` being highlighting as globbing when the `MULTIOS` option is unset. + [#583] + +- Fix `echo >&2` highlighting the `2` as a filename if a file by that name happened to exist + [#694, part of #645] + +- Fix `echo >&-` highlighting the `-` as a filename if a file by that name happened to exist + [part of #645] + +- Fix `echo >&p` highlighting the `p` as a filename if a file by that name happened to exist + [part of #645] + +- Fix wrong highlighting of unquoted parameter expansions under zsh 5.2 and older + [e165f18c758e] + +- Highlight global aliases + [#700] + +- Highlight `: =nosuchcommand' as an error (when the `EQUALS` option hasn't been unset). + [#430] + +- Highlight reserved word after assignments as errors (e.g., `foo=bar (ls;)`) + [#461] + +- Correctly highlight `[[ foo && bar || baz ]]`. + +- Highlight non-executable files in command position correctly (e.g., `% /etc/passwd`) + [#202, #669] + +- Highlight directories in command position correctly, including `AUTO_CD` support + [#669] + +- Recognize `env` as a precommand (e.g., `env FOO=bar ls`) + +- Recognize `ionice` as a precommand + +- Recognize `strace` as a precommand + +- Fix an error message on stderr before every prompt when the `WARN_NESTED_VAR` zsh option is set: + `_zsh_highlight_main__precmd_hook:1: array parameter _zsh_highlight_main__command_type_cache set in enclosing scope in function _zsh_highlight_main__precmd_hook` + [#727, #731, #732, #733] + +- Fix highlighting of alias whose definitions use a simple command terminator + (such as `;`, `|`, `&&`) before a newline + [#677; had regressed in 0.7.0] + +- Highlight arithmetic expansions (e.g., `$(( 42 ))`) + [#607 #649 #704] + +- Highlight the parentheses of array assignments as reserved words (`foo=( bar )`). + The `assign` style remains supported and has precedence. + [#585] + +- Fix interoperability issue with other plugins that use highlighting. The fix + requires zsh 5.8.0.3 or newer. (zsh 5.8.0.2-dev from the `master` branch, + revision zsh-5.8-172-gdd6e702ee or newer is also fine.) + [#418, https://github.com/okapia/zsh-viexchange/issues/1] + +- Improve performance of the `brackets` highlighter. + +- Fix highlighting of pre-command redirections (e.g., the `$fn` in `<$fn cat`) + [#712] + + +# Changes in version 0.7.1 + +- Remove out-of-date information from the 0.7.0 changelog. + + +# Changes in version 0.7.0 + +This is a stable bugfix and feature release. Major new features and changes include: + +- Add `ZSH_HIGHLIGHT_DIRS_BLACKLIST` to disable "path" and "path prefix" + highlighting for specific directories + [#379] + +- Add the "regexp" highlighter, modelled after the pattern highlighter + [4e6f60063f1c] + +- When a word uses globbing, only the globbing metacharacters will be highlighted as globbing: + in `: foo*bar`, only the `*` will be blue. + [e48af357532c] + +- Highlight pasted quotes (e.g., `: foo"bar"`) + [dc1b2f6fa4bb] + +- Highlight command substitutions (`` : `ls` ``, `: $(ls)`) + [c0e64fe13178 and parents, e86f75a840e7, et al] + +- Highlight process substitutions (`: >(nl)`, `: <(pwd)`, `: =(git diff)`) + [c0e64fe13178 and parents, e86f75a840e7, et al] + +- Highlight command substitutions inside double quotes (``: "`foo`"``) + [f16e858f0c83] + +- Highlight many precommands (e.g., `nice`, `stdbuf`, `eatmydata`; + see `$precommand_options` in the source) + +- Highlight numeric globs (e.g., `echo /lib<->`) + +- Assorted improvements to aliases highlighting + (e.g., + `alias sudo_u='sudo -u'; sudo_u jrandom ls`, + `alias x=y y=z z=nosuchcommand; x`, + `alias ls='ls -l'; \ls`) + [f3410c5862fc, 57386f30aec8, #544, and many others] + +- Highlight some more syntax errors + [dea05e44e671, 298ef6a2fa30] + +- New styles: named file descriptors, `RC_QUOTES`, and unclosed quotes (e.g., `echo "foo`) + [38c794a978cd, 25ae1c01216c, 967335dfc5fd] + +- The 'brackets' highlighting no longer treats quotes specially. + [ecdda36ef56f] + + +Selected bugfixes include: + +- Highlight `sudo` correctly when it's not installed + [26a82113b08b] + +- Handle some non-default options being set in zshrc + [b07ada1255b7, a2a899b41b8, 972ad197c13d, b3f66fc8748f] + +- Fix off-by-one highlighting in vi "visual" mode (vicmd keymap) + [be3882aeb054] + +- The 'yank-pop' widget is not wrapped + [#183] + + +Known issues include: + +- A multiline alias that uses a simple command terminator (such as `;`, `|`, `&&`) + before a newline will incorrectly be highlighted as an error. See issue #677 + for examples and workarounds. + [#677] + [UPDATE: Fixed in 0.8.0] + + +# Changes in version 0.6.0 + +This is a stable release, featuring bugfixes and minor improvements. + + +## Performance improvements: + +(none) + + +## Added highlighting of: + +- The `isearch` and `suffix` [`$zle_highlight` settings][zshzle-Character-Highlighting]. + (79e4d3d12405, 15db71abd0cc, b56ee542d619; requires zsh 5.3 for `$ISEARCHMATCH_ACTIVE` / `$SUFFIX_ACTIVE` support) + +[zshzle-Character-Highlighting]: https://zsh.sourceforge.io/Doc/Release/Zsh-Line-Editor.html#Character-Highlighting + +- Possible history expansions in double-quoted strings. + (76ea9e1df316) + +- Mismatched `if`/`then`/`elif`/`else`/`fi`. + (73cb83270262) + + +## Fixed highlighting of: + +- A comment line followed by a non-comment line. + (#385, 9396ad5c5f9c) + +- An unquoted `$*` (expands to the positional parameters). + (237f89ad629f) + +- history-incremental-pattern-search-backward under zsh 5.3.1. + (#407, #415, 462779629a0c) + + +## API changes (for highlighter authors): + +(none) + + +## Developer-visible changes: + +- tests: Set the `ALIAS_FUNC_DEF` option for zsh 5.4 compatibility. + (9523d6d49cb3) + + +## Other changes: + +- docs: Added before/after screenshots. + (cd9ec14a65ec..b7e277106b49) + +- docs: Link Fedora package. + (3d74aa47e4a7, 5feed23962df) + +- docs: Link FreeBSD port. + (626c034c68d7) + +- docs: Link OpenSUSE Build Service packages + (#419, dea1fedc7358) + +- Prevent user-defined aliases from taking effect in z-sy-h's own code. + (#390, 2dce602727d7, 8d5afe47f774; and #392, #395, b8fa1b9dc954) + +- docs: Update zplug installation instructions. + (#399, 4f49c4a35f17) + +- Improve "unhandled ZLE widget 'foo'" error message. + (#409, be083d7f3710) + +- Fix printing of "failed loading highlighters" error message. + (#426, ad522a091429) + + +# Changes in version 0.5.0 + + +## Performance improvements: + +We thank Sebastian Gniazdowski and "m0viefreak" for significant contributions +in this area. + +- Optimize string operations in the `main` (default) highlighter. + (#372/3cb58fd7d7b9, 02229ebd6328, ef4bfe5bcc14, #372/c6b6513ac0d6, #374/15461e7d21c3) + +- Command word highlighting: Use the `zsh/parameter` module to avoid forks. + Memoize (cache) the results. + (#298, 3ce01076b521, 2f18ba64e397, 12b879caf7a6; #320, 3b67e656bff5) + +- Avoid forks in the driver and in the `root` highlighter. + (b9112aec798a, 38c8fbea2dd2) + + +## Added highlighting of: + +- `pkexec` (a precommand). + (#248, 4f3910cbbaa5) + +- Aliases that cannot be defined normally nor invoked normally (highlighted as an error). + (#263 (in part), 28932316cca6) + +- Path separators (`/`) — the default behaviour remains to highlight path separators + and path components the same way. + (#136, #260, 6cd39e7c70d3, 9a934d291e7c, f3d3aaa00cc4) + +- Assignments to individual positional arguments (`42=foo` to assign to `$42`). + (f4036a09cee3) + +- Linewise region (the `visual-line-mode` widget, bound to `V` in zsh's `vi` keymap). + (#267, a7a7f8b42280, ee07588cfd9b) + +- Command-lines recalled by `isearch` mode; requires zsh≥5.3. + (#261 (in part); #257; 4ad311ec0a68) + +- Command-lines whilst the `IGNORE_BRACES` or `IGNORE_CLOSE_BRACES` option is in effect. + (a8a6384356af, 02807f1826a5) + +- Mismatched parentheses and braces (in the `main` highlighter). + (51b9d79c3bb6, 2fabf7ca64b7, a4196eda5e6f, and others) + +- Mismatched `do`/`done` keywords. + (b2733a64da93) + +- Mismatched `foreach`/`end` keywords. + (#96, 2bb8f0703d8f) + +- In Bourne-style function definitions, when the `MULTI_FUNC_DEF` option is set + (which is the default), highlight the first word in the function body as + a command word: `f() { g "$@" }`. + (6f91850a01e1) + +- `always` blocks. + (#335, e5782e4ddfb6) + +- Command substitutions inside double quotes, `"$(echo foo)"`. + (#139 (in part), c3913e0d8ead) + +- Non-alphabetic parameters inside double quotes (`"$$"`, `"$#"`, `"$*"`, `"$@"`, `"$?"`, `"$-"`). + (4afe670f7a1b, 44ef6e38e5a7) + +- Command words from future versions of zsh (forward compatibly). + This also adds an `arg0` style that all other command word styles fall back to. + (b4537a972eed, bccc3dc26943) + +- Escaped history expansions inside double quotes: `: "\!"` + (28d7056a7a06, et seq) + + +## Fixed highlighting of: + +- Command separator tokens in syntactically-invalid positions. + (09c4114eb980) + +- Redirections with a file descriptor number at command word. + (#238 (in part), 73ee7c1f6c4a) + +- The `select` prompt, `$PS3`. + (#268, 451665cb2a8b) + +- Values of variables in `vared`. + (e500ca246286) + +- `!` as an argument (neither a history expansion nor a reserved word). + (4c23a2fd1b90) + +- "division by zero" error under the `brackets` highlighter when `$ZSH_HIGHLIGHT_STYLES` is empty. + (f73f3d53d3a6) + +- Process substitutions, `<(pwd)` and `>(wc -l)`. + (#302, 6889ff6bd2ad, bfabffbf975c, fc9c892a3f15) + +- The non-`SHORT_LOOPS` form of `repeat` loops: `repeat 42; do true; done`. + (#290, 4832f18c50a5, ef68f50c048f, 6362c757b6f7) + +- Broken symlinks (are now highlighted as files). + (#342, 95f7206a9373, 53083da8215e) + +- Lines accepted from `isearch` mode. + (#284; #257, #259, #288; 5bae6219008b, a8fe22d42251) + +- Work around upstream bug that triggered when the command word was a relative + path, that when interpreted relative to a $PATH directory denoted a command; + the effect of that upstream bug was that the relative path was cached as + a "valid external command name". + (#354, #355, 51614ca2c994, fdaeec45146b, 7d38d07255e4; + upstream fix slated to be released in 5.3 (workers/39104)) + +- After accepting a line with the cursor on a bracket, the matching bracket + of the bracket under the cursor no longer remains highlighted (with the + `brackets` highlighter). + (4c4baede519a) + +- The first word on a new line within an array assignment or initialization is no + longer considered a command position. + (8bf423d16d46) + +- Subshells that end at command position, `(A=42)`, `(true;)`. + (#231, 7fb6f9979121; #344, 4fc35362ee5a) + +- Command word after array assignment, `a=(lorem ipsum) pwd`. + (#330, 7fb6f9979121) + + +## API changes (for highlighter authors): + +- New interface `_zsh_highlight_add_highlight`. + (341a3ae1f015, c346f6eb6fb6) + +- tests: Specify the style key, not its value, in test expectations. + (a830613467af, fd061b5730bf, eaa4335c3441, among others) + +- Module author documentation improvements. + (#306 (in part), 217669270418, 0ff354b44b6e, 80148f6c8402, 364f206a547f, and others) + +- The driver no longer defines a `_zsh_highlight_${highlighter}_highlighter_cache` + variable, which is in the highlighters' namespace. + (3e59ab41b6b8, 80148f6c8402, f91a7b885e7d) + +- Rename highlighter entry points. The old names remain supported for + backwards compatibility. + (a3d5dfcbdae9, c793e0dceab1) + +- tests: Add the "NONE" expectation. + (4da9889d1545, 13018f3dd735, d37c55c788cd) + +- tests: consider a test that writes to stderr to have failed. + (#291, 1082067f9315) + + +## Developer-visible changes: + +- Add `make quiet-test`. + (9b64ad750f35) + +- test harness: Better quote replaceables in error messages. + (30d8f92df225) + +- test harness: Fix exit code for XPASS. + (bb8d325c0cbd) + +- Create [HACKING.md](HACKING.md). + (cef49752fd0e) + +- tests: Emit a description for PASS test points. + (6aa57d60aa64, f0bae44b76dd) + +- tests: Create a script that generates a test file. + (8013dc3b8db6, et seq; `tests/generate.zsh`) + + +## Other changes: + +- Under zsh≤5.2, widgets whose names start with a `_` are no longer excluded + from highlighting. + (ed33d2cb1388; reverts part of 186d80054a40 which was for #65) + +- Under zsh≤5.2, widgets implemented by a function named after the widget are + no longer excluded from highlighting. + (487b122c480d; reverts part of 776453cb5b69) + +- Under zsh≤5.2, shell-unsafe widget names can now be wrapped. + (#278, 6a634fac9fb9, et seq) + +- Correct some test expectations. + (78290e043bc5) + +- `zsh-syntax-highlighting.plugin.zsh`: Convert from symlink to plain file + for msys2 compatibility. + (#292, d4f8edc9f3ad) + +- Document installation under some plugin managers. + (e635f766bef9, 9cab566f539b) + +- Don't leak the `PATH_DIRS` option. + (7b82b88a7166) + +- Don't require the `FUNCTION_ARGZERO` option to be set. + (#338, 750aebc553f2) + +- Under zsh≤5.2, support binding incomplete/nonexistent widgets. + (9e569bb0fe04, part of #288) + +- Make the driver reentrant, fixing possibility of infinite recursion + under zsh≤5.2 under interaction with theoretical third-party code. + (#305, d711563fe1bf, 295d62ec888d, f3242cbd6aba) + +- Fix warnings when `WARN_CREATE_GLOBAL` is set prior to sourcing zsh-syntax-highlighting. + (z-sy-h already sets `WARN_CREATE_GLOBAL` internally.) + (da60234fb236) + +- Warn only once, rather than once per keypress, when a highlighter is unavailable. + (0a9b347483ae) + + +# Changes in version 0.4.1 + +## Fixes: + +- Arguments to widgets were not properly dash-escaped. Only matters for widgets + that take arguments (i.e., that are invoked as `zle ${widget} -- ${args}`). + (282c7134e8ac, reverts c808d2187a73) + + +# Changes in version 0.4.0 + + +## Added highlighting of: + +- incomplete sudo commands + (a3047a912100, 2f05620b19ae) + + ```zsh + sudo; + sudo -u; + ``` + +- command words following reserved words + (#207, #222, b397b12ac139 et seq, 6fbd2aa9579b et seq, 8b4adbd991b0) + + ```zsh + if ls; then ls; else ls; fi + repeat 10 do ls; done + ``` + + (The `ls` are now highlighted as a command.) + +- comments (when `INTERACTIVE_COMMENTS` is set) + (#163, #167, 693de99a9030) + + ```zsh + echo Hello # comment + ``` + +- closing brackets of arithmetic expansion, subshells, and blocks + (#226, a59f442d2d34, et seq) + + ```zsh + (( foo )) + ( foo ) + { foo } + ``` + +- command names enabled by the `PATH_DIRS` option + (#228, 96ee5116b182) + + ```zsh + # When ~/bin/foo/bar exists, is executable, ~/bin is in $PATH, + # and 'setopt PATH_DIRS' is in effect + foo/bar + ``` + +- parameter expansions with braces inside double quotes + (#186, 6e3720f39d84) + + ```zsh + echo "${foo}" + ``` + +- parameter expansions in command word + (#101, 4fcfb15913a2) + + ```zsh + x=/bin/ls + $x -l + ``` + +- the command separators '\|&', '&!', '&\|' + + ```zsh + view file.pdf &! ls + ``` + + +## Fixed highlighting of: + +- precommand modifiers at non-command-word position + (#209, 2c9f8c8c95fa) + + ```zsh + ls command foo + ``` + +- sudo commands with infix redirections + (#221, be006aded590, 86e924970911) + + ```zsh + sudo -u >/tmp/foo.out user ls + ``` + +- subshells; anonymous functions + (#166, #194, 0d1bfbcbfa67, 9e178f9f3948) + + ```zsh + (true) + () { true } + ``` + +- parameter assignment statements with no command + (#205, 01d7eeb3c713) + + ```zsh + A=1; + ``` + + (The semicolon used to be highlighted as a mistake) + +- cursor highlighter: Remove the cursor highlighting when accepting a line. + (#109, 4f0c293fdef0) + + +## Removed features: + +- Removed highlighting of approximate paths (`path_approx`). + (#187, 98aee7f8b9a3) + + +## Other changes: + +- main highlighter refactored to use states rather than booleans. + (2080a441ac49, et seq) + +- Fix initialization when sourcing `zsh-syntax-highlighting.zsh` via a symlink + (083c47b00707) + +- docs: Add screenshot. + (57624bb9f64b) + +- widgets wrapping: Don't add '--' when invoking widgets. + (c808d2187a73) [_reverted in 0.4.1_] + +- Refresh highlighting upon `accept-*` widgets (`accept-line` et al). + (59fbdda64c21) + +- Stop leaking match/mbegin/mend to global scope (thanks to upstream + `WARN_CREATE_GLOBAL` improvements). + (d3deffbf46a4) + +- 'make install': Permit setting `$(SHARE_DIR)` from the environment. + (e1078a8b4cf1) + +- driver: Tolerate KSH_ARRAYS being set in the calling context. + (#162, 8f19af6b319d) + +- 'make install': Install documentation fully and properly. + (#219, b1619c001390, et seq) + +- docs: Improve 'main' highlighter's documentation. + (00de155063f5, 7d4252f5f596) + +- docs: Moved to a new docs/ tree; assorted minor updates + (c575f8f37567, 5b34c23cfad5, et seq) + +- docs: Split README.md into INSTALL.md + (0b3183f6cb9a) + +- driver: Report `$ZSH_HIGHLIGHT_REVISION` when running from git + (84734ba95026) + + +## Developer-visible changes: + +- Test harness converted to [TAP](https://testanything.org/tap-specification.html) format + (d99aa58aaaef, et seq) + +- Run each test in a separate subprocess, isolating them from each other + (d99aa58aaaef, et seq) + +- Fix test failure with nonexisting $HOME + (#216, b2ac98b98150) + +- Test output is now colorized. + (4d3da30f8b72, 6fe07c096109) + +- Document `make install` + (a18a7427fd2c) + +- tests: Allow specifying the zsh binary to use. + (557bb7e0c6a0) + +- tests: Add 'make perf' target + (4513eaea71d7) + +- tests: Run each test in a sandbox directory + (c01533920245) + + +# Changes in version 0.3.0 + + +## Added highlighting of: + +- suffix aliases (requires zsh 5.1.1 or newer): + + ```zsh + alias -s png=display + foo.png + ``` + +- prefix redirections: + + ```zsh + foo.txt + ``` + +- arithmetic evaluations: + + ```zsh + (( 42 )) + ``` + +- $'' strings, including \x/\octal/\u/\U escapes + + ```zsh + : $'foo\u0040bar' + ``` + +- multiline strings: + + ```zsh + % echo "line 1 + line 2" + ``` + +- string literals that haven't been finished: + + ```zsh + % echo "Hello, world + ``` +- command words that involve tilde expansion: + + ```zsh + % ~/bin/foo + ``` + +## Fixed highlighting of: + +- quoted command words: + + ```zsh + % \ls + ``` + +- backslash escapes in "" strings: + + ```zsh + % echo "\x41" + ``` + +- noglob after command separator: + + ```zsh + % :; noglob echo * + ``` + +- glob after command separator, when the first command starts with 'noglob': + + ```zsh + % noglob true; echo * + ``` + +- the region (vi visual mode / set-mark-command) (issue #165) + +- redirection and command separators that would be highlighted as `path_approx` + + ```zsh + % echo foo;‸ + % echo <‸ + ``` + + (where `‸` represents the cursor location) + +- escaped globbing (outside quotes) + + ```zsh + % echo \* + ``` + + +## Other changes: + +- implemented compatibility with zsh's paste highlighting (issue #175) + +- `$?` propagated correctly to wrapped widgets + +- don't leak $REPLY into global scope + + +## Developer-visible changes: + +- added makefile with `install` and `test` targets + +- set `warn_create_global` internally + +- document release process + + + + +# Version 0.2.1 + +(Start of changelog.) + diff --git a/plugins/zsh-syntax-highlighting/images/after1-smaller.png b/plugins/zsh-syntax-highlighting/images/after1-smaller.png new file mode 100644 index 0000000000000000000000000000000000000000..768294c3b3cdee1b8bb60849faad86aaa05b4ab9 GIT binary patch literal 2517 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 Gp$P!J#f60c literal 0 HcmV?d00001 diff --git a/plugins/zsh-syntax-highlighting/images/after1.png b/plugins/zsh-syntax-highlighting/images/after1.png new file mode 100644 index 0000000000000000000000000000000000000000..ea378d3efbcf363e727d6c0689702d02ebd9700a GIT binary patch literal 5842 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 literal 0 HcmV?d00001 diff --git a/plugins/zsh-syntax-highlighting/images/after2-smaller.png b/plugins/zsh-syntax-highlighting/images/after2-smaller.png new file mode 100644 index 0000000000000000000000000000000000000000..8b5b1f8f21d923c80a7d4c787e66774f4d9a170f GIT binary patch literal 4386 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 literal 0 HcmV?d00001 diff --git a/plugins/zsh-syntax-highlighting/images/after3-smaller.png b/plugins/zsh-syntax-highlighting/images/after3-smaller.png new file mode 100644 index 0000000000000000000000000000000000000000..d6aaa7bdf30aea607d98d8fa23f715534cb3bea7 GIT binary patch literal 1673 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�UI$EDE9<9C2>~#Ll>GL+*ugtryr`M(Z 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 aGSez?YuFLa`+|Xifx*+&&t;ucLK6V--rW8G literal 0 HcmV?d00001 diff --git a/plugins/zsh-syntax-highlighting/images/before1.png b/plugins/zsh-syntax-highlighting/images/before1.png new file mode 100644 index 0000000000000000000000000000000000000000..80c6f54ff5941aad6244aa9f3be3cb4d4d0311ec GIT binary patch literal 2636 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 S^S%Hz6Fpu1T-G@yGywq2gzV7( literal 0 HcmV?d00001 diff --git a/plugins/zsh-syntax-highlighting/images/before2-smaller.png b/plugins/zsh-syntax-highlighting/images/before2-smaller.png new file mode 100644 index 0000000000000000000000000000000000000000..991a716d54186b242ea0a09c13b5533f5719d6bf GIT binary patch literal 2605 zcmeAS@N?(olHy`uVBq!ia0y~yVA#ySz@W^*!oa{#TK(CYfq{V~-O<;Pfnj4m_n$;o z1_lO&WRD zmbgK;wrPfG-@#?({ajia&lUQGrBVWFE9Q6}k;r5hU3T}uqI%6{rcLub4WG&+2Mc^; ztZ@FJYg^eI=wjSB)3Hs`;@pOM>!`=Z{@VDA$o_I4_uAObkkS5c`&Sc(#!L9a>^5P7?do%RHuem zp9Jr9##vrLR(J-}DY*)s9e(l?2g>N1*M3uWUcIT>aj(63*8IQ;&(e%pPU4Nob5 znU*Kkm%HJUh@!|U8D62R^^;%ewp3-dTwn>!+7U2=YpR-wTWglu6_3hU&yqG*{hodA z;@e%$#ic&AtpR%kxGuI!X^E_y{7R!`oA%L*hdg8hS1wyIPoV3fr0wd?Q&;p%iz1DK z%Oh*+|K45c;$CZQ?{~I(+DpbO$*rf?o3}7sk~nCv?^#rWg!E5-hDaU81at4kqB23| zo-{$#1BGG}o?X|y(ZpgE=%s&;QDJ_8)#YBLq{gJUXJrq9qBfo@{KtJH@PGu@4jzjG zsy+#f=0WEwri)4!+R9xaLW=nK$oBq{zc+$`bd1bZM_Ulag)u$IM>QwJ9`F11Zo8X}}S)cTl3Hr@kZCzRNJd+uGP9+uhO{}18-_wiz@wo_r!{p=&_@}D2y9;!OWsxP9bW9_#a zpN`syO{m{@x5Rbsa?6(G5$E^rIs5nd?Wx5M8(dr7^UB$&%{;1ObH8s+vPkKltbc_M zmREiL-jv_?Y*~!ZhdF5u9KPquzucF6^Re~NQJ+-nmmPW~50*Cg@;$vCBX^-^-Or|2P}+Yyu$B`$X95eNM&oToFAzc5r1T3gU+<#)``k94(?7d zyd7gZ;Xu*7=|Oq1N1wRy60Hp8z?O*vsjvJCwO$N&6STYV}} zR=k)ox?%l{6WR_My_R98{Yp8kCC(X?ZMf!N|8~Rc+dnrRXJ7Da*0Pkpe%&!~B8y7` z9*eA8_{%A`Mejm&)Y`aL>v(hpW-T~e6{3~#m1eN)`-eB^}g68 z#P}mRG=JOc+dm6eW-459Vn4HJU+%JhnN|NUlq|fxCH$e2M$AMf;Sv|$mJ4jYB3{?K z-Tq7dJ*_{>yVRq-)X6*7w6Q*W(*$>G6R#Efysq53=;VC%O5oGXO?#XsMy-)pIL~V3 z>ey>B%R9sF$JejU09%yxO!6c9rOb08x2*0c#lG;j`}xFpg2n>&_cNcwr5W9k3s$o6 zV!3eH>i=C2@%?#+c!XZK6t@Luh1E&iQ%Kkc4qTUQT37%tq)D&KW_aR;MlMZA`s@iItIM5&HsPzMexI2odvo4VL8+ZD+(JIz zjIY;!u)ptDSzS!#yu*i8Hq2DF^sttn`t?qh-E_;}!fTeuhcjQ8B*v!}Za9nM!0Ce5 ziozUjn>(i8IJrC~$E|O33;T<6TJC@4Y!c2L5dO)rV?y;uhOZuG>UZ~9_+}q)cDDbM z>sq`(^WvMbp7ZDWjju%C{G=7O^VQmZk%yDR4{dRie`R+ztkIHZZ~XEtA>5@AlEOpC1F!gVFyGitHY>NWQRFHP3_T)*(_uMpQ;i*;N%k7jK* zd%^iMYqDj_*IeV081AWycmMrRzUo`nx}vo_IoH2GJ-+dtO^cHqi_ng~&^N_DRBdAX z!}}(kOix?FY|fDX$?(F|(~&F(&b~?KexN$jPh``n{>K#_N?UI62|w_v3O>ZPE8s{P z!yXx>R{ogWEyKx`vR<2>S@-^Q|NE-a zeNN);iseRqd0VqeQ~TeZ?%360*g@OvNUO_QmvAUQWHy38H@}J&2$Y7bd3x`3=FJ{O|6W~ pwG9lc3=AA+SyiBD$jwj5OsmAL!Qgn)5e5bZ22WQ%mvv4FO#p=IsK)>R literal 0 HcmV?d00001 diff --git a/plugins/zsh-syntax-highlighting/images/before2.png b/plugins/zsh-syntax-highlighting/images/before2.png new file mode 100644 index 0000000000000000000000000000000000000000..48cfc327a65b527fd73a8eaf144298e753e64357 GIT binary patch literal 2614 zcmeAS@N?(olHy`uVBq!ia0y~yU`%6RU~uDLU|?XlH7(JDfq{V~-O<;Pfnj4m_n$;o z1_lO&WRDI~ z{R&rBaE1szQg-z3Yi*vlV#yU1UtxI_w`kQP%^{amxQYx8uFAZ$_~H_|z{MT?4-7A= zEVoM%@zGXeJ-T?BMnZ>t-+69di(Y=(ee;g& zVaA(oIPI`)ZZ19k>4%VXOn+TXn8fZ_G~NPxz<-+_^%RD@%et*k*~}qUFTT2Q+b^6Wp(4Uk@0d12 zTaf8&9s7=)*PEOEzDnEoYsD`s!<70>Gg317lr>{5FYSEY!gT4+(T_2D3uO0;zsi4b zo-0?^p?UsaufzN=&Q^R4efxWjiSxhU&HMRGPQRV|qp-u@#b@JN`^__KBNkuUmnWa~ z|H}hr?tRX7A8WIeU)`Vg-N()J%tV{ByZ3KOv)#W)=$T>6Ry+1>XP(cyli~PNf5y3k zmu%)Oxv}t%MYZ9S2Y0j$`*k#&O#eTyKg1a%&(#xgwxpt5==%^jlF~j6=Cp_mx%ak|jOQIy08v zY;a5TlrZRin0YM3Zudm_*6(+ZMFq{(*t>l0g_@-c7A#o7w&Leh=d(p~p8wp>w(0DN z<3dl>4((5y`B%?(hV-(>?JVD>a@ug7PMK;qc?atnhPD5?Ai>)hA+mC<;c>>p9$G93 z?w#wHUd!;D>(swl6qCH8y_-=bKgVH}+APk0yFy5ddTcYmT%;*<<@@a9o#fP4rXZ$Yh zzHjo?@;Xd^{s<60yPunnPtGh`BtB0)WCdRid!%CKR6uB1L7_W_tnJm!an5(`)(0$34uzFW; zfM0nSp3G|&b09o5z(OjrX*J)^i3e)JP2L~ho^*D3*~N_IGh$6x(!ZlRFT8rM_%K>?`}EI?`${XOR|@Vfy{F2x`|iz* z(un01rYFBmG@5n&fZDC;35$Q5RL|bf&9jPQV%oOu{YLMTw|0kB%$ojiLG4YE6>oQK z{;+e(wO8*AmuTEN{WH*Y!Ony8WoH=jeC|6`b@+UfMSD|oMp4ARQyKGE3WX0YOWW=L zS$M-2<&_ql&z^tWUst-#;VE0&ew9l#9X6d8etR7CGWj03FID@W?$WKlqLp}(cJ39n z&$`i^lBeTRxcQ9J^H;Jf1eOJTTIIjtp~%hmHeaJzXU!De@l~Mw?d1L>UiA}2vz{-W z`DRnCp0`Q$^~C))3)V2+^^TTJ@omRts9E6gPdoG)j$7y z$NiAigeRc%9AY4tx>r(7a($8fY=P&$7K-lJc;Ubcx7_Bg6h^utq#$v{2J5Len@XS$7XUYBjIKxS4_@f^^+&%w_UBj z%a`ql3hTMb?d6)vB$#-&92j7q#|sOdAAq{6g<=l`nSs%~p#J}R_x?;Ls8GiLLj zec$H1$>*pho2&3+?)fuk`5d4AO^mzAEM~=O>;3cg=%k-{64TphJe_mi(fO;gG)`S8 zT6FNgr|HFwDkbNa{_>Vr{pDvI?v<+Ede}Pk+M&nA8_U;}sF@ip-mvY@=FsLV?=P%B zv0C?rVes;k_aoc2Uvp1-J8#pSd!6&EMfc{H74hZ&k5_12ULh+U^MAAO%#R-Bzbo>S z^{ngt|2aNh)OpDH$Gse@iWR)azn0$BDTpy!UFUDLY>6W>2OQrMjM z^uH8DAIC0dx4Nl|jl+KMZ)HDqLiUmHg|9}R+6yNBz1u48GV5?_mz<8c~vxSdwa$T$GwvlFDFYU}&amXrOCk5Mp3pWo&9?WUg&s lU}a$7ILoR6MMG|WN@iLmZVd*=OV0 literal 0 HcmV?d00001 diff --git a/plugins/zsh-syntax-highlighting/images/before3-smaller.png b/plugins/zsh-syntax-highlighting/images/before3-smaller.png new file mode 100644 index 0000000000000000000000000000000000000000..e525c6d4b1478af025a32e29bed9c3883d5e9d2d GIT binary patch literal 763 zcmeAS@N?(olHy`uVBq!ia0y~yU`SzLU=ZS9U|?YA_@olTz`($g?&#~tz_78O`%fY( z0|SFXvPY0F14ES>14Ba#1H&%{28MmEry73tF%YYuWfzcPQX-pLClf{}4Q&nY>o0e#Je$ceNp9ZkuNrA{coP!@jz53VWv|M^bBKRV<)wSxO5N%28-Kpq zdf>_-)}<$kdVkLdI8%|tw(#km(uo;md;$sVo3{AnGe;d#U^vpAG{H2=u4&^WdAZ^p zhx=5HemTP(nR;&O{qprD46&ELrd(ZYnp5!Wg1CSM6VIB(%cQ*)bm{+4%HG-^nBcKP|HOgny)u4>9V^+H&rI5JTcgwC7q|VKx3w*Tk*A(A zMoqA1K7Rk7l)}V%A-}^7&sh0ps4mnm2`o*U*U`KwVqL_U{dYSj6jrocos>OOAvy2x z%YV8G1``wC&aM3&cmE|b7n_~i=H|qMLe(1DwJZPTJ&Qh7AUU(X>4r|EwYVJ@rvMYV@aJrg6hM}O3O@P1*F>fT&IACcKkHVh1T zXEw|$)-8O?z`&qd;u=wsl30>zm0XmXSdz+MWMF8fYiOWrWDsItU}b7)Wo)W#U|?ln i@IsA|2}MJ0eoAIqC2kEft9R}LrD{)CKbLh*2~7a_*exXh literal 0 HcmV?d00001 diff --git a/plugins/zsh-syntax-highlighting/images/before3.png b/plugins/zsh-syntax-highlighting/images/before3.png new file mode 100644 index 0000000000000000000000000000000000000000..40c360151a09b90ea2b449b4e8f07c9a16d5837d GIT binary patch literal 1461 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 M>FVdQ&MBb@0H49S#{d8T literal 0 HcmV?d00001 diff --git a/plugins/zsh-syntax-highlighting/images/preview-smaller.png b/plugins/zsh-syntax-highlighting/images/preview-smaller.png new file mode 100644 index 0000000000000000000000000000000000000000..6fb84d18e545b56beef047eea45d7b03f9e50c05 GIT binary patch literal 5982 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 V=WLr>#=yY9;OXk;vd$@?2>^ +``` + +All tests may be run with + +```zsh +make test +``` + +which will run all highlighting tests and report results in [TAP format][TAP]. +By default, the results of all tests will be printed; to show only "interesting" +results (tests that failed but were expected to succeed, or vice-versa), run +`make quiet-test` (or `make test QUIET=y`). + +[TAP]: https://testanything.org/ + + +Performance test +---------------- + +[`test-perfs.zsh`](tests/test-perfs.zsh) measures the time spent doing the +highlighting. Usage: + +```zsh +zsh test-perfs.zsh +``` + +All tests may be run with + +```zsh +make perf +``` diff --git a/plugins/zsh-syntax-highlighting/tests/edit-failed-tests b/plugins/zsh-syntax-highlighting/tests/edit-failed-tests new file mode 100644 index 000000000..e3a76685c --- /dev/null +++ b/plugins/zsh-syntax-highlighting/tests/edit-failed-tests @@ -0,0 +1,40 @@ +#!/usr/bin/env zsh +# ------------------------------------------------------------------------------------------------- +# Copyright (c) 2020 zsh-syntax-highlighting contributors +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without modification, are permitted +# provided that the following conditions are met: +# +# * Redistributions of source code must retain the above copyright notice, this list of conditions +# and the following disclaimer. +# * Redistributions in binary form must reproduce the above copyright notice, this list of +# conditions and the following disclaimer in the documentation and/or other materials provided +# with the distribution. +# * Neither the name of the zsh-syntax-highlighting contributors nor the names of its contributors +# may be used to endorse or promote products derived from this software without specific prior +# written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR +# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND +# FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER +# IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT +# OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +# ------------------------------------------------------------------------------------------------- +# -*- mode: zsh; sh-indentation: 2; indent-tabs-mode: nil; sh-basic-offset: 2; -*- +# vim: ft=zsh sw=2 ts=2 et +# ------------------------------------------------------------------------------------------------- + +type perl sponge >/dev/null || { print -ru2 -- "$0: This script requires perl(1) and sponge(1) [from moreutils]"; exit 1; } + +local editor=( "${(@Q)${(z)${VISUAL:-${EDITOR:-vi}}}}" ) +() { + > "$2" perl -nE '$highlighter = $1 if /^Running test (\S*)/; say "highlighters/${highlighter}/test-data/$1.zsh" if /^## (\S*)/' "$1" + >>"$2" echo "" + >>"$2" cat <"$1" + "${editor[@]}" -- "$2" +} =(${MAKE:-make} quiet-test) =(:) +# TODO: tee(1) the quiet-test output to /dev/tty as it's happening, with colors. diff --git a/plugins/zsh-syntax-highlighting/tests/generate.zsh b/plugins/zsh-syntax-highlighting/tests/generate.zsh new file mode 100644 index 000000000..56960202b --- /dev/null +++ b/plugins/zsh-syntax-highlighting/tests/generate.zsh @@ -0,0 +1,117 @@ +#!/usr/bin/env zsh +# ------------------------------------------------------------------------------------------------- +# Copyright (c) 2016 zsh-syntax-highlighting contributors +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without modification, are permitted +# provided that the following conditions are met: +# +# * Redistributions of source code must retain the above copyright notice, this list of conditions +# and the following disclaimer. +# * Redistributions in binary form must reproduce the above copyright notice, this list of +# conditions and the following disclaimer in the documentation and/or other materials provided +# with the distribution. +# * Neither the name of the zsh-syntax-highlighting contributors nor the names of its contributors +# may be used to endorse or promote products derived from this software without specific prior +# written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR +# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND +# FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER +# IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT +# OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +# ------------------------------------------------------------------------------------------------- +# -*- mode: zsh; sh-indentation: 2; indent-tabs-mode: nil; sh-basic-offset: 2; -*- +# vim: ft=zsh sw=2 ts=2 et +# ------------------------------------------------------------------------------------------------- + +emulate -LR zsh +setopt localoptions extendedglob + +# Required for add-zle-hook-widget. +zmodload zsh/zle + +# Argument parsing. +if (( $# * $# - 7 * $# + 12 )) || [[ $1 == -* ]]; then + print -r -- >&2 "$0: usage: $0 BUFFER HIGHLIGHTER BASENAME [PREAMBLE]" + print -r -- >&2 "" + print -r -- >&2 "Generate highlighters/HIGHLIGHTER/test-data/BASENAME.zsh based on the" + print -r -- >&2 "current highlighting of BUFFER, using the setup code PREAMBLE." + exit 1 +fi +buffer=$1 +ZSH_HIGHLIGHT_HIGHLIGHTERS=( $2 ) +fname=${0:A:h:h}/highlighters/$2/test-data/${3%.zsh}.zsh +preamble=${4:-""} + +# Load the main script. +. ${0:A:h:h}/zsh-syntax-highlighting.zsh + +# Overwrite _zsh_highlight_add_highlight so we get the key itself instead of the style +_zsh_highlight_add_highlight() +{ + region_highlight+=("$1 $2 $3") +} + + +# Copyright block +year="`LC_ALL=C date +%Y`" +if ! { read -q "?Set copyright year to $year? " } always { echo "" }; then + year="YYYY" +fi +<$0 sed -n -e '1,/^$/p' | sed -e "s/2[0-9][0-9][0-9]/${year}/" > $fname +# Assumes stdout is line-buffered +git add -- $fname +exec > >(tee -a $fname) + +# Preamble +if [[ -n $preamble ]]; then + print -rl -- "$preamble" "" +fi + +# Buffer +print -n 'BUFFER=' +if [[ $buffer != (#s)[$'\t -~']#(#e) ]]; then + print -r -- ${(qqqq)buffer} +else + print -r -- ${(qq)buffer} +fi +echo "" + +# Expectations +print 'expected_region_highlight=(' +() { + local i + local PREBUFFER + local BUFFER + + PREBUFFER="" + BUFFER="$buffer" + region_highlight=() + eval $( + exec 3>&1 >/dev/null + typeset -r __tests_tmpdir="$(mktemp -d)" + { + # Use a subshell to ensure $__tests_tmpdir, which is to be rm -rf'd, won't be modified. + (cd -- "$__tests_tmpdir" && eval $preamble && _zsh_highlight && typeset -p region_highlight >&3) + : # workaround zsh bug workers/45305 with respect to the $(…) subshell we're in + } always { + rm -rf -- ${__tests_tmpdir} + } + ) + + for ((i=1; i<=${#region_highlight}; i++)); do + local -a highlight_zone; highlight_zone=( ${(z)region_highlight[$i]} ) + integer start=$highlight_zone[1] end=$highlight_zone[2] + if (( start < end )) # region_highlight ranges are half-open + then + (( --end )) # convert to closed range, like expected_region_highlight + (( ++start, ++end )) # region_highlight is 0-indexed; expected_region_highlight is 1-indexed + fi + printf " %s # %s\n" ${(qq):-"$start $end $highlight_zone[3]"} ${${(qqqq)BUFFER[start,end]}[3,-2]} + done +} +print ')' diff --git a/plugins/zsh-syntax-highlighting/tests/tap-colorizer.zsh b/plugins/zsh-syntax-highlighting/tests/tap-colorizer.zsh new file mode 100644 index 000000000..f3dc84e7e --- /dev/null +++ b/plugins/zsh-syntax-highlighting/tests/tap-colorizer.zsh @@ -0,0 +1,71 @@ +#!/usr/bin/env zsh +# ------------------------------------------------------------------------------------------------- +# Copyright (c) 2015, 2017 zsh-syntax-highlighting contributors +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without modification, are permitted +# provided that the following conditions are met: +# +# * Redistributions of source code must retain the above copyright notice, this list of conditions +# and the following disclaimer. +# * Redistributions in binary form must reproduce the above copyright notice, this list of +# conditions and the following disclaimer in the documentation and/or other materials provided +# with the distribution. +# * Neither the name of the zsh-syntax-highlighting contributors nor the names of its contributors +# may be used to endorse or promote products derived from this software without specific prior +# written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR +# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND +# FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER +# IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT +# OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +# ------------------------------------------------------------------------------------------------- +# -*- mode: zsh; sh-indentation: 2; indent-tabs-mode: nil; sh-basic-offset: 2; -*- +# vim: ft=zsh sw=2 ts=2 et +# ------------------------------------------------------------------------------------------------- + +# This is a stdin-to-stdout filter that takes TAP output (such as 'make test') +# on stdin and passes it, colorized, to stdout. + +emulate -LR zsh + +if [[ ! -t 1 ]] ; then + exec cat +fi + +while read -r line; +do + case $line in + # comment (filename header) or plan + (#* | <->..<->) + print -nP %F{blue} + ;; + # SKIP + (*# SKIP*) + print -nP %F{yellow} + ;; + # XPASS + (ok*# TODO*) + print -nP %F{red} + ;; + # XFAIL + (not ok*# TODO*) + print -nP %F{yellow} + ;; + # FAIL + (not ok*) + print -nP %F{red} + ;; + # PASS + (ok*) + print -nP %F{green} + ;; + esac + print -nr - "$line" + print -nP %f + echo "" # newline +done diff --git a/plugins/zsh-syntax-highlighting/tests/tap-filter b/plugins/zsh-syntax-highlighting/tests/tap-filter new file mode 100644 index 000000000..f9aa60414 --- /dev/null +++ b/plugins/zsh-syntax-highlighting/tests/tap-filter @@ -0,0 +1,47 @@ +#!/usr/bin/env perl +# ------------------------------------------------------------------------------------------------- +# Copyright (c) 2015 zsh-syntax-highlighting contributors +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without modification, are permitted +# provided that the following conditions are met: +# +# * Redistributions of source code must retain the above copyright notice, this list of conditions +# and the following disclaimer. +# * Redistributions in binary form must reproduce the above copyright notice, this list of +# conditions and the following disclaimer in the documentation and/or other materials provided +# with the distribution. +# * Neither the name of the zsh-syntax-highlighting contributors nor the names of its contributors +# may be used to endorse or promote products derived from this software without specific prior +# written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR +# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND +# FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER +# IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT +# OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +# ------------------------------------------------------------------------------------------------- +# vim: ft=perl sw=2 ts=2 et +# ------------------------------------------------------------------------------------------------- + +# This is a stdin-to-stdout filter that takes TAP output (such as 'make test') +# on stdin and deletes lines pertaining to expected results. +# +# More specifically, if any of the test points in a test file either failed but +# was expected to pass, or passed but was expected to fail, then emit that test +# file's output; else, elide that test file's output. + +use v5.10.0; +use warnings; +use strict; + +undef $/; # slurp mode +print for + grep { /^ok.*# TODO/m or /^not ok(?!.*# TODO)/m or /^Bail out!/m } + # Split on plan lines and remove them from the output. (To keep them, + # use the lookahead syntax, «(?=…)», to make the match zero-length.) + split /^\d+\.\.\d+$/m, + ; diff --git a/plugins/zsh-syntax-highlighting/tests/test-highlighting.zsh b/plugins/zsh-syntax-highlighting/tests/test-highlighting.zsh new file mode 100644 index 000000000..8b564a8b9 --- /dev/null +++ b/plugins/zsh-syntax-highlighting/tests/test-highlighting.zsh @@ -0,0 +1,291 @@ +#!/usr/bin/env zsh +# ------------------------------------------------------------------------------------------------- +# Copyright (c) 2010-2017 zsh-syntax-highlighting contributors +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without modification, are permitted +# provided that the following conditions are met: +# +# * Redistributions of source code must retain the above copyright notice, this list of conditions +# and the following disclaimer. +# * Redistributions in binary form must reproduce the above copyright notice, this list of +# conditions and the following disclaimer in the documentation and/or other materials provided +# with the distribution. +# * Neither the name of the zsh-syntax-highlighting contributors nor the names of its contributors +# may be used to endorse or promote products derived from this software without specific prior +# written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR +# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND +# FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER +# IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT +# OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +# ------------------------------------------------------------------------------------------------- +# -*- mode: zsh; sh-indentation: 2; indent-tabs-mode: nil; sh-basic-offset: 2; -*- +# vim: ft=zsh sw=2 ts=2 et +# ------------------------------------------------------------------------------------------------- + + +setopt NO_UNSET WARN_CREATE_GLOBAL + +# Required for add-zle-hook-widget. +zmodload zsh/zle + +local -r root=${0:h:h} +local -a anon_argv; anon_argv=("$@") + +(){ +set -- "${(@)anon_argv}" +# Check an highlighter was given as argument. +[[ -n "$1" ]] || { + echo >&2 "Bail out! You must provide the name of a valid highlighter as argument." + exit 2 +} + +# Check the highlighter is valid. +[[ -f $root/highlighters/$1/$1-highlighter.zsh ]] || { + echo >&2 "Bail out! Could not find highlighter ${(qq)1}." + exit 2 +} + +# Check the highlighter has test data. +[[ -d $root/highlighters/$1/test-data ]] || { + echo >&2 "Bail out! Highlighter ${(qq)1} has no test data." + exit 2 +} + +# Set up results_filter +local results_filter +if [[ ${QUIET-} == y ]]; then + if type -w perl >/dev/null; then + results_filter=$root/tests/tap-filter + else + echo >&2 "Bail out! quiet mode not supported: perl not found"; exit 2 + fi +else + results_filter=cat +fi +[[ -n $results_filter ]] || { echo >&2 "Bail out! BUG setting \$results_filter"; exit 2 } + +# Load the main script. +# While here, test that it doesn't eat aliases. +print > >($results_filter | $root/tests/tap-colorizer.zsh) -r -- "# global (driver) tests" +print > >($results_filter | $root/tests/tap-colorizer.zsh) -r -- "1..1" +alias -- +plus=plus +alias -- _other=other +local original_alias_dash_L_output="$(alias -L)" +. $root/zsh-syntax-highlighting.zsh +if [[ $original_alias_dash_L_output == $(alias -L) ]]; then + print -r -- "ok 1 # 'alias -- +foo=bar' is preserved" +else + print -r -- "not ok 1 # 'alias -- +foo=bar' is preserved" + exit 1 +fi > >($results_filter | $root/tests/tap-colorizer.zsh) + +# Overwrite _zsh_highlight_add_highlight so we get the key itself instead of the style +_zsh_highlight_add_highlight() +{ + region_highlight+=("$1 $2 $3") +} + +# Activate the highlighter. +ZSH_HIGHLIGHT_HIGHLIGHTERS=($1) + +# In zsh<5.3, 'typeset -p arrayvar' emits two lines, so we use this wrapper instead. +typeset_p() { + for 1 ; do + if [[ ${(tP)1} == *array* ]]; then + print -r -- "$1=( ${(@qqqqP)1} )" + else + print -r -- "$1=${(qqqqP)1}" + fi + done +} + +# Escape # as ♯ and newline as ↵ they are illegal in the 'description' part of TAP output +# The string to escape is «"$@"»; the result is returned in $REPLY. +tap_escape() { + local s="${(j. .)@}" + REPLY="${${s//'#'/♯}//$'\n'/↵}" +} + +# Runs a highlighting test +# $1: data file +run_test_internal() { + + local tests_tempdir="$1"; shift + local srcdir="$PWD" + builtin cd -q -- "$tests_tempdir" || { echo >&2 "Bail out! On ${(qq)1}: cd failed: $?"; return 1 } + + # Load the data and prepare checking it. + local BUFFER CURSOR MARK PENDING PREBUFFER REGION_ACTIVE WIDGET REPLY skip_test fail_test unsorted=0 + local expected_mismatch + local skip_mismatch + local -a expected_region_highlight region_highlight + + local ARG="$1" + local RETURN="" + () { + setopt localoptions + + # WARNING: The remainder of this anonymous function will run with the test's options in effect + if { ! . "$srcdir"/"$ARG" } || (( $#fail_test )); then + print -r -- "1..1" + print -r -- "## ${ARG:t:r}" + tap_escape $fail_test; fail_test=$REPLY + print -r -- "not ok 1 - failed setup: $fail_test" + return ${RETURN:=0} + fi + + (( $#skip_test )) && { + print -r -- "1..0 # SKIP $skip_test" + print -r -- "## ${ARG:t:r}" + return ${RETURN:=0} + } + + # Check the data declares $PREBUFFER or $BUFFER. + [[ -z $PREBUFFER && -z $BUFFER ]] && { echo >&2 "Bail out! On ${(qq)ARG}: Either 'PREBUFFER' or 'BUFFER' must be declared and non-blank"; return ${RETURN:=1}; } + [[ $PREBUFFER == (''|*$'\n') ]] || { echo >&2 "Bail out! On ${(qq)ARG}: PREBUFFER=${(qqqq)PREBUFFER} doesn't end with a newline"; return ${RETURN:=1}; } + + # Set sane defaults for ZLE variables + : ${CURSOR=$#BUFFER} ${PENDING=0} ${WIDGET=z-sy-h-test-harness-test-widget} + + # Process the data. + _zsh_highlight + }; [[ -z $RETURN ]] || return $RETURN + unset ARG + + integer print_expected_and_actual=0 + + if (( unsorted )); then + region_highlight=("${(@n)region_highlight}") + expected_region_highlight=("${(@n)expected_region_highlight}") + fi + + # Print the plan line, and some comments for human readers + echo "1..$(( $#expected_region_highlight + 1))" + echo "## ${1:t:r}" # note: tests/edit-failed-tests looks for the "##" emitted by this line + [[ -n $PREBUFFER ]] && printf '# %s\n' "$(typeset_p PREBUFFER)" + [[ -n $BUFFER ]] && printf '# %s\n' "$(typeset_p BUFFER)" + + local i + for ((i=1; i<=$#expected_region_highlight; i++)); do + local -a expected_highlight_zone; expected_highlight_zone=( ${(z)expected_region_highlight[i]} ) + integer exp_start=$expected_highlight_zone[1] exp_end=$expected_highlight_zone[2] + local todo= + if (( $+expected_highlight_zone[4] )); then + todo="# TODO $expected_highlight_zone[4]" + skip_mismatch="cardinality check disabled whilst regular test points are expected to fail" + fi + if ! (( $+region_highlight[i] )); then + print -r -- "not ok $i - unmatched expectation ($exp_start $exp_end $expected_highlight_zone[3])" \ + "${skip_mismatch:+"# TODO ${(qqq)skip_mismatch}"}" + if [[ -z $skip_mismatch ]]; then (( ++print_expected_and_actual )); fi + continue + fi + local -a highlight_zone; highlight_zone=( ${(z)region_highlight[i]} ) + integer start=$(( highlight_zone[1] + 1 )) end=$highlight_zone[2] + local desc="[$start,$end] «${BUFFER[$start,$end]}»" + tap_escape $desc; desc=$REPLY + if + [[ $start != $exp_start ]] || + [[ $end != $exp_end ]] || + [[ ${highlight_zone[3]%,} != ${expected_highlight_zone[3]} ]] # remove the comma that's before the memo field + then + print -r -- "not ok $i - $desc - expected ($exp_start $exp_end ${(qqq)expected_highlight_zone[3]}), observed ($start $end ${(qqq)highlight_zone[3]}). $todo" + if [[ -z $todo ]]; then (( ++print_expected_and_actual )); fi + else + print -r -- "ok $i - $desc${todo:+ - }$todo" + fi + unset expected_highlight_zone + unset exp_start exp_end + unset todo + unset highlight_zone + unset start end + unset desc + done + + # If both $skip_mismatch and $expected_mismatch are set, that means the test + # has some XFail test points, _and_ explicitly sets $expected_mismatch as + # well. Explicit settings should have priority, so we ignore $skip_mismatch + # if $expected_mismatch is set. + if [[ -n $skip_mismatch && -z $expected_mismatch ]]; then + tap_escape $skip_mismatch; skip_mismatch=$REPLY + print "ok $i - cardinality check" "# SKIP $skip_mismatch" + else + local todo + if [[ -n $expected_mismatch ]]; then + tap_escape $expected_mismatch; expected_mismatch=$REPLY + todo="# TODO $expected_mismatch" + fi + if (( $#expected_region_highlight == $#region_highlight )); then + print -r -- "ok $i - cardinality check${todo:+ - }$todo" + else + local details + details+="have $#expected_region_highlight expectations and $#region_highlight region_highlight entries: " + details+="«$(typeset_p expected_region_highlight)» «$(typeset_p region_highlight)»" + tap_escape $details; details=$REPLY + print -r -- "not ok $i - cardinality check - $details${todo:+ - }$todo" + if [[ -z $todo ]]; then (( ++print_expected_and_actual )); fi + fi + fi + if (( print_expected_and_actual )); then + () { + local -a left_column right_column + left_column=( "expected_region_highlight" "${(qq)expected_region_highlight[@]}" ) + right_column=( "region_highlight" "${(qq)region_highlight[@]}" ) + integer difference=$(( $#right_column - $#left_column )) + repeat $difference do left_column+=(.); done + paste \ + =(print -rC1 -- $left_column) \ + =(print -rC1 -- $right_column) \ + | if type column >/dev/null; then column -t -s $'\t'; else cat; fi \ + | sed 's/^/# /' + } + fi +} + +# Run a single test file. The exit status is 1 if the test harness had +# an error and 0 otherwise. The exit status does not depend on whether +# test points succeeded or failed. +run_test() { + # Do not combine the declaration and initialization: «local x="$(false)"» does not set $?. + local __tests_tempdir + __tests_tempdir="$(mktemp -d)" && [[ -d $__tests_tempdir ]] || { + echo >&2 "Bail out! mktemp failed"; return 1 + } + typeset -r __tests_tempdir # don't allow tests to override the variable that we will 'rm -rf' later on + + { + # Use a subshell to isolate tests from each other. + # (So tests can alter global shell state using 'cd', 'hash', etc) + { + # These braces are so multios don't come into play. + { (run_test_internal "$__tests_tempdir" "$@") 3>&1 >&2 2>&3 } | grep \^ + local ret=$pipestatus[1] stderr=$pipestatus[2] + if (( ! stderr )); then + # stdout will become stderr + echo "Bail out! On ${(qq)1}: output on stderr"; return 1 + else + return $ret + fi + } 3>&1 >&2 2>&3 + } always { + rm -rf -- "$__tests_tempdir" + } +} + +# Process each test data file in test data directory. +integer something_failed=0 +ZSH_HIGHLIGHT_STYLES=() +local data_file +for data_file in $root/highlighters/$1/test-data/*.zsh; do + run_test "$data_file" | tee >($results_filter | $root/tests/tap-colorizer.zsh) | grep -v '^not ok.*# TODO' | grep -Eq '^not ok|^ok.*# TODO' && (( something_failed=1 )) + (( $pipestatus[1] )) && exit 2 +done + +exit $something_failed +} diff --git a/plugins/zsh-syntax-highlighting/tests/test-perfs.zsh b/plugins/zsh-syntax-highlighting/tests/test-perfs.zsh new file mode 100644 index 000000000..aa139aad5 --- /dev/null +++ b/plugins/zsh-syntax-highlighting/tests/test-perfs.zsh @@ -0,0 +1,103 @@ +#!/usr/bin/env zsh +# ------------------------------------------------------------------------------------------------- +# Copyright (c) 2010-2015 zsh-syntax-highlighting contributors +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without modification, are permitted +# provided that the following conditions are met: +# +# * Redistributions of source code must retain the above copyright notice, this list of conditions +# and the following disclaimer. +# * Redistributions in binary form must reproduce the above copyright notice, this list of +# conditions and the following disclaimer in the documentation and/or other materials provided +# with the distribution. +# * Neither the name of the zsh-syntax-highlighting contributors nor the names of its contributors +# may be used to endorse or promote products derived from this software without specific prior +# written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR +# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND +# FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER +# IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT +# OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +# ------------------------------------------------------------------------------------------------- +# -*- mode: zsh; sh-indentation: 2; indent-tabs-mode: nil; sh-basic-offset: 2; -*- +# vim: ft=zsh sw=2 ts=2 et +# ------------------------------------------------------------------------------------------------- + + +# Required for add-zle-hook-widget. +zmodload zsh/zle + +# Check an highlighter was given as argument. +[[ -n "$1" ]] || { + echo >&2 "Bail out! You must provide the name of a valid highlighter as argument." + exit 2 +} + +# Check the highlighter is valid. +[[ -f ${0:h:h}/highlighters/$1/$1-highlighter.zsh ]] || { + echo >&2 "Bail out! Could not find highlighter ${(qq)1}." + exit 2 +} + +# Check the highlighter has test data. +[[ -d ${0:h:h}/highlighters/$1/test-data ]] || { + echo >&2 "Bail out! Highlighter ${(qq)1} has no test data." + exit 2 +} + +# Load the main script. +typeset -a region_highlight +. ${0:h:h}/zsh-syntax-highlighting.zsh + +# Activate the highlighter. +ZSH_HIGHLIGHT_HIGHLIGHTERS=($1) + +# Runs a highlighting test +# $1: data file +run_test_internal() { + local -a highlight_zone + + local tests_tempdir="$1"; shift + local srcdir="$PWD" + builtin cd -q -- "$tests_tempdir" || { echo >&2 "Bail out! cd failed: $?"; return 1 } + + # Load the data and prepare checking it. + PREBUFFER= BUFFER= ; + . "$srcdir"/"$1" + + # Check the data declares $PREBUFFER or $BUFFER. + [[ -z $PREBUFFER && -z $BUFFER ]] && { echo >&2 "Bail out! Either 'PREBUFFER' or 'BUFFER' must be declared and non-blank"; return 1; } + + # Set $? for _zsh_highlight + true && _zsh_highlight +} + +run_test() { + # Do not combine the declaration and initialization: «local x="$(false)"» does not set $?. + local __tests_tempdir + __tests_tempdir="$(mktemp -d)" && [[ -d $__tests_tempdir ]] || { + echo >&2 "Bail out! mktemp failed"; return 1 + } + typeset -r __tests_tempdir # don't allow tests to override the variable that we will 'rm -rf' later on + + { + (run_test_internal "$__tests_tempdir" "$@") + } always { + rm -rf -- "$__tests_tempdir" + } +} + +# Process each test data file in test data directory. +local data_file +TIMEFMT="%*Es" +{ time (for data_file in ${0:h:h}/highlighters/$1/test-data/*.zsh; do + run_test "$data_file" + (( $pipestatus[1] )) && exit 2 +done) } 2>&1 || exit $? + +exit 0 diff --git a/plugins/zsh-syntax-highlighting/tests/test-zprof.zsh b/plugins/zsh-syntax-highlighting/tests/test-zprof.zsh new file mode 100644 index 000000000..ada161879 --- /dev/null +++ b/plugins/zsh-syntax-highlighting/tests/test-zprof.zsh @@ -0,0 +1,78 @@ +#!/usr/bin/env zsh +# ------------------------------------------------------------------------------------------------- +# Copyright (c) 2010-2015 zsh-syntax-highlighting contributors +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without modification, are permitted +# provided that the following conditions are met: +# +# * Redistributions of source code must retain the above copyright notice, this list of conditions +# and the following disclaimer. +# * Redistributions in binary form must reproduce the above copyright notice, this list of +# conditions and the following disclaimer in the documentation and/or other materials provided +# with the distribution. +# * Neither the name of the zsh-syntax-highlighting contributors nor the names of its contributors +# may be used to endorse or promote products derived from this software without specific prior +# written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR +# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND +# FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER +# IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT +# OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +# ------------------------------------------------------------------------------------------------- +# -*- mode: zsh; sh-indentation: 2; indent-tabs-mode: nil; sh-basic-offset: 2; -*- +# vim: ft=zsh sw=2 ts=2 et +# ------------------------------------------------------------------------------------------------- + +# Load the main script. +typeset -a region_highlight +. ${0:h:h}/zsh-syntax-highlighting.zsh + +# Activate the highlighter. +ZSH_HIGHLIGHT_HIGHLIGHTERS=(main) + +source_file=0.7.1:highlighters/$1/$1-highlighter.zsh + +# Runs a highlighting test +# $1: data file +run_test_internal() { + setopt interactivecomments + + local -a highlight_zone + + local tests_tempdir="$1"; shift + local srcdir="$PWD" + builtin cd -q -- "$tests_tempdir" || { echo >&2 "Bail out! cd failed: $?"; return 1 } + + # Load the data and prepare checking it. + PREBUFFER= + BUFFER=$(cd -- "$srcdir" && git cat-file blob $source_file) + expected_region_highlight=() + + zmodload zsh/zprof + zprof -c + # Set $? for _zsh_highlight + true && _zsh_highlight + zprof +} + +run_test() { + # Do not combine the declaration and initialization: «local x="$(false)"» does not set $?. + local __tests_tempdir + __tests_tempdir="$(mktemp -d)" && [[ -d $__tests_tempdir ]] || { + echo >&2 "Bail out! mktemp failed"; return 1 + } + typeset -r __tests_tempdir # don't allow tests to override the variable that we will 'rm -rf' later on + + { + (run_test_internal "$__tests_tempdir" "$@") + } always { + rm -rf -- "$__tests_tempdir" + } +} + +run_test diff --git a/plugins/zsh-syntax-highlighting/zsh-syntax-highlighting.plugin.zsh b/plugins/zsh-syntax-highlighting/zsh-syntax-highlighting.plugin.zsh new file mode 100644 index 000000000..f2456aecd --- /dev/null +++ b/plugins/zsh-syntax-highlighting/zsh-syntax-highlighting.plugin.zsh @@ -0,0 +1,2 @@ +0=${(%):-%N} +source ${0:A:h}/zsh-syntax-highlighting.zsh diff --git a/plugins/zsh-syntax-highlighting/zsh-syntax-highlighting.zsh b/plugins/zsh-syntax-highlighting/zsh-syntax-highlighting.zsh new file mode 100644 index 000000000..4295c93f4 --- /dev/null +++ b/plugins/zsh-syntax-highlighting/zsh-syntax-highlighting.zsh @@ -0,0 +1,587 @@ +# ------------------------------------------------------------------------------------------------- +# Copyright (c) 2010-2020 zsh-syntax-highlighting contributors +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without modification, are permitted +# provided that the following conditions are met: +# +# * Redistributions of source code must retain the above copyright notice, this list of conditions +# and the following disclaimer. +# * Redistributions in binary form must reproduce the above copyright notice, this list of +# conditions and the following disclaimer in the documentation and/or other materials provided +# with the distribution. +# * Neither the name of the zsh-syntax-highlighting contributors nor the names of its contributors +# may be used to endorse or promote products derived from this software without specific prior +# written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR +# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND +# FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR +# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER +# IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT +# OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +# ------------------------------------------------------------------------------------------------- +# -*- mode: zsh; sh-indentation: 2; indent-tabs-mode: nil; sh-basic-offset: 2; -*- +# vim: ft=zsh sw=2 ts=2 et +# ------------------------------------------------------------------------------------------------- + +# First of all, ensure predictable parsing. +typeset zsh_highlight__aliases="$(builtin alias -Lm '[^+]*')" +# In zsh <= 5.2, aliases that begin with a plus sign ('alias -- +foo=42') +# are emitted by `alias -L` without a '--' guard, so they don't round trip. +# +# Hence, we exclude them from unaliasing: +builtin unalias -m '[^+]*' + +# Set $0 to the expected value, regardless of functionargzero. +0=${(%):-%N} +if true; then + # $0 is reliable + typeset -g ZSH_HIGHLIGHT_VERSION=$(<"${0:A:h}"/.version) + typeset -g ZSH_HIGHLIGHT_REVISION=$(<"${0:A:h}"/.revision-hash) + if [[ $ZSH_HIGHLIGHT_REVISION == \$Format:* ]]; then + # When running from a source tree without 'make install', $ZSH_HIGHLIGHT_REVISION + # would be set to '$Format:%H$' literally. That's an invalid value, and obtaining + # the valid value (via `git rev-parse HEAD`, as Makefile does) might be costly, so: + ZSH_HIGHLIGHT_REVISION=HEAD + fi +fi + +# This function takes a single argument F and returns True iff F is an autoload stub. +_zsh_highlight__function_is_autoload_stub_p() { + if zmodload -e zsh/parameter; then + #(( ${+functions[$1]} )) && + [[ "$functions[$1]" == *"builtin autoload -X"* ]] + else + #[[ $(type -wa -- "$1") == *'function'* ]] && + [[ "${${(@f)"$(which -- "$1")"}[2]}" == $'\t'$histchars[3]' undefined' ]] + fi + # Do nothing here: return the exit code of the if. +} + +# Return True iff the argument denotes a function name. +_zsh_highlight__is_function_p() { + if zmodload -e zsh/parameter; then + (( ${+functions[$1]} )) + else + [[ $(type -wa -- "$1") == *'function'* ]] + fi +} + +# This function takes a single argument F and returns True iff F denotes the +# name of a callable function. A function is callable if it is fully defined +# or if it is marked for autoloading and autoloading it at the first call to it +# will succeed. In particular, if F has been marked for autoloading +# but is not available in $fpath, then calling this function on F will return False. +# +# See users/21671 https://www.zsh.org/cgi-bin/mla/redirect?USERNUMBER=21671 +_zsh_highlight__function_callable_p() { + if _zsh_highlight__is_function_p "$1" && + ! _zsh_highlight__function_is_autoload_stub_p "$1" + then + # Already fully loaded. + return 0 # true + else + # "$1" is either an autoload stub, or not a function at all. + # + # Use a subshell to avoid affecting the calling shell. + # + # We expect 'autoload +X' to return non-zero if it fails to fully load + # the function. + ( autoload -U +X -- "$1" 2>/dev/null ) + return $? + fi +} + +# ------------------------------------------------------------------------------------------------- +# Core highlighting update system +# ------------------------------------------------------------------------------------------------- + +# Use workaround for bug in ZSH? +# zsh-users/zsh@48cadf4 https://www.zsh.org/mla/workers/2017/msg00034.html +autoload -Uz is-at-least +if is-at-least 5.4; then + typeset -g zsh_highlight__pat_static_bug=false +else + typeset -g zsh_highlight__pat_static_bug=true +fi + +# Array declaring active highlighters names. +typeset -ga ZSH_HIGHLIGHT_HIGHLIGHTERS + +# Update ZLE buffer syntax highlighting. +# +# Invokes each highlighter that needs updating. +# This function is supposed to be called whenever the ZLE state changes. +_zsh_highlight() +{ + # Store the previous command return code to restore it whatever happens. + local ret=$? + # Make it read-only. Can't combine this with the previous line when POSIX_BUILTINS may be set. + typeset -r ret + + # $region_highlight should be predefined, either by zle or by the test suite's mock (non-special) array. + (( ${+region_highlight[@]} )) || { + echo >&2 'zsh-syntax-highlighting: error: $region_highlight is not defined' + echo >&2 'zsh-syntax-highlighting: (Check whether zsh-syntax-highlighting was installed according to the instructions.)' + return $ret + } + + # Probe the memo= feature, once. + (( ${+zsh_highlight__memo_feature} )) || { + region_highlight+=( " 0 0 fg=red, memo=zsh-syntax-highlighting" ) + case ${region_highlight[-1]} in + ("0 0 fg=red") + # zsh 5.8 or earlier + integer -gr zsh_highlight__memo_feature=0 + ;; + ("0 0 fg=red memo=zsh-syntax-highlighting") + # zsh 5.9 or later + integer -gr zsh_highlight__memo_feature=1 + ;; + (" 0 0 fg=red, memo=zsh-syntax-highlighting") ;& + (*) + # We can get here in two ways: + # + # 1. When not running as a widget. In that case, $region_highlight is + # not a special variable (= one with custom getter/setter functions + # written in C) but an ordinary one, so the third case pattern matches + # and we fall through to this block. (The test suite uses this codepath.) + # + # 2. When running under a future version of zsh that will have changed + # the serialization of $region_highlight elements from their underlying + # C structs, so that none of the previous case patterns will match. + # + # In either case, fall back to a version check. + if is-at-least 5.9; then + integer -gr zsh_highlight__memo_feature=1 + else + integer -gr zsh_highlight__memo_feature=0 + fi + ;; + esac + region_highlight[-1]=() + } + + # Reset region_highlight to build it from scratch + if (( zsh_highlight__memo_feature )); then + region_highlight=( "${(@)region_highlight:#*memo=zsh-syntax-highlighting*}" ) + else + # Legacy codepath. Not very interoperable with other plugins (issue #418). + region_highlight=() + fi + + # Remove all highlighting in isearch, so that only the underlining done by zsh itself remains. + # For details see FAQ entry 'Why does syntax highlighting not work while searching history?'. + # This disables highlighting during isearch (for reasons explained in README.md) unless zsh is new enough + # and doesn't have the pattern matching bug + if [[ $WIDGET == zle-isearch-update ]] && { $zsh_highlight__pat_static_bug || ! (( $+ISEARCHMATCH_ACTIVE )) }; then + return $ret + fi + + # Before we 'emulate -L', save the user's options + local -A zsyh_user_options + if zmodload -e zsh/parameter; then + zsyh_user_options=("${(kv)options[@]}") + else + local canonical_options onoff option raw_options + raw_options=(${(f)"$(emulate -R zsh; set -o)"}) + canonical_options=(${${${(M)raw_options:#*off}%% *}#no} ${${(M)raw_options:#*on}%% *}) + for option in "${canonical_options[@]}"; do + [[ -o $option ]] + case $? in + (0) zsyh_user_options+=($option on);; + (1) zsyh_user_options+=($option off);; + (*) # Can't happen, surely? + echo "zsh-syntax-highlighting: warning: '[[ -o $option ]]' returned $?" + ;; + esac + done + fi + typeset -r zsyh_user_options + + emulate -L zsh + setopt localoptions warncreateglobal nobashrematch + local REPLY # don't leak $REPLY into global scope + + # Do not highlight if there are more than 300 chars in the buffer. It's most + # likely a pasted command or a huge list of files in that case.. + [[ -n ${ZSH_HIGHLIGHT_MAXLENGTH:-} ]] && [[ $#BUFFER -gt $ZSH_HIGHLIGHT_MAXLENGTH ]] && return $ret + + # Do not highlight if there are pending inputs (copy/paste). + (( KEYS_QUEUED_COUNT > 0 )) && return $ret + (( PENDING > 0 )) && return $ret + + { + local cache_place + local -a region_highlight_copy + + # Select which highlighters in ZSH_HIGHLIGHT_HIGHLIGHTERS need to be invoked. + local highlighter; for highlighter in $ZSH_HIGHLIGHT_HIGHLIGHTERS; do + + # eval cache place for current highlighter and prepare it + cache_place="_zsh_highlight__highlighter_${highlighter}_cache" + typeset -ga ${cache_place} + + # If highlighter needs to be invoked + if ! type "_zsh_highlight_highlighter_${highlighter}_predicate" >&/dev/null; then + echo "zsh-syntax-highlighting: warning: disabling the ${(qq)highlighter} highlighter as it has not been loaded" >&2 + # TODO: use ${(b)} rather than ${(q)} if supported + ZSH_HIGHLIGHT_HIGHLIGHTERS=( ${ZSH_HIGHLIGHT_HIGHLIGHTERS:#${highlighter}} ) + elif "_zsh_highlight_highlighter_${highlighter}_predicate"; then + + # save a copy, and cleanup region_highlight + region_highlight_copy=("${region_highlight[@]}") + region_highlight=() + + # Execute highlighter and save result + { + "_zsh_highlight_highlighter_${highlighter}_paint" + } always { + : ${(AP)cache_place::="${region_highlight[@]}"} + } + + # Restore saved region_highlight + region_highlight=("${region_highlight_copy[@]}") + + fi + + # Use value form cache if any cached + region_highlight+=("${(@P)cache_place}") + + done + + # Re-apply zle_highlight settings + + # region + () { + (( REGION_ACTIVE )) || return + integer min max + if (( MARK > CURSOR )) ; then + min=$CURSOR max=$MARK + else + min=$MARK max=$CURSOR + fi + if (( REGION_ACTIVE == 1 )); then + [[ $KEYMAP = vicmd ]] && (( max++ )) + elif (( REGION_ACTIVE == 2 )); then + local needle=$'\n' + # CURSOR and MARK are 0 indexed between letters like region_highlight + # Do not include the newline in the highlight + (( min = ${BUFFER[(Ib:min:)$needle]} )) + (( max = ${BUFFER[(ib:max:)$needle]} - 1 )) + fi + _zsh_highlight_apply_zle_highlight region standout "$min" "$max" + } + + # yank / paste (zsh-5.1.1 and newer) + (( $+YANK_ACTIVE )) && (( YANK_ACTIVE )) && _zsh_highlight_apply_zle_highlight paste standout "$YANK_START" "$YANK_END" + + # isearch + (( $+ISEARCHMATCH_ACTIVE )) && (( ISEARCHMATCH_ACTIVE )) && _zsh_highlight_apply_zle_highlight isearch underline "$ISEARCHMATCH_START" "$ISEARCHMATCH_END" + + # suffix + (( $+SUFFIX_ACTIVE )) && (( SUFFIX_ACTIVE )) && _zsh_highlight_apply_zle_highlight suffix bold "$SUFFIX_START" "$SUFFIX_END" + + + return $ret + + + } always { + typeset -g _ZSH_HIGHLIGHT_PRIOR_BUFFER="$BUFFER" + typeset -gi _ZSH_HIGHLIGHT_PRIOR_CURSOR=$CURSOR + } +} + +# Apply highlighting based on entries in the zle_highlight array. +# This function takes four arguments: +# 1. The exact entry (no patterns) in the zle_highlight array: +# region, paste, isearch, or suffix +# 2. The default highlighting that should be applied if the entry is unset +# 3. and 4. Two integer values describing the beginning and end of the +# range. The order does not matter. +_zsh_highlight_apply_zle_highlight() { + local entry="$1" default="$2" + integer first="$3" second="$4" + + # read the relevant entry from zle_highlight + # + # ### In zsh≥5.0.8 we'd use ${(b)entry}, but we support older zsh's, so we don't + # ### add (b). The only effect is on the failure mode for callers that violate + # ### the precondition. + local region="${zle_highlight[(r)${entry}:*]-}" + + if [[ -z "$region" ]]; then + # entry not specified at all, use default value + region=$default + else + # strip prefix + region="${region#${entry}:}" + + # no highlighting when set to the empty string or to 'none' + if [[ -z "$region" ]] || [[ "$region" == none ]]; then + return + fi + fi + + integer start end + if (( first < second )); then + start=$first end=$second + else + start=$second end=$first + fi + region_highlight+=("$start $end $region, memo=zsh-syntax-highlighting") +} + + +# ------------------------------------------------------------------------------------------------- +# API/utility functions for highlighters +# ------------------------------------------------------------------------------------------------- + +# Array used by highlighters to declare user overridable styles. +typeset -gA ZSH_HIGHLIGHT_STYLES + +# Whether the command line buffer has been modified or not. +# +# Returns 0 if the buffer has changed since _zsh_highlight was last called. +_zsh_highlight_buffer_modified() +{ + [[ "${_ZSH_HIGHLIGHT_PRIOR_BUFFER:-}" != "$BUFFER" ]] +} + +# Whether the cursor has moved or not. +# +# Returns 0 if the cursor has moved since _zsh_highlight was last called. +_zsh_highlight_cursor_moved() +{ + [[ -n $CURSOR ]] && [[ -n ${_ZSH_HIGHLIGHT_PRIOR_CURSOR-} ]] && (($_ZSH_HIGHLIGHT_PRIOR_CURSOR != $CURSOR)) +} + +# Add a highlight defined by ZSH_HIGHLIGHT_STYLES. +# +# Should be used by all highlighters aside from 'pattern' (cf. ZSH_HIGHLIGHT_PATTERN). +# Overwritten in tests/test-highlighting.zsh when testing. +_zsh_highlight_add_highlight() +{ + local -i start end + local highlight + start=$1 + end=$2 + shift 2 + for highlight; do + if (( $+ZSH_HIGHLIGHT_STYLES[$highlight] )); then + region_highlight+=("$start $end $ZSH_HIGHLIGHT_STYLES[$highlight], memo=zsh-syntax-highlighting") + break + fi + done +} + +# ------------------------------------------------------------------------------------------------- +# Setup functions +# ------------------------------------------------------------------------------------------------- + +# Helper for _zsh_highlight_bind_widgets +# $1 is name of widget to call +_zsh_highlight_call_widget() +{ + builtin zle "$@" && + _zsh_highlight +} + +# Decide whether to use the zle-line-pre-redraw codepath (colloquially known as +# "feature/redrawhook", after the topic branch's name) or the legacy "bind all +# widgets" codepath. +# +# We use the new codepath under two conditions: +# +# 1. If it's available, which we check by testing for add-zle-hook-widget's availability. +# +# 2. If zsh has the memo= feature, which is required for interoperability reasons. +# See issues #579 and #735, and the issues referenced from them. +# +# We check this with a plain version number check, since a functional check, +# as done by _zsh_highlight, can only be done from inside a widget +# function — a catch-22. +if is-at-least 5.9 && _zsh_highlight__function_callable_p add-zle-hook-widget +then + autoload -U add-zle-hook-widget + _zsh_highlight__zle-line-finish() { + # Reset $WIDGET since the 'main' highlighter depends on it. + # + # Since $WIDGET is declared by zle as read-only in this function's scope, + # a nested function is required in order to shadow its built-in value; + # see "User-defined widgets" in zshall. + () { + local -h -r WIDGET=zle-line-finish + _zsh_highlight + } + } + _zsh_highlight__zle-line-pre-redraw() { + # Set $? to 0 for _zsh_highlight. Without this, subsequent + # zle-line-pre-redraw hooks won't run, since add-zle-hook-widget happens to + # call us with $? == 1 in the common case. + true && _zsh_highlight "$@" + } + _zsh_highlight_bind_widgets(){} + if [[ -o zle ]]; then + add-zle-hook-widget zle-line-pre-redraw _zsh_highlight__zle-line-pre-redraw + add-zle-hook-widget zle-line-finish _zsh_highlight__zle-line-finish + fi +else + # Rebind all ZLE widgets to make them invoke _zsh_highlights. + _zsh_highlight_bind_widgets() + { + setopt localoptions noksharrays + typeset -F SECONDS + local prefix=orig-s$SECONDS-r$RANDOM # unique each time, in case we're sourced more than once + + # Load ZSH module zsh/zleparameter, needed to override user defined widgets. + zmodload zsh/zleparameter 2>/dev/null || { + print -r -- >&2 'zsh-syntax-highlighting: failed loading zsh/zleparameter.' + return 1 + } + + # Override ZLE widgets to make them invoke _zsh_highlight. + local -U widgets_to_bind + widgets_to_bind=(${${(k)widgets}:#(.*|run-help|which-command|beep|set-local-history|yank|yank-pop)}) + + # Always wrap special zle-line-finish widget. This is needed to decide if the + # current line ends and special highlighting logic needs to be applied. + # E.g. remove cursor imprint, don't highlight partial paths, ... + widgets_to_bind+=(zle-line-finish) + + # Always wrap special zle-isearch-update widget to be notified of updates in isearch. + # This is needed because we need to disable highlighting in that case. + widgets_to_bind+=(zle-isearch-update) + + local cur_widget + for cur_widget in $widgets_to_bind; do + case ${widgets[$cur_widget]:-""} in + + # Already rebound event: do nothing. + user:_zsh_highlight_widget_*);; + + # The "eval"'s are required to make $cur_widget a closure: the value of the parameter at function + # definition time is used. + # + # We can't use ${0/_zsh_highlight_widget_} because these widgets are always invoked with + # NO_function_argzero, regardless of the option's setting here. + + # User defined widget: override and rebind old one with prefix "orig-". + user:*) zle -N $prefix-$cur_widget ${widgets[$cur_widget]#*:} + eval "_zsh_highlight_widget_${(q)prefix}-${(q)cur_widget}() { _zsh_highlight_call_widget ${(q)prefix}-${(q)cur_widget} -- \"\$@\" }" + zle -N $cur_widget _zsh_highlight_widget_$prefix-$cur_widget;; + + # Completion widget: override and rebind old one with prefix "orig-". + completion:*) zle -C $prefix-$cur_widget ${${(s.:.)widgets[$cur_widget]}[2,3]} + eval "_zsh_highlight_widget_${(q)prefix}-${(q)cur_widget}() { _zsh_highlight_call_widget ${(q)prefix}-${(q)cur_widget} -- \"\$@\" }" + zle -N $cur_widget _zsh_highlight_widget_$prefix-$cur_widget;; + + # Builtin widget: override and make it call the builtin ".widget". + builtin) eval "_zsh_highlight_widget_${(q)prefix}-${(q)cur_widget}() { _zsh_highlight_call_widget .${(q)cur_widget} -- \"\$@\" }" + zle -N $cur_widget _zsh_highlight_widget_$prefix-$cur_widget;; + + # Incomplete or nonexistent widget: Bind to z-sy-h directly. + *) + if [[ $cur_widget == zle-* ]] && (( ! ${+widgets[$cur_widget]} )); then + _zsh_highlight_widget_${cur_widget}() { :; _zsh_highlight } + zle -N $cur_widget _zsh_highlight_widget_$cur_widget + else + # Default: unhandled case. + print -r -- >&2 "zsh-syntax-highlighting: unhandled ZLE widget ${(qq)cur_widget}" + print -r -- >&2 "zsh-syntax-highlighting: (This is sometimes caused by doing \`bindkey ${(q-)cur_widget}\` without creating the ${(qq)cur_widget} widget with \`zle -N\` or \`zle -C\`.)" + fi + esac + done + } +fi + +# Load highlighters from directory. +# +# Arguments: +# 1) Path to the highlighters directory. +_zsh_highlight_load_highlighters() +{ + setopt localoptions noksharrays bareglobqual + + # Check the directory exists. + [[ -d "$1" ]] || { + print -r -- >&2 "zsh-syntax-highlighting: highlighters directory ${(qq)1} not found." + return 1 + } + + # Load highlighters from highlighters directory and check they define required functions. + local highlighter highlighter_dir + for highlighter_dir ($1/*/(/)); do + highlighter="${highlighter_dir:t}" + [[ -f "$highlighter_dir${highlighter}-highlighter.zsh" ]] && + . "$highlighter_dir${highlighter}-highlighter.zsh" + if type "_zsh_highlight_highlighter_${highlighter}_paint" &> /dev/null && + type "_zsh_highlight_highlighter_${highlighter}_predicate" &> /dev/null; + then + # New (0.5.0) function names + elif type "_zsh_highlight_${highlighter}_highlighter" &> /dev/null && + type "_zsh_highlight_${highlighter}_highlighter_predicate" &> /dev/null; + then + # Old (0.4.x) function names + if false; then + # TODO: only show this warning for plugin authors/maintainers, not for end users + print -r -- >&2 "zsh-syntax-highlighting: warning: ${(qq)highlighter} highlighter uses deprecated entry point names; please ask its maintainer to update it: https://github.com/zsh-users/zsh-syntax-highlighting/issues/329" + fi + # Make it work. + eval "_zsh_highlight_highlighter_${(q)highlighter}_paint() { _zsh_highlight_${(q)highlighter}_highlighter \"\$@\" }" + eval "_zsh_highlight_highlighter_${(q)highlighter}_predicate() { _zsh_highlight_${(q)highlighter}_highlighter_predicate \"\$@\" }" + else + print -r -- >&2 "zsh-syntax-highlighting: ${(qq)highlighter} highlighter should define both required functions '_zsh_highlight_highlighter_${highlighter}_paint' and '_zsh_highlight_highlighter_${highlighter}_predicate' in ${(qq):-"$highlighter_dir${highlighter}-highlighter.zsh"}." + fi + done +} + + +# ------------------------------------------------------------------------------------------------- +# Setup +# ------------------------------------------------------------------------------------------------- + +# Try binding widgets. +_zsh_highlight_bind_widgets || { + print -r -- >&2 'zsh-syntax-highlighting: failed binding ZLE widgets, exiting.' + return 1 +} + +# Resolve highlighters directory location. +_zsh_highlight_load_highlighters "${ZSH_HIGHLIGHT_HIGHLIGHTERS_DIR:-${${0:A}:h}/highlighters}" || { + print -r -- >&2 'zsh-syntax-highlighting: failed loading highlighters, exiting.' + return 1 +} + +# Reset scratch variables when commandline is done. +_zsh_highlight_preexec_hook() +{ + typeset -g _ZSH_HIGHLIGHT_PRIOR_BUFFER= + typeset -gi _ZSH_HIGHLIGHT_PRIOR_CURSOR= +} +autoload -Uz add-zsh-hook +add-zsh-hook preexec _zsh_highlight_preexec_hook 2>/dev/null || { + print -r -- >&2 'zsh-syntax-highlighting: failed loading add-zsh-hook.' + } + +# Load zsh/parameter module if available +zmodload zsh/parameter 2>/dev/null || true + +# Initialize the array of active highlighters if needed. +[[ $#ZSH_HIGHLIGHT_HIGHLIGHTERS -eq 0 ]] && ZSH_HIGHLIGHT_HIGHLIGHTERS=(main) + +if (( $+X_ZSH_HIGHLIGHT_DIRS_BLACKLIST )); then + print >&2 'zsh-syntax-highlighting: X_ZSH_HIGHLIGHT_DIRS_BLACKLIST is deprecated. Please use ZSH_HIGHLIGHT_DIRS_BLACKLIST.' + ZSH_HIGHLIGHT_DIRS_BLACKLIST=($X_ZSH_HIGHLIGHT_DIRS_BLACKLIST) + unset X_ZSH_HIGHLIGHT_DIRS_BLACKLIST +fi + +# Restore the aliases we unned +eval "$zsh_highlight__aliases" +builtin unset zsh_highlight__aliases + +# Set $?. +true