File: magithub-issue-view.el

package info (click to toggle)
magithub 0.1.7-2
  • links: PTS, VCS
  • area: main
  • in suites: bullseye, sid
  • size: 1,920 kB
  • sloc: lisp: 3,684; makefile: 82
file content (177 lines) | stat: -rw-r--r-- 6,633 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
;;; magithub-issue-view.el --- view issues       -*- lexical-binding: t; -*-

;; Copyright (C) 2017-2018  Sean Allred

;; Author: Sean Allred <code@seanallred.com>
;; Keywords: lisp

;; This program is free software; you can redistribute it and/or modify
;; it under the terms of the GNU General Public License as published by
;; the Free Software Foundation, either version 3 of the License, or
;; (at your option) any later version.

;; This program is distributed in the hope that it will be useful,
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
;; GNU General Public License for more details.

;; You should have received a copy of the GNU General Public License
;; along with this program.  If not, see <http://www.gnu.org/licenses/>.

;;; Commentary:

;; View issues in magit-like buffers.

;;; Code:

(require 'magit-mode)

(require 'magithub-core)
(require 'magithub-issue)
(require 'magithub-comment)

(defvar magithub-issue-view-mode-map
  (let ((m (make-composed-keymap (list magithub-map) magit-mode-map)))
    (define-key m [remap magithub-reply-thing] #'magithub-comment-new)
    (define-key m [remap magithub-browse-thing] #'magithub-issue-browse)
    (define-key m [remap magit-refresh] #'magithub-issue-view-refresh)
    m))

(define-derived-mode magithub-issue-view-mode magit-mode
  "Issue View" "View GitHub issues with Magithub.")

(defvar magithub-issue-view-headers-hook
  '(magithub-issue-view-insert-title
    magithub-issue-view-insert-author
    magithub-issue-view-insert-state
    magithub-issue-view-insert-asked
    magithub-issue-view-insert-labels)
  "Header information for each issue.")

(defvar magithub-issue-view-sections-hook
  '(magithub-issue-view-insert-headers
    magithub-issue-view-insert-body
    magithub-issue-view-insert-comments)
  "Sections to be inserted for each issue.")

(defun magithub-issue-view-refresh ()
  "Refresh the current issue."
  (interactive)
  (if (derived-mode-p 'magithub-issue-view-mode)
      (progn
        ;; todo: find a better means to separate the keymaps of issues
        ;; in the status buffer vs issues in their own buffer
        (when magithub-issue
          (magithub-cache-without-cache :issues
            (setq-local magithub-issue
                        (magithub-issue magithub-repo magithub-issue))
            (magithub-issue-comments magithub-issue)))
        (let ((magit-refresh-args (list magithub-issue)))
          (magit-refresh))
        (message "refreshed"))
    (call-interactively #'magit-refresh)))

(defun magithub-issue-view-refresh-buffer (issue &rest _)
  (setq-local magithub-issue issue)
  (setq-local magithub-repo (magithub-issue-repo issue))
  (magit-insert-section (magithub-issue issue)
    (run-hooks 'magithub-issue-view-sections-hook)))

(defun magithub-issue-view-insert-headers ()
  "Run `magithub-issue-view-headers-hook'."
  (magit-insert-headers magithub-issue-view-headers-hook))

(defun magithub-issue-view--lock-value (issue &rest _args)
  "Provide an identifying value for ISSUE.
See also `magit-buffer-lock-functions'."
  (let-alist `((repo . ,(magithub-issue-repo issue))
               (issue . ,issue))
    (list .repo.owner.login .repo.name .issue.number)))
(push (cons 'magithub-issue-view-mode #'magithub-issue-view--lock-value)
      magit-buffer-lock-functions)

(defun magithub-issue-view--buffer-name (_mode issue-lock-value)
  "Generate a buffer name for ISSUE-LOCK-VALUE.
See also `magithub-issue-view--lock-value'."
  (let ((owner  (nth 0 issue-lock-value))
        (repo   (nth 1 issue-lock-value))
        (number (nth 2 issue-lock-value)))
    (format "*magithub: %s/%s#%d: %s*"
            owner
            repo
            number
            (alist-get 'title (magithub-issue `((owner (login . ,owner))
                                                (name . ,repo))
                                              number)))))

;;;###autoload
(defun magithub-issue-view (issue)
  "View ISSUE in a new buffer.
Return the new buffer."
  (interactive (list (magithub-interactive-issue)))
  (let ((magit-generate-buffer-name-function #'magithub-issue-view--buffer-name))
    (magit-mode-setup-internal #'magithub-issue-view-mode (list issue) t)
    (current-buffer)))

(cl-defun magithub-issue-view-insert--generic (title text &optional type section-value &key face)
  "Insert a generic header line with TITLE: VALUE"
  (declare (indent 2))
  (setq type (or type 'magithub))
  (magit-insert-section ((eval type) section-value)
    (insert (format "%-10s" title)
            (or (and face (propertize text 'face face))
                text)
            ?\n)
    (magit-insert-heading)))

(defun magithub-issue-view-insert-title ()
  "Insert issue title."
  (let-alist magithub-issue
    (magithub-issue-view-insert--generic "Title:" .title)))

(defun magithub-issue-view-insert-author ()
  "Insert issue author."
  (insert (format "%-10s" "Author:"))
  (let-alist magithub-issue
    (magit-insert-section (magithub-user .user)
      (insert (propertize .user.login 'face 'magithub-user) ?\n)
      (magit-insert-heading))))

(defun magithub-issue-view-insert-state ()
  "Insert issue state (either \"open\" or \"closed\")."
  (let-alist magithub-issue
    (magithub-issue-view-insert--generic "State:" .state
      :face 'magit-dimmed)))

(defun magithub-issue-view-insert-asked ()
  "Insert posted time."
  (let-alist magithub-issue
    (magithub-issue-view-insert--generic "Posted:" (magithub--format-time .created_at)
      :face 'magit-dimmed)))

(defun magithub-issue-view-insert-labels ()
  "Insert labels."
  (insert (format "%-10s" "Labels:"))
  (magithub-label-insert-list (alist-get 'labels magithub-issue))
  (insert ?\n))

(defun magithub-issue-view-insert-body ()
  "Insert issue body."
  (let-alist magithub-issue
    (magit-insert-section (magithub-issue-body magithub-issue)
      (magit-insert-heading "Body")
      (if (or (null .body) (string= .body ""))
          (insert (propertize "There's nothing here!\n\n" 'face 'magit-dimmed))
        (insert (magithub-fill-gfm (magithub-wash-gfm (s-trim .body))) "\n\n")))))

(defun magithub-issue-view-insert-comments ()
  "Insert issue comments."
  (let ((comments (magithub-issue-comments magithub-issue)))
    (magit-insert-section (magithub-issue-comments comments)
      (magit-insert-heading "Comments:")
      (if (null comments)
          (insert (propertize "There's nothing here!\n\n" 'face 'magit-dimmed))
        (mapc #'magithub-comment-insert comments)))))

(provide 'magithub-issue-view)
;;; magithub-issue-view.el ends here