diff --git a/tern.py b/tern.py
index c5c9d53..2c5b058 100644
--- a/tern.py
+++ b/tern.py
@@ -2,6 +2,11 @@
import sublime, sublime_plugin
import os, sys, platform, subprocess, webbrowser, json, re, time, atexit
+try:
+ # python 2
+ from utils.renderer import create_arghints_renderer
+except:
+ from .utils.renderer import create_arghints_renderer
windows = platform.system() == "Windows"
python3 = sys.version_info[0] > 2
@@ -12,11 +17,10 @@ def is_js_file(view):
files = {}
arghints_enabled = False
-arghints_type = "status"
+arghints_renderer = None
arg_completion_enabled = False
tern_command = None
tern_arguments = []
-tern_arghint = ""
def on_deactivated(view):
pfile = files.get(view.file_name(), None)
@@ -460,65 +464,10 @@ def show_argument_hints(pfile, view):
render_argument_hints(pfile, view, parsed, argpos)
def render_argument_hints(pfile, view, ftype, argpos):
- global tern_arghint
if ftype is None:
- if pfile.showing_arguments:
- if arghints_type == "panel":
- panel = view.window().get_output_panel("tern_arghint")
- tern_arghint = ""
- panel.run_command("tern_arghint")
- elif arghints_type == "status":
- sublime.status_message("")
- pfile.showing_arguments = False
- return
-
- msg = ftype["name"] + "("
- i = 0
- for name, type in ftype["args"]:
- if i > 0: msg += ", "
- if i == argpos: msg += "*"
- msg += name + ("" if type == "?" else ": " + type)
- i += 1
- msg += ")"
- if ftype["retval"] is not None:
- msg += " -> " + ftype["retval"]
-
- if arghints_type == "panel":
- panel = view.window().get_output_panel("tern_arghint")
- tern_arghint = msg
- panel.run_command("tern_arghint")
- view.window().run_command("show_panel", {"panel": "output.tern_arghint"})
- elif arghints_type == "status":
- sublime.status_message(msg)
- elif arghints_type == "tooltip":
- view.show_popup(render_tooltip(ftype, msg), sublime.COOPERATE_WITH_AUTO_COMPLETE, max_width=600, on_navigate=go_to_url)
- pfile.showing_arguments = True
-
-def go_to_url(url=None):
- if url:
- import webbrowser
- webbrowser.open(url)
-
-def render_tooltip(ftype, msg):
- output = '''
-
- '''
- output = output + '
{}
'.format(msg)
- url = ''
- doc = '{doc}
'
-
- if ftype['url']:
- output += url.format(url=ftype['url'])
- if ftype['doc']:
- output += doc.format(doc=ftype['doc'])
- return output
+ arghints_renderer.clean(pfile, view)
+ else:
+ arghints_renderer.render(pfile, view, ftype, argpos)
def parse_function_type(data):
type = data["type"]
@@ -555,8 +504,8 @@ def parse_function_type(data):
jump_stack = []
class TernArghintCommand(sublime_plugin.TextCommand):
- def run(self, edit):
- self.view.insert(edit, 0, tern_arghint)
+ def run(self, edit, **args):
+ self.view.insert(edit, 0, args.get('msg', ''))
class TernJumpToDef(sublime_plugin.TextCommand):
def run(self, edit, **args):
@@ -604,15 +553,18 @@ def run(self, edit, **args):
plugin_dir = os.path.abspath(os.path.dirname(__file__))
def plugin_loaded():
- global arghints_enabled, arghints_type, tern_command, tern_arguments
+ global arghints_enabled, arghints_renderer, tern_command, tern_arguments
global arg_completion_enabled
settings = sublime.load_settings("Preferences.sublime-settings")
arghints_enabled = settings.get("tern_argument_hints", False)
arg_completion_enabled = settings.get("tern_argument_completion", False)
if arghints_enabled:
if "show_popup" in dir(sublime.View):
- arghints_type = "tooltip"
- arghints_type = settings.get("tern_argument_hints_type", arghints_type)
+ default_arghints_type = "tooltip"
+ else:
+ default_arghints_type = "status"
+ arghints_type = settings.get("tern_argument_hints_type", default_arghints_type)
+ arghints_renderer = create_arghints_renderer(arghints_type)
tern_arguments = settings.get("tern_arguments", [])
if not isinstance(tern_arguments, list):
tern_arguments = [tern_arguments]
diff --git a/utils/__init__.py b/utils/__init__.py
new file mode 100644
index 0000000..8d1c8b6
--- /dev/null
+++ b/utils/__init__.py
@@ -0,0 +1 @@
+
diff --git a/utils/renderer.py b/utils/renderer.py
new file mode 100644
index 0000000..3dd6a87
--- /dev/null
+++ b/utils/renderer.py
@@ -0,0 +1,138 @@
+import sublime
+
+def get_message_from_ftype(ftype, argpos):
+ msg = ftype["name"] + "("
+ i = 0
+ for name, type in ftype["args"]:
+ if i > 0: msg += ", "
+ if i == argpos: msg += "*"
+ msg += name + ("" if type == "?" else ": " + type)
+ i += 1
+ msg += ")"
+ if ftype["retval"] is not None:
+ msg += " -> " + ftype["retval"]
+ return msg
+
+def get_html_message_from_ftype(ftype, argpos):
+ style = '''
+
+ '''
+
+ func_signature = '{func_name}('.format(func_name=ftype["name"])
+ i = 0
+ for name, type in ftype["args"]:
+ if i > 0: func_signature += ", "
+ if i == argpos:
+ func_signature += '{name}'.format(name=name)
+ else:
+ func_signature += '{name}'.format(name=name)
+ if type != "?":
+ func_signature += ': {type}'.format(type=type)
+ i += 1
+ func_signature += ")"
+ if ftype["retval"] is not None:
+ func_signature += ' ➜ {type}'.format(type=ftype["retval"])
+
+ template = '''
+ {style}
+
+ '''
+
+ template_data = {
+ 'style': style,
+ 'func_signature': hint_line(func_signature),
+ 'doc_link': hint_line(link(ftype['url'])),
+ 'doc': hint_line(ftype['doc'])
+ }
+
+ return template.format(**template_data)
+
+def maybe(fn):
+ def maybe_fn(arg):
+ return fn(arg) if arg else ''
+ return maybe_fn
+
+@maybe
+def link(url):
+ return '{url}'.format(url=url)
+
+@maybe
+def hint_line(txt):
+ return '{txt}
'.format(txt=txt)
+
+def go_to_url(url=None):
+ if url:
+ import webbrowser
+ webbrowser.open(url)
+
+class TooltipArghintsRenderer(object):
+ def render(self, pfile, view, ftype, argpos):
+ view.show_popup(get_html_message_from_ftype(ftype, argpos), sublime.COOPERATE_WITH_AUTO_COMPLETE, max_width=600, on_navigate=go_to_url)
+ pfile.showing_arguments = True
+
+ def clean(self, pfile, view):
+ pfile.showing_arguments = False
+
+
+class StatusArghintsRenderer(object):
+ def render(self, pfile, view, ftype, argpos):
+ msg = get_message_from_ftype(ftype, argpos)
+ sublime.status_message(msg)
+ pfile.showing_arguments = True
+
+ def clean(self, pfile, view):
+ if pfile.showing_arguments:
+ sublime.status_message("")
+ pfile.showing_arguments = False
+
+
+class PanelArghintsRenderer(object):
+ def render(self, pfile, view, ftype, argpos):
+ msg = get_message_from_ftype(ftype, argpos)
+ panel = view.window().get_output_panel("tern_arghint")
+ panel.run_command("tern_arghint", {"msg": msg})
+ view.window().run_command("show_panel", {"panel": "output.tern_arghint"})
+ pfile.showing_arguments = True
+
+ def clean(self, pfile, view):
+ if pfile.showing_arguments:
+ panel = view.window().get_output_panel("tern_arghint")
+ panel.run_command("tern_arghint", {"msg": ""})
+ pfile.showing_arguments = False
+
+
+def create_arghints_renderer(arghints_type):
+ if arghints_type == "tooltip":
+ return TooltipArghintsRenderer()
+ elif arghints_type == "status":
+ return StatusArghintsRenderer()
+ elif arghints_type == "panel":
+ return PanelArghintsRenderer()
\ No newline at end of file