Add files via upload
23
plugins/zsh-syntax-highlighting/COPYING.md
Normal file
|
|
@ -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.
|
||||
99
plugins/zsh-syntax-highlighting/HACKING.md
Normal file
|
|
@ -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.
|
||||
|
||||
64
plugins/zsh-syntax-highlighting/Makefile
Normal file
|
|
@ -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
|
||||
97
plugins/zsh-syntax-highlighting/README.md
Normal file
|
|
@ -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: [](images/before1.png)
|
||||
<br/>
|
||||
After: [](images/after1.png)
|
||||
|
||||
Before: [](images/before2.png)
|
||||
<br/>
|
||||
After: [](images/after2.png)
|
||||
|
||||
Before: [](images/before3.png)
|
||||
<br/>
|
||||
After: [](images/after3.png)
|
||||
|
||||
Before: [](images/before4-smaller.png)
|
||||
<br/>
|
||||
After: [](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 <kbd>Ctrl+R</kbd> 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
|
||||
920
plugins/zsh-syntax-highlighting/changelog.md
Normal file
|
|
@ -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 <kbd>⮀ Tab</kbd> 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<CURSOR>`)
|
||||
[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 cat
|
||||
```
|
||||
|
||||
- redirection operators:
|
||||
|
||||
```zsh
|
||||
echo > 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.)
|
||||
|
||||
BIN
plugins/zsh-syntax-highlighting/images/after1-smaller.png
Normal file
|
After Width: | Height: | Size: 2.5 KiB |
BIN
plugins/zsh-syntax-highlighting/images/after1.png
Normal file
|
After Width: | Height: | Size: 5.7 KiB |
BIN
plugins/zsh-syntax-highlighting/images/after2-smaller.png
Normal file
|
After Width: | Height: | Size: 4.3 KiB |
BIN
plugins/zsh-syntax-highlighting/images/after2.png
Normal file
|
After Width: | Height: | Size: 10 KiB |
BIN
plugins/zsh-syntax-highlighting/images/after3-smaller.png
Normal file
|
After Width: | Height: | Size: 1.6 KiB |
BIN
plugins/zsh-syntax-highlighting/images/after3.png
Normal file
|
After Width: | Height: | Size: 3.3 KiB |
BIN
plugins/zsh-syntax-highlighting/images/after4-smaller.png
Normal file
|
After Width: | Height: | Size: 3.1 KiB |
BIN
plugins/zsh-syntax-highlighting/images/before1-smaller.png
Normal file
|
After Width: | Height: | Size: 1.6 KiB |
BIN
plugins/zsh-syntax-highlighting/images/before1.png
Normal file
|
After Width: | Height: | Size: 2.6 KiB |
BIN
plugins/zsh-syntax-highlighting/images/before2-smaller.png
Normal file
|
After Width: | Height: | Size: 2.5 KiB |
BIN
plugins/zsh-syntax-highlighting/images/before2.png
Normal file
|
After Width: | Height: | Size: 2.6 KiB |
BIN
plugins/zsh-syntax-highlighting/images/before3-smaller.png
Normal file
|
After Width: | Height: | Size: 763 B |
BIN
plugins/zsh-syntax-highlighting/images/before3.png
Normal file
|
After Width: | Height: | Size: 1.4 KiB |
BIN
plugins/zsh-syntax-highlighting/images/before4-smaller.png
Normal file
|
After Width: | Height: | Size: 2.9 KiB |
BIN
plugins/zsh-syntax-highlighting/images/preview-smaller.png
Normal file
|
After Width: | Height: | Size: 5.8 KiB |
BIN
plugins/zsh-syntax-highlighting/images/preview.png
Normal file
|
After Width: | Height: | Size: 14 KiB |
21
plugins/zsh-syntax-highlighting/release.md
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
# Release procedure (for developers):
|
||||
|
||||
- Ensure every `is-at-least` invocation passes a stable zsh release's version number as the first argument
|
||||
- For minor (A.B.0) releases:
|
||||
- Check whether the release uses any not-yet-released zsh features
|
||||
- Check open issues and outstanding pull requests
|
||||
- Confirm `make test` passes
|
||||
- check with multiple zsh versions
|
||||
(easiest to check GitHub Actions: https://github.com/zsh-users/zsh-syntax-highlighting/actions)
|
||||
- Update changelog.md
|
||||
`tig --abbrev=12 --abbrev-commit 0.4.1..upstream/master`
|
||||
- Make sure there are no local commits and that `git status` is clean;
|
||||
Remove `-dev` suffix from `./.version`;
|
||||
Commit that using `git commit -m "Tag version $(<.version)." .version`;
|
||||
Tag it using `git tag -s -m "Tag version $(<.version)" $(<.version)`;
|
||||
Increment `./.version` and restore the `-dev` suffix;
|
||||
Commit that using `git commit -C b5c30ae52638e81a38fe5329081c5613d7bd6ca5 .version`.
|
||||
- Push with `git push && git push --tags`
|
||||
- Notify downstreams (OS packages)
|
||||
- anitya should autodetect the tag
|
||||
- Update /topic on IRC
|
||||
124
plugins/zsh-syntax-highlighting/tests/README.md
Normal file
|
|
@ -0,0 +1,124 @@
|
|||
zsh-syntax-highlighting / tests
|
||||
===============================
|
||||
|
||||
Utility scripts for testing zsh-syntax-highlighting highlighters.
|
||||
|
||||
The tests harness expects the highlighter directory to contain a `test-data`
|
||||
directory with test data files.
|
||||
See the [main highlighter](../highlighters/main/test-data) for examples.
|
||||
|
||||
Tests should set the following variables:
|
||||
|
||||
1.
|
||||
Each test should define the string `$BUFFER` that is to be highlighted and the
|
||||
array parameter `$expected_region_highlight`.
|
||||
The value of that parameter is a list of strings of the form `"$i $j $style"`.
|
||||
or `"$i $j $style $todo"`.
|
||||
Each string specifies the highlighting that `$BUFFER[$i,$j]` should have;
|
||||
that is, `$i` and `$j` specify a range, 1-indexed, inclusive of both endpoints.
|
||||
`$style` is a key of `$ZSH_HIGHLIGHT_STYLES`.
|
||||
If `$todo` exists, the test point is marked as TODO (the failure of that test
|
||||
point will not fail the test), and `$todo` is used as the explanation.
|
||||
|
||||
2.
|
||||
If a test sets `$skip_test` to a non-empty string, the test will be skipped
|
||||
with the provided string as the reason.
|
||||
|
||||
3.
|
||||
If a test sets `$fail_test` to a non-empty string, the test will be skipped
|
||||
with the provided string as the reason.
|
||||
|
||||
4.
|
||||
If a test sets `unsorted=1` the order of highlights in `$expected_region_highlight`
|
||||
need not match the order in `$region_highlight`.
|
||||
|
||||
5.
|
||||
Normally, tests fail if `$expected_region_highlight` and `$region_highlight`
|
||||
have different numbers of elements. To mark this check as expected to fail,
|
||||
tests may set `$expected_mismatch` to an explanation string (like `$todo`);
|
||||
this is useful when the only difference between actual and expected is that actual
|
||||
has some additional, superfluous elements. This check is skipped if the
|
||||
`$todo` component is present in any regular test point.
|
||||
|
||||
**Note**: `$region_highlight` uses the same `"$i $j $style"` syntax but
|
||||
interprets the indexes differently.
|
||||
|
||||
**Note**: Tests are run with `setopt NOUNSET WARN_CREATE_GLOBAL`, so any
|
||||
variables the test creates must be declared local.
|
||||
|
||||
**Isolation**: Each test is run in a separate subshell, so any variables,
|
||||
aliases, functions, etc., it defines will be visible to the tested code (that
|
||||
computes `$region_highlight`), but will not affect subsequent tests. The
|
||||
current working directory of tests is set to a newly-created empty directory,
|
||||
which is automatically cleaned up after the test exits. For example:
|
||||
|
||||
```zsh
|
||||
setopt PATH_DIRS
|
||||
mkdir -p foo/bar
|
||||
touch foo/bar/testing-issue-228
|
||||
chmod +x foo/bar/testing-issue-228
|
||||
path+=( "$PWD"/foo )
|
||||
|
||||
BUFFER='bar/testing-issue-228'
|
||||
|
||||
expected_region_highlight=(
|
||||
"1 21 command" # bar/testing-issue-228
|
||||
)
|
||||
```
|
||||
|
||||
|
||||
Writing new tests
|
||||
-----------------
|
||||
|
||||
An experimental tool is available to generate test files:
|
||||
|
||||
```zsh
|
||||
zsh -f tests/generate.zsh 'ls -x' acme newfile
|
||||
```
|
||||
|
||||
This generates a `highlighters/acme/test-data/newfile.zsh` test file based on
|
||||
the current highlighting of the given `$BUFFER` (in this case, `ls -x`).
|
||||
|
||||
_This tool is experimental._ Its interface may change. In particular it may
|
||||
grow ways to set `$PREBUFFER` to inject free-form code into the generated file.
|
||||
|
||||
|
||||
Highlighting test
|
||||
-----------------
|
||||
|
||||
[`test-highlighting.zsh`](tests/test-highlighting.zsh) tests the correctness of
|
||||
the highlighting. Usage:
|
||||
|
||||
```zsh
|
||||
zsh test-highlighting.zsh <HIGHLIGHTER NAME>
|
||||
```
|
||||
|
||||
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 <HIGHLIGHTER NAME>
|
||||
```
|
||||
|
||||
All tests may be run with
|
||||
|
||||
```zsh
|
||||
make perf
|
||||
```
|
||||
40
plugins/zsh-syntax-highlighting/tests/edit-failed-tests
Normal file
|
|
@ -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.
|
||||
117
plugins/zsh-syntax-highlighting/tests/generate.zsh
Normal file
|
|
@ -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 ')'
|
||||
71
plugins/zsh-syntax-highlighting/tests/tap-colorizer.zsh
Normal file
|
|
@ -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
|
||||
47
plugins/zsh-syntax-highlighting/tests/tap-filter
Normal file
|
|
@ -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,
|
||||
<STDIN>;
|
||||
291
plugins/zsh-syntax-highlighting/tests/test-highlighting.zsh
Normal file
|
|
@ -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
|
||||
}
|
||||
103
plugins/zsh-syntax-highlighting/tests/test-perfs.zsh
Normal file
|
|
@ -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
|
||||
78
plugins/zsh-syntax-highlighting/tests/test-zprof.zsh
Normal file
|
|
@ -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
|
||||
|
|
@ -0,0 +1,2 @@
|
|||
0=${(%):-%N}
|
||||
source ${0:A:h}/zsh-syntax-highlighting.zsh
|
||||
587
plugins/zsh-syntax-highlighting/zsh-syntax-highlighting.zsh
Normal file
|
|
@ -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 <keys> ${(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
|
||||