From: Chong Yidong Date: Sun, 31 Oct 2010 14:40:01 +0000 (-0400) Subject: Merge changes from emacs-23 branch X-Git-Tag: emacs-pretest-24.0.90~104^2~275^2~438^2~45^2~422^2~42 X-Git-Url: http://git.eshelyaron.com/gitweb/?a=commitdiff_plain;h=2699a55464f7b43171c7b0e64d095640904e9e21;p=emacs.git Merge changes from emacs-23 branch --- 2699a55464f7b43171c7b0e64d095640904e9e21 diff --cc doc/lispref/ChangeLog index afd20c3890a,5974893288a..5607d179aad --- a/doc/lispref/ChangeLog +++ b/doc/lispref/ChangeLog @@@ -1,8 -1,8 +1,12 @@@ -2010-10-27 Glenn Morris ++2010-10-31 Glenn Morris + + * maps.texi (Standard Keymaps): Update File menu description. + -2010-10-22 Eli Zaretskii +2010-10-28 Glenn Morris + + * Makefile.in (elisp.dvi, elisp.pdf): Also include $emacsdir. + +2010-10-24 Eli Zaretskii * display.texi (Window Systems): Deprecate use of window-system as a predicate. diff --cc doc/misc/ChangeLog index f1401cca9b7,a37b8db475f..d5c5df92087 --- a/doc/misc/ChangeLog +++ b/doc/misc/ChangeLog @@@ -1,37 -1,12 +1,45 @@@ -2010-10-30 Glenn Morris ++2010-10-31 Glenn Morris + + * mh-e.texi (Preface, From Bill Wohler): Change 23 to past tense. + -2010-10-29 Glenn Morris ++2010-10-31 Glenn Morris + + * cc-mode.texi: Remove reference to defunct viewcvs URL. + -2010-10-22 Juanma Barranquero +2010-10-29 Lars Magne Ingebrigtsen + + * gnus.texi (Client-Side IMAP Splitting): Mention + nnimap-unsplittable-articles. + +2010-10-29 Julien Danjou + + * gnus.texi (Finding the News): Remove references to obsoletes + variables `gnus-nntp-server' and `gnus-secondary-servers'. + +2010-10-29 Eli Zaretskii + + * makefile.w32-in (MAKEINFO): Add -I$(emacsdir). + (ENVADD): Remove extra -I$(emacsdir), included in $(MAKEINFO). + ($(infodir)/efaq): Remove -I$(emacsdir), included in $(MAKEINFO). + ($(infodir)/calc, calc.dvi): Depend on $(emacsdir)/emacsver.texi. + +2010-10-28 Glenn Morris + + * Makefile.in (MAKEINFO, ENVADD): Add $emacsdir to include path. + (($(infodir)/calc, calc.dvi, calc.pdf): Depend on emacsver.texi. + ($(infodir)/efaq): Remove -I option now in $MAKEINFO. + +2010-10-25 Daiki Ueno + + * epa.texi (Mail-mode integration): Add alternative key bindings + for epa-mail commands; escape comma. + Don't use the word "PGP", since it is a non-free program. + +2010-10-24 Jay Belanger + + * calc.texi: Use emacsver.texi to determine Emacs version. + +2010-10-24 Juanma Barranquero * gnus.texi (Group Parameters, Buttons): Fix typos. diff --cc lisp/ChangeLog index 4a49b8d4880,3944fdebc69..61a23268f41 --- a/lisp/ChangeLog +++ b/lisp/ChangeLog @@@ -1,246 -1,32 +1,279 @@@ -2010-10-30 Michael Albinus ++2010-10-31 Michael Albinus + + * net/tramp.el (tramp-handle-insert-file-contents): For root, + preserve owner and group when editing files. (Bug#7289) + -2010-10-29 Glenn Morris ++2010-10-31 Stefan Monnier + + * speedbar.el (speedbar-mode): + * play/fortune.el (fortune-in-buffer, fortune): + * play/gomoku.el (gomoku-mode): + * play/landmark.el (lm-mode): + * textmodes/bibtex.el (bibtex-validate, bibtex-validate-globally): + Replace inappropriate uses of toggle-read-only. (Bug#7292) + -2010-10-28 Glenn Morris ++2010-10-31 Glenn Morris + + * select.el (x-selection): Mark it as an obsolete alias. + -2010-10-27 Aaron S. Hawley ++2010-10-31 Aaron S. Hawley + + * add-log.el (find-change-log): Use derived-mode-p rather than + major-mode (bug#7284). + -2010-10-27 Glenn Morris ++2010-10-31 Glenn Morris + + * menu-bar.el (menu-bar-files-menu): Make it into an actual alias, + rather than just an unused variable that inherits from the real one. + -2010-10-23 Michael McNamara ++2010-10-31 Glenn Morris ++ ++ * comint.el (comint-password-prompt-regexp): ++ Match "enter the password". (Bug#7224) ++ +2010-10-31 Alan Mackenzie + + * progmodes/cc-cmds.el (c-mask-paragraph): Fix an off-by-1 error. + This fixes bug #7185. + +2010-10-30 Chong Yidong + + * startup.el (command-line): Search for package directories, and + don't load package.el if none are found. + + * emacs-lisp/package.el (describe-package, list-packages): Call + package-initialize if it has not been called yet. + +2010-10-30 Alan Mackenzie + + * progmodes/cc-fonts.el (c-font-lock-enum-tail): New function + which fontifies the tail of an enum. + (c-basic-matchers-after): Insert a call to the above new function. + This fixes bug #7264. + +2010-10-30 Glenn Morris + + * cus-start.el: Add :set properties for minor modes menu-bar-mode, + tool-bar-mode, transient-mark-mode. (Bug#7306) + Include the :set property in the dumped Emacs. + +2010-10-29 Stefan Monnier + + SMIE: change indent rules format, improve smie-setup. + * emacs-lisp/smie.el (smie-precs-precedence-table) + (smie-merge-prec2s, smie-bnf-precedence-table, smie-prec2-levels): + Mark them pure so the tables gets built at compile time. + (smie-bnf-precedence-table): Store the closer-alist in the table. + (smie-prec2-levels): Preserve the closer-alist. + (smie-blink-matching-open): Be more forgiving in case of indentation. + (smie-hanging-p): Rename from smie-indent--hanging-p. + (smie-bolp): Rename from smie-indent--bolp. + (smie--parent, smie--after): New dynamic vars. + (smie-parent-p, smie-next-p, smie-prev-p): New funs. + (smie-indent-rules): Remove. + (smie-indent--offset-rule): Remove fun. + (smie-rules-function): New var. + (smie-indent--rule): New fun. + (smie-indent--offset, smie-indent-keyword, smie-indent-after-keyword) + (smie-indent-exps): Use it. + (smie-setup): Setup paren blinking; add keyword args for token + functions; extract closer-alist from op-levels. + (smie-indent-debug-log): Remove var. + (smie-indent-debug): Remove fun. + * progmodes/prolog.el (prolog-smie-indent-rules): Remove. + (prolog-smie-rules): New fun to replace it. + (prolog-mode-variables): Simplify. + * progmodes/octave-mod.el (octave-smie-closer-alist): Remove, now that + it's setup automatically. + (octave-smie-indent-rules): Remove. + (octave-smie-rules): New fun to replace it. + (octave-mode): Simplify. + +2010-10-29 Glenn Morris + + * files.el (temporary-file-directory): Remove (already defined in C). + * cus-start.el: Add temporary-file-directory. + + * abbrev.el (abbrev-mode): + * composite.el (auto-composition-mode): + * menu-bar.el (menu-bar-mode): + * simple.el (transient-mark-mode): + * tool-bar.el (tool-bar-mode): Adjust the define-minor-mode calls so + that they do not define the associated variables twice. + * simple.el (transient-mark-mode): Remove defvar. + * composite.el (auto-composition-mode): Make variable auto-buffer-local. + * cus-start.el: Add transient-mark-mode, menu-bar-mode, tool-bar-mode. + Handle multiple groups, and also custom-delayed-init-variables. + * emacs-lisp/easy-mmode.el (define-minor-mode): Doc fix. + +2010-10-29 Stefan Monnier + + * emacs-lisp/pcase.el (pcase): New `string' and `guard' patterns. + (pcase-if): Add one minor optimization. + (pcase-split-equal): Rename from pcase-split-eq. + (pcase-split-member): Rename from pcase-split-memq. + (pcase-u1): Add strings to the member optimization. + Add `guard' variant of predicates. + (pcase-q1): Add string patterns. + +2010-10-28 Stefan Monnier + + * vc/log-edit.el (log-edit-rewrite-fixes): State its safety pred. + +2010-10-28 Glenn Morris + + * term/ns-win.el (global-map, menu-bar-final-items, menu-bar-help-menu): + Move menu-bar related settings to ../menu-bar.el. + * menu-bar.el (global-map, menu-bar-final-items, menu-bar-help-menu): + Move ns-specific settings here from term/ns-win.el. + + * simple.el (x-selection-owner-p): Remove unused declaration. + +2010-10-28 Stefan Monnier + + * minibuffer.el (completion-cycling): New var (bug#7266). + (minibuffer-complete, completion--do-completion): + Use completion--flush-all-sorted-completions. + (minibuffer-complete): Only cycle if completion-cycling is set. + (completion--flush-all-sorted-completions): Unset completion-cycling. + (minibuffer-force-complete): Set completion-cycling. + (completion-all-sorted-completions): Move declaration before first use. + +2010-10-28 Leo + + * iswitchb.el (iswitchb-kill-buffer): Avoid `iswitchb-make-buflist' + which changes the order of matches seen by users (bug#7231). + +2010-10-28 Jes Bodi Klinke (tiny change) + + * progmodes/compile.el (compilation-mode-font-lock-keywords): + Don't confuse -omega as "-o mega". + +2010-10-27 Stefan Monnier + + * vc/log-edit.el (log-edit-rewrite-fixes): New var. + (log-edit-author): New dynamic var. + (log-edit-changelog-ours-p, log-edit-insert-changelog-entries): Use it + to return the author if different from committer. + (log-edit-insert-changelog): Use them to add Author: and Fixes headers. + + * play/landmark.el: Adjust commenting convention. + (lm-nil-score): Rename from nil-score. + (Xscore, XXscore, XXXscore, XXXXscore, Oscore, OOscore, OOOscore) + (OOOOscore): Move into a let in lm-score-trans-table. + (lm-winning-threshold, lm-loosing-threshold): Use lm-score-trans-table. + + * electric.el (electric-indent-chars): Autoload. + * progmodes/octave-mod.el (octave-mode): + * progmodes/ruby-mode.el (ruby-mode): Take advantage of it. + (ruby-mode-abbrev-table): Merge initialization and declaration. + +2010-10-27 Glenn Morris + + * abbrev.el (abbrev-mode): Remove one of the three definitions of this + variable. + + * server.el (server-host, server-port, server-auth-dir): Autoload risky. + + * term/ns-win.el: Restore require of cl when compiling. + (menu-bar-final-items): Remove non-existent `windows' menu. + (ns-handle-nxopen): Optionally handle the temp-case. + (ns-handle-nxopentemp): Just call ns-handle-nxopen. + (ns-insert-file, ns-find-file): Use `pop'. + +2010-10-26 Glenn Morris + + * term/common-win.el (xw-defined-colors): Simplify the 'ns case. + +2010-10-26 Adrian Robert + + * term/ns-win.el (ns-new-frame, ns-show-prefs): Don't add to + global map. + * term/common-win.el (x-setup-function-keys): Remove most of the + keymappings. Comment on the remaining ones. + +2010-10-26 Peter Oliver (tiny change) + + * server.el (server-port): New option. (Bug#854) + (server-start): Use server-port. + +2010-10-26 Glenn Morris + + * term/ns-win.el (ns-version-string): Remove unused declaration. + (ns-invocation-args): Change to x-invocation-args. + (ns-handle-switch, ns-handle-numeric-switch, ns-handle-iconic) + (ns-handle-name-switch, ns-ignore-2-arg): Remove. + (ns-handle-nxopen, ns-handle-nxopentemp, ns-ignore-1-arg): + Use x-invocation-args instead of ns-invocation-args. + (ns-initialize-window-system, handle-args-function-alist): + Use x-handle-args instead of ns-handle-args. + * term/common-win.el (x-handle-args): Also handle nextstep arguments. + * startup.el (command-line-ns-option-alist): Replace + ns-handle-name-switch, ns-handle-switch, ns-handle-numeric-switch, + ns-handle-iconic with the x- equivalents. + + * term/common-win.el (x-select-enable-clipboard): + * term/pc-win.el (x-select-enable-clipboard): Doc fix. + + * term/ns-win.el: No need to require cl when compiling. + (x-display-name, x-setup-function-keys, x-select-text, x-colors) + (xw-defined-colors): Use the common-win definitions. + (ns-alternatives-map): Make it an obsolete alias for x-alternatives-map. + (ns-handle-iconic): Make it an alias for x-handle-iconic. + * term/common-win.el (x-select-text, x-alternatives-map) + (x-setup-function-keys, x-colors, xw-defined-colors): Handle 'ns case. + * loadup.el [ns]: Load common-win. + +2010-10-26 Daiki Ueno + + * epa-mail.el (epa-mail-encrypt): Handle local-part only + recipients; expand mail aliases (Bug#7280). + +2010-10-25 Glenn Morris + + * term/common-win.el (x-handle-switch): Simplify with pop. + Optionally handle numeric switches. + (x-handle-numeric-switch): Just call x-handle-switch. + (x-handle-initial-switch, x-handle-xrm-switch, x-handle-geometry) + (x-handle-name-switch, x-handle-display, x-handle-args): + Simplify with pop. + + * term/ns-win.el: Do not require easymenu. + (menu-bar-edit-menu) : + : Move adjustments to menu-bar.el. + * menu-bar.el (menu-bar-edit-menu) : + : Move ns-win's adjustments here. + * loadup.el [ns]: Do not load easymenu. + +2010-10-24 Chong Yidong + + * image.el (image-checkbox-checked, image-checkbox-unchecked): + Delete (Bug#7222). + + * startup.el (fancy-startup-tail): Instead of using inline images, + refer to image files from etc/. + + * wid-edit.el (checkbox): Likewise. + (widget-image-find): Center image specs. + +2010-10-24 Glenn Morris + + * term/ns-win.el (x-select-text): Doc fix. + * w32-fns.el (x-alternatives-map, x-setup-function-keys) + (x-select-text): Move to term/common-win. + * term/w32-win.el (xw-defined-colors): Move to common-win. + * term/x-win.el (xw-defined-colors, x-alternatives-map) + (x-setup-function-keys, x-select-text): Move to common-win. + * term/common-win.el (x-select-text, x-alternatives-map) + (x-setup-function-keys, xw-defined-colors): Merge x- and w32- + definitions here. + +2010-10-24 T.V. Raman (tiny change) + + * net/mairix.el (mairix-searches-mode-map): + * mail/mspools.el (mspools-mode-map): Fix 2010-10-10 change. + +2010-10-24 Michael McNamara * verilog-mode.el (verilog-directive-re): Make this variable auto-built for efficiency of execution and updating. diff --cc lisp/cedet/ChangeLog index bc024355b96,a483d3b70c8..3ab14039828 --- a/lisp/cedet/ChangeLog +++ b/lisp/cedet/ChangeLog @@@ -1,3 -1,17 +1,17 @@@ -2010-10-29 Glenn Morris ++2010-10-31 Glenn Morris + + * mode-local.el (mode-local-augment-function-help): + * semantic/analyze/debug.el (semantic-analyzer-debug-add-buttons): + * semantic/symref/list.el (semantic-symref-results-dump) + (semantic-symref-rb-toggle-expand-tag): Replace inappropriate uses + of toggle-read-only. + -2010-10-12 Juanma Barranquero ++2010-10-31 Juanma Barranquero + + * semantic/symref/list.el (semantic-symref-list-rename-open-hits): + Fix typo in message. + (semantic-symref-list-map-open-hits): Fix typo in docstring. + 2010-09-30 Chong Yidong * semantic/bovine/el.el: diff --cc lisp/menu-bar.el index ac33940011a,d25de5b385c..a3a28c3dcfc --- a/lisp/menu-bar.el +++ b/lisp/menu-bar.el @@@ -71,20 -51,12 +71,20 @@@ (define-key global-map [menu-bar options] (cons (purecopy "Options") menu-bar-options-menu)) (defvar menu-bar-edit-menu (make-sparse-keymap "Edit")) -(define-key global-map [menu-bar edit] (cons (purecopy "Edit") menu-bar-edit-menu)) +(define-key global-map [menu-bar edit] + (cons (purecopy "Edit") menu-bar-edit-menu)) (defvar menu-bar-file-menu (make-sparse-keymap "File")) -(define-key global-map [menu-bar file] (cons (purecopy "File") menu-bar-file-menu)) +(define-key global-map [menu-bar file] + (cons (purecopy "File") menu-bar-file-menu)) + +;; Put "Help" menu at the front, called "Info". +(and (featurep 'ns) + (not (eq system-type 'darwin)) + (define-key global-map [menu-bar help-menu] + (cons (purecopy "Info") menu-bar-help-menu))) - ;; This alias is for compatibility with 19.28 and before. - (defvar menu-bar-files-menu menu-bar-file-menu) + ;; Only declared obsolete (and only made a proper alias) in 23.3. + (define-obsolete-variable-alias 'menu-bar-files-menu 'menu-bar-file-menu "22.1") ;; This is referenced by some code below; it is defined in uniquify.el (defvar uniquify-buffer-name-style) diff --cc lisp/net/tramp.el index 7b2d8a0a6e6,50fbaed01e0..1ca46d213d3 --- a/lisp/net/tramp.el +++ b/lisp/net/tramp.el @@@ -2567,381 -6366,326 +2567,385 @@@ User is always nil. (forward-line 1) result)) -;;; Internal Functions: +;;; Common file name handler functions for different backends: -(defun tramp-maybe-send-script (vec script name) - "Define in remote shell function NAME implemented as SCRIPT. -Only send the definition if it has not already been done." - (let* ((p (tramp-get-connection-process vec)) - (scripts (tramp-get-connection-property p "scripts" nil))) - (unless (member name scripts) - (with-progress-reporter vec 5 (format "Sending script `%s'" name) - ;; The script could contain a call of Perl. This is masked with `%s'. - (tramp-send-command-and-check - vec - (format "%s () {\n%s\n}" name - (format script (tramp-get-remote-perl vec)))) - (tramp-set-connection-property p "scripts" (cons name scripts)))))) - -(defun tramp-set-auto-save () - (when (and ;; ange-ftp has its own auto-save mechanism - (eq (tramp-find-foreign-file-name-handler (buffer-file-name)) - 'tramp-sh-file-name-handler) - auto-save-default) - (auto-save-mode 1))) -(add-hook 'find-file-hooks 'tramp-set-auto-save t) -(add-hook 'tramp-unload-hook - (lambda () - (remove-hook 'find-file-hooks 'tramp-set-auto-save))) +(defvar tramp-handle-file-local-copy-hook nil + "Normal hook to be run at the end of `tramp-*-handle-file-local-copy'.") + +(defvar tramp-handle-write-region-hook nil + "Normal hook to be run at the end of `tramp-*-handle-write-region'.") + +(defun tramp-handle-directory-file-name (directory) + "Like `directory-file-name' for Tramp files." + ;; If localname component of filename is "/", leave it unchanged. + ;; Otherwise, remove any trailing slash from localname component. + ;; Method, host, etc, are unchanged. Does it make sense to try + ;; to avoid parsing the filename? + (with-parsed-tramp-file-name directory nil + (if (and (not (zerop (length localname))) + (eq (aref localname (1- (length localname))) ?/) + (not (string= localname "/"))) + (substring directory 0 -1) + directory))) + +(defun tramp-handle-directory-files + (directory &optional full match nosort files-only) + "Like `directory-files' for Tramp files." + ;; FILES-ONLY is valid for XEmacs only. + (when (file-directory-p directory) + (setq directory (file-name-as-directory (expand-file-name directory))) + (let ((temp (nreverse (file-name-all-completions "" directory))) + result item) + + (while temp + (setq item (directory-file-name (pop temp))) + (when (and (or (null match) (string-match match item)) + (or (null files-only) + ;; Files only. + (and (equal files-only t) (file-regular-p item)) + ;; Directories only. + (file-directory-p item))) + (push (if full (concat directory item) item) + result))) + (if nosort result (sort result 'string<))))) + +(defun tramp-handle-directory-files-and-attributes + (directory &optional full match nosort id-format) + "Like `directory-files-and-attributes' for Tramp files." + (mapcar + (lambda (x) + (cons x (tramp-compat-file-attributes + (if full x (expand-file-name x directory)) id-format))) + (directory-files directory full match nosort))) + +(defun tramp-handle-dired-uncache (dir &optional dir-p) + "Like `dired-uncache' for Tramp files." + ;; DIR-P is valid for XEmacs only. + (with-parsed-tramp-file-name + (if (or dir-p (file-directory-p dir)) dir (file-name-directory dir)) nil + (tramp-flush-directory-property v localname))) + +(defun tramp-handle-file-exists-p (filename) + "Like `file-exists-p' for Tramp files." + (not (null (file-attributes filename)))) + +(defun tramp-handle-file-modes (filename) + "Like `file-modes' for Tramp files." + (let ((truename (or (file-truename filename) filename))) + (when (file-exists-p truename) + (tramp-mode-string-to-int (nth 8 (file-attributes truename)))))) + +;; Localname manipulation functions that grok Tramp localnames... +(defun tramp-handle-file-name-as-directory (file) + "Like `file-name-as-directory' but aware of Tramp files." + ;; `file-name-as-directory' would be sufficient except localname is + ;; the empty string. + (let ((v (tramp-dissect-file-name file t))) + ;; Run the command on the localname portion only. + (tramp-make-tramp-file-name + (tramp-file-name-method v) + (tramp-file-name-user v) + (tramp-file-name-host v) + (tramp-run-real-handler + 'file-name-as-directory (list (or (tramp-file-name-localname v) "")))))) + +(defun tramp-handle-file-name-completion + (filename directory &optional predicate) + "Like `file-name-completion' for Tramp files." + (unless (tramp-tramp-file-p directory) + (error + "tramp-handle-file-name-completion invoked on non-tramp directory `%s'" + directory)) + (try-completion + filename + (mapcar 'list (file-name-all-completions filename directory)) + (when predicate + (lambda (x) (funcall predicate (expand-file-name (car x) directory)))))) + +(defun tramp-handle-file-name-directory (file) + "Like `file-name-directory' but aware of Tramp files." + ;; Everything except the last filename thing is the directory. We + ;; cannot apply `with-parsed-tramp-file-name', because this expands + ;; the remote file name parts. This is a problem when we are in + ;; file name completion. + (let ((v (tramp-dissect-file-name file t))) + ;; Run the command on the localname portion only. + (tramp-make-tramp-file-name + (tramp-file-name-method v) + (tramp-file-name-user v) + (tramp-file-name-host v) + (tramp-run-real-handler + 'file-name-directory (list (or (tramp-file-name-localname v) "")))))) + +(defun tramp-handle-file-name-nondirectory (file) + "Like `file-name-nondirectory' but aware of Tramp files." + (with-parsed-tramp-file-name file nil + (tramp-run-real-handler 'file-name-nondirectory (list localname)))) + +(defun tramp-handle-file-newer-than-file-p (file1 file2) + "Like `file-newer-than-file-p' for Tramp files." + (cond + ((not (file-exists-p file1)) nil) + ((not (file-exists-p file2)) t) + (t (tramp-time-less-p (nth 5 (file-attributes file2)) + (nth 5 (file-attributes file1)))))) + +(defun tramp-handle-file-regular-p (filename) + "Like `file-regular-p' for Tramp files." + (and (file-exists-p filename) + (eq ?- (aref (nth 8 (file-attributes filename)) 0)))) + +(defun tramp-handle-file-remote-p (filename &optional identification connected) + "Like `file-remote-p' for Tramp files." + (let ((tramp-verbose 3)) + (when (tramp-tramp-file-p filename) + (let* ((v (tramp-dissect-file-name filename)) + (p (tramp-get-connection-process v)) + (c (and p (processp p) (memq (process-status p) '(run open))))) + ;; We expand the file name only, if there is already a connection. + (with-parsed-tramp-file-name + (if c (expand-file-name filename) filename) nil + (and (or (not connected) c) + (cond + ((eq identification 'method) method) + ((eq identification 'user) user) + ((eq identification 'host) host) + ((eq identification 'localname) localname) + (t (tramp-make-tramp-file-name method user host ""))))))))) -(defun tramp-run-test (switch filename) - "Run `test' on the remote system, given a SWITCH and a FILENAME. -Returns the exit code of the `test' program." +(defun tramp-handle-file-symlink-p (filename) + "Like `file-symlink-p' for Tramp files." (with-parsed-tramp-file-name filename nil - (tramp-send-command-and-check - v - (format - "%s %s %s" - (tramp-get-test-command v) - switch - (tramp-shell-quote-argument localname))))) - -(defun tramp-run-test2 (format-string file1 file2) - "Run `test'-like program on the remote system, given FILE1, FILE2. -FORMAT-STRING contains the program name, switches, and place holders. -Returns the exit code of the `test' program. Barfs if the methods, -hosts, or files, disagree." - (unless (tramp-equal-remote file1 file2) - (with-parsed-tramp-file-name (if (tramp-tramp-file-p file1) file1 file2) nil - (tramp-error - v 'file-error - "tramp-run-test2 only implemented for same method, user, host"))) - (with-parsed-tramp-file-name file1 v1 - (with-parsed-tramp-file-name file1 v2 - (tramp-send-command-and-check - v1 - (format format-string - (tramp-shell-quote-argument v1-localname) - (tramp-shell-quote-argument v2-localname)))))) + (let ((x (car (file-attributes filename)))) + (when (stringp x) + ;; When Tramp is running on VMS, then `file-name-absolute-p' + ;; might do weird things. + (if (file-name-absolute-p x) + (tramp-make-tramp-file-name method user host x) + x))))) -(defun tramp-buffer-name (vec) - "A name for the connection buffer VEC." - ;; We must use `tramp-file-name-real-host', because for gateway - ;; methods the default port will be expanded later on, which would - ;; tamper the name. - (let ((method (tramp-file-name-method vec)) - (user (tramp-file-name-user vec)) - (host (tramp-file-name-real-host vec))) - (if (not (zerop (length user))) - (format "*tramp/%s %s@%s*" method user host) - (format "*tramp/%s %s*" method host)))) +(defun tramp-handle-find-backup-file-name (filename) + "Like `find-backup-file-name' for Tramp files." + (with-parsed-tramp-file-name filename nil + ;; We set both variables. It doesn't matter whether it is + ;; Emacs or XEmacs. + (let ((backup-directory-alist + ;; Emacs case. + (when (boundp 'backup-directory-alist) + (if (symbol-value 'tramp-backup-directory-alist) + (mapcar + (lambda (x) + (cons + (car x) + (if (and (stringp (cdr x)) + (file-name-absolute-p (cdr x)) + (not (tramp-file-name-p (cdr x)))) + (tramp-make-tramp-file-name method user host (cdr x)) + (cdr x)))) + (symbol-value 'tramp-backup-directory-alist)) + (symbol-value 'backup-directory-alist)))) -(defun tramp-delete-temp-file-function () - "Remove temporary files related to current buffer." - (when (stringp tramp-temp-buffer-file-name) - (condition-case nil - (delete-file tramp-temp-buffer-file-name) - (error nil)))) + (bkup-backup-directory-info + ;; XEmacs case. + (when (boundp 'bkup-backup-directory-info) + (if (symbol-value 'tramp-bkup-backup-directory-info) + (mapcar + (lambda (x) + (nconc + (list (car x)) + (list + (if (and (stringp (car (cdr x))) + (file-name-absolute-p (car (cdr x))) + (not (tramp-file-name-p (car (cdr x))))) + (tramp-make-tramp-file-name + method user host (car (cdr x))) + (car (cdr x)))) + (cdr (cdr x)))) + (symbol-value 'tramp-bkup-backup-directory-info)) + (symbol-value 'bkup-backup-directory-info))))) -(add-hook 'kill-buffer-hook 'tramp-delete-temp-file-function) -(add-hook 'tramp-cache-unload-hook - (lambda () - (remove-hook 'kill-buffer-hook - 'tramp-delete-temp-file-function))) + (tramp-run-real-handler 'find-backup-file-name (list filename))))) -(defun tramp-get-buffer (vec) - "Get the connection buffer to be used for VEC." - (or (get-buffer (tramp-buffer-name vec)) - (with-current-buffer (get-buffer-create (tramp-buffer-name vec)) - (setq buffer-undo-list t) - (setq default-directory - (tramp-make-tramp-file-name - (tramp-file-name-method vec) - (tramp-file-name-user vec) - (tramp-file-name-host vec) - "/")) - (current-buffer)))) +(defun tramp-handle-insert-file-contents + (filename &optional visit beg end replace) + "Like `insert-file-contents' for Tramp files." + (barf-if-buffer-read-only) + (setq filename (expand-file-name filename)) + (let (result local-copy remote-copy) + (with-parsed-tramp-file-name filename nil + (unwind-protect + (if (not (file-exists-p filename)) + ;; We don't raise a Tramp error, because it might be + ;; suppressed, like in `find-file-noselect-1'. + (signal 'file-error + (list "File not found on remote host" filename)) -(defun tramp-get-connection-buffer (vec) - "Get the connection buffer to be used for VEC. -In case a second asynchronous communication has been started, it is different -from `tramp-get-buffer'." - (or (tramp-get-connection-property vec "process-buffer" nil) - (tramp-get-buffer vec))) + (if (and (tramp-local-host-p v) + (let (file-name-handler-alist) + (file-readable-p localname))) + ;; Short track: if we are on the local host, we can + ;; run directly. + (setq result + (tramp-run-real-handler + 'insert-file-contents + (list localname visit beg end replace))) + + ;; When we shall insert only a part of the file, we copy + ;; this part. + (when (or beg end) + (setq remote-copy (tramp-make-tramp-temp-file v)) + ;; This is defined in tramp-sh.el. Let's assume this + ;; is loaded already. + (tramp-compat-funcall 'tramp-send-command + v + (cond + ((and beg end) + (format "tail -c +%d %s | head -c +%d >%s" + (1+ beg) (tramp-shell-quote-argument localname) + (- end beg) remote-copy)) + (beg + (format "tail -c +%d %s >%s" + (1+ beg) (tramp-shell-quote-argument localname) + remote-copy)) + (end + (format "head -c +%d %s >%s" + (1+ end) (tramp-shell-quote-argument localname) + remote-copy))))) -(defun tramp-get-connection-process (vec) - "Get the connection process to be used for VEC. -In case a second asynchronous communication has been started, it is different -from the default one." - (get-process - (or (tramp-get-connection-property vec "process-name" nil) - (tramp-buffer-name vec)))) + ;; `insert-file-contents-literally' takes care to avoid + ;; calling jka-compr. By let-binding + ;; `inhibit-file-name-operation', we propagate that care + ;; to the `file-local-copy' operation. + (setq local-copy + (let ((inhibit-file-name-operation + (when (eq inhibit-file-name-operation + 'insert-file-contents) + 'file-local-copy))) + (cond + ((stringp remote-copy) + (file-local-copy + (tramp-make-tramp-file-name + method user host remote-copy))) + ((stringp tramp-temp-buffer-file-name) + (copy-file filename tramp-temp-buffer-file-name 'ok) + tramp-temp-buffer-file-name) + (t (file-local-copy filename))))) -(defun tramp-debug-buffer-name (vec) - "A name for the debug buffer for VEC." - ;; We must use `tramp-file-name-real-host', because for gateway - ;; methods the default port will be expanded later on, which would - ;; tamper the name. - (let ((method (tramp-file-name-method vec)) - (user (tramp-file-name-user vec)) - (host (tramp-file-name-real-host vec))) - (if (not (zerop (length user))) - (format "*debug tramp/%s %s@%s*" method user host) - (format "*debug tramp/%s %s*" method host)))) + ;; When the file is not readable for the owner, it + ;; cannot be inserted, even it is redable for the group + ;; or for everybody. + (set-file-modes local-copy (tramp-compat-octal-to-decimal "0600")) -(defconst tramp-debug-outline-regexp - "[0-9]+:[0-9]+:[0-9]+\\.[0-9]+ [a-z0-9-]+ (\\([0-9]+\\)) #") + (when (and (null remote-copy) + (tramp-get-method-parameter + method 'tramp-copy-keep-tmpfile)) + ;; We keep the local file for performance reasons, + ;; useful for "rsync". + (setq tramp-temp-buffer-file-name local-copy) + (put 'tramp-temp-buffer-file-name 'permanent-local t)) -(defun tramp-get-debug-buffer (vec) - "Get the debug buffer for VEC." - (with-current-buffer - (get-buffer-create (tramp-debug-buffer-name vec)) - (when (bobp) - (setq buffer-undo-list t) - ;; Activate `outline-mode'. This runs `text-mode-hook' and - ;; `outline-mode-hook'. We must prevent that local processes - ;; die. Yes: I've seen `flyspell-mode', which starts "ispell". - ;; Furthermore, `outline-regexp' must have the correct value - ;; already, because it is used by `font-lock-compile-keywords'. - (let ((default-directory (tramp-compat-temporary-file-directory)) - (outline-regexp tramp-debug-outline-regexp)) - (outline-mode)) - (set (make-local-variable 'outline-regexp) tramp-debug-outline-regexp) - (set (make-local-variable 'outline-level) 'tramp-outline-level)) - (current-buffer))) + (with-progress-reporter + v 3 (format "Inserting local temp file `%s'" local-copy) + ;; We must ensure that `file-coding-system-alist' + ;; matches `local-copy'. + (let ((file-coding-system-alist + (tramp-find-file-name-coding-system-alist + filename local-copy))) + (setq result + (insert-file-contents + local-copy nil nil nil replace)))))) -(defun tramp-outline-level () - "Return the depth to which a statement is nested in the outline. -Point must be at the beginning of a header line. + ;; Save exit. + (progn + (when visit + (setq buffer-file-name filename) + (setq buffer-read-only (not (file-writable-p filename))) + (set-visited-file-modtime) - (set-buffer-modified-p nil)) ++ (set-buffer-modified-p nil) ++ ;; For root, preserve owner and group when editing files. ++ (when (string-equal (file-remote-p filename 'user) "root") ++ (set (make-local-variable 'backup-by-copying-when-mismatch) t) ++ (put 'backup-by-copying-when-mismatch 'permanent-local t))) + (when (and (stringp local-copy) + (or remote-copy (null tramp-temp-buffer-file-name))) + (delete-file local-copy)) + (when (stringp remote-copy) + (delete-file + (tramp-make-tramp-file-name method user host remote-copy)))))) -The outline level is equal to the verbosity of the Tramp message." - (1+ (string-to-number (match-string 1)))) + ;; Result. + (list (expand-file-name filename) + (cadr result)))) -(defun tramp-find-executable - (vec progname dirlist &optional ignore-tilde ignore-path) - "Searches for PROGNAME in $PATH and all directories mentioned in DIRLIST. -First arg VEC specifies the connection, PROGNAME is the program -to search for, and DIRLIST gives the list of directories to -search. If IGNORE-TILDE is non-nil, directory names starting -with `~' will be ignored. If IGNORE-PATH is non-nil, searches -only in DIRLIST. +(defun tramp-handle-load (file &optional noerror nomessage nosuffix must-suffix) + "Like `load' for Tramp files." + (with-parsed-tramp-file-name (expand-file-name file) nil + (unless nosuffix + (cond ((file-exists-p (concat file ".elc")) + (setq file (concat file ".elc"))) + ((file-exists-p (concat file ".el")) + (setq file (concat file ".el"))))) + (when must-suffix + ;; The first condition is always true for absolute file names. + ;; Included for safety's sake. + (unless (or (file-name-directory file) + (string-match "\\.elc?\\'" file)) + (tramp-error + v 'file-error + "File `%s' does not include a `.el' or `.elc' suffix" file))) + (unless noerror + (when (not (file-exists-p file)) + (tramp-error v 'file-error "Cannot load nonexistent file `%s'" file))) + (if (not (file-exists-p file)) + nil + (let ((tramp-message-show-message (not nomessage))) + (with-progress-reporter v 0 (format "Loading %s" file) + (let ((local-copy (file-local-copy file))) + ;; MUST-SUFFIX doesn't exist on XEmacs, so let it default to nil. + (unwind-protect + (load local-copy noerror t t) + (delete-file local-copy))))) + t))) -Returns the absolute file name of PROGNAME, if found, and nil otherwise. +(defun tramp-handle-substitute-in-file-name (filename) + "Like `substitute-in-file-name' for Tramp files. +\"//\" and \"/~\" substitute only in the local filename part. +If the URL Tramp syntax is chosen, \"//\" as method delimeter and \"/~\" at +beginning of local filename are not substituted." + ;; First, we must replace environment variables. + (setq filename (tramp-replace-environment-variables filename)) + (with-parsed-tramp-file-name filename nil + (if (equal tramp-syntax 'url) + ;; We need to check localname only. The other parts cannot contain + ;; "//" or "/~". + (if (and (> (length localname) 1) + (or (string-match "//" localname) + (string-match "/~" localname 1))) + (tramp-run-real-handler 'substitute-in-file-name (list filename)) + (tramp-make-tramp-file-name + (when method (substitute-in-file-name method)) + (when user (substitute-in-file-name user)) + (when host (substitute-in-file-name host)) + (when localname + (tramp-run-real-handler + 'substitute-in-file-name (list localname))))) + ;; Ignore in LOCALNAME everything before "//" or "/~". + (when (and (stringp localname) (string-match ".+?/\\(/\\|~\\)" localname)) + (setq filename + (concat (file-remote-p filename) + (replace-match "\\1" nil nil localname))) + ;; "/m:h:~" does not work for completion. We use "/m:h:~/". + (when (string-match "~$" filename) + (setq filename (concat filename "/")))) + (tramp-run-real-handler 'substitute-in-file-name (list filename))))) -This function expects to be in the right *tramp* buffer." - (with-current-buffer (tramp-get-connection-buffer vec) - (let (result) - ;; Check whether the executable is in $PATH. "which(1)" does not - ;; report always a correct error code; therefore we check the - ;; number of words it returns. - (unless ignore-path - (tramp-send-command vec (format "which \\%s | wc -w" progname)) - (goto-char (point-min)) - (if (looking-at "^\\s-*1$") - (setq result (concat "\\" progname)))) - (unless result - (when ignore-tilde - ;; Remove all ~/foo directories from dirlist. In XEmacs, - ;; `remove' is in CL, and we want to avoid CL dependencies. - (let (newdl d) - (while dirlist - (setq d (car dirlist)) - (setq dirlist (cdr dirlist)) - (unless (char-equal ?~ (aref d 0)) - (setq newdl (cons d newdl)))) - (setq dirlist (nreverse newdl)))) - (tramp-send-command - vec - (format (concat "while read d; " - "do if test -x $d/%s -a -f $d/%s; " - "then echo tramp_executable $d/%s; " - "break; fi; done <<'EOF'\n" - "%s\nEOF") - progname progname progname (mapconcat 'identity dirlist "\n"))) - (goto-char (point-max)) - (when (search-backward "tramp_executable " nil t) - (skip-chars-forward "^ ") - (skip-chars-forward " ") - (setq result (buffer-substring - (point) (tramp-compat-line-end-position))))) - result))) - -(defun tramp-set-remote-path (vec) - "Sets the remote environment PATH to existing directories. -I.e., for each directory in `tramp-remote-path', it is tested -whether it exists and if so, it is added to the environment -variable PATH." - (tramp-message vec 5 (format "Setting $PATH environment variable")) - (tramp-send-command - vec (format "PATH=%s; export PATH" - (mapconcat 'identity (tramp-get-remote-path vec) ":")))) - -;; ------------------------------------------------------------ -;; -- Communication with external shell -- -;; ------------------------------------------------------------ - -(defun tramp-find-file-exists-command (vec) - "Find a command on the remote host for checking if a file exists. -Here, we are looking for a command which has zero exit status if the -file exists and nonzero exit status otherwise." - (let ((existing "/") - (nonexisting - (tramp-shell-quote-argument "/ this file does not exist ")) - result) - ;; The algorithm is as follows: we try a list of several commands. - ;; For each command, we first run `$cmd /' -- this should return - ;; true, as the root directory always exists. And then we run - ;; `$cmd /this\ file\ does\ not\ exist ', hoping that the file indeed - ;; does not exist. This should return false. We use the first - ;; command we find that seems to work. - ;; The list of commands to try is as follows: - ;; `ls -d' This works on most systems, but NetBSD 1.4 - ;; has a bug: `ls' always returns zero exit - ;; status, even for files which don't exist. - ;; `test -e' Some Bourne shells have a `test' builtin - ;; which does not know the `-e' option. - ;; `/bin/test -e' For those, the `test' binary on disk normally - ;; provides the option. Alas, the binary - ;; is sometimes `/bin/test' and sometimes it's - ;; `/usr/bin/test'. - ;; `/usr/bin/test -e' In case `/bin/test' does not exist. - (unless (or - (and (setq result (format "%s -e" (tramp-get-test-command vec))) - (zerop (tramp-send-command-and-check - vec (format "%s %s" result existing))) - (not (zerop (tramp-send-command-and-check - vec (format "%s %s" result nonexisting))))) - (and (setq result "/bin/test -e") - (zerop (tramp-send-command-and-check - vec (format "%s %s" result existing))) - (not (zerop (tramp-send-command-and-check - vec (format "%s %s" result nonexisting))))) - (and (setq result "/usr/bin/test -e") - (zerop (tramp-send-command-and-check - vec (format "%s %s" result existing))) - (not (zerop (tramp-send-command-and-check - vec (format "%s %s" result nonexisting))))) - (and (setq result (format "%s -d" (tramp-get-ls-command vec))) - (zerop (tramp-send-command-and-check - vec (format "%s %s" result existing))) - (not (zerop (tramp-send-command-and-check - vec (format "%s %s" result nonexisting)))))) - (tramp-error - vec 'file-error "Couldn't find command to check if file exists")) - result)) +(defun tramp-handle-unhandled-file-name-directory (filename) + "Like `unhandled-file-name-directory' for Tramp files." + ;; With Emacs 23, we could simply return `nil'. But we must keep it + ;; for backward compatibility. + (expand-file-name "~/")) -(defun tramp-open-shell (vec shell) - "Opens shell SHELL." - (with-progress-reporter vec 5 (format "Opening remote shell `%s'" shell) - ;; Find arguments for this shell. - (let ((tramp-end-of-output tramp-initial-end-of-output) - (alist tramp-sh-extra-args) - item extra-args) - (while (and alist (null extra-args)) - (setq item (pop alist)) - (when (string-match (car item) shell) - (setq extra-args (cdr item)))) - (when extra-args (setq shell (concat shell " " extra-args))) - (tramp-send-command - vec (format "exec env ENV='' PROMPT_COMMAND='' PS1=%s PS2='' PS3='' %s" - (shell-quote-argument tramp-end-of-output) shell) - t)) - ;; Setting prompts. - (tramp-send-command - vec (format "PS1=%s" (shell-quote-argument tramp-end-of-output)) t) - (tramp-send-command vec "PS2=''" t) - (tramp-send-command vec "PS3=''" t) - (tramp-send-command vec "PROMPT_COMMAND=''" t))) - -(defun tramp-find-shell (vec) - "Opens a shell on the remote host which groks tilde expansion." - (unless (tramp-get-connection-property vec "remote-shell" nil) - (let (shell) - (with-current-buffer (tramp-get-buffer vec) - (tramp-send-command vec "echo ~root" t) - (cond - ((or (string-match "^~root$" (buffer-string)) - ;; The default shell (ksh93) of OpenSolaris is buggy. - (string-equal (tramp-get-connection-property vec "uname" "") - "SunOS 5.11")) - (setq shell - (or (tramp-find-executable - vec "bash" (tramp-get-remote-path vec) t t) - (tramp-find-executable - vec "ksh" (tramp-get-remote-path vec) t t))) - (unless shell - (tramp-error - vec 'file-error - "Couldn't find a shell which groks tilde expansion")) - (tramp-message - vec 5 "Starting remote shell `%s' for tilde expansion" shell) - (tramp-open-shell vec shell)) - - (t (tramp-message - vec 5 "Remote `%s' groks tilde expansion, good" - (tramp-set-connection-property - vec "remote-shell" - (tramp-get-method-parameter - (tramp-file-name-method vec) 'tramp-remote-sh))))))))) - -;; ------------------------------------------------------------ -;; -- Functions for establishing connection -- -;; ------------------------------------------------------------ +;;; Functions for establishing connection: ;; The following functions are actions to be taken when seeing certain ;; prompts from the remote host. See the variable diff --cc lisp/play/gomoku.el index dbe3317a020,1b11388a0d7..bb77c5a33ea --- a/lisp/play/gomoku.el +++ b/lisp/play/gomoku.el @@@ -188,15 -187,23 +188,15 @@@ One useful value to include is `turn-on You and Emacs play in turn by marking a free square. You mark it with X and Emacs marks it with O. The winner is the first to get five contiguous marks horizontally, vertically or in diagonal. - +\\ You play by moving the cursor over the square you choose and hitting \\[gomoku-human-plays]. -Other useful commands: -\\{gomoku-mode-map} -Entry to this mode calls the value of `gomoku-mode-hook' if that value -is non-nil." - (interactive) - (kill-all-local-variables) - (setq major-mode 'gomoku-mode - mode-name "Gomoku") +Other useful commands:\n +\\{gomoku-mode-map}" (gomoku-display-statistics) - (use-local-map gomoku-mode-map) (make-local-variable 'font-lock-defaults) - (setq font-lock-defaults '(gomoku-font-lock-keywords t)) - (toggle-read-only t)) + (setq font-lock-defaults '(gomoku-font-lock-keywords t) - buffer-read-only t) - (run-mode-hooks 'gomoku-mode-hook)) ++ buffer-read-only t)) ;;; ;;; THE BOARD. diff --cc lisp/progmodes/sql.el index 7148027f487,6bd0d45bbd9..acb34eacc2b --- a/lisp/progmodes/sql.el +++ b/lisp/progmodes/sql.el @@@ -5,9 -5,10 +5,10 @@@ ;; Author: Alex Schroeder ;; Maintainer: Michael Mauger -;; Version: 2.0.2 +;; Version: 2.8 ;; Keywords: comm languages processes - ;; URL: http://savannah.gnu.org/cgi-bin/viewcvs/emacs/emacs/lisp/progmodes/sql.el + ;; URL: http://savannah.gnu.org/projects/emacs/ + ;; URL: http://www.emacswiki.org/cgi-bin/wiki.pl?SqlMode ;; This file is part of GNU Emacs. @@@ -4270,6 -2885,4 +4271,5 @@@ buffer (provide 'sql) - ;; arch-tag: 7e1fa1c4-9ca2-402e-87d2-83a5eccb7ac3 ;;; sql.el ends here + diff --cc lisp/vc/add-log.el index b63e482ff05,00000000000..c356dde8226 mode 100644,000000..100644 --- a/lisp/vc/add-log.el +++ b/lisp/vc/add-log.el @@@ -1,1371 -1,0 +1,1371 @@@ +;;; add-log.el --- change log maintenance commands for Emacs + +;; Copyright (C) 1985, 1986, 1988, 1993, 1994, 1997, 1998, 2000, 2001, +;; 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 +;; Free Software Foundation, Inc. + +;; Maintainer: FSF +;; Keywords: vc tools + +;; This file is part of GNU Emacs. + +;; GNU Emacs is free software: you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation, either version 3 of the License, or +;; (at your option) any later version. + +;; GNU Emacs is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. + +;; You should have received a copy of the GNU General Public License +;; along with GNU Emacs. If not, see . + +;;; Commentary: + +;; This facility is documented in the Emacs Manual. + +;; Todo: + +;; - Find/use/create _MTN/log if there's a _MTN directory. +;; - Find/use/create ++log.* if there's an {arch} directory. +;; - Use an open *VC-Log* or *cvs-commit* buffer if it's related to the +;; source file. +;; - Don't add TAB indents (and username?) if inserting entries in those +;; special places. + +;;; Code: + +(defgroup change-log nil + "Change log maintenance." + :group 'tools + :link '(custom-manual "(emacs)Change Log") + :prefix "change-log-" + :prefix "add-log-") + + +(defcustom change-log-default-name nil + "Name of a change log file for \\[add-change-log-entry]." + :type '(choice (const :tag "default" nil) + string) + :group 'change-log) +;;;###autoload +(put 'change-log-default-name 'safe-local-variable 'string-or-null-p) + +(defcustom change-log-mode-hook nil + "Normal hook run by `change-log-mode'." + :type 'hook + :group 'change-log) + +;; Many modes set this variable, so avoid warnings. +;;;###autoload +(defcustom add-log-current-defun-function nil + "If non-nil, function to guess name of surrounding function. +It is used by `add-log-current-defun' in preference to built-in rules. +Returns function's name as a string, or nil if outside a function." + :type '(choice (const nil) function) + :group 'change-log) + +;;;###autoload +(defcustom add-log-full-name nil + "Full name of user, for inclusion in ChangeLog daily headers. +This defaults to the value returned by the function `user-full-name'." + :type '(choice (const :tag "Default" nil) + string) + :group 'change-log) + +;;;###autoload +(defcustom add-log-mailing-address nil + "Email addresses of user, for inclusion in ChangeLog headers. +This defaults to the value of `user-mail-address'. In addition to +being a simple string, this value can also be a list. All elements +will be recognized as referring to the same user; when creating a new +ChangeLog entry, one element will be chosen at random." + :type '(choice (const :tag "Default" nil) + (string :tag "String") + (repeat :tag "List of Strings" string)) + :group 'change-log) + +(defcustom add-log-time-format 'add-log-iso8601-time-string + "Function that defines the time format. +For example, `add-log-iso8601-time-string', which gives the +date in international ISO 8601 format, +and `current-time-string' are two valid values." + :type '(radio (const :tag "International ISO 8601 format" + add-log-iso8601-time-string) + (const :tag "Old format, as returned by `current-time-string'" + current-time-string) + (function :tag "Other")) + :group 'change-log) + +(defcustom add-log-keep-changes-together nil + "If non-nil, normally keep day's log entries for one file together. + +Log entries for a given file made with \\[add-change-log-entry] or +\\[add-change-log-entry-other-window] will only be added to others \ +for that file made +today if this variable is non-nil or that file comes first in today's +entries. Otherwise another entry for that file will be started. An +original log: + + * foo (...): ... + * bar (...): change 1 + +in the latter case, \\[add-change-log-entry-other-window] in a \ +buffer visiting `bar', yields: + + * bar (...): -!- + * foo (...): ... + * bar (...): change 1 + +and in the former: + + * foo (...): ... + * bar (...): change 1 + (...): -!- + +The NEW-ENTRY arg to `add-change-log-entry' can override the effect of +this variable." + :version "20.3" + :type 'boolean + :group 'change-log) + +(defcustom add-log-always-start-new-record nil + "If non-nil, `add-change-log-entry' will always start a new record." + :version "22.1" + :type 'boolean + :group 'change-log) + +(defcustom add-log-buffer-file-name-function nil + "If non-nil, function to call to identify the full filename of a buffer. +This function is called with no argument. If this is nil, the default is to +use `buffer-file-name'." + :type '(choice (const nil) function) + :group 'change-log) + +(defcustom add-log-file-name-function nil + "If non-nil, function to call to identify the filename for a ChangeLog entry. +This function is called with one argument, the value of variable +`buffer-file-name' in that buffer. If this is nil, the default is to +use the file's name relative to the directory of the change log file." + :type '(choice (const nil) function) + :group 'change-log) + + +(defcustom change-log-version-info-enabled nil + "If non-nil, enable recording version numbers with the changes." + :version "21.1" + :type 'boolean + :group 'change-log) + +(defcustom change-log-version-number-regexp-list + (let ((re "\\([0-9]+\.[0-9.]+\\)")) + (list + ;; (defconst ad-version "2.15" + (concat "^(def[^ \t\n]+[ \t]+[^ \t\n][ \t]\"" re) + ;; Revision: pcl-cvs.el,v 1.72 1999/09/05 20:21:54 monnier Exp + (concat "^;+ *Revision: +[^ \t\n]+[ \t]+" re))) + "List of regexps to search for version number. +The version number must be in group 1. +Note: The search is conducted only within 10%, at the beginning of the file." + :version "21.1" + :type '(repeat regexp) + :group 'change-log) + +(defface change-log-date + '((t (:inherit font-lock-string-face))) + "Face used to highlight dates in date lines." + :version "21.1" + :group 'change-log) +(define-obsolete-face-alias 'change-log-date-face 'change-log-date "22.1") + +(defface change-log-name + '((t (:inherit font-lock-constant-face))) + "Face for highlighting author names." + :version "21.1" + :group 'change-log) +(define-obsolete-face-alias 'change-log-name-face 'change-log-name "22.1") + +(defface change-log-email + '((t (:inherit font-lock-variable-name-face))) + "Face for highlighting author email addresses." + :version "21.1" + :group 'change-log) +(define-obsolete-face-alias 'change-log-email-face 'change-log-email "22.1") + +(defface change-log-file + '((t (:inherit font-lock-function-name-face))) + "Face for highlighting file names." + :version "21.1" + :group 'change-log) +(define-obsolete-face-alias 'change-log-file-face 'change-log-file "22.1") + +(defface change-log-list + '((t (:inherit font-lock-keyword-face))) + "Face for highlighting parenthesized lists of functions or variables." + :version "21.1" + :group 'change-log) +(define-obsolete-face-alias 'change-log-list-face 'change-log-list "22.1") + +(defface change-log-conditionals + '((t (:inherit font-lock-variable-name-face))) + "Face for highlighting conditionals of the form `[...]'." + :version "21.1" + :group 'change-log) +(define-obsolete-face-alias 'change-log-conditionals-face + 'change-log-conditionals "22.1") + +(defface change-log-function + '((t (:inherit font-lock-variable-name-face))) + "Face for highlighting items of the form `<....>'." + :version "21.1" + :group 'change-log) +(define-obsolete-face-alias 'change-log-function-face + 'change-log-function "22.1") + +(defface change-log-acknowledgement + '((t (:inherit font-lock-comment-face))) + "Face for highlighting acknowledgments." + :version "21.1" + :group 'change-log) +(define-obsolete-face-alias 'change-log-acknowledgement-face + 'change-log-acknowledgement "22.1") + +(defconst change-log-file-names-re "^\\( +\\|\t\\)\\* \\([^ ,:([\n]+\\)") +(defconst change-log-start-entry-re "^\\sw.........[0-9:+ ]*") + +(defvar change-log-font-lock-keywords + `(;; + ;; Date lines, new (2000-01-01) and old (Sat Jan 1 00:00:00 2000) styles. + ;; Fixme: this regepx is just an approximate one and may match + ;; wrongly with a non-date line existing as a random note. In + ;; addition, using any kind of fixed setting like this doesn't + ;; work if a user customizes add-log-time-format. + ("^[0-9-]+ +\\|^ \\{11,\\}\\|^\\(Sun\\|Mon\\|Tue\\|Wed\\|Thu\\|Fri\\|Sat\\) [A-z][a-z][a-z] [0-9:+ ]+" + (0 'change-log-date-face) + ;; Name and e-mail; some people put e-mail in parens, not angles. + ("\\([^<(]+?\\)[ \t]*[(<]\\([A-Za-z0-9_.+-]+@[A-Za-z0-9_.-]+\\)[>)]" nil nil + (1 'change-log-name) + (2 'change-log-email))) + ;; + ;; File names. + (,change-log-file-names-re + (2 'change-log-file) + ;; Possibly further names in a list: + ("\\=, \\([^ ,:([\n]+\\)" nil nil (1 'change-log-file)) + ;; Possibly a parenthesized list of names: + ("\\= (\\([^(),\n]+\\|(\\(setf\\|SETF\\) [^() ,\n]+)\\)" + nil nil (1 'change-log-list)) + ("\\=, *\\([^(),\n]+\\|(\\(setf\\|SETF\\) [^() ,\n]+)\\)" + nil nil (1 'change-log-list))) + ;; + ;; Function or variable names. + ("^\\( +\\|\t\\)(\\([^(),\n]+\\|(\\(setf\\|SETF\\) [^() ,\n]+)\\)" + (2 'change-log-list) + ("\\=, *\\([^(),\n]+\\|(\\(setf\\|SETF\\) [^() ,\n]+)\\)" nil nil + (1 'change-log-list))) + ;; + ;; Conditionals. + ("\\[!?\\([^]\n]+\\)\\]\\(:\\| (\\)" (1 'change-log-conditionals)) + ;; + ;; Function of change. + ("<\\([^>\n]+\\)>\\(:\\| (\\)" (1 'change-log-function)) + ;; + ;; Acknowledgements. + ;; Don't include plain "From" because that is vague; + ;; we want to encourage people to say something more specific. + ;; Note that the FSF does not use "Patches by"; our convention + ;; is to put the name of the author of the changes at the top + ;; of the change log entry. + ("\\(^\\( +\\|\t\\)\\| \\)\\(Patch\\(es\\)? by\\|Report\\(ed by\\| from\\)\\|Suggest\\(ed by\\|ion from\\)\\)" + 3 'change-log-acknowledgement)) + "Additional expressions to highlight in Change Log mode.") + +(defun change-log-search-file-name (where) + "Return the file-name for the change under point." + (save-excursion + (goto-char where) + (beginning-of-line 1) + (if (looking-at change-log-start-entry-re) + ;; We are at the start of an entry, search forward for a file + ;; name. + (progn + (re-search-forward change-log-file-names-re nil t) + (match-string-no-properties 2)) + (if (looking-at change-log-file-names-re) + ;; We found a file name. + (match-string-no-properties 2) + ;; Look backwards for either a file name or the log entry start. + (if (re-search-backward + (concat "\\(" change-log-start-entry-re + "\\)\\|\\(" + change-log-file-names-re "\\)") nil t) + (if (match-beginning 1) + ;; We got the start of the entry, look forward for a + ;; file name. + (progn + (re-search-forward change-log-file-names-re nil t) + (match-string-no-properties 2)) + (match-string-no-properties 4)) + ;; We must be before any file name, look forward. + (re-search-forward change-log-file-names-re nil t) + (match-string-no-properties 2)))))) + +(defun change-log-find-file () + "Visit the file for the change under point." + (interactive) + (let ((file (change-log-search-file-name (point)))) + (if (and file (file-exists-p file)) + (find-file file) + (message "No such file or directory: %s" file)))) + +(defun change-log-search-tag-name-1 (&optional from) + "Search for a tag name within subexpression 1 of last match. +Optional argument FROM specifies a buffer position where the tag +name should be located. Return value is a cons whose car is the +string representing the tag and whose cdr is the position where +the tag was found." + (save-restriction + (narrow-to-region (match-beginning 1) (match-end 1)) + (when from (goto-char from)) + ;; The regexp below skips any symbol near `point' (FROM) followed by + ;; whitespace and another symbol. This should skip, for example, + ;; "struct" in a specification like "(struct buffer)" and move to + ;; "buffer". A leading paren is ignored. + (when (looking-at + "[(]?\\(?:\\(?:\\sw\\|\\s_\\)+\\(?:[ \t]+\\(\\sw\\|\\s_\\)+\\)\\)") + (goto-char (match-beginning 1))) + (cons (find-tag-default) (point)))) + +(defconst change-log-tag-re + "(\\(\\(?:\\sw\\|\\s_\\)+\\(?:[, \t]+\\(?:\\sw\\|\\s_\\)+\\)*\\))" + "Regexp matching a tag name in change log entries.") + +(defun change-log-search-tag-name (&optional at) + "Search for a tag name near `point'. +Optional argument AT non-nil means search near buffer position AT. +Return value is a cons whose car is the string representing +the tag and whose cdr is the position where the tag was found." + (save-excursion + (goto-char (setq at (or at (point)))) + (save-restriction + (widen) + (or (condition-case nil + ;; Within parenthesized list? + (save-excursion + (backward-up-list) + (when (looking-at change-log-tag-re) + (change-log-search-tag-name-1 at))) + (error nil)) + (condition-case nil + ;; Before parenthesized list on same line? + (save-excursion + (when (and (skip-chars-forward " \t") + (looking-at change-log-tag-re)) + (change-log-search-tag-name-1))) + (error nil)) + (condition-case nil + ;; Near file name? + (save-excursion + (when (and (progn + (beginning-of-line) + (looking-at change-log-file-names-re)) + (goto-char (match-end 0)) + (skip-syntax-forward " ") + (looking-at change-log-tag-re)) + (change-log-search-tag-name-1))) + (error nil)) + (condition-case nil + ;; Anywhere else within current entry? + (let ((from + (save-excursion + (end-of-line) + (if (re-search-backward change-log-start-entry-re nil t) + (match-beginning 0) + (point-min)))) + (to + (save-excursion + (end-of-line) + (if (re-search-forward change-log-start-entry-re nil t) + (match-beginning 0) + (point-max))))) + (when (and (< from to) (<= from at) (<= at to)) + (save-restriction + ;; Narrow to current change log entry. + (narrow-to-region from to) + (cond + ((re-search-backward change-log-tag-re nil t) + (narrow-to-region (match-beginning 1) (match-end 1)) + (goto-char (point-max)) + (cons (find-tag-default) (point-max))) + ((re-search-forward change-log-tag-re nil t) + (narrow-to-region (match-beginning 1) (match-end 1)) + (goto-char (point-min)) + (cons (find-tag-default) (point-min))))))) + (error nil)))))) + +(defvar change-log-find-head nil) +(defvar change-log-find-tail nil) +(defvar change-log-find-window nil) + +(defun change-log-goto-source-1 (tag regexp file buffer + &optional window first last) + "Search for tag TAG in buffer BUFFER visiting file FILE. +REGEXP is a regular expression for TAG. The remaining arguments +are optional: WINDOW denotes the window to display the results of +the search. FIRST is a position in BUFFER denoting the first +match from previous searches for TAG. LAST is the position in +BUFFER denoting the last match for TAG in the last search." + (with-current-buffer buffer + (save-excursion + (save-restriction + (widen) + (if last + (progn + ;; When LAST is set make sure we continue from the next + ;; line end to not find the same tag again. + (goto-char last) + (end-of-line) + (condition-case nil + ;; Try to go to the end of the current defun to avoid + ;; false positives within the current defun's body + ;; since these would match `add-log-current-defun'. + (end-of-defun) + ;; Don't fall behind when `end-of-defun' fails. + (error (progn (goto-char last) (end-of-line)))) + (setq last nil)) + ;; When LAST was not set start at beginning of BUFFER. + (goto-char (point-min))) + (let (current-defun) + (while (and (not last) (re-search-forward regexp nil t)) + ;; Verify that `add-log-current-defun' invoked at the end + ;; of the match returns TAG. This heuristic works well + ;; whenever the name of the defun occurs within the first + ;; line of the defun. + (setq current-defun (add-log-current-defun)) + (when (and current-defun (string-equal current-defun tag)) + ;; Record this as last match. + (setq last (line-beginning-position)) + ;; Record this as first match when there's none. + (unless first (setq first last))))))) + (if (or last first) + (with-selected-window + (setq change-log-find-window (or window (display-buffer buffer))) + (if last + (progn + (when (or (< last (point-min)) (> last (point-max))) + ;; Widen to show TAG. + (widen)) + (push-mark) + (goto-char last)) + ;; When there are no more matches go (back) to FIRST. + (message "No more matches for tag `%s' in file `%s'" tag file) + (setq last first) + (goto-char first)) + ;; Return new "tail". + (list (selected-window) first last)) + (message "Source location of tag `%s' not found in file `%s'" tag file) + nil))) + +(defun change-log-goto-source () + "Go to source location of \"change log tag\" near `point'. +A change log tag is a symbol within a parenthesized, +comma-separated list. If no suitable tag can be found nearby, +try to visit the file for the change under `point' instead." + (interactive) + (if (and (eq last-command 'change-log-goto-source) + change-log-find-tail) + (setq change-log-find-tail + (condition-case nil + (apply 'change-log-goto-source-1 + (append change-log-find-head change-log-find-tail)) + (error + (format "Cannot find more matches for tag `%s' in file `%s'" + (car change-log-find-head) + (nth 2 change-log-find-head))))) + (save-excursion + (let* ((at (point)) + (tag-at (change-log-search-tag-name)) + (tag (car tag-at)) + (file (when tag-at (change-log-search-file-name (cdr tag-at)))) + (file-at (when file (match-beginning 2))) + ;; `file-2' is the file `change-log-search-file-name' finds + ;; at `point'. We use `file-2' as a fallback when `tag' or + ;; `file' are not suitable for some reason. + (file-2 (change-log-search-file-name at)) + (file-2-at (when file-2 (match-beginning 2)))) + (cond + ((and (or (not tag) (not file) (not (file-exists-p file))) + (or (not file-2) (not (file-exists-p file-2)))) + (error "Cannot find tag or file near `point'")) + ((and file-2 (file-exists-p file-2) + (or (not tag) (not file) (not (file-exists-p file)) + (and (or (and (< file-at file-2-at) (<= file-2-at at)) + (and (<= at file-2-at) (< file-2-at file-at)))))) + ;; We either have not found a suitable file name or `file-2' + ;; provides a "better" file name wrt `point'. Go to the + ;; buffer of `file-2' instead. + (setq change-log-find-window + (display-buffer (find-file-noselect file-2)))) + (t + (setq change-log-find-head + (list tag (concat "\\_<" (regexp-quote tag) "\\_>") + file (find-file-noselect file))) + (condition-case nil + (setq change-log-find-tail + (apply 'change-log-goto-source-1 change-log-find-head)) + (error + (format "Cannot find matches for tag `%s' in file `%s'" + tag file))))))))) + +(defun change-log-next-error (&optional argp reset) + "Move to the Nth (default 1) next match in a ChangeLog buffer. +Compatibility function for \\[next-error] invocations." + (interactive "p") + (let* ((argp (or argp 0)) + (count (abs argp)) ; how many cycles + (down (< argp 0)) ; are we going down? (is argp negative?) + (up (not down)) + (search-function (if up 're-search-forward 're-search-backward))) + + ;; set the starting position + (goto-char (cond (reset (point-min)) + (down (line-beginning-position)) + (up (line-end-position)) + ((point)))) + + (funcall search-function change-log-file-names-re nil t count)) + + (beginning-of-line) + ;; if we found a place to visit... + (when (looking-at change-log-file-names-re) + (let (change-log-find-window) + (change-log-goto-source) + (when change-log-find-window + ;; Select window displaying source file. + (select-window change-log-find-window))))) + +(defvar change-log-mode-map + (let ((map (make-sparse-keymap)) + (menu-map (make-sparse-keymap))) + (define-key map [?\C-c ?\C-p] 'add-log-edit-prev-comment) + (define-key map [?\C-c ?\C-n] 'add-log-edit-next-comment) + (define-key map [?\C-c ?\C-f] 'change-log-find-file) + (define-key map [?\C-c ?\C-c] 'change-log-goto-source) + (define-key map [menu-bar changelog] (cons "ChangeLog" menu-map)) + (define-key menu-map [gs] + '(menu-item "Go To Source" change-log-goto-source + :help "Go to source location of ChangeLog tag near point")) + (define-key menu-map [ff] + '(menu-item "Find File" change-log-find-file + :help "Visit the file for the change under point")) + (define-key menu-map [sep] '("--")) + (define-key menu-map [nx] + '(menu-item "Next Log-Edit Comment" add-log-edit-next-comment + :help "Cycle forward through Log-Edit mode comment history")) + (define-key menu-map [pr] + '(menu-item "Previous Log-Edit Comment" add-log-edit-prev-comment + :help "Cycle backward through Log-Edit mode comment history")) + map) + "Keymap for Change Log major mode.") + +;; It used to be called change-log-time-zone-rule but really should be +;; called add-log-time-zone-rule since it's only used from add-log-* code. +(defvaralias 'change-log-time-zone-rule 'add-log-time-zone-rule) +(defvar add-log-time-zone-rule nil + "Time zone used for calculating change log time stamps. +It takes the same format as the TZ argument of `set-time-zone-rule'. +If nil, use local time. +If t, use universal time.") +(put 'add-log-time-zone-rule 'safe-local-variable + '(lambda (x) (or (booleanp x) (stringp x)))) + +(defun add-log-iso8601-time-zone (&optional time) + (let* ((utc-offset (or (car (current-time-zone time)) 0)) + (sign (if (< utc-offset 0) ?- ?+)) + (sec (abs utc-offset)) + (ss (% sec 60)) + (min (/ sec 60)) + (mm (% min 60)) + (hh (/ min 60))) + (format (cond ((not (zerop ss)) "%c%02d:%02d:%02d") + ((not (zerop mm)) "%c%02d:%02d") + (t "%c%02d")) + sign hh mm ss))) + +(defvar add-log-iso8601-with-time-zone nil) + +(defun add-log-iso8601-time-string () + (let ((time (format-time-string "%Y-%m-%d" + nil (eq t add-log-time-zone-rule)))) + (if add-log-iso8601-with-time-zone + (concat time " " (add-log-iso8601-time-zone)) + time))) + +(defun change-log-name () + "Return (system-dependent) default name for a change log file." + (or change-log-default-name + "ChangeLog")) + +(defun add-log-edit-prev-comment (arg) + "Cycle backward through Log-Edit mode comment history. +With a numeric prefix ARG, go back ARG comments." + (interactive "*p") + (save-restriction + (narrow-to-region (point) + (if (memq last-command '(add-log-edit-prev-comment + add-log-edit-next-comment)) + (mark) (point))) + (when (fboundp 'log-edit-previous-comment) + (log-edit-previous-comment arg) + (indent-region (point-min) (point-max)) + (goto-char (point-min)) + (unless (save-restriction (widen) (bolp)) + (delete-region (point) (progn (skip-chars-forward " \t\n") (point)))) + (set-mark (point-min)) + (goto-char (point-max)) + (delete-region (point) (progn (skip-chars-backward " \t\n") (point)))))) + +(defun add-log-edit-next-comment (arg) + "Cycle forward through Log-Edit mode comment history. +With a numeric prefix ARG, go back ARG comments." + (interactive "*p") + (add-log-edit-prev-comment (- arg))) + +;;;###autoload +(defun prompt-for-change-log-name () + "Prompt for a change log name." + (let* ((default (change-log-name)) + (name (expand-file-name + (read-file-name (format "Log file (default %s): " default) + nil default)))) + ;; Handle something that is syntactically a directory name. + ;; Look for ChangeLog or whatever in that directory. + (if (string= (file-name-nondirectory name) "") + (expand-file-name (file-name-nondirectory default) + name) + ;; Handle specifying a file that is a directory. + (if (file-directory-p name) + (expand-file-name (file-name-nondirectory default) + (file-name-as-directory name)) + name)))) + +(defun change-log-version-number-search () + "Return version number of current buffer's file. +This is the value returned by `vc-working-revision' or, if that is +nil, by matching `change-log-version-number-regexp-list'." + (let* ((size (buffer-size)) + (limit + ;; The version number can be anywhere in the file, but + ;; restrict search to the file beginning: 10% should be + ;; enough to prevent some mishits. + ;; + ;; Apply percentage only if buffer size is bigger than + ;; approx 100 lines. + (if (> size (* 100 80)) (+ (point) (/ size 10))))) + (or (and buffer-file-name (vc-working-revision buffer-file-name)) + (save-restriction + (widen) + (let ((regexps change-log-version-number-regexp-list) + version) + (while regexps + (save-excursion + (goto-char (point-min)) + (when (re-search-forward (pop regexps) limit t) + (setq version (match-string 1) + regexps nil)))) + version))))) + +(declare-function diff-find-source-location "diff-mode" + (&optional other-file reverse noprompt)) + +;;;###autoload +(defun find-change-log (&optional file-name buffer-file) + "Find a change log file for \\[add-change-log-entry] and return the name. + +Optional arg FILE-NAME specifies the file to use. +If FILE-NAME is nil, use the value of `change-log-default-name'. +If `change-log-default-name' is nil, behave as though it were 'ChangeLog' +\(or whatever we use on this operating system). + +If `change-log-default-name' contains a leading directory component, then +simply find it in the current directory. Otherwise, search in the current +directory and its successive parents for a file so named. + +Once a file is found, `change-log-default-name' is set locally in the +current buffer to the complete file name. +Optional arg BUFFER-FILE overrides `buffer-file-name'." + ;; If we are called from a diff, first switch to the source buffer; + ;; in order to respect buffer-local settings of change-log-default-name, etc. - (with-current-buffer (let ((buff (if (eq major-mode 'diff-mode) ++ (with-current-buffer (let ((buff (if (derived-mode-p 'diff-mode) + (car (ignore-errors + (diff-find-source-location)))))) + (if (buffer-live-p buff) buff + (current-buffer))) + ;; If user specified a file name or if this buffer knows which one to use, + ;; just use that. + (or file-name + (setq file-name (and change-log-default-name + (file-name-directory change-log-default-name) + change-log-default-name)) + (progn + ;; Chase links in the source file + ;; and use the change log in the dir where it points. + (setq file-name (or (and (or buffer-file buffer-file-name) + (file-name-directory + (file-chase-links + (or buffer-file buffer-file-name)))) + default-directory)) + (if (file-directory-p file-name) + (setq file-name (expand-file-name (change-log-name) file-name))) + ;; Chase links before visiting the file. + ;; This makes it easier to use a single change log file + ;; for several related directories. + (setq file-name (file-chase-links file-name)) + (setq file-name (expand-file-name file-name)) + ;; Move up in the dir hierarchy till we find a change log file. + (let ((file1 file-name) + parent-dir) + (while (and (not (or (get-file-buffer file1) (file-exists-p file1))) + (progn (setq parent-dir + (file-name-directory + (directory-file-name + (file-name-directory file1)))) + ;; Give up if we are already at the root dir. + (not (string= (file-name-directory file1) + parent-dir)))) + ;; Move up to the parent dir and try again. + (setq file1 (expand-file-name + (file-name-nondirectory (change-log-name)) + parent-dir))) + ;; If we found a change log in a parent, use that. + (if (or (get-file-buffer file1) (file-exists-p file1)) + (setq file-name file1))))) + ;; Make a local variable in this buffer so we needn't search again. + (set (make-local-variable 'change-log-default-name) file-name)) + file-name) + +(defun add-log-file-name (buffer-file log-file) + ;; Never want to add a change log entry for the ChangeLog file itself. + (unless (or (null buffer-file) (string= buffer-file log-file)) + (if add-log-file-name-function + (funcall add-log-file-name-function buffer-file) + (setq buffer-file + (let* ((dir (file-name-directory log-file)) + (rel (file-relative-name buffer-file dir))) + ;; Sometimes with symlinks, the two buffers may have names that + ;; appear to belong to different directory trees. So check the + ;; file-truenames, to see if we get a better result. + (if (not (string-match "\\`\\.\\./" rel)) + rel + (let ((new (file-relative-name (file-truename buffer-file) + (file-truename dir)))) + (if (< (length new) (length rel)) + new rel))))) + ;; If we have a backup file, it's presumably because we're + ;; comparing old and new versions (e.g. for deleted + ;; functions) and we'll want to use the original name. + (if (backup-file-name-p buffer-file) + (file-name-sans-versions buffer-file) + buffer-file)))) + +;;;###autoload +(defun add-change-log-entry (&optional whoami file-name other-window new-entry + put-new-entry-on-new-line) + "Find change log file, and add an entry for today and an item for this file. +Optional arg WHOAMI (interactive prefix) non-nil means prompt for user +name and email (stored in `add-log-full-name' and `add-log-mailing-address'). + +Second arg FILE-NAME is file name of the change log. +If nil, use the value of `change-log-default-name'. + +Third arg OTHER-WINDOW non-nil means visit in other window. + +Fourth arg NEW-ENTRY non-nil means always create a new entry at the front; +never append to an existing entry. Option `add-log-keep-changes-together' +otherwise affects whether a new entry is created. + +Fifth arg PUT-NEW-ENTRY-ON-NEW-LINE non-nil means that if a new +entry is created, put it on a new line by itself, do not put it +after a comma on an existing line. + +Option `add-log-always-start-new-record' non-nil means always create a +new record, even when the last record was made on the same date and by +the same person. + +The change log file can start with a copyright notice and a copying +permission notice. The first blank line indicates the end of these +notices. + +Today's date is calculated according to `add-log-time-zone-rule' if +non-nil, otherwise in local time." + (interactive (list current-prefix-arg + (prompt-for-change-log-name))) + (let* ((defun (add-log-current-defun)) + (version (and change-log-version-info-enabled + (change-log-version-number-search))) + (buf-file-name (if add-log-buffer-file-name-function + (funcall add-log-buffer-file-name-function) + buffer-file-name)) + (buffer-file (if buf-file-name (expand-file-name buf-file-name))) + (file-name (expand-file-name (find-change-log file-name buffer-file))) + ;; Set ITEM to the file name to use in the new item. + (item (add-log-file-name buffer-file file-name))) + + (unless (equal file-name buffer-file-name) + (cond + ((equal file-name (buffer-file-name (window-buffer (selected-window)))) + ;; If the selected window already shows the desired buffer don't show + ;; it again (particularly important if other-window is true). + ;; This is important for diff-add-change-log-entries-other-window. + (set-buffer (window-buffer (selected-window)))) + ((or other-window (window-dedicated-p (selected-window))) + (find-file-other-window file-name)) + (t (find-file file-name)))) + (or (derived-mode-p 'change-log-mode) + (change-log-mode)) + (undo-boundary) + (goto-char (point-min)) + + (let ((full-name (or add-log-full-name (user-full-name))) + (mailing-address (or add-log-mailing-address user-mail-address))) + + (when whoami + (setq full-name (read-string "Full name: " full-name)) + ;; Note that some sites have room and phone number fields in + ;; full name which look silly when inserted. Rather than do + ;; anything about that here, let user give prefix argument so that + ;; s/he can edit the full name field in prompter if s/he wants. + (setq mailing-address + (read-string "Mailing address: " mailing-address))) + + ;; If file starts with a copyright and permission notice, skip them. + ;; Assume they end at first blank line. + (when (looking-at "Copyright") + (search-forward "\n\n") + (skip-chars-forward "\n")) + + ;; Advance into first entry if it is usable; else make new one. + (let ((new-entries + (mapcar (lambda (addr) + (concat + (if (stringp add-log-time-zone-rule) + (let ((tz (getenv "TZ"))) + (unwind-protect + (progn + (set-time-zone-rule add-log-time-zone-rule) + (funcall add-log-time-format)) + (set-time-zone-rule tz))) + (funcall add-log-time-format)) + " " full-name + " <" addr ">")) + (if (consp mailing-address) + mailing-address + (list mailing-address))))) + (if (and (not add-log-always-start-new-record) + (let ((hit nil)) + (dolist (entry new-entries hit) + (when (looking-at (regexp-quote entry)) + (setq hit t))))) + (forward-line 1) + (insert (nth (random (length new-entries)) + new-entries) + (if use-hard-newlines hard-newline "\n") + (if use-hard-newlines hard-newline "\n")) + (forward-line -1)))) + + ;; Determine where we should stop searching for a usable + ;; item to add to, within this entry. + (let ((bound + (save-excursion + (if (looking-at "\n*[^\n* \t]") + (skip-chars-forward "\n") + (if add-log-keep-changes-together + (forward-page) ; page delimits entries for date + (forward-paragraph))) ; paragraph delimits entries for file + (point)))) + + ;; Now insert the new line for this item. + (cond ((re-search-forward "^\\s *\\*\\s *$" bound t) + ;; Put this file name into the existing empty item. + (if item + (insert item))) + ((and (not new-entry) + (let (case-fold-search) + (re-search-forward + (concat (regexp-quote (concat "* " item)) + ;; Don't accept `foo.bar' when + ;; looking for `foo': + "\\(\\s \\|[(),:]\\)") + bound t))) + ;; Add to the existing item for the same file. + (re-search-forward "^\\s *$\\|^\\s \\*") + (goto-char (match-beginning 0)) + ;; Delete excess empty lines; make just 2. + (while (and (not (eobp)) (looking-at "^\\s *$")) + (delete-region (point) (line-beginning-position 2))) + (insert (if use-hard-newlines hard-newline "\n") + (if use-hard-newlines hard-newline "\n")) + (forward-line -2) + (indent-relative-maybe)) + (t + ;; Make a new item. + (while (looking-at "\\sW") + (forward-line 1)) + (while (and (not (eobp)) (looking-at "^\\s *$")) + (delete-region (point) (line-beginning-position 2))) + (insert (if use-hard-newlines hard-newline "\n") + (if use-hard-newlines hard-newline "\n") + (if use-hard-newlines hard-newline "\n")) + (forward-line -2) + (indent-to left-margin) + (insert "* ") + (if item (insert item))))) + ;; Now insert the function name, if we have one. + ;; Point is at the item for this file, + ;; either at the end of the line or at the first blank line. + (if (not defun) + ;; No function name, so put in a colon unless we have just a star. + (unless (save-excursion + (beginning-of-line 1) + (looking-at "\\s *\\(\\*\\s *\\)?$")) + (insert ": ") + (if version (insert version ?\s))) + ;; Make it easy to get rid of the function name. + (undo-boundary) + (unless (save-excursion + (beginning-of-line 1) + (looking-at "\\s *$")) + (insert ?\s)) + ;; See if the prev function name has a message yet or not. + ;; If not, merge the two items. + (let ((pos (point-marker))) + (skip-syntax-backward " ") + (skip-chars-backward "):") + (if (and (not put-new-entry-on-new-line) + (looking-at "):") + (let ((pos (save-excursion (backward-sexp 1) (point)))) + (when (equal (buffer-substring pos (point)) defun) + (delete-region pos (point))) + (> fill-column (+ (current-column) (length defun) 4)))) + (progn (skip-chars-backward ", ") + (delete-region (point) pos) + (unless (memq (char-before) '(?\()) (insert ", "))) + (when (and (not put-new-entry-on-new-line) (looking-at "):")) + (delete-region (+ 1 (point)) (line-end-position))) + (goto-char pos) + (insert "(")) + (set-marker pos nil)) + (insert defun "): ") + (if version (insert version ?\s))))) + +;;;###autoload +(defun add-change-log-entry-other-window (&optional whoami file-name) + "Find change log file in other window and add entry and item. +This is just like `add-change-log-entry' except that it displays +the change log file in another window." + (interactive (if current-prefix-arg + (list current-prefix-arg + (prompt-for-change-log-name)))) + (add-change-log-entry whoami file-name t)) + + +(defvar change-log-indent-text 0) + +(defun change-log-fill-parenthesized-list () + ;; Fill parenthesized lists of names according to GNU standards. + ;; * file-name.ext (very-long-foo, very-long-bar, very-long-foobar): + ;; should be filled as + ;; * file-name.ext (very-long-foo, very-long-bar) + ;; (very-long-foobar): + (save-excursion + (end-of-line 0) + (skip-chars-backward " \t") + (when (and (equal (char-before) ?\,) + (> (point) (1+ (point-min)))) + (condition-case nil + (when (save-excursion + (and (prog2 + (up-list -1) + (equal (char-after) ?\() + (skip-chars-backward " \t")) + (or (bolp) + ;; Skip everything but a whitespace or asterisk. + (and (not (zerop (skip-chars-backward "^ \t\n*"))) + (skip-chars-backward " \t") + ;; We want one asterisk here. + (= (skip-chars-backward "*") -1) + (skip-chars-backward " \t") + (bolp))))) + ;; Delete the comma. + (delete-char -1) + ;; Close list on previous line. + (insert ")") + (skip-chars-forward " \t\n") + ;; Start list on new line. + (insert-before-markers "(")) + (error nil))))) + +(defun change-log-indent () + (change-log-fill-parenthesized-list) + (let* ((indent + (save-excursion + (beginning-of-line) + (skip-chars-forward " \t") + (cond + ((and (looking-at "\\(.*\\) [^ \n].*[^ \n] <.*>\\(?: +(.*)\\)? *$") + ;; Matching the output of add-log-time-format is difficult, + ;; but I'll get it has at least two adjacent digits. + (string-match "[[:digit:]][[:digit:]]" (match-string 1))) + 0) + ((looking-at "[^*(]") + (+ (current-left-margin) change-log-indent-text)) + (t (current-left-margin))))) + (pos (save-excursion (indent-line-to indent) (point)))) + (if (> pos (point)) (goto-char pos)))) + + +(defvar smerge-resolve-function) +(defvar copyright-at-end-flag) + +;;;###autoload +(define-derived-mode change-log-mode text-mode "Change Log" + "Major mode for editing change logs; like Indented Text mode. +Prevents numeric backups and sets `left-margin' to 8 and `fill-column' to 74. +New log entries are usually made with \\[add-change-log-entry] or \\[add-change-log-entry-other-window]. +Each entry behaves as a paragraph, and the entries for one day as a page. +Runs `change-log-mode-hook'. +\n\\{change-log-mode-map}" + (setq left-margin 8 + fill-column 74 + indent-tabs-mode t + tab-width 8 + show-trailing-whitespace t) + (set (make-local-variable 'fill-forward-paragraph-function) + 'change-log-fill-forward-paragraph) + ;; Make sure we call `change-log-indent' when filling. + (set (make-local-variable 'fill-indent-according-to-mode) t) + ;; Avoid that filling leaves behind a single "*" on a line. + (add-hook 'fill-nobreak-predicate + '(lambda () + (looking-back "^\\s *\\*\\s *" (line-beginning-position))) + nil t) + (set (make-local-variable 'indent-line-function) 'change-log-indent) + (set (make-local-variable 'tab-always-indent) nil) + (set (make-local-variable 'copyright-at-end-flag) t) + ;; We really do want "^" in paragraph-start below: it is only the + ;; lines that begin at column 0 (despite the left-margin of 8) that + ;; we are looking for. Adding `* ' allows eliding the blank line + ;; between entries for different files. + (set (make-local-variable 'paragraph-start) "\\s *$\\|\f\\|^\\<") + (set (make-local-variable 'paragraph-separate) paragraph-start) + ;; Match null string on the date-line so that the date-line + ;; is grouped with what follows. + (set (make-local-variable 'page-delimiter) "^\\<\\|^\f") + (set (make-local-variable 'version-control) 'never) + (set (make-local-variable 'smerge-resolve-function) + 'change-log-resolve-conflict) + (set (make-local-variable 'adaptive-fill-regexp) "\\s *") + (set (make-local-variable 'font-lock-defaults) + '(change-log-font-lock-keywords t nil nil backward-paragraph)) + (set (make-local-variable 'multi-isearch-next-buffer-function) + 'change-log-next-buffer) + (set (make-local-variable 'beginning-of-defun-function) + 'change-log-beginning-of-defun) + (set (make-local-variable 'end-of-defun-function) + 'change-log-end-of-defun) + ;; next-error function glue + (setq next-error-function 'change-log-next-error) + (setq next-error-last-buffer (current-buffer))) + +(defun change-log-next-buffer (&optional buffer wrap) + "Return the next buffer in the series of ChangeLog file buffers. +This function is used for multiple buffers isearch. +A sequence of buffers is formed by ChangeLog files with decreasing +numeric file name suffixes in the directory of the initial ChangeLog +file were isearch was started." + (let* ((name (change-log-name)) + (files (cons name (sort (file-expand-wildcards + (concat name "[-.][0-9]*")) + (lambda (a b) + ;; The file's extension may not have a valid + ;; version form (e.g. VC backup revisions). + (ignore-errors + (version< (substring b (length name)) + (substring a (length name)))))))) + (files (if isearch-forward files (reverse files)))) + (find-file-noselect + (if wrap + (car files) + (cadr (member (file-name-nondirectory (buffer-file-name buffer)) + files)))))) + +(defun change-log-fill-forward-paragraph (n) + "Cut paragraphs so filling preserves open parentheses at beginning of lines." + (let (;; Add lines starting with whitespace followed by a left paren or an + ;; asterisk. + (paragraph-start (concat paragraph-start "\\|\\s *\\(?:\\s(\\|\\*\\)"))) + (forward-paragraph n))) + +(defcustom add-log-current-defun-header-regexp + "^\\([[:upper:]][[:upper:]_ ]*[[:upper:]_]\\|[-_[:alpha:]]+\\)[ \t]*[:=]" + "Heuristic regexp used by `add-log-current-defun' for unknown major modes. +The regexp's first submatch is placed in the ChangeLog entry, in +parentheses." + :type 'regexp + :group 'change-log) + +;;;###autoload +(defvar add-log-lisp-like-modes + '(emacs-lisp-mode lisp-mode scheme-mode dsssl-mode lisp-interaction-mode) + "*Modes that look like Lisp to `add-log-current-defun'.") + +;;;###autoload +(defvar add-log-c-like-modes + '(c-mode c++-mode c++-c-mode objc-mode) + "*Modes that look like C to `add-log-current-defun'.") + +;;;###autoload +(defvar add-log-tex-like-modes + '(TeX-mode plain-TeX-mode LaTeX-mode tex-mode) + "*Modes that look like TeX to `add-log-current-defun'.") + +(declare-function c-cpp-define-name "cc-cmds" ()) +(declare-function c-defun-name "cc-cmds" ()) + +;;;###autoload +(defun add-log-current-defun () + "Return name of function definition point is in, or nil. + +Understands C, Lisp, LaTeX (\"functions\" are chapters, sections, ...), +Texinfo (@node titles) and Perl. + +Other modes are handled by a heuristic that looks in the 10K before +point for uppercase headings starting in the first column or +identifiers followed by `:' or `='. See variables +`add-log-current-defun-header-regexp' and +`add-log-current-defun-function'. + +Has a preference of looking backwards." + (condition-case nil + (save-excursion + (let ((location (point))) + (cond (add-log-current-defun-function + (funcall add-log-current-defun-function)) + ((apply 'derived-mode-p add-log-lisp-like-modes) + ;; If we are now precisely at the beginning of a defun, + ;; make sure beginning-of-defun finds that one + ;; rather than the previous one. + (or (eobp) (forward-char 1)) + (beginning-of-defun) + ;; Make sure we are really inside the defun found, + ;; not after it. + (when (and (looking-at "\\s(") + (progn (end-of-defun) + (< location (point))) + (progn (forward-sexp -1) + (>= location (point)))) + (if (looking-at "\\s(") + (forward-char 1)) + ;; Skip the defining construct name, typically "defun" + ;; or "defvar". + (forward-sexp 1) + ;; The second element is usually a symbol being defined. + ;; If it is not, use the first symbol in it. + (skip-chars-forward " \t\n'(") + (buffer-substring-no-properties (point) + (progn (forward-sexp 1) + (point))))) + ((apply 'derived-mode-p add-log-c-like-modes) + (or (c-cpp-define-name) + (c-defun-name))) - ((memq major-mode add-log-tex-like-modes) ++ ((apply #'derived-mode-p add-log-tex-like-modes) + (if (re-search-backward + "\\\\\\(sub\\)*\\(section\\|paragraph\\|chapter\\)" + nil t) + (progn + (goto-char (match-beginning 0)) + (buffer-substring-no-properties + (1+ (point)) ; without initial backslash + (line-end-position))))) + ((derived-mode-p 'texinfo-mode) + (if (re-search-backward "^@node[ \t]+\\([^,\n]+\\)" nil t) + (match-string-no-properties 1))) + ((derived-mode-p 'perl-mode 'cperl-mode) + (if (re-search-backward "^sub[ \t]+\\([^({ \t\n]+\\)" nil t) + (match-string-no-properties 1))) + ;; Emacs's autoconf-mode installs its own + ;; `add-log-current-defun-function'. This applies to + ;; a different mode apparently for editing .m4 + ;; autoconf source. + ((derived-mode-p 'autoconf-mode) + (if (re-search-backward + "^\\(\\(m4_\\)?define\\|A._DEFUN\\)(\\[?\\([A-Za-z0-9_]+\\)" nil t) + (match-string-no-properties 3))) + (t + ;; If all else fails, try heuristics + (let (case-fold-search + result) + (end-of-line) + (when (re-search-backward + add-log-current-defun-header-regexp + (- (point) 10000) + t) + (setq result (or (match-string-no-properties 1) + (match-string-no-properties 0))) + ;; Strip whitespace away + (when (string-match "\\([^ \t\n\r\f].*[^ \t\n\r\f]\\)" + result) + (setq result (match-string-no-properties 1 result))) + result)))))) + (error nil))) + +(defvar change-log-get-method-definition-md) + +;; Subroutine used within change-log-get-method-definition. +;; Add the last match in the buffer to the end of `md', +;; followed by the string END; move to the end of that match. +(defun change-log-get-method-definition-1 (end) + (setq change-log-get-method-definition-md + (concat change-log-get-method-definition-md + (match-string 1) + end)) + (goto-char (match-end 0))) + +(defun change-log-get-method-definition () +"For Objective C, return the method name if we are in a method." + (let ((change-log-get-method-definition-md "[")) + (save-excursion + (if (re-search-backward "^@implementation\\s-*\\([A-Za-z_]*\\)" nil t) + (change-log-get-method-definition-1 " "))) + (save-excursion + (cond + ((re-search-forward "^\\([-+]\\)[ \t\n\f\r]*\\(([^)]*)\\)?\\s-*" nil t) + (change-log-get-method-definition-1 "") + (while (not (looking-at "[{;]")) + (looking-at + "\\([A-Za-z_]*:?\\)\\s-*\\(([^)]*)\\)?[A-Za-z_]*[ \t\n\f\r]*") + (change-log-get-method-definition-1 "")) + (concat change-log-get-method-definition-md "]")))))) + +(autoload 'timezone-make-date-sortable "timezone") + +(defun change-log-sortable-date-at () + "Return date of log entry in a consistent form for sorting. +Point is assumed to be at the start of the entry." + (if (looking-at change-log-start-entry-re) + (let ((date (match-string-no-properties 0))) + (if date + (if (string-match "\\(....\\)-\\(..\\)-\\(..\\)\\s-+" date) + (concat (match-string 1 date) (match-string 2 date) + (match-string 3 date)) + (ignore-errors (timezone-make-date-sortable date))))) + (error "Bad date"))) + +(defun change-log-resolve-conflict () + "Function to be used in `smerge-resolve-function'." + (save-excursion + (save-restriction + (narrow-to-region (match-beginning 0) (match-end 0)) + (let ((mb1 (match-beginning 1)) + (me1 (match-end 1)) + (mb3 (match-beginning 3)) + (me3 (match-end 3)) + (tmp1 (generate-new-buffer " *changelog-resolve-1*")) + (tmp2 (generate-new-buffer " *changelog-resolve-2*"))) + (unwind-protect + (let ((buf (current-buffer))) + (with-current-buffer tmp1 + (change-log-mode) + (insert-buffer-substring buf mb1 me1)) + (with-current-buffer tmp2 + (change-log-mode) + (insert-buffer-substring buf mb3 me3) + ;; Do the merge here instead of inside `buf' so as to be + ;; more robust in case change-log-merge fails. + (change-log-merge tmp1)) + (goto-char (point-max)) + (delete-region (point-min) + (prog1 (point) + (insert-buffer-substring tmp2)))) + (kill-buffer tmp1) + (kill-buffer tmp2)))))) + +;;;###autoload +(defun change-log-merge (other-log) + "Merge the contents of change log file OTHER-LOG with this buffer. +Both must be found in Change Log mode (since the merging depends on +the appropriate motion commands). OTHER-LOG can be either a file name +or a buffer. + +Entries are inserted in chronological order. Both the current and +old-style time formats for entries are supported." + (interactive "*fLog file name to merge: ") + (if (not (derived-mode-p 'change-log-mode)) + (error "Not in Change Log mode")) + (let ((other-buf (if (bufferp other-log) other-log + (find-file-noselect other-log))) + (buf (current-buffer)) + date1 start end) + (save-excursion + (goto-char (point-min)) + (set-buffer other-buf) + (goto-char (point-min)) + (if (not (derived-mode-p 'change-log-mode)) + (error "%s not found in Change Log mode" other-log)) + ;; Loop through all the entries in OTHER-LOG. + (while (not (eobp)) + (setq date1 (change-log-sortable-date-at)) + (setq start (point) + end (progn (forward-page) (point))) + ;; Look for an entry in original buffer that isn't later. + (with-current-buffer buf + (while (and (not (eobp)) + (string< date1 (change-log-sortable-date-at))) + (forward-page)) + (if (not (eobp)) + (insert-buffer-substring other-buf start end) + ;; At the end of the original buffer, insert a newline to + ;; separate entries and then the rest of the file being + ;; merged. + (unless (or (bobp) + (and (= ?\n (char-before)) + (or (<= (1- (point)) (point-min)) + (= ?\n (char-before (1- (point))))))) + (insert (if use-hard-newlines hard-newline "\n"))) + ;; Move to the end of it to terminate outer loop. + (with-current-buffer other-buf + (goto-char (point-max))) + (insert-buffer-substring other-buf start))))))) + +(defun change-log-beginning-of-defun () + (re-search-backward change-log-start-entry-re nil 'move)) + +(defun change-log-end-of-defun () + ;; Look back and if there is no entry there it means we are before + ;; the first ChangeLog entry, so go forward until finding one. + (unless (save-excursion (re-search-backward change-log-start-entry-re nil t)) + (re-search-forward change-log-start-entry-re nil t)) + + ;; In case we are at the end of log entry going forward a line will + ;; make us find the next entry when searching. If we are inside of + ;; an entry going forward a line will still keep the point inside + ;; the same entry. + (forward-line 1) + + ;; In case we are at the beginning of an entry, move past it. + (when (looking-at change-log-start-entry-re) + (goto-char (match-end 0)) + (forward-line 1)) + + ;; Search for the start of the next log entry. Go to the end of the + ;; buffer if we could not find a next entry. + (when (re-search-forward change-log-start-entry-re nil 'move) + (goto-char (match-beginning 0)) + (forward-line -1))) + +(provide 'add-log) + +;; arch-tag: 81eee6fc-088f-4372-a37f-80ad9620e762 +;;; add-log.el ends here diff --cc src/ChangeLog index 2d46e42e17b,391dc3eaa07..359869027dc --- a/src/ChangeLog +++ b/src/ChangeLog @@@ -1,46 -1,15 +1,58 @@@ + 2010-10-31 Chong Yidong + + * xterm.c (x_connection_closed): Print informative error message + when aborting on GTK. This requires using shut_down_emacs + directly instead of Fkill_emacs. + -2010-10-25 Michael Albinus ++2010-10-31 Michael Albinus + + * dbusbind.c (Fdbus_call_method_asynchronously) + (Fdbus_register_signal, Fdbus_register_method): Check, whether + `dbus-registered-objects-table' is initialized. + +2010-10-29 Eli Zaretskii + + * emacs.c (main): Call syms_of_filelock unconditionally. + + * filelock.c (syms_of_filelock): Move out of #ifdef CLASH_DETECTION + clause, but keep part of it conditioned on CLASH_DETECTION. + +2010-10-29 Glenn Morris + + * nsfns.m (Fx-display-save-under, Fx-open-connection) + (Fxw-color-defined-p, Fxw-display-color-p, Fx-show-tip): + * w32fns.c (Fxw_color_defined_p, Fx_open_connection): + * xfns.c (Fxw_color_defined_p, Fx_open_connection): + Sync docs between X, W32, NS. + + * buffer.c (syms_of_buffer) : + * frame.c (syms_of_frame) : Move doc here from Lisp. + +2010-10-26 Juanma Barranquero + + * eval.c (init_eval_once): Set max_lisp_eval_depth to 600; + otherwise, bootstrapping on Windows fails to compile macroexp.el. + +2010-10-26 Eli Zaretskii + + * cmds.c (internal_self_insert): Don't insert if argument N is + zero or negative. (Bug#7281) + +2010-10-26 Jan Djärv + + * gtkutil.c (qttip_cb): Set title to empty for ATK (Bug#7278). + +2010-10-25 Glenn Morris + + * Makefile.in (SOME_MACHINE_LISP): Remove easymenu.elc. + +2010-10-24 Glenn Morris + + * w32fns.c (Fx_synchronize, Fx_change_window_property) + (Fx_window_property, Fx_file_dialog): + * xfns.c (Fx_synchronize, Fx_change_window_property) + (Fx_window_property, Fx_file_dialog): Sync docs between w32 and X. + 2010-10-24 Chong Yidong * xterm.c (x_connection_closed): Kill Emacs unconditionally. diff --cc src/dbusbind.c index 683b7cb583b,37bfbf4badf..beb1faaf4aa --- a/src/dbusbind.c +++ b/src/dbusbind.c @@@ -1232,8 -1175,12 +1232,12 @@@ usage: (dbus-call-method-asynchronousl SDATA (interface), SDATA (method)); + /* Check dbus-registered-objects-table. */ + if (!HASH_TABLE_P (Vdbus_registered_objects_table)) + XD_SIGNAL1 (build_string ("dbus.el is not loaded")); + /* Open a connection to the bus. */ - connection = xd_initialize (bus); + connection = xd_initialize (bus, TRUE); /* Create the message. */ dmessage = dbus_message_new_method_call (SDATA (service), @@@ -1981,8 -1984,12 +1989,12 @@@ used for composing the returning D-Bus /* TODO: We must check for a valid service name, otherwise there is a segmentation fault. */ + /* Check dbus-registered-objects-table. */ + if (!HASH_TABLE_P (Vdbus_registered_objects_table)) + XD_SIGNAL1 (build_string ("dbus.el is not loaded")); + /* Open a connection to the bus. */ - connection = xd_initialize (bus); + connection = xd_initialize (bus, TRUE); /* Request the known name from the bus. We can ignore the result, it is set to -1 if there is an error - kind of redundancy. */