wiki:HemlockProgrammer/AlteringAndSearchingText

Version 2 (modified by rme, 7 years ago) (diff)

--

4. Altering and Searching Text

4.1. Altering Text

A note on marks and text alteration: :temporary marks are invalid after any change has been made to the text the mark points to; it is an error to use a temporary mark after such a change has been made. If text is deleted which has permanent marks pointing into it then they are left pointing to the position where the text was.

insert-character mark character [Function]

insert-string mark string [Function]

insert-region mark region [Function]

Inserts character, string or region at mark. insert-character signals an error if character is not string-char-p. If string or region is empty, and mark is in some buffer, then Hemlock leaves buffer-modified of mark’s buffer unaffected.

ninsert-region mark region [Function]

Like insert-region, inserts the region at the mark’s position, destroying the source region. This must be used with caution, since if anyone else can refer to the source region bad things will happen. In particular, one should make sure the region is not linked into any existing buffer. If region is empty, and mark is in some buffer, then Hemlock leaves buffer-modified of mark’s buffer unaffected.

delete-characters mark n [Function]

This deletes n characters after the mark (or -n before if n is negative). If n characters after (or -n before) the mark do not exist, then this returns nil; otherwise, it returns t. If n is zero, and mark is in some buffer, then Hemlock leaves buffer-modified of mark’s buffer unaffected.

delete-region region [Function]

This deletes region. This is faster than delete-and-save-region (below) because no lines are copied. If region is empty and contained in some buffer’s buffer-region, then Hemlock leaves buffer-modified of the buffer unaffected.

delete-and-save-region region [Function]

This deletes region and returns a region containing the original region’s text. If region is empty and contained in some buffer’s buffer-region, then Hemlock leaves buffer-modified of the buffer unaffected. In this case, this returns a distinct empty region.

filter-region function region [Function]

Destructively modifies region by replacing the text of each line with the result of the application of function to a string containing that text. Function must obey the following restrictions:

  1. The argument may not be destructively modified.
  2. The return value may not contain newline characters.
  3. The return value may not be destructively modified after it is returned fromfunction.

The strings are passed in order, and are always simple strings.

Using this function, a region could be uppercased by doing:

