Document revision date: 30 March 2001

## DEC Text Processing Utility Reference Manual

Previous | Contents | Index

The following example determines whether the cursor is at the end of the line. It sends a text message to the message area on the screen about the position of the cursor.

#2
    PROCEDURE user_on_eol

    ! test if at eol, return true or false

       MOVE_HORIZONTAL (1);
       IF CURRENT_OFFSET = 0             ! then we are on eol
       THEN
           user_on_end_of_line := 1;   ! return true
           MESSAGE ("Cursor at end of line");
       ELSE
           user_on_end_of_line := 0;   ! return false
           MESSAGE ("Cursor is not at the end of line");
       ENDIF;
       MOVE_HORIZONTAL (-1);             ! move back
    ENDPROCEDURE;

> The following example fetches the text associated with the message code TPU$_OPENIN and substitutes the string "BAT.BAR" into the message:

#3
    MESSAGE (TPU$_OPENIN, TPU$K_MESSAGE_TEXT, "bat.bar");

> All of the text of the message is fetched. The following string is displayed in the message buffer:

>     Error opening BAT.BAR as input

## MESSAGE_TEXT

### Format

> string := MESSAGE_TEXT ( {integer1 |keyword} [[, integer2 [[, FAO-parameter
> [[, FAO-parameters... ]] ]] ]])

### Parameters

> #### integer1

> The integer for the message code associated with the text that is to be fetched.

> #### keyword

> The keyword for the message code associated with the text that is to be fetched. DECTPU provides keywords for all of the message codes used by DECTPU and the EVE editor.

> #### integer2

> A bit-encoded integer that specifies what fields of the message text associated with the message code from the first parameter are to be fetched. If the message flags are not specified or the value is 0, then the message flags set by the SET (MESSAGE_FLAGS) built-in procedure are used.

> Table 2-8 shows the message flags.

> Table 2-8 Message Flag Values for MESSAGE_TEXT
> Bit | Constant | Meaning
> --- | --- | ---
> 0 | TPU$K_MESSAGE_TEXT | Include text of message.
> 1 | TPU$K_MESSAGE_ID | Include message identifier.
> 2 | TPU$K_MESSAGE_SEVERITY | Include severity level indicator.
> 3 | TPU$K_MESSAGE_FACILITY | Include facility name.

> #### FAO-parameter

> One or more expressions that evaluate to an integer or string. The MESSAGE_TEXT built-in procedure uses these integers and strings as arguments to the $FAO system service. It then substitutes the resultant values into the text associated with the message code to form the returned string.

### Return Value

The text associated with a message code that is fetched and formatted by MESSAGE_TEXT.

### Description

> The MESSAGE_TEXT procedure fetches the text associated with a message code. MESSAGE_TEXT uses FAO directives to specify how strings and integers should be substituted into the text.

> MESSAGE_TEXT accepts up to 127 parameters. This built-in can return strings of 65535 characters maximum.

> MESSAGE_TEXT returns a formatted string, specified by the message code passed as the first parameter and constructed according to the rules of the $FAO system service. The control string associated with the message code directs the formatting process, and the optional arguments are values to be substituted into the control string.

> MESSAGE_TEXT does not capitalize the first character of the returned string. The MESSAGE built-in procedure, on the other hand, does capitalize the first character.

> You can include the following FAO directives as part of the message text:

> !AS | Inserts a string as is
> !OL | Converts an integer to octal notation
> !XL | Converts an integer to hexadecimal notation
> !ZL | Converts an integer to decimal notation
> !UL | Converts an integer to decimal notation without adjusting for negative number
> !SL | Converts an integer to decimal notation with negative numbers converted properly
> !/ | Inserts a new line character (carriage return/line feed)
> !_ | Inserts a tab
> !} | Inserts a form feed
> !! | Inserts an exclamation point
> !%S | Inserts an s if the most recently converted number is not 1
> !%T | Inserts the current time if you enter 0 as the parameter (you cannot pass a specific time because DECTPU does not use quadwords)
> !%D | Inserts the current date and time if you enter 0 as the parameter (you cannot pass a specific date because DECTPU does not use quadwords)

