├── .gitignore ├── README.asciidoc ├── broom.vim ├── originals ├── 1_editor_fundamentals.txt ├── 2_line_addresses.txt ├── 3_global_command.txt ├── 4_substitute_command.txt ├── 5_take_control_of_your_editing_environment.txt ├── 6_addresses_and_columns.txt ├── 7_the_replacement_commands.txt ├── 8_indent_like_a_typewriter.txt └── 9_take_charge_with_macros.txt └── vimmified ├── 1_editor_fundamentals.txt ├── 2_line_addresses.txt ├── 2_line_addresses_solutions.txt ├── 3_global_command.txt ├── 3_global_command_solutions.txt ├── 4_substitute_command.txt ├── 4_substitute_command_solutions.txt ├── Makefile ├── html ├── 1_editor_fundamentals.html ├── 2_line_addresses.html ├── 2_line_addresses_solutions.html ├── 3_global_command.html ├── 3_global_command_solutions.html ├── 4_substitute_command.html └── 4_substitute_command_solutions.html └── images ├── hal_deletes_managers.png ├── hal_deletes_managers.svg ├── slimy_vp.png └── slimy_vp.svg /.gitignore: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dahu/vim_waz_ere/ccfb0f19fcba9954764a4429277bfbd473221ca8/.gitignore -------------------------------------------------------------------------------- /README.asciidoc: -------------------------------------------------------------------------------- 1 | Vim WAZ Ere 2 | ----------- 3 | 4 | __Vimmified version of the venerable http://www.networkcomputing.com/unixworld/tutorial/009/009.html[Walter A. Zintz Vi/Ex Tutorial Series]__ 5 | 6 | TIP: If you like Vim Waz Ere and want to share the W00t!, I'm grateful for 7 | https://www.gittip.com/bairuidahu/[tips] or 8 | http://of-vim-and-vigor.blogspot.com/[beverages]. 9 | 10 | Now you can read it http://dahu.github.io/vim_waz_ere[online!] 11 | 12 | . (done) Editor Fundamentals 13 | . (done) Line Addresses 14 | . (done) Global Command 15 | . (done) Substitute Command 16 | . Take Control Of Your Editing Environment 17 | . Addresses And Columns 18 | . The Replacement Commands 19 | . Indent Like A Typewriter 20 | . Take Charge With Macros 21 | -------------------------------------------------------------------------------- /broom.vim: -------------------------------------------------------------------------------- 1 | " Usual replacements. 2 | %s/\c\/&m/gce 3 | %s/\\ze.mode/normal/gce 4 | %s/\/normal/gce 5 | %s/\\ze.mode/normal/gce 6 | %s/\/normal/gce 7 | %s/\\ze.mode/ex/gce 8 | %s/\/ex/gce 9 | $put ='// vim:set ft=asciidoc tw=78:' 10 | " Place the cursor on the first line of the block of code and make me run. Two 11 | " consecutive non-empty lines mark the end of the code block. 12 | let @a = "O[source,vim]\----\:/^.\\+\\n./-2put='----'\\" 13 | " Select block of code (from top to bottom) and let me it do the magic. 14 | let @b = "\j4i-\o\gvo\O[source,vim]\----\/----\\" 15 | " Just type the kind of header you want the current line to be. 16 | let @c = "\yypVr" 17 | 0 18 | let @/ = '^\n\zs.\+\n$' 19 | 20 | set ft=asciidoc 21 | -------------------------------------------------------------------------------- /originals/1_editor_fundamentals.txt: -------------------------------------------------------------------------------- 1 | Part 1: Vi Editor Fundamentals 2 | 3 | By Walter Alan Zintz 4 | 5 | Why Vi? 6 | A Heartwarming Edit 7 | The Plan Of This Ongoing Tutorial 8 | The Editor's Basic Concepts 9 | Search Patterns 10 | Searching From Where You Are Now 11 | The Find-Them-All Search 12 | Simple Search Patterns 13 | Metacharacters 14 | Table Of Search Pattern Metacharacters 15 | Character Classes 16 | What's Coming For The Next Installment 17 | 18 | Why Vi? 19 | 20 | A HEARTWARMING EDIT 21 | 22 | Pity poor Hal, a corporate maintenance programmer. A large module of 23 | badly-broken, poorly-patched legacy code -- the spaghetti variety -- finally 24 | broke down completely yesterday, leaving one corporate division running at half 25 | speed. By dint of some inspired fixes during an all-nighter, Hal has the module 26 | up and running again this morning... but just as he's ready to go out for food 27 | that isn't from a vending machine, in walks the corporation's VP of IS, with a 28 | big surprise. 29 | 30 | "Nice work on that crash fix, Hal; but right now I need some formatted 31 | technical data about it, in a hurry. The Board of Directors' Information 32 | Systems Committee has called a rush meeting this morning to convince themselves 33 | they're on top of the problem. I'll be in the hotseat, and I need technical 34 | data I can put up on the video projector to keep them occupied. 35 | 36 | "They'll want me to discuss the logfile of errors that led up to the crash... 37 | yes, I know that's in /oltp/err/m7, but appending puts the latest report lines 38 | at the bottom of the file. Those suits aren't interested in what they think is 39 | ancient history, and they wouldn't be caught reading anything but a commuter 40 | train timetable from the bottom up, so you'll have to make a copy with the 41 | order of the lines reversed: what was the last line becomes the first line, 42 | what was the second to the last line is now line number two, and so on. 43 | 44 | "And let's take a look at that logfile. 45 | 46 | 374a12 44872 130295/074457 nonabort 5982d34 971 130295/221938 nonabort 47 | 853f7 2184 140295/102309 abort ... 48 | 49 | Hmmm. Explaining the second column to them would be advertising the fact that 50 | we knew this failure was just waiting for a chance to happen. So while you're 51 | at it, go through and erase all but the first and last digits of each number in 52 | column two. 53 | 54 | "Oh, and when they get tired of that they'll want to scrutinize the Lint 55 | report. Last month I told them that our Lint substitute was the greatest thing 56 | since Marilyn Monroe, so now they'll want me to tell them why the messages it 57 | still generates on this module aren't real hazards. Just run Lint over the 58 | revamped module; then combine the Lint output with a copy of the source file by 59 | taking each message line like: 60 | 61 | Line 257: obsolete operator += 62 | 63 | and putting the significant part at the end of the source line it refers to. 64 | And put a separator, like XXX, between the source line and the message so I can 65 | page through quickly. Nothing like a hefty dose of source code they can't begin 66 | to fathom to make the meeting break up early. 67 | 68 | "And get right on this. The meeting starts in 35 minutes." 69 | 70 | Our VP walks away inwardly smiling, thinking he's getting out of detailed 71 | explanations and putting all the blame on an underling, just by demanding more 72 | editing than anyone could do in the time available. "I'll tell the Information 73 | Systems Committee that I made it perfectly clear to the programmer that we 74 | needed this at 9:30, but when I asked him for it a minute ago he said it wasn't 75 | finished and he wasn't sure when it would be. Then I'll remark that those 76 | programmers just can't understand that keeping management informed is every bit 77 | as important as writing code!" 78 | 79 | But Hal has a secret weapon against this squeeze play: an expert knowledge of 80 | the Vi editor. 81 | 82 | Reversing the order of the lines in a file is a piece of cake with this editor. 83 | The eight keystrokes in: 84 | 85 | :g/^/m0 86 | 87 | will do it. Taking the digits out of the middle of the second column throughout 88 | the file also requires just one command line: 89 | 90 | :%s/\v +\zs(\d)\d+(\d)/\1\2 91 | 92 | And integrating the Lint messages into a copy of the source code? Even that can 93 | be automated with the Vi editor. The editor command: 94 | 95 | :%s/\vLine (\d+): (.*)/\1s;$; XXX \2 96 | 97 | will turn that file of Lint messages into an editor script, and running that 98 | script on a copy of the source file will mark it up as requested. 99 | 100 | Rather than being portrayed as a bungler, Hal can have it all ready in a couple 101 | of minutes, just by typing a few lines. He'll even have time to guard against 102 | vice-presidential prevarication, by disappearing into the coffee shop across 103 | the street and reappearing just as the meeting is getting started, to tell the 104 | VP (and everyone else in earshot), "Those files you wanted are in 105 | slash-temp-slash-hal". 106 | 107 | THE PLAN OF THIS ONGOING TUTORIAL 108 | 109 | I'm writing here for editor users who have some fluency in Vi at the surface 110 | level. That is, you know how to do the ordinary things that are belabored in 111 | all the "Introducing Vi" books on the market, but rarely venture beyond that 112 | level. 113 | 114 | This tutorial series will explore a lot of other capabilities that hardly 115 | anyone knows are in Vi. That includes quite a few tricks that may be built on 116 | editor functions we all use every day, but which nonetheless are not obvious -- 117 | for instance, telling the global command to mark every line it encounters. 118 | I'll also be clarifying the real nature of the many misunderstood aspects of 119 | this editor. 120 | 121 | To do all this, I'll be explaining things in more depth than you might think 122 | warranted at first. I'll also throw in exercises wherever they seem helpful. 123 | And to save you readers from gross information overload, I'll write this 124 | tutorial in a large number of fairly small modules, to be put up on our website 125 | at a calm, reasonable pace. 126 | 127 | The Editor's Basic Concepts 128 | 129 | To get a real grasp on this editor's power, you need to know the basic ideas 130 | embodied in it, and a few fundamental building blocks that are used throughout 131 | its many functions. 132 | 133 | One cause of editor misuse is that most users, even experienced ones, don't 134 | really know what the editor is good at and what it's not capable of. Here's a 135 | quick rundown on its capabilities. 136 | 137 | First, it's strictly a general-purpose editor. It doesn't format the text; it 138 | doesn't have the handholding of a word processor; it doesn't have built-in 139 | special facilities for editing binaries, graphics, tables, outlines, or any 140 | programming language except Lisp. 141 | 142 | It's two editors in one. Visual mode is a better full-screen editor than most, 143 | and it runs faster than those rivals that have a larger bag of screen-editing 144 | commands. Line editing mode dwarfs the "global search and replace" facilities 145 | found in word processors and simple screen editors; its only rivals are 146 | non-visual editors like Sed where you must know in advance exactly what you 147 | want to do. But in the Vi editor, the two sides are very closely linked, 148 | giving the editor a combination punch that no other editor I've tried can 149 | rival. 150 | 151 | Finally, this editor is at its best when used by people who have taken the 152 | trouble to learn it thoroughly. It's too capable to be learned well in an hour 153 | or two, and too idiosyncratic to be mastered in a week, and yet the power 154 | really is in it, for the few who care to delve into it. A large part of that 155 | power requires custom-programming the editor: that's not easy or 156 | straightforward, but what can be done by the skillful user goes beyond the 157 | direct programmability of any editor except (possibly) Emacs. 158 | 159 | Search Patterns 160 | 161 | In quite a few functions of this editor, you can use string-pattern searching 162 | to say where something is to be done or how far some effect is to extend. These 163 | search patterns are a good example of an editor function that is very much in 164 | the Unix style, but not exactly the same in detail as search patterns in any 165 | other Unix utility. 166 | 167 | Search patterns function in both line editing and visual editing modes, and 168 | they work the same way in both, with just a few exceptions. But how you tell 169 | the editor you're typing in a search pattern will vary with the circumstances. 170 | 171 | SEARCHING FROM WHERE YOU ARE NOW 172 | 173 | The more common use for search patterns is to go to some new place in the file, 174 | or make some editing change that will extend from your present position to the 175 | place the pattern search finds. (In line editing mode it's also possible to 176 | have an action take place from one pattern's location to where another pattern 177 | is found, but both searches still start from your present location.) 178 | 179 | If you want to search forward in the file from your present location (toward 180 | the end of the file), precede the search pattern with a slash ( / ) character, 181 | and type another to end the pattern. So if you want to move forward to the next 182 | instance of the string "j++" in your file, typing: 183 | 184 | /j++/ 185 | 186 | will do it. And so will: 187 | 188 | /j++ 189 | 190 | When there is nothing between the pattern and the RETURN key, the RETURN itself 191 | will indicate the end of the search pattern, so the second slash is not 192 | necessary. 193 | 194 | To search backward (toward the start of the file), begin and end with a 195 | question mark instead of a slash. The same rules of abbreviation apply to 196 | backward searches, so: 197 | 198 | ?j++? 199 | 200 | and: 201 | 202 | ?j++ 203 | 204 | both head backward in the file to the same pattern. 205 | 206 | Either way, you've expressed both your request for a pattern search and the 207 | direction the search is to take in just one keystroke. But don't assume that if 208 | you search backward, any matching pattern the editor finds will be above your 209 | present position in the file, and vice versa if you search forward. The editor 210 | looks there first, certainly, but if it gets to the top or bottom line of the 211 | file and hasn't found a match yet, it wraps around to the other end of the file 212 | and continues the search in the same direction. That is, if you used a question 213 | mark to order a backward search and the editor searches all the way through the 214 | top line of the file without finding a match, it will go on to search the 215 | bottom line next, then the second-to-the-bottom line, and so on until (if 216 | necessary) it gets back to the point where the search started. Or if you were 217 | searching forward and the editor found no match up through the very last line 218 | of the file, it would next search the first line, then the second line, 219 | etcetera. 220 | 221 | If you don't want searches to go past either end of the file, you'll need to 222 | type in a line mode command: 223 | 224 | :set nowrapscan 225 | 226 | This will disable the wraparound searching during the present session in the 227 | editor. If you want to restore the wraparound searching mechanism, typing: 228 | 229 | :set wrapscan 230 | 231 | will do it, and you can turn this on and off as often as you like. 232 | 233 | THE FIND-THEM-ALL SEARCH 234 | 235 | Up to now, I've been considering searches that find just one instance of the 236 | pattern; the one closest to your current location in the file, in the direction 237 | you chose for the search. But there is another style of search, used primarily 238 | by certain line editing mode commands, such as global and substitute. This 239 | search finds every line in the file (or in a selected part of the file) that 240 | contains the pattern and operates on them all. 241 | 242 | Don't get confused when using the global and substitute commands. You'll often 243 | use both styles of search pattern in one command line. But the 244 | find-one-instance pattern or patterns will go before the command name or 245 | abbreviation, while the find-them-all pattern will come just behind it. For 246 | example, in the command: 247 | 248 | :?Chapter 10?,/The End/substitute/cat/dog/g 249 | 250 | the first two patterns refer to the preceding line closest to the current line 251 | that contains the string "Chapter 10" and the following line closest to the 252 | current line containing the string "The End". Note that each address finds only 253 | one line. Combined with the intervening comma, they indicate that the 254 | substitute command is to operate on those two lines and all the lines in 255 | between them. But the patterns immediately after the substitute command itself 256 | tell the command to find every instance of the string "cat" within that range 257 | of lines and replace it with the string "dog". 258 | 259 | Aside from the difference in meaning, the two styles also have different 260 | standards for the delimiters that mark pattern beginnings and (sometimes) 261 | endings. With a find-them-all pattern, there's no need to indicate whether to 262 | search forward or backward. Thus, you aren't limited to slash and question mark 263 | as your pattern delimiters. Almost any punctuation mark will do, because the 264 | editor takes note of the first punctuation mark to appear after the command 265 | name, and regards it as the delimiter in that instance. So: 266 | 267 | :?Chapter 10?,/The End/substitute;cat;dog;g 268 | 269 | :?Chapter 10?,/The End/substitute+cat+dog+g 270 | 271 | :?Chapter 10?,/The End/substitute{cat{dog{g 272 | 273 | are all equivalent to the substitution command above. (It is a good idea to 274 | avoid using punctuation characters that might have a meaning in the command, 275 | such as an exclamation point, which often appears as a switch at the end of a 276 | command name.) 277 | 278 | The benefit of this liberty comes when the slash mark will appear as itself in 279 | the search pattern. For example, suppose our substitution command above was to 280 | find each pair of consecutive slash marks in the text, and separate them with a 281 | hyphen -- that is, change // to /-/ . Obviously: 282 | 283 | :?Chapter 10?,/The End/substitute/////-//g 284 | 285 | won't work; the command will only regard the first three slashes as delimiters, 286 | and everything after that as extraneous characters at the end of the command. 287 | This can be solved by backslashing: 288 | 289 | :?Chapter 10?,/The End/substitute/\/\//\/-\//g 290 | 291 | but this is even harder to type correctly than the first attempt was. But with 292 | another punctuation mark as the separator: 293 | 294 | :?Chapter 10?,/The End/substitute;//;/-/;g 295 | 296 | the typing is easy and the final command is readable. 297 | 298 | SIMPLE SEARCH PATTERNS 299 | 300 | The simplest search pattern is just a string of characters you want the editor 301 | to find, exactly as you've typed them in. For instance: "the cat". But, already 302 | there are several caveats: 303 | 304 | This search finds a string of characters, which may or may not be words by 305 | themselves. That is, it may find its target in the middle of the phrase "we fed 306 | the cat boiled chicken", or in the middle of "we sailed a lithe catamaran down 307 | the coast". It's all a matter of which it encounters first. 308 | 309 | Whether the search calls "The Cat" a match or not depends on how you've set an 310 | editor variable named ignorecase . If you've left that variable in its default 311 | setting, the capitalized version will not match. If you want a capital letter 312 | to match its lower-case equivalent, and vice versa, type in the line mode 313 | command: 314 | 315 | :set ignorecase 316 | 317 | To resume letting caps match only caps and vice versa, type: 318 | 319 | :set noignorecase 320 | 321 | The search absolutely will not find a match where "the" occurs at the end of 322 | one line and "cat" is at the start of the next line: 323 | 324 | and with Michael's careful help, we prodded the 325 | cat back into its cage. Next afternoon several 326 | 327 | It makes no difference whether there is or isn't a space character between one 328 | of the words and the linebreak. Finding a pattern that may break across a line 329 | ending is a practically impossible task with this line-oriented editor. 330 | 331 | Where the search starts depends on which editor mode you're using. A search in 332 | visual mode starts with the character next to the cursor. In line mode, the 333 | search starts with the line adjacent to the current line. 334 | 335 | METACHARACTERS 336 | 337 | Then there are search metacharacters or "wild cards": characters that represent 338 | something other than themselves in the search. As an example, the 339 | metacharacters . and * in: 340 | 341 | /Then .ed paid me $50*!/ 342 | 343 | could cause the pattern to match any of: 344 | 345 | Then Ted paid me $5! 346 | 347 | Then Red paid me $5000! 348 | 349 | Then Ned paid me $50! 350 | 351 | or a myriad of other strings. Metacharacters are what give search patterns 352 | their real power, but they need to be well understood. 353 | 354 | To understand these, you must know the varied uses of the backslash ( \ ) 355 | metacharacter in turning the "wild card" value of metacharacters on and off. 356 | 357 | In many cases, the meta value of the metacharacter is on whenever the character 358 | appears in a search pattern unless it is preceded by a backslash; when the 359 | backslash is ahead of it the meta value is turned off and the character simply 360 | represents itself. As an example, the backslash is a metacharacter by itself, 361 | even if it precedes a character that never has a meta value. The only way to 362 | put an actual backslash in your search pattern is to precede it with another 363 | backslash to remove its meta value. That is, to search for the pattern "a\y", 364 | type: 365 | 366 | /a\\y/ 367 | 368 | as your search pattern. If you type: 369 | 370 | /a\y/ 371 | 372 | the backslash will be interpreted as a metacharacter without any effect (since 373 | the letter y is never a metacharacter) and your search pattern will find the 374 | string "ay". 375 | 376 | Less-often-used metacharacters are used in exactly the opposite way. This sort 377 | of character represents only itself when it appears by itself. You must use a 378 | preceding backslash to turn the meta value on. For example, in: 379 | 380 | /\ 454 | 455 | A backslashed right angle bracket means the match can occur only at the end of 456 | a simple word. Otherwise the same as the left angle bracket, above. 457 | 458 | ~ 459 | 460 | The tilde represents the last string you put into a line by means of a line 461 | mode substitute command, regardless of whether you were in line mode then or 462 | ran it from visual mode by preceding it with a colon ( : ). For instance, if 463 | your last line mode substitution command was s/dog/cat/ then a /the ~/ search 464 | pattern will find "the cat". But the replacement string of a substitute command 465 | can use metacharacters of its own, and if your last use involved any of those 466 | metacharacters then a tilde in your search pattern will give you either an 467 | error message or a match that is not what you expected. When the editor 468 | variable magic is turned off, you must backslash the tilde to give it its meta 469 | value. 470 | 471 | CHARACTER CLASSES 472 | 473 | There is one metastring form (a "multicharacter metacharacter") used in search 474 | patterns. When several characters are enclosed within a set of brackets ( [] ), 475 | the group matches any one of the characters inside the brackets. That is, /part 476 | [123]/ will match "part 1", "part 2" or "part 3", whichever the search comes to 477 | first. One frequent use for this feature is in finding a string that may or may 478 | not be capitalized, when the editor variable ignorecase is turned off (as it is 479 | by default). Typing /[Cc]at/ will find either "Cat" or "cat", and 480 | /[Cc][Aa][Tt]/ will find those or "CAT". (In case there was a slip of the shift 481 | key when "CAT" was typed in, the last pattern will even find "CaT", "CAt", 482 | etcetera.) 483 | 484 | There's more power (and some complication) in another feature of this 485 | metastring: there can be metacharacters inside it. Inside the brackets, a 486 | circumflex as the first character reverses the meaning. Now the metastring 487 | matches any one character that is NOT within the brackets. A /^[^ ]/ search 488 | pattern finds a line that does not begin with a space character. (You're so 489 | right if you think that the different meta values of the circumflex inside and 490 | outside the character class brackets is not one of the editor's best points.) A 491 | circumflex that is not the first character inside the brackets represents just 492 | an actual circumflex. 493 | 494 | A hyphen can be a metacharacter within the brackets, too. When it's between two 495 | characters, and the first of the two other characters has a lower ASCII value 496 | than the second, it's as if you'd typed in all of the characters in the ASCII 497 | collating sequence from the first to the second one, inclusive. So /[0-9]%/ 498 | will find any numeral followed by the percent sign ( % ), just as 499 | /[0123456789]%/ would. A /[a-z]/ search pattern will match any lower-case 500 | letter, and /[a-zA-Z]/ matches any letter, capital or lower case. These two 501 | internal metacharacters can be combined: /[^A-Z]/ will find any character 502 | except a capital letter. A hyphen that is either the first or the last 503 | character inside the brackets has no meta value. When a 504 | character-hyphen-character string has a first character with a higher ASCII 505 | value than the last character, Vi complains with the error message: 506 | 507 | E16: Invalid range. 508 | 509 | Backslashing character classes is complex. Within the brackets you must 510 | backslash a right bracket that's part of the class; otherwise the editor will 511 | mistake it for the bracket that closes the class. Of course you must backslash 512 | a backslash that you want to be part of the class, and you can backslash a 513 | circumflex at the start or a hyphen between two characters if you want them in 514 | the class literally and don't want to move them elsewhere in the construct. 515 | Elsewhere in a search pattern you will have to backslash a left bracket that 516 | you want to appear as itself, or else the editor will take it as your attempt 517 | to begin a character class. Finally, if magic is turned off, you'll have to 518 | backslash a left bracket when you do want it to begin a character class. 519 | 520 | Coming Up Next 521 | 522 | In the second part of this tutorial, I'll be following up on all this 523 | information about search patterns, by showing the right ways to combine them 524 | with other elements to generate command addresses. 525 | 526 | -------------------------------------------------------------------------------- /originals/2_line_addresses.txt: -------------------------------------------------------------------------------- 1 | The Vi/Ex Editor, Part 2: Line-Mode Addresses 2 | 3 | By Walter Alan Zintz 4 | 5 | Line-Mode Addressing 6 | Addressing a Section of Text 7 | Now You Try It 8 | Coming Up Next 9 | 10 | [ Editor's note : We'll surround text to be typed with actual double 11 | quotes, like: enter: "vi file1". Of course, don't type the quotes 12 | unless so instructed. We'll use ``balanced quotes'', constructed using 13 | pairs of backward and forward quotes, for all other purposes.] 14 | 15 | Line-Mode Addressing 16 | 17 | Whenever you want to give an editor command that will operate on text 18 | that's already in the file you're editing--to delete some text, change 19 | lower-case letters to capitals, write to a file, etcetera--the editor 20 | needs to know what part of the file to go to work on. A few commands 21 | have their addresses built in, and most line-mode commands have 22 | default addresses that the editor will use if you don't give an 23 | address, but that still leaves a lot of occasions where you need to 24 | know how to give the editor an address and what address to give. 25 | 26 | Many line-mode commands are almost identical to corresponding commands 27 | in visual mode; many more do similar things in different ways. Most of 28 | the benefit of these duplicative command sets comes from the 29 | totally-different addressing styles of line and visual modes. The 30 | differing address concepts mean that an edit that would be difficult 31 | or impossible to do with one mode's available addresses can be a piece 32 | of cake with an address form found in the other mode. 33 | 34 | Since I mention ``line mode'' so often, you may wonder whether there 35 | really is a separate mode for line editing. There surely is--instead 36 | of filling your screen with text from the file you're editing, this 37 | mode gives you a colon ( : ) prompt for your line mode commands, and 38 | prints only an occasional line from the file on your screen. The feel 39 | of this mode is very much like giving UNIX commands from your shell 40 | prompt. Few people work in line mode these days, largely because you 41 | can give most line-mode commands from visual mode, but you can't give 42 | any visual-mode commands while you are in line mode. Or perhaps they 43 | just prefer the comfortable WYSIWYG feeling of seeing the text on 44 | screen, with changes appearing as they are made. 45 | 46 | But there are times when you will need to work temporarily in line 47 | mode. To get to line mode when you first launch the editor, invoke it 48 | by typing "ex" instead of "vi". To go to line mode when you are 49 | already in the editor's visual mode, enter "Q". To get back to visual 50 | mode, type "vi" followed by a carriage return. 51 | 52 | Wondering why I didn't put a colon in front of that command to return 53 | to visual mode, which is obviously a line-mode command? Because you 54 | don't need to type that colon when you're giving a command from within 55 | line mode. It may even be harmful; the rule is that if you type a 56 | colon at the start of a command from within line mode, there must be 57 | nothing between the colon and the command name or abbreviation. Not an 58 | address, not even a space, nothing at all. 59 | 60 | So from this point on, I will display line-mode commands without an 61 | initial colon, because you now know enough to type that colon only if 62 | you're working in visual mode. And I'll leave off the tag at the end 63 | of a line-mode command that reminds you to finish with a carriage 64 | return because you now realize that any line-mode command, given from 65 | either line or visual mode, has to end with a carriage return. 66 | 67 | Some of you may ask why I show line-mode command lines in long-winded 68 | form, with spelled-out command names and lots of whitespace instead of 69 | using abbreviations. For instance, the two command lines: 70 | 71 | 72 | 73 | global /^/ move 0 74 | 75 | g/^/m0 76 | 77 | 78 | 79 | are identical in their effect, and the second is surely faster to 80 | type, so why do I show the first form? Because the long version is 81 | much easier to follow when I'm demonstrating a new concept, and almost 82 | everything here will be new to at least some of you. And it's a good 83 | idea to get to know the long forms, because you'll soon be learning to 84 | write editor scripts, and those scripts would be as cryptic as APL to 85 | future maintenance programmers if you wrote them in terse style. When 86 | I go over the roster of line-mode commands, I'll tell you both the 87 | long name and one or two short names for each. 88 | 89 | Line-Mode Addressing 90 | 91 | A SINGLE ADDRESS is often all you need with a line-mode command. One 92 | address refers to just one line, which tells a command like delete or 93 | substitute to operate on that one line only. A command like insert or 94 | read, which puts something immediately before or after a particular 95 | line, has no use for more than one address. 96 | 97 | A search pattern, as discussed in the first installment of this 98 | tutorial, is always an acceptable line-mode address. You put the 99 | address at the start of the command line, before the command name 100 | (but after the initial colon if you are giving the command from visual 101 | mode), so: 102 | 103 | 104 | 105 | ?the [cC]at? delete 106 | 107 | 108 | 109 | will erase the last previous line that contains the string ``the cat'' 110 | or ``the Cat'', while: 111 | 112 | 113 | 114 | /^GLOSSARY$/ read gloss.book 115 | 116 | 117 | 118 | puts the contents of the file ``gloss.book'' right after the next line 119 | in the file you're editing that contains only the word ``GLOSSARY''. 120 | 121 | There are two shorthand forms for reusing search patterns as 122 | addresses. Typing "??" or "//" tells the editor to use the last search 123 | pattern you used previously, and your choice of "??" or "//" will set 124 | the direction of the search, overriding the direction you chose the 125 | previous time you used that search pattern. That is, if you type: 126 | 127 | 128 | 129 | ?the cat? yank 130 | 131 | // delete 132 | 133 | ?? print 134 | 135 | 136 | 137 | the second command will search forward, to remove the last previous 138 | line containing the string ``the cat'', even though your original use 139 | of that pattern was in a backward search. The third command will 140 | search backward to find the line to print, which (by coincidence) is 141 | the direction of the original search. 142 | 143 | But the search pattern that those preceding abbreviations reuse may 144 | not be a pattern you used to search for a line. If you ran a 145 | substitute command after any pattern searches for lines, then the 146 | pattern you gave the substitute command to tell it what text to take 147 | out of the line is the pattern that will be reused. This is so even if 148 | your substitute command began with a search pattern to specify the 149 | line on which the substitution was to be performed--the search to find 150 | the pattern to be replaced within the line was run after the first 151 | search pattern had found the line to operate on, so the search within 152 | the line was the last pattern search run. So if you were to type: 153 | 154 | 155 | 156 | /the cat/ substitute /in the hat/on the mat 157 | 158 | ?? delete 159 | 160 | 161 | 162 | the second command would, in this case, delete the last previous line 163 | containing ``in the hat''. To be sure that the pattern that gets 164 | reused is the last one used to find a line, use the abbreviations "\?" 165 | and "\/" to search backward and forward, respectively. In all other 166 | respects these work just as typing "??" and "//" do. 167 | 168 | A LINE NUMBER is also a valid line-mode address. The editor 169 | automatically numbers each line in the file consecutively, and this 170 | numbering is dynamic--that is, whenever you add or delete lines 171 | somewhere, the editor renumbers all the lines following the insertion 172 | or deletion point. So if you change some text on line 46 in your file, 173 | and then delete lines 11 and 12, the line with the text you changed is 174 | now line 44. And if you then add ten new lines after line 17, the line 175 | with your changed text on it now automatically becomes line 54. 176 | 177 | There is never a gap or an overlap in the line number sequence, so the 178 | nth line in the file is always line number n ; that is, the 7th line 179 | is always line number 7, and so on. (There are several ways to display 180 | these line numbers, which I will expound in a later tutorial 181 | installment.) To delete the 153rd line in your file, just type: 182 | 183 | 184 | 185 | 153 delete 186 | 187 | 188 | 189 | You don't use any delimiters around a line number, or around any other 190 | address except a search pattern. 191 | 192 | There are two symbolic line numbers and one fictional one that can be 193 | used in line-mode addresses. As long as there are any lines in the 194 | buffer (that is, you haven't specified a not-yet-existent file to edit 195 | and failed to enter any text so far), the editor regards you as being 196 | `on' one of them, usually the last line affected by your latest 197 | command. A period or dot ( . ) is the symbolic address for this line. 198 | The last line in the file also has a symbolic address: the dollar sign 199 | ( $ $). So if you should type: 200 | 201 | 202 | 203 | . write >> goodlines 204 | 205 | $ delete 206 | 207 | 208 | 209 | the first command would append a copy of just the line you are on now 210 | to a file named ``goodlines'', while the second would delete the last 211 | line in the file you are editing. 212 | 213 | A few commands put text immediately after the line address you give: 214 | the append command is one of them. In order to let them put their text 215 | at the very start of a file (if that is where you want it), these 216 | commands can take the fictitious line number zero (0) as their 217 | address. So, if you want to type some text that will appear ahead of 218 | anything already in the file, you can do it with either of these 219 | command lines: 220 | 221 | 222 | 223 | 1 insert 224 | 225 | 0 append 226 | 227 | 228 | 229 | (Note, though, that insert and append are among the few line-mode 230 | commands that cannot be run from visual mode by starting with a colon, 231 | because they occupy more than one line including the text to be put 232 | in.) 233 | 234 | WRITING YOUR OWN LINE ADDRESSES is possible, too. You can attach 235 | lower-case letters to lines as line addresses, and change the 236 | attachments whenever you like. You can even use a special address that 237 | is automatically attached to the last line you jumped off from. 238 | 239 | There are ways to mark a particular line with a lower-case letter of 240 | the alphabet, and those ways differ between line and visual modes. 241 | I'll be explaining all these ways in later installments of this 242 | tutorial. But once a line is marked, the line-mode address that refers 243 | to that line is just the single-quote character followed immediately 244 | by the lower-case letter with which the line was marked. So typing: 245 | 246 | 247 | 248 | 'b print 249 | 250 | 251 | 252 | will display on the screen whatever line you have previously marked 253 | with the letter b, no matter where the line is in relation to where 254 | you are when you give the command. No need to tell the editor whether 255 | to search forward or backward; there can be only one line at a time 256 | marked with any one letter, and the editor will find that line 257 | regardless. 258 | 259 | The editor does some line marking on its own, too. Whenever you move 260 | from one line to another by a non-relative address, the editor marks 261 | the line you just left. (A non-relative address is one that isn't a 262 | known number of lines from where you were.) So: 263 | 264 | 265 | 266 | $ 267 | 268 | /the cat/ 269 | 270 | 358 271 | 272 | ?glossary? +7 273 | 274 | 'b 275 | 276 | 277 | 278 | are all non-relative addresses, and if you give any one of them, the 279 | editor will mark the line you are leaving for future reference. Then 280 | you can return to that line just by typing two successive single 281 | quotes: 282 | 283 | 284 | 285 | '' 286 | 287 | 288 | 289 | as a line-mode address. In theory, you can use this address with any 290 | line-mode command. But it is so difficult to know for sure when you 291 | left a line via a non-relative address that this address form is best 292 | saved for going back to where you were when a mistake moves you far 293 | away, at least until you're a wizard with this editor. 294 | 295 | MODIFYING ANY OF THESE ADDRESSES is possible, and there are two ways 296 | to do this. The simpler way is to offset the address a certain number 297 | of lines forward or backward with plus ( + ) or minus ( - ) signs. The 298 | rule is that each plus sign following an address tells the editor to 299 | go one line farther forward in the file than the basic address, while 300 | each minus sign means a line backward. So these three addresses all 301 | refer to the same line: 302 | 303 | 304 | 305 | 35 306 | 307 | 37 -- 308 | 309 | 30 +++++ 310 | 311 | 312 | 313 | Not that you're likely to want to modify line-number addresses with 314 | counts, unless you're weak in arithmetic and want the editor to do the 315 | adding and subtracting for you. But the count offsets will work with 316 | any line-mode addresses, and are most often used with search patterns. 317 | In any event, there is a shorthand for these counts, too. A plus or 318 | minus sign immediately followed by a number (single or multiple 319 | digits) is equivalent to a string of plus or minus signs equal to that 320 | number, so that these two addresses are the same: 321 | 322 | 323 | 324 | /^register long/ ++++ 325 | 326 | /^register long/ +4 327 | 328 | 329 | 330 | Take note that the ``4'' in the second example does not mean ``line 331 | number 4'', as it would if it appeared by itself as an address. After 332 | a plus or minus sign, a number is a count forward or backward from 333 | where the primary address lands (or if there is no primary address 334 | before the count, from the line you are on when you run the command). 335 | 336 | Note also that this is one of the few places in line-mode commands 337 | where you may not insert a blank space. The number must start in the 338 | very next character position after the plus or minus sign. If you 339 | violate this rule, the editor will uncomplainingly operate on some 340 | line that definitely is not the line you expected. 341 | 342 | The second style of address modifier is used where you want to do a 343 | search that's complex. Let's say you want to go forward in the file to 344 | delete a line that starts with ``WARNING!'', but not the first such 345 | line the editor would encounter; you want the second instance. Either 346 | of these command lines will do it: 347 | 348 | 349 | 350 | /^WARNING!/ ; /^WARNING!/ delete 351 | 352 | /^WARNING!/ ; // delete 353 | 354 | 355 | 356 | A semicolon ( ; ) between two search patterns tells the editor to find 357 | the location of the first pattern in the usual way, then start 358 | searching from that location for the second pattern. In this case, the 359 | first search pattern turned up the first instance of a line starting 360 | with ``WARNING!'', and the second search pattern led the editor on to 361 | the second instance. 362 | 363 | A very significant point here is that this combination of two search 364 | patterns, either of which could be a line address in itself, does not 365 | tell the editor to delete two lines. The semicolon means that the 366 | first pattern is merely a way station, and that the single line found 367 | by the second search pattern is the only line to be deleted. In brief, 368 | what looks like addresses for two lines is actually only an address 369 | for one. (This is not what the official documentation for this editor 370 | says, but the documentation is just plain wrong on this point.) 371 | 372 | But that's just the start of what you can do. You are not restricted 373 | to just two addresses. I've used up to ten of them, all separated by 374 | semicolons, to reach one specific line. As an example: 375 | 376 | 377 | 378 | ?^Chapter 3$? ; /^Bibliography$/ ; /^Spinoza/ ; /Monads/ 379 | 380 | 381 | 382 | will bring me to the title line of Spinoza's first work with 383 | ``Monads'' in the title, in the bibliography for Chapter 3. 384 | 385 | Nor are you limited to search pattern addresses when putting together 386 | a semicolon-separated address string. If you want to reach the first 387 | line following line 462 that contains the word ``union'', typing: 388 | 389 | 390 | 391 | 462 ; /\/ 392 | 393 | 394 | 395 | will bring you there. And any of the addresses can take numerical 396 | offsets, so: 397 | 398 | 399 | 400 | 462 +137 ; /register int/ --- 401 | 402 | 403 | 404 | is also a legitimate address string. 405 | 406 | But there are two unfortunate limitations on using semicolon-separated 407 | address strings. The lesser problem is that such a string can use 408 | ``line zero'' as an address only if the command following the address 409 | string could take line zero by itself as its address. That is, you 410 | can't even start at line zero and then proceed elsewhere with 411 | additional addresses, unless the command can operate from line zero. 412 | So: 413 | 414 | 415 | 416 | 0 ; /Spinoza/ +++ ; /Kant/ delete 417 | 418 | 419 | 420 | which looks like a reasonable way to be sure your search will find the 421 | very first ``Spinoza'' in your file, will actually fail with an error 422 | message about an illegal address. 423 | 424 | The larger misfortune is that each address in a semicolon-separated 425 | string must be farther down in the file than the one that precedes it. 426 | (This means the actual location found, after applying any plus-sign or 427 | minus-sign offset.) You cannot move backward within the series of way 428 | points. 429 | 430 | But that does not mean that you cannot use a backward search pattern 431 | within the string. The first address can be a backward search, of 432 | course. And a subsequent address can search backward if you are 433 | certain that the line it finds will actually be more forward in the 434 | file. For example, you may know that a certain backward search will 435 | wrap around to the bottom end of the file before it finds a match. A 436 | common example would be: 437 | 438 | 439 | 440 | 1 ; ?Spinoza? ; /Hegel/ yank 441 | 442 | 443 | 444 | Beginning a backward search from the first line in the file means that 445 | the search must start with the last line in the file due to 446 | wraparound, which guarantees that the search will yank the ``Hegel'' 447 | line that follows the vary last ``Spinoza'' line in your file. 448 | 449 | Also, you can use a plus-sign offset after a backward search when you 450 | are certain that the line finally found after the offset is applied 451 | will be farther down in the file than the preceding way point had 452 | been. Thus, if I want to find the first mention of Hegel in Chapter 8 453 | that is at least 120 lines after the last mention of him in Chapter 7, 454 | I can type: 455 | 456 | 457 | 458 | /^Chapter 8$/ ; ?Hegel? +119 ; // 459 | 460 | 461 | 462 | If a command with this address fails and gives an error message about 463 | a bad address, I'll know that the last mention of Hegel in Chapter 7 464 | is more than 120 lines before the end of the chapter, so the very 465 | first mention of his name in Chapter 8 is what I'm looking for. In 466 | that case, the address: 467 | 468 | 469 | 470 | /^Chapter 8$/ ; /Hegel/ 471 | 472 | 473 | 474 | is all that my command needs. 475 | 476 | The situation with forward searches inside a semicolon-separated 477 | address string is a mirror image of what I've just said. A forward 478 | search can take a minus-sign offset if you know that the offset is 479 | small enough that the line found will be further down than the last 480 | way point. But a forward search will fail, even with no offset or a 481 | plus-sign offset, if wraparound makes it find a line earlier in the 482 | file than the way point from which it began. 483 | 484 | Addressing a Section of Text 485 | 486 | TWO ADDRESSES CAN ALSO STAND FOR A RANGE OF LINES. When two addresses 487 | are separated by a comma rather than a semicolon, the meaning changes 488 | radically. (What a difference a dot makes!) 489 | 490 | Often you will want a line-mode command to act on a series of 491 | successive lines. For example, you may want to move a stretch of text 492 | from one place to another. To do this, you give the address of the 493 | first line you want the command to act on, followed by the last line 494 | it should act on, and separate the two addresses with a comma. So, the 495 | command: 496 | 497 | 498 | 499 | 14 , 17 delete 500 | 501 | 502 | 503 | will delete line 14 and line 15 and line 16 and line 17. You can see 504 | that putting more than two addresses in a comma-separated address 505 | string would be pointless. The line mode of this editor is discreet if 506 | you ignore this and string together three or more addresses with comma 507 | separation: it uses the first two addresses and discards the rest. 508 | 509 | Any line-mode addresses may be used with a comma. All of the following 510 | combinations make sense: 511 | 512 | 513 | 514 | 'd , /^struct/ 515 | 516 | 257 , . 517 | 518 | ?^Chapter 9$? , $ 519 | 520 | 521 | 522 | The first address combination would cause the command that follows it 523 | to operate on the section starting with the line you have previously 524 | marked ``d'' and ending with the next forward line that begins with 525 | ``struct'', inclusive. The second combination covers line 257 through 526 | the line you are on now. The third goes backward to include the 527 | previous line containing only ``Chapter 9'', and forward to include 528 | the very last line in your file; plus all the lines in between, of 529 | course. 530 | 531 | There are limitations on this technique, too. The primary one is that 532 | the address after the comma (after any offsets, of course) cannot be 533 | earlier in the file than the address before the comma. That is, the 534 | range of lines must run forward from the first address to the second 535 | address. So the command: 536 | 537 | 538 | 539 | 57 , 188 delete 540 | 541 | 542 | 543 | is just fine, while the similar-looking command: 544 | 545 | 546 | 547 | 188 , 57 delete 548 | 549 | 550 | 551 | will only produce an error message. (But if the two addresses happen 552 | to evaluate to the same line, there is no problem. The command will 553 | silently operate on the one line you've specified.) 554 | 555 | As you work up to more sophisticated line-mode addresses, you may get 556 | unexpected error messages about the second address being prior to 557 | first address, when you don't see how you could have anticipated that 558 | the addresses would evaluate that way. That's no disgrace, and the 559 | solution is simple. After you've looked over the addresses you used, 560 | and you're certain that they are the ones you want, just type the 561 | command in again with the two addresses in reverse order. That is, if: 562 | 563 | 564 | 565 | 642 , /in Table 23/ delete 566 | 567 | 568 | 569 | has failed, giving an error message that the lines are in the wrong 570 | order, then: 571 | 572 | 573 | 574 | /in Table 23/ , 642 delete 575 | 576 | 577 | 578 | will solve that problem. 579 | 580 | The last limitation is that when you use search patterns on both sides 581 | of a comma, the second search starts from the current line just as the 582 | first search did; it does not start from the line that the first 583 | search found. There's a way around that, though, that involves using 584 | one or more semicolons along with a comma. 585 | 586 | A semicolon-separated address string can be used anywhere in line mode 587 | that you would use a single address. One very useful technique is to 588 | use these address strings on one or both sides of a comma, to indicate 589 | a range of lines to be affected. Remember that an address string 590 | separated by semicolons is the address of just one line, so this one 591 | line can be the start or the end of a range of lines. For example, in: 592 | 593 | 594 | 595 | /^INDEX$/ ; /^Xerxes/ , $ write tailfile 596 | 597 | ?^PREFACE$? ; /^My 7th point/ , ?^PREFACE$? ; /^In summary/ -- delete 598 | 599 | 600 | 601 | the first command would write the latter part of the index to a new 602 | file, while the second could be used to remove a section of a book's 603 | preface. 604 | 605 | And that brings up the solution to our previous obstacle; the second 606 | search's starting point. If you want the search after the comma to 607 | begin from the point the first search found, use the first search 608 | pattern followed by a semicolon as the start of your after-the-comma 609 | search string, as in either of: 610 | 611 | 612 | 613 | ?Stradivarius? , ?Stradivarius? ; /Guarnerius/ 614 | 615 | ?Stradivarius? , ?? ; /Guarnerius/ 616 | 617 | 618 | 619 | In view of the rules about not going backward in line-mode address 620 | strings, I'd better clarify the way these limitations work when you 621 | combine semicolon and comma separation, as in these two examples. All 622 | but the first of the way points in each semicolon-separated string 623 | must be in the forward direction, of course, but the start of the 624 | second semicolon-separated string may be prior to any of the addresses 625 | in the first such string, that is, the one-way meter resets itself at 626 | the comma point. And using semicolon-separated strings on both sides 627 | of a comma only requires that the final landing point of the second 628 | semicolon-separated string not be earlier in the file than the final 629 | landing point of the first; the relative locations of the way points 630 | don't matter to the comma. To clarify this, consider a couple of 631 | odd-looking, and useless, but very lucid examples. The combination: 632 | 633 | 634 | 635 | 125 ; 176 ; 221 , 32 ; 67 ; 240 636 | 637 | 638 | 639 | looks invalid due to the backward jump from line 221 to line 32, but 640 | is actually a perfectly good address. The back jump comes right after 641 | the comma, where it is all right. But: 642 | 643 | 644 | 645 | 125 ; 176 ; 221 , 32 ; 67 ; 218 646 | 647 | 648 | 649 | will produce an error message, because the final landing point of the 650 | first semicolon-separated string, line 221, falls later in the file 651 | than the final landing point of the second semicolon-separated string, 652 | line 218. 653 | 654 | Now, a note about default addresses. I've already mentioned that most 655 | line-mode commands that can take an address have a ``default'' address 656 | built in, which tells the editor where to run the command if you don't 657 | give an address with it. Each command has its own default address, 658 | which may be the current line, the current line plus the one 659 | following, the last line of the file, or the entire file. 660 | 661 | The comma separator has default addresses of its own. They are the 662 | same regardless of what command is being used, and they override any 663 | command's own default address. If you put a comma before a command and 664 | don't put an address before the comma, by default the address there is 665 | the current line. In the same way, if you leave out the address after 666 | the comma, the default there is also the current line. You can even 667 | leave out the address in both places and use the current-line default 668 | in both: that means the implied address is ``from the current line to 669 | the current line'', which makes the current line the only line the 670 | command will operate on. So every one of the following command lines: 671 | 672 | 673 | 674 | . write >> goodlines 675 | 676 | . , . write >> goodlines 677 | 678 | , . write >> goodlines 679 | 680 | . , write >> goodlines 681 | 682 | , write >> goodlines 683 | 684 | 685 | 686 | will do exactly the same thing: append a copy of j ust the current 687 | line in the file you're editing to another file named ``goodlines''. 688 | 689 | Finally, there is one special symbol that represents a comma-separated 690 | address combination. The percent sign ( % ) has the same meaning as 691 | 1,$ as a line-mode address combination. Both refer to the entire file. 692 | 693 | Now You Try It 694 | 695 | Before you try the complex aspects of line-mode addresses in actual 696 | editing situations, here are some problems you can build yourself up 697 | on. For each problem I've included a solution that will work fairly 698 | efficiently. 699 | 700 | How can you tell the editor to delete the line that holds the very 701 | last instance of ``EXPORT'' in your file? The solution is 702 | straightforward once you know where to start searching. 703 | 704 | 705 | 706 | 707 | 708 | Suppose you want to delete the very first line in the file with 709 | ``EXPORT'' on it, and that just might be line 1. You can't start the 710 | search from line zero because the delete command cannot take line 0 as 711 | an address. When you type the address string "$ ; /EXPORT/" to use 712 | wraparound, you get an error message asserting that the search pattern 713 | found a line prior to the line found by the ``$'' address that 714 | appeared first, which is what you'd expect. How can you tell the 715 | editor to find and delete this line? The solution requires just a bit 716 | of creativity. 717 | 718 | 719 | 720 | 721 | 722 | If you use the address "?abc? , /xyz/" , it includes the two lines the 723 | searches (for ``abc'' and ``xyx'') find, as well as all the lines 724 | between them. How would you specify that you want the affected lines 725 | to go up to, but not include, the lines the two searches find? In this 726 | case the solution is simpler than you might think. 727 | 728 | Coming Up Next 729 | 730 | The next installment of this tutorial will deal with the Global 731 | commands--they're just too much to absorb right after the 732 | mind-numbing collection of address forms we've just gone through. And 733 | to give you more scope for using all these address forms, I'll also 734 | cover line-mode commands themselves, particularly the ones that have 735 | more capabilities than you suspect. 736 | 737 | -------------------------------------------------------------------------------- /originals/3_global_command.txt: -------------------------------------------------------------------------------- 1 | The Vi/Ex Editor, Part 3: The Global Command 2 | 3 | By Walter Alan Zintz 4 | 5 | The Details of Global Operations 6 | A Few More Uses for Global Commands 7 | Now You Give It A Try 8 | Coming Up Next 9 | 10 | The Wondrous Global Command 11 | 12 | If you're surprised that I made no mention of :global in the preceding 13 | installment of this tutorial -- well, :global is not an address. It's actually 14 | a line-mode command, and it's much more powerful than most users suspect. 15 | 16 | Even experienced users of line mode usually think of :global along these lines: 17 | ``If you type :global and then a search pattern and then a line-mode command, 18 | all on one line, then the editor finds every line in the file that contains 19 | that pattern and runs the command on every one of those lines''. That is, 20 | typing: 21 | 22 | global /^Chapter [1-9]/ delete 23 | 24 | is expected to find and delete every line in the file that starts with a 25 | chapter heading. This example will do just that, and so will many other such 26 | uses of the command. But spectacular failures will happen from time to 27 | time--typing: 28 | 29 | 30 | global /^Chapter [1-9]/ write >> t.of.contents 31 | 32 | 33 | definitely will not append each of the marked lines to a file named 34 | ``t.of.contents'', as moderately experienced users might expect. (It's likely 35 | to overflow your file system quota instead.) 36 | 37 | The Details of Global Operations 38 | 39 | More important, misunderstanding the :global command keeps users from 40 | exploiting more than a small fraction of that command's power. But you don't 41 | have to live with the limitations of ignorance on this--here's the full story 42 | in plain terms: 43 | 44 | Searching where you tell it to look: 45 | 46 | As a line-mode command, :global can be preceded by an address or pair of 47 | addresses. Its default is to search the entire file, but if you start your 48 | command as 257, 382 global then it will only search through lines 257 through 49 | 382 inclusive. Any line-mode addresses can begin a :global command, so starting 50 | with ?^Exercises? +++, $ global will restrict the pattern search and line 51 | marking to a stretch beginning three lines past the last previous line that 52 | starts with the string ``Exercises'', and ending at the end of the file. 53 | 54 | Marking either hits or misses: 55 | 56 | Typing the command name as global or g will definitely cause it to mark every 57 | line in the search area that contains the pattern. But typing it as global! or 58 | g! or v reverses the procedure--now it will only mark lines that do not contain 59 | the search string. So if you are editing a copy of a log file of error 60 | messages, and only the lines that begin with ``Error 3b:'' are of interest, you 61 | can eliminate all the unwanted lines by typing: 62 | 63 | global! /^Error 3b:/ delete 64 | 65 | Choose your own search pattern delimiter: 66 | 67 | Since this command always searches the file (or the section of it that you 68 | select) from top to bottom, you can use almost any punctuation character to 69 | mark the start and end of your search pattern. There's no need to use ? or / 70 | characters to indicate a direction for the search. If you want to eliminate 71 | lines that contain three consecutive slash marks, any of: 72 | 73 | global +///+ delete 74 | 75 | global ;///; delete 76 | 77 | global ]///] delete 78 | 79 | will be a simpler choice than using slashes as delimiters and backslashing all 80 | three of the slashes you are searching for. (However, using ! as you delimiter 81 | is dangerous, because :global is likely to mistake your delimiter for the 82 | switch that tells it to find only lines that do not contain the search 83 | pattern.) 84 | 85 | Of course this applies only to the search pattern that goes right after the 86 | :global command name, the one that says which lines to mark. If you use any 87 | search patterns before the command name, to say which area of the file is to be 88 | searched, then use ? and / delimiters as usual. 89 | 90 | Global searches that seem senseless can be very useful: 91 | 92 | At times it's wise to have :global or :global ! run a search over just one line 93 | in a file. This is the basis for conditional execution of line-mode commands. 94 | As a simple example, you may find yourself editing files from outside your 95 | organization that are sometimes (but not always) sent to you with an extra, 96 | empty last line, as a spacer. You need to remove that last line, if and only if 97 | it is empty. You could go the end of each file and look, but it's easier to 98 | have the editor do the checking and (where necessary) the deletion, so you 99 | type: 100 | 101 | $ global /^$/ delete 102 | 103 | It can also be useful to have :global mark every line in the area of the file 104 | you tell it to search! Our put-upon programmer, Hal (in the first installment 105 | of this tutorial) used this when he had to reverse the order of the lines in 106 | one file. His command line, which would look like this if typed out in 107 | unabbreviated form: 108 | 109 | global /^/ move 0 110 | 111 | begins by marking each line that has a start-of-line point, which makes every 112 | line qualify. Next it goes to the first line and moves it up right after the 113 | fictitious line zero--a no-op, of course. But then it moves the second line to 114 | the same place, pushing the former first line down one position in the file. As 115 | it does the same with the third line, the fourth line, etcetera, it's changing 116 | the order of the lines to the exact opposite of the order they were in at the 117 | start. 118 | 119 | One :global can run many commands: 120 | 121 | You can put several commands on the line after a :global command and its search 122 | pattern. After marking the appropriate lines, :global will then go to each 123 | marked line and run all of the commands you've given it, in the order you gave 124 | them. Just separate these commands with a vertical bar (``|'') character. If 125 | you type: 126 | 127 | global /^CHAPTER/ substitute /APTER/apter/ | copy $ 128 | 129 | the editor will go to each line that starts with a chapter heading, change 130 | ``CHAPTER'' to `` Chapter'', and then copy the line (now beginning ``Chapter'' 131 | instead of ``CHAPTER'') to the end of the file. The order in which you put 132 | those two commands is important -- the substitute command must come first so 133 | the subsequent copy command will copy the decapitalized version of the line, 134 | not the original all-caps version. 135 | 136 | You're not limited to just two commands in a :global command line; there is no 137 | maximum on the number of commands there. The maximum string length for the 138 | command list varies with the editor version you're using, but I've never 139 | encountered a limit of less then 256 characters. There are a few restrictions 140 | on what the command list can contain, though: 141 | 142 | The global keyword and the following list of commands all must be on one line. 143 | (That is, on one physical line, with no carriage returns in it. If that one 144 | line is too long for your terminal's screen width, the terminal may wrap it 145 | around to occupy two or more lines on your screen, but this will not cause a 146 | problem.) 147 | 148 | The command list cannot include an undo or another :global command. 149 | 150 | If you include a command that escapes to the shell, it must be the last command 151 | on the line. (Putting two or more shell-escape commands in one command list 152 | will not work.) This makes it possible to use pipes (symbolized by the | 153 | character) in your shell-escape command string, without having the editor 154 | mistake the pipe symbol for the separator between two editor commands in your 155 | :global command line. 156 | 157 | 158 | Commands don't have to run on the lines :global marks. 159 | 160 | Using :global is essentially the same as moving to each marked line manually, 161 | then typing in the command string while you are there. Just as you no longer 162 | expect every command you type in to operate on the line you are on when you 163 | type it, you don't have to have the commands in a :global string operate 164 | entirely on the marked lines. Here are three points to note regarding this: 165 | 166 | Any command in a :global command line can take its own address or addresses, 167 | just as it could if it were typed in as a separate command. So this command 168 | string: 169 | 170 | global /^XX/ - copy $ | /ZZ$/ , +5 delete 171 | 172 | is entirely legitimate. It goes to each line that begins with two capital X's, 173 | then copies the line just before that one to the end of the file, and finally 174 | goes forward to the next line that ends with two capital Z's and deletes that 175 | line and the five lines that follow it. 176 | 177 | Even if you give no addresses for the commands in a :global string, default 178 | addresses for those commands may make them operate on other than the marked 179 | line. That's the fault in that :global command string in the introduction to 180 | this installment of my tutorial that tries to write individual lines to another 181 | file. Because the default address for the write command is the entire file, 182 | this command will write the entire file the user is editing to the end of the 183 | other file, once for every line that :global has marked. The correct way to 184 | write individual lines is to type: 185 | 186 | global /^Chapter [1-9]/ . write >> t.of.contents 187 | 188 | where the dot address in front of the write command tells it to write only the 189 | line it is on. 190 | 191 | But even if you take a command that has the current line as its default 192 | address, and put it in the string following :global without giving it an 193 | address of its own, it can still operate on different lines from the ones 194 | :global has marked if it is not the first command in the string. The reason: 195 | each subsequent command in a :global takes as the current line whatever line 196 | the command before it left as the current line. 197 | 198 | In my earlier example about wanting to both change the capitalization of lines 199 | beginning with ``CHAPTER'' and copy those lines to the end of the file, the 200 | task was easy because the lines were to be copied in their changed state. But 201 | what if the user wanted only the lines in the midst of the file decapitalized, 202 | while the ones copied to the end of the file were to remain all-caps? It might 203 | seem obvious to simply reverse the order of the two commands, so the copy 204 | command was executed first, before the substitute command was called to change 205 | the capitalization, like this: 206 | 207 | global /^CHAPTER/ copy $ | substitute /APTER/apter/ 208 | 209 | Surprisingly, that would produce the opposite of the effect that was intended. 210 | That is, it would decapitalize the copied lines at the end of the file, but 211 | leave the marked lines in the midst of the file all-caps. The reason? The copy 212 | command leaves the last line of the copy text block, not the original text 213 | block, as the current line. So after the copy command has run, the substitute 214 | command, using the command's default address (the current line) because it has 215 | not been given an explicit address, would operate on the copy line rather than 216 | the original. 217 | 218 | But there is one thing that no amount of current-line shifting can change. 219 | Wherever in the file the command string may leave the current line, when the 220 | commands have finished running, :global will go to the next marked line without 221 | fail. The only way any of the commands in the string can prevent this is by 222 | deleting the next marked line -- in that case, :global will merely go on to the 223 | next marked line that has not been deleted. And even this fact has uses that 224 | might not be obvious. 225 | 226 | Let's say you want to thin out the lines in a file, by deleting every second 227 | line. You can do it by typing: 228 | 229 | global /^/ + delete 230 | 231 | This :global starts off by marking every line. When it goes to line 1, the 232 | command it executes will delete line 2. The next undeleted marked line is line 233 | 3, where its command deletes line 4, and so on. Or if you want to delete 234 | two-thirds of the lines in your file, type: 235 | 236 | global /^/ + , ++ delete 237 | 238 | A Few More Uses for Global Commands 239 | 240 | The examples above are designed to show not only the working principles of the 241 | :global command, but also some of the less-obvious tricks it can do. But I 242 | couldn't fit every important trick in above. Here are some more that are well 243 | worth knowing. 244 | 245 | Keeping Count. At times it's a good idea to follow :global with a string of 246 | commands that have absolutely nothing to do with the lines that :global has 247 | marked. The most common occasion for this comes when you need to repeat a 248 | line-mode command a certain number of times. 249 | 250 | At tradeshows I'm often invited to test a system right there on the show floor. 251 | I can't carry a 10,000-line test file along with me in every media and format 252 | any system might require, so I type in a ten-line file on the spot and expand 253 | it by telling the editor ten times to make a copy of the entire file and put 254 | that copy at the end of the present file. (Each such copy doubles the file's 255 | size, so I wind up with 10,240 lines.) 256 | 257 | But that requires accurate counting. If I'm off by even one on the number of 258 | times I type that command in, I get a half-size or double-size file that ruins 259 | my test results. Instead of trying to count without an error, I let the editor 260 | do the counting for me. After I've typed in the initial ten lines, I give one 261 | :global command: 262 | 263 | global /^/ % copy $ 264 | 265 | This tells the editor to search the ten lines of the file, mark every line that 266 | has a start-of-line (which means every line, of course), and then go to each of 267 | those ten lines and run the subsequent command to make a whole-file copy. This 268 | guarantees that the command will run exactly ten times. 269 | 270 | Not that this trick is limited to files that have exactly as many lines as the 271 | number of times I want to command to be repeated. If I had typed in a 272 | twenty-line file, I could copy it ten times by giving my :global as: 273 | 274 | 1 , 10 global /^/ % copy $ 275 | 276 | Moving Around Automatically. At times you may need to handle a series of 277 | editing problems in a file, where the edits must be dealt with one by one, not 278 | with a :global editing script. But moving to each spot where work needs to be 279 | done can be a very tedious business. If there is a text pattern that identifies 280 | each place that needs editing, or if you can write a script to insert such a 281 | pattern, as Hal did at the start of this tutorial's first installment, then 282 | :global can move you around automatically. 283 | 284 | You may recall that Hal used a script to mark up the legacy source code, 285 | putting each lint warning at the end of the source line to which it referred, 286 | preceded by "XXX" to make the affected lines identifiable. Suppose that the 287 | nefarious Vice President for Information Systems comes back to Hal to demand 288 | that each warning be investigated, to see whether the code can be rewritten to 289 | eliminate the warning. 290 | 291 | Should Hal just leaf through the code, searching for XXX patterns to guide him 292 | to the trouble spots? Hal knows that with the spaghetti code he's facing, the 293 | actual problem may be a long way from the line lint has designated. In 294 | traveling to the actual trouble spot he may have passed several XXX patterns 295 | along the way, so searching for the next XXX in the file may bring him to a 296 | site he's already dealt with, or may miss a number of XXX sites that he passed 297 | when he moved forward to get to the actual problem spot on the previous fix. 298 | Besides, because he frequently does pattern searching while fixing a problem, 299 | he can't depend on a visual-mode n command to use the XXX pattern he needs to 300 | find; he must type the pattern in afresh each time. 301 | 302 | But Hal knows a way around all this--dropping back to line mode (by typing a 303 | capital letter Q from visual mode) and giving a simple :global command: 304 | 305 | global /XXX/ visual | write 306 | 307 | This command brings Hal to the first "XXX" line, where it puts him into visual 308 | mode to do his editing. When the edit is finished, Hal simply types a capital 309 | letter Q and the editor takes him to the second "XXX" line and puts him into 310 | visual mode there, no matter how much moving around Hal did during the first 311 | edit, and so on through the list of "XXX" lines. As frosting on the cake, the 312 | write command automatically writes the changed file to disk after each 313 | individual edit. 314 | 315 | Now You Give it a Try 316 | 317 | Here are a few exercises you can try to solve, before you start using advanced 318 | :global tactics in your own editing. To keep things rolling I've provided at 319 | least one solution to each exercise, and also a hint on the last (and toughest) 320 | problem. 321 | 322 | Copy and Decapitalize. Let's think back to the user who wanted to find each 323 | line in the file that begins with "CHAPTER", then copy each such line to the 324 | end of the file just as it is, and finally change the start of each original 325 | line (in mid-file) from "CHAPTER" to "Chapter" while leaving the copied lines 326 | (at the end of the file) beginning "CHAPTER". 327 | 328 | We've already learned that this cannot be done with either of: 329 | 330 | global /^CHAPTER/ substitute /APTER/apter/ | copy $ 331 | 332 | global /^CHAPTER/ copy $ | substitute /APTER/apter/ 333 | 334 | What :global command (or commands) would it take to do what's desired here? 335 | Finding a solution to this is not difficult when there are so many workable 336 | ones. 337 | 338 | A Precise String Length. An old friend who does some pretty tricky work with 339 | troff often needs to insert a string of backslashes in a line--up to 64 of them 340 | in a row. The count of backslashes must be exactly right or troff will choke. 341 | How can he get these strings exactly right without tedious counting and 342 | checking? 343 | 344 | Let's say he needs to put 16 backslashes in line 217, right before the string 345 | "n(PDu". What command(s) should he use to get them in there without hand 346 | counting. My solution is pretty plain once you know which commands to use. 347 | 348 | Numbering Paragraphs. A documentation writer has divided each section of a 349 | document into paragraphs, and as a troff user, marks the start of each 350 | paragraph by a line that contains the macro ".pp" only. That is, a break 351 | between paragraphs looks like this: 352 | 353 | which is the only way that argon gas can be dissolved 354 | 355 | in this liquid. 356 | 357 | .pp 358 | 359 | The problem of energizing the 360 | 361 | argon to fluorescence while 362 | 363 | it is dissolved was first approached by applying a strong 364 | 365 | How can this tech writer use the vi editor to number the paragraphs in each 366 | section? (If this seems far-fetched to you, consider that I once got a phone 367 | call from a Unix guru asking how to do just this.) To keep the problem simple, 368 | let's say that there are never more than 35 paragraphs in a section, and that 369 | they should be numbered with Roman numerals. 370 | 371 | This problem is still difficult enough that I'm offering you two hints. The 372 | first is that :global is essential here. Look at the second hint only if you're 373 | about to give up and check my solution . 374 | 375 | Coming Up Next 376 | 377 | In the next part of this tutorial, I'll cover the less-known aspects of the 378 | other line-mode commands for dealing with text and files. If you're a little 379 | overwhelmed with all that I've said about :global, you'll be pleased to know 380 | that substitute is notably simpler, and all the remaining commands are very 381 | much simpler, than :global . 382 | 383 | After that, future parts of this tutorial will deal with visual mode; easier 384 | and more fun than line mode any day. 385 | 386 | -------------------------------------------------------------------------------- /originals/6_addresses_and_columns.txt: -------------------------------------------------------------------------------- 1 | Addresses and Columns 2 | ===================== 3 | By Walter Alan Zintz 4 | 5 | By popular demand I'm trying something new in the tutorial, starting with this 6 | installment. The e-mail I receive from tutorial readers most often asks me how 7 | to do some specific type of editing job, using whatever editor tools are 8 | needed. So, I'm now mixing my general-principle explanations with in-depth 9 | coverage of particular work areas. 10 | 11 | The first application area I'm covering is the one readers ask about most 12 | often, by far: editing files where columns are a major factor. Future areas are 13 | up to you readers. If you have an application area you'd like to see explained 14 | in some depth, e-mail me your suggestion. 15 | 16 | Normal-Mode Addresses 17 | --------------------- 18 | 19 | You use them all the time. They're the address targets that tell normal-mode 20 | commands like `c d y` which stretch of your file to act on. And even more often 21 | you use such addresses without commands, to move around in the file. 22 | 23 | For starters, I'll tell you some basics of normal-mode addressing that aren't 24 | particularly clear to most editor users. Then it's on to a few powerful but 25 | obscure addresses that most of us rarely or never use. 26 | 27 | A FEW ADDRESS PRINCIPLES 28 | ~~~~~~~~~~~~~~~~~~~~~~~~ 29 | 30 | 31 | The first fact of normal-mode range addresses is simple enough: one end of the 32 | range to be affected by the command is always marked by the cursor itself. The 33 | address you give the command (always a single address) indicates where the 34 | other end of the affected range is to be. The address target can be either 35 | forward or backward from the cursor position , in most cases. But exactly how 36 | the cursor and the target terminate the two ends of the range is variable. 37 | 38 | At the start we have to distinguish between line addresses and character 39 | addresses. Line addresses are very straightforward: the command affects the 40 | entire line the cursor is on, the entire line where the address point is 41 | located, and all the lines in between. If you are using an address without a 42 | command, in order to move the cursor, a line address generally puts the cursor 43 | on the first non-whitespace character in the line addressed. 44 | 45 | But line versus character addresses affect a lot more than exactly what's 46 | included in the range. As one example, if you yank or delete text using a line 47 | address and then place that text somewhere with a p or P command, that text 48 | will appear on a new line or lines, above or below the line you are on, 49 | respectively. But if you yanked or deleted with a character address, when you 50 | put the text back in, it will appear within the line you are on, just just 51 | ahead of or behind the cursor. And to dispose of one editor fallacy here and 52 | now, it does not make a bit of difference that the range of text you yanked or 53 | deleted with a character address amounts to exactly one or more lines -- it 54 | will still behave as any other text yanked or deleted with a character address. 55 | 56 | So which addresses are line addresses? That depends on what your command is. 57 | 58 | Besides the three commands I cited as examples above, there are four other, 59 | less-used commands `-- ! < > = --` that also take addresses. The only thing you 60 | have to know right now about these four commands is that they can act only on 61 | entire lines; that's inherent in what they do. So with these four commands, 62 | every address is a line address. (Except a handful of addresses, such as ``f'', 63 | that cannot be used with these commands at all.) 64 | 65 | With the three more-used commands c d y or with an address used by itself to 66 | move the cursor, an individual address is either always a line address or 67 | always a character address -- usually. There are exceptions to this rule also, 68 | such as the address ``j'', which is a character address when you are just 69 | moving the cursor, but a line address to any command. 70 | 71 | So just where does a character address take you? When you are just moving 72 | around in the file, the cursor lands on the character that is the target you 73 | sought. Or if the target was a string of characters, the character address puts 74 | the cursor on the first of these. 75 | 76 | When you are using a character address with a command, the situation is more 77 | complex. The one firm rule is that if the character address is farther down in 78 | the file than the cursor position, the cursor position is included in the range 79 | the command affects; while if the address target is earlier in the file than 80 | the cursor, the cursor position is not included in the range. 81 | 82 | The question of whether the address target is included in the command's range, 83 | like all the other open questions raised in the last few paragraphs, will have 84 | to be answered separately for each address. (But the usual rule is that if the 85 | address target is forward of the cursor, the target is not included; if the 86 | target lies backward from the cursor, the target is included.) 87 | 88 | Note also that a count given with any of these seven commands is passed to the 89 | address. You may give the count before or after the command character itself, 90 | but always before the address. What the address does with the count, if 91 | anything, is also a case-by-case question. 92 | 93 | USEFUL ADDRESSES 94 | ~~~~~~~~~~~~~~~~ 95 | 96 | There are four addresses that together resemble a miniaturized, localized 97 | version of the / and ? search patterns. In each case, the search takes place 98 | only in the current line, and only for a single character. To use any of them, 99 | you type one of the four letters designating the kind of inline search, 100 | immediately followed by the character to be searched for. (There are no 101 | metacharacters used with these addresses.) 102 | 103 | The letter ``f'' means that the search will go forward in the current line and 104 | stop on the character typed next. ``F'' makes the search run backward within 105 | the current line, otherwise the same as ``f''. A ``t'' search is the same as an 106 | ``f'' search except that the search stops with the character just short of the 107 | one you type after the ``t'', and a ``T'' search is like a ``t'' search but 108 | running backward within the current line. Any of these addresses can take a 109 | preceding count, which tells the search not to stop at the first instance of 110 | the character sought, but to go on to the nth, where n is the count. 111 | 112 | Any of these search commands, including the repeat-search commands mentioned 113 | below, are character addresses and can be used as an address for any of the 114 | three range commands that does not require a line address. In every case, the 115 | character on which the cursor would have landed had there been no command is 116 | the furthest character included in the range the command will affect. 117 | 118 | A few examples. ``Fp'' would cause a search that went backward and landed on 119 | the closest prior letter ``p''. ``3f-'' would make the search run forward 120 | within the current line and stop on the third instance of a hyphen. ``2T '' 121 | would cause a backward search that ended one character short of the second 122 | closest space character. 123 | 124 | This search system has its own repeat-search characters, which use storage 125 | buffers completely independent of those used for storing previous / and ? 126 | search strings. A semicolon ``;'' repeats the last inline search, in the same 127 | direction. A comma ``,'' repeats the last search but reverses the direction. 128 | Any count to the original search is not included in the repeat, but you can 129 | give a count to either repeat character which will be passed to the search 130 | command that is repeated. While a search is limited to the current line, you 131 | can run a search, move to another line, then use a semicolon or comma to repeat 132 | the original search on the new line. 133 | 134 | Another very useful address that operates within a single line is the vertical 135 | bar ``|''. When preceded by a count, this address takes the cursor to the nth 136 | character on the current line, where n is the count, regardless of where the 137 | cursor was when the address was given. (In this address, n is absolute, not 138 | relative, starting from character one at the left edge of the text.) 139 | 140 | This address can also be used with a command. If the target character position 141 | is forward from the cursor position, the furthest character affected will be 142 | the last one before the target character. If the target is backward from the 143 | cursor, the target character as well as all those between it and the cursor 144 | will be affected by the command. 145 | 146 | Editing in Columns 147 | ------------------ 148 | 149 | Although the Vim/Ex editor was not specifically designed to deal with columnar 150 | material, there are ways to use it effectively for this kind of work. Your 151 | choice of techniques will depend on whether you are dealing with 152 | single-character columns wherein each character in a line is in a separate 153 | column, or multi-character columns where the columns are set apart from each 154 | other by a separator character. 155 | 156 | SINGLE-CHARACTER COLUMNS 157 | ~~~~~~~~~~~~~~~~~~~~~~~~ 158 | 159 | Here I'm using ``columns'' the way most programmers do. A column in this sense 160 | is simply the characters in a vertical section of a file, one character wide. 161 | That is, the first character on each line of the file is in the first column, 162 | the second character of each line is in the second column, and so on. You'll 163 | find this usage in systems that use punch-card images, such as early Fortran 164 | programs; in the blocked records in certain databases, such as the ones used 165 | for very large mailing lists; etcetera. 166 | 167 | The essential point is that the systems th at use these records absolutely 168 | depend on each piece of information being entirely within a certain column or 169 | range of columns, and nothing else being within those columns except padding 170 | characters to fill up any column positions not needed for the information in a 171 | particular record. 172 | 173 | For example, a mailing list may require that a suite or apartment number be in 174 | columns 122 through 125 in each record (line), with any padding following the 175 | actual number, so that an address printing program that finds ``316 '' in those 176 | columns will print ``, #316'' at the end of the street address line. If it 177 | finds ``3A  '' it will then print ``, #3A'', etcetera. Should the suite number 178 | be even partially shifted out of the designated columns, the system will either 179 | print garbage as the suite number or issue an error message and skip that 180 | address altogether. The principle is the same, and even more important, with 181 | computer programs in punch-card image form. 182 | 183 | When you are making changes in existing records, and editing visually, the 184 | first important point is to be sure your are at the start of the particular 185 | field you need to modify. The ``|'' address I've explained above takes care of 186 | that -- wherever you are in a line, typing 122| brings the cursor to the 122nd 187 | column. Unless there are not 122 columns in that line: then the cursor will be 188 | placed in the last column that does exist, without any warning or error 189 | message. But files of this sort have generally been checked for exact block 190 | sizing, and if yours have not been, it's easy to check visually. 191 | 192 | To check visually that all the lines in the file are of the proper length, 193 | start by running a :se list command, which will display a dollar sign at the 194 | end of each file line. Then scan through the file to check that all those 195 | dollar signs are aligned vertically. If so, then check that the uniform line 196 | length is the correct one -- if your line length should be 66 characters (not 197 | counting the nonvisible newline), then run a 65| command on any line, and make 198 | sure that the cursor lands one column away from the end of the line. 199 | 200 | When you are at the start of the field to be changed, you have a choice of ways 201 | to change it. If the change area is 12 characters long, then typing 12cl 202 | followed by the 12 new characters and then the escape key will do it. But if 203 | you miss the count by even one character; if the actual number of characters 204 | you type in is 11 or 13; then all the subsequent fields on that line will be 205 | shifted one character out of place, which is probably a recipe for disaster. 206 | 207 | To avoid this hazard, make use of the little-known `R` command. It starts like 208 | the familiar `r` command, in that when you type the letter ``R'' in normal 209 | command mode the system waits to see what character you type next, and whatever 210 | that next character is, it replaces the character that was under the cursor. 211 | But instead of then returning you to command mode, the R command then moves the 212 | cursor one character to the right and again waits to see what character you 213 | type next -- the character you now type replaces the character that is now 214 | under the cursor. This process continues until you stop it by hitting the 215 | escape key. So if your cursor is on the capital P in the following line: 216 | 217 | but the greatest ancient Greek was Plato, who 218 | 219 | and you type in ``RHomer'' followed by the escape key, your line will now read: 220 | 221 | but the greatest ancient Greek was Homer, who 222 | 223 | and the cursor will be on the letter r at the end of ``Homer''. This character 224 | at a time replacement is the way to make sure you don't inadvertently shift any 225 | fields. Just be certain that you don't keep typing replacement characters 226 | beyond the existing end of the line; you would extend the line length that way. 227 | You can give a count to the R command, but you don't want to in this use 228 | because the count will multiply the number of times the new character string is 229 | inserted. That is, in that example above about replacing ``Plato'' with 230 | ``Homer'', if you had typed 3R instead of R your revised line would read: 231 | 232 | but the greatest ancient Greek was HomerHomerHomer, who 233 | 234 | Entering completely new lines of information is another matter. You should just 235 | type them straight across, as you would with any text entry, but if the 236 | existing lines are cryptic to human eyes you may not be able to tell by looking 237 | just where one field ends and another begins. You can try to keep count of the 238 | characters, of course, but a single mistake will throw all the subsequent 239 | fields in that line out of position. 240 | 241 | What you need here is an on-screen template to show you what goes where. You 242 | can make one on the spot, just by typing a template line into your file, 243 | entering each data line just above it, and deleting that template line when you 244 | are finished adding lines. For example, suppose you are adding to a name file 245 | where each record (line) starts with a month, day and year, continues with a 246 | source code (each of the preceding as a two-digit number, with a leading zero 247 | to pad it if necessary), and then has fields for a last name, first name, and 248 | middle initial. It would not be practical to judge where fields break just by 249 | looking at the existing data lines, which might look like this: 250 | 251 | 07215854von TarekenstuttLeopold J 252 | 253 | 12077338Henderson-Blyth La Toya P 254 | 255 | 10108972Thistlethwaites Geraldine 256 | 257 | But a simple template line can clear it all up. Here is one for the job above: 258 | 259 | m|d|y|s|LLLLLLLLLLLLLLL|FFFFFFFF|M 260 | 261 | It has mnemonic characters to remind you of what goes in each field, and the 262 | ``|'' to indicate the last position of each field more noticeably. I've even 263 | used a lower-case letter for each field that takes numeric characters right 264 | justified and zero padded, and a capital letter for each field that takes alpha 265 | characters left justified and space padded. 266 | 267 | The way to use this template is to start entering data lines immediately above 268 | the template line. That way, as you hit return to start a new line, that new 269 | line replaces the one you've just finished in the position right above the 270 | template line. Yes, eventually the template line will be driven down off the 271 | bottom of the screen, but returning to command mode and typing the lower-case 272 | letter ``z'' followed by the return key will move the template line and the 273 | lines around it to the top of the screen. 274 | 275 | But there will be times when you don't want to spend time making individual 276 | changes that you should be able to handle globally. Suppose an obsolescent 277 | operations code has been replaced, and you now need to change every ``B27'' to 278 | ``K53'' throughout your file, but only when the ``B27'' appears in the 279 | operations code columns, which are columns 9 through 11. Th is odd-looking 280 | command will do it: 281 | 282 | [source,vim] 283 | ---- 284 | :%s/^\(........\)B27/\1K53 285 | ---- 286 | 287 | Those eight consecutive dots in the search pattern guarantee that a match will 288 | occur only when there are exactly eight characters between the beginning of the 289 | line and the ``B27''. So of necessity, the ``B'' must occur in column 9, and so 290 | on. The ``\1'' puts those eight characters right back in again, so only the 291 | ``B27'' is actually replaced. 292 | 293 | If your columnar file has all lines of equal length, as most do, you can use 294 | this technique from the right side, too. If all lines in the file have 66 295 | characters, then typing that last command as: 296 | 297 | [source,vim] 298 | ---- 299 | :%s/B27\(...\)$/K53\1 300 | ---- 301 | 302 | will accomplish the changes in a case where the operations code columns are 61 303 | through 63, without the need to type (and carefully count) sixty consecutive 304 | dots. 305 | 306 | But there will be times when the columns to be changed are in the middle of 307 | horrendously long record lines. There are still a couple of tricks you may be 308 | able to use. One is to find a landmark somewhere in mid-line. Does column 158 309 | always contain either a ``*'' or a ``|'' character, neither of which can appear 310 | anywhere else in the lines? Then you can make the above change in columns 163 311 | through 165 by typing: 312 | 313 | [source,vim] 314 | ---- 315 | :%s/\([*|]....\)B27/\1K53 316 | ---- 317 | 318 | Failing a landmark, let the editor count out a long string of dots for you. To 319 | use this technique, you must first create your substitution command as a text 320 | line within the file you are editing, next write that line as a separate file 321 | (and then delete the command line from your original file), and finally use the 322 | :so command to pull in that one-line file and run it as a ex-mode command. If 323 | you need a string of 92 consecutive dots in your command, create a blank line 324 | at the end of your file, next type: 325 | 326 | [source,vim] 327 | ---- 328 | :1,92g/^/$s/^/. 329 | ---- 330 | 331 | to put those 92 dots there, and finally put the rest of the command around that 332 | dot string. 333 | 334 | MULTI-CHARACTER COLUMNS 335 | ~~~~~~~~~~~~~~~~~~~~~~~ 336 | 337 | The other meaning of ``editing in columns'' has to do with text rather than 338 | data files. It refers to tables of data such as you might find accompanying a 339 | technical article, columns of text and/or illustrations running in parallel as 340 | you'd find on a newspaper page, and the like. 341 | 342 | Yes, Unix formatting utilities and some word processing programs will format 343 | your final output into columns. But you may not have all these utilities, you 344 | may not want to spend time trying to get the results you want from those 345 | benighted programs, or you may plan to direct your output where formatters 346 | won't work. 347 | 348 | Visually editing the columns of data in a table requires little explanation. 349 | The one thing to remember: use the R as far as possible, to avoid shifting 350 | subsequent columns out of alignment inadvertently. This holds for creating 351 | tables, too; start by setting up a rectangular block of space characters, then 352 | replace spaces with the column entries you want, to keep your next entry from 353 | misaligning previous ones. This is also the best way to create pictures, 354 | diagrams, graphs and maps using ASCII characters. 355 | 356 | Things become problematic when you want to shift whole columns around -- there 357 | are no built-in Vim facilities for doing this. Here is what it is practical to 358 | do in the editor. As a real life example, consider the piece below, which I use 359 | as the tail end of Usenet (Net news) posts that announce Indonesian classical 360 | music and dance performances at a local restaurant: 361 | 362 | It's at the Dutch East Indies Restaurant ;,,,,;,,,,;,,,,;,,,,; 363 | on Oakland's downtown waterfront. The food /%%%%%%%%%%%%%%%%%%%%%\ 364 | there is very good Indonesian cuisine at /%%%%%%%%%%%%%%%%%%%%%%%\ 365 | reasonable prices - dinners $8.95 to $17.50. "|""|"""|"""""|"""|""|" 366 | Views are spectacular from the second floor _|__|___|_ _|___|__|_ 367 | picture windows, out over the water to Jack =|==|===|=====|===|==|= 368 | London Square, Alameda and San Francisco. ~~~~~~~~~~~( (~~~~~~~~~~~ 369 | Formality is medium - cloth napkins and oil ) ) 370 | candles at the tables, but no supercilious 371 | waiters, and the wall decorations are mostly Indonesian handicrafts. 372 | 373 | The phone number for information and reservations is 510/444-6555. 374 | 375 | ( ( ( | Broadway ||I The Dutch East Indies Restaurant is 376 | ) ) )Jack London |==========||== in Jack London Village, a boutiques & 377 | ( ( ( Square |E ||8 bistros cluster that is just down the 378 | ) ) ) |m ||8 estuary from Jack London Square. Jack 379 | ( ( ( JACK LONDON |b ||0 London Village is rustic, picturesque, 380 | ) ) )VILLAGE |a || quiet and safe. To get there from the 381 | ( ( ( Alice|r Amtrak ||f Interstate 880 freeway heading north, 382 | ) ) ) -----------|c station ||r take the Oak Street exit and turn left; 383 | ( ( ( Street|a ||e five blocks will bring you to Embarca- 384 | ) ) ) |d Jackson||e dero on your right, just before Oak 385 | ( ( ( parking lot |e ------||-- curves away to the left. (Going south 386 | ) ) ) |r Street||w on I-880, take the Jackson Street exit 387 | ( ( ( |o ||a and go two blocks straight ahead before 388 | ) ) ) | ||y you turn right on Oak Street.) Turn 389 | ( ( ( -------------||-- right onto Embarcadero and go three 390 | ) ) ) Oak Street|| blocks, until you go under an overpass 391 | of Victorian ironwork. Immediately 392 | turn left onto Alice Street, where you will see Jack London Village on 393 | your right, and a large lot that offers validated parking on the left. 394 | Walk into the Village's central courtyard, and you'll see the Dutch East 395 | Indies on the estuary side, toward the right, and upstairs. 396 | 397 | To create this, I started by drawing the stylized building and then the map. In 398 | each case I created a large rectangular block of space characters, then began 399 | trying ideas with the R command until I had something that satisfied me. (The 400 | pavilion sketch eventually became wider than I had planned, so I had to run a 401 | `:%s/.*/ & /` command to give me more working space.) Next I put additional 402 | blocks of space characters on the left of the drawing and the right of the map, 403 | to make a place for the text I wanted to include. Then I started replacing 404 | spaces with text, rewriting the text as I went along to fit it in nicely. When 405 | the text reached the bottom of the figure I was fitting it to, I went to 406 | full-width text lines, entering them the usual way. A tedious labor, but pretty 407 | straightforward. 408 | 409 | Now suppose I decided to redo this piece, by moving the picture to where the 410 | map is now, and vice versa. A few well chosen substitution and deletion 411 | commands would make copies of the two figures minus the text, and I could just 412 | as easily copy the text without the two figures. But how would I recombine 413 | them? 414 | 415 | Short of typing the text in again from scratch, the best I could do is to yank 416 | the lines of each figure, one at a time, and put them after (or before) the 417 | appropriate text lines, one at a time. Not that I would have to move back and 418 | forth between files with each yank and put; I could yank up to 26 lines into 419 | the named buffers, then move to the other file and put all 26 in their proper 420 | places. But there is no Vim command to yank a rectangular block of characters. 421 | 422 | Also take note that I should yank using addresses that are not line addresses, 423 | even though I will be yanking whole lines. If I should yank with line 424 | addresses, putting the pieces into the other file must make those pieces 425 | separate lines -- then I would have to join each pair of lines to create the 426 | columns I want. 427 | 428 | Next Time Around 429 | ---------------- 430 | 431 | In the next part of this tutorial, I will go over host of complications and 432 | opportunities that come from allowing the replacement commands I've discussed 433 | to use metacharacters. Th en I'll answer a couple of questions from readers 434 | that should be of use to quite a few of you from time to time. 435 | 436 | // vim:set ft=asciidoc tw=78: 437 | -------------------------------------------------------------------------------- /originals/7_the_replacement_commands.txt: -------------------------------------------------------------------------------- 1 | A Little ``R'' and ``r'': The Fine Points of those Replacement Commands 2 | ======================================================================= 3 | By Walter Alan Zintz 4 | 5 | This installment of our Vim/Ex tutorial series is a diversion from the subjects 6 | I promised at the end of the previous part -- the change is my fault, and yet 7 | it is necessary. When I blithely suggested last time that the R command is just 8 | like the familiar r command, except for a few differences I mentioned, I was 9 | leading you astray. 10 | 11 | There are several differences that can cause problems in certain uses unless 12 | you understand those differences. And you won't really comprehend the greatest 13 | of those differences until you know about metacharacters in insert mode. But as 14 | an encouragement to follow all this, consider that almost all of what I say 15 | here about the R command also is valid with all the other commands that put you 16 | into text insertion mode: a A i I o O c s :a :i etcetera. 17 | 18 | There's more to R than to r 19 | --------------------------- 20 | 21 | The r command replaces whatever character is presently under the cursor, so 22 | there must be some character under the cursor for it to replace -- otherwise it 23 | just gives you an error beep. Not so with R . You can give the R command on an 24 | empty line; whatever you type after that, up to the next escape character, will 25 | take the place of that empty line just as though you had typed past the end of 26 | an existing line after giving an R command. (I was going to say ``just as 27 | though you had given an a command'', but I'm now very wary of making 28 | comparisons that are incomplete without paragraphs of explanations.) You can 29 | even start entering text into a brand-new file via the R command. 30 | 31 | The factor above can be useful in various situations; I only have space to 32 | mention one. At times I want to type new characters to replace blank spaces in 33 | a place where some of the lines are empty. These do not have any blanks; no 34 | characters at all. But I do not have to look at each line before I start typing 35 | on it, to see whether I should use an R or an a command, because R will work in 36 | either case. 37 | 38 | The R command is more forgiving of your typing errors, too. Whatever character 39 | you type after an r is final. If you accidentally type d the wrong character, 40 | you can only put back what was there by typing a u command, if the mistake was 41 | the last editing command you typed, or put in the replacement you had in mind 42 | by returning the cursor to the spot and running another, more careful, r 43 | command. 44 | 45 | But if you mistype during an R command, you can backspace over the error with 46 | the backspace key. Then you can type in the character (or characters; you can 47 | back up multiple spaces by repeating the backspace key) you should have typed. 48 | And if you simply typed too far, you'll be glad to know that backspacing 49 | doesn't just remove the incorrect characters, it restores the characters that 50 | were there, either right away or as soon as you hit the escape key. You can 51 | even backspace over everything you've typed during this R command before you 52 | type escape, because the editor does not object to a replacement string length 53 | of zero. 54 | 55 | One caveat here, though, lest my clarification turn out to need a clarification 56 | of its own. With either of these commands it is possible to break a line, just 57 | by typing the return key as a replacement character, and with the R command 58 | this linebreaking can be done either while actually replacing characters or 59 | when typing on beyond the end of the existing line. With almost all versions of 60 | the editor, it is not possible to backspace over an inserted linebreak, even 61 | while you are still in R insertion mode. 62 | 63 | The most important difference, though, is the handling of metacharacters. Yes, 64 | text insertion utilizes metacharacters too, quite apart from the ones that the 65 | replacement patterns in :substitute commands use. The r command recognizes 66 | hardly any of these metacharacters, and quoting those in as literal characters 67 | is very simple. The R command, though, recognizes almost all of them, and 68 | quoting characters in with R is rather complicated. 69 | 70 | Quoting in Characters 71 | --------------------- 72 | 73 | The phrase ``quoting in'' is standard terminology, but it is rather misleading 74 | in the editor. Unlike Unix shells, the editor does not use any of the ASCII 75 | quotation marks: ` ' " (backquote, single and double quote) to quote characters 76 | into a file. Instead, it uses the backslash (``\'') and control-V (``^V''); 77 | the latter is what you send when you press the V key while holding the CONTROL 78 | or CTRL key down. In either case, you quote a character in by typing the 79 | quoting character just prior to the character you want to quote in. So if @ is 80 | your line kill character, and you want to put that character in the text you 81 | are typing in, you would have to type either `\@` or `^V@` to get it there. And if 82 | you want several consecutive characters quoted in, you must quote each of them 83 | individually. That is, if you want to put @@@ into a line, you must type either 84 | `^V@^V@^V@` or `\@\@\@` to put that string there. 85 | 86 | But `\` and `^V` are not always interchangeable. In many cases either will work; 87 | but sometimes you must choose the right one. Which one to use depends both on 88 | what character you want to quote in and whether you're using the r or R 89 | command. 90 | 91 | One obvious use for quoting is to insert a character that normally erases part 92 | or all of what you've just typed in. The ASCII backspace character, control-H, 93 | must be quoted in, and so must your own line-kill character (@ in the example 94 | above) and your own erase character if it is not control-H. With the r command 95 | you quote in any of these with a backslash; when using R you may quote any of 96 | these in using either backslash or control-V. 97 | 98 | A pause here, to answer a question that might be in the minds of people who 99 | know a little about Unix internals. Ordinarily it is the asynchronous serial 100 | terminal line (or TTY) driver that recognizes the erase and line-kill 101 | characters and edits the input line accordingly without including these 102 | characters in the final result. Then, how can one enter these same input-line 103 | characters into the edit buffer if they don't get past the TTY driver? Because 104 | Vim/Ex places the TTY driver into a special ``raw'' mode that ignores the 105 | line-editing characters passing them on to the editor. Otherwise you would not 106 | be able to quote these characters in. Also, the editor is set up to discover 107 | your erase and line-kill characters by querying your personal environment, and 108 | then interpret these characters as the line driver would have. A nifty feature 109 | -- but unfortunately, the editor has no way to let the user turn this feature 110 | off. 111 | 112 | The editor's creators came up with a curious method for repeating short text 113 | insertions, where the text to go in is always the same but any outgoing text 114 | varies. They decided that when you are in normal mode, and have just gone into 115 | typing-in-text submode, and make Control-@ (``^@'') the first character you 116 | type in, then the editor should insert the last piece of text you had 117 | previously inserted (if it was not more than 128 characters long) and take you 118 | back to command mode. Unfortunately, they never made this work as promised. 119 | 120 | In actuality, `^@` operates anywhere in a text insertion, not just in the first 121 | character position. What a `^@` does there depends on the situation. If your last 122 | c d y command, or one of their variants such as s D etcetera, removed or copied 123 | a full line of text or parts of two or more lines, or if you haven't run one of 124 | those commands in your current editing session, then typing `^@` is just a 125 | nuisance. It will take you out of text input submode and probably move the 126 | cursor back a few characters from where the input ended. 127 | 128 | But if you have done at least one c d y command or a variant, and if the very 129 | last one you did removed or copied only a part of a single line of text, then 130 | surprise! Typing a `^@` in this case will do three things: 131 | 132 | . Unless you typed it at the first character position on a line, it will move the 133 | cursor back one character. This will move over the last character you typed in 134 | if you've typed any, or over one existing character if you type `^@` as the first 135 | character of your insertion, but will not erase the character it passes over. 136 | 137 | . Just to the left of the new cursor position, the editor will insert the text 138 | that was removed or copied by your last c d y command or variant. (If you went 139 | into text-insertion submode via a c command or a variant of it, the text you 140 | just took out is what will be put back in.) 141 | 142 | . Finally, the text insertion will automatically end and you will be back in 143 | command submode, with the cursor positioned at the start of the last simple 144 | word that was inserted by the `^@` metacharacter. 145 | 146 | Quoting a `^@` into your text isn't possible, because the editor reserves that 147 | character for internal use and will not accept it as itself in any file you may 148 | edit. Not that there would be any reason to put `^@` in a file anyway: it is the 149 | ASCII character NUL, a padding character that is routinely inserted in data 150 | streams by device drivers, and just as routinely stripped at the receiving end, 151 | so any `^@` characters you might add would be lost in the shuffle. But when you 152 | are using the R command, or any other command that lets you insert an 153 | indefinite amount of text, you can quote a `^@` anyway by preceding it with a `^V`. 154 | The result will be to quote `^[Pb` into your file at that point; this being the 155 | command string the editor issues to perform the odd operation I've detailed 156 | above. 157 | 158 | Those of you who are skillful with the editor may wonder why the `^@` insertion 159 | ope rates only when your last text extraction was a fragment of one line. After 160 | all, the P command by itself inserts the contents of the unnamed buffer, and 161 | that buffer holds whatever was extracted last, be it half a line or a hundred 162 | lines, doesn't it? The answer lies in one of the editor's undocumented 163 | features. When you give a command to insert text, even the r command that only 164 | inserts a single character, the editor simultaneously flushes the unnamed 165 | buffer and leaves it empty -- if and only if that buffer contained more than a 166 | fragment of one line. So, when you entered the text insertion mode from which 167 | `^@` operates, you emptied the unnamed buffer unless there was only a fragment of 168 | one line in it. 169 | 170 | At times you may want to use the beautify option to the set command. This tells 171 | the editor to throw away most, but not all, control characters you may try to 172 | type in -- the exceptions usually are the tab (`^I`), newline (`^J`), and form 173 | feed (`^L`) -- in order to keep you from inadvertently putting in invisible 174 | control characters that will be hard to detect later. This option is normally 175 | off, but you can type :se bf to turn it on. 176 | 177 | But even when you want most control characters thrown out, there will be 178 | occasions when one must go in. This is not possible using a r command. The 179 | usual r technique of backslashing will usually bite back in this case -- the 180 | editor will interpret the control character by acting on its control meaning 181 | rather than inserting it in the text. Using R, though, you can insert most 182 | control characters by preceding each with `^V`. 183 | 184 | Even this may not be enough. Some systems are set up so that when certain 185 | control characters are typed in, even though preceded by `^V`, the system acts on 186 | them as control characters before the editor ever sees them. To get around this 187 | problem, many implementations of the editor, especially older ones, interpret 188 | an ordinary character typed right after a `^V` as a control character. That is, 189 | on these systems, typing `^VF` or `^Vf` while running an R command inserts a `^F` in 190 | the file, just as typing `^V^F` would on systems that don't have this challenge. 191 | 192 | Readers Ask 193 | ----------- 194 | 195 | Here are the latest questions, and my solutions, from inquiring readers with 196 | problems you might face someday. 197 | 198 | Tommy Spratlin writes: 199 | ~~~~~~~~~~~~~~~~~~~~~~ 200 | 201 | Hi Walter, 202 | 203 | In moving files from Windows machines to UNIX, some of our users do binary 204 | transfers which result in ^M characters in the ASCII files. Usually they occur 205 | at the ends of individual lines and I do: 206 | 207 | :1,$ s/^M//g 208 | 209 | where ^M is generated by ^V^M and everything works fine to delete these 210 | characters. I now have a new problem: I found a file with ^M characters 211 | embedded in it, but the file is one long line. I need to replace them with Vim's 212 | line-end character to split this long line into multiple lines. But I can't 213 | because it's the same as pressing the ENTER or RETURN key in the middle of the 214 | substitution command. How can I replace the superfluous carriage return? We 215 | have several files like this and it's causing problems viewing them with Web 216 | browsers. 217 | 218 | I tried substituting a newline with the character code and the octal code 219 | unsuccessfully, and tried the ^M as a last unsuccessful resort. 220 | 221 | Things aren't as complicated as you make them seem, Tommy. First of all, Web 222 | browsers generally ignore carriage-return and/or linefeed characters while 223 | formatting text for display. If your browser is choking on these all-one-line 224 | files, it is probably because the lines are too long for your browser, or for 225 | some other cause not related to embedded `^M` characters. 226 | 227 | Now, as you have deduced, the difference between Microsoft and Unix text file 228 | formats is that Microsoft operating systems seem to favor carriage-return 229 | followed by linefeed (`^J`) as the line separator, while Unix systems use 230 | linefeed alone. 231 | 232 | As you've discovered, you cannot directly quote a `^J` into any editor command. 233 | And yet, you put a `^J` into your file every time you hit return during text 234 | entry, although the return key on most terminals sends a `^M` character. That's 235 | the trick; the substitute command regards a `^M` in the input pattern as a signal 236 | to insert a `^J` and discard the `^M`. So you only need to get that `^M` into the 237 | replacement pattern by typing in your command line like this: 238 | 239 | [source,vim] 240 | ---- 241 | :1,$ s/^V^M/^V^M/g 242 | ---- 243 | 244 | You just have to overlook the appearance of futility in this command line, as 245 | though it were going to replace each `^M` with itself. That first `^M` is in the 246 | outgoing pattern, so it matches a real `^M`. The second, in the replacement 247 | pattern, calls for a `^J` as I explained above. 248 | 249 | However, these all-one-line files may be too long for the Vim editor, which 250 | cannot handle lines much more than a thousand characters long in most common 251 | implementations, with shorter limits in older versions. The editor will 252 | truncate lines that exceed the limit, with only a minimal and rather cryptic 253 | warning. In such cases, use the tr utility to replace the `^M` characters (which 254 | is a very straightforward job with that tool), before you bring the file into 255 | the Vim editor. 256 | 257 | You may wonder then, how you would use the substitute command to put `^M` 258 | characters into your file. The answer is to backslash the quoted-in `^M`. To add 259 | a `^M` at the end of every line in your file, so as to conform it to Microsoft 260 | practice, type this command: 261 | 262 | [source,vim] 263 | ---- 264 | :%s/$/\^V^M 265 | ---- 266 | 267 | (Note that it is important to type the \ first, then the `^V`, followed by the 268 | `^M`.) The `^V` puts the immediately-following `^M` into the command line, and the 269 | backslash tells the command that this `^M` is to be considered a real one, not a 270 | metacharacter for `^J`. In fact, these are the general principles for quoting 271 | characters almost everywhere except in typing-in-text mode: 272 | 273 | Precede a character by `^V` to keep that character from being interpreted as a 274 | metacharacter at the moment you type it. In this case, you don't want typing `^M` 275 | to immediately end the substitution command. 276 | 277 | Precede a character by a backslash to keep that character from acting as a 278 | metacharacter later, when what you've typed is interpreted by the editor -- for 279 | example, when what you have typed in is run as a command, or interpreted as a 280 | search pattern. This command uses a backslash to keep the command from 281 | inserting `^J` instead of `^M` at the time it executes. 282 | 283 | When you must use both, as in this case, type the backslash before you type the 284 | `^V`. (If you think that this backslash would then affect the immediately 285 | following `^V` rather than the later `^M`, remember that the `^V` is not there when 286 | the backslash takes effect. The `^V` disappears as soon as it tells the editor 287 | to insert the `^M` in the command instead of taking the `^M` as the signal to end 288 | the command.) 289 | 290 | Finally, you can replace linefeed characters with something else via ex mode 291 | commands, but you must use two commands and only one of them is the substitute 292 | command. Suppose you need to change a short file's format from a number of 293 | lines to the format Tommy encountered: a single line with `^M` separators. That 294 | is, replace each `^J` (except the last) with a `^M`. (This had better be a fairly 295 | short file, because even newer versions of the editor can't handle any lines 296 | longer than 1024 characters.) 297 | 298 | Start by using a command similar to the one above to put `^M` at the end of every 299 | line except the last. (Since these `^M` characters are to separate lines, there's 300 | no use for one at the end of the last line.) Then use this command: 301 | 302 | [source,vim] 303 | ---- 304 | :%j! 305 | ---- 306 | 307 | to join all the lines into one. The ``j'' in this command line is the shortest 308 | abbreviation for the ex mode join command, and the ``!'' switch at the end of 309 | it tells the command not to insert blank space between the lines it joins. 310 | 311 | Thai-Nghia Dinh writes: 312 | ~~~~~~~~~~~~~~~~~~~~~~~ 313 | 314 | Hi, 315 | 316 | I have a question (rather simple, really) but no one seem able to know the 317 | answer. Not even the help desk (with all the Vim gurus :) ). I'm hoping you can 318 | help me with it. 319 | 320 | I have a text file of unknown length. Each line of the file can be very short 321 | or very long (from 3 characters up to 1000 characters). 322 | 323 | Within this file, I'm trying to locate (search) the nth occurrence of a word. 324 | 325 | Here are a few things I've tried: 326 | 327 | The simple solution would be (from normal command mode): a /foobar command 328 | followed by the n command typed n -1 times. But what if n is large, say 200 or 329 | greater?) 330 | 331 | :1,$ global /^/ /foobar/ (and its variations) Nothing useful... 332 | 333 | Can you suggest a better way? 334 | 335 | Yes, although it involves a slightly tricky procedure. Consider the following 336 | command string: 337 | 338 | [source,vim] 339 | ---- 340 | :$|/\/s//QQQ 341 | ---- 342 | 343 | The first command in this string takes us to the last line of our file and -- 344 | incidentally -- displays it on our screen, which is not important here. The 345 | second command searches forward for a line containing ``foobar'' as a word, and 346 | starting from the last line the search must wrap around and find the first 347 | instance in the file. Then that second command replaces the word ``foobar'' 348 | with ``QQQ'', leaving the cursor at the point where the substitution was made. 349 | 350 | Now let us make an addition to the start of this command string: 351 | 352 | [source,vim] 353 | ---- 354 | :1,199g/^/$|/\/s//QQQ 355 | ---- 356 | 357 | This revised string repeats the procedure 199 times; each time the first 358 | instance of ``foobar'' remaining in the file is the one replaced. So we end up 359 | sitting on the ``QQQ'' string that replaced the 199th instance of ``foobar''; 360 | simply typing n will bring us to the 200th instance. And if we move off that 361 | 200th instance for any reason, going to the top of the file and searching for 362 | ``foobar'' will bring us right back to it, because the first 199 are now gone. 363 | 364 | When we are finished with that 200th ``foobar'', this command: 365 | 366 | [source,vim] 367 | ---- 368 | :%s/QQQ/foobar/g 369 | ---- 370 | 371 | will change those 199 ``QQQ'' strings back to ``foobar''. Of course, if there 372 | is any chance that ``QQQ'' might occur in the document as itself, we can choose 373 | another dummy string. 374 | 375 | And while I'm at it, I've got another question. 376 | 377 | How do I delete all lines beginning with a certain string, say, !@#$ (or foobar 378 | for that matter). And a related question: how to delete lines containing the 379 | word foobar (anywhere within the line)? 380 | 381 | The first command line following will solve your first problem, and the second 382 | will solve your second: 383 | 384 | [source,vim] 385 | ---- 386 | :g/^foobar/d 387 | 388 | :g/\/d 389 | ---- 390 | 391 | Next Time Around 392 | ---------------- 393 | 394 | To make room to answer two readers' questions, I had to skip presenting three 395 | great Vim tools -- autoindent, abbreviate, and map! -- and the effect their 396 | metacharacters have in text-insertion mode. They'll be first up in the next 397 | part of this tutorial. 398 | 399 | More answers to reader questions are coming, too. I have queries to answer 400 | about the semicolon address separator and about yanking within macros -- and if 401 | a few more significant problems arrive here, I'll try to fit them in, too. 402 | 403 | And this time you won't have to wait and wait for the next tutorial part. As I 404 | write this paragraph, I'm already in the middle of creating the next part, so 405 | you should see it within a month after this part appears online. 406 | 407 | // vim:set ft=asciidoc tw=78: 408 | -------------------------------------------------------------------------------- /originals/8_indent_like_a_typewriter.txt: -------------------------------------------------------------------------------- 1 | Indent, Like a Typewriter 2 | ========================= 3 | By Walter Alan Zintz 4 | 5 | Automatic Indentation 6 | --------------------- 7 | 8 | Computer editing is a great advance over typing on paper, the consensus has it. 9 | But wouldn't you be happier yet if you had the tabstop-setting capability of 10 | your old typewriter, too? With the Vim and Ex editor, you have a feature that's 11 | just as powerful and a lot easier to use, but not many users know it's there. 12 | Yet there it is, on even early versions of the editor -- its name is autoindent. 13 | 14 | With autoindent turned on, you can start a running indent any time you are in 15 | text-insert mode -- whether initiated from an R or from any other command that 16 | starts you typing in text. Just put some whitespace at the start of the first 17 | line you want indented. From then on, each time you hit the return key, the 18 | editor will automatically insert exactly the same amount of whitespace at the 19 | start of the next line. That is, if you begin a line with five space 20 | characters, every following line you type in will begin with five space 21 | characters also; causing the left margin to line up nicely, but five spaces in 22 | from the normal margin setting. 23 | 24 | Note that I said ``whitespace'' above, which includes the tab character as well 25 | as the space character. Autoindentation works whether you start a line with 26 | spaces, or tabs, or some combination of the two. In fact, it even understands 27 | redundant combinations, such as starting a line with two space characters 28 | followed by a tab character. 29 | 30 | We both know that tabbing from two spaces in will reach the first tabstop, as 31 | surely as tabbing from the left margin would -- those two spaces have no effect 32 | as far as where the indented line actually starts. Autoindentation knows this 33 | too, and will st art each subsequent line with just a tab character. But if you 34 | started a line with a tab followed by two space characters, then the spaces 35 | would have an effect -- moving the margin to the right two more character 36 | positions than the tab alone would have. In this case, autoindentation will 37 | incorporate those two following space characters, as well as the leading tab, 38 | into the text at the start of each subsequent line. 39 | 40 | The general rule is that while autoindentation will always put in the same 41 | amount of leading whitespace that you did, or at least try hard to do so, it 42 | may use its own discretion as to the combination of tab and space characters it 43 | uses to do this. 44 | 45 | If you want to increase the indentation at some point, just type more 46 | whitespace at the beginning of an (already indented) line, and your new 47 | indentation depth will be the rule from that point on. You can even leave 48 | insert mode to correct a mistake without losing the indented margin setting, 49 | providing you return to insert mode with a n o or O command. 50 | 51 | Backing off Indentation 52 | ----------------------- 53 | 54 | To set the indentation back (or off), you need to use the Control-D character. 55 | When you want to stop the indentation temporarily, for just one or a few lines, 56 | type a circumflex (^) followed by Control-D at the start of each such line, to 57 | move the start of just that one line back to the left margin. If you type the 58 | numeral zero followed by control-D at the start of a line, automatic 59 | indentation disappears completely until you again start a line with whitespace. 60 | This takes effect starting with the line you are on when you type it. 61 | 62 | To set the indentation point back to the nearest shiftwidth (discussed below) 63 | stopping place that's to the left of your present indent point, and leave it 64 | there until you change it again, type just control-D at the start of the line. 65 | If that is not enough margin reduction for you, just type several consecutive 66 | control-D characters to get the amount you want. This setback also takes effect 67 | starting with the line you are on when you type the control-D. 68 | 69 | Juggling a few :set options 70 | --------------------------- 71 | 72 | And that brings up the whole vexed question of lengths of tabs and lineshifts, 73 | which are controlled by three options of the :set command. When you are in the 74 | editor, type in the :set command query as in the first line below, and see 75 | whether the response is the default -- as given in the line following it: 76 | 77 | [source,vim] 78 | ---- 79 | :se sw ts ht 80 | 81 | shiftwidth=8 tabstop=8 hardtabs=8 82 | ---- 83 | 84 | The first of these reflects the primary problem in using autoindentation. The 85 | shiftwidth option was created to control some commands I haven't discussed yet, 86 | which add or subtract whitespace at the start of each line you designate; this 87 | option sets the number of spaces these commands add or subtract. In addition, 88 | though, the value of this option also determines where your left margin will 89 | land when you go back part of the way to your window or screen's left margin. 90 | 91 | So if your shiftwidth option is set to the default value of eight spaces, as 92 | shown above, then there will be a stopping point every eight spaces across your 93 | screen or window -- in the ninth column, in the seventeenth column, in the 94 | twenty-fifth column, etcetera. (This presumes that you call the leftmost 95 | character position on your window or screen column one, which is what the 96 | editor calls it, and not column zero.) So if your autoindented margin is in the 97 | twenty-first column, typing control-D at the start of a line will put it back 98 | to the seventeenth column. If the margin is presently in the eighteenth or the 99 | twenty-fourth column, the effect would be the same. But if the present margin 100 | is in the twenty-seventh or thirtieth column, then a single control-D would set 101 | it back to column twenty-five. 102 | 103 | Of course, you can reset the shiftwidth value via the :set command. Many 104 | programmers reset that value to four. Then the stop points will be in every 105 | fourth column -- in column five, in column nine, in column thirteen, in column 106 | seventeen, and so on. This reduces line wrap in program source code with many 107 | levels of tab indentation. 108 | 109 | Here's a visual representation of the difference: first of the default tab 110 | stops every eight columns, then as they are when reset to every four columns: 111 | 112 | +-------+-------+-------+-------+-... 113 | 114 | 1 9 17 25 33 115 | 116 | +---+---+---+---+---+---+---+---+-... 117 | 118 | 1 5 9 13 17 21 25 29 33 119 | 120 | But you just might be creating a problem by doing this. With identical 121 | shiftwidth and tabstop values, backing up via a control-D requires only erasing 122 | one tab character or erasing one or more space characters; never anything more 123 | complex. With a shiftwidth value of four and a tabstop value of eight, though, 124 | there will be times when a control-D requires the editor to remove one tab from 125 | the whitespace sequence with which it starts each line, and simultaneously add 126 | four space characters. A few versions of the editor cannot handle this 127 | complexity in some circumstances, and will at times put garbage in your file. 128 | Even more likely is that the editor will mess up when it encounters tab 129 | characters in the middle of lines. 130 | 131 | The tabstop option controls the number of spaces the editor thinks you want 132 | between tabstops. With this option at its default value of eight, there will be 133 | a tabstop every eight spaces, falling in the same columns as the shiftwidth 134 | stop points when that option's value was also at its default value of eight. So 135 | if you set the values of both options to four, you will still have both 136 | options' stop points falling in the same columns, solving the problem posed in 137 | the last paragraph. 138 | 139 | Solving it at quite a price, though. The editor can use your special value of 140 | four spaces between tabstops (or any other value you choose to give) when it 141 | is inserting and removing tabs as you type, but it has no way to mark those 142 | characters in your file to say ``This is a four-column tab character'' and 143 | ``That is an eight-column tab character''. Not that there is any difference 144 | between the tab characters themselves. A tab always moves the cursor to the 145 | next tabstop point in the line, wherever that may be. The difference is that 146 | some of your tabs will be inserted when you expected the editor to find a 147 | tabstop point every four columns; others when you (or someone else) were 148 | expecting tabstops every eight columns. 149 | 150 | So when you set your tabs value to four and then edit a file that was composed 151 | with tabs at their default value of eight, indentations will be only about half 152 | as deep as the original writer intended they should be. And when you write this 153 | file back to permanent storage, anyone who uses the file after you and has 154 | default tab settings will find the indentations you added to be about twice as 155 | deep as you intended - - this will often cause deeply indented lines to be too 156 | long to be displayed on a single line of the user's screen or window. 157 | 158 | Since you've gotten this far in the tutorial, you're surely a skilled user who 159 | can see how to get around this -- by writing a .exrc file entry to translate 160 | eight-column-tab indentations into four-column-tab equivalents as you pull in a 161 | file to edit, and a macro to do the reverse in the course of writing your work 162 | out to permanent storage. 163 | 164 | An Exercise for You 165 | ------------------- 166 | 167 | It was several tutorial parts ago that I last put exercises for the reader in 168 | the tutorial itself. This seems like a good place to revive that practice. Just 169 | how would you write a command sequence to handle that latter operation as 170 | regards start-of-line indentations? Let's say you edit in normal mode, with 171 | your tabstop option set to a value of four, so that a ten-column indentation 172 | consists of two tabs followed by two spaces and a thirteen-column indent is 173 | three tabs followed by one space. But when you write the file to permanent 174 | storage, you want it to be in the conventional format of eight columns between 175 | tab points (at least for indentations) -- so that same ten-column indentation 176 | will now consist of just one tab followed by two spaces, and the 177 | thirteen-column indent will have a single tab followed by five spaces -- to 178 | keep the indentations at the same depth they were. What sequence of commands 179 | will accomplish this? 180 | 181 | To simplify the problem, assume that the curly brace characters (``{'' and 182 | ``}'') never appear in files you edit (if they are present, which is common for 183 | program source code, choose another character pair) and that you will only be 184 | writing to the original file name, let `^I` stand for a real tab character when 185 | you write your answer, and don't worry about how you would turn your command 186 | sequence into a macro. But, definitely do remember that you will be doing a 187 | write in the middle of your editing session from time to time, to guard against 188 | losing work in a system crash, so your command sequence must leave the file 189 | copy in the editor buffer just as it was before you wrote the modified version 190 | to storage, ready for you to continue editing. 191 | 192 | This exercise is not so difficult if you've been following this tutorial 193 | carefully. The biggest hazard for those readers is that they may come up with a 194 | sequence that will work, but is much longer than it needs to be. So if your 195 | solution seems long-winded, take a look at my hint before you jump to my 196 | solution . 197 | 198 | These translator macros will work nicely for leading whitespace (indentations), 199 | but it would take incredibly complex scripts (whether Vim editor scripts or 200 | scripts for most other Unix utilities) to deal with tabs in the interiors of 201 | lines. The pestilential problem there is that you don't know just where an 202 | interior tab character is placed -- how many positions in from the start of the 203 | line. For example, when you are trying to translate eight-column tabs into 204 | four-column equivalents, and your macro finds a single eight-column tab in the 205 | middle of a line, is that tab in a column that is five or more columns from the 206 | next tab stopping point? If yes, it must be replaced by two of the four-column 207 | tabs; if no, it is correct as it is. Similarly, when going from four-column to 208 | eight-column tabs, a solitary tab in the middle of a line may be left there or 209 | may have to be replaced by space characters, depending on its column position. 210 | 211 | If you must do this kind of translation, your best bets are the -e and -i 212 | options to recent versions of the pr Unix command. Running a file through this 213 | utility will make the conversions correctly, even when the whitespace appears 214 | in the middle of lines. The downside is that your text may be reformatted to 215 | some degree. 216 | 217 | Hard Tabs 218 | --------- 219 | 220 | And then there is the hardtabs option to the :set command. That option is used 221 | to tell the editor how far apart the tab stopping points are on your physical 222 | terminal -- the editor uses this information to decide what mix of tab and 223 | space characters will represent on your screen the indentation depth that's in 224 | your file. That is, the editor runs its own translator program, if necessary, 225 | to make the spacings on your screen the same depth as those in your file. Here 226 | too, any difference between this value and either of the previous two is likely 227 | to cause problems. It's fortunate that any value you give to this option will 228 | be overridden by the spacing value that is in your Termcap or Terminfo file, 229 | because a difference between the terminal tab setting Vim expects and that which 230 | your terminal is actually using will scramble your screen for sure. 231 | 232 | So my reluctant admonition to you is to leave all three of these options set at 233 | their default values of eight. Messing around with any of them is just too 234 | likely to cause trouble. 235 | 236 | Enable and Disable autoindent 237 | ----------------------------- 238 | 239 | Of course, all this means that when you have autoindentation on, the control-D, 240 | circumflex followed by control-D, and zero followed by control-D sequences are 241 | all metastrings at the beginning of an indented line. To turn the metavalue 242 | off, so you can put one of these strings into the text at the start of an 243 | indented line, quote in the control-D character by preceding it with a 244 | control-V. 245 | 246 | So how do you turn the whole autoindent mode on and off? It's normally off when 247 | you begin an editor session, and the usual way to turn it on is to use the :set 248 | command. Just type :se ai to turn this feature on. When you want to tell the 249 | editor to stop automatically indenting every time you start a line with 250 | whitespace, type :se noai (from command mode) to turn autoindent off again. 251 | 252 | Autoindent also works with the ex-mode append insert commands, which can be 253 | abbreviated a i respectively. These commands let you type in new lines of text, 254 | below or above the current line, respectively. That is, they are generally the 255 | ex-mode equivalents of the normal-mode o O commands. They can only be run 256 | when you are in ex mode; even preceding one of them with a colon (``:'') will 257 | not let you run it from normal mode. 258 | 259 | The setting of the autoindent option controls autoindentation within these text 260 | insertions, too, but there is also another way to control it that works only 261 | with these ex-mode commands. Whenever you follow one of these commands or its 262 | abbreviation with an exclamation point (``!''), without any characters or space 263 | in between, you toggle the autoindention setting for that insertion only. That 264 | is, if autoindentation was off, the ! turns it on during this insertion. 265 | Similarly, if autoindentation was on at the time, the ! turns it off just for 266 | this insertion. 267 | 268 | [ Editor's Note : Here's an example where it really helps to disable 269 | autoindent. When programming, I use a simple .exrc file containing an `se ai bf 270 | nu sw=4 ts=4 wm=0` line. If I cut a section of indented lines from one window 271 | and paste it into my program I get a staircase effect as each line is inserted 272 | with one more tab than the last. Most annoying.] 273 | 274 | Next Time 275 | --------- 276 | 277 | The next part of this tutorial will cover the :abbreviate and :map! commands, 278 | both of which help you save typing while you are in text-insertion submode. 279 | Then, on to the editor's several facilities for creating macros and 280 | pseudo-macros that you can use from the command submode. And it will finish 281 | with more readers' questions and my answers, if you readers will send me some 282 | worthwhile questions soon. 283 | 284 | You may be laughing at that final word, ``soon'' 285 | 286 | But my secret weapon this time is that, while my editor was away I spent some 287 | time writing about half of the next part. So, when she returns from a week of 288 | well-deserved vacation in mid-November, I plan to have the completed tutorial 289 | installment waiting for her. Wish me luck. 290 | 291 | // vim:set ft=asciidoc tw=78: 292 | -------------------------------------------------------------------------------- /vimmified/1_editor_fundamentals.txt: -------------------------------------------------------------------------------- 1 | Editor Fundamentals 2 | =================== 3 | Walter Alan Zintz 4 | 5 | Why Vim? 6 | -------- 7 | 8 | A Heartwarming Edit 9 | ~~~~~~~~~~~~~~~~~~~ 10 | 11 | Pity poor Hal, a corporate maintenance programmer. A large module of 12 | badly-broken, poorly-patched legacy code -- the spaghetti variety -- finally 13 | broke down completely yesterday, leaving one corporate division running at half 14 | speed. By dint of some inspired fixes during an all-nighter, Hal has the module 15 | up and running again this morning... but just as he's ready to go out for food 16 | that isn't from a vending machine, in walks the corporation's VP of IS, with a 17 | big surprise. 18 | 19 | ``Nice work on that crash fix, Hal; but right now I need some formatted 20 | technical data about it, in a hurry. The Board of Directors' Information 21 | Systems Committee has called a rush meeting this morning to convince themselves 22 | they're on top of the problem. I'll be in the hotseat, and I need technical 23 | data I can put up on the video projector to keep them occupied.'' 24 | 25 | ``They'll want me to discuss the logfile of errors that led up to the crash... 26 | yes, I know that's in ++/oltp/err/m7++, but appending puts the latest 27 | report lines at the bottom of the file. Those suits aren't interested 28 | in what they think is ancient history, and they wouldn't be caught 29 | reading anything but a commuter train timetable from the bottom up, so 30 | you'll have to make a copy with the order of the lines reversed: what 31 | was the last line becomes the first line, what was the second to the 32 | last line is now line number two, and so on.'' 33 | 34 | ``And let's take a look at that logfile.'' 35 | 36 | .... 37 | 374a12 44872 130295/074457 nonabort 38 | 5982d34 971 130295/221938 nonabort 39 | 853f7 2184 140295/102309 abort ... 40 | .... 41 | 42 | ``Hmmm. Explaining the second column to them would be advertising the fact that 43 | we knew this failure was just waiting for a chance to happen. So while you're 44 | at it, go through and erase all but the first and last digits of each number in 45 | column two.'' 46 | 47 | ``Oh, and when they get tired of that they'll want to scrutinize the Lint 48 | report. Last month I told them that our Lint substitute was the greatest thing 49 | since Marilyn Monroe, so now they'll want me to tell them why the messages it 50 | still generates on this module aren't real hazards. Just run Lint over the 51 | revamped module; then combine the Lint output with a copy of the source file by 52 | taking each message line like:'' 53 | 54 | .... 55 | Line 257: obsolete operator += 56 | .... 57 | 58 | 59 | ``and putting the significant part at the end of the source line it refers to. 60 | And put a separator, like XXX, between the source line and the message so I can 61 | page through quickly. Nothing like a hefty dose of source code they can't begin 62 | to fathom to make the meeting break up early.'' 63 | 64 | image:images/slimy_vp.png[] 65 | 66 | ``And get right on this. The meeting starts in 35 minutes.'' 67 | 68 | image:images/hal_deletes_managers.png[] 69 | 70 | Our VP walks away inwardly smiling, thinking he's getting out of detailed 71 | explanations and putting all the blame on an underling, just by demanding more 72 | editing than anyone could do in the time available. ``I'll tell the Information 73 | Systems Committee that I made it perfectly clear to the programmer that we 74 | needed this at 9:30, but when I asked him for it a minute ago he said it wasn't 75 | finished and he wasn't sure when it would be. Then I'll remark that those 76 | programmers just can't understand that keeping management informed is every bit 77 | as important as writing code!'' 78 | 79 | But Hal has a secret weapon against this squeeze play: an expert knowledge of 80 | the Vim editor. 81 | 82 | anchor:T1_move[] 83 | 84 | Reversing the order of the lines in a file is a piece of cake with this editor. 85 | The eight keystrokes in: 86 | 87 | [source,vim] 88 | ---- 89 | :g/^/m0 90 | ---- 91 | 92 | will do it. Taking the digits out of the middle of the second column throughout 93 | the file also requires just one command line: 94 | 95 | [source,vim] 96 | ---- 97 | :%s/\v +\zs(\d)\d+(\d)/\1\2 98 | ---- 99 | 100 | And integrating the Lint messages into a copy of the source code? Even that can 101 | be automated with the Vim editor. The editor command: 102 | 103 | [source,vim] 104 | ---- 105 | :%s/\vLine (\d+): (.*)/\1s;$; XXX \2 106 | ---- 107 | 108 | will turn that file of Lint messages into an editor script, and running that 109 | script on a copy of the source file will mark it up as requested. 110 | 111 | Rather than being portrayed as a bungler, Hal can have it all ready in a couple 112 | of minutes, just by typing a few lines. He'll even have time to guard against 113 | vice-presidential prevarication, by disappearing into the coffee shop across 114 | the street and reappearing just as the meeting is getting started, to tell the 115 | VP (and everyone else in earshot), ``Those files you wanted are in 116 | slash-temp-slash-hal''. 117 | 118 | The Plan Of This Ongoing Tutorial 119 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 120 | 121 | I'm writing here for editor users who have some fluency in Vim at the surface 122 | level. That is, you know how to do the ordinary things that are belabored in 123 | all the ``Introducing Vim'' books on the market, but rarely venture beyond that 124 | level. 125 | 126 | This tutorial series will explore a lot of other capabilities that hardly 127 | anyone knows are in Vim. That includes quite a few tricks that may be built on 128 | editor functions we all use every day, but which nonetheless are not obvious -- 129 | for instance, telling the global command to mark every line it encounters. 130 | I'll also be clarifying the real nature of the many misunderstood aspects of 131 | this editor. 132 | 133 | To do all this, I'll be explaining things in more depth than you might think 134 | warranted at first. I'll also throw in exercises wherever they seem helpful. 135 | And to save you readers from gross information overload, I'll write this 136 | tutorial in a large number of fairly small modules, to be put up on our website 137 | at a calm, reasonable pace. 138 | 139 | The Editor's Basic Concepts 140 | --------------------------- 141 | 142 | To get a real grasp on this editor's power, you need to know the basic ideas 143 | embodied in it, and a few fundamental building blocks that are used throughout 144 | its many functions. 145 | 146 | One cause of editor misuse is that most users, even experienced ones, don't 147 | really know what the editor is good at and what it's not capable of. Here's a 148 | quick rundown on its capabilities. 149 | 150 | First, it's strictly a general-purpose editor. It doesn't format the text; it 151 | doesn't have the handholding of a word processor; it doesn't have built-in 152 | special facilities for editing binaries, graphics, tables, outlines, or any 153 | programming language except Lisp. 154 | 155 | It's two editors in one. Visual mode is a better full-screen editor than most, 156 | and it runs faster than those rivals that have a larger bag of screen-editing 157 | commands. Line editing mode dwarfs the ``global search and replace'' facilities 158 | found in word processors and simple screen editors; its only rivals are 159 | non-visual editors like Sed where you must know in advance exactly what you 160 | want to do. But in the Vim editor, the two sides are very closely linked, 161 | giving the editor a combination punch that no other editor I've tried can 162 | rival. 163 | 164 | Finally, this editor is at its best when used by people who have taken the 165 | trouble to learn it thoroughly. It's too capable to be learned well in an hour 166 | or two, and too idiosyncratic to be mastered in a week, and yet the power 167 | really is in it, for the few who care to delve into it. A large part of that 168 | power requires custom-programming the editor: that's not easy or 169 | straightforward, but what can be done by the skillful user goes beyond the 170 | direct programmability of any editor except (possibly) Emacs. 171 | 172 | Search Patterns 173 | --------------- 174 | 175 | In quite a few functions of this editor, you can use string-pattern searching 176 | to say where something is to be done or how far some effect is to extend. These 177 | search patterns are a good example of an editor function that is very much in 178 | the Unix style, but not exactly the same in detail as search patterns in any 179 | other Unix utility. 180 | 181 | Search patterns function in both line editing and visual editing modes, and 182 | they work the same way in both, with just a few exceptions. But how you tell 183 | the editor you're typing in a search pattern will vary with the circumstances. 184 | 185 | Searching From Where You Are Now 186 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 187 | 188 | The more common use for search patterns is to go to some new place in the file, 189 | or make some editing change that will extend from your present position to the 190 | place the pattern search finds. (In line editing mode it's also possible to 191 | have an action take place from one pattern's location to where another pattern 192 | is found, but both searches still start from your present location.) 193 | 194 | If you want to search forward in the file from your present location (toward 195 | the end of the file), precede the search pattern with a slash ( ++/++ 196 | ) character, and type another to end the pattern. So if you want to 197 | move forward to the next instance of the string ``j++'' in your file, 198 | typing: 199 | 200 | [source,vim] 201 | ---- 202 | /j++/ 203 | ---- 204 | 205 | will do it. And so will: 206 | 207 | [source,vim] 208 | ---- 209 | /j++ 210 | ---- 211 | 212 | When there is nothing between the pattern and the ++RETURN++ key, the 213 | ++RETURN++ itself will indicate the end of the search pattern, so the 214 | second slash is not necessary. 215 | 216 | To search backward (toward the start of the file), begin and end with a 217 | question mark instead of a slash. The same rules of abbreviation apply to 218 | backward searches, so: 219 | 220 | [source,vim] 221 | ---- 222 | ?j++? 223 | ---- 224 | 225 | and: 226 | 227 | [source,vim] 228 | ---- 229 | ?j++ 230 | ---- 231 | 232 | both head backward in the file to the same pattern. 233 | 234 | Either way, you've expressed both your request for a pattern search and the 235 | direction the search is to take in just one keystroke. But don't assume that if 236 | you search backward, any matching pattern the editor finds will be above your 237 | present position in the file, and vice versa if you search forward. The editor 238 | looks there first, certainly, but if it gets to the top or bottom line of the 239 | file and hasn't found a match yet, it wraps around to the other end of the file 240 | and continues the search in the same direction. That is, if you used a question 241 | mark to order a backward search and the editor searches all the way through the 242 | top line of the file without finding a match, it will go on to search the 243 | bottom line next, then the second-to-the-bottom line, and so on until (if 244 | necessary) it gets back to the point where the search started. Or if you were 245 | searching forward and the editor found no match up through the very last line 246 | of the file, it would next search the first line, then the second line, 247 | etcetera. 248 | 249 | If you don't want searches to go past either end of the file, you'll need to 250 | type in a line mode command: 251 | 252 | [source,vim] 253 | ---- 254 | :set nowrapscan 255 | ---- 256 | 257 | This will disable the wraparound searching during the present session in the 258 | editor. If you want to restore the wraparound searching mechanism, typing: 259 | 260 | [source,vim] 261 | ---- 262 | :set wrapscan 263 | ---- 264 | 265 | will do it, and you can turn this on and off as often as you like. 266 | 267 | The Find-Them-All Search 268 | ~~~~~~~~~~~~~~~~~~~~~~~~ 269 | 270 | Up to now, I've been considering searches that find just one instance of the 271 | pattern; the one closest to your current location in the file, in the direction 272 | you chose for the search. But there is another style of search, used primarily 273 | by certain line editing mode commands, such as global and substitute. This 274 | search finds every line in the file (or in a selected part of the file) that 275 | contains the pattern and operates on them all. 276 | 277 | Don't get confused when using the global and substitute commands. You'll often 278 | use both styles of search pattern in one command line. But the 279 | find-one-instance pattern or patterns will go before the command name or 280 | abbreviation, while the find-them-all pattern will come just behind it. For 281 | example, in the command: 282 | 283 | [source,vim] 284 | ---- 285 | :?Chapter 10?,/The End/substitute/cat/dog/g 286 | ---- 287 | 288 | the first two patterns refer to the preceding line closest to the 289 | current line that contains the string ``Chapter 10'' and the following 290 | line closest to the current line containing the string ``The End''. 291 | 292 | NOTE: Each address finds only one line. 293 | 294 | Combined with the intervening comma, they indicate that the substitute 295 | command is to operate on those two lines and all the lines in between 296 | them. But the patterns immediately after the substitute command itself 297 | tell the command to find every instance of the string ``cat'' within 298 | that range of lines and replace it with the string ``dog''. 299 | 300 | Aside from the difference in meaning, the two styles also have different 301 | standards for the delimiters that mark pattern beginnings and (sometimes) 302 | endings. With a find-them-all pattern, there's no need to indicate whether to 303 | search forward or backward. Thus, you aren't limited to slash and question mark 304 | as your pattern delimiters. Almost any punctuation mark will do, because the 305 | editor takes note of the first punctuation mark to appear after the command 306 | name, and regards it as the delimiter in that instance. So: 307 | 308 | [source,vim] 309 | ---- 310 | :?Chapter 10?,/The End/substitute;cat;dog;g 311 | 312 | :?Chapter 10?,/The End/substitute+cat+dog+g 313 | 314 | :?Chapter 10?,/The End/substitute{cat{dog{g 315 | ---- 316 | 317 | are all equivalent to the substitution command above. (It is a good idea to 318 | avoid using punctuation characters that might have a meaning in the command, 319 | such as an exclamation point, which often appears as a switch at the end of a 320 | command name.) 321 | 322 | The benefit of this liberty comes when the slash mark will appear as itself in 323 | the search pattern. For example, suppose our substitution command above was to 324 | find each pair of consecutive slash marks in the text, and separate them with a 325 | hyphen -- that is, change ++//++ to ++/-/++ . Obviously: 326 | 327 | [source,vim] 328 | ---- 329 | :?Chapter 10?,/The End/substitute/////-//g 330 | ---- 331 | 332 | won't work; the command will only regard the first three slashes as delimiters, 333 | and everything after that as extraneous characters at the end of the command. 334 | This can be solved by backslashing: 335 | 336 | [source,vim] 337 | ---- 338 | :?Chapter 10?,/The End/substitute/\/\//\/-\//g 339 | ---- 340 | 341 | but this is even harder to type correctly than the first attempt was. But with 342 | another punctuation mark as the separator: 343 | 344 | [source,vim] 345 | ---- 346 | :?Chapter 10?,/The End/substitute;//;/-/;g 347 | ---- 348 | 349 | the typing is easy and the final command is readable. 350 | 351 | Simple Search Patterns 352 | ~~~~~~~~~~~~~~~~~~~~~~ 353 | 354 | The simplest search pattern is just a string of characters you want 355 | the editor to find, exactly as you've typed them in. For instance: 356 | ``the cat''. But, already there are several caveats: 357 | 358 | This search finds a string of characters, which may or may not be 359 | words by themselves. That is, it may find its target in the middle of 360 | the phrase ``we fed the cat boiled chicken'', or in the middle of ``we 361 | sailed a lithe catamaran down the coast''. It's all a matter of which 362 | it encounters first. 363 | 364 | Whether the search calls ``The Cat'' a match or not depends on how 365 | you've set an editor option named ++ignorecase++ . If you've left that 366 | option in its default setting, the capitalized version will not match. 367 | If you want a capital letter to match its lower-case equivalent, and 368 | vice versa, type in the line mode command: 369 | 370 | [source,vim] 371 | ---- 372 | :set ignorecase 373 | ---- 374 | 375 | To resume letting caps match only caps and vice versa, type: 376 | 377 | [source,vim] 378 | ---- 379 | :set noignorecase 380 | ---- 381 | 382 | Unlike vi, Vim can find a match where ``the'' occurs at the end of one 383 | line and ``cat'' is at the start of the next line: 384 | 385 | ... 386 | and with Michael's careful help, we prodded the 387 | cat back into its cage. Next afternoon several 388 | ... 389 | 390 | This is done using the ++\n++ metacharacter (Metacharacters are 391 | discussed next): 392 | 393 | [source,vim] 394 | ---- 395 | /the\ncat/ delete 396 | ---- 397 | 398 | NOTE: The ex mode is line oriented, so the resulting (line) address of 399 | this search is the first line (containing ``the''). 400 | 401 | Where the search starts depends on which editor mode you're using. A search in 402 | visual mode starts with the character next to the cursor. In line mode, the 403 | search starts with the line adjacent to the current line. 404 | 405 | Metacharacters 406 | ~~~~~~~~~~~~~~ 407 | 408 | Then there are search metacharacters or ``wild cards'': characters that represent 409 | something other than themselves in the search. As an example, the 410 | metacharacters ++.++ and ++*++ in: 411 | 412 | [source,vim] 413 | ---- 414 | /Then .ed paid me $50*!/ 415 | ---- 416 | 417 | could cause the pattern to match any of: 418 | 419 | .... 420 | Then Ted paid me $5! 421 | 422 | Then Red paid me $5000! 423 | 424 | Then Ned paid me $50! 425 | .... 426 | 427 | or a myriad of other strings. Metacharacters are what give search patterns 428 | their real power, but they need to be well understood. 429 | 430 | To understand these, you must know the varied uses of the backslash ( 431 | ++\++ ) metacharacter in turning the ``wild card'' value of 432 | metacharacters on and off. 433 | 434 | In many cases, the meta value of the metacharacter is on whenever the character 435 | appears in a search pattern unless it is preceded by a backslash; when the 436 | backslash is ahead of it the meta value is turned off and the character simply 437 | represents itself. As an example, the backslash is a metacharacter by itself, 438 | even if it precedes a character that never has a meta value. The only way to 439 | put an actual backslash in your search pattern is to precede it with another 440 | backslash to remove its meta value. That is, to search for the pattern ``a\y'', 441 | type: 442 | 443 | [source,vim] 444 | ---- 445 | /a\\y/ 446 | ---- 447 | 448 | as your search pattern. If you type: 449 | 450 | [source,vim] 451 | ---- 452 | /a\y/ 453 | ---- 454 | 455 | the backslash will be interpreted as a metacharacter without any effect (since 456 | the letter y is never a metacharacter) and your search pattern will find the 457 | string ``ay''. 458 | 459 | Less-often-used metacharacters are used in exactly the opposite way. This sort 460 | of character represents only itself when it appears by itself. You must use a 461 | preceding backslash to turn the meta value on. For example, in: 462 | 463 | [source,vim] 464 | ---- 465 | /\++ 549 | 550 | A backslashed right angle bracket means the match can occur only at 551 | the end of a simple word. Otherwise the same as the left angle 552 | bracket, above. 553 | 554 | ++~++ 555 | 556 | The tilde represents the last string you put into a line by means of a 557 | line mode substitute command, regardless of whether you were in line 558 | mode then or ran it from visual mode by preceding it with a colon ( 559 | ++:++ ). For instance, if your last line mode substitution command was 560 | ++s/dog/cat/++ then a ++/the ~/++ search pattern will find ``the 561 | cat''. But the replacement string of a substitute command can use 562 | metacharacters of its own, and if your last use involved any of those 563 | metacharacters then a tilde in your search pattern will give you 564 | either an error message or a match that is not what you expected. When 565 | the editor option ++magic++ is turned off, you must backslash the 566 | tilde to give it its meta value. 567 | 568 | Vim also has a ++verymagic++ mode which can be enabled within patterns 569 | using the ++\v++ metacharacter. This ++verymagic++ mode was used in 570 | Hal's story earlier. See ++:help magic++ for a thorough explanation of 571 | Vim's ++magic++, ++nomagic++ and ++verymagic++ modes. 572 | 573 | Character Classes 574 | ~~~~~~~~~~~~~~~~~ 575 | 576 | There is one metastring form (a ``multicharacter metacharacter'') used 577 | in search patterns. When several characters are enclosed within a set 578 | of brackets ( ++[]++ ), the group matches any one of the characters 579 | inside the brackets. That is, ++/part [123]/++ will match ``part 1'', 580 | ``part 2'' or ``part 3'', whichever the search comes to first. One 581 | frequent use for this feature is in finding a string that may or may 582 | not be capitalized, when the editor option ++ignorecase++ is turned 583 | off (as it is by default). Typing ++/[Cc]at/++ will find either 584 | ``Cat'' or ``cat'', and ++/[Cc][Aa][Tt]/++ will find those or ``CAT''. 585 | (In case there was a slip of the shift key when ``CAT'' was typed in, 586 | the last pattern will even find ``CaT'', ``CAt'', etcetera.) 587 | 588 | There's more power (and some complication) in another feature of this 589 | metastring: there can be metacharacters inside it. Inside the brackets, a 590 | circumflex as the first character reverses the meaning. Now the metastring 591 | matches any one character that is NOT within the brackets. A ++/\^[^ ]/++ search 592 | pattern finds a line that does not begin with a space character. (You're so 593 | right if you think that the different meta values of the circumflex inside and 594 | outside the character class brackets is not one of the editor's best points.) A 595 | circumflex that is not the first character inside the brackets represents just 596 | an actual circumflex. 597 | 598 | A hyphen can be a metacharacter within the brackets, too. When it's between two 599 | characters, and the first of the two other characters has a lower ASCII value 600 | than the second, it's as if you'd typed in all of the characters in the ASCII 601 | collating sequence from the first to the second one, inclusive. So ++/[0-9]%/++ 602 | will find any numeral followed by the percent sign ( % ), just as 603 | ++/[0123456789]%/++ would. A ++/[a-z]/++ search pattern will match any lower-case 604 | letter, and ++/[a-zA-Z]/++ matches any letter, capital or lower case. These two 605 | internal metacharacters can be combined: ++/[^A-Z]/++ will find any character 606 | except a capital letter. A hyphen that is either the first or the last 607 | character inside the brackets has no meta value. When a 608 | character-hyphen-character string has a first character with a higher ASCII 609 | value than the last character, Vim complains with the error message: 610 | 611 | .... 612 | E16: Invalid range. 613 | .... 614 | 615 | Backslashing character classes is complex. Within the brackets you must 616 | backslash a right bracket that's part of the class; otherwise the editor will 617 | mistake it for the bracket that closes the class. Of course you must backslash 618 | a backslash that you want to be part of the class, and you can backslash a 619 | circumflex at the start or a hyphen between two characters if you want them in 620 | the class literally and don't want to move them elsewhere in the construct. 621 | Elsewhere in a search pattern you will have to backslash a left bracket that 622 | you want to appear as itself, or else the editor will take it as your attempt 623 | to begin a character class. Finally, if ++magic++ is turned off, you'll have to 624 | backslash a left bracket when you do want it to begin a character class. 625 | 626 | Coming Up Next 627 | -------------- 628 | 629 | In the link:2_line_addresses.html[second part] of this tutorial, I'll 630 | be following up on all this information about search patterns, by 631 | showing the right ways to combine them with other elements to generate 632 | command addresses. 633 | 634 | -------------------------------------------------------------------------------- /vimmified/2_line_addresses.txt: -------------------------------------------------------------------------------- 1 | Ex-Mode Addresses 2 | ================= 3 | Walter Alan Zintz 4 | 5 | Ex-Mode Addressing 6 | ------------------ 7 | 8 | Whenever you want to give an editor command that will operate on text that's 9 | already in the file you're editing -- to delete some text, change lower-case 10 | letters to capitals, write to a file, etcetera -- the editor needs to know 11 | what part of the file to go to work on. A few commands have their addresses 12 | built in, and most ex-mode commands have default addresses that the editor 13 | will use if you don't give an address, but that still leaves a lot of 14 | occasions where you need to know how to give the editor an address and what 15 | address to give. 16 | 17 | Many ex-mode commands are almost identical to corresponding commands in normal 18 | mode; many more do similar things in different ways. Most of the benefit of 19 | these duplicative command sets comes from the totally-different addressing 20 | styles of ex and normal modes. The differing address concepts mean that an 21 | edit that would be difficult or impossible to do with one mode's available 22 | addresses can be a piece of cake with an address form found in the other mode. 23 | 24 | Since I mention ``ex mode'' so often, you may wonder whether there really is a 25 | separate mode for ex editing. There surely is -- instead of filling your 26 | screen with text from the file you're editing, this mode gives you a colon 27 | (++:++) prompt for your ex mode commands, and prints only an occasional line 28 | from the file on your screen. The feel of this mode is very much like giving 29 | UNIX commands from your shell prompt. Few people work in ex mode these days, 30 | largely because you can give most ex-mode commands from normal mode, but you 31 | can't give any normal-mode commands while you are in ex mode. Or perhaps they 32 | just prefer the comfortable WYSIWYG feeling of seeing the text on screen, with 33 | changes appearing as they are made. 34 | 35 | But there are times when you will need to work temporarily in ex mode. To get 36 | to ex mode when you first launch the editor, invoke it by typing ++ex++ 37 | instead of ++vim++. To go to ex mode when you are already in the editor's 38 | normal mode, enter ++Q++. To get back to normal mode, type ++visual++ followed 39 | by a carriage return. 40 | 41 | Wondering why I didn't put a colon in front of that command to return to 42 | normal mode, which is obviously an ex-mode command? Because you don't need to 43 | type that colon when you're giving a command from within ex mode. It may even 44 | be harmful; the rule is that if you type a colon at the start of a command 45 | from within ex mode, there must be nothing between the colon and the command 46 | name or abbreviation. Not an address, not even a space, nothing at all. 47 | 48 | So from this point on, I will display ex-mode commands without an initial 49 | colon, because you now know enough to type that colon only if you're working 50 | in normal mode. And I'll leave off the tag at the end of an ex-mode command 51 | that reminds you to finish with a carriage return because you now realize that 52 | any ex-mode command, given from either ex or normal mode, has to end with a 53 | carriage return. 54 | 55 | Some of you may ask why I show ex-mode command lines in long-winded form, with 56 | spelled-out command names and lots of whitespace instead of using 57 | abbreviations. For instance, the two command lines: 58 | 59 | [source,vim] 60 | ---- 61 | global /^/ move 0 62 | 63 | g/^/m0 64 | ---- 65 | 66 | are identical in their effect, and the second is surely faster to type, so why 67 | do I show the first form? Because the long version is much easier to follow 68 | when I'm demonstrating a new concept, and almost everything here will be new 69 | to at least some of you. And it's a good idea to get to know the long forms, 70 | because you'll soon be learning to write editor scripts, and those scripts 71 | would be as cryptic as APL to future maintenance programmers if you wrote them 72 | in terse style. When I go over the roster of ex-mode commands, I'll tell you 73 | both the long name and one or two short names for each. 74 | 75 | Ex-Mode Address 76 | ~~~~~~~~~~~~~~~ 77 | 78 | Single Addresses 79 | ^^^^^^^^^^^^^^^^ 80 | 81 | A single address is often all you need with an ex-mode command. One address 82 | refers to just one line, which tells a command like delete or substitute to 83 | operate on that one line only. A command like insert or read, which puts 84 | something immediately before or after a particular line, has no use for more 85 | than one address. 86 | 87 | A search pattern, as discussed in the link:1_editor_fundamentals.html[first 88 | installment] of this tutorial, is always an acceptable ex-mode address. You 89 | put the address at the start of the command line, before the command name (but 90 | after the initial colon if you are giving the command from normal mode), so: 91 | 92 | [source,vim] 93 | ---- 94 | ?the [cC]at? delete 95 | ---- 96 | 97 | will erase the last previous line that contains the string ``the cat'' or 98 | ``the Cat'', while: 99 | 100 | [source,vim] 101 | ---- 102 | /^GLOSSARY$/ read gloss.book 103 | ---- 104 | 105 | puts the contents of the file ``gloss.book'' right after the next line in the 106 | file you're editing that contains only the word ``GLOSSARY''. 107 | 108 | There are two shorthand forms for reusing search patterns as addresses. 109 | Typing ++??++ or ++//++ tells the editor to use the last search pattern you 110 | used previously, and your choice of ++??++ or ++//++ will set the direction of 111 | the search, overriding the direction you chose the previous time you used that 112 | search pattern. That is, if you type: 113 | 114 | [source,vim] 115 | ---- 116 | ?the cat? yank 117 | 118 | // delete 119 | 120 | ?? print 121 | ---- 122 | 123 | the second command will search forward, to remove the last previous line 124 | containing the string ``the cat'', even though your original use of that 125 | pattern was in a backward search. The third command will search backward to 126 | find the line to print, which (by coincidence) is the direction of the 127 | original search. 128 | 129 | But the search pattern that those preceding abbreviations reuse may not be a 130 | pattern you used to search for a line. If you ran a substitute command after 131 | any pattern searches for lines, then the pattern you gave the substitute 132 | command to tell it what text to take out of the line is the pattern that will 133 | be reused. This is so even if your substitute command began with a search 134 | pattern to specify the line on which the substitution was to be performed -- 135 | the search to find the pattern to be replaced within the line was run after 136 | the first search pattern had found the line to operate on, so the search 137 | within the line was the last pattern search run. So if you were to type: 138 | 139 | [source,vim] 140 | ---- 141 | /the cat/ substitute /in the hat/on the mat 142 | 143 | ?? delete 144 | ---- 145 | 146 | the second command would, in this case, delete the last previous line 147 | containing ``in the hat''. To be sure that the pattern that gets reused is the 148 | last one used to find a line, use the abbreviations ++\?++ and ++\/++ to 149 | search backward and forward, respectively. In all other respects these work 150 | just as typing ++??++ and ++//++ do. 151 | 152 | Numeric Addresses 153 | ^^^^^^^^^^^^^^^^^ 154 | 155 | A line number is also a valid ex-mode address. The editor automatically 156 | numbers each line in the file consecutively, and this numbering is dynamic -- 157 | that is, whenever you add or delete lines somewhere, the editor renumbers all 158 | the lines following the insertion or deletion point. So if you change some 159 | text on line 46 in your file, and then delete lines 11 and 12, the line with 160 | the text you changed is now line 44. And if you then add ten new lines after 161 | line 17, the line with your changed text on it now automatically becomes line 162 | 54. 163 | 164 | // TODO: link to later tutorial 165 | 166 | There is never a gap or an overlap in the line number sequence, so the nth 167 | line in the file is always line number n ; that is, the 7th line is always 168 | line number 7, and so on. (There are several ways to display these line 169 | numbers, which I will expound in a later tutorial installment.) To delete the 170 | 153rd line in your file, just type: 171 | 172 | [source,vim] 173 | ---- 174 | 153 delete 175 | ---- 176 | 177 | You don't use any delimiters around a line number, or around any other address 178 | except a search pattern. 179 | 180 | There are two symbolic line numbers and one fictional one that can be used in 181 | ex-mode addresses. As long as there are any lines in the buffer (that is, you 182 | haven't specified a not-yet-existent file to edit and failed to enter any text 183 | so far), the editor regards you as being `on' one of them, usually the last 184 | line affected by your latest command. A period or dot (++.++) is the symbolic 185 | address for this line. The last line in the file also has a symbolic address: 186 | the dollar sign (++$++). So if you should type: 187 | 188 | [source,vim] 189 | ---- 190 | . write >> goodlines 191 | 192 | $ delete 193 | ---- 194 | 195 | the first command would append a copy of just the line you are on now to a 196 | file named ``goodlines'', while the second would delete the last line in the 197 | file you are editing. 198 | 199 | A few commands put text immediately after the line address you give: the 200 | append command is one of them. In order to let them put their text at the very 201 | start of a file (if that is where you want it), these commands can take the 202 | fictitious line number zero (0) as their address. So, if you want to type some 203 | text that will appear ahead of anything already in the file, you can do it 204 | with either of these command lines: 205 | 206 | [source,vim] 207 | ---- 208 | 1 insert 209 | 210 | 0 append 211 | ---- 212 | 213 | NOTE: ++insert++ and ++append++ are among the few ex-mode commands that cannot 214 | be run from normal mode by starting with a colon, because they occupy more 215 | than one line including the text to be put in. 216 | 217 | Marked Line Addresses 218 | ^^^^^^^^^^^^^^^^^^^^^ 219 | 220 | Writing your own line addresses is possible, too. You can attach lower-case 221 | letters to lines as line addresses, and change the attachments whenever you 222 | like. You can even use a special address that is automatically attached to the 223 | last line you jumped off from. 224 | 225 | There are ways to mark a particular line with a lower-case letter of the 226 | alphabet, and those ways differ between ex and normal modes. I'll be 227 | explaining all these ways in later installments of this tutorial. But once a 228 | line is marked, the ex-mode address that refers to that line is just the 229 | single-quote character followed immediately by the lower-case letter with 230 | which the line was marked. So typing: 231 | 232 | [source,vim] 233 | ---- 234 | 'b print 235 | ---- 236 | 237 | will display on the screen whatever line you have previously marked with the 238 | letter b, no matter where the line is in relation to where you are when you 239 | give the command. No need to tell the editor whether to search forward or 240 | backward; there can be only one line at a time marked with any one letter, and 241 | the editor will find that line regardless. 242 | 243 | The editor does some line marking on its own, too. Whenever you move from one 244 | line to another by a non-relative address, the editor marks the line you just 245 | left. (A non-relative address is one that isn't a known number of lines from 246 | where you were.) So: 247 | 248 | [source,vim] 249 | ---- 250 | $ 251 | 252 | /the cat/ 253 | 254 | 358 255 | 256 | ?glossary? +7 257 | 258 | 'b 259 | ---- 260 | 261 | are all non-relative addresses, and if you give any one of them, the editor 262 | will mark the line you are leaving for future reference. Then you can return 263 | to that line just by typing two successive single quotes: 264 | 265 | [source,vim] 266 | ---- 267 | '' 268 | ---- 269 | 270 | as an ex-mode address. In theory, you can use this address with any ex-mode 271 | command. But it is so difficult to know for sure when you left a line via a 272 | non-relative address that this address form is best saved for going back to 273 | where you were when a mistake moves you far away, at least until you're a 274 | wizard with this editor. 275 | 276 | Address Offsets 277 | ^^^^^^^^^^^^^^^ 278 | 279 | Modifying any of these addresses is possible, and there are two ways to do 280 | this. The simpler way is to offset the address a certain number of lines 281 | forward or backward with plus (++ + ++) or minus (++-++) signs. The rule is 282 | that each plus sign following an address tells the editor to go one line 283 | farther forward in the file than the basic address, while each minus sign 284 | means a line backward. So these three addresses all refer to the same line: 285 | 286 | [source,vim] 287 | ---- 288 | 35 289 | 290 | 37 -- 291 | 292 | 30 +++++ 293 | ---- 294 | 295 | Not that you're likely to want to modify line-number addresses with counts, 296 | unless you're weak in arithmetic and want the editor to do the adding and 297 | subtracting for you. But the count offsets will work with any ex-mode 298 | addresses, and are most often used with search patterns. In any event, there 299 | is a shorthand for these counts, too. A plus or minus sign immediately 300 | followed by a number (single or multiple digits) is equivalent to a string of 301 | plus or minus signs equal to that number, so that these two addresses are the 302 | same: 303 | 304 | [source,vim] 305 | ---- 306 | /^register long/ ++++ 307 | 308 | /^register long/ +4 309 | ---- 310 | 311 | [NOTE] 312 | ==== 313 | The ``4'' in the second example does not mean ``line number 4'', as it would 314 | if it appeared by itself as an address. After a plus or minus sign, a number 315 | is a count forward or backward from where the primary address lands (or if 316 | there is no primary address before the count, from the line you are on when 317 | you run the command). 318 | 319 | This is also one of the few places in ex-mode commands where you may not 320 | insert a blank space. The number must start in the very next character 321 | position after the plus or minus sign. If you violate this rule, the editor 322 | will uncomplainingly operate on some line that definitely is not the line you 323 | expected. 324 | ==== 325 | 326 | The second style of address modifier is used where you want to do a search 327 | that's complex. Let's say you want to go forward in the file to delete a line 328 | that starts with ``WARNING!'', but not the first such line the editor would 329 | encounter; you want the second instance. Either of these command lines will do 330 | it: 331 | 332 | [source,vim] 333 | ---- 334 | /^WARNING!/ /^WARNING!/ delete 335 | 336 | /^WARNING!/ // delete 337 | ---- 338 | 339 | The consecutive search patterns tells the editor to find the location of the 340 | first pattern in the usual way, then start searching from that location for 341 | the second pattern. In this case, the first search pattern turned up the first 342 | instance of a line starting with ``WARNING!'', and the second search pattern 343 | led the editor on to the second instance. 344 | 345 | A very significant point here is that this combination of two search patterns, 346 | either of which could be a line address in itself, does not tell the editor to 347 | delete two lines. The sequence means that the first pattern is merely a way 348 | station, and that the single line found by the second search pattern is the 349 | only line to be deleted. In brief, what looks like addresses for two lines is 350 | actually only an address for one. 351 | 352 | But that's just the start of what you can do. You are not restricted to just 353 | two addresses. I've used up to ten of them to reach one specific line. As an 354 | example: 355 | 356 | [source,vim] 357 | ---- 358 | ?^Chapter 3$? /^Bibliography$/ /^Spinoza/ /Monads/ 359 | ---- 360 | 361 | will bring me to the title line of Spinoza's first work with ``Monads'' in the 362 | title, in the bibliography for Chapter 3. 363 | 364 | Nor are you limited to search pattern addresses when putting together address 365 | string. If you want to reach the first line following line 462 that contains 366 | the word ``union'', typing: 367 | 368 | [source,vim] 369 | ---- 370 | 462 /\/ 371 | ---- 372 | 373 | will bring you there. And any of the addresses can take numerical offsets, so: 374 | 375 | [source,vim] 376 | ---- 377 | 462 +137 /register int/ --- 378 | ---- 379 | 380 | is also a legitimate address string. 381 | 382 | Even though an explicit ++ +137 ++ was used there to show that it will be 383 | added to ++462++, successive numeric addresses are additive in Vim. So this 384 | is the same as the last command: 385 | 386 | [source,vim] 387 | ---- 388 | 462 137 /register int/ --- 389 | ---- 390 | 391 | Indeed, the awkward looking ++ --- ++ demonstrates this well. Each ++ 392 | - ++ is effectively ++ -1 ++ so ++ --- ++ is the same as ++ -1 -1 -1 ++. 393 | 394 | Semicolon Separators 395 | ^^^^^^^^^^^^^^^^^^^^ 396 | 397 | There is another way to chain several addresses together to identify a single 398 | line in Vim -- by separating the addresses with a semicolon. 399 | 400 | Using ++addr ;++ sets the cursor to the line where ++addr++ matches before 401 | considering the subsequent address. Using: 402 | 403 | [source,vim] 404 | ---- 405 | /pat1/ /pat2/ 406 | ---- 407 | 408 | will find the next line forward containing "pat2" after the next line forward 409 | (from the cursor) containing "pat1", whereas: 410 | 411 | [source,vim] 412 | ---- 413 | 7 ; /pat2/ 414 | ---- 415 | 416 | will find the next line forward from line 7 containing "pat2", leaving the 417 | cursor in line 7. 418 | 419 | Addressing a Section of Text 420 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 421 | 422 | Often you will want an ex-mode command to act on a series of successive lines. 423 | For example, you may want to delete a stretch of text or move it from one 424 | place to another. To do this, you give the address of the first line you want 425 | the command to act on, followed by the last line it should act on, and 426 | separate the two addresses with a comma or semicolon. So, the command: 427 | 428 | [source,vim] 429 | ---- 430 | 14 , 17 delete 431 | ---- 432 | 433 | will delete line 14 and line 15 and line 16 and line 17. 434 | 435 | Whether two addresses are separated by a comma or a semicolon changes the 436 | meaning radically. 437 | 438 | With ++,++ the subsequent search starts from the __current__ cursor position 439 | (and does not move the cursor, as ++;++ does). 440 | 441 | As with the single line usage of ++addr ;++ the cursor is set to the line 442 | where ++addr++ matches before considering the subsequent address. 443 | 444 | .Spot Quiz 445 | [caption=""] 446 | ==== 447 | Assuming the cursor is currently on line 3 of the following famous rhyme: 448 | 449 | [source,text,numbered] 450 | ---- 451 | Write a line of source code an edit full of Vim, 452 | Four and twenty buffers opened on a whim. 453 | When the make was issued the buffers tested clean, 454 | Oh switch between your code and shell easily with screen. 455 | The nerd was on his pimped out box cranking out the gems, 456 | The boss was in his office thinking of his Benz. 457 | The team were heading out the door and gave a little wave 458 | When up came a buffer that had to be saved! 459 | ---- 460 | 461 | what do you think: 462 | 463 | [source,vim] 464 | ---- 465 | 2 ; /was/ print 466 | ---- 467 | 468 | will print? 469 | 470 | .Answer 471 | 472 | [source,text] 473 | ---- 474 | Four and twenty buffers opened on a whim. 475 | When the make was issued the buffers tested clean, 476 | ---- 477 | 478 | The subsequent ``was'' after line 2 (where the next search starts from because 479 | ++;++ resets the cursor position) resides on line 3. 480 | 481 | Had the command been (again, with the cursor on line 3): 482 | 483 | [source,vim] 484 | ---- 485 | 2 , /was/ print 486 | ---- 487 | 488 | it would have printed: 489 | 490 | [source,text] 491 | ---- 492 | Four and twenty buffers opened on a whim. 493 | When the make was issued the buffers tested clean, 494 | Oh switch between your code and shell easily with screen. 495 | The nerd was on his pimped out box cranking out the gems, 496 | ---- 497 | 498 | because the subsequent ``was'' from (after) line 3 (where the cursor is (it 499 | wasn't moved, after all)) resides on line 5. 500 | ==== 501 | 502 | Any ex-mode addresses may be used with a comma or semicolon. All of the 503 | following combinations make sense: 504 | 505 | [source,vim] 506 | ---- 507 | 'd ; /^struct/ 508 | 509 | 257 , . 510 | 511 | ?^Chapter 9$? , $ 512 | ---- 513 | 514 | The first address combination would cause the command that follows it to 515 | operate on the section starting with the line you have previously marked ``d'' 516 | and ending with the next forward (from mark ``d'') line that begins with 517 | ``struct'', inclusive. The second combination covers line 257 through the 518 | line you are on now. The third goes backward to include the previous line 519 | containing only ``Chapter 9'', and forward to include the very last line in 520 | your file; plus all the lines in between, of course. 521 | 522 | Line Order of Range Addresses 523 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 524 | 525 | Vim prefers the second address in a separated range addresses to be farther 526 | ahead in the file than the first address. Vim will ask for confirmation to 527 | swap both sides and continue if this is not the case. So, the range: 528 | 529 | [source,vim] 530 | ---- 531 | 57 , 188 delete 532 | ---- 533 | 534 | is just fine, while the similar-looking command: 535 | 536 | [source,vim] 537 | ---- 538 | 188 , 57 delete 539 | ---- 540 | 541 | will result in the request to swap the addresses. You can prevent Vim from 542 | asking and let it swap the addresses automatically by prepending ++silent++ to 543 | the start of the ex range, as in: 544 | 545 | [source,vim] 546 | ---- 547 | silent 188 , 57 delete 548 | ---- 549 | 550 | If the two addresses happen to evaluate to the same line, the command will 551 | silently operate on the one line you've specified. 552 | 553 | Chained Range Address Ends 554 | ^^^^^^^^^^^^^^^^^^^^^^^^^^ 555 | 556 | Multiple space separated addresses can be chained together to achieve your 557 | desired range. For example, in: 558 | 559 | [source,vim] 560 | ---- 561 | /^INDEX$/ /^Xerxes/ , $ write tailfile 562 | 563 | ?^PREFACE$? /^My 7th point/ , ?^PREFACE$? /^In summary/ -- delete 564 | ---- 565 | 566 | the first command would write the latter part of the index to a new file, 567 | while the second could be used to remove a section of a book's preface. 568 | 569 | However, if you want the search after the comma to begin from the point the 570 | first search found, use a semicolon instead of a comma, as in: 571 | 572 | [source,vim] 573 | ---- 574 | ?Stradivarius? ; /Guarnerius/ 575 | ---- 576 | 577 | A note about default addresses 578 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 579 | 580 | I've already mentioned that most ex-mode commands that can take an address 581 | have a ``default'' address built in, which tells the editor where to run the 582 | command if you don't give an address with it. Each command has its own default 583 | address, which may be the current line, the current line plus the one 584 | following, the last line of the file, or the entire file. 585 | 586 | The range separators have default addresses of their own. They are the same 587 | regardless of what command is being used, and they override any command's own 588 | default address. If you put a comma or semicolon before a command and don't 589 | put an address before the it, by default the address there is the current 590 | line. In the same way, if you leave out the address after it, the default 591 | there is also the current line. You can even leave out the address in both 592 | places and use the current-line default in both: that means the implied 593 | address is ``from the current line to the current line'', which makes the 594 | current line the only line the command will operate on. So every one of the 595 | following command lines: 596 | 597 | [source,vim] 598 | ---- 599 | . write >> goodlines 600 | 601 | . , . write >> goodlines 602 | 603 | , . write >> goodlines 604 | 605 | . , write >> goodlines 606 | 607 | , write >> goodlines 608 | ---- 609 | 610 | will do exactly the same thing: append a copy of just the current line in the 611 | file you're editing to another file named ``goodlines''. 612 | 613 | NOTE: The exact same behaviour would have been observed with the semicolon 614 | separator instead of the comma in these examples because the explicit virtual 615 | line ++.++ and the implicit current line used by the ++write++ command are all 616 | referring to the ``current line'' (which is where semicolon and comma differ). 617 | 618 | Finally, there is one special symbol that represents the ++1,$++ (comma or 619 | semicolon-separated) address combination -- the percent sign (++%++). Both 620 | refer to the entire file. 621 | 622 | Now You Try It 623 | -------------- 624 | 625 | Before you try the complex aspects of ex-mode addresses in actual editing 626 | situations, here are some problems you can build yourself up on. For each 627 | problem I've included a solution that will work fairly efficiently. 628 | 629 | anchor:E2.1[] 630 | 631 | Exercise 2.1 632 | ~~~~~~~~~~~~ 633 | 634 | How can you tell the editor to delete the line that holds the very last 635 | instance of ``EXPORT'' in your file? Be sure to check for cases where 636 | ``EXPORT'' appears on the last line of the file too. The solution is 637 | straightforward once you know where to start searching. 638 | 639 | link:2_line_addresses_solutions.html#S2.1[Solution 2.1] 640 | 641 | anchor:E2.2[] 642 | 643 | Exercise 2.2 644 | ~~~~~~~~~~~~ 645 | 646 | Suppose you want to delete the very first line in the file with ``EXPORT'' on 647 | it, and that just might be line 1. Show two different ways to do this with 648 | ranges in Vim. 649 | 650 | link:2_line_addresses_solutions.html#S2.2[Solution 2.2] 651 | 652 | anchor:E2.3[] 653 | 654 | Exercise 2.3 655 | ~~~~~~~~~~~~ 656 | 657 | If you use the address ++?abc? , /xyz/++ , it includes the two lines the 658 | searches (for ``abc'' and ``xyx'') find, as well as all the lines between 659 | them. How would you specify that you want the affected lines to go up to, but 660 | not include, the lines the two searches find? In this case the solution is 661 | simpler than you might think. 662 | 663 | link:2_line_addresses_solutions.html#S2.3[Solution 2.3] 664 | 665 | Coming Up Next 666 | -------------- 667 | 668 | The link:3_global_command.html[next installment] of this tutorial will deal 669 | with the Global commands -- they're just too much to absorb right after the 670 | mind-numbing collection of address forms we've just gone through. And to give 671 | you more scope for using all these address forms, I'll also cover ex-mode 672 | commands themselves, particularly the ones that have more capabilities than 673 | you suspect. 674 | 675 | // vim: set ft=asciidoc tw=78: 676 | -------------------------------------------------------------------------------- /vimmified/2_line_addresses_solutions.txt: -------------------------------------------------------------------------------- 1 | Ex-Mode Addresses 2 | ================= 3 | Walter Alan Zintz 4 | 5 | Solutions to Exercises 6 | ---------------------- 7 | 8 | // TODO: folding the actual solutions in a clickable reveal would be nice. 9 | 10 | anchor:S2.1[] 11 | 12 | Solution 2.1 13 | ~~~~~~~~~~~~ 14 | 15 | link:2_line_addresses.html#E2.1[Question] 16 | 17 | Start at virtual address line ++0++ and search backwards to find the last line 18 | containing ``EXPORT'': 19 | 20 | [source,vim] 21 | ---- 22 | :0 ?EXPORT? delete 23 | ---- 24 | 25 | 26 | anchor:S2.2[] 27 | 28 | Solution 2.2 29 | ~~~~~~~~~~~~ 30 | 31 | link:2_line_addresses.html#E2.2[Question] 32 | 33 | . Starting at virtual address line ++0++ which includes a match on line 1: 34 | + 35 | [source,vim] 36 | ---- 37 | :0 /EXPORT/ delete 38 | ---- 39 | + 40 | . Starting at virtual address line ++$++ (last line) and searching forward, 41 | wrapping around the buffer to find the first line containing ``EXPORT'': 42 | + 43 | [source,vim] 44 | ---- 45 | :$ /EXPORT/ delete 46 | ---- 47 | 48 | 49 | anchor:S2.3[] 50 | 51 | Solution 2.3 52 | ~~~~~~~~~~~~ 53 | 54 | link:2_line_addresses.html#E2.3[Question] 55 | 56 | Use a positive numeric offset of ++ +1++ to move one line past the ++?abc?++ 57 | search and a negative numeric offset of ++-1++ to move one line prior to the 58 | ++/xyz/++ search: 59 | 60 | [source,vim] 61 | ---- 62 | ?abc?+1 , /xyz/-1 delete 63 | ---- 64 | 65 | -------------------------------------------------------------------------------- /vimmified/3_global_command.txt: -------------------------------------------------------------------------------- 1 | The Global Command 2 | ================== 3 | Walter Alan Zintz 4 | 5 | The Wondrous Global Command 6 | --------------------------- 7 | 8 | If you're surprised that I made no mention of ++:global++ in the 9 | link:2_line_addresses.html#T3_good_write[preceding installment] of this 10 | tutorial -- well, ++:global++ is not an address. It's actually an ex-mode 11 | command, and it's much more powerful than most users suspect. 12 | 13 | Even experienced users of ex mode usually think of ++:global++ along these 14 | lines: ``If you type :global and then a search pattern and then an ex-mode 15 | command, all on one line, then the editor finds every line in the file that 16 | contains that pattern and runs the command on every one of those lines''. That 17 | is, typing: 18 | 19 | 20 | [source,vim] 21 | ---- 22 | global /^Chapter [1-9]/ delete 23 | ---- 24 | 25 | is expected to find and delete every line in the file that starts with a 26 | chapter heading. This example will do just that, and so will many other such 27 | uses of the command. But spectacular failures will happen from time to time -- 28 | typing: 29 | 30 | anchor:T3_bad_write[] 31 | 32 | [source,vim] 33 | ---- 34 | global /^Chapter [1-9]/ write >> t.of.contents 35 | ---- 36 | 37 | definitely will not append each of the marked lines to a file named 38 | ``t.of.contents'', as moderately experienced users might expect. (It's likely 39 | to overflow your file system quota instead.) 40 | 41 | .Spot Quiz 42 | [caption=""] 43 | ==== 44 | Can you guess what is wrong with this global command? 45 | 46 | [source,vim] 47 | ---- 48 | global /^Chapter [1-9]/ write >> t.of.contents 49 | ---- 50 | 51 | What is the author's mistake? You can link:#T3_good_write[jump ahead to the 52 | answer] now if it's really bugging you. 53 | ==== 54 | 55 | The Details of Global Operations 56 | -------------------------------- 57 | 58 | More important, misunderstanding the ++:global++ command keeps users from 59 | exploiting more than a small fraction of that command's power. But you don't 60 | have to live with the limitations of ignorance on this -- here's the full 61 | story in plain terms: 62 | 63 | Searching where you tell it to look 64 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 65 | 66 | As an ex-mode command, ++:global++ can be preceded by an address or pair of 67 | addresses. Its default is to search the entire file, but if you start your 68 | command as ++:257, 382 global++ then it will only search through lines 257 69 | through 382 inclusive. Any ex-mode addresses can begin a ++:global++ command, 70 | so starting with `:?^Exercises? +++, $ global` will restrict the pattern search 71 | and line marking to a stretch beginning three lines past the last previous 72 | line that starts with the string ``Exercises'', and ending at the end of the 73 | file. 74 | 75 | Marking either hits or misses 76 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 77 | 78 | Typing the command name as global or ++:g++ will definitely cause it to mark 79 | every line in the search area that contains the pattern. But typing it as 80 | ++:global!++ or ++:g!++ or ++:vglobal++ or just ++:v++ reverses the procedure 81 | -- now it will only mark lines that do *not* contain the search string. So if 82 | you are editing a copy of a log file of error messages, and only the lines 83 | that begin with ``Error 3b:'' are of interest, you can eliminate all the 84 | unwanted lines by typing: 85 | 86 | [source,vim] 87 | ---- 88 | global! /^Error 3b:/ delete 89 | ---- 90 | 91 | or 92 | 93 | [source,vim] 94 | ---- 95 | vglobal /^Error 3b:/ delete 96 | ---- 97 | 98 | Choose your own search pattern delimiter 99 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 100 | 101 | Since this command always searches the file (or the section of it that you 102 | select) from top to bottom, you can use almost any punctuation character to 103 | mark the start and end of your search pattern. There's no need to use ++?++ or 104 | ++/++ characters to indicate a direction for the search. If you want to 105 | eliminate lines that contain three consecutive slash marks, any of: 106 | 107 | [source,vim] 108 | ---- 109 | global +///+ delete 110 | 111 | global ;///; delete 112 | 113 | global ]///] delete 114 | ---- 115 | 116 | will be a simpler choice than using slashes as delimiters and backslashing all 117 | three of the slashes you are searching for. (However, using ++!++ as your 118 | delimiter is dangerous, because ++:global++ will mistake your delimiter for 119 | the switch that tells it to find only lines that do not contain the search 120 | pattern. If you do use ++!++ as your delimiter, put a space between it and the 121 | ++:global++ command, as in ++:global !///!++) 122 | 123 | Of course this applies only to the search pattern that goes right after the 124 | ++:global++ command name, the one that says which lines to mark. If you use 125 | any search patterns before the command name, to say which area of the file is 126 | to be searched, then use ++?++ and ++/++ delimiters as usual. 127 | 128 | Global searches that seem senseless can be very useful 129 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 130 | 131 | At times it's wise to have ++:global++ or ++:vglobal++ run a search over just 132 | one line in a file. This is the basis for conditional execution of ex-mode 133 | commands. As a simple example, you may find yourself editing files from 134 | outside your organization that are sometimes (but not always) sent to you with 135 | an extra, empty last line, as a spacer. You need to remove that last line, if 136 | and only if it is empty. You could go to the end of each file and look, but 137 | it's easier to have the editor do the checking and (where necessary) the 138 | deletion, so you type: 139 | 140 | [source,vim] 141 | ---- 142 | $ global /^$/ delete 143 | ---- 144 | 145 | It can also be useful to have ++:global++ mark every line in the area of the 146 | file you tell it to search! Our put-upon programmer, Hal (in the 147 | link:1_editor_fundamentals.html[first installment] of this tutorial) used this 148 | when he had to reverse the order of the lines in one file. His 149 | link:1_editor_fundamentals.html#T1_move[command line], which would look like 150 | this if typed out in unabbreviated form: 151 | 152 | [source,vim] 153 | ---- 154 | global /^/ move 0 155 | ---- 156 | 157 | begins by marking each line that has a start-of-line point, which makes every 158 | line qualify. Next it goes to the first line and moves it up right after the 159 | fictitious line zero -- effectively placing it as the new first line of the 160 | file. But then it moves the second line to the same place, pushing the former 161 | first line down one position in the file. As it does the same with the third 162 | line, the fourth line, etcetera, it's changing the order of the lines to the 163 | exact opposite of the order they were in at the start. 164 | 165 | One :global can run many commands 166 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 167 | 168 | You can put several commands on the line after a ++:global++ command and its 169 | search pattern. After marking the appropriate lines, ++:global++ will then go 170 | to each marked line and run all of the commands you've given it, in the order 171 | you gave them. Just separate these commands with a vertical bar (++|++) 172 | character. If you type: 173 | 174 | [source,vim] 175 | ---- 176 | global /^CHAPTER/ substitute /HAPTER/hapter/ | copy $ 177 | ---- 178 | 179 | the editor will go to each line that starts with a chapter heading, change 180 | ``CHAPTER'' to ``Chapter'', and then copy the line (now beginning ``Chapter'' 181 | instead of ``CHAPTER'') to the end of the file. The order in which you put 182 | those two commands is important -- the substitute command must come first so 183 | the subsequent copy command will copy the decapitalized version of the line, 184 | not the original all-caps version. 185 | 186 | You're not limited to just two commands in a ++:global++ command line; there 187 | is no maximum on the number of commands there. The maximum string length for 188 | the command list varies with the editor version you're using, but I've never 189 | encountered a limit of less then 256 characters. There are a few restrictions 190 | on what the command list can contain, though: 191 | 192 | The global keyword and the following list of commands all must be on one line. 193 | (That is, on one physical line, with no carriage returns in it. If that one 194 | line is too long for your terminal's screen width, the terminal may wrap it 195 | around to occupy two or more lines on your screen, but this will not cause a 196 | problem.) 197 | 198 | The command list cannot include an undo or another :global command 199 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 200 | 201 | If you include a command that escapes to the shell, it must be the last 202 | command on the line. (Putting two or more shell-escape commands in one command 203 | list will not work.) This makes it possible to use pipes (symbolized by the | 204 | character) in your shell-escape command string, without having the editor 205 | mistake the pipe symbol for the separator between two editor commands in your 206 | ++:global++ command line. 207 | 208 | Commands don't have to run on the lines :global marks 209 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 210 | 211 | Using ++:global++ is essentially the same as moving to each marked line 212 | manually, then typing in the command string while you are there. Just as you 213 | no longer expect every command you type in to operate on the line you are on 214 | when you type it, you don't have to have the commands in a ++:global++ string 215 | operate entirely on the marked lines. Here are three points to note regarding 216 | this: 217 | 218 | Any command in a ++:global++ command line can take its own address or 219 | addresses, just as it could if it were typed in as a separate command. So this 220 | command string: 221 | 222 | [source,vim] 223 | ---- 224 | global /^XX/ - copy $ | /ZZ$/ , +5 delete 225 | ---- 226 | 227 | is entirely legitimate. It goes to each line that begins with two capital X's, 228 | then copies the line just before that one to the end of the file, and finally 229 | goes forward to the next line that ends with two capital Z's and deletes that 230 | line and the five lines that follow it. 231 | 232 | anchor:T3_good_write[] 233 | 234 | Even if you give no addresses for the commands in a ++:global++ string, 235 | default addresses for those commands may make them operate on other than the 236 | marked line. That's the fault in link:#T3_bad_write[that ++:global++ command] 237 | string in the introduction to this installment of my tutorial that tries to 238 | write individual lines to another file. Because the default address for the 239 | ++:write++ command is the entire file, this command will write the entire file 240 | the user is editing to the end of the other file, once for every line that 241 | ++:global++ has marked. The correct way to write individual lines is to type: 242 | 243 | [source,vim] 244 | ---- 245 | global /^Chapter [1-9]/ . write >> t.of.contents 246 | ---- 247 | 248 | where the dot address in front of the ++:write++ command tells it to write 249 | only the line it is on. 250 | 251 | But even if you take a command that has the current line as its default 252 | address, and put it in the string following ++:global++ without giving it an 253 | address of its own, it can still operate on different lines from the ones 254 | ++:global++ has marked if it is not the first command in the string. The 255 | reason: __each subsequent command in a ++:global++ takes as the current line 256 | whatever line the command before it left as the current line__. 257 | 258 | In my earlier example about wanting to both change the capitalization of lines 259 | beginning with ``CHAPTER'' and copy those lines to the end of the file, the 260 | task was easy because the lines were to be copied in their changed state. But 261 | what if the user wanted only the lines in the midst of the file decapitalized, 262 | while the ones copied to the end of the file were to remain all-caps? It might 263 | seem obvious to simply reverse the order of the two commands, so the copy 264 | command was executed first, before the substitute command was called to change 265 | the capitalization, like this: 266 | 267 | [source,vim] 268 | ---- 269 | global /^CHAPTER/ copy $ | substitute /HAPTER/hapter/ 270 | ---- 271 | 272 | // TODO: Does the explanation of "the original text block" need a rewrite? 273 | 274 | Surprisingly, that would produce the opposite of the effect that was intended. 275 | That is, it would decapitalize the copied lines at the end of the file, but 276 | leave the marked lines in the midst of the file all-caps. The reason? The copy 277 | command leaves the last line of the copy text block, not the original text 278 | block, as the current line. So after the copy command has run, the substitute 279 | command, using the command's default address (the current line) because it has 280 | not been given an explicit address, would operate on the copy line rather than 281 | the original. 282 | 283 | But there is one thing that no amount of current-line shifting can change. 284 | Wherever in the file the command string may leave the current line, when the 285 | commands have finished running, ++:global++ will go to the next marked line 286 | without fail. The only way any of the commands in the string can prevent this 287 | is by deleting the next marked line -- in that case, ++:global++ will merely 288 | go on to the next marked line that has not been deleted. And even this fact 289 | has uses that might not be obvious. 290 | 291 | Let's say you want to thin out the lines in a file, by deleting every second 292 | line. You can do it by typing: 293 | 294 | [source,vim] 295 | ---- 296 | global /^/ + delete 297 | ---- 298 | 299 | This ++:global++ starts off by marking every line. When it goes to line 1, the 300 | command it executes will delete line 2. The next undeleted marked line is line 301 | 3, where its command deletes line 4, and so on. Or if you want to delete 302 | two-thirds of the lines in your file, type: 303 | 304 | [source,vim] 305 | ---- 306 | global /^/ + , ++ delete 307 | ---- 308 | 309 | Keeping Count 310 | ~~~~~~~~~~~~~ 311 | 312 | At times it's a good idea to follow ++:global++ with a string of commands that 313 | have absolutely nothing to do with the lines that ++:global++ has marked. The 314 | most common occasion for this comes when you need to repeat an ex-mode command 315 | a certain number of times. 316 | 317 | // TODO: upgrade this dinosaur story to the modern day? 318 | 319 | At tradeshows I'm often invited to test a system right there on the show 320 | floor. I can't carry a 10,000-line test file along with me in every media and 321 | format any system might require, so I type in a ten-line file on the spot and 322 | expand it by telling the editor ten times to make a copy of the entire file 323 | and put that copy at the end of the present file. (Each such copy doubles the 324 | file's size, so I wind up with 10,240 lines.) 325 | 326 | But that requires accurate counting. If I'm off by even one on the number of 327 | times I type that command in, I get a half-size or double-size file that ruins 328 | my test results. Instead of trying to count without an error, I let the editor 329 | do the counting for me. After I've typed in the initial ten lines, I give one 330 | ++:global++ command: 331 | 332 | [source,vim] 333 | ---- 334 | global /^/ % copy $ 335 | ---- 336 | 337 | This tells the editor to search the ten lines of the file, mark every line 338 | that has a start-of-line (which means every line, of course), and then go to 339 | each of those ten lines and run the subsequent command to make a whole-file 340 | copy. This guarantees that the command will run exactly ten times. 341 | 342 | Not that this trick is limited to files that have exactly as many lines as the 343 | number of times I want the command to be repeated. If I had typed in a 344 | twenty-line file, I could copy it ten times by giving my ++:global++ as: 345 | 346 | [source,vim] 347 | ---- 348 | 1 , 10 global /^/ % copy $ 349 | ---- 350 | 351 | Moving Around Automatically 352 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~ 353 | 354 | At times you may need to handle a series of editing problems in a file, where 355 | the edits must be dealt with one by one, not with a ++:global++ editing 356 | script. But moving to each spot where work needs to be done can be a very 357 | tedious business. If there is a text pattern that identifies each place that 358 | needs editing, or if you can write a script to insert such a pattern, as Hal 359 | did at the start of this tutorial's link:1_editor_fundamentals.html[first 360 | installment], then ++:global++ can move you around automatically. 361 | 362 | You may recall that Hal used a script to mark up the legacy source code, 363 | putting each lint warning at the end of the source line to which it referred, 364 | preceded by ``XXX'' to make the affected lines identifiable. Suppose that the 365 | nefarious Vice President for Information Systems comes back to Hal to demand 366 | that each warning be investigated, to see whether the code can be rewritten to 367 | eliminate the warning. 368 | 369 | Should Hal just leaf through the code, searching for ``XXX'' patterns to guide 370 | him to the trouble spots? Hal knows that with the spaghetti code he's facing, 371 | the actual problem may be a long way from the line lint has designated. In 372 | travelling to the actual trouble spot he may have passed several ``XXX'' 373 | patterns along the way, so searching for the next ``XXX'' in the file may 374 | bring him to a site he's already dealt with, or may miss a number of ``XXX'' 375 | sites that he passed when he moved forward to get to the actual problem spot 376 | on the previous fix. Besides, because he frequently does pattern searching 377 | while fixing a problem, he can't depend on a normal-mode ++n++ command to use 378 | the ``XXX'' pattern he needs to find; he must type the pattern in afresh each 379 | time. 380 | 381 | But Hal knows a way around all this -- dropping back to ex mode (by typing a 382 | capital letter ++Q++ from normal mode) and giving a simple ++:global++ 383 | command: 384 | 385 | [source,vim] 386 | ---- 387 | global /XXX/ visual | write 388 | ---- 389 | 390 | This command brings Hal to the first ``XXX'' line, where it puts him into 391 | normal mode to do his editing. When the edit is finished, Hal simply types a 392 | capital letter ++Q++ and the editor takes him to the second ``XXX'' line and 393 | puts him into normal mode there, no matter how much moving around Hal did 394 | during the first edit, and so on through the list of ``XXX'' lines. As 395 | frosting on the cake, the write command automatically writes the changed file 396 | to disk after each individual edit. 397 | 398 | NOTE: Some people have replaced the seemingly useless ++Q++ key with the map 399 | ++:nnoremap Q gqap++ which reformats a paragraph of text. If your ++Q++ key 400 | doesn't do as Hal's does above, you might need to ++:nunmap Q++ first. 401 | 402 | Now You Give it a Try 403 | --------------------- 404 | 405 | Here are a few exercises you can try to solve, before you start using advanced 406 | ++:global++ tactics in your own editing. To keep things rolling I've provided 407 | at least one solution to each exercise, and also a hint on the last (and 408 | toughest) problem. 409 | 410 | anchor:E3.1[] 411 | 412 | .Exercise 3.1 : Copy and Decapitalize 413 | 414 | Let's think back to the user who wanted to find each line in the file that 415 | begins with ``CHAPTER'', then copy each such line to the end of the file just as 416 | it is, and finally change the start of each original line (in mid-file) from 417 | "CHAPTER" to "Chapter" while leaving the copied lines (at the end of the file) 418 | beginning "CHAPTER". 419 | 420 | We've already learned that this cannot be done with either of: 421 | 422 | [source,vim] 423 | ---- 424 | global /^CHAPTER/ substitute /APTER/apter/ | copy $ 425 | 426 | global /^CHAPTER/ copy $ | substitute /APTER/apter/ 427 | ---- 428 | 429 | What ++:global++ command (or commands) would it take to do what's desired 430 | here? Finding a solution to this is not difficult when there are so many 431 | workable ones. 432 | 433 | link:3_global_command_solutions.html#S3.1[Solution 3.1] 434 | 435 | anchor:E3.2[] 436 | 437 | .Exercise 3.2 : A Precise String Length 438 | 439 | An old friend who does some pretty tricky work with troff often needs to 440 | insert a string of backslashes in a line -- up to 64 of them in a row. The 441 | count of backslashes must be exactly right or troff will choke. How can he 442 | get these strings exactly right without tedious counting and checking? 443 | 444 | Let's say he needs to put 16 backslashes in line 217, right before the string 445 | "n(PDu". What command(s) should he use to get them in there without hand 446 | counting. My solution is pretty plain once you know which commands to use. 447 | 448 | link:3_global_command_solutions.html#S3.2[Solution 3.2] 449 | 450 | anchor:E3.3[] 451 | 452 | .Exercise 3.3 : Numbering Paragraphs 453 | 454 | A documentation writer has divided each section of a document into paragraphs, 455 | and as a troff user, marks the start of each paragraph by a line that contains 456 | the macro ".pp" only. That is, a break between paragraphs looks like this: 457 | 458 | .... 459 | which is the only way that argon gas can be dissolved 460 | 461 | in this liquid. 462 | 463 | .pp 464 | 465 | The problem of energizing the 466 | 467 | argon to fluorescence while 468 | 469 | it is dissolved was first approached by applying a strong 470 | .... 471 | 472 | How can this tech writer use the vim editor to number the paragraphs in each 473 | section? (If this seems far-fetched to you, consider that I once got a phone 474 | call from a Unix guru asking how to do just this.) To keep the problem simple, 475 | let's say that there are never more than 35 paragraphs in a section, and that 476 | they should be numbered with Roman numerals. 477 | 478 | This problem is still difficult enough that I'm offering you two hints. The 479 | first is that ++:global++ is essential here. Look at the second hint only if 480 | you're about to give up and check my solution. 481 | 482 | .Hint 2 483 | 484 | My solution to this problem has an intermediate stage in which each macro is 485 | followed by a string of capital I letters on the same line. The count of the 486 | capital I letters on any macro line is equal to the paragraph number. That is, 487 | the macro line for the fifth paragraph looks like this in the intermediate 488 | stage: 489 | 490 | .... 491 | .ppIIIII 492 | .... 493 | 494 | link:3_global_command_solutions.html#S3.3[Solution 3.3] 495 | 496 | Coming Up Next 497 | -------------- 498 | 499 | In the link:4_substitute_command.html[next part] of this tutorial, I'll cover 500 | the less-known aspects of the other ex-mode commands for dealing with text and 501 | files. If you're a little overwhelmed with all that I've said about 502 | ++:global++ you'll be pleased to know that ++:substitute++ is notably simpler, 503 | and all the remaining commands are very much simpler, than ++:global++. 504 | 505 | After that, future parts of this tutorial will deal with normal mode; easier 506 | and more fun than ex mode any day. 507 | 508 | // vim: set ft=asciidoc tw=78: 509 | -------------------------------------------------------------------------------- /vimmified/3_global_command_solutions.txt: -------------------------------------------------------------------------------- 1 | The Global Command 2 | ================== 3 | Walter Alan Zintz 4 | 5 | Solutions to Exercises 6 | ---------------------- 7 | 8 | // TODO: folding the actual solutions in a clickable reveal would be nice. 9 | 10 | anchor:S3.1[] 11 | 12 | Solution 3.1 13 | ~~~~~~~~~~~~ 14 | 15 | link:3_global_command.html#E3.1[Question] 16 | 17 | 18 | One solution to this problem is to ++:mark++ (here with named mark 19 | ``a'') each mid-file occurrence of ++^CHAPTER++ before we copy it to 20 | the end of the file. We can then use the marked line address ++ 'a ++ 21 | with the ++:substitute++ command to change the mid-file occurrence to 22 | lower case: 23 | 24 | [source,vim] 25 | ---- 26 | global /^CHAPTER/ mark a | copy $ | 'a substitute /HAPTER/hapter/ 27 | ---- 28 | 29 | Another solution doesn't use a register, but copies the found 30 | ++^CHAPTER++ line to the next line (after the current line: `copy .`), 31 | lower cases the previous line (the replace pattern is `\L&`, meaning 32 | make lower-case all the rest, which is `&` — the whole match), and 33 | finally moves the original, duplicated line to the end: 34 | 35 | [source,vim] 36 | ---- 37 | global /^CHAPTER/ copy . | - substitute /HAPTER/\L&/ | + move $ 38 | ---- 39 | 40 | 41 | anchor:S3.2[] 42 | 43 | Solution 3.2 44 | ~~~~~~~~~~~~ 45 | 46 | link:3_global_command.html#E3.2[Question] 47 | 48 | Using a line range that yields 16 lines in a ++:global++ command runs 49 | its ++:substitution++ command 16 times, even when the range of the 50 | ++:substitution++ command is fixed to one line (217). Each time it 51 | inserts a single backslash. (The double backslash in the replacement 52 | pattern is necessary because the backslash is a special character even 53 | there.) 54 | 55 | [source,vim] 56 | ---- 57 | 1 , 16 global /^/ 217 substitute /n(PDu/\\&/ 58 | ---- 59 | 60 | [NOTE] 61 | ==== 62 | The ++&++ character used in the replacement pattern expands to the 63 | entire match found by the search pattern. 64 | 65 | Also, this solution suffers from the necessity that there *be* at 66 | least 16 lines in the file. 67 | ==== 68 | 69 | 70 | anchor:S3.3[] 71 | 72 | Solution 3.3 73 | ~~~~~~~~~~~~ 74 | 75 | link:3_global_command.html#E3.3[Question] 76 | 77 | The paragraphs can be numbered with just two global commands. The 78 | first one: 79 | 80 | [source,vim] 81 | ---- 82 | global /^\.pp/ . , $ substitute //&I/ 83 | ---- 84 | 85 | goes to each line beginning with a start-of-paragraph macro, then runs 86 | a substitute command from that line through the end of the file that 87 | puts a capital letter I after each such macro. So the substitute 88 | command that runs from the first marked line puts an I after every one 89 | of the macros; from the second marked line it puts an I after every 90 | such macro except the first; from the third marked line it puts an I 91 | after every such macro except the first and the second; and so on. 92 | Thus, after this global finishes, you have a string of the letter I 93 | after every macro that is equal in number to the paragraph's number. 94 | That is, after the macro for the third paragraph you have the string 95 | "III"; after paragraph 5 you have the string "IIIII"; etcetera. 96 | Already you have Roman numerals (of a very primitive sort) numbering 97 | the paragraphs. A second global command puts those Roman numerals into 98 | canonical form: 99 | 100 | [source,vim] 101 | ---- 102 | global /^\.pp/ substitute /IIIII/V/g | substitute /VV/X/g | substitute /IIII/IV/ 103 | ---- 104 | 105 | NOTE: As you'll learn in the next installment of this tutorial, a 106 | lower-case letter g at the end of a substitute command tells the 107 | editor to perform the substitution as many times as it can on each 108 | line. 109 | 110 | To see how our second global command sets things right, consider the 111 | case of the 19th paragraph. The next four lines show what the macro 112 | line looks like at the start of the command and how it has changed 113 | after each of the three substitute commands has done its work: 114 | 115 | .... 116 | .ppIIIIIIIIIIIIIIIIIII 117 | .ppVVVIIII 118 | .ppXVIIII 119 | .ppXVIV 120 | .... 121 | 122 | NOTE: Astute readers will realize that the paragraphs could have been 123 | numbered with just one global command. Each macro line has all the 124 | capital I letters it will get before global leaves it for the next 125 | line. So we could have had the command string start by marking the 126 | line, next run the substitution that adds a capital I to all remaining 127 | macro lines, then return to the line and run the substitutions that 128 | produce a true Roman numeral. Bonus points for actually trying this. 129 | 130 | -------------------------------------------------------------------------------- /vimmified/4_substitute_command_solutions.txt: -------------------------------------------------------------------------------- 1 | The Subtle Substitute Command 2 | ============================= 3 | Walter Alan Zintz 4 | 5 | Solutions to Exercises 6 | ---------------------- 7 | 8 | // TODO: folding the actual solutions in a clickable reveal would be nice. 9 | 10 | anchor:S4.1[] 11 | 12 | Solution 4.1 -- Substituting the second-to-last element on a line 13 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 14 | 15 | link:4_substitute_command.html#Q4.1[Question] 16 | 17 | When there are two or more wild cards in a search pattern, Vim finds 18 | the longest match for the first one that allows any match for the 19 | subsequent ones, and so on. 20 | 21 | [source,vim] 22 | ---- 23 | % substitute /\(.*\)k37\(.*k37\)/\1q53\2 24 | ---- 25 | 26 | 27 | anchor:S4.2[] 28 | 29 | Solution 4.2 -- Setting a line to Title Case 30 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 31 | 32 | link:4_substitute_command.html#Q4.2[Question] 33 | 34 | Because the original lines could be any mix of case, we have to 35 | capture and operate on each word. Because we want the first letter to 36 | be upper-case and the rest of the letters in the word to be 37 | lower-case, we capture them separately and operate on them in the 38 | replacement part as ++\1++ and ++\2++ respectively. Recall that ++\u++ 39 | operates on the following letter whereas ++\L++ operates on the 40 | following word. 41 | 42 | [source,vim] 43 | ---- 44 | 237 , 289 substitute /\(\w\)\(\w\+\)/\u\1\L\2/g 45 | ---- 46 | 47 | If you're just changing an all lowercase line into Title Case, the 48 | substitution is much simpler: 49 | 50 | [source,vim] 51 | ---- 52 | 237 , 289 substitute /\<\w/\u&/g 53 | ---- 54 | 55 | So, an alternative way to Title Case a line without using explicit 56 | capture: 57 | 58 | [source,vim] 59 | ---- 60 | 237 , 289 global /./ substitute /.*/\L&/ | s/\<\w/\u&/g 61 | ---- 62 | 63 | 64 | anchor:S4.3.1[] 65 | 66 | Solution 4.3 -- Substituting the third element in a line of many 67 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 68 | 69 | 1. Deleting The Third Column 70 | + 71 | link:4_substitute_command.html#Q4.3[Question] 72 | + 73 | We use ++\zs++ to focus the match within the search part 74 | of a substitution while using the patterns outside of these markers as 75 | anchors. Assuming you've visually selected the lines you want to 76 | operate on, the following substitute will delete column 3 from all 77 | rows: 78 | + 79 | [source,vim] 80 | ---- 81 | '< , '> substitute /\(\d\+,\s*\)\{2}\zs\d\+,\s*// 82 | ---- 83 | + 84 | The ++\{2}++ notation is Vim's way of requiring two repetitions of the 85 | previous element, which in this case is a number followed by a comma 86 | -- effectively stepping past the first two columns. We then start our 87 | match with ++\zs++, restricting it to only the third column. 88 | + 89 | anchor:S4.3.2[] 90 | + 91 | 2. Doubling The Numbers In The Third Column 92 | + 93 | link:4_substitute_command.html#Q4.3[Question] 94 | + 95 | [NOTE] 96 | ==== 97 | Read the Substitute With An Expression section if you don't know how 98 | to approach this problem. 99 | ==== 100 | + 101 | Much the same approach is taken in the search side of the substitute 102 | to narrow our search down to just column three -- however because this 103 | time we want to double the numbers and not delete the whole column, 104 | we're narrowing down even more to just the numbers themselves. The 105 | replacement needs to be an expression so we enter expression mode by 106 | starting the replacement string with the ++\=++ special. Within a 107 | replacement expression, we use ++submatch(1)++ to refer to the first 108 | captured text in the match (what ++\1++ would ordinarily give us, but 109 | which can't be used inside an expression replacement.) 110 | + 111 | [source,vim] 112 | ---- 113 | '< , '> substitute /\%(\d\+,\s*\)\{2}\zs\d\+/\=submatch(0)*2/ 114 | ---- 115 | + 116 | We use the non-capturing ++\%(...\)++ group in the column skip section 117 | to make the replacement clearer -- ++submatch(0)++ now refers to 118 | column three which starts after the ++\zs++ marker. Non-capturing 119 | groups are slightly more efficient, but I usually use them to reduce 120 | confusion, as shown in this example. 121 | 122 | 123 | anchor:S4.4[] 124 | 125 | Solution 4.4 -- A Seemingly Useless Substitution 126 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 127 | 128 | link:4_substitute_command.html#Q4.4[Question] 129 | 130 | So, what does this seemingly useless substitute do? 131 | 132 | [source,vim] 133 | ---- 134 | % substitute /^$ 135 | ---- 136 | 137 | It counts the number of blank lines in your file. That might still 138 | sound useless to you, unless you always separate your paragraphs with 139 | a single blank line. Now you know how many paragraphs you've written! 140 | 141 | anchor:S4.5.1[] 142 | 143 | Solution 4.5 -- Avoiding Duplicating HTML Paragraph Tags 144 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 145 | 146 | 1. Using Multiple Simple Substitutions (Bottom-Up Approach) 147 | + 148 | link:4_substitute_command.html#Q4.5[Question] 149 | + 150 | Where the substitution command to add a tag at the start of a 151 | paragraph presently removes and then replaces any first character on 152 | the line, now it should remove and replace anything except a ``<'' 153 | character in that position. If that first character is a ``<'' it is 154 | necessary that the substitution command fail so it will change 155 | nothing. To arrange this, replace that period in the search pattern 156 | with a negative character class -- ++[^<]++ -- which matches any 157 | character except the one that begins every HTML tag. Similarly, 158 | replace the period in the other substitution pattern with the negative 159 | character class that matches any character except the one that always 160 | ends an HTML tag. Now the two commands will look like this: 161 | + 162 | [source,vim] 163 | ---- 164 | global /^$/ + substitute /^[^<]/

