Super Stutter Sequences for “vim”

Since the early days of UNIX, the vi editor had commands called Stutter Sequences. Two commonly used Stutter Sequence commands are dd to delete one or more lines or yy to yank (copy) one or more lines. Repeating a letter while typing is very easy and very intuitive.

Also for many decades, vi and vim had the facility to define abbreviations with the X command :ab . Abbreviations are used in Insert mode, Replace mode and Command-line mode.  If you enter a word that is an abbreviation, it is replaced with the word or sequence of words it stands for. This can be used to save typing for often-used long words. And you can use it to generate more complex blocks of text because it is possible to switch from insert mode to command mode and back in the replacement sequence.

Another useful vim function is the X command :map . It allows defining a vi command or insert sequence for pressing any key, including function keys. A series of :map and :ab commands are usually pre-defined in the vi support file ~/.exrc as part of a Linux distribution. I have extended ~/.exrc to provide extra mappings and abbreviations making up the Super Stutter Seqences.

A simple example of an abbreviation:
:ab hh    hello

:ab"hh<Space>" is expanded to "hello<Space>"

I call abbreviations consisting mostly of three identical letters followed by a non-letter “Super Stutter Sequences“. The replacement string of the Super Stutter Sequences consists of a string of insertions and vim commands and is rather cryptic. I will only show and analyze the first one in detail:

