* Disable most shell expansion to function or script
@ 2024-01-04 18:09 Sam B.
2024-01-04 18:55 ` Stephane Chazelas
` (2 more replies)
0 siblings, 3 replies; 6+ messages in thread
From: Sam B. @ 2024-01-04 18:09 UTC (permalink / raw)
To: zsh-users
[-- Attachment #1: Type: text/plain, Size: 790 bytes --]
Hello,
I'm looking for a way to disable most shell expansion for the arguments
to a script or function and treat everything up to a newline char as
verbatim text, i.e. as if quoted.
For example, given a function/script "todo", I'd like
todo Text inc. $var, *glob?, events!, <redirs, >(sub) & more
to behave more like it was quoted:
todo 'Text inc. $var, *glob?, events!, <redirs, >(sub) & more'
I know of noglob to disable glob chars, and can have a look at histchars
to see if events can be disabled. But I'm not sure if any of the other
expansion can possibly disabled.
Mostly I'm interested joting down some plain text which could include
'?!&' and have "todo" receive it all without the shell having done some
magic beforehand.
Any ideas?
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: Disable most shell expansion to function or script
2024-01-04 18:09 Disable most shell expansion to function or script Sam B.
@ 2024-01-04 18:55 ` Stephane Chazelas
2024-01-04 19:16 ` Mikael Magnusson
2024-01-04 23:38 ` Bart Schaefer
2 siblings, 0 replies; 6+ messages in thread
From: Stephane Chazelas @ 2024-01-04 18:55 UTC (permalink / raw)
To: zsh-users
[-- Attachment #1: Type: text/plain, Size: 1275 bytes --]
See
https://unix.stackexchange.com/questions/714338/any-shell-where-expansions-are-turned-off-without-escaping-or-quoting
https://unix.stackexchange.com/questions/716836/zsh-alias-or-shell-function-to-only-echo-its-command-line-including-shell-cont
https://unix.stackexchange.com/questions/731845/how-to-write-a-function-that-takes-an-argument-string-that-does-not-need-to-be-q
For some possible avenues.
On 4 January 2024 18:09:57 GMT, "Sam B." <me@rmz.io> wrote:
>Hello,
>
>I'm looking for a way to disable most shell expansion for the arguments to a script or function and treat everything up to a newline char as verbatim text, i.e. as if quoted.
>
>For example, given a function/script "todo", I'd like
>
> todo Text inc. $var, *glob?, events!, <redirs, >(sub) & more
>
>to behave more like it was quoted:
>
> todo 'Text inc. $var, *glob?, events!, <redirs, >(sub) & more'
>
>I know of noglob to disable glob chars, and can have a look at histchars to see if events can be disabled. But I'm not sure if any of the other expansion can possibly disabled.
>
>Mostly I'm interested joting down some plain text which could include '?!&' and have "todo" receive it all without the shell having done some magic beforehand.
>
>Any ideas?
[-- Attachment #2: Type: text/html, Size: 2062 bytes --]
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: Disable most shell expansion to function or script
2024-01-04 18:09 Disable most shell expansion to function or script Sam B.
2024-01-04 18:55 ` Stephane Chazelas
@ 2024-01-04 19:16 ` Mikael Magnusson
2024-01-04 23:38 ` Bart Schaefer
2 siblings, 0 replies; 6+ messages in thread
From: Mikael Magnusson @ 2024-01-04 19:16 UTC (permalink / raw)
To: zsh-users; +Cc: Sam B.
On 1/4/24, Sam B. <me@rmz.io> wrote:
> Hello,
>
> I'm looking for a way to disable most shell expansion for the arguments
> to a script or function and treat everything up to a newline char as
> verbatim text, i.e. as if quoted.
>
> For example, given a function/script "todo", I'd like
>
> todo Text inc. $var, *glob?, events!, <redirs, >(sub) & more
>
> to behave more like it was quoted:
>
> todo 'Text inc. $var, *glob?, events!, <redirs, >(sub) & more'
>
> I know of noglob to disable glob chars, and can have a look at histchars
> to see if events can be disabled. But I'm not sure if any of the other
> expansion can possibly disabled.
>
> Mostly I'm interested joting down some plain text which could include
> '?!&' and have "todo" receive it all without the shell having done some
> magic beforehand.
>
> Any ideas?
function _accept_line () {
if [[ $CONTEXT = vared ]] || [[ $zsh_eval_context != shfunc ]]; then
zle .$WIDGET
return
fi
if [[ "$BUFFER" = todo\ * ]]; then
BUFFER="todo ${(q)BUFFER[6,-1]}"
zle .$WIDGET
return # not needed in this example but if you handle other stuff below
fi
}
zle -N accept-line _accept_line
zle -N accept-line-and-down-history _accept_line
zle -N accept-and-hold _accept_line
Note that the quoted version will be saved in the history, and if you
recall the event, it will be quoted again by the above code, so there
is room for improvement / other ideas.
For example, make a function that takes no arguments, reads a single
line, and runs todo $REPLY for you. (todo itself could handle this if
given no arguments too?)
runquoted() {
local cmd=( ${@:-todo} ) REPLY
IFS= read -r
$cmd $REPLY
}
% runquoted print -rl
asoeu a-;ua;,. ua-h,.uch <- my input
asoeu a-;ua;,. ua-h,.uch
% runquoted
aosot
zsh: command not found: todo
--
Mikael Magnusson
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: Disable most shell expansion to function or script
2024-01-04 18:09 Disable most shell expansion to function or script Sam B.
2024-01-04 18:55 ` Stephane Chazelas
2024-01-04 19:16 ` Mikael Magnusson
@ 2024-01-04 23:38 ` Bart Schaefer
2024-01-05 17:53 ` Sam B.
2 siblings, 1 reply; 6+ messages in thread
From: Bart Schaefer @ 2024-01-04 23:38 UTC (permalink / raw)
To: zsh-users
On Thu, Jan 4, 2024 at 10:10 AM Sam B. <me@rmz.io> wrote:
>
> I'm looking for a way to disable most shell expansion for the arguments
> to a script or function
> todo Text inc. $var, *glob?, events!, <redirs, >(sub) & more
accept-and-do-nothing() {
BUFFER=': !#:0:s/\://:p !"'"$BUFFER"
zle accept-line
}
zle -N accept-and-do-nothing
It's really difficult to avoid having the history references get
backslash-quoted ( in this example !, becomes \!, ), but otherwise
this skips everything.
What this does is:
- insert a : command as the word in command position.
- insert a history substitution that replaces that word with nothing
and then reprints the whole command without executing it
(substitution is to avoid doubling the first word when !#:0 is reprinted)
- insert the !" reference that disables history for the remainder of
the command line
- accept the result to add the whole thing to the history list
If "todo" is the only command for which you want this effect, you
could replace the ":" with "todo".
> Mostly I'm interested joting down some plain text which could include
> '?!&' and have "todo" receive it all without the shell having done some
> magic beforehand.
The foregoing could be augmented with a zshaddhistory hook to
recognize the magic first word and dump the rest of the line into a
file. Then
todo $(<thatfile)
would pass the whole thing unmodified into "todo" which would have to
"eval" it or something.
However, have you considered using edit-command-line (possibly
repeatedly) to jot things down, and then quote-region or similar when
happy before executing?
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: Disable most shell expansion to function or script
2024-01-04 23:38 ` Bart Schaefer
@ 2024-01-05 17:53 ` Sam B.
2024-01-14 23:28 ` Sam B.
0 siblings, 1 reply; 6+ messages in thread
From: Sam B. @ 2024-01-05 17:53 UTC (permalink / raw)
To: zsh-users
[-- Attachment #1: Type: text/plain, Size: 1737 bytes --]
On Jan 04, 2024 at 15:38, Bart Schaefer wrote:
> On Thu, Jan 4, 2024 at 10:10 AM Sam B. <me@rmz.io> wrote:
>>
>> I'm looking for a way to disable most shell expansion for the arguments
>> to a script or function
>
>> todo Text inc. $var, *glob?, events!, <redirs, > (sub) & more
>
> accept-and-do-nothing() {
> BUFFER=': !#:0:s/\://:p !"'"$BUFFER"
> zle accept-line
> }
> zle -N accept-and-do-nothing
That looks promising. Thanks.
> If "todo" is the only command for which you want this effect, you
> could replace the ":" with "todo".
Might want a few more. But this should only apply to these selected
commands.
>> Mostly I'm interested joting down some plain text which could include
>> '?!&' and have "todo" receive it all without the shell having done some
>> magic beforehand.
>
> However, have you considered using edit-command-line (possibly
> repeatedly) to jot things down, and then quote-region or similar when
> happy before executing?
I want this to be as frictionless and quick as possible. Opening up an
editor is a bit much.
This made me realise though that I don't *need* it to be quoted, I would
be happy if it would escape those chars individually, either as I type
or on accepting the line.
I found this very similar question[1] from a few years ago which solves
the problem for quotes. I'll also try this and see if it'll work for
other special chars too.
[1]: https://www.zsh.org/mla/users/2021/msg00819.html
Will have a play with all this when back from holiday though. Silly of
me to ask a question just before being AFK for a few weeks.
I'll have a read through `url-quote-magic` too, which seems to do
something similar.
Thanks.
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: Disable most shell expansion to function or script
2024-01-05 17:53 ` Sam B.
@ 2024-01-14 23:28 ` Sam B.
0 siblings, 0 replies; 6+ messages in thread
From: Sam B. @ 2024-01-14 23:28 UTC (permalink / raw)
To: zsh-users
[-- Attachment #1: Type: text/plain, Size: 1738 bytes --]
On Jan 05, 2024 at 17:53, Sam B. wrote:
> I'll have a read through `url-quote-magic` too, which seems to do
> something similar.
I quite liked the behaviour of `url-quote-magic` to simply type any of
the "special" chars and have them automatically quoted. So I've modified
`url-quote-magic` to escape chars only when the first word matches
`task` or any alias to it.
There's probably a few improvements possible, but here's a first pass of
my solution.
zstyle -m ':task-quote-magic:\*' task-seps '*' ||
zstyle -e ':task-quote-magic:*' task-seps 'reply=("#{}&<>''${histchars[1]}")'
zstyle -m ':task-quote-magic' task-cmds '*' ||
zstyle -e ':task-quote-magic' task-cmds \
'zmodload -i zsh/parameter;
reply=( task
${(k)galiases[(R)(* |)task *]:-}
${(k)aliases[(R)(* |)task *]:-} )'
function task-quote-magic {
setopt localoptions noksharrays extendedglob
local qkey="${(q)KEYS}"
local -a reply match mbegin mend
# is key different than quoted key
if [[ "$KEYS" != "$qkey" ]]
then
local lbuf="$LBUFFER$qkey"
if [[ "${(Q)LBUFFER}$KEYS" == "${(Q)lbuf}" ]]
then
local -a words
words=("${(@Q)${(z)lbuf}}")
local taskseps taskcmds
zstyle -s ":task-quote-magic" task-cmds taskcmds '|'
if [[ "$words[1]" == (#b)${~taskcmds} ]]
then
zstyle -s ":task-quote-magic:$match[1]" task-seps taskseps ''
fi
[[ "$taskseps" == *"$KEYS"* ]] &&
LBUFFER="$LBUFFER\\"
fi
fi
zle .self-insert
}
zle -N self-insert task-quote-magic
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]
^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2024-01-14 23:30 UTC | newest]
Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2024-01-04 18:09 Disable most shell expansion to function or script Sam B.
2024-01-04 18:55 ` Stephane Chazelas
2024-01-04 19:16 ` Mikael Magnusson
2024-01-04 23:38 ` Bart Schaefer
2024-01-05 17:53 ` Sam B.
2024-01-14 23:28 ` Sam B.
Code repositories for project(s) associated with this public inbox
https://git.vuxu.org/mirror/zsh/
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).