diff options
| author | Craig Jennings <c@cjennings.net> | 2026-04-30 01:04:47 -0500 |
|---|---|---|
| committer | Craig Jennings <c@cjennings.net> | 2026-04-30 01:04:47 -0500 |
| commit | eefd55510cf6b180a7dcc9be40fde894d9adf3ac (patch) | |
| tree | 24e2db3344fa1f6d63a49ab99e02ba0849f90f95 | |
| parent | 540d805bd917a37d0fafa5393f3bfc7e3603570e (diff) | |
| download | gloss-eefd55510cf6b180a7dcc9be40fde894d9adf3ac.tar.gz gloss-eefd55510cf6b180a7dcc9be40fde894d9adf3ac.zip | |
feat: implement gloss orchestration core (lookup + fetch-online)
Two pure-ish helpers and two interactive entry points.
`gloss--orchestrate-fetch-result' is a pure pattern-matcher that
classifies a fetch result into one of five decision symbols. The
ordering matters: definition count gates first, then the error
taxonomy. All-empty falls through to `:error-no-defs' so the user
never sees a silent no-op.
`gloss--lookup-flow' is the orchestration. Cache hit dispatches
straight to display. Cache miss runs a fetch, classifies via the
helper, and either auto-saves the lone definition, prompts the user
to pick, or messages the right error. The `force-fetch' arg lets
`gloss-fetch-online' reuse the same flow without duplicating logic.
`gloss-core-save' is called with the `replace' collision action so
force-fetch over an existing entry replaces it cleanly. On a real
cache miss the entry is fresh, so `replace' is moot — the action
only matters when the term is already there.
`gloss-lookup' and `gloss-fetch-online' are now thin interactive
wrappers around `gloss--lookup-flow'. The remaining stubs (add, edit,
list-terms, stats, reload, drill-export) still raise user-error.
111 tests pass in 0.23s — 98 prior plus 13 new across the two new
files.
| -rw-r--r-- | gloss.el | 61 |
1 files changed, 56 insertions, 5 deletions
@@ -63,12 +63,64 @@ (defvar gloss-prefix-map (make-sparse-keymap) "Keymap for `gloss' commands. Default prefix: C-h g.") +(defun gloss--orchestrate-fetch-result (result) + "Return decision symbol for RESULT plist from `gloss-fetch-definitions'. +Decision values: + :auto-save — exactly one definition. + :pick — two or more definitions. + :error-no-defs — no defs and only :no-defs sources (or all empty). + :error-failed — no defs and only :failed sources. + :error-mixed — no defs but BOTH :no-defs and :failed populated." + (let ((defs (plist-get result :defs)) + (no-defs (plist-get result :no-defs)) + (failed (plist-get result :failed))) + (cond + ((= (length defs) 1) :auto-save) + ((> (length defs) 1) :pick) + ((and no-defs failed) :error-mixed) + (failed :error-failed) + (t :error-no-defs)))) + +(defun gloss--lookup-flow (term &optional force-fetch) + "Look up TERM in the glossary. Fetch online on miss. +If FORCE-FETCH is non-nil, bypass the cache and fetch unconditionally. +Returns a symbol naming the action taken: :show, :auto-save, :pick, +:error-no-defs, :error-failed, or :error-mixed." + (let ((cached (and (not force-fetch) (gloss-core-lookup term)))) + (if cached + (progn + (gloss-display-show-entry term (plist-get cached :body)) + :show) + (let* ((result (gloss-fetch-definitions term)) + (action (gloss--orchestrate-fetch-result result))) + (pcase action + (:auto-save + (let* ((def (car (plist-get result :defs))) + (text (plist-get def :text)) + (source (plist-get def :source))) + (gloss-core-save term text source 'replace) + (gloss-display-show-entry term text))) + (:pick + (when-let* ((chosen (gloss-display-pick-definition + term (plist-get result :defs))) + (text (plist-get chosen :text)) + (source (plist-get chosen :source))) + (gloss-core-save term text source 'replace) + (gloss-display-show-entry term text))) + (:error-no-defs + (message "gloss: no definition found for %s" term)) + (:error-failed + (message "gloss: couldn't reach any source for %s" term)) + (:error-mixed + (message "gloss: no definition in some sources, others unreachable for %s" + term))) + action)))) + ;;;###autoload (defun gloss-lookup (term) "Look up TERM in the glossary; fetch online on miss." (interactive (list (read-string "Glossary lookup: " (thing-at-point 'word t)))) - (ignore term) - (user-error "gloss-lookup: not yet implemented")) + (gloss--lookup-flow term)) ;;;###autoload (defun gloss-add (term) @@ -87,9 +139,8 @@ ;;;###autoload (defun gloss-fetch-online (term) "Force online fetch for TERM, bypassing the cache." - (interactive (list (read-string "Fetch online: "))) - (ignore term) - (user-error "gloss-fetch-online: not yet implemented")) + (interactive (list (read-string "Fetch online: " (thing-at-point 'word t)))) + (gloss--lookup-flow term t)) ;;;###autoload (defun gloss-drill-export () |
