# Variables(4)

[Home] [Commands] [Variables] [Macro-Dev] [Glossary]

## NAME

Variables - Macro variables

## SYNOPSIS

#tn
$variableName
%variableName
.variableName
.commandName.variableName
:variableName
:bufferName:variableName

## DESCRIPTION

Variables are part of MicroEmacs macro language and may be used wherever an argument is required. The variable space comprises:-

# - Register Variable
$ - System Variable
% - Global Variable
. - Command Variable
: - Buffer Variable

All variables hold string information, the interpretation of the string (numeric, string or boolean) is determined when the variable is used within the context of the command. There are five types of variable, Register Variables (prefixed with a hash #), System Variables (prefixed with a dollar $), Global Variables (prefixed with a percentage %), Buffer Variables (prefixed with a colon :) and Command Variables (prefixed with a period .).

## Register Variables

Register Variables provide a set of 10 prefixed global (#g0 .. #g9), parent (#p0 .. #p9) and local (#l0 .. #l9) register variables. The interpreted decode time of the register variables is significantly smaller than other variable types as no name space search is performed.

Register variables are assigned using set-variable(2), their value may be queried with describe-variable(2), unlike Global Buffer or Command variables they cannot be deleted.

Register variables are implemented like a stack, where the global registers are the top of the stack and every executing macro gets its own set of resister variables (#l?). The macro also has access to the global registers (#g?) and its calling, or parent macro (#p?). If the macro has no parent macro then the global registers are also the parent registers. Outside macros, i.e. using set-variable manually, the global parent and local registers are the same.

Register variables are typically used for retaining short term state, computation steps etc. As with the User Variables, the global register variables are global and care must be taken with nested macro invocations to ensure that the register usage does not conflict.

## System Variables

MicroEmacs defines many System variables which are used to configure many aspects of the editors environment. The functionality of each system variable has been documented, they can be set and described but cannot be unset. If the user attempts to set or describe a non-existent MicroEmacs system variable (e.g. $PATH) the system environment is used instead, allowing the user to query and alter the system environment.

## Global, Command and Buffer Variables

The Global variables are denoted by an initial % character followed by the name of the variable variableName. The variableName may be any ASCII character string up to 127 characters in length, all characters of the name are significant. Shorter names are preferred as this speeds up execution. Global Variables exist in a global context which all macros have access to.

Command variables exist within the scope of a command, they are denoted by the period (.) character. They can be accessed by one of two forms, either .variableName or .commandName.variableName. The first form, without the command name, assumes the scope to be the current command, as such may only be used to access internal variables. The second form qualifies the scope by specifying the command, this form is much more versatile and may be used to access any command variable from any other command, e.g.

    define-macro foo
        set-variable .foo "Hello world"
        1000 ml-write &cat "foo1: " .foo
        1000 ml-write &cat "foo2: " .foo.foo
    !emacro
    define-macro bar
        foo
        1000 ml-write &cat "bar1: " .foo
        1000 ml-write &cat "bar2: " .foo.foo
    !emacro

    bar

When bar is executed the following messages may be observed:-

    foo1: Hello World
    foo2: Hello World
    bar1: ERROR
    bar2: Hello World

When a macro file or buffer is executed, they are executed within their own scope so local scope command variables (form 1) may be created and used in that scope. Any such variables created are automatically deleted at the end of execution. For example, the default color scheme generator macro file, `schemed.emf`, creates command variables for the created colors to aid readability:-

    add-color &set .green     3 0   200 0
    a0dd-color &set .lgreen   11 0   255 0

    ...

    add-color-scheme .scheme.cardback   .lgreen   .green   .lgreen ...

The variables only exist as a file or buffer is being executed, they are not accessible by another command once the command or buffer execution has finished.

Buffer variables are similar to Command variable in function and behaviour except that their scope is of a buffer and are denoted by the colon (:) character. Access can be in one of two forms, either :variableName where the scope is assumed to be the current buffer or :bufferName:variableName, where the scope is explicitly given allowing access to any buffer variable, e.g.

    find-buffer "foo"
    set-variable :foo "Hello world"
    find-buffer "bar"
    set-variable :bar "Hello world"
    1000 ml-write &cat ":foo     " :foo
    1000 ml-write &cat ":foo:foo " :foo:foo
    1000 ml-write &cat ":bar     " :bar
    1000 ml-write &cat ":bar:bar " :bar:bar

When the above is executed the following messages may be observed:-

    :foo     ERROR
    :foo:foo Hello World
    :bar     Hello World
    :bar:bar Hello World

Global, Buffer and Command variables are automatically defined when they are used. A variable is assigned with set-variable(2) and may be subsequently deleted with unset-variable(2). The current assignment of a variable may be queried from the command line using describe-variable(2). e.g.

    define-macro foo
    !emacro
    set-variable %foo "Some string"
    set-variable :bar "Some string"
    set-variable .foo.bar "Some string"

    ...

    ml-write &spr "%s %s %s" %foo :bar .foo.bar

    ...

    unset-variable :bar
    unset-variable %foo
    unset-variable .foo.bar

An undefined variable returns the string `ERROR`, this known state is used to advantage with the hilighting initialization, e.g.

    !if &sequal .hilight.c "ERROR"
        set-variable .hilight.c &pinc .hilight.next 1
    !endif
    ;
    ; Hi-light C Mode
    ;
    0 hilight .hilight.c  2 50             $global-scheme

In this case the variable .hilight.c is explicitly tested for definition, if it is undefined then it is assigned a new value.

Conventionally, names are separated with a minus sign character (-) e.g. `foo-bar`. It is strongly advised that the name space is kept reasonably clean, since there are no restrictions on the number of macros that may be defined, problems will arise if different macros use the same variables in different contexts. Where possible, Command or Buffer Variables are preferable to Global Variables since they have no side effects on other macros or buffers. It is advised that all variable names associated with a particular macro set are prefixed with short identifier to make the variable name space unique. e.g. the Metris macro prefixes all variables with :met-; the draw macro uses :dw-, the patience macro :pat- etc.

Macro writers should endeavor to use the minimal number of variables, obviously the more variables that exist in the system, the greater the lookup time to find a variable. Use Register Variables in preference to Command, Global or Buffer variables for intimidate computation steps, temporary state etc.

Note that Buffer Variables are automatically deleted when the buffer is deleted.

## EXAMPLE

The following example is the macro to convert tabs to spaces, it is shown in two forms, with User Variables and with Register Variables, the register variable implementation is obviously preferable since no new variables have been defined.

## User Variable Implementation

    ;
    ; tabs-to-spaces.
    ; Convert all of the tabs to spaces.
    define-macro tabs-to-spaces
        set-variable %curline $window-line        ; Remember line
        beginning-of-buffer
        !force search-forward "\t"
        !while $status
            3 drop-history
            set-variable %curcol $window-acol
            backward-delete-char
            &sub %curcol $window-acol insert-space
            !force search-forward "\t"
        !done
        3 drop-history
        goto-line %curline
        update-screen
        ml-write "Converted tabs!"
    !emacro

## Register Variable Implementation

    ;
    ; tabs-to-spaces.
    ; Convert all of the tabs to spaces.
    define-macro tabs-to-spaces
        ; Remember line
        set-variable #l0 $window-line
        beginning-of-buffer
        !force search-forward "\t"
        !while $status
            set-variable #l1 $window-acol
            backward-delete-char
            &sub #l1 $window-acol insert-space
            !force search-forward "\t"
        !done
        goto-line #l0
        screen-update
        ml-write "[Converted tabs]"
    !emacro

## SEE ALSO

@wc(4), define-macro(2), describe-variable(2), set-variable(2), unset-variable(2).

(c) Copyright JASSPA 2009
Last Modified: 2009/08/29
Generated On: 2009/10/12

</HMTL>