Programming Emacs From Other Languages

You can program Emacs using the Mock Lisp programming language built in to Emacs, or you can use any other supported VMS programming language. This chapter describes the various ways you can program Emacs from other VMS programming languages.

EMACSSHR and Callable Emacs describes how to invoke Emacs from another program. Shareable Image Access describes how to access internal Emacs routines from another program.

EMACSSHR and Callable Emacs

The image SYS$SHARE:EMACSSHR.EXE is a callable interface to Emacs that allows you to access Emacs from a program.

EMACSSHR tries to access the Emacs running in the subprocess described by the logical name EMACS_PROCESSNAME. If this logical name does not exist, EMACSSHR uses the default Emacs subprocess name. If the target Emacs subprocess does not exist, EMACSSHR creates the subprocess and starts Emacs in the subprocess. Otherwise, it simply attaches to the specified Emacs as usual.

The following sections describe the various entry points in EMACSSHR.

emacs_emacs

This interface is the simplest entry point to EMACSSHR. You specify the address of a string descriptor as the only argument, and EMACSSHR treats the string as a DCL command line. The command is parsed in the usual way, and then the arguments are passed to the appropriate Emacs image.

emacs_edit

EMACSSHR conforms to the calling standards for callable VMS MAIL images. EMACSSHR has an appropriate universal symbol, EMACS_EDIT, which is the callable entry point for callable VMS MAIL. EMACS_EDIT takes the following parameters:

INFILE

The address of a string descriptor containing the name of the file to be edited.

OUTFILE

The address of a string descriptor containing the name of the file to be written with the completed edits. If this parameter is omitted, The default action is to write a new version of the input file.

PACKAGENAME

The address of a descriptor containing the name of the Emacs package to be run to edit the file. If this parameter is omitted, the default package Emacs is invoked.

emacs_utility

The EMACS_UTILITY entry point in EMACSSHR provides access to all of the functionality of the Emacs command interface. This entry point takes the following parameters:

PROCESSNAME

The address of a descriptor containing the name of the subprocess to which to attach when resuming a paused Emacs or to spawn when creating a new EMACS. Omit this parameter to use the current process name.

PACKAGE

The address of a descriptor containing the name of the package to run when Emacs gains control. Omit this parameter to run the default package (EMACS).

RESTORE

The address of a descriptor containing the name of the environment file to be restored by Emacs when it is starting a new subprocess. If you omit this argument, no environment is restored.

ARGCOUNT

A longword containing the number of entries in the ARGS vector.

ARGS

The address of a vector of descriptors containing the arguments for EMACS.

LOG

A longword used to control whether logging messages are displayed between Emacs and DCL transitions. If true, logging is performed.

CURRENTPROCESS

A longword used to control whether Emacs is run in the current process or in a subprocess. If true, Emacs runs in the current process.

PATH

The address of a descriptor which contains the default directory of the parent process. If omitted, the default directory is used.

RETADR

The address of a string descriptor that EMACS_UTILITY fills with any information returned from Emacs when it exits or pauses.

Shareable Image Access

The Shareable Image Access facility allows you to access and execute any routines defined with the universal attribute in a VMS shareable image. You can access routines in external images from Emacs by defining an Emacs external function and by specifying the image location of the external function; Emacs will load in the specified shareable image file when the function is called.

Emacs allows you to call an external function in exactly the same way as any other Emacs function. Arguments can be provided with the usual range of types.

Emacs provides an external function with a set of call-back operations that enable it to perform operations such as fetching arguments and reading and writing buffers.

These features provide a layered interface to any shareable image by providing interfacing routines between Emacs and the shareable image. This is shown in ~~~Ref:layermodelfig~~~.

Figure: Layer Model of External FunctionsFIGUREFILE: postscript:docs$src:emacspglayermodelfig.psFIGUREFILE: bookreader:docs$src:emacspglayermodelfig.fse

shareable image access functions

