Specfork

@specfork/text-editor

Desktop text and source code editor. Tabs, encodings and line endings, large files, find and replace with regex and find in files, syntax highlighting, multi-cursor, macros, session restore.

desktopdeveloper-tools Version 0.1.1 101 requirements Licence CC-BY-4.0 Specfork/text-editor

Text editor

One person edits plain text and source code files on their own computer. Files open in tabs, keep their encoding and line endings byte for byte, and can be converted on request. Find and replace works in one file, all open files, or a folder tree, with regular expressions. Languages are described by data files that drive highlighting, comments and folding. Several carets and rectangular selections edit many lines at once, macros repeat edits, and the whole session, unsaved text included, comes back after a restart or crash. Behaviour derived from Notepad++'s open-source code (GPL-3.0-or-later), written fresh, stack-free and for any desktop OS. Not affiliated with or endorsed by Don Ho or the Notepad++ project. The name is used only to credit the source.

Area Prefix Covers
documents.md DOC Tabs, untitled documents, open and close, recent files, split view, command line
files.md FIL Encodings, detection, conversion, line endings, large and binary files, external changes
editing.md EDT Undo, multi-cursor, column editing, line and case operations, indentation, bookmarks
search.md FND Find, replace, extended escapes, regex, mark, find in files, results panel
languages.md LNG Language-definition contract, detection, themes, folding, comments
macros.md MAC Record, replay, repeat, save macros
session.md SES Session restore, unsaved buffers, periodic snapshots, backups on save
view.md VEW Zoom, word wrap, whitespace, margins, status bar
commands.md CMD Command list, shortcut mapping, minimal plugin command interface

Single user, no account, no network: everything runs on one computer (Windows, macOS, Linux). Shortcuts are defaults and can be remapped (CMD-2); Mod = Ctrl on Windows and Linux, Cmd on macOS; Alt = Option on macOS. Line and column numbers shown to the user start at 1.

Commands

Status: Draft · Prefix: CMD

Purpose

Every action is a named command with a remappable shortcut, and add-ons can contribute commands through one small interface.

Requirements

ID Requirement Verified by
CMD-1 Every menu action is a command {id (dotted, stable, e.g. "file.save"), title, category, default_shortcut?}. Ids never change between versions; renamed actions keep their id. menu "Save" → command file.save
CMD-2 Shortcut mapping lists every command, macro and add-on command with its shortcut; the user can assign, clear, or reset one or all. Assigning a shortcut already used asks to move it (the other loses it) or cancel. Saved in the user config folder as JSON {id: shortcut} with only differences from defaults. assign Mod+S to another command → conflict prompt
CMD-3 Shortcut syntax: modifiers Mod, Ctrl, Alt, Shift, Meta joined by + with one key; two-step chords are not supported. On macOS Mod = Cmd and Ctrl is the Control key. Mod+Shift+K on macOS → Cmd+Shift+K
CMD-4 Settings live in one JSON file in the user config folder (per OS convention); portable mode: when a marker file portable sits beside the app, config, sessions, snapshots and macros live beside the app instead. marker present → no files written to the user config folder
CMD-5 Add-on: a folder in the add-ons folder with manifest.json {id, name, version, api_version, entry, commands: [{id, title, shortcut?}]}. Its commands appear in an add-ons menu under its name and in the shortcut mapping as <addon id>.<command id>. install add-on with 2 commands → 2 menu items
CMD-6 Add-on interface (api_version 1): on its command, an add-on can read the active document's text, path, language, encoding, line ending, selections and carets; replace a range or the selections (one undo step per call); open a file; create a new document with text; show a message. Nothing else of the editor is reachable. add-on uppercases selection → one undo restores
CMD-7 Add-on events (subscribe in the manifest): document_opened, document_activated, document_saved, document_closed, each with the document's path or untitled name. subscribe document_saved, save → add-on receives path
CMD-8 Load safety: an add-on with an unsupported api_version, invalid manifest or failing load is skipped with a message naming it; an add-on error during a command is reported and the document is left as before that call. --no-plugins disables all add-ons. manifest api_version 9 → skipped with message

Out of scope

  • Add-on discovery, download, update and signing; add-on UI panels, docking windows and custom lexers.
  • The source's native plugin binary interface and its message list.
  • Command palette (implementations may add one from CMD-1).

Decisions

  • Add-ons get a narrow, versioned document API instead of full editor access: enough for text transforms, safe to keep stable across stacks.

Documents

Status: Draft · Prefix: DOC

Purpose

Open documents as tabs: creating, opening, switching, closing and reopening them, in one or two side-by-side views.

Requirements

ID Requirement Verified by
DOC-1 Each open document is one tab: a file path or an untitled buffer. A new untitled document (Mod+N, or double-click on empty tab bar space) is named new <n> with the lowest free n ≥ 1; it can be renamed without saving. close new 1 with new 2 open, Mod+N → new 1
DOC-2 Tab shows the file name, a modified marker while unsaved, a read-only marker, and the full path as tooltip. Middle-click or the tab's close button closes it. Tabs reorder by drag. edit → marker shown; save → marker gone
DOC-3 Open (Mod+O, multi-select, drag and drop of files onto the window, or command line) a file already open activates its tab instead of opening it again; paths compare case-insensitively on case-insensitive file systems. open same file twice → one tab
DOC-4 Opening a file while the only tab is an empty, unmodified untitled document replaces that tab. fresh start, open file → 1 tab
DOC-5 Closing (Mod+W) a modified document asks save / don't save / cancel; "close all", "close all but this", "close all to the left/right" and "close all unchanged" ask once per modified document, with "save all" and "discard all" choices. Closing the last tab leaves one empty untitled document. close all with 3 modified → prompts offer "save all"
DOC-6 Reopen closed document Mod+Shift+T reopens the most recently closed file at its last caret position, repeatable through the last 20 closed. Recent files list: 10 entries by default (0..30), newest first, missing files removed when chosen with a message. close 2 files, Mod+Shift+T twice → both back
DOC-7 Switch documents: Ctrl+Tab/Ctrl+Shift+Tab in most-recently-used order (setting, default on) or tab order, Ctrl+PgDn/Ctrl+PgUp in tab order. MRU on: A, B, C used in that order, Ctrl+Tab from C → B
DOC-8 Read-only: a file the OS marks read-only, or a document toggled read-only by the user, refuses edits with a short notice; saving such a file asks for "save as". toggle read-only, type → text unchanged
DOC-9 Two views: a document can be moved or cloned to the second view (side by side or stacked, setting). A clone shares the same buffer: edits appear in both, caret and scroll are separate. Optional synchronised vertical and horizontal scrolling. clone, type in view 1 → visible in view 2
DOC-10 Single instance by default: launching again forwards its files and options to the running instance and exits; --new-instance starts another one. open file from file manager → opens as a tab in the running window
DOC-11 Command line: [files…] --line <n> --column <n> --language <id> --read-only --no-session --new-instance --no-plugins; --line/--column place the caret in each given file; unknown options are reported and ignored. --line 120 big.txt → caret on line 120
DOC-12 Document actions: copy full path, copy file name, open containing folder in the OS file manager, rename file on disk (renames an open file and keeps its tab), delete file (to the OS trash after confirmation). rename a.txt → b.txt → tab shows b.txt, undo history kept

Out of scope

  • Project or workspace panels, folder tree side panel, document list panel.
  • Printing and print preview.

Decisions

  • File deletion only to the OS trash: never a permanent delete from the editor.
  • MRU switching default on: it is the common desktop behaviour on all three OSs.

Editing

Status: Draft · Prefix: EDT

Purpose

Changing text fast: undo, several carets, rectangular selections, number columns, line and case operations, indentation, comments and bookmarks.

Requirements

