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.

210 lines
8.0 KiB

  1. ;; Copyright (C) 2010-2011, 2013-2014, 2016-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. ; Should realgud:file-loc-from-line be here or elsewhere?
  12. (require 'load-relative)
  13. (require 'compile) ;; for compilation-find-file
  14. (require 'seq) ;; for seq-find
  15. (require-relative-list '("helper" "loc") "realgud-")
  16. (require-relative-list '("buffer/command") "realgud-buffer-")
  17. (declare-function realgud:strip 'realgud)
  18. (declare-function realgud-loc-goto 'realgud-loc)
  19. (declare-function realgud-get-cmdbuf 'realgud-buffer-helper)
  20. (declare-function buffer-killed? 'helper)
  21. (declare-function compilation-find-file 'compile)
  22. (declare-function realgud-cmdbuf-info-ignore-re-file-list 'realgud-buffer-command)
  23. (declare-function realgud-cmdbuf-info-source-path= 'realgud-buffer-command)
  24. (declare-function realgud-cmdbuf-mutex 'realgud-buffer-command)
  25. (declare-function realgud-cmdbuf-filename-remap-alist 'realgud-buffer-command)
  26. (declare-function realgud-cmdbuf-filename-remap-alist= 'realgud-buffer-command)
  27. (declare-function realgud-cmdbuf-mutex 'realgud-buffer-command)
  28. (defcustom realgud-file-find-function 'realgud:find-file
  29. ;;(defcustom realgud-file-find-function 'compilation-find-file
  30. "Function to call when we can't easily find file"
  31. :type 'function
  32. :group 'realgud)
  33. (defun realgud:find-file (marker filename directory &optional formats)
  34. "A wrapper around compilation find-file. We set the prompt
  35. to indicate we are looking for a source-code file."
  36. (or formats (setq formats "%s"))
  37. (let ((compilation-error "source-code file"))
  38. (compilation-find-file marker filename directory formats)))
  39. (defun realgud:file-line-count(filename)
  40. "Return the number of lines in file FILENAME, or nil FILENAME can't be
  41. found"
  42. (if (file-exists-p filename)
  43. (let ((file-buffer (find-file-noselect filename)))
  44. (with-current-buffer-safe file-buffer
  45. (line-number-at-pos (point-max))))
  46. nil))
  47. (defun realgud:file-column-from-string(filename line-number source-text
  48. &optional no-strip-blanks)
  49. "Return the column of the first column position of SOURCE-TEXT
  50. at LINE-NUMBER or nil if it is not there"
  51. (condition-case nil
  52. (when (and source-text (file-exists-p filename))
  53. (let ((file-buffer (find-file-noselect filename)))
  54. (with-current-buffer-safe file-buffer
  55. (save-excursion
  56. (goto-char (point-min))
  57. (forward-line (1- line-number))
  58. (unless no-strip-blanks
  59. (setq source-text (realgud:strip source-text)))
  60. (when (search-forward source-text (point-at-eol))
  61. (goto-char (match-beginning 0))
  62. (current-column))))))
  63. (error nil)))
  64. (defun realgud:file-ignore(filename ignore-re-file-list)
  65. (seq-find '(lambda (file-re) (string-match file-re filename)) ignore-re-file-list))
  66. ;; FIXME: should allow column number to be passed in.
  67. (defun realgud:file-loc-from-line(filename line-number
  68. &optional cmd-marker source-text bp-num
  69. find-file-fn directory)
  70. "Return a realgud-loc for FILENAME and LINE-NUMBER and the
  71. other optional position information.
  72. CMD-MARKER and BP-NUM get stored in the realgud-loc
  73. object. FIND-FILE-FN is a function which do special things to
  74. transform filename so it can be found. This could include
  75. searching classpaths (in Java), stripping leading and trailing
  76. blanks, or deliberately ignoring 'pseudo-file patterns like (eval
  77. 1) of Perl and <string> of Python.
  78. If we're unable find the source code we return a string describing the
  79. problem as best as we can determine."
  80. (let* ((cmdbuf (or (realgud-get-cmdbuf) cmd-marker))
  81. (ignore-re-file-list (realgud-cmdbuf-ignore-re-file-list cmdbuf))
  82. (filename-remap-alist (realgud-cmdbuf-filename-remap-alist cmdbuf))
  83. (remapped-filename
  84. (assoc filename filename-remap-alist))
  85. (mutex (realgud-cmdbuf-mutex cmdbuf))
  86. )
  87. ;;(with-mutex
  88. ;; mutex
  89. (when remapped-filename
  90. (if (file-readable-p (cdr remapped-filename))
  91. (setq filename (cdr remapped-filename))
  92. ;; else remove from map since no find
  93. (realgud-cmdbuf-filename-remap-alist=
  94. (delq (assoc remapped-filename filename-remap-alist)
  95. filename-remap-alist))))
  96. (unless (and filename (file-readable-p filename))
  97. (cond
  98. ;; Is file already listed for ignore?
  99. ((realgud:file-ignore filename ignore-re-file-list)
  100. (message "tracking ignored for %s" filename))
  101. ;; Do we want to black-list this?
  102. ((y-or-n-p (format "Black-list file %s for location tracking?" filename))
  103. ;; FIXME: there has to be a simpler way to set ignore-file-list
  104. (with-current-buffer cmdbuf
  105. (push filename ignore-re-file-list)
  106. (realgud-cmdbuf-info-ignore-re-file-list= ignore-re-file-list))
  107. (setq filename nil)
  108. )
  109. ;; Do we have a custom find-file function?
  110. (find-file-fn
  111. (setq filename (funcall find-file-fn cmd-marker filename directory)))
  112. (t
  113. (let ((found-file (funcall realgud-file-find-function (point-marker) filename directory)))
  114. (if found-file
  115. (progn
  116. (setq remapped-filename (buffer-file-name found-file))
  117. (when (and remapped-filename (file-exists-p remapped-filename))
  118. (realgud-cmdbuf-filename-remap-alist=
  119. (cons
  120. (cons filename remapped-filename)
  121. filename-remap-alist)
  122. cmdbuf)
  123. (setq filename remapped-filename)
  124. ))
  125. ;; else
  126. (setq filename nil)
  127. )))
  128. )))
  129. ;;)
  130. (if filename
  131. (if (file-readable-p filename)
  132. (if (integerp line-number)
  133. (if (> line-number 0)
  134. (let ((line-count))
  135. (if (setq line-count (realgud:file-line-count filename))
  136. (if (> line-count line-number)
  137. (let* ((column-number
  138. (realgud:file-column-from-string filename
  139. line-number
  140. source-text))
  141. (source-buffer (find-file-noselect filename))
  142. (source-mark))
  143. ;; Set this filename as the last one seen in cmdbuf
  144. (realgud-cmdbuf-info-source-path= filename)
  145. ;; And you thought we'd never get around to
  146. ;; doing something other than validation?
  147. (with-current-buffer source-buffer
  148. (goto-char (point-min))
  149. ;; FIXME also allow column number and byte offset
  150. (forward-line (1- line-number))
  151. (make-realgud-loc
  152. :num bp-num
  153. :cmd-marker cmd-marker
  154. :filename filename
  155. :line-number line-number
  156. :column-number column-number
  157. :source-text source-text
  158. :marker (point-marker)
  159. )
  160. ))
  161. ;; else
  162. (format "File %s has only %d lines. (Line %d requested.)"
  163. filename line-count line-number))
  164. (format "Problem getting line count for file `%s'" filename)))
  165. (format "line number %s should be greater than 0" line-number))
  166. (format "%s is not an integer" line-number))
  167. ;; else
  168. (if filename
  169. (format "File named `%s' not readable" filename))))
  170. )
  171. ;; FIXME: should allow column number to be passed in.
  172. (defun realgud:file-remove-ignore(path-to-stop-ignoring)
  173. "Remove `path-to-stop-ignoring' from the list of paths which
  174. are ignored in debugger location tracking. You might do this if you accidentllay
  175. added a a path for ignoring by mistake."
  176. (interactive
  177. (list (completing-read "File name to stop ignoring: "
  178. (realgud-cmdbuf-ignore-re-file-list (current-buffer))
  179. nil t)))
  180. (when (member path-to-stop-ignoring (realgud-cmdbuf-ignore-re-file-list (current-buffer)))
  181. (realgud-cmdbuf-info-ignore-re-file-list=
  182. (delete path-to-stop-ignoring (realgud-cmdbuf-ignore-re-file-list (current-buffer)))))
  183. )
  184. (provide-me "realgud-")