This is the mail archive of the guile-emacs@sourceware.cygnus.com mailing list for the Guile project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

multibyte string


Gerd Moellmann <gerd@gnu.org> writes:

> On the other hand, I'm not sure one can write a sufficient interface
> between Emacs and the current Guile.  The handling of multibyte text,
> and strings with text properties come to mind.  Can one do something
> meaningful on the Scheme side with multibyte text coming from Emacs?
> Won't text properties be lost when passing them through Scheme?  OTOH,
> I'm not a Guile expert.  Maybe it's doable already, or maybe Ken has
> done worked on this.

This is a rough idea of how to handle multibyte strings within the
current Guile Emacs.

If we call a Lisp function from the Scheme side, it returns a reference
to a Lisp object:

  (lisp-eval '(buffer-string))  => #<lisp-reference "hello">

We can convert this reference to a Scheme string by using the procedure
lispref->scm:

  (lispref->scm (lisp-eval '(buffer-string)))  => "hello"

Since this conversion is inefficient and incomplete, we don't want to
do that.  Instead, we can create a GOOPS (the Guile Object Oriented
Programming System) class to handle Emacs strings:

  (define-class <emacs-string> ...)
  (define hello (make-emacs-string (lisp-eval '(buffer-string))))

  hello         => #<<emacs-string> "hello">

After that, we can define a generic function for each string procedure
so that it calls an appropriate Lisp function:

  (define-method string-ref ((string <emacs-string>) n)
    (lisp-apply 'aref (list (emacs-string-lispref string) n)))

Now we can use string-ref for both Scheme and Lisp strings:

  (string-ref "hello" 0)        => #\h
  (string-ref hello 0)          => #<lisp-reference 104>

We can call any Lisp function as well:

  (define-method insert ((string <emacs-string>))
    (lisp-apply 'insert (list (emacs-string-lispref string))))

  (define-method insert ((string <string>))
    (lisp-apply 'insert (list string)))

  (insert hello)        ;; This inserts "hello"
  (insert "hello")      ;; The same but use a scheme string

Automatic conversion for Scheme procedures can be done this way:

  (define-method eval-string ((string <emacs-string>))
    (eval-string (lispref->scm (emacs-string-lispref string))))

  (eval-string hello)   ;; ERR: Unbound variable: hello

We can handle any Lisp value in this manner.  I guess this solves
most interface problems.  How sweet GOOPS is :)

-- Kei

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]