[slim-vim] ECL Socket callbacks?
Larry Clapp
larry at theclapp.org
Fri May 19 12:54:35 CDT 2006
On Fri, May 19, 2006 at 09:37:29AM -0700, Brad Beveridge wrote:
> I just posted this to the ECL list, but thought I'd ask here too.
> I'm hoping Jim might have some ideas :)
>
> Do we need to modify Vim a bit more to support this kind of async
> action, or do the current async changes suffice? If so - what do I
> need to do?
Yes, Jim's code can already do this. The network code I posted a
while back built on the api Jim had already mentioned. Here's the
last version I played with, which might or might not still work (bit
rot sucks). See the end of the file for usage examples (which assume
you've started a netcat listening on port 1234 in another window).
Sorry I can't say more, and haven't been very active on the list
lately. I was on vacation last week and work this week has been
pretty busy.
-- Larry
-------------- next part --------------
(defpackage #:vim.network
(:use #:cl)
(:shadow #:length)
(:export #:socket
#:length))
(in-package :vim.network)
(defconstant +newline+ (format nil "~%"))
(defclass socket (si::fundamental-character-input-stream
si::fundamental-character-output-stream)
((data :initform "" :accessor data-of)
(socket :initarg :socket :reader socket-of)
(listening-p :reader listening-p :accessor listening-p-of)
(callback :initarg :callback :initform (constantly nil) :accessor callback-of)))
(defmethod si:stream-write-char ((s socket) char)
(princ char (socket-of s))
char)
(defmethod si:stream-terpri ((s socket))
(terpri (socket-of s)))
(defmethod si:stream-clear-output ((s socket))
(clear-output (socket-of s))
nil)
(defmethod si:stream-force-output ((s socket))
(force-output (socket-of s))
nil)
(defmethod si:stream-interactive-p ((s socket))
t)
(defmethod si:stream-close :after ((s socket) &key abort)
(vim:remove-input-listener (socket-of s))
(setf (listening-p-of s) nil)
(close (socket-of s)))
(defmethod si:stream-read-char ((s socket))
(block si:stream-read-char
(with-slots (data) s
(when (string= data "")
(return-from si:stream-read-char
(if (listening-p s)
(read-char (socket-of s))
:eof)))
(prog1
(char data 0)
(setf data (subseq data 1))))))
(defmethod si:stream-unread-char ((s socket) char)
(setf (data-of s)
(concatenate 'string (string char) (data-of s)))
char)
(defmethod si:stream-listen ((s socket))
(listen (socket-of s)))
(defmethod si:stream-clear-input ((s socket))
(setf (data-of s) "")
nil)
(defmethod initialize-instance :after ((this socket) &key socket)
; (format t "socket is ~S~%" socket)
(labels ((receive-data (line)
(setf (data-of this)
(concatenate 'string (data-of this) line +newline+))
(funcall (callback-of this) this))
(no-more-data ()
(vim:remove-input-listener socket)
(setf (listening-p-of this) nil))
(read-socket-listener ()
(loop with line
while (listen socket)
if (setq line (read-line socket nil nil))
do (receive-data line)
else
do (no-more-data))))
(vim:add-input-listener socket #'read-socket-listener)
(setf (listening-p-of this) t)))
(defmethod print-object ((this socket) s)
(format s "#<SOCKET-LISTENER :data ~S :socket ~S :listening-p ~S>"
(data-of this)
(socket-of this)
(listening-p this)))
(defmethod length ((this t))
(cl:length this))
(defmethod length ((this socket))
(cl:length (data-of this)))
#|
; Usage
(in-package :vim.network)
(defparameter c
(make-instance 'socket
:socket (si:open-client-stream "localhost" 1234)
:callback
#'(lambda (this)
(vim:msg (format nil "callback called; length of data is ~D"
(length this))))))
(data-of c)
(listening-p c)
(length c)
(print "this is a test" c)
(prin1 "this is a test" c)
(princ "this is a test" c)
(terpri c)
(progn (prin1 (read c)) (data-of c))
(read c)
(close c)
|#
More information about the slim-vim
mailing list