diff --git a/PowerEditor/installer/functionList/asm65c02.xml b/PowerEditor/installer/functionList/asm65c02.xml new file mode 100644 index 000000000000..0bdc00c218f3 --- /dev/null +++ b/PowerEditor/installer/functionList/asm65c02.xml @@ -0,0 +1,33 @@ + + + + + + + + + + + diff --git a/PowerEditor/src/MISC/PluginsManager/Notepad_plus_msgs.h b/PowerEditor/src/MISC/PluginsManager/Notepad_plus_msgs.h index 1059a785fc7b..53996a77d987 100644 --- a/PowerEditor/src/MISC/PluginsManager/Notepad_plus_msgs.h +++ b/PowerEditor/src/MISC/PluginsManager/Notepad_plus_msgs.h @@ -39,6 +39,7 @@ enum LangType {L_TEXT, L_PHP , L_C, L_CPP, L_CS, L_OBJC, L_JAVA, L_RC,\ L_REGISTRY, L_RUST, L_SPICE, L_TXT2TAGS, L_VISUALPROLOG,\ L_TYPESCRIPT, L_JSON5, L_MSSQL, L_GDSCRIPT, L_HOLLYWOOD,\ L_GOLANG, L_RAKU, L_TOML, L_SAS, L_ERRORLIST, \ + L_ASM_65C02, \ // Don't use L_JS_EMBEDDED, use L_JAVASCRIPT instead // The end of enumerated language type, so it should be always at the end L_EXTERNAL}; diff --git a/PowerEditor/src/Notepad_plus.cpp b/PowerEditor/src/Notepad_plus.cpp index 95588faaeb0d..70ddd656ecec 100644 --- a/PowerEditor/src/Notepad_plus.cpp +++ b/PowerEditor/src/Notepad_plus.cpp @@ -4132,6 +4132,8 @@ LangType Notepad_plus::menuID2LangType(int cmdID) return L_SAS; case IDM_LANG_ERRORLIST: return L_ERRORLIST; + case IDM_LANG_ASM_65C02: + return L_ASM_65C02; case IDM_LANG_USER: return L_USER; default: diff --git a/PowerEditor/src/Notepad_plus.rc b/PowerEditor/src/Notepad_plus.rc index 856285b9fb88..1f460a35015f 100644 --- a/PowerEditor/src/Notepad_plus.rc +++ b/PowerEditor/src/Notepad_plus.rc @@ -1001,6 +1001,7 @@ BEGIN MENUITEM "ASN.1", IDM_LANG_ASN1 MENUITEM "ASP", IDM_LANG_ASP MENUITEM "Assembly", IDM_LANG_ASM + MENUITEM "Assembly (65C02)", IDM_LANG_ASM_65C02 MENUITEM "AutoIt", IDM_LANG_AU3 MENUITEM "AviSynth", IDM_LANG_AVS MENUITEM "BaanC", IDM_LANG_BAANC @@ -1105,6 +1106,7 @@ BEGIN MENUITEM "ASN.1", IDM_LANG_ASN1 MENUITEM "ASP", IDM_LANG_ASP MENUITEM "Assembly", IDM_LANG_ASM + MENUITEM "Assembly (65C02)", IDM_LANG_ASM_65C02 MENUITEM "AutoIt", IDM_LANG_AU3 MENUITEM "AviSynth", IDM_LANG_AVS END diff --git a/PowerEditor/src/Parameters.cpp b/PowerEditor/src/Parameters.cpp index 0357e453d06d..f841c5409caf 100644 --- a/PowerEditor/src/Parameters.cpp +++ b/PowerEditor/src/Parameters.cpp @@ -8160,6 +8160,9 @@ int NppParameters::langTypeToCommandID(LangType lt) const case L_ERRORLIST: id = IDM_LANG_ERRORLIST; break; + case L_ASM_65C02: + id = IDM_LANG_ASM_65C02; break; + case L_SEARCHRESULT : id = -1; break; diff --git a/PowerEditor/src/ScintillaComponent/ScintillaEditView.cpp b/PowerEditor/src/ScintillaComponent/ScintillaEditView.cpp index 44275a6b151c..de1c46442aa2 100644 --- a/PowerEditor/src/ScintillaComponent/ScintillaEditView.cpp +++ b/PowerEditor/src/ScintillaComponent/ScintillaEditView.cpp @@ -198,6 +198,7 @@ LanguageNameInfo ScintillaEditView::_langNameInfoArray[L_EXTERNAL + 1] = { {L"toml", L"TOML", L"Tom's Obvious Minimal Language file", L_TOML, "toml"}, {L"sas", L"SAS", L"SAS file", L_SAS, "sas"}, {L"errorlist", L"ErrorList", L"ErrorList", L_ERRORLIST, "errorlist"}, + {L"asm65c02", L"Assembly (65C02)", L"WDC 65C02 assembly source file", L_ASM_65C02, "asm"}, {L"ext", L"External", L"External", L_EXTERNAL, "null"} }; @@ -1817,7 +1818,7 @@ void ScintillaEditView::defineDocType(LangType typeDoc) { if (getCurrentBuffer()->getUnicodeMode() == uni8Bit) { - if (typeDoc == L_CSS || typeDoc == L_CAML || typeDoc == L_ASM || typeDoc == L_MATLAB) + if (typeDoc == L_CSS || typeDoc == L_CAML || typeDoc == L_ASM || typeDoc == L_ASM_65C02 || typeDoc == L_MATLAB) execute(SCI_SETCODEPAGE, CP_ACP); else execute(SCI_SETCODEPAGE, _codepage); @@ -1974,6 +1975,9 @@ void ScintillaEditView::defineDocType(LangType typeDoc) case L_ASM : setAsmLexer(); break; + case L_ASM_65C02 : + setAsm65C02Lexer(); break; + case L_DIFF : setDiffLexer(); break; @@ -2474,7 +2478,7 @@ void ScintillaEditView::bufferUpdated(Buffer * buffer, int mask) if (isCJK()) { LangType typeDoc = buffer->getLangType(); - if (typeDoc == L_CSS || typeDoc == L_CAML || typeDoc == L_ASM || typeDoc == L_MATLAB) + if (typeDoc == L_CSS || typeDoc == L_CAML || typeDoc == L_ASM || typeDoc == L_ASM_65C02 || typeDoc == L_MATLAB) enc = CP_ACP; //you may also want to set charsets here, not yet implemented else enc = _codepage; diff --git a/PowerEditor/src/ScintillaComponent/ScintillaEditView.h b/PowerEditor/src/ScintillaComponent/ScintillaEditView.h index 89eb5649ff58..497fc4c4b80b 100644 --- a/PowerEditor/src/ScintillaComponent/ScintillaEditView.h +++ b/PowerEditor/src/ScintillaComponent/ScintillaEditView.h @@ -858,6 +858,13 @@ friend class Finder; execute(SCI_SETPROPERTY, reinterpret_cast("fold.asm.comment.explicit"), reinterpret_cast("1")); } + void setAsm65C02Lexer(){ + setLexer(L_ASM_65C02, LIST_0 | LIST_1 | LIST_2 | LIST_3 | LIST_4 | LIST_5 | LIST_6 | LIST_7); + execute(SCI_SETPROPERTY, reinterpret_cast("fold.asm.syntax.based"), reinterpret_cast("1")); + execute(SCI_SETPROPERTY, reinterpret_cast("fold.asm.comment.multiline"), reinterpret_cast("1")); + execute(SCI_SETPROPERTY, reinterpret_cast("fold.asm.comment.explicit"), reinterpret_cast("1")); + } + void setDiffLexer(){ setLexer(L_DIFF, LIST_NONE); } diff --git a/PowerEditor/src/langs.model.xml b/PowerEditor/src/langs.model.xml index 1a7f56791491..bb435a9f365e 100644 --- a/PowerEditor/src/langs.model.xml +++ b/PowerEditor/src/langs.model.xml @@ -33,6 +33,24 @@ .endif .endsw end endp + + + adc and asl bcc bcs beq bit bmi bne bpl brk bvc bvs clc cld cli clv cmp cpx cpy dec dex dey eor inc inx iny jmp jsr lda ldx ldy lsr nop ora pha php pla plp rol ror rti rts sbc sec sed sei sta stx sty tax tay tsx txa txs tya bra phx phy plx ply stz trb tsb wai stp smb0 smb1 smb2 smb3 smb4 smb5 smb6 smb7 rmb0 rmb1 rmb2 rmb3 rmb4 rmb5 rmb6 rmb7 bbr0 bbr1 bbr2 bbr3 bbr4 bbr5 bbr6 bbr7 bbs0 bbs1 bbs2 bbs3 bbs4 bbs5 bbs6 bbs7 + + + + a x y s sp p pc + + equ db dw dd ds fill org chip endasm end include import export extern global public record macro mend mexit mlist mnolist if ifdef ifndef else elseif endif list nolist title subttl page lf clrlst radix code data bss udata dpage ipage + + + + + + macro if ifdef ifndef + + mend endif + ACCESS AGENT AUGMENTS BEGIN BITS CAPABILITIES CHOICE COMPLIANCE CONTACT CONVENTION DEFINITIONS DEFVAL DESCRIPTION DISPLAY END ENTERPRISE EXPORTS FALSE FROM GROUP GROUPS HINT IDENTITY IMPLIED IMPORTS INCLUDES INDEX INFO LAST MANDATORY MAX MIN MODULE NOTATION NOTIFICATION NULL OBJECTS OBJECT-TYPE OF ORGANIZATION PRODUCT RELEASE REFERENCE REQUIRES REVISION SEQUENCE SIZE STATUS SUPPORTS SYNTAX TEXTUAL TRAP TYPE TRAP-TYPE UPDATED VALUE VARIABLES VARIATION WRITE accessible create current deprecated for mandatory not notify not-accessible obsolete only optional read read-only read-write write diff --git a/PowerEditor/src/menuCmdID.h b/PowerEditor/src/menuCmdID.h index c5c4943f68c0..8f975558a9da 100644 --- a/PowerEditor/src/menuCmdID.h +++ b/PowerEditor/src/menuCmdID.h @@ -571,6 +571,7 @@ #define IDM_LANG_TOML (IDM_LANG + 91) #define IDM_LANG_SAS (IDM_LANG + 92) #define IDM_LANG_ERRORLIST (IDM_LANG + 93) + #define IDM_LANG_ASM_65C02 (IDM_LANG + 94) #define IDM_LANG_EXTERNAL (IDM_LANG + 165) #define IDM_LANG_EXTERNAL_LIMIT (IDM_LANG + 179) diff --git a/PowerEditor/src/stylers.model.xml b/PowerEditor/src/stylers.model.xml index e3c5cb70686f..b6dfb7e14772 100644 --- a/PowerEditor/src/stylers.model.xml +++ b/PowerEditor/src/stylers.model.xml @@ -89,6 +89,22 @@ + + + + + + + + + + + + + + + + diff --git a/docs/superpowers/plans/2026-05-11-asm-65c02-language.md b/docs/superpowers/plans/2026-05-11-asm-65c02-language.md new file mode 100644 index 000000000000..f719d6215dc8 --- /dev/null +++ b/docs/superpowers/plans/2026-05-11-asm-65c02-language.md @@ -0,0 +1,602 @@ +# Assembly (65C02) Language Implementation Plan + +> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking. + +**Goal:** Add a new first-class language `Assembly (65C02)` to PaperWasp that highlights WDC W65C02S source files using the existing Lexilla `SCLEX_ASM` lexer fed with WDC-flavored keyword lists. + +**Architecture:** Reuse `LexAsm.cxx` unchanged — it accepts 8 `WordList`s (instructions, FPU, registers, directives, directive operands, ext instructions, fold-open, fold-close). Wire a new `LangType` enum value, a new menu command, a new language descriptor row, and corresponding entries in `langs.model.xml` and `stylers.model.xml`. Add a thin label-based function-list parser. Both x86 ASM and 65C02 ASM coexist; the new language is appended last in the langs list so it wins by default for `.asm`. + +**Tech Stack:** C++20, CMake (Xcode generator on macOS), Lexilla `SCLEX_ASM`, Notepad++ XML config files (`langs.model.xml`, `stylers.model.xml`, function-list parsers). + +**Spec:** `docs/superpowers/specs/2026-05-11-asm-65c02-language-design.md` + +**Verification model:** This codebase has no automated unit tests for lexer plumbing on macOS (the Windows test scripts in `PowerEditor/Test/` cover function-list regex and URL detection only). Each task therefore commits small, compilable changes; the final task performs a build + manual smoke test against a hand-written 65C02 sample. + +--- + +## File Map + +**Modify:** +- `PowerEditor/src/MISC/PluginsManager/Notepad_plus_msgs.h` — append `L_ASM_65C02` to the `LangType` enum (before `L_EXTERNAL`). +- `PowerEditor/src/menuCmdID.h` — add `IDM_LANG_ASM_65C02` (`IDM_LANG + 94`). +- `PowerEditor/src/ScintillaComponent/ScintillaEditView.h` — declare `setAsm65C02Lexer()` mirroring `setAsmLexer()`. +- `PowerEditor/src/ScintillaComponent/ScintillaEditView.cpp` — descriptor table row, CJK 8-bit codepage checks (2 sites), `defineDocType` case. +- `PowerEditor/src/Parameters.cpp` — `langTypeToCommandID` case. +- `PowerEditor/src/Notepad_plus.cpp` — `getLangFromMenuName` case. +- `PowerEditor/src/Notepad_plus.rc` — menu items in two places. +- `PowerEditor/src/langs.model.xml` — new `` block. +- `PowerEditor/src/stylers.model.xml` — new `` block. + +**Create:** +- `PowerEditor/installer/functionList/asm65c02.xml` — function-list parser (cloned from `asm.xml`). + +**Not touched:** `overrideMap.xml` — function-list parser names map to language short names by convention; the example entries in that file are inside a documentation comment block. + +--- + +## Task 1: Append `L_ASM_65C02` to the `LangType` enum + +**Files:** +- Modify: `PowerEditor/src/MISC/PluginsManager/Notepad_plus_msgs.h:41-44` + +- [ ] **Step 1: Edit the enum** + +Locate the closing of the `LangType` enum at lines 41–44: + +```cpp + L_GOLANG, L_RAKU, L_TOML, L_SAS, L_ERRORLIST, \ + // Don't use L_JS_EMBEDDED, use L_JAVASCRIPT instead + // The end of enumerated language type, so it should be always at the end + L_EXTERNAL}; +``` + +Replace with: + +```cpp + L_GOLANG, L_RAKU, L_TOML, L_SAS, L_ERRORLIST, \ + L_ASM_65C02, \ + // Don't use L_JS_EMBEDDED, use L_JAVASCRIPT instead + // The end of enumerated language type, so it should be always at the end + L_EXTERNAL}; +``` + +Rationale: appending immediately before `L_EXTERNAL` preserves the enum-tail invariant called out in the comment and keeps every existing enum value stable (binary ABI for plugins). The new value is `L_ERRORLIST + 1 == 95`. + +- [ ] **Step 2: Verify the file compiles in isolation** + +The enum is a pure declaration; nothing else in this file references the new value. No build needed yet — Task 10 covers the full build. + +- [ ] **Step 3: Commit** + +```bash +git add PowerEditor/src/MISC/PluginsManager/Notepad_plus_msgs.h +git commit -m "Add L_ASM_65C02 to LangType enum" +``` + +--- + +## Task 2: Add `IDM_LANG_ASM_65C02` command ID + +**Files:** +- Modify: `PowerEditor/src/menuCmdID.h:573-575` + +- [ ] **Step 1: Insert the new macro** + +The current block ends with: + +```cpp + #define IDM_LANG_ERRORLIST (IDM_LANG + 93) + + #define IDM_LANG_EXTERNAL (IDM_LANG + 165) +``` + +Insert a new line between them so the file reads: + +```cpp + #define IDM_LANG_ERRORLIST (IDM_LANG + 93) + #define IDM_LANG_ASM_65C02 (IDM_LANG + 94) + + #define IDM_LANG_EXTERNAL (IDM_LANG + 165) +``` + +Rationale: +94 is the next free slot; the +165 base for EXTERNAL leaves plenty of headroom. + +- [ ] **Step 2: Commit** + +```bash +git add PowerEditor/src/menuCmdID.h +git commit -m "Add IDM_LANG_ASM_65C02 command ID" +``` + +--- + +## Task 3: Add language descriptor row + `setAsm65C02Lexer()` helper + +**Files:** +- Modify: `PowerEditor/src/ScintillaComponent/ScintillaEditView.cpp:138` +- Modify: `PowerEditor/src/ScintillaComponent/ScintillaEditView.h:854-859` + +- [ ] **Step 1: Add the descriptor row** + +Locate the table at `ScintillaEditView.cpp:138`: + +```cpp + {L"asm", L"Assembly", L"Assembly language source file", L_ASM, "asm"}, +``` + +Insert the new row immediately after: + +```cpp + {L"asm", L"Assembly", L"Assembly language source file", L_ASM, "asm"}, + {L"asm65c02", L"Assembly (65C02)", L"WDC 65C02 assembly source file", L_ASM_65C02, "asm65c02"}, +``` + +The 5 fields are: short-name (used by `langs.model.xml`), display name (menu label and styler `desc`), description (tooltip), `LangType`, and lexer-name passed to Scintilla (`asm65c02` matches the new `` we'll add in Task 8). + +- [ ] **Step 2: Add the lexer helper** + +In `ScintillaEditView.h`, locate `setAsmLexer()` at lines 854–859: + +```cpp + void setAsmLexer(){ + setLexer(L_ASM, LIST_0 | LIST_1 | LIST_2 | LIST_3 | LIST_4 | LIST_5 | LIST_6 | LIST_7); + execute(SCI_SETPROPERTY, reinterpret_cast("fold.asm.syntax.based"), reinterpret_cast("1")); + execute(SCI_SETPROPERTY, reinterpret_cast("fold.asm.comment.multiline"), reinterpret_cast("1")); + execute(SCI_SETPROPERTY, reinterpret_cast("fold.asm.comment.explicit"), reinterpret_cast("1")); + } +``` + +Insert directly after it: + +```cpp + void setAsm65C02Lexer(){ + setLexer(L_ASM_65C02, LIST_0 | LIST_1 | LIST_2 | LIST_3 | LIST_4 | LIST_5 | LIST_6 | LIST_7); + execute(SCI_SETPROPERTY, reinterpret_cast("fold.asm.syntax.based"), reinterpret_cast("1")); + execute(SCI_SETPROPERTY, reinterpret_cast("fold.asm.comment.multiline"), reinterpret_cast("1")); + execute(SCI_SETPROPERTY, reinterpret_cast("fold.asm.comment.explicit"), reinterpret_cast("1")); + } +``` + +The fold properties are global to `SCLEX_ASM` regardless of which `LangType` triggers it; setting them twice (once per lang) is harmless. + +- [ ] **Step 3: Commit** + +```bash +git add PowerEditor/src/ScintillaComponent/ScintillaEditView.cpp PowerEditor/src/ScintillaComponent/ScintillaEditView.h +git commit -m "Add Assembly (65C02) language descriptor and lexer setter" +``` + +--- + +## Task 4: Wire `defineDocType` and CJK 8-bit codepage checks + +**Files:** +- Modify: `PowerEditor/src/ScintillaComponent/ScintillaEditView.cpp:1820` +- Modify: `PowerEditor/src/ScintillaComponent/ScintillaEditView.cpp:1974-1975` +- Modify: `PowerEditor/src/ScintillaComponent/ScintillaEditView.cpp:2477` + +- [ ] **Step 1: Add the lexer case to `defineDocType`** + +At line 1974, the existing case reads: + +```cpp + case L_ASM : + setAsmLexer(); break; +``` + +Replace with: + +```cpp + case L_ASM : + setAsmLexer(); break; + + case L_ASM_65C02 : + setAsm65C02Lexer(); break; +``` + +- [ ] **Step 2: Update first CJK codepage check** + +At line 1820, change: + +```cpp + if (typeDoc == L_CSS || typeDoc == L_CAML || typeDoc == L_ASM || typeDoc == L_MATLAB) +``` + +to: + +```cpp + if (typeDoc == L_CSS || typeDoc == L_CAML || typeDoc == L_ASM || typeDoc == L_ASM_65C02 || typeDoc == L_MATLAB) +``` + +- [ ] **Step 3: Update second CJK codepage check** + +At line 2477, change: + +```cpp + if (typeDoc == L_CSS || typeDoc == L_CAML || typeDoc == L_ASM || typeDoc == L_MATLAB) +``` + +to: + +```cpp + if (typeDoc == L_CSS || typeDoc == L_CAML || typeDoc == L_ASM || typeDoc == L_ASM_65C02 || typeDoc == L_MATLAB) +``` + +Rationale: these two sites force `CP_ACP` for 8-bit CJK buffers in ASM-style languages; 65C02 sources have the same single-byte ASCII assumption. + +- [ ] **Step 4: Commit** + +```bash +git add PowerEditor/src/ScintillaComponent/ScintillaEditView.cpp +git commit -m "Wire L_ASM_65C02 into defineDocType and codepage handling" +``` + +--- + +## Task 5: Wire `langTypeToCommandID` and `getLangFromMenuName` + +**Files:** +- Modify: `PowerEditor/src/Parameters.cpp:8160-8161` +- Modify: `PowerEditor/src/Notepad_plus.cpp:4133-4134` + +- [ ] **Step 1: Add the case in `Parameters.cpp`** + +At `Parameters.cpp:8160-8161` the tail of `langTypeToCommandID` looks like: + +```cpp + case L_ERRORLIST: + id = IDM_LANG_ERRORLIST; break; +``` + +Insert immediately after: + +```cpp + case L_ERRORLIST: + id = IDM_LANG_ERRORLIST; break; + + case L_ASM_65C02: + id = IDM_LANG_ASM_65C02; break; +``` + +- [ ] **Step 2: Add the case in `Notepad_plus.cpp`** + +At `Notepad_plus.cpp:4133-4134`: + +```cpp + case IDM_LANG_ERRORLIST: + return L_ERRORLIST; +``` + +Insert immediately after: + +```cpp + case IDM_LANG_ERRORLIST: + return L_ERRORLIST; + case IDM_LANG_ASM_65C02: + return L_ASM_65C02; +``` + +(Preserve the surrounding 8-space indent style used in this file.) + +- [ ] **Step 3: Commit** + +```bash +git add PowerEditor/src/Parameters.cpp PowerEditor/src/Notepad_plus.cpp +git commit -m "Map L_ASM_65C02 <-> IDM_LANG_ASM_65C02" +``` + +--- + +## Task 6: Add Windows resource menu items + +**Files:** +- Modify: `PowerEditor/src/Notepad_plus.rc:1003` +- Modify: `PowerEditor/src/Notepad_plus.rc:1107` + +These edits are required for upstream Windows parity and for the macOS port's menu generation path (the resource file is parsed during build). Both edits go in alphabetical order between "Assembly" and "AutoIt". + +- [ ] **Step 1: First menu (main Language popup) at line 1003** + +Existing: + +``` + MENUITEM "Assembly", IDM_LANG_ASM + MENUITEM "AutoIt", IDM_LANG_AU3 +``` + +Replace with: + +``` + MENUITEM "Assembly", IDM_LANG_ASM + MENUITEM "Assembly (65C02)", IDM_LANG_ASM_65C02 + MENUITEM "AutoIt", IDM_LANG_AU3 +``` + +- [ ] **Step 2: Second menu (Language-by-letter "A" popup) at line 1107** + +Existing: + +``` + MENUITEM "Assembly", IDM_LANG_ASM + MENUITEM "AutoIt", IDM_LANG_AU3 +``` + +Replace with: + +``` + MENUITEM "Assembly", IDM_LANG_ASM + MENUITEM "Assembly (65C02)", IDM_LANG_ASM_65C02 + MENUITEM "AutoIt", IDM_LANG_AU3 +``` + +(Note the trailing whitespace difference between the two blocks; preserve the existing alignment of each block when editing.) + +- [ ] **Step 3: Commit** + +```bash +git add PowerEditor/src/Notepad_plus.rc +git commit -m "Add Assembly (65C02) menu items" +``` + +--- + +## Task 7: Add `` keyword block + +**Files:** +- Modify: `PowerEditor/src/langs.model.xml:35` (insert *after* the existing `` that closes the `asm` block) + +- [ ] **Step 1: Insert the new Language block** + +Locate the closing `` of the existing `asm` block at line 35: + +```xml + .endif .endsw end endp + + +``` + +Insert the new block between the closing `` and ``: + +```xml + .endif .endsw end endp + + + + adc and asl bcc bcs beq bit bmi bne bpl brk bvc bvs clc cld cli clv cmp cpx cpy dec dex dey eor inc inx iny jmp jsr lda ldx ldy lsr nop ora pha php pla plp rol ror rti rts sbc sec sed sei sta stx sty tax tay tsx txa txs tya bra phx phy plx ply stz trb tsb wai stp smb0 smb1 smb2 smb3 smb4 smb5 smb6 smb7 rmb0 rmb1 rmb2 rmb3 rmb4 rmb5 rmb6 rmb7 bbr0 bbr1 bbr2 bbr3 bbr4 bbr5 bbr6 bbr7 bbs0 bbs1 bbs2 bbs3 bbs4 bbs5 bbs6 bbs7 + + + + a x y s sp p pc + + equ db dw dd ds fill org chip endasm end include import export extern global public record macro mend mexit mlist mnolist if ifdef ifndef else elseif endif list nolist title subttl page lf clrlst radix code data bss udata dpage ipage + + + + + + macro if ifdef ifndef + + mend endif + + +``` + +Rationale for placement: the order in `langs.model.xml` is the order Notepad++ walks when matching a file extension at open. Placing `asm65c02` after `asm` makes 65C02 the default for `.asm` files, which matches the spec's preference for PaperWasp. + +- [ ] **Step 2: Commit** + +```bash +git add PowerEditor/src/langs.model.xml +git commit -m "Add asm65c02 language keywords (WDC W65C02S)" +``` + +--- + +## Task 8: Add `` styler block + +**Files:** +- Modify: `PowerEditor/src/stylers.model.xml:91` (insert after the existing `` that closes the `asm` block) + +- [ ] **Step 1: Insert the new LexerType block** + +The existing ASM `` is at line 91, immediately followed by `` at line 92. Insert between them: + +```xml + + + + + + + + + + + + + + + + + + + +``` + +Note: style ID 13 is intentionally absent (matches the existing `asm` block). Colors are copied verbatim from the existing ASM block so first-launch behavior is familiar; users can re-tune via Style Configurator. + +- [ ] **Step 2: Commit** + +```bash +git add PowerEditor/src/stylers.model.xml +git commit -m "Add asm65c02 default styler" +``` + +--- + +## Task 9: Create function-list parser `asm65c02.xml` + +**Files:** +- Create: `PowerEditor/installer/functionList/asm65c02.xml` + +- [ ] **Step 1: Write the parser file** + +Write this content verbatim to `PowerEditor/installer/functionList/asm65c02.xml`: + +```xml + + + + + + + + + + + +``` + +Differences from `asm.xml`: +- `displayName` and `id` updated. +- `[A-Za-z_$]` becomes `[A-Za-z_]` — WDC uses `$` as a hex-literal prefix (`$C000`), not as a label character. + +- [ ] **Step 2: Commit** + +```bash +git add PowerEditor/installer/functionList/asm65c02.xml +git commit -m "Add Assembly (65C02) function-list parser" +``` + +--- + +## Task 10: Build and smoke-test + +**Files:** none modified — verification only. + +- [ ] **Step 1: Clean build with the Xcode generator** + +```bash +cd macos/build +rm -rf * +cmake -G Xcode .. +cmake --build . --target PaperWasp +``` + +Expected: build succeeds. If it fails: +- Linker error about `setAsm65C02Lexer` — check Task 3 Step 2 (header inline definition). +- `'L_ASM_65C02' was not declared` — check Task 1 enum edit landed in the right header and the include path is the one used by the failing TU. +- `.rc` parse error on macOS — confirm by checking which file is actually consumed by the macOS build; if the `.rc` is only used on Windows, the macOS build may skip it and the Windows menu update is a no-op on macOS until the menu is wired through the AppKit bridge. That is acceptable for v1. + +- [ ] **Step 2: Build the .app bundle** + +```bash +cmake --build . --target PaperWasp_package +``` + +Expected: `macos/build/dist/PaperWasp.app` exists. + +- [ ] **Step 3: Author a sample file** + +Write a temporary sample `/tmp/claude/sample_65c02.asm`: + +``` +; WDC 65C02 sample for smoke testing + chip 65C02 + +stack_top equ $01FF +buffer ds 32 + + org $C000 + +main: + sei + cld + ldx #stack_top + txs + jsr init + bra loop + +loop: + wai + bra loop + +init: + lda #$00 + sta buffer + rts + + end +``` + +- [ ] **Step 4: Open in PaperWasp and verify** + +```bash +open -a macos/build/dist/PaperWasp.app /tmp/claude/sample_65c02.asm +``` + +Verify (visual checks — there's no programmatic harness): + +1. **Languages menu** contains "Assembly (65C02)" near "Assembly". +2. On open, the language indicator shows **Assembly (65C02)** by default (because the new entry is last in `langs.model.xml` for `.asm`). +3. Distinct coloring for: + - Opcodes (`sei`, `cld`, `ldx`, `txs`, `jsr`, `bra`, `wai`, `rts`) — CPU INSTRUCTION color (default blue). + - Registers (`a`, `x`, `s` in any "TAX"/"TXS"/"PHA" forms if you write them) — REGISTER color. + - Directives (`chip`, `equ`, `ds`, `org`, `end`) — DIRECTIVE color. + - `;` comment — COMMENT color (green). +4. Manually switch via **Languages → Assembly** and confirm x86 highlighting takes over (sanity check that both languages coexist and the menu mapping is wired in both directions). +5. Open the **Function List** panel (View → Function List). Confirm it lists `main`, `loop`, `init`. +6. Add an `if` / `endif` pair around a block and confirm a fold marker appears in the gutter. + +- [ ] **Step 5: Cleanup commit (if any incidental fixups were needed)** + +If Steps 1–4 surfaced anything that required code adjustments, fix them and: + +```bash +git add -p +git commit -m "Fixups discovered during 65C02 smoke test" +``` + +Otherwise no commit needed. + +--- + +## Self-Review + +**Spec coverage:** +- Spec §4.1 (lexer reuse & 8 wordlists) — Task 3 (`setAsm65C02Lexer`) and Task 7 (keyword content). +- Spec §4.2 (enum, names, ext) — Task 1, Task 3 (descriptor row). +- Spec §4.3 (menu) — Task 2, Task 6. +- Spec §4.4 (ScintillaEditView wiring) — Task 3, Task 4. +- Spec §4.5 (lang ↔ command-ID maps) — Task 5. +- Spec §4.6 (default extension routing, ordering in langs.xml) — Task 7 (placement after existing `asm` block). +- Spec §4.7 (styler) — Task 8. +- Spec §4.8 (function list) — Task 9. *Override-map registration was called out in the spec but is unnecessary in practice; explained in the File Map header.* +- Spec §5 (concrete keyword lists) — Task 7. +- Spec §6 (file inventory) — File Map header reconciles spec inventory with discovered reality (no overrideMap.xml change needed). +- Spec §8 (verification plan) — Task 10. + +**Placeholder scan:** No TBDs, no "implement appropriate X", no "see Task N — repeated". + +**Type / name consistency:** Short-name `asm65c02` used identically in descriptor row, `langs.model.xml`, `stylers.model.xml`, and the function-list parser `displayName`. Enum spelling `L_ASM_65C02` and macro spelling `IDM_LANG_ASM_65C02` consistent across Tasks 1, 2, 3, 4, 5, 6. The lexer helper `setAsm65C02Lexer` is declared and called by the same name. diff --git a/docs/superpowers/specs/2026-05-11-asm-65c02-language-design.md b/docs/superpowers/specs/2026-05-11-asm-65c02-language-design.md new file mode 100644 index 000000000000..b2b2c267678b --- /dev/null +++ b/docs/superpowers/specs/2026-05-11-asm-65c02-language-design.md @@ -0,0 +1,242 @@ +# Assembly (65C02) Language Support — Design + +**Status:** Draft for review +**Date:** 2026-05-11 +**Author:** Brian Tabone (PaperWasp) + +## 1. Background + +PaperWasp inherits Notepad++'s Assembly (`L_ASM`) language, which is wired through +the Lexilla `LexAsm.cxx` lexer (`SCLEX_ASM`) and uses an x86/x64/MASM-flavored +keyword set. The lexer itself is dialect-agnostic — it exposes eight `WordList` +slots that are filled by `langs.model.xml`. The current `` +entry populates them with Intel/AMD mnemonics, x86 registers (`ax`, `eax`, +`rax`, `xmm0`…), and MASM directives (`.386`, `.code`, `.model`…). + +The author works on the **WDC W65C02S** (per the WDC Assembler/Linker manual: +https://www.westerndesigncenter.com/wdc/documentation/Assembler_Linker.pdf) +and wants first-class syntax highlighting for that dialect. + +## 2. Goals + +- Add a new language `Assembly (65C02)` that: + - Highlights the full WDC W65C02S instruction set (including WDC `WAI`/`STP` + and Rockwell `SMB`/`RMB`/`BBR`/`BBS` extensions). + - Highlights 65C02 registers (`A X Y S P SP PC`). + - Highlights WDC Assembler directives. + - Folds on `macro`/`mend` and `if`/`endif`. +- Live alongside the existing x86 `Assembly` language; do not break or replace it. + +## 3. Non-goals (out of scope for v1) + +- 65816 long-mode support (`longa`/`longi`/`shorta`/`shorti`, 24-bit operands, + bank wrapping). A future `L_ASM_65C816` can be added the same way. +- WDC linker control file (`.lkr`) highlighting. +- Editor-side build integration (running `WDC65xx.exe`, parsing `.lst`). +- Auto-completion API file (`PowerEditor/installer/APIs/asm65c02.xml`). Can be + added later when API completion is wanted. +- A sophisticated function-list parser. v1 reuses the existing "label at column + 0 followed by `:`" heuristic. + +## 4. Architecture + +### 4.1 Lexer reuse + +LexAsm.cxx (`SCLEX_ASM`) is reused unchanged. It accepts eight `WordList`s: + +| Index | LexAsm role | Styler class | 65C02 content | +|-------|--------------------------|--------------|----------------------------------------------| +| 0 | CPU instructions | `instre1` | All W65C02S opcodes (NMOS + CMOS + WDC + Rockwell extensions) | +| 1 | Math (FPU) instructions | `instre2` | *empty* — no FPU | +| 2 | Registers | `type1` | `a x y s sp p pc` (case-insensitive matching)| +| 3 | Directives | `type2` | WDC Assembler directive set | +| 4 | Directive operands | `type3` | *empty* in v1 | +| 5 | Extended instructions | `type4` | *empty* in v1 | +| 6 | Fold-open directives | n/a | `macro if ifdef ifndef` | +| 7 | Fold-close directives | n/a | `mend endif` | + +LexAsm is case-insensitive by default (`asm.case.sensitive` defaults to false), +so keywords are listed in lowercase and match both `LDA` and `lda`. + +### 4.2 Language identity + +- Enum value: `L_ASM_65C02`, appended **immediately before `L_EXTERNAL`** in + `LangType` (preserves the "L_EXTERNAL is always last" invariant called out in + the enum's source comment, and keeps existing enum values stable for plugin + ABI compatibility). +- Short name: `asm65c02` +- Display name: `Assembly (65C02)` +- Description: `WDC 65C02 assembly source file` +- Default extension entry: `asm` (the same as `L_ASM` — see §4.5). +- Comment line marker: `;`. No block comments. + +### 4.3 Menu integration + +- New command ID `IDM_LANG_ASM_65C02` in `menuCmdID.h`, placed in the same + numeric block as other `IDM_LANG_*` commands. +- Two `Notepad_plus.rc` insertions, both immediately after the existing + `IDM_LANG_ASM` line: + - Language submenu (currently `MENUITEM "Assembly", IDM_LANG_ASM` at + `Notepad_plus.rc:1003`). + - Tab-context language list (currently `Notepad_plus.rc:1107`). + +### 4.4 ScintillaEditView wiring + +`PowerEditor/src/ScintillaComponent/ScintillaEditView.{h,cpp}`: + +- Append `{L"asm65c02", L"Assembly (65C02)", L"WDC 65C02 assembly source file", + L_ASM_65C02, "asm65c02"}` to the language descriptor table at line 138. +- Add `L_ASM_65C02` to each of the language-set checks at lines 1820 and 2477 + (these enable column-aware behavior shared with `L_CSS`, `L_CAML`, `L_ASM`, + `L_MATLAB`). +- Add `case L_ASM_65C02: setAsm65C02Lexer(); break;` in `defineDocType` near + line 1974 (immediately after the existing `L_ASM` case). +- Declare and inline-define `setAsm65C02Lexer()` in the header alongside + `setAsmLexer()` (around line 855); the body is identical: + `setLexer(L_ASM_65C02, LIST_0 | LIST_1 | LIST_2 | LIST_3 | LIST_4 | LIST_5 + | LIST_6 | LIST_7);`. + +### 4.5 Language ↔ command-ID maps + +- `Parameters.cpp` `langTypeToCommandID` (around line 8005): add a case + mapping `L_ASM_65C02 → IDM_LANG_ASM_65C02`. +- `Notepad_plus.cpp` `getLangFromMenuName` (around line 4024): add a branch + returning `L_ASM_65C02` for the menu name `Assembly (65C02)`. + +### 4.6 Default file-extension routing + +Both `L_ASM` and `L_ASM_65C02` declare `ext="asm"`. WDC source files +conventionally use `.asm`; the author accepts the trade-off that the *default* +language picked when opening a `.asm` file depends on the order in which the +two `` blocks appear in `langs.xml`, and that the language for any +individual file can be overridden manually via the **Languages** menu. + +To make 65C02 the default for `.asm` in PaperWasp, the new `` block is placed **after** `` in +`langs.model.xml`. Notepad++'s language registration is last-write-wins per +extension, so 65C02 will claim `.asm` on a fresh install. Users who prefer x86 +can reorder the entries in their personal `langs.xml`. + +### 4.7 Default styler + +`PowerEditor/src/stylers.model.xml` gains a new `` block. The `WordsStyle` entries (style IDs 0, +1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 14) mirror the existing `asm` lexer +block at line 76 since the underlying SCLEX_ASM style IDs are identical. The +default color choices are copied verbatim from the existing ASM block; users +can re-tune via Style Configurator. + +### 4.8 Function list + +`PowerEditor/installer/functionList/asm65c02.xml` is created by cloning +`asm.xml` and renaming `displayName` and `id` to `asm65c02` / +`asm65c02_subroutine`. The label-at-column-0-followed-by-`:` heuristic in the +existing parser already matches the dominant 65C02 source convention. + +`PowerEditor/installer/functionList/overrideMap.xml` is updated to associate +`asm65c02` with the new parser file. + +## 5. Keyword content (concrete lists) + +### 5.1 `instre1` — W65C02S instructions (lowercase, case-insensitive) + +NMOS-6502 base set: +`adc and asl bcc bcs beq bit bmi bne bpl brk bvc bvs clc cld cli clv cmp cpx +cpy dec dex dey eor inc inx iny jmp jsr lda ldx ldy lsr nop ora pha php pla +plp rol ror rti rts sbc sec sed sei sta stx sty tax tay tsx txa txs tya` + +CMOS additions: `bra phx phy plx ply stz trb tsb` + +WDC additions: `wai stp` + +Rockwell bit-test/bit-branch extensions: +`smb0 smb1 smb2 smb3 smb4 smb5 smb6 smb7 +rmb0 rmb1 rmb2 rmb3 rmb4 rmb5 rmb6 rmb7 +bbr0 bbr1 bbr2 bbr3 bbr4 bbr5 bbr6 bbr7 +bbs0 bbs1 bbs2 bbs3 bbs4 bbs5 bbs6 bbs7` + +### 5.2 `type1` — Registers + +`a x y s sp p pc` + +### 5.3 `type2` — WDC Assembler directives + +Data / layout: `equ db dw dd ds fill org chip endasm end` + +Modules / linker: `include import export extern global public record` + +Macros: `macro mend mexit mlist mnolist` + +Conditionals: `if ifdef ifndef else elseif endif` + +Listing controls: `list nolist title subttl page lf clrlst radix` + +Sections: `code data bss udata dpage ipage` + +### 5.4 `type5` / `type6` — fold pairs + +- Fold open (`type5`): `macro if ifdef ifndef` +- Fold close (`type6`): `mend endif` + +These keywords also appear in `type2` per the existing langs.model.xml +convention (the comment block at line 31 of the existing `asm` entry). + +## 6. Files changed / created + +**Modified:** + +- `PowerEditor/src/MISC/PluginsManager/Notepad_plus_msgs.h` — append + `L_ASM_65C02` before `L_EXTERNAL` in the `LangType` enum. +- `PowerEditor/src/menuCmdID.h` — add `IDM_LANG_ASM_65C02`. +- `PowerEditor/src/Notepad_plus.rc` — two `MENUITEM` insertions. +- `PowerEditor/src/ScintillaComponent/ScintillaEditView.h` — declare + `setAsm65C02Lexer()`. +- `PowerEditor/src/ScintillaComponent/ScintillaEditView.cpp` — descriptor table + row, two language-set updates, one `defineDocType` case. +- `PowerEditor/src/Parameters.cpp` — `langTypeToCommandID` case. +- `PowerEditor/src/Notepad_plus.cpp` — `getLangFromMenuName` case. +- `PowerEditor/src/langs.model.xml` — new `` block + after the existing ``. +- `PowerEditor/src/stylers.model.xml` — new `` + block. +- `PowerEditor/installer/functionList/overrideMap.xml` — register + `asm65c02.xml`. + +**Created:** + +- `PowerEditor/installer/functionList/asm65c02.xml` — cloned from `asm.xml`. + +## 7. Risks & trade-offs + +- **`.asm` extension collision.** Both languages claim `.asm`. Default routing + depends on ordering in `langs.xml`; PaperWasp ships with 65C02 last so it + wins. The fallback for any user who prefers x86 is the Languages menu or a + manual reorder of their `langs.xml`. +- **Enum-value stability.** `L_ASM_65C02` is appended at the tail (before + `L_EXTERNAL`) so existing plugin binaries that reference older `LangType` + values are unaffected. +- **Function-list parser is a heuristic.** Pure label-at-column-0 detection + will surface every label, including data and macro labels — not just + subroutines. Acceptable for v1; refinement is future work. +- **Upstream divergence.** This is a PaperWasp-only language; the upstream + Notepad++ project will not have it. Future merges from upstream need to + preserve these additions (typical for the PaperWasp port). + +## 8. Verification + +- macOS Xcode build (`cmake --build macos/build --target PaperWasp`) succeeds. +- App launches, **Languages** menu shows "Assembly (65C02)" near the existing + "Assembly" item. +- Opening a hand-written 65C02 sample file (`*.asm`) auto-detects the new + language; all four keyword classes (opcode, register, directive, comment) + render with distinct colors. +- Folding works on a sample using `if … endif` and `macro … mend`. +- Function list panel shows top-level labels. +- Switching a buffer manually from "Assembly (65C02)" → "Assembly" and back + works without crash. + +## 9. Open questions + +None at design time. Implementation may surface minor issues (e.g., how the +Windows resource compiler reacts to inserting the new menu item — should be +trivial) that will be handled in the implementation plan. diff --git a/macos/platform/language_defs.h b/macos/platform/language_defs.h index 0aed220ead01..b80d6a2aa9d4 100644 --- a/macos/platform/language_defs.h +++ b/macos/platform/language_defs.h @@ -12,6 +12,7 @@ struct LangDef const char* keywords; // Primary keywords (set 0) const char* keywords2; // Secondary keywords (set 1) - types, builtins int menuId; // Menu command ID + const char* keywordsExtra[6]; // Sets 2-7. Null-init means "not used". Required for lexers (e.g. LexAsm) that consume more than two word lists. }; // Named language indices for type-safe references @@ -49,6 +50,7 @@ constexpr int LANG_R = 30; constexpr int LANG_KOTLIN = 31; constexpr int LANG_SCALA = 32; constexpr int LANG_LATEX = 33; +constexpr int LANG_ASM_65C02 = 34; extern const LangDef g_languages[]; extern const int g_numLanguages; diff --git a/macos/platform/language_defs.mm b/macos/platform/language_defs.mm index ecb9ae544b9d..0a5419f19b07 100644 --- a/macos/platform/language_defs.mm +++ b/macos/platform/language_defs.mm @@ -240,6 +240,35 @@ "include input maketitle tableofcontents textbf textit emph underline", "article report book letter beamer memoir standalone", IDM_LANG_BASE + LANG_LATEX}, + {"Assembly (65C02)", "asm", + // keywords (set 0, CPU INSTRUCTION): NMOS 6502 + CMOS 65C02 + WDC (WAI/STP) + Rockwell (SMB/RMB/BBR/BBS) + "adc and asl bcc bcs beq bit bmi bne bpl brk bvc bvs clc cld cli clv cmp cpx cpy " + "dec dex dey eor inc inx iny jmp jsr lda ldx ldy lsr nop ora pha php pla plp rol " + "ror rti rts sbc sec sed sei sta stx sty tax tay tsx txa txs tya " + "bra phx phy plx ply stz trb tsb wai stp " + "smb0 smb1 smb2 smb3 smb4 smb5 smb6 smb7 " + "rmb0 rmb1 rmb2 rmb3 rmb4 rmb5 rmb6 rmb7 " + "bbr0 bbr1 bbr2 bbr3 bbr4 bbr5 bbr6 bbr7 " + "bbs0 bbs1 bbs2 bbs3 bbs4 bbs5 bbs6 bbs7", + // keywords2 (set 1, MATH INSTRUCTION): empty — no FPU on 65C02 + "", + IDM_LANG_BASE + LANG_ASM_65C02, + { + // set 2, REGISTER (type1) + "a x y s sp p pc", + // set 3, DIRECTIVE (type2): WDC Assembler/Linker directives + "equ db dw dd ds fill org chip endasm end include import export extern global " + "public record macro mend mexit mlist mnolist if ifdef ifndef else elseif endif " + "list nolist title subttl page lf clrlst radix code data bss udata dpage ipage", + // set 4, DIRECTIVE OPERAND (type3) — unused in v1 + "", + // set 5, EXT INSTRUCTION (type4) — unused in v1 + "", + // set 6, FOLD OPEN (type5) — must also appear in directives + "macro if ifdef ifndef", + // set 7, FOLD CLOSE (type6) — must also appear in directives + "mend endif", + }}, }; const int g_numLanguages = sizeof(g_languages) / sizeof(g_languages[0]); @@ -334,6 +363,9 @@ int guessLanguage(const std::wstring& filePath) if ([ext isEqualToString:@"tex"] || [ext isEqualToString:@"latex"] || [ext isEqualToString:@"sty"] || [ext isEqualToString:@"cls"]) return LANG_LATEX; + if ([ext isEqualToString:@"asm"] || [ext isEqualToString:@"a65"] || + [ext isEqualToString:@"s65"]) + return LANG_ASM_65C02; return LANG_NORMAL_TEXT; } diff --git a/macos/platform/lexer_styles.mm b/macos/platform/lexer_styles.mm index 803d7c8bd780..c5f489ce0553 100644 --- a/macos/platform/lexer_styles.mm +++ b/macos/platform/lexer_styles.mm @@ -282,7 +282,23 @@ {9, 0xCC6600, 0xDCDCAA, false, false}, // short command }; +// Assembly lexer styles (SCE_ASM_*) — used by Assembly (65C02) +static const StyleDef s_asmStyles[] = { + {1, 0x008000, 0x6A9955, false, false}, // COMMENT + {2, 0x0080FF, 0xB5CEA8, false, false}, // NUMBER + {3, 0x808080, 0xCE9178, false, false}, // STRING + {4, 0x800000, 0xD4D4D4, true, false}, // OPERATOR + {6, 0xFF0000, 0x569CD6, true, false}, // CPU INSTRUCTION + {7, 0xC08000, 0x4EC9B0, true, false}, // MATH INSTRUCTION + {8, 0xFF8080, 0xC586C0, true, false}, // REGISTER + {9, 0xFF8000, 0xDCDCAA, false, false}, // DIRECTIVE + {10, 0x800000, 0x9CDCFE, true, false}, // DIRECTIVE OPERAND + {12, 0x008080, 0xCE9178, false, false}, // CHARACTER + {14, 0x004080, 0xDCDCAA, true, false}, // EXT INSTRUCTION +}; + static const LexerStyles s_allLexerStyles[] = { + {"asm", s_asmStyles, sizeof(s_asmStyles) / sizeof(s_asmStyles[0])}, {"cpp", s_cppStyles, sizeof(s_cppStyles) / sizeof(s_cppStyles[0])}, {"objc", s_objcStyles, sizeof(s_objcStyles) / sizeof(s_objcStyles[0])}, {"python", s_pythonStyles, sizeof(s_pythonStyles) / sizeof(s_pythonStyles[0])}, @@ -333,6 +349,12 @@ void applyLanguageToView(void* sci, int langIndex) ScintillaBridge_sendMessage(sci, SCI_SETKEYWORDS, 0, (intptr_t)lang.keywords); if (lang.keywords2 && lang.keywords2[0]) ScintillaBridge_sendMessage(sci, SCI_SETKEYWORDS, 1, (intptr_t)lang.keywords2); + for (int i = 0; i < 6; ++i) + { + const char* kw = lang.keywordsExtra[i]; + if (kw && kw[0]) + ScintillaBridge_sendMessage(sci, SCI_SETKEYWORDS, 2 + i, (intptr_t)kw); + } ScintillaBridge_sendMessage(sci, SCI_SETPROPERTY, (uintptr_t)"fold", (intptr_t)"1"); ScintillaBridge_sendMessage(sci, SCI_SETPROPERTY, (uintptr_t)"fold.compact", (intptr_t)"0"); diff --git a/plugins/comparePlus/src/NppAPI/Notepad_plus_msgs.h b/plugins/comparePlus/src/NppAPI/Notepad_plus_msgs.h index 5a373ad1e8f4..10722d65eb2a 100644 --- a/plugins/comparePlus/src/NppAPI/Notepad_plus_msgs.h +++ b/plugins/comparePlus/src/NppAPI/Notepad_plus_msgs.h @@ -39,6 +39,7 @@ enum LangType {L_TEXT, L_PHP , L_C, L_CPP, L_CS, L_OBJC, L_JAVA, L_RC,\ L_REGISTRY, L_RUST, L_SPICE, L_TXT2TAGS, L_VISUALPROLOG,\ L_TYPESCRIPT, L_JSON5, L_MSSQL, L_GDSCRIPT, L_HOLLYWOOD,\ L_GOLANG, L_RAKU, L_TOML, L_SAS, L_ERRORLIST, \ + L_ASM_65C02, \ // Don't use L_JS_EMBEDDED, use L_JAVASCRIPT instead // The end of enumerated language type, so it should be always at the end L_EXTERNAL};