Skip to content

Commit 03ead2a

Browse files
authored
Merge pull request #8 from SublimeText/feature/dirty-tab-indicator
Add dirty tab indicator
2 parents 9dd9cb0 + 5c2633a commit 03ead2a

5 files changed

Lines changed: 46 additions & 5 deletions

File tree

‎plugin/_compat.py‎

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,11 +17,23 @@ def set(self, key, value):
1717
def erase(self, key):
1818
self.pop(key, None)
1919

20+
class _QuickPanelItem:
21+
__slots__ = ["trigger", "details", "annotation", "kind"]
22+
23+
def __init__(self, trigger, details="", annotation="", kind=(0, "", "")):
24+
self.trigger = trigger
25+
self.details = details
26+
self.annotation = annotation
27+
self.kind = kind
28+
2029
class _SublimeModule(SimpleNamespace):
2130
OP_EQUAL = 0
2231
OP_NOT_EQUAL = 1
2332
KEEP_OPEN_ON_FOCUS_LOST = 0
2433
MONOSPACE_FONT = 0
34+
KIND_ID_COLOR_ORANGISH = 10
35+
KIND_AMBIGUOUS = (0, "", "")
36+
QuickPanelItem = _QuickPanelItem
2537

2638
def set_timeout(self, callback, timeout=0):
2739
callback()

‎plugin/constants.py‎

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,5 @@
1+
from ._compat import sublime
2+
13
TAB_HISTORY_LIMIT = 20
4+
5+
KIND_MODIFIED = (sublime.KIND_ID_COLOR_ORANGISH, "●", "Modified")

‎plugin/mru.py‎

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,15 @@
55

66
from .captions import caption_for_sheet_identities
77
from .constants import TAB_HISTORY_LIMIT
8-
from .sheets import SheetIdentity, sheet_identity
8+
from .sheets import SheetIdentity, identities_have_dirty_sheet, sheet_identity
99
from .state import GroupSelectionState, SheetSelectionHistory
1010

1111

1212
@dataclass
1313
class Entry:
1414
selection: GroupSelectionState
1515
caption: list[str]
16+
dirty: bool = False
1617

1718

1819
def collect_entries(window, history: SheetSelectionHistory) -> list[Entry]:
@@ -23,10 +24,12 @@ def collect_entries(window, history: SheetSelectionHistory) -> list[Entry]:
2324
group_state_stack = history["groups"].get(str(active_group))
2425
if group_state_stack:
2526
for group_state in group_state_stack:
27+
identities = group_state["selected_sheets"]
2628
entries.append(
2729
Entry(
2830
selection=group_state,
29-
caption=caption_for_sheet_identities(group_state["selected_sheets"], window),
31+
caption=caption_for_sheet_identities(identities, window),
32+
dirty=identities_have_dirty_sheet(identities, window, active_group),
3033
)
3134
)
3235
seen_identities.update(_selection_identity_keys(group_state))
@@ -38,20 +41,21 @@ def collect_entries(window, history: SheetSelectionHistory) -> list[Entry]:
3841
if identity in seen_identities:
3942
continue
4043

41-
entries.append(_entry_for_sheet(sheet, window))
44+
entries.append(_entry_for_sheet(sheet, window, active_group))
4245
seen_identities.add(identity)
4346

4447
return entries
4548

4649

47-
def _entry_for_sheet(sheet, window) -> Entry:
50+
def _entry_for_sheet(sheet, window, group: int) -> Entry:
4851
identity = sheet_identity(sheet, window)
4952
return Entry(
5053
selection={
5154
"active_sheet_index": 0,
5255
"selected_sheets": [identity],
5356
},
5457
caption=caption_for_sheet_identities([identity], window),
58+
dirty=identities_have_dirty_sheet([identity], window, group),
5559
)
5660

5761

‎plugin/session.py‎

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
from __future__ import annotations
22

33
from ._compat import sublime
4+
from .constants import KIND_MODIFIED
45
from .ctrl_release import CtrlReleasePoller
56
from .sheets import apply_group_selection
67
from .state import TabStackWindowState
@@ -26,7 +27,14 @@ def show_panel(window, state) -> None:
2627
if not state.session_active or not state.session_entries:
2728
return
2829

29-
items = [entry.caption for entry in state.session_entries]
30+
items = [
31+
sublime.QuickPanelItem(
32+
trigger=entry.caption[0],
33+
details=entry.caption[1],
34+
kind=KIND_MODIFIED if entry.dirty else sublime.KIND_AMBIGUOUS,
35+
)
36+
for entry in state.session_entries
37+
]
3038

3139
def on_select(index: int) -> None:
3240
if index < 0:

‎plugin/sheets.py‎

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,19 @@ def sheet_name(sheet) -> Optional[str]:
7979
return get_name() if get_name else None
8080

8181

82+
def sheet_is_dirty(sheet) -> bool:
83+
view = sheet.view()
84+
return view is not None and view.is_dirty()
85+
86+
87+
def identities_have_dirty_sheet(identities: list[SheetIdentity], window, group: int) -> bool:
88+
return any(
89+
(sheet := find_sheet_by_identity_and_group(window, identity, group)) is not None
90+
and sheet_is_dirty(sheet)
91+
for identity in identities
92+
)
93+
94+
8295
def find_live_sheets(window, identities: list[SheetIdentity], group: int) -> list[object]:
8396
return [
8497
live_sheet

0 commit comments

Comments
 (0)