gds.el 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630
  1. ;;; gds.el -- frontend for Guile development in Emacs
  2. ;;;; Copyright (C) 2003, 2004 Free Software Foundation, Inc.
  3. ;;;;
  4. ;;;; This library is free software; you can redistribute it and/or
  5. ;;;; modify it under the terms of the GNU Lesser General Public
  6. ;;;; License as published by the Free Software Foundation; either
  7. ;;;; version 2.1 of the License, or (at your option) any later
  8. ;;;; version.
  9. ;;;;
  10. ;;;; This library is distributed in the hope that it will be useful,
  11. ;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. ;;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  13. ;;;; Lesser General Public License for more details.
  14. ;;;;
  15. ;;;; You should have received a copy of the GNU Lesser General Public
  16. ;;;; License along with this library; if not, write to the Free
  17. ;;;; Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
  18. ;;;; 02111-1307 USA
  19. ; TODO:
  20. ; ?transcript
  21. ; scheme-mode menu
  22. ; interrupt/sigint/async-break
  23. ; (module browsing)
  24. ; load file
  25. ; doing common protocol from debugger
  26. ; thread override for debugging
  27. ;;;; Prerequisites.
  28. (require 'scheme)
  29. (require 'cl)
  30. (require 'gds-server)
  31. (require 'gds-scheme)
  32. ;; The subprocess object for the debug server.
  33. (defvar gds-debug-server nil)
  34. (defvar gds-socket-type-alist '((tcp . 8333)
  35. (unix . "/tmp/.gds_socket"))
  36. "Maps each of the possible socket types that the GDS server can
  37. listen on to the path that it should bind to for each one.")
  38. (defun gds-run-debug-server ()
  39. "Start (or restart, if already running) the GDS debug server process."
  40. (interactive)
  41. (if gds-debug-server (gds-kill-debug-server))
  42. (setq gds-debug-server
  43. (gds-start-server "gds-debug"
  44. (cdr (assq gds-server-socket-type
  45. gds-socket-type-alist))
  46. 'gds-debug-protocol))
  47. (process-kill-without-query gds-debug-server))
  48. (defun gds-kill-debug-server ()
  49. "Kill the GDS debug server process."
  50. (interactive)
  51. (mapcar (function gds-client-gone)
  52. (mapcar (function car) gds-client-info))
  53. (condition-case nil
  54. (progn
  55. (kill-process gds-debug-server)
  56. (accept-process-output gds-debug-server 0 200))
  57. (error))
  58. (setq gds-debug-server nil))
  59. ;; Send input to the subprocess.
  60. (defun gds-send (string client)
  61. (with-current-buffer (get-buffer-create "*GDS Transcript*")
  62. (goto-char (point-max))
  63. (insert (number-to-string client) ": (" string ")\n"))
  64. (gds-client-put client 'thread-id nil)
  65. (gds-show-client-status client gds-running-text)
  66. (process-send-string gds-debug-server (format "(%S %s)\n" client string)))
  67. ;;;; Per-client information
  68. (defun gds-client-put (client property value)
  69. (let ((client-info (assq client gds-client-info)))
  70. (if client-info
  71. (let ((prop-info (memq property client-info)))
  72. (if prop-info
  73. (setcar (cdr prop-info) value)
  74. (setcdr client-info
  75. (list* property value (cdr client-info)))))
  76. (setq gds-client-info
  77. (cons (list client property value) gds-client-info)))))
  78. (defun gds-client-get (client property)
  79. (let ((client-info (assq client gds-client-info)))
  80. (and client-info
  81. (cadr (memq property client-info)))))
  82. (defvar gds-client-info '())
  83. (defun gds-get-client-buffer (client)
  84. (let ((existing-buffer (gds-client-get client 'stack-buffer)))
  85. (if (and existing-buffer
  86. (buffer-live-p existing-buffer))
  87. existing-buffer
  88. (let ((new-buffer (generate-new-buffer (gds-client-get client 'name))))
  89. (with-current-buffer new-buffer
  90. (gds-debug-mode)
  91. (setq gds-client client)
  92. (setq gds-stack nil))
  93. (gds-client-put client 'stack-buffer new-buffer)
  94. new-buffer))))
  95. (defun gds-client-gone (client &rest ignored)
  96. ;; Kill the client's stack buffer, if it has one.
  97. (let ((stack-buffer (gds-client-get client 'stack-buffer)))
  98. (if (and stack-buffer
  99. (buffer-live-p stack-buffer))
  100. (kill-buffer stack-buffer)))
  101. ;; Dissociate all the client's associated buffers.
  102. (mapcar (function (lambda (buffer)
  103. (if (buffer-live-p buffer)
  104. (with-current-buffer buffer
  105. (gds-dissociate-buffer)))))
  106. (copy-sequence (gds-client-get client 'associated-buffers)))
  107. ;; Remove this client's record from gds-client-info.
  108. (setq gds-client-info (delq (assq client gds-client-info) gds-client-info)))
  109. (defvar gds-client nil)
  110. (make-variable-buffer-local 'gds-client)
  111. (defvar gds-stack nil)
  112. (make-variable-buffer-local 'gds-stack)
  113. (defvar gds-tweaking nil)
  114. (make-variable-buffer-local 'gds-tweaking)
  115. (defvar gds-selected-frame-index nil)
  116. (make-variable-buffer-local 'gds-selected-frame-index)
  117. ;;;; Debugger protocol
  118. (defun gds-debug-protocol (client form)
  119. (or (eq client '*)
  120. (let ((proc (car form)))
  121. (cond ((eq proc 'name)
  122. ;; (name ...) - client name.
  123. (gds-client-put client 'name (caddr form)))
  124. ((eq proc 'stack)
  125. ;; (stack ...) - stack information.
  126. (with-current-buffer (gds-get-client-buffer client)
  127. (setq gds-stack (cddr form))
  128. (setq gds-tweaking (memq 'instead (cadr gds-stack)))
  129. (setq gds-selected-frame-index (cadr form))
  130. (gds-display-stack)))
  131. ((eq proc 'closed)
  132. ;; (closed) - client has gone/died.
  133. (gds-client-gone client))
  134. ((eq proc 'eval-result)
  135. ;; (eval-result RESULT) - result of evaluation.
  136. (if gds-last-eval-result
  137. (message "%s" (cadr form))
  138. (setq gds-last-eval-result (cadr form))))
  139. ((eq proc 'info-result)
  140. ;; (info-result RESULT) - info about selected frame.
  141. (message "%s" (cadr form)))
  142. ((eq proc 'thread-id)
  143. ;; (thread-id THREAD) - says which client thread is reading.
  144. (let ((thread-id (cadr form))
  145. (debug-thread-id (gds-client-get client 'debug-thread-id)))
  146. (if (and debug-thread-id
  147. (/= thread-id debug-thread-id))
  148. ;; Tell the newly reading thread to go away.
  149. (gds-send "dismiss" client)
  150. ;; Either there's no current debug-thread-id, or
  151. ;; the thread now reading is the debug thread.
  152. (if debug-thread-id
  153. (progn
  154. ;; Reset the debug-thread-id.
  155. (gds-client-put client 'debug-thread-id nil)
  156. ;; Indicate debug status in modelines.
  157. (gds-show-client-status client gds-debug-text))
  158. ;; Indicate normal read status in modelines..
  159. (gds-show-client-status client gds-ready-text)))))
  160. ((eq proc 'debug-thread-id)
  161. ;; (debug-thread-id THREAD) - debug override indication.
  162. (gds-client-put client 'debug-thread-id (cadr form))
  163. ;; If another thread is already reading, send it away.
  164. (if (gds-client-get client 'thread-id)
  165. (gds-send "dismiss" client)))
  166. (t
  167. ;; Non-debug-specific protocol.
  168. (gds-nondebug-protocol client proc (cdr form)))))))
  169. ;;;; Displaying a stack
  170. (define-derived-mode gds-debug-mode
  171. scheme-mode
  172. "Guile-Debug"
  173. "Major mode for debugging a Guile client application."
  174. (use-local-map gds-mode-map))
  175. (defun gds-display-stack-first-line ()
  176. (let ((flags (cadr gds-stack)))
  177. (cond ((memq 'application flags)
  178. (insert "Calling procedure:\n"))
  179. ((memq 'evaluation flags)
  180. (insert "Evaluating expression"
  181. (cond ((stringp gds-tweaking) (format " (tweaked: %s)"
  182. gds-tweaking))
  183. (gds-tweaking " (tweakable)")
  184. (t ""))
  185. ":\n"))
  186. ((memq 'return flags)
  187. (let ((value (cadr (memq 'return flags))))
  188. (while (string-match "\n" value)
  189. (setq value (replace-match "\\n" nil t value)))
  190. (insert "Return value"
  191. (cond ((stringp gds-tweaking) (format " (tweaked: %s)"
  192. gds-tweaking))
  193. (gds-tweaking " (tweakable)")
  194. (t ""))
  195. ": " value "\n")))
  196. ((memq 'error flags)
  197. (let ((value (cadr (memq 'error flags))))
  198. (while (string-match "\n" value)
  199. (setq value (replace-match "\\n" nil t value)))
  200. (insert "Error: " value "\n")))
  201. (t
  202. (insert "Stack: " (prin1-to-string flags) "\n")))))
  203. (defun gds-display-stack ()
  204. (if gds-undisplay-timer
  205. (cancel-timer gds-undisplay-timer))
  206. (setq gds-undisplay-timer nil)
  207. ;(setq buffer-read-only nil)
  208. (mapcar 'delete-overlay
  209. (overlays-in (point-min) (point-max)))
  210. (erase-buffer)
  211. (gds-display-stack-first-line)
  212. (let ((frames (car gds-stack)))
  213. (while frames
  214. (let ((frame-text (cadr (car frames)))
  215. (frame-source (caddr (car frames))))
  216. (while (string-match "\n" frame-text)
  217. (setq frame-text (replace-match "\\n" nil t frame-text)))
  218. (insert " "
  219. (if frame-source "s" " ")
  220. frame-text
  221. "\n"))
  222. (setq frames (cdr frames))))
  223. ;(setq buffer-read-only t)
  224. (gds-show-selected-frame))
  225. (defun gds-tweak (expr)
  226. (interactive "sTweak expression or return value: ")
  227. (or gds-tweaking
  228. (error "The current stack cannot be tweaked"))
  229. (setq gds-tweaking
  230. (if (> (length expr) 0)
  231. expr
  232. t))
  233. (save-excursion
  234. (goto-char (point-min))
  235. (delete-region (point) (progn (forward-line 1) (point)))
  236. (gds-display-stack-first-line)))
  237. (defvar gds-undisplay-timer nil)
  238. (make-variable-buffer-local 'gds-undisplay-timer)
  239. (defvar gds-undisplay-wait 1)
  240. (defun gds-undisplay-buffer ()
  241. (if gds-undisplay-timer
  242. (cancel-timer gds-undisplay-timer))
  243. (setq gds-undisplay-timer
  244. (run-at-time gds-undisplay-wait
  245. nil
  246. (function kill-buffer)
  247. (current-buffer))))
  248. (defun gds-show-selected-frame ()
  249. (setq gds-local-var-cache nil)
  250. (goto-char (point-min))
  251. (forward-line (+ gds-selected-frame-index 1))
  252. (delete-char 3)
  253. (insert "=> ")
  254. (beginning-of-line)
  255. (gds-show-selected-frame-source (caddr (nth gds-selected-frame-index
  256. (car gds-stack)))))
  257. (defun gds-unshow-selected-frame ()
  258. (if gds-frame-source-overlay
  259. (move-overlay gds-frame-source-overlay 0 0))
  260. (save-excursion
  261. (goto-char (point-min))
  262. (forward-line (+ gds-selected-frame-index 1))
  263. (delete-char 3)
  264. (insert " ")))
  265. ;; Overlay used to highlight the source expression corresponding to
  266. ;; the selected frame.
  267. (defvar gds-frame-source-overlay nil)
  268. (defcustom gds-source-file-name-transforms nil
  269. "Alist of regexps and substitutions for transforming Scheme source
  270. file names. Each element in the alist is (REGEXP . SUBSTITUTION).
  271. Each source file name in a Guile backtrace is compared against each
  272. REGEXP in turn until the first one that matches, then `replace-match'
  273. is called with SUBSTITUTION to transform that file name.
  274. This mechanism targets the situation where you are working on a Guile
  275. application and want to install it, in /usr/local say, before each
  276. test run. In this situation, even though Guile is reading your Scheme
  277. files from /usr/local/share/guile, you probably want Emacs to pop up
  278. the corresponding files from your working codebase instead. Therefore
  279. you would add an element to this alist to transform
  280. \"^/usr/local/share/guile/whatever\" to \"~/codebase/whatever\"."
  281. :type '(alist :key-type regexp :value-type string)
  282. :group 'gds)
  283. (defun gds-show-selected-frame-source (source)
  284. ;; Highlight the frame source, if possible.
  285. (if source
  286. (let ((filename (car source))
  287. (client gds-client)
  288. (transforms gds-source-file-name-transforms))
  289. ;; Apply possible transforms to the source file name.
  290. (while transforms
  291. (if (string-match (caar transforms) filename)
  292. (let ((trans-fn (replace-match (cdar transforms)
  293. t nil filename)))
  294. (if (file-readable-p trans-fn)
  295. (setq filename trans-fn
  296. transforms nil))))
  297. (setq transforms (cdr transforms)))
  298. ;; Try to map the (possibly transformed) source file to a
  299. ;; buffer.
  300. (let ((source-buffer (gds-source-file-name-to-buffer filename)))
  301. (if source-buffer
  302. (with-current-buffer source-buffer
  303. (if gds-frame-source-overlay
  304. nil
  305. (setq gds-frame-source-overlay (make-overlay 0 0))
  306. (overlay-put gds-frame-source-overlay 'face 'highlight)
  307. (overlay-put gds-frame-source-overlay
  308. 'help-echo
  309. (function gds-show-local-var)))
  310. ;; Move to source line. Note that Guile line numbering
  311. ;; is 0-based, while Emacs numbering is 1-based.
  312. (save-restriction
  313. (widen)
  314. (goto-line (+ (cadr source) 1))
  315. (move-to-column (caddr source))
  316. (move-overlay gds-frame-source-overlay
  317. (point)
  318. (if (not (looking-at ")"))
  319. (save-excursion (forward-sexp 1) (point))
  320. ;; It seems that the source
  321. ;; coordinates for backquoted
  322. ;; expressions are at the end of the
  323. ;; sexp rather than the beginning...
  324. (save-excursion (forward-char 1)
  325. (backward-sexp 1) (point)))
  326. (current-buffer)))
  327. ;; Record that this source buffer has been touched by a
  328. ;; GDS client process.
  329. (setq gds-last-touched-by client))
  330. (message "Source for this frame cannot be shown: %s:%d:%d"
  331. filename
  332. (cadr source)
  333. (caddr source)))))
  334. (message "Source for this frame was not recorded"))
  335. (gds-display-buffers))
  336. (defvar gds-local-var-cache nil)
  337. (defun gds-show-local-var (window overlay position)
  338. (let ((frame-index gds-selected-frame-index)
  339. (client gds-client))
  340. (with-current-buffer (overlay-buffer overlay)
  341. (save-excursion
  342. (goto-char position)
  343. (let ((gds-selected-frame-index frame-index)
  344. (gds-client client)
  345. (varname (thing-at-point 'symbol))
  346. (state (parse-partial-sexp (overlay-start overlay) (point))))
  347. (when (and gds-selected-frame-index
  348. gds-client
  349. varname
  350. (not (or (nth 3 state)
  351. (nth 4 state))))
  352. (set-text-properties 0 (length varname) nil varname)
  353. (let ((existing (assoc varname gds-local-var-cache)))
  354. (if existing
  355. (cdr existing)
  356. (gds-evaluate varname)
  357. (setq gds-last-eval-result nil)
  358. (while (not gds-last-eval-result)
  359. (accept-process-output gds-debug-server))
  360. (setq gds-local-var-cache
  361. (cons (cons varname gds-last-eval-result)
  362. gds-local-var-cache))
  363. gds-last-eval-result))))))))
  364. (defun gds-source-file-name-to-buffer (filename)
  365. ;; See if filename begins with gds-emacs-buffer-port-name-prefix.
  366. (if (string-match (concat "^"
  367. (regexp-quote gds-emacs-buffer-port-name-prefix))
  368. filename)
  369. ;; It does, so get the named buffer.
  370. (get-buffer (substring filename (match-end 0)))
  371. ;; It doesn't, so treat as a file name.
  372. (and (file-readable-p filename)
  373. (find-file-noselect filename))))
  374. (defun gds-select-stack-frame (&optional frame-index)
  375. (interactive)
  376. (let ((new-frame-index (or frame-index
  377. (gds-current-line-frame-index))))
  378. (or (and (>= new-frame-index 0)
  379. (< new-frame-index (length (car gds-stack))))
  380. (error (if frame-index
  381. "No more frames in this direction"
  382. "No frame here")))
  383. (gds-unshow-selected-frame)
  384. (setq gds-selected-frame-index new-frame-index)
  385. (gds-show-selected-frame)))
  386. (defun gds-up ()
  387. (interactive)
  388. (gds-select-stack-frame (- gds-selected-frame-index 1)))
  389. (defun gds-down ()
  390. (interactive)
  391. (gds-select-stack-frame (+ gds-selected-frame-index 1)))
  392. (defun gds-current-line-frame-index ()
  393. (- (count-lines (point-min)
  394. (save-excursion
  395. (beginning-of-line)
  396. (point)))
  397. 1))
  398. (defun gds-display-buffers ()
  399. (let ((buf (current-buffer)))
  400. ;; If there's already a window showing the buffer, use it.
  401. (let ((window (get-buffer-window buf t)))
  402. (if window
  403. (progn
  404. (make-frame-visible (window-frame window))
  405. (select-window window))
  406. (switch-to-buffer buf)
  407. (setq window (get-buffer-window buf t))))
  408. ;; If there is an associated source buffer, display it as well.
  409. (if (and gds-frame-source-overlay
  410. (overlay-end gds-frame-source-overlay)
  411. (> (overlay-end gds-frame-source-overlay) 1))
  412. (progn
  413. (delete-other-windows)
  414. (let ((window (display-buffer
  415. (overlay-buffer gds-frame-source-overlay))))
  416. (set-window-point window
  417. (overlay-start gds-frame-source-overlay)))))))
  418. ;;;; Debugger commands.
  419. ;; Typically but not necessarily used from the `stack' view.
  420. (defun gds-send-tweaking ()
  421. (if (stringp gds-tweaking)
  422. (gds-send (format "tweak %S" gds-tweaking) gds-client)))
  423. (defun gds-go ()
  424. (interactive)
  425. (gds-send-tweaking)
  426. (gds-send "continue" gds-client)
  427. (gds-unshow-selected-frame)
  428. (gds-undisplay-buffer))
  429. (defvar gds-last-eval-result t)
  430. (defun gds-evaluate (expr)
  431. (interactive "sEvaluate variable or expression: ")
  432. (gds-send (format "evaluate %d %s"
  433. gds-selected-frame-index
  434. (prin1-to-string expr))
  435. gds-client))
  436. (defun gds-frame-info ()
  437. (interactive)
  438. (gds-send (format "info-frame %d" gds-selected-frame-index)
  439. gds-client))
  440. (defun gds-frame-args ()
  441. (interactive)
  442. (gds-send (format "info-args %d" gds-selected-frame-index)
  443. gds-client))
  444. (defun gds-proc-source ()
  445. (interactive)
  446. (gds-send (format "proc-source %d" gds-selected-frame-index)
  447. gds-client))
  448. (defun gds-traps-here ()
  449. (interactive)
  450. (gds-send "traps-here" gds-client))
  451. (defun gds-step-into ()
  452. (interactive)
  453. (gds-send-tweaking)
  454. (gds-send (format "step-into %d" gds-selected-frame-index)
  455. gds-client)
  456. (gds-unshow-selected-frame)
  457. (gds-undisplay-buffer))
  458. (defun gds-step-over ()
  459. (interactive)
  460. (gds-send-tweaking)
  461. (gds-send (format "step-over %d" gds-selected-frame-index)
  462. gds-client)
  463. (gds-unshow-selected-frame)
  464. (gds-undisplay-buffer))
  465. (defun gds-step-file ()
  466. (interactive)
  467. (gds-send-tweaking)
  468. (gds-send (format "step-file %d" gds-selected-frame-index)
  469. gds-client)
  470. (gds-unshow-selected-frame)
  471. (gds-undisplay-buffer))
  472. ;;;; Guile Interaction mode keymap and menu items.
  473. (defvar gds-mode-map (make-sparse-keymap))
  474. (define-key gds-mode-map "c" (function gds-go))
  475. (define-key gds-mode-map "g" (function gds-go))
  476. (define-key gds-mode-map "q" (function gds-go))
  477. (define-key gds-mode-map "e" (function gds-evaluate))
  478. (define-key gds-mode-map "I" (function gds-frame-info))
  479. (define-key gds-mode-map "A" (function gds-frame-args))
  480. (define-key gds-mode-map "S" (function gds-proc-source))
  481. (define-key gds-mode-map "T" (function gds-traps-here))
  482. (define-key gds-mode-map "\C-m" (function gds-select-stack-frame))
  483. (define-key gds-mode-map "u" (function gds-up))
  484. (define-key gds-mode-map [up] (function gds-up))
  485. (define-key gds-mode-map "\C-p" (function gds-up))
  486. (define-key gds-mode-map "d" (function gds-down))
  487. (define-key gds-mode-map [down] (function gds-down))
  488. (define-key gds-mode-map "\C-n" (function gds-down))
  489. (define-key gds-mode-map " " (function gds-step-file))
  490. (define-key gds-mode-map "i" (function gds-step-into))
  491. (define-key gds-mode-map "o" (function gds-step-over))
  492. (define-key gds-mode-map "t" (function gds-tweak))
  493. (defvar gds-menu nil
  494. "Global menu for GDS commands.")
  495. (if nil;gds-menu
  496. nil
  497. (setq gds-menu (make-sparse-keymap "Guile-Debug"))
  498. (define-key gds-menu [traps-here]
  499. '(menu-item "Show Traps Here" gds-traps-here))
  500. (define-key gds-menu [proc-source]
  501. '(menu-item "Show Procedure Source" gds-proc-source))
  502. (define-key gds-menu [frame-args]
  503. '(menu-item "Show Frame Args" gds-frame-args))
  504. (define-key gds-menu [frame-info]
  505. '(menu-item "Show Frame Info" gds-frame-info))
  506. (define-key gds-menu [separator-1]
  507. '("--"))
  508. (define-key gds-menu [evaluate]
  509. '(menu-item "Evaluate..." gds-evaluate))
  510. (define-key gds-menu [separator-2]
  511. '("--"))
  512. (define-key gds-menu [down]
  513. '(menu-item "Move Down A Frame" gds-down))
  514. (define-key gds-menu [up]
  515. '(menu-item "Move Up A Frame" gds-up))
  516. (define-key gds-menu [separator-3]
  517. '("--"))
  518. (define-key gds-menu [step-over]
  519. '(menu-item "Step Over Current Expression" gds-step-over))
  520. (define-key gds-menu [step-into]
  521. '(menu-item "Step Into Current Expression" gds-step-into))
  522. (define-key gds-menu [step-file]
  523. '(menu-item "Step Through Current Source File" gds-step-file))
  524. (define-key gds-menu [separator-4]
  525. '("--"))
  526. (define-key gds-menu [go]
  527. '(menu-item "Go [continue execution]" gds-go))
  528. (define-key gds-mode-map [menu-bar gds-debug]
  529. (cons "Guile-Debug" gds-menu)))
  530. ;;;; Autostarting the GDS server.
  531. (defcustom gds-autorun-debug-server t
  532. "Whether to automatically run the GDS server when `gds.el' is loaded."
  533. :type 'boolean
  534. :group 'gds)
  535. (defcustom gds-server-socket-type 'tcp
  536. "What kind of socket the GDS server should listen on."
  537. :group 'gds
  538. :type '(choice (const :tag "TCP" tcp)
  539. (const :tag "Unix" unix)))
  540. ;;;; If requested, autostart the server after loading.
  541. (if (and gds-autorun-debug-server
  542. (not gds-debug-server))
  543. (gds-run-debug-server))
  544. ;;;; The end!
  545. (provide 'gds)
  546. ;;; gds.el ends here.