(filter-region #’string-upcase region)

4.2. Text Predicates

start-line-p mark [Function]

Returns t if the mark points before the first character in a line, nil otherwise.

end-line-p mark [Function]

Returns t if the mark points after the last character in a line and before the newline, nil otherwise.

empty-line-p mark [Function] Return t if the line which mark points to contains no characters.

blank-line-p line [Function]

Returns t if line contains only characters with a Whitespace attribute of 1. See chapter 9 for discussion of character attributes.

blank-before-p mark [Function]

blank-after-p mark [Function]

These functions test if all the characters preceding or following mark on the line it is on have a Whitespace attribute of 1.

same-line-p mark1 mark2 [Function]

Returns t if mark1 and mark2 point to the same line, or nil otherwise; That is,

(same-line-p a b) <==> (eq (mark-line a) (mark-line b))

mark< mark1 mark2 [Function]

mark<= mark1 mark2 [Function]

mark= mark1 mark2 [Function]

mark/= mark1 mark2 [Function]

mark>= mark1 mark2 [Function]

mark> mark1 mark2 [Function]

These predicates test the relative ordering of two marks in a piece of text, that is a mark is mark> another if it points to a position after it. If the marks point into different, non-connected pieces of text, such as different buffers, then it is an error to test their ordering; for such marks mark= is always false and mark/= is always true.

line< line1 line2 [Function]

line<= line1 line2 [Function]

line>= line1 line2 [Function]

line> line1 line2 [Function]

These predicates test the ordering of line1 and line2. If the lines are in unconnected pieces of text it is an error to test their ordering.

lines-related line1 line2 [Function]

This function returns t if line1 and line2 are in the same piece of text, or nil otherwise.

first-line-p mark [Function]

last-line-p mark [Function]

first-line-p returns t if there is no line before the line mark is on, and nil otherwise. Last-line-p similarly tests tests whether there is no line after mark.

4.3. Kill Ring

*kill-ring* [Variable]

This is a ring (see section 16.2) of regions deleted from buffers. Some commands save affected regions on the kill ring before performing modifications. You should consider making the command undoable (see section 16.3), but this is a simple way of achieving a less satisfactory means for the user to recover.

kill-region region current-type [Function]

This kills region saving it in *kill-ring*. Current-type is either :kill-forward or :kill-backward. When the last-command-type (page 31) is one of these, this adds region to the beginning or end, respectively, of the top of *kill-ring*. The result of calling this is undoable using the command Undo (see the Hemlock User’s Manual). This sets last-command-type to current-type, and it interacts with kill-characters.

kill-characters mark count [Function]

Character Deletion Threshold (initial value 5) [Hemlock Variable]

kill-characters kills count characters after mark if count is positive, otherwise before mark if count is negative. When count is greater than or equal to Character Deletion Threshold, the killed characters are saved on *kill-ring*. This may be called multiple times contiguously (that is, without last-command-type (page 31) being set) to accumulate an effective count for purposes of comparison with the threshold.

This sets last-command-type, and it interacts with kill-region. When this adds a new region to *kill-ring*, it sets last-command-type to :kill-forward (if count is positive) or :kill-backward (if count is negative). When last-command-type is :kill-forward or :kill-backward, this adds the killed characters to the beginning (if count is negative) or the end (if count is positive) of the top of *kill-ring*, and it sets last-command-type as if it added a new region to *kill-ring*. When the kill ring is unaffected, this sets last-command-type to :char-kill-forward or :char-kill-backward depending on whether count is positive or negative, respectively.

This returns mark if it deletes characters. If there are not count characters in the appropriate direction, this returns nil.

4.4. Active Regions

Every buffer has a mark stack (page 9) and a mark known as the point where most text altering nominally occurs. Between the top of the mark stack, the current-mark, and the current-buffer’s point, the current-point, is what is known as the current-region . Certain commands signal errors when the user tries to operate on the current-region without its having been activated. If the user turns off this feature, then the current-region is effectively always active.

When writing a command that marks a region of text, the programmer should make sure to activate the region. This typically occurs naturally from the primitives that you use to mark regions, but sometimes you must explicitly activate the region. These commands should be written this way, so they do not require the user to separately mark an area and then activate it. Commands that modify regions do not have to worry about deactivating the region since modifying a buffer automatically deactivates the region. Commands that insert text often activate the region ephemerally; that is, the region is active for the immediately following command, allowing the user wants to delete the region inserted, fill it, or whatever.

Once a marking command makes the region active, it remains active until:

  • a command uses the region,
  • a command modifies the buffer,
  • a command changes the current window or buffer,
  • a command signals an editor-error,
  • or the user types C-g.

Active Regions Enabled (initial value t) [Hemlock Variable]

When this variable is non-nil, some primitives signal an editor-error if the region is not active. This may be set to nil for more traditional Emacs region semantics.

*ephemerally-active-command-types* [Variable]

This is a list of command types (see section 7.3), and its initial value is the list of :ephemerally-active and :unkill. When the previous command’s type is one of these, the current-region is active for the currently executing command only, regardless of whether it does something to deactivate the region. However, the current command may activate the region for future commands. :ephemerally-active is a default command type that may be used to ephemerally activate the region, and:unkill is the type used by two commands, Un-kill and Rotate Kill Ring (what users typically think of as C-y and M-y).

activate-region [Function]

This makes the current-region active.

deactivate-region [Function]

After invoking this the current-region is no longer active.

region-active-p [Function]

Returns whether the current-region is active, including ephemerally. This ignores Active Regions Enabled.

check-region-active [Function]

This signals an editor-error when active regions are enabled, and the current-region is not active.

current-region &optional error-if-not-active deactivate-region [Function]

This returns a region formed with current-mark and current-point, optionally signaling an editor-error if the current region is not active. Error-if-not-active defaults to t. Each call returns a distinct region object. Depending on deactivate-region (defaults to t), fetching the current region deactivates it. Hemlock primitives are free to modify text regardless of whether the region is active, so a command that checks for this can deactivate the region whenever it is convenient.

4.5. Searching and Replacing

Before using any of these functions to do a character search, look at character attributes (page 37). They provide a facility similar to the syntax table in real Emacs. Syntax tables are a powerful, general, and efficient mechanism for assigning meanings to characters in various modes.

search-char-code-limit [Constant]

An exclusive upper limit for the char-code of characters given to the searching functions. The result of searches for characters with a char-code greater than or equal to this limit is ill-defined, but it is not an error to do such searches.

new-search-pattern kind direction pattern &optional result-search-pattern [Function]

Returns a search-pattern object which can be given to the find-pattern and replace-pattern functions. A search-pattern is a specification of a particular sort of search to do. direction is either :forward or :backward, indicating the direction to search in. kind specifies the kind of search pattern to make, and pattern is a thing which specifies what to search for. The interpretation of pattern depends on the kind of pattern being made. Currently defined kinds of search pattern are:

:string-insensitive Does a case-insensitive string search,patternbeing the string to search for.

:string-sensitive Does a case-sensitive string search forpattern.

:character Finds an occurrence of the characterpattern. This is case sensitive.

:not-character Find a character which is not the characterpattern.

:test Finds a character which satisfies the function pattern. This function may not be applied an any particular fashion, so it should depend only on what its argument is, and should have no side-effects.

:test-not Similar to :test, except it finds a character that fails the test.

:any Finds a character that is in the stringpattern.

:not-any Finds a character that is not in the stringpattern.

result-search-pattern, if supplied, is a search-pattern to destructively modify to produce the new pattern. Where reasonable this should be supplied, since some kinds of search patterns may involve large data structures.

search-pattern-p search-pattern [Function]

Returns t if search-pattern is a search-pattern object, otherwise nil.

get-search-pattern string direction [Function]

*last-search-pattern* [Variable]

*last-search-string* [Variable]

get-search-pattern interfaces to a default search string and pattern that search and replacing commands can use. These commands then share a default when prompting for what to search or replace, and save on consing a search pattern each time they execute. This uses Default Search Kind (see the Hemlock User’s Manual) when updating the pattern object. This returns the pattern, so you probably don’t need to refer to *last-search-pattern*, but *last-search-string* is useful when prompting.

find-pattern mark search-pattern [Function]

Find the next match of search-pattern starting at mark. If a match is found then mark is altered to point before the matched text and the number of characters matched is returned. If no match is found then nil is returned and mark is not modified.

replace-pattern mark search-pattern replacement &optional n [Function] Replace n matches of search-pattern with the string replacement starting at mark. If n is nil (the default) then replace all matches. A mark pointing before the last replacement done is returned.