branch: elpa/fj
commit 1db871d8189c7a4a4dae0b60ab3099fc679d7261
Author: marty hiatt <[email protected]>
Commit: marty hiatt <[email protected]>

    buffer macros that handle dir local vars, tabulated list setup. #185.
---
 fj.el | 182 ++++++++++++++++++++++++++++++++++++------------------------------
 1 file changed, 100 insertions(+), 82 deletions(-)

diff --git a/fj.el b/fj.el
index 456ff49fd5..2e72383ed8 100644
--- a/fj.el
+++ b/fj.el
@@ -675,10 +675,50 @@ 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 &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 4)
+           (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))
+     ;; 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,7 +957,7 @@ 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 arg!
   (let ((params (append
                  `(("limit" . ,(or limit (fj-default-limit))))
                  (fedi-opt-params page)))
@@ -930,14 +970,17 @@ PAGE, LIMIT, ORDER."
   (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)
+         (buf (format "*fj-repos-%s*" user))
+         (prev-buf (buffer-name))
+         (wd default-directory))
+    (fj-with-tl #'fj-user-repo-tl-mode buf entries wd
       (setq fj-buffer-spec
             `( :owner ,user :url ,(concat fj-host "/" user)
                :viewargs ( :user ,user :page ,page
                            :limit ,limit :order ,order)
-               :viewfun fj-user-repos)))))
+               :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."
@@ -957,17 +1000,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
         (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 +1038,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
         (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 +1107,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
       (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 +1426,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
@@ -2291,7 +2341,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))
@@ -2353,12 +2403,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
         (setq fj-current-repo repo
               fj-repo-data repo-data
               fj-buffer-spec
@@ -2373,16 +2418,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)
@@ -2926,12 +2967,11 @@ PAGE and LIMIT are for `fj-issue-get-timeline'."
          (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:
@@ -3767,9 +3807,10 @@ LIMIT is the amount of result (to a page)."
          (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
       (setq fj-buffer-spec
             `( :url ,url
                :viewargs
@@ -3777,40 +3818,14 @@ LIMIT is the amount of result (to a page)."
                  :exclusive ,exclusive :include-desc ,include-desc
                  :priority-owner-id ,priority-owner-id :sort ,sort
                  :order ,order :page ,page :limit ,limit)
-               :viewfun fj-repo-search)))))
+               :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)))))))
-
 ;;; TL ACTIONS
 
 (defun fj-create-issue (&optional _)
@@ -4637,8 +4652,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 +4665,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 +4961,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 +5079,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 +5144,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

Reply via email to