-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathgitlab.el
143 lines (105 loc) · 4.82 KB
/
gitlab.el
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
;;; gitlab.el --- A helm based interface to gitlab -*- lexical-binding: t; -*-
;; Copyright (C) 2016 David Vazquez Pua
;; Author: David Vazquez Pua <davazp@gmail.com>
;; Keywords: tools
;; 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:
;;
;;; Code:
(require 'eieio)
(require 'request)
(defvar gitlab-token)
(defvar gitlab-projects)
(defvar gitlab-clone-default-directory)
;;;; Cache
(defvar gitlab-cache-file
"~/.emacs.d/gitlab.eieio")
(defclass gitlab-cache (eieio-persistent)
((projects
:initarg :projects
:accessor gitlab-cache-projects)))
(defun gitlab-read-cache ()
(ignore-errors
(let ((cache (eieio-persistent-read gitlab-cache-file 'gitlab-cache)))
(setq gitlab-projects (gitlab-cache-projects cache)))))
(gitlab-read-cache)
(defun gitlab-refresh-projects ()
(interactive)
(request "http://git.ctrl/api/v3/projects"
:params `(("per_page" . "100")
("private_token" . ,gitlab-token))
:parser (lambda ()
(let ((json-array-type 'list))
(json-read)))
:success (cl-function
(lambda (&key data &allow-other-keys)
(setq gitlab-projects data)
(eieio-persistent-save
(make-instance 'gitlab-cache
:file gitlab-cache-file
:projects gitlab-projects))
(message "List of gitlab projects updated.")))))
(defun gitlab-browse (project &optional relative-path)
(let ((url (assoc-default 'web_url project)))
(browse-url (concat url (or relative-path "")))))
(defun gitlab-clone (project)
(let* ((url (assoc-default 'ssh_url_to_repo project))
(directory (read-directory-name
"Clone to: " gitlab-clone-default-directory nil nil
(and (string-match "\\([^./]+\\)\\(\\.git\\)?$" url)
(match-string 1 url)))))
(magit-clone url directory)))
;;; Helm integration
(defface helm-gitlab-namespace-face
'((t :foreground "grey50"))
"Face to display the namespace of a project.")
(defface helm-gitlab-project-face
'((t :weight extra-bold))
"Face to display the project.")
(defvar helm-gitlab-project-source
(helm-build-sync-source "Gitlab Projects"
:action `(("Visit" . (lambda (c) (gitlab-browse c)))
("Files" . (lambda (c) (gitlab-browse c "/tree/master")))
("Issues" . (lambda (c) (gitlab-browse c "/issues")))
("Merge Requests" . (lambda (c) (gitlab-browse c "/merge_requests")))
("Clone" . (lambda (c) (gitlab-clone c))))
:candidates (lambda ()
(sort (mapcar (lambda (project)
(let* ((id (assoc-default 'id project))
(ns (assoc-default 'namespace project))
(namespace (assoc-default 'name ns))
(name (assoc-default 'name project))
(path (assoc-default 'path project)))
(cons (format "%15s / %-50s %s"
(propertize namespace 'face 'helm-gitlab-namespace-face)
(propertize name 'face 'helm-gitlab-project-face)
(if (string-equal (upcase path) (upcase name))
""
path))
project)))
gitlab-projects)
(lambda (c1 c2)
(string-lessp (car c1) (car c2)))))))
(defvar helm-gitlab-map
(let ((map (make-sparse-keymap)))
(set-keymap-parent map helm-map)
(define-key map (kbd "C-r") 'gitlab-refresh-projects)
map))
(defun helm-gitlab ()
(interactive)
(unless gitlab-projects
(gitlab-refresh-projects))
(helm :buffer "*helm gitlab*"
:keymap helm-gitlab-map
:sources '(helm-gitlab-project-source)))
(provide 'gitlab)
;;; gitlab.el ends here