1import os.path 2import logging 3import tkinter as tk 4 5from thonny import get_workbench, jedi_utils 6from thonny.ui_utils import control_is_pressed 7 8logger = logging.getLogger(__name__) 9 10 11def goto_definition(event): 12 if not control_is_pressed(event.state): 13 return 14 15 assert isinstance(event.widget, tk.Text) 16 text = event.widget 17 18 source = text.get("1.0", "end") 19 index = text.index("insert") 20 index_parts = index.split(".") 21 line, column = int(index_parts[0]), int(index_parts[1]) 22 try: 23 editor = text.master.home_widget 24 path = editor.get_filename() 25 except Exception as e: 26 logger.warning("Could not get path", exc_info=e) 27 path = None 28 29 defs = jedi_utils.get_definitions(source, line, column, path) 30 if len(defs) > 0: 31 # TODO: handle multiple results like PyCharm 32 module_path = str(defs[0].module_path) 33 if not os.path.isfile(module_path): 34 logger.warning("%s is not a file", module_path) 35 return 36 37 module_name = defs[0].module_name 38 line = defs[0].line 39 if module_path and line is not None: 40 get_workbench().get_editor_notebook().show_file(module_path, line) 41 elif module_name == "" and line is not None: # current editor 42 get_workbench().get_editor_notebook().get_current_editor().select_range(line) 43 44 45def load_plugin() -> None: 46 wb = get_workbench() 47 wb.bind_class("CodeViewText", "<1>", goto_definition, True) 48