Skip to content

Commit a7c75a9

Browse files
authored
Merge pull request #662 from Rejdukien/feature/stylesheet-imports-watcher
feat(watcher): implement stylesheet import tracking and refresh logic
2 parents 4cfd649 + fe030ac commit a7c75a9

File tree

2 files changed

+55
-4
lines changed

2 files changed

+55
-4
lines changed

src/core/utils/css_processor.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ def process(self) -> str:
2323
"""
2424
if not self.css_content:
2525
return ""
26+
self.imported_files = set()
2627
# Remove comments from the CSS content
2728
css = self._remove_comments(self.css_content)
2829
# Process @import statements and CSS variables

src/core/watcher.py

Lines changed: 54 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,14 @@
11
import hashlib
22
import logging
3+
import os
34
from os.path import basename
45

56
from watchdog.events import FileModifiedEvent, PatternMatchingEventHandler
67
from watchdog.observers import Observer
78

89
from core.bar_manager import BarManager
9-
from core.config import get_config_dir
10+
from core.config import get_config_dir, get_stylesheet_path
11+
from core.utils.css_processor import CSSProcessor
1012
from settings import DEFAULT_CONFIG_FILENAME, DEFAULT_STYLES_FILENAME
1113

1214

@@ -23,6 +25,44 @@ def __init__(self, bar_manager: BarManager):
2325
self._case_sensitive = False
2426
self._last_styles_hash = None
2527
self._last_config_hash = None
28+
self._stylesheet_path = self._normalize_path(get_stylesheet_path())
29+
self._imported_stylesheets = set()
30+
self._imported_hashes = {}
31+
self._observer = None
32+
self._watched_dirs = set()
33+
self._refresh_imported_stylesheets()
34+
35+
def _normalize_path(self, path: str) -> str:
36+
return os.path.normcase(os.path.normpath(path))
37+
38+
def _refresh_imported_stylesheets(self) -> None:
39+
try:
40+
processor = CSSProcessor(self._stylesheet_path)
41+
processor.process()
42+
self._imported_stylesheets = {self._normalize_path(path) for path in processor.imported_files}
43+
if self._stylesheet_path:
44+
self._imported_stylesheets.add(self._stylesheet_path)
45+
self._patterns = [self.styles_file, self.config_file, *self._imported_stylesheets]
46+
self._ensure_watch_paths()
47+
except Exception:
48+
logging.exception("Failed to refresh imported stylesheets list")
49+
50+
def set_observer(self, observer) -> None:
51+
self._observer = observer
52+
self._ensure_watch_paths()
53+
54+
def _ensure_watch_paths(self) -> None:
55+
if not self._observer:
56+
return
57+
paths = {get_config_dir()}
58+
for css_path in self._imported_stylesheets:
59+
if css_path:
60+
paths.add(os.path.dirname(css_path))
61+
for path in {self._normalize_path(path) for path in paths}:
62+
if path and path not in self._watched_dirs and os.path.isdir(path):
63+
self._observer.schedule(self, path=path, recursive=False)
64+
self._watched_dirs.add(path)
65+
logging.info(f"Watching directory: {path}")
2666

2767
def _file_hash(self, path):
2868
try:
@@ -33,23 +73,33 @@ def _file_hash(self, path):
3373

3474
def on_modified(self, event: FileModifiedEvent):
3575
modified_file = basename(event.src_path)
76+
normalized_path = self._normalize_path(event.src_path)
3677

3778
if modified_file == self.styles_file and self.bar_manager.config["watch_stylesheet"]:
3879
new_hash = self._file_hash(event.src_path)
3980
if new_hash and new_hash != self._last_styles_hash:
4081
self._last_styles_hash = new_hash
82+
self._refresh_imported_stylesheets()
4183
self.bar_manager.styles_modified.emit()
84+
logging.debug(f"Stylesheet modified: {event.src_path}")
4285
elif modified_file == self.config_file and self.bar_manager.config["watch_config"]:
4386
new_hash = self._file_hash(event.src_path)
4487
if new_hash and new_hash != self._last_config_hash:
4588
self._last_config_hash = new_hash
4689
self.bar_manager.config_modified.emit()
90+
logging.debug(f"Config file modified: {event.src_path}")
91+
elif normalized_path in self._imported_stylesheets and self.bar_manager.config["watch_stylesheet"]:
92+
new_hash = self._file_hash(event.src_path)
93+
if new_hash and self._imported_hashes.get(normalized_path) != new_hash:
94+
self._imported_hashes[normalized_path] = new_hash
95+
self._refresh_imported_stylesheets()
96+
self.bar_manager.styles_modified.emit()
97+
logging.debug(f"Imported stylesheet modified: {event.src_path}")
4798

4899

49100
def create_observer(bar_manager: BarManager):
50101
event_handler = FileModifiedEventHandler(bar_manager)
51-
config_path = get_config_dir()
52102
observer = Observer()
53-
observer.schedule(event_handler, path=config_path, recursive=False)
54-
logging.info(f"Created file watcher for path {config_path}")
103+
event_handler.set_observer(observer)
104+
logging.info("Created file watcher")
55105
return observer

0 commit comments

Comments
 (0)