&/ 165 | global /^$/ - substitute :[^>]$:&

: 166 | ---- 167 | + 168 | anchor:S4.5.2[] 169 | + 170 | 2. Using A Single Complex Substitution 171 | + 172 | link:4_substitute_command.html#Q4.5[Question] 173 | + 174 | Perhaps now you'll appreciate the simplicity of using bottom-up 175 | techniques to break complex edits down into multiple simpler 176 | substitutions. 177 | + 178 | [source,vim] 179 | ---- 180 | % substitute /.\(<.\+>\)\@\)\@!/<\/p>&

/ 181 | ---- 182 | -------------------------------------------------------------------------------- /vimmified/Makefile: -------------------------------------------------------------------------------- 1 | INPUT_FILES = 1_editor_fundamentals.txt 2_line_addresses.txt 2_line_addresses_solutions.txt 3_global_command.txt 3_global_command_solutions.txt 4_substitute_command.txt 4_substitute_command_solutions.txt 2 | HTML_DIR = html 3 | HTML_FILES = $(addprefix html/,$(INPUT_FILES:txt=html)) 4 | ETC_ASCIIDOC_ICONS = /etc/asciidoc/images/icons/ 5 | SHARE_ASCIIDOC_ICONS = /usr/share/asciidoc/images/icons/ 6 | ifneq "$(wildcard $(ETC_ASCIIDOC_ICONS) ])" '' 7 | ICONS_DIR = $(ETC_ASCIIDOC_ICONS) 8 | else 9 | ifeq "$(wildcard $(SHARE_ASCIIDOC_ICONS) ])" '' 10 | $(error Missing $(ETC_ASCIIDOC_ICONS) and $(SHARE_ASCIIDOC_ICONS)) 11 | endif 12 | ICONS_DIR = $(SHARE_ASCIIDOC_ICONS) 13 | endif 14 | 15 | .PHONY: all html5 clean 16 | 17 | all: demand_pygments html5 18 | 19 | html5: $(HTML_FILES) 20 | 21 | $(HTML_DIR): 22 | mkdir $(HTML_DIR) 23 | 24 | html/%.html: %.txt 25 | asciidoc -v -b html5 \ 26 | -a toc2 \ 27 | -a toclevels=3 \ 28 | -a icons \ 29 | -a iconsdir=$(ICONS_DIR) \ 30 | -a theme=flask \ 31 | -a data-uri \ 32 | -a pygments \ 33 | -o $@ \ 34 | $< 35 | 36 | demand_pygments: 37 | @type pygmentize >/dev/null 38 | 39 | clean: 40 | rm -fr $(HTML_DIR) 41 | 42 | # vim: set noet tw=80: 43 | -------------------------------------------------------------------------------- /vimmified/images/hal_deletes_managers.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dahu/vim_waz_ere/ccfb0f19fcba9954764a4429277bfbd473221ca8/vimmified/images/hal_deletes_managers.png -------------------------------------------------------------------------------- /vimmified/images/slimy_vp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dahu/vim_waz_ere/ccfb0f19fcba9954764a4429277bfbd473221ca8/vimmified/images/slimy_vp.png --------------------------------------------------------------------------------