summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThanos Apollo <public@thanosapollo.org>2026-04-25 10:46:37 +0300
committerThanos Apollo <public@thanosapollo.org>2026-04-25 10:46:37 +0300
commit246d83c548da6b113c92f5bcd3d6083456944a02 (patch)
treeb80f92c546344ba396c73489c2601a16dfb65c38
parentec8676e149998707696516e1b3b7b16399b84e38 (diff)
buffer: Remove DB dependency, move CAPF to utils and routing to view
Move CAPF completion functions (issue-capf, mention-capf) from buffer.el to utils.el where the DB dependency already exists. Move view-item routing to view.el. buffer.el is now a pure rendering library with no forgejo-db references. Re-render helper also moved to view.el.
-rw-r--r--lisp/forgejo-buffer.el117
-rw-r--r--lisp/forgejo-issue.el4
-rw-r--r--lisp/forgejo-pull.el8
-rw-r--r--lisp/forgejo-utils.el87
-rw-r--r--lisp/forgejo-view.el39
5 files changed, 128 insertions, 127 deletions
diff --git a/lisp/forgejo-buffer.el b/lisp/forgejo-buffer.el
index ed439e4..de00701 100644
--- a/lisp/forgejo-buffer.el
+++ b/lisp/forgejo-buffer.el
@@ -31,7 +31,6 @@
(require 'dom)
(require 'diff-mode)
(require 'forgejo)
-(require 'forgejo-db)
(defvar forgejo-repo--host)
(defvar forgejo-repo--owner)
@@ -193,7 +192,7 @@ Returns nil if BODY is :null, nil, or empty."
(defun forgejo-buffer--browse-url (url &rest _args)
"Open URL in forgejo.el if it's a Forgejo issue/PR, else in browser."
(if-let* ((parsed (forgejo-buffer--parse-forgejo-url url)))
- (forgejo-buffer-view-item (nth 0 parsed) (nth 1 parsed) (nth 2 parsed))
+ (forgejo-view-item (nth 0 parsed) (nth 1 parsed) (nth 2 parsed))
(browse-url-default-browser url)))
(defun forgejo-buffer--insert-html (html)
@@ -327,20 +326,8 @@ NODE-DATA is a plist with :type and type-specific keys."
map)
"Keymap for reference links in event lines.")
-(declare-function forgejo-issue-view "forgejo-issue.el"
+(declare-function forgejo-view-item "forgejo-view.el"
(owner repo number))
-(declare-function forgejo-pull-view "forgejo-pull.el"
- (owner repo number))
-
-(defun forgejo-buffer-view-item (owner repo number)
- "View issue or PR NUMBER in OWNER/REPO.
-Checks the DB to determine if it's a PR, falls back to issue view."
- (let ((cached (forgejo-db-get-issue
- (url-host (url-generic-parse-url forgejo-repo--host))
- owner repo number)))
- (if (and cached (alist-get 'pull_request cached))
- (forgejo-pull-view owner repo number)
- (forgejo-issue-view owner repo number))))
(defun forgejo-buffer-follow-ref ()
"Follow the reference link at point.
@@ -351,7 +338,7 @@ Uses the ref-repo text property for cross-repo references."
(parts (when full-name (split-string full-name "/")))
(owner (or (nth 0 parts) forgejo-repo--owner))
(repo (or (nth 1 parts) forgejo-repo--name)))
- (forgejo-buffer-view-item owner repo number))))
+ (forgejo-view-item owner repo number))))
(defvar forgejo-buffer-commit-map
(let ((map (make-sparse-keymap)))
@@ -812,86 +799,6 @@ Both should be alists with `body_html' pre-populated from the DB."
(push result nodes)))))
(nreverse nodes)))
-;;; Issue/PR # completion
-
-(defvar-local forgejo-buffer--capf-candidates nil
- "Cached completion candidates for # references.")
-
-(defun forgejo-buffer--issue-capf ()
- "Completion-at-point function for #N issue/PR references."
- (when-let* ((bounds (forgejo-buffer--capf-bounds)))
- (let ((start (car bounds))
- (end (cdr bounds)))
- (list start end
- (forgejo-buffer--capf-collection)
- :annotation-function #'forgejo-buffer--capf-annotate
- :exclusive 'no))))
-
-(defun forgejo-buffer--capf-bounds ()
- "Return (START . END) for the # reference at point, or nil."
- (save-excursion
- (let ((end (point)))
- (when (re-search-backward "#" (line-beginning-position) t)
- (cons (point) end)))))
-
-(defun forgejo-buffer--capf-collection ()
- "Return completion candidates for # references."
- (or forgejo-buffer--capf-candidates
- (setq forgejo-buffer--capf-candidates
- (mapcar (lambda (pair)
- (format "#%d" (car pair)))
- (forgejo-buffer--capf-load-candidates)))))
-
-(defun forgejo-buffer--capf-load-candidates ()
- "Load issue/PR candidates from the DB for the current repo context."
- (when-let* ((host (and (boundp 'forgejo-repo--host)
- (url-host (url-generic-parse-url forgejo-repo--host))))
- (owner (and (boundp 'forgejo-repo--owner) forgejo-repo--owner))
- (repo (and (boundp 'forgejo-repo--name) forgejo-repo--name)))
- (forgejo-db-get-issue-titles host owner repo)))
-
-(defun forgejo-buffer--capf-annotate (candidate)
- "Return the title annotation for CANDIDATE (#N)."
- (when (string-match "#\\([0-9]+\\)" candidate)
- (let* ((number (string-to-number (match-string 1 candidate)))
- (titles (forgejo-buffer--capf-load-candidates))
- (title (alist-get number titles)))
- (when title (concat " " title)))))
-
-;;; @mention completion
-
-(defvar-local forgejo-buffer--mention-candidates nil
- "Cached completion candidates for @ mentions.")
-
-(defun forgejo-buffer--mention-capf ()
- "Completion-at-point function for @user mentions."
- (when-let* ((bounds (forgejo-buffer--mention-bounds)))
- (list (car bounds) (cdr bounds)
- (forgejo-buffer--mention-collection)
- :exclusive 'no)))
-
-(defun forgejo-buffer--mention-bounds ()
- "Return (START . END) for the @ mention at point, or nil."
- (save-excursion
- (let ((end (point)))
- (when (re-search-backward "@" (line-beginning-position) t)
- (cons (point) end)))))
-
-(defun forgejo-buffer--mention-collection ()
- "Return completion candidates for @ mentions."
- (or forgejo-buffer--mention-candidates
- (setq forgejo-buffer--mention-candidates
- (mapcar (lambda (login) (concat "@" login))
- (forgejo-buffer--mention-load-users)))))
-
-(defun forgejo-buffer--mention-load-users ()
- "Load usernames from the DB for the current repo context."
- (when-let* ((host (and (boundp 'forgejo-repo--host)
- (url-host (url-generic-parse-url forgejo-repo--host))))
- (owner (and (boundp 'forgejo-repo--owner) forgejo-repo--owner))
- (repo (and (boundp 'forgejo-repo--name) forgejo-repo--name)))
- (forgejo-db-get-authors host owner repo)))
-
;;; Utilities for detail views
(defun forgejo-buffer--node-at-point (ewoc)
@@ -921,24 +828,6 @@ Both should be alists with `body_html' pre-populated from the DB."
(when (and assignees (not (string-empty-p assignees)))
(concat " " (propertize assignees 'face 'shadow)))))))
-;;; Re-render helper
-
-(defun forgejo-buffer--re-render (buf-name host owner repo number
- render-fn &optional restore-line)
- "Re-render detail buffer BUF-NAME from fresh DB data.
-RENDER-FN is called with (BUF-NAME HOST-URL OWNER REPO ISSUE-ALIST
-TIMELINE-ALISTS)."
- (when (buffer-live-p (get-buffer buf-name))
- (let* ((host-url (forgejo--host-url-for-hostname host))
- (issue (forgejo-db-get-issue host owner repo number))
- (tl-rows (forgejo-db-get-timeline host owner repo number))
- (tl-alists (mapcar #'forgejo-db--row-to-timeline-alist tl-rows)))
- (funcall render-fn buf-name host-url owner repo issue tl-alists)
- (when restore-line
- (with-current-buffer buf-name
- (goto-char (point-min))
- (forward-line (1- restore-line)))))))
-
;;; Diff hunk rendering
(defun forgejo-buffer--insert-diff-hunk (hunk-text)
diff --git a/lisp/forgejo-issue.el b/lisp/forgejo-issue.el
index c9e1900..2337bcf 100644
--- a/lisp/forgejo-issue.el
+++ b/lisp/forgejo-issue.el
@@ -345,8 +345,8 @@ When RESTORE-LINE is non-nil, go to that line after re-rendering."
(lambda (timeline _tl-headers)
(forgejo-db-save-timeline host owner repo number timeline)
;; First render with whatever we have
- (forgejo-buffer--re-render
- buf-name host owner repo number
+ (forgejo-view--re-render
+ buf-name host-url host owner repo number
#'forgejo-issue--render-detail restore-line)
;; Then render missing HTML and re-render
(forgejo-view--render-missing-html
diff --git a/lisp/forgejo-pull.el b/lisp/forgejo-pull.el
index d84e829..4932242 100644
--- a/lisp/forgejo-pull.el
+++ b/lisp/forgejo-pull.el
@@ -310,8 +310,8 @@ When RESTORE-LINE is non-nil, go to that line after re-rendering."
(lambda (timeline _tl-headers)
(forgejo-db-save-timeline host owner repo number timeline)
;; First render with whatever we have
- (forgejo-buffer--re-render
- buf-name host owner repo number
+ (forgejo-view--re-render
+ buf-name host-url host owner repo number
#'forgejo-pull--render-detail restore-line)
;; Fetch review comments, then render missing HTML
(let ((tl-alists (mapcar #'forgejo-db--row-to-timeline-alist
@@ -319,8 +319,8 @@ When RESTORE-LINE is non-nil, go to that line after re-rendering."
(forgejo-review-sync-comments
host-url host owner repo number tl-alists
(lambda ()
- (forgejo-buffer--re-render
- buf-name host owner repo number
+ (forgejo-view--re-render
+ buf-name host-url host owner repo number
#'forgejo-pull--render-detail restore-line)
(forgejo-view--render-missing-html
host-url host owner repo number buf-name restore-line
diff --git a/lisp/forgejo-utils.el b/lisp/forgejo-utils.el
index 83ae3a5..1752946 100644
--- a/lisp/forgejo-utils.el
+++ b/lisp/forgejo-utils.el
@@ -73,10 +73,87 @@ CALLBACK is called on success."
(message "%sd %s/%s#%d" action owner repo number)
(when callback (funcall callback)))))))
-;;; Comment
+;;; Issue/PR # completion
+
+(defvar-local forgejo-utils--capf-candidates nil
+ "Cached completion candidates for # references.")
+
+(defun forgejo-utils-issue-capf ()
+ "Completion-at-point function for #N issue/PR references."
+ (when-let* ((bounds (forgejo-utils--capf-bounds)))
+ (let ((start (car bounds))
+ (end (cdr bounds)))
+ (list start end
+ (forgejo-utils--capf-collection)
+ :annotation-function #'forgejo-utils--capf-annotate
+ :exclusive 'no))))
+
+(defun forgejo-utils--capf-bounds ()
+ "Return (START . END) for the # reference at point, or nil."
+ (save-excursion
+ (let ((end (point)))
+ (when (re-search-backward "#" (line-beginning-position) t)
+ (cons (point) end)))))
+
+(defun forgejo-utils--capf-collection ()
+ "Return completion candidates for # references."
+ (or forgejo-utils--capf-candidates
+ (setq forgejo-utils--capf-candidates
+ (mapcar (lambda (pair)
+ (format "#%d" (car pair)))
+ (forgejo-utils--capf-load-candidates)))))
+
+(defun forgejo-utils--capf-load-candidates ()
+ "Load issue/PR candidates from the DB for the current repo context."
+ (when-let* ((host (and (boundp 'forgejo-repo--host)
+ (url-host (url-generic-parse-url forgejo-repo--host))))
+ (owner (and (boundp 'forgejo-repo--owner) forgejo-repo--owner))
+ (repo (and (boundp 'forgejo-repo--name) forgejo-repo--name)))
+ (forgejo-db-get-issue-titles host owner repo)))
+
+(defun forgejo-utils--capf-annotate (candidate)
+ "Return the title annotation for CANDIDATE (#N)."
+ (when (string-match "#\\([0-9]+\\)" candidate)
+ (let* ((number (string-to-number (match-string 1 candidate)))
+ (titles (forgejo-utils--capf-load-candidates))
+ (title (alist-get number titles)))
+ (when title (concat " " title)))))
+
+;;; @mention completion
+
+(defvar-local forgejo-utils--mention-candidates nil
+ "Cached completion candidates for @ mentions.")
+
+(defun forgejo-utils-mention-capf ()
+ "Completion-at-point function for @user mentions."
+ (when-let* ((bounds (forgejo-utils--mention-bounds)))
+ (list (car bounds) (cdr bounds)
+ (forgejo-utils--mention-collection)
+ :exclusive 'no)))
+
+(defun forgejo-utils--mention-bounds ()
+ "Return (START . END) for the @ mention at point, or nil."
+ (save-excursion
+ (let ((end (point)))
+ (when (re-search-backward "@" (line-beginning-position) t)
+ (cons (point) end)))))
+
+(defun forgejo-utils--mention-collection ()
+ "Return completion candidates for @ mentions."
+ (or forgejo-utils--mention-candidates
+ (setq forgejo-utils--mention-candidates
+ (mapcar (lambda (login) (concat "@" login))
+ (forgejo-utils--mention-load-users)))))
+
+(defun forgejo-utils--mention-load-users ()
+ "Load usernames from the DB for the current repo context."
+ (when-let* ((host (and (boundp 'forgejo-repo--host)
+ (url-host (url-generic-parse-url forgejo-repo--host))))
+ (owner (and (boundp 'forgejo-repo--owner) forgejo-repo--owner))
+ (repo (and (boundp 'forgejo-repo--name) forgejo-repo--name)))
+ (forgejo-db-get-authors host owner repo)))
-(declare-function forgejo-buffer--issue-capf "forgejo-buffer.el" ())
-(declare-function forgejo-buffer--mention-capf "forgejo-buffer.el" ())
+;;; Comment
(defun forgejo-utils-read-body (prompt &optional initial)
"Read multi-line text with # issue/PR completion.
@@ -89,8 +166,8 @@ Like `read-string-from-buffer' but with # completion for issue references."
forgejo-repo--owner owner
forgejo-repo--name repo)
(setq-local completion-at-point-functions
- (list #'forgejo-buffer--issue-capf
- #'forgejo-buffer--mention-capf))
+ (list #'forgejo-utils-issue-capf
+ #'forgejo-utils-mention-capf))
(run-hooks 'forgejo-compose-hook))))
(unwind-protect
(progn
diff --git a/lisp/forgejo-view.el b/lisp/forgejo-view.el
index b1e6044..dc4f893 100644
--- a/lisp/forgejo-view.el
+++ b/lisp/forgejo-view.el
@@ -64,6 +64,23 @@ Called with (HOST-URL OWNER REPO NUMBER).")
"Return the data plist of the EWOC node at point, or nil."
(forgejo-buffer--node-at-point forgejo-view--ewoc))
+;;; Item routing
+
+(declare-function forgejo-issue-view "forgejo-issue.el"
+ (owner repo number))
+(declare-function forgejo-pull-view "forgejo-pull.el"
+ (owner repo number))
+
+(defun forgejo-view-item (owner repo number)
+ "View issue or PR NUMBER in OWNER/REPO.
+Checks the DB to determine if it's a PR, falls back to issue view."
+ (let ((cached (forgejo-db-get-issue
+ (url-host (url-generic-parse-url forgejo-repo--host))
+ owner repo number)))
+ (if (and cached (alist-get 'pull_request cached))
+ (forgejo-pull-view owner repo number)
+ (forgejo-issue-view owner repo number))))
+
;;; List-view rendering
(defun forgejo-view--render-from-db (buf-name host-url host owner repo
@@ -120,6 +137,24 @@ SYNC-FN and BROWSE-FN are stored as buffer-locals for action commands."
(set-buffer-modified-p nil)
(current-buffer))))
+;;; Re-render from DB
+
+(defun forgejo-view--re-render (buf-name host-url host owner repo number
+ render-fn &optional restore-line)
+ "Re-render detail buffer BUF-NAME from fresh DB data.
+HOST-URL is the instance. HOST is the hostname.
+RENDER-FN is called with (BUF-NAME HOST-URL OWNER REPO ITEM TIMELINE).
+Restores point to RESTORE-LINE if given."
+ (when (buffer-live-p (get-buffer buf-name))
+ (let* ((issue (forgejo-db-get-issue host owner repo number))
+ (tl-rows (forgejo-db-get-timeline host owner repo number))
+ (tl-alists (mapcar #'forgejo-db--row-to-timeline-alist tl-rows)))
+ (funcall render-fn buf-name host-url owner repo issue tl-alists)
+ (when restore-line
+ (with-current-buffer buf-name
+ (goto-char (point-min))
+ (forward-line (1- restore-line)))))))
+
;;; Markdown rendering for missing HTML
(defun forgejo-view--render-missing-html (host-url host owner repo number
@@ -138,8 +173,8 @@ restore RESTORE-LINE."
(lambda ()
(cl-decf pending)
(when (<= pending 0)
- (forgejo-buffer--re-render
- buf-name host owner repo number
+ (forgejo-view--re-render
+ buf-name host-url host owner repo number
render-detail-fn restore-line)))))
;; Item body
(when (and item