> For complete information on the $FAO and $GETMSG system services, see the OpenVMS System Services Reference Manual.

#### Signaled Errors

TPU$_INVFAOPARAM | WARNING | Argument was not a string or integer.
TPU$_NEEDTOASSIGN | ERROR | MESSAGE_TEXT must appear on the right-hand side of an assignment statement.
TPU$_INVPARAM | ERROR | You specified an argument of the wrong type.
TPU$_TOOFEW | ERROR | MESSAGE_TEXT requires at least one parameter.
TPU$_TOOMANY | ERROR | MESSAGE_TEXT accepts up to 20 FAO directives.
TPU$_FLAGTRUNC | INFORMATIONAL | Message flag truncated to 4 bits.
TPU$_SYSERROR | ERROR | Error fetching the message text.

### Example

> The following example fetches the text associated with the message code TPU$_OPENIN and substitutes the string "BAT.BAR" into the message:

    all_message_flags := TPU$K_MESSAGE_TEXT OR
                         TPU$K_MESSAGE_ID OR
                         TPU$K_MESSAGE_SEVERITY OR
                         TPU$K_MESSAGE_FACILITY;
    openin_text := MESSAGE_TEXT (TPU$_OPENIN, all_message_flags,
                   "bat.bar");

> All of the text of the message is fetched. The following string is stored in the variable openin_text:

>     %TPU-E-OPENIN, error opening BAT.BAR as input

## MODIFY_RANGE

### Format

> MODIFY_RANGE (range, {marker1 |keyword1}, {marker2 |keyword1}
> [[, keyword2 ]])

### Parameters

> #### range

> The range to be modified.

> #### marker1

> The starting mark for the range.

> #### marker2

> The ending mark for the range.

> #### keyword1

> A keyword that indicates the point in the buffer where you want the range to begin or end. Table 2-9 shows the valid keywords and their meanings. Use of the delimiting keywords is more efficient than the BEGINNING_OF and END_OF built-in procedures.

> Table 2-9 MODIFY_RANGE Keyword Parameters
> Keyword | Meaning
> --- | ---
> LINE_BEGIN | The beginning of the current buffer's current line.
> LINE_END | The end of the current buffer's current line.
> BUFFER_BEGIN | Line 1, offset 0 in the current buffer. This is the first position where a character could be inserted, regardless of whether there is a character there. This is the same as the point referred to by BEGINNING_OF (CURRENT_BUFFER).
> BUFFER_END | The last position in the buffer where a character could be inserted, regardless of whether there is a character there. This is the same as the point referred to by END_OF (CURRENT_BUFFER).

> #### keyword2

> A keyword that specifies the new video attribute for the range. By default, the attribute is not modified. You can use the NONE, REVERSE, UNDERLINE, BLINK, or BOLD keywords to specify this parameter.

### Description

> The MODIFY_RANGE procedure dynamically modifies a range. You can use MODIFY_RANGE to specify a new starting mark and ending mark for an existing range.

> MODIFY_RANGE can also change the characteristics of the range without deleting, re-creating, and repainting all the characters in the range. Using MODIFY_RANGE, you can direct DECTPU to apply or remove the range's video attribute to or from characters as you select and unselect text.

> Ranges are limited to one video attribute at a time. Specifying a video attribute different from the present attribute causes DECTPU to apply the new attribute to the entire visible portion of the range.

> If the video attribute stays the same and only the markers move, the only characters that are refreshed are those visible characters newly added to the range and those visible characters that are no longer part of the range.

#### Signaled Errors

