Skip to content

Commit

Permalink
refactor: tidy codes
Browse files Browse the repository at this point in the history
Signed-off-by: Jack Cherng <jfcherng@gmail.com>
  • Loading branch information
jfcherng committed Feb 17, 2023
1 parent 72099ef commit 9fd53a5
Show file tree
Hide file tree
Showing 19 changed files with 233 additions and 296 deletions.
2 changes: 1 addition & 1 deletion boot.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
def reload_plugin() -> None:
import sys

# Remove all previously loaded plugin modules.
# remove all previously loaded plugin modules.
prefix = f"{__package__}."
for module_name in tuple(filter(lambda m: m.startswith(prefix) and m != __name__, sys.modules)):
del sys.modules[module_name]
Expand Down
18 changes: 7 additions & 11 deletions plugin/__init__.py
Original file line number Diff line number Diff line change
@@ -1,18 +1,16 @@
import sublime

# import all listeners and commands
from .commands.copy_uri import CopyUriFromContextMenuCommand, CopyUriFromCursorsCommand, CopyUriFromViewCommand
from .commands.open_uri import OpenUriFromCursorsCommand, OpenUriFromViewCommand
from .commands.select_uri import SelectUriFromCursorsCommand, SelectUriFromViewCommand
from .constant import PLUGIN_NAME
from .functions import compile_uri_regex, view_is_dirty_val
from .constants import PLUGIN_NAME
from .helpers import compile_uri_regex
from .listener import OpenUriViewEventListener
from .logger import apply_user_log_level, init_plugin_logger, log
from .phatom_sets_manager import PhatomSetsManager
from .renderer import RendererThread
from .settings import get_image_info, get_setting_renderer_interval, get_settings_object
from .shared import global_get, global_set
from .utils import is_processable_view
from .ui.phatom_sets_manager import PhatomSetsManager
from .utils import is_processable_view, list_all_views, view_is_dirty_val

