|
22 | 22 | (require 'context-navigator-icons) |
23 | 23 | (require 'context-navigator-persist) |
24 | 24 | (require 'context-navigator-i18n) |
| 25 | +(require 'context-navigator-log) |
25 | 26 |
|
26 | 27 | (defcustom context-navigator-auto-open-groups-on-error t |
27 | 28 | "When non-nil, automatically switch the sidebar to the groups list if a group fails to load." |
@@ -1102,15 +1103,56 @@ Wraps to the bottom when no previous element is found before point." |
1102 | 1103 | "0.2.1") |
1103 | 1104 |
|
1104 | 1105 | (defun context-navigator-sidebar-toggle-enabled () |
1105 | | - "Toggle enabled/disabled for the item at point, apply to gptel. |
| 1106 | + "Toggle inclusion of the item at point in gptel sync (model :enabled). |
1106 | 1107 |
|
1107 | | -Deprecated for 't' binding: use `context-navigator-sidebar-toggle-gptel' to toggle gptel membership." |
| 1108 | +Toggles the item's enabled flag and, when push→gptel is ON, applies the |
| 1109 | +updated set to gptel immediately. The new state is persisted via the |
| 1110 | +existing debounced autosave." |
1108 | 1111 | (interactive) |
1109 | 1112 | (when-let* ((item (context-navigator-sidebar--at-item))) |
1110 | | - (let* ((key (context-navigator-model-item-key item))) |
1111 | | - (message "Deprecated: toggling model only for %s" (or (context-navigator-item-name item) key)) |
1112 | | - (let* ((st (ignore-errors (context-navigator-toggle-item key)))) |
1113 | | - (ignore-errors st)) |
| 1113 | + (let* ((key (context-navigator-model-item-key item)) |
| 1114 | + (name (or (context-navigator-item-name item) key))) |
| 1115 | + ;; Toggle model |
| 1116 | + (ignore-errors (context-navigator-toggle-item key)) |
| 1117 | + ;; Apply to gptel immediately when auto-push is ON and refresh indicators snapshot |
| 1118 | + (when (and (boundp 'context-navigator--push-to-gptel) |
| 1119 | + context-navigator--push-to-gptel) |
| 1120 | + (let* ((st (ignore-errors (context-navigator--state-get))) |
| 1121 | + (items (and st (context-navigator-state-items st)))) |
| 1122 | + (let ((res (ignore-errors (context-navigator-gptel-apply (or items '()))))) |
| 1123 | + (ignore-errors |
| 1124 | + (context-navigator-debug :debug :ui "toggle:t apply -> %S" res))) |
| 1125 | + ;; Immediately refresh cached keys so lamps reflect actual presence now. |
| 1126 | + (let* ((lst (ignore-errors (context-navigator-gptel-pull))) |
| 1127 | + (pulled-keys (and (listp lst) |
| 1128 | + (mapcar #'context-navigator-model-item-key lst))) |
| 1129 | + (raw-keys (and (or (null pulled-keys) (= (length pulled-keys) 0)) |
| 1130 | + (fboundp 'context-navigator-gptel--raw-keys) |
| 1131 | + (ignore-errors (context-navigator-gptel--raw-keys)))) |
| 1132 | + (fallback-keys |
| 1133 | + (when (and (or (null pulled-keys) (= (length pulled-keys) 0)) |
| 1134 | + (or (null raw-keys) (= (length raw-keys) 0))) |
| 1135 | + (and (listp items) |
| 1136 | + (mapcar #'context-navigator-model-item-key |
| 1137 | + (cl-remove-if-not #'context-navigator-item-enabled items))))) |
| 1138 | + (keys (or pulled-keys raw-keys fallback-keys '()))) |
| 1139 | + (let ((h (sxhash-equal keys))) |
| 1140 | + (setq context-navigator-sidebar--gptel-keys keys |
| 1141 | + context-navigator-sidebar--gptel-keys-hash h) |
| 1142 | + (ignore-errors |
| 1143 | + (context-navigator-debug :debug :ui |
| 1144 | + "toggle:t immediate pull -> keys=%d hash=%s%s" |
| 1145 | + (length keys) h |
| 1146 | + (if (and (or (null pulled-keys) (= (length pulled-keys) 0)) |
| 1147 | + (or (null raw-keys) (= (length raw-keys) 0))) |
| 1148 | + " (fallback)" ""))))))) |
| 1149 | + ;; Report new state briefly |
| 1150 | + (let* ((st2 (ignore-errors (context-navigator--state-get))) |
| 1151 | + (idx (and st2 (context-navigator-state-index st2))) |
| 1152 | + (it2 (and idx (gethash key idx))) |
| 1153 | + (en (and it2 (context-navigator-item-enabled it2)))) |
| 1154 | + (message (if en "Enabled: %s" "Disabled: %s") name)) |
| 1155 | + ;; Refresh UI and advance to the next item |
1114 | 1156 | (context-navigator-sidebar--schedule-render) |
1115 | 1157 | (context-navigator-sidebar--render-if-visible) |
1116 | 1158 | (context-navigator-sidebar-next-item)))) |
@@ -1233,20 +1275,54 @@ Order of operations: |
1233 | 1275 | :gptel-change |
1234 | 1276 | (lambda (&rest _) |
1235 | 1277 | (let* ((lst (ignore-errors (context-navigator-gptel-pull))) |
1236 | | - (keys (and (listp lst) |
1237 | | - (mapcar #'context-navigator-model-item-key lst)))) |
| 1278 | + (pulled-keys (and (listp lst) |
| 1279 | + (mapcar #'context-navigator-model-item-key lst))) |
| 1280 | + (raw-keys (and (or (null pulled-keys) (= (length pulled-keys) 0)) |
| 1281 | + (fboundp 'context-navigator-gptel--raw-keys) |
| 1282 | + (ignore-errors (context-navigator-gptel--raw-keys)))) |
| 1283 | + ;; Last-resort fallback: enabled items in model only if both pulled and raw are empty |
| 1284 | + (fallback-keys |
| 1285 | + (when (and (or (null pulled-keys) (= (length pulled-keys) 0)) |
| 1286 | + (or (null raw-keys) (= (length raw-keys) 0))) |
| 1287 | + (let* ((st (ignore-errors (context-navigator--state-get))) |
| 1288 | + (items (and st (context-navigator-state-items st)))) |
| 1289 | + (and (listp items) |
| 1290 | + (mapcar #'context-navigator-model-item-key |
| 1291 | + (cl-remove-if-not #'context-navigator-item-enabled items)))))) |
| 1292 | + (keys (or pulled-keys raw-keys fallback-keys '())) |
| 1293 | + (h (sxhash-equal keys)) |
| 1294 | + (n (length keys)) |
| 1295 | + (use-fallback (and (or (null pulled-keys) (= (length pulled-keys) 0)) |
| 1296 | + (or (null raw-keys) (= (length raw-keys) 0)))) |
| 1297 | + (sample (mapconcat (lambda (s) s) |
| 1298 | + (cl-subseq keys 0 (min 5 n)) |
| 1299 | + ", "))) |
1238 | 1300 | (setq context-navigator-sidebar--gptel-keys keys |
1239 | | - context-navigator-sidebar--gptel-keys-hash (sxhash-equal keys))) |
| 1301 | + context-navigator-sidebar--gptel-keys-hash h) |
| 1302 | + (ignore-errors |
| 1303 | + (context-navigator-debug :debug :ui |
| 1304 | + "gptel-change: pulled %d keys, hash=%s, sample=[%s]%s" |
| 1305 | + n h sample |
| 1306 | + (if use-fallback " (fallback)" "")))) |
1240 | 1307 | (context-navigator-sidebar--schedule-render))) |
1241 | 1308 | context-navigator-sidebar--subs)) |
1242 | 1309 |
|
1243 | 1310 | (defun context-navigator-sidebar--init-gptel-cache () |
1244 | 1311 | "Initialize cached gptel keys once." |
1245 | 1312 | (let* ((lst (ignore-errors (context-navigator-gptel-pull))) |
1246 | | - (keys (and (listp lst) |
1247 | | - (mapcar #'context-navigator-model-item-key lst)))) |
| 1313 | + (pulled (and (listp lst) |
| 1314 | + (mapcar #'context-navigator-model-item-key lst))) |
| 1315 | + (raw (and (or (null pulled) (= (length pulled) 0)) |
| 1316 | + (fboundp 'context-navigator-gptel--raw-keys) |
| 1317 | + (ignore-errors (context-navigator-gptel--raw-keys)))) |
| 1318 | + (keys (or pulled raw '())) |
| 1319 | + (h (sxhash-equal keys))) |
1248 | 1320 | (setq context-navigator-sidebar--gptel-keys keys |
1249 | | - context-navigator-sidebar--gptel-keys-hash (sxhash-equal keys)))) |
| 1321 | + context-navigator-sidebar--gptel-keys-hash h) |
| 1322 | + (ignore-errors |
| 1323 | + (context-navigator-debug :debug :ui |
| 1324 | + "gptel-init: pulled %d keys, hash=%s" |
| 1325 | + (length (or keys '())) h)))) |
1250 | 1326 |
|
1251 | 1327 | (defun context-navigator-sidebar--close-hijacked-windows () |
1252 | 1328 | "Close any windows previously marked as sidebar that now show a foreign buffer. |
@@ -1324,12 +1400,31 @@ render." |
1324 | 1400 | (with-current-buffer buf |
1325 | 1401 | (when (get-buffer-window buf t) |
1326 | 1402 | (let* ((lst (ignore-errors (context-navigator-gptel-pull))) |
1327 | | - (keys (and (listp lst) |
1328 | | - (mapcar #'context-navigator-model-item-key lst))) |
1329 | | - (h (sxhash-equal keys))) |
| 1403 | + (pulled-keys (and (listp lst) |
| 1404 | + (mapcar #'context-navigator-model-item-key lst))) |
| 1405 | + (raw-keys (and (or (null pulled-keys) (= (length pulled-keys) 0)) |
| 1406 | + (fboundp 'context-navigator-gptel--raw-keys) |
| 1407 | + (ignore-errors (context-navigator-gptel--raw-keys)))) |
| 1408 | + (fallback-keys |
| 1409 | + (when (and (or (null pulled-keys) (= (length pulled-keys) 0)) |
| 1410 | + (or (null raw-keys) (= (length raw-keys) 0))) |
| 1411 | + (let* ((st (ignore-errors (context-navigator--state-get))) |
| 1412 | + (items (and st (context-navigator-state-items st)))) |
| 1413 | + (and (listp items) |
| 1414 | + (mapcar #'context-navigator-model-item-key |
| 1415 | + (cl-remove-if-not #'context-navigator-item-enabled items)))))) |
| 1416 | + (keys (or pulled-keys raw-keys fallback-keys '())) |
| 1417 | + (h (sxhash-equal keys)) |
| 1418 | + (use-fallback (and (or (null pulled-keys) (= (length pulled-keys) 0)) |
| 1419 | + (or (null raw-keys) (= (length raw-keys) 0))))) |
1330 | 1420 | (unless (equal h context-navigator-sidebar--gptel-keys-hash) |
1331 | 1421 | (setq context-navigator-sidebar--gptel-keys keys |
1332 | 1422 | context-navigator-sidebar--gptel-keys-hash h) |
| 1423 | + (ignore-errors |
| 1424 | + (context-navigator-debug :debug :ui |
| 1425 | + "gptel-poll: updated keys=%d hash=%s%s" |
| 1426 | + (length keys) h |
| 1427 | + (if use-fallback " (fallback)" ""))) |
1333 | 1428 | (context-navigator-sidebar--schedule-render))))))))))))) |
1334 | 1429 |
|
1335 | 1430 | (defun context-navigator-sidebar--install-subs () |
@@ -1401,7 +1496,7 @@ MAP is a keymap to search for COMMAND bindings." |
1401 | 1496 | (context-navigator-sidebar-previous-item . :help-previous-item) |
1402 | 1497 | (context-navigator-sidebar-activate . :help-activate) |
1403 | 1498 | (context-navigator-sidebar-preview . :help-preview) |
1404 | | - (context-navigator-sidebar-toggle-gptel . :help-toggle-gptel) |
| 1499 | + (context-navigator-sidebar-toggle-enabled . :help-toggle-gptel) |
1405 | 1500 | (context-navigator-sidebar-delete-dispatch . :help-delete) |
1406 | 1501 | (context-navigator-sidebar-refresh-dispatch . :help-refresh) |
1407 | 1502 | (context-navigator-sidebar-go-up . :help-go-up) |
@@ -1501,7 +1596,7 @@ MAP is a keymap to search for COMMAND bindings." |
1501 | 1596 | (define-key m (kbd "j") #'context-navigator-sidebar-next-item) |
1502 | 1597 | (define-key m (kbd "k") #'context-navigator-sidebar-previous-item) |
1503 | 1598 | (define-key m (kbd "l") #'context-navigator-sidebar-activate) |
1504 | | - (define-key m (kbd "t") #'context-navigator-sidebar-toggle-gptel) |
| 1599 | + (define-key m (kbd "t") #'context-navigator-sidebar-toggle-enabled) |
1505 | 1600 |
|
1506 | 1601 | ;; TAB navigation between interactive elements |
1507 | 1602 | ;; Bind several TAB event representations to be robust across terminals/minor-modes. |
@@ -1548,7 +1643,7 @@ MAP is a keymap to search for COMMAND bindings." |
1548 | 1643 | ;; Ensure bindings are updated after reloads (defvar won't reinitialize an existing keymap). |
1549 | 1644 | (when (keymapp context-navigator-sidebar-mode-map) |
1550 | 1645 | ;; Keep legacy binding in sync |
1551 | | - (define-key context-navigator-sidebar-mode-map (kbd "t") #'context-navigator-sidebar-toggle-gptel) |
| 1646 | + (define-key context-navigator-sidebar-mode-map (kbd "t") #'context-navigator-sidebar-toggle-enabled) |
1552 | 1647 | ;; Make TAB robust across reloads/terminals/minor-modes |
1553 | 1648 | (define-key context-navigator-sidebar-mode-map (kbd "TAB") #'context-navigator-sidebar-tab-next) |
1554 | 1649 | (define-key context-navigator-sidebar-mode-map (kbd "<tab>") #'context-navigator-sidebar-tab-next) |
@@ -1660,6 +1755,18 @@ Do not highlight header/separator lines." |
1660 | 1755 | "Toggle push-to-gptel session flag and refresh header immediately." |
1661 | 1756 | (interactive) |
1662 | 1757 | (ignore-errors (context-navigator-toggle-push-to-gptel)) |
| 1758 | + ;; Immediately refresh cached keys from gptel so indicators reflect actual presence, |
| 1759 | + ;; regardless of push flag. |
| 1760 | + (let* ((lst (ignore-errors (context-navigator-gptel-pull))) |
| 1761 | + (keys (and (listp lst) |
| 1762 | + (mapcar #'context-navigator-model-item-key lst))) |
| 1763 | + (h (sxhash-equal keys))) |
| 1764 | + (setq context-navigator-sidebar--gptel-keys keys |
| 1765 | + context-navigator-sidebar--gptel-keys-hash h) |
| 1766 | + (ignore-errors |
| 1767 | + (context-navigator-debug :debug :ui |
| 1768 | + "toggle:push -> keys=%d hash=%s" |
| 1769 | + (length (or keys '())) h))) |
1663 | 1770 | ;; Force immediate redraw for visible sidebar |
1664 | 1771 | (let ((buf (get-buffer context-navigator-sidebar--buffer-name))) |
1665 | 1772 | (when (buffer-live-p buf) |
|
0 commit comments