[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