wiki:HemlockProgrammer/Miscellaneous

Version 1 (modified by rme, 6 years ago) (diff)

--

17. Miscellaneous

This chapter is somewhat of a catch-all for comments and features that don't fit well anywhere else.

17.1. Generic Pointer Up

Generic Pointer Up is a Hemlock command bound to mouse up-clicks. It invokes a function supplied with the interface described in this section. This command allows different commands to be bound to the same down-click in various modes with one command bound to the corresponding up-click.

supply-generic-pointer-up-function function [Function] This function supplies a function that Generic Pointer Up invokes the next time it executes.

17.2. Using View Mode

View mode supports scrolling through files automatically terminating the buffer at end-of-file as well as commands for quitting the mode and popping back to the buffer that spawned the View mode buffer. Modes such as Dired and Lisp-Lib use this to view files and description of library entries.

Modes that want similar commands should use view-file-command to view a file and get a handle on the view buffer. To allow the View Return and View Quit commands to return to the originating buffer, you must set the variable View Return Function in the viewing buffer to a function that knows how to do this. Furthermore, since you now have a reference to the originating buffer, you must add a buffer local delete hook to it that will clear the view return function's reference. This needs to happen for two reasons in case the user deletes the originating buffer:

  1. You don't want the return function to go to a non-existing, invalid buffer.
  1. Since the viewing buffer still exists, its View Return Function buffer local variable still exists. This means the function still references the deleted originating buffer, and garbage collection cannot reclaim the memory locked down by the deleted buffer.

The following is a piece of code that could implement part of Dired View File that uses two closures to accomplish that described above:

(let* ((dired-buf (current-buffer))
       (buffer (view-file-command nil pathname)))
  (push #'(lambda (buffer) 
            (declare (ignore buffer))
            (setf dired-buf nil))
        (buffer-delete-hook dired-buf))
  (setf (variable-value 'view-return-function :buffer buffer)
        #'(lambda ()
            (if dired-buf
              (change-to-buffer dired-buf)
              (dired-from-buffer-pathname-command nil)))))

The Dired buffer's delete hook clears the return function's reference to the Dired buffer. The return function tests the variable to see if it still holds a buffer when the function executes.