TPU$_NOTSAMEBUF | WARNING | The first and second marker are in different buffers.
TPU$_ARGMISMATCH | ERROR | The data type of the indicated parameter is not supported by the MODIFY_RANGE built-in.
TPU$_BADKEY | WARNING | You specified an illegal keyword.
TPU$_INVPARAM | ERROR | You specified a parameter of the wrong type.
TPU$_MODRANGEMARKS | ERROR | MODIFY_RANGE requires either two marker parameters or none.
TPU$_TOOFEW | ERROR | Too few arguments passed to the MODIFY_RANGE built-in.
TPU$_TOOMANY | ERROR | Too many arguments passed to the MODIFY_RANGE built-in.
TPU$_NORETURNVALUE | ERROR | MODIFY_RANGE cannot return a value.

### Examples

> The following example creates a range between the editing point and the pointer cursor location. At a point in the program after you might have moved the pointer cursor, the code fragment modifies the range to reflect the new pointer cursor location.

#1
    begin_mark := MARK (BOLD);
    POSITION (MOUSE);
    finish_mark := MARK (BOLD);
    this_range := CREATE_RANGE (begin_mark, finish_mark, BOLD);
    !  .
    !  .  (User may have moved mouse)
    !  .
    POSITION (MOUSE);
    new_mark := MARK (BOLD);
    IF new_mark <> finish_mark
    THEN
        MODIFY_RANGE (this_range, begin_mark, new_mark, BOLD);
    ENDIF;

> The following example causes the range dynamic_range to shrink to one character, then grow until it becomes as large as the range remembered_range:

#2
    PROCEDURE move_mark (place_to_start, direction);

        POSITION (place_to_start);

        IF direction = 1
        THEN
            MOVE_HORIZONTAL (1);
        ELSE
            MOVE_HORIZONTAL (-1);
        ENDIF;

        RETURN MARK (NONE);

    ENDPROCEDURE;

    PROCEDURE user_shrink_and_enlarge_range

        LOCAL  start_mark,
               end_mark,
               direction,
               dynamic_range,
               rendition,
               remembered_range;

                                               ! The following lines
                                               ! create a range that
                                               ! shrinks and grows and
                                               ! a range that defines
                                               ! the limits of the dynamic
                                               ! range.

        POSITION (LINE_BEGIN);
        start_mark := MARK (NONE);
        POSITION (LINE_END);
        end_mark := MARK (NONE);
        rendition := REVERSE;
        remembered_range := CREATE_RANGE (start_mark, end_mark, NONE);
        dynamic_range := CREATE_RANGE (start_mark, end_mark, rendition);

                                                ! The following lines
                                                ! shrink and enlarge
                                                ! the dynamic range.

        direction := 1;

        LOOP
            UPDATE (CURRENT_WINDOW);

            start_mark := move_mark (BEGINNING_OF (dynamic_range), direction);
            end_mark := move_mark (END_OF (dynamic_range), 1 - direction);

            MODIFY_RANGE (dynamic_range, start_mark, end_mark);

            IF start_mark > end_mark
            THEN
                EXITIF READ_KEY = Ctrl_Z_KEY;
                direction := 0;
                IF rendition = REVERSE
                THEN
                    rendition := BOLD;
                ELSE
                    rendition := REVERSE;
                ENDIF;
                MODIFY_RANGE (dynamic_range, , , rendition);

            ENDIF;

            IF (start_mark = BEGINNING_OF (remembered_range)) OR
               (end_mark = END_OF (remembered_range))
            THEN
                direction := 1;
            ENDIF;
        ENDLOOP;

    ENDPROCEDURE;

> The following example aligns text that conforms to the pattern specified in the second parameter. For example, if you want to align all comments in a piece of DECTPU code, you would pass as the second parameter a pattern defined as an exclamation point followed by an arbitrary amount of text or white space and terminated by a line end.

> The procedure is passed a range of text. As the procedure searches the range to identify the rightmost piece of text that matches the pattern, the procedure modifies the range to exclude any matching text. Next, the procedure searches the original range again and inserts padding spaces in front of each instance of matching text, making the text align with the rightmost instance of matching text.

