Character Display ||
Primitives and EEL Subroutines ||
Displaying Status Messages|
Epsilon User's Manual and Reference >
Primitives and EEL Subroutines >
Display Primitives >
Normal Buffer Display >
Character Widths and Columns
int display_width(int ch, int col)
int column_to_pos(int col)
The number of characters that fit on each screen line depends on the
display codes of the characters in the line. Epsilon moves
characters with multi-character representations as a unit to the next
screen line when they don't fit at the end of the previous one
(except in horizontal scrolling mode). Tab characters also vary in
width depending upon the column they start in. There are several
primitives that count screen columns using display class information.
The display_width( ) primitive is the simplest. It returns
the width a character
ch would have if it were at column
The move_to_column( ) primitive moves to column
the current line, or to the end of the line if it does not reach to
col. The column_to_pos( ) subroutine accepts a
column number but doesn't move point; instead it returns the
buffer position of that column.
int horizontal(int pos)
int get_column(int pos) /* indent.e */
int get_indentation(int pos) /* indent.e */
int give_position_at_column(int p, int col)
to_column(int col) /* indent.e */
indent_to_column(int col) /* indent.e */
insert_to_column(int start, int end) /* indent.e */
indent_like_tab() /* indent.e */
The horizontal( ) primitive returns the number of columns from
point to position
pos. Point doesn't change. It must be
pos. The primitive returns
-1 if there is a character
of display code BNEWLINE between point and
pos. This primitive
assumes that point is in column
The current_column( ) primitive uses the horizontal( )
primitive to return the number of the current column.
The get_column( ) subroutine returns the column number of a
given buffer position. The get_indentation( ) subroutine
returns the indentation of the line containing position
The give_position_at_column( ) subroutine returns the buffer
position of the character at column
col on the line containing
p; the column may be
-1 to retrieve the position of
the end of
The to_column( ) subroutine indents so that the character
immediately after point winds up in column
col. It replaces any
spaces and tabs before point with the new indentation. It doesn't
modify any characters after point.
The indent_to_column( ) subroutine indents so that the next
non-whitespace character on the line winds up in column
replaces any spaces and tabs before or after point. The older
insert_to_column( ) function inserts spaces and tabs in a
simpler way, and must be told what starting column to assume. In most
cases indent_to_column( ) is a better choice.
The indent_like_tab( ) subroutine indents like inserting a
<Tab> character at point would. However, it respects the
indent-with-tabs variable and avoids using tabs when the
variable is zero. It also converts spaces and tabs immediately
before point so that they match indent-with-tabs and use the
minimum number of characters.
force_to_column(int col) /* indent.e */
The force_to_column( ) subroutine tries to move to column
col. If the line doesn't reach to that column, the function
indents out to the column. If the column occurs inside a tab
character, the function converts the tab to spaces.
user window short cursor_to_column;
to_virtual_column(int col) /* basic.e */
int virtual_column() /* basic.e */
int virtual_mark_column() /* basic.e */
The window-specific cursor_to_column variable lets you
position the cursor in a part of a window where there are no
characters. It's normally
-1, and the cursor stays on the
character after point. If it's non-negative in the current window,
Epsilon puts the cursor at the specified column in the window
instead. Epsilon resets cursor_to_column to
the buffer changes, or point moves from where it was when you last
set cursor_to_column. (Epsilon only checks these conditions
when it redisplays the window, so you can safely move point
Similarly, the window-specific mark_to_column variable lets
you position the mark in a part of a window where there are no
characters. Epsilon uses this variable when it displays a region
that runs to the mark's position, and swaps the variable with
cursor_to_column when you exchange the point and mark. It's
-1, so Epsilon highlights up to the actual buffer
position of the mark. If it's non-negative in the current window,
Epsilon highlights up to the specified column instead. Epsilon
resets mark_to_column to
-1 just as described above for
The to_virtual_column( ) subroutine positions the cursor to
col on the current line. It tries to simply move to the
correct position in the buffer, but if no buffer character begins at
that column, it uses the cursor_to_column variable to get the
cursor to the right place.
The virtual_column( ) subroutine provides the column the cursor
would appear in: either the value of the cursor_to_column
variable, or (if it's negative) the current column. Similarly, the
virtual_mark_column( ) subroutine provides the column for the
mark, taking mark_to_column into account.
tab_convert(int from, int to, int totabs)
int maybe_indent_rigidly(int rev)
int standard_tab_cmd(int (*func)(), int indent, int flags)
The tab_convert( ) subroutine converts tabs to spaces in the
specified region when its parameter
totabs is zero. When
totabs is nonzero, it converts spaces to tabs.
The hack_tabs( ) subroutine converts tabs to spaces in the
offset columns following point. If
offset is negative, the
function converts tabs in the columns preceding point.
Commands bound to <Tab> often call the
maybe_indent_rigidly( ) subroutine. If a region's been
highlighted, this subroutine indents it using the
indent-rigidly command and then returns nonzero. Otherwise,
it returns zero. If its parameter
rev is nonzero, the subroutine
unindents; a command bound to Shift-<Tab> often provides a nonzero
rev, but for commands on <Tab> this is typically zero.
The standard_tab_cmd( ) subroutine packages a lot of standard
functionality often found on the <Tab> key for a mode. A mode's
command for the <Tab> key can call it, passing it the mode's
indenter function (see below).
If there's a highlighted region, it calls maybe_indent_rigidly( )
1. Otherwise, if the cursor is past the current
line's indentation, it indents to the next level, where the
parameter supplies the number of columns to indent for each level,
2. (Epsilon uses the tab-size if
zero or negative.)
Next, if the user's pressed <Tab> twice or more in a row, it
indents one level more and returns
3; otherwise it calls the
indenting function and returns
4. But if the indenting function
supplies no indentation (placing the line at the left margin), there
was no indentation on the line before, and the
1 bit in the
flags argument is provided, the function adds one level of
indentation and returns
buffer int (*indenter)(); /* EEL variable */
user buffer int auto_indent; /* EEL variable */
prev_indenter() /* indent.e */
zeroed int indenter_action; // Bits for why we're indenting.
#define IACT_AUTO_INDENT 1
#define IACT_AUTO_FILL 2
#define IACT_COMMENT 4
#define IACT_FILL_COMMENT 8
#define IACT_AUTO_FILL_COMMENT 16
#define IACT_REINDENT_PREV 32
The normal-character command provides a hook for automatic
line indentation when it inserts the newline character. If the
buffer-specific variable auto-indent is nonzero, the
normal-character command will call the function pointed to by
indenter, a buffer-specific function pointer,
after inserting a newline character. By default, it calls the
prev_indenter( ) subroutine, which indents to the same
indentation as the previous line.
Various other functions call a buffer's indenter function (if nonzero)
at certain times.
Whenever Epsilon calls a buffer's indenter function, it sets the
indenter_action variable to a value that indicates why it's
indenting, so modes can vary indentation behavior based on context.
IACT_AUTO_INDENT indicates the user pressed
<Enter> in a buffer with auto-indenting enabled, as above.
IACT_AUTO_FILL indicates Epsilon broke a long line
due to auto-filling, and it's now indenting the new line.
The commenting commands indent-for-comment and
set-comment-column use the value
when indenting comments.
The fill-comment command uses the value
IACT_FILL_COMMENT when creating new lines for the comment.
(In some modes it doesn't use the indenter when creating new lines.)
Auto-filling of long comment lines uses the value
IACT_REINDENT_PREV indicates the user pressed
<Enter>, and a mode-specific setting caused Epsilon to reindent
the existing line. See the default-reindent-previous-line
The possible values of indenter_action are arranged as bits, so
a function can use a bitmask to select particular sets of conditions.
Character Display ||
Primitives and EEL Subroutines ||
Displaying Status Messages|
Copyright (C) 1984, 2020 by Lugaru Software Ltd. All rights reserved.