local GruvboxDark0Hard = 0x1d2021ff local GruvboxDark0 = 0x282828ff local GruvboxDark0Soft = 0x32302fff local GruvboxDark1 = 0x3c3836ff local GruvboxDark2 = 0x504945ff local GruvboxDark3 = 0x665c54ff local GruvboxDark4 = 0x7c6f64ff local GruvboxGray245 = 0x928374ff local GruvboxGray244 = 0x928374ff local GruvboxLight0Hard = 0xf9f5d7ff local GruvboxLight0 = 0xfbf1c7ff local GruvboxLight0Soft = 0xf2e5bcff local GruvboxLight1 = 0xebdbb2ff local GruvboxLight2 = 0xd5c4a1ff local GruvboxLight3 = 0xbdae93ff local GruvboxLight4 = 0xa89984ff local GruvboxBrightRed = 0xfb4934ff local GruvboxBrightGreen = 0xb8bb26ff local GruvboxBrightYellow = 0xfabd2fff local GruvboxBrightBlue = 0x83a598ff local GruvboxBrightPurple = 0xd3869bff local GruvboxBrightAqua = 0x8ec07cff local GruvboxBrightOrange = 0xfe8019ff local GruvboxNeutralRed = 0xcc241dff local GruvboxNeutralGreen = 0x98971aff local GruvboxNeutralYellow = 0xd79921ff local GruvboxNeutralBlue = 0x458588ff local GruvboxNeutralPurple = 0xb16286ff local GruvboxNeutralAqua = 0x689d6aff local GruvboxNeutralOrange = 0xd65d0eff local GruvboxFadedRed = 0x9d0006ff local GruvboxFadedGreen = 0x79740eff local GruvboxFadedYellow = 0xb57614ff local GruvboxFadedBlue = 0x076678ff local GruvboxFadedPurple = 0x8f3f71ff local GruvboxFadedAqua = 0x427b58ff local GruvboxFadedOrange = 0xaf3a03ff Color = {} Color.Text = GruvboxDark0Hard Color.LoadTextHighlight = 0x0000000F Color.Background = GruvboxLight0Hard Color.InactiveWindow = 0x0000000F Color.TextLineNumbers = GruvboxDark4 Color.LineHighlight = GruvboxLight0Soft Color.MainCaret = GruvboxDark0Hard Color.SubCaret = GruvboxGray245 Color.Selection = GruvboxLight1 Color.WhitespaceDuringSelection = GruvboxLight4 Color.MouseUnderline = GruvboxDark0Hard Color.CaretUnderline = GruvboxGray245 Color.FuzzySearchLineHighlight = GruvboxDark0 Color.ScrollbarBackground = GruvboxLight2 Color.ScrollbarScroller = GruvboxLight1 Color.ScrollbarScrollerSelected = GruvboxLight0Hard Color.TitleBarText = GruvboxDark2 Color.TitleBarBackground = GruvboxLight1 Color.TitleBarActiveBackground = 0xfefefefe Color.TitleBarSelection = GruvboxLight3 Color.ResizerBackground = GruvboxLight0Hard Color.ResizerOutline = GruvboxLight3 Style = {} Style.WaitForEvents = 1 Style.DrawLineNumbers = 1 Style.DrawScrollbar = 1 Style.IndentSize = 4 Style.FontSize = 15 Style.Font = GetExeDir().."/CascadiaMono.ttf" Style.VCVarsall = "C:/Program Files/Microsoft Visual Studio/2022/Community/VC/Auxiliary/Build/vcvars64.bat" Style.TrimWhitespaceOnSave = true Style.ClangFormatOnSave = false Style.StyleUndoMergeTimeout = 0.3 INTERNET_BROWSER = 'C:/Program Files/BraveSoftware/Brave-Browser/Application/brave.exe' OS_WINDOWS = 0 OS_UNIX = 1 SDLK_CTRL = 1073742048 SDLK_PAGE_DOWN = 1073741902 SDLK_PAGE_UP = 1073741899 SDLK_DOWN = 1073741905 -- 0x40000051 SDLK_UP = 1073741906 -- 0x40000052u SDLK_RIGHT = 1073741903 SDLK_LEFT = 1073741904 SDLK_Q = 113 SDLK_BACKSLASH = 0x5c SDLK_RETURN = 13 SDLK_EQUALS = 0x0000003d SDLK_MINUS = 0x0000002d SDLK_F1 = 0x4000003a SDLK_F2 = 0x4000003b SDLK_F3 = 0x4000003c SDLK_F4 = 0x4000003d SDLK_F5 = 0x4000003e SDLK_F6 = 0x4000003f SDLK_F7 = 0x40000040 SDLK_F8 = 0x40000041 SDLK_F9 = 0x40000042 SDLK_F10 = 0x40000043 SDLK_F11 = 0x40000044 SDLK_F12 = 0x40000045 SDLK_A = 0x00000061 SDLK_B = 0x00000062 SDLK_C = 0x00000063 SDLK_D = 0x00000064 SDLK_E = 0x00000065 SDLK_F = 0x00000066 SDLK_G = 0x00000067 SDLK_H = 0x00000068 SDLK_I = 0x00000069 SDLK_J = 0x0000006a SDLK_K = 0x0000006b SDLK_L = 0x0000006c SDLK_M = 0x0000006d SDLK_N = 0x0000006e SDLK_O = 0x0000006f SDLK_P = 0x00000070 SDLK_Q = 0x00000071 SDLK_R = 0x00000072 SDLK_S = 0x00000073 SDLK_T = 0x00000074 SDLK_U = 0x00000075 SDLK_V = 0x00000076 SDLK_W = 0x00000077 SDLK_X = 0x00000078 SDLK_Y = 0x00000079 SDLK_Z = 0x0000007a VERTICAL = 1 HORIZONTAL = 2 function IsAlpha(a) if a == nil then return false end local x = string.byte(a) local result = (x >= string.byte('a') and x <= string.byte('z')) or (x >= string.byte('A') and x <= string.byte('Z')) return result end function SkipLineAndColumn(s) local line, col = "-1", "-1" function parse_line_and_column(line_and_col, delimiter) ic, jc = line_and_col:find(delimiter) line = line_and_col:sub(1, ic - 1) col = line_and_col:sub(ic + 1) return line, col end do -- :line:column local i, j = s:find("^:%d+:%d+") if i then skip_pattern = s:sub(j + 1) line, col = parse_line_and_column(s:sub(2, j), ":") return line, col, skip_pattern end end do -- :line local i, j = s:find("^:%d+") if i then skip_pattern = s:sub(j + 1) line = s:sub(2, j) return line, col, skip_pattern end end do -- (line,column) local i, j = s:find("^%(%d+,%d+%)") if i then skip_pattern = s:sub(j + 1) line, col = parse_line_and_column(s:sub(2, j - 1), ",") return line, col, skip_pattern end end do -- (line) local i, j = s:find("^%(%d+%)") if i then skip_pattern = s:sub(j + 1) line = s:sub(2, j - 1) return line, col, skip_pattern end end return line, col, s end function SkipSlashes(s) found_slash = false while s:sub(1,1) == '/' or s:sub(1,1) == '\\' do s = s:sub(2) found_slash = true end return s, found_slash end function SkipDrive(s) local i, j = s:find("^%a:") if not i then return s, nil, true end local drive = s:sub(i, j) local new_s = s:sub(j + 1) new_s, found_slash = SkipSlashes(new_s) if not found_slash then return s, drive, false end return new_s, drive, true end function WindowsSkipPathCell(s) local i, j = s:find("^[%w_%.-% +]+") if not i then return s, nil, false end local word = s:sub(i, j) local new_s = s:sub(j + 1) local new_s, found_slash = SkipSlashes(new_s) return new_s, word, found_slash end function WindowsSkipPath(s) local input_s = s local s, drive, ok = SkipDrive(s) if not ok then return s end local cells = {} if drive ~= nil then table.insert(cells, drive) end while true do s, word, slash_eaten = WindowsSkipPathCell(s) if word then cells[#cells + 1] = word end if not slash_eaten then break end end if #cells == 0 then return s end local skip_size = input_s:len() - s:len() local path = input_s:sub(1, skip_size) return s, path, drive, cells end function MatchWindowsPath(_s, meta) local s, file_path, drive = WindowsSkipPath(_s) if not file_path and FileExists(drive) then return {kind = "text", file_path = drive, line = line, col = col} end if not file_path then return nil end if not drive then local d = GetMainDir() file_path = d..'/'..file_path end local line, col, s = SkipLineAndColumn(s) local exists = FileExists(file_path) or BufferExists(file_path) if not exists then return nil end return {kind = "text", file_path = file_path, line = line, col = col} end function MatchUnixPath(s, meta) local i, j = s:find("^[%w_%.-% %/]+") local path = s:sub(i, j) local rest = s:sub(j + 1, -1) local line, col, s = SkipLineAndColumn(rest) Print(path, rest, line, col) return {kind = "text", file_path = path, line = line, col = col} end if OS_VALUE == OS_WINDOWS then MatchPath = MatchWindowsPath else MatchPath = MatchUnixPath end function MatchGitCommit(s, meta) local i, j = string.find(s, "^commit ([a-zA-Z0-9]+)") if i then s = s:sub(8) local command = "git --no-pager show "..s return {kind = "exec", cmd = command, working_dir = GetMainDir()} end return nil end function MatchURL(s, meta) local i, j = string.find(s, "^https://") if i then return {kind = "exec_console", cmd = '"'..INTERNET_BROWSER..'" '..s, working_dir = GetMainDir()} end return nil end function MatchGotoBuild(s, meta) if meta ~= "goto_build" then return nil end local windows_path = IsAlpha(s:sub(1,1)) and s:sub(2,2) == ':' local windows_rela = s:sub(1,1) == '.' and s:sub(2,2) == '\\' local unix_path = s:sub(1,1) == '/' local unix_rela = s:sub(1,1) == '.' and s:sub(2,2) == '/' if not windows_path and not windows_rela and not unix_path and not windows_rela then return {kind = "skip"} end return nil end function MatchExec(s, meta) if s:match(".exe$") or s:match(".bat$") or s:match(".sh$") then return {kind = "exec_console", cmd = s, working_dir = GetMainDir()} end if s:match("^%$") then return {kind = "exec_console", cmd = s:sub(2, -1), working_dir = GetMainDir()} end return nil end BuiltinOnOpenMatchers = { MatchPath, MatchGitCommit, MatchURL, MatchGotoBuild, MatchExec, } OnOpenMatchers = BuiltinOnOpenMatchers function OnOpen(path, meta) for i = #OnOpenMatchers,1,-1 do rule = OnOpenMatchers[i] result = rule(path, meta) if result then return result end end return nil end Coroutines = {} function CoAdd(f) local i = #Coroutines + 1 Coroutines[i] = coroutine.create(f) coroutine.resume(Coroutines[i]) return Coroutines[i] end function OnUpdate(e) local new_co_list = {} for key, co in pairs(Coroutines) do local status = coroutine.status(co) if status ~= "dead" then coroutine.resume(co, e) new_co_list[#new_co_list + 1] = co end end Coroutines = new_co_list end function KeybindsBasic(e) if e.key == SDLK_F and e.ctrl == 1 and e.shift == 1 then C("git grep -n "..GetLoadWord().." :/") return true end return false end function BasicBuild() SaveAll() if OS_VALUE == OS_WINDOWS then return "build.bat" else return "./build.sh" end end FKey = {BasicBuild, "", "", "", "", "", "", "", "", "", "", ""} FKeySDLK = {SDLK_F1, SDLK_F2, SDLK_F3, SDLK_F4, SDLK_F5, SDLK_F6, SDLK_F7, SDLK_F8, SDLK_F9, SDLK_F10, SDLK_F11, SDLK_F12} function KeybindsFKeys(e) for i = #FKey,1,-1 do if FKey[i] ~= "" then if e.key == FKeySDLK[i] then local cmdline = FKey[i] if type(cmdline) == "function" then cmdline = FKey[i]() end Cmd { working_dir = GetWorkDir(), kind = "console", cmd = cmdline } return true end end end return false end BuiltinOnCommandCallbacks = { KeybindsBasic, KeybindsFKeys, } OnCommandCallbacks = BuiltinOnCommandCallbacks function OnCommand(e) for i = #OnCommandCallbacks,1,-1 do on_command = OnCommandCallbacks[i] local result = on_command(e) if result then return true end end return false end function OnInit() end function OnSave(buffer_id) local dont_trim_lines_with_caret = false ConvertLineEndingsToLF(buffer_id, dont_trim_lines_with_caret) if Style.TrimWhitespaceOnSave then TrimTrailingWhitespace(buffer_id, dont_trim_lines_with_caret) end local name = GetBufferNameByID(buffer_id) if Style.ClangFormatOnSave and (name:match(".c$") or name:match(".h$") or name:match(".cpp$") or name:match(".hpp$")) then ApplyClangFormat(buffer_id) end end function IsCodeExclude(s, meta) if s:match("/.git$") or s:match("\\.git$") or s:match(".exe$") or s:match(".bin$") or s:match(".obj$") or s:match(".o$") or s:match(".lib$") or s:match(".ilk$") or s:match(".cache$") or s:match(".exp$") or s:match(".pdb$") or s:match("/external/") or s:match("\\external\\") then return false end return true end BuiltinIsCodeMatchers = { IsCodeExclude, } IsCodeMatchers = BuiltinIsCodeMatchers function IsCode(path, meta) for i = #IsCodeMatchers,1,-1 do rule = IsCodeMatchers[i] result = rule(path, meta) if result then return result end end return false end