mirror of https://github.com/Chizi123/.emacs.d.git

Chizi123
2018-11-18 8f6f2705a38e2515b6c57fda12c5be29fb9a798f
commit | author | age
5cb5f7 1 ;;; magit-imenu.el --- Integrate Imenu in magit major modes  -*- lexical-binding: t -*-
C 2
3 ;; Copyright (C) 2010-2018  The Magit Project Contributors
4 ;;
5 ;; You should have received a copy of the AUTHORS.md file which
6 ;; lists all contributors.  If not, see http://magit.vc/authors.
7
8 ;; Author: Damien Cassou <damien@cassou.me>
9 ;; Maintainer: Jonas Bernoulli <jonas@bernoul.li>
10
11 ;; Magit is free software; you can redistribute it and/or modify it
12 ;; under the terms of the GNU General Public License as published by
13 ;; the Free Software Foundation; either version 3, or (at your option)
14 ;; any later version.
15 ;;
16 ;; Magit is distributed in the hope that it will be useful, but WITHOUT
17 ;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
18 ;; or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
19 ;; License for more details.
20 ;;
21 ;; You should have received a copy of the GNU General Public License
22 ;; along with Magit.  If not, see http://www.gnu.org/licenses.
23
24 ;;; Commentary:
25
26 ;; Emacs' major modes can facilitate navigation in their buffers by
27 ;; supporting Imenu.  In such major modes, launching Imenu (M-x imenu)
28 ;; makes Emacs display a list of items (e.g., function definitions in
29 ;; a programming major mode).  Selecting an item from this list moves
30 ;; point to this item.
31
32 ;; magit-imenu.el adds Imenu support to every major mode in Magit
33
34 ;;; Code:
35
36 (eval-when-compile
37   (require 'subr-x))
38
39 (require 'magit)
40 (require 'git-rebase)
41
42 (defun magit-imenu--index-function (entry-types menu-types)
43   "Return an alist of imenu entries in current buffer.
44
45 ENTRY-TYPES is a list of section types to be selected through
46 `imenu'.
47
48 MENU-TYPES is a list of section types containing elements of
49 ENTRY-TYPES.  Elements of MENU-TYPES are are used to categories
50 elements of ENTRY-TYPES.
51
52 This function is used as a helper for functions set as
53 `imenu-create-index-function'."
54   (let ((entries (make-hash-table :test 'equal)))
55     (goto-char (point-max))
56     (while (magit-section--backward-find
57             (lambda ()
58               (let* ((section (magit-current-section))
59                      (type (oref section type))
60                      (parent (oref section parent))
61                      (parent-type (oref parent type)))
62                 (and (-contains-p entry-types type)
63                      (-contains-p menu-types parent-type)))))
64       (let* ((section (magit-current-section))
65              (name (buffer-substring-no-properties
66                     (line-beginning-position)
67                     (line-end-position)))
68              (parent (oref section parent))
69              (parent-title (buffer-substring-no-properties
70                             (oref parent start)
71                             (1- (oref parent content)))))
72         (puthash parent-title
73                  (cons (cons name (point))
74                        (gethash parent-title entries (list)))
75                  entries)))
76     (mapcar (lambda (menu-title)
77               (cons menu-title (gethash menu-title entries)))
78             (hash-table-keys entries))))
79
80 ;;; Log mode
81
82 ;;;###autoload
83 (defun magit-imenu--log-prev-index-position-function ()
84   "Move point to previous line in current buffer.
85 This function is used as a value for
86 `imenu-prev-index-position-function'."
87   (magit-section--backward-find
88    (lambda ()
89      (-contains-p '(commit stash)
90                   (oref (magit-current-section) type)))))
91
92 ;;;###autoload
93 (defun magit-imenu--log-extract-index-name-function ()
94   "Return imenu name for line at point.
95 This function is used as a value for
96 `imenu-extract-index-name-function'.  Point should be at the
97 beginning of the line."
98   (save-match-data
99     (looking-at "\\([^ ]+\\)[ *|]+\\(.+\\)$")
100     (format "%s: %s"
101             (match-string-no-properties 1)
102             (match-string-no-properties 2))))
103
104 ;;; Diff mode
105
106 ;;;###autoload
107 (defun magit-imenu--diff-prev-index-position-function ()
108   "Move point to previous file line in current buffer.
109 This function is used as a value for
110 `imenu-prev-index-position-function'."
111   (magit-section--backward-find
112    (lambda ()
113      (let ((section (magit-current-section)))
114        (and (magit-file-section-p section)
115             (not (equal (oref (oref section parent) type)
116                         'diffstat)))))))
117
118 ;;;###autoload
119 (defun magit-imenu--diff-extract-index-name-function ()
120   "Return imenu name for line at point.
121 This function is used as a value for
122 `imenu-extract-index-name-function'.  Point should be at the
123 beginning of the line."
124   (buffer-substring-no-properties (line-beginning-position)
125                                   (line-end-position)))
126
127 ;;; Status mode
128
129 ;;;###autoload
130 (defun magit-imenu--status-create-index-function ()
131   "Return an alist of all imenu entries in current buffer.
132 This function is used as a value for
133 `imenu-create-index-function'."
134   (magit-imenu--index-function
135    '(file commit stash)
136    '(unpushed unstaged unpulled untracked staged stashes)))
137
138 ;;;; Refs mode
139
140 ;;;###autoload
141 (defun magit-imenu--refs-create-index-function ()
142   "Return an alist of all imenu entries in current buffer.
143 This function is used as a value for
144 `imenu-create-index-function'."
145   (magit-imenu--index-function
146    '(branch commit tag)
147    '(local remote tags)))
148
149 ;;;; Cherry mode
150
151 ;;;###autoload
152 (defun magit-imenu--cherry-create-index-function ()
153   "Return an alist of all imenu entries in current buffer.
154 This function is used as a value for
155 `imenu-create-index-function'."
156   (magit-imenu--index-function
157    '(commit)
158    '(cherries)))
159
160 ;;;; Submodule list mode
161
162 ;;;###autoload
163 (defun magit-imenu--submodule-prev-index-position-function ()
164   "Move point to previous line in magit-submodule-list buffer.
165 This function is used as a value for
166 `imenu-prev-index-position-function'."
167   (unless (bobp)
168     (forward-line -1)))
169
170 ;;;###autoload
171 (defun magit-imenu--submodule-extract-index-name-function ()
172   "Return imenu name for line at point.
173 This function is used as a value for
174 `imenu-extract-index-name-function'.  Point should be at the
175 beginning of the line."
176   (elt (tabulated-list-get-entry) 0))
177
178 ;;;; Repolist mode
179
180 ;;;###autoload
181 (defun magit-imenu--repolist-prev-index-position-function ()
182   "Move point to previous line in magit-repolist buffer.
183 This function is used as a value for
184 `imenu-prev-index-position-function'."
185   (unless (bobp)
186     (forward-line -1)))
187
188 ;;;###autoload
189 (defun magit-imenu--repolist-extract-index-name-function ()
190   "Return imenu name for line at point.
191 This function is used as a value for
192 `imenu-extract-index-name-function'.  Point should be at the
193 beginning of the line."
194   (let ((entry (tabulated-list-get-entry)))
195     (format "%s (%s)"
196             (elt entry 0)
197             (elt entry (1- (length entry))))))
198
199 ;;;; Process mode
200
201 ;;;###autoload
202 (defun magit-imenu--process-prev-index-position-function ()
203   "Move point to previous process in magit-process buffer.
204 This function is used as a value for
205 `imenu-prev-index-position-function'."
206   (magit-section--backward-find
207    (lambda ()
208      (eq (oref (magit-current-section) type) 'process))))
209
210 ;;;###autoload
211 (defun magit-imenu--process-extract-index-name-function ()
212   "Return imenu name for line at point.
213 This function is used as a value for
214 `imenu-extract-index-name-function'.  Point should be at the
215 beginning of the line."
216   (buffer-substring-no-properties (line-beginning-position)
217                                   (line-end-position)))
218
219 ;;;; Rebase mode
220
221 ;;;###autoload
222 (defun magit-imenu--rebase-prev-index-position-function ()
223   "Move point to previous commit in git-rebase buffer.
224 This function is used as a value for
225 `imenu-prev-index-position-function'."
226   (catch 'found
227     (while (not (bobp))
228       (git-rebase-backward-line)
229       (when (git-rebase-line-p)
230         (throw 'found t)))))
231
232 ;;;###autoload
233 (defun magit-imenu--rebase-extract-index-name-function ()
234   "Return imenu name for line at point.
235 This function is used as a value for
236 `imenu-extract-index-name-function'.  Point should be at the
237 beginning of the line."
238   (buffer-substring-no-properties (line-beginning-position)
239                                   (line-end-position)))
240
241 ;;; _
242 (provide 'magit-imenu)
243 ;;; magit-imenu.el ends here