Advertisement
Guest User

Библиотека подсветки синтаксиса

a guest
Jul 13th, 2020
123
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 10.14 KB | None | 0 0
  1. local gpu = require("component").gpu
  2. local unicode = require("unicode")
  3. local syntax = {}
  4.  
  5. local colorSchemes = {
  6.   ["custom"] = {
  7.     -- ["recommendedBackground"] = 0x000000,
  8.     ["functions"] = 0xff6699,
  9.     ["comments"]  = 0x336600,
  10.     ["compares"]  = 0xff3333,
  11.     ["strings"]   = 0x333333,
  12.     ["boolean"]   = 0xffcc33,
  13.     ["numbers"]   = 0x333399,
  14.     ["default"]   = 0xcccccc,
  15.     ["loops"]     = 0x6699ff,
  16.     ["logic"]     = 0xcc66cc,
  17.     ["vars"]      = 0x33cc33,
  18.   },
  19. }
  20.  
  21. local currentColorScheme = {}
  22. local patterns
  23. local patternsCount
  24.  
  25. --Приоритет поиска шаблонов снижается сверху вниз
  26. local function definePatterns()
  27.   local Scheme = currentColorScheme
  28.   local Trim2 = function(Return, str, fs, fe, tPattern)
  29.                   --table.insert(Return, {
  30.                   --  ["word"] = string.sub(str, fs, fs),
  31.                   --  ["color"] = currentColorScheme.default
  32.                   --})
  33.                  
  34.                   table.insert(Return, {
  35.                     ["word"] = string.sub(str, fs, fe - 1),
  36.                     ["color"] = tPattern.color
  37.                   })
  38.                  
  39.                   table.insert(Return, {
  40.                     ["word"] = string.sub(str, fe, fe),
  41.                     ["color"] = currentColorScheme.default
  42.                   })
  43.          
  44.                   return fe + 1
  45.                 end
  46.  
  47.   local TrimR = function(Return, str, fs, fe, tPattern)
  48.                   table.insert(Return, {
  49.                     ["word"] = string.sub(str, fs, fe - 1),
  50.                     ["color"] = tPattern.color
  51.                   })
  52.                  
  53.                   return fe
  54.                 end
  55.  
  56.   local TrimOffset = function(Return, str, fs, fe, tPattern)
  57.                   table.insert(Return, {
  58.                     ["word"] = string.sub(str, fs, fe - 1),
  59.                     ["color"] = tPattern.color
  60.                   })
  61.                  
  62.                   return fe
  63.                 end
  64.  
  65.   local FuncOnNum = function(Return, str, fs, fe, tPattern)
  66.                       local Color = currentColorScheme.default
  67.                      
  68.                       if string.find(string.sub(str, fs - 1, fs - 1), "%A") then
  69.                         Color = tPattern.color
  70.                       end
  71.                      
  72.                       table.insert(Return, {
  73.                         ["word"] = string.sub(str, fs, fe),
  74.                         ["color"] = Color
  75.                       })
  76.                      
  77.                       return fe + 1
  78.                     end
  79.  
  80.   patterns = {
  81.     --Комментарии
  82.     { ["pattern"] = "%-%-.*", ["color"] = Scheme.comments },
  83.    
  84.     --Строки
  85.     { ["pattern"] = "\"\"", ["color"] = Scheme.strings },
  86.     { ["pattern"] = "\'\'", ["color"] = Scheme.strings },
  87.    
  88.     { ["pattern"] = "\".-[^\\]\"", ["color"] = Scheme.strings },
  89.     { ["pattern"] = "\'.-[^\\]\'", ["color"] = Scheme.strings },
  90.    
  91.     --Слова с большой буквы(переменые)
  92.     { ["pattern"] = "%u[%a0-9_]*", ["color"] = Scheme.vars, ["func"] = FuncOnNum },
  93.    
  94.     --Числа
  95.     { ["pattern"] = "0x[A-Fa-f0-9]+", ["color"] = Scheme.numbers, ["func"] = FuncOnNum },
  96.     { ["pattern"] = "(%d+%.?%d*)",    ["color"] = Scheme.numbers, ["func"] = FuncOnNum },
  97.    
  98.     --Сравнения и мат. операции
  99.     { ["pattern"] = "%.%.", ["color"] = Scheme.compares },
  100.    
  101.     { ["pattern"] = "[%<%>%=%~]=?",   ["color"] = Scheme.compares },
  102.     { ["pattern"] = "[%+%-%*%/%#]",   ["color"] = Scheme.compares },
  103.    
  104.     --Состояния переменной
  105.     { ["pattern"] = "%Wtrue%W",  ["color"] = Scheme.boolean, ["func"] = TrimR },
  106.     { ["pattern"] = "%Wfalse%W", ["color"] = Scheme.boolean, ["func"] = TrimR },
  107.     { ["pattern"] = "%Wnil%W",   ["color"] = Scheme.boolean, ["func"] = TrimR },
  108.    
  109.     --And, or, not
  110.     { ["pattern"] = "%Wand%W",   ["color"] = Scheme.logic, ["func"] = TrimR },
  111.     { ["pattern"] = "%Wor%W",    ["color"] = Scheme.logic, ["func"] = TrimR },
  112.     { ["pattern"] = "%Wnot%W",   ["color"] = Scheme.logic, ["func"] = TrimR },
  113.  
  114.     --Циклы, условия, объявления
  115.     { ["pattern"] = "%Wwhile%W",    ["color"] = Scheme.loops, ["func"] = TrimR },
  116.     { ["pattern"] = "%Wdo%W",       ["color"] = Scheme.loops, ["func"] = TrimR },
  117.     { ["pattern"] = "%Wend%W",      ["color"] = Scheme.loops, ["func"] = TrimR },
  118.     { ["pattern"] = "%Wfor%W",      ["color"] = Scheme.loops, ["func"] = TrimR },
  119.     { ["pattern"] = "%Win%W",       ["color"] = Scheme.loops, ["func"] = TrimR },
  120.     { ["pattern"] = "%Wrepeat%W",   ["color"] = Scheme.loops, ["func"] = TrimR },
  121.     { ["pattern"] = "%Wif%W",       ["color"] = Scheme.loops, ["func"] = TrimR },
  122.     { ["pattern"] = "%Wthen%W",     ["color"] = Scheme.loops, ["func"] = TrimR },
  123.     { ["pattern"] = "%Wuntil%W",    ["color"] = Scheme.loops, ["func"] = TrimR },
  124.     { ["pattern"] = "%Wreturn%W",   ["color"] = Scheme.loops, ["func"] = TrimR },
  125.     { ["pattern"] = "%Wlocal%W",    ["color"] = Scheme.loops, ["func"] = TrimR },
  126.     { ["pattern"] = "%Wfunction%W", ["color"] = Scheme.loops, ["func"] = TrimR },
  127.     { ["pattern"] = "%Welse%W",     ["color"] = Scheme.loops, ["func"] = TrimR },
  128.     { ["pattern"] = "%Welseif%W",   ["color"] = Scheme.loops, ["func"] = TrimR },
  129.     { ["pattern"] = "%Wbreak%W",    ["color"] = Scheme.loops, ["func"] = TrimR },
  130.     { ["pattern"] = "%Wrequire%W",  ["color"] = Scheme.loops, ["func"] = TrimR },
  131.     { ["pattern"] = "%Wi?pairs%W",  ["color"] = Scheme.loops, ["func"] = TrimR },
  132.    
  133.     --Функции
  134.     { ["pattern"] = "[%s%.%:]?([%a%d%_]+)%(", ["color"] = Scheme.functions, ["func"] = Trim2 },
  135.    
  136.     --Библиотеки
  137.     { ["pattern"] = "table%.",      ["color"] = Scheme.functions, ["func"] = TrimOffset },
  138.     { ["pattern"] = "string%.",     ["color"] = Scheme.functions, ["func"] = TrimOffset },
  139.     { ["pattern"] = "coroutine%.",  ["color"] = Scheme.functions, ["func"] = TrimOffset },
  140.     { ["pattern"] = "package%.",    ["color"] = Scheme.functions, ["func"] = TrimOffset },
  141.     { ["pattern"] = "term%.",       ["color"] = Scheme.functions, ["func"] = TrimOffset },
  142.     { ["pattern"] = "math%.",       ["color"] = Scheme.functions, ["func"] = TrimOffset },
  143.     { ["pattern"] = "bit32%.",      ["color"] = Scheme.functions, ["func"] = TrimOffset },
  144.     { ["pattern"] = "io%.",         ["color"] = Scheme.functions, ["func"] = TrimOffset },
  145.     { ["pattern"] = "filesystem%.", ["color"] = Scheme.functions, ["func"] = TrimOffset },
  146.     { ["pattern"] = "os%.",         ["color"] = Scheme.functions, ["func"] = TrimOffset },
  147.     { ["pattern"] = "debug%.",      ["color"] = Scheme.functions, ["func"] = TrimOffset },
  148.     { ["pattern"] = "unicode%.",    ["color"] = Scheme.functions, ["func"] = TrimOffset },
  149.     { ["pattern"] = "component%.",  ["color"] = Scheme.functions, ["func"] = TrimOffset },
  150.     { ["pattern"] = "computer%.",   ["color"] = Scheme.functions, ["func"] = TrimOffset },
  151.     { ["pattern"] = "event%.",      ["color"] = Scheme.functions, ["func"] = TrimOffset },
  152.     { ["pattern"] = "internet%.",   ["color"] = Scheme.functions, ["func"] = TrimOffset },
  153.     { ["pattern"] = "keybord%.",    ["color"] = Scheme.functions, ["func"] = TrimOffset },
  154.     { ["pattern"] = "thread%.",     ["color"] = Scheme.functions, ["func"] = TrimOffset },
  155.     { ["pattern"] = "shell%.",      ["color"] = Scheme.functions, ["func"] = TrimOffset },
  156.     { ["pattern"] = "utf8%.",       ["color"] = Scheme.functions, ["func"] = TrimOffset },
  157.     { ["pattern"] = "gpu%.",        ["color"] = Scheme.functions, ["func"] = TrimOffset },
  158.    
  159.     --Удаление задниго костыля
  160.     { ["pattern"] = " $", ["func"] = function(t, s, fs, fe, t2) return fe + 1 end },
  161.   }
  162.  
  163.   patternsCount = #patterns
  164. end
  165.  
  166. function syntax.highlight(str)
  167.   local Return = {}
  168.   local Length = string.len(str)
  169.   local Default = currentColorScheme.default
  170.   local Offset = 1
  171.  
  172.   str = " ".. str .." " -- +Костыль что бы искало везде
  173.  
  174.   while Offset < Length do
  175.     local collision = {}
  176.     local Found = false
  177.    
  178.     for i=1, patternsCount do
  179.       local tPattern = patterns[i]
  180.       local fs, fe = string.find(str, tPattern.pattern, Offset)
  181.      
  182.       if fs then
  183.         table.insert(collision, { fs, fe, i })
  184.        
  185.         -- Offset = fe + 1
  186.         Found = true
  187.       end
  188.     end
  189.    
  190.     local Min = math.huge
  191.     local Key = 0
  192.    
  193.     for k,v in ipairs(collision) do
  194.       if v[1] < Min then
  195.         Min = v[1]
  196.         Key = k
  197.       end
  198.     end
  199.    
  200.     local fs, fe, key = table.unpack(collision[Key] or {})
  201.    
  202.     if Found then
  203.       local tPattern = patterns[key]
  204.      
  205.       if fs ~= Offset then
  206.         table.insert(Return,{
  207.                   ["word"] = string.sub(str, Offset, fs - 1),
  208.                   ["color"] = Default
  209.                 })
  210.       end
  211.      
  212.       if tPattern.func then
  213.         Offset = tPattern.func(Return, str, fs, fe, tPattern)
  214.       else
  215.         table.insert(Return,{
  216.                   ["word"] = string.sub(str, fs, fe),
  217.                   ["color"] = tPattern.color
  218.                 })
  219.         Offset = fe + 1
  220.       end
  221.     end
  222.    
  223.     if not Found then
  224.       table.insert(Return,{
  225.             ["word"] = string.sub(str, Offset, Length),
  226.             ["color"] = Default
  227.           })
  228.       break
  229.     end
  230.   end
  231.  
  232.   --Удаление переднего костыля из результата
  233.  
  234.   if #Return then
  235.     local F = Return[1].word
  236.    
  237.     if string.len(F) > 1 then
  238.       Return[1].word = string.sub(F, 2, string.len(F))
  239.     else
  240.       Return[1] = nil
  241.     end
  242.   end
  243.  
  244.   return Return
  245. end
  246.  
  247. function syntax.setColorScheme(colorScheme)
  248.   currentColorScheme = colorScheme
  249.  
  250.   definePatterns()
  251. end
  252.  
  253. function syntax.highlightAndDraw(x, y, limit, str)
  254.   local HL = syntax.highlight(str)
  255.  
  256.   for _,v in pairs(HL) do
  257.     local Color = v.color
  258.     local Word = v.word
  259.    
  260.     gpu.setForeground(Color)
  261.     gpu.set(x, y, Word)
  262.    
  263.     x = x + unicode.len(Word)
  264.   end
  265.  
  266. end
  267.  
  268. syntax.setColorScheme(colorSchemes.custom)
  269.  
  270. return syntax
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement