### Start a script with environment variables Source: https://lite-xl.com/developer-guide/using-libraries/child-processes Example of starting a script and passing environment variables to it using the `env` option in `process.start`. ```Lua -- start a script with verbose output (accepting options over env vars) local proc = process.start({ "./site.rb" }, { env = { VERBOSE = "1" } }) ``` -------------------------------- ### Start a process and read its output Source: https://lite-xl.com/developer-guide/using-libraries/child-processes Example of starting a process with its standard output redirected to a pipe and then reading from it using `proc:read_stdout()`. ```Lua -- start a process and read its output local proc = process.start({ "cat", "myfile" }, { stdout = process.REDIRECT_PIPE }) -- might or might not print something as the child process -- might not have written data to the standard output print(proc:read_stdout()) ``` -------------------------------- ### Run a command in the background Source: https://lite-xl.com/developer-guide/using-libraries/child-processes Example of starting a Lua process to run a shell command asynchronously using `process.start`. ```Lua -- run something in the background local proc = process.start { "bash", "-c", "echo hello world" } ``` -------------------------------- ### Lua: Process Termination Examples Source: https://lite-xl.com/developer-guide/using-libraries/child-processes Provides examples of how to use `process:terminate()` to attempt a graceful shutdown and `process:kill()` as a fallback for forceful termination if the graceful method fails. ```lua -- try to terminate child process proc:terminate() -- wait for child process to end if not proc:wait(1000) then -- didn't work, have to terminate it forcefully proc:kill() end ``` -------------------------------- ### Example IME Composition Sequence Source: https://lite-xl.com/developer-guide/writing-plugins/views Illustrates a typical sequence of `on_ime_text_editing` and `on_text_input` events during Pinyin IME composition, showing how text is composed and finalized. ```APIDOC Example IME Sequence: on_ime_text_editing: "和", 3, 0 on_ime_text_editing: "合理", 6, 0 on_ime_text_editing: "hell", 3, 0 on_ime_text_editing: "hello", 3, 0 on_text_input: "hello" on_ime_text_editing: "", 0, 0 ``` -------------------------------- ### Install lite-debugger with lpm (Shell) Source: https://lite-xl.com/developer-guide/writing-plugins/debugging Installs the lite-debugger plugin using the Lite XL Plugin Manager (lpm). This is a convenient way to add debugging capabilities to your Lite XL environment. ```shell $ lpm install lite-debugger ``` -------------------------------- ### Example: Logging Keypresses and Handling IME Source: https://lite-xl.com/developer-guide/commands-and-shortcuts/managing-keyboard-shortcuts Demonstrates how to override `keymap.on_key_pressed` to log key presses and handle Input Method Editor (IME) text composition events, especially on non-Linux platforms. ```lua local keymap = require "core.keymap" local ime = require "core.ime" -- Store original handler to call it later local original_keymap_on_key_pressed = keymap.on_key_pressed -- Override the key press handler function keymap.on_key_pressed(key, ...) -- On non-Linux platforms, check ime.editing to ignore keypresses during composition if PLATFORM ~= "Linux" and ime.editing then return false -- Event not handled, allow IME to process end -- Call the original handler to ensure normal keymap behavior local handled = original_keymap_on_key_pressed(key, ...) -- Custom logging for key presses print(key, "Pressed!") -- Return whether the event was handled by the original handler return handled end ``` -------------------------------- ### Lite XL HelloView Mouse Drag Example Source: https://lite-xl.com/developer-guide/writing-plugins/views An example implementation of a custom `HelloView` in Lite XL that demonstrates dragging text around the view using mouse events. It overrides `on_mouse_pressed`, `on_mouse_moved`, and `on_mouse_released` to implement the drag functionality. ```lua -- mod-version:3 local core = require "core" local command = require "core.command" local common = require "core.common" local style = require "core.style" local View = require "core.view" local HelloView = View:extend() function HelloView:new() -- This is the constructor for HelloView. -- Here, we'll call View's constructor to initialize -- some important states. HelloView.super.new(self) -- Set a caption that we'll use later self:set_caption "Hello world!" -- Position of the caption relative to View self.caption_pos = { x = 0, y = 0 } -- Position of cursor relative to caption self.cursor_pos = { x = 0, y = 0 } -- True if the user is dragging the caption self.hold = false self.scrollable = true end function HelloView:get_name() -- Returns the display name of the View. -- If tabs are enabled, this will be displayed as the tab title. return "Hello!" end function HelloView:get_caption_size() -- getter method for caption size return self.caption_w, self.caption_h end function HelloView:set_caption(caption) -- setter method for caption self.caption_w = style.font:get_width(caption) self.caption_h = style.font:get_height() self.caption = caption end function HelloView:get_scrollable_size() -- the "actual" height of the View return 2 * self.size.y end function HelloView:get_h_scrollable_size() -- the "actual" width of the View return 2 * self.size.x end function HelloView:get_caption_bounding_box() local x1, y1 = self:get_content_offset() x1, y1 = x1 + self.caption_pos.x, y1 + self.caption_pos.y local x2, y2 = x1 + self.caption_w, y1 + self.caption_h return x1, y1, x2, y2 end function HelloView:on_mouse_pressed(button, x, y, clicks) -- Skip if the event is already handled if HelloView.super.on_mouse_pressed(self, button, x, y, clicks) then return true end local x1, y1, x2, y2 = self:get_caption_bounding_box() if x >= x1 and y >= y1 and x <= x2 and y <= y2 then -- Store cursor position relative to caption self.cursor_pos.x, self.cursor_pos.y = x - x1, y - y1 self.hold = true return true end return false end function HelloView:on_mouse_moved(x, y, dx, dy) -- Skip if the event is already handled if HelloView.super.on_mouse_moved(self, x, y, dx, dy) then return true end if self.hold then -- Normalize cursor position to top left corner of the caption x, y = x - self.cursor_pos.x, y - self.cursor_pos.y -- Get the position relative to View local vx, vy = self:get_content_offset() local vw, vh = self:get_h_scrollable_size() - self.caption_w, self:get_scrollable_size() - self.caption_h self.caption_pos.x, self.caption_pos.y = common.clamp(x - vx, 0, vw), common.clamp(y - vy, 0, vh) end end function HelloView:on_mouse_released(...) HelloView.super.on_mouse_released(self, ...) self.hold = false end function HelloView:update() -- Update some important View states. HelloView.super.update(self) -- system.get_time() returns the number of seconds since Lite XL started. self:set_caption(string.format("Time elapsed: %.2f", system.get_time())) -- This tells Lite XL that we want to constantly redraw. core.redraw = true end function HelloView:draw() -- You should call this to avoid overdrawing -- previous content. self:draw_background(style.background) -- Get the top-left corner of the View local x, y = self:get_content_offset() ``` -------------------------------- ### Lua: Process Lifecycle Examples Source: https://lite-xl.com/developer-guide/using-libraries/child-processes Illustrates how to use `process:running()` to monitor a process's state within a thread and how to use `process:wait()` to block until a process exits, retrieving its exit code. ```lua -- wait for a process to end core.add_thread(function() while process:running() do coroutine.yield(0) print("I am still running") end print("Oh no!") end) -- wait for a process to end, and print its exit code. print("The process exited with the exit code " .. process:wait(process.WAIT_INFINITE)) ``` -------------------------------- ### Start and Read from Child Process (Lua) Source: https://lite-xl.com/developer-guide/using-libraries/child-processes Demonstrates launching an external command ('cat') and reading its standard output asynchronously using Lite XL's process API. It utilizes `core.add_thread` to prevent editor lock-ups while processing output. ```lua local core = require "core" local filename = "myfile.lua" local proc = process.start { "cat", filename } -- we use core.add_thread so that we don't softlock the editor -- while reading the output of the child process. core.add_thread(function() local readbuf = {} while true do -- yield so that the rest of the editor can carry out its tasks -- eg. accepting input, updating the UI coroutine.yield(1) -- try to read from the standard output of the process. local read = proc:read_stdout() -- read == nil is a pretty good indication that the pipe is closed -- therefore, no more data can be read. if read == nil then break end if read ~= "" then -- if we read something, append it into the table readbuf[#readbuf+1] = read end -- efficiently concatenate all the output into a string local process_output = table.concat(readbuf) -- note: never use core.log(process_output)! -- core.log() accepts the same parameters as string.format(), -- so you risk injecting invalid format strings! core.log("read: %s", process_output) end end) ``` -------------------------------- ### regex.gsub Usage Examples Source: https://lite-xl.com/developer-guide/using-libraries/using-regular-expressions Demonstrates various ways to use the regex.gsub function with different replacement string syntaxes, including literal replacements, capture groups, case manipulation, and conditional replacements. ```Lua local s = "John Doe, Jane Doe, Peter Doe" local r = regex.compile "(\w+)" -- Prints: No No, No No, No No 6 print(r:gsub(s, "No")) -- Prints: $John $doe, $Jane $Doe, $Peter $Doe 6 print(r:gsub(s, "($1)")) -- Prints: john doe, jane doe, peter doe 6 print(r:gsub(s, "\\l${1}")) -- Prints: Matched => John Matched => doe, Matched => Jane Matched => Doe, Matched => Peter Matched => Doe 6 print(r:gsub(s, "${1:+Matched => $1:No match.}")) ``` -------------------------------- ### Add Custom Command Source: https://lite-xl.com/developer-guide/writing-plugins/views Demonstrates how to add a new command to the Lite-XL system. This example adds a command named 'hello:hello' which, when executed, retrieves the currently active node and adds a new 'HelloView' to it, typically opening a new tab. ```lua -- Add a command to create a View. command.add(nil, { ["hello:hello"] = function() -- We'll get the current active node and add a view to it. -- This will usually create a new tab. core.root_view:get_active_node():add_view(HelloView()) end }) ``` -------------------------------- ### Iterate Through All Selections Source: https://lite-xl.com/developer-guide/writing-plugins/documents Provides an example of iterating through all user selections in the document. It shows how to distinguish between selections and carets (single points) and print their coordinates. ```lua -- iterate through all the selections from oldest to newest for idx, line1, col1, line2, col2 in doc:get_selections(true) do if line1 == line2 and col1 == col2 then print(string.format("cursor[%d]: %d, %d", idx, line1, col1)) else print(string.format("selection[%d]: %d, %d -> %d, %d", idx, line1, col1, line2, col2)) end end ``` -------------------------------- ### Lite XL Simple Pattern Definition Source: https://lite-xl.com/developer-guide/syntaxes-and-themes/creating-syntaxes An example of a simple pattern definition in Lite XL syntax. This pattern matches a line starting with '#' and assigns it the 'comment' token type. Patterns are processed in order, and the first match wins. ```lua { pattern = "#.*\n", type = "comment" } ``` -------------------------------- ### Get and use indentation info (Lua) Source: https://lite-xl.com/developer-guide/writing-plugins/documents Shows how to retrieve indentation settings (type, size, confirmation) and the string used for one level of indentation. ```Lua -- indent_type is either "soft" for space or "hard" for tabs. -- indent_size is the number of spaces for soft indentation or the number -- of spaces represented by one hard indent. local indent_type, indent_size, confirmed = doc:get_indent_info() -- a few space characters for soft indent, a tab character for hard indent print(doc:get_indent_string()) ``` -------------------------------- ### Add a selection (Lua) Source: https://lite-xl.com/developer-guide/writing-plugins/documents Example of adding a selection to the document using the `Doc:add_selection` function. Demonstrates adding a standard selection and an empty selection (caret). ```Lua -- add a selection doc:add_selection(1, 1, 2, 1) -- add an empty selection (a caret) doc:add_selection(1, 1) ``` -------------------------------- ### Mouse Hover Idiom Example Source: https://lite-xl.com/developer-guide/commands-and-shortcuts Demonstrates a common pattern in Lite XL for handling mouse interactions. It involves listening to mouse movement events to identify the hovered item and then setting it as the selected item upon a left-click, unifying mouse and keyboard handling. ```lua local function on_mouse_moved(view, event) local hovered_item = view:get_hovered_item(event.x, event.y) if hovered_item then view:set_hovered_item(hovered_item) end end local function on_mouse_click(view, event) if event.button == 1 then -- Left click local hovered_item = view:get_hovered_item(event.x, event.y) if hovered_item then view:set_selected_item(hovered_item) end end end view:connect_signal("on_mouse_moved", on_mouse_moved) view:connect_signal("on_mouse_click", on_mouse_click) ``` -------------------------------- ### Defer Command Execution with Background Task (Lua) Source: https://lite-xl.com/developer-guide/writing-plugins/background-tasks Shows how to defer the execution of commands until Lite XL is fully loaded, using `core.add_thread`. This is useful for commands added by plugins that depend on the editor's UI and other plugins being ready. The example defers a hypothetical `my-plugin:show` command. ```lua local core = require "core" local command = require "core.command" local config = require "core.config" core.add_thread(function() -- At this points, plugins are not loaded yet. -- We need to defer the execution after the editor is loaded. command:perform "my-plugin:show" end) ``` -------------------------------- ### Configure lite-debugger with Miq (Lua) Source: https://lite-xl.com/developer-guide/writing-plugins/debugging Configures the lite-debugger plugin for use with the Miq plugin manager. This involves adding 'lite-debugger' to the list of plugins in your Lite XL configuration. ```lua local config = require "core.config" config.plugins.miq.plugins = { 'TorchedSammy/Miq', 'lite-debugger', } ``` -------------------------------- ### Lite XL Start & End Pattern with Escape Source: https://lite-xl.com/developer-guide/syntaxes-and-themes/creating-syntaxes Shows how to define a token type for text with delimiters and support for escape sequences. This example uses double quotes (") as delimiters and a backslash (\) as the escape character, correctly handling strings like `\"Hello\"`. ```lua { pattern = { '"', '"', '\\' }, type = "string" }, ``` -------------------------------- ### Extend HelloView and Handle Update Event Source: https://lite-xl.com/developer-guide/writing-plugins/views This Lua code extends the `HelloView` class in Lite XL to manage UI updates. It demonstrates how to implement the `update` method to refresh the view's caption with elapsed time and ensures continuous redrawing by setting `core.redraw = true`. The example also includes methods for view naming, scrollable size calculation, and drawing the view's content and scrollbar, along with a command to instantiate and add the view. ```lua -- mod-version:3 local core = require "core" local command = require "core.command" local common = require "core.common" local style = require "core.style" local View = require "core.view" local HelloView = View:extend() function HelloView:new() -- This is the constructor for HelloView. -- Here, we'll call View's constructor to initialize -- some important states. HelloView.super.new(self) -- set a caption that we'll use later self.caption = "Hello world!" self.scrollable = true end function HelloView:get_name() -- Returns the display name of the View. -- If tabs are enabled, this will be displayed as the tab title. return "Hello!" end function HelloView:get_scrollable_size() -- the "actual" height of the View return 2 * self.size.y end function HelloView:get_h_scrollable_size() -- the "actual" width of the View return 2 * self.size.x end function HelloView:update() -- Update some important View states. HelloView.super.update(self) -- system.get_time() returns the number of seconds since Lite XL started. self.caption = string.format("Time elapsed: %.2f", system.get_time()) -- This tells Lite XL that we want to constantly redraw. core.redraw = true end function HelloView:draw() -- You should call this to avoid overdrawing -- previous content. self:draw_background(style.background) -- Get the top-left corner of the View local x, y = self:get_content_offset() -- We'll use view.size here so that looks centered -- At the start. local w, h = self.size.x, self.size.y -- Draw the caption with common.draw_text(). -- This function provides some utilities such as alignment -- over renderer.draw_text(). common.draw_text(style.font, style.text, self.caption, "center", x, y, w, h) -- Draw the scrollbar self:draw_scrollbar() end -- Add a command to create a View. command.add(nil, { ["hello:hello"] = function() -- We'll get the current active node and add a view to it. -- This will usually create a new tab. core.root_view:get_active_node():add_view(HelloView()) end }) ``` -------------------------------- ### Lua: Lite XL Plugin Setup and Configuration Source: https://lite-xl.com/developer-guide/samples/simple-plugin Demonstrates importing essential Lite XL modules like 'core', 'command', 'style', 'config', 'keymap', and 'rootview'. It also shows how to set plugin-specific configurations, such as defining custom colors and helper functions within the 'config.plugins' namespace. ```lua -- mod-version:3 -- you MUST put mod-version:x on the first line of your plugin -- mod-version usually maps to lite-xl releases (eg. mod-version: 2 == lite-xl 2.0) -- lite-xl won't load the plugin if the mod-version mismatches ----------------------------------------------------------------------- -- NAME : Simple -- DESCRIPTION: A simple guide on how to make your first Lite XL plugin -- AUTHOR : Ashwin Godbole (aelobdog) -- GOALS : To render some text inside the editor ----------------------------------------------------------------------- -- Disclaimer : -- I am not a lua developer, and my knowledge about writing plugins for -- Lite XL is very limited. This file serves the purpose of helping the -- reader get started with plugin development for Lite XL, and therefore -- demonstrates only some very basic features. For more complex plugin -- development, be sure to check out the source code of some other -- plugins after going through this file. ----------------------------------------------------------------------- -- Before we start writing any code for the plugin, we must import the -- required modules from the "core" package. -- the "core" module local core = require "core" -- the "command" module will help us register commands for our plugin. local command = require "core.command" -- the "style" module will allow us to use styling options local style = require "core.style" -- the "config" module will be used to store certain things like colors -- and functions local config = require "core.config" -- the "keymap" module will allow us to set keybindings for our commands local keymap = require "core.keymap" -- since we want to modify RootView, we'll need to require it first local RootView = require "core.rootview" ----------------------------------------------------------------------- -- per-plugin config must stay in config.plugins.(plugin name) config.plugins.simple = {} -- colors are just three or four comma separated values (RGBA) (range 0 - 255) -- put inside of '{ }'. We will add our color to the config module. config.plugins.simple.text_color = {200, 140, 220} -- or use `{ common.color "#C88CDC" }` ----------------------------------------------------------------------- -- Let's create a function to calculate the coordinates of our text. -- While we're at it, let's add our function to the `config` module. -- We'll take the message we want to display as the argument to the -- function to determine the x and y coordinates of the text. function config.plugins.simple.get_text_coordinates(message) -- For this plugin, we want to display the text on the top right -- corner of the screen. For this, we need to know the editor's width -- and height. -- The current font's size can be obtained from the "style" module. -- The editor's dimensions can be obtained by -- 1. WIDTH : core.root_view.size.x -- 2. HEIGHT : core.root_view.size.y local message_width = style.code_font:get_width(message.." ") local font_height = style.code_font:get_size() local x = core.root_view.size.x - message_width local y = font_height / 2 return x, y end ``` -------------------------------- ### Plugin Entrypoint and Structure Source: https://lite-xl.com/developer-guide/writing-plugins A Lite XL plugin is typically a Lua file or a directory containing an `init.lua` file. This file serves as the main entry point for the plugin's logic and initialization. ```lua -- init.lua -- This file is the entrypoint for your Lite XL plugin. -- Example: Define a new command or override an existing one local commands = require "core.commands" commands.add { name = "my_plugin.hello", func = function (args) print("Hello from My Plugin!") end } -- You can also load other Lua files or native libraries -- local utils = require "my_plugin.utils" -- utils.do_something() ``` -------------------------------- ### Get Specific Selection by Index Source: https://lite-xl.com/developer-guide/writing-plugins/documents Demonstrates how to retrieve a specific selection from the document using its index. The function can also sort the selection's start and end positions. ```lua -- get the 2nd selection local l1, c1, l2, c2 = doc:get_selection_idx(2, true) ``` -------------------------------- ### Lite XL Process API: process.start Source: https://lite-xl.com/developer-guide/using-libraries/child-processes Defines the `process.start` function for creating child processes. It details the arguments for program execution, the `ProcessOptions` record for configuration (timeout, cwd, stdin, stdout, stderr, env), and the returned `Process` object. It also explains the behavior of string vs. table arguments and environment variable handling on different platforms. ```APIDOC local type RedirectType = number local record ProcessOptions timeout: number, cwd: string, stdin: RedirectType, stdout: RedirectType, stderr: RedirectType, env: {string: string} end function process.start(program_args: {string} | string, options: ProcessOptions): Process end -- Redirect Type Values: -- process.REDIRECT_DEFAULT: Default behavior, deprecated, nil preferred. -- process.REDIRECT_PIPE: Allows reading/writing to the process's I/O. -- process.REDIRECT_PARENT: Redirects I/O to the parent process's console. -- process.REDIRECT_DISCARD: Discards any data to/from the child process. -- process.REDIRECT_STDOUT: Redirects stderr to stdout (only for stderr). -- Environment Variable Handling: -- POSIX: Extends parent's environment. -- Windows (v2.1.1 and below): Replaces parent's environment. -- Windows (v2.1.2+): Extends parent's environment (behavior consistent with POSIX). -- Process Object Behavior: -- If the Process object is garbage-collected, the child process will be killed. ``` -------------------------------- ### Modify/Truncate selection (Lua) Source: https://lite-xl.com/developer-guide/writing-plugins/documents Examples of modifying existing selections using `Doc:set_selections`. Shows how to truncate a selection into a caret and how to move a selection to new start and end positions. ```Lua -- truncate the 2nd selection and move it to 1, 1 -- (convert a selection into a caret) doc:set_selections(2, 1, 1) -- move the selection to (1, 1, 10, 10) doc:set_selections(2, 1, 1, 10, 10) ``` -------------------------------- ### Lite XL Syntax File Matching Example Source: https://lite-xl.com/developer-guide/syntaxes-and-themes/creating-syntaxes This Lua code demonstrates how to specify which files a syntax definition should apply to. It uses Lua patterns to match against the file path, allowing for flexible targeting of files based on their names or locations. ```lua files = { "sshd?/?_?config$" }, ``` -------------------------------- ### Creating and Initializing a New Class Source: https://lite-xl.com/developer-guide/writing-plugins/classes-and-objects Demonstrates how to create a new class by extending the base Object class using Object:extend(). It also shows how to define a constructor method (`new`) for initializing instances of the new class. ```lua -- load the Object class local Object = require "core.object" -- since the source class is usually the one you want to copy, -- we often simplify it to Object:extend(). -- This is equivalent to Object.extend(Object). local Animal = Object:extend() -- define a constructor for Animal function Animal:new() self.type = "animal" end ``` -------------------------------- ### Lite XL Start & End Pattern Definition Source: https://lite-xl.com/developer-guide/syntaxes-and-themes/creating-syntaxes Illustrates defining a token type for text enclosed between a start and end delimiter. This example uses '[' and ']' to define a range, assigning the 'keyword' type to content within these brackets. It does not handle escape sequences. ```lua { pattern = { "%[", "%]" }, type = "keyword" }, ``` -------------------------------- ### Creating a Custom View Source: https://lite-xl.com/developer-guide/writing-plugins/views Demonstrates how to create a custom View by extending the base `View` class in Lite XL. It includes initializing the view's context and caption, defining a display name, and adding a command to instantiate and display the view. ```lua -- mod-version:3 local core = require "core" local command = require "core.command" local common = require "core.common" local style = require "core.style" local View = require "core.view" local HelloView = View:extend() function HelloView:new() -- This is the constructor for HelloView. -- Here, we'll call View's constructor to initialize -- some important states. HelloView.super.new(self) -- This can be "session" or "application" -- If you specify "application", then the View will -- not be closed when the user performs "root:close-all". -- The user must explicitly close this View. self.context = "session" self.caption = "Hello world!" end function HelloView:get_name() -- Returns the display name of the View. -- If tabs are enabled, this will be displayed as the tab title. return "Hello!" end -- Add a command to create a View. command.add(nil, { ["hello:hello"] = function() -- We'll get the current active node and add a view to it. -- This will usually create a new tab. core.root_view:get_active_node():add_view(HelloView()) end }) ``` -------------------------------- ### Add View Down Command Source: https://lite-xl.com/developer-guide/writing-plugins/views Example command to split a node downwards and add a new view. The new node is configured to be resizable on the Y axis. ```Lua command.add { ["hello:split-down"] = function() -- the new Node will have a fixed initial size based on -- what the View provides, but the user can resize it. -- The other (old) Node will take up the rest of the space. core.root_view:get_active_node():split("down", view, { y = true }, { y = true }) end } ``` -------------------------------- ### Lua: Example Dracula Theme Source: https://lite-xl.com/developer-guide/syntaxes-and-themes/creating-themes This Lua code snippet demonstrates the structure of a Lite XL theme file. It imports necessary modules (`core.style`, `core.common`) and defines various style properties for the user interface and syntax highlighting using hex color codes. Themes are executed as Lua modules and can be reloaded. ```lua -- import the style table, and the common module -- which provides hex / rgb() -> color conversion functions local style = require "core.style" local common = require "core.common" -- set user interface colors style.background = { common.color "#282a36" } style.background2 = { common.color "#21222b" } style.background3 = { common.color "#21222b" } style.text = { common.color "#7b81a6" } style.caret = { common.color "#f8f8f0" } style.accent = { common.color "#8be9fd" } style.dim = { common.color "#4f5873" } style.divider = { common.color "#1f2029" } style.selection = { common.color "#44475a" } style.line_number = { common.color "#53576e" } style.line_number2 = { common.color "#f8f8f0" } style.line_highlight = { common.color "#313442" } style.scrollbar = { common.color "#44475a" } style.scrollbar2 = { common.color "#ff79c6" } -- set syntax highlighting colors style.syntax["normal"] = { common.color "#f8f8f2" } style.syntax["symbol"] = { common.color "#f8f8f2" } style.syntax["comment"] = { common.color "#6272a4" } style.syntax["keyword"] = { common.color "#ff79c6" } style.syntax["keyword2"] = { common.color "#ff79c6" } style.syntax["number"] = { common.color "#bd93f9" } style.syntax["literal"] = { common.color "#f1fa8c" } style.syntax["string"] = { common.color "#f1fa8c" } style.syntax["operator"] = { common.color "#ff79c6" } style.syntax["function"] = { common.color "#50fa7b" } ``` -------------------------------- ### Read default bytes from standard output Source: https://lite-xl.com/developer-guide/using-libraries/child-processes Example demonstrating how to read the default number of bytes (2048) from a process's standard output stream. ```Lua -- proc is a process with stdout set to process.REDIRECT_PIPE -- read default number of bytes (2048) from the process' standard output print(proc:read_stdout()) ``` -------------------------------- ### Get Text from Multiple Selections Source: https://lite-xl.com/developer-guide/writing-plugins/documents Shows how to extract the text content from one or more user selections. The function concatenates the text from the specified number of latest selections, separated by newlines. ```lua -- the text from the first 5 selections -- Don't pass anything to get text from all selections local text = doc:get_selection_text(5) ``` -------------------------------- ### Lite XL Syntax Header and Module Import Source: https://lite-xl.com/developer-guide/syntaxes-and-themes/creating-syntaxes The initial lines of a Lite XL syntax definition file. The first line specifies the required Lite XL version, and the second imports the necessary `core.syntax` module to enable syntax definition capabilities. ```lua -- mod-version:2 -- lite-xl 2.0 local syntax = require "core.syntax" ``` -------------------------------- ### Indent text region (Lua) Source: https://lite-xl.com/developer-guide/writing-plugins/documents Example of indenting a region of text across multiple selections. It iterates through selections, applies indentation using `Doc:indent_text`, and updates the selection positions. ```Lua -- indent all selections -- FIXME: this might not indent correctly with selections spanning multiple lines for idx, l1, c1, l2, c2 in doc:get_selections(true) do local new_l1, new_c1, new_l2, new_c2 = doc:indent_text(true, l1, c1, l2, c2) if new_l1 then doc:set_selections(idx, new_l1, new_c1, new_l2, new_c2) end end ``` -------------------------------- ### Read default bytes from standard error Source: https://lite-xl.com/developer-guide/using-libraries/child-processes Example demonstrating how to read the default number of bytes (2048) from a process's standard error stream, with a note to ensure stderr is not redirected to stdout. ```Lua -- read default number of bytes (2048) from the process' standard error -- ensure that stderr of the process is not set to process.REDIRECT_STDOUT! print(proc:read_stderr()) ``` -------------------------------- ### Lite XL Library Integration Overview Source: https://lite-xl.com/developer-guide/using-libraries Lite XL integrates several key libraries to extend its capabilities beyond pure Lua. It uses SDL2 for cross-platform windowing and event handling, PCRE2 for advanced regular expression support, and offers a dedicated API for managing child processes. ```APIDOC Library Integration: - SDL2: Provides cross-platform windowing and event handling. - PCRE2: Offers advanced regular expression matching capabilities. - Process API: Enables starting and managing child processes, handling their I/O without blocking the editor. ``` -------------------------------- ### Lite XL: Miscellaneous System Functions Source: https://lite-xl.com/developer-guide/using-libraries/interacting-with-the-os Includes utility functions for executing external commands and performing fuzzy string matching. These are part of the `system` module. ```APIDOC Miscellaneous System Functions: -- Runs a command in the background. system.exec(command: string): () - Description: - Executes a given command string in a separate process. Useful for fire-and-forget operations. - Parameters: - command: The command string to execute. On POSIX, it runs as `system(" &")`; on Windows, as `cmd /c ""`. Ensure proper escaping. -- Generates a score for sorting text based on relevance. system.fuzzy_match(haystack: string, needle: string, file: boolean): number - Description: - Compares two strings to determine their similarity, returning a score. - Parameters: - haystack: The string to search within or compare against. - needle: The string to search for or compare. - file: A boolean flag. If true, matching is performed backwards, suitable for path matching. - Returns: - A number representing the similarity score. A score of 1 indicates identical strings. ``` -------------------------------- ### Overriding Existing Functionality Source: https://lite-xl.com/developer-guide/writing-plugins Lite XL allows plugins to override existing functions to modify or extend editor behavior. For example, you can hook into the `Doc:save()` function to add custom logic before or after a file is saved. ```lua -- Example of overriding Doc:save() local Doc = require "core.doc" local original_save = Doc.save Doc.save = function (self, filename) -- Add custom logic before saving print("Saving document: " .. (filename or self.filename)) -- Call the original save function local success, err = original_save(self, filename) -- Add custom logic after saving if success then print("Document saved successfully.") else print("Error saving document: " .. (err or "unknown")) end return success, err end ``` -------------------------------- ### Native Library Loading Convention Source: https://lite-xl.com/developer-guide/writing-plugins Lite XL supports loading shared libraries (DLLs on Windows) using Lua's standard `package.searchers` convention. This allows integration of functionalities not exposed by Lite XL's native bindings. ```lua -- Example of loading a native library -- Assumes 'mylib' is available in Lua's package.cpath local mylib = require "mylib" -- Now you can call functions exposed by the native library -- local result = mylib.some_native_function(arg1, arg2) -- print(result) ``` -------------------------------- ### Define SSH Config Syntax in Lite XL Source: https://lite-xl.com/developer-guide/syntaxes-and-themes/creating-syntaxes This snippet demonstrates the complete structure for defining syntax highlighting for SSH configuration files in Lite XL. It includes file matching, comment characters, and a set of patterns for tokenizing keywords, numbers, symbols, and operators. ```lua -- mod-version:2 -- lite-xl 2.0 local syntax = require "core.syntax" syntax.add { files = { "sshd?/?_?config$" }, comment = '#', patterns = { { pattern = "#.*\n", type = "comment" }, { pattern = "%d+", type = "number" }, { pattern = "[%a_][%w_]*", type = "symbol" }, { pattern = "@", type = "operator" }, }, symbols = { -- ssh config ["Host"] = "function", ["ProxyCommand"] = "function", ["HostName"] = "keyword", ["IdentityFile"] = "keyword", ... -- sshd config ["Subsystem"] = "keyword2", -- Literals ["yes"] = "literal", ["no"] = "literal", ["any"] = "literal", ["ask"] = "literal", }, } ``` -------------------------------- ### Lite XL Command Registration for Custom Views Source: https://lite-xl.com/developer-guide/writing-plugins/views Shows how to register custom commands in Lite XL using `command.add`. This example registers a 'hello:hello' command to add a new 'HelloView' and a 'hello:delete-char' command for deleting characters from a view's caption. ```lua -- add a command to create a View. command.add(nil, { ["hello:hello"] = function() -- we'll get the current active node and add a view to it. -- it will create a new tab. core.root_view:get_active_node():add_view(HelloView()) end, }) -- add a command to delete caption text from the back command.add(HelloView, { ["hello:delete-char"] = function() -- we use string.usub to account for unicode multi-byte characters core.active_view.caption = core.active_view.caption:usub(1, -2) end }) ``` -------------------------------- ### Lite XL Syntax Highlighting Color Configuration Source: https://lite-xl.com/developer-guide/syntaxes-and-themes/creating-themes Defines colors for tokens produced by the Tokenizer, used for syntax highlighting in Lite XL. These are intentionally loosely defined and depend on syntax files. ```APIDOC style.syntax["normal"]: Description: Used for highlighting normal (plain) text. style.syntax["symbol"]: Description: Used for highlighting variables. style.syntax["comment"]: Description: Used for highlighting comments. style.syntax["keyword"]: Description: Used for highlighting keywords (e.g. `local`, `function`, `end`, `if`). style.syntax["keyword2"]: Description: Used for highlighting a different set of keywords (e.g. `self`, `int`). style.syntax["number"]: Description: Used for highlighting numbers. style.syntax["literal"]: Description: Used for highlighting literals (e.g. `true`, `false`, `nil`). style.syntax["string"]: Description: Used for highlighting strings. style.syntax["operator"]: Description: Used for highlighting operators (e.g. `+`, `-`, `/`, `*`). style.syntax["function"]: Description: Used for highlighting functions. ``` -------------------------------- ### Lua Pattern Matching with Token Types Source: https://lite-xl.com/developer-guide/syntaxes-and-themes/creating-syntaxes Demonstrates Lua pattern matching in Lite XL, explaining how empty parentheses capture text positions to change token types. This allows for fine-grained control over syntax highlighting by assigning different types to parts of a pattern. ```Lua local in_squares_match = "^%[%]" -- reference links { pattern = "^%s*%[%^()["..in_squares_match.."]+%()%%]: ", type = { "function", "number", "function" } }, ``` -------------------------------- ### Doc API: Selection Management Source: https://lite-xl.com/developer-guide/writing-plugins/documents Provides functions for managing text selections within a document. This includes adding new selections, modifying existing ones by setting start and end positions, and removing selections. It also covers retrieving current selections and merging overlapping or adjacent selections to maintain consistency. ```APIDOC Doc:add_selection(start_line: number, start_col: number, end_line: number, end_col: number, swap_ends: boolean?) Adds a new selection to the document. If start and end positions are the same, it creates a caret. The function replaces an existing smaller selection if applicable. Parameters: start_line: The starting line number of the selection. start_col: The starting column number of the selection. end_line: The ending line number of the selection. end_col: The ending column number of the selection. swap_ends: Optional boolean to swap start and end positions if start > end. Doc:set_selections(index: number, start_line: number, start_col: number, end_line: number, end_col: number, swap_ends: boolean?, remove_count: number?) Modifies an existing selection at a given index. Can be called with 3, 6, or 7 arguments. - 3 arguments: index, end_line, end_col (truncates selection). - 6 arguments: index, start_line, start_col, end_line, end_col, swap_ends (modifies selection with optional swap). - 7 arguments: index, start_line, start_col, end_line, end_col, swap_ends, remove_count (removes 'remove_count' selections before inserting new ones). Parameters: index: The index of the selection to modify. start_line: The starting line number. start_col: The starting column number. end_line: The ending line number. end_col: The ending column number. swap_ends: Optional boolean to swap start and end positions. remove_count: Optional number of selections to remove before inserting. Doc:remove_selection(index: number) Removes a selection at the specified index. It's advised not to remove selections while iterating over them directly. Parameters: index: The index of the selection to remove. Doc:get_selections(include_empty: boolean?): iterator Retrieves all current selections as an iterator. Each iteration yields selection details. Parameters: include_empty: Optional boolean to include empty selections (carets). Returns: An iterator yielding (index, l1, c1, l2, c2) for each selection. Doc:merge_cursors(idx: number?) Merges adjacent or overlapping selections. If 'idx' is provided, it merges selections around that index. If 'idx' is omitted, it attempts to merge all selections in the document. ``` -------------------------------- ### System Clipboard Functions Source: https://lite-xl.com/developer-guide/using-libraries/interacting-with-the-os Provides functions to interact with the system clipboard. `system.set_clipboard` sets the clipboard content, and `system.get_clipboard` retrieves it. These functions do not support rich content like images or files. ```lua function system.set_clipboard(text: string): () end function system.get_clipboard(text: string): string end ``` ```lua system.set_clipboard("wow magic") -- prints: -- wow magic print(system.get_clipboard("wow magic")) ``` -------------------------------- ### Create Toolbar View Instance Source: https://lite-xl.com/developer-guide/samples/toolbarview Defines a new ToolbarView by extending the base ToolbarView class. It initializes the view, loads a custom icon font, and sets up an array of commands with associated symbols. ```lua local Toolbar = ToolbarView:extend() function Toolbar:new() Toolbar.super.new(self) self.toolbar_font = renderer.font.load(get_plugin_directory() .. PATHSEP .. "toolbar.ttf", style.icon_big_font:get_size()) self.toolbar_commands = { {symbol = "A", command = "core:open-log"}, {symbol = "B", command = "core:new-doc"}, {symbol = "C", command = ""}, {symbol = "D", command = ""}, {symbol = "E", command = ""}, {symbol = "F", command = ""}, } end ```