#3
    PROCEDURE line_up_characters (text_range, lined_chars_pat)

    LOCAL
        range_start,
        range_end,
        temp_range,
        max_cols;

    range_end := END_OF (text_range);         ! These statements store
                                              ! the ends of the range
                                              ! containing the text operated on.

    range_start := BEGINNING_OF (text_range);

                                              ! The following statements
                                              ! locate the portions of
                                              ! text that match the pattern
                                              ! and determine which is
                                              ! furthest to the right.

    max_cols := 0;
    LOOP
        temp_range := SEARCH_QUIETLY (lined_chars_pat, REVERSE, EXACT, text_range);
        EXITIF temp_range = 0;
        POSITION (temp_range);
        IF GET_INFO (MARK (NONE), "offset_column") > max_cols
        THEN
            max_cols := GET_INFO (MARK (NONE), "offset_column");
        ENDIF;
        MOVE_HORIZONTAL (-1);
        MODIFY_RANGE (text_range, BEGINNING_OF (text_range), MARK (NONE));
    ENDLOOP;

                                                         ! The following lines
                                                         ! locate matches to the
    text_range := CREATE_RANGE (range_start, range_end); ! pattern and align them
                                                         ! with the rightmost
                                                         ! piece of matching text.
    LOOP
        temp_range := SEARCH_QUIETLY (lined_chars_pat, FORWARD, EXACT, text_range);
        EXITIF temp_range = 0;
        POSITION (temp_range);
        IF GET_INFO (MARK (NONE), "offset_column") < max_cols
        THEN
            COPY_TEXT (" " * (max_cols - GET_INFO (MARK (NONE), "offset_column")));
        ENDIF;
        MOVE_HORIZONTAL (1);
        MODIFY_RANGE (text_range, END_OF (text_range), MARK (NONE));
    ENDLOOP;

    !
    ! Restore the range to its original state, plus a reverse attribute.
    !
    text_range := CREATE_RANGE (range_start, range_end, REVERSE); ! This line
                                                                  ! restores the
                                                                  ! range to its
                                                                  ! original state
                                                                  ! and displays
                                                                  ! the contents
                                                                  ! in reverse
                                                                  ! video.
    ENDPROCEDURE;

## MOVE_HORIZONTAL

### Format

> MOVE_HORIZONTAL (integer)

### Parameter

> #### integer

> The signed integer value that indicates the number of characters the editing point should be moved. A positive integer specifies movement toward the end of the buffer. A negative integer specifies movement toward the beginning of the buffer.

> DECTPU does not count the column where the editing point is located when determining where to establish the new editing point. DECTPU does count the end-of-line (the column after the last text character on the line) when determining where to establish the new editing point.

### Description

> The MOVE_HORIZONTAL procedure changes the editing point in the current buffer by the number of characters you specify. The horizontal adjustment of the editing point is tied to text. MOVE_HORIZONTAL crosses line boundaries to adjust the current character position.

> You cannot see the adjustment caused by MOVE_HORIZONTAL unless the current buffer is mapped to a visible window. If it is, DECTPU scrolls text in the window, if necessary, so that the editing point you establish with MOVE_HORIZONTAL is within the scrolling limits set for the window.

> If you try to move past the beginning or the end of a buffer, DECTPU displays a warning message.

> Using MOVE_HORIZONTAL may cause DECTPU to insert padding spaces or blank lines in the buffer. MOVE_HORIZONTAL causes the screen manager to place the editing point at the cursor position if the current buffer is mapped to a visible window. For more information on the distinction between the cursor position and the editing point, see Appendix C.

> If the cursor is not located on a character (that is, if the cursor is before the beginning of a line, beyond the end of a line, in the middle of a tab, or below the end of the buffer), DECTPU inserts padding spaces or blank lines into the buffer to fill the space between the cursor position and the nearest text.

#### Signaled Errors

TPU$_TOOFEW | ERROR | MOVE_HORIZONTAL requires one parameter.
TPU$_TOOMANY | ERROR | You specified more than one parameter.
TPU$_INVPARAM | ERROR | The specified parameter has the wrong type.
TPU$_NOCURRENTBUF | WARNING | You are not positioned in a buffer.
TPU$_ENDOFBUF | WARNING | You are trying to move forward past the last character of the buffer.
TPU$_BEGOFBUF | WARNING | You are trying to move in reverse past the first character of the buffer.

