Architectural Blueprints for a Next-Generation Linux Text Editor: Comparative Analysis and System Design Specifications
The design of a software development editor requires balancing computational efficiency, user extensibility, and interface ergonomics.1 Developers frequently find themselves choosing between lightweight, high-performance editors that lack integrated intelligence and feature-rich environments that impose significant CPU and memory overhead.1 While established systems like Sublime Text set a high standard for operational speed, their reliance on complex manual configurations and unstructured plugin ecosystems introduces clear points of friction.1 Conversely, modern alternatives written in systems languages like Rust attempt to resolve these trade-offs but introduce new architectural compromises, such as rigid feature sets or forced integrations of external AI services.1
For a developer planning to build a custom, high-performance editor tailored for the Linux ecosystem, analyzing the structural gaps in existing tooling is an essential first step. This analysis establishes the system specifications, data structures, and rendering architectures required to create a lightweight, extensible, and natively integrated editing platform.
To identify opportunities for architectural improvement, one must first evaluate the design philosophies, interface paradigms, and technical underpinnings of the leading text editors.
┌─────────────────────────────────────────┐
│ Text Editor Taxonomy │
└────────────────────┬────────────────────┘
│
┌─────────────────────────────┴─────────────────────────────┐
▼ ▼
┌──────────────────┐ ┌──────────────────┐
│ GUI-Centric │ │ Terminal-Base │
└────────┬─────────┘ └────────┬─────────┘
│ │
├─► Sublime Text (C++, Skia/OpenGL) ├─► Helix (Rust, TUI)
├─► Zed (Rust, GPUI Shaders) └─► Neovim (C/Lua, TUI)
├─► Lapce (Rust, Floem GPU)
└─► VS Code (TypeScript, Electron)
Sublime Text remains a benchmark for desktop editing performance due to its lightweight memory footprint and rapid startup times.1 Built with a custom C++ codebase and a proprietary GUI framework, it utilizes a rendering engine that composites the interface via OpenGL on macOS and Linux.2
However, its extensibility model represents a significant source of user friction.1 Package management is handled through a third-party Python API system (Package Control), which often requires complex manual configurations and is prone to breaking during major application updates.1 Enabling standard IDE capabilities, such as the Language Server Protocol (LSP), diagnostics, and advanced autocompletion, requires users to manually install and configure independent plugins.1
Furthermore, Sublime Text lacks native real-time collaboration tools and restricts settings modifications to raw, side-by-side JSON configuration files, presenting a steep learning curve for developers who prefer interactive graphical controls.1
Zed is a collaborative, high-performance editor built from the ground up in Rust.1 It uses a custom GPU-accelerated UI framework called GPUI, which bypasses traditional web runtimes and OS widget toolkits to render layouts directly on the GPU at 120 frames per second.11 Zed features built-in support for LSPs, Git integrations, and real-time multiplayer pair programming.1
To protect the main thread from plugin crashes, Zed isolates extensions using a WebAssembly (WASM) sandbox powered by Wasmtime.10 The primary drawbacks of this architecture are an immature plugin library and highly restrictive API surfaces that currently limit extensions to themes, basic language grammars, and language server routing.1
Additionally, Zed integrates complex, model-backed AI tools directly into its core interface.1 While these features can be deactivated, many developers find this forced integration introduces unnecessary complexity and contributors have reported issues with persistent memory leaks.4
Lapce represents an open-source attempt to build a fast desktop editor using Rust and the Floem GUI toolkit.8 It supports remote development environments natively, includes built-in terminal emulation, and compiles plugins to the WebAssembly System Interface (WASI).14
Despite these advanced specifications, Lapce is currently in a semi-abandoned state with limited active development.8 It suffers from significant stability and rendering bugs, fragile LSP integrations, and a failure to support standard Linux interface conventions.8
Helix is a terminal-native, modal text editor written in Rust.5 In contrast to Vim's traditional modal commands, Helix adopts a Kakoune-inspired selection-first (object-to-action) interaction paradigm.5 This allows the editor to visually highlight target text selections before a deletion, modification, or movement command is executed, reducing accidental edits.5
Helix packages tree-sitter syntax highlighting, LSP client configurations, and multiple cursors directly out of the box without requiring manual plugin setups.5
However, its lack of a plugin system or snippet execution engine limits its appeal for complex, highly customized software development workflows.17
Visual Studio Code represents the industry standard for developer integrations and ecosystem maturity, but it achieves this at the expense of computational efficiency.3 Built on Electron and rendering via a heavy Chromium-based DOM model, VS Code routinely consumes upwards of of RAM and experiences noticeable startup latencies.3 This resource overhead and reliance on heavy web runtimes make it poorly suited for resource-constrained systems or simple, distraction-free file editing.1
The following comparison matrix details these structural differences:
| Architectural Metric | Sublime Text | Zed | Lapce | Helix | VS Code |
|---|---|---|---|---|---|
| Implementation Language | C++ 2 | Rust 10 | Rust 14 | Rust 5 | TypeScript / C++ 3 |
| Rendering Subsystem | Skia / Custom OpenGL 19 | GPUI Shader Pipelines 11 | Floem Toolkit 8 | Terminal TUI | Chromium DOM / WebGL 11 |
| Package / Plugin Runtime | Python Interpreter 2 | WASI Sandboxed (Wasmtime) 10 | WASI Sandboxed 14 | Not Supported 5 | Node.js Runtime 3 |
| Package Complexity | High; manual Package Control and JSON setup 1 | Minimal; isolated WASM packages 10 | Minimal; automated WASI download 14 | N/A (All features built-in) 5 | Low; single-click GUI installation 3 |
| Settings Interface | Dual-Pane raw JSON files 1 | Hybrid GPUI Form & JSON 9 | Native GUI Panel 22 | TOML text file 5 | Unified GUI & JSON 3 |
| Startup Responsiveness | Instantaneous 1 | Instantaneous 1 | Instantaneous 14 | Instantaneous 17 | Slow (3–4 seconds) 3 |
| Memory Footprint | Low (~50MB–100MB) | Moderate (~150MB–300MB) | Low (~100MB) 15 | Very Low (~20MB–50MB) | Very High (800MB+) 3 |
The configuration pipeline of an editor is a frequent source of user friction. Developers often struggle with the trade-offs between editing raw text configurations and using a graphical settings interface.
┌───────────────────────────────────────────────────────────────────┐
│ Bidirectional Settings Sync │
├─────────────────────────────────┬─────────────────────────────────┤
│ Direct JSON Configuration │ Dynamic Schema GUI Form │
│ - Raw edits in settings.json │ - Auto-generated inputs │
│ - Full keyboard control │ - Tooltips and explanations │
│ - Comments supported [23] │ - Live, safe data validation │
└────────────────┬────────────────┴────────────────┬────────────────┘
│ │
└──────────────► ◄──┘
│
▼
[24]
│
▼
Sublime Text relies on dual-pane JSON configuration documents, displaying the immutable application defaults in the left pane and the user's modifications in the right pane.1 While this model supports direct keyboard interaction and allows configuration changes to be tracked in version control, it lacks discoverability.9
Users must read external documentation to identify available options, and a simple syntax error (such as a missing comma or bracket) can crash the configuration parsing engine.9 This manual process makes customizing the editor difficult, particularly for developers installing and configuring complex external plugins.1
Zed originally parsed and managed its configurations using a decentralized model.9 Each independent crate inside the application codebase declared the specific settings it required, and the editor compiled these options at runtime to parse the central settings.json file.9 While this kept compile times manageable, it meant Zed lacked a unified, strongly-typed settings model, which often caused unintended side effects when settings were modified.9
To address these limitations, Zed refactored its settings engine into a strongly-typed model that splits configuration into distinct, clearly scoped UserSettings and ProjectSettings structs.9 This structured foundation allowed Zed to build a hybrid Settings Editor GUI directly into GPUI.9 Users can search for and modify options using interactive forms, dropdown selectors, and toggles, while changes are bidirectionally written back to the underlying settings.json file, which remains accessible for manual editing.9
For a developer building a custom text editor, writing and maintaining a separate graphical interface for every settings parameter is highly inefficient.9 A more elegant solution is to use a decoupled, schema-driven configuration architecture.25
By defining the editor's configuration parameters in a standardized JSON Schema document, the system can dynamically auto-generate its graphical interface.24 This schema acts as an explicit data contract, declaring the exact data types, default values, validation ranges, and hover tooltips for every setting.24
A specialized GUI form engine (such as the Rust-based schemaui framework) can read this JSON Schema and the active user configuration file at runtime.27 The form engine parses the schema and automatically generates the corresponding interface elements:
- An integer with a defined range, such as "buffer_font_size": { "type": "integer", "minimum": 6, "maximum": 72 }, is automatically rendered as a bounded numeric input or slider.
- A setting with a fixed list of string variants, such as the cursor blinking style, maps to a dropdown selection menu.27
- Every setting can leverage its schema-defined description annotation to render helpful interactive tooltips on mouse hover.24
During edits, every change in the GUI runs through a fast, compiled validator (e.g., using jsonschema::validator_for in Rust).27 If a user enters an invalid value, the validation engine intercepts the commit, highlights the erroneous field in the UI with a visual warning indicator, and blocks serialization.27 Once validated, changes are bidirectionally synchronized: edits in the GUI are written back to the local text file (supporting JSON, TOML, or YAML), and direct manual updates to the configuration file instantly refresh the state of the GUI controls.24
This decoupled design allows the developer to add or update configuration options by simply editing the central JSON Schema, completely eliminating the need to write custom GUI layout code.25
Evaluating existing text editors reveals several persistent design flaws, feature omissions, and operational bottlenecks. Understanding these gaps helps guide the development of a next-generation custom editor.
Traditional desktop editors often run plugins directly within the application's primary process or via unconstrained scripting runtimes.2 For example, Sublime Text runs Python-based plugins within a shared runtime environment.2 A poorly written extension can experience CPU lockups, leak memory, or crash the entire editing session.12
While Electron-based editors isolate plugins in separate processes, they incur significant memory overhead.3 Modern systems like Zed attempt to solve this by running WASM-sandboxed plugins via Wasmtime.10 However, Zed's API surfaces are currently highly restricted, preventing plugins from modifying visual elements or introducing advanced custom interfaces.10
Many modern cross-platform editors fail to support standard Linux interface conventions.2 For instance, Lapce does not support the native UNIX primary selection clipboard, which prevents developers from pasting text using a standard mouse middle-click.16
Additionally, several Rust-based GPU frameworks do not support standard text dragging, and they frequently drop key input focus when users resize sidebar panels or interact with floating UI elements.16
Several modern editors, including Zed, Cursor, and Windsurf, heavily prioritize integrated AI tools and agentic coding workflows.11
While some developers appreciate these tools, others prefer a minimal, privacy-centric editor.4 These modern platforms often mandate internet connectivity for AI assistance, run telemetry services in the background, and can introduce persistent memory leaks and performance regression.4 This creates a clear gap in the market for a fast, local-first editor that remains completely offline by default.1
Modal terminal editors like Neovim offer unmatched keyboard efficiency, but configuring them is a highly complex process.3 Setting up a productive development environment in Neovim typically requires writing hundreds of lines of custom Lua code and micro-managing third-party plugins that frequently break during application updates.3
Helix addresses this by providing structured, out-of-the-box LSP support, but it lacks a plugin API, preventing developers from adding custom, project-specific workflows.5
Building a high-performance text editor for Linux requires selecting system components and data structures that prioritize low-latency execution and memory efficiency. The following specifications outline a technical blueprint for a custom Rust-based editor.
┌───────────────────────────────────────────────────────────────────┐
│ Custom Editor System Architecture │
├─────────────────────────────────┬─────────────────────────────────┤
│ UI Layer (Slint) │ Layout & Shaping (Swash) │
│ - Declarative markup UI │ - cosmic-text engine integration│
│ - Compile-time optimisations │ - Font fallback matching │
│ - Low runtime RAM (<300KiB) │ - Multi-line wrap calculations │
└────────────────┬────────────────┴────────────────┬────────────────┘
│ │
└──────────────► ◄──┘
│
▼
[32]
│
▼
- Core Language: Rust. Its system-level access and strong compile-time checks provide the safety and speed required to build a responsive text engine.11
- GUI Toolkit: Slint.33 Slint uses a declarative markup language that compiles directly to optimized machine code, keeping the runtime footprint extremely small (less than
of RAM).33 It supports multiple graphics backends, allowing it to render via OpenGL or fall back to CPU-bound software rendering on systems with buggy GPU drivers.33
- Text Layout and Shaping Subsystem: cosmic-text.35 This library provides pure-Rust text handling, integrating HarfRust for shaping, fontdb for system font discovery, and Swash for dynamic glyph rasterization.35
To ensure the editor can open and edit multi-gigabyte files instantly, the developer should implement a Piece Tree data structure.32
┌──────────────┐
│ Root Node │
│ (Piece Tree) │
└──────┬───────┘
│
┌─────────────────┴─────────────────┐
▼ ▼
┌──────────────┐ ┌──────────────┐
│ Left Node │ │ Right Node │
│ (Descriptor) │ │ (Descriptor) │
└──────┬───────┘ └──────┬───────┘
│ │
┌────────┴────────┐ ┌────────┴────────┐
▼ ▼ ▼ ▼
Original Buffer Add Buffer Original Buffer Add Buffer
(Memory-Mapped) (Append-Only) (Memory-Mapped) (Append-Only)
The document is represented as a balanced red-black tree where every node is a descriptor pointing to a specific slice of either the memory-mapped original file or an append-only memory buffer containing new edits.32 This ensures that insertions and deletions operate at complexity regardless of the document size.32
To build a stable custom editor, the developer can draw valuable lessons from successful, self-driven development projects, such as Joshua Barretto's experience building his own text editor in Rust.38
The initial development phase should focus strictly on core editing capabilities: opening a file, rendering its text, and saving changes.38 The developer should use simple string-backed buffers and hardcode application preferences directly into the binary, avoiding complex configuration parsing and advanced layouts until the editor is stable.38
Once the editor can reliably open and save a file, the developer must replace all default system editors (like nano) with their custom executable for daily tasks.38 Every observed bug, rendering artifact, or missing capability must be logged immediately in a local file and resolved before writing any new, advanced features.38 This practical approach ensures that structural bugs and performance bottlenecks are identified and fixed early in the development cycle.38
Writing input handlers for text selections and cursor movements is notoriously difficult.38 The developer can make this manageable by decomposing all complex keyboard interactions into chains of simple, primitive actions.38
A word-wise deletion command should run as three sequential primitives:
- Calculate and move the cursor to the previous word boundary.
- Extend the selection range from the starting coordinate to the new position.
- Delete the active selection.38
Grouping these individual actions into a single transaction block ensures that the undo/redo history remains intuitive for the user.32
Running syntax highlighting engines (like tree-sitter or regex-based lexers) across an entire file on every keystroke causes significant input lag.38 To maintain low latency, the editor should use a demand-driven cache.38
The text buffer is split into equally sized horizontal chunks.38 Syntax highlighting is computed lazily, running only on the chunks currently visible within the user's viewport.38 When a line is edited, only the overlapping chunk and any subsequent chunks affected by the modification are invalidated, leaving the rest of the cache untouched.38
To further optimize this system, the developer can build a custom regex engine featuring an AST walker optimized for common prefixes (e.g., optimizing hel[(lo)p] to search only for locations beginning with hel), and compiling instructions into a Continuation-Passing Style (CPS) virtual machine that runs directly on bytes rather than slow Unicode code points.38
To ensure the editor remains fast when running over remote SSH connections, the visual output should use a double-buffered layout.3
The editor maintains two internal screen grids: the current frame and the previous frame.38 Before drawing, the system compares the two frames and emits ANSI escape sequences and style modifications only for the specific screen cells that have changed.38 This significantly reduces bandwidth usage and prevents cursor flickering over high-latency connections.38
Heavy operations, such as project-wide file indexing and global regex searches, must be offloaded from the main UI thread.38
The editor should implement a multi-threaded search engine utilizing a work-stealing task scheduler managed by atomic counters.38 This engine recursively walks the directories from the project root, automatically filters out directories defined in .gitignore files, and ranks search results based on their spatial proximity to the active file, ensuring the editor's interface remains completely responsive.38
To deliver a high-quality user experience, a custom text editor built for the Linux operating system must handle several platform-specific windowing and graphics requirements.
┌─────────────────────────────────────────┐
│ Linux OS Platform │
└────────────────────┬────────────────────┘
│
┌─────────────────────────────┼─────────────────────────────┐
▼ ▼ ▼
┌──────────────────┐ ┌──────────────────┐ ┌──────────────────┐
│ X11 / Wayland │ │ GPU Shading │ │ UNIX Clipboards │
│ - Manage bounds │ │ - OpenGL/Vulkan │ │ - Primary selection│
│ - Input focus │ │ - Driver checks │ │ - Standard copy │
└──────────────────┘ └──────────────────┘ └──────────────────┘
The editor must interface reliably with both X11 and Wayland display servers.16 This is achieved by utilizing modern abstraction libraries (such as winit) to manage window bounds, track high-DPI scaling factors, and handle desktop scaling changes seamlessly.
The application must also manage window focus transitions gracefully; if a user clicks an interactive sidebar panel or drags a resize handle, the editor must preserve the keyboard input focus on the text buffer, preventing the UI from freezing or dropping keystrokes.16
On Linux systems, users expect two distinct clipboards: the standard clipboard (accessible via Ctrl+C and Ctrl+V) and the primary selection clipboard.16 The primary selection clipboard stores whatever text is currently highlighted by the cursor.16
The custom editor must actively monitor text selections and write highlighted spans to the primary selection buffer, allowing users to instantly paste text elsewhere using a middle mouse click.16
While rendering layouts directly on the GPU using OpenGL or Vulkan yields excellent performance at high resolutions, Linux graphics drivers can be highly inconsistent and prone to rendering bugs.6
To prevent rendering failures, the editor should implement a defensive graphics strategy:
- On initialization, query the system's OpenGL or Vulkan driver context information.6
- If the driver is missing, unaccelerated, or known to be buggy, the editor should automatically disable hardware acceleration and fall back to a highly optimized CPU-bound software renderer.6
- Provide a command-line flag and a direct configuration setting (e.g., "hardware_acceleration": "software") to allow users to manually override the rendering engine.6
By adopting these system architectures, data structures, and platform integration guidelines, a developer can build a custom, lightweight, and incredibly fast text editor that combines the performance of Sublime Text with the modern, safe, and extensible design patterns of the Rust ecosystem.1
- Zed vs. Sublime Text: An Honest Comparison for 2026, accessed June 8, 2026, https://zed.dev/compare/sublime
- Building a High Performance Text Editor – Will Bond, accessed June 8, 2026, https://wbond.net/thoughts/building_a_high_performance_text_editor
- VS Code vs Neovim: I Used Both for a Year. My Fingers Made the Decision - Devrim Ozcay, accessed June 8, 2026, https://devrimozcay.medium.com/vs-code-vs-neovim-i-used-both-for-a-year-my-fingers-made-the-decision-f54637f3957c
- Lapce: A Rust-Based Native Code Editor Lighter Than VSCode and Zed - Reddit, accessed June 8, 2026, https://www.reddit.com/r/programming/comments/1qhuhw3/lapce_a_rustbased_native_code_editor_lighter_than/
- On Neovim and Helix - Langur Monkey, accessed June 8, 2026, https://tonisagrista.com/blog/2024/on-neovim-and-helix/
- GPU Rendering - Sublime Text, accessed June 8, 2026, https://www.sublimetext.com/docs/gpu_rendering.html
- Faster Rendering Using Hardware Acceleration - News - Sublime HQ, accessed June 8, 2026, https://www.sublimetext.com/blog/articles/hardware-accelerated-rendering
- Lapce: A Rust-Based Native Code Editor Lighter Than VSCode and Zed - Reddit, accessed June 8, 2026, https://www.reddit.com/r/rust/comments/1qhui75/lapce_a_rustbased_native_code_editor_lighter_than/
- How We Rebuilt Settings in Zed — Zed's Blog, accessed June 8, 2026, https://zed.dev/blog/settings-ui
- WebAssembly Text Format — Zed Extension, accessed June 8, 2026, https://zed.dev/extensions/wat
- The Complete Guide to the ZED Editor 2026 Edition: The Full Picture and Capabilities of the Next-Generation Code Editor Built in Rust - note, accessed June 8, 2026, https://note.com/snake_dragon/n/n21504046b929?hl=en
- How to write a Zed extension for a made up language | BAML Blog, accessed June 8, 2026, https://boundaryml.com/blog/how-to-write-a-zed-extension-for-a-made-up-language
- Lapce vs Zed: A Detailed Comparison of Code Editors - How to create an AI agent, accessed June 8, 2026, https://createaiagent.net/comparisons/lapce-vs-zed/
- Lapce - Lightning-fast and Powerful Code Editor - Lapdev, accessed June 8, 2026, https://lap.dev/lapce/
- Rust Bytes: "Meet Lapce, a powerful code editor written in Rust" - Reddit, accessed June 8, 2026, https://www.reddit.com/r/rust/comments/1bbyr9w/rust_bytes_meet_lapce_a_powerful_code_editor/
- Lapce for C++ Development - Loren's blog, accessed June 8, 2026, https://lorendb.dev/posts/lapce-for-cpp-development/
- Should I use Helix or Neovim as someone brand new to vim motions? - Reddit, accessed June 8, 2026, https://www.reddit.com/r/HelixEditor/comments/1abuqf4/should_i_use_helix_or_neovim_as_someone_brand_new/
- It is 2025, so how does Helix compare to Neovim now? - Reddit, accessed June 8, 2026, https://www.reddit.com/r/neovim/comments/1jni3fc/it_is_2025_so_how_does_helix_compare_to_neovim_now/
- Graphics extensions possible? - Plugin Development - Sublime Forum, accessed June 8, 2026, https://forum.sublimetext.com/t/graphics-extensions-possible/35723
- CPU rather than GPU rendering - Technical Support - Sublime Forum, accessed June 8, 2026, https://forum.sublimetext.com/t/cpu-rather-than-gpu-rendering/12450
- Agent Settings - Zed, accessed June 8, 2026, https://zed.dev/docs/ai/agent-settings
- Settings | Lapce Docs, accessed June 8, 2026, https://docs.lapce.dev/get-started/settings
- Trying out Zed after more than a decade of Vim/Neovim | Hacker News, accessed June 8, 2026, https://news.ycombinator.com/item?id=42817277
- JSON Schema Editor - Liquid Technologies, accessed June 8, 2026, https://www.liquid-technologies.com/json-schema-editor
- Generic configuration GUI : r/linux - Reddit, accessed June 8, 2026, https://www.reddit.com/r/linux/comments/1hrspgv/generic_configuration_gui/
- Create your first schema - JSON Schema, accessed June 8, 2026, https://json-schema.org/learn/getting-started-step-by-step
- schemaui - crates.io: Rust Package Registry, accessed June 8, 2026, https://crates.io/crates/schemaui
- schemaui - Rust - Docs.rs, accessed June 8, 2026, https://docs.rs/schemaui
- jdorn/json-editor: JSON Schema Based Editor - GitHub, accessed June 8, 2026, https://github.com/jdorn/json-editor
- Visual JSON Schema Diagram Editor (Design Mode), accessed June 8, 2026, https://www.oxygenxml.com/json_schema_design_mode.html
- Zed vs. Every Editor: Honest Comparisons for 2026, accessed June 8, 2026, https://zed.dev/compare
- The Data Structures Behind Text Editors: Gap Buffers, Piece Tables, Ropes, and CRDTs | by Gaurav Sarma | Apr, 2026, accessed June 8, 2026, https://gauravsarma1992.medium.com/the-data-structures-behind-text-editors-gap-buffers-piece-tables-ropes-and-crdts-8df38a999cce
- Slint | Declarative GUI for Rust, C++, JavaScript & Python, accessed June 8, 2026, https://slint.dev/
- Slint is an open-source declarative GUI toolkit to build native user interfaces for Rust, C++, JavaScript, or Python apps. · GitHub, accessed June 8, 2026, https://github.com/slint-ui/slint
- pop-os/cosmic-text: Pure Rust multi-line text handling - GitHub, accessed June 8, 2026, https://github.com/pop-os/cosmic-text
- cosmic_text - Rust, accessed June 8, 2026, https://pop-os.github.io/cosmic-text/cosmic_text/
- Data Structures for Editing Text - Medium, accessed June 8, 2026, https://medium.com/ytuskylab/data-structures-for-editing-text-c6c153ba64f4
- Writing my own text editor, and daily-driving it - Joshua Barretto, accessed June 8, 2026, https://blog.jsbarretto.com/post/text-editor
- The Linux User's Ultimate Guide to Text Editors - The New Stack, accessed June 8, 2026, https://thenewstack.io/the-linux-users-ultimate-guide-to-text-editors/
- Sublime Text 4 - News, accessed June 8, 2026, https://www.sublimetext.com/blog/articles/sublime-text-4