From ce0aebc6048301ac68acc69bb09d4c929f4da29d Mon Sep 17 00:00:00 2001 From: DisposaBoy Date: Tue, 8 May 2018 17:42:21 +0100 Subject: [PATCH] * implement goto definition with a dedicated margo.sh command goto.definition * misc polish --- Default (Linux).sublime-keymap | 4 +- Default (OSX).sublime-keymap | 4 +- Default (Windows).sublime-keymap | 4 +- gosubl/margo.py | 31 ++++++++---- gosubl/margo_agent.py | 2 - gosubl/margo_render.py | 11 +++- gosubl/margo_state.py | 86 +++++++++++++++++++------------- gscommands.py | 4 +- gsev.py | 6 ++- 9 files changed, 96 insertions(+), 56 deletions(-) diff --git a/Default (Linux).sublime-keymap b/Default (Linux).sublime-keymap index 0f9d58dc..91faa07a 100644 --- a/Default (Linux).sublime-keymap +++ b/Default (Linux).sublime-keymap @@ -77,8 +77,8 @@ }, { "keys": ["ctrl+.", "ctrl+g"], - "command": "gs_doc", - "args": {"mode": "goto"}, + "command": "gs9o_open", + "args": {"run": ["goto.definition"], "focus_view": false, "show_view": false}, "context": [{ "key": "selector", "operator": "equal", "operand": "source.go" }] }, { diff --git a/Default (OSX).sublime-keymap b/Default (OSX).sublime-keymap index 3052c065..2d79fdd0 100644 --- a/Default (OSX).sublime-keymap +++ b/Default (OSX).sublime-keymap @@ -71,8 +71,8 @@ }, { "keys": ["super+.", "super+g"], - "command": "gs_doc", - "args": {"mode": "goto"}, + "command": "gs9o_open", + "args": {"run": ["goto.definition"], "focus_view": false, "show_view": false}, "context": [{ "key": "selector", "operator": "equal", "operand": "source.go" }] }, { diff --git a/Default (Windows).sublime-keymap b/Default (Windows).sublime-keymap index 5471287e..6e5450dc 100644 --- a/Default (Windows).sublime-keymap +++ b/Default (Windows).sublime-keymap @@ -77,8 +77,8 @@ }, { "keys": ["ctrl+.", "ctrl+g"], - "command": "gs_doc", - "args": {"mode": "goto"}, + "command": "gs9o_open", + "args": {"run": ["goto.definition"], "focus_view": false, "show_view": false}, "context": [{ "key": "selector", "operator": "equal", "operand": "source.go" }] }, { diff --git a/gosubl/margo.py b/gosubl/margo.py index 5a882857..13476aa1 100644 --- a/gosubl/margo.py +++ b/gosubl/margo.py @@ -3,7 +3,7 @@ from .margo_agent import MargoAgent from .margo_common import OutputLogger, TokenCounter from .margo_render import render, render_src -from .margo_state import State, actions, Config, _view_scope_lang +from .margo_state import State, actions, client_actions, Config, _view_scope_lang, view_is_9o from collections import namedtuple import glob import os @@ -12,6 +12,7 @@ class MargoSingleton(object): def __init__(self): + self._ready = False self.package_dir = os.path.dirname(os.path.abspath(__file__)) self.out = OutputLogger('margo') self.agent_tokens = TokenCounter('agent', format='{}#{:03d}', start=6) @@ -21,6 +22,12 @@ def __init__(self): self.state = State() self.status = [] self.output_handler = None + self._client_actions_handlers = { + client_actions.Activate: self._handle_act_activate, + client_actions.Restart: self._handle_act_restart, + client_actions.Shutdown: self._handle_act_shutdown, + client_actions.CmdOutput: self._handle_act_output, + } def render(self, rs=None): # ST has some locking issues due to its "thread-safe" API @@ -47,6 +54,9 @@ def _render(): sublime.set_timeout(_render) + def _handle_act_activate(self, rs, act): + gs.focus(act.name or act.path, row=act.row, col=act.col, focus_pat='') + def _handle_act_restart(self, rs, act): self.restart() @@ -59,12 +69,12 @@ def _handle_act_output(self, rs, act): h(rs, act) def _handle_client_actions(self, rs): - for a in rs.state.client_actions: - try: - f = getattr(self, '_handle_act_' + a.name) - f(rs, a) - except AttributeError: - self.out.println('Unknown client-action: %s: %s' % (a.name, a)) + for act in rs.state.client_actions: + f = self._client_actions_handlers.get(act.action_name) + if f: + f(rs, act) + else: + self.out.println('Unknown client-action: %s: %s' % (act.action_name, act)) def render_status(self, *a): self.status = list(a) @@ -90,6 +100,9 @@ def stop(self): a.stop() def enabled(self, view): + if not self._ready: + return False + if '*' in self.enabled_for_langs: return True @@ -107,7 +120,7 @@ def can_trigger_event(self, view, allow_9o=False): return False vs = view.settings() - if allow_9o and vs.get('9o'): + if allow_9o and view_is_9o(view): return True if vs.get('is_widget'): @@ -117,7 +130,6 @@ def can_trigger_event(self, view, allow_9o=False): def event(self, name, view, handler, args): allow_9o = name in ( - 'query_completions', ) if not self.can_trigger_event(view, allow_9o=allow_9o): return None @@ -256,6 +268,7 @@ def ext_fn(): mg = MargoSingleton() def gs_init(_): + mg._ready = True mg.start() def gs_fini(_): diff --git a/gosubl/margo_agent.py b/gosubl/margo_agent.py index 76d8c37d..3afd6d08 100644 --- a/gosubl/margo_agent.py +++ b/gosubl/margo_agent.py @@ -163,8 +163,6 @@ def _handle_send_ipc(self, rq): try: ipc_enc(rq.data(), self.proc.stdin) exc = None - except ipc_silent_exceptions as e: - exc = e except Exception as e: exc = e if not self.stopped.is_set(): diff --git a/gosubl/margo_render.py b/gosubl/margo_render.py index 3363c87d..732a7628 100644 --- a/gosubl/margo_render.py +++ b/gosubl/margo_render.py @@ -43,13 +43,19 @@ def __init__(self, *, key, scope, icon, flags): issue_key_pfx = '#mg.Issue.' issue_cfg_error = IssueCfg( key = issue_key_pfx + 'error', - scope = 'keyword sublimelinter.mark.error region.redish', + scope = 'region.redish', icon = 'Packages/GoSublime/images/issue.png', flags = sublime.DRAW_SQUIGGLY_UNDERLINE | sublime.DRAW_NO_OUTLINE | sublime.DRAW_NO_FILL, ) issue_cfg_warning = IssueCfg( key = issue_key_pfx + 'warning', - scope = 'entity sublimelinter.mark.warning region.orangish', + scope = 'region.orangish', + icon = issue_cfg_error.icon, + flags = issue_cfg_error.flags, +) +issue_cfg_notice = IssueCfg( + key = issue_key_pfx + 'notice', + scope = 'region.greenish', icon = issue_cfg_error.icon, flags = issue_cfg_error.flags, ) @@ -57,6 +63,7 @@ def __init__(self, *, key, scope, icon, flags): issue_cfgs = { 'error': issue_cfg_error, 'warning': issue_cfg_warning, + 'notice': issue_cfg_notice, } def _render_issues(view, issues): diff --git a/gosubl/margo_state.py b/gosubl/margo_state.py index 7bc75fe2..14719174 100644 --- a/gosubl/margo_state.py +++ b/gosubl/margo_state.py @@ -21,6 +21,13 @@ 'RunCmd', )}) +client_actions = NS(**{k: k for k in ( + 'Activate', + 'Restart', + 'Shutdown', + 'CmdOutput', +)}) + class Config(object): def __init__(self, m): self.override_settings = m.get('OverrideSettings') or {} @@ -48,33 +55,51 @@ def __init__(self, v={}): self.client_actions = [] for ca in (v.get('ClientActions') or []): - if ca.get('Name') == 'output': - self.client_actions.append(CmdOutput(v=ca)) - else: - self.client_actions.append(ClientAction(v=ca)) + CA = client_action_creators.get(ca.get('Name') or '') or ClientAction + self.client_actions.append(CA(v=ca)) def __repr__(self): return repr(self.__dict__) class ClientAction(object): def __init__(self, v={}): - self.name = v.get('Name') or '' - self.data = v.get('Data') or {} + self.action_name = v.get('Name') or '' + self.action_data = v.get('Data') or {} def __repr__(self): return repr(vars(self)) -class CmdOutput(ClientAction): - def __init__(self, v={}): +class ClientAction_Output(ClientAction): + def __init__(self, v): super().__init__(v=v) - self.fd = self.data.get('Fd') or '' - self.output = self.data.get('Output') or '' - self.close = self.data.get('Close') or False - self.fd = self.data.get('Fd') or '' + ad = self.action_data + + self.fd = ad.get('Fd') or '' + self.output = ad.get('Output') or '' + self.close = ad.get('Close') or False + self.fd = ad.get('Fd') or '' def __repr__(self): return repr(vars(self)) +class ClientAction_Activate(ClientAction): + def __init__(self, v): + super().__init__(v=v) + ad = self.action_data + + self.path = ad.get('Path') or '' + self.name = ad.get('Name') or '' + self.row = ad.get('Row') or 0 + self.col = ad.get('Col') or 0 + + def __repr__(self): + return repr(vars(self)) + +client_action_creators = { + client_actions.CmdOutput: ClientAction_Output, + client_actions.Activate: ClientAction_Activate, +} + class Completion(object): def __init__(self, v): self.query = v.get('Query') or '' @@ -198,38 +223,27 @@ def _editor_props(view): 'Settings': sett, } +def view_is_9o(view): + return view is not None and view.settings().get('9o') + def _view_props(view): - view = gs.active_view(view=view) + was_9o = view_is_9o(view) + if was_9o: + view = gs.active_view() + else: + view = gs.active_view(view=view) + if view is None: return {} pos = gs.sel(view).begin() - row, col = view.rowcol(pos) scope, lang, fn, props = _view_header(view, pos) - wd = gs.basedir_or_cwd(fn) - - if lang == '9o': - if 'prompt.9o' in scope: - r = view.extract_scope(pos) - pos -= r.begin() - s = view.substr(r) - src = s.lstrip().lstrip('#').lstrip() - pos -= len(s) - len(src) - src = src.rstrip() - else: - pos = 0 - src = '' - - wd = view.settings().get('9o.wd') or wd - props['Path'] = '_.9o' - else: - src = _view_src(view, lang) + wd = gs.getwd() or gs.basedir_or_cwd(fn) + src = _view_src(view, lang) props.update({ 'Wd': wd, 'Pos': pos, - 'Row': row, - 'Col': col, 'Dirty': view.is_dirty(), 'Src': src, }) @@ -272,7 +286,6 @@ def _view_header(view, pos): return scope, lang, path, { 'Path': path, 'Name': view_name(view, ext=ext, lang=lang), - 'Ext': ext, 'Hash': _view_hash(view), 'Lang': lang, 'Scope': scope, @@ -296,6 +309,9 @@ def _view_scope_lang(view, pos): return ('', '') scope = view.scope_name(pos).strip().lower() + if view_is_9o(view): + return (scope, 'cmd-promp') + l = _scope_lang_pat.findall(scope) lang = l[-1] if l else '' return (scope, lang) diff --git a/gscommands.py b/gscommands.py index 2c0108ca..82df256b 100644 --- a/gscommands.py +++ b/gscommands.py @@ -82,7 +82,9 @@ def run(self, edit, row, col=0): r = sublime.Region(pt, pt) self.view.sel().clear() self.view.sel().add(r) - self.view.show(pt) + self.view.show(pt, True) + xpos, ypos = self.view.viewport_position() + self.view.set_viewport_position((0, ypos), False) dmn = 'gs.focus.%s:%s:%s' % (gs.view_fn(self.view), row, col) flags = sublime.DRAW_EMPTY_AS_OVERWRITE show = lambda: self.view.add_regions(dmn, [r], 'comment', 'bookmark', flags) diff --git a/gsev.py b/gsev.py index c84a5457..9ae5d8f2 100644 --- a/gsev.py +++ b/gsev.py @@ -30,7 +30,11 @@ def run(self, edit): view = self.view if gs.is_go_source_view(view): if not gstest.handle_action(view, 'left-click'): - view.run_command('gs_doc', {"mode": "goto"}) + view.run_command('gs9o_open', { + "run": ["goto.definition"], + "focus_view": False, + "show_view": False, + }) elif view.score_selector(gs.sel(view).begin(), "text.9o") > 0: view.window().run_command("gs9o_open_selection")