Comments in command-line Zsh
Asked Answered
P

6

183

I switched from Bash to Zsh on Ubuntu and I'm quite happy about it. However, there is something I really miss and I did not find how to achieve the same thing.

In Bash, whenever I was typing a long command and noticed I had to run something else before, I just had to comment it out like in the following:

me@home> #mysuperlongcommand with some arguments
me@home> thecommandIhavetorunfirst #and then: up up
me@home> #mysuperlongcommand with some arguments #I just need to uncomment it!

However, this quite recurrent situation is not as easy to address as with zsh, given #mysuperlongcommand will be run as such (and resulting in: zsh: command not found: #mysuperlongcommand.

Preferable answered 26/7, 2012 at 13:58 Comment(1)
It's also dangerous because if you put a ; character in your comment, it will execute the proceeding commands (I just ran a rm -r operation I wasn't planning on running yet :P ).Coster
B
258

Having just started trying out zsh, I ran into this problem too. You can do setopt interactivecomments (in your .zshrc file to make it permanent) to activate the bash-style comments.

The Z Shell Manual indicates that while this is default behavior for ksh (Korn shell) and sh (Bourne shell), and I am guessing also for bash (Bourne-again shell), it is not default for zsh (Z shell):

In the following list, options set by default in all emulations are marked <D>; those set by default only in csh, ksh, sh, or zsh emulations are marked <C>, <K>, <S>, <Z> as appropriate.

INTERACTIVE_COMMENTS (-k) <K> <S> Allow comments even in interactive shells.

Bot answered 8/8, 2012 at 21:56 Comment(8)
You can also do set -k if it's just a one off. But I'd use the setopt line from this answer in my zshrcTenderhearted
Is there a reason that this isn't the default behaviour?Adora
@Adora lots of the best bits of zsh are default off. don't know whyPronounced
@Adora maybe this should encourage people to dig down into mans and settings to make zsh their own tool as opposed to something that just worksSoandso
@Adora I like too, tho some tools don't ;)Soandso
@aryndin, good/sane/meaningful defaults is the hallmark of usability. Besides, that argument doesn't fare well if I have to ssh into dozens of computers (where I cannot expect to find my zshrc).Waist
I did this at some point but the setting doesn't appear to be permanent and goes away later. Maybe if I had it to .zshrc it will workDisputant
@6005 It is not permanent no. When I quite and reopen Terminal, I need to run setopt again. Anyone knows how to make it permanent?Crowned
S
47

I use

bindkey "^Q" push-input

From the zsh manual:

Push the entire current multiline construct onto the buffer stack and return to the top-level (PS1) prompt. If the current parser construct is only a single line, this is exactly like push-line. Next time the editor starts up or is popped with get-line, the construct will be popped off the top of the buffer stack and loaded into the editing buffer.

So it looks like this:

> long command
Ctrl+Q => long command disappears to the stack
> forgotten command
long command reappears from stack
> long command

Also, if you set the INTERACTIVE_COMMENTS option (setopt INTERACTIVE_COMMENTS), you will be able to use comments in interactive shells like you are used to.

Singly answered 27/7, 2012 at 15:8 Comment(8)
I like your option, but I can't make it work :( Is there a way I should write the binding in the file, or is it just two characters, ^ and Q? My command is erased, but I don't know how to make it appear again in input.Illimani
@Mihnea if the command disappears it seems that push-input is working. It should appear back when you run the next command or just press enter. Doesn't it do that?Pantelegraph
Silly me, i was expecting to have to press up-arrow. Thanks, great tip, !Illimani
Is there a way to share the stack with child processes? I often used the comment thingy with bash when I forgot to launch a screen, i.e. i did '#large command; history -a; screen' and the picked it up inside the screen from the history...Immingle
@Immingle the stack can be manipulated with read -z and print -z, so with some scripting and temporary files you could. But then a custom zle widget for saving the command line to a temp file might be simpler, and shared history will be simpler still.Pantelegraph
While the currently accepted answer addresses the questioner's question, this answer addresses the questioner's intention. I.e. zsh has a better way of achieving the intended result, and this is it.Chacha
This should be the accepted answer. If you use oh-my-zsh you can use Ctrl-Q for this out of the box.Latrinalatrine
Thanks for the tip! Adding setopt INTERACTIVE_COMMENTS to my ~/.zshrc file worked for me!Janiculum
Y
23

