vis

a vi-like editor based on Plan 9's structural regular expressions

git clone https://9o.is/git/vis.git

autohotkey.lua

(10370B)


      1 -- Copyright 2022-2025 Mitchell. See LICENSE.
      2 -- AutoHotkey LPeg lexer.
      3 -- Contributed by Snoopy.
      4 
      5 local lexer = lexer
      6 local P, S, B = lpeg.P, lpeg.S, lpeg.B
      7 
      8 local lex = lexer.new(...)
      9 
     10 -- Keywords.
     11 lex:add_rule('keyword', lex:tag(lexer.KEYWORD, lex:word_match(lexer.KEYWORD, true)))
     12 
     13 -- Variables.
     14 lex:add_rule('variable',
     15 	lex:tag(lexer.VARIABLE_BUILTIN, 'A_' * lex:word_match(lexer.VARIABLE_BUILTIN, true)))
     16 
     17 -- Constants.
     18 lex:add_rule('constant', lex:tag(lexer.CONSTANT_BUILTIN, S('fF') * lexer.digit * (lexer.digit)^-1 +
     19 	lex:word_match(lexer.CONSTANT_BUILTIN, true)))
     20 
     21 -- Functions.
     22 local builtin_func = -B('.') *
     23 	lex:tag(lexer.FUNCTION_BUILTIN, lex:word_match(lexer.FUNCTION_BUILTIN, true))
     24 local func = lex:tag(lexer.FUNCTION, lexer.word)
     25 local method = B('.') * lex:tag(lexer.FUNCTION_METHOD, lexer.word)
     26 lex:add_rule('function', (builtin_func + method + func) * #(lexer.space^0 * '('))
     27 
     28 -- Identifiers.
     29 lex:add_rule('identifier', lex:tag(lexer.IDENTIFIER, lexer.word))
     30 
     31 -- Comments.
     32 local line_comment = lexer.to_eol(';')
     33 local block_comment = lexer.range('/*', '*/')
     34 lex:add_rule('comment', lex:tag(lexer.COMMENT, line_comment + block_comment))
     35 
     36 -- Preprocessor.
     37 lex:add_rule('preprocessor',
     38 	lex:tag(lexer.PREPROCESSOR, '#' * lex:word_match(lexer.PREPROCESSOR, true)))
     39 
     40 -- Strings.
     41 local dq_str = lexer.range('"', true, false)
     42 local sq_str = lexer.range("'", true, false)
     43 lex:add_rule('string', lex:tag(lexer.STRING, dq_str + sq_str))
     44 
     45 -- Numbers.
     46 lex:add_rule('number', lex:tag(lexer.NUMBER, lexer.number))
     47 
     48 -- Operators.
     49 lex:add_rule('operator', lex:tag(lexer.OPERATOR, S('~+-^*/&<>=?:()[]{}')))
     50 
     51 lex:set_word_list(lexer.KEYWORD, {
     52 	'as', 'and', 'class', 'contains', 'extends', 'false', 'in', 'is', 'IsSet', 'not', 'or', 'super',
     53 	'true', 'unset', 'Break', 'Catch', 'Continue', 'Else', 'Finally', 'For', 'Global', 'Goto', 'If',
     54 	'Local', 'Loop', 'Return', 'Static', 'Throw', 'Try', 'Until', 'While'
     55 })
     56 
     57 lex:set_word_list(lexer.FUNCTION_BUILTIN, {
     58 	'Abs', 'AutoTrim', 'Asc', 'ASin', 'ACos', 'ATan', 'BlockInput', 'Ceil', 'Chr', 'Click',
     59 	'ClipWait', 'ComObjActive', 'ComObjArray', 'ComObjConnect', 'ComObjCreate', 'ComObject',
     60 	'ComObjEnwrap', 'ComObjUnwrap', 'ComObjError', 'ComObjFlags', 'ComObjGet', 'ComObjMissing',
     61 	'ComObjParameter', 'ComObjQuery', 'ComObjType', 'ComObjValue', 'Control', 'ControlClick',
     62 	'ControlFocus', 'ControlGet', 'ControlGetFocus', 'ControlGetPos', 'ControlGetText', 'ControlMove',
     63 	'ControlSend', 'ControlSendRaw', 'ControlSetText', 'CoordMode', 'Cos', 'Critical',
     64 	'DetectHiddenText', 'DetectHiddenWindows', 'DllCall', 'Drive', 'DriveGet', 'DriveSpaceFree',
     65 	'Edit', 'Else', 'EnvAdd', 'EnvDiv', 'EnvGet', 'EnvMult', 'EnvSet', 'EnvSub', 'EnvUpdate',
     66 	'Exception', 'Exit', 'ExitApp', 'Exp', 'FileAppend', 'FileCopy', 'FileCopyDir', 'FileCreateDir',
     67 	'FileCreateShortcut', 'FileDelete', 'FileEncoding', 'FileExist', 'FileInstall', 'FileGetAttrib',
     68 	'FileGetShortcut', 'FileGetSize', 'FileGetTime', 'FileGetVersion', 'FileMove', 'FileMoveDir',
     69 	'FileOpen', 'FileRead', 'FileReadLine', 'FileRecycle', 'FileRecycleEmpty', 'FileRemoveDir',
     70 	'FileSelectFile', 'FileSelectFolder', 'FileSetAttrib', 'FileSetTime', 'Floor', 'Format',
     71 	'FormatTime', 'Func', 'GetKeyName', 'GetKeyVK', 'GetKeySC', 'GetKeyState', 'GetKeyState', 'Gosub',
     72 	'GroupActivate', 'GroupAdd', 'GroupClose', 'GroupDeactivate', 'Gui', 'GuiControl',
     73 	'GuiControlGet', 'Hotkey', 'Hotstring', 'IfEqual', 'IfNotEqual', 'IfExist', 'IfNotExist',
     74 	'IfGreater', 'IfGreaterOrEqual', 'IfInString', 'IfNotInString', 'IfLess', 'IfLessOrEqual',
     75 	'IfMsgBox', 'IfWinActive', 'IfWinNotActive', 'IfWinExist', 'IfWinNotExist', 'IL_Create', 'IL_Add',
     76 	'IL_Destroy', 'ImageSearch', 'IniDelete', 'IniRead', 'IniWrite', 'Input', 'InputBox', 'InputHook',
     77 	'InStr', 'IsByRef', 'IsFunc', 'IsLabel', 'IsObject', 'IsSet', 'KeyHistory', 'KeyWait',
     78 	'ListHotkeys', 'ListLines', 'ListVars', 'LoadPicture', 'Log', 'Ln', 'LV_Add', 'LV_Delete',
     79 	'LV_DeleteCol', 'LV_GetCount', 'LV_GetNext', 'LV_GetText', 'LV_Insert', 'LV_InsertCol',
     80 	'LV_Modify', 'LV_ModifyCol', 'LV_SetImageList', 'Max', 'Menu', 'MenuGetHandle', 'MenuGetName',
     81 	'Min', 'Mod', 'MouseClick', 'MouseClickDrag', 'MouseGetPos', 'MouseMove', 'MsgBox', 'NumGet',
     82 	'NumPut', 'ObjAddRef', 'ObjRelease', 'ObjBindMethod', 'ObjClone', 'ObjCount', 'ObjDelete',
     83 	'ObjGetAddress', 'ObjGetCapacity', 'ObjHasKey', 'ObjInsert', 'ObjInsertAt', 'ObjLength',
     84 	'ObjMaxIndex', 'ObjMinIndex', 'ObjNewEnum', 'ObjPop', 'ObjPush', 'ObjRemove', 'ObjRemoveAt',
     85 	'ObjSetCapacity', 'ObjGetBase', 'ObjRawGet', 'ObjRawSet', 'ObjSetBase', 'OnClipboardChange',
     86 	'OnError', 'OnExit', 'OnExit', 'OnMessage', 'Ord', 'OutputDebug', 'Pause', 'PixelGetColor',
     87 	'PixelSearch', 'PostMessage', 'Process', 'Progress', 'Random', 'RegExMatch', 'RegExReplace',
     88 	'RegDelete', 'RegRead', 'RegWrite', 'RegisterCallback', 'Reload', 'Round', 'Run', 'RunAs',
     89 	'RunWait', 'SB_SetIcon', 'SB_SetParts', 'SB_SetText', 'Send', 'SendRaw', 'SendInput', 'SendPlay',
     90 	'SendEvent', 'SendLevel', 'SendMessage', 'SendMode', 'SetBatchLines', 'SetCapsLockState',
     91 	'SetControlDelay', 'SetDefaultMouseSpeed', 'SetEnv', 'SetFormat', 'SetKeyDelay', 'SetMouseDelay',
     92 	'SetNumLockState', 'SetScrollLockState', 'SetRegView', 'SetStoreCapsLockMode', 'SetTimer',
     93 	'SetTitleMatchMode', 'SetWinDelay', 'SetWorkingDir', 'Shutdown', 'Sin', 'Sleep', 'Sort',
     94 	'SoundBeep', 'SoundGet', 'SoundGetWaveVolume', 'SoundPlay', 'SoundSet', 'SoundSetWaveVolume',
     95 	'SplashImage', 'SplashTextOn', 'SplashTextOff', 'SplitPath', 'Sqrt', 'StatusBarGetText',
     96 	'StatusBarWait', 'StrGet', 'StringCaseSense', 'StringGetPos', 'StringLeft', 'StringLen',
     97 	'StringLower', 'StringMid', 'StringReplace', 'StringRight', 'StringSplit', 'StringTrimLeft',
     98 	'StringTrimRight', 'StringUpper', 'StrLen', 'StrPut', 'StrReplace', 'StrSplit', 'SubStr',
     99 	'Suspend', 'Switch', 'SysGet', 'Tan', 'Thread', 'ToolTip', 'Transform', 'TrayTip', 'Trim',
    100 	'LTrim', 'RTrim', 'TV_Add', 'TV_Delete', 'TV_Get', 'TV_GetChild', 'TV_GetCount', 'TV_GetNext',
    101 	'TV_GetParent', 'TV_GetPrev', 'TV_GetSelection', 'TV_GetText', 'TV_Modify', 'TV_SetImageList',
    102 	'UrlDownloadToFile', 'VarSetCapacity', 'WinActivate', 'WinActivateBottom', 'WinActive',
    103 	'WinClose', 'WinExist', 'WinGetActiveStats', 'WinGetActiveTitle', 'WinGetClass', 'WinGet',
    104 	'WinGetPos', 'WinGetText', 'WinGetTitle', 'WinHide', 'WinKill', 'WinMaximize',
    105 	'WinMenuSelectItem', 'WinMinimize', 'WinMinimizeAll', 'WinMinimizeAllUndo', 'WinMove',
    106 	'WinRestore', 'WinSet', 'WinSetTitle', 'WinShow', 'WinWait', 'WinWaitActive', 'WinWaitNotActive',
    107 	'WinWaitClose'
    108 })
    109 
    110 lex:set_word_list(lexer.PREPROCESSOR, {
    111 	'ClipboardTimeout', 'CommentFlag', 'Delimiter', 'DerefChar', 'ErrorStdOut', 'EscapeChar',
    112 	'HotkeyInterval', 'HotkeyModifierTimeout', 'Hotstring', 'If', 'IfTimeout', 'IfWinActive',
    113 	'IfWinNotActive', 'IfWinExist', 'IfWinNotExist', 'Include', 'IncludeAgain', 'InputLevel',
    114 	'InstallKeybdHook', 'InstallMouseHook', 'KeyHistory', 'LTrim', 'MaxHotkeysPerInterval', 'MaxMem',
    115 	'MaxThreads', 'MaxThreadsBuffer', 'MaxThreadsPerHotkey', 'MenuMaskKey', 'NoEnv', 'NoTrayIcon',
    116 	'Persistent', 'Requires', 'SingleInstance', 'UseHook', 'Warn', 'WinActivateForce'
    117 })
    118 
    119 lex:set_word_list(lexer.CONSTANT_BUILTIN, {
    120 	'LButton', 'RButton', 'MButton', 'Advanced Buttons', 'XButton1', 'XButton2', 'Wheel', 'WheelDown',
    121 	'WheelUp', 'WheelLeft', 'WheelRight', 'CapsLock', 'Space', 'Tab', 'Enter', 'Return', 'Esc',
    122 	'Escape', 'BS', 'Backspace', 'ScrollLock', 'Del', 'Delete', 'Ins', 'Insert', 'Home', 'End',
    123 	'PgUp', 'PgDn', 'Up', 'Down', 'Left', 'Right', 'Numpad0', 'NumpadIns', 'Numpad1', 'NumpadEnd',
    124 	'Numpad2', 'NumpadDown', 'Numpad3', 'NumpadPgDn', 'Numpad4', 'NumpadLeft', 'Numpad5',
    125 	'NumpadClear', 'Numpad6', 'NumpadRight', 'Numpad7', 'NumpadHome', 'Numpad8', 'NumpadUp',
    126 	'Numpad9', 'NumpadPgUp', 'NumpadDot', 'NumpadDel', 'NumLock', 'NumpadDiv', 'NumpadMult',
    127 	'NumpadAdd', 'NumpadSub', 'NumpadEnter', 'LWin', 'RWin', 'Ctrl', 'Control', 'Alt', 'Shift',
    128 	'LCtrl', 'LControl', 'RCtrl', 'RControl', 'LShift', 'RShift', 'LAlt', 'RAlt', 'Browser_Back',
    129 	'Browser_Forward', 'Browser_Refresh', 'Browser_Stop', 'Browser_Search', 'Browser_Favorites',
    130 	'Browser_Home', 'Volume_Mute', 'Volume_Down', 'Volume_Up', 'Media_Next', 'Media_Prev',
    131 	'Media_Stop', 'Media_Play_Pause', 'Launch_Mail', 'Launch_Media', 'Launch_App1', 'Launch_App2',
    132 	'AppsKey', 'PrintScreen', 'CtrlBreak', 'Pause', 'Break', 'Help'
    133 })
    134 
    135 lex:set_word_list(lexer.VARIABLE_BUILTIN, {
    136 	'Space', 'Tab', 'Args', 'WorkingDir', 'InitialWorkingDir', 'ScriptDir', 'ScriptName',
    137 	'ScriptFullPath', 'ScriptHwnd', 'LineNumber', 'LineFile', 'ThisFunc', 'ThisLabel', 'AhkVersion',
    138 	'AhkPath', 'IsUnicode', 'IsCompiled', 'ExitReason', 'Year', 'MM', 'DD', 'MMMM', 'MMM', 'DDDD',
    139 	'DDD', 'WDay', 'YDay', 'YWeek', 'Hour', 'Min', 'Sec', 'MSec', 'Now', 'NowUTC', 'TickCount',
    140 	'IsSuspended', 'IsPaused', 'IsCritical', 'BatchLines', 'ListLines', 'TitleMatchMode',
    141 	'TitleMatchModeSpeed', 'DetectHiddenWindows', 'DetectHiddenText', 'AutoTrim', 'StringCaseSense',
    142 	'FileEncoding', 'FormatInteger', 'FormatFloat', 'SendMode', 'SendLevel', 'StoreCapsLockMode',
    143 	'KeyDelay', 'KeyDuration', 'KeyDelayPlay', 'KeyDurationPlay', 'WinDelay', 'ControlDelay',
    144 	'MouseDelay', 'MouseDelayPlay', 'DefaultMouseSpeed', 'CoordModeToolTip', 'CoordModePixel',
    145 	'CoordModeMouse', 'CoordModeCaret', 'CoordModeMenu', 'RegView', 'IconHidden', 'IconTip',
    146 	'IconFile', 'IconNumber', 'TimeIdle', 'TimeIdlePhysical', 'TimeIdleKeyboard', 'TimeIdleMouse',
    147 	'DefaultGui', 'DefaultListView', 'DefaultTreeView', 'Gui', 'GuiControl', 'GuiWidth', 'GuiHeight',
    148 	'GuiX', 'GuiY', 'GuiEvent', 'GuiControlEvent', 'EventInfo', 'ThisMenuItem', 'ThisMenu',
    149 	'ThisMenuItemPos', 'ThisHotkey', 'PriorHotkey', 'PriorKey', 'TimeSinceThisHotkey',
    150 	'TimeSincePriorHotkey', 'EndChar', 'ComSpec', 'Temp', 'OSType', 'OSVersion', 'Is64bitOS',
    151 	'PtrSize', 'Language', 'ComputerName', 'UserName', 'WinDir', 'ProgramFiles', 'AppData',
    152 	'AppDataCommon', 'Desktop', 'DesktopCommon', 'StartMenu', 'StartMenuCommon', 'Programs',
    153 	'ProgramsCommon', 'Startup', 'StartupCommon', 'MyDocuments', 'IsAdmin', 'ScreenWidth',
    154 	'ScreenHeight', 'ScreenDPI', 'Cursor', 'CaretX', 'CaretY', 'Clipboard', 'LastError', 'Index',
    155 	'LoopFileName', 'LoopRegName', 'LoopReadLine', 'LoopField'
    156 })
    157 
    158 lexer.property['scintillua.comment'] = ';'
    159 
    160 -- Fold points.
    161 lex:add_fold_point(lexer.OPERATOR, '{', '}')
    162 lex:add_fold_point(lexer.COMMENT, '/*', '*/')
    163 
    164 return lex