No description
  • Rust 96.9%
  • C 2.5%
  • C++ 0.6%
Find a file
Max Fiedler b5d7ab4971
All checks were successful
CI / fmt (push) Successful in 2s
CI / build (linux) (push) Successful in 19s
CI / lint (linux) (push) Successful in 14s
CI / cargo-deny (push) Successful in 2s
CI / lint (macos) (push) Successful in 14s
CI / build (macos) (push) Successful in 27s
CI / build (windows) (push) Successful in 1m51s
CI / lint (windows) (push) Successful in 1m33s
Phase 4.5: wire TCL via LexTCL with four-class theme
LexTCL emits 22 contiguous SCE_TCL_* states (0..=21). All added to
scintilla-sys with a multi-paragraph banner covering the byte-exact
case-sensitivity (no property — strict strcmp, unlike NSIS),
9-wordlist surface (TCL Keywords / TK Keywords / iTCL Keywords /
tkCommands / expand / user1-4), three string flavours documented
(`"..."` IN_QUOTE, `{...}` brace-grouped lexed as code, `[cmd]`
command substitution), $-variable and ${expr} substitution states,
absence of any hard-wired structural tokens (every keyword flows
through `keywords[N].InList()` — no NSIS-style shortcut).

Four wordlist classes populated:
- TCL_KEYWORDS (class 0) — Tcl 8.6/9.0 built-in commands plus
  commonly-used standard-library procedures from auto.tcl /
  word.tcl / package.tcl (auto_* family, tclLog, tcl_wordBreak*,
  pkg_mkIndex) for N++ default-set parity
- TCL_TK_KEYWORDS (class 1) — Tk widget creation commands
  (button / label / canvas / entry / text / etc.) plus ttk::*
  themed-widget namespace
- TCL_ITCL_KEYWORDS (class 2) — [incr Tcl] + TclOO extensions
  (class / inherit / public / private / method / etc.)
- TCL_TK_COMMANDS (class 3) — Tk geometry managers and bind
  commands (pack / grid / place / bind / wm / winfo / etc.)

Classes 4 (expand) and 5-8 (user1-4) left empty per N++ default
parity. Classes 5-8 override classes 0-3 unconditionally per
LexTCL.cxx:172-179 — documented for future contributors.

Extensions expanded from `["tcl"]` to `["tcl", "tk", "itcl",
"exp", "wfs"]` matching N++ parity. `.exp` (Expect) routes
through LexTCL since Expect's lexical surface is TCL. All five
get parallel `from_extension` test assertions.

ui_win32 gets TCL_STYLES (20 mappings — DEFAULT + IDENTIFIER
intentionally unmapped per banner), TCL_ITALIC (4 comment-family
entries: COMMENT, COMMENTLINE, COMMENT_BOX, BLOCK_COMMENT),
TCL_BOLD (WORD + EXPAND), TCL_THEME, the L_TCL dispatch arm,
`(L_TCL, "TCL")` in wired_languages_have_complete_themes, and a
comprehensive `tcl_uses_lextcl_nine_class_theme` test with 10
cross-language non-reuse pins, HashSet cross-class no-overlap
guard across the 4 populated classes, structure pins, style
routing, italic + bold anchors.

Routing decisions documented in comments:
- SUBSTITUTION (`$var`) + SUB_BRACE (`${var}` body) → Lifetime
  (sigil-variable archetype, matches Bash/NSIS precedent)
- MODIFIER (`-flag`) → Keyword2 (command modifier archetype)
- EXPAND ({*}) → Keyword (bold) per the expansion-mechanism
  archetype
- WORD_IN_QUOTE → String defensively, with a comment noting the
  state is upstream-dead-code today (entry guard at :150
  requires IDENTIFIER or MODIFIER, never IN_QUOTE) but kept
  routed in case a future Lexilla patch activates it
- OPERATOR comment explicitly notes `$` is NOT in this class —
  bare `$` triggers SUBSTITUTION, `${` triggers SUB_BRACE

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-24 15:50:08 +02:00
.claude Revert agent 2026-06-11 16:03:18 +02:00
.forgejo/workflows ci: enable clippy::pedantic in workspace + DESIGN.md §9.3 2026-05-13 14:13:30 +02:00
assets ui_win32: owner-draw tab strip with save icon + close X 2026-05-10 12:02:39 +02:00
crates Phase 4.5: wire TCL via LexTCL with four-class theme 2026-06-24 15:50:08 +02:00
docs Phase 4.5: wire TCL via LexTCL with four-class theme 2026-06-24 15:50:08 +02:00
plugins cppmimetools: fix Quoted-Printable Encode — RFC 2045 §6.7 line wrapping 2026-06-11 15:52:13 +02:00
tools ui_win32: owner-draw tab strip with save icon + close X 2026-05-10 12:02:39 +02:00
.gitattributes Exclude tools from statistics 2026-05-09 07:32:17 +02:00
.gitignore chore: drop stray mojibaked temp file, broaden gitignore 2026-05-11 13:25:55 +02:00
.gitmodules Phase 0: workspace, crate skeletons, vendored Scintilla/Lexilla, CI 2026-05-03 14:40:08 +02:00
Cargo.lock cppmimetools: expand to N++ mimeTools menu shape (17 commands + 3 separators) 2026-06-11 13:15:52 +02:00
Cargo.toml deps: bump quick-xml 0.39 → 0.40 2026-05-13 10:12:42 +02:00
CLAUDE.md Claude update 2026-05-13 09:54:09 +02:00
deny.toml ci: clear cargo-deny wildcard errors and unused-license noise 2026-05-03 15:02:53 +02:00
LICENSE Adopt MIT license and add license-compliance scaffolding 2026-05-03 12:36:15 +02:00
README.md docs: move logo to assets/ + render at 128px width 2026-05-08 23:26:09 +02:00
rust-toolchain.toml Phase 0: workspace, crate skeletons, vendored Scintilla/Lexilla, CI 2026-05-03 14:40:08 +02:00
THIRD_PARTY_LICENSES.md Adopt MIT license and add license-compliance scaffolding 2026-05-03 12:36:15 +02:00

Code++

A 1:1, cross-platform clone of Notepad++ — written in Rust, powered by Scintilla, fast on every OS.

Code++

What It Is

Code++ is what Notepad++ would be if it shipped on Linux and macOS without compromising on what made it great on Windows: a fast cold start, instant typing, modest memory use, and a thriving plugin ecosystem.

The promise is concrete:

  • Same UX as Notepad++. Tabs, sessions, encoding control, EOL control, find-in-files, syntax highlighting via Scintilla's lexers — the keyboard shortcuts and menus you already know.
  • Same plugin ecosystem. Existing Notepad++ plugin DLLs load into Code++ on Windows unchanged. The same plugin source compiles to .so/.dylib on Linux and macOS.
  • Same performance class. Cold start under 80 ms, keystroke latency under 5 ms p99, empty-buffer footprint under 25 MB. These are not aspirations — they are constraints enforced at every phase boundary.
  • Truly cross-platform. Native Win32, GTK 4, and Cocoa front-ends over a single Rust core. No Electron. No browser engine. No GC runtime.

Why Build This

Notepad++ is excellent and Windows-only. Every "cross-platform Notepad++ alternative" trades performance for portability — usually by wrapping a web view, embedding a JavaScript runtime, or layering a heavy framework. Code++ rejects that trade.

The thesis: performance is an architectural property, not a tuning result. You get Notepad++-class speed by making the right choices up front — a headless core, statically linked Scintilla, the direct-call API for hot paths, lazy plugin loading, and zero startup work that isn't strictly required to paint the first frame. Once those decisions are in place, the speed follows. Once they are violated, no amount of profiling brings it back.


Core Ideas

  1. Scintilla does what Scintilla does best. We use Scintilla 5.x and Lexilla 5.x for the editing surface, undo/redo, search, and syntax highlighting. We do not reimplement them. We compile them statically into the binary so there is no DLL hell and no loader-time penalty.
  2. The core is headless. crates/core knows about sessions, files, encodings, and EOL — and nothing about windows, HWNDs, GTK widgets, or Scintilla. It is unit-testable without an OS event loop. UI crates depend on core; core depends on no one.
  3. Direct-call on every hot path. Scintilla's SCI_GETDIRECTFUNCTION returns a function pointer that bypasses the window message pump. Code++ captures it once per editor and routes every keystroke, insert, and selection through it. SendMessage is reserved for setup and cross-thread one-shots.
  4. Zero work at startup that isn't on the visible-frame critical path. No directory scans. No plugin DLL loads. No project indexing. No AST construction. The session file is read; windows are created; threads are spawned for whatever needs to happen later. That's it.
  5. Plugins load when they are first used, not before. A user with 40 installed plugins pays no startup cost for the 39 they don't touch this session.
  6. Notepad++ plugin compatibility from the ground up. The six plugin entry points, the NppData struct, and the NPPM_*/NPPN_* message families are implemented to match Notepad++'s public ABI. A binary plugin that works in Notepad++ on Windows works in Code++ on Windows.
  7. End-to-end demos at every phase. Every implementation phase (see DESIGN.md §7) ends with a runnable demo against real Scintilla, real OS events, real disk I/O, and real plugin DLLs. No phase ships on stubs. This rule exists to stop architectural drift before it starts.

Project Status

Phase 0 — Scaffolding is the current phase. The repository contains the design and developer-environment documentation; the workspace, crates, and submodule pins land next. See DESIGN.md §7.2 for the full phase plan and end-of-phase demo for each.

Phase Theme Demo
0 Workspace + CI green Empty Win32 window opens and closes
1 Scintilla shell Real Scintilla control, type/undo/redo work
2 Core: session, files, encoding Open/save/restore real files, no UI freeze
3 Multi-tab + plugin host Real N++ plugin DLL loads and runs
4 Lexers, search, find-in-files Highlighting + search at scale
5 Linux (GTK) and macOS (Cocoa) Same binary builds and runs natively

Getting Started

For setup instructions on Windows, Linux, and macOS, see DEVELOPMENT.md.

The short version, once your toolchain is in place:

git clone --recurse-submodules https://git.fiedler.live/tux/code-plus-plus.git
cd code-plus-plus
cargo build --workspace
cargo run -p codepp-app

The canonical repository is hosted on Forgejo at https://git.fiedler.live/tux/code-plus-plus. A read-only mirror is pushed to GitHub.


Documentation

  • DESIGN.md — full architecture, dependency graph, crate responsibilities, plugin ABI, performance budgets, and the phase plan. Read this if you want to understand any decision in the codebase.
  • DEVELOPMENT.md — platform-by-platform setup for Windows, Linux, and macOS, plus common development tasks and troubleshooting.
  • CLAUDE.md — operational rules and project conventions used by the AI development assistant.

License

Code++ is licensed under the MIT License. See LICENSE for the full text and THIRD_PARTY_LICENSES.md for the notices required by upstream components (Scintilla and Lexilla under HPND, plus bundled Rust crates).

The Notepad++ plugin compatibility layer under plugins/nppcompat-headers/ is an independent clean-room reimplementation of the public ABI — message numbers, struct layouts, behavior contracts. No source has been copied from Notepad++; the ABI itself is not copyrightable.


Acknowledgements

Code++ stands on the work of two communities:

  • Notepad++ by Don Ho and contributors — for two decades of proving that a small, fast text editor is worth caring about.
  • Scintilla and Lexilla by Neil Hodgson and contributors — for the editing engine that makes any of this possible.

Code++ is an independent project and is not affiliated with either.