On Lispworks, the output associated with an editor window goes to the Output Browser pane. So evaluating a line such as (format t "foo~%"), or (format *standard-output* "foo~%") with C-M-x in an editor pane would print "foo" in the Output Browser.
However, when using SLIME, once emacs has connected to Lispworks over SWANK, the output starts goes to the terminal on which Lispworks was initially started. This is because the value of *STANDARD-OUTPUT* in the editor pane gets clobbered and set to a Synonym stream to *TERMINAL-IO*.
This behaviour is observed on LWL with any version of slime, and is not desirable. How can one get the `output stream' back so output from the Lispworks IDE can be seen inside the IDE ?
-- Madhu
* Madhu [2009-06-20 09:37+0200] writes:
This behaviour is observed on LWL with any version of slime, and is not desirable. How can one get the `output stream' back so output from the Lispworks IDE can be seen inside the IDE ?
Setting swank:*global-debugger* to nil could solve the problem.
Helmut.
The following can be added to swank-openmcl.lisp to make it provide a resident editor when evaluating #'ed in a remote repl:
(push '(ccl:*resident-editor-hook* . swank:ed-in-emacs) swank:*default-worker-thread-bindings*)
-- Terje Norderhaug
On Sat, 20 Jun 2009 13:07:27 +0530, Madhu said:
Cancel-Lock: sha1:E3KjN+JxDXTc+tqC03Kn9y8Hbpk=
On Lispworks, the output associated with an editor window goes to the Output Browser pane. So evaluating a line such as (format t "foo~%"), or (format *standard-output* "foo~%") with C-M-x in an editor pane would print "foo" in the Output Browser.
However, when using SLIME, once emacs has connected to Lispworks over SWANK, the output starts goes to the terminal on which Lispworks was initially started. This is because the value of *STANDARD-OUTPUT* in the editor pane gets clobbered and set to a Synonym stream to *TERMINAL-IO*.
This behaviour is observed on LWL with any version of slime, and is not desirable. How can one get the `output stream' back so output from the Lispworks IDE can be seen inside the IDE ?
Which version of SLIME, which contribs are you loading and how are you starting it? What is the value of SWANK:*GLOBALLY-REDIRECT-IO*?
__Martin
* Martin Simmons 200906221121.n5MBLMr6011420@higson.cam.lispworks.com : Wrote on Mon, 22 Jun 2009 12:21:22 +0100:
|>>>>> On Sat, 20 Jun 2009 13:07:27 +0530, Madhu said: |> On Lispworks, the output associated with an editor window goes to the |> Output Browser pane. So evaluating a line such as (format t "foo~%"), |> or (format *standard-output* "foo~%") with C-M-x in an editor pane would |> print "foo" in the Output Browser. |> |> However, when using SLIME, once emacs has connected to Lispworks over |> SWANK, the output starts goes to the terminal on which Lispworks was |> initially started. This is because the value of *STANDARD-OUTPUT* in |> the editor pane gets clobbered and set to a Synonym stream to |> *TERMINAL-IO*. |> |> This behaviour is observed on LWL with any version of slime, and is not |> desirable. How can one get the `output stream' back so output from the |> Lispworks IDE can be seen inside the IDE ? | | Which version of SLIME, which contribs are you loading and how are you | starting it? What is the value of SWANK:*GLOBALLY-REDIRECT-IO*?
Helmut's suggestion worked for me. Setting SWANK:*GLOBAL-DEBUGGER* to NIL avoids the code path where ENV:*ENVIRONMENT* was being set to freshly created SWANK-BACKEND::SLIME-ENV which seemed to be defaulting *STANDARD-OUTPUT* to *TERMINAL-IO*.
[I believe the behaviour I noted above is common to all versions of slime without any contribs; with *GLOBALLY-REDIRECT-IO* set to NIL. LWL Personal can be started with C-u M-x slime, and then pressing "Break to TTY" button on the GC Monitor; and after the slime connection is established, invoking a continue restart in the *inferior-lisp* buffer]
-- Madhu
The slimefun swank:list-threads currently provides only four values for each thread, namely id, name, status and description.
However, it would be useful to have a generalized interface to other information about threads, such as their priority, creation time, idle time, and total run time.
Could such optional information perhaps be made available as keyword attributes in the result of swank:list-thread?
-- Terje Norderhaug
Terje Norderhaug terje@in-progress.com writes:
The slimefun swank:list-threads currently provides only four values for each thread, namely id, name, status and description.
However, it would be useful to have a generalized interface to other information about threads, such as their priority, creation time, idle time, and total run time.
Could such optional information perhaps be made available as keyword attributes in the result of swank:list-thread?
If you know how to obtain such information.
On Jun 22, 2009, at 2:05 PM, Stas Boukarev wrote:
Terje Norderhaug terje@in-progress.com writes:
The slimefun swank:list-threads currently provides only four values for each thread, namely id, name, status and description.
However, it would be useful to have a generalized interface to other information about threads, such as their priority, creation time, idle time, and total run time.
Could such optional information perhaps be made available as keyword attributes in the result of swank:list-thread?
If you know how to obtain such information.
It is implementation dependent for the different Common LISPs.
For example, Clozure provides:
process-priority process-creation-time
MCL provides these as well, plus:
process-total-run-time process-last-run-time (from which idle time can be calculated).
LispWorks has:
process-total-run-time process-idle-time
If Swank defines a unified interface to such additional process attributes, it can be added to the different back-end implementations by those in the know.
-- Terje Norderhaug
Terje Norderhaug terje@in-progress.com writes:
The slimefun swank:list-threads currently provides only four values for each thread, namely id, name, status and description.
However, it would be useful to have a generalized interface to other information about threads, such as their priority, creation time, idle time, and total run time.
The idea is to compute a description string which contains such data.
-T.
On Jun 22, 2009, at 11:18 PM, Tobias C. Rittweiler wrote:
Terje Norderhaug terje@in-progress.com writes:
The slimefun swank:list-threads currently provides only four values for each thread, namely id, name, status and description.
However, it would be useful to have a generalized interface to other information about threads, such as their priority, creation time, idle time, and total run time.
The idea is to compute a description string which contains such data.
A swank client (like slime) will have a hard time extracting thread data from such a human readable description string.
Swank may very well continue to provide a description of each thread, but the same data should also be passed on to the swank client in a form that can easily be made sense out of by code. Generally, separate the content from the presentation. This will allow swank clients to display or use the information in alternative ways.
For example, I am building a Processes Inspector that uses data from a swank server to display a table of the threads on the remote LISP (this screenshot is for real, not a mock up):
-- Terje Norderhaug
Terje Norderhaug terje@in-progress.com writes:
On Jun 22, 2009, at 11:18 PM, Tobias C. Rittweiler wrote:
Terje Norderhaug terje@in-progress.com writes:
The slimefun swank:list-threads currently provides only four values for each thread, namely id, name, status and description.
However, it would be useful to have a generalized interface to other information about threads, such as their priority, creation time, idle time, and total run time.
The idea is to compute a description string which contains such data.
A swank client (like slime) will have a hard time extracting thread data from such a human readable description string.
The description could be a plist instead of a string. How about that?
-T.
On Jun 23, 2009, at 11:29 AM, Tobias C. Rittweiler wrote:
Terje Norderhaug terje@in-progress.com writes:
On Jun 22, 2009, at 11:18 PM, Tobias C. Rittweiler wrote:
Terje Norderhaug terje@in-progress.com writes:
The slimefun swank:list-threads currently provides only four values for each thread, namely id, name, status and description.
However, it would be useful to have a generalized interface to other information about threads, such as their priority, creation time, idle time, and total run time.
The idea is to compute a description string which contains such data.
A swank client (like slime) will have a hard time extracting thread data from such a human readable description string.
The description could be a plist instead of a string. How about that?
A plist with additional thread data would serve the purpose, just as long as the format is consistent between the implementations.
-- Terje Norderhaug
On Jun 23, 2009, at 12:19 PM, Terje Norderhaug wrote:
On Jun 23, 2009, at 11:29 AM, Tobias C. Rittweiler wrote:
Terje Norderhaug terje@in-progress.com writes:
On Jun 22, 2009, at 11:18 PM, Tobias C. Rittweiler wrote:
Terje Norderhaug terje@in-progress.com writes:
The slimefun swank:list-threads currently provides only four values for each thread, namely id, name, status and description.
However, it would be useful to have a generalized interface to other information about threads, such as their priority, creation time, idle time, and total run time.
The idea is to compute a description string which contains such data.
A swank client (like slime) will have a hard time extracting thread data from such a human readable description string.
The description could be a plist instead of a string. How about that?
A plist with additional thread data would serve the purpose, just as long as the format is consistent between the implementations.
Another possibility is to have the list-threads response include a declaration of the structure of the items in the list. For example, the first item could be a list of symbols labeling the data, as in this amended response from swank:list-threads:
((id name status description) (18 "worker" "Active" "") (16 "repl-thread" "Semaphore timed wait" "") (15 "auto-flush-thread" "Sleep" "") (12 "reader-thread" "Active" "") (11 "control-thread" "Semaphore timed wait" "") (2 "Swank 0" "Active" "") (1 "listener" "Active" "") (0 "Initial" "Sleep" ""))
Benefits of heading with such a declaration vs using a detailed property list for each item includes less redundancy and that a swank client can make decisions about how to present the items in the list before processing the rest of the response.
Implementations can then add process attributes like priority, creation-time, total-run-time, last-run-time, idle-time etc, preferably using consistent labels.
-- Terje Norderhaug
* Terje Norderhaug [2009-06-23 22:07+0200] writes:
Another possibility is to have the list-threads response include a declaration of the structure of the items in the list. For example, the first item could be a list of symbols labeling the data, as in this amended response from swank:list-threads:
((id name status description) (18 "worker" "Active" "") (16 "repl-thread" "Semaphore timed wait" "") (15 "auto-flush-thread" "Sleep" "") (12 "reader-thread" "Active" "") (11 "control-thread" "Semaphore timed wait" "") (2 "Swank 0" "Active" "") (1 "listener" "Active" "") (0 "Initial" "Sleep" ""))
Benefits of heading with such a declaration vs using a detailed property list for each item includes less redundancy and that a swank client can make decisions about how to present the items in the list before processing the rest of the response.
Implementations can then add process attributes like priority, creation-time, total-run-time, last-run-time, idle-time etc, preferably using consistent labels.
-- Terje Norderhaug
Yet another possibility would be to pass the interesting attributes as input to swank:list-threads. E.g.
(list-threads '(:id :name :status :description :priority :total-runtime)) => ((18 "worker" "Active" "" 10 0.2) (16 "repl-thread" "Semaphore timed wait" "" 5 0.3))
Perhaps complemented with a function to find out all possible attribute names.
Helmut.
On Jun 23, 2009, at 2:35 PM, Helmut Eller wrote:
- Terje Norderhaug [2009-06-23 22:07+0200] writes:
Another possibility is to have the list-threads response include a declaration of the structure of the items in the list. For example, the first item could be a list of symbols labeling the data, as in this amended response from swank:list-threads:
((id name status description) (18 "worker" "Active" "") (16 "repl-thread" "Semaphore timed wait" "") (15 "auto-flush-thread" "Sleep" "") (12 "reader-thread" "Active" "") (11 "control-thread" "Semaphore timed wait" "") (2 "Swank 0" "Active" "") (1 "listener" "Active" "") (0 "Initial" "Sleep" ""))
Benefits of heading with such a declaration vs using a detailed property list for each item includes less redundancy and that a swank client can make decisions about how to present the items in the list before processing the rest of the response.
Implementations can then add process attributes like priority, creation-time, total-run-time, last-run-time, idle-time etc, preferably using consistent labels.
-- Terje Norderhaug
Yet another possibility would be to pass the interesting attributes as input to swank:list-threads. E.g.
(list-threads '(:id :name :status :description :priority :total- runtime)) => ((18 "worker" "Active" "" 10 0.2) (16 "repl-thread" "Semaphore timed wait" "" 5 0.3))
Perhaps complemented with a function to find out all possible attribute names.
Having the client explicitly requesting which attributes it wants is a possibility worth consideration. A variation is to have the list- threads function declare the response and return as many attributes is available, but have a public function that can filter responses on the server before the result is passed back to the client, as in this request:
(filter '(id name status description priority total-runtime) (list- threads))
Sample demo:
(defun list-threads () '((id name status description) (18 "worker" "Active" "") (16 "repl-thread" "Semaphore timed wait" "") (15 "auto-flush-thread" "Sleep" "") (12 "reader-thread" "Active" "") (11 "control-thread" "Semaphore timed wait" "") (2 "Swank 0" "Active" "") (1 "listener" "Active" "") (0 "Initial" "Sleep" "")))
(defun filter (wanted items) (loop with given = (first items) for item in (rest items) collect (loop for w in wanted for p = (position w given) collect (when p (nth p item)))))
(filter '(id status) (list-threads)) => ((18 "Active") (16 "Semaphore timed wait") (15 "Sleep") (12 "Active") (11 "Semaphore timed wait") (2 "Active") (1 "Active") (0 "Sleep"))
(filter '(id name status description priority total-runtime) (list- threads)) => ((18 "worker" "Active" "" NIL NIL) (16 "repl-thread" "Semaphore timed wait" "" NIL NIL) (15 "auto-flush-thread" "Sleep" "" NIL NIL) (12 "reader-thread" "Active" "" NIL NIL) (11 "control-thread" "Semaphore timed wait" "" NIL NIL) (2 "Swank 0" "Active" "" NIL NIL) (1 "listener" "Active" "" NIL NIL) (0 "Initial" "Sleep" "" NIL NIL))
Where do we go from here?
-- Terje Norderhaug
* Terje Norderhaug [2009-06-24 02:35+0200] writes:
Where do we go from here?
I'd say we should implement a backend function, say thread-attributes, for some Lisps. thread-attributes could just return a plist and the list-threads function can then figure out how to send them over the wire. By default list-threads should just return everything (including the attribute names in the first "row") and if we ever feel a need for filtering we can add that as optional argument.
Helmut.
On Jun 24, 2009, at 1:16 PM, Helmut Eller wrote:
- Terje Norderhaug [2009-06-24 02:35+0200] writes:
Where do we go from here?
I'd say we should implement a backend function, say thread-attributes, for some Lisps. thread-attributes could just return a plist and the list-threads function can then figure out how to send them over the wire. By default list-threads should just return everything (including the attribute names in the first "row") and if we ever feel a need for filtering we can add that as optional argument.
I second that. Here is a candidate implementation that is flexible when it comes to the plist returned by thread-attributes. I have included a working tread-attributes function for openmcl.
; swank-backend.lisp
(definterface thread-attributes (thread) "Returns a plist of implementation-dependent attributes for the THREAD")
; swank.lisp
(defslimefun list-threads () "Return a list ((ID NAME STATUS DESCRIPTION ...) ...) of all threads, with the first item in the table being a list of attribute names and the rest containing the corresponding attribute values (possibly excluding trailing null values)." (setq *thread-list* (all-threads)) (loop with labels = NIL for thread in *thread-list* for name = (thread-name thread) for attributes = (thread-attributes thread) do (do ((plist attributes (cddr plist))) ((null plist)) (unless (find (car plist) labels) (setf labels (nconc labels (list (car plist)))))) collect (list* (thread-id thread) (if (symbolp name) (symbol-name name) name) (thread-status thread) (thread-description thread) (loop for label in labels collect (getf attributes label))) into result finally (return (cons (append '(id name status description) labels) result))))
; swank-openmcl.lisp
(defimplementation thread-attributes (thread) (list 'swank::priority (ccl::process-priority thread)))
-- Terje Norderhaug
* Terje Norderhaug [2009-06-28 01:25+0200] writes:
I second that. Here is a candidate implementation that is flexible when it comes to the plist returned by thread-attributes. I have included a working tread-attributes function for openmcl.
Thanks. I committed it.
Helmut.
Helmut Eller heller@common-lisp.net writes:
- Terje Norderhaug [2009-06-28 01:25+0200] writes:
I second that. Here is a candidate implementation that is flexible when it comes to the plist returned by thread-attributes. I have included a working tread-attributes function for openmcl.
Thanks. I committed it.
THREAD-DESCRIPTION can go now, can't it?
-T.