jot is a modern terminal code editor written in C++17. It is built around a
modeless editing workflow with direct typing, standard editor shortcuts, mouse
selection, and terminal-native power commands. Keep multiple files open, split
panes, browse a workspace tree, search across a project, run terminal tasks,
debug programs, and use native LSP features without leaving the terminal.
The installed binary name is jot.
- Modeless editor UX with mouse support, selections, tabs, split panes, minimap, status bar, command palette, and a workspace sidebar.
- Native C++ core for buffers, panes, syntax, LSP, debugging, Git, terminal emulation, and workspace state.
- Tree-sitter syntax highlighting with runtime grammar installation, status, reload, fallback queries, and richer theme slots for semantic captures.
- Native LSP support for diagnostics, completion, hover, definition jumps, document symbols, server lifecycle, and lightweight server install/remove helpers.
- Integrated terminal panel with multiple shell tabs plus local/global task runner support.
- GDB/LLDB Debug Adapter Protocol panel with launch/config/attach flows, breakpoints, threads, stack, variables, memory, disassembly, and output.
- Git workflow commands for status, diffs, staging, unstaging, committing, log, blame, and refresh.
- Python-backed colorschemes only; editor behavior is owned by the C++ core.
Officially supported platforms:
- Linux x86_64 / arm64
- macOS Intel / Apple Silicon
Experimental platform target:
- Windows 10/11 with MSVC and Windows Terminal
Notes:
jotrelies on POSIX terminal APIs (termios,poll, PTY/forkpty) for the Linux/macOS editor UI and integrated terminal.- Linux and other non-Apple Unix builds link
libutilfor PTY support. - macOS uses native system PTY APIs without a
libutillink. - Windows uses a Win32 console backend for the main editor UI. Integrated terminal ConPTY support and Tree-sitter source installation are still pending.
For a user-local install:
./install.shBy default, the installer configures, builds, and installs to $HOME/.local.
It also runs CTest and attempts Tree-sitter runtime setup unless
--skip-tests or --skip-treesitter is passed.
Use ./install.sh --help for prefix, build type, test, Tree-sitter, formatter,
and LSP tooling options.
Manual CMake install:
cmake -S . -B build -DCMAKE_BUILD_TYPE=Release
cmake --build build -j
cmake --install build --prefix "$HOME/.local"Experimental Windows/MSVC build:
cmake --preset windows-msvc-vs2026-vcpkg
cmake --build --preset windows-msvc-vs2026-vcpkg-debugThe generated solution is build\vs2026-x64\jot.sln. You can open it directly
in Visual Studio after configure, or open the folder and select the preset.
If VS Code CMake Tools keeps configuring build with -A win32, run
CMake: Delete Cache and Reconfigure, then select the
windows-msvc-vs2026 configure preset.
Use 64-bit MSVC and 64-bit Python. The experimental Windows target does not
support -A win32. Python development files are required. libuv and
utf8proc are fetched automatically when CMake packages are unavailable; set
JOT_FETCH_DEPS=OFF if you want to provide them through vcpkg or another package
manager. Tree-sitter runtime support can be enabled after installing a compatible
tree-sitter package and parser DLLs.
Installed files include:
$prefix/bin/jot$prefix/share/jot/python/$prefix/share/jot/configs/
jot
jot path/to/file.cpp
jot path/to/projectLaunch behavior:
- no argument: resume the most recent valid workspace session, or show the home menu when no session exists
- file argument: open that file in an editor session
- directory argument: change into that directory, use it as the workspace root, load the file tree, open the sidebar, and restore that workspace session
Workspace sessions are stored under:
~/.config/jot/workspaces/
- Modeless text entry with direct typing by default.
- Undo/redo, copy/cut/paste, select all, mouse selection, double-click word selection, and triple-click line selection.
- Multi-line paste with optional smart indentation rebased to the cursor context.
- Auto-indent, optional indent detection, tab insertion, selection indent, and selection outdent.
- Auto-closing brackets, bracket matching, bracket jump, rainbow bracket colors, and active bracket guide rendering.
- Duplicate/delete current line, move current line or selection up/down, join lines, trim trailing whitespace, and trim blank lines in a selection.
- Uppercase/lowercase transforms for the selection or current word.
- Sort, sort descending, reverse, deduplicate, and shuffle selected lines.
- Replace commands for case-sensitive, case-insensitive, whole-word, and regex replacement.
- Surround/unsurround selection or current word.
- Increment/decrement number at cursor.
- Format document command.
- Word-wise deletion, smart line-start movement, file start/end movement, and page movement.
- Buffer statistics and current date/time insertion.
- Multiple open buffers, including saved files and unsaved buffers.
- Pane-local file tabs with click-to-switch and close buttons.
- Reopen last closed tab.
- Split panes left/right/up/down.
- Directional pane focus and pane resize by keyboard or mouse drag.
- Close current pane without necessarily closing the underlying buffer.
- Open, save, save-as, save-and-quit, close buffer, quit, and force quit commands.
- Autosave on/off/toggle/status plus configurable autosave interval.
- Workspace root from the current directory or a launched folder.
- Sidebar file explorer with folders before files, hidden-file toggle, expand all, collapse all, refresh, and parent-folder workspace navigation.
- Keyboard and mouse navigation for the sidebar.
- Create file, create folder, rename, and delete file/folder workflows.
- Recent files and recent workspace resume.
- Home menu with recent entries, new file, command palette, theme chooser, and recent prompt entry points.
- C++ helper commands for creating matching header/source pairs and generating missing source implementations from declarations.
- Buffer-local search panel with next/previous match navigation.
- Search options for case sensitivity, whole-word matching, and regex mode.
- Replace panel with replace current and replace all actions.
- Selection-scoped replace from
Ctrl+Shift+F, with replacements limited to the highlighted code. - Go to line or line:column.
- Bookmarks.
- Telescope file finder with mouse selection/scrolling and syntax-highlighted previews.
- Project-wide text search picker.
- Diagnostics picker and next/previous diagnostic navigation.
- Document symbol/outline picker using LSP symbols when available and a regex fallback for supported buffers.
- Tree-sitter parser-based highlighting when the runtime and grammar are available.
- Built-in regex fallback highlighting for common file types.
- Runtime Tree-sitter commands to install grammars, inspect status, and reload parser/query caches.
- Built-in and minimal query fallback paths for C++ so highlighting remains Tree-sitter-backed when runtime queries are incompatible.
- Rich Tree-sitter capture mapping for variables, parameters, fields, constants, builtins, operators, punctuation, control/storage/preprocessor keywords, methods, constructors, builtin types, macro constants, string escapes, tags, attributes, namespaces, and modules.
- Theme slots for both classic syntax colors and richer Tree-sitter captures.
- Code folding with gutter indicators, toggle/collapse/expand commands, fold all, unfold all, mouse toggling, and persisted collapsed ranges.
Built-in fallback syntax rules cover common file types including:
- C / C++:
.c,.cpp,.h,.hpp - Python:
.py - JavaScript / JSX / TypeScript / TSX:
.js,.jsx,.mjs,.cjs,.ts,.tsx,.mts,.cts - HTML / XML:
.html,.xml - Rust:
.rs - CSS:
.css - Java:
.java - Go:
.go - Markdown:
.md - JSON:
.json - Shell:
.sh,.bash,.zsh - Ruby:
.rb - PHP:
.php
- Native C++ LSP client ownership; Python is not used to drive editor behavior.
- One LSP client per language and workspace root.
- File open/change/save notifications with debounced document sync.
- Diagnostics overlay, diagnostics picker, and next/previous diagnostic jumps.
- Completion dropdown with fuzzy filtering,
textEditsupport, and plain-text snippet degradation. - Manual and trigger-character completion requests.
- Hover popup by command or debounced mouse hover.
- Go to definition, preview/cross-file open, Ctrl-click definition requests when
terminal mouse modifiers are available, and
:lspbackreturn stack. - Document symbols from LSP with regex fallback.
- LSP status, start, stop, restart, manager, install, and remove commands.
Default language server commands:
- Python:
pylsp - JavaScript / JSX / TypeScript / TSX:
typescript-language-server --stdio - HTML:
vscode-html-language-server --stdio - C / C++:
clangd
The LSP manager/install/remove helpers expose language entries for Python, JavaScript/JSX/TypeScript/TSX, HTML, C++, Rust, Go, Lua, and Bash.
- Bottom terminal panel backed by PTY and libvterm.
- Native shell launch using
$SHELLwhen available, with fallback shell paths. - Multiple terminal tabs.
- Mouse terminal tab switching, closing, and
+tab creation. - Terminal instances remain alive while hidden.
Escreleases terminal focus back to the editor.- Local and global task files:
<workspace>/.jot/tasks.json
~/.config/jot/configs/tasks.json
Task schema:
{ "tasks": { "build": "cmake --build build -j" } }Local tasks override global tasks with the same name. :task lists tasks,
:task <name> runs or reuses a task tab, :tasknew <name> starts a fresh task
tab, and :taskrerun reruns the last task.
- Opens common image files in a right-side viewer.
- Uses real terminal graphics when available: Kitty graphics first, Sixel
through
img2sixelsecond, then the 256-color cell preview fallback. - Configure with
image_viewer_backend = auto; supported values areauto,kitty,sixel,cell, andoff.
- Native Debug Adapter Protocol client integration.
- GDB and LLDB launch commands.
debug.jsonconfigured sessions from the workspace or global config.- Attach-to-PID command.
- Toggle breakpoints by clicking the editor gutter marker column.
- Continue, pause, restart, stop, step into, step over, and step out commands.
- Threads, stack, variables, memory, disassembly, breakpoints, and output views in the debugger panel.
Debug config locations:
<workspace>/.jot/debug.json
~/.config/jot/configs/debug.json
Debug config shape:
{
"sessions": {
"app": {
"adapter": "gdb",
"program": "./build/app",
"args": [],
"cwd": ".",
"env": {}
}
}
}- Git status summary in the editor state/status surfaces.
- Popup commands for
status, unstaged diff, staged diff, recent log, and blame for the current line. - Stage/unstage current or specified file.
- Stage all and unstage all.
- Commit staged changes with an explicit message.
- Refresh repository state.
Git operations are local only; push, pull, fetch, reset, checkout, and discard are intentionally not exposed as editor commands.
- Embedded Python runtime for colorscheme discovery and application.
- Bundled and user theme directories.
vimcompatibility alias for existing theme files.- Neovim-style highlight group mapping for classic groups and Tree-sitter captures.
- Theme chooser,
:theme, and:colorschemecommands.
User theme paths:
~/.config/jot/configs/colors/
~/.config/jot/themes/
See docs/THEMES.md for theme authoring.
- Top application/menu chrome, pane file tabs, editor panes, optional sidebar, optional minimap, optional right-side tool dock, bottom terminal/debugger panels, and two-row status/message area.
- Mouse click to place cursor, drag to select, edge auto-scroll while dragging, double-click word selection, and triple-click line selection.
- Mouse tab switching and close buttons.
- Mouse split resizing.
- Mouse minimap viewport jump.
- Mouse sidebar navigation.
- Mouse debugger breakpoint toggles.
- Context menus and menu-bar actions route to existing editor commands.
- Modeless text entry: typing inserts at the cursor immediately.
Esc: clear selection or release/close the active floating surface.Ctrl+Z/Ctrl+Y: undo / redoCtrl+A: select allCtrl+C/Ctrl+X/Ctrl+V: copy / cut / pasteCtrl+D: duplicate current lineCtrl+K: delete current lineCtrl+/: toggle commentCtrl+Backspace: delete previous wordCtrl+Delete: delete next wordCtrl+Enter: insert a new line below without splitting the current lineCtrl+Shift+Enter: insert a new line above without splitting the current lineAlt+Enter/Alt+Shift+Enter: terminal fallback for line below / aboveCtrl+Space: request LSP completionCtrl+Shift+L: select current lineCtrl+Shift+U: uppercase selection or wordCtrl+Shift+N: lowercase selection or word
Arrow keys: move cursorShift+Arrow keys: extend selectionHome/End: smart line start / line endPage Up/Page Down: move by 10 linesAlt+I/Alt+A: smart line start / line endAlt+G/Alt+Shift+G: file start / file endAlt+H/Alt+L: previous / next wordAlt+Up/Alt+Down: move current line or selection up/downTab: indent selection or insert indentationShift+Tab: outdent selection
Ctrl+Tab/Ctrl+Shift+Tab: next / previous pane-local tabAlt+,/Alt+.: previous / next pane-local tabAlt+1..9/Alt+0: switch to tab 1..9 / last tabAlt+W: close current file tabAlt+N: new bufferAlt+S: saveCtrl+BorAlt+B: toggle sidebarCtrl+ForAlt+F: search panelCtrl+G: go-to-line promptCtrl+PorAlt+P: command paletteCtrl+E: Telescope file finderCtrl+R: recent-file promptCtrl+Shift+T: reopen last closed tabCtrl+Shift+F: replace inside selected text, or project-wide search when no text is selectedCtrl+Shift+M: diagnostics pickerCtrl+Shift+O: document symbolsCtrl+MorAlt+M: toggle minimapCtrl+TorAlt+T: theme chooser- `Ctrl+``: open, focus, or hide terminal panel
Alt+H/J/K/L: focus pane or explorer left/down/up/rightCtrl+Alt+H/J/K/L: split left/down/up/rightCtrl+Alt+Arrow: focus pane in that directionCtrl+Alt+Q: close current paneCtrl+Shift+H/J/K/L: resize paneCtrl+Arrow: resize pane
Enter,Arrow Down, orCtrl+F: next matchArrow Up: previous matchTab: toggle case-sensitive search, or switch fields when replace is openCtrl+H: show/hide replace fieldCtrl+R: replace current matchCtrl+Shift+R: replace all matchesCtrl+W: toggle whole-word searchCtrl+E: toggle regex searchEsc: close search
Arrow Up/k: move upArrow Down/j: move downPage Up/Page Down: fast scrollHome/End: first / last nodeArrow Right/l/Enter: expand folder or open fileArrow Left/h: collapse folder or move to parent noder: refresh treea: create file in selected folderA: create folder in selected folderi: generate missing C++ implementationsC: create matching C++ header/source paird, thendagain: delete selected file or folder.: show/hide dotfiles*: expand all recursivelyz: collapse allBackspace: open parent folder as workspace rootEsc: return focus to editor
- Quick pick: type to filter,
Up/Downto move,Home/Endto jump,Enterto accept,Backspaceto edit,Escto close - LSP completion:
Up/Downto select,EnterorTabto apply,Escto close
- `Ctrl+``: show, hide, or focus terminal panel
Ctrl+Shift+T: create a new terminal tab while terminal focus is activeEsc: release terminal focus- Mouse click terminal tab: focus tab
- Mouse click
+: create tab - Mouse click tab close button: close tab
Open the command palette with Ctrl+P and run ex-style commands.
:q,:quit,:q!,:quit!:w,:write,:wq,:x,:xit:e <file>,:edit <file>,:open <file>:new,:enew:bd,:bdelete,:close:home,:resume:recent,:openrecent [index|query]:reopen,:reopenlast:autosave [on|off|toggle|status|<ms>]
:sp,:split,:splith:vsp,:splitv:splitleft,:splitright,:splitup,:splitdown:spleft,:spright,:spup,:spdown:bn,:nextpane,:bp,:prevpane:focusleft,:focusright,:focusup,:focusdown:wincmd h|j|k|l:resizeleft,:resizeright,:resizeup,:resizedown:minimap:theme <name>,:colorscheme <name>,:colo <name>:help [topic],:h [topic]
:find [dir],:ff [dir]:mkfile <path>:mkdir <path>:rename <old_path> <new_path>:rm <path>:cpppair <path>:cppimpl [header-or-source]
:search:grep <text>,:projectsearch <text>,:searchall <text>:diagnostics,:problems:diagnext,:diagnosticnext,:diagprev:symbols,:outline:line <line>[:col],:goto <line>[:col]:format,:trim,:trimblank:upper,:lower:sortlines,:sortdesc,:reverselines,:uniquelines,:shufflelines,:joinlines:dupe:replace <from> <to>,:replacei <from> <to>,:replaceword <from> <to>,:replacere <pattern> <replacement>:surround <left> [right],:unsurround:fold,:collapse,:unfold,:expand,:togglefold,:foldall,:unfoldall:incnum,:decnum:copypath,:copyname:datetime,:stats
:lspstart,:lspstatus,:lspstop,:lsprestart:lspmanager:lspinstall <python|typescript|javascript|jsx|tsx|cpp|rust|go|lua|bash|html>:lspremove <python|typescript|javascript|jsx|tsx|cpp|rust|go|lua|bash|html>:hover,:lsphover:definition,:lspdefinition,:lspdef,:gd:lspback
:tsinstall <language>,:treesitterinstall <language>- JavaScript / JSX:
:tsinstall javascriptor:tsinstall jsx - TypeScript / TSX:
:tsinstall typescriptand:tsinstall tsx :tsstatus:tsreload,:treesitterreload
:term,:terminal:termnew,:terminalnew:task [name]:tasknew <name>:taskrerun
:debug <program> [args...]:debuggdb <program> [args...]:debuglldb <program> [args...]:debugconfig [name]:debugattach <pid>:debugpanel:debugstop,:debugrestart:debugcontinue,:debugpause:debugstep,:debugnext,:debugout:debugthreads:debugmemory <expr|addr>:debugdisasm [expr|addr]
:gitstatus:gitdiff [file]:gitdiffstaged [file]:gitstage [file]:gitunstage [file]:gitstageall:gitunstageall:gitcommit <message>:gitlog:gitblame:gitrefresh
User config lives in:
~/.config/jot/
Current layout:
~/.config/jot/
configs/
settings.conf
colors/
my_theme.py
themes/ # legacy colorscheme path
Bundled starter config in this repo:
.configs/configs/
Built-in defaults include:
explorer_width=25minimap_width=15show_explorer=trueshow_minimap=truetab_size=2show_indent_guides=falseauto_indent=truesmart_paste_indent=trueauto_save=falseauto_save_interval_ms=2000auto_detect_indent=falseshow_line_numbers=truerelative_line_numbers=trueword_wrap=falsecursor_style=blockrender_fps=120idle_fps=60lsp_change_debounce_ms=120terminal_height=10debugger_height=12
Example settings.conf:
tab_size=2
show_indent_guides=false
auto_indent=true
smart_paste_indent=true
auto_save=false
auto_save_interval_ms=2000
auto_detect_indent=true
relative_line_numbers=true
render_fps=120
idle_fps=60
terminal_height=12
debugger_height=12
minimap_width=18
explorer_width=30
lsp_change_debounce_ms=120- CMake 3.16+
- C++17 compiler
- Python 3 development headers and
python3-config - libvterm development headers (
vtermpkg-config package) - libtermkey development headers (
termkeypkg-config package) - libuv development headers (
libuvpkg-config package) - Unix-like environment with POSIX terminal APIs
Notes:
- The UI uses raw terminal handling, not ncurses.
- Editor keyboard input is decoded with libtermkey for reliable modifier and advanced shortcut handling.
- The integrated terminal uses PTY support and libvterm.
- Async editor I/O, timers, child process pipes, and file-tree notifications use libuv.
- Tree-sitter runtime support is optional at build time but recommended.
The benchmark suite is opt-in and separate from CTest so normal builds stay fast and deterministic. It exercises non-interactive helper paths such as line providers, folding, UI text measurement, symbol extraction, and workspace search.
cmake -S . -B build -DJOT_BUILD_BENCHMARKS=ON
cmake --build build --target jot_benchmarks -j
./build/benchmarks/jot_benchmarksBenchmark output reports per-case iteration counts plus min/average/max runtime in milliseconds. Use the same build type and machine when comparing runs.
apps/jot/ CLI entrypoint and executable target
benchmarks/ opt-in non-interactive performance benchmark suite
cmake/ reusable CMake modules
include/jot/ public C++ API headers
src/core/ editor state, buffers, panes, workspace, LSP, debugger, terminal
src/edit/ text editing, cursor movement, selection, clipboard, search
src/features/ syntax, folding, config, bracket helpers, C++ assist
src/input/ keyboard, mouse, command palette, command dispatch
src/render/ buffer drawing, minimap, overlays, panels, UI views
src/tools/ integrated terminal, DAP client, LSP client, search helpers
src/python/ Python-side theme runtime
src/python_bridge/
C++ bridge for theme-facing Python API
src/ui/ raw terminal and UI abstraction
docs/ user-facing documentation
tests/ unit test scaffolding
Build graph highlights:
jot_engine: aggregated static engine target for the appjot_core,jot_edit,jot_features,jot_input,jot_render,jot_tools,jot_python_bridge,jot_ui: module libraries for ownership boundaries and reuse
- The user-facing workflow is modeless. Typing edits text directly, selection is handled by mouse or Shift+Arrow extension, and common editing commands use standard Ctrl/Alt shortcuts.
- The integrated terminal is useful for normal shell/task workflows, but it is not intended to be a complete replacement for a mature standalone terminal emulator.
- Python is reserved for themes. Plugins, keybindings, editor commands, and behavior hooks are not loaded from Python.
- Windows is not supported yet.
MIT
