Say you're coding a shell script and you want to write something like:
if [[ "$out" =~ 'none' ]]; then
return $err
fi
If you're just typing it out and have any of the various electric/pair modules active, you'll likely get something like
if [[‸]]
(with the position of point indicated by ‸
).
In most programming languages, this is great, but in POSIX/Korn-family shells like Bash or Zsh, you pretty much always should have a space after the [[
and before the ]]
.
Inserting this manually is a pain since you need a space before, and a space after, and still get the point back in the middle. I frequently have wild error messages the first time i test a script because one of those spaces is missing, or they both ended up before or after the double-brace contents.
Is there a good way to rectify this, so that, ideally, in sh-script-mode
, typing [[
would result in
[[ ‸ ]]
so the necessary space is there and the point is correctly positioned?
Ideally, the answer would also let me select a region and press [[
, and just as I can already today surround the region with brackets, parens, etc. this way, I'd get the same, just with [[ $region ]]
instead of [[$region]]
. Also, it would be useful if the Zsh (( ... ))
form would act in the same way.
(Note that I specifically do not want this behavior for square brackets in general; they're too-frequently used in other contexts when one doesn't want extraneous spaces, and the use of the single-bracket [ ... ]
test construct is generally less preferable to the double-bracket one.)
p.s.
I'm setting aside YAS snippets and such for the moment—they could clearly solve this problem in many cases, and I even already use them to create entire if..elif..else..fi
blocks with built-in [[ $0 ]]
-type positioning code. And so, for writing entirely new shell code, this problem isn't that big of a deal.
But this issue tends to arise when I'm modifying existing logic, rather than entering in entirely new conditionals. One of the most common ways one might need to fix a wayward conditional is to change a simple conditional into a test, so introducing the [[ ... ]]
test into an existing conditional is a frequent task.
An acceptable answer, but one I've tried to avoid, would be to make [[
a YAS snippet in its own right. The issue is that if I defined it such that invocation was [[⇥
(⇥
meaning the tab or other YAS invocation key), the doubling expansion will have already happened, so I'd have to have Elisp in the snippet to fix the characters after the snippet's environment, which is something of a pain.