branch: elpa/fj
commit 835050814e6ab5bc68763793be86b6a99bdf247a
Merge: 16d4dfc586 789f7daf3b
Author: marty hiatt <[email protected]>
Commit: marty hiatt <[email protected]>
Merge branch 'dev'
---
fj.el | 346 +++++++++++++++++++++++++++++++++-----------------------
readme.org | 5 +-
test/fj-test.el | 32 ++++++
3 files changed, 242 insertions(+), 141 deletions(-)
diff --git a/fj.el b/fj.el
index 98dc16c4f2..89b261f72e 100644
--- a/fj.el
+++ b/fj.el
@@ -6,7 +6,7 @@
;; Package-Requires: ((emacs "29.1") (fedi "0.2") (tp "0.8") (transient
"0.10.0") (magit "4.3.8"))
;; Keywords: git, convenience
;; URL: https://codeberg.org/martianh/fj.el
-;; Version: 0.30
+;; Version: 0.31
;; Separator: -
;; This program is free software; you can redistribute it and/or modify
@@ -609,6 +609,13 @@ If CURRENT-REPO, get from `fj-current-repo' instead."
(user-error "Not in an issue view?")
,@body))
+(defmacro fj-with-item-tl (&rest body)
+ "Execute BODY if we are in an item TL."
+ (declare (debug t))
+ `(if (not (equal major-mode 'fj-issue-tl-mode))
+ (user-error "Not in an item TL?")
+ ,@body))
+
(defmacro fj-with-own-repo (&rest body)
"Execute BODY if a repo owned by `fj-user'."
(declare (debug t))
@@ -675,10 +682,52 @@ If CURRENT-REPO, get from `fj-current-repo' instead."
"Destructure `fj-buffer-spec' with keyword PARAMETERS and call BODY."
(declare (debug t)
(indent 1))
+ ;; FIXME: wrapping this macro breaks edebug:
`(cl-destructuring-bind (&key ,@parameters &allow-other-keys)
fj-buffer-spec
,@body))
+(defmacro fj-with-tl (mode buffer entries wd sort-key &rest body)
+ "Set up a tabulated-list BUFFER and execute BODY.
+Sets `tabulated-list-entries' to ENTRIES, enables MODE, and uses WD as
+the working-directory (for directory-local variables)."
+ (declare (indent 5)
+ (debug t))
+ `(with-current-buffer (get-buffer-create ,buffer)
+ (setq tabulated-list-entries ,entries)
+ (funcall ,mode)
+ ;; ensure our .dir-locals.el settings take effect:
+ ;; via
https://emacs.stackexchange.com/questions/13080/reloading-directory-local-variables
+ (setq default-directory ,wd)
+ (let ((enable-local-variables :all))
+ (hack-dir-local-variables-non-file-buffer))
+ (when ,sort-key
+ (setq tabulated-list-sort-key
+ ,(if (eq :unset sort-key) nil sort-key)))
+ (tabulated-list-init-header)
+ (tabulated-list-print)
+ ,@body
+ ;; other-window maybe?
+ ;; message bindings maybe?
+ ))
+
+
+(defmacro fj-with-buffer (buf mode wd ow &rest body)
+ "Set up a BUF fer in MODE and call BODY.
+Sets up default-directory as WD and ensures local variables take effect
+in non-file buffers.
+OW is other window argument for `fedi-with-buffer'."
+ (declare (indent 4)
+ (debug t))
+ `(fedi-with-buffer ,buf
+ ,mode ,ow
+ ;; ensure our .dir-locals.el settings take effect:
+ ;; via
https://emacs.stackexchange.com/questions/13080/reloading-directory-local-variables
+ (setq default-directory ,wd)
+ (let ((enable-local-variables :all))
+ (hack-dir-local-variables-non-file-buffer))
+ ,@body))
+
;;; MAP
(defvar-keymap fj-generic-map
@@ -917,37 +966,49 @@ X and Y are sorting args."
(defun fj-get-user-repos (user &optional page limit)
"GET request repos owned by USER.
PAGE, LIMIT."
- ;; NB: no order arg avail :/
+ ;; NB: API has no sort/order arg!
(let ((params (append
`(("limit" . ,(or limit (fj-default-limit))))
(fedi-opt-params page)))
(endpoint (format "users/%s/repos" user)))
(fj-get endpoint params)))
-(defun fj-user-repos (&optional user page limit order)
+(defun fj-user-repos (&optional user page limit) ;; order)
"View a tabulated list of respos for USER.
-PAGE, LIMIT, ORDER."
+PAGE, LIMIT."
+ ;; NB: API has no order arg
(interactive "sView user repos: ")
(let* ((repos (fj-get-user-repos user page limit))
(entries (fj-repo-tl-entries repos :no-owner))
- (buf (format "*fj-repos-%s*" user)))
- (fj-repos-tl-render buf entries #'fj-user-repo-tl-mode)
- (with-current-buffer (get-buffer-create buf)
- (setq fj-buffer-spec
- `( :owner ,user :url ,(concat fj-host "/" user)
- :viewargs ( :user ,user :page ,page
- :limit ,limit :order ,order)
- :viewfun fj-user-repos)))))
+ (buf (format "*fj-repos-%s*" user))
+ (prev-buf (buffer-name))
+ (wd default-directory))
+ (fj-with-tl #'fj-user-repo-tl-mode buf entries wd nil
+ (setq fj-buffer-spec
+ `( :owner ,user :url ,(concat fj-host "/" user)
+ :viewargs ( :user ,user :page ,page
+ :limit ,limit) ;; :order ,order)
+ :viewfun fj-user-repos))
+ (fj-other-window-maybe
+ prev-buf "*fj-search" #'string-prefix-p))))
(defun fj-list-own-repos-read ()
"List repos for `fj-user', prompting for an order type."
(interactive)
+ ;; NB: if we respect page here, we fetch from server with a new sort
+ ;; arg, then stay on the same relative page, it is a bit confusing. but
+ ;; it is also confusing to return to page one with a new sort type...
+ ;; maybe it is too confusing to enable, as what it would used in place
+ ;; of is just sorting the current page, which the user can do in the
+ ;; usual TL mode way...
+ ;; (let ((page (plist-get (fj--get-buffer-spec :viewargs) :page)))
(fj-list-own-repos '(4)))
(defun fj-list-own-repos (&optional order page limit)
"List repos for `fj-user'.
With prefix arg ORDER, prompt for an argument to sort
-results (server-side).
+results (server-side). Note that this will reset any
+pagination (i.e. return to page 1).
LIMIT and PAGE are for pagination."
(interactive "P")
(let* ((order (fj-repos-order-arg order))
@@ -957,17 +1018,20 @@ LIMIT and PAGE are for pagination."
(repos (and fj-user (fj-get-repos
limit nil nil page
(or order fj-own-repos-default-order))))
- (entries (fj-repo-tl-entries repos :no-owner)))
+ (entries (fj-repo-tl-entries repos :no-owner))
+ (wd default-directory)
+ (prev-buf (buffer-name)))
(if (not repos)
(user-error "No repos")
- (fj-repos-tl-render buf entries #'fj-user-repo-tl-mode :unset)
- (with-current-buffer (get-buffer-create buf)
+ (fj-with-tl #'fj-user-repo-tl-mode buf entries wd :unset
(setq fj-buffer-spec
`( :owner ,fj-user :url ,(concat fj-host "/" fj-user)
:viewfun fj-list-own-repos
:viewargs (:order ,order :page ,page)))
(message
- (substitute-command-keys "\\`C-c C-c': sort by"))))))
+ (substitute-command-keys "\\`C-c C-c': sort by"))
+ (fj-other-window-maybe
+ prev-buf "*fj-search" #'string-prefix-p)))))
(defun fj-repos-order-arg (&optional order)
"Return an ORDER argument.
@@ -992,16 +1056,18 @@ Order by ORDER, paginate by PAGE and LIMIT."
(fj-get (format "repos/%s/" repo)))
fj-extra-repos))
(repos (append own-repos extra-repos))
- (entries (fj-repo-tl-entries repos)))
+ (entries (fj-repo-tl-entries repos))
+ (wd default-directory)
+ (prev-buf (buffer-name)))
(if (not repos)
(user-error "No (more) repos. \
Unless paginating, set `fj-user' or `fj-extra-repos'")
- (fj-repos-tl-render buf entries #'fj-repo-tl-mode)
- (with-current-buffer (get-buffer-create buf)
+ (fj-with-tl #'fj-repo-tl-mode buf entries wd nil
(setq fj-buffer-spec
`( :owner ,fj-user :url ,(concat fj-host "/" fj-user)
:viewfun fj-list-repos
- :viewargs (:order ,order :page ,page)))))))
+ :viewargs (:order ,order :page ,page)))
+ (fj-other-window-maybe prev-buf "*fj-search" #'string-prefix-p)))))
(defun fj-star-repo* (repo owner &optional unstar)
"Star or UNSTAR REPO owned by OWNER."
@@ -1059,16 +1125,18 @@ BUF-STR is to name the buffer, URL-STR is for the
buffer-spec."
(entries (fj-repo-tl-entries repos))
(buf (format "*fj-%s-repos*" buf-str))
(url (when url-str
- (concat fj-host "/" fj-user url-str))))
- (fj-repos-tl-render buf entries #'fj-repo-tl-mode)
- (with-current-buffer buf
+ (concat fj-host "/" fj-user url-str)))
+ (prev-buf (buffer-name))
+ (wd default-directory))
+ (fj-with-tl #'fj-repo-tl-mode buf entries wd nil
(setq fj-buffer-spec
`( :owner fj-user
:url ,url
:viewfun fj--list-user-repos
:viewargs ( :endpoint ,endpoint
:buf-str ,buf-str
- :url ,url))))))
+ :url ,url)))
+ (fj-other-window-maybe prev-buf "*fj-search" #'string-prefix-p))))
;;; USER REPOS
@@ -1376,7 +1444,7 @@ all for `fj-issues-search'."
nil page))
(buf-name (format "*fj-search-%s%s*" (or type "items")
(fj-cycle-str created assigned mentioned owner)))
- (prev-buf (buffer-name (current-buffer)))
+ (prev-buf (buffer-name))
(prev-mode major-mode))
;; FIXME refactor with `fj-list-issues'? just tab list entries fun and
;; the buffer spec settings change
@@ -2059,7 +2127,9 @@ Optionally specify REPO and OWNER."
"L" #'fj-repo-commit-log
"j" #'imenu
"l" #'fj-item-label-add
- "U" #'fj-copy-pr-url)
+ ;; TODO: conflicts with fj-user-settings-transient:
+ ;; "U" #'fj-copy-pr-url
+ )
(define-derived-mode fj-issue-tl-mode tabulated-list-mode
"fj-issues"
@@ -2098,7 +2168,7 @@ Optionally specify REPO and OWNER."
(hl-line-mode 1)
(setq tabulated-list-padding 0 ;2) ; point directly on issue
;; this is changed by `tabulated-list-sort' which sorts by col at
point:
- tabulated-list-sort-key '("Updated" . t) ;; default
+ ;; tabulated-list-sort-key '("Updated" . t) ;; default
tabulated-list-format
'[("#" 5 fj-tl-sort-by-issues :right-align)
("💬" 3 fj-tl-sort-by-comment-count :right-align)
@@ -2291,7 +2361,7 @@ git config."
;; fall back to `fj--repo-owner' repos:
(fj-list-issues-do repo owner state type)
;; if in fj buffer, respect its buf-spec:
- (if (string-prefix-p "*fj-" (buffer-name (current-buffer)))
+ (if (string-prefix-p "*fj-" (buffer-name))
(let* ((repo (fj-read-user-repo repo))
(owner (or owner (fj--repo-owner))))
(fj-list-issues-do repo owner state type))
@@ -2308,18 +2378,20 @@ git config."
"List issues in REPO by OWNER, filtering by milestone.
STATE, TYPE, QUERY, and LABELS are for `fj-list-issues-do'."
(interactive)
- (let* ((milestones (fj-get-milestones repo owner))
- (alist (fj-milestones-alist milestones))
- (milestone (completing-read "Milestone: " alist)))
- (fj-list-issues-do repo owner state type query labels milestone)))
+ (fj-with-item-tl
+ (let* ((milestones (fj-get-milestones repo owner))
+ (alist (fj-milestones-alist milestones))
+ (milestone (completing-read "Milestone: " alist)))
+ (fj-list-issues-do repo owner state type query labels milestone))))
(defun fj-list-issues-by-label (&optional repo owner state type query)
"List issues in REPO by OWNER, filtering by label.
STATE, TYPE and QUERY are for `fj-list-issues-do'."
(interactive)
- ;; FIXME: labels list is CSV, so we should do that here and send on:
- (let* ((label (fj-issue-read-label)))
- (fj-list-issues-do repo owner state type query label)))
+ (fj-with-item-tl
+ ;; FIXME: labels list is CSV, so we should do that here and send on:
+ (let* ((label (fj-issue-read-label)))
+ (fj-list-issues-do repo owner state type query label))))
(defvar fj-repo-data nil) ;; for transients for now
@@ -2353,12 +2425,7 @@ SORT defaults to `fj-issues-sort-default'."
(buf-name (format "*fj-%s-%s-%s*" repo state-str type)))
(if (not has-issues)
(user-error "Repo does not have %s" type)
- (with-current-buffer (get-buffer-create buf-name)
- (setq tabulated-list-entries
- (fj-issue-tl-entries issues))
- (fj-issue-tl-mode)
- (tabulated-list-init-header)
- (tabulated-list-print)
+ (fj-with-tl #'fj-issue-tl-mode buf-name (fj-issue-tl-entries issues) wd
nil
(setq fj-current-repo repo
fj-repo-data repo-data
fj-buffer-spec
@@ -2373,16 +2440,12 @@ SORT defaults to `fj-issues-sort-default'."
:page ,page :limit ,limit)
:viewfun fj-list-issues-do
:url ,url))
- ;; ensure our .dir-locals.el settings take effect:
- ;; via
https://emacs.stackexchange.com/questions/13080/reloading-directory-local-variables
- (setq default-directory wd)
- (let ((enable-local-variables :all))
- (hack-dir-local-variables-non-file-buffer))
(fj-other-window-maybe
prev-buf "-issues*" #'string-suffix-p prev-mode)
- (message (substitute-command-keys
- ;; it can't find our bindings:
- "\\`C-c C-c': cycle state | \\`C-c C-d': sort\
+ (message
+ (substitute-command-keys
+ ;; it can't find our bindings:
+ "\\`C-c C-c': cycle state | \\`C-c C-d': sort\
| \\`C-c C-s': cycle type"))))))
(defun fj-repo-has-items-p (type data)
@@ -2923,15 +2986,14 @@ PAGE and LIMIT are for `fj-issue-get-timeline'."
(page (or page "1"))
(limit (or limit (fj-timeline-default-items)))
;; mode check for other-window arg:
- (ow (not (eq major-mode 'fj-item-view-mode)))
+ ;; (ow (not (eq major-mode 'fj-item-view-mode)))
(repo (fj-read-user-repo repo))
(item (fj-get-item repo owner number type))
- (number (or number (alist-get 'number item))))
+ (number (or number (alist-get 'number item)))
+ (wd default-directory))
;; (timeline (fj-issue-get-timeline repo owner number page limit)))
- (fedi-with-buffer (format "*fj-%s-item-%s*" repo number)
- 'fj-item-view-mode ow
- (let ((enable-local-variables :all))
- (hack-dir-local-variables-non-file-buffer))
+ (fj-with-buffer (format "*fj-%s-item-%s*" repo number)
+ 'fj-item-view-mode wd nil ;; other-window
;; render actual (top) item:
(fj-render-item repo owner item number type page limit)
;; if we have paginated, re-append all pages sequentially:
@@ -3639,7 +3701,7 @@ PAGE LIMIT"
(let* ((params
(append
`(("limit" . ,(or limit (fj-default-limit)))
- ("sort" . ,(or sort "updated")))
+ ("sort" . ,sort))
;; (when id `(("exclusive" . "true")))
(fedi-opt-params (query :alias "q") (topic :boolean "true")
(id :alias "uid")
@@ -3663,7 +3725,8 @@ Returns annotation for CAND, a candidate."
(defvar-keymap fj-repo-tl-mode-map
:doc "Map for `fj-repo-tl-mode', a tabluated list of repos."
- :parent fj-repo-tl-map)
+ :parent fj-repo-tl-map
+ "C-c C-c" #'fj-list-repos-sort)
(define-derived-mode fj-repo-tl-mode tabulated-list-mode
"fj-repo-search"
@@ -3671,7 +3734,7 @@ Returns annotation for CAND, a candidate."
:group 'fj
(hl-line-mode 1)
(setq tabulated-list-padding 0 ;2) ; point directly on issue
- tabulated-list-sort-key '("Updated" . t) ;; default
+ ;; tabulated-list-sort-key '("Updated" . t) ;; default
tabulated-list-format
'[("Name" 12 t)
("Owner" 12 t)
@@ -3742,7 +3805,7 @@ NO-OWNER means don't display owner column (user repos
view)."
face default
item repo)
(,(string-replace "
\n" " " .description)
- face 'fj-comment-face
+ face fj-comment-face
item repo)])))))
(defun fj-repo-search (query &optional topic id mode exclusive
@@ -3760,56 +3823,55 @@ ORDER is the sort order, either \"asc\" or \"desc\"; it
requires SORT to be set.
PAGE is the page number of results.
LIMIT is the amount of result (to a page)."
(interactive "sSearch for repos: ")
- (let* ((resp (fj-repo-search-do query topic id mode exclusive
- (or include-desc :desc)
- priority-owner-id
- sort order page limit))
+ (let* ((resp (fj-repo-search-do
+ query topic id mode exclusive
+ ;; include description by default:
+ (or include-desc :desc)
+ priority-owner-id
+ ;; provide better default than the API.
+ ;; default is alphabetic, which
+ ;; indicates very little for repos
+ ;; results:
+ (or sort "updated")
+ ;; provide better default than the API.
+ ;; if we sort alphabetic but don't to
+ ;; desc it is reverse alphabetic, or for
+ ;; stars it starts with least stars:
+ (or order "desc")
+ page limit))
(buf (format "*fj-search-%s*" query))
(url (concat fj-host "/explore/repos"))
(data (alist-get 'data resp))
- (entries (fj-repo-tl-entries data)))
- (fj-repos-tl-render buf entries #'fj-repo-tl-mode)
- (with-current-buffer (get-buffer-create buf)
+ (entries (fj-repo-tl-entries data))
+ (prev-buf (buffer-name))
+ (wd default-directory))
+ (fj-with-tl #'fj-repo-tl-mode buf entries wd nil
(setq fj-buffer-spec
`( :url ,url
:viewargs
( :query ,query :topic ,topic :id ,id :mode ,mode
- :exclusive ,exclusive :include-desc ,include-desc
- :priority-owner-id ,priority-owner-id :sort ,sort
- :order ,order :page ,page :limit ,limit)
- :viewfun fj-repo-search)))))
+ :exclusive ,exclusive
+ :include-desc ,(or include-desc :desc)
+ :priority-owner-id ,priority-owner-id
+ :sort ,(or sort "updated")
+ :order ,(or order "desc") ;; else the default is backwards
+ :page ,page :limit ,limit)
+ :viewfun fj-repo-search))
+ (fj-other-window-maybe prev-buf "*fj-search" #'string-prefix-p))))
(defun fj-repo-search-topic (query)
"Search repo topics for QUERY, and display a tabulated list."
(interactive "sSearch for topic in repos: ")
(fj-repo-search query 'topic))
-(defun fj-repos-tl-render (buf entries mode &optional sort-key)
- "Render a tabulated list in BUF fer, with ENTRIES, in MODE.
-Optionally specify repo OWNER and URL.
-Set `tabulated-list-sort-key' to SORT-KEY. It may optionally be :unset to
-unset any default values."
- (let ((prev-buf (buffer-name (current-buffer))))
- (with-current-buffer (get-buffer-create buf)
- (setq tabulated-list-entries entries)
- (funcall mode)
- ;; some modes set a sort-key, but we also may want to selectively
- ;; unset it. but if we don't have sort-key, we also don't want to
- ;; nil the mode setting:
- (when sort-key
- (if (eq :unset sort-key)
- (setq tabulated-list-sort-key nil)
- (setq tabulated-list-sort-key sort-key)))
- (tabulated-list-init-header)
- (tabulated-list-print)
- (fj-other-window-maybe prev-buf "*fj-search" #'string-prefix-p))))
-
-;; (cond ((or (string= buf prev-buf) ;; reloading
-;; (string-prefix-p "*fj-search" buf)) ;; any search
-;; ;; (string-suffix-p "-issues*" prev-buf) ; diff repo
-;; (switch-to-buffer (current-buffer)))
-;; (t ;; new buf
-;; (switch-to-buffer-other-window (current-buffer)))))))
+(defun fj-list-repos-sort ()
+ "Reload current repos listing, prompting for a sort type.
+The default sort value is \"latest\"."
+ (interactive)
+ (fj-destructure-buf-spec (viewfun viewargs)
+ (let* ((sort (completing-read "Sort by: " fj-search-sorts))
+ (args (plist-put (copy-sequence viewargs) :sort sort)))
+ (apply viewfun (fj-plist-values args)))))
;;; TL ACTIONS
@@ -3932,32 +3994,33 @@ Or if viewing a repo's issues, use its clone_url."
(defun fj-copy-pr-url ()
"Copy upstream Pull Request URL with branch name."
(interactive)
- (fj-destructure-buf-spec (owner repo item author)
- (let* ((number (if (eq major-mode 'fj-issue-tl-mode)
- (fj--get-tl-col 0)
- item))
- (author (if (eq major-mode 'fj-issue-tl-mode)
- (fj--get-tl-col 2)
- author))
- (endpoint (format "repos/%s/%s/pulls/%s" owner repo number))
- (pr (fj-get endpoint))
- (data (alist-get 'head pr))
- (branch (alist-get 'ref data))
- (author+repo (alist-get 'full_name
- (alist-get 'repo data)))
- ;; this format, $host/$author/$repo/src/branch/$branch, is what
- ;; a PR in the webUI links to:
- (str (concat fj-host "/" author+repo
- "/src/branch/" branch)))
- ;; old/strange format, in case we ever remember why this was used:
- ;; " "
- ;; (format "%s:pr-%s-%s-%s"
- ;; branch
- ;; number
- ;; author
- ;; branch))))
- (kill-new str)
- (message "Copied: %s" str))))
+ (fj-with-pull
+ (fj-destructure-buf-spec (owner repo item _author)
+ (let* ((number (if (eq major-mode 'fj-issue-tl-mode)
+ (fj--get-tl-col 0)
+ item))
+ ;; (author (if (eq major-mode 'fj-issue-tl-mode)
+ ;; (fj--get-tl-col 2)
+ ;; author))
+ (endpoint (format "repos/%s/%s/pulls/%s" owner repo number))
+ (pr (fj-get endpoint))
+ (data (alist-get 'head pr))
+ (branch (alist-get 'ref data))
+ (author+repo (alist-get 'full_name
+ (alist-get 'repo data)))
+ ;; this format, $host/$author/$repo/src/branch/$branch, is what
+ ;; a PR in the webUI links to:
+ (str (concat fj-host "/" author+repo
+ "/src/branch/" branch)))
+ ;; old/strange format, in case we ever remember why this was used:
+ ;; " "
+ ;; (format "%s:pr-%s-%s-%s"
+ ;; branch
+ ;; number
+ ;; author
+ ;; branch))))
+ (kill-new str)
+ (message "Copied: %s" str)))))
(defun fj-fork-to-parent ()
"From a repo TL listing, jump to the parent repo."
@@ -4637,8 +4700,9 @@ PAGE and LIMIT are for pagination."
(concat "-" subject-type "s")
"")))
(data (fj-get-notifications all status-types
- subject-type page limit)))
- (fedi-with-buffer buf 'fj-notifications-mode nil
+ subject-type page limit))
+ (wd default-directory))
+ (fj-with-buffer buf 'fj-notifications-mode wd nil
(if (not data)
(insert
(format "No notifications of type: %s %s" all-type
@@ -4649,11 +4713,10 @@ PAGE and LIMIT are for pagination."
( :all ,all :status-types ,status-types
:subject-type ,subject-type
:page ,page :limit ,limit))))
- ;; FIXME: make this an option in `fedi-with-buffer'?
- ;; else it just goes to point-min:
- (fj-next-tab-item)
- (message (substitute-command-keys
- "\\`C-c C-c': cycle state | \\`C-c C-s': cycle type"))))
+ (with-current-buffer buf
+ (fj-next-tab-item)
+ (message (substitute-command-keys
+ "\\`C-c C-c': cycle state | \\`C-c C-s': cycle type")))))
(defun fj-view-notifications-all (&optional status-types subject-type
page limit)
@@ -4946,8 +5009,9 @@ If PREFIX arg, prompt for branch to show commits of."
(fj-repo-branches-list repo owner))))
(data (fj-get-repo-commits repo owner branch))
(buf (format "*fj-%s-commit-log%s*" repo
- (if branch (format "-branch-%s" branch) ""))))
- (fedi-with-buffer buf 'fj-commits-mode nil
+ (if branch (format "-branch-%s" branch) "")))
+ (wd default-directory))
+ (fj-with-buffer buf 'fj-commits-mode wd nil
;; FIXME: use `fj-other-window-maybe'
(setq-local header-line-format (format "Commits in branch: %s"
(or branch "default")))
@@ -5063,8 +5127,9 @@ BUF-STR is the name of the buffer string to use."
(data (funcall fetch-fun repo owner page limit))
(endpoint (if (eq fetch-fun #'fj-get-stargazers)
"stars"
- "watchers")))
- (fedi-with-buffer buf 'fj-users-mode nil
+ "watchers"))
+ (wd default-directory))
+ (fj-with-buffer buf 'fj-users-mode wd nil
(fj-render-users data)
(when repo (setq fj-current-repo repo))
(setq fj-buffer-spec
@@ -5127,8 +5192,9 @@ Fetch users by calling FETCH-FUN with no args.
BUF-STR is the name of the `buffer-string' to use."
(let* ((user (or user fj-user))
(buf (format "*fj-%s" buf-str))
- (data (funcall fetch-fun)))
- (fedi-with-buffer buf 'fj-users-mode nil
+ (data (funcall fetch-fun))
+ (wd default-directory))
+ (fj-with-buffer buf 'fj-users-mode wd nil
(fj-render-users data)
;; (when repo (setq fj-current-repo repo))
(setq fj-buffer-spec
@@ -5178,7 +5244,7 @@ PAGE and LIMIT are for pagination."
(propertize
(fj-propertize-link .login 'handle .login)
'fj-url .html_url
- 'fj-item-data .login_name
+ 'fj-item-data user
'fj-byline t)) ; for nav
;; timestamp:
(insert
@@ -5187,13 +5253,15 @@ PAGE and LIMIT are for pagination."
(insert
"\n"
;; website:
- (unless (string-empty-p .website)
+ (if (string-empty-p .website)
+ .website
(concat (fj-propertize-link .website 'shr nil
'fj-simple-link-face)
"\n"))
;; description:
;; TODO: render links here:
- (unless (string-empty-p .description)
+ (if (string-empty-p .description)
+ .description
(concat (string-clean-whitespace .description) "\n")))
(insert "\n" fedi-horiz-bar fedi-horiz-bar "\n\n"))))
diff --git a/readme.org b/readme.org
index f0ae3daf8e..73645bccce 100644
--- a/readme.org
+++ b/readme.org
@@ -41,7 +41,7 @@ If you run into any auth issues, feel free to open an issue
or contact me.
** basic views
-Once you are authenticated, try =fj-list-own-repos= to view your repos, or
=fj-list-issues= to view issues of the current repo, or with completing-read of
a repo is no repo is found.
+Once you are authenticated, try =fj-list-own-repos= to view your repos, or
=fj-list-issues= to view issues of the current repo, or with completing-read of
a repo if no repo is found.
If you are already viewing a repo and want to force the prompt to choose
another, call =fj-list-issues= with a prefix arg (=C-u=).
@@ -276,7 +276,7 @@ Diffs (as commits and PRs):
| C-c S-RET | fj-compose-remove-milestone | Remove milestone from item
being composed. |
| C-c C-c | fj-compose-send | Submit the issue or comment to
your Forgejo instance. |
| C | fj-copy-item-url | Copy URL of current item,
either issue or PR. |
-| U | fj-copy-pr-url | Copy upstream Pull Request URL
with branch name. |
+| | fj-copy-pr-url | Copy upstream Pull Request URL
with branch name. |
| c | fj-create-issue | Create issue in current repo or
repo at point in tabulated listing. |
| | fj-create-milestone | Create a milestone for REPO by
OWNER. |
| | fj-create-token | Create an access token for
`fj-user' on `fj-host'. |
@@ -326,6 +326,7 @@ Diffs (as commits and PRs):
| C-c C-c | fj-list-own-repos-read | List repos for `fj-user',
prompting for an order type. |
| P | fj-list-pulls | List pulls for REPO by OWNER,
filtered by STATE. |
| | fj-list-repos | List repos for `fj-user'
extended by `fj-extra-repos'. |
+| C-c C-c | fj-list-repos-sort | Reload current repos listing,
prompting for a sort type. |
| | fj-list-user-repos | View repos of current entry
user from tabulated repos listing. |
| | fj-mark-notification-read | Mark notification at point as
read. |
| | fj-mark-notification-unread | Mark notification at point as
unread. |
diff --git a/test/fj-test.el b/test/fj-test.el
index f33dec3440..9085246ec7 100644
--- a/test/fj-test.el
+++ b/test/fj-test.el
@@ -25,6 +25,8 @@
;; TODO: test the arity of buffer-spec viewfun matches length of viewargs
;; for all views.
+(require 'ert)
+(require 'el-mock)
(require 'exemplify-ert)
(require 'exemplify-eval)
(require 'fj)
@@ -1747,4 +1749,34 @@ the webUI only completes names in the issue.")
(fj-string-number> "12" "34") => nil
(fj-string-number> "12" "12" #'>=) => t)
+(ert-deftest fj-test-issues-tl-buffer-spec ()
+ "Test that the `fj-buffer-spec' is set up as expected.
+Mock test of `fj-list-issues-do'."
+ ;; TODO: unfortunately we can't cycle and test again, because doing so
+ ;; will also use our mock results, with state set to "open".
+ (let* ((fj-host "https://codeberg.org")
+ (fj-user "martianh")
+ (repo "fj.el")
+ (type "issues")
+ (state "open")
+ (buf (format "*fj-%s-%s-%s*" repo state type)))
+ (with-mock
+ (mock (fj-repo-get-issues repo fj-user
+ state type nil nil nil nil nil nil)
+ => fj-test-issues)
+ (mock (fj-get-repo repo fj-user) => (car fj-test-repos))
+ (fj-list-issues-do repo fj-user state type)
+ (with-current-buffer buf
+ (should
+ (equal
+ fj-buffer-spec
+ '( :repo "fj.el" :owner "martianh"
+ :viewargs
+ ( :repo "fj.el" :owner "martianh" :state "open"
+ :type "issues" :query nil :labels nil :milestones nil
+ :page nil :limit nil)
+ :viewfun fj-list-issues-do
+ :url "https://codeberg.org/martianh/fj.el/issues"))))
+ (kill-buffer buf))))
+
;; TODO: tests for timeline items