@Ekopalypse said in RFC: Track previous position:
I just install it via pip install tree-sitter and pip install tree-sitter-languages and of course use PS3 with the preferred local installation to access it.
Much nicer. Modified script playground.py to work with that setup:
import os import re from tree_sitter_languages import get_parser from Npp import editor, editor1, editor2, notepad, MENUCOMMAND, SCINTILLANOTIFICATION class TreeSitterPlayground(): """ Follow a `tree-sitter` parse output (in `editor2`) and highlight syntax (in `editor1`). """ def __init__(self): super().__init__() self._edCallbacks = { self._on_updateui: [ SCINTILLANOTIFICATION.UPDATEUI ] } self._cst = [] def _on_updateui(self, args): if notepad.getCurrentView() != 1: return if self.DEBUG: print(args) if args['hwndFrom'] != editor2.hwnd: return line = editor2.getCurLine() match = re.search(r'Node\stype\=(.*?)\,\sstart_point\=\((\d+)\,\s(\d+)\)\,\send_point\=\((\d+)\,\s(\d+)\)', line) if (match is None) or (len(match.groups()) != 5): return # nm = match.group(1) sl = int(match.group(2)) sc = int(match.group(3)) el = int(match.group(4)) ec = int(match.group(5)) if self.DEBUG: print(f"[{sl}, {sc}] - [{el}, {ec}]") editor1.gotoLine(sl) spos = editor1.findColumn(sl, sc) editor1.gotoLine(el) epos = editor1.findColumn(el, ec) editor1.setSelectionStart(spos) editor1.setSelectionEnd(epos) def _dump_tree(self, node, indent=0): self._cst.append(f"{' '*indent}{node}") if node.child_count > 0: for c in node.children: self._dump_tree(c, indent+1) def parse(self): """Parse the current file.""" self._cst = [] # file name, path, extension parsing full = notepad.getCurrentFilename() path, file = os.path.split(full) name, ext = os.path.splitext(file) # get file language type and adjust for Tree-Sitter parser names filetype = notepad.getLanguageName(notepad.getLangType()).lower() if filetype == 'c++': filetype = 'cpp' elif filetype == 'shell': filetype = 'bash' # parse the file try: tree = get_parser(filetype).parse(editor.getText().encode()) except: print(f"tree_sitter_languages `{filetype}' not found") return # recurse the CST, create the output string and put it in N++ self._dump_tree(tree.root_node) cst = '\n'.join(self._cst) notepad.new() editor.setText(cst) notepad.saveAs(f"{os.environ['TEMP']}/{name}.trs") # Make sure the CST is in view 1 and the source file is in view 0 if notepad.getCurrentView() == 0: notepad.menuCommand(MENUCOMMAND.VIEW_GOTO_ANOTHER_VIEW) else: notepad.open(full) notepad.menuCommand(MENUCOMMAND.VIEW_GOTO_ANOTHER_VIEW) notepad.open(f"{os.environ['TEMP']}/{name}.trs") def start(self): """Start the service""" for cb in self._edCallbacks: editor.callback(cb, self._edCallbacks[cb]) self._ENABLED = True def stop(self): """Stop the service""" for cb in self._edCallbacks: editor.clearCallbacks(cb) self._ENABLED = False if __name__ == '__main__': try: isinstance(tsp, TreeSitterPlayground) print("Tree-Sitter Playground `tsp' already enabled") except NameError: tsp = TreeSitterPlayground() tsp.start() print("Tree-Sitter Playground instantiated as `tsp'") tsp.parse()Now, just open a file in Notepad++, run the “Plugins => Python Script => Scripts => playground” and it will try to parse the current file and setup the output CST (syntax tree) in view 1 and the source file in view 0 to allow scrolling through the CST and auto-highlighting the source in view 0 as per my screenshot in the previous post.
Cheers.