import { addBanner, addArticle, addTitle, addHeader, addParagraph, addClassParagraph, addSubHeader, addOrderedList, addUnorderedList, addBlockquote, addInset, addInsetList, addInsetCodeListing, addInsetBulletList, addImageWithCaption, addButtonGroup, addSidebar, addSyntax, menu, global_menu, addTable } from '/scripts/import.js'; import { local_menu } from '/scripts/webdev.js'; const heading = document.querySelector(".heading"); const global = document.querySelector(".global_menu"); const local = document.querySelector(".local_menu"); const sidebar = document.querySelector(".sidebar"); const main = document.querySelector(".main_content"); heading.append(addTitle("Learning Vi")); heading.append(addParagraph("David D. Levine - LinkedIn Learning - April 2014")); heading.append(addParagraph("Chapter 2 - Getting Started with vi")); main.append(addHeader("Entering and Leaving vi")); main.append(addParagraph("You invoke vi/vim by typing vi or vim followed by the name of the file you want to edit. As we saw in the previous chapter, these names are almost entirely interchangeable these days so to avoid complicating things, for the rest of the course, I will just use one name at a time but I will use both to emphasise the fact that for most people, they are the same. The command might look something like this:")); main.append(addSyntax("vi myfile.txt")); main.append(addParagraph("The filename is optional and if you leave it out, you will invoke the editor without a filename so if you then try to write the file, you might see an error as shown in figure 2.")); main.append(addImageWithCaption("./images/figure2.png", "Figure 2 - the error you see when saving a file without a filename.")); main.append(addParagraph("If you need to edit a file that doesn't exist yet, you can simply invoke vi with the name of the file you want to create")); main.append(addSyntax("vim newfile.txt")); main.append(addParagraph("This will have the effect of opening the editor in the same way that you see with only the vi command but it tells the editor what file name you want to save it as so if you try to save the file in the same manner as that shown in fgiure 2, vi will save it as newfile.txt or whatever filename you provided.")); main.append(addParagraph("Using :wq is probably the most common way to save the file and exit but you can also do that (in command mode) by tying ZZ or shift zz.")); main.append(addParagraph("The :wq is often that of as being a command performed in command mode but this is actually a different mode as we will see later and both the w and the q are separate commands and can be used individually. The w command will write the file and you can also add a filename. This would allow you to save the file if you invoked the editor with vi or will allow you to save the file with a different name (effectively saving it to a different file) is you had invoked the editor with a filename but don't want to save to that file. Similary, you can quit without saving with only ther q if there are no changes to the file.")); main.append(addParagraph("If there are changes to the file and you want to add the ! character so q! will quit and discard changes. This is often thought of as a command to ignore errors which generally a useful interpretation for practical purposes but it is actually a force option so it will force an exit (in this case) even if the file hasn't been saved.")); main.append(addHeader("Understanding vi's Modes")); main.append(addSubHeader("Command Mode")); main.append(addParagraph("When you start vi, it starts in command mode. Whatever you type whilst in command mode is interpreted as a command. It is in command mode that you type commands like :w to write the file or dd to delete a line.")); main.append(addSubHeader("Insert Mode")); main.append(addParagraph("When you invoke insert mode, characters you type are interpreted as a text. You would invoke insert mode in order to edit the file. You can type any of the characters i, a, o or c to go into insert mode and they all behave in slightly different ways.")); main.append(addSubHeader("i or I")); main.append(addParagraph("If you enter insert mode by pressing i, you can then start inputting text from the current cursor position.")); main.append(addSubHeader("a or A")); main.append(addParagraph("If you type an A, this starts inputting text from the end of the current line. A lower case a will invoke insert mode but will start editing text after the current character.")); main.append(addSubHeader("o or O")); main.append(addParagraph("Either o or O will insert a new line and allow you to start editing the text from there. The difference is that o inserts the new line after the current line whereas O inserts the new line before the current line.")); main.append(addSubHeader("c or C")); main.append(addParagraph("Either c or C will also starting editing om a new line, but will delete the current line and start editing from there.")); main.append(addParagraph("While you are in insert mode, you can return to command mode by pressing escape.")); main.append(addSubHeader("Ex Mode")); main.append(addParagraph("Ex mode is sometimes called prompt mode and it is invoked in command mode by pressing one of :, / or ? and is followed by a command or a parameter. We have already seen some examples of this, for instance with the command to write a file which was :w. Essentially Ex mode allows you to specify a command with : and either / or ? allows you to perform a search. You would use the / command to search forwards in the file so it will find the first instance of your search term after the current cursor position. The search will wrap around so if there is only one instance of the search term and it happens to occur before the current cursor position, the search will still find it!")); main.append(addParagraph("With the ? you can search backwards and the same applies in that the search will wrap around if the search term isn't found befure the current cursor position.")); main.append(("If the search term is found, you can press n for next to find the next instance (if there is another instance) and it searches in the same direction so if you searched using the / character, n will find the next instance later in the file and if you searched with ?, it will find he next instance earlier in the file and again, this will wrap around.")); main.append(addHeader("Using vi in a Terminal Emulator Window")); main.append(addParagraph("It is worth remembering that vi was written for use on a physical terminal with a fixed number of rows and columns and this can lead to some weird effects when you run it in a terminal emulator. For example, you can't scroll the window in a terminal, but you can in a terminal emulator. This means that you can scroll vi completely off the screeen but you can get it back with control + L (the L in this instance is not case sensitive so l would work too). Alternatively, you can use any movement key such as an arrow key, page up or down or any of the movement keys we will see later.")); main.append(addParagraph("Another thing that you can do in a terminal emulator that wasn't possible with a physical terminal is that you can resize the window and that can also produce some strange effects. It's worth remembering that vi is a line based editor but because of the nature of a terminal with it's fixed size, a line is not quite the same thing as a line in, for instance, a word processor or a web browser. In a web browser, a loose definition of a line is the amount of text that can be fitted into the browser viewport without needing to wrap it around to the next line but that will change as the size of the viewport changes. This means that the number of characters on each line is going to vary.")); main.append(addParagraph("In a terminal, because the text occupies the full screen and has a fixed number of columns, the number of characters per line is constant. If you open up a terminal on a Linux (or Windows if you are using a Linux shell with the WSL), vi is a little bit like a cross between the two. The number of characters per line is fixed but the text will still wrap around to the next line in your window. However, the position of the end of the line, relative to the whole line, does not change and the consequence of this is that we have two different representations of a line.")); main.append(addParagraph("The first is the most obvious, a line being defined as a a series of characters that starts at one end of the screen (or window) or at the end of the line. You can see this in figure 3 where each line has 210 characters and to make it easier to see any changes, there are 5 lines and each one has a number from 1 to 5 at the end.")); main.append(addImageWithCaption("./images/figure3.png", "Figure 3 - The file with 5 lines.")); main.append(addParagraph("In this case, there isn't really any ambiguity because the screen is wide enough to accomodate each of the lines but what do you think we would see (what would the file look like if window was reduced in size and could only accomodate 80 characters per line)? This is shown in figure 4.")); addSidebar("linux"); sidebar.append(addParagraph("A link to this course.")); sidebar.append(addParagraph("A handy downloadable vim cheat sheet from PhoenixAP.com."));