" ---------------------------------------------------------------------------------
" Vimscript Reference and Guide
"
" ReferenceCollection.com
" Licensed under CC BY-SA
" ---------------------------------------------------------------------------------
" TABLE OF CONTENTS
" -----------------
" 1. Introduction to Vim Script
" 2. Basic Syntax and Structure
" 3. Variables and Data Types
" 4. Operators and Expressions
" 5. Control Flow Statements
" 6. Functions (Built-in and User-defined)
" 7. Working with Buffers and Windows
" 8. Working with Text
" 9. User Interaction
" 10. Autocommands
" 11. External Commands and System Interaction
" 12. Error Handling
" 13. Debugging Vim Script
" 14. Advanced Topics
" 15. Common Vim Script Patterns
" ---------------------------------------------------------------------------------
" 1. Introduction to Vim Script
" ---------------------------------------------------------------------------------
" Vim script (also known as VimL or simply script) is the built-in scripting
" language of the Vim text editor. It allows users to automate tasks, extend
" Vim's functionality, and customize the editor to their specific needs.
" Why Learn Vim Script?
" - Automation: Automate repetitive editing tasks, saving time and effort.
" - Customization: Tailor Vim's behavior, appearance, and functionality.
" - Plugins: Develop your own Vim plugins or contribute to existing ones.
" - Deeper Understanding: Gain a more profound understanding of how Vim works.
" Where to Use Vim Script:
" - `.vimrc` or `_vimrc`: Your main Vim configuration file.
" - Plugin files: To implement the logic of your plugins.
" - Command-line execution: Execute Vim scripts from the terminal.
" - Dynamically during a Vim session: Enter and execute script commands directly.
" Basic Execution:
" - Sourcing a file: `:source <filename>` or `:so <filename>`
" - Executing a string: `:execute "echom 'Hello, Vim Script!'"`
" - Evaluating an expression: `:echo 1 + 1`
" ---------------------------------------------------------------------------------
" 2. Basic Syntax and Structure
" ---------------------------------------------------------------------------------
" Comments:
" --------
" Comments start with a double quote (").
" Commands:
" ---------
" Vim script consists of a series of commands, typically one per line.
" Commands are often prefixed with a colon `:`
" Case Sensitivity:
" ---------------
" Vim script commands are case-sensitive. `echom` is correct, `Echom` is not.
" Whitespace:
" -----------
" Generally, whitespace is ignored, but it improves readability.
" Line Continuations:
" -----------------
" To split a long command over multiple lines, use a backslash (`\`):
let very_long_variable_name = "This is a very long string " \
. "that spans multiple lines " \
. "using a backslash."
" Command Ranges:
" --------------
" Some commands can operate on a range of lines.
" `:10,20 delete` " Deletes lines 10 through 20.
" `:%s/old/new/g` " Substitute 'old' with 'new' globally in the buffer.
" `:'a,'b delete` " Delete lines marked with 'a' and 'b'.
" Command Modifiers:
" -----------------
" Commands can be modified using flags or options.
" `:silent !date` " Executes the external command 'date' silently.
" ---------------------------------------------------------------------------------
" 3. Variables and Data Types
" ---------------------------------------------------------------------------------
" Variables in Vim script are dynamically typed, meaning you don't need to
" declare their type explicitly.
" Declaration and Assignment:
" --------------------------
" Use the `let` command to declare and assign values to variables.
let my_string = "Hello"
let my_number = 10
let my_list = [1, 2, 3]
let my_dict = {'name': 'Vim', 'version': '9.0'}
" Variable Scope:
" --------------
" Vim script has several scopes for variables:
" - Global (`g:`): Accessible from anywhere in Vim.
" - Buffer-local (`b:`): Specific to the current buffer.
" - Window-local (`w:`): Specific to the current window.
" - Tabpage-local (`t:`): Specific to the current tabpage.
" - Function-local (`l:`): Only within the function where it's defined.
" - Script-local (`s:`): Only within the script file where it's defined.
" - Environment (`v:env`): Access environment variables.
" - Option (`&`): Access Vim options.
" - Register (`@`): Access register contents.
" - Mapping (`maplocalleader`, etc.): Access mapping settings.
" Accessing Variables:
" --------------------
" Use the variable name (prefixed with its scope identifier if needed).
echom g:my_string
let l:local_var = "Local"
echom l:local_var
" Data Types:
" ----------
" - Number: Integers and floating-point numbers.
let num1 = 10
let num2 = 3.14
" - String: Sequences of characters.
let str1 = "Vim script"
let str2 = 'Single quoted string' " No special interpretation.
" - List: Ordered collections of items.
let list1 = [1, "two", 3.0]
" - Dictionary: Unordered collections of key-value pairs.
let dict1 = {'name': 'Example', 'value': 100}
" - Funcref: References to functions.
function MyFunc()
echom "Function called"
endfunction
let my_func_ref = function('MyFunc')
call my_func_ref()
" - Job: Represents a running external command.
" - Channel: Represents a connection for asynchronous communication.
" Type Conversion:
" ---------------
" Vim script automatically performs type conversions where necessary.
let result = "10" + 5 " Result will be 15 (string "10" converted to number)
let str_num = 123 .. "" " Convert number to string (concatenation with empty string)
let num_str = str2nr("456") " Convert string to number. Returns 0 if not a valid number.
" ---------------------------------------------------------------------------------
" 4. Operators and Expressions
" ---------------------------------------------------------------------------------
" Operators in Vim script are similar to those found in other programming languages.
" Arithmetic Operators:
" --------------------
" `+` (addition), `-` (subtraction), `*` (multiplication), `/` (division),
" `%` (modulo), `^` or `**` (exponentiation).
let sum = 10 + 5
let product = 4 * 6
" String Operators:
" ----------------
" `.` (concatenation).
let greeting = "Hello, " . "Vim!"
" Comparison Operators:
" ---------------------
" `==` (equal), `!=` (not equal), `>` (greater than), `<` (less than),
" `>=` (greater than or equal), `<=` (less than or equal).
" Case sensitivity: `==?`, `!=?`, `>?`, `<?, `>=?`, `<=?` for case-insensitive.
if 10 > 5
echom "10 is greater than 5"
endif
" Logical Operators:
" -----------------
" `&&` or `and` (logical AND), `||` or `or` (logical OR), `!` or `not` (logical NOT).
if (10 > 5) && ("a" != "b")
echom "Both conditions are true"
endif
" List Operators:
" ---------------
" `+` (list concatenation), `[]` (indexing), `[start:end]` (slicing), `in` (membership).
let my_list = [1, 2, 3] + [4, 5] " Result: [1, 2, 3, 4, 5]
echom my_list[0] " Access the first element (index 0)
let sub_list = my_list[1:3] " Result: [2, 3, 4]
if 2 in my_list
echom "2 is in the list"
endif
" Dictionary Operators:
" --------------------
" `.` (access by key), `['key']` (access by key).
let my_dict = {'name': 'Vim', 'version': '9.0'}
echom my_dict.name
echom my_dict['version']
" Ternary Operator:
" ----------------
" `condition ? expr_if_true : expr_if_false`.
let result = (10 > 5) ? "Yes" : "No"
" ---------------------------------------------------------------------------------
" 5. Control Flow Statements
" ---------------------------------------------------------------------------------
" Control flow statements allow you to control the execution of your Vim script
" based on conditions or to repeat actions.
" `if` Statements:
" ---------------
" Executes a block of code if a condition is true.
if condition
" Code to execute if the condition is true
endif
" `if-else` Statements:
" --------------------
" Executes one block of code if the condition is true, and another if it's false.
if condition
" Code if true
else
" Code if false
endif
" `if-elseif-else` Statements:
" ----------------------------
" Allows for multiple conditions to be checked.
if condition1
" Code if condition1 is true
elseif condition2
" Code if condition2 is true
else
" Code if none of the conditions are true
endif
" `while` Loops:
" --------------
" Executes a block of code repeatedly as long as a condition is true.
let counter = 0
while counter < 5
echom "Counter: " . counter
let counter += 1
endwhile
" `for` Loops:
" ------------
" Iterates over items in a list or dictionary.
" Iterating over a list:
let my_list = ['a', 'b', 'c']
for item in my_list
echom "Item: " . item
endfor
" Iterating over a dictionary (items):
let my_dict = {'one': 1, 'two': 2, 'three': 3}
for [key, value] in items(my_dict)
echom "Key: " . key . ", Value: " . value
endfor
" Iterating over a dictionary (keys):
for key in keys(my_dict)
echom "Key: " . key
endfor
" `break` and `continue`:
" ----------------------
" - `break`: Exits the current loop.
" - `continue`: Skips the current iteration and continues to the next.
let counter = 0
while counter < 10
let counter += 1
if counter == 5
continue " Skip printing when counter is 5
endif
if counter > 7
break " Exit the loop when counter exceeds 7
endif
echom "Counter: " . counter
endwhile
" ---------------------------------------------------------------------------------
" 6. Functions (Built-in and User-defined)
" ---------------------------------------------------------------------------------
" Functions are reusable blocks of code that perform specific tasks. Vim script
" provides a rich set of built-in functions and allows you to define your own.
" Built-in Functions:
" -------------------
" Vim offers a vast library of built-in functions for various purposes. Refer to
" `:help functions` for a comprehensive list.
" Common built-in functions:
" - String manipulation: `strlen()`, `substring()`, `match()`, `substitute()`.
" - List manipulation: `len()`, `add()`, `remove()`, `sort()`.
" - Dictionary manipulation: `has_key()`, `get()`, `extend()`.
" - Buffer and window management: `bufnr()`, `win_getid()`, `wincmd()`.
" - User interface: `echom()`, `input()`, `confirm()`.
" - File system interaction: `readfile()`, `writefile()`, `filereadable()`.
" Example of using built-in functions:
let my_string = "Hello, Vim!"
echom strlen(my_string) " Output: 11
echom substring(my_string, 0, 5) " Output: Hello
" User-defined Functions:
" -----------------------
" Use the `function` keyword to define your own functions.
function! MyGreeting(name)
echom "Hello, " . a:name . "!"
endfunction
" Calling User-defined Functions:
" ------------------------------
" Use the `call` command followed by the function name and arguments.
call MyGreeting("User")
" Function Arguments:
" ------------------
" Arguments passed to a function are accessed using `a:`. The first argument
" is `a:1`, the second is `a:2`, and so on. `a:0` contains the number of arguments.
" `a:000` is a list of all arguments. Named arguments are also supported (see below).
" Function Return Values:
" ----------------------
" Use the `return` keyword to return a value from a function.
function! Add(num1, num2)
return a:num1 + a:num2
endfunction
let result = call Add(5, 3)
echom result " Output: 8
" Function Scope:
" ---------------
" By default, user-defined functions have global scope. To define a script-local
" function, prefix the function name with `s:`.
function! s:MyScriptLocalFunction()
echom "This is a script-local function"
endfunction
" Named Function Arguments:
" ------------------------
" You can define functions with named arguments, improving readability.
function! CalculateArea(width, height)
return a:width * a:height
endfunction
let area = CalculateArea(width=10, height=5)
echom area " Output: 50
" Variable Number of Arguments (`...`):
" ------------------------------------
" Functions can accept a variable number of arguments using `...`. These arguments
" are available in the `a:000` list.
function! Sum(...)
let total = 0
for num in a:000
let total += num
endfor
return total
endfunction
echom Sum(1, 2, 3, 4) " Output: 10
" ---------------------------------------------------------------------------------
" 7. Working with Buffers and Windows
" ---------------------------------------------------------------------------------
" Vim's interface revolves around buffers (in-memory representations of files) and
" windows (viewports into those buffers). Vim script provides commands and
" functions to interact with them.
" Buffers:
" --------
" - `bufnr()`: Get the buffer number of a buffer (current, by name, etc.).
" - `bufname()`: Get the name of a buffer given its number.
" - `buflisted()`: Check if a buffer is listed.
" - `setbufvar()`: Set a buffer-local variable.
" - `getbufvar()`: Get a buffer-local variable.
" - `bufexists()`: Check if a buffer exists.
" - `buffer`: Switch to a buffer by number or name.
" Examples:
let current_bufnr = bufnr('%') " Get the buffer number of the current buffer
echom bufname(current_bufnr) " Get the name of the current buffer
let file_bufnr = bufnr('myfile.txt')
if bufexists(file_bufnr)
buffer myfile.txt
endif
" Windows:
" --------
" - `win_getid()`: Get the ID of a window.
" - `winbufnr()`: Get the buffer number displayed in a window.
" - `winnr()`: Get the number of the current window or a window by ID.
" - `winrestview()`: Restore the view of a window (cursor position, folds, etc.).
" - `winsaveview()`: Save the current view of a window.
" - `wincmd`: Execute a window command (e.g., `wincmd w` to switch windows).
" Examples:
let current_winid = win_getid()
let current_winnr = winnr()
let buf_in_current_win = winbufnr(current_winid)
echom "Buffer in current window: " . bufname(buf_in_current_win)
" Tab Pages:
" ----------
" - `tabpagenr()`: Get the number of the current tab page or the total number of tab pages.
" - `tabpagebuflist()`: Get a list of buffer numbers in a tab page.
" - `tabedit`: Open a new tab page with a file.
" - `tabclose`: Close the current tab page.
" Examples:
let current_tabnr = tabpagenr()
let total_tabs = tabpagenr('