checkwinsize equivalent in zsh? - bash

I am migrating from bash to zsh and as part of that I am transitioning over my dotfiles. Is there an equivalent to "checkwinsize" in zsh? I couldn't find one after searching, the relevant code in my .bashrc is
shopt -s checkwinsize
I tried
setopt -s checkwinsize
to no avail. It might be the case that this option isn't needed in zsh (my understanding is that this fixes some sort of bash bug with resizing the windows after exiting an editor).

Zsh doesn't have that option - at least, there's no mention of it in the Z Shell Manual (Chapter 16:Options).
If you see issues with your terminal after resizing the window I guess reset is always an option!

Related

commenting not working in iTerm2 on macOS Big Sur

I'm using iTerm2(Z shell) on macOS 11.5.2. Because I use certain Perl one-liners (one line of Perl command in a shell application like iTerm2) a lot, it would be a lot easier if adding some comments to the one-liners so I could navigate back to it using the search function of iTerm2.
Normally, it's like perl path-to-perl-snippet/xxx.pl --an-arg xxx --other-args xxx a.txt #this is doing some task to do some work with a.txt.
Recently, I clean install the system and find some issues with commenting using #, i.e. the content behind # is interpreted by the command. This is not what I intend; It should be just comments.
At first, I thought it was a Perl problem. But the simplest command ls #display list also has the exact same problem, giving the following error ls: #display: No such file or directory ls: list: No such file or directory"
The expected behavior should be like executing ls (without the #display list) in the iTerm2, which is to display all the files under current directory.
So the real problem probably doesn't lie with Perl. It could be a setting problem with iTerm2 or other settings.
Any suggestions would be helpful. Thank you.
Newer versions of OS X (as of 10.15 Catalina) use the zsh shell by default, which has an "interactivecomments" shell option. It is set "off" by default. Turn it on with:
setopt interactivecomments
To preserve this setting for future shells, edit that line into your ~/.zshrc file.
The setting is documented in the man zshoptions section or online at https://zsh.sourceforge.io/Doc/Release/Options.html#index-comments_002c-in-interactive-shells. It is listed there as INTERACTIVE_COMMENTS, but the introduction to that section says:
These names are case insensitive and underscores are ignored. For example, ‘allexport’ is equivalent to ‘A__lleXP_ort’.
This means that you have several ways to enable the option (a partial list):
set -o interactivecomments
set -o Interactive_Comments
set -k
setopt interactivecomments
as well as disabling it (a partial list):
set +o interactivecomments
set +o Interactive_Comments
set +k
setopt nointeractivecomments
Whether or not # introduces a comment in an interactive shell is controlled by the interactive_comments option. It should be enabled by default, but if it has been disabled, run
shopt -s interactive_comments

echo command color not working

I have a code like this:
#!/bin/bash
COLOR_REST='\e[0m'
COLOR_GREEN='\e[0;32m'
echo -e "${COLOR_GREEN}OK${COLOR_REST}"
When I copy and paste the code into my iTerm, it displays OK in the color of green.
However, when I store the code in a file named testColor.sh, and execute ./testColor.sh. It displays \e[0;32mOK\e[0m on my screen.
Why doesn't it display OK with green?
I've also tried bash testColor.sh, and sh testColor.sh. Both fail to display the text in green.
Another thing I feel strange is that I don't see the -e option in the BSD General Commands Manual in man echo.
I'm using macOS High Sierra as my operating system.
Use
#!/bin/bash
COLOR_REST="$(tput sgr0)"
COLOR_GREEN="$(tput setaf 2)"
printf '%s%s%s\n' $COLOR_GREEN 'OK' $COLOR_REST
which uses printf to avoid echo options and tput to be portable across different terminals.
Using printf instead of echo should work in any POSIX compliant shell. I tried this in High Sierra with the default terminal and it didn't work (there weren't any extended options, just -n).
As for an explanation, I haven't used iTerm so I'm not completely sure, but could be a different echo implementation by iTerm, which would cause the flag to work only when using iTerm itself, not /bin/bash. Notice that in the man page for echo, it says
NOTE: your shell may have its own version of echo, which usually supersedes the version described here. Please refer to your shell's documentation for details about the options it supports.
I am a fan of this syntax:
echo $'\e[31mRED\e[0m'
The $'...' notation causes the shell to honor escape codes e.g. \t, \n, \e.
This seems to work in bash, ksh, zsh, and sh -- yes, on MacOS.
The problem seems to be that Darwin's BSD-era /bin/echo does not actually accept -e argument at all. The zsh in recent versions of MacOS has a builtin echo that does take -e, but that's obviously not portable to other shells unless you want to run every shell script with zsh.

bash: vim mode instead of vi mode?

I noticed when in vi mode in bash (i.e. the mode enabled with "set -o vi"), that some commands, such as "diw", that work in vim but not in vi, don't work on the bash command line. Is there an easy way to configure bash so that its keybindings will support vim commands? I would like to be able to enter vim commands on the command line without having to actually start the vim program, as described in this question.
The best way of doing this that I know of would be to use athame.
It can be a surprisingly powerful experience in some cases. I particularly like it for interacting with a repl.
Athame patches your shell to add full Vim support by routing your keystrokes through an actual Vim process. Athame can currently be used to patch readline (used by bash, gdb, python, etc) and/or zsh (which doesn't use readline).
Alternatively I find spacemacs with the eshell to be a reasonably functional if strange solution.
Teach vi-command-mode diw to any software that uses readline (such as bash) by adding this to your ~/.inputrc:
set keymap vi-command
"diw": "bde"
First, the "vi mode" you get with set -o vi is not vi itself. It's an incomplete approximation of vi's behavior built into readline, the command-line editing library used by bash under the hood.
Second, because it is incomplete there's no reason whatsoever to expect every vi command to work.
Third, no, there's no "vim mode" so even less reason to expect any vim commands to work.
Fourth, if you absolutely want to edit the current command-line with Vim-like commands, why don't you go all the way and… actually use Vim:
<C-x><C-e>
That said, $ man readline tells you everything you need to customize its behavior and add bindings.
You can use ble.sh. Which is a command line editor written in pure Bash which replaces the default GNU Readline. I like to call it "zsh for bash".
Appart from vim-style navigation it gives you:
Enhanced completion
Syntax highlighting
Other interesting features
After installation don't forget to add (recommended) to your .bashrc:
# at the start of your .bashrc file
[[ $- == *i* ]] && source /usr/share/blesh/ble.sh --noattach
...
#for vim-style mode
set -o vi
...
#at the end of your .bashrc file
[[ ${BLE_VERSION-} ]] && ble-attach
or you can just:
# at the start of your .bashrc file
source /usr/share/blesh/ble.sh
but this may not work as expected - read this.

bash tabbing for autocompletion escapes $

In shell (GNU bash, version 4.2.47(1)-release (x86_64-suse-linux-gnu)), when I hit tab for autocompletion, the "$" is escaped after the variable name is completed, but if there is no completion then it just bells. E.g.
$ ls $JDK_H<tab>
results in
$ ls \$JDK_HOME (with a trailing space)
On an old GNU bash, version 3.2.51(1)-release (x86_64-suse-linux-gnu), it did not escape the "$" after completion which is what I would like.
Is there a way to get that old behavior without strong side-effects? My BASHOPTS and SHELLOPTS are:
# (indented for readability)
BASHOPTS=checkwinsize:cmdhist:expand_aliases:extglob:extquote
:force_fignore:histappend:interactive_comments:login_shell
:progcomp:promptvars:sourcepath
SHELLOPTS=braceexpand:emacs:hashall:histexpand:history
:interactive-comments:monitor
Thanks. I am using SLES SP11.
--UPDATE. Other completions seem to work as usual, e.g. cd or echo do not escape the $. I also momentarily commented out /etc/share/bash-completion/bash_completion from my /etc/bash.bashrc which stopped $-escaping. So it appears like some kind of complete config issue.
Recent bash versions introduced some compatibility issues regarding this. Try like this:
complete -r # temporarily disable all completion rules
shopt -s direxpand
Links to similar problems reported to the bug-bash mail list:
http://lists.gnu.org/archive/html/bug-bash/2014-01/msg00062.html
http://lists.gnu.org/archive/html/bug-bash/2015-08/msg00176.html

nullglob disables pathname tab-completion

I have found that shopt -s nullglob apparently disables tab-completion for files and directories, and shopt -u nullglob restores it. Why does tab-completion for directories apparently rely on nullglob being unset?
I am using Bash 4.2.37(1)-release on Debian 7.
This is apparently a known issue with bash-completion and is listed as an objective to be fixed in the 3.0 version.
But apparently it has been that way since at least 2012.
See https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=666933 for reference.
Edit: At least 2011: http://thread.gmane.org/gmane.comp.shells.bash.completion.devel/3652
I do not at all understand how nullglob causes the problem listed in that email though.
Edit: I now understand what is happening. The problem is that glob expansion is dumb. It sees the entire "word" $2[$j]=\${!ref}\${COMP_WORDS[i]} as a single glob and tries to expand it. Normally that fails and it gets left alone but will nullglob on that entire argument simply vanishes (thus causing the problem).
Quick testing indicates that replacing this:
eval $2[$j]=\${!ref}\${COMP_WORDS[i]}
with either:
eval $2\[$j\]=\${!ref}\${COMP_WORDS\[i\]}
or:
eval "$2[$j]=\${!ref}\${COMP_WORDS[i]}"
seems to fix the problem. I can't vouch for either of those being a fully correct fix though.
Update: This is fixed in the debian bash-completion git repository already (in a way I hadn't thought of but which is clearly better).
This commit fixes it. There are other globbing related fixes too.
Grabbing the __reassemble_comp_words_by_ref from git head and sourcing that on top of the current one appears to fix the problem as a temporary workaround/solution.

Resources