[Openmcl-devel] format to a hemlock view's buffer

Arthur Cater arthur.cater at ucd.ie
Fri Feb 3 11:50:53 UTC 2012

Thank you Gary for responding, I appreciate the help.

The test case code attached here is quite small, 42 lines, see below.
Since everything it does is done inside gui::execute-in-gui I have removed
the redefinitions of stream-write-char and stream-write-string that ensured this.

I have taken code from handle-hemlock-event that seems to me to cover
the protocol issues you mentioned, and - with some reordering of bindings -
encapsulated it in the with-hemlock-protocol macro. Without success:
still, a mouseclick moves the visible cursor but a subsequent arrowkey
reveals the buffer-point is still at the end of the inserted text.

-------------- next part --------------
A non-text attachment was scrubbed...
Name: unclickable.lisp
Type: application/octet-stream
Size: 2291 bytes
Desc: not available
URL: <http://lists.clozure.com/pipermail/openmcl-devel/attachments/20120203/7264ef48/attachment.obj>
-------------- next part --------------

(in-package hemlock)

(defmacro with-hemlock-protocol (streamexpr &rest actions)
  (let ((stream (gensym)) (mark (gensym)) (view (gensym)) (text-buffer (gensym)))
    `(ccl::with-standard-abort-handling "Abort editor event handling"
       (let ((,stream ,streamexpr) ,mark)
         (if (and (typep ,stream 'hi::hemlock-output-stream)
                  (setq ,mark (hi::hemlock-output-stream-mark ,stream)))
           (let* ((,text-buffer (hi::line-buffer (hi::mark-line ,mark)))
                  (hi::*current-buffer* ,text-buffer)
                  (,view (gui::front-view-for-buffer hi::*current-buffer*))
                  (hi::*current-view* ,view)
                  (hi::*next-view-start* nil) ;; gets set by scrolling commands
                  (mod (hi::buffer-modification-state ,text-buffer)))
             (hi::modifying-buffer-storage (hi::*current-buffer*)
                   (handler-bind ((error #'(lambda (c)
                                             (hi::lisp-error-error-handler c :debug-p t))))
                     , at actions)
                 (hi::exit-event-handler () :report "Exit from hemlock event handler")))
             ;; Update display
             (if hi::*next-view-start*
               (destructuring-bind (how . where) hi::*next-view-start*
                 (hemlock-ext:scroll-view ,view how where))
               (unless (equal mod (hi::buffer-modification-state ,text-buffer))
                 ;; Modified buffer, make sure user sees what happened
                 (hemlock-ext:ensure-selection-visible ,view)))
             (hi::update-echo-area-after-command ,view))
           (error "~s is not a hemlock-output-stream" ,stream))))))

(defun cl-user::myview (nlines)
  (gui::execute-in-gui   ; Makes the view
   #'(lambda nil
       (let* ((ccl::*default-file-character-encoding* :utf-8)
              (view (gui::find-or-make-hemlock-view nil))
              (buffer (hemlock-view-buffer view))
              (stream (hi:make-hemlock-output-stream (buffer-start-mark buffer) :none)))
              ; All possible values {:none, :line, :full} apparently have the same effect
         (with-hemlock-protocol stream
           (dotimes (num nlines) (format stream "Line ~a is here~%" num)))))))

(cl-user::myview 7)

On 3 Feb 2012, at 02:11, Gary Byers wrote:

> Sorry for not responding earlier (and I still haven't looked at your
> test case in any detail.)
> A Hemlock buffer in the IDE is (usually/always/almost always) associated
> with a Cocoa text view; from the point of view of the text view, the
> Hemlock buffer implements the view's text storage.
> Modifying an NSTextStorage object safely and sanely requires that a certain protocol be observed; that protocol involves telling the text
> system that editing (if the storage object) is in progress, informing
> it of what ranges of text are affected by insertions/deletions/etc,
> and telling the text system that a sequence of editing operations has
> been completed and the view should redisplay affected areas.
> When a Hemlock command runs (usually in response to some key event),
> it (a) runs on the main Cocoa event thread and (b) observes this protocol;
> do that), and these things mean that modification on the buffer/textstorage
> is synchronised with redisplay of the containing view.  Nothing really
> enforces the first constraint (that everything's happening on a single
> thread) except for the fact that trying to modify the buffer from some
> other thread will probably lead to display and other problems.)
> It'd be nice if there was some protocol that allowed arbitrary code
> (running in an arbitrary thread) to modify Hemlock buffers in thread-safe
> ways and to ensure that those modifications were made in accordance with
> Cocoa constraints.  That protocol doesn't exist.
> Like I said, I haven't really looked at this but I suspect you'll find
> that FORMAT modified the buffer as expected but (a) the text view doesn't
> know that and (b) it's possible that other code running concurrently
> was also modifying the buffer in some ways while FORMAT was.
> On Thu, 2 Feb 2012, Arthur Cater wrote:
>> Thanks Glen.
>> I've never looked at the innards of Format, but I assumed it bottoms out in calls
>> to stream-write-char, stream-write-string, and perhaps stream-terpri.
>> And these all turn into hi::insert-character and hi::insert-string.
>> So I'm puzzled about what does foul up the insertion point.
>> Arthur
>> On 2 Feb 2012, at 09:49, Glen Foy wrote:
>>> Arthur,
>>> If you can't find a solution to the stream/format approach (which I like), you might try using hi::insert-string.
>>> It accepts a :charprops parameter and will not foul up the insertion point.
>>> -- Glen
>>> On Feb 1, 2012, at 10:36 AM, Arthur Cater wrote:
>>>> I am having trouble with cursor position in a programmatic Hemlock view.
>>>> The attached (also enclosed) code makes a Hemlock view, creates a stream
>>>> to write to it, and writes a few lines using format.
>> _______________________________________________
>> Openmcl-devel mailing list
>> Openmcl-devel at clozure.com
>> http://clozure.com/mailman/listinfo/openmcl-devel

More information about the Openmcl-devel mailing list