:ab iii    if ) {^M^T///^M^D}^[%F)i
Explanatory form (output by :ab listing):
:ab iii    if ) {<CR><C-T>///<CR><C-D>}<Esc>%F)i
To enter <CR> type ctrl-V <Enter> which shows up as ^M
To enter <C-T> type ctrl-V ctrl-T which shows up as ^T
To enter <C-D> type ctrl-V ctrl-D which shows up as ^D
To enter <Esc> type ctrl-V <Esc> which shows up as ^[

The replacement string starts with “if ) {“. <CR> starts a new line. <C-T> indents text in that line by 4 spaces to the right. “///” is inserted in that line at the new indent. Another <CR> starts a third line. <C-D> indents text 4 spaces to the left, where the closing brace “}” to finish the block is inserted. The insert cursor is now after the closing brace. An <Esc> follows, which turns on command mode. The vi command “%” moves the insert cursor to the matching opening brace in the first line. The vi command “F)” moves the insert cursor in front of the “)” after the “if“, which was inserted at the beginning. The vi command “i” restores insert mode at which point the abbreviation for “iii” is complete. The abbreviation trigger character “(” is now inserted before the “)” character leaving the insert cursor in insert mode between the parentheses.

NOTE: in the following expansions the character ‘|‘ represents the insert cursor and not the vertical bar character.

"iii(" is expanded to
if (|) {
    ///
}

Since the insert cursor is in insert mode between the parentheses after the abbreviation is expanded, the if condition can be typed immediately after the opening parenthesis after typing only iii(.

The properly indented placeholder /// is used to enter code in the correct place in the curly brace de-limited block after the if condition. The F10 keystroke mapping in either command line or insert mode, which is part of the Super Stutter Sequences, is used to search for ///, which is then replaced with code for the new block. The placeholder /// has the added quality, that it is a comment in the languages C, C++, and GO.

In Insert or Replace mode:
:map! <F10> ^[0/\/\/\/^Mcw
:map! <F9> ^[k0/zzz^Mcw

The F9 keystroke mapping in insert mode is used to search for zzz, which is then replaced with the name of a new function (used later with the rrr abbreviation).

In Command Line mode:
:map <F10> 0/\/\/\/^Mcw
:map <F9> :g//s//

The F9 keystroke mapping in command line mode is used to initiate a global search and replace using regular expressions, which has nothing to do with any Super Stutter Sequence. It is shown here because F9 in insert mode (shown above), which supports the rrr abbreviation is relevant here and the two should not be confused.

Note 1: All curly brace de-limited statement blocks are generated in the K&R style, which is also mandatory in GO, with the opening brace placed on the same line as the condition.

NOTE 2: I discourage conditional statements followed by a single statement not de-limited by braces – they cause serious bugs. These are allowed in C but not in Perl, GO or my language immediate C. The Super Stutter Sequences make it very easy to write conditional statements with brace de-limited statement blocks.

 

Further similar Super Stutter Sequences  to iii are:

"www(" is expanded to
while (|) {
    ///
}
"fff(" is expanded to
for (|) {
    ///
}
"ddd(" is expanded to
do {
    ///
} while (|);
"sss(" is expanded to
switch (|) {
    ///
default:
    ///
    break;
}

To support the switch statement

"ccc<space>" is expanded to
case |:
    ///
    break;

The insert cursor is positioned immediately after the <space> and before the : to allow entry of the case value.

To support the if statement block:

"eee<space>" is expanded to
} else {
    ///
"eei(" is expanded to
} else if (|) {
    ///

For the Perl language:

"eii(" is expanded to
} elsif (|) {
    ///

Enter the last three abbreviations “eee”, “eei” or “eii” as the last line of a previous if block before the closing brace. The indentation will then be correct.

Also for Perl:

"ffe(" is expanded to
foreach (|) {
    ///
}

To enter a properly formatted “main” block in C and C++

"mmm<space>" is expanded to
#include <stdio.h>

int
main (int argc, char **argv)
{
    ///
    return 0;
} /* main */

To enter a properly formatted function in C and C++

"rrr(" is expanded to
///
zzz (|)
{
    ///
} /* zzz */

First enter the function parameters between parentheses. Then replace “zzz” twice with the new function name using <F9> (I like to have a comment containing the function name after the final curly brace of a function). Then use <F10> twice to enter the return type of the function at the top and finally to fill in the body of the function.

To enter a properly formatted printf statement in C and C++

"ppp"" is expanded to
printf("|\n");

The insert cursor is between ” and \n, to allow immediate entry of the format line. Any further parameters must be entered manually between the last ” and the closing parentheses.

There are various Super Stutter Sequences to generate C style comments and comment blocks:

"kkk<space>" is expanded as a simple inline comment
/* | */
"lll<space>" is expanded as a simple comment block to 
/* 
* | 
*/

///
"LLL<space>" is expanded as a Doxygen comment block to 
/** 
* | 
*/

///
"hhh<space or tab>" is expanded to
/*********************************************************** 
 *<space or tab>| 
 **********************************************************/ 
///

I use “hhh<space” for properly indented C comment blocks between lines of code.

"HHH<space or tab>" is expanded to
/***********************************************************
 * 
 *<space or tab>|
 *
 **********************************************************/

///

I use “HHH<tab>” for stand-alone C comment blocks before new functions.

The comment blocks generated by hhh and HHH are not (by default) valid Doxygen comment blocks. However they will function as Doxygen comment blocks  as long as JAVADOC_BLOCK = YES is added to the Doxyfile.
"PPP<space>" is expanded as a comment block for Perl and SH code to 
########################################################### 
# 
#<space or tab>| 
# 
###########################################################

///
"aaa<space>" is expanded as a comment block for assembler code to 
;************************************************** 
;* 
;*<space or tab>| 
;* 
;**************************************************

///

A number of miscellaneous SuperStutterSequences follow:

"III<space>" is expanded to 
#include |
"DDD<space>" is expanded to 
#define |
"FFF<space>" is expanded to 
#ifdef |  
/// 
#else 
/// 
#endif 
///
"CCC<space>" is expanded to 
class | { 
private: 
   /// 
public: 
   /// 
};
"SSSpace>" is expanded to 
struct | { 
   /// 
};
"UUU<space>" is expanded to 
union | { 
   /// 
};

If vim recognizes GO code, the following Super Stutter Sequences are changed, because GO does not require parentheses around conditions in a conditional statement.:

"iii<space>" is expanded to
if | {
    ///
}
"eei<space>" is expanded to
} else if | {
    ///
"fff<space>" is expanded to
for | {
    ///
}
"sss<space>" is expanded to
switch | {
    ///
default:
    ///
 }
"ccc<space>" is expanded to
case |:
    ///

Simply copy the Super Stutter Sequences from the block below into your .exrc file. I have used them for many years for writing C, C++, Perl and GO programs.

Further similar Super Stutter Sequences  to iii are:

"www(" is expanded to
while (|) {
    ///
}
"fff(" is expanded to
for (|) {
    ///
}
"ddd(" is expanded to
do {
    ///
} while (|);
"sss(" is expanded to
switch (|) {
    ///
default:
    ///
    break;
}

To support the switch statement

"ccc<space>" is expanded to
case |:
    ///
    break;

The insert cursor is positioned immediately after the <space> and before the : to allow entry of the case value.

To support the if statement block:

"eee<space>" is expanded to
} else {
    ///
"eei(" is expanded to
} else if (|) {
    ///

For the Perl language:

"eii(" is expanded to
} elsif (|) {
    ///

Enter the last three abbreviations “eee”, “eei” or “eii” as the last line of a previous if block before the closing brace. The indentation will then be correct.

Also for Perl:

"ffe(" is expanded to
foreach (|) {
    ///
}

To enter a properly formatted “main” block in C and C++

"mmm<space>" is expanded to
#include <stdio.h>

int
main (int argc, char **argv)
{
    ///
    return 0;
} /* main */

To enter a properly formatted function in C and C++

"rrr(" is expanded to
///
zzz (|)
{
    ///
} /* zzz */

First enter the function parameters between parentheses. Then replace “zzz” twice with the new function name using <F9> (I like to have a comment containing the function name after the final curly brace of a function). Then use <F10> twice to enter the return type of the function at the top and finally to fill in the body of the function.

To enter a properly formatted printf statement in C and C++

"ppp"" is expanded to
printf("|\n");

The insert cursor is between ” and \n, to allow immediate entry of the format line. Any further parameters must be entered manually between the last ” and the closing parentheses.

There are various Super Stutter Sequences to generate C style comments and comment blocks:

"kkk<space>" is expanded as a simple inline comment
/* | */
"lll<space>" is expanded as a simple comment block to 
/* 
* | 
*/

///
"LLL<space>" is expanded as a Doxygen comment block to 
/** 
* | 
*/

///
"hhh<space or tab>" is expanded to
/*********************************************************** 
 *<space or tab>| 
 **********************************************************/ 
///

I use “hhh<space” for properly indented C comment blocks between lines of code.

"HHH<space or tab>" is expanded to
/***********************************************************
 * 
 *<space or tab>|
 *
 **********************************************************/

///

I use “HHH<tab>” for stand-alone C comment blocks before new functions.

The comment blocks generated by hhh and HHH are not (by default) valid Doxygen comment blocks. However they will function as Doxygen comment blocks  as long as JAVADOC_BLOCK = YES is added to the Doxyfile.
"PPP<space>" is expanded as a comment block for Perl and SH code to 
########################################################### 
# 
#<space or tab>| 
# 
###########################################################

///
"aaa<space>" is expanded as a comment block for assembler code to 
;************************************************** 
;* 
;*<space or tab>| 
;* 
;**************************************************

///

A number of miscellaneous SuperStutterSequences follow:

"III<space>" is expanded to 
#include |
"DDD<space>" is expanded to 
#define |
"FFF<space>" is expanded to 
#ifdef |  
/// 
#else 
/// 
#endif 
///
"CCC<space>" is expanded to 
class | { 
private: 
   /// 
public: 
   /// 
};
"SSSpace>" is expanded to 
struct | { 
   /// 
};
"UUU<space>" is expanded to 
union | { 
   /// 
};

If vim recognizes GO code, the following Super Stutter Sequences are changed, because GO does not require parentheses around conditions in a conditional statement.:

"iii<space>" is expanded to
if | {
    ///
}
"eei<space>" is expanded to
} else if | {
    ///
"fff<space>" is expanded to
for | {
    ///
}
"sss<space>" is expanded to
switch | {
    ///
default:
    ///
 }
"ccc<space>" is expanded to
case |:
    ///

Simply copy the Super Stutter Sequences from the block below into your .exrc file. I have used them for many years for writing C, C++, Perl and GO programs.

Author: John E

Retired software engineer interested in real-time control systems and languages. I developed "immediate C", a language for high-speed control and robotics. This Blog also contains articles about early work in a 60-year career as a Software Engineer.

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.