wiki:HemlockProgrammer/Files

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

--

13. Files

This chapter discusses ways to read and write files at various levels---at marks, into regions, and into buffers. This also treats automatic mechanisms that affect the state of buffers in which files are read.

13.1. File Options and Type Hooks

The user specifies file options with a special syntax on the first line of a file. If the first line contains the string "-*-", then Hemlock interprets the text between the first such occurrence and the second, which must be contained in one line , as a list of "option: value" pairs separated by semicolons. The following is a typical example:

;;; -*- Mode: Lisp, Editor; Package: Hemlock -*-

See the Hemlock User's Manual for more details and predefined options.

File type hooks are executed when Hemlock reads a file into a buffer based on the type of the pathname. When the user specifies a Mode file option that turns on a major mode, Hemlock ignores type hooks. This mechanism is mostly used as a simple means for turning on some appropriate default major mode.

define-file-option name (buffer value) {declaration}* {form}* [Macro]

This defines a new file option with the string name name. Buffer and value specify variable names for the buffer and the option value string, and forms are evaluated with these bound.

define-file-type-hook type-list (buffer type) {declaration}* {form}* [Macro]

This defines some code that process-file-options(below) executes when the file options fail to set a major mode. This associates each type, asimple-string, intype-list with a routine that binds bufferto the buffer the file is in andtypeto the type of the pathname.

process-file-options buffer &optional pathname [Function]

This checks for file options in buffer and invokes handlers if there are any. Pathname defaults to buffer's pathname but may be nil. If there is no Mode file option that specifies a major mode, and pathname has a type, then this tries to invoke the appropriate file type hook. read-buffer-file calls this.

13.2. Pathnames and Buffers

There is no good way to uniquely identify buffer names and pathnames. However, Hemlock has one way of mapping pathnames to buffer names that should be used for consistency among customizations and primitives. Independent of this, Hemlock provides a means for consistently generating prompting defaults when asking the user for pathnames.

pathname-to-buffer-namepathname [Function]

This function returns a string of the form "file-namestring directory-namestring".

Pathname Defaults (initial value (pathname "gazonk.del")) [Hemlock Variable]

Last Resort Pathname Defaults Function [Hemlock Variable]

Last Resort Pathname Defaults(initial value (pathname "gazonk")) [Hemlock Variable]

These variables control the computation of default pathnames when needed for promting the user. Pathname Defaults is a sticky default. See the Hemlock User's Manual for more details.

buffer-default-pathname buffer [Function]

This returns Buffer Pathname if it is bound. If it is not bound, and buffer's name is composed solely of alphnumeric characters, then return a pathname formed from buffer's name. If buffer's name has other characters in it, then return the value of Last Resort Pathname Defaults Function called on buffer.

13.3. File Groups

File groups provide a simple way of collecting the files that compose a system and naming that collection. Hemlock supports commands for searching, replacing, and compiling groups.

*active-file-group* [Variable]

This is the list of files that constitute the currently selected file group. If this is nil, then there is no current group.

do-active-group {form}* [Macro]

Group Find File (initial value nil) [Hemlock Variable]

Group Save File Confirm (initial value t) [Hemlock Variable]

do-active-group iterates over *active-file-group* executing the forms once for each file. While the forms are executing, the file is in the current buffer, and the point is at the beginning. If there is no active group, this signals an editor-error.

This reads each file into its own buffer using find-file-buffer. Since unwanted buffers may consume large amounts of memory, Group Find File controls whether to delete the buffer after executing the forms. When the variable is false, this deletes the buffer if it did not previously exist; however, regardless of this variable, if the user leaves the buffer modified, the buffer persists after the forms have completed. Whenever this processes a buffer that already existed, it saves the location of the buffer's point before and restores it afterwards.

After processing a buffer, if it is modified, do-active-group tries to save it. If Group Save File Confirmis non-nil, it asks for confirmation.

13.4. File Reading and Writing

Common Lisp pathnames are used by the file primitives. For probing, checking write dates, and so forth, all of the Common Lisp file functions are available.

read-file pathname mark [Function]

This inserts the file named bypathnameatmark.

write-file region pathname &key :keep-backup :access :append [Function]

Keep Backup Files(initial valuenil) [Hemlock Variable]

This function writes the contents of region to the file named by pathname. This writes region using a stream as if it were opened with :if-exists supplied as :rename-and-delete.

When keep-backup, which defaults to the value of Keep Backup Files, is non-nil, this opens the stream as if :if-exists were :rename. If append is non-nil, this writes the file as if it were opened with:if-exists supplied as :append.

This signals an error if both append and keep-backup are supplied as non-nil.

Access is an implementation dependent value that is suitable for setting pathname's access or protection bits.

write-buffer-file buffer pathname [Function]

Write File Hook [Hemlock Variable]

Add Newline at EOF on Writing File(initial value:ask-user) [Hemlock Variable]

write-buffer-file writes buffer to the file named by pathname including the following:

  • It assumes pathname is somehow related to buffer's pathname: if the buffer's write date is not the same as pathname's, then this prompts the user for confirmation before overwriting the file.
  • It consults Add Newline at EOF on Writing File (see Hemlock User's Manual for possible values) and interacts with the user if necessary.
  • It sets Pathname Defaults, and after using write-file, marks buffer unmodified.
  • It updates Buffer's pathname and write date.
  • It renames the buffer according to the new pathname if possible.
  • It invokes Write File Hook.

Write File Hoo kis a list of functions that take the newly written buffer as an argument.

read-buffer-file pathname buffer [Function]

Read File Hook [Hemlock Variable]

read-buffer-file deletes buffer's region and uses read-file to read pathname into it, including the following:

  • It sets buffer's write date to the file's write date if the file exists; otherwise, it messages that this is a new file and sets buffer's write date to nil.
  • It movesbuffer's point to the beginning.
  • It setsbuffer's unmodified status.
  • It sets buffer's pathname to the result of probing pathname if the file exists; otherwise, this function sets buffer's pathname to the result of merging pathname with default-directory.
  • It sets Pathname Defaults to the result of the previous item.
  • It processes the file options.
  • It invokes Read File Hook.

Read File Hook is a list functions that take two arguments---the buffer read into and whether the file existed, t if so.

find-file-buffer pathname [Function]

This returns a buffer assoicated with the pathname, reading the file into a new buffer if necessary. This returns a second value indicating whether a new buffer was created, t if so. If the file has already been read, this checks to see if the file has been modified on disk since it was read, giving the user various recovery options. This is the basis of the Find File command.