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.

239 lines
8.5 KiB

  1. ;; Copyright (C) 2015-2017 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. ;; tracks shell output
  14. (require 'shell)
  15. (require 'load-relative)
  16. (require-relative-list
  17. '("core" "helper" "track" "loc" "lochist" "file"
  18. "fringe" "window" "regexp" "menu" "backtrace-mode"
  19. "send" "shortkey" "utils") "realgud-")
  20. (require-relative-list '("buffer/command") "realgud-buffer-")
  21. ;; FIXME figure out if I can put this in something like a header file.
  22. (declare-function realgud-fringe-erase-history-arrows 'realgud-buffer-command)
  23. (declare-function realgud:track-set-debugger 'realgud-track)
  24. (declare-function realgud-populate-debugger-menu 'realgud-menu)
  25. (declare-function realgud-cmdbuf-info-divert-output?= 'realgud-buffer-command)
  26. (declare-function realgud-cmdbuf-info-prior-prompt-regexp=
  27. 'realgud-buffer-command)
  28. (declare-function realgud-cmdbuf-info-set?
  29. 'realgud-buffer-command)
  30. (declare-function realgud:canonic-major-mode
  31. 'realgud-utils)
  32. (declare-function shell-mode 'shell)
  33. (defvar realgud-track-mode-map
  34. (let ((map (copy-keymap shell-mode-map)))
  35. (realgud-populate-debugger-menu map)
  36. (define-key map "\r" 'realgud:send-input)
  37. (define-key map [M-right] 'realgud-track-hist-newest)
  38. (define-key map [M-down] 'realgud-track-hist-newer)
  39. (define-key map [M-up] 'realgud-track-hist-older)
  40. (define-key map [M-print] 'realgud-track-hist-older)
  41. (define-key map [M-S-down] 'realgud-track-hist-newest)
  42. (define-key map [M-S-up] 'realgud-track-hist-oldest)
  43. (define-key map "\C-cS" 'realgud-window-src-undisturb-cmd)
  44. (define-key map (kbd "C-c !d") 'realgud:goto-debugger-loc-line)
  45. map)
  46. "Keymap used in `realgud-track-minor-mode'.
  47. \\{realgud-track-mode-map}")
  48. (defvar realgud:tool-bar-map
  49. (let ((map (make-sparse-keymap)))
  50. (dolist (x '((realgud:cmd-break . "gud/break")
  51. ;; (realgud:cmd-remove . "gud/remove")
  52. ;; (realgud:cmd-print . "gud/print")
  53. ;; (realgud:cmd-pstar . "gud/pstar")
  54. ;; (realgud:cmd-pp . "gud/pp")
  55. ;; (realgud:cmd-watch . "gud/watch")
  56. (realgud:cmd-restart . "gud/run")
  57. ;; (realgud:cmd-go . "gud/go")
  58. ;; (realgud:cmd-stop-subjob . "gud/stop")
  59. (realgud:cmd-continue . "gud/cont")
  60. (realgud:cmd-until . "gud/until")
  61. (realgud:cmd-next . "gud/next")
  62. (realgud:cmd-step . "gud/step")
  63. (realgud:cmd-finish . "gud/finish")
  64. ;; (realgud:cmd-nexti . "gud/nexti")
  65. ;; (realgud:cmd-stepi . "gud/stepi")
  66. (realgud:cmd-older-frame . "gud/up")
  67. (realgud:cmd-newer-frame . "gud/down")
  68. (realgud:cmdbuf-info-describe . "info"))
  69. map)
  70. (tool-bar-local-item-from-menu
  71. (car x) (cdr x) map realgud-track-mode-map)))
  72. "toolbar use when `realgud' interface is active"
  73. )
  74. (define-minor-mode realgud-track-mode
  75. "Minor mode for tracking debugging inside a process shell."
  76. :init-value nil
  77. :global nil
  78. :group 'realgud
  79. :lighter
  80. (:eval (progn
  81. (concat " "
  82. (if (realgud-cmdbuf-info-set?)
  83. (realgud-sget 'cmdbuf-info 'debugger-name)
  84. "dbgr??"))))
  85. :keymap realgud-track-mode-map
  86. ;; Setup/teardown
  87. (realgud-track-mode-setup realgud-track-mode)
  88. )
  89. ;; FIXME: this should have been picked up by require'ing track.
  90. (defvar realgud-track-divert-string)
  91. (defun realgud-track-mode-setup (mode-on?)
  92. "Called when entering or leaving `realgud-track-mode'. Variable
  93. MODE-ON is a boolean which specifies if we are going into or out
  94. of this mode."
  95. (if mode-on?
  96. (let ((process (get-buffer-process (current-buffer))))
  97. (unless process
  98. (setq realgud-track-mode nil)
  99. (error "Can't find a process for buffer %s" (current-buffer)))
  100. (setq realgud-track-divert-string "")
  101. (setq realgud-track-mode 't)
  102. ;; FIXME: save and chain process-sentinel via
  103. ;; (process-sentinel (get-buffer-process (current-buffer)))
  104. (set-process-sentinel process 'realgud-term-sentinel)
  105. (unless (and (realgud-cmdbuf-info-set?)
  106. (realgud-sget 'cmdbuf-info 'debugger-name))
  107. (call-interactively 'realgud:track-set-debugger))
  108. (if (boundp 'comint-last-output-start)
  109. (progn
  110. (realgud-cmdbuf-info-prior-prompt-regexp= comint-prompt-regexp)
  111. (realgud-cmdbuf-info-divert-output?= nil)
  112. (let* ((regexp-hash
  113. (and (realgud-cmdbuf-info? realgud-cmdbuf-info)
  114. (realgud-sget 'cmdbuf-info 'regexp-hash)))
  115. (prompt-pat (and regexp-hash
  116. (gethash "prompt" regexp-hash))))
  117. (if prompt-pat
  118. (setq comint-prompt-regexp
  119. (realgud-loc-pat-regexp prompt-pat)))))
  120. (set-marker comint-last-output-start (point)))
  121. (set (make-local-variable 'tool-bar-map) realgud:tool-bar-map)
  122. (let ((mode (realgud:canonic-major-mode)))
  123. (cond ((eq mode 'eshell)
  124. (add-hook 'eshell-output-filter-functions
  125. 'realgud-track-eshell-output-filter-hook))
  126. ((eq mode 'comint)
  127. (add-hook 'comint-output-filter-functions
  128. 'realgud-track-comint-output-filter-hook))
  129. ))
  130. (run-mode-hooks 'realgud-track-mode-hook))
  131. ;; else
  132. (progn
  133. (if (and (boundp 'comint-last-output-start) realgud-cmdbuf-info)
  134. (setq comint-prompt-regexp
  135. (realgud-sget 'cmdbuf-info 'prior-prompt-regexp))
  136. )
  137. (kill-local-variable 'realgud:tool-bar-map)
  138. (realgud-fringe-erase-history-arrows)
  139. (let ((mode (realgud:canonic-major-mode)))
  140. (cond ((eq mode 'eshell)
  141. (remove-hook 'eshell-output-filter-functions
  142. 'realgud-track-eshell-output-filter-hook))
  143. ((eq mode 'comint)
  144. (remove-hook 'comint-output-filter-functions
  145. 'realgud-track-comint-output-filter-hook))
  146. ))
  147. (let* ((cmd-process (get-buffer-process (current-buffer)))
  148. (status (if cmd-process
  149. (list (propertize (format ":%s"
  150. (process-status cmd-process))
  151. 'face 'realgud-debugger-running))
  152. ""))
  153. )
  154. (setq mode-line-process status)
  155. ;; Force mode line redisplay soon.
  156. (force-mode-line-update)
  157. ;; FIXME: This is a workaround. Without this, we comint doesn't
  158. ;; process commands
  159. (unless (member 'comint-mode minor-mode-list) (comint-mode))
  160. )
  161. ;; FIXME: restore/unchain old process sentinels.
  162. )
  163. )
  164. )
  165. ;; For name == "trepan", produces:
  166. ;; (defvar trepan-track-mode nil
  167. ;; "Non-nil if using trepan track-mode ... "
  168. ;; (defvar trepan-track-mode-map (make-sparse-keymap))
  169. ;; (defvar trepan-short-key-mode-map (make-sparse-keymap))
  170. ;; (set-keymap-parent trepan-short-key-mode-map realgud-short-key-mode-map)
  171. (defmacro realgud-track-mode-vars (name)
  172. `(progn
  173. (defvar ,(intern (concat name "-track-mode")) nil
  174. ,(format "Non-nil if using %s-track-mode as a minor mode of some other mode.
  175. Use the command `%s-track-mode' to toggle or set this variable." name name))
  176. (defvar ,(intern (concat name "-track-mode-map")) (make-sparse-keymap)
  177. ,(format "Keymap used in `%s-track-mode'." name))
  178. (defvar ,(intern (concat name "-short-key-mode-map")) (make-sparse-keymap))
  179. ))
  180. ;; FIXME: The below could be a macro? I have a hard time getting
  181. ;; macros right.
  182. (defun realgud-track-mode-body(name)
  183. "Used in by custom debuggers: pydbgr, trepan, gdb, etc. NAME is
  184. the name of the debugger which is used to preface variables."
  185. (realgud:track-set-debugger name)
  186. (funcall (intern (concat "realgud-define-" name "-commands")))
  187. (if (intern (concat name "-track-mode"))
  188. (progn
  189. (setq realgud-track-mode 't)
  190. (run-mode-hooks (intern (concat name "-track-mode-hook"))))
  191. (progn
  192. (setq realgud-track-mode nil)
  193. )))
  194. (defun realgud:track-mode-disable()
  195. "Disable the debugger track-mode hook"
  196. (interactive "")
  197. (if realgud-track-mode
  198. (progn
  199. (setq realgud-track-mode nil)
  200. ;; FIXME: for some reason, disabling trak mode also
  201. ;; disables shell mode. Reinitialize it?
  202. (if (equal mode-name "Shell")
  203. (shell-mode))
  204. )
  205. (message "Debugger is not in track mode")))
  206. (defun realgud:track-mode-enable()
  207. "Enable the debugger track-mode hook"
  208. (interactive "")
  209. (if realgud-track-mode
  210. (message "Debugger track mode is already enabled.")
  211. (setq realgud-track-mode t))
  212. )
  213. (provide-me "realgud-")