Open Raizo62 opened 5 years ago
However, I'm asking a different question: what algorithm should 'sudo foo' follow to decide what color to highlight 'foo' in when root's path is NOT configured.
'sudo foo' must follow the same algorithm as sudo to know what color to use with 'foo'.
But zsh doesn't have the same right as the sudo command then it can't do the same thing, and you don't want tu use sudo
(and you have right)
I am not the good person to answer to this question. I choose the solution which colors correctly more often foo
.
With me, initialize ZSH_HIGHLIGHT_SPECIAL_PATH with root's path will be the default.
Then if an user removes the value of this variable, sudo ifconfig
will be red.
I can add also that unset ZSH_HIGHLIGHT_SPECIAL_PATH can is the case where the user is not in sudoers : then all commands behind sudo (even ls
) will be red (This default choose will be do by the admin of the server)
I can add also that unset ZSH_HIGHLIGHT_SPECIAL_PATH can is the case where the user is not in sudoers : then all commands behind sudo (even ls ) will be red
First, ls
would be green when your variable is unset. (I agree that it would make sense for it to be red if the command would fail, but we can't determine that.)
Second, the common case, provided that the user has typed sudo
, is that the user is in sudoers(5) and hasn't configured z-sy-h's "root's PATH" knob.
You may have meant "set to empty" rather than "unset", but your code doesn't distinguish these two cases, and even if it did, I doubt zsh-syntax-highlighting is popular enough that admins will code their sudoers(5) configs into /usr/local/etc/zshrc's setting of your variable.
You may have meant "set to empty" rather than "unset", but your code doesn't distinguish these two cases,
Yes, i know. I did think this idea when i was answer you. It is easy to modify the patch to do this.
I doubt zsh-syntax-highlighting is popular enough that admins will code their sudoers(5) configs into /usr/local/etc/zshrc's setting of your variable.
sudo ls
will fail and ls
will be red. It is correct.sudo ls
will success but ls
will be red. It is uncorrect. Perhaps the user can read the doc and configure the variable to have green.sudo ls
will success and ls
will be green. It is correct.sudo ls
will fail and ls
will be green. It is uncorrect. Perhaps the user can read the doc and open a ticket or speak to the admin ;-)I doubt zsh-syntax-highlighting is popular enough that admins will code their sudoers(5) configs into /usr/local/etc/zshrc's setting of your variable.
Perhaps, but if zsh-syntax-highlighting is enough popular to be installed by the "admin", the "admin" can configured it ;-)
I propose a boolean variable to color the command after sudo
: if this variable is unset or true, the command behind sudo
is always uncolored, otherwise zsh uses ZSH_HIGHLIGHT_SPECIAL_PATH.
If an user is not in sudoers and the admin does nothing, then the command sudo ls will fail and ls will be red. It is correct.
No, it won't be red. It will be green, like I already said.
I propose a boolean variable to color the command after sudo : if this variable is unset or true, the command behind sudo is always uncolored, otherwise zsh uses ZSH_HIGHLIGHT_SPECIAL_PATH.
That's what I proposed back in December. I'm glad we agree on something :-)
If an user is not in sudoers and the admin does nothing, then the command sudo ls will fail and ls will be red. It is correct.
No, it won't be red. It will be green, like I already said.
I speaked with a system with ZSH_HIGHLIGHT_SPECIAL_PATH (and with unset)
I propose a boolean variable to color the command after sudo : if this variable is unset or true, the command behind sudo is always uncolored, otherwise zsh uses ZSH_HIGHLIGHT_SPECIAL_PATH.
That's what I proposed back in December. I'm glad we agree on something :-)
I am not against if i have always a functionality to color the commands behind sudo ;-)
I speaked with a system with ZSH_HIGHLIGHT_SPECIAL_PATH (and with unset)
Yes, and I already said —
Second, the common case, provided that the user has typed
sudo
, is that the user is in sudoers(5) and hasn't configured z-sy-h's "root's PATH" knob.
That means ls
shouldn't be red by default.
I regret to say that I find this thread/discussion/collaboration challenging to participate in; moreover, I suspect the feeling's mutual. There are still unanswered design questions¹, but I fear that trying to discuss them would frustrate both of us. I'd like to avoid that outcome, if possible.
¹ For one, shouldn't the actual argument to the -u
option be part of the zstyle context the path is looked up under? But this doesn't answer all open questions, not to mention that there isn't yet consensus on how much sudo
should be special-cased in the first place...
I believe that you want a miracle solution. Miracle solution because zsh-syntax-highlighting doesn't have access to files like sudoers(5)
, but zsh-syntax-highlighting must have access to this files to choose automatically the good color for foo
behind sudo
.
I tried to convince you to accept a partial solution where it is the user who explains to zsh-syntax-highlighting what is the good color.
I'm afraid that this functionality stays in standby for a longtime. Already 3 months without progress. I think that a miracle solution will need more more time.
It is too bad because we need it : When we tape a command, we have no interest for sudo
but for foo
.
At the end, i hoped that you accept to have a "beta-functionality" (beta because no perfect) disabled by default.
Ok. It is your code after all.
I will try to write a patch which applies our discussion. I will copy-paste it here.
I believe that you want a miracle solution. Miracle solution because zsh-syntax-highlighting doesn't have access to files like
sudoers(5)
, but zsh-syntax-highlighting must have access to this files to choose automatically the good color forfoo
behindsudo
.
Then you misunderstood me. As far as I'm concerned, "z-sy-h doesn't have access to sudoers(5)" is a design constraint. What I'd like to do is to find a good solution, within the bounds of the effective constraints.
I tried to convince you to accept a partial solution where it is the user who explains to zsh-syntax-highlighting what is the good color.
That part I agree with.
At the end, i hoped that you accept to have a "beta-functionality" (beta because no perfect) disabled by default.
For avoidance of doubt, I never consider whether a fix is complete as a criterion to merging it; I only consider whether it is sound. In other words, I would happily merge a patch that implements only part of the desired behaviour. Your patch, however, fixes one use-case but regresses others.
I will try to write a patch which applies our discussion. I will copy-paste it here.
I look forward to the revised patch.
zsh_highlight_main__test_type_builtin
also the change of PATH can't modify the behavior of the commands in zsh_highlight_main__type
builtin type -w -- $1 >/dev/null
are replaced by call to zsh_highlight_main__test_type_builtin
ZSH_HIGHLIGHT_SPECIAL_PATH
exists but is empty, foo
in sudo foo
is always redZSH_HIGHLIGHT_SPECIAL_PATH
is not empty, zsh searchs in the PATH ZSH_HIGHLIGHT_SPECIAL_PATH
to know if the command foo
in sudo foo
existsfoo
is in ZSH_HIGHLIGHT_SPECIAL_COMMAND
then "Admin" says that user has access to this command : foo
in sudo foo
is greenfoo
in sudo foo
has no color if ZSH_HIGHLIGHT_SPECIAL_PATH
is not exist, but i don't know how to do that....._zsh_highlight_main__test_type_builtin() {
if [[ -n ${ZSH_HIGHLIGHT_SPECIAL_PATH} ]]; then
if [ "$this_word" = ":sudo_opt::start:" ]; then
# ZSH_HIGHLIGHT_SPECIAL_PATH exist is not empty : "Admin" says that user has access to commands in these paths with sudo
local PATH="${ZSH_HIGHLIGHT_SPECIAL_PATH}"
fi
fi
builtin type -w -- $1 >/dev/null 2>&1
}
# Get the type of a command.
#
# Uses the zsh/parameter module if available to avoid forks, and a
# wrapper around 'type -w' as fallback.
#
# If $2 is 0, do not consider aliases.
#
# The result will be stored in REPLY.
_zsh_highlight_main__type() {
integer -r aliases_allowed=${2-1}
# We won't cache replies of anything that exists as an alias at all, to
# ensure the cached value is correct regardless of $aliases_allowed.
#
# ### We probably _should_ cache them in a cache that's keyed on the value of
# ### $aliases_allowed, on the assumption that aliases are the common case.
integer may_cache=1
# Cache lookup
if (( $+_zsh_highlight_main__command_type_cache )); then
REPLY=$_zsh_highlight_main__command_type_cache[(e)$1]
if [[ -n "$REPLY" ]]; then
return
fi
fi
if [[ -v ZSH_HIGHLIGHT_SPECIAL_COMMAND ]]; then
if (( ${ZSH_HIGHLIGHT_SPECIAL_COMMAND[(I)$1]} )); then
# ZSH_HIGHLIGHT_SPECIAL_COMMAND exists : if foo of "sudo foo" is in ZSH_HIGHLIGHT_SPECIAL_COMMAND then "Admin" says that user has access to this command
REPLY=command
return 0
fi
fi
if [[ -v ZSH_HIGHLIGHT_SPECIAL_PATH ]]; then
if [ "$this_word" = ":sudo_opt::start:" ]; then
if [ -z "${ZSH_HIGHLIGHT_SPECIAL_PATH}" ]; then
# ZSH_HIGHLIGHT_SPECIAL_PATH exist and is empty : "Admin" wants to say that user has no access to sudo : foo in "sudo foo" is red
REPLY=none
return 0
fi
fi
fi
# Main logic
if (( $#options_to_set )); then
setopt localoptions $options_to_set;
fi
unset REPLY
if zmodload -e zsh/parameter; then
if (( $+aliases[(e)$1] )); then
may_cache=0
fi
if (( $+aliases[(e)$1] )) && (( aliases_allowed )); then
REPLY=alias
elif [[ $1 == *.* && -n ${1%.*} ]] && (( $+saliases[(e)${1##*.}] )); then
REPLY='suffix alias'
elif (( $reswords[(Ie)$1] )); then
REPLY=reserved
elif (( $+functions[(e)$1] )); then
REPLY=function
elif (( $+builtins[(e)$1] )); then
REPLY=builtin
elif (( $+commands[(e)$1] )); then
REPLY=command
# zsh 5.2 and older have a bug whereby running 'type -w ./sudo' implicitly
# runs 'hash ./sudo=/usr/local/bin/./sudo' (assuming /usr/local/bin/sudo
# exists and is in $PATH). Avoid triggering the bug, at the expense of
# falling through to the $() below, incurring a fork. (Issue #354.)
#
# The first disjunct mimics the isrelative() C call from the zsh bug.
elif { [[ $1 != */* ]] || is-at-least 5.3 } &&
! _zsh_highlight_main__test_type_builtin; then
REPLY=none
fi
fi
if ! (( $+REPLY )); then
# Note that 'type -w' will run 'rehash' implicitly.
#
# We 'unalias' in a subshell, so the parent shell is not affected.
#
# The colon command is there just to avoid a command substitution that
# starts with an arithmetic expression [«((…))» as the first thing inside
# «$(…)»], which is area that has had some parsing bugs before 5.6
# (approximately).
REPLY="${$(:; (( aliases_allowed )) || unalias -- $1 2>/dev/null; LC_ALL=C _zsh_highlight_main__test_type_builtin)##*: }"
if [[ $REPLY == 'alias' ]]; then
may_cache=0
fi
fi
# Cache population
if (( may_cache )) && (( $+_zsh_highlight_main__command_type_cache )); then
_zsh_highlight_main__command_type_cache[(e)$1]=$REPLY
fi
[[ -n $REPLY ]]
return $?
}
- Add funtion
zsh_highlight_main__test_type_builtin
also the change of PATH can't modify the behavior of the commands inzsh_highlight_main__type
Thanks for the patch!
Please send the same code as a pull request so it's easier to review.
- I wanted that foo in
sudo foo
has normal color ifZSH_HIGHLIGHT_SPECIAL_PATH
is not exist, but i don't know how to do that.....
Good question.
Right now, it gets highlighted as unknown-token because of line 840 in master, right?
How about adding a new style, "indeterminate"? _zsh_highlight_main__type would return some new value, the loop would map that value to the style [indeterminate] (rather than [unknown-token], and we can make that style have no special highlighting by default. (@phy1729 what do you think?)
_zsh_highlight_main__test_type_builtin() { } _zsh_highlight_main__type() { }
So, to summarize, your overall approach is:
When falling back to the 'type' builtin, run it with a custom PATH;
Add two new knobs, ZSH_HIGHLIGHT_SPECIAL_PATH and ZSH_HIGHLIGHT_SPECIAL_COMMAND.
Is that an accurate summary?
Thanks again for the patch; I'll have to sleep on it.
Please send the same code as a pull request so it's easier to review.
It is done.
Is that an accurate summary?
Yes it is. ZSH_HIGHLIGHT_SPECIAL_PATH and ZSH_HIGHLIGHT_SPECIAL_COMMAND are not dependent on each other. These are 2 different approaches. ZSH_HIGHLIGHT_SPECIAL_PATH is more generic, and ZSH_HIGHLIGHT_SPECIAL_COMMAND is more precise
In the description of the pull request, i have put examples to use them.
How about adding a new style, "indeterminate"? _zsh_highlight_main__type would return some new value, the loop would map that value to the style [indeterminate] (rather than [unknown-token], and we can make that style have no special highlighting by default. (@phy1729 what do you think?)
I'm all for distinguishing the different meanings of unknown-token. Couple of questions,
I don't see it brought up before (apologies if I missed it), but the current approach would mishighlight other precomamnds (e.g. command ifconfig
). This is partially an existing bug (since z-sy-h doesn't keep track of precommands), but the interface should allow for the user or admin to specify to which precommands the special path applies.
This is partially an existing bug (since z-sy-h doesn't keep track of precommands), but the interface should allow for the user or admin to specify to which precommands the special path applies.
That's a textbook case for zstyle's, isn't it? (in order to simulate an associative array having plain arrays for values)
I wonder what to do with multiple precommands (e.g., builtin command doas -u alice sudo -u bob ssh foo ls
). I suppose we can make them available in the style context (:…:builtin+command+…:…
), or in a parameter for zstyle -e
to access.
See also #608.
Note to self: upstream, should zstyle -e
make available to the run code the concrete value of the style, as passed to the zstyle -[asb]
call?
See also workers/45424, "completion: Add **/sbin to PATH when completing commands like sudo".
This is a special case of #695: once we have the additional styles proposed there, we could easily highlight the command word after sudo
(or ssh
or whatever) as "indeterminate" rather than as a hard error.
… and a duplicate of #107.
Hi
Sorry, i come back for an other problem with sudo
With "sudo ls" , "ls" is colorized correctly with green
with "sudo ifup" where "ifup" is only in "/sbin", "ifup" is colorized in red