mirror of
https://git.savannah.gnu.org/git/guile.git
synced 2025-04-30 03:40:34 +02:00
* gds.el (gds-handle-client-input): Handle new `thread-status'
protocol. (gds-display-slow-eval): New. (gds-client-ref): Bugfix: buf -> (cdr buf). (gds-display-buffers): Bugfix: minimum overlay end value is 1, not 0. (gds-evals-in-progress): New. (gds-results): New. (gds-insert-interaction): Show evaluations in progress (with button to interrupt them) and results of last help or evaluation. (gds-interrupt-eval): New. (gds-debug-trap-hooks, gds-up, gds-down): New. (gds-eval-region, gds-eval-expression): Include abbreviated code in eval correlator. (gds-abbreviated-length, gds-abbreviated): New. (gds-mode-map): New keys for gds-debug-trap-hooks, gds-up, gds-down. (gds-debug-menu): New menu entries for gds-up, gds-down. * gds-client.scm (gds-connect): Enable trapping for gds-eval stacks. (ui-read-thread-proc): Write 'running status earlier. (stack->emacs-readable): Limit stack length to 'depth debug option. (handle-instruction): Update format of eval correlator. (handle-instruction-1): Resolve module names from root module instead of from current module. (resolve-module-from-root): New. (handle-instruction-1): New protocol `interrupt-eval'. (eval-thread-table): New. (eval-thread): Add thread to eval-thread-table; write new protocol to frontend to communicate eval thread status; update for new correlator format; bind correlator local before entering loop2. (gds-eval): Use start-stack 'gds-eval-stack to rebase stack. * gds.el (gds-start, gds-start-captive): Do `process-kill-without-query' as soon as processes started, ... (gds-shutdown, gds-kill-captive): ... instead of here. (gds-display-results): More clearly show unspecified results; show results in interaction view instead of in separate window. (gds-send): Add sent protocol to transcript.
This commit is contained in:
parent
328df3e3be
commit
15e6a33592
4 changed files with 240 additions and 59 deletions
|
@ -1,2 +1,6 @@
|
||||||
Makefile
|
Makefile
|
||||||
Makefile.in
|
Makefile.in
|
||||||
|
version.texi
|
||||||
|
*.info
|
||||||
|
stamp-vti
|
||||||
|
mdate-sh
|
||||||
|
|
|
@ -1,3 +1,47 @@
|
||||||
|
2004-01-28 Neil Jerram <neil@ossau.uklinux.net>
|
||||||
|
|
||||||
|
* gds.el (gds-handle-client-input): Handle new `thread-status'
|
||||||
|
protocol.
|
||||||
|
(gds-display-slow-eval): New.
|
||||||
|
(gds-client-ref): Bugfix: buf -> (cdr buf).
|
||||||
|
(gds-display-buffers): Bugfix: minimum overlay end value is 1, not
|
||||||
|
0.
|
||||||
|
(gds-evals-in-progress): New.
|
||||||
|
(gds-results): New.
|
||||||
|
(gds-insert-interaction): Show evaluations in progress (with
|
||||||
|
button to interrupt them) and results of last help or evaluation.
|
||||||
|
(gds-interrupt-eval): New.
|
||||||
|
(gds-debug-trap-hooks, gds-up, gds-down): New.
|
||||||
|
(gds-eval-region, gds-eval-expression): Include abbreviated code
|
||||||
|
in eval correlator.
|
||||||
|
(gds-abbreviated-length, gds-abbreviated): New.
|
||||||
|
(gds-mode-map): New keys for gds-debug-trap-hooks, gds-up,
|
||||||
|
gds-down.
|
||||||
|
(gds-debug-menu): New menu entries for gds-up, gds-down.
|
||||||
|
|
||||||
|
* gds-client.scm (gds-connect): Enable trapping for gds-eval
|
||||||
|
stacks.
|
||||||
|
(ui-read-thread-proc): Write 'running status earlier.
|
||||||
|
(stack->emacs-readable): Limit stack length to 'depth debug
|
||||||
|
option.
|
||||||
|
(handle-instruction): Update format of eval correlator.
|
||||||
|
(handle-instruction-1): Resolve module names from root module
|
||||||
|
instead of from current module.
|
||||||
|
(resolve-module-from-root): New.
|
||||||
|
(handle-instruction-1): New protocol `interrupt-eval'.
|
||||||
|
(eval-thread-table): New.
|
||||||
|
(eval-thread): Add thread to eval-thread-table; write new protocol
|
||||||
|
to frontend to communicate eval thread status; update for new
|
||||||
|
correlator format; bind correlator local before entering loop2.
|
||||||
|
(gds-eval): Use start-stack 'gds-eval-stack to rebase stack.
|
||||||
|
|
||||||
|
* gds.el (gds-start, gds-start-captive): Do
|
||||||
|
`process-kill-without-query' as soon as processes started, ...
|
||||||
|
(gds-shutdown, gds-kill-captive): ... instead of here.
|
||||||
|
(gds-display-results): More clearly show unspecified results; show
|
||||||
|
results in interaction view instead of in separate window.
|
||||||
|
(gds-send): Add sent protocol to transcript.
|
||||||
|
|
||||||
2004-01-26 Neil Jerram <neil@ossau.uklinux.net>
|
2004-01-26 Neil Jerram <neil@ossau.uklinux.net>
|
||||||
|
|
||||||
* gds.el (gds-request-focus, gds-quit): Simplify. Old algorithm
|
* gds.el (gds-request-focus, gds-quit): Simplify. Old algorithm
|
||||||
|
|
|
@ -23,6 +23,7 @@
|
||||||
#:use-module (ice-9 debugger breakpoints procedural)
|
#:use-module (ice-9 debugger breakpoints procedural)
|
||||||
#:use-module (ice-9 debugger breakpoints source)
|
#:use-module (ice-9 debugger breakpoints source)
|
||||||
#:use-module (ice-9 debugger state)
|
#:use-module (ice-9 debugger state)
|
||||||
|
#:use-module (ice-9 debugger trap-hooks)
|
||||||
#:use-module (ice-9 debugger utils)
|
#:use-module (ice-9 debugger utils)
|
||||||
#:use-module (ice-9 optargs)
|
#:use-module (ice-9 optargs)
|
||||||
#:use-module (ice-9 regex)
|
#:use-module (ice-9 regex)
|
||||||
|
@ -101,6 +102,7 @@ decimal IP address where the UI server is running; default is
|
||||||
"w"))
|
"w"))
|
||||||
;; Announce ourselves to the server.
|
;; Announce ourselves to the server.
|
||||||
(write-form (list 'name name (getpid)))
|
(write-form (list 'name name (getpid)))
|
||||||
|
(add-trapped-stack-id! 'gds-eval-stack)
|
||||||
;; Start the UI read thread.
|
;; Start the UI read thread.
|
||||||
(set! ui-read-thread (make-thread ui-read-thread-proc)))
|
(set! ui-read-thread (make-thread ui-read-thread-proc)))
|
||||||
|
|
||||||
|
@ -124,6 +126,7 @@ decimal IP address where the UI server is running; default is
|
||||||
;; this purpose. This design avoids having to modify application code
|
;; this purpose. This design avoids having to modify application code
|
||||||
;; at the expense of requiring a Guile with threads support.
|
;; at the expense of requiring a Guile with threads support.
|
||||||
(define (ui-read-thread-proc)
|
(define (ui-read-thread-proc)
|
||||||
|
(write-status 'running)
|
||||||
(let ((eval-thread-needed? #t))
|
(let ((eval-thread-needed? #t))
|
||||||
;; Start up the default eval thread.
|
;; Start up the default eval thread.
|
||||||
(make-thread eval-thread 1 (lambda () (not eval-thread-needed?)))
|
(make-thread eval-thread 1 (lambda () (not eval-thread-needed?)))
|
||||||
|
@ -269,7 +272,8 @@ decimal IP address where the UI server is running; default is
|
||||||
;; Return Emacs-readable representation of STACK.
|
;; Return Emacs-readable representation of STACK.
|
||||||
(map (lambda (index)
|
(map (lambda (index)
|
||||||
(frame->emacs-readable (stack-ref stack index)))
|
(frame->emacs-readable (stack-ref stack index)))
|
||||||
(iota (stack-length stack))))
|
(iota (min (stack-length stack)
|
||||||
|
(cadr (memq 'depth (debug-options)))))))
|
||||||
|
|
||||||
(define (frame->emacs-readable frame)
|
(define (frame->emacs-readable frame)
|
||||||
;; Return Emacs-readable representation of FRAME.
|
;; Return Emacs-readable representation of FRAME.
|
||||||
|
@ -336,7 +340,7 @@ decimal IP address where the UI server is running; default is
|
||||||
(apply throw key args))
|
(apply throw key args))
|
||||||
(else
|
(else
|
||||||
(write-form
|
(write-form
|
||||||
`(eval-results error
|
`(eval-results (error . "")
|
||||||
"GDS Internal Error\n"
|
"GDS Internal Error\n"
|
||||||
,(list (with-output-to-string
|
,(list (with-output-to-string
|
||||||
(lambda ()
|
(lambda ()
|
||||||
|
@ -373,7 +377,7 @@ decimal IP address where the UI server is running; default is
|
||||||
,(or (loaded-module-source name) "(no source file)")
|
,(or (loaded-module-source name) "(no source file)")
|
||||||
,@(sort (module-map (lambda (key value)
|
,@(sort (module-map (lambda (key value)
|
||||||
(symbol->string key))
|
(symbol->string key))
|
||||||
(resolve-module name))
|
(resolve-module-from-root name))
|
||||||
string<?))))
|
string<?))))
|
||||||
state)
|
state)
|
||||||
((debugger-command)
|
((debugger-command)
|
||||||
|
@ -397,7 +401,7 @@ decimal IP address where the UI server is running; default is
|
||||||
(display (cadddr ins))
|
(display (cadddr ins))
|
||||||
(display "' behaviour; doing `debug-here' instead.\n")
|
(display "' behaviour; doing `debug-here' instead.\n")
|
||||||
(debug-here))))
|
(debug-here))))
|
||||||
(module-ref (resolve-module (cadr ins)) (caddr ins)))
|
(module-ref (resolve-module-from-root (cadr ins)) (caddr ins)))
|
||||||
state)
|
state)
|
||||||
((eval)
|
((eval)
|
||||||
(apply (lambda (correlator module port-name line column bpinfo code)
|
(apply (lambda (correlator module port-name line column bpinfo code)
|
||||||
|
@ -406,7 +410,7 @@ decimal IP address where the UI server is running; default is
|
||||||
(set-port-filename! (current-input-port) port-name)
|
(set-port-filename! (current-input-port) port-name)
|
||||||
(set-port-line! (current-input-port) line)
|
(set-port-line! (current-input-port) line)
|
||||||
(set-port-column! (current-input-port) column)
|
(set-port-column! (current-input-port) column)
|
||||||
(let ((m (and module (resolve-module module))))
|
(let ((m (and module (resolve-module-from-root module))))
|
||||||
(let loop ((exprs '()) (x (read)))
|
(let loop ((exprs '()) (x (read)))
|
||||||
(if (eof-object? x)
|
(if (eof-object? x)
|
||||||
;; Expressions to be evaluated have all been
|
;; Expressions to be evaluated have all been
|
||||||
|
@ -468,11 +472,23 @@ decimal IP address where the UI server is running; default is
|
||||||
(debug-stack (make-stack #t 3) #:continuable))
|
(debug-stack (make-stack #t 3) #:continuable))
|
||||||
thread))
|
thread))
|
||||||
state)
|
state)
|
||||||
|
((interrupt-eval)
|
||||||
|
(let ((thread (hash-ref eval-thread-table (cadr ins))))
|
||||||
|
(system-async-mark (lambda ()
|
||||||
|
(debug-stack (make-stack #t 3) #:continuable))
|
||||||
|
thread))
|
||||||
|
state)
|
||||||
(else state)))
|
(else state)))
|
||||||
|
|
||||||
(define the-ice-9-debugger-commands-module
|
(define the-ice-9-debugger-commands-module
|
||||||
(resolve-module '(ice-9 debugger commands)))
|
(resolve-module '(ice-9 debugger commands)))
|
||||||
|
|
||||||
|
(define (resolve-module-from-root name)
|
||||||
|
(save-module-excursion
|
||||||
|
(lambda ()
|
||||||
|
(set-current-module the-root-module)
|
||||||
|
(resolve-module name))))
|
||||||
|
|
||||||
|
|
||||||
;;;; {Module Browsing}
|
;;;; {Module Browsing}
|
||||||
|
|
||||||
|
@ -565,12 +581,19 @@ decimal IP address where the UI server is running; default is
|
||||||
(set! count (+ count 1))
|
(set! count (+ count 1))
|
||||||
count)))
|
count)))
|
||||||
|
|
||||||
|
(define eval-thread-table (make-hash-table 3))
|
||||||
|
|
||||||
(define (eval-thread depth thread-should-exit-thunk)
|
(define (eval-thread depth thread-should-exit-thunk)
|
||||||
;; Acquire mutex to check trigger variables.
|
;; Acquire mutex to check trigger variables.
|
||||||
(with-mutex eval-work-mutex
|
(with-mutex eval-work-mutex
|
||||||
(let ((thread-number (next-thread-number)))
|
(let ((thread-number (next-thread-number)))
|
||||||
|
;; Add this thread to global hash, so we can correlate back to
|
||||||
|
;; this thread from the ID used by the GDS front end.
|
||||||
|
(hash-set! eval-thread-table thread-number (current-thread))
|
||||||
(trc 'eval-thread depth thread-number "entering loop")
|
(trc 'eval-thread depth thread-number "entering loop")
|
||||||
(let loop ()
|
(let loop ()
|
||||||
|
;; Tell the front end this thread is ready.
|
||||||
|
(write-form `(thread-status eval ,thread-number ready))
|
||||||
(cond ((thread-should-exit-thunk)
|
(cond ((thread-should-exit-thunk)
|
||||||
;; Allow thread to exit.
|
;; Allow thread to exit.
|
||||||
)
|
)
|
||||||
|
@ -579,8 +602,11 @@ decimal IP address where the UI server is running; default is
|
||||||
;; Take a local copy of the work, reset global
|
;; Take a local copy of the work, reset global
|
||||||
;; variables, then do the work with mutex released.
|
;; variables, then do the work with mutex released.
|
||||||
(trc 'eval-thread depth thread-number "starting work")
|
(trc 'eval-thread depth thread-number "starting work")
|
||||||
(let ((work eval-work)
|
(let* ((work eval-work)
|
||||||
(subthread-needed? #t))
|
(subthread-needed? #t)
|
||||||
|
(correlator (car work)))
|
||||||
|
;; Tell the front end this thread is busy.
|
||||||
|
(write-form `(thread-status eval ,thread-number busy ,correlator))
|
||||||
(set! eval-work-available #f)
|
(set! eval-work-available #f)
|
||||||
(signal-condition-variable eval-work-taken)
|
(signal-condition-variable eval-work-taken)
|
||||||
(without-mutex eval-work-mutex
|
(without-mutex eval-work-mutex
|
||||||
|
@ -591,14 +617,12 @@ decimal IP address where the UI server is running; default is
|
||||||
(make-thread eval-thread (+ depth 1)
|
(make-thread eval-thread (+ depth 1)
|
||||||
(lambda () (not subthread-needed?)))
|
(lambda () (not subthread-needed?)))
|
||||||
;; Do the evaluation(s).
|
;; Do the evaluation(s).
|
||||||
(let loop2 ((correlator (car work))
|
(let loop2 ((m (cadr work))
|
||||||
(m (cadr work))
|
|
||||||
(exprs (cddr work))
|
(exprs (cddr work))
|
||||||
(results '()))
|
(results '()))
|
||||||
(if (null? exprs)
|
(if (null? exprs)
|
||||||
(write-form `(eval-results ,correlator ,@results))
|
(write-form `(eval-results ,correlator ,@results))
|
||||||
(loop2 correlator
|
(loop2 m
|
||||||
m
|
|
||||||
(cdr exprs)
|
(cdr exprs)
|
||||||
(append results (gds-eval (car exprs) m))))))
|
(append results (gds-eval (car exprs) m))))))
|
||||||
(trc 'eval-thread depth thread-number "work done")
|
(trc 'eval-thread depth thread-number "work done")
|
||||||
|
@ -615,7 +639,9 @@ decimal IP address where the UI server is running; default is
|
||||||
(wait-condition-variable eval-work-changed eval-work-mutex)
|
(wait-condition-variable eval-work-changed eval-work-mutex)
|
||||||
(trc 'eval-thread depth thread-number "wait done")
|
(trc 'eval-thread depth thread-number "wait done")
|
||||||
(loop))))
|
(loop))))
|
||||||
(trc 'eval-thread depth thread-number "exiting"))))
|
(trc 'eval-thread depth thread-number "exiting")
|
||||||
|
;; Tell the front end this thread is ready.
|
||||||
|
(write-form `(thread-status eval ,thread-number exiting)))))
|
||||||
|
|
||||||
(define (gds-eval x m)
|
(define (gds-eval x m)
|
||||||
;; Consumer to accept possibly multiple values and present them for
|
;; Consumer to accept possibly multiple values and present them for
|
||||||
|
@ -635,7 +661,8 @@ decimal IP address where the UI server is running; default is
|
||||||
(newline)
|
(newline)
|
||||||
(set! value
|
(set! value
|
||||||
(call-with-values (lambda ()
|
(call-with-values (lambda ()
|
||||||
(eval x m))
|
(start-stack 'gds-eval-stack
|
||||||
|
(eval x m)))
|
||||||
value-consumer)))
|
value-consumer)))
|
||||||
(lambda ()
|
(lambda ()
|
||||||
(display "Evaluating in current module ")
|
(display "Evaluating in current module ")
|
||||||
|
@ -643,7 +670,8 @@ decimal IP address where the UI server is running; default is
|
||||||
(newline)
|
(newline)
|
||||||
(set! value
|
(set! value
|
||||||
(call-with-values (lambda ()
|
(call-with-values (lambda ()
|
||||||
(primitive-eval x))
|
(start-stack 'gds-eval-stack
|
||||||
|
(primitive-eval x)))
|
||||||
value-consumer)))))
|
value-consumer)))))
|
||||||
(output
|
(output
|
||||||
(with-output-to-string
|
(with-output-to-string
|
||||||
|
|
145
emacs/gds.el
145
emacs/gds.el
|
@ -61,7 +61,8 @@
|
||||||
(setq gds-read-cursor (point-min))
|
(setq gds-read-cursor (point-min))
|
||||||
(set-process-filter gds-process (function gds-filter))
|
(set-process-filter gds-process (function gds-filter))
|
||||||
(set-process-sentinel gds-process (function gds-sentinel))
|
(set-process-sentinel gds-process (function gds-sentinel))
|
||||||
(set-process-coding-system gds-process 'latin-1-unix))
|
(set-process-coding-system gds-process 'latin-1-unix)
|
||||||
|
(process-kill-without-query gds-process))
|
||||||
|
|
||||||
;; Shutdown the subprocess and cleanup all associated data.
|
;; Shutdown the subprocess and cleanup all associated data.
|
||||||
(defun gds-shutdown ()
|
(defun gds-shutdown ()
|
||||||
|
@ -70,7 +71,6 @@
|
||||||
;; Reset variables.
|
;; Reset variables.
|
||||||
(setq gds-buffers nil)
|
(setq gds-buffers nil)
|
||||||
;; Kill the subprocess.
|
;; Kill the subprocess.
|
||||||
(process-kill-without-query gds-process)
|
|
||||||
(condition-case nil
|
(condition-case nil
|
||||||
(progn
|
(progn
|
||||||
(kill-process gds-process)
|
(kill-process gds-process)
|
||||||
|
@ -104,7 +104,13 @@
|
||||||
|
|
||||||
;; Send input to the subprocess.
|
;; Send input to the subprocess.
|
||||||
(defun gds-send (string client)
|
(defun gds-send (string client)
|
||||||
(process-send-string gds-process (format "(%S %s)\n" client string)))
|
(process-send-string gds-process (format "(%S %s)\n" client string))
|
||||||
|
(let ((buf (gds-client-ref 'gds-transcript)))
|
||||||
|
(if buf
|
||||||
|
(with-current-buffer buf
|
||||||
|
(goto-char (point-max))
|
||||||
|
(let ((inhibit-read-only t))
|
||||||
|
(insert (format "tx (%S %s)\n" client string)))))))
|
||||||
|
|
||||||
|
|
||||||
;;;; Focussing in and out on interaction with a particular client.
|
;;;; Focussing in and out on interaction with a particular client.
|
||||||
|
@ -314,8 +320,38 @@ The function is called with one argument, the CLIENT in question."
|
||||||
(setq os nil))
|
(setq os nil))
|
||||||
(setq os (cdr os)))))))))
|
(setq os (cdr os)))))))))
|
||||||
|
|
||||||
|
(;; (thread-status THREAD-TYPE THREAD-NUMBER STATUS [CORRELATOR])
|
||||||
|
(eq proc 'thread-status)
|
||||||
|
(if (eq (car args) 'eval)
|
||||||
|
(let ((number (nth 1 args))
|
||||||
|
(status (nth 2 args))
|
||||||
|
(correlator (nth 3 args)))
|
||||||
|
(if (eq status 'busy)
|
||||||
|
(progn
|
||||||
|
(setq gds-evals-in-progress
|
||||||
|
(append gds-evals-in-progress
|
||||||
|
(list (cons number correlator))))
|
||||||
|
(run-at-time 0.5 nil
|
||||||
|
(function gds-display-slow-eval)
|
||||||
|
buf number correlator)
|
||||||
|
(gds-promote-view 'interaction))
|
||||||
|
(let ((existing (assq number gds-evals-in-progress)))
|
||||||
|
(if existing
|
||||||
|
(setq gds-evals-in-progress
|
||||||
|
(delq existing gds-evals-in-progress)))))
|
||||||
|
(gds-update-buffers))))
|
||||||
|
|
||||||
)))
|
)))
|
||||||
|
|
||||||
|
(defun gds-display-slow-eval (buf number correlator)
|
||||||
|
(with-current-buffer buf
|
||||||
|
(let ((entry (assq number gds-evals-in-progress)))
|
||||||
|
(if (and entry
|
||||||
|
(eq (cdr entry) correlator))
|
||||||
|
(progn
|
||||||
|
(gds-promote-view 'interaction)
|
||||||
|
(gds-request-focus gds-client))))))
|
||||||
|
|
||||||
|
|
||||||
;;;; Per-client buffer state.
|
;;;; Per-client buffer state.
|
||||||
|
|
||||||
|
@ -379,7 +415,7 @@ The function is called with one argument, the CLIENT in question."
|
||||||
(and buf
|
(and buf
|
||||||
(cdr buf)
|
(cdr buf)
|
||||||
(buffer-live-p (cdr buf))
|
(buffer-live-p (cdr buf))
|
||||||
(with-current-buffer buf
|
(with-current-buffer (cdr buf)
|
||||||
(symbol-value sym))))))
|
(symbol-value sym))))))
|
||||||
|
|
||||||
(defun gds-client-blocked ()
|
(defun gds-client-blocked ()
|
||||||
|
@ -439,7 +475,7 @@ The function is called with one argument, the CLIENT in question."
|
||||||
;; If there is an associated source buffer, display it as well.
|
;; If there is an associated source buffer, display it as well.
|
||||||
(if (and (eq (car gds-views) 'stack)
|
(if (and (eq (car gds-views) 'stack)
|
||||||
gds-frame-source-overlay
|
gds-frame-source-overlay
|
||||||
(> (overlay-end gds-frame-source-overlay) 0))
|
(> (overlay-end gds-frame-source-overlay) 1))
|
||||||
(let ((window (display-buffer
|
(let ((window (display-buffer
|
||||||
(overlay-buffer gds-frame-source-overlay))))
|
(overlay-buffer gds-frame-source-overlay))))
|
||||||
(set-window-point window
|
(set-window-point window
|
||||||
|
@ -505,6 +541,14 @@ the following symbols.
|
||||||
"The exception keys for which to debug a GDS client.")
|
"The exception keys for which to debug a GDS client.")
|
||||||
(make-variable-buffer-local 'gds-exception-keys)
|
(make-variable-buffer-local 'gds-exception-keys)
|
||||||
|
|
||||||
|
(defvar gds-evals-in-progress nil
|
||||||
|
"Alist describing evaluations in progress.")
|
||||||
|
(make-variable-buffer-local 'gds-evals-in-progress)
|
||||||
|
|
||||||
|
(defvar gds-results nil
|
||||||
|
"Last help or evaluation results.")
|
||||||
|
(make-variable-buffer-local 'gds-results)
|
||||||
|
|
||||||
(defun gds-insert-interaction ()
|
(defun gds-insert-interaction ()
|
||||||
(erase-buffer)
|
(erase-buffer)
|
||||||
;; Insert stuff for interacting with a running (non-blocked) Guile
|
;; Insert stuff for interacting with a running (non-blocked) Guile
|
||||||
|
@ -534,7 +578,18 @@ the following symbols.
|
||||||
(widget-create 'editable-field
|
(widget-create 'editable-field
|
||||||
:notify (function gds-set-exception-keys)
|
:notify (function gds-set-exception-keys)
|
||||||
gds-exception-keys)
|
gds-exception-keys)
|
||||||
(widget-insert "\n"))
|
(let ((evals gds-evals-in-progress))
|
||||||
|
(if evals
|
||||||
|
(widget-insert "\nEvaluations in progress:\n"))
|
||||||
|
(while evals
|
||||||
|
(let ((w (widget-create 'push-button
|
||||||
|
:notify (function gds-interrupt-eval)
|
||||||
|
"Interrupt")))
|
||||||
|
(widget-put w :thread-number (caar evals))
|
||||||
|
(widget-insert " " (cddar evals) "\n"))
|
||||||
|
(setq evals (cdr evals))))
|
||||||
|
(if gds-results
|
||||||
|
(widget-insert "\n" (cdr gds-results))))
|
||||||
|
|
||||||
(defun gds-sigint (w &rest ignore)
|
(defun gds-sigint (w &rest ignore)
|
||||||
(interactive)
|
(interactive)
|
||||||
|
@ -544,6 +599,11 @@ the following symbols.
|
||||||
(interactive)
|
(interactive)
|
||||||
(gds-send "async-break" gds-client))
|
(gds-send "async-break" gds-client))
|
||||||
|
|
||||||
|
(defun gds-interrupt-eval (w &rest ignore)
|
||||||
|
(interactive)
|
||||||
|
(gds-send (format "interrupt-eval %S" (widget-get w :thread-number))
|
||||||
|
gds-client))
|
||||||
|
|
||||||
(defun gds-toggle-debug-exceptions (w &rest ignore)
|
(defun gds-toggle-debug-exceptions (w &rest ignore)
|
||||||
(interactive)
|
(interactive)
|
||||||
(setq gds-debug-exceptions (widget-value w))
|
(setq gds-debug-exceptions (widget-value w))
|
||||||
|
@ -815,6 +875,18 @@ are not readable by Emacs.")
|
||||||
(interactive)
|
(interactive)
|
||||||
(gds-send "debugger-command info-args" gds-client))
|
(gds-send "debugger-command info-args" gds-client))
|
||||||
|
|
||||||
|
(defun gds-debug-trap-hooks ()
|
||||||
|
(interactive)
|
||||||
|
(gds-send "debugger-command debug-trap-hooks" gds-client))
|
||||||
|
|
||||||
|
(defun gds-up ()
|
||||||
|
(interactive)
|
||||||
|
(gds-send "debugger-command up 1" gds-client))
|
||||||
|
|
||||||
|
(defun gds-down ()
|
||||||
|
(interactive)
|
||||||
|
(gds-send "debugger-command down 1" gds-client))
|
||||||
|
|
||||||
|
|
||||||
;;;; Setting breakpoints.
|
;;;; Setting breakpoints.
|
||||||
|
|
||||||
|
@ -1107,7 +1179,9 @@ region's code."
|
||||||
(setq column (current-column)) ; 0-based
|
(setq column (current-column)) ; 0-based
|
||||||
(beginning-of-line)
|
(beginning-of-line)
|
||||||
(setq line (count-lines (point-min) (point)))) ; 0-based
|
(setq line (count-lines (point-min) (point)))) ; 0-based
|
||||||
(gds-send (format "eval region %s %S %d %d %s %S"
|
(let ((code (buffer-substring-no-properties start end)))
|
||||||
|
(gds-send (format "eval (region . %S) %s %S %d %d %s %S"
|
||||||
|
(gds-abbreviated code)
|
||||||
(if module (prin1-to-string module) "#f")
|
(if module (prin1-to-string module) "#f")
|
||||||
port-name line column
|
port-name line column
|
||||||
(let ((bpinfo (gds-region-breakpoint-info start end)))
|
(let ((bpinfo (gds-region-breakpoint-info start end)))
|
||||||
|
@ -1115,18 +1189,35 @@ region's code."
|
||||||
;; as "()", not "nil", as Scheme doesn't
|
;; as "()", not "nil", as Scheme doesn't
|
||||||
;; understand "nil".
|
;; understand "nil".
|
||||||
(if bpinfo (format "%S" bpinfo) "()"))
|
(if bpinfo (format "%S" bpinfo) "()"))
|
||||||
(buffer-substring-no-properties start end))
|
code)
|
||||||
client)))
|
client))))
|
||||||
|
|
||||||
(defun gds-eval-expression (expr &optional client correlator)
|
(defun gds-eval-expression (expr &optional client correlator)
|
||||||
"Evaluate the supplied EXPR (a string)."
|
"Evaluate the supplied EXPR (a string)."
|
||||||
(interactive "sEvaluate expression: \nP")
|
(interactive "sEvaluate expression: \nP")
|
||||||
(setq client (gds-choose-client client))
|
(setq client (gds-choose-client client))
|
||||||
(gds-send (format "eval %S #f \"Emacs expression\" 0 0 () %S"
|
(gds-send (format "eval (%S . %S) #f \"Emacs expression\" 0 0 () %S"
|
||||||
(or correlator 'expression)
|
(or correlator 'expression)
|
||||||
|
(gds-abbreviated expr)
|
||||||
expr)
|
expr)
|
||||||
client))
|
client))
|
||||||
|
|
||||||
|
(defconst gds-abbreviated-length 35)
|
||||||
|
|
||||||
|
(defun gds-abbreviated (code)
|
||||||
|
(let ((nlpos (string-match (regexp-quote "\n") code)))
|
||||||
|
(while nlpos
|
||||||
|
(setq code
|
||||||
|
(if (= nlpos (- (length code) 1))
|
||||||
|
(substring code 0 nlpos)
|
||||||
|
(concat (substring code 0 nlpos)
|
||||||
|
"\\n"
|
||||||
|
(substring code (+ nlpos 1)))))
|
||||||
|
(setq nlpos (string-match (regexp-quote "\n") code))))
|
||||||
|
(if (> (length code) gds-abbreviated-length)
|
||||||
|
(concat (substring code 0 (- gds-abbreviated-length 3)) "...")
|
||||||
|
code))
|
||||||
|
|
||||||
(defun gds-eval-defun (&optional client)
|
(defun gds-eval-defun (&optional client)
|
||||||
"Evaluate the defun (top-level form) at point."
|
"Evaluate the defun (top-level form) at point."
|
||||||
(interactive "P")
|
(interactive "P")
|
||||||
|
@ -1219,29 +1310,38 @@ interesting happened, `nil' if not."
|
||||||
;;;; Display of evaluation and help results.
|
;;;; Display of evaluation and help results.
|
||||||
|
|
||||||
(defun gds-display-results (client correlator results)
|
(defun gds-display-results (client correlator results)
|
||||||
(let ((helpp (eq correlator 'help)))
|
(let ((helpp (eq (car correlator) 'help)))
|
||||||
(let ((buf (get-buffer-create (if helpp
|
(let ((buf (get-buffer-create (if helpp
|
||||||
"*Guile Help*"
|
"*Guile Help*"
|
||||||
"*Guile Results*"))))
|
"*Guile Results*"))))
|
||||||
|
(setq gds-results
|
||||||
(save-excursion
|
(save-excursion
|
||||||
(set-buffer buf)
|
(set-buffer buf)
|
||||||
(erase-buffer)
|
(erase-buffer)
|
||||||
(scheme-mode)
|
(scheme-mode)
|
||||||
|
(insert (cdr correlator) "\n\n")
|
||||||
(while results
|
(while results
|
||||||
(insert (car results))
|
(insert (car results))
|
||||||
|
(or (bolp) (insert "\\\n"))
|
||||||
(if helpp
|
(if helpp
|
||||||
nil
|
nil
|
||||||
|
(if (cadr results)
|
||||||
(mapcar (function (lambda (value)
|
(mapcar (function (lambda (value)
|
||||||
(insert " => " value "\n")))
|
(insert " => " value "\n")))
|
||||||
(cadr results))
|
(cadr results))
|
||||||
|
(insert " => no (or unspecified) value\n"))
|
||||||
(insert "\n"))
|
(insert "\n"))
|
||||||
(setq results (cddr results)))
|
(setq results (cddr results)))
|
||||||
(goto-char (point-min))
|
(goto-char (point-min))
|
||||||
(if (and helpp (looking-at "Evaluating in "))
|
(if (and helpp (looking-at "Evaluating in "))
|
||||||
(delete-region (point) (progn (forward-line 1) (point)))))
|
(delete-region (point) (progn (forward-line 1) (point))))
|
||||||
(pop-to-buffer buf)
|
(cons correlator (buffer-string))))
|
||||||
(run-hooks 'temp-buffer-show-hook)
|
;;(pop-to-buffer buf)
|
||||||
(other-window 1))))
|
;;(run-hooks 'temp-buffer-show-hook)
|
||||||
|
;;(other-window 1)
|
||||||
|
))
|
||||||
|
(gds-promote-view 'interaction)
|
||||||
|
(gds-request-focus client))
|
||||||
|
|
||||||
|
|
||||||
;;;; Loading (evaluating) a whole Scheme file.
|
;;;; Loading (evaluating) a whole Scheme file.
|
||||||
|
@ -1301,7 +1401,9 @@ Used for determining the default for the next `gds-load-file'.")
|
||||||
(define-key gds-mode-map "t" (function gds-trace-finish))
|
(define-key gds-mode-map "t" (function gds-trace-finish))
|
||||||
(define-key gds-mode-map "I" (function gds-frame-info))
|
(define-key gds-mode-map "I" (function gds-frame-info))
|
||||||
(define-key gds-mode-map "A" (function gds-frame-args))
|
(define-key gds-mode-map "A" (function gds-frame-args))
|
||||||
|
(define-key gds-mode-map "H" (function gds-debug-trap-hooks))
|
||||||
|
(define-key gds-mode-map "u" (function gds-up))
|
||||||
|
(define-key gds-mode-map "d" (function gds-down))
|
||||||
(define-key gds-mode-map "b" (function gds-set-breakpoint))
|
(define-key gds-mode-map "b" (function gds-set-breakpoint))
|
||||||
|
|
||||||
(define-key gds-mode-map "vi" (function gds-view-interaction))
|
(define-key gds-mode-map "vi" (function gds-view-interaction))
|
||||||
|
@ -1338,6 +1440,10 @@ Used for determining the default for the next `gds-load-file'.")
|
||||||
(setq gds-debug-menu (make-sparse-keymap "Debug"))
|
(setq gds-debug-menu (make-sparse-keymap "Debug"))
|
||||||
(define-key gds-debug-menu [go]
|
(define-key gds-debug-menu [go]
|
||||||
'(menu-item "Go" gds-go))
|
'(menu-item "Go" gds-go))
|
||||||
|
(define-key gds-debug-menu [down]
|
||||||
|
'(menu-item "Move Down 1 Frame" gds-down))
|
||||||
|
(define-key gds-debug-menu [up]
|
||||||
|
'(menu-item "Move Up 1 Frame" gds-up))
|
||||||
(define-key gds-debug-menu [trace-finish]
|
(define-key gds-debug-menu [trace-finish]
|
||||||
'(menu-item "Trace This Frame" gds-trace-finish))
|
'(menu-item "Trace This Frame" gds-trace-finish))
|
||||||
(define-key gds-debug-menu [step-out]
|
(define-key gds-debug-menu [step-out]
|
||||||
|
@ -1464,6 +1570,7 @@ Used for determining the default for the next `gds-load-file'.")
|
||||||
nil
|
nil
|
||||||
"-q")))
|
"-q")))
|
||||||
(let ((proc (get-buffer-process gds-captive)))
|
(let ((proc (get-buffer-process gds-captive)))
|
||||||
|
(process-kill-without-query proc)
|
||||||
(comint-send-string proc "(set! %load-path (cons \"/home/neil/Guile/cvs/guile-core\" %load-path))\n")
|
(comint-send-string proc "(set! %load-path (cons \"/home/neil/Guile/cvs/guile-core\" %load-path))\n")
|
||||||
(comint-send-string proc "(debug-enable 'backtrace)\n")
|
(comint-send-string proc "(debug-enable 'backtrace)\n")
|
||||||
(comint-send-string proc "(use-modules (emacs gds-client))\n")
|
(comint-send-string proc "(use-modules (emacs gds-client))\n")
|
||||||
|
@ -1471,13 +1578,11 @@ Used for determining the default for the next `gds-load-file'.")
|
||||||
|
|
||||||
(defun gds-kill-captive ()
|
(defun gds-kill-captive ()
|
||||||
(if gds-captive
|
(if gds-captive
|
||||||
(let ((proc (get-buffer-process gds-captive)))
|
|
||||||
(process-kill-without-query proc)
|
|
||||||
(condition-case nil
|
(condition-case nil
|
||||||
(progn
|
(progn
|
||||||
(kill-process proc)
|
(kill-process (get-buffer-process gds-captive))
|
||||||
(accept-process-output gds-process 0 200))
|
(accept-process-output gds-process 0 200))
|
||||||
(error)))))
|
(error))))
|
||||||
|
|
||||||
|
|
||||||
;;;; The end!
|
;;;; The end!
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue