diff options
author | Neil Jerram <neil@ossau.uklinux.net> | 2009-08-27 22:52:20 +0100 |
---|---|---|
committer | Neil Jerram <neil@ossau.uklinux.net> | 2009-08-27 22:52:20 +0100 |
commit | 639bf3e507959ca53fef713306eb33f1074f1588 (patch) | |
tree | f29a7fdd8e296976b041388892f68c97bc7469b2 /emacs | |
parent | cdc4f3db09727cc1613f7a2fd2335efa10a9d53f (diff) | |
parent | 8a40db3714628f88b138017835d448231257d13b (diff) |
Merge branch 'ossau-gds-dev'
Conflicts:
THANKS
Diffstat (limited to 'emacs')
-rwxr-xr-x | emacs/gds-faq.txt | 225 | ||||
-rw-r--r-- | emacs/gds-server.el | 19 | ||||
-rw-r--r-- | emacs/gds-test.el | 166 | ||||
-rwxr-xr-x | emacs/gds-test.sh | 2 | ||||
-rw-r--r-- | emacs/gds-test.stdin | 1 | ||||
-rwxr-xr-x | emacs/gds-tutorial.txt | 223 | ||||
-rw-r--r-- | emacs/gds.el | 27 |
7 files changed, 645 insertions, 18 deletions
diff --git a/emacs/gds-faq.txt b/emacs/gds-faq.txt new file mode 100755 index 000000000..b60a2c9ae --- /dev/null +++ b/emacs/gds-faq.txt @@ -0,0 +1,225 @@ + +* Installation + +** How do I install guile-debugging? + +After unpacking the .tar.gz file, run the usual sequence of commands: + +$ ./configure +$ make +$ sudo make install + +Then you need to make sure that the directory where guile-debugging's +Scheme files were installed is included in your Guile's load path. +(The sequence above will usually install guile-debugging under +/usr/local, and /usr/local is not in Guile's load path by default, +unless Guile itself was installed under /usr/local.) You can discover +your Guile's default load path by typing + +$ guile -q -c '(begin (write %load-path) (newline))' + +There are two ways to add guile-debugging's installation directory to +Guile's load path, if it isn't already there. + +1. Edit or create the `init.scm' file, which Guile reads on startup, + so that it includes a line like this: + + (set! %load-path (cons "/usr/local/share/guile" %load-path)) + + but with "/usr/local" replaced by the prefix that you installed + guile-debugging under, if not /usr/local. + + The init.scm file must be installed (if it does not already exist + there) in one of the directories in Guile's default load-path. + +2. Add this line to your .emacs file: + + (setq gds-scheme-directory "/usr/local/share/guile") + + before the `require' or `load' line that loads GDS, but with + "/usr/local" replaced by the prefix that you installed + guile-debugging under, if not /usr/local. + +Finally, if you want guile-debugging's GDS interface to be loaded +automatically whenever you run Emacs, add this line to your .emacs: + +(require 'gds) + +* Troubleshooting + +** "error in process filter" when starting Emacs (or loading GDS) + +This is caused by an internal error in GDS's Scheme code, for which a +backtrace will have appeared in the gds-debug buffer, so please switch +to the gds-debug buffer and see what it says there. + +The most common cause is a load path problem: Guile cannot find GDS's +Scheme code because it is not in the known load path. In this case +you should see the error message "no code for module" somewhere in the +backtrace. If you see this, please try the remedies described in `How +do I install guile-debugging?' above, then restart Emacs and see if +the problem has been cured. + +If you don't see "no code for module", or if the described remedies +don't fix the problem, please send the contents of the gds-debug +buffer to me at <neil@ossau.uklinux.net>, so I can debug the problem. + +If you don't see a backtrace at all in the gds-debug buffer, try the +next item ... + +** "error in process filter" at some other time + +This is caused by an internal error somewhere in GDS's Emacs Lisp +code. If possible, please + +- switch on the `debug-on-error' option (M-x set-variable RET + debug-on-error RET t RET) + +- do whatever you were doing so that the same error happens again + +- send the Emacs Lisp stack trace which pops up to me at + <neil@ossau.uklinux.net>. + +If that doesn't work, please just mail me with as much detail as +possible of what you were doing when the error occurred. + +* GDS Features + +** How do I inspect variable values? + +Type `e' followed by the name of the variable, then <RET>. This +works whenever GDS is displaying a stack for an error at at a +breakpoint. (You can actually `e' to evaluate any expression in the +local environment of the selected stack frame; inspecting variables is +the special case of this where the expression is only a variable name.) + +If GDS is displaying the associated source code in the window above or +below the stack, you can see the values of any variables in the +highlighted code just by hovering your mouse over them. + +** How do I change a variable's value? + +Type `e' and then `(set! VARNAME NEWVAL)', where VARNAME is the name +of the variable you want to set and NEWVAL is an expression which +Guile can evaluate to get the new value. This works whenever GDS is +displaying a stack for an error at at a breakpoint. The setting will +take effect in the local environment of the selected stack frame. + +** How do I change the expression that Guile is about to evaluate? + +Type `t' followed by the expression that you want Guile to evaluate +instead, then <RET>. + +Then type one of the commands that tells Guile to continue execution. + +(Tweaking expressions, as described here, is only supported by the +latest CVS version of Guile. The GDS stack display tells you when +tweaking is possible by adding "(tweakable)" to the first line of the +stack window.) + +** How do I return a value from the current stack frame different to what the evaluator has calculated? + +You have to be at the normal exit of the relevant frame first, so if +GDS is not already showing you the normally calculated return value, +type `o' to finish the evaluation of the selected frame. + +Then type `t' followed by the value you want to return, and <RET>. +The value that you type can be any expression, but note that it will +not be evaluated before being returned; for example if you type `(+ 2 +3)', the return value will be a three-element list, not 5. + +Finally type one of the commands that tells Guile to continue +execution. + +(Tweaking return values, as described here, is only supported by the +latest CVS version of Guile. The GDS stack display tells you when +tweaking is possible by adding "(tweakable)" to the first line of the +stack window.) + +** How do I step over a line of code? + +Scheme isn't organized by lines, so it doesn't really make sense to +think of stepping over lines. Instead please see the next entry on +stepping over expressions. + +** How do I step over an expression? + +It depends what you mean by "step over". If you mean that you want +Guile to evaluate that expression normally, but then show you its +return value, type `o', which does exactly that. + +If you mean that you want to skip the evaluation of that expression +(for example because it has side effects that you don't want to +happen), use `t' to change the expression to something else which +Guile will evaluate instead. + +There has to be a substitute expression so Guile can calculate a value +to return to the calling frame. If you know at a particular point +that the return value is not important, you can type `t #f <RET>' or +`t 0 <RET>'. + +See `How do I change the expression that Guile is about to evaluate?' +above for more on using `t'. + +** How do I move up and down the call stack? + +Type `u' to move up and `d' to move down. "Up" in GDS means to a more +"inner" frame, and "down" means to a more "outer" frame. + +** How do I run until the next breakpoint? + +Type `g' (for "go"). + +** How do I run until the end of the selected stack frame? + +Type `o'. + +** How do I set a breakpoint? + +First identify the code that you want to set the breakpoint in, and +what kind of breakpoint you want. To set a breakpoint on entry to a +top level procedure, move the cursor to anywhere in the procedure +definition, and make sure that the region/mark is inactive. To set a +breakpoint on a particular expression (or sequence of expressions) set +point and mark so that the region covers the opening parentheses of +all the target expressions. + +Then type ... + + `C-c C-b d' for a `debug' breakpoint, which means that GDS will + display the stack when the breakpoint is hit + + `C-c C-b t' for a `trace' breakpoint, which means that the start and + end of the relevant procedure or expression(s) will be traced to the + *GDS Trace* buffer + + `C-c C-b T' for a `trace-subtree' breakpoint, which means that every + evaluation step involved in the evaluation of the relevant procedure + or expression(s) will be traced to the *GDS Trace* buffer. + +You can also type `C-x <SPC>', which does the same as one of the +above, depending on the value of `gds-default-breakpoint-type'. + +** How do I clear a breakpoint? + +Select a region containing the breakpoints that you want to clear, and +type `C-c C-b <DEL>'. + +** How do I trace calls to a particular procedure or evaluations of a particular expression? + +In GDS this means setting a breakpoint whose type is `trace' or +`trace-subtree'. See `How do I set a breakpoint?' above. + +* Development + +** How can I follow or contribute to guile-debugging's development? + +guile-debugging is hosted at http://gna.org, so please see the project +page there. Feel free to raise bugs, tasks containing patches or +feature requests, and so on. You can also write directly to me by +email: <neil@ossau.uklinux.net>. + + +Local Variables: +mode: outline +End: diff --git a/emacs/gds-server.el b/emacs/gds-server.el index d4fe997c2..9cfcd3aab 100644 --- a/emacs/gds-server.el +++ b/emacs/gds-server.el @@ -43,25 +43,24 @@ :group 'gds :type '(choice (const :tag "nil" nil) directory)) -(defun gds-start-server (procname port-or-path protocol-handler &optional bufname) - "Start a GDS server process called PROCNAME, listening on TCP port -or Unix domain socket PORT-OR-PATH. PROTOCOL-HANDLER should be a -function that accepts and processes one protocol form. Optional arg -BUFNAME specifies the name of the buffer that is used for process -output; if not specified the buffer name is the same as the process -name." - (with-current-buffer (get-buffer-create (or bufname procname)) +(defun gds-start-server (procname unix-socket-name tcp-port protocol-handler) + "Start a GDS server process called PROCNAME, listening on Unix +domain socket UNIX-SOCKET-NAME and TCP port number TCP-PORT. +PROTOCOL-HANDLER should be a function that accepts and processes +one protocol form." + (with-current-buffer (get-buffer-create procname) (erase-buffer) (let* ((code (format "(begin %s (use-modules (ice-9 gds-server)) - (run-server %S))" + (run-server %S %S))" (if gds-scheme-directory (concat "(set! %load-path (cons " (format "%S" gds-scheme-directory) " %load-path))") "") - port-or-path)) + unix-socket-name + tcp-port)) (process-connection-type nil) ; use a pipe (proc (start-process procname (current-buffer) diff --git a/emacs/gds-test.el b/emacs/gds-test.el new file mode 100644 index 000000000..dfd4f6c7b --- /dev/null +++ b/emacs/gds-test.el @@ -0,0 +1,166 @@ + +;; Test utility code. +(defun gds-test-execute-keys (keys &optional keys2) + (execute-kbd-macro (apply 'vector (listify-key-sequence keys)))) + +(defvar gds-test-expecting nil) + +(defun gds-test-protocol-hook (form) + (message "[protocol: %s]" (car form)) + (if (eq (car form) gds-test-expecting) + (setq gds-test-expecting nil))) + +(defun gds-test-expect-protocol (proc &optional timeout) + (message "[expect: %s]" proc) + (setq gds-test-expecting proc) + (while gds-test-expecting + (or (accept-process-output gds-debug-server (or timeout 5)) + (error "Timed out after %ds waiting for %s" (or timeout 5) proc)))) + +(defun gds-test-check-buffer (name &rest strings) + (let ((buf (or (get-buffer name) (error "No %s buffer" name)))) + (save-excursion + (set-buffer buf) + (goto-char (point-min)) + (while strings + (search-forward (car strings)) + (setq strings (cdr strings)))))) + +(defun TEST (desc) + (message "TEST: %s" desc)) + +;; Make sure we take GDS elisp code from this code tree. +(setq load-path (cons (concat default-directory "emacs/") load-path)) + +;; Protect the tests so we can do some cleanups in case of error. +(unwind-protect + (progn + + ;; Visit the tutorial. + (find-file "gds-tutorial.txt") + + (TEST "Load up GDS.") + (search-forward "(require 'gds)") + (setq load-path (cons (concat default-directory "emacs/") load-path)) + (gds-test-execute-keys "\C-x\C-e") + + ;; Install our testing hook. + (add-hook 'gds-protocol-hook 'gds-test-protocol-hook) + + (TEST "Help.") + (search-forward "(list-ref") + (backward-char 2) + (gds-test-execute-keys "\C-hg\C-m") + (gds-test-expect-protocol 'eval-results 10) + (gds-test-check-buffer "*Guile Help*" + "help list-ref" + "is a primitive procedure in the (guile) module") + + (TEST "Completion.") + (re-search-forward "^with-output-to-s") + (gds-test-execute-keys "\e\C-i") + (beginning-of-line) + (or (looking-at "with-output-to-string") + (error "Expected completion `with-output-to-string' failed")) + + (TEST "Eval defun.") + (search-forward "(display z)") + (gds-test-execute-keys "\e\C-x") + (gds-test-expect-protocol 'eval-results) + (gds-test-check-buffer "*Guile Evaluation*" + "(let ((x 1) (y 2))" + "Arctangent is: 0.46" + "=> 0.46") + + (TEST "Multiple values.") + (search-forward "(values 'a ") + (gds-test-execute-keys "\e\C-x") + (gds-test-expect-protocol 'eval-results) + (gds-test-check-buffer "*Guile Evaluation*" + "(values 'a" + "hello world" + "=> a" + "=> b" + "=> c") + + (TEST "Eval region with multiple expressions.") + (search-forward "(display \"Arctangent is: \")") + (beginning-of-line) + (push-mark nil nil t) + (forward-line 3) + (gds-test-execute-keys "\C-c\C-r") + (gds-test-expect-protocol 'eval-results) + (gds-test-check-buffer "*Guile Evaluation*" + "(display \"Arctangent is" + "Arctangent is:" + "=> no (or unspecified) value" + "ERROR: Unbound variable: z" + "=> error-in-evaluation" + "Evaluating expression 3" + "=> no (or unspecified) value") + + (TEST "Eval syntactically unbalanced region.") + (search-forward "(let ((z (atan x y)))") + (beginning-of-line) + (push-mark nil nil t) + (forward-line 4) + (gds-test-execute-keys "\C-c\C-r") + (gds-test-expect-protocol 'eval-results) + (gds-test-check-buffer "*Guile Evaluation*" + "(let ((z (atan" + "Reading expressions to evaluate" + "ERROR" + "end of file" + "=> error-in-read") + + (TEST "Stepping through an evaluation.") + (search-forward "(for-each (lambda (x)") + (forward-line 1) + (push-mark nil nil t) + (forward-line 1) + (gds-test-execute-keys "\C-u\e\C-x") + (gds-test-expect-protocol 'stack) + (gds-test-execute-keys " ") + (gds-test-expect-protocol 'stack) + (gds-test-execute-keys "o") + (gds-test-expect-protocol 'stack) + (gds-test-execute-keys "o") + (gds-test-expect-protocol 'stack) + (gds-test-execute-keys "o") + (gds-test-expect-protocol 'stack) + (gds-test-execute-keys "o") + (gds-test-expect-protocol 'stack) + (gds-test-execute-keys "o") + (gds-test-expect-protocol 'stack) + (gds-test-execute-keys "o") + (gds-test-expect-protocol 'stack) + (gds-test-execute-keys "o") + (gds-test-expect-protocol 'stack) + (gds-test-execute-keys "o") + (gds-test-expect-protocol 'stack) + (gds-test-execute-keys "o") + (gds-test-expect-protocol 'stack) + (gds-test-execute-keys "o") + (gds-test-expect-protocol 'stack) + (gds-test-execute-keys "g") + (gds-test-expect-protocol 'eval-results) + (gds-test-check-buffer "*Guile Evaluation*" + "(for-each (lambda" + "Evaluating in current module" + "3 cubed is 27" + "=> no (or unspecified) value") + + ;; Done. + (message "====================================") + (message "gds-test.el completed without errors") + (message "====================================") + + ) + + (switch-to-buffer "gds-debug") + (write-region (point-min) (point-max) "gds-test.debug") + + (switch-to-buffer "*GDS Transcript*") + (write-region (point-min) (point-max) "gds-test.transcript") + + ) diff --git a/emacs/gds-test.sh b/emacs/gds-test.sh new file mode 100755 index 000000000..2f8ddff9f --- /dev/null +++ b/emacs/gds-test.sh @@ -0,0 +1,2 @@ +#!/bin/sh +GUILE_LOAD_PATH=$(pwd) emacs --batch --no-site-file -q -l gds-test.el < gds-test.stdin diff --git a/emacs/gds-test.stdin b/emacs/gds-test.stdin new file mode 100644 index 000000000..8b1378917 --- /dev/null +++ b/emacs/gds-test.stdin @@ -0,0 +1 @@ + diff --git a/emacs/gds-tutorial.txt b/emacs/gds-tutorial.txt new file mode 100755 index 000000000..4254803ec --- /dev/null +++ b/emacs/gds-tutorial.txt @@ -0,0 +1,223 @@ + +;; Welcome to the GDS tutorial! + +;; This tutorial teaches the use of GDS by leading you through a set +;; of examples where you actually use GDS, in Emacs, along the way. +;; To get maximum benefit, therefore, you should be reading this +;; tutorial in Emacs. + +;; ** GDS setup + +;; The first thing to do, if you haven't already, is to load the GDS +;; library into Emacs. The Emacs Lisp expression for this is: + +(require 'gds) + +;; So, if you don't already have this in your .emacs, either add it +;; and then restart Emacs, or evaluate it just for this Emacs session +;; by moving the cursor to just after the closing parenthesis and +;; typing `C-x C-e'. + +;; (Note that if you _have_ already loaded GDS, and you type `C-x C-e' +;; after this expression, you will see a *Guile Evaluation* window +;; telling you that the evaluation failed because `require' is +;; unbound. Don't worry; this is not a problem, and the rest of the +;; tutorial should still work just fine.) + +;; ** Help + +;; GDS makes it easy to access the Guile help system when working on a +;; Scheme program in Emacs. For example, suppose that you are writing +;; code that uses list-ref, and need to remind yourself about +;; list-ref's arguments ... + +(define (penultimate l) + (list-ref + +;; Just place the cursor on the word "list-ref" and type `C-h g RET'. +;; Try it now! + +;; If GDS is working correctly, a window should have popped up above +;; or below showing the Guile help for list-ref. + +;; You can also do an "apropos" search through Guile's help. If you +;; couldn't remember the name list-ref, for example, you could search +;; for anything matching "list" by typing `C-h C-g' and entering +;; "list" at the minibuffer prompt. Try doing this now: you should +;; see a longish list of Guile definitions whose names include "list". +;; As usual in Emacs, you can use `M-PageUp' and `M-PageDown' to +;; conveniently scroll the other window without having to select it. + +;; The functions called by `C-h g' and `C-h C-g' are gds-help-symbol +;; and gds-apropos. They both look up the symbol or word at point by +;; default, but that default can be overidden by typing something else +;; at the minibuffer prompt. + +;; ** Completion + +;; As you are typing Scheme code, you can ask GDS to complete the +;; symbol before point for you, by typing `ESC TAB'. GDS selects +;; possible completions by matching the text so far against all +;; definitions in the Guile environment. (This may be contrasted with +;; the "dabbrev" completion performed by `M-/', which selects possible +;; completions from the contents of Emacs buffers. So, if you are +;; trying to complete "with-ou", to get "with-output-to-string", for +;; example, `ESC TAB' will always work, because with-output-to-string +;; is always defined in Guile's default environment, whereas `M-/' +;; will only work if one of Emacs's buffers happens to contain the +;; full name "with-output-to-string".) + +;; To illustrate the idea, here are some partial names that you can +;; try completing. For each one, move the cursor to the end of the +;; line and type `ESC TAB' to try to complete it. + +list- +with-ou +with-output-to-s +mkst + +;; (If you are not familiar with any of the completed definitions, +;; feel free to use `C-h g' to find out about them!) + +;; ** Evaluation + +;; GDS provides several ways for you to evaluate Scheme code from +;; within Emacs. + +;; Just like in Emacs Lisp, a single expression in a buffer can be +;; evaluated using `C-x C-e' or `C-M-x'. For `C-x C-e', the +;; expression is that which ends immediately before point (so that it +;; is useful for evaluating something just after you have typed it). +;; For `C-M-x', the expression is the "top level defun" around point; +;; this means the balanced chunk of code around point whose opening +;; parenthesis is in column 0. + +;; Take this code fragment as an example: + +(let ((x 1) (y 2)) + (let ((z (atan x y))) + (display "Arctangent is: ") + (display z) + (newline) + z)) + +;; If you move the cursor to the end of the (display z) line and type +;; `C-x C-e', the code evaluated is just "(display z)", which normally +;; produces an error, because z is not defined in the usual Guile +;; environment. If, however, you type `C-M-x' with the cursor in the +;; same place, the code evaluated is the whole "(let ((x 1) (y 2)) +;; ...)" kaboodle, because that is the most recent expression before +;; point that starts in column 0. + +;; Try these now. The Guile Evaluation window should pop up again, +;; and show you: +;; - the expression that was evaluated (probably abbreviated) +;; - the module that it was evaluated in +;; - anything that the code wrote to its standard output +;; - the return value(s) of the evaluation. +;; Following the convention of the Emacs Lisp and Guile manuals, +;; return values are indicated by the symbol "=>". + +;; To see what happens when an expression has multiple return values, +;; try evaluating this one: + +(values 'a (begin (display "hello world\n") 'b) 'c) + +;; You can also evaluate a region of a buffer using `C-c C-r'. If the +;; code in the region consists of multiple expressions, GDS evaluates +;; them sequentially. For example, try selecting the following three +;; lines and typing `C-c C-r'. + + (display "Arctangent is: ") + (display z) + (newline) + +;; If the code in the region evaluated isn't syntactically balanced, +;; GDS will indicate a read error, for example for this code: + + (let ((z (atan x y))) + (display "Arctangent is: ") + (display z) + (newline) + +;; Finally, if you want to evaluate something quickly that is not in a +;; buffer, you can use `C-c C-e' and type the code to evaluate at the +;; minibuffer prompt. The results are popped up in the same way as +;; for code from a buffer. + +;; ** Breakpoints + +;; Before evaluating Scheme code from an Emacs buffer, you may want to +;; set some breakpoints in it. With GDS you can set breakpoints in +;; Scheme code by typing `C-x SPC'. +;; +;; To see how this works, select the second line of the following code +;; (the `(format ...)' line) and type `C-x SPC'. + +(for-each (lambda (x) + (format #t "~A cubed is ~A\n" x (* x x x))) + (iota 6)) + +;; The two opening parentheses in that line should now be highlighted +;; in red, to show that breakpoints have been set at the start of the +;; `(format ...)' and `(* x x x)' expressions. Then evaluate the +;; whole for-each expression by typing `C-M-x' ... +;; +;; In the upper half of your Emacs, a buffer appears showing you the +;; Scheme stack. +;; +;; In the lower half, the `(format ...)' expression is highlighted. +;; +;; What has happened is that Guile started evaluating the for-each +;; code, but then hit the breakpoint that you set on the start of the +;; format expression. Guile therefore pauses the evaluation at that +;; point and passes the stack (which encapsulates everything that is +;; interesting about the state of Guile at that point) to GDS. You +;; can then explore the stack and decide how to tell Guile to +;; continue. +;; +;; - If you move your mouse over any of the identifiers in the +;; highlighted code, a help echo (or tooltip) will appear to tell +;; you that identifier's current value. (Note though that this only +;; works when the stack buffer is selected. So if you have switched +;; to this buffer in order to scroll down and read these lines, you +;; will need to switch back to the stack buffer before trying this +;; out.) +;; +;; - In the stack buffer, the "=>" on the left shows you that the top +;; frame is currently selected. You can move up and down the stack +;; by pressing the up and down arrows (or `u' and `d'). As you do +;; this, GDS will change the highlight in the lower window to show +;; the code that corresponds to the selected stack frame. +;; +;; - You can evaluate an arbitrary expression in the local environment +;; of the selected stack frame by typing `e' followed by the +;; expression. +;; +;; - You can show various bits of information about the selected frame +;; by typing `I', `A' and `S'. Feel free to try these now, to see +;; what they do. +;; +;; You also have control over the continuing evaluation of this code. +;; Here are some of the things you can do - please try them as you +;; read. +;; +;; - `g' tells Guile to continue execution normally. In this case +;; that means that evaluation will continue until it hits the next +;; breakpoint, which is on the `(* x x x)' expression. +;; +;; - `SPC' tells Guile to continue until the next significant event in +;; the same source file as the selected frame. A "significant +;; event" means either beginning to evaluate an expression in the +;; relevant file, or completing such an evaluation, in which case +;; GDS tells you the value that it is returning. Pressing `SPC' +;; repeatedly is a nice way to step through all the details of the +;; code in a given file, but stepping over calls that involve code +;; from other files. +;; +;; - `o' tells Guile to continue execution until the selected stack +;; frame completes, and then to show its return value. + +;; Local Variables: +;; mode: scheme +;; End: diff --git a/emacs/gds.el b/emacs/gds.el index a9450d065..991ba7504 100644 --- a/emacs/gds.el +++ b/emacs/gds.el @@ -36,10 +36,11 @@ ;; The subprocess object for the debug server. (defvar gds-debug-server nil) -(defvar gds-socket-type-alist '((tcp . 8333) - (unix . "/tmp/.gds_socket")) - "Maps each of the possible socket types that the GDS server can -listen on to the path that it should bind to for each one.") +(defvar gds-unix-socket-name (format "/tmp/.gds-socket-%d" (emacs-pid)) + "Name of the Unix domain socket that GDS will listen on.") + +(defvar gds-tcp-port 8333 + "The TCP port number that GDS will listen on.") (defun gds-run-debug-server () "Start (or restart, if already running) the GDS debug server process." @@ -47,10 +48,14 @@ listen on to the path that it should bind to for each one.") (if gds-debug-server (gds-kill-debug-server)) (setq gds-debug-server (gds-start-server "gds-debug" - (cdr (assq gds-server-socket-type - gds-socket-type-alist)) + gds-unix-socket-name + gds-tcp-port 'gds-debug-protocol)) - (process-kill-without-query gds-debug-server)) + (process-kill-without-query gds-debug-server) + ;; Add the Unix socket name to the environment, so that Guile + ;; clients started from within this Emacs will be able to use it, + ;; and thereby ensure that they connect to the GDS in this Emacs. + (setenv "GDS_UNIX_SOCKET_NAME" gds-unix-socket-name)) (defun gds-kill-debug-server () "Kill the GDS debug server process." @@ -137,7 +142,13 @@ listen on to the path that it should bind to for each one.") ;;;; Debugger protocol +(defcustom gds-protocol-hook nil + "Hook called on receipt of a protocol form from the GDS client." + :type 'hook + :group 'gds) + (defun gds-debug-protocol (client form) + (run-hook-with-args 'gds-protocol-hook form) (or (eq client '*) (let ((proc (car form))) (cond ((eq proc 'name) @@ -610,7 +621,7 @@ you would add an element to this alist to transform :group 'gds) (defcustom gds-server-socket-type 'tcp - "What kind of socket the GDS server should listen on." + "This option is now obsolete and has no effect." :group 'gds :type '(choice (const :tag "TCP" tcp) (const :tag "Unix" unix))) |