__all__ = (
# ST: core
Expand Down Expand Up @@ -72,8 +70,6 @@ def _set_is_dirty_for_all_views(is_dirty: bool) -> None:
@param is_dirty Indicate if views are dirty
"""

for w in sublime.windows():
for v in w.views():
if is_processable_view(v):
view_is_dirty_val(v, is_dirty)
for view in list_all_views():
if is_processable_view(view):
view_is_dirty_val(view, is_dirty)
2 changes: 1 addition & 1 deletion plugin/commands/abstract.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
import sublime
import sublime_plugin

from ..functions import find_uri_regions_by_regions
from ..helpers import find_uri_regions_by_regions
from ..shared import is_plugin_ready
from ..types import EventDict, RegionLike

Expand Down
2 changes: 1 addition & 1 deletion plugin/commands/open_uri.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

import sublime

from ..functions import open_uri_with_browser
from ..helpers import open_uri_with_browser
from ..types import EventDict
from .abstract import AbstractUriCommand, UriSource

Expand Down
File renamed without changes.
89 changes: 2 additions & 87 deletions plugin/functions.py → plugin/helpers.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
import re
import urllib.parse as urllib_parse
import webbrowser
from typing import Any, Dict, Iterable, List, Optional, Pattern, Tuple, overload
from typing import Any, Dict, Iterable, List, Optional, Pattern, Tuple

import sublime

from .libs import triegex
from .logger import log
from .settings import get_setting, get_timestamp
from .settings import get_setting
from .shared import global_get
from .types import RegionLike
from .utils import convert_to_st_region, is_regions_intersected, merge_regions, region_expand, region_shift
Expand All @@ -20,7 +20,6 @@ def open_uri_with_browser(uri: str, browser: Optional[str] = "") -> None:
@param uri The uri
@param browser The browser
"""

parsed_uri = urllib_parse.urlparse(uri)

log("debug", f"Parsed URI: {parsed_uri}")
Expand Down Expand Up @@ -50,7 +49,6 @@ def compile_uri_regex() -> Tuple[Optional[Pattern[str]], Tuple[str, ...]]:
@return (compiled regex object, activated schemes)
"""

detect_schemes: Dict[str, Dict[str, Any]] = get_setting("detect_schemes")
uri_path_regexes: Dict[str, str] = get_setting("uri_path_regexes")

Expand Down Expand Up @@ -109,7 +107,6 @@ def find_uri_regions_by_region(
@return Found URI regions
"""

return find_uri_regions_by_regions(view, (region,), search_radius)


Expand All @@ -126,7 +123,6 @@ def find_uri_regions_by_regions(
@return Found URI regions
"""

st_regions = sorted(convert_to_st_region(region, sort=True) for region in regions)
search_regions = merge_regions(
(
Expand Down Expand Up @@ -163,84 +159,3 @@ def find_uri_regions_by_regions(
break

return uri_regions_intersected


@overload
def view_last_typing_timestamp_val(view: sublime.View) -> float:
...


@overload
def view_last_typing_timestamp_val(view: sublime.View, timestamp_s: float) -> None:
...


def view_last_typing_timestamp_val(view: sublime.View, timestamp_s: Optional[float] = None) -> Optional[float]:
"""
@brief Set/Get the last timestamp (in sec) when "OUIB_uri_regions" is updated
@param view The view
@param timestamp_s The last timestamp (in sec)
@return None if the set mode, otherwise the value
"""

if timestamp_s is None:
return float(view.settings().get("OUIB_last_update_timestamp", 0))

view.settings().set("OUIB_last_update_timestamp", timestamp_s)
return None


@overload
def view_is_dirty_val(view: sublime.View) -> bool:
...


@overload
def view_is_dirty_val(view: sublime.View, is_dirty: bool) -> None:
...


def view_is_dirty_val(view: sublime.View, is_dirty: Optional[bool] = None) -> Optional[bool]:
"""
@brief Set/Get the is_dirty of the current view
@param view The view
@param is_dirty Indicates if dirty
@return None if the set mode, otherwise the is_dirty
"""

if is_dirty is None:
return bool(view.settings().get("OUIB_is_dirty", True))

view.settings().set("OUIB_is_dirty", is_dirty)
return None


def is_view_typing(view: sublime.View) -> bool:
"""
@brief Determine if the view typing.
@param view The view
@return `True` if the view is typing, `False` otherwise.
"""

now_s = get_timestamp()
last_typing_s = view_last_typing_timestamp_val(view) or 0

return (now_s - last_typing_s) * 1000 < get_setting("typing_period")


def is_view_too_large(view: sublime.View) -> bool:
"""
@brief Determine if the view is too large. Note that size will be `0` if the view is loading.
@param view The view
@return `True` if the view is too large, `False` otherwise.
"""

return view.size() > get_setting("large_file_threshold")
11 changes: 6 additions & 5 deletions plugin/listener.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,12 @@
import sublime
import sublime_plugin

from .functions import find_uri_regions_by_region, view_is_dirty_val, view_last_typing_timestamp_val
from .phantom_set import delete_phantom_set, init_phantom_set
from .popup import show_popup
from .region_drawing import draw_uri_regions
from .settings import get_setting, get_setting_show_open_button, get_timestamp
from .helpers import find_uri_regions_by_region
from .settings import get_setting, get_setting_show_open_button
from .ui.phantom_set import delete_phantom_set, init_phantom_set
from .ui.popup import show_popup
from .ui.region_drawing import draw_uri_regions
from .utils import get_timestamp, view_is_dirty_val, view_last_typing_timestamp_val


class OpenUriViewEventListener(sublime_plugin.ViewEventListener):
Expand Down
8 changes: 2 additions & 6 deletions plugin/logger.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,7 @@ def init_plugin_logger() -> logging.Logger:
@return The initiated plugin logger.
"""

from .constant import PLUGIN_NAME
from .constants import PLUGIN_NAME

def set_logger_hander(logger: logging.Logger) -> None:
# remove all existing log handlers
Expand All @@ -39,7 +38,6 @@ def apply_user_log_level(logger: logging.Logger) -> None:
@param logger The logger
"""

from .settings import get_setting

log_level = get_setting("log_level").upper()
Expand All @@ -61,7 +59,6 @@ def log(level: str, msg: str) -> None:
@param level The log level
@param msg The message
"""

level_upper = level.upper()
level_int = logging.getLevelName(level_upper)

Expand All @@ -79,7 +76,6 @@ def msg(msg: str) -> str:
@return The plugin message.
"""

from .constant import PLUGIN_NAME
from .constants import PLUGIN_NAME

return f"[{PLUGIN_NAME}] {msg}"
56 changes: 39 additions & 17 deletions plugin/renderer.py
Original file line number Diff line number Diff line change
@@ -1,39 +1,61 @@
from typing import Generator
import threading
from typing import Any, Callable, Optional

import sublime

from .functions import is_view_too_large, is_view_typing, view_is_dirty_val
from .logger import log
from .phantom_set import erase_phantom_set, update_phantom_set
from .region_drawing import draw_uri_regions, erase_uri_regions
from .settings import get_setting, get_setting_show_open_button
from .settings import get_setting, get_setting_show_open_button, is_view_too_large, is_view_typing
from .shared import global_get
from .timer import RepeatingTimer
from .utils import is_processable_view, is_transient_view, view_find_all
from .ui.phantom_set import erase_phantom_set, update_phantom_set
from .ui.region_drawing import draw_uri_regions, erase_uri_regions
from .utils import is_processable_view, is_transient_view, list_foreground_views, view_find_all, view_is_dirty_val


def foreground_views() -> Generator[sublime.View, None, None]:
for window in sublime.windows():
for group_idx in range(window.num_groups()):
if view := window.active_view_in_group(group_idx):
yield view
class RepeatingTimer:
def __init__(self, interval_ms: int, func: Callable, *args: Any, **kwargs: Any) -> None:
self.interval_s = interval_ms / 1000
self.timer: Optional[threading.Timer] = None
self.is_running = False
self.set_func(func, *args, **kwargs)

def set_func(self, func: Callable, *args: Any, **kwargs: Any) -> None:
self.func = func
self.args = args
self.kwargs = kwargs

def set_interval(self, interval_ms: int) -> None:
self.interval_s = interval_ms / 1000

def start(self) -> None:
self.timer = threading.Timer(self.interval_s, self._callback)
self.timer.start()
self.is_running = True

def cancel(self) -> None:
if self.timer:
self.timer.cancel()
self.is_running = False

def _callback(self) -> None:
self.func(*self.args, **self.kwargs)
self.start()


class RendererThread(RepeatingTimer):
def __init__(self, interval_ms: int = 1000) -> None:
super().__init__(interval_ms, self._update_foreground_views)

# to prevent from overlapped processes when using a low interval
self.is_rendering = False
self._is_rendering = False

def _update_foreground_views(self) -> None:
if self.is_rendering:
if self._is_rendering:
return

self.is_rendering = True
for view in foreground_views():
self._is_rendering = True
for view in list_foreground_views():
self._update_view(view)
self.is_rendering = False
self._is_rendering = False

def _update_view(self, view: sublime.View) -> None:
if (
Expand Down
Loading

0 comments on commit 9fd53a5

Please sign in to comment.