3
(require 'magithub-issue)
4
(require 'magithub-label)
6
(defun magithub-issue-refresh (even-if-offline)
7
"Refresh issues for this repository.
8
If EVEN-IF-OFFLINE is non-nil, we'll still refresh (that is,
9
we'll hit the API) if Magithub is offline."
11
(let ((magithub-cache (if even-if-offline nil magithub-cache)))
12
(magithub-cache-without-cache :issues
13
(ignore (magithub--issue-list))))
14
(when (derived-mode-p 'magit-status-mode)
17
(defvar magit-magithub-issue-section-map
18
(let ((map (make-sparse-keymap)))
19
(define-key map [remap magit-visit-thing] #'magithub-issue-browse)
20
(define-key map [remap magit-refresh] #'magithub-issue-refresh)
21
(define-key map "L" #'magithub-issue-add-labels)
23
"Keymap for `magithub-issue' sections.")
25
(defvar magit-magithub-issue-list-section-map
26
(let ((map (make-sparse-keymap)))
27
(define-key map [remap magit-visit-thing] #'magithub-issue-browse)
28
(define-key map [remap magit-refresh] #'magithub-issue-refresh)
30
"Keymap for `magithub-issue-list' sections.")
32
(defvar magit-magithub-pull-request-section-map
33
(let ((map (make-sparse-keymap)))
34
(define-key map [remap magit-visit-thing] #'magithub-pull-browse)
35
(define-key map [remap magit-refresh] #'magithub-issue-refresh)
36
(define-key map "L" #'magithub-issue-add-labels)
38
"Keymap for `magithub-pull-request' sections.")
40
(defvar magit-magithub-pull-request-list-section-map
41
(let ((map (make-sparse-keymap)))
42
(define-key map [remap magit-visit-thing] #'magithub-pull-browse)
43
(define-key map [remap magit-refresh] #'magithub-issue-refresh)
45
"Keymap for `magithub-pull-request-list' sections.")
47
(defun magithub-issue-add-labels (issue labels)
48
"Update ISSUE's labels to LABELS."
50
(when (magithub-verify-manage-labels t)
51
(let* ((fmt (lambda (l) (alist-get 'name l)))
52
(issue (or (magithub-thing-at-point 'issue)
53
(magithub-thing-at-point 'pull-request)))
54
(current-labels (alist-get 'labels issue))
55
(to-remove (magithub--completing-read-multiple
56
"Remove labels: " current-labels fmt)))
57
(setq current-labels (cl-set-difference current-labels to-remove))
58
(list issue (magithub--completing-read-multiple
59
"Add labels: " (magithub-label-list) fmt
60
nil nil current-labels)))))
61
(setcdr (assq 'labels issue) labels)
62
(ghubp-patch-repos-owner-repo-issues-number
63
(magithub-source-repo) issue `((labels . ,labels)))
64
(when (derived-mode-p 'magit-status-mode)
67
(defun magithub-issue--label-string (issue)
69
(mapconcat #'magithub-label-propertize .labels " ")))
71
(defun magithub-issue--format (issue justify type)
72
(magithub--object-propertize type issue
74
(let* ((fc fill-column)
76
(format " %%%ds %%%ds "
77
(alist-get 'number justify)
78
(+ 2 (alist-get 'comments justify))))
81
(number-to-string .number)
82
(if (= .comments 0) ""
83
(format "(%d)" .comments))))
85
(issue-title-width (- fc (length issue-prefix)))
86
(indent (make-string (length issue-prefix) ?\ )))
89
(insert issue-prefix (s-word-wrap issue-title-width .title)))
99
(insert (magithub-issue--label-string issue)))
100
(concat (s-trim-right (buffer-string)) "\n"))))))
102
(defun magithub-issue--insert (issue justify is-pr)
103
"Insert ISSUE as a Magit section into the buffer."
105
(let ((issue-string (magithub-issue--format issue justify (if is-pr 'pull-request 'issue))))
106
(if is-pr (magit-insert-section (magithub-pull-request issue)
107
(insert issue-string))
108
(magit-insert-section (magithub-issue issue)
109
(insert issue-string))))))
111
(defun magithub-issue--format-justify ()
112
(let* ((issue-list (magithub--issue-list))
113
(fn1 (lambda (p i) (length (format "%d" (alist-get p i)))))
114
(fn2 (lambda (p) (apply #'max (mapcar (apply-partially fn1 p) issue-list)))))
115
`((number . ,(funcall fn2 'number))
116
(comments . ,(funcall fn2 'comments)))))
118
(defun magithub-issue--insert-issue-section ()
119
"Insert GitHub issues if appropriate."
120
(when (magithub-usable-p)
121
(when-let ((issues (magithub-issues)))
122
(let ((justify (magithub-issue--format-justify)))
123
(magit-insert-section (magithub-issue-list)
124
(magit-insert-heading "Issues:")
125
(mapc (lambda (i) (magithub-issue--insert i justify nil))
129
(defun magithub-issue--insert-pr-section ()
130
"Insert GitHub pull requests if appropriate."
131
(magithub-feature-maybe-idle-notify
133
'pull-request-checkout)
134
(when (magithub-usable-p)
135
(when-let ((pull-requests (magithub-pull-requests)))
136
(let ((justify (magithub-issue--format-justify)))
137
(magit-insert-section (magithub-pull-request-list)
138
(magit-insert-heading "Pull Requests:")
139
(mapc (lambda (i) (magithub-issue--insert i justify t))
143
(defun magithub-issue-browse (issue)
144
"Visits ISSUE in the browser.
145
Interactively, this finds the issue at point."
146
(interactive (list (or (magithub-thing-at-point 'issue)
147
(magithub-issue-completing-read-issues))))
148
(magithub-issue--browse issue))
150
(defun magithub-pull-browse (pr)
151
"Visits PR in the browser.
152
Interactively, this finds the pull request at point."
153
(interactive (list (or (magithub-thing-at-point 'pull-request)
154
(magithub-issue-completing-read-pull-requests))))
155
(magithub-issue--browse pr))
157
(defun magithub-issue--browse (issue-or-pr)
158
"Visits ISSUE-OR-PR in the browser.
159
Interactively, this finds the issue at point."
160
(when-let ((url (alist-get 'html_url issue-or-pr)))
163
(defun magithub-repolist-column-issue (_id)
164
"Insert the number of open issues in this repository."
165
(number-to-string (length (magithub-issues))))
167
(defun magithub-repolist-column-pull-request (_id)
168
"Insert the number of open pull requests in this repository."
169
(number-to-string (length (magithub-pull-requests))))
171
(magithub--deftoggle magithub-toggle-issues
172
magit-status-sections-hook #'magithub-issue--insert-issue-section "issues")
173
(magithub--deftoggle magithub-toggle-pull-requests
174
magit-status-sections-hook #'magithub-issue--insert-pr-section "pull requests")
176
(magithub-toggle-pull-requests)
177
(magithub-toggle-issues)
179
(provide 'magithub-issue-status)