slipers

Minecraft. OpenComputers. Cedit (/lib/highlighter.lua).

May 22nd, 2023
180
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. local component = require("component")
  2. local fs = require("filesystem")
  3. local shell = require("shell")
  4. local term = require("term")
  5. local unicode = require("unicode")
  6. local colors = require("colors")
  7.  
  8. local config = {}
  9. local hl = {}
  10.  
  11. local function loadConfig()
  12.   -- Try to load user settings.
  13.   local env = {}
  14.   local config = loadfile("/etc/hl.cfg", nil, env)
  15.   if config then
  16.     pcall(config)
  17.   end
  18.   -- Fill in defaults.
  19.   if env.colors then
  20.     -- convert color names to palette indices
  21.     for k, v in pairs(env.colors) do
  22.       local fg = env.colors[k].pal.fg
  23.       local bg = env.colors[k].pal.bg
  24.       if type(fg) == "string" then
  25.         env.colors[k].pal.fg = colors[fg]
  26.       else
  27.         env.colors[k].pal.fg = fg
  28.       end
  29.       if type(bg) == "string" then
  30.         env.colors[k].pal.bg = colors[bg]
  31.       else
  32.         env.colors[k].pal.bg = bg
  33.       end
  34.     end
  35.   else
  36.     env.colors = {
  37.       number     = { rgb = { fg = 0x9933CC, bg = 0x000000 }, pal = { fg = colors.purple,    bg = colors.black } },
  38.       keyword    = { rgb = { fg = 0x6899FF, bg = 0x000000 }, pal = { fg = colors.lightblue, bg = colors.black } },
  39.       ident      = { rgb = { fg = 0xFFFFFF, bg = 0x000000 }, pal = { fg = colors.white,     bg = colors.black } },
  40.       punct      = { rgb = { fg = 0xCCCCCC, bg = 0x000000 }, pal = { fg = colors.silver,    bg = colors.black } },
  41.       comment    = { rgb = { fg = 0x336600, bg = 0x000000 }, pal = { fg = colors.green,     bg = colors.black } },
  42.       string     = { rgb = { fg = 0x33CC33, bg = 0x000000 }, pal = { fg = colors.lime,      bg = colors.black } },
  43.       vstring    = { rgb = { fg = 0x33CC33, bg = 0x7F7F7F }, pal = { fg = colors.lime,      bg = colors.gray } },
  44.       invalid    = { rgb = { fg = 0xFFFFFF, bg = 0xFF0000 }, pal = { fg = colors.white,     bg = colors.red } },
  45.     }
  46.   end
  47.   env.keywords = env.keywords or {
  48.     ["and"]=true, ["break"]=true, ["do"]=true, ["else"]=true,
  49.     ["elseif"]=true, ["end"]=true, ["false"]=true, ["for"]=true,
  50.     ["function"]=true, ["goto"]=true, ["if"]=true, ["in"]=true,
  51.     ["local"]=true, ["nil"]=true, ["not"]=true, ["or"]=true,
  52.     ["repeat"]=true, ["return"]=true, ["then"]=true, ["true"]=true,
  53.     ["until"]=true, ["while"]=true
  54.   }
  55.   -- Generate config file if it didn't exist.
  56.   if not config then
  57.     local root = fs.get("/")
  58.     if root and not root.isReadOnly() and not fs.exists("/etc/hl.cfg") then
  59.       fs.makeDirectory("/etc")
  60.       local f = io.open("/etc/hl.cfg", "w")
  61.       if f then
  62.         local serialization = require("serialization")
  63.         for k, v in pairs(env) do
  64.           f:write(k.."="..tostring(serialization.serialize(v, math.huge)).."\n")
  65.         end
  66.         f:close()
  67.       end
  68.     end
  69.   end
  70.   return env
  71. end
  72.  
  73. function hl.reload()
  74.   config = {}
  75.   config = loadConfig()
  76. end
  77.  
  78. function hl.set_color(tag)
  79.   local d = component.gpu.getDepth()
  80.   if d == 1 then
  81.     component.gpu.setForeground(1)
  82.     component.gpu.setBackground(0)
  83.   elseif d == 4 then
  84.     component.gpu.setForeground( config.colors[tag].pal.fg, true)
  85.     component.gpu.setBackground( config.colors[tag].pal.bg, true)
  86.   elseif d == 8 then
  87.     component.gpu.setForeground( config.colors[tag].rgb.fg)
  88.     component.gpu.setBackground( config.colors[tag].rgb.bg)
  89.   end
  90. end
  91.  
  92. function hl.put( x, y, str)
  93.   local gpu = component.gpu
  94.   local d = gpu.getDepth()
  95.   if d == 1 then
  96.     hl.set_color("ident")
  97.     gpu.set( x, y, str)
  98.     return
  99.   end
  100.   local fg, fgp = gpu.getForeground()
  101.   local bg, bgp = gpu.getBackground()
  102.   local i, len = 1, string.len(str)
  103.   while i <= len do
  104.     if string.find( str, "^%-%-", i) then
  105. -- comments
  106.       hl.set_color("comment")
  107.       gpu.set( x + i - 1, y,  string.sub( str, i))
  108.       break
  109.     end
  110.     if string.find( str, "^[%u%l_]", i) then
  111. -- keywords and identifiers
  112.       local start = i
  113.       i = i + 1
  114.       local b, e = string.find( str, "^[%u%l%d_]+", i)
  115.       if b then
  116.         i = e + 1
  117.       end
  118.       local k = string.sub( str, start, i - 1)
  119.       if config.keywords[k] then
  120.         hl.set_color("keyword")
  121.       else
  122.         hl.set_color("ident")
  123.       end
  124.       gpu.set( x + start - 1, y, k)
  125.     elseif string.find( str, "^%d", i) then
  126. -- numbers
  127.       local start = i
  128.       i = i + 1
  129.       local b, e = string.find( str, "^x%x+", i)
  130.       if not b then
  131.         b, e = string.find( str, "^%d*%.?%d*", i)
  132.       end
  133.       if b then
  134.         i = e + 1
  135.       end
  136.       local k = string.sub( str, start, i - 1)
  137.       hl.set_color("number")
  138.       gpu.set( x + start - 1, y, k)
  139.     elseif string.find( str, "^[\"']", i) then
  140. -- strings
  141.       local q = "^" .. string.sub( str, i, i)
  142.       local start = i
  143.       i = i + 1
  144.       while i <= str:len() do
  145.         if string.find( str, q, i) then
  146.           break
  147.         elseif string.find( str, "^\\", i) then
  148.           i = i + 1
  149.         end
  150.         i = i + 1
  151.       end
  152.       i = i + 1
  153.       local k = string.sub( str, start, i - 1)
  154.       hl.set_color("string")
  155.       gpu.set( x + start - 1, y, k)
  156.     elseif string.find( str, "^%[%[", i) then
  157. -- verbatim strings
  158.       local start = i
  159.       i = i + 2
  160.       local b, e = string.find( str, "%]%]", i)
  161.       if e then
  162.         i = e + 1
  163.       end
  164.       local k = string.sub( str, start, i)
  165.       hl.set_color("vstring")
  166.       gpu.set( x + start - 1, y, k)
  167.     elseif string.find( str, "^[%p%s]", i) then
  168. -- whitespace & punctuation
  169.       local b, e = string.find( str, "^[%p%s]+", i)
  170.       i = e + 1
  171.       -- dont allow string and comment starters at end
  172.       for ii = b, e do
  173.         if string.find( str, "^['\"]", ii) or string.find( str, "^%[%[", ii) or string.find( str, "^%-%-", ii) then
  174.           i = ii
  175.           e = ii - 1
  176.           break
  177.         end
  178.       end
  179.       hl.set_color("punct")
  180.       gpu.set( x + b - 1, y, string.sub( str, b, e))
  181.     else
  182. -- invalid characters
  183.       hl.set_color("invalid")
  184.       gpu.set( x + i - 1, y, string.sub( str, i, i))
  185.       i = i + 1
  186.     end    
  187.   end
  188.   gpu.setForeground(fg, fgp)
  189.   gpu.setBackground(bg, bgp)
  190. end
  191.  
  192. -- returns number of lines outputted
  193. function hl.line( str, wrap)
  194.   local w, h = component.gpu.getResolution()
  195.   local cx, cy = term.getCursor()
  196.   local dx = w - unicode.len(str)
  197.   if dx >= 0 and dx <= w then
  198.     hl.put( cx, cy, str)
  199.     term.setCursor( cx + unicode.len(str), cy)
  200.     term.write("\n")
  201.     return 1
  202.   elseif wrap and wrap == true then
  203.     local count = 0
  204.     while unicode.len(str) > 0 do
  205.       -- +-8=length of largest keyword, for highlighting tokens split on screen border
  206.       local ww = math.min( w + 8, unicode.len(str))
  207.       local s1 = unicode.sub( str, 1, ww)
  208.       if unicode.len(str) > w - 8 then
  209.         str = unicode.sub( str, w - 8)
  210.       else
  211.         str = ""
  212.       end
  213.       hl.put( cx, cy, s1)
  214.       if cx < 1 then
  215.         term.setCursor( 1 + unicode.len(s1), cy)
  216.       else
  217.         term.setCursor( cx + unicode.len(s1), cy)
  218.       end
  219.       term.write("\n")
  220.       cx, cy = term.getCursor()
  221.       cx = -8
  222.       count = count + 1
  223.     end
  224.     return count
  225.   else
  226.     local ww = math.min( w + 8, unicode.len(str))
  227.     hl.put( cx, cy, unicode.sub( str, 1, ww))
  228.     term.setCursor( cx + ww, cy)
  229.     term.write("\n")
  230.     return 1
  231.   end
  232. end
  233.  
  234. config = loadConfig()
  235. return hl
Add Comment
Please, Sign In to add comment