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.

200 lines
7.0 KiB

  1. ;; Copyright (C) 2015-2017, 2019 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. ;; You should have received a copy of the GNU General Public License
  12. ;; along with this program. If not, see <http://www.gnu.org/licenses/>.
  13. ;; This describes a debugger location structure and has code for
  14. ;; working with them.
  15. (eval-when-compile (require 'cl-lib))
  16. (require 'load-relative)
  17. (require 'loc-changes)
  18. (require-relative-list '("fringe" "follow") "realgud-")
  19. (require-relative-list '("buffer/source") "realgud-buffer-")
  20. ;; FIXME: removed because of recursive loads
  21. ;; (require-relative-list '("buffer/helper") "realgud-buffer-")
  22. (declare-function realgud:strip 'realgud)
  23. (declare-function realgud-get-cmdbuf-from-srcbuf 'realgud-buffer-helper)
  24. (declare-function realgud-srcbuf? 'realgud-buffer-source)
  25. (cl-defstruct realgud-loc
  26. "Our own location type. Even though a mark contains a
  27. file-name (via a buffer) and a line number (via an offset), we
  28. want to save the values that were seen/requested originally."
  29. num ;; If there is a number such as a breakpoint or frame
  30. ;; number associated with this location, this is set.
  31. ;; nil otherwise.
  32. filename
  33. line-number
  34. column-number ;; Column offset within line
  35. source-text ;; Source text if available
  36. marker ;; Position in source code
  37. cmd-marker ;; Position in command process buffer
  38. )
  39. (defalias 'realgud-loc? 'realgud-loc-p)
  40. ;; The below function is generic and might be found in standard
  41. ;; library. Or it might be moved someplace more generic.
  42. (defun realgud:buffer-line-no-props()
  43. "Returns a string containing the line that `point' is at,
  44. without buffer properties."
  45. (buffer-substring-no-properties (point-at-bol)
  46. (point-at-eol)))
  47. (defun realgud:loc-describe (loc)
  48. "Display realgud-cmdcbuf-info.
  49. Information is put in an internal buffer called *Describe Debugger Session*."
  50. (interactive "")
  51. (switch-to-buffer (get-buffer-create "*Describe Debugger Session*"))
  52. (realgud:org-mode-append-loc loc))
  53. (defun realgud:org-mode-append-loc (loc)
  54. "Display realgud-cmdcbuf-info.
  55. Information is put in an internal buffer called *Describe Debugger Session*."
  56. (let ((column-number (realgud-loc-column-number loc))
  57. (bp-num (realgud-loc-num loc))
  58. (source-text (realgud-loc-source-text loc))
  59. (filename (realgud-loc-filename loc)))
  60. (insert " - filename :: ")
  61. (put-text-property
  62. (insert-text-button filename
  63. 'action 'realgud:follow-event
  64. 'help-echo "mouse-2: go to this file")
  65. (point)
  66. 'file filename)
  67. (insert "\n")
  68. (mapc 'insert
  69. (list
  70. (format " - line number :: %s\n" (realgud-loc-line-number loc))
  71. (if bp-num
  72. (format " - brkpt num :: %s\n" (realgud-loc-num loc))
  73. "")
  74. (if column-number
  75. (format " - column number :: %s\n"
  76. (realgud-loc-column-number loc))
  77. "")
  78. (if source-text
  79. (format " - source text :: %s\n" (realgud-loc-source-text loc))
  80. "")
  81. ))
  82. ;; Make locations clickable
  83. (insert " - source marker :: ")
  84. (put-text-property
  85. (insert-text-button (format "%s" (realgud-loc-marker loc))
  86. 'action 'realgud:follow-event
  87. 'help-echo "mouse-2: go to this source location")
  88. (point)
  89. 'mark (realgud-loc-marker loc))
  90. (insert "\n - cmdbuf marker :: ")
  91. (put-text-property
  92. (insert-text-button (format "%s" (realgud-loc-cmd-marker loc))
  93. 'action 'realgud:follow-event
  94. 'help-echo "mouse-2: go to this command-buffer location")
  95. (point)
  96. 'mark (realgud-loc-cmd-marker loc))
  97. (insert "\n")
  98. )
  99. )
  100. (defun realgud-loc-current(&optional source-buffer cmd-marker)
  101. "Create a location object for the point in the current buffer.
  102. If SOURCE-BUFFER is not given, take the current buffer as the
  103. source buffer."
  104. (interactive "")
  105. (unless source-buffer
  106. (setq source-buffer (current-buffer)))
  107. (unless (realgud-srcbuf? source-buffer)
  108. (error "%s is not a realgud source buffer" source-buffer))
  109. (unless cmd-marker
  110. (setq cmd-marker
  111. (realgud-get-cmdbuf-from-srcbuf source-buffer))
  112. )
  113. (with-current-buffer source-buffer
  114. (let ((mark (point-marker))
  115. (text (realgud:buffer-line-no-props)))
  116. (make-realgud-loc
  117. :filename (buffer-file-name source-buffer)
  118. :column-number (current-column)
  119. :line-number (line-number-at-pos)
  120. :source-text text
  121. :marker mark
  122. :cmd-marker cmd-marker
  123. )
  124. )))
  125. (defun realgud-loc-marker=(loc marker)
  126. (setf (realgud-loc-marker loc) marker))
  127. (defun realgud-loc-goto(loc)
  128. "Position point in the buffer referred to by LOC. This may
  129. involve reading in a file. In the process, the marker inside LOC
  130. may be updated.
  131. If LOC is found, The buffer containing the location referred to,
  132. the source-code buffer, is returned. Otherwise, nil is returned."
  133. (if (realgud-loc? loc)
  134. (let* ((filename (realgud-loc-filename loc))
  135. (line-number (realgud-loc-line-number loc))
  136. (column-number (realgud-loc-column-number loc))
  137. (marker (realgud-loc-marker loc))
  138. (cmd-marker (realgud-loc-cmd-marker loc))
  139. (use-marker nil)
  140. (src-buffer (marker-buffer (or marker (make-marker)))))
  141. (if (and (not src-buffer) filename)
  142. (setq src-buffer (find-file-noselect filename)))
  143. (if cmd-marker
  144. (with-current-buffer (marker-buffer cmd-marker)
  145. (goto-char cmd-marker)))
  146. (if src-buffer
  147. (with-current-buffer src-buffer
  148. (when (and marker (marker-position marker))
  149. ;; A marker has been set in loc, so use that.
  150. (goto-char (marker-position marker))
  151. (setq use-marker 't)
  152. (let ((current-text (realgud:buffer-line-no-props))
  153. (loc-text (realgud-loc-source-text loc)))
  154. (unless (and loc-text
  155. (equal (realgud:strip current-text) (realgud:strip loc-text)))
  156. (loc-changes-goto line-number)
  157. (setq current-text (realgud:buffer-line-no-props))
  158. (when (equal current-text loc-text)
  159. (message "Marked location needed updating")
  160. (setq use-marker nil))
  161. )))
  162. (if use-marker
  163. (goto-char (marker-position marker))
  164. ;; else
  165. ;; We don't have a position set in the source buffer
  166. ;; so find it and go there. We use `loc-changes-goto'
  167. ;; to find that spot. `loc-changes-goto' keeps a
  168. ;; record of the first time we went to that spot, so
  169. ;; in the face of buffer modifications, it may be more
  170. ;; reliable.
  171. (let ((src-marker))
  172. (loc-changes-goto line-number)
  173. (when column-number
  174. (move-to-column column-number))
  175. (setq src-marker (point-marker))
  176. (realgud-loc-marker= loc src-marker)
  177. ))))
  178. src-buffer )))
  179. (provide-me "realgud-")