Center Macro Hall of Fame
Center Intro
I am always looking for new ways to use vi. In July, 1996, Joshua Wright (jwright@jwu.edu)
shared with me his macro for centering a single line of text. I added the commentary
you will find below to my vi Web page, and asked several folks on the Net to look
it over for errors, and invited anyone to improve the macro. Over time, I got
a number of versions and so created this "hall of fame."
Pete Mastren improved on Johsua
Wright's version, and about the time that I discovered that the January, 2003
vi FAQ, section 2,
had a version I liked better, I got another version from Logan
Shaw which was pretty good, though I still like the one in the vi FAQ better
(you can see this on my vi page,
under macros, where the center
macro is described). Here, on this page, I have preserved the various forms
which have been sent to me. My thanks to all who have contributed.
The map command is placed in your .exrc file, and in mine, the command, '=c'
(or in Joshua's case, '^Kc') is executed when you need something centered in
vi.
Sandy Herring points out that wrapmargin
should be set to zero before entering the macro. Most vi editors default to
this setting, but if yours does not, or if you have it set in your .exrc file,
you can unset it with ':set wrapmargin=0' when working on the .exrc file. Sandy
also noticed that this macro will not work with a string length of more than
74 characters. This turns out to be an artifact of the editor prompting for
you to "[hit return to continue]" when the command which has been executed is
long enough to wrap a line, as happens when the text to be centered goes beyond
74 characters.
Logan Shaw's Center Macro
Logan Shaw sent this along to me on the 24th of January, 2003. It seemed pretty
clever to me, so I added it to my Center Macro Hall of Fame!
map =c >>d0O^[80a ^[jA^[kd02i ^[:.s/../ /g^MJ0xx
Note: the acronym LTBC stands for Line To Be Centered).
- >>d0
- Trim off leading whitespace (>> adds a tab,
moves to 1st non-blank; d0 deletes whitespace preceeding that point).
-
- O^[80a ^[j
- Use 'O' to open up a new line above the
LTBC, escape, '80a ' to add 80 spaces, escape, 'j' to go back to the LTBC.
-
- A^[kd0
- Use 'A', escape to go into append mode at
the end of the line, then back out of it, causing vi to remember that column
position. 'k' moves to the same column position on the line of spaces above.
The 'd0' removes the same number of leading blanks as there are characters
in the LTBC.
-
- 2i ^[:.s/../ /g^M
- This line replaces every two spaces with
one, which is effectively a divide-by-two. It is preceeded with a '2i ' to
insert two blanks to prevent the failure of the 's' replace in case there
were no blanks. Failure of the 's' would blow the macro.
-
- J0xx
- Use 'J' to join the trimmed, blank line
with the LTBC. '0' to move to the front of the line and 'xx' to delete two
characters (extra blanks added with the '2i ').
Pete Mastren's Center Macro
Pete's center macro--which, if I recall correctly, was sent
to me in late summer 1996--functions as follows:
map =c >>d0:co.^Mk:s/./x/g^M40A x^[077lD:s/x//g^MJj
- >>d0
- Trim off leading whitespace (>> adds a tab,
moves to 1st non-blank).
- :co.^M
- Make a copy of the line to be centered.
- k
- Move back up to the original.
- :s/./x/g^M
- Convert all characters in original line
to x's, creating the first part of a template, which will become a leading-pad.
- 40A x^[
- Append forty pairs of ' x' to the x...x
template.
- 0
- Move to the beginning of the template line.
- 79l
- Move over to column eighty of the template
line (79 l).
- D
- Delete everything from column 80, on.
- :s/x//g^M
- Remove all x's, effectively leaving the
number of blanks in an eighty-column line, less the length of the line to
be centered, divided by two.
- J
- Join the leading-pad with the next line--the copy of the line to be centered,
thus centering it. Done. The cursor stays on the now-centered line. If you
want it to advance, place a 'j' on the end of the macro.
Joshua Wright's Center Macro
The 'map =c' is shown on two lines but must appear as one line!
map =c o^[k:c0.^M:s/./ /g^Mo^[80a ^[:-1s;^;:s/;^M:s;$;//;^M
"mdd@m:s/ / /g^M:s;^;:-1s/^/;^M"mdd@mjdd^L
Note: the acronym LTBC stands for Line To Be Centered):
- o^[
- Create an open line after the LTBC, then
escape-out. This deals with anomalies which occur when working on the last
line in the file).
- k
- :co.^M
- Move back to the LTBC and make a copy of
it.
- :s/./ /g^M
- Convert all characters in the copy line
to blanks to create a blank template.
- o^[
- Open yet another empty line after the blank
template, and...
- 80a ^[
- Make this third line 80 chars of blanks.
- :-1s;^;:s/;^M
- Modify the blank template line to begin
with ':s/'.
- :s;$;//;^M
- Modify the blank template line to end with
'//'.
- "mdd
- Delete the blank template line into buffer
"m".
- @m
- Execute the blank template line, now a command.
This removes a number of blanks from the 80 char blanks line equal to the
number of characters in the line to be centered.
:s/ / /g^M
- Divide the remaining number of blanks by
two. This is the second change I made to the macro, with the original containing
':s/\(.\)./\1/g'. Both work, but the latter would only be required for dividing
the length of an arbitrary character string.
- :s;^;:-1s/^/;^M
- "mdd
- @m
- Build a substitute command to modify the
LTBC, by prepending it with the correct number of blanks, then execute the
command out of the m buffer, after deleting the newly-built command from the
document and into the m buffer.
- jdd^L
- Remove the extra buffer line added in the
first step, and repaint the screen to clean up any left-over messages or other
garbage. The cursor will end up on the next line.
Have a vi tip you'd like to share? Just
drop me a line, like Joshua did!
This document may be found at: http://www.nacs.uci.edu/indiv/gdh/vi/center-hof.html
Comments and suggestions welcome.
Last revised Friday, 24-Jan-2003 18:00:47 PST.
Garrett Hildebrand -- gdh@uci.edu