(external-function function shareable-image symbol)

Defines an Emacs function which executes code in a shareable image. function is the name of the Emacs function to be defined. When this function is called, the code in the shareable image is executed. shareable-image is the filename of the shareable image in which the code is located. If no device or directory is specified, SYS$SHARE: is used. symbol is the name of the universal symbol defining the entry point to the routine to be executed. If this argument is omitted, function is used to define symbol.

(list-images)

Creates a buffer called Image list and fills it with information about the images in which external functions have been referenced.

A call to external-function does not actually cause the shareable image to be loaded and no check is made to see that the required symbol is defined in the image---the image is loaded and symbol is checked when the function is first called.

When a saved environment is restored, images are automatically re-loaded the first time an external function is called.

external function interface

Each function called by Emacs must comply with a strict set of inputs and outputs. Emacs imposes these rules to limit the possibility of a called routine destroying EMACS' internal data structures.

Each function called by Emacs must accept the following arguments:

CALLBACK

This is the address of the Emacs call-back routine that allows the code to access the call-back operations. You call this routine according to the rules described in the following sections.

CONTEXT

This is the address of a longword that the called routine can use to maintain some cross-call context. You could use this longword as the address of a context block, and allocate this block using the Emacs memory allocation call-back operation.

RESTORE

This is the address of a longword that contains the current value of the restored-environment variable. You should use this value in conjunction with the routine's context block to decide when to take any special action after a saved environment is restored.

Any routine value that is returned to Emacs is ignored.

call-back operations

Each call-back operation is invoked by calling the passed call-back routine address. Each operation is identified by passing its operation code as the first argument. The argument codes are described below and the symbols are available for the supported VMS languages in the file SYS$-LIBRARY:-EMACS-CALL-BACK.*-0. Each operation may have additional arguments which are also described below.

The call-back routine returns an indication of the success of the requested operation. When an operation fails, the Emacs error buffer is filled with a suitable error message and the error flag is set. Unless you decide to issue a better error message, your routine should exit and Emacs will display the generated error message; all further MLisp processing will be aborted.

emacs__k_message

This operation is equivalent to the message MLisp function. You should provide one additional argument which is the address of a string descriptor containing the message text to be displayed.

The message will be displayed when the screen is next updated.

emacs__k_error

This operation is equivalent to the error-message MLisp function. You should provide one additional argument which is the address of a string descriptor containing the error message to be displayed.

All further MLisp processing will be aborted (until the most enclosing error-occurred block is encountered), and the error message will be displayed when the screen is next updated.

emacs__k_sitfor

This operation is equivalent to the sit-for MLisp function. You provide one additional argument which is the number of tenths of a second that you want to pause the display and Emacs processing. You pass this argument by value.

The display is updated, and Emacs pauses for the specified amount of time.

emacs__k_arg_count

This operation is equivalent to the nargs MLisp function. You provide one additional argument which is the address of a longword where the argument count is returned.

The returned value is the number of arguments with which the external function was called.

emacs__k_check_args

This operation implements an easy way for external functions to check that they were called with a satisfactory number of arguments. You provide the following arguments:

MIN

The minimum number of arguments acceptable. It is passed by value.

MAX

The maximum number of arguments acceptable. This parameter is passed by value.

This request checks that the number of arguments supplied with the external function call is between the specified limits. If the argument count is unsatisfactory, Emacs generates a suitable error message, and the call-back function returns an error status. If the argument count is within the bounds, Emacs returns a success status.

emacs__k_string_arg

This operation provides access to the specified argument and returns it as a string.

You provide the following arguments:

ARGNUM

The number of the argument that you want to access. Argument number 1 is the first argument.

STRING

The address of a string descriptor which Emacs fills with the specified argument.

RETLEN

The address of a word which Emacs fills with the length of the returned string.

This operation evaluates the specified argument. If the argument is not a string, it is coerced into one. The resulting string is then copied into the provided buffer.