### Examples

> The following example moves the editing point five characters toward the end of the current buffer:

#1
    MOVE_HORIZONTAL (+5)

> The following example moves the editing point by sections that are eight lines long and uses MOVE_HORIZONTAL to put the editing point at the beginning of the line:

#2
    PROCEDURE user_move_by_lines

       IF CURRENT_DIRECTION = FORWARD
       THEN
           MOVE_VERTICAL (8)
       ELSE
           MOVE_VERTICAL(- 8)
       ENDIF;
       MOVE_HORIZONTAL (-CURRENT_OFFSET);
    ENDPROCEDURE;

## MOVE_TEXT

### Format

> [[range2 := ]]MOVE_TEXT ( {buffer |range1 |string})

### Parameters

> #### buffer

> The buffer from which text is moved.

> #### range1

> The range from which text is moved.

> #### string

> A string that represents the text you want to move. Text is not removed from its original location with this argument.

### Return Value

The range where the copied text has been placed.

### Description

> The MOVE_TEXT procedure moves the text you specify and inserts or overwrites it in the current buffer, depending on the mode of the current buffer. When you move text with range and buffer parameters, you remove it from its original location. For information on how to copy text instead of removing it, see the description of the COPY_TEXT built-in procedure.

> If the current buffer is in insert mode, the text you specify is inserted before the editing point in the current buffer. If the current buffer is in overstrike mode, the text you specify replaces text starting at the current position and continuing for the length of the string, range, or buffer.

> Markers and ranges are not moved with the text. If the text of a marker or a range is moved, the marker or range structure and any video attribute that you specified for the marker or range are moved to the next closest character, which is always the character following the marker or range. To remove the marker or range structure, use the DELETE built-in procedure or set the variable to which the range is assigned to 0.

> MOVE_TEXT is similar to COPY_TEXT. However, MOVE_TEXT erases the text from its original string, range, or buffer, while COPY_TEXT just makes a copy of the text and places the copy at the new location.

> You cannot add a buffer or a range to itself. If you try to do so, DECTPU issues an error message. If you try to insert a range into itself, part of the range is copied before DECTPU signals an error. If you try to overstrike a range into itself, DECTPU may or may not signal an error.

> MOVE_TEXT may cause DECTPU to insert padding spaces or blank lines in the buffer. MOVE_TEXT causes the screen manager to place the editing point at the cursor position if the current buffer is mapped to a visible window. For more information on the distinction between the cursor position and the editing point, see Appendix C.

> If the cursor is not located on a character (that is, if the cursor is before the beginning of a line, beyond the end of a line, in the middle of a tab, or below the end of the buffer), DECTPU inserts padding spaces or blank lines into the buffer to fill the space between the cursor position and the nearest text.

#### Signaled Errors

TPU$_NOCACHE | ERROR | There is not enough memory to allocate a new cache.
TPU$_TOOFEW | ERROR | MOVE_TEXT requires one argument.
TPU$_TOOMANY | ERROR | MOVE_TEXT accepts only one argument.
TPU$_ARGMISMATCH | ERROR | The argument to MOVE_TEXT must be a buffer, range, or string.
TPU$_NOTMODIFIABLE | ERROR | You cannot copy text into an unmodifiable buffer.
TPU$_MOVETOCOPY | WARNING | MOVE_TEXT was able to copy the text into the current buffer but could not delete it from the source buffer because the source buffer is unmodifiable.

### Examples

> If you are using insert mode for text entry, the following statement causes the text from main_buffer to be placed in front of the current position in the current buffer. The text is removed from main_buffer.

#1
    MOVE_TEXT (main_buffer)

> Previous | Next | Contents | Index

> | privacy and legal statement |
> 6020PRO_019.HTML