diff options
| author | Eric S. Raymond | 1992-05-31 19:41:40 +0000 |
|---|---|---|
| committer | Eric S. Raymond | 1992-05-31 19:41:40 +0000 |
| commit | 21d7e0804f008778f8882e4a1c08a0e15ffef607 (patch) | |
| tree | 2ca9e16ac5c03624ade7856043e61fbebd1f6102 | |
| parent | 0560661c7642c3e97557f20bc2479a04a8845e89 (diff) | |
| download | emacs-21d7e0804f008778f8882e4a1c08a0e15ffef607.tar.gz emacs-21d7e0804f008778f8882e4a1c08a0e15ffef607.zip | |
*** empty log message ***
| -rw-r--r-- | lisp/add-log.el | 158 |
1 files changed, 145 insertions, 13 deletions
diff --git a/lisp/add-log.el b/lisp/add-log.el index f2c279ae357..8d935ae23a7 100644 --- a/lisp/add-log.el +++ b/lisp/add-log.el | |||
| @@ -42,7 +42,10 @@ Second arg is file name of change log. If nil, uses `change-log-default-name'. | |||
| 42 | Third arg OTHER-WINDOW non-nil means visit in other window." | 42 | Third arg OTHER-WINDOW non-nil means visit in other window." |
| 43 | (interactive (list current-prefix-arg | 43 | (interactive (list current-prefix-arg |
| 44 | (prompt-for-change-log-name))) | 44 | (prompt-for-change-log-name))) |
| 45 | (let* ((full-name (if whoami | 45 | (let* ((default (if (eq system-type 'vax-vms) |
| 46 | "$CHANGE_LOG$.TXT" | ||
| 47 | "ChangeLog")) | ||
| 48 | (full-name (if whoami | ||
| 46 | (read-input "Full name: " (user-full-name)) | 49 | (read-input "Full name: " (user-full-name)) |
| 47 | (user-full-name))) | 50 | (user-full-name))) |
| 48 | ;; Note that some sites have room and phone number fields in | 51 | ;; Note that some sites have room and phone number fields in |
| @@ -54,7 +57,16 @@ Third arg OTHER-WINDOW non-nil means visit in other window." | |||
| 54 | (user-login-name))) | 57 | (user-login-name))) |
| 55 | (site-name (if whoami | 58 | (site-name (if whoami |
| 56 | (read-input "Site name: " (system-name)) | 59 | (read-input "Site name: " (system-name)) |
| 57 | (system-name)))) | 60 | (system-name))) |
| 61 | (defun (add-log-current-defun)) | ||
| 62 | (entry (and buffer-file-name | ||
| 63 | (file-name-nondirectory buffer-file-name))) | ||
| 64 | entry-position entry-boundary empty-entry) | ||
| 65 | ;; Never want to add a change log entry for the ChangeLog buffer itself: | ||
| 66 | (if (equal default entry) | ||
| 67 | (setq entry nil | ||
| 68 | formatted-revision nil | ||
| 69 | defun nil)) | ||
| 58 | (or file-name | 70 | (or file-name |
| 59 | (setq file-name (or change-log-default-name | 71 | (setq file-name (or change-log-default-name |
| 60 | default-directory))) | 72 | default-directory))) |
| @@ -74,17 +86,59 @@ Third arg OTHER-WINDOW non-nil means visit in other window." | |||
| 74 | " (" login-name | 86 | " (" login-name |
| 75 | "@" site-name ")\n\n"))) | 87 | "@" site-name ")\n\n"))) |
| 76 | (goto-char (point-min)) | 88 | (goto-char (point-min)) |
| 77 | (forward-line 1) | 89 | (setq empty-entry |
| 78 | (while (looking-at "\\sW") | 90 | (and (search-forward "\n\t* \n" nil t) |
| 79 | (forward-line 1)) | 91 | (1- (point)))) |
| 80 | (delete-region (point) | 92 | (if (and entry |
| 81 | (progn | 93 | (not empty-entry)) |
| 82 | (skip-chars-backward "\n") | 94 | ;; Look for today's entry for same file |
| 83 | (point))) | 95 | ;; If there is an empty entry (just a `*'), take the hint and |
| 84 | (open-line 3) | 96 | ;; use it. This is so that C-x a from the ChangeLog buffer |
| 85 | (forward-line 2) | 97 | ;; itself can be used to force the next entry to be added at |
| 86 | (indent-to left-margin) | 98 | ;; the beginning, even if there are today's entries for the |
| 87 | (insert "* "))) | 99 | ;; same file (but perhaps different revisions). |
| 100 | (setq entry-boundary (save-excursion | ||
| 101 | (and (re-search-forward "\n[A-Z]" nil t) | ||
| 102 | (point))) | ||
| 103 | entry-position (save-excursion | ||
| 104 | (and (re-search-forward | ||
| 105 | (concat | ||
| 106 | (regexp-quote (concat "* " entry)) | ||
| 107 | ;; don't accept `foo.bar' when | ||
| 108 | ;; looking for `foo': | ||
| 109 | "[ \n\t,]") | ||
| 110 | entry-boundary | ||
| 111 | t) | ||
| 112 | (1- (match-end 0)))))) | ||
| 113 | (cond (entry-position | ||
| 114 | ;; Move to existing entry for same file. | ||
| 115 | (goto-char entry-position) | ||
| 116 | (search-forward "\n\n") | ||
| 117 | (forward-line -1)) | ||
| 118 | (empty-entry | ||
| 119 | ;; Put this file name into existing empty entry. | ||
| 120 | (goto-char empty-entry) | ||
| 121 | (insert (or entry ""))) | ||
| 122 | (t | ||
| 123 | ;; Make a new entry | ||
| 124 | (forward-line 1) | ||
| 125 | (while (looking-at "\\sW") | ||
| 126 | (forward-line 1)) | ||
| 127 | (delete-region (point) | ||
| 128 | (progn | ||
| 129 | (skip-chars-backward "\n") | ||
| 130 | (point))) | ||
| 131 | (open-line 3) | ||
| 132 | (forward-line 2) | ||
| 133 | (indent-to left-margin) | ||
| 134 | (insert "* " (or entry "")))) | ||
| 135 | ;; Point is at the entry for this file, | ||
| 136 | ;; either at the end of the line or at the first blank line. | ||
| 137 | (if defun | ||
| 138 | (progn | ||
| 139 | ;; Make it easy to get rid of the defun name. | ||
| 140 | (undo-boundary) | ||
| 141 | (insert "(" defun "): "))))) | ||
| 88 | 142 | ||
| 89 | ;;;###autoload | 143 | ;;;###autoload |
| 90 | (define-key ctl-x-4-map "a" 'add-change-log-entry-other-window) | 144 | (define-key ctl-x-4-map "a" 'add-change-log-entry-other-window) |
| @@ -100,4 +154,82 @@ Interactively, with a prefix argument, the file name is prompted for." | |||
| 100 | (prompt-for-change-log-name)))) | 154 | (prompt-for-change-log-name)))) |
| 101 | (add-change-log-entry whoami file-name t)) | 155 | (add-change-log-entry whoami file-name t)) |
| 102 | 156 | ||
| 157 | (defun change-log-mode () | ||
| 158 | (interactive) | ||
| 159 | (kill-all-local-variables) | ||
| 160 | (indented-text-mode) | ||
| 161 | (setq major-mode 'change-log-mode) | ||
| 162 | (setq mode-name "Change Log") | ||
| 163 | ;; Let each entry behave as one paragraph: | ||
| 164 | (set (make-local-variable 'paragraph-start) "^$\\|^^L") | ||
| 165 | (set (make-local-variable 'paragraph-separate) "^$\\|^^L") | ||
| 166 | ;; Let all entries for one day behave as one page. | ||
| 167 | ;; Note that a page boundary is also a paragraph boundary. | ||
| 168 | ;; Unfortunately the date line of a page actually belongs to | ||
| 169 | ;; the next day, but I don't see how to avoid that since | ||
| 170 | ;; page moving cmds go to the end of the match, and Emacs | ||
| 171 | ;; regexps don't have a context feature. | ||
| 172 | (set (make-local-variable 'page-delimiter) "^[A-Z][a-z][a-z] .*\n\\|^") | ||
| 173 | (run-hooks 'change-log-mode-hook)) | ||
| 174 | |||
| 175 | (defvar add-log-current-defun-header-regexp | ||
| 176 | "^\\([A-Z][A-Z_ ]+\\|[a-z_---A-Z]+\\)[ \t]*[:=]" | ||
| 177 | "*Heuristic regexp used by `add-log-current-defun' for unknown major modes.") | ||
| 178 | |||
| 179 | (defun add-log-current-defun () | ||
| 180 | "Return name of function definition point is in, or nil. | ||
| 181 | |||
| 182 | Understands Lisp, LaTeX (\"functions\" are chapters, sections, ...), | ||
| 183 | Texinfo (@node titles), and C. | ||
| 184 | |||
| 185 | Other modes are handled by a heuristic that looks in the 10K before | ||
| 186 | point for uppercase headings starting in the first column or | ||
| 187 | identifiers followed by `:' or `=', see variable | ||
| 188 | `add-log-current-defun-header-regexp'. | ||
| 189 | |||
| 190 | Has a preference of looking backwards." | ||
| 191 | (save-excursion | ||
| 192 | (cond ((memq major-mode '(emacs-lisp-mode lisp-mode)) | ||
| 193 | (beginning-of-defun) | ||
| 194 | (forward-word 1) | ||
| 195 | (skip-chars-forward " ") | ||
| 196 | (buffer-substring (point) | ||
| 197 | (progn (forward-sexp 1) (point)))) | ||
| 198 | ((eq major-mode 'c-mode) | ||
| 199 | ;; must be inside function body for this to work | ||
| 200 | (beginning-of-defun) | ||
| 201 | (forward-line -1) | ||
| 202 | (while (looking-at "[ \t\n]") ; skip typedefs of arglist | ||
| 203 | (forward-line -1)) | ||
| 204 | (down-list 1) ; into arglist | ||
| 205 | (backward-up-list 1) | ||
| 206 | (skip-chars-backward " \t") | ||
| 207 | (buffer-substring (point) | ||
| 208 | (progn (backward-sexp 1) | ||
| 209 | (point)))) | ||
| 210 | ((memq major-mode | ||
| 211 | '(TeX-mode plain-TeX-mode LaTeX-mode;; tex-mode.el | ||
| 212 | plain-tex-mode latex-mode;; cmutex.el | ||
| 213 | )) | ||
| 214 | (if (re-search-backward | ||
| 215 | "\\\\\\(sub\\)*\\(section\\|paragraph\\|chapter\\)" nil t) | ||
| 216 | (progn | ||
| 217 | (goto-char (match-beginning 0)) | ||
| 218 | (buffer-substring (1+ (point));; without initial backslash | ||
| 219 | (progn | ||
| 220 | (end-of-line) | ||
| 221 | (point)))))) | ||
| 222 | ((eq major-mode 'texinfo-mode) | ||
| 223 | (if (re-search-backward "^@node[ \t]+\\([^,]+\\)," nil t) | ||
| 224 | (buffer-substring (match-beginning 1) | ||
| 225 | (match-end 1)))) | ||
| 226 | (t | ||
| 227 | ;; If all else fails, try heuristics | ||
| 228 | (let (case-fold-search) | ||
| 229 | (if (re-search-backward add-log-current-defun-header-regexp | ||
| 230 | (- (point) 10000) | ||
| 231 | t) | ||
| 232 | (buffer-substring (match-beginning 1) | ||
| 233 | (match-end 1)))))))) | ||
| 234 | |||
| 103 | ;;; add-log.el ends here | 235 | ;;; add-log.el ends here |