Personal emacs config
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.

224 lines
8.2 KiB

  1. ;; Copyright (C) 2010, 2012, 2014-2016, 2018 Free Software Foundation, Inc
  2. ;; Author: Rocky Bernstein <rocky@gnu.org>
  3. ;; This program is free software; you can redistribute it and/or modify
  4. ;; it under the terms of the GNU General Public License as published by
  5. ;; the Free Software Foundation, either version 3 of the License, or
  6. ;; (at your option) any later version.
  7. ;; This program is distributed in the hope that it will be useful,
  8. ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  10. ;; GNU General Public License for more details.
  11. ;; Fringe marks for history of stopping points
  12. (require 'load-relative)
  13. (require-relative-list '("helper") "realgud-")
  14. (declare-function realgud-loc-hist-item-at 'realgud-lochist)
  15. (declare-function buffer-killed? 'helper)
  16. (declare-function realgud-loc-cmd-marker 'realgud-loc)
  17. (declare-function realgud:follow-mark 'realgud-follow)
  18. (declare-function realgud-loc-marker 'realgud-loc)
  19. ;; Bitmap for hollow overlay-arrow in fringe
  20. (if (display-images-p)
  21. (define-fringe-bitmap 'hollow-right-triangle
  22. "\xe0\x90\x88\x84\x84\x88\x90\xe0"))
  23. (defface realgud-debugger-running
  24. '((((class color) (min-colors 16) (background light))
  25. (:foreground "Green4" :weight bold))
  26. (((class color) (min-colors 88) (background dark))
  27. (:foreground "Green1" :weight bold))
  28. (((class color) (min-colors 16) (background dark))
  29. (:foreground "Green" :weight bold))
  30. (((class color)) (:foreground "green" :weight bold))
  31. (t (:weight bold)))
  32. "Face used to highlight debugger run information."
  33. :group 'realgud
  34. :version "25.1")
  35. (defface realgud-debugger-not-running
  36. '((t :inherit font-lock-warning-face))
  37. "Face used when debugger or process is not running."
  38. :group 'realgud
  39. :version "25.1")
  40. ;; FIXME: Figure out how to do this as a macro.
  41. (defface realgud-overlay-arrow1
  42. '((t :inherit realgud-debugger-running))
  43. "Realgud fringe face for current position indicator."
  44. :group 'realgud)
  45. (defface realgud-overlay-arrow2
  46. '((((background dark)) :foreground "white" :weight bold)
  47. (((background light)) :foreground "tan1" :weight bold))
  48. "Fringe face for current position."
  49. :group 'realgud)
  50. (defface realgud-overlay-arrow3
  51. '((((background dark)) :foreground "DimGray")
  52. (((background light)) :foreground "tan4"))
  53. "Fringe face for current position."
  54. :group 'realgud)
  55. (defvar realgud-overlay-arrow1 nil
  56. "Overlay arrow variable which contains the most recent debugger
  57. position.")
  58. (defvar realgud-overlay-arrow2 nil
  59. "Overlay arrow variable which contains the 2nd most recent debugger
  60. position.")
  61. (defvar realgud-overlay-arrow3 nil
  62. "Overlay arrow variable which contains the 3rd most recent debugger
  63. position.")
  64. ;; FIXME: since overlay overlay-arrow-list can be global, and perhaps
  65. ;; has to stay that way since some Emacs code may expect that, we
  66. ;; should use different global overlay arrow variables for the
  67. ;; different debuggers. E.g. trepan-overlay-arrow1,
  68. ;; pyrealgud-overlay-arrow1 and so on. That way, if those debuggers are
  69. ;; running concurrently, the fringe for one doesn't interfere with the
  70. ;; fringe for another.
  71. ;; Loop to set up fringe position markers.
  72. ;; Here is an example of what each iteration does:
  73. ;;
  74. ;; (make-local-variable 'realgud-overlay-arrow1) ;; or 2, or 3
  75. ;; (put 'realgud-overlay-arrow1 'overlay-arrow-string "=>" ;; or "2>", or ">3"
  76. ;; (define-fringe-bitmap 'realgud-overlay-arrow1 "\xc0...")
  77. ;; (add-to-list 'overlay-arrow-variable-list 'realgud-overlay-arrow1)
  78. (dolist (pair
  79. '( ("3" . "3>") ("2" . "2>") ("1" . "=>")))
  80. (let ((arrow-symbol (intern (concat "realgud-overlay-arrow" (car pair))))
  81. (arrow-bitmap (intern (concat "realgud-right-triangle" (car pair))))
  82. (arrow-face (intern (concat "realgud-overlay-arrow" (car pair)))))
  83. (make-local-variable arrow-symbol)
  84. (put arrow-symbol 'overlay-arrow-string (cdr pair))
  85. (if (display-images-p)
  86. (progn
  87. (define-fringe-bitmap arrow-bitmap "\xc0\xf0\xf8\xfc\xfc\xf8\xf0\xc0")
  88. (put arrow-symbol 'overlay-arrow-bitmap arrow-bitmap)
  89. (set-fringe-bitmap-face arrow-bitmap arrow-face)))
  90. (add-to-list 'overlay-arrow-variable-list arrow-symbol)))
  91. (defun realgud-fringe-set-arrow (overlay-arrow marker)
  92. "Set the fringe indicator or overlay arrow to MARKER. This is done
  93. for example to indicate a debugger position."
  94. (let ((position (marker-position marker)))
  95. (if position
  96. (with-current-buffer (marker-buffer marker)
  97. (save-excursion
  98. (save-restriction
  99. (widen)
  100. (progn
  101. (goto-char position)
  102. ;; We need to ignore field boundaries, so we use
  103. ;; forward-line rather than beginning-of-line.
  104. (forward-line 0)
  105. (set overlay-arrow (point-marker)))))))))
  106. (defun realgud-fringe-history-set (loc-hist &optional do-cmdbuf?)
  107. "Set arrows on the last positions we have stopped on."
  108. ;; FIXME DRY somehow
  109. (let* (
  110. (loc1 (realgud-loc-hist-item-at loc-hist 2))
  111. (loc2 (realgud-loc-hist-item-at loc-hist 1))
  112. (loc3 (realgud-loc-hist-item-at loc-hist 0))
  113. (mark1 (and loc3 (realgud-loc-marker loc3)))
  114. (mark2 (and loc2 (realgud-loc-marker loc2)))
  115. (mark3 (and loc1 (realgud-loc-marker loc1)))
  116. (cmd-mark1 (and loc3 (realgud-loc-cmd-marker loc3)))
  117. (cmd-mark2 (and loc2 (realgud-loc-cmd-marker loc2)))
  118. (cmd-mark3 (and loc1 (realgud-loc-cmd-marker loc1)))
  119. )
  120. (when (and loc3 (not (equal mark3 mark2)))
  121. (realgud-fringe-set-arrow 'realgud-overlay-arrow3 mark3)
  122. (if do-cmdbuf?
  123. (realgud-fringe-set-arrow 'realgud-overlay-arrow3 cmd-mark3)))
  124. (when (and loc2 (not (equal mark2 mark1)))
  125. (realgud-fringe-set-arrow 'realgud-overlay-arrow2 mark2)
  126. (if do-cmdbuf?
  127. (realgud-fringe-set-arrow 'realgud-overlay-arrow2 cmd-mark2)))
  128. (when loc1
  129. (realgud-fringe-set-arrow 'realgud-overlay-arrow1 mark1)
  130. (when (and do-cmdbuf? cmd-mark1)
  131. (realgud-fringe-set-arrow 'realgud-overlay-arrow1 cmd-mark1)
  132. (goto-char (marker-position cmd-mark1)))
  133. )
  134. ))
  135. (defun realgud-fringe-erase-history-arrows ()
  136. "Erase the history arrows from the fringe. You might want call
  137. this command interactively if you have conceptually stopped
  138. debugging and now find the fringe arrows distracting. But you
  139. don't want to kill the debugger process or quit a debugger
  140. session which should also erase those fringe arrows."
  141. (interactive)
  142. (setq realgud-overlay-arrow1 nil)
  143. (setq realgud-overlay-arrow2 nil)
  144. (setq realgud-overlay-arrow3 nil))
  145. (defun realgud-goto-arrow1()
  146. "Goto the position stored in realgud-overlay-arrow1"
  147. (interactive "")
  148. (if realgud-overlay-arrow1
  149. (realgud:follow-mark realgud-overlay-arrow1))
  150. )
  151. (defun realgud-goto-arrow2()
  152. "Goto the position stored in realgud-overlay-arrow2"
  153. (interactive "")
  154. (if realgud-overlay-arrow2
  155. (realgud:follow-mark realgud-overlay-arrow2))
  156. )
  157. (defun realgud-goto-arrow3()
  158. "Goto the position stored in realgud-overlay-arrow3"
  159. (interactive "")
  160. (if realgud-overlay-arrow3
  161. (realgud:follow-mark realgud-overlay-arrow3))
  162. )
  163. (defun realgud-recenter-arrow1()
  164. "If the current buffer contains realgud-overlay-arrow1 go to that position"
  165. (interactive "")
  166. (if (and realgud-overlay-arrow1
  167. (eq (marker-buffer realgud-overlay-arrow1) (current-buffer)))
  168. (goto-char realgud-overlay-arrow1))
  169. )
  170. (defun realgud-recenter-arrow(&optional opt-buffer)
  171. "If the current buffer contains realgud-overlay-arrows 1, 2 or 3
  172. recenter window to show that"
  173. (interactive "")
  174. (let ((buffer (or opt-buffer (current-buffer))))
  175. ;; We need to update in the order 3..1 so that if there are more than on
  176. ;; arrows in the same buffer the smaller number (e.g. arrow 1) is the
  177. ;; position we are at rather than the earlier one (e.g. arrow 3).
  178. (with-current-buffer-safe buffer
  179. (if (and realgud-overlay-arrow3
  180. (eq (marker-buffer realgud-overlay-arrow3) buffer))
  181. (realgud:follow-mark realgud-overlay-arrow3)
  182. )
  183. (if (and realgud-overlay-arrow2
  184. (eq (marker-buffer realgud-overlay-arrow2) buffer))
  185. (realgud:follow-mark realgud-overlay-arrow2)
  186. )
  187. (if (and realgud-overlay-arrow1
  188. (eq (marker-buffer realgud-overlay-arrow1) buffer))
  189. (realgud:follow-mark realgud-overlay-arrow1)
  190. )
  191. (redisplay)
  192. )
  193. ))
  194. (provide 'realgud-fringe)