Skip to content

Review performance of ZSH_HIGHLIGHT_DIRS_BLACKLIST #801

Open
@danielshahaf

Description

Here's the implementation of ZSH_HIGHLIGHT_DIRS_BLACKLIST:

# Check if this is a blacklisted path
if [[ $expanded_path[1] == / ]]; then
tmp_path=$expanded_path
else
tmp_path=$PWD/$expanded_path
fi
tmp_path=$tmp_path:a
while [[ $tmp_path != / ]]; do
[[ -n ${(M)ZSH_HIGHLIGHT_DIRS_BLACKLIST:#$tmp_path} ]] && return 1
tmp_path=$tmp_path:h
done

That runs a nested loop for each ordinary (non-option) word on the command line. I suspect that's not very performant.

  • Confirm whether that's performing acceptably or not

In case that's an issue, ideas:

  • Special case the common case that ZSH_HIGHLIGHT_DIRS_BLACKLIST is empty.
  • Join the blacklist entries into a pattern that uses alternations.
  • Join the blacklist entries with NULs and use plain substring matching

The last option should be something like this:

readonly NUL=$'\0'
local -a t=( "" "${ZSH_HIGHLIGHT_DIRS_BLACKLIST[@]}" "" )
haystack="${(pj.\0.)^ZSH_HIGHLIGHT_DIRS_BLACKLIST[@]%/}/"
needle=${NUL}${expanded_arg%/}/${NUL}
if [[ $haystack == *$needle* ]]; then

That munges both the needle and the haystack by ensuring each path has a trailing slash and is both prefixed and suffixed by NULs (the latter is because /foo shouldn't match /foobar or /baz/foo).

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions