From 2668ca66e3639d3e943dbb674aefe18ec3b59d2e Mon Sep 17 00:00:00 2001 From: "METANEOCORTEX\\Kotti" Date: Wed, 24 Nov 2021 10:48:18 +0100 Subject: [PATCH 1/2] =?UTF-8?q?+fix:=20sync=20with=20current=20Oniguruma?= =?UTF-8?q?=20v7.0(=C3=9F)=20dev?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- scintilla/oniguruma/src/regcomp.c | 33 ++++++++++++++++++++----------- scintilla/oniguruma/src/regexec.c | 21 ++++++++++---------- 2 files changed, 32 insertions(+), 22 deletions(-) diff --git a/scintilla/oniguruma/src/regcomp.c b/scintilla/oniguruma/src/regcomp.c index 3145bf3e0..b0d673e39 100644 --- a/scintilla/oniguruma/src/regcomp.c +++ b/scintilla/oniguruma/src/regcomp.c @@ -3249,27 +3249,34 @@ enum GetValue { GET_VALUE_FOUND = 1 }; +#define MAX_NEST_LEVEL_GET_TREE_TAIL_LITERAL 16 + static int -get_tree_tail_literal(Node* node, Node** rnode, regex_t* reg) +get_tree_tail_literal(Node* node, Node** rnode, regex_t* reg, int nest_level) { int r; + nest_level++; + if (nest_level >= MAX_NEST_LEVEL_GET_TREE_TAIL_LITERAL) { + return GET_VALUE_NONE; + } + switch (NODE_TYPE(node)) { case NODE_LIST: if (IS_NULL(NODE_CDR(node))) { - r = get_tree_tail_literal(NODE_CAR(node), rnode, reg); + r = get_tree_tail_literal(NODE_CAR(node), rnode, reg, nest_level); } else { - r = get_tree_tail_literal(NODE_CDR(node), rnode, reg); + r = get_tree_tail_literal(NODE_CDR(node), rnode, reg, nest_level); if (r == GET_VALUE_IGNORE) { - r = get_tree_tail_literal(NODE_CAR(node), rnode, reg); + r = get_tree_tail_literal(NODE_CAR(node), rnode, reg, nest_level); } } break; #ifdef USE_CALL case NODE_CALL: - r = get_tree_tail_literal(NODE_BODY(node), rnode, reg); + r = get_tree_tail_literal(NODE_BODY(node), rnode, reg, nest_level); break; #endif @@ -3307,7 +3314,7 @@ get_tree_tail_literal(Node* node, Node** rnode, regex_t* reg) { QuantNode* qn = QUANT_(node); if (qn->lower != 0) { - r = get_tree_tail_literal(NODE_BODY(node), rnode, reg); + r = get_tree_tail_literal(NODE_BODY(node), rnode, reg, nest_level); } else r = GET_VALUE_NONE; @@ -3323,12 +3330,12 @@ get_tree_tail_literal(Node* node, Node** rnode, regex_t* reg) r = GET_VALUE_NONE; else { NODE_STATUS_ADD(node, MARK1); - r = get_tree_tail_literal(NODE_BODY(node), rnode, reg); + r = get_tree_tail_literal(NODE_BODY(node), rnode, reg, nest_level); NODE_STATUS_REMOVE(node, MARK1); } } else { - r = get_tree_tail_literal(NODE_BODY(node), rnode, reg); + r = get_tree_tail_literal(NODE_BODY(node), rnode, reg, nest_level); } } break; @@ -4585,7 +4592,7 @@ tune_look_behind(Node* node, regex_t* reg, int state, ParseEnv* env) if (IS_NULL(an->lead_node)) { an->char_min_len = ci.min; an->char_max_len = ci.max; - r = get_tree_tail_literal(body, &tail, reg); + r = get_tree_tail_literal(body, &tail, reg, 0); if (r == GET_VALUE_FOUND) { r = onig_node_copy(&(an->lead_node), tail); if (r != 0) return r; @@ -8079,8 +8086,12 @@ onig_detect_can_be_slow_pattern(const UChar* pattern, if (count.max_empty_check_nest_level > 2) n += count.max_empty_check_nest_level - 2; - if (count.heavy_element != 0) - n += count.heavy_element << 8; + if (count.heavy_element != 0) { + if (count.heavy_element < 0x10000) + n += count.heavy_element << 8; + else + n += count.heavy_element; + } r = n; diff --git a/scintilla/oniguruma/src/regexec.c b/scintilla/oniguruma/src/regexec.c index d0b1f4bf2..fa8c1b176 100644 --- a/scintilla/oniguruma/src/regexec.c +++ b/scintilla/oniguruma/src/regexec.c @@ -50,7 +50,6 @@ const OnigUChar* const _CRLF = "\r\n\0"; #define IS_LF_CODE(enc, s, end) (ONIGENC_MBC_TO_CODE((enc), (s), (end)) == NEWLINE_CODE) #define IS_CR_CODE(enc, s, end) (ONIGENC_MBC_TO_CODE((enc), (s), (end)) == CARRIAGE_RET) // ---------------------------------------------------------------------------- - #define CHECK_INTERRUPT_IN_MATCH #define STACK_MEM_START(reg, idx) \ @@ -3689,11 +3688,11 @@ match_at(regex_t* reg, const UChar* str, const UChar* end, UChar* sprev = (UChar* )onigenc_get_prev_char_head(encode, str, s); if (ONIGENC_IS_MBC_NEWLINE(encode, sprev, end)) { if (!IS_CRLF_NEWLINE(encode) || IS_LF_CODE(encode, sprev, end)) { - INC_OP; - JUMP_OUT; + INC_OP; + JUMP_OUT; + } } } - } goto fail; CASE_OP(END_LINE) @@ -3711,9 +3710,9 @@ match_at(regex_t* reg, const UChar* str, const UChar* end, } else if (ONIGENC_IS_MBC_NEWLINE(encode, s, end)) { if (!IS_CRLF_NEWLINE(encode) || IS_CR_CODE(encode, s, end)) { - INC_OP; - JUMP_OUT; - } + INC_OP; + JUMP_OUT; + } } #ifdef USE_CRNL_AS_LINE_TERMINATOR else if (ONIGENC_IS_MBC_CRNL(encode, s, end)) { @@ -5262,7 +5261,7 @@ forward_search(regex_t* reg, const UChar* str, const UChar* end, UChar* start, prev = onigenc_get_prev_char_head(reg->enc, (pprev ? pprev : str), p); if (IS_NOT_NULL(prev)) { if (!ONIGENC_IS_MBC_NEWLINE(reg->enc, prev, end)) { - goto retry_gate; + goto retry_gate; } else if (IS_CRLF_NEWLINE(reg->enc) && !IS_LF_CODE(reg->enc, prev, end)) { goto retry_gate; } @@ -5363,14 +5362,14 @@ backward_search(regex_t* reg, const UChar* str, const UChar* end, UChar* s, prev = onigenc_get_prev_char_head(reg->enc, str, p); if (IS_NOT_NULL(prev)) { if (!ONIGENC_IS_MBC_NEWLINE(reg->enc, prev, end)) { - p = prev; - goto retry; + p = prev; + goto retry; } else if (IS_CRLF_NEWLINE(reg->enc) && !IS_LF_CODE(reg->enc, prev, end)) { p = prev; goto retry; + } } } - } break; case ANCR_END_LINE: From 3e3dc5796bdfc257ff0d5def184a768bfdd15a57 Mon Sep 17 00:00:00 2001 From: "METANEOCORTEX\\Kotti" Date: Thu, 25 Nov 2021 13:49:45 +0100 Subject: [PATCH 2/2] +chg: switching to Philippe Lhoste's (PhiLho) AutoHotkey (AHK) Lexer --- Build/Notepad3.ini | 2 +- language/common_res.h | 2 + language/np3_de_de/lexer_de_de.rc | 4 +- language/np3_en_us/lexer_en_us.rc | 2 + lexilla/Lexilla.vcxproj | 2 +- lexilla/Lexilla.vcxproj.filters | 6 +- lexilla/lexers_x/CharSetX.h | 7 +- lexilla/lexers_x/LexAHK.cxx | 663 ++++++++++++++++++ lexilla/lexers_x/LexTOML.cxx | 2 +- lexilla/lexers_x/SciXLexer.h | 54 +- .../{LexAHKL.cxx => orig/LexAHKL2.cxx} | 0 .../lexers_x/orig}/styleLexAHKL.c | 0 lexilla/scripts/LexillaGen.py | 1 + lexilla/src/Lexilla.cxx | 4 +- .../Lexilla/Lexilla.xcodeproj/project.pbxproj | 4 + lexilla/src/deps.mak | 4 +- lexilla/src/lexilla.mak | 2 +- lexilla/src/nmdeps.mak | 4 +- res/StdDarkModeScheme.ini | 38 +- src/Notepad3.vcxproj | 2 +- src/Notepad3.vcxproj.filters | 6 +- src/StyleLexers/EditLexer.c | 4 +- src/StyleLexers/EditLexer.h | 2 +- src/StyleLexers/styleLexAHK.c | 156 +++++ src/Styles.c | 4 +- 25 files changed, 893 insertions(+), 82 deletions(-) create mode 100644 lexilla/lexers_x/LexAHK.cxx rename lexilla/lexers_x/{LexAHKL.cxx => orig/LexAHKL2.cxx} (100%) rename {src/StyleLexers => lexilla/lexers_x/orig}/styleLexAHKL.c (100%) create mode 100644 src/StyleLexers/styleLexAHK.c diff --git a/Build/Notepad3.ini b/Build/Notepad3.ini index 98d32b90e..5cb89200c 100644 --- a/Build/Notepad3.ini +++ b/Build/Notepad3.ini @@ -118,7 +118,7 @@ SettingsVersion=5 [ANSI Art] [Apache Config Files] [Assembly Script] -[AutoHotkey_L Script] +[AutoHotkey Script] [AutoIt3 Script] [AviSynth Script] [Awk Script] diff --git a/language/common_res.h b/language/common_res.h index 5664b5d36..1c6a4b97c 100644 --- a/language/common_res.h +++ b/language/common_res.h @@ -1232,6 +1232,8 @@ #define IDS_LEX_STR_63373 63373 #define IDS_LEX_STR_63374 63374 #define IDS_LEX_STR_63375 63375 +#define IDS_LEX_STR_63376 63376 +#define IDS_LEX_STR_63377 63377 #define IDS_LEX_CSV_COL_0 63400 #define IDS_LEX_CSV_COL_1 63401 diff --git a/language/np3_de_de/lexer_de_de.rc b/language/np3_de_de/lexer_de_de.rc index 6888ab35d..39e2ee920 100644 --- a/language/np3_de_de/lexer_de_de.rc +++ b/language/np3_de_de/lexer_de_de.rc @@ -481,7 +481,9 @@ BEGIN IDS_LEX_STR_63373 "Task Marker" IDS_LEX_STR_63374 "Comment Doc Error" IDS_LEX_STR_63375 "Type Operator" - END + IDS_LEX_STR_63376 "Special" + IDS_LEX_STR_63377 "Syntax Operator" +END STRINGTABLE BEGIN diff --git a/language/np3_en_us/lexer_en_us.rc b/language/np3_en_us/lexer_en_us.rc index 0f0423b95..04d667eb9 100644 --- a/language/np3_en_us/lexer_en_us.rc +++ b/language/np3_en_us/lexer_en_us.rc @@ -481,6 +481,8 @@ BEGIN IDS_LEX_STR_63373 "Task Marker" IDS_LEX_STR_63374 "Comment Doc Error" IDS_LEX_STR_63375 "Type Operator" + IDS_LEX_STR_63376 "Special" + IDS_LEX_STR_63377 "Syntax Operator" END STRINGTABLE diff --git a/lexilla/Lexilla.vcxproj b/lexilla/Lexilla.vcxproj index e420a530d..3b259596d 100644 --- a/lexilla/Lexilla.vcxproj +++ b/lexilla/Lexilla.vcxproj @@ -87,7 +87,7 @@ - + diff --git a/lexilla/Lexilla.vcxproj.filters b/lexilla/Lexilla.vcxproj.filters index 412c90057..61ec16a2d 100644 --- a/lexilla/Lexilla.vcxproj.filters +++ b/lexilla/Lexilla.vcxproj.filters @@ -203,9 +203,6 @@ lexers - - lexers_x - lexers_x @@ -272,6 +269,9 @@ lexers_x + + lexers_x + diff --git a/lexilla/lexers_x/CharSetX.h b/lexilla/lexers_x/CharSetX.h index 430df02ad..c01c2ffd4 100644 --- a/lexilla/lexers_x/CharSetX.h +++ b/lexilla/lexers_x/CharSetX.h @@ -50,14 +50,9 @@ constexpr bool IsWordCharEx(int ch) noexcept { return Lexilla::iswordchar(ch) || ch >= 0x80; } -constexpr bool IsABlankOrTab(const int ch) noexcept -{ - return ((ch == ' ') || (ch == '\t')); -} - constexpr bool IsWhiteSpace(const int ch) noexcept { - return ((ch == ' ') || ((ch >= 0x09) && (ch <= 0x0d))); + return Lexilla::isspacechar(ch); } constexpr bool IsAHexDigit(int ch) noexcept diff --git a/lexilla/lexers_x/LexAHK.cxx b/lexilla/lexers_x/LexAHK.cxx new file mode 100644 index 000000000..922492058 --- /dev/null +++ b/lexilla/lexers_x/LexAHK.cxx @@ -0,0 +1,663 @@ +// encoding: UTF-8 +// Scintilla source code edit control +/** @file LexAHK.cxx + ** Lexer for AutoHotkey, simplified version + ** Written by Philippe Lhoste (PhiLho) + **/ + // Copyright 1998-2006 by Neil Hodgson + // The License.txt file describes the conditions under which this software may be distributed. + /* notepad2-mod custom code for the AutoHotkey lexer */ + + +#include +#include +#include +// +#include "ILexer.h" +#include "Scintilla.h" +#include "StringCopy.h" +#include "PropSetSimple.h" +#include "LexAccessor.h" +#include "Accessor.h" +#include "StyleContext.h" +#include "LexerModule.h" +#include "DefaultLexer.h" +#include "OptionSet.h" +#include "WordList.h" +// +#include "CharSetX.h" +#include "SciXLexer.h" + + +using namespace Lexilla; +using namespace Scintilla; + + +// Options used for LexerRust +struct OptionsAHK +{ + bool fold; + bool foldComment; + bool foldCompact; + OptionsAHK() + : fold(false) + , foldComment(true) + , foldCompact(true) + { } +}; + +static const char* const ahkWordLists[] = +{ + "Flow of Control", + "Commands", + "Functions", + "Directives", + "Keys & Buttons", + "Variables", + "Special Parameters (keywords)", + "User Defined", + nullptr +}; + + + +struct OptionSetAHK : public OptionSet +{ + OptionSetAHK() + { + DefineProperty("fold", &OptionsAHK::fold); + DefineProperty("fold.comment", &OptionsAHK::foldComment); + DefineProperty("fold.compact", &OptionsAHK::foldCompact); + + DefineWordListSets(ahkWordLists); + } +}; + +class LexerAHK : public DefaultLexer +{ + + OptionsAHK options; + OptionSetAHK osAHK; + + WordList controlFlow; + WordList commands; + WordList functions; + WordList directives; + WordList keysButtons; + WordList variables; + WordList specialParams; + WordList userDefined; + + CharacterSet WordChar; + CharacterSet ExpOperator; + +public: + LexerAHK() : DefaultLexer("AHK", SCLEX_AHK, nullptr, 0), + //valLabel(CharacterSet::setAlphaNum, "@#$_~!^&*()+[]\';./\\<>?|{}-=\""), + WordChar(CharacterSet::setAlphaNum, "@#$_[]?"), + ExpOperator(CharacterSet::setNone, "+-*/!~&|^=<>.()") + { + } + + virtual ~LexerAHK() = default; + + void SCI_METHOD Release() override + { + delete this; + } + int SCI_METHOD Version() const override + { + return lvRelease5; + } + const char* SCI_METHOD PropertyNames() override + { + return osAHK.PropertyNames(); + } + int SCI_METHOD PropertyType(const char* name) override + { + return osAHK.PropertyType(name); + } + const char* SCI_METHOD PropertyGet(const char* name) override + { + return osAHK.PropertyGet(name); + } + const char* SCI_METHOD DescribeProperty(const char* name) override + { + return osAHK.DescribeProperty(name); + } + const char* SCI_METHOD DescribeWordListSets() override + { + return osAHK.DescribeWordListSets(); + } + void * SCI_METHOD PrivateCall(int, void *) override + { + return nullptr; + } + + // -------------------------------------------------------------------------- + Sci_Position SCI_METHOD PropertySet(const char* key, const char* val) override; + Sci_Position SCI_METHOD WordListSet(int n, const char *wl) override; + void SCI_METHOD Lex(Sci_PositionU startPos, Sci_Position lengthDoc, int initStyle, IDocument *pAccess) override; + void SCI_METHOD Fold(Sci_PositionU startPos, Sci_Position lengthDoc, int initStyle, IDocument *pAccess) override; + + static ILexer5 *LexerFactoryAHK() + { + return new LexerAHK(); + } + +private: + void HighlightKeyword(char currentWord[], StyleContext& sc); + +}; + +Sci_Position SCI_METHOD LexerAHK::PropertySet(const char* key, const char* val) +{ + if (osAHK.PropertySet(&options, key, val)) + { + return 0; + } + return -1; +} + + +Sci_Position SCI_METHOD LexerAHK::WordListSet(int n, const char *wl) +{ + WordList *wordListN = nullptr; + switch (n) + { + + case 0: + wordListN = &controlFlow; + break; + + case 1: + wordListN = &commands; + break; + + case 2: + wordListN = &functions; + break; + + case 3: + wordListN = &directives; + break; + + case 4: + wordListN = &keysButtons; + break; + + case 5: + wordListN = &variables; + break; + + case 6: + wordListN = &specialParams; + break; + + case 7: + wordListN = &userDefined; + break; + + } + + int firstModification = -1; + if (wordListN) + { + WordList wlNew; + wlNew.Set(wl); + if (*wordListN != wlNew) + { + wordListN->Set(wl); + firstModification = 0; + } + } + return firstModification; +} + + +void LexerAHK::HighlightKeyword(char currentWord[], StyleContext& sc) { + + if (controlFlow.InList(currentWord)) { + sc.ChangeState(SCE_AHK_WORD_CF); + } + else if (commands.InList(currentWord)) { + sc.ChangeState(SCE_AHK_WORD_CMD); + } + else if (functions.InList(currentWord)) { + sc.ChangeState(SCE_AHK_WORD_FN); + } + else if (currentWord[0] == '#' && directives.InList(currentWord + 1)) { + sc.ChangeState(SCE_AHK_WORD_DIR); + } + else if (keysButtons.InList(currentWord)) { + sc.ChangeState(SCE_AHK_WORD_KB); + } + else if (variables.InList(currentWord)) { + sc.ChangeState(SCE_AHK_WORD_VAR); + } + else if (specialParams.InList(currentWord)) { + sc.ChangeState(SCE_AHK_WORD_SP); + } + else if (userDefined.InList(currentWord)) { + sc.ChangeState(SCE_AHK_WORD_UD); + } + else { + sc.ChangeState(SCE_AHK_DEFAULT); + } +} + + + +void SCI_METHOD LexerAHK::Lex(Sci_PositionU startPos, Sci_Position lengthDoc, int initStyle, IDocument *pAccess) +{ + PropSetSimple props; + Accessor styler(pAccess, &props); + StyleContext sc(startPos, lengthDoc, initStyle, styler); + + // Do not leak onto next line + if (initStyle != SCE_AHK_COMMENTBLOCK && + initStyle != SCE_AHK_STRING) { + initStyle = SCE_AHK_DEFAULT; + } + int currentState = initStyle; + int nextState = -1; + char currentWord[256]; + + /* The AutoHotkey syntax is heavily context-dependent. + For example, for each command, the lexer knows if parameter #n + is a string, a variable, a number, an expression, etc. + I won't go this far, but I will try to handle most regular cases. + */ + // True if in a continuation section + bool bContinuationSection = (initStyle == SCE_AHK_STRING); + // Indicate if the lexer has seen only spaces since the start of the line + bool bOnlySpaces = (!bContinuationSection); + // Indicate if since the start of the line, lexer met only legal label chars + bool bIsLabel = false; + // Distinguish hotkeys from hotstring + bool bIsHotkey = false; + bool bIsHotstring = false; + // In an expression + bool bInExpression = false; + // A quoted string in an expression (share state with continuation section string) + bool bInExprString = false; + // To accept A-F chars in a number + bool bInHexNumber = false; + + + for (; sc.More(); sc.Forward()) { + if (nextState >= 0) { + // I need to reset a state before checking new char + sc.SetState(nextState); + nextState = -1; + } + if (sc.state == SCE_AHK_SYNOPERATOR) { + // Only one char (if two detected, we move Forward() anyway) + sc.SetState(SCE_AHK_DEFAULT); + } + if (sc.atLineEnd && (bIsHotkey || bIsHotstring)) { + // I make the hotkeys and hotstrings more visible + // by changing the line end to LABEL style (if style uses eolfilled) + bIsHotkey = bIsHotstring = false; + sc.SetState(SCE_AHK_LABEL); + } + if (sc.atLineStart) { + if (sc.state != SCE_AHK_COMMENTBLOCK && + !bContinuationSection) { + // Prevent some styles from leaking back to previous line + sc.SetState(SCE_AHK_DEFAULT); + } + bOnlySpaces = true; + bIsLabel = false; + bInExpression = false; // I don't manage multiline expressions yet! + bInHexNumber = false; + } + + // Manage cases occuring in (almost) all states (not in comments) + if (sc.state != SCE_AHK_COMMENTLINE && + sc.state != SCE_AHK_COMMENTBLOCK && + !IsASpace(sc.ch)) { + if (sc.ch == '`') { + // Backtick, escape sequence + currentState = sc.state; + sc.SetState(SCE_AHK_ESCAPE); + sc.Forward(); + nextState = currentState; + continue; + } + if (sc.ch == '%' && !bIsHotstring && !bInExprString && + sc.state != SCE_AHK_VARREF && + sc.state != SCE_AHK_VARREFKW && + sc.state != SCE_AHK_ERROR) { + if (IsASpace(sc.chNext)) { + if (sc.state == SCE_AHK_STRING) { + // Illegal unquoted character! + sc.SetState(SCE_AHK_ERROR); + } + else { + // % followed by a space is expression start + bInExpression = true; + } + } + else { + // Variable reference + currentState = sc.state; + sc.SetState(SCE_AHK_SYNOPERATOR); + nextState = SCE_AHK_VARREF; + continue; + } + } + if (sc.state != SCE_AHK_STRING && !bInExpression) { + // Management of labels, hotkeys, hotstrings and remapping + + // Check if the starting string is a label candidate + if (bOnlySpaces && + sc.ch != ',' && sc.ch != ';' && sc.ch != ':' && + sc.ch != '%' && sc.ch != '`') { + // A label cannot start with one of the above chars + bIsLabel = true; + } + + // The current state can be IDENTIFIER or DEFAULT, + // depending if the label starts with a word char or not + if (bIsLabel && sc.ch == ':' && + (IsASpace(sc.chNext) || sc.atLineEnd)) { + // ?l/a|b\e^l!: + // Only ; comment should be allowed after + sc.ChangeState(SCE_AHK_LABEL); + sc.SetState(SCE_AHK_SYNOPERATOR); + nextState = SCE_AHK_DEFAULT; + continue; + } + else if (sc.Match(':', ':')) { + if (bOnlySpaces) { + // Hotstring ::aa::Foo + bIsHotstring = true; + sc.SetState(SCE_AHK_SYNOPERATOR); + sc.Forward(); + nextState = SCE_AHK_LABEL; + continue; + } + // Hotkey F2:: or remapping a::b + bIsHotkey = true; + // Check if it is a known key + sc.GetCurrentLowered(currentWord, sizeof(currentWord)); + if (keysButtons.InList(currentWord)) { + sc.ChangeState(SCE_AHK_WORD_KB); + } + sc.SetState(SCE_AHK_SYNOPERATOR); + sc.Forward(); + if (bIsHotstring) { + nextState = SCE_AHK_STRING; + } + continue; + } + } + } + // Check if the current string is still a label candidate + // Labels are much more permissive than regular identifiers... + if (bIsLabel && + (sc.ch == ',' || sc.ch == '%' || sc.ch == '`' || IsASpace(sc.ch))) { + // Illegal character in a label + bIsLabel = false; + } + + // Determine if the current state should terminate. + if (sc.state == SCE_AHK_COMMENTLINE) { + if (sc.atLineEnd) { + sc.SetState(SCE_AHK_DEFAULT); + } + } + else if (sc.state == SCE_AHK_COMMENTBLOCK) { + if (bOnlySpaces && sc.Match('*', '/')) { + // End of comment at start of line (skipping white space) + sc.Forward(); + sc.ForwardSetState(SCE_AHK_DEFAULT); + } + } + else if (sc.state == SCE_AHK_EXPOPERATOR) { + if (!ExpOperator.Contains(sc.ch)) { + sc.SetState(SCE_AHK_DEFAULT); + } + } + else if (sc.state == SCE_AHK_STRING) { + if (bContinuationSection) { + if (bOnlySpaces && sc.ch == ')') { + // End of continuation section + bContinuationSection = false; + sc.SetState(SCE_AHK_SYNOPERATOR); + } + } + else if (bInExprString) { + if (sc.ch == '\"') { + if (sc.chNext == '\"') { + // In expression string, double quotes are doubled to escape them + sc.Forward(); // Skip it + } + else { + bInExprString = false; + sc.ForwardSetState(SCE_AHK_DEFAULT); + } + } + else if (sc.atLineEnd) { + sc.ChangeState(SCE_AHK_ERROR); + } + } + else { + if (sc.ch == ';' && IsASpace(sc.chPrev)) { + // Line comments after code must be preceded by a space + sc.SetState(SCE_AHK_COMMENTLINE); + } + } + } + else if (sc.state == SCE_AHK_NUMBER) { + if (bInHexNumber) { + if (!IsADigit(sc.ch, 16)) { + bInHexNumber = false; + sc.SetState(SCE_AHK_DEFAULT); + } + } + else if (!(IsADigit(sc.ch) || sc.ch == '.')) { + sc.SetState(SCE_AHK_DEFAULT); + } + } + else if (sc.state == SCE_AHK_IDENTIFIER) { + if (!WordChar.Contains(sc.ch)) { + sc.GetCurrentLowered(currentWord, sizeof(currentWord)); + HighlightKeyword(currentWord, sc); + if (strcmp(currentWord, "if") == 0) { + bInExpression = true; + } + sc.SetState(SCE_AHK_DEFAULT); + } + } + else if (sc.state == SCE_AHK_VARREF) { + if (sc.ch == '%') { + // End of variable reference + sc.GetCurrentLowered(currentWord, sizeof(currentWord)); + if (variables.InList(currentWord)) { + sc.ChangeState(SCE_AHK_VARREFKW); + } + sc.SetState(SCE_AHK_SYNOPERATOR); + nextState = currentState; + continue; + } + else if (!WordChar.Contains(sc.ch)) { + // Oops! Probably no terminating % + sc.ChangeState(SCE_AHK_ERROR); + } + } + else if (sc.state == SCE_AHK_LABEL) { + // Hotstring -- modifier or trigger string :*:aa::Foo or ::aa::Foo + if (sc.ch == ':') { + sc.SetState(SCE_AHK_SYNOPERATOR); + if (sc.chNext == ':') { + sc.Forward(); + } + nextState = SCE_AHK_LABEL; + continue; + } + } + + // Determine if a new state should be entered + if (sc.state == SCE_AHK_DEFAULT) { + if (sc.ch == ';' && + (bOnlySpaces || IsASpace(sc.chPrev))) { + // Line comments are alone on the line or are preceded by a space + sc.SetState(SCE_AHK_COMMENTLINE); + } + else if (bOnlySpaces && sc.Match('/', '*')) { + // Comment at start of line (skipping white space) + sc.SetState(SCE_AHK_COMMENTBLOCK); + sc.Forward(); + } + else if (sc.ch == '{' || sc.ch == '}') { + // Code block or special key {Enter} + sc.SetState(SCE_AHK_SYNOPERATOR); + } + else if (bOnlySpaces && sc.ch == '(') { + // Continuation section + bContinuationSection = true; + sc.SetState(SCE_AHK_SYNOPERATOR); + nextState = SCE_AHK_STRING; // !!! Can be an expression! + } + else if (sc.Match(':', '=') || + sc.Match('+', '=') || + sc.Match('-', '=') || + sc.Match('/', '=') || + sc.Match('*', '=')) { + // Expression assignment + bInExpression = true; + sc.SetState(SCE_AHK_SYNOPERATOR); + sc.Forward(); + nextState = SCE_AHK_DEFAULT; + } + else if (ExpOperator.Contains(sc.ch)) { + sc.SetState(SCE_AHK_EXPOPERATOR); + } + else if (sc.ch == '\"') { + bInExprString = true; + sc.SetState(SCE_AHK_STRING); + } + else if (sc.ch == '0' && (sc.chNext == 'x' || sc.chNext == 'X')) { + // Hexa, skip forward as we don't accept any other alpha char (beside A-F) inside + bInHexNumber = true; + sc.SetState(SCE_AHK_NUMBER); + sc.Forward(2); + } + else if (IsADigit(sc.ch) || (sc.ch == '.' && IsADigit(sc.chNext))) { + sc.SetState(SCE_AHK_NUMBER); + } + else if (WordChar.Contains(sc.ch)) { + sc.SetState(SCE_AHK_IDENTIFIER); + } + else if (sc.ch == ',') { + sc.SetState(SCE_AHK_SYNOPERATOR); + nextState = SCE_AHK_DEFAULT; + } + else if (sc.ch == ':') { + if (bOnlySpaces) { + // Start of hotstring :*:foo::Stuff or ::btw::Stuff + bIsHotstring = true; + sc.SetState(SCE_AHK_SYNOPERATOR); + if (sc.chNext == ':') { + sc.Forward(); + } + nextState = SCE_AHK_LABEL; + } + } + else if (WordChar.Contains(sc.ch)) { + sc.SetState(SCE_AHK_IDENTIFIER); + } + } + if (!IsASpace(sc.ch)) { + bOnlySpaces = false; + } + } + // End of file: complete any pending changeState + if (sc.state == SCE_AHK_IDENTIFIER) { + sc.GetCurrentLowered(currentWord, sizeof(currentWord)); + HighlightKeyword(currentWord, sc); + } + else if (sc.state == SCE_AHK_STRING && bInExprString) { + sc.ChangeState(SCE_AHK_ERROR); + } + else if (sc.state == SCE_AHK_VARREF) { + sc.ChangeState(SCE_AHK_ERROR); + } + sc.Complete(); + +} + + +void SCI_METHOD LexerAHK::Fold(Sci_PositionU startPos, Sci_Position lengthDoc, int initStyle, IDocument *pAccess) +{ + if (!options.fold) { return; } + + PropSetSimple props; + Accessor styler(pAccess, &props); + + bool const foldComment = options.foldComment; //props.GetInt("fold.comment") != 0; + bool const foldCompact = options.foldCompact; //props.GetInt("fold.compact", 1) != 0; + + Sci_PositionU endPos = startPos + lengthDoc; + + bool bOnlySpaces = true; + int lineCurrent = styler.GetLine(startPos); + int levelCurrent = SC_FOLDLEVELBASE; + if (lineCurrent > 0) { + levelCurrent = styler.LevelAt(lineCurrent - 1) & SC_FOLDLEVELNUMBERMASK; + } + int levelNext = levelCurrent; + char chNext = styler[startPos]; + int styleNext = styler.StyleAt(startPos); + int style = initStyle; + for (Sci_PositionU i = startPos; i < endPos; i++) { + char ch = chNext; + chNext = styler.SafeGetCharAt(i + 1); + int stylePrev = style; + style = styleNext; + styleNext = styler.StyleAt(i + 1); + bool atEOL = (ch == '\r' && chNext != '\n') || (ch == '\n'); + if (foldComment && style == SCE_AHK_COMMENTBLOCK) { + if (stylePrev != SCE_AHK_COMMENTBLOCK) { + levelNext++; + } + else if ((styleNext != SCE_AHK_COMMENTBLOCK) && !atEOL) { + // Comments don't end at end of line and the next character may be unstyled. + levelNext--; + } + } + if (style == SCE_AHK_SYNOPERATOR) { + if (ch == '(' || ch == '{') { + levelNext++; + } + else if (ch == ')' || ch == '}') { + levelNext--; + } + } + if (atEOL) { + int level = levelCurrent; + if (bOnlySpaces && foldCompact) { + // Empty line + level |= SC_FOLDLEVELWHITEFLAG; + } + if (!bOnlySpaces && levelNext > levelCurrent) { + level |= SC_FOLDLEVELHEADERFLAG; + } + if (level != styler.LevelAt(lineCurrent)) { + styler.SetLevel(lineCurrent, level); + } + lineCurrent++; + levelCurrent = levelNext; + bOnlySpaces = true; + } + if (!isspacechar(ch)) { + bOnlySpaces = false; + } + } + +} + +LexerModule lmAHK(SCLEX_AHK, LexerAHK::LexerFactoryAHK, "ahk", ahkWordLists); + diff --git a/lexilla/lexers_x/LexTOML.cxx b/lexilla/lexers_x/LexTOML.cxx index 67e68808e..6b252b7f0 100644 --- a/lexilla/lexers_x/LexTOML.cxx +++ b/lexilla/lexers_x/LexTOML.cxx @@ -339,7 +339,7 @@ static bool IsLookAheadInList(StyleContext& sc, const CharacterSet& validCh, con { int const ch = sc.GetRelative(i); - if (IsABlankOrTab(ch)) + if (IsASpaceOrTab(ch)) { if (j == 0) { diff --git a/lexilla/lexers_x/SciXLexer.h b/lexilla/lexers_x/SciXLexer.h index a33919185..251940bd4 100644 --- a/lexilla/lexers_x/SciXLexer.h +++ b/lexilla/lexers_x/SciXLexer.h @@ -3,7 +3,7 @@ #include "SciLexer.h" // Scintilla/Lexilla Lexer defines -#define SCLEX_AHKL 200 +#define SCLEX_AHK 200 #define SCLEX_CSV 201 #define SCLEX_DART 202 #define SCLEX_KOTLIN 203 @@ -13,37 +13,27 @@ // !!!!! ADD Lexer Linkage in: scintilla\src\Catalogue.cxx !!!!! // ----------------------------------------------------------------------------- -#define SCE_AHKL_NEUTRAL 0 -#define SCE_AHKL_IDENTIFIER 1 -#define SCE_AHKL_COMMENTDOC 2 -#define SCE_AHKL_COMMENTLINE 3 -#define SCE_AHKL_COMMENTBLOCK 4 -#define SCE_AHKL_COMMENTKEYWORD 5 -#define SCE_AHKL_STRING 6 -#define SCE_AHKL_STRINGOPTS 7 -#define SCE_AHKL_STRINGBLOCK 8 -#define SCE_AHKL_STRINGCOMMENT 9 -#define SCE_AHKL_LABEL 10 -#define SCE_AHKL_HOTKEY 11 -#define SCE_AHKL_HOTSTRING 12 -#define SCE_AHKL_HOTSTRINGOPT 13 -#define SCE_AHKL_HEXNUMBER 14 -#define SCE_AHKL_DECNUMBER 15 -#define SCE_AHKL_VAR 16 -#define SCE_AHKL_VARREF 17 -#define SCE_AHKL_OBJECT 18 -#define SCE_AHKL_USERFUNCTION 19 -#define SCE_AHKL_DIRECTIVE 20 -#define SCE_AHKL_COMMAND 21 -#define SCE_AHKL_PARAM 22 -#define SCE_AHKL_CONTROLFLOW 23 -#define SCE_AHKL_BUILTINFUNCTION 24 -#define SCE_AHKL_BUILTINVAR 25 -#define SCE_AHKL_KEY 26 -#define SCE_AHKL_USERDEFINED1 27 -#define SCE_AHKL_USERDEFINED2 28 -#define SCE_AHKL_ESCAPESEQ 30 -#define SCE_AHKL_ERROR 31 +#define SCE_AHK_DEFAULT 0 +#define SCE_AHK_COMMENTLINE 1 +#define SCE_AHK_COMMENTBLOCK 2 +#define SCE_AHK_ESCAPE 3 +#define SCE_AHK_SYNOPERATOR 4 +#define SCE_AHK_EXPOPERATOR 5 +#define SCE_AHK_STRING 6 +#define SCE_AHK_NUMBER 7 +#define SCE_AHK_IDENTIFIER 8 +#define SCE_AHK_VARREF 9 +#define SCE_AHK_LABEL 10 +#define SCE_AHK_WORD_CF 11 +#define SCE_AHK_WORD_CMD 12 +#define SCE_AHK_WORD_FN 13 +#define SCE_AHK_WORD_DIR 14 +#define SCE_AHK_WORD_KB 15 +#define SCE_AHK_WORD_VAR 16 +#define SCE_AHK_WORD_SP 17 +#define SCE_AHK_WORD_UD 18 +#define SCE_AHK_VARREFKW 19 +#define SCE_AHK_ERROR 20 #define SCE_CSV_DEFAULT 0 diff --git a/lexilla/lexers_x/LexAHKL.cxx b/lexilla/lexers_x/orig/LexAHKL2.cxx similarity index 100% rename from lexilla/lexers_x/LexAHKL.cxx rename to lexilla/lexers_x/orig/LexAHKL2.cxx diff --git a/src/StyleLexers/styleLexAHKL.c b/lexilla/lexers_x/orig/styleLexAHKL.c similarity index 100% rename from src/StyleLexers/styleLexAHKL.c rename to lexilla/lexers_x/orig/styleLexAHKL.c diff --git a/lexilla/scripts/LexillaGen.py b/lexilla/scripts/LexillaGen.py index be72ba1ae..4c65b156b 100644 --- a/lexilla/scripts/LexillaGen.py +++ b/lexilla/scripts/LexillaGen.py @@ -12,6 +12,7 @@ import os, pathlib, sys, uuid thisPath = pathlib.Path(__file__).resolve() +sys.path.append(str(thisPath.parent)) sys.path.append(str(thisPath.parent.parent.parent / "scintilla" / "scripts")) from FileGenerator import Regenerate, UpdateLineInFile, \ diff --git a/lexilla/src/Lexilla.cxx b/lexilla/src/Lexilla.cxx index 8a8b5a36a..175f35188 100644 --- a/lexilla/src/Lexilla.cxx +++ b/lexilla/src/Lexilla.cxx @@ -28,7 +28,7 @@ using namespace Lexilla; //++Autogenerated -- run lexilla/scripts/LexillaGen.py to regenerate //**\(extern LexerModule \*;\n\) -extern LexerModule lmAHKL; +extern LexerModule lmAHK; extern LexerModule lmAs; extern LexerModule lmAsm; extern LexerModule lmAU3; @@ -94,7 +94,7 @@ void AddEachLexer() { catalogueLexilla.AddLexerModules({ //++Autogenerated -- run scripts/LexillaGen.py to regenerate //**\(\t\t&\*,\n\) - &lmAHKL, + &lmAHK, &lmAs, &lmAsm, &lmAU3, diff --git a/lexilla/src/Lexilla/Lexilla.xcodeproj/project.pbxproj b/lexilla/src/Lexilla/Lexilla.xcodeproj/project.pbxproj index 9399b9cdb..a9e6fc0c6 100644 --- a/lexilla/src/Lexilla/Lexilla.xcodeproj/project.pbxproj +++ b/lexilla/src/Lexilla/Lexilla.xcodeproj/project.pbxproj @@ -160,6 +160,7 @@ 08084D78A14ADD9A4E3BBF45 /* LexerUtils.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 214542D293B8229DF76865BF /* LexerUtils.cxx */; }; 5CC5494D93A9A27918106106 /* LexKotlin.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 47A1492780FE119CF797F463 /* LexKotlin.cxx */; }; 63104C2F805ED6F2623BA2DC /* LexTOML.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 55A340DFB663EDFC048C3842 /* LexTOML.cxx */; }; + 5FC44C1DAAB2A99B8BFF4FF2 /* LexAHK.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 09C9445A93AF2DE63F616464 /* LexAHK.cxx */; }; /* End PBXBuildFile section */ /* Begin PBXFileReference section */ @@ -318,6 +319,7 @@ 214542D293B8229DF76865BF /* LexerUtils.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LexerUtils.cxx; path = ../../lexers/LexerUtils.cxx; sourceTree = SOURCE_ROOT; }; 47A1492780FE119CF797F463 /* LexKotlin.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LexKotlin.cxx; path = ../../lexers/LexKotlin.cxx; sourceTree = SOURCE_ROOT; }; 55A340DFB663EDFC048C3842 /* LexTOML.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LexTOML.cxx; path = ../../lexers/LexTOML.cxx; sourceTree = SOURCE_ROOT; }; + 09C9445A93AF2DE63F616464 /* LexAHK.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LexAHK.cxx; path = ../../lexers/LexAHK.cxx; sourceTree = SOURCE_ROOT; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -365,6 +367,7 @@ 28BA730624E34D9400272C2D /* LexA68k.cxx */, 28BA72EE24E34D9300272C2D /* LexAbaqus.cxx */, 28BA730024E34D9400272C2D /* LexAda.cxx */, + 09C9445A93AF2DE63F616464 /* LexAHK.cxx */, 1BCB4EB388CAB8BC57C8E524 /* LexAHKL.cxx */, 28BA72DF24E34D9200272C2D /* LexAPDL.cxx */, 28BA72FF24E34D9400272C2D /* LexAsm.cxx */, @@ -744,6 +747,7 @@ 08084D78A14ADD9A4E3BBF45 /* LexerUtils.cxx in Sources */, 5CC5494D93A9A27918106106 /* LexKotlin.cxx in Sources */, 63104C2F805ED6F2623BA2DC /* LexTOML.cxx in Sources */, + 5FC44C1DAAB2A99B8BFF4FF2 /* LexAHK.cxx in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/lexilla/src/deps.mak b/lexilla/src/deps.mak index 1e8fae10f..3ffe80ea1 100644 --- a/lexilla/src/deps.mak +++ b/lexilla/src/deps.mak @@ -555,8 +555,8 @@ LexYAML.o: \ ../lexlib/StyleContext.h \ ../lexlib/CharacterSet.h \ ../lexlib/LexerModule.h -LexAHKL.o: \ - ../lexers_x/LexAHKL.cxx \ +LexAHK.o: \ + ../lexers_x/LexAHK.cxx \ ../../scintilla/include/ILexer.h \ ../../scintilla/include/Sci_Position.h \ ../../scintilla/include/Scintilla.h \ diff --git a/lexilla/src/lexilla.mak b/lexilla/src/lexilla.mak index e9aed82cd..4a7a363b7 100644 --- a/lexilla/src/lexilla.mak +++ b/lexilla/src/lexilla.mak @@ -109,7 +109,7 @@ LEX_OBJS=\ $(DIR_O)\LexVB.obj \ $(DIR_O)\LexVHDL.obj \ $(DIR_O)\LexYAML.obj \ - $(DIR_O)\LexAHKL.obj \ + $(DIR_O)\LexAHK.obj \ $(DIR_O)\LexCSV.obj \ $(DIR_O)\LexDart.obj \ $(DIR_O)\LexerUtils.obj \ diff --git a/lexilla/src/nmdeps.mak b/lexilla/src/nmdeps.mak index 518cf0401..9493d0548 100644 --- a/lexilla/src/nmdeps.mak +++ b/lexilla/src/nmdeps.mak @@ -555,8 +555,8 @@ $(DIR_O)/LexYAML.obj: \ ../lexlib/StyleContext.h \ ../lexlib/CharacterSet.h \ ../lexlib/LexerModule.h -$(DIR_O)/LexAHKL.obj: \ - ../lexers_x/LexAHKL.cxx \ +$(DIR_O)/LexAHK.obj: \ + ../lexers_x/LexAHK.cxx \ ../../scintilla/include/ILexer.h \ ../../scintilla/include/Sci_Position.h \ ../../scintilla/include/Scintilla.h \ diff --git a/res/StdDarkModeScheme.ini b/res/StdDarkModeScheme.ini index 87bc0fd6b..268693ced 100644 --- a/res/StdDarkModeScheme.ini +++ b/res/StdDarkModeScheme.ini @@ -60,28 +60,24 @@ Extended Instruction=fore:#B4E1F5 Directive=fore:#B4E1F5 Directive Operand=fore:#B4E1F5 Register=fore:#F27E0D -[AutoHotkey_L Script] -Comment=fore:#76F873 -String=fore:#B7B7B7 -Label=fore:#8E9BED -HotKey=fore:#8EDAED -HotString=fore:#48F5F5 -KeyHotstringOption=fore:#F763F7 -Hex Number=fore:#F770F7 -Number=fore:#F28B0D -Variable=fore:#F28B0D -Variable Dereferencing=fore:#F761B5 -Object=fore:#70F7F7 -User-Defined Function=fore:#8E9BED -Directive=italic; fore:#FA949A -Command=bold; fore:#8E9BED -Parameter=fore:#8ECCED -Flow of Control=fore:#8E9BED -Function=fore:#F42BF4 -Built-In Variables=bold; fore:#E73619 -Key=fore:#5E5E5E +[AutoHotkey Script] +Comment=fore:#B7B7B7 Escape=italic; fore:#F98488 -Error=back:#F20C0D +Syntax Operator=fore:#B02D15 +Expression Operator=fore:#FF4F00 +String=fore:#0DAE09 +Number=fore:#F28B0D +Identifier=fore:#CF2F0F +Variable Dereferencing=fore:#F761B5 +Label=fore:#80FF80 +Flow of Control=fore:#0077EE +Command=bold; fore:#9B7309 +Function=fore:#F42BF4 +Directive=italic; fore:#FA949A +Keys & Buttons=bold; fore:#AC00AC +Built-In Variables=bold; fore:#E73619 +Special=italic; fore:#8888FF +Variable Keyword=italic; fore:#CF00CF [AutoIt3 Script] Comment=fore:#76F873 Number=fore:#76F8F8 diff --git a/src/Notepad3.vcxproj b/src/Notepad3.vcxproj index afa50ebfc..146772a41 100644 --- a/src/Notepad3.vcxproj +++ b/src/Notepad3.vcxproj @@ -636,6 +636,7 @@ + @@ -726,7 +727,6 @@ - diff --git a/src/Notepad3.vcxproj.filters b/src/Notepad3.vcxproj.filters index 79b7bc26a..faf9aac65 100644 --- a/src/Notepad3.vcxproj.filters +++ b/src/Notepad3.vcxproj.filters @@ -198,9 +198,6 @@ Source Files\StyleLexers - - Source Files\StyleLexers - Source Files\StyleLexers @@ -417,6 +414,9 @@ Source Files\StyleLexers + + Source Files\StyleLexers + diff --git a/src/StyleLexers/EditLexer.c b/src/StyleLexers/EditLexer.c index f7fd12c10..da7c35471 100644 --- a/src/StyleLexers/EditLexer.c +++ b/src/StyleLexers/EditLexer.c @@ -49,7 +49,7 @@ void Lexer_GetStreamCommentStrgs(LPWSTR beg_out, LPWSTR end_out, size_t maxlen) break; // ------------------ case SCLEX_NULL: - case SCLEX_AHKL: + case SCLEX_AHK: case SCLEX_ASM: case SCLEX_BASH: case SCLEX_BATCH: @@ -118,7 +118,7 @@ bool Lexer_GetLineCommentStrg(LPWSTR pre_out, size_t maxlen) case SCLEX_YAML: StringCchCopy(pre_out, maxlen, L"#"); return true; - case SCLEX_AHKL: + case SCLEX_AHK: case SCLEX_ASM: case SCLEX_AU3: case SCLEX_INNOSETUP: diff --git a/src/StyleLexers/EditLexer.h b/src/StyleLexers/EditLexer.h index 87cdeffec..0ae84b68d 100644 --- a/src/StyleLexers/EditLexer.h +++ b/src/StyleLexers/EditLexer.h @@ -93,7 +93,7 @@ extern EDITLEXER lexTEXT; // Pure Text Files extern EDITLEXER lexANSI; // ANSI Files extern EDITLEXER lexCONF; // Apache Config Files extern EDITLEXER lexASM; // Assembly Script -extern EDITLEXER lexAHKL; // AutoHotkey L Script +extern EDITLEXER lexAHK; // AutoHotkey Script extern EDITLEXER lexAU3; // AutoIt3 Script extern EDITLEXER lexAVS; // AviSynth Script extern EDITLEXER lexAwk; // Awk Script diff --git a/src/StyleLexers/styleLexAHK.c b/src/StyleLexers/styleLexAHK.c new file mode 100644 index 000000000..ce4d6d163 --- /dev/null +++ b/src/StyleLexers/styleLexAHK.c @@ -0,0 +1,156 @@ +#include "StyleLexers.h" + +// ---------------------------------------------------------------------------- + +KEYWORDLIST KeyWords_AHK = { + + // Flow of Control + "break continue else exit exitapp gosub goto if ifequal ifexist ifgreater ifgreaterorequal " + "ifinstring ifless iflessorequal ifmsgbox ifnotequal ifnotexist ifnotinstring ifwinactive " + "ifwinexist ifwinnotactive ifwinnotexist loop onexit pause repeat return settimer sleep " + "suspend static global local var byref while until for class try catch throw", + + // Commands + "autotrim blockinput clipwait control controlclick controlfocus controlget controlgetfocus " + "controlgetpos controlgettext controlmove controlsend controlsendraw controlsettext coordmode " + "critical detecthiddentext detecthiddenwindows drive driveget drivespacefree edit endrepeat " + "envadd envdiv envget envmult envset envsub envupdate fileappend filecopy filecopydir filecreatedir " + "filecreateshortcut fileencoding filedelete filegetattrib filegetshortcut filegetsize filegettime filegetversion " + "fileinstall filemove filemovedir fileread filereadline filerecycle filerecycleempty fileremovedir " + "fileselectfile fileselectfolder filesetattrib filesettime formattime getkeystate groupactivate " + "groupadd groupclose groupdeactivategui guicontrol guicontrolget hideautoitwin hotkey imagesearch " + "inidelete iniread iniwrite input inputbox keyhistory keywait listhotkeys listlines listvars menu " + "mouseclick mouseclickdrag mousegetpos mousemove msgbox outputdebug pixelgetcolor pixelsearch " + "postmessage process progress random regdelete regread regwrite reload run runas runwait send " + "sendevent sendinput sendmessage sendmode sendplay sendraw setbatchlines setcapslockstate " + "setcontroldelay setdefaultmousespeed setenv setformat setkeydelay setmousedelay setnumlockstate " + "setscrolllockstate setstorecapslockmode settitlematchmode setwindelay setworkingdir shutdown sort " + "soundbeep soundget soundgetwavevolume soundplay soundset soundsetwavevolume splashimage splashtextoff " + "splashtexton splitpath statusbargettext statusbarwait stringcasesense stringgetpos stringleft stringlen " + "stringlower stringmid stringreplace stringright stringsplit stringtrimleft stringtrimright stringupper " + "sysget thread tooltip transform traytip urldownloadtofile winactivate winactivatebottom winclose winget " + "wingetactivestats wingetactivetitle wingetclass wingetpos wingettext wingettitle winhide winkill " + "winmaximize winmenuselectitem winminimize winminimizeall winminimizeallundo winmove winrestore winset " + "winsettitle winshow winwait winwaitactive winwaitclose winwaitnotactive", + + // Functions + "abs acos asc asin atan ceil chr cos dllcall exp fileexist floor getkeystate numget numput " + "registercallback il_add il_create il_destroy instr islabel isfunc ln log lv_add lv_delete " + "lv_deletecol lv_getcount lv_getnext lv_gettext lv_insert lv_insertcol lv_modify lv_modifycol " + "lv_setimagelist mod onmessage round regexmatch regexreplace sb_seticon sb_setparts sb_settext " + "sin sqrt strlen substr tan tv_add tv_delete tv_getchild tv_getcount tv_getnext tv_get tv_getparent " + "tv_getprev tv_getselection tv_gettext tv_modify tv_setimagelist varsetcapacity winactive winexist " + "trim ltrim rtrim fileopen strget strput object array isobject objinsert objremove objminindex " + "objmaxindex objsetcapacity objgetcapacity objgetaddress objnewenum objaddref objrelease objhaskey " + "objclone _insert _remove _minindex _maxindex _setcapacity _getcapacity _getaddress _newenum _addref " + "_release _haskey _clone comobjcreate comobjget comobjconnect comobjerror comobjactive comobjenwrap " + "comobjunwrap comobjparameter comobjmissing comobjtype comobjvalue comobjarray comobjquery comobjflags " + "func getkeyname getkeyvk getkeysc isbyref exception", + + // Directives + "allowsamelinecomments clipboardtimeout commentflag errorstdout escapechar hotkeyinterval " + "hotkeymodifiertimeout hotstring if iftimeout ifwinactive ifwinexist include includeagain " + "installkeybdhook installmousehook keyhistory ltrim maxhotkeysperinterval maxmem maxthreads " + "maxthreadsbuffer maxthreadsperhotkey menumaskkey noenv notrayicon persistent singleinstance " + "usehook warn winactivateforce", + + // Keys & Buttons + "shift lshift rshift alt lalt ralt control lcontrol rcontrol ctrl lctrl rctrl lwin rwin appskey " + "altdown altup shiftdown shiftup ctrldown ctrlup lwindown lwinup rwindown rwinup lbutton rbutton " + "mbutton wheelup wheeldown xbutton1 xbutton2 joy1 joy2 joy3 joy4 joy5 joy6 joy7 joy8 joy9 joy10 " + "joy11 joy12 joy13 joy14 joy15 joy16 joy17 joy18 joy19 joy20 joy21 joy22 joy23 joy24 joy25 joy26 " + "joy27 joy28 joy29 joy30 joy31 joy32 joyx joyy joyz joyr joyu joyv joypov joyname joybuttons " + "joyaxes joyinfo space tab enter escape esc backspace bs delete del insert ins pgup pgdn home end " + "up down left right printscreen ctrlbreak pause scrolllock capslock numlock numpad0 numpad1 numpad2 " + "numpad3 numpad4 numpad5 numpad6 numpad7 numpad8 numpad9 numpadmult numpadadd numpadsub numpaddiv " + "numpaddot numpaddel numpadins numpadclear numpadup numpaddown numpadleft numpadright numpadhome " + "numpadend numpadpgup numpadpgdn numpadenter f1 f2 f3 f4 f5 f6 f7 f8 f9 f10 f11 f12 f13 f14 f15 " + "f16 f17 f18 f19 f20 f21 f22 f23 f24 browser_back browser_forward browser_refresh browser_stop " + "browser_search browser_favorites browser_home volume_mute volume_down volume_up media_next " + "media_prev media_stop media_play_pause launch_mail launch_media launch_app1 launch_app2 blind " + "click raw wheelleft wheelright", + + // Variables + "a_ahkpath a_ahkversion a_appdata a_appdatacommon a_autotrim a_batchlines a_caretx a_carety " + "a_computername a_controldelay a_cursor a_dd a_ddd a_dddd a_defaultmousespeed a_desktop " + "a_desktopcommon a_detecthiddentext a_detecthiddenwindows a_endchar a_eventinfo a_exitreason " + "a_formatfloat a_formatinteger a_gui a_guievent a_guicontrol a_guicontrolevent a_guiheight " + "a_guiwidth a_guix a_guiy a_hour a_iconfile a_iconhidden a_iconnumber a_icontip a_index " + "a_ipaddress1 a_ipaddress2 a_ipaddress3 a_ipaddress4 a_isadmin a_iscompiled a_issuspended " + "a_keydelay a_language a_lasterror a_linefile a_linenumber a_loopfield a_loopfileattrib " + "a_loopfiledir a_loopfileext a_loopfilefullpath a_loopfilelongpath a_loopfilename " + "a_loopfileshortname a_loopfileshortpath a_loopfilesize a_loopfilesizekb a_loopfilesizemb " + "a_loopfiletimeaccessed a_loopfiletimecreated a_loopfiletimemodified a_loopreadline a_loopregkey " + "a_loopregname a_loopregsubkey a_loopregtimemodified a_loopregtype a_mday a_min a_mm a_mmm " + "a_mmmm a_mon a_mousedelay a_msec a_mydocuments a_now a_nowutc a_numbatchlines a_ostype " + "a_osversion a_priorhotkey a_programfiles a_programs a_programscommon a_screenheight " + "a_screenwidth a_scriptdir a_scriptfullpath a_scriptname a_sec a_space a_startmenu " + "a_startmenucommon a_startup a_startupcommon a_stringcasesense a_tab a_temp a_thishotkey " + "a_thismenu a_thismenuitem a_thismenuitempos a_tickcount a_timeidle a_timeidlephysical " + "a_timesincepriorhotkey a_timesincethishotkey a_titlematchmode a_titlematchmodespeed " + "a_username a_wday a_windelay a_windir a_workingdir a_yday a_year a_yweek a_yyyy " + "clipboard clipboardall comspec errorlevel programfiles true false a_thisfunc a_thislabel " + "a_ispaused a_iscritical a_isunicode a_ptrsize a_scripthwnd a_priorkey", + + // Special Parameters (keywords) + "ltrim rtrim join ahk_id ahk_pid ahk_class ahk_group ahk_exe processname processpath minmax " + "controllist statuscd filesystem setlabel alwaysontop mainwindow nomainwindow useerrorlevel " + "altsubmit hscroll vscroll imagelist wantctrla wantf2 vis visfirst wantreturn backgroundtrans " + "minimizebox maximizebox sysmenu toolwindow exstyle check3 checkedgray readonly notab lastfound " + "lastfoundexist alttab shiftalttab alttabmenu alttabandmenu alttabmenudismiss controllisthwnd " + "hwnd deref pow bitnot bitand bitor bitxor bitshiftleft bitshiftright sendandmouse mousemove " + "mousemoveoff hkey_local_machine hkey_users hkey_current_user hkey_classes_root hkey_current_config " + "hklm hku hkcu hkcr hkcc reg_sz reg_expand_sz reg_multi_sz reg_dword reg_qword reg_binary reg_link " + "reg_resource_list reg_full_resource_descriptor reg_resource_requirements_list reg_dword_big_endian " + "regex pixel mouse screen relative rgb low belownormal normal abovenormal high realtime between " + "contains in is integer float number digit xdigit integerfast floatfast alpha upper lower alnum " + "time date not or and topmost top bottom transparent transcolor redraw region id idlast count " + "list capacity eject lock unlock label serial type status seconds minutes hours days read parse " + "logoff close error single shutdown menu exit reload tray add rename check uncheck togglecheck " + "enable disable toggleenable default nodefault standard nostandard color delete deleteall icon " + "noicon tip click show edit progress hotkey text picture pic groupbox button checkbox radio " + "dropdownlist ddl combobox statusbar treeview listbox listview datetime monthcal updown slider " + "tab tab2 activex iconsmall tile report sortdesc nosort nosorthdr grid hdr autosize range xm ym " + "ys xs xp yp font resize owner submit nohide minimize maximize restore noactivate na cancel " + "destroy center margin owndialogs guiescape guiclose guisize guicontextmenu guidropfiles tabstop " + "section wrap border top bottom buttons expand first lines number uppercase lowercase limit " + "password multi group background bold italic strike underline norm theme caption delimiter flash " + "style checked password hidden left right center section move focus hide choose choosestring text " + "pos enabled disabled visible notimers interrupt priority waitclose unicode tocodepage fromcodepage " + "yes no ok cancel abort retry ignore force on off all send wanttab monitorcount monitorprimary " + "monitorname monitorworkarea pid this base extends __get __set __call __delete __new new " + "useunsetlocal useunsetglobal useenv localsameasglobal", + + // User Defined + NULL, + + NULL +}; + + +EDITLEXER lexAHK = { + SCLEX_AHK, "ahk", IDS_LEX_AHK, L"AutoHotkey Script", L"ahk; ahkl; ia; scriptlet", L"", + &KeyWords_AHK, { + { {STYLE_DEFAULT}, IDS_LEX_STR_63126, L"Default", L"", L"" }, + //{ SCE_AHK_DEFAULT, IDS_LEX_STR_63126, L"Default", L"", L"" }, + { {MULTI_STYLE(SCE_AHK_COMMENTLINE,SCE_AHK_COMMENTBLOCK,0,0)}, IDS_LEX_STR_63127, L"Comment", L"fore:#008000", L"" }, + { {SCE_AHK_ESCAPE}, IDS_LEX_STR_63306, L"Escape", L"fore:#FF8000", L"" }, + { {SCE_AHK_SYNOPERATOR}, IDS_LEX_STR_63377, L"Syntax Operator", L"fore:#7F200F", L"" }, + { {SCE_AHK_EXPOPERATOR}, IDS_LEX_STR_63308, L"Expression Operator", L"fore:#FF4F00", L"" }, + { {SCE_AHK_STRING}, IDS_LEX_STR_63131, L"String", L"fore:#747474", L"" }, + { {SCE_AHK_NUMBER}, IDS_LEX_STR_63130, L"Number", L"fore:#416CAD", L"" }, + { {SCE_AHK_IDENTIFIER}, IDS_LEX_STR_63129, L"Identifier", L"fore:#CF2F0F", L"" }, + { {SCE_AHK_VARREF}, IDS_LEX_STR_63309, L"Variable Dereferencing", L"fore:#CF2F0F; back:#E4FFE4", L"" }, + { {SCE_AHK_LABEL}, IDS_LEX_STR_63235, L"Label", L"fore:#000000; back:#FFFFA1", L"" }, + { {SCE_AHK_WORD_CF}, IDS_LEX_STR_63310, L"Flow of Control", L"bold; fore:#880088", L"" }, + { {SCE_AHK_WORD_CMD}, IDS_LEX_STR_63236, L"Command", L"fore:#0036D9", L"" }, + { {SCE_AHK_WORD_FN}, IDS_LEX_STR_63277, L"Function", L"italic; fore:#0F707F", L"" }, + { {SCE_AHK_WORD_DIR}, IDS_LEX_STR_63203, L"Directive", L"italic; fore:#F04020", L"" }, + { {SCE_AHK_WORD_KB}, IDS_LEX_STR_63311, L"Keys & Buttons", L"bold; fore:#FF00FF", L"" }, + { {SCE_AHK_WORD_VAR}, IDS_LEX_STR_63312, L"Built-In Variables", L"italic; fore:#CF00CF", L"" }, + { {SCE_AHK_WORD_SP}, IDS_LEX_STR_63376, L"Special", L"italic; fore:#BD8E00", L"" }, + //{ {SCE_AHK_WORD_UD}, IDS_LEX_STR_63106, L"User Defined", L"fore:#800020", L"" }, + { {SCE_AHK_VARREFKW}, IDS_LEX_STR_63313, L"Variable Keyword", L"italic; fore:#CF00CF; back:#F9F9FF", L"" }, + EDITLEXER_SENTINEL + } +}; diff --git a/src/Styles.c b/src/Styles.c index e170ef384..46d77dabe 100644 --- a/src/Styles.c +++ b/src/Styles.c @@ -58,7 +58,7 @@ static PEDITLEXER g_pLexArray[] = { &lexANSI, // ANSI Files (ASCII Art) &lexCONF, // Apache Config Files &lexASM, // Assembly Script - &lexAHKL, // AutoHotkey L Script + &lexAHK, // AutoHotkey Script &lexAU3, // AutoIt3 Script &lexAVS, // AviSynth Script &lexAwk, // Awk Script @@ -4431,7 +4431,7 @@ CASE_WM_CTLCOLOR_SET: } ++i; } - assert(iCurStyleIdx != -1); + //assert(iCurStyleIdx != -1); } if (pCurrentStyle) { bIsStyleSelected = true;