Lugaru's Epsilon
Programmer's
Editor

Context:
Epsilon User's Manual and Reference
   Primitives and EEL Subroutines
      Buffer Primitives
         . . .
         Comparing Primitives
         Managing Buffers
         Catching Buffer Changes
         Listing Buffers
      Display Primitives
         Creating & Destroying Windows
         Window Resizing Primitives
         Preserving Window Arrangements
         . . .
         Colors
      . . .

Previous   Up    Next
Managing Buffers  Primitives and EEL Subroutines   Listing Buffers


Epsilon User's Manual and Reference > Primitives and EEL Subroutines > Buffer Primitives >

Catching Buffer Changes

user buffer short call_on_modify;
on_modify()     /* buffer.e */
zeroed buffer (*buffer_on_modify)();
buffer char _buf_readonly;
check_modify(int buf)

If the buffer-specific call_on_modify variable has a nonzero value in a particular buffer, whenever any primitive tries to modify that buffer, Epsilon calls the EEL subroutine on_modify( ) first. By default, that subroutine calls the normal_on_modify( ) subroutine, which aborts the modification if the buffer-specific variable _buf_readonly is nonzero, indicating a read-only buffer, and does various similar things.

But if the buffer_on_modify buffer-specific function pointer is nonzero for that buffer, on_modify( ) instead calls the subroutine it indicates. That subroutine may wish to call normal_on_modify( ) itself.

An on_modify( ) function can abort the modification or set variables. But if it plans to return, it must not create or delete buffers, or permanently switch buffers.

One of normal_on_modify( )'s tasks is to handle read-only buffers. There are several types of these, distinguished by the value of the _buf_readonly variable, which if nonzero indicates the buffer is read-only. A value of 1 means the user explicitly set the buffer read-only. The value 2 means Epsilon automatically set the buffer read-only because its corresponding file was read-only.

A value of 3 indicates pager mode; this is just like a normal read-only buffer, but if the user action causing the attempt at buffer modification happens to be the result of the <Space> or <Backspace> keys, Epsilon cancels the modification and pages forward or backward, respectively. In other types of read-only buffers, this happens only if the readonly-pages variable permits it.

The check_modify( ) primitive runs the on_modify( ) function on a specified buffer (if call_on_modify is nonzero in that buffer). You can use this if you plan to modify a buffer later but want any side effects to happen now. If the buffer is marked read-only, this function will abort with an error message. If the buffer is in virtual mode and its cursor is positioned in virtual space, Epsilon will insert whitespace characters to reach the virtual column. Because this can change the value of point, you should call check_modify( ) before passing the values of spots to any function.

For example, suppose you write a subroutine to replace the previous character with a "+", using a statement like replace(point - 1, '+');. Suppose point has the value 10, and appears at the end of a line containing "abc" (in column 3). Using virtual mode, the user might have positioned the cursor to column 50, however. If you used the above statement, Epsilon would call replace( ) with the value 9. Before replacing, Epsilon would call on_modify( ), which, in virtual mode, would insert tabs and spaces to reach column 50, and move point to the end of the inserted text. Then Epsilon would replace the character "c" at buffer position 9 with "+". If you call check_modify(bufnum); first, however, Epsilon inserts its tabs and spaces to reach column 50, and point - 1 correctly refers to the last space it inserted.

reset_modified_buffer_region(char *tag)
int modified_buffer_region(int *from, int *to, ?char *tag)

Sometimes an EEL function needs to know if a buffer has been modified since the last time it checked. Epsilon can maintain this information using tagged buffer modification regions.

An EEL function first tells Epsilon to begin collecting this information for the current buffer by calling the reset_modified_buffer_region( ) primitive and passing a unique tag name. (Epsilon's syntax highlighting uses a modified buffer region named needs-color, for instance.) Later it can call the modified_buffer_region( ) primitive, passing the same tag name. Epsilon will set its from and to parameters to indicate the range of the buffer that has been modified since the first call.

For example, say a buffer contains six characters abcdef when reset_modified_buffer_region( ) is called. Then the user inserts and deletes some characters resulting in abxyf. A modified_buffer_region( ) would now report that characters in the range 2 to 4 have been changed. If the buffer contains many disjoint changes, from will indicate the start of the first change, and to the end of the last.

The modified_buffer_region( ) primitive returns 0 if the buffer hasn't been modified since the last reset_modified_buffer_region( ) with that tag. In this case from and to will be equal. (They might also be equal if only deletion of text had occurred, but then the primitive wouldn't have returned 0.) It returns 1 if the buffer has been modified. If reset_modified_buffer_region( ) has never been used with the specified tag in the current buffer, it returns -1, and sets the from and to variables to indicate the whole buffer.

The tag may be omitted when calling modified_buffer_region( ). In that case Epsilon uses an internal tag that's reset on each buffer display. So the primitive indicates which part of the current buffer has been modified since the last buffer display.



Previous   Up    Next
Managing Buffers  Primitives and EEL Subroutines   Listing Buffers


Lugaru Copyright (C) 1984, 2012 Lugaru Software Ltd. All Rights Reserved.