We couldn't find that page... Did you mean one of these?

Lua is a lightweight, cross-platform, high-level programming language that has become increasingly-popular as an embedded scripting language. Lua is often praised as a clean, simple, easy to learn scripting language that is applicable to a wide range of tasks. Today Lua can be found in a wide range of applications ranging from wezterm to xplr and neovim . Let's get started.
What is a Terminal?
Much of the terminology used when discussing modern terminals comes from history, which can make understanding terminals seem more confusing than it should be. A small amount history can help provide some background information to help some of the concepts be more relatable. Early computers were comprised of multiple refrigerator-sized cabinets, each of which performed one of the basic tasks of the system. For example, one cabinet would contain the " central processing unit " (CPU), while other cabinets held tape drives , disk drives , punched-card readers , a line printer , and any other peripherals that were available to the computer. The user-interface to these computers consisted of a keyboard and some means of displaying the output from the computer, such as a sequence of light bulbs or later a Cathode-ray Tube (CRT) display , connected to the computer via cables. The user-interface was typically arranged into a " console ", where the operator could sit and interact with the computer. Since the user-interface represented the point at which electrical signals "enter" and "exit" the network, the user-interfaces themselves became known as " terminals ". Standardization As often happens in technology development, there were initially a wide range of competing technologies, but over time market forces and economies of scale led these competing technologies to converge towards standardization around a handful of those technologies, the names of which have become much of the jargon that surrounds the terminal today. Early terminals were electro-mechanical "Teletype writers", generally shortened to " TTY ", which is a term still used today when interacting with the terminal. As with a modern keyboard, each key on the TTY represented a human-readable character such as a letter, number, punctuation, etc. As the user would press a key to input data into the computer, each key would be " encoded " into a sequence of 8 1s and 0s called bytes , which could be understood by the computer. These bytes were sent over the cable to the CPU, which performed the requested operations, then the resulting byte(s) were transmitted back to the terminal where they were "decoded" back into characters for human-consumption. The rules used for encoding and decoding each character eventually became the ASCII standard. Despite the benefits of standardization, the ASCII standard was written to support US English, which led to several extensions in order to support other languages, which eventually led to the UTF-8 standard which unified the various extensions into a single encoding that is broadly in use today. Over time display technologies evolved which led to the introduction of "video terminals" (VT) which allowed text and other graphical information to be displayed on a screen. Some of the most popular video terminals were the VT100 and later VT200 series, which introduced support for the ANSI escape codes that have become standards that are still in use today. Emulation As microprocessor technology advanced and the cost of memory and other peripherals dropped, terminals began to handle increasingly-advanced operations, which led to the introduction of " intelligent terminals ", which differentiated them from the "dumb terminals" they replaced. In order to make the newer terminals " backward compatible " with existing software, these terminals included hardware to " emulate " the older devices. Over time the emulation functions were implemented in software, which eventually led to the introduction of fully-software " terminal emulators " that could offer features that would have been difficult to impossible to implement in hardware, such as command-line completion and syntax highlighting . With the introduction of terminal emulators, "the terminal" became a software window that is opened in order to gain access to the operating system . The software that provides this access is called "the shell", which is the subject of the next section.
Match Boundaries
By default, when a pattern matches a string the entire match is returned. For example, suppose we have a buffer that contains a number of dates: Initial Conditions 2 022-01-14 2022-07-09 2022-10-23 2022-12-20 2023-01-26 2023-03-17 2023-08-06 2023-11-05 COMMAND Top 1:1 /2022-1\d-\d\d Suppose we wanted to edit all dates that occur in Q4 (months 10, 11, and 12) of 2022. Our first thought might be to define capturing groups then use back-references to search and replace to make the necessary edits. This is a great solution when the edits are well-defined, but this hypothetical scenario requires us to manually-edit the dates. Our next thought might be to search for all dates that meet these constraints with a pattern such as: 2022-1\d-\d\d Search with generic pattern 2 022-01-14 2022-07-09 2 022-10-23 2022-12-20 2023-01-26 2023-03-17 2023-08-06 2023-11-05 NORMAL 33% 3:1 then jump to a result, move the cursor to the month and day, make the necessary edits, then repeat the search for each match. This works, but can be improved. Our pattern matches to correct lines, but returns the entire date when we only want the month and date. This is a good use-case for adding match boundaries . At a high-level, match boundaries break the searching process up into two steps: The entire pattern is used to define which text to matched, then The match boundaries define which portion of the matched text to return Match boundaries are defined using one or both of the following markers: Shortcut Definition \zs Defines where the matched text will start \ze Defines where the matched text will end When \zs is present, the match will start with the character immediately to the right of it. Likewise, when \ze is present, the match will end with the character immediately to the left of it. Back to our example, our current pattern does a good job of matching the correct lines in the buffer, we just need to isolate the match to the month and date. This can be done by defining the starting boundary: 2022-\zs1\d-\d\d and executing the search again: Search with start boundary 2 022-01-14 2022-07-09 2022- 1 0-23 2022- 12-20 2023-01-26 2023-03-17 2023-08-06 2023-11-05 NORMAL 33% 3:6 Now, when we just from match to match to make our edits, we are already in the correct location. Pretty cool. To extend the example, let's add an ending boundary to isolate only the month portion of the date: 2022-\zs1\d\ze-\d\d and execute again: Search with start and end boundaries 2 022-01-14 2022-07-09 2022- 1 0 -23 2022- 12 -20 2023-01-26 2023-03-17 2023-08-06 2023-11-05 NORMAL 33% 3:6 Match boundaries provide an extra degree of freedom that can be leveraged in some cases, such as this.
Control Structures
Lua implements several of the basic control structures that might be expected in a programming language. Here is a quick summary of the available options, then we will get into the details in the coming sections: Control Type Structure Conditional If-Then Condition-controlled Loop While Condition-controlled Loop Repeat Count-controlled Loop Numeric For Collection-controlled Loop Generic For
Words and other sequences of characters are represented by strings . Lua strings are immutable , meaning that they cannot be modified after they are created. Changing a string requires creating a new string that consists of the characters of the previous string , plus whatever changes are desired. We will learn more about this when we look at string buffers in the Strings chapter. Lua strings are defined by a sequence of characters contained in: Double quotes Single quotes Double square brackets The characters of strings defined with either single or double quotes must exist on a single line, while those in strings defined with brackets can be on multiple lines. Strings defined with single and double quotes are equivalent, and both types of quotes are supported so that quote characters can be included in strings themselves. print ( "this 'contains' quotes'" ) print ( 'this "also" contains quotes' ) The following compares strings defined with quotes vs brackets: -- single or double quotes print ( "this is a string" ) print ( "this is a \n multi-line string" ) -- square brackets print ( [[this is a string]] ) print ( [[this is a multi-line string]] ) Note that the quoted multi-line string definition included a \n at the point where the string broke between lines. This is called an escape character (sometimes also called an "escape sequence" or simply "escapes"), which is the topic of the next section.
Up to now we have reviewed many ways to navigate through a document, from simple cursor movements, to paging, to text objects. Vim also provides the ability to search a buffer for specific text or a pattern for desired text, then quickly navigating through matching text. Searching forward The first search operator we will look at it / , which searches the buffer forward from the current cursor location. Starting from the following buffer: Initial Conditions 1 . Beautiful is better than ugly. 2. Explicit is better than implicit. 3. Simple is better than complex. 4. Complex is better than complicated. COMMAND Top 1:1 /comp Initiate the search by typing / , followed by the text you want to search for, then finally hit enter to start the search. Search forward 1 . Beautiful is better than ugly. 2. Explicit is better than implicit. 3. Simple is better than c omplex. 4. Complex is better than complicated. NORMAL 60% 3:26 Vim found the text, and moved the cursor forward to the start of the first match. Since there are often multiple matches, Vim provides a shortcut command for repeating a search. To repeat the search, hit n . Repeat the previous search n 1. Beautiful is better than ugly. 2. Explicit is better than implicit. 3. Simple is better than c omplex. 4. Complex is better than c omplicated. NORMAL 80% 4:27 Repeating the search moves the cursor to the location of the next matching text. The cursor is now at the last match, what happens if we repeat the search once more? Repeat again n 1. Beautiful is better than ugly. 2. Explicit is better than implicit. 3. Simple is better than c omplex. 4. Complex is better than c omplicated. NORMAL 60% 3:26 search hit BOTTOM, continuing at TOP When Vim is not able to find matching text, it "wraps around" to the top of the buffer and continues the search. In this example there are only two matches in the document, so the cursor returns to the first match. Searching backward Searching backward uses the ? operator, but otherwise operates the same as searching forward: Search backward 1. Beautiful is better than ugly. 2. Explicit is better than implicit. 3. Simple is b etter than c omplex. 4. Complex is better than complicated. NORMAL 60% 3:14 The n also works when searching backward, and like most operators this shortcut accepts a count . To move the cursor to the "second next match", precede the operator with a count of 2: Repeat search with count 2n 1. Beautiful is b etter than ugly. 2. Explicit is better than implicit. 3. Simple is b etter than complex. 4. Complex is better than complicated. NORMAL Top 1:17 As expected, this moves the cursor to the start of the first match. Now, suppose we moved the cursor too far, and wanted to jump to the second match. Vim has a second shortcut for repeating a search, but in the opposite direction: N . Repeat in the opposite direction N 1. Beautiful is b etter than ugly. 2. Explicit is b etter than implicit. 3. Simple is better than complex. 4. Complex is better than complicated. NORMAL 40% 2:16 Search for word under cursor Vim provides two additional shortcuts, & and # , for searching in the forward and backward directions, respectively. These shortcuts initiate a search and populate the search pattern with the word that is currently under the cursor, so that the search executes by simply hitting <CR> . Here is a quick summary of the search-related operators: Command Action /{pattern} search forward for the Nth occurrence of {pattern} ?{pattern} search backward for the Nth previous occurrence of {pattern} & repeat last :s # search backward for the Nth occurrence of the ident under the cursor n repeat the latest '/' or '?' N times N repeat the latest '/' or '?' N times in opposite direction This section has introduced the basics of searching a buffer with simple patterns. Vim extends the searching function with powerful patterns that can pinpoint specific text, and also supports the ability to search and replace text that has been matched.
Concatenation refers to the common operation of joining of two strings . In Lua, when two strings are concatenated the result is a third string that contains the characters of the first string followed by the characters contained in the second string: local x = "left side" local y = "right side" print ( x .. y ) -- left sideright side -- separating strings with a literal " " print ( x .. " " .. y ) -- left side right side Note that the concatenation is literal: no space is added between two concatenated strings. When concatenating sentences be sure to include a literal space between the two strings. Concatenation also works with numbers , by first coercing each value to its string-equivalent then concatenating those values: local x = 2 local y = 3 print ( x .. y ) -- 23 Note that concatenation won't work with other value fundamentals, such as booleans or nil .
Neovim originated as a fork of Vim and while it continues to maintain backward-compatibility with Vim, the two projects have slightly different goals which has led them to evolve down slightly different paths. While Vim continues to be a great project with a great community, Neovim has added several new features that in our opinion significantly upgrade the user experience: Lua First and foremost, one of the major advantages of Neovim over Vim is the inclusion of Lua as a first-class alternative to Vimscript for plugins and configuration . Lua is easy to learn, read, and write, executes quickly, and allows Neovim to benefit from a lot of great work being done by Lua's extensive community. Tree-sitter Tree-sitter is a fast document parser that maintains a syntax tree for each document as it is edited, which basically replaces slow and often-inaccurate regular expressions when implementing a variety of features. Prior to Tree-sitter, syntax-highlighting, indentation, and folding were implemented using regular expressions, which was often slow, inaccurate, and lacked features such as the ability to handle nested code blocks. By leveraging Tree-sitter's syntax tree, Neovim gains additional contextual information about the document that can be leveraged to provide accurate and consistent syntax highlighting, indentations, and folds, improved navigation between classes, functions, parameters, conditional statements, as well as some useful extensions to text objects . You can learn more Neovim's Tree-sitter integration at the nvim-treesitter and nvim-treesitter-textobjects repos. Language Server Protocol (LSP) Neovim includes a built-in Language Server Protocol client, which provides a wide range of functionality. Whereas Tree-sitter improves the experience of working with documents, LSP provides similar benefits to projects , to provide improved code-completion, snippets, formatting, jump to definition, refactoring, etc. Learn more about setting up Neovim's LSP at the nvim-lspconfig repo. More Information This is just a brief summary of the key improvements that Neovim offers vs Vim. If you are transitioning from Vim to Neovim you can find a complete list of the differences here Neovim.io Github Home Github Releases Documentation
The While Loop is a "condition-controlled" loop, which executes a block of code 0 or more times, stopping when the controlling condition is true . While loops follow the pattern: while [ boolean expression ] do -- loop body -- repeat as long as boolean expression is true end As a simple example, let's sum up all numbers from 0 to 4: local x = 0 local result = 0 while x < 5 do result = result + x x = x + 1 end print ( result ) -- 10 The break statement can be used to terminate a while loop early. The following is equivalent to the previous example. local x = 0 local result = 0 while true do result = result + x x = x + 1 if x >= 5 then break end end print ( result ) -- 10 Note that in this case we used a boolean expression that is simply true . This is a common practice in many situations, but requires a bit of care in order to prevent infinite loops . We should point out that when a While Loop is contained within a function, the loop can also terminate when it encounters a return statement: local function sum () local x = 0 local result = 0 while true do result = result + x x = x + 1 if x >= 5 then return result end end end print ( sum ()) -- 10