Mercurial > emacs
comparison lisp/add-log.el @ 666:7fa6b835da67
*** empty log message ***
author | Eric S. Raymond <esr@snark.thyrsus.com> |
---|---|
date | Sun, 31 May 1992 19:41:40 +0000 |
parents | 36fbc3f71803 |
children | 8cff3b3bd089 |
comparison
equal
deleted
inserted
replaced
665:f9274ecd9acd | 666:7fa6b835da67 |
---|---|
40 Optional arg (interactive prefix) non-nil means prompt for user name and site. | 40 Optional arg (interactive prefix) non-nil means prompt for user name and site. |
41 Second arg is file name of change log. If nil, uses `change-log-default-name'. | 41 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 |
49 ;; full name which look silly when inserted. Rather than do | 52 ;; full name which look silly when inserted. Rather than do |
50 ;; anything about that here, let user give prefix argument so that | 53 ;; anything about that here, let user give prefix argument so that |
52 (login-name (if whoami | 55 (login-name (if whoami |
53 (read-input "Login name: " (user-login-name)) | 56 (read-input "Login name: " (user-login-name)) |
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))) |
61 (if (file-directory-p file-name) | 73 (if (file-directory-p file-name) |
62 (setq file-name (concat (file-name-as-directory file-name) | 74 (setq file-name (concat (file-name-as-directory file-name) |
72 (progn (insert (current-time-string) | 84 (progn (insert (current-time-string) |
73 " " full-name | 85 " " full-name |
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) |
91 | 145 |
92 ;;;###autoload | 146 ;;;###autoload |
98 (interactive (if current-prefix-arg | 152 (interactive (if current-prefix-arg |
99 (list current-prefix-arg | 153 (list current-prefix-arg |
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 |