ID Requirement Verified by
EDT-1 Undo Mod+Z, redo Mod+Y and Mod+Shift+Z, limited only by memory. Consecutive typed characters group into one step until the caret moves or 1 s passes. Saving keeps the history; undoing back to the saved state clears the modified marker. type, save, type, undo → not modified
EDT-2 Multiple carets: Mod+click adds a caret (setting, default on); Mod+D adds the next occurrence of the selection (or of the word at the caret) as a new selection; Esc returns to one caret. Typing, deleting, moving and selecting apply at every caret. 3 carets, type x → 3 x inserted
EDT-3 Paste with N carets when the clipboard holds exactly N lines puts one line at each caret, in caret order; otherwise the whole clipboard at each caret. 3 carets, paste a\nb\nc → a, b, c
EDT-4 Rectangular selection: Alt+drag or Alt+Shift+arrows. Typing or pasting replaces the block on every line; past a line's end, spaces are added as needed (virtual space). Copying a block puts one line per row on the clipboard and marks it rectangular, so pasting re-creates a block. select 3-line block, type # → # on 3 lines at same column
EDT-5 Column editor (on a rectangular selection or the caret column through the following lines): insert text, or numbers with initial, step, repeat (each value N times), base (dec, hex, oct, bin) and pad (none, zeros, spaces) to the widest value. 5 lines, initial 8, step 1, pad zeros → 08..12
EDT-6 Line commands on the selected lines or the caret line: duplicate Mod+Shift+D, delete Mod+Shift+K, move up Alt+Up, move down Alt+Down, join (with one space), split at the edge column. caret line 3, Alt+Up → becomes line 2
EDT-7 Sort lines (selection or whole document): ascending or descending; text (code-point order), text_ignore_case, locale, integer, decimal (both use the first number on the line; lines without one sort first); stable. sort integer 10, 9, a → a, 9, 10
EDT-8 Clean-up commands: remove duplicate lines (all or consecutive only, keeping the first), remove empty lines (or also whitespace-only), trim trailing, trim leading, trim both, tabs→spaces and spaces→tabs (leading only or all) using the tab width. Each is one undo step. a, b, a remove duplicates → a, b
EDT-9 Case: upper Mod+Shift+U, lower Mod+U, title case, sentence case, invert; Unicode-aware. džemal title → Džemal
EDT-10 Indentation per language: tab_width (default 4, 1..16) and use_spaces (default off). Enter keeps the previous line's indentation (setting, default on). Tab/Shift+Tab on a multi-line selection indents or outdents every selected line. select 3 lines, Tab → each starts with one tab
EDT-11 Comments from the language definition (LNG-1): toggle line comment Mod+/ (adds when any selected line lacks it, else removes); block comment Mod+Shift+/ wraps the selection; languages without the needed form disable the command. toggle on 2 Python lines → both start with #
EDT-12 Matching pairs: the bracket at or before the caret and its partner are highlighted (default on); Mod+B jumps to the partner. Auto-closing of ( [ { " ' (each optional, default off) inserts the closer and types over it when typed next. caret after ( → its ) highlighted
EDT-13 Word completion: after completion_min_chars (default 3, 1..9) word characters, a list offers matching words from the document and the language's keywords, sorted alphabetically; Enter or Tab accepts, Esc closes. Setting off by default for large files (FIL-12). type fun in a JS file → function offered
EDT-14 Bookmarks: toggle Mod+F2, next F2, previous Shift+F2, clear all; shown in a margin; they move with their lines and are removed with them. Commands to cut, copy, delete or keep only bookmarked lines. bookmark line 5, insert 2 lines above → bookmark on line 7
EDT-15 Go to line Mod+G: a line number, or a character offset when chosen; out-of-range values go to the last line. Overwrite mode toggles with Insert. Mod+G 9999 in a 100-line file → line 100

Out of scope

  • Code intelligence: symbol lists, go to definition, call tips, linting.
  • Spell checking; snippets.

Decisions

  • Mod+D adds the next occurrence and duplicate moves to Mod+Shift+D: the multi-caret binding is what users of current editors expect; the source uses other keys.
  • Delete line is Mod+Shift+K to avoid clashing with select-all-occurrence bindings.

Files

Status: Draft · Prefix: FIL

Purpose

Read and write files exactly: encodings, byte order marks, line endings, detection, explicit conversion, very large or binary files, and changes made by other programs.

Requirements

ID Requirement Verified by
FIL-1 Encodings: utf-8 (no BOM), utf-8-bom, utf-16le and utf-16be (with BOM; also read without), and legacy code pages, at least windows-1250..1258, ISO-8859-1..16 (not 12), KOI8-R, KOI8-U, IBM437, IBM850, Mac Roman, Shift_JIS, EUC-JP, GBK, GB18030, Big5, EUC-KR, TIS-620. Names follow the WHATWG/IANA labels. open each test file → text shown correctly
FIL-2 Round trip: opening and saving without edits writes the same bytes: same encoding, BOM, line endings (mixed ones too) and trailing newline or none. open + save 50 sample files → all byte-identical
FIL-3 Detection order on open: BOM (UTF-8, UTF-16 LE/BE) → UTF-16 without BOM when, in the first 4 KiB, ≥ 40 % of bytes at one parity are 0x00 and none at the other → an encoding declared in the first 1 KiB (<?xml … encoding=…?>, <meta charset=…>) → valid UTF-8 (pure ASCII counts) → statistical guess (setting, default on) → the fallback_encoding setting (default windows-1252). UTF-8 file without BOM containing é → utf-8
FIL-4 Bytes invalid in the document's encoding are shown as visible hex markers (e.g. xE9), kept byte for byte when saving, and counted in the status bar tooltip. UTF-8 file with one stray 0xE9 → marker shown, saved unchanged
FIL-5 "Reinterpret as " reloads the file bytes with that encoding, changes nothing on disk and does not mark the document modified; on a modified document it first asks to discard unsaved changes. reinterpret windows-1251 file as KOI8-R → text changes, not modified
FIL-6 "Convert to " keeps the text, changes the encoding used on the next save and marks the document modified. Characters the target cannot represent are listed (first 20 with line:column) and the conversion asks to proceed (they become ?) or cancel. convert € text to ISO-8859-1 → warning names line:column
FIL-7 New documents use default_encoding (default utf-8). A setting also applies it to opened pure-ASCII files (default on), so typed non-ASCII text saves as UTF-8. new doc, type ü, save → bytes C3 BC
FIL-8 Line endings crlf, lf, cr. A document's type = the first line ending in the file; a file with none uses default_eol (default: CRLF on Windows, LF elsewhere). Enter inserts the document's type; pasted text is normalised to it (setting, default on). LF file, press Enter → 0A inserted
FIL-9 "Convert line endings to " rewrites every line ending, mixed ones included, as one undo step, and marks the document modified. file with CRLF and LF lines → all LF after convert
FIL-10 Saving (Mod+S) writes to a temporary file in the same folder and replaces the original, keeping its permissions; where that is not possible (no rights to the folder) it writes in place. Failure leaves the old file intact and the document modified. "Save as" Mod+Alt+S, "save a copy as", "save all" Mod+Shift+S. disk full during save → original unchanged
FIL-11 Saving to a location that needs higher OS rights tells the user and offers "save as"; the editor never elevates itself silently. save to a protected folder → message, no write
FIL-12 Large files: at or above large_file_size (default 200 MiB, settable 1..4096 MiB) the document opens without syntax styling, word wrap, matching-pair highlight, auto-completion, occurrence highlight or clickable links, each re-enableable per setting. Opening shows progress with cancel. Files over 2 GiB ask to confirm first. open 300 MiB log → opens plain, scrolling stays smooth
FIL-13 A file with a 0x00 byte in its first 8 KiB that is not UTF-16 opens as text with visible markers for control bytes and saves byte for byte. open small binary, save → identical
FIL-14 External changes: on window focus and through a file watcher, each open file is checked (size, modification time). Setting on_external_change: ask (default), reload (silent when the document has no unsaved changes, else ask), off; plus follow_end (after reload, scroll to the end). The prompt appears when that document is active. ask, another app appends a line → prompt on focus; yes → line shown
FIL-15 Reload keeps caret line, scroll position and bookmarks where those lines still exist, and adds an undo point so the reload can be undone. reload after append, Mod+Z → previous text
FIL-16 A file deleted or moved by another program: the prompt offers keep (document stays open, marked modified so it can be saved again) or close. delete open file outside → prompt; keep → modified marker

Out of scope

  • Remote files (SFTP, cloud); file locking against other programs.
  • Hex editing view.

Decisions

  • Pure-ASCII files are treated as UTF-8 by default (the source treats them as the system code page): typed non-ASCII text then saves portably on every OS.
  • Fallback legacy code page is a setting instead of the OS code page: macOS and Linux have no system "ANSI" code page.
  • Mixed line endings are preserved until the user converts; the document type is only for new lines.

Languages

Status: Draft · Prefix: LNG

Purpose

Languages are data: a language-definition file says how to colour, comment and fold a kind of file, and a theme says how each kind of token looks.

Requirements

ID Requirement Verified by
LNG-1 Language definition (JSON): {id, name, extensions[], first_line[] (regex), case_sensitive, line_comment, block_comment {open, close}, keyword_groups (≤ 8 lists of words), operators[], delimiters (≤ 8: {open, close, escape}), numbers {prefixes[], suffixes[], extra_chars[], range_separator}, folds {code: [{open, middle?, close}] (≤ 3), comment: [{open, close}]}}. Every field but id and name is optional. load a minimal {id, name} → valid, everything plain
LNG-2 Tokens the highlighter emits: default, comment, comment_line, number, keyword1..keyword8, operator, delimiter1..delimiter8, fold_open, fold_close. Built-in languages may add their own token classes, each falling back to one of these for themes that do not name it. theme without string → strings shown as delimiter1
LNG-3 Matching rules: keywords match whole words, ignoring case unless case_sensitive; a keyword ending in * matches any word starting with it; delimiters span lines until their close and honour their escape character; comments and delimiters win over keywords inside them. "a\"b" with escape \ → one delimiter token
LNG-4 The editor ships definitions for at least: plain text, C, C++, C#, Java, JavaScript, TypeScript, JSON, Python, Ruby, PHP, Go, Rust, Shell, PowerShell, Batch, SQL, HTML, XML, CSS, Markdown, YAML, INI, Makefile, Lua, Perl, Diff. Users add or override definitions by dropping files into a user folder; a user file with a built-in id replaces it. user file id: python → used instead of built-in
LNG-5 Language of a document, first match: user choice for that document (menu or --language) → extension (case-insensitive; user definitions before built-ins) → first line: #! interpreter name (python3 → python), <?xml → xml, <!DOCTYPE html/<html → html, <?php → php, then each definition's first_line patterns → plain text. Saving with a new extension re-detects unless the user chose. script with #!/usr/bin/env bash → shell
LNG-6 Theme (JSON): {name, dark: bool, default: style, styles: {token: style}, ui: {caret, selection, current_line, margin, fold_margin, whitespace, edge, marks}} where style = {fg, bg, bold, italic, underline, font?, size?} with colours #RRGGBB; missing fields inherit from default. Ships a light and a dark theme; the default follows the OS appearance. OS switches to dark → dark theme applied
LNG-7 Highlighting is incremental: the visible range is styled first; after an edit only from the edited line onwards until the styling state matches the previous run; typing in a 10 MB file stays under 16 ms per keystroke. type in 10 MB C file → no visible lag
LNG-8 Folding: a margin shows fold points from folds (and from indentation for languages that set fold_by_indent); fold/unfold current Mod+Alt+[/Mod+Alt+], fold all Alt+0, unfold all Alt+Shift+0, fold level n Alt+<n> (1..8). Editing inside a folded block unfolds it. fold all in a 3-function file → 3 folded blocks
LNG-9 A language editor lets users create, copy, rename, delete, import and export definitions (LNG-1 files) and preview them on sample text; export then import gives an identical definition. export, delete, import → identical JSON
LNG-10 A broken definition or theme file (invalid JSON, unknown field type, > 8 groups) is skipped with a message naming the file and problem; the rest load. malformed file → message, other languages fine

Out of scope

  • Language servers, semantic highlighting, code outline panel.
  • The source's per-language lexer internals; grammar formats from other editors.

Decisions

  • One JSON contract for user and built-in languages: the source has a compiled lexer per language and a separate user format; here built-ins may still use richer engines but must expose the same token names.
  • Theme follows OS appearance by default on all three OSs.

Macros

Status: Draft · Prefix: MAC

Purpose

Record a sequence of edits once and replay it, a set number of times or down to the end of the document, and keep useful macros with names and shortcuts.

Requirements

ID Requirement Verified by
MAC-1 Start and stop recording Mod+Shift+R; a recording indicator shows while active. Recording a new macro replaces the current unsaved one. record → indicator; stop → indicator gone
MAC-2 Recorded steps: typed text, caret moves and selections by keyboard, editing commands (EDT-6..EDT-9, clipboard, indent, comment), and find or replace runs with all their options. Mouse clicks, dialogs that open files, and settings changes are not recorded; the user is told when recording stops which were skipped. record with a mouse click → "1 action not recorded"
MAC-3 Play Mod+Shift+P runs the current macro once at the active caret. record Home, #, Down; play → next line commented
MAC-4 Run multiple: N times (1..100000) or until the end of the document; "until end" stops when a run reaches the last line, when the caret did not advance during a run, or when a recorded find finds nothing. 10-line file, macro edits and moves down → stops after line 10
MAC-5 A whole playback (all repetitions) is one undo step. run 50 times, Mod+Z once → document as before
MAC-6 Save current macro with a name (unique, 1..64 chars) and optional shortcut (CMD-2 conflict rules); saved macros appear in a macro menu, survive restarts, and can be renamed, re-bound or deleted. save "prefix", restart → listed and runnable
MAC-7 Macro file (JSON, in the user config folder): [{name, shortcut?, steps: [{type: "command", id} | {type: "text", value} | {type: "find", mode, find, replace?, options, action: "next"|"replace"|"replace_all"}]}]. Unknown step types make that macro unavailable with a message, others still load. hand-edit a bad step → that macro disabled, others work
MAC-8 Playback with multiple carets or a rectangular selection applies each step at every caret as typing would (EDT-2). 3 carets, play End, ; → 3 lines end in ;

Out of scope

  • A scripting language; editing macro steps inside the app (the file can be edited).

Decisions

  • One undo step per playback: replay is a single user intention; the source undoes step by step.

Session

Status: Draft · Prefix: SES

Purpose

Quit and come back to exactly where you were, unsaved text included, even after a crash, and keep optional copies of files before they are overwritten.

Requirements

ID Requirement Verified by
SES-1 With remember_session (default on), quitting stores per view: open documents in tab order, the active one, and per document: path or untitled name, caret and selections, first visible line, folded lines, bookmarks, chosen language and encoding (when user-set), read-only flag and zoom. Starting restores it. 5 tabs, caret line 40 in tab 3, quit, start → same tabs, caret line 40
SES-2 Files given on the command line open in addition to the session and become active; --no-session opens only them. Files that no longer exist are skipped, and a message lists them. delete one session file, start → message names it
SES-3 Unsaved buffers (snapshot, default on): every snapshot_seconds (default 7, 1..3600) each modified or untitled document whose text changed since its last snapshot is written to the app's backup folder. Quitting does not ask to save; the next start restores those documents with their unsaved text, still marked modified, and untitled ones with their names. type in new 1, quit, start → text back, modified
SES-4 After a crash or forced end, the next start restores from the last snapshots (SES-3), so at most snapshot_seconds of typing is lost. kill process 10 s after typing → text restored
SES-5 A file changed on disk while its unsaved snapshot exists: on restore the snapshot text is shown, marked modified, and the external-change prompt (FIL-14) offers reloading the disk version. edit file on disk between sessions → restored snapshot + prompt
SES-6 A snapshot is deleted when its document is saved, closed with "don't save", or becomes unmodified through undo; the backup folder holds nothing else. Snapshots are plain files readable only by the current user. save → snapshot file gone
SES-7 Turning snapshot off: quitting asks save / don't save / cancel for each modified document again (DOC-5). setting off, quit with edits → prompt
SES-8 Backup on save, setting backup: none (default), simple (copy the old file to <name>.bak next to it, overwriting), timestamped (copy into the backup folder or a chosen folder as <name>.<YYYY-MM-DD_HHmmss>.bak). A failed backup aborts the save with a message. simple, save twice → one .bak with the version before the last save
SES-9 Named sessions: save the current set of documents as a session file (JSON, same data as SES-1 without unsaved text) and load one later, replacing or adding to open documents (choice). save session, close all, load → same tabs

Out of scope

  • Syncing sessions between computers; per-project sessions tied to folders.

Decisions

  • Snapshot on by default: losing typed text is worse than a quit that does not ask.
  • Snapshots are separate from backup-on-save: one protects unsaved text, the other protects the previous saved file.

View

Status: Draft · Prefix: VEW

Purpose

How text is shown: zoom, word wrap, invisible characters, margins, guides and the status bar.

Requirements

ID Requirement Verified by
VEW-1 Zoom per view: level −10..+20 added to the base font size in points (minimum shown size 2 pt); Mod+= / Mod+- one step, Mod+0 resets to 0, Mod+wheel steps; the level shows in the status bar while not 0. Optional sync of both views (default off). Mod+= 3 times → level +3
VEW-2 Word wrap toggle (Alt+Z, default off) wraps at the view's width on word boundaries (or any character when a word is wider); wrapped parts may keep the first part's indentation (setting wrap_indent, default on). Line numbers and Mod+G count file lines, not wrapped rows. 200-char line, wrap on → several rows, one line number
VEW-3 Show whitespace (spaces as dots, tabs as arrows), show line endings (CR, LF, CRLF markers), and show all; each a toggle, default off. Control and invalid bytes are always visible (FIL-4). show line endings in a mixed file → both marker kinds
VEW-4 Margins: line numbers (default on, width grows with line count), bookmarks, folding. Indent guides (default on) at each tab stop within leading whitespace. Edge column (default off, column 80, setting 1..1000) as a line or background colour. Current line highlight (default on). 10,000-line file → numbers fully visible
VEW-5 Status bar: language name, document length in characters and line count, Ln, Col (column counts tabs to the next tab stop), Sel (characters and lines; with several selections, their totals and count), line ending type, encoding, insert or overwrite. Clicking the line ending or encoding opens the convert or reinterpret menu. select 2 lines of 5 chars → Sel: 11 | 2 with LF
VEW-6 Full screen F11 hides menus and toolbars; distraction-free mode also hides tabs and margins and centres the text at 80 characters wide (setting 40..400). Esc or the same key leaves. F11 → only text and scrollbars
VEW-7 Clickable links: URLs (http, https, ftp, file, mailto) are underlined and open with Mod+click (or double-click, setting) in the OS handler. Default on, off for large files. Mod+click https://example.org → OS browser opens
VEW-8 Base font, size, line spacing and caret width and blink rate are settings; caret position and scroll are never changed by changing them. change font size → caret on same character

Out of scope

  • Document map, minimap, function list panels; tab bar themes; toolbar customisation.

Decisions

  • Column in the status bar counts visual columns with tab expansion, not characters: it matches what an edge column at 80 shows.
  • Alt+Z for word wrap, matching another common editor; the source has no default key.

From Specfork/text-editor at 720f295, licence CC-BY-4.0.