Klimi's new dotfiles with stow.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

245 line
8.0 KiB

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