import sublime
import sublime_plugin
import re
from subprocess import Popen, PIPE
def get_luac(contents):
try:
process = Popen('luac -p -l -- -', stdin=PIPE, stderr=PIPE, stdout=PIPE, shell=True)
return process.communicate(input=contents.encode())[0].decode()
except BrokenPipeError as e:
return None
def get_regions(view):
regions = []
# get view as a region
viewContents = sublime.Region(0, view.size())
# get every line region from the region
lineRegions = view.lines(viewContents)
# get every line content from the regions
lineContents = view.substr(viewContents).split('\n')
# get globals from the current content
output = get_luac(view.substr(viewContents))
if not output:
return regions
# parse each line from luac
for line in output.split('\n'):
# clean up the line
line = ' '.join(line.split())
# match global references
match = re.match(r'\d+ \[(\d+)\] GETGLOBAL -?\d+ -?\d+ ; (.*)', line)
if match:
lineNumber, globalValue = match.groups()
lineNumber = int(lineNumber) - 1
# sadly, luac doesn't tell us the character
# positions, so we'll have to grab that ourselves
region = lineRegions[lineNumber]
contents = view.substr(region)
print(contents, '---', globalValue)
# grab the start character point
start = contents.find(globalValue)
if start != -1:
# grab the end character point
end = start + len(globalValue)
# create a new region for the value
valueRegion = sublime.Region(region.a + start, region.a + end)
# add the region to the output
regions.append(valueRegion)
# TODO: now we have to remove the value so we don't
# match it again (multiple of same globals on one line)
return regions
def highlight_globals(view):
if view.settings().get('syntax').encode() == 'Packages/Lua/Lua.sublime-syntax'.encode():
# only execute in Lua files
view.add_regions('HighlightLuaGlobals', get_regions(view),
'comment', '', sublime.DRAW_NO_FILL | sublime.DRAW_NO_OUTLINE | sublime.DRAW_SOLID_UNDERLINE | sublime.HIDE_ON_MINIMAP)
class HighlightLuaGlobals(sublime_plugin.EventListener):
def on_modified_async(self, view):
highlight_globals(view)
def on_activated_async(self, view):
highlight_globals(view)
def on_load_async(self, view):
highlight_globals(view)
def plugin_loaded():
for window in sublime.windows():
for view in window.views():
view.settings().add_on_change('HighlightLuaGlobals', lambda: highlight_globals(view))