The problem
In shell scripting, conditionals and loops don't use curly braces to indicate blocks, but rather special keywords: if [ ... ]; then
statements close with fi
, while [ ... ]; do
statements close with done
, and case
statements close with esac
.
Without mappings, the normal protocol to complete, e.g., a then...fi pair would be the following sequence of keys, starting in insert mode: then<CR><BS>fi<Esc>O
. I'm not very fond of this workflow since it takes so many keystrokes and exits insert mode, so I've come up with my own solution. I'm not sure if this is the best solution though, so I'd appreciate recommendations if you have any.
My current solution
I use the following mappings to facilitate easier completion of pairs:
" if statements:
inoremap fi<CR> <BS>fi<Esc>O
" case statements:
inoremap c<CR> c<Esc>O
" for, while, until, and select loops:
inoremap one<CR> one<Esc>O
This leads to the following workflow when creating then...fi, do...done, and case...esac pairs:
then...fi pairs: then<CR>fi<CR>
do...done pairs: do<CR>done<CR>
case...esac pairs: case[...]<CR>esac<CR>
Things I want the mapping to do
I want a mapping to:
- Allow me to complete pairs without manually exiting insert mode.
End with my cursor between the two lines and indented one tab, like so (cursor indicated with [ ]):
if [ ... ] then [] fi
- Be a similar calling workflow for all 3 pair types.
- Require the least amount of keystrokes while avoiding things I don't want, as described below.
Things I want the mapping to NOT do
I want to avoid the following problems:
- Trigger in situations when I wouldn't want it to. For example, I wouldn't want the mapping
inoremap do<CR> do<CR>done<Esc>O
since that would also trigger when I'm writing do...while loops in C++. If this can be worked around to only trigger in files with certain file extensions, that would be an exception. - Be distracting while writing code normally. For example, I mapped
one<CR>
instead ofdone<CR>
since I want to be able to see the letters as I type them unless I'm probably trying to use the mapping (i.e.done<CR>
would hide my characters while typingdo
until I typed a character other thann
, which I don't like).
Do you have recommendations for changes? Or do you think my mappings best fit what I want and don't want?