diff --git a/anaconda_lib/linting/sublime.py b/anaconda_lib/linting/sublime.py
index 23999a78..02a3224b 100644
--- a/anaconda_lib/linting/sublime.py
+++ b/anaconda_lib/linting/sublime.py
@@ -330,6 +330,35 @@ def get_lineno_msgs(view, lineno):
return errors_msg
+def get_specific_lineno_msgs(view, lineno):
+ """Get lineno error messages and return them by message type
+ """
+
+ ERRORS = ANACONDA.get('ERRORS')
+ WARNINGS = ANACONDA.get('WARNINGS')
+ VIOLATIONS = ANACONDA.get('VIOLATIONS')
+
+ specific_errors_msg = {}
+
+ if lineno is not None:
+ def check_and_delete_if_empty(dct: dict, key: str):
+ if not dct.get(key):
+ del dct[key]
+
+ vid = view.id()
+ if vid in ERRORS:
+ specific_errors_msg['ERRORS'] = ERRORS[vid].get(lineno, [])
+ check_and_delete_if_empty(specific_errors_msg, 'ERRORS')
+ if vid in WARNINGS:
+ specific_errors_msg['WARNINGS'] = WARNINGS[vid].get(lineno, [])
+ check_and_delete_if_empty(specific_errors_msg, 'WARNINGS')
+ if vid in VIOLATIONS:
+ specific_errors_msg['VIOLATIONS'] = VIOLATIONS[vid].get(lineno, [])
+ check_and_delete_if_empty(specific_errors_msg, 'VIOLATIONS')
+
+ return specific_errors_msg
+
+
def run_linter(view=None, hook=None):
"""Run the linter for the given view
"""
diff --git a/anaconda_lib/tooltips.py b/anaconda_lib/tooltips.py
index 18370c0b..c48e5a8c 100644
--- a/anaconda_lib/tooltips.py
+++ b/anaconda_lib/tooltips.py
@@ -33,7 +33,7 @@ def __init__(self, theme: str) -> None:
self._load_tooltips()
Tooltip.loaded = True
- def show_tooltip(self, view: sublime.View, tooltip: str, content: Dict[str, str], fallback: Callable) -> None: # noqa
+ def show_tooltip(self, view: sublime.View, tooltip: str, content: Dict[str, str], fallback: Callable, **kwargs: dict) -> None: # noqa
"""Generates and display a tooltip or pass execution to fallback
"""
@@ -42,14 +42,15 @@ def show_tooltip(self, view: sublime.View, tooltip: str, content: Dict[str, str]
return fallback()
width = get_settings(view, 'font_size', 8) * 75
- kwargs = {'location': -1, 'max_width': width if width < 900 else 900}
+ popup_kwargs = {'location': kwargs.get('location', -1),
+ 'max_width': kwargs.get('max_width', width if width < 900 else 900)}
if st_ver >= 3071:
kwargs['flags'] = sublime.COOPERATE_WITH_AUTO_COMPLETE
text = self._generate(tooltip, content)
if text is None:
return fallback()
- return view.show_popup(text, **kwargs)
+ return view.show_popup(text, **popup_kwargs)
def _generate(self, tooltip: str, content: Dict[str, str]) -> Union[Dict[str, str], None]: # noqa
"""Generate a tooltip with the given text
@@ -114,3 +115,43 @@ def _load_css(self, css_file: str) -> str:
self.themes[theme_name] = resource.read()
return theme_name
+
+
+class TooltipHelper(Tooltip):
+ loaded = False
+ themes = {} # type: Dict[str, bytes]
+ tooltips = {} # type: Dict[str, str]
+
+ def __init__(self, theme: str) -> None:
+ self.theme = theme
+
+ if int(sublime.version()) < 3070:
+ return
+
+ if TooltipHelper.loaded is False:
+ self._load_css_themes()
+ self._load_tooltips()
+ TooltipHelper.loaded = True
+
+ def _load_tooltips(self) -> None:
+ """Load tooltips templates from anaconda tooltips templates
+ """
+
+ template_files_pattern = os.path.join(
+ os.path.dirname(__file__), os.pardir,
+ 'templates', 'tooltips', '*.tpl')
+ for template_file in glob.glob(template_files_pattern):
+ with open(template_file, 'r', encoding='utf8') as tplfile:
+ tplname = os.path.basename(template_file).split('.tpl')[0]
+ self.tooltips[tplname] = Template(tplfile.read())
+
+ def generate_no_css(self, tooltip: str, content: Dict[str, str]) -> Union[Dict[str, str], None]:
+ try:
+ data = self.tooltips[tooltip].safe_substitute(content)
+ return data
+ except KeyError as err:
+ logging.error(
+ 'while generating tooltip without css: tooltip {} don\'t exists'.format(
+ str(err))
+ )
+ return None
diff --git a/css/popup.css b/css/popup.css
index 10aa857a..1e70b6a5 100644
--- a/css/popup.css
+++ b/css/popup.css
@@ -19,3 +19,15 @@ div.anaconda {
font-weight: bold;
font-size: 1.05em;
}
+
+.anaconda .error_warning .errors {
+ color: red;
+}
+
+.anaconda .error_warning .warnings {
+ color: orange;
+}
+
+.anaconda .error_warning .violations {
+ color: blue;
+}
diff --git a/listeners/linting.py b/listeners/linting.py
index d1f09272..e915cb5d 100644
--- a/listeners/linting.py
+++ b/listeners/linting.py
@@ -7,6 +7,7 @@
import sublime
import sublime_plugin
+from ..anaconda_lib.tooltips import Tooltip, TooltipHelper
from ..anaconda_lib._typing import Callable, Dict, Any
from ..anaconda_lib.helpers import (
check_linting, get_settings, check_linting_behaviour,
@@ -15,7 +16,7 @@
from ..anaconda_lib.linting.sublime import (
ANACONDA, erase_lint_marks, run_linter,
last_selected_lineno, update_statusbar,
- get_lineno_msgs
+ get_specific_lineno_msgs
)
@@ -154,28 +155,30 @@ def _erase_marks(self, view: sublime.View) -> None:
erase_lint_marks(view)
- def on_hover(self, view: sublime.View, point: int, hover_zone: int):
- # Planned to make my own listener class(sublime_plugin.ViewEventListener) for this function
- # but couldn't figure out how to register them
- # Tell me if I need to move this, or if it can piggyback under this listener
-
- # from anaconda_lib.tooltips:show_tooltips
- st_ver = int(sublime.version())
- if st_ver < 3070:
- return
-
- if hover_zone == sublime.HOVER_TEXT:
- if get_settings(view, 'anaconda_linter_hover_message', False):
- rowcol = view.rowcol(point)
- line = rowcol[0] # tuple (lineno, col)
- messages = get_lineno_msgs(view, line)
-
- if messages:
- # Not sure how to properly choose the height & width values, but this works fine on my laptop
- # Also unsure as to how to format it so its pretty and colorful (Tooltip._generate ?)
- max_width = len(messages) * 840
- max_height = len(max(messages))
- message = "\n".join(messages)
- # Newline is not rendered , errors all on one line :( help
- view.show_popup(message, location=point, max_width=max_width, max_height=max_height)
- # amount of time of popup?
+ def on_hover(self, view: sublime.View, point: int, hover_zone: int) -> None:
+ """Called when user hovers cursor above a line
+ """
+ if hover_zone == sublime.HOVER_TEXT and get_settings(view, 'anaconda_linter_hover_message', False):
+ rowcol = view.rowcol(point)
+ line = rowcol[0] # tuple (lineno, col)
+ messages_with_type = get_specific_lineno_msgs(view, line)
+
+ if messages_with_type:
+ css = get_settings(view, 'anaconda_tooltip_theme', 'popup')
+ main_tooltip = Tooltip(css)
+ tooltip_helper = TooltipHelper(css)
+ helper_content = []
+
+ for key in messages_with_type.keys():
+ for msg in messages_with_type.get(key):
+ tooltip_data = {'level': key.lower(), 'messages': msg}
+ helper_content.append(tooltip_helper.generate_no_css('error_warning_helper', tooltip_data))
+
+ def do_nothing():
+ return
+
+ messages = "
".join(helper_content)
+ tooltip_name = 'error_warning'
+ main_content = {'helper_content': messages}
+ kwargs = {'location': point}
+ main_tooltip.show_tooltip(view, tooltip_name, main_content, do_nothing, **kwargs)
diff --git a/templates/tooltips/error_warning.tpl b/templates/tooltips/error_warning.tpl
new file mode 100644
index 00000000..f0d8db6c
--- /dev/null
+++ b/templates/tooltips/error_warning.tpl
@@ -0,0 +1,5 @@
+
${messages}