If the buffer is not big enough for the string, a suitable error status is returned, and the extra characters are ignored.

Note that each time this operation is performed on a particular argument,the expression that makes up the argument is evaluated. So, if the argument calls a function which has side effects, strange behaviour may result. It is better to access the argument once, and then maintain the argument in your code.

emacs__k_numeric_arg

This operation provides access to the specified argument, and returns it as an integer.

You provide the following arguments:

ARGNUM

The number of the argument that you want to access. Argument number 1 is the first argument.

RESULT

The address of a longword that Emacs fills with the required argument.

The specified argument is evaluated. If the argument is not an integer, it is coerced into one. The resulting integer value is then copied into the provided longword.

Note that each time this operation is requested on a particular argument,the expression that makes up the argument is evaluated. So, if the argument calls a function which has side effects, strange behaviour may result. It is better to access the argument once, and then maintain the argument in your code.

emacs__k_string_result

This request causes the specified text string to be returned as the result of the external function call. It takes a single argument which is the address of a descriptor containing the string to be returned.

This request does not cause the calling routine to be terminated; it merely specifies the value to be returned when the code does eventually exit. If this call-back is requested more that once from the same routine, the value returned is the value specified in the last call to either the emacs__k_string_result or emacs__k_numeric_result operations.

emacs__k_numeric_result

This request causes the specified integer to be returned as the result of the external function call. It takes a single argument which is the value to be returned.

This request does not cause the calling routine to be terminated; it merely specifies the value to be returned when the routine does eventually exit. If this operation is requested more that once from the same routine, the value returned is the value specified in the last call to either the emacs__k_string_result or emacs__k_numeric_result operations.

emacs__k_allocate

This request allocates some memory using the Emacs memory allocation scheme. Memory allocated by Emacs is saved in environment files when the save-environment function is executed.

The following parameters are expected:

SIZE

The number of bytes of memory you want Emacs to allocate. This argument is passed by value.

RETADR

The address of a longword that Emacs fills with the address of the allocated memory.

emacs__k_reallocate

This request reallocates some memory using the Emacs memory allocation scheme. You provide some existing Emacs memory, and it is reallocated with an adjusted size. Existing data is copied into the new memory block and is truncated if the new block is shorter than the old block. You can use this call-back to grow some already-allocated memory by a specified amount.

The following parameters are expected:

OLDBUF

The address of the existing memory to be reallocated.

SIZE

The size required for the reallocated memory.

RETADR

The address of a longword that Emacs fills with the address of the reallocated memory.

emacs__k_free

This request frees some Emacs memory previously allocated by emacs__k_allocate or emacs__k_reallocate. Memory freed that was not allocated by these routines will be ignored.

The following parameter is expected:

BUFFER

The address of the memory to be freed.

emacs__k_buffer_size

This routine is used to find out how many characters are in the current buffer. When narrowing is in force, only accessible characters are counted.

The following parameter is expected:

RETLEN

The address of a longword that Emacs fills with the size of the current buffer.

emacs__k_dot

This request returns the current buffer name and current position of dot in the buffer. It is equivalent to the dot MLisp function.

The following parameters are expected:

RETPOS

The address of a longword that Emacs fills with the current position of dot.

BUFFER

The address of a string descriptor into which Emacs puts the current buffer name.

RETLEN

The address of a word that Emacs fills with the length of the current buffer's name.

emacs__k_mark

This request returns the current buffer name and current position of the mark in the buffer. It is equivalent to the mark MLisp function.

The following parameters are expected:

RETPOS

The address of a longword that Emacs fills with the current position of the mark.

BUFFER

The address of a string descriptor into which Emacs puts the current buffer name.

RETLEN

The address of a word that Emacs fills with the length of the current buffer's name.

emacs__k_set_mark

This request sets or unsets the current buffer's mark. If the mark is set, it is set to the current value of dot. It is equivalent to the set-mark and unset-mark MLisp functions.