I find myself doing this often as well. What I do is cut the long command, execute the command that needs to go first and then paste the long command back in. This is easy: CTRL+U cuts the current command into a buffer, CTRL+Y pastes it. Works in zsh and bash.

Yam answered 26/7, 2012 at 15:2 Comment(3)
well, actually, my way is a workaround while your solution is the best fit ;)Preferable
This shouldn't be the accepted answer. The solution below which says to use "setopt interactivecomments" should be. The reason for this is that if you just cut the current command, then it isn't in your zsh history, and also you then can't easily use cut and paste while typing in your new command without overwriting the command you were trying to save.Hebdomad
Using comments and the solution in this answers are both workarounds; the push-input method posted by Michał Politowski is more correct.Yam
S
11

Add the line setopt INTERACTIVE_COMMENTS to your ~/.zshrc file, save it, and relaunch the shell.

This is to clarify on @Lajnold's answer and @Hamish Downer's comment. It just took me a little bit to figure out how to make this change permanent. You probably want to add that line before exporting variables, so maybe add it toward the top of the file. I already had setopt PROMPT_SUBST in my ~/.zshrc file, so I just added it after that line. This will ensure the settings are loaded every time you launch the zsh terminal.

Serenaserenade answered 5/4, 2022 at 22:38 Comment(3)
set interactive_comments also works for command line. I wonder why this doesn't work for comments within a function?Baber
i didn't even have a .zshrc file in ~ in my refurbished Mac Mini that came with Catalina. Thanks.Foist
Once you've edited ~/.zshrc you can apply the changes to your current shell without closing or relaunching anything by running this: source ~/.zshrcPolyandry
E
7
: sh generate_sample.sh arg1

The addition of ":" doesn't execute the command in zsh.

sh generate_sample.sh : arg1

Now the arg1 is commented.

I am on Mac OS Big Sur and used it multiple times.

Edit: ":" procedure works with giving no spaces. ": command" is correct but ":command" isn't

Erich answered 6/8, 2021 at 7:42 Comment(2)
This seems to work? But I'm having a hard time googling to find more info...Southwards
@DanielWaltrip Check out https://mcmap.net/q/22367/-what-is-the-purpose-of-the-colon-gnu-bash-builtin/115690 for details in bash, but the same should apply to zshGrazier
M
0

In addition to setopt interactivecomments, suggested by @Lajnold, you might also want to add something like the following to prevent certain comments from being written to history (from https://superuser.com/questions/352788/how-to-prevent-a-command-in-the-zshell-from-being-saved-into-history):

This overrides the ZSH built-in function zshaddhistory():

  • Will log comments that start in column 1 not followed by one or more spaces (i.e. #somecommand that I want to come back to)
  • Won't log comments that start in column 1 followed by one or more spaces
  • Won't log indented comments, padded by spaces from column 1
  • Won't log commands with a space in column 1 (handy shortcut for running commands that you don't want logged
setopt interactivecomments

function zshaddhistory() {
  emulate -L zsh
  if ! [[ "$1" =~ "(^#\s+|^\s+#|^ )" ]] ; then
      print -sr -- "${1%%$'\n'}"
      fc -p
  else
      return 1
  fi
}

For reference, this is the default zshaddhistory() http://zsh.sourceforge.net/Doc/Release/Functions.html

zshaddhistory() {
  print -sr -- ${1%%$'\n'}
  fc -p .zsh_local_history
}
Mammet answered 8/1, 2020 at 15:54 Comment(1)
Or just add setopt HIST_IGNORE_SPACE to your ~/.zshrc as mentioned in that link.Aerotherapeutics

© 2022 - 2024 — McMap. All rights reserved.