| [6] | 1 | ;;; -*- Log: hemlock.log; Package: Hemlock-Internals -*-
|
|---|
| 2 | ;;;
|
|---|
| 3 | ;;; **********************************************************************
|
|---|
| 4 | ;;; This code was written as part of the CMU Common Lisp project at
|
|---|
| 5 | ;;; Carnegie Mellon University, and has been placed in the public domain.
|
|---|
| 6 | ;;;
|
|---|
| 7 | #+CMU (ext:file-comment
|
|---|
| 8 | "$Header$")
|
|---|
| 9 | ;;;
|
|---|
| 10 | ;;; **********************************************************************
|
|---|
| 11 | ;;;
|
|---|
| 12 | ;;; Hemlock initialization code and random debugging stuff.
|
|---|
| 13 | ;;;
|
|---|
| 14 | ;;; Written by Bill Chiles and Rob MacLachlan
|
|---|
| 15 | ;;;
|
|---|
| 16 |
|
|---|
| 17 | (in-package :hemlock-internals)
|
|---|
| 18 |
|
|---|
| 19 | ;;;; Definition of *hemlock-version*.
|
|---|
| 20 |
|
|---|
| 21 | (defvar *hemlock-version* "3.5")
|
|---|
| 22 | (pushnew :hemlock *features*)
|
|---|
| 23 | #+(or CMU scl)
|
|---|
| 24 | (setf (getf ext:*herald-items* :hemlock)
|
|---|
| 25 | `(" Hemlock " ,*hemlock-version*))
|
|---|
| 26 |
|
|---|
| 27 | |
|---|
| 28 |
|
|---|
| 29 | ;;;; %INIT-HEMLOCK.
|
|---|
| 30 |
|
|---|
| 31 | (defvar *hemlock-initialized* nil)
|
|---|
| 32 |
|
|---|
| 33 | (defun %init-hemlock ()
|
|---|
| [13161] | 34 | "Initialize hemlock's internal data structures."
|
|---|
| 35 | (let ((*current-buffer* nil)) ;; don't set it globally
|
|---|
| 36 | ;;
|
|---|
| 37 | ;; This function is defined in Buffer.Lisp. It creates fundamental mode
|
|---|
| 38 | ;; and the buffer main. Until this is done it is not possible to define
|
|---|
| 39 | ;; or use Hemlock variables.
|
|---|
| 40 | (setup-initial-buffer)
|
|---|
| 41 | ;;
|
|---|
| 42 | ;; Define some of the system variables.
|
|---|
| 43 | (define-some-variables)
|
|---|
| 44 | ;;
|
|---|
| 45 | ;; Site initializations such as window system variables.
|
|---|
| 46 | (site-init)
|
|---|
| 47 | ;;
|
|---|
| 48 | ;; Set up syntax table data structures.
|
|---|
| 49 | (%init-syntax-table)
|
|---|
| 50 | ;;
|
|---|
| [6] | 51 | (setq *hemlock-initialized* t)))
|
|---|
| 52 |
|
|---|
| 53 | |
|---|
| 54 |
|
|---|
| 55 | ;;;; Define some globals.
|
|---|
| 56 |
|
|---|
| 57 | ;;; These globals cannot be defined in the appropriate file due to compilation
|
|---|
| 58 | ;;; or load time constraints.
|
|---|
| 59 | ;;;
|
|---|
| 60 |
|
|---|
| 61 | ;;; The following belong in other files, but those files are loaded before
|
|---|
| 62 | ;;; table.lisp which defines MAKE-STRING-TABLE.
|
|---|
| 63 | ;;;
|
|---|
| 64 | ;;; vars.lisp
|
|---|
| 65 | (defvar *global-variable-names* (make-string-table)
|
|---|
| 66 | "A String Table of global variable names, the values are the symbol names.")
|
|---|
| 67 | ;;;
|
|---|
| 68 | ;;; buffer.lisp
|
|---|
| 69 | (defvar *mode-names* (make-string-table) "A String Table of Mode names.")
|
|---|
| 70 | (defvar *buffer-names* (make-string-table)
|
|---|
| 71 | "A String Table of Buffer names and their corresponding objects.")
|
|---|
| 72 | ;;;
|
|---|
| 73 | ;;; interp.lisp
|
|---|
| 74 | (defvar *command-names* (make-string-table) "String table of command names.")
|
|---|
| 75 | ;;;
|
|---|
| 76 | ;;; syntax.lisp
|
|---|
| 77 | (defvar *character-attribute-names* (make-string-table)
|
|---|
| 78 | "String Table of character attribute names and their corresponding keywords.")
|
|---|
| 79 |
|
|---|
| 80 |
|
|---|
| 81 | |
|---|
| 82 |
|
|---|
| 83 | ;;;; DEFINE-SOME-VARIABLES.
|
|---|
| 84 |
|
|---|
| [7607] | 85 | (defun define-some-variables ()
|
|---|
| [6] | 86 | (defhvar "Default Modes"
|
|---|
| 87 | "This variable contains the default list of modes for new buffers."
|
|---|
| 88 | :value '("Fundamental"))
|
|---|
| 89 | (defhvar "Make Buffer Hook"
|
|---|
| 90 | "This hook is called with the new buffer whenever a buffer is created.")
|
|---|
| 91 | (defhvar "Delete Buffer Hook"
|
|---|
| 92 | "This hook is called with the buffer whenever a buffer is deleted.")
|
|---|
| 93 | (defhvar "Buffer Major Mode Hook"
|
|---|
| 94 | "This hook is called with the buffer and the new mode when a buffer's
|
|---|
| 95 | major mode is changed.")
|
|---|
| 96 | (defhvar "Buffer Minor Mode Hook"
|
|---|
| 97 | "This hook is called a minor mode is changed. The arguments are
|
|---|
| 98 | the buffer, the mode affected and T or NIL depending on when the
|
|---|
| 99 | mode is being turned on or off.")
|
|---|
| 100 | (defhvar "Buffer Writable Hook"
|
|---|
| 101 | "This hook is called whenever someone sets whether the buffer is
|
|---|
| 102 | writable.")
|
|---|
| 103 | (defhvar "Buffer Name Hook"
|
|---|
| 104 | "This hook is called with the buffer and the new name when the name of a
|
|---|
| 105 | buffer is changed.")
|
|---|
| 106 | (defhvar "Buffer Pathname Hook"
|
|---|
| 107 | "This hook is called with the buffer and the new Pathname when the Pathname
|
|---|
| 108 | associated with the buffer is changed.")
|
|---|
| 109 | (defhvar "Buffer Modified Hook"
|
|---|
| [607] | 110 | "This hook is called whenever a buffer changes from unmodified to modified
|
|---|
| 111 | and vice versa. It takes the buffer and the new value for modification
|
|---|
| [6] | 112 | flag.")
|
|---|
| 113 | (defhvar "Buffer Package Hook"
|
|---|
| 114 | "This hook is called with the new package name whenever a (Lisp) buffer's package changes")
|
|---|
| 115 | (defhvar "Delete Variable Hook"
|
|---|
| 116 | "This hook is called when a variable is deleted with the args to
|
|---|
| 117 | delete-variable.")
|
|---|
| 118 | (defhvar "Key Echo Delay"
|
|---|
| 119 | "Wait this many seconds before echoing keys in the command loop. This
|
|---|
| 120 | feature is inhibited when nil."
|
|---|
| 121 | :value 1.0)
|
|---|
| 122 | (defhvar "Input Hook"
|
|---|
| 123 | "The functions in this variable are invoked each time a character enters
|
|---|
| 124 | Hemlock."
|
|---|
| 125 | :value nil)
|
|---|
| 126 | (defhvar "Abort Hook"
|
|---|
| 127 | "These functions are invoked when ^G is typed. No arguments are passed."
|
|---|
| 128 | :value nil)
|
|---|
| 129 | (defhvar "Command Abort Hook"
|
|---|
| 130 | "These functions get called when commands are aborted, such as with
|
|---|
| 131 | EDITOR-ERROR."
|
|---|
| 132 | :value nil)
|
|---|
| 133 | (defhvar "Character Attribute Hook"
|
|---|
| 134 | "This hook is called with the attribute, character and new value
|
|---|
| 135 | when the value of a character attribute is changed.")
|
|---|
| 136 | (defhvar "Shadow Attribute Hook"
|
|---|
| 137 | "This hook is called when a mode character attribute is made.")
|
|---|
| [8428] | 138 | (defhvar "Unshadow Attribute Hook"
|
|---|
| [6] | 139 | "This hook is called when a mode character attribute is deleted.")
|
|---|
| 140 | (defhvar "Default Modeline Fields"
|
|---|
| 141 | "The default list of modeline-fields for MAKE-BUFFER."
|
|---|
| 142 | :value *default-modeline-fields*)
|
|---|
| 143 | (defhvar "Maximum Modeline Pathname Length"
|
|---|
| 144 | "When set, this variable is the maximum length of the display of a pathname
|
|---|
| 145 | in a modeline. When the pathname is too long, the :buffer-pathname
|
|---|
| [8428] | 146 | modeline-field function chops off leading directory specifications until
|
|---|
| 147 | the pathname fits. \"...\" indicates a truncated pathname."
|
|---|
| 148 | :value nil
|
|---|
| 149 | :hooks (list 'maximum-modeline-pathname-length-hook))
|
|---|
| 150 | (defhvar "Self Insert Command Name"
|
|---|
| 151 | "The name of the command to invoke to handle quoted input (i.e. after c-q).
|
|---|
| 152 | By default, this is \"Self Insert\"."
|
|---|
| 153 | :value "Self Insert")
|
|---|
| 154 | (defhvar "Default Command Name"
|
|---|
| 155 | "The name of the command to invoke to handle keys that have no binding
|
|---|
| [6] | 156 | defined. By default, this is \"Illegal\"."
|
|---|
| 157 | :value "Illegal")
|
|---|
| 158 | )
|
|---|
| 159 |
|
|---|
| 160 |
|
|---|
| 161 | |
|---|
| 162 |
|
|---|
| 163 | ;;;; ED.
|
|---|
| 164 |
|
|---|
| 165 | (defvar *editor-has-been-entered* ()
|
|---|
| 166 | "True if and only if the editor has been entered.")
|
|---|
| 167 | (defvar *in-the-editor* ()
|
|---|
| 168 | "True if we are inside the editor. This is used to prevent ill-advised
|
|---|
| 169 | \"recursive\" edits.")
|
|---|
| 170 |
|
|---|
| 171 | (defvar *after-editor-initializations-funs* nil
|
|---|
| 172 | "A list of functions to be called after the editor has been initialized upon
|
|---|
| 173 | entering the first time.")
|
|---|
| 174 |
|
|---|
| 175 | (defmacro after-editor-initializations (&rest forms)
|
|---|
| 176 | "Causes forms to be executed after the editor has been initialized.
|
|---|
| 177 | Forms supplied with successive uses of this macro will be executed after
|
|---|
| 178 | forms supplied with previous uses."
|
|---|
| 179 | `(push #'(lambda () ,@forms)
|
|---|
| 180 | *after-editor-initializations-funs*))
|
|---|
| 181 |
|
|---|
| 182 | ;;;; SAVE-ALL-BUFFERS.
|
|---|
| 183 |
|
|---|
| 184 | ;;; SAVE-ALL-BUFFERS -- Public.
|
|---|
| 185 | ;;;
|
|---|
| 186 | (defun save-all-buffers (&optional (list-unmodified-buffers nil))
|
|---|
| 187 | "This prompts users with each modified buffer as to whether they want to
|
|---|
| 188 | write it out. If the buffer has no associated file, this will also prompt
|
|---|
| 189 | for a file name. Supplying the optional argument non-nil causes this
|
|---|
| 190 | to prompt for every buffer."
|
|---|
| 191 | (dolist (buffer *buffer-list*)
|
|---|
| 192 | (when (or list-unmodified-buffers (buffer-modified buffer))
|
|---|
| 193 | (maybe-save-buffer buffer))))
|
|---|
| 194 |
|
|---|
| 195 | (defun maybe-save-buffer (buffer)
|
|---|
| 196 | (let* ((modified (buffer-modified buffer))
|
|---|
| 197 | (pathname (buffer-pathname buffer))
|
|---|
| 198 | (name (buffer-name buffer))
|
|---|
| 199 | (string (if pathname (namestring pathname))))
|
|---|
| 200 | (format t "Buffer ~S is ~:[UNmodified~;modified~], Save it? "
|
|---|
| 201 | name modified)
|
|---|
| 202 | (force-output)
|
|---|
| 203 | (when (y-or-n-p)
|
|---|
| 204 | (let ((name (read-line-default "File to write" string)))
|
|---|
| 205 | (format t "Writing file ~A..." name)
|
|---|
| 206 | (force-output)
|
|---|
| 207 | (write-file (buffer-region buffer) name)
|
|---|
| 208 | (write-line "write WON")))))
|
|---|
| 209 |
|
|---|
| 210 | (defun read-line-default (prompt default)
|
|---|
| 211 | (format t "~A:~@[ [~A]~] " prompt default)
|
|---|
| 212 | (force-output)
|
|---|
| 213 | (do ((result (read-line) (read-line)))
|
|---|
| 214 | (())
|
|---|
| 215 | (declare (simple-string result))
|
|---|
| 216 | (when (plusp (length result)) (return result))
|
|---|
| 217 | (when default (return default))
|
|---|
| 218 | (format t "~A:~@[ [~A]~] " prompt default)
|
|---|
| 219 | (force-output)))
|
|---|
| 220 |
|
|---|
| 221 | (unless *hemlock-initialized*
|
|---|
| 222 | (%init-hemlock))
|
|---|