The following parameter is expected:

SETUNSET

A longword indicating whether to set the mark (low bit set)or unset it (low bit clear).

emacs__k_use_buffer

This function provides access to the MLisp temp-use-buffer function. It switches the current buffer to the named buffer without altering any windows. Note that if you use this function and you cause the screen to be updated (with emacs__k_sitfor), Emacs will bind the buffer to a window.

The following parameter is expected:

BUFFER

The address of a descriptor containing the name of the buffer to be used.

emacs__k_goto_character

This request causes dot to be positioned at the specified character. If you specify a value before the start of the buffer, dot is moved to the start of the buffer. If you specify a value beyond the end of the buffer,dot is moved to the end of the buffer.

emacs__k_gotocharacter call-back is equivalent to the goto-character MLisp function.

The following parameter is expected:

POSITION

A longword describing the position required.

emacs__k_insert_character

This request implements the insert-character MLisp function. It inserts the single character specified by the ASCII code provided.

The following parameter is expected:

CHARACTER

A longword containing the ASCII code for the character to be inserted.

emacs__k_insert_string

This request provides access to the insert-string MLisp function. It inserts the specified string into the current buffer.

The following parameter is expected:

STRING

The address of a string descriptor containing the string to be inserted in the current buffer.

emacs__k_delete_characters

This request allows you to delete characters from the current buffer around dot. You provide the number of characters to be deleted. A request to delete 0 characters has no effect; positive character counts cause characters after dot to be deleted, while negative counts cause characters before dot to be deleted.

The following parameter is expected:

COUNT

The number of characters to be deleted.

emacs__k_fetch_character

This request returns the value of the single character at the specified position in the current buffer. If the requested position is beyond the bounds of the current buffer, -1 is returned.

The following parameters are expected:

POSITION

The character position of the character to be fetched.

RETCHAR

The address of a longword that Emacs fills with the character at the specified position.

emacs__k_return_string_to_param

This request writes a string to the parameter specified in the original call of the external function. It can be used to pass multiple text values from an external function.

An error is generated if the designated argument is not a variable name.

The following parameters are expected:

ARG

A longword indicating the parameter to be written.

STRING

The address of a string descriptor containing the text to be written into the specified argument.

emacs__k_return_number_to_param

This request writes a number to the parameter specified in the original call of the external function. It can be used to pass multiple numeric values from an external function.

An error is generated if the designated argument is not a variable name.

The following parameters are expected:

ARG

A longword indicating the parameter to be written.

VALUE

The value to be written into the specified argument.

emacs__k_buffer_extent

This request returns complex information about the current buffer. Emacs keeps the contents of a buffer in two regions of memory with an area in between used to insert and delete characters. The first region, which contains the top part of the buffer, is called P1 ; the second region, which contains the bottom of the buffer, is called P2 . The region between the two areas is called the Gap This call-back returns the sizes and addresses of the base of P1 and P2.

The following parameters are expected:

S1

The address of a longword that Emacs fills with the size of the P1 region.

P1

The address of a longword that Emacs fills with the address of the P1 region.

S2

The address of a longword that Emacs fills with the size of the P2 region.

P2

The address of a longword that Emacs fills with the address of the P2 region.

emacs__k_gap_to

This request moves the Gap to the specified character. You can use this request to force the entire contents of the current buffer into either the P1 or P2 regions by selecting a suitable value for the Gap position.

The following parameter is expected:

POSITION

A longword containing the character position to which the Gap is set. A value of 0 puts Gap before all characters; -1 puts it after all characters.

emacs__k_gap_room

This request forces the Gap to be at least as big as the specified value.

The following parameter is expected:

SIZE

A longword containing the size to set the Gap.

emacs__k_change_buffer_extent

This request changes the size of the P1 and P2 regions for the current buffer.

The following parameters are expected:

S1

A longword containing the new size of P1.

S2

A longword containing the new size of P2.