[Openmcl-devel] Hemlock ain't Fred
Gary Byers
gb at clozure.com
Tue Oct 30 04:27:51 PDT 2007
You generally have to tell the display system that the buffer's being
changed and tell it when you're through making changes.
HI::BUFFER-DOCUMENT-BEGIN-EDITING and HI::BUFFER-DOCUMENT-END-EDITING
do that (they ultimately invoke #/beginEditing and #/endEditing on
the underlying NSTextStorage object, which is kind of a Hemlock buffer.)
So:
(defmacro editing-buffer ((buf b) &body body)
`(let* ((,buf ,b)
;; Might as well hide this nonsense, too:
(hi::*buffer-gap-context* (hi::buffer-gap-context ,buf)))
(unwind-protect
(progn
(hi::buffer-document-begin-editing ,buf)
;; Safe to make changes in BODY.
, at body)
(hi::buffer-document-end-editing ,buf)))))
HI::*BUFFER-LIST* is (usually, mostly) a list of alternating echo-area
buffers and primary "document" buffers; if you open a new editor
window via cmd-n, that "document"'s buffer is in the CADR of that
list:
? (editing-buffer (b (cadr hi::*buffer-list*))
(let* ((point ((hi::buffer-point b))))
(hi::insert-string point "This is almost too much funk")
;; Whoops. A typo ... or maybe not.
(hi::delete-characters point -1) ; delete 1 char preceding point
(hi::insert-character point #\!)))
I don't remember (if I ever knew) what the issues were with synchronizing
redisplay with buffer changes in FRED. The issues here include the
fact that the redisplay code runs on a different thread than the listener
you're typing things into; it's a real (native) thread and can therefore
run concurrently with any thread that's making modifications to the
buffer. It might be good if there was a layer that hid this from you
a bit better (and the plan is to introduce such a layer), and it might
also be good to have something like the EDITING-BUFFER above (so that
redisplay can be deferred until a set of editing changes is complete.)
Consider:
(defun mark-buffer (mark)
"Return the buffer that contains MARK. A mark might not have
a containing line and a line might not have a containing buffer;
error in either of those cases, to keep the example simple."
(let* ((line (hi::mark-line mark)))
(or (and line (hi::line-%buffer line))
(error "~s is disembodied ..." mark))))
(defun insert-string-at-mark (mark string)
(editing-buffer (b (mark-buffer mark))
(hi::insert-string mark string)))
(defun delete-characters-at-mark (mark &optional (n 1))
(editing-buffer (b (mark-buffer mark))
(hi::delete-characters mark n)))
(defun insert-character-at-mark (mark char)
(editing-buffer (b (mark-buffer mark))
(hi::insert-character mark char)))
(defun too-much-fun (buffer)
(let* ((point (hi::buffer-point buffer)))
(insert-string-at-mark point "Hello, ")
(sleep 1)
(insert-string-at-mark point "ween!")))
On Tue, 30 Oct 2007, Ron Garret wrote:
> Aw geez, don't mind me. Classes. Structs. Blarg.
>
> So I got all that squared away. I can insert characters into a buffer
> now. But when I try to delete them I get some, er, "interesting"
> results. :-)
>
> rg
>
> On Oct 30, 2007, at 1:27 AM, Ron Garret wrote:
>
>> Guess I ought to RTFM. This is explained in http://trac.clozure.com/openmcl/wiki/CocoaIdeInternals
>>
>> But now I'm stuck on this:
>>
>> ? (describe b)
>> #<Hemlock Buffer "Untitled 2">
>> Type: HEMLOCK-INTERNALS:BUFFER
>> Class: #<STRUCTURE-CLASS HEMLOCK-INTERNALS:BUFFER>
>> %NAME: "Untitled 2"
>> %REGION: #<Hemlock Region "">
>> %PATHNAME: NIL
>> MODES: ("Lisp" "Editor")
>> MODE-OBJECTS: (#<Hemlock Mode "Editor"> #<Hemlock Mode "Lisp">)
>> BINDINGS: #<HASH-TABLE :TEST EQL size 0/60 #x3000418D2E3D>
>> POINT: #<Hemlock Mark "^">
>> %MARK: #<Hemlock Mark "^">
>> REGION-ACTIVE: NIL
>> %WRITABLE: T
>> MODIFIED-TICK: -2
>> UNMODIFIED-TICK: -1
>> DOCUMENT: #<HEMLOCK-EDITOR-DOCUMENT <HemlockEditorDocument: 0xa6b3e70>
>> (#xA6B3E70)>
>> VAR-VALUES: #((#<Hemlock Variable-Object #1="Buffer Mark Ring">)
>> #<Hemlock Variable-Object #1#>
>> #((#<Hemlock Variable-Object #2="Current Package">)
>> #<Hemlock Variable-Object #2#> NIL HEMLOCK::CURRENT-
>> PACKAGE)
>> HEMLOCK::BUFFER-MARK-RING)
>> VARIABLES: #<String Table>
>> WRITE-DATE: NIL
>> DISPLAY-START: #<Hemlock Mark "^">
>> %MODELINE-FIELDS: (#<Hemlock Modeline-field-info :MODIFIEDP>
>> #<Hemlock Modeline-field-info :EXTERNAL-FORMAT>
>> #<Hemlock Modeline-field-info :PACKAGE>
>> #<Hemlock Modeline-field-info :MODES>)
>> DELETE-HOOK: NIL
>> LINE-TERMINATION: :UNIX
>> PROCESS: NIL
>> GAP-CONTEXT: #S(HEMLOCK-INTERNALS::BUFFER-GAP-CONTEXT :LOCK
>> #<RECURSIVE-LOCK [ptr @ #xA6D6140] #x3000418D22DD>
>> :LEFT-OPEN-POS 0
>> :RIGHT-OPEN-
>> POS 0
>> :LINE-CACHE-
>> LENGTH 200
>> :OPEN-LINE NIL
>> :OPEN-CHARS
>> "
>>
>>
>>
>>
>>
>>
>>
>>
>>
>>
>>
>>
>>
>>
>>
>>
>>
>>
>>
>>
>>
>>
>>
>>
>>
>>
>>
>>
>>
>>
>>
>>
>>
>>
>>
>>
>>
>>
>>
>>
>>
>>
>>
>>
>>
>>
>>
>>
>>
>>
>>
>>
>>
>>
>>
>>
>>
>>
>>
>>
>>
>>
>>
>>
>>
>>
>>
>>
>>
>>
>>
>>
>>
>>
>>
>>
>>
>>
>>
>>
>>
>>
>>
>>
>>
>>
>>
>>
>>
>>
>>
>>
>>
>>
>>
>>
>>
>>
>>
>>
>>
>>
>>
>>
>>
>>
>>
>>
>>
>>
>>
>>
>>
>>
>>
>>
>>
>>
>>
>>
>>
>>
>>
>>
>>
>>
>>
>>
>>
>>
>> PROTECTED-REGION: NIL
>> FONT-REGIONS: #<DLL-HEADER #x3000418D2C7D>
>> ACTIVE-FONT-REGION: NIL
>> ? (slot-value b 'gap-context)
>>> Error: #<Hemlock Buffer "Untitled 2"> has no slot named GAP-CONTEXT.
>>> While executing: #<CCL::STANDARD-KERNEL-METHOD SLOT-MISSING (T T T
>> T)>, in process Listener(75).
>>> Type :POP to abort, :R for a list of available restarts.
>>> Type :? for other options.
>> 1 >
>>
>> On Oct 29, 2007, at 11:56 PM, Ron Garret wrote:
>>
>>> I'm trying to manipulate Hemlock windows in the new IDE the way I
>>> used
>>> to be able to manipulate Fred windows. Turns out I can't just do
>>> e.g.
>>>
>>> (insert-string mark string)
>>>
>>> Instead I have to do this:
>>>
>>> (let ((HEMLOCK-INTERNALS::*BUFFER-GAP-CONTEXT* (hi::buffer-gap-
>>> context
>>> (line-buffer (mark-line mark)))))
>>> (insert-string mark "foo"))
>>>
>>> which is not a show stopper, but it's damned annoying. What is this
>>> *BUFFER-GAP-CONTEXT* thing and why isn't it bound automatically?
>>>
>>> rg
>>>
>>> _______________________________________________
>>> Openmcl-devel mailing list
>>> Openmcl-devel at clozure.com
>>> http://clozure.com/mailman/listinfo/openmcl-devel
>>
>>
>> _______________________________________________
>> Openmcl-devel mailing list
>> Openmcl-devel at clozure.com
>> http://clozure.com/mailman/listinfo/openmcl-devel
>
> _______________________________________________
> Openmcl-devel mailing list
> Openmcl-devel at clozure.com
> http://clozure.com/mailman/listinfo/openmcl-devel
>
>
More information about the Openmcl-devel
mailing list