Now on revision 113311. ------------------------------------------------------------ revno: 113311 author: Gnus developers committer: Katsumi Yamaoka branch nick: trunk timestamp: Sat 2013-07-06 23:40:56 +0000 message: Merge changes made in Gnus master 2013-07-06 Lars Ingebrigtsen * gnus.texi (Group Parameters): Mention regexp substitutions (bug#11688). 2013-07-06 Nathan Trapuzzano (tiny change) * gnus.texi (Generic Marking Commands): Fix grammar (bug#13368). 2013-07-06 Lars Ingebrigtsen * gnus.texi (Emacsen): Fix version. * gnus-faq.texi (FAQ 1-6): Mention the correct Emacs version. 2013-07-06 Lars Ingebrigtsen * gnus-art.el (gnus-block-private-groups): Allow `global' methods to display images. * gnus.el (gnus-valid-select-methods): Mark nnrss as global. * message.el (message-cancel-news): According to , "cancel" is preferred over "cmsg cancel" in the Subject. * nnir.el (nnir-engines): Note that the group specs are regexps (bug#13238). * gnus-msg.el (gnus-copy-article-buffer): If the article buffer has gotten read-only text properties, ensure that those aren't heeded when copying stuff over (bug#13434). * mm-view.el (mm-inline-text-html): Don't bug out on multipart messages (bug#13762). diff: === modified file 'doc/misc/ChangeLog' --- doc/misc/ChangeLog 2013-07-06 01:39:21 +0000 +++ doc/misc/ChangeLog 2013-07-06 23:40:56 +0000 @@ -1,3 +1,18 @@ +2013-07-06 Lars Ingebrigtsen + + * gnus.texi (Group Parameters): Mention regexp + substitutions (bug#11688). + +2013-07-06 Nathan Trapuzzano (tiny change) + + * gnus.texi (Generic Marking Commands): Fix grammar (bug#13368). + +2013-07-06 Lars Ingebrigtsen + + * gnus.texi (Emacsen): Fix version. + + * gnus-faq.texi (FAQ 1-6): Mention the correct Emacs version. + 2013-07-06 Glenn Morris * mh-e.texi: Fix external links. === modified file 'doc/misc/gnus-faq.texi' --- doc/misc/gnus-faq.texi 2013-07-06 01:39:21 +0000 +++ doc/misc/gnus-faq.texi 2013-07-06 23:40:56 +0000 @@ -222,10 +222,9 @@ @subsubheading Answer -Gnus 5.10 requires an Emacs version that is greater than or equal -to Emacs 20.7 or XEmacs 21.1. -The development versions of Gnus (aka No Gnus) requires Emacs 21 -or XEmacs 21.4. +Gnus 5.13 requires an Emacs version that is greater than or equal +to Emacs 23.1 or XEmacs 21.1, although there are some features that +only work on Emacs 24. @node FAQ 1-7 @subsubheading Question 1.7 === modified file 'doc/misc/gnus.texi' --- doc/misc/gnus.texi 2013-07-06 01:39:21 +0000 +++ doc/misc/gnus.texi 2013-07-06 23:40:56 +0000 @@ -3091,6 +3091,12 @@ @} @end example +You can also use regexp expansions in the rules: + +@example +(sieve header :regex "list-id" "") +@end example + See @pxref{Sieve Commands} for commands and variables that might be of interest in relation to the sieve parameter. @@ -6380,10 +6386,10 @@ @node Generic Marking Commands @subsection Generic Marking Commands -Some people would like the command that ticks an article (@kbd{!}) go to -the next article. Others would like it to go to the next unread -article. Yet others would like it to stay on the current article. And -even though I haven't heard of anybody wanting it to go to the +Some people would like the command that ticks an article (@kbd{!}) to +go to the next article. Others would like it to go to the next unread +article. Yet others would like it to stay on the current article. +And even though I haven't heard of anybody wanting it to go to the previous (unread) article, I'm sure there are people that want that as well. @@ -26575,7 +26581,7 @@ @itemize @bullet @item -Emacs 21.1 and up. +Emacs 23.1 and up. @item XEmacs 21.4 and up. === modified file 'lisp/gnus/ChangeLog' --- lisp/gnus/ChangeLog 2013-07-06 12:49:38 +0000 +++ lisp/gnus/ChangeLog 2013-07-06 23:40:56 +0000 @@ -1,3 +1,24 @@ +2013-07-06 Lars Ingebrigtsen + + * gnus-art.el (gnus-block-private-groups): Allow `global' methods to + display images. + + * gnus.el (gnus-valid-select-methods): Mark nnrss as global. + + * message.el (message-cancel-news): According to + , "cancel" is + preferred over "cmsg cancel" in the Subject. + + * nnir.el (nnir-engines): Note that the group specs are regexps + (bug#13238). + + * gnus-msg.el (gnus-copy-article-buffer): If the article buffer has + gotten read-only text properties, ensure that those aren't heeded when + copying stuff over (bug#13434). + + * mm-view.el (mm-inline-text-html): Don't bug out on multipart messages + (bug#13762). + 2013-07-05 David Kastrup * auth-source.el (auth-source-netrc-parse-one): Allow empty strings in === modified file 'lisp/gnus/gnus-art.el' --- lisp/gnus/gnus-art.el 2013-06-28 08:03:21 +0000 +++ lisp/gnus/gnus-art.el 2013-07-06 23:40:56 +0000 @@ -6947,7 +6947,8 @@ (set-buffer buf)))))) (defun gnus-block-private-groups (group) - (if (gnus-news-group-p group) + (if (or (gnus-news-group-p group) + (gnus-member-of-valid 'global group)) ;; Block nothing in news groups. nil ;; Block everything anywhere else. === modified file 'lisp/gnus/gnus-msg.el' --- lisp/gnus/gnus-msg.el 2013-04-26 02:08:43 +0000 +++ lisp/gnus/gnus-msg.el 2013-07-06 23:40:56 +0000 @@ -920,6 +920,7 @@ (with-current-buffer article-buffer (let ((gnus-newsgroup-charset (or gnus-article-charset gnus-newsgroup-charset)) + (inhibit-read-only t) (gnus-newsgroup-ignored-charsets (or gnus-article-ignored-charsets gnus-newsgroup-ignored-charsets))) === modified file 'lisp/gnus/gnus.el' --- lisp/gnus/gnus.el 2013-07-02 10:38:58 +0000 +++ lisp/gnus/gnus.el 2013-07-06 23:40:56 +0000 @@ -1628,7 +1628,7 @@ ("nnfolder" mail respool address) ("nngateway" post-mail address prompt-address physical-address) ("nnweb" none) - ("nnrss" none) + ("nnrss" none global) ("nnagent" post-mail) ("nnimap" post-mail address prompt-address physical-address respool server-marks) === modified file 'lisp/gnus/message.el' --- lisp/gnus/message.el 2013-05-19 22:50:16 +0000 +++ lisp/gnus/message.el 2013-07-06 23:40:56 +0000 @@ -7145,7 +7145,7 @@ (erase-buffer) (insert "Newsgroups: " newsgroups "\n" "From: " from "\n" - "Subject: cmsg cancel " message-id "\n" + "Subject: cancel " message-id "\n" "Control: cancel " message-id "\n" (if distribution (concat "Distribution: " distribution "\n") === modified file 'lisp/gnus/mm-view.el' --- lisp/gnus/mm-view.el 2013-06-10 05:17:51 +0000 +++ lisp/gnus/mm-view.el 2013-07-06 23:40:56 +0000 @@ -419,16 +419,18 @@ (buffer-string))))) (defun mm-inline-text-html (handle) - (let* ((func mm-text-html-renderer) - (entry (assq func mm-text-html-renderer-alist)) - (inhibit-read-only t)) - (if entry - (setq func (cdr entry))) - (cond - ((functionp func) - (funcall func handle)) - (t - (apply (car func) handle (cdr func)))))) + (if (stringp (car handle)) + (mapcar 'mm-inline-text-html (cdr handle)) + (let* ((func mm-text-html-renderer) + (entry (assq func mm-text-html-renderer-alist)) + (inhibit-read-only t)) + (if entry + (setq func (cdr entry))) + (cond + ((functionp func) + (funcall func handle)) + (t + (apply (car func) handle (cdr func))))))) (defun mm-inline-text-vcard (handle) (let ((inhibit-read-only t)) === modified file 'lisp/gnus/nnir.el' --- lisp/gnus/nnir.el 2013-07-02 10:38:58 +0000 +++ lisp/gnus/nnir.el 2013-07-06 23:40:56 +0000 @@ -548,15 +548,15 @@ (gmane nnir-run-gmane ((gmane-author . "Gmane Author: "))) (swish++ nnir-run-swish++ - ((swish++-group . "Swish++ Group spec: "))) + ((swish++-group . "Swish++ Group spec (regexp): "))) (swish-e nnir-run-swish-e - ((swish-e-group . "Swish-e Group spec: "))) + ((swish-e-group . "Swish-e Group spec (regexp): "))) (namazu nnir-run-namazu ()) (notmuch nnir-run-notmuch ()) (hyrex nnir-run-hyrex - ((hyrex-group . "Hyrex Group spec: "))) + ((hyrex-group . "Hyrex Group spec (regexp): "))) (find-grep nnir-run-find-grep ((grep-options . "Grep options: ")))) "Alist of supported search engines. ------------------------------------------------------------ revno: 113310 committer: Glenn Morris branch nick: trunk timestamp: Sat 2013-07-06 12:17:22 -0700 message: * etc/NEWS: Tweak +++/--- description diff: === modified file 'etc/NEWS' --- etc/NEWS 2013-07-06 09:37:29 +0000 +++ etc/NEWS 2013-07-06 19:17:22 +0000 @@ -15,10 +15,10 @@ with a prefix argument or by typing C-u C-h C-n. Temporary note: -+++ indicates that the appropriate manual has already been updated. ---- means no change in the manuals is called for. -When you add a new item, please add it without either +++ or --- -so we will look at it and add it to the manual. ++++ indicates that all necessary updates to the manuals in doc/ are complete. +--- means no change in the manuals is needed. +When you add a new item, use the appropriate mark if you know it applies, +otherwise leave it unmarked. * Installation Changes in Emacs 24.4 ------------------------------------------------------------ revno: 113309 committer: Glenn Morris branch nick: trunk timestamp: Sat 2013-07-06 11:28:54 -0700 message: * admin.el (make-manuals): Add the option to only make certain output types. (manual-misc-html): Special-case ccmode and efaq. (manual-html-mono, manual-html-node, manual-pdf, manual-ps): Move creation of output directory here from make-manuals. (manual-html-fix-index-2): Avoid dynamic reference to `f'. diff: === modified file 'admin/ChangeLog' --- admin/ChangeLog 2013-07-06 02:32:13 +0000 +++ admin/ChangeLog 2013-07-06 18:28:54 +0000 @@ -2,6 +2,11 @@ * admin.el (manual-misc-manuals): New function. (make-manuals): Avoid hard-coding list of misc manuals. + Add the option to only make certain type(s) of output. + (manual-misc-html): Special-case ccmode and efaq. + (manual-html-mono, manual-html-node, manual-pdf, manual-ps): + Move creation of output directory here from make-manuals. + (manual-html-fix-index-2): Avoid dynamic reference to `f'. 2013-07-05 Glenn Morris === modified file 'admin/admin.el' --- admin/admin.el 2013-07-06 02:32:13 +0000 +++ admin/admin.el 2013-07-06 18:28:54 +0000 @@ -209,44 +209,66 @@ "\\(\\\\\\|\\.info\\)" "" (buffer-substring start (point))))))) -(defun make-manuals (root) - "Generate the web manuals for the Emacs webpage." - (interactive "DEmacs root directory: ") +(defun make-manuals (root &optional type) + "Generate the web manuals for the Emacs webpage. +Interactively with a prefix argument, prompt for TYPE. +Optional argument TYPE is type of output (nil means all)." + (interactive (let ((root (read-directory-name "Emacs root directory: " + source-directory nil t))) + (list root + (if current-prefix-arg + (completing-read + "Type: " + (append + '("misc" "pdf" "ps") + (let (res) + (dolist (i '("emacs" "elisp" "eintr") res) + (dolist (j '("" "-mono" "-node" "-ps" "-pdf")) + (push (concat i j) res)))) + (manual-misc-manuals root))))))) (let* ((dest (expand-file-name "manual" root)) (html-node-dir (expand-file-name "html_node" dest)) (html-mono-dir (expand-file-name "html_mono" dest)) (ps-dir (expand-file-name "ps" dest)) - (pdf-dir (expand-file-name "pdf" dest))) + (pdf-dir (expand-file-name "pdf" dest)) + (emacs (expand-file-name "doc/emacs/emacs.texi" root)) + (elisp (expand-file-name "doc/lispref/elisp.texi" root)) + (eintr (expand-file-name "doc/lispintro/emacs-lisp-intro.texi" root)) + (misc (manual-misc-manuals root))) + ;; TODO this makes it non-continuable. + ;; Instead, delete the individual dest directory each time. (when (file-directory-p dest) - (if (y-or-n-p (format "Directory %s exists, delete it first?" dest)) + (if (y-or-n-p (format "Directory %s exists, delete it first? " dest)) (delete-directory dest t) - (error "Aborted"))) - (make-directory dest) - (make-directory html-node-dir) - (make-directory html-mono-dir) - (make-directory ps-dir) - (make-directory pdf-dir) - ;; Emacs manual - (let ((texi (expand-file-name "doc/emacs/emacs.texi" root))) - (manual-html-node texi (expand-file-name "emacs" html-node-dir)) - (manual-html-mono texi (expand-file-name "emacs.html" html-mono-dir)) - (manual-pdf texi (expand-file-name "emacs.pdf" pdf-dif)) - (manual-ps texi (expand-file-name "emacs.ps" ps-dir))) - ;; Lisp manual - (let ((texi (expand-file-name "doc/lispref/elisp.texi" root))) - (manual-html-node texi (expand-file-name "elisp" html-node-dir)) - (manual-html-mono texi (expand-file-name "elisp.html" html-mono-dir)) - (manual-pdf texi (expand-file-name "elisp.pdf" pdf-dir)) - (manual-ps texi (expand-file-name "elisp.ps" ps-dir))) - ;; Lisp intro. - (let ((texi (expand-file-name "doc/lispintro/emacs-lisp-intro.texi" root))) - (manual-html-node texi (expand-file-name "eintr" html-node-dir)) - (manual-html-mono texi (expand-file-name "eintr.html" html-mono-dir)) - (manual-pdf texi (expand-file-name "eintr.pdf" pdf-dir)) - (manual-ps texi (expand-file-name "eintr.ps" ps-dir))) + (user-error "Aborted"))) + (if (member type '(nil "emacs" "emacs-node")) + (manual-html-node emacs (expand-file-name "emacs" html-node-dir))) + (if (member type '(nil "emacs" "emacs-mono")) + (manual-html-mono emacs (expand-file-name "emacs.html" html-mono-dir))) + (if (member type '(nil "emacs" "emacs-pdf" "pdf")) + (manual-pdf emacs (expand-file-name "emacs.pdf" pdf-dir))) + (if (member type '(nil "emacs" "emacs-ps" "ps")) + (manual-ps emacs (expand-file-name "emacs.ps" ps-dir))) + (if (member type '(nil "elisp" "elisp-node")) + (manual-html-node elisp (expand-file-name "elisp" html-node-dir))) + (if (member type '(nil "elisp" "elisp-mono")) + (manual-html-mono elisp (expand-file-name "elisp.html" html-mono-dir))) + (if (member type '(nil "elisp" "elisp-pdf" "pdf")) + (manual-pdf elisp (expand-file-name "elisp.pdf" pdf-dir))) + (if (member type '(nil "elisp" "elisp-ps" "ps")) + (manual-ps elisp (expand-file-name "elisp.ps" ps-dir))) + (if (member type '(nil "eintr" "eintr-node")) + (manual-html-node eintr (expand-file-name "eintr" html-node-dir))) + (if (member type '(nil "eintr" "eintr-node")) + (manual-html-mono eintr (expand-file-name "eintr.html" html-mono-dir))) + (if (member type '(nil "eintr" "eintr-pdf" "pdf")) + (manual-pdf eintr (expand-file-name "eintr.pdf" pdf-dir))) + (if (member type '(nil "eintr" "eintr-ps" "ps")) + (manual-ps eintr (expand-file-name "eintr.ps" ps-dir))) ;; Misc manuals - (dolist (manual (manual-misc-manuals root)) - (manual-misc-html manual root html-node-dir html-mono-dir)) + (dolist (manual misc) + (if (member type `(nil ,manual "misc")) + (manual-misc-html manual root html-node-dir html-mono-dir))) (message "Manuals created in %s" dest))) (defconst manual-doctype-string @@ -264,7 +286,12 @@ @import url('/s/emacs/manual.css');\n\n") (defun manual-misc-html (name root html-node-dir html-mono-dir) - (let ((texi (expand-file-name (format "doc/misc/%s.texi" name) root))) + ;; Hack to deal with the cases where .texi creates a different .info. + ;; Blech. TODO Why not just rename the .texi files? + (let* ((texiname (cond ((equal name "ccmode") "cc-mode") + ((equal name "efaq") "faq") + (t name))) + (texi (expand-file-name (format "doc/misc/%s.texi" texiname) root))) (manual-html-node texi (expand-file-name name html-node-dir)) (manual-html-mono texi (expand-file-name (concat name ".html") html-mono-dir)))) @@ -274,6 +301,7 @@ This function also edits the HTML files so that they validate as HTML 4.01 Transitional, and pulls in the gnu.org stylesheet using the @import directive." + (make-directory (or (file-name-directory dest) ".") t) (call-process "makeinfo" nil nil nil "-D" "WWW_GNU_ORG" "-I" (expand-file-name "../emacs" @@ -300,6 +328,7 @@ the @import directive." (unless (file-exists-p texi-file) (error "Manual file %s not found" texi-file)) + (make-directory dir t) (call-process "makeinfo" nil nil nil "-D" "WWW_GNU_ORG" "-I" (expand-file-name "../emacs" @@ -336,6 +365,7 @@ (defun manual-pdf (texi-file dest) "Run texi2pdf on TEXI-FILE, emitting pdf output to DEST." + (make-directory (or (file-name-directory dest) ".") t) (let ((default-directory (file-name-directory texi-file))) (call-process "texi2pdf" nil nil nil "-I" "../emacs" "-I" "../misc" @@ -343,6 +373,7 @@ (defun manual-ps (texi-file dest) "Generate a PostScript version of TEXI-FILE as DEST." + (make-directory (or (file-name-directory dest) ".") t) (let ((dvi-dest (concat (file-name-sans-extension dest) ".dvi")) (default-directory (file-name-directory texi-file))) (call-process "texi2dvi" nil nil nil @@ -454,7 +485,8 @@ (setq done t)) (t (if (eobp) - (error "Parse error in %s" f)) ; f is bound in manual-html-node + (error "Parse error in %s" + (file-name-nondirectory buffer-file-name))) (unless open-td (setq done t)))) (forward-line 1)))) ------------------------------------------------------------ revno: 113308 fixes bug: http://debbugs.gnu.org/14578 committer: Jan D. branch nick: trunk timestamp: Sat 2013-07-06 19:58:41 +0200 message: * lisp/files.el (write-file): Do not display confirm dialog for NS, it does its own dialog, which can't be cancelled. * src/nsfns.m: Remove panelOK. (ns_fd_data): New. (ns_run_file_dialog): New function. (Fns_read_file_name): Fill in ns_fd_data, post an event and start the event loop, so file dialog is popped up by ns_run_file_dialog, called by sendEvent (Bug#14578). (EmacsSavePanel, EmacsOpenPanel): Remove ok and cancel methods. * src/nsterm.h (NSSavePanel): Update comment. (NSAPP_DATA2_RUNFILEDIALOG): Define. (ns_run_file_dialog): Declare. * src/nsterm.m (sendEvent:): Handle NSAPP_DATA2_RUNFILEDIALOG. diff: === modified file 'lisp/ChangeLog' --- lisp/ChangeLog 2013-07-06 17:38:24 +0000 +++ lisp/ChangeLog 2013-07-06 17:58:41 +0000 @@ -1,3 +1,8 @@ +2013-07-06 Jan Djärv + + * files.el (write-file): Do not display confirm dialog for NS, + it does its own dialog, which can't be cancelled (Bug#14578). + 2013-07-06 Eli Zaretskii * simple.el (line-move-partial): Adjust the row returned by === modified file 'lisp/files.el' --- lisp/files.el 2013-06-30 22:29:23 +0000 +++ lisp/files.el 2013-07-06 17:58:41 +0000 @@ -3878,6 +3878,10 @@ (or buffer-file-name (buffer-name)))))) (and confirm (file-exists-p filename) + ;; NS does its own confirm dialog. + (not (and (eq (framep-on-display) 'ns) + (listp last-nonmenu-event) + use-dialog-box)) (or (y-or-n-p (format "File `%s' exists; overwrite? " filename)) (error "Canceled"))) (set-visited-file-name filename (not confirm)))) === modified file 'src/ChangeLog' --- src/ChangeLog 2013-07-06 10:41:38 +0000 +++ src/ChangeLog 2013-07-06 17:58:41 +0000 @@ -1,3 +1,19 @@ +2013-07-06 Jan Djärv + + * nsterm.m (sendEvent:): Handle NSAPP_DATA2_RUNFILEDIALOG. + + * nsterm.h (NSSavePanel): Update comment. + (NSAPP_DATA2_RUNFILEDIALOG): Define. + (ns_run_file_dialog): Declare. + + * nsfns.m: Remove panelOK. + (ns_fd_data): New. + (ns_run_file_dialog): New function. + (Fns_read_file_name): Fill in ns_fd_data, post an event and start the + event loop, so file dialog is popped up by ns_run_file_dialog, called + by sendEvent (Bug#14578). + (EmacsSavePanel, EmacsOpenPanel): Remove ok and cancel methods. + 2013-07-06 Eli Zaretskii * xdisp.c (default_line_pixel_height): New function. === modified file 'src/nsfns.m' --- src/nsfns.m 2013-06-30 16:38:26 +0000 +++ src/nsfns.m 2013-07-06 17:58:41 +0000 @@ -89,9 +89,6 @@ Lisp_Object Qbuffered; Lisp_Object Qfontsize; -/* hack for OS X file panels */ -char panelOK = 0; - EmacsTooltip *ns_tooltip = nil; /* Need forward declaration here to preserve organizational integrity of file */ @@ -1396,6 +1393,41 @@ return Qnil; } +static struct +{ + id panel; + BOOL ret; +#if ! defined (NS_IMPL_COCOA) || \ + MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_6 + NSString *dirS, *initS; + BOOL no_types; +#endif +} ns_fd_data; + +void +ns_run_file_dialog (void) +{ + if (ns_fd_data.panel == nil) return; +#if defined (NS_IMPL_COCOA) && \ + MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_6 + ns_fd_data.ret = [ns_fd_data.panel runModal]; +#else + if (ns_fd_data.no_types) + { + ns_fd_data.ret = [ns_fd_data.panel + runModalForDirectory: ns_fd_data.dirS + file: ns_fd_data.initS]; + } + else + { + ns_fd_data.ret = [ns_fd_data.panel + runModalForDirectory: ns_fd_data.dirS + file: ns_fd_data.initS + types: nil]; + } +#endif + ns_fd_data.panel = nil; +} DEFUN ("ns-read-file-name", Fns_read_file_name, Sns_read_file_name, 1, 5, 0, doc: /* Use a graphical panel to read a file name, using prompt PROMPT. @@ -1420,6 +1452,7 @@ [NSString stringWithUTF8String: SSDATA (dir)]; NSString *initS = NILP (init) || !STRINGP (init) ? nil : [NSString stringWithUTF8String: SSDATA (init)]; + NSEvent *nxev; check_window_system (NULL); @@ -1440,7 +1473,6 @@ [panel setTreatsFilePackagesAsDirectories: YES]; [panel setDelegate: fileDelegate]; - panelOK = 0; if (! NILP (dir_only_p)) { [panel setCanChooseDirectories: YES]; @@ -1454,7 +1486,9 @@ [panel setCanChooseFiles: YES]; } - block_input (); + block_input (); + ns_fd_data.panel = panel; + ns_fd_data.ret = NO; #if defined (NS_IMPL_COCOA) && \ MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_6 if (! NILP (mustmatch) || ! NILP (dir_only_p)) @@ -1465,19 +1499,32 @@ else [panel setNameFieldStringValue: @""]; - ret = [panel runModal]; #else - if (NILP (mustmatch) && NILP (dir_only_p)) - { - ret = [panel runModalForDirectory: dirS file: initS]; - } - else - { - ret = [panel runModalForDirectory: dirS file: initS types: nil]; - } + ns_fd_data.no_types = NILP (mustmatch) && NILP (dir_only_p); + ns_fd_data.dirS = dirS; + ns_fd_data.initS = initS; #endif - ret = (ret == NSOKButton) || panelOK; + /* runModalForDirectory/runModal restarts the main event loop when done, + so we must start an event loop and then pop up the file dialog. + The file dialog may pop up a confirm dialog after Ok has been pressed, + so we can not simply pop down on the Ok/Cancel press. + */ + nxev = [NSEvent otherEventWithType: NSApplicationDefined + location: NSMakePoint (0, 0) + modifierFlags: 0 + timestamp: 0 + windowNumber: [[NSApp mainWindow] windowNumber] + context: [NSApp context] + subtype: 0 + data1: 0 + data2: NSAPP_DATA2_RUNFILEDIALOG]; + + [NSApp postEvent: nxev atStart: NO]; + while (ns_fd_data.panel != nil) + [NSApp run]; + + ret = (ns_fd_data.ret == NSOKButton); if (ret) { @@ -2755,25 +2802,6 @@ } @implementation EmacsSavePanel -#ifdef NS_IMPL_COCOA -/* -------------------------------------------------------------------------- - These are overridden to intercept on OS X: ending panel restarts NSApp - event loop if it is stopped. Not sure if this is correct behavior, - perhaps should check if running and if so send an appdefined. - -------------------------------------------------------------------------- */ -- (void) ok: (id)sender -{ - [super ok: sender]; - panelOK = 1; - [NSApp stop: self]; -} -- (void) cancel: (id)sender -{ - [super cancel: sender]; - [NSApp stop: self]; -} -#endif - - (BOOL)performKeyEquivalent:(NSEvent *)theEvent { BOOL ret = handlePanelKeys (self, theEvent); @@ -2785,31 +2813,6 @@ @implementation EmacsOpenPanel -#ifdef NS_IMPL_COCOA -/* -------------------------------------------------------------------------- - These are overridden to intercept on OS X: ending panel restarts NSApp - event loop if it is stopped. Not sure if this is correct behavior, - perhaps should check if running and if so send an appdefined. - -------------------------------------------------------------------------- */ -- (void) ok: (id)sender -{ - [super ok: sender]; - - // If not choosing directories, and Open is pressed on a directory, return. - if (! [self canChooseDirectories] && ns_directory_from_panel (self) && - ! ns_filename_from_panel (self)) - return; - - panelOK = 1; - [NSApp stop: self]; -} -- (void) cancel: (id)sender -{ - [super cancel: sender]; - [NSApp stop: self]; -} - -#endif - (BOOL)performKeyEquivalent:(NSEvent *)theEvent { // NSOpenPanel inherits NSSavePanel, so passing self is OK. === modified file 'src/nsterm.h' --- src/nsterm.h 2013-06-02 19:14:25 +0000 +++ src/nsterm.h 2013-07-06 17:58:41 +0000 @@ -286,8 +286,7 @@ /* ========================================================================== File open/save panels - This and next override methods to work around OS X behavior of - restarting application loop when user dismisses panel. + This and next override methods to handle keyboard input in panels. ========================================================================== */ @@ -838,6 +837,9 @@ #define NSAPP_DATA2_RUNASSCRIPT 10 extern void ns_run_ascript (void); +#define NSAPP_DATA2_RUNFILEDIALOG 11 +extern void ns_run_file_dialog (void); + extern const char *ns_etc_directory (void); extern const char *ns_exec_path (void); extern const char *ns_load_path (void); === modified file 'src/nsterm.m' --- src/nsterm.m 2013-06-27 14:47:52 +0000 +++ src/nsterm.m 2013-07-06 17:58:41 +0000 @@ -4419,15 +4419,22 @@ /* NSTRACE (sendEvent); */ /*fprintf (stderr, "received event of type %d\t%d\n", type);*/ + if (type == NSApplicationDefined) + { + switch ([theEvent data2]) + { #ifdef NS_IMPL_COCOA - if (type == NSApplicationDefined - && [theEvent data2] == NSAPP_DATA2_RUNASSCRIPT) - { - ns_run_ascript (); - [self stop: self]; - return; + case NSAPP_DATA2_RUNASSCRIPT: + ns_run_ascript (); + [self stop: self]; + return; +#endif + case NSAPP_DATA2_RUNFILEDIALOG: + ns_run_file_dialog (); + [self stop: self]; + return; + } } -#endif if (type == NSCursorUpdate && window == nil) { ------------------------------------------------------------ revno: 113307 fixes bug: http://debbugs.gnu.org/14567 committer: Eli Zaretskii branch nick: trunk timestamp: Sat 2013-07-06 20:38:24 +0300 message: Fix vertical cursor motion with non-default fonts. lisp/simple.el (line-move-partial): Adjust the row returned by posn-at-point for the current window-vscroll. (Bug#14567) diff: === modified file 'lisp/ChangeLog' --- lisp/ChangeLog 2013-07-06 16:17:16 +0000 +++ lisp/ChangeLog 2013-07-06 17:38:24 +0000 @@ -1,3 +1,8 @@ +2013-07-06 Eli Zaretskii + + * simple.el (line-move-partial): Adjust the row returned by + posn-at-point for the current window-vscroll. (Bug#14567) + 2013-07-06 Michael Albinus * net/tramp-sh.el (tramp-sh-file-gvfs-monitor-dir-process-filter): === modified file 'lisp/simple.el' --- lisp/simple.el 2013-07-06 13:31:59 +0000 +++ lisp/simple.el 2013-07-06 17:38:24 +0000 @@ -4759,9 +4759,12 @@ this-height (nth 4 wstart)))) (setq py (or (nth 1 this-lh) - (let ((ppos (posn-at-point))) - (cdr (or (posn-actual-col-row ppos) - (posn-col-row ppos)))))) + (let ((ppos (posn-at-point)) + col-row) + (setq col-row (posn-actual-col-row ppos)) + (if col-row + (- (cdr col-row) (window-vscroll)) + (cdr (posn-col-row ppos)))))) (cond ;; If last line of window is fully visible, and vscrolling ;; more would make this line invisible, move forward. ------------------------------------------------------------ revno: 113306 committer: Michael Albinus branch nick: trunk timestamp: Sat 2013-07-06 18:17:16 +0200 message: * net/tramp-sh.el (tramp-sh-file-gvfs-monitor-dir-process-filter): (tramp-sh-file-inotifywait-process-filter): Handle file names with spaces. diff: === modified file 'lisp/ChangeLog' --- lisp/ChangeLog 2013-07-06 14:24:54 +0000 +++ lisp/ChangeLog 2013-07-06 16:17:16 +0000 @@ -1,3 +1,9 @@ +2013-07-06 Michael Albinus + + * net/tramp-sh.el (tramp-sh-file-gvfs-monitor-dir-process-filter): + (tramp-sh-file-inotifywait-process-filter): Handle file names with + spaces. + 2013-07-06 Martin Rudalics * window.el (window-state-put-stale-windows): New variable. === modified file 'lisp/net/tramp-sh.el' --- lisp/net/tramp-sh.el 2013-07-05 15:17:16 +0000 +++ lisp/net/tramp-sh.el 2013-07-06 16:17:16 +0000 @@ -3421,17 +3421,22 @@ (let ((remote-prefix (with-current-buffer (process-buffer proc) (file-remote-p default-directory))) - (previous-string (tramp-compat-process-get proc 'previous-string))) - (when previous-string - (tramp-message proc 10 (format "Previous string:\n%s" previous-string))) + (rest-string (tramp-compat-process-get proc 'rest-string))) + (when rest-string + (tramp-message proc 10 (format "Previous string:\n%s" rest-string))) (tramp-message proc 6 (format "%S\n%s" proc string)) - (setq string (concat previous-string string) + (setq string (concat rest-string string) ;; Attribute change is returned in unused wording. string (replace-regexp-in-string "ATTRIB CHANGED" "ATTRIBUTE_CHANGED" string)) (while (string-match - "^Directory Monitor Event:[\n\r]+Child = \\([^[:blank:]]+\\)[\n\r]+\\(Other = \\([^[:blank:]]+\\)[\n\r]+\\)?Event = \\([^[:blank:]]+\\)[\n\r]+$" string) + (concat "^[\n\r]*" + "Directory Monitor Event:[\n\r]+" + "Child = \\([^\n\r]+\\)[\n\r]+" + "\\(Other = \\([^\n\r]+\\)[\n\r]+\\)?" + "Event = \\([^[:blank:]]+\\)[\n\r]+") + string) (let ((object (list proc @@ -3443,15 +3448,16 @@ (concat remote-prefix (match-string 1 string)) (when (match-string 3 string) (concat remote-prefix (match-string 3 string)))))) + (setq string (replace-match "" nil nil string)) ;; Usually, we would add an Emacs event now. Unfortunately, ;; `unread-command-events' does not accept several events at ;; once. Therefore, we apply the callback directly. - (tramp-compat-funcall 'file-notify-callback object) - (setq string (replace-match "" nil nil string))))) + (tramp-compat-funcall 'file-notify-callback object))) - ;; Save rest of the string. - (when string (tramp-message proc 10 (format "Rest string:\n%s" string))) - (tramp-compat-process-put proc 'previous-string string)) + ;; Save rest of the string. + (when (zerop (length string)) (setq string nil)) + (when string (tramp-message proc 10 (format "Rest string:\n%s" string))) + (tramp-compat-process-put proc 'rest-string string))) (defun tramp-sh-file-inotifywait-process-filter (proc string) "Read output from \"inotifywait\" and add corresponding file-notify events." @@ -3460,7 +3466,10 @@ ;; Check, whether there is a problem. (unless (string-match - "^[^[:blank:]]+[[:blank:]]+\\([^[:blank:]]+\\)+\\([[:blank:]]+\\([^[:blank:]]+\\)\\)?[[:blank:]]*$" line) + (concat "^[^[:blank:]]+" + "[[:blank:]]+\\([^[:blank:]]+\\)+" + "\\([[:blank:]]+\\([^\n\r]+\\)\\)?") + line) (tramp-error proc 'file-notify-error "%s" line)) (let ((object ------------------------------------------------------------ revno: 113305 committer: Michael Albinus branch nick: trunk timestamp: Sat 2013-07-06 18:12:04 +0200 message: Add TODO entry. diff: === modified file 'lisp/net/tramp.el' --- lisp/net/tramp.el 2013-07-04 09:39:36 +0000 +++ lisp/net/tramp.el 2013-07-06 16:12:04 +0000 @@ -4160,6 +4160,9 @@ ;; * Run emerge on two remote files. Bug is described here: ;; . ;; (Bug#6850) +;; * Use also port to distinguish connections. This is needed for +;; different hosts sitting behind a single router (distinguished by +;; different port numbers). (Tzvi Edelman) ;;; tramp.el ends here ------------------------------------------------------------ revno: 113304 author: Martin Rudalics committer: Juanma Barranquero branch nick: trunk timestamp: Sat 2013-07-06 16:24:54 +0200 message: lisp/window.el (window-state-put): Remove window if buffer was not restored. (window-state-put-stale-windows): New variable. (window--state-put-2): Save list of windows without matching buffer. (window-state-put): Remove "bufferless" windows if possible. diff: === modified file 'lisp/ChangeLog' --- lisp/ChangeLog 2013-07-06 13:31:59 +0000 +++ lisp/ChangeLog 2013-07-06 14:24:54 +0000 @@ -1,3 +1,9 @@ +2013-07-06 Martin Rudalics + + * window.el (window-state-put-stale-windows): New variable. + (window--state-put-2): Save list of windows without matching buffer. + (window-state-put): Remove "bufferless" windows if possible. + 2013-07-06 Juanma Barranquero * simple.el (alternatives-define): Remove leftover :group keyword. === modified file 'lisp/window.el' --- lisp/window.el 2013-06-25 17:20:19 +0000 +++ lisp/window.el 2013-07-06 14:24:54 +0000 @@ -4347,6 +4347,9 @@ (defvar window-state-put-list nil "Helper variable for `window-state-put'.") +(defvar window-state-put-stale-windows nil + "Helper variable for `window-state-put'.") + (defun window--state-put-1 (state &optional window ignore totals) "Helper function for `window-state-put'." (let ((type (car state))) @@ -4429,9 +4432,14 @@ (set-window-parameter window (car parameter) (cdr parameter)))) ;; Process buffer related state. (when state - ;; We don't want to raise an error here so we create a buffer if - ;; there's none. - (set-window-buffer window (get-buffer-create (car state))) + ;; We don't want to raise an error in case the buffer does not + ;; exist anymore, so we switch to a previous one and save the + ;; window with the intention of deleting it later if possible. + (let ((buffer (get-buffer (car state)))) + (if buffer + (set-window-buffer window buffer) + (switch-to-prev-buffer window) + (push window window-state-put-stale-windows))) (with-current-buffer (window-buffer window) (set-window-hscroll window (cdr (assq 'hscroll state))) (apply 'set-window-fringes @@ -4491,6 +4499,7 @@ sizes and fixed size restrictions. IGNORE equal `safe' means windows can get as small as `window-safe-min-height' and `window-safe-min-width'." + (setq window-state-put-stale-windows nil) (setq window (window-normalize-window window t)) (let* ((frame (window-frame window)) (head (car state)) @@ -4539,6 +4548,10 @@ (set-window-buffer window (current-buffer)) (window--state-put-1 state window nil totals) (window--state-put-2 ignore)) + (while window-state-put-stale-windows + (let ((window (pop window-state-put-stale-windows))) + (when (eq (window-deletable-p window) t) + (delete-window window)))) (window--check frame)))) (defun display-buffer-record-window (type window buffer) ------------------------------------------------------------ revno: 113303 committer: Juanma Barranquero branch nick: trunk timestamp: Sat 2013-07-06 15:31:59 +0200 message: lisp/simple.el (alternatives-define): Remove leftover :group keyword. Tweak docstring. diff: === modified file 'lisp/ChangeLog' --- lisp/ChangeLog 2013-07-06 12:37:12 +0000 +++ lisp/ChangeLog 2013-07-06 13:31:59 +0000 @@ -1,3 +1,8 @@ +2013-07-06 Juanma Barranquero + + * simple.el (alternatives-define): Remove leftover :group keyword. + Tweak docstring. + 2013-07-06 Leo Liu * ido.el (ido-use-virtual-buffers): Allow new value 'auto. === modified file 'lisp/simple.el' --- lisp/simple.el 2013-07-06 09:35:37 +0000 +++ lisp/simple.el 2013-07-06 13:31:59 +0000 @@ -7368,7 +7368,7 @@ will allow the user to chose among them. CUSTOMIZATIONS, if non-nil, should be composed of alternating `defcustom' keywords and values to add to the declaration of -`COMMAND-alternatives' (typically to add new groups)." +`COMMAND-alternatives' (typically :group and :version)." (let* ((command-name (symbol-name command)) (varalt-name (concat command-name "-alternatives")) (varalt-sym (intern varalt-name)) @@ -7383,7 +7383,6 @@ ALTFUN - The function called to implement this alternative." command-name) :type '(alist :key-type string :value-type function) - :group 'dispatcher ,@customizations) (defvar ,varimp-sym nil "Internal use only.") ------------------------------------------------------------ revno: 113302 author: David Kastrup committer: Katsumi Yamaoka branch nick: trunk timestamp: Sat 2013-07-06 12:49:38 +0000 message: lisp/gnus/auth-source.el (auth-source-netrc-parse-one): Allow empty strings in authinfo file again (important for blank passwords). This had been broken with 2013-06-15 change diff: === modified file 'lisp/gnus/ChangeLog' --- lisp/gnus/ChangeLog 2013-07-03 04:15:38 +0000 +++ lisp/gnus/ChangeLog 2013-07-06 12:49:38 +0000 @@ -1,3 +1,9 @@ +2013-07-05 David Kastrup + + * auth-source.el (auth-source-netrc-parse-one): Allow empty strings in + authinfo file again (important for blank passwords). This had been + broken with 2013-06-15 change. + 2013-07-03 Katsumi Yamaoka * gnus-sum.el (gnus-summary-from-or-to-or-newsgroups): === modified file 'lisp/gnus/auth-source.el' --- lisp/gnus/auth-source.el 2013-06-18 22:38:34 +0000 +++ lisp/gnus/auth-source.el 2013-07-06 12:49:38 +0000 @@ -1048,8 +1048,8 @@ "Read one thing from the current buffer." (auth-source-netrc-parse-next-interesting) - (when (or (looking-at "'\\([^']+\\)'") - (looking-at "\"\\([^\"]+\\)\"") + (when (or (looking-at "'\\([^']*\\)'") + (looking-at "\"\\([^\"]*\\)\"") (looking-at "\\([^ \t\n]+\\)")) (forward-char (length (match-string 0))) (auth-source-netrc-parse-next-interesting) ------------------------------------------------------------ revno: 113301 committer: Leo Liu branch nick: trunk timestamp: Sat 2013-07-06 20:37:12 +0800 message: * ido.el (ido-use-virtual-buffers): Allow new value 'auto. (ido-enable-virtual-buffers): New variable. (ido-buffer-internal, ido-toggle-virtual-buffers) (ido-make-buffer-list): Use it. (ido-exhibit): Support turning on and off virtual buffers automatically. diff: === modified file 'lisp/ChangeLog' --- lisp/ChangeLog 2013-07-06 09:35:37 +0000 +++ lisp/ChangeLog 2013-07-06 12:37:12 +0000 @@ -1,3 +1,12 @@ +2013-07-06 Leo Liu + + * ido.el (ido-use-virtual-buffers): Allow new value 'auto. + (ido-enable-virtual-buffers): New variable. + (ido-buffer-internal, ido-toggle-virtual-buffers) + (ido-make-buffer-list): Use it. + (ido-exhibit): Support turning on and off virtual buffers + automatically. + 2013-07-06 Juanma Barranquero * simple.el (alternatives-define): New macro. === modified file 'lisp/ido.el' --- lisp/ido.el 2013-07-03 03:01:34 +0000 +++ lisp/ido.el 2013-07-06 12:37:12 +0000 @@ -782,21 +782,29 @@ :group 'ido) (defcustom ido-use-virtual-buffers nil - "If non-nil, refer to past buffers as well as existing ones. + "Specify how vritual buffers should be used. +The value can be one of the following: + + nil: No virtual buffers are used. + auto: Use virtual bufferw when the current input matches no + existing buffers. + t: Always use virtual buffers. + Essentially it works as follows: Say you are visiting a file and the buffer gets cleaned up by midnight.el. Later, you want to -switch to that buffer, but find it's no longer open. With -virtual buffers enabled, the buffer name stays in the buffer -list (using the `ido-virtual' face, and always at the end), and if -you select it, it opens the file back up again. This allows you -to think less about whether recently opened files are still open -or not. Most of the time you can quit Emacs, restart, and then -switch to a file buffer that was previously open as if it still -were. - This feature relies upon the `recentf' package, which will be -enabled if this variable is configured to a non-nil value." - :version "24.1" - :type 'boolean +switch to that buffer, but find it's no longer open. With virtual +buffers enabled, the buffer name stays in the buffer list (using +the `ido-virtual' face, and always at the end), and if you select +it, it opens the file back up again. This allows you to think +less about whether recently opened files are still open or not. +Most of the time you can quit Emacs, restart, and then switch to +a file buffer that was previously open as if it still were. This +feature relies upon the `recentf' package, which will be enabled +if this variable is configured to a non-nil value." + :version "24.4" + :type '(choice (const :tag "Always" t) + (const :tag "Automatic" auto) + (const :tag "Never" nil)) :group 'ido) (defcustom ido-use-faces t @@ -1103,6 +1111,9 @@ ;; Don't process ido-ignore- lists once. (defvar ido-process-ignore-lists-inhibit) +;; Is ido using virtual buffers? +(defvar ido-enable-virtual-buffers) + ;; Buffer from which ido was entered. (defvar ido-entry-buffer) @@ -2202,7 +2213,8 @@ (ido-current-directory nil) (ido-directory-nonreadable nil) (ido-directory-too-big nil) - (ido-use-virtual-buffers ido-use-virtual-buffers) + (ido-enable-virtual-buffers (and ido-use-virtual-buffers + (not (eq ido-use-virtual-buffers 'auto)))) (require-match (confirm-nonexistent-file-or-buffer)) (buf (ido-read-internal 'buffer (or prompt "Buffer: ") 'ido-buffer-history default require-match initial)) @@ -2243,7 +2255,8 @@ (ido-visit-buffer buf method t))) ;; check for a virtual buffer reference - ((and ido-use-virtual-buffers ido-virtual-buffers + ((and ido-enable-virtual-buffers + ido-virtual-buffers (setq filename (assoc buf ido-virtual-buffers))) (ido-visit-buffer (find-file-noselect (cdr filename)) method t)) @@ -2734,7 +2747,11 @@ See `ido-use-virtual-buffers' for explanation of virtual buffer." (interactive) (when (and ido-mode (eq ido-cur-item 'buffer)) - (setq ido-use-virtual-buffers (not ido-use-virtual-buffers)) + (setq ido-enable-virtual-buffers + (if ido-enable-virtual-buffers + nil + ;; Use `always' instead of t for `ido-exhibit'. + 'always)) (setq ido-text-init ido-text) (setq ido-exit 'refresh) (exit-minibuffer))) @@ -3427,9 +3444,9 @@ (nconc ido-temp-list ido-current-buffers) (setq ido-temp-list ido-current-buffers)) (if default - (setq ido-temp-list - (cons default (delete default ido-temp-list)))) - (if ido-use-virtual-buffers + (setq ido-temp-list + (cons default (delete default ido-temp-list)))) + (if (bound-and-true-p ido-enable-virtual-buffers) (ido-add-virtual-buffers-to-list)) (run-hooks 'ido-make-buffer-list-hook) ido-temp-list)) @@ -4477,6 +4494,27 @@ (setq ido-exit 'refresh) (exit-minibuffer)) + (when (and (boundp 'ido-enable-virtual-buffers) + (not (eq ido-enable-virtual-buffers 'always)) + (eq ido-cur-item 'buffer) + (eq ido-use-virtual-buffers 'auto)) + + (when (and (not ido-enable-virtual-buffers) + (not ido-matches)) + (setq ido-text-init ido-text) + (setq ido-enable-virtual-buffers t) + (setq ido-exit 'refresh) + (exit-minibuffer)) + + ;; If input matches real buffers turn off virtual buffers. + (when (and ido-enable-virtual-buffers + ido-matches + (ido-set-matches-1 (ido-make-buffer-list-1))) + (setq ido-enable-virtual-buffers nil) + (setq ido-text-init ido-text) + (setq ido-exit 'refresh) + (exit-minibuffer))) + (when (and (not ido-matches) (not ido-directory-nonreadable) (not ido-directory-too-big) ------------------------------------------------------------ revno: 113300 fixes bug: http://debbugs.gnu.org/14771 committer: Eli Zaretskii branch nick: trunk timestamp: Sat 2013-07-06 13:41:38 +0300 message: Fix bug #14771 with scroll-step = 1 and non-nil line-spacing. src/xdisp.c (default_line_pixel_height): New function. (pos_visible_p, move_it_vertically_backward, try_scrolling) (try_cursor_movement, redisplay_window, try_window) (try_window_id): Use it instead of FRAME_LINE_HEIGHT. (Bug#14771) src/window.c (window_scroll_pixel_based): use default_line_pixel_height. src/dispextern.h (default_line_pixel_height): Add prototype. src/frame.c (x_set_line_spacing): Accept a float value for line-spacing parameter, per the documentation. diff: === modified file 'src/ChangeLog' --- src/ChangeLog 2013-07-06 08:05:21 +0000 +++ src/ChangeLog 2013-07-06 10:41:38 +0000 @@ -1,5 +1,18 @@ 2013-07-06 Eli Zaretskii + * xdisp.c (default_line_pixel_height): New function. + (pos_visible_p, move_it_vertically_backward, try_scrolling) + (try_cursor_movement, redisplay_window, try_window) + (try_window_id): Use it instead of FRAME_LINE_HEIGHT. (Bug#14771) + + * window.c (window_scroll_pixel_based): use + default_line_pixel_height. + + * dispextern.h (default_line_pixel_height): Add prototype. + + * frame.c (x_set_line_spacing): Accept a float value for + line-spacing parameter, per the documentation. + * data.c (Fmultibyte_string_p): Doc fix. 2013-07-05 Paul Eggert === modified file 'src/dispextern.h' --- src/dispextern.h 2013-07-02 16:45:28 +0000 +++ src/dispextern.h 2013-07-06 10:41:38 +0000 @@ -3116,6 +3116,7 @@ struct glyph_row *, struct glyph_row *, int); int line_bottom_y (struct it *); +int default_line_pixel_height (struct window *); int display_prop_intangible_p (Lisp_Object, Lisp_Object, ptrdiff_t, ptrdiff_t); void resize_echo_area_exactly (void); int resize_mini_window (struct window *, int); === modified file 'src/frame.c' --- src/frame.c 2013-06-17 21:12:21 +0000 +++ src/frame.c 2013-07-06 10:41:38 +0000 @@ -2964,6 +2964,15 @@ f->extra_line_spacing = 0; else if (RANGED_INTEGERP (0, new_value, INT_MAX)) f->extra_line_spacing = XFASTINT (new_value); + else if (FLOATP (new_value)) + { + int new_spacing = XFLOAT_DATA (new_value) * FRAME_LINE_HEIGHT (f) + 0.5; + + if (new_spacing >= 0) + f->extra_line_spacing = new_spacing; + else + signal_error ("Invalid line-spacing", new_value); + } else signal_error ("Invalid line-spacing", new_value); if (FRAME_VISIBLE_P (f)) === modified file 'src/window.c' --- src/window.c 2013-06-17 06:03:19 +0000 +++ src/window.c 2013-07-06 10:41:38 +0000 @@ -4368,6 +4368,8 @@ int vscrolled = 0; int x, y, rtop, rbot, rowh, vpos; void *itdata = NULL; + int window_total_lines; + int frame_line_height = default_line_pixel_height (w); SET_TEXT_POS_FROM_MARKER (start, w->start); /* Scrolling a minibuffer window via scroll bar when the echo area @@ -4411,7 +4413,7 @@ if (rtop || rbot) /* partially visible */ { int px; - int dy = WINDOW_FRAME_LINE_HEIGHT (w); + int dy = frame_line_height; if (whole) dy = max ((window_box_height (w) - next_screen_context_lines * dy), @@ -4497,7 +4499,7 @@ if (whole) { ptrdiff_t start_pos = IT_CHARPOS (it); - int dy = WINDOW_FRAME_LINE_HEIGHT (w); + int dy = frame_line_height; dy = max ((window_box_height (w) - next_screen_context_lines * dy), dy) * n; @@ -4614,10 +4616,12 @@ /* Move PT out of scroll margins. This code wants current_y to be zero at the window start position even if there is a header line. */ + window_total_lines + = w->total_lines * WINDOW_FRAME_LINE_HEIGHT (w) / frame_line_height; this_scroll_margin = max (0, scroll_margin); this_scroll_margin - = min (this_scroll_margin, w->total_lines / 4); - this_scroll_margin *= FRAME_LINE_HEIGHT (it.f); + = min (this_scroll_margin, window_total_lines / 4); + this_scroll_margin *= frame_line_height; if (n > 0) { === modified file 'src/xdisp.c' --- src/xdisp.c 2013-07-05 16:58:01 +0000 +++ src/xdisp.c 2013-07-06 10:41:38 +0000 @@ -1232,6 +1232,52 @@ return make_number (line_bottom_y (&it)); } +/* Return the default pixel height of text lines in window W. The + value is the canonical height of the W frame's default font, plus + any extra space required by the line-spacing variable or frame + parameter. + + Implementation note: this ignores any line-spacing text properties + put on the newline characters. This is because those properties + only affect the _screen_ line ending in the newline (i.e., in a + continued line, only the last screen line will be affected), which + means only a small number of lines in a buffer can ever use this + feature. Since this function is used to compute the default pixel + equivalent of text lines in a window, we can safely ignore those + few lines. For the same reasons, we ignore the line-height + properties. */ +int +default_line_pixel_height (struct window *w) +{ + struct frame *f = WINDOW_XFRAME (w); + int height = FRAME_LINE_HEIGHT (f); + + if (!FRAME_INITIAL_P (f) && BUFFERP (w->contents)) + { + struct buffer *b = XBUFFER (w->contents); + Lisp_Object val = BVAR (b, extra_line_spacing); + + if (NILP (val)) + val = BVAR (&buffer_defaults, extra_line_spacing); + if (!NILP (val)) + { + if (RANGED_INTEGERP (0, val, INT_MAX)) + height += XFASTINT (val); + else if (FLOATP (val)) + { + int addon = XFLOAT_DATA (val) * height + 0.5; + + if (addon >= 0) + height += addon; + } + } + else + height += f->extra_line_spacing; + } + + return height; +} + /* Subroutine of pos_visible_p below. Extracts a display string, if any, from the display spec given as its argument. */ static Lisp_Object @@ -1366,8 +1412,7 @@ struct it save_it = it; /* Why 10? because we don't know how many canonical lines will the height of the next line(s) be. So we guess. */ - int ten_more_lines = - 10 * FRAME_LINE_HEIGHT (XFRAME (WINDOW_FRAME (w))); + int ten_more_lines = 10 * default_line_pixel_height (w); move_it_to (&it, charpos, -1, bottom_y + ten_more_lines, -1, MOVE_TO_POS | MOVE_TO_Y); @@ -9056,7 +9101,7 @@ start_pos = IT_CHARPOS (*it); /* Estimate how many newlines we must move back. */ - nlines = max (1, dy / FRAME_LINE_HEIGHT (it->f)); + nlines = max (1, dy / default_line_pixel_height (it->w)); if (it->line_wrap == TRUNCATE) pos_limit = BEGV; else @@ -14536,6 +14581,9 @@ Lisp_Object aggressive; /* We will never try scrolling more than this number of lines. */ int scroll_limit = SCROLL_LIMIT; + int frame_line_height = default_line_pixel_height (w); + int window_total_lines + = WINDOW_TOTAL_LINES (w) * FRAME_LINE_HEIGHT (f) / frame_line_height; #ifdef GLYPH_DEBUG debug_method_add (w, "try_scrolling"); @@ -14546,8 +14594,8 @@ /* Compute scroll margin height in pixels. We scroll when point is within this distance from the top or bottom of the window. */ if (scroll_margin > 0) - this_scroll_margin = min (scroll_margin, WINDOW_TOTAL_LINES (w) / 4) - * FRAME_LINE_HEIGHT (f); + this_scroll_margin = min (scroll_margin, window_total_lines / 4) + * frame_line_height; else this_scroll_margin = 0; @@ -14558,19 +14606,19 @@ if (arg_scroll_conservatively > scroll_limit) { arg_scroll_conservatively = scroll_limit + 1; - scroll_max = scroll_limit * FRAME_LINE_HEIGHT (f); + scroll_max = scroll_limit * frame_line_height; } else if (scroll_step || arg_scroll_conservatively || temp_scroll_step) /* Compute how much we should try to scroll maximally to bring point into view. */ scroll_max = (max (scroll_step, max (arg_scroll_conservatively, temp_scroll_step)) - * FRAME_LINE_HEIGHT (f)); + * frame_line_height); else if (NUMBERP (BVAR (current_buffer, scroll_down_aggressively)) || NUMBERP (BVAR (current_buffer, scroll_up_aggressively))) /* We're trying to scroll because of aggressive scrolling but no scroll_step is set. Choose an arbitrary one. */ - scroll_max = 10 * FRAME_LINE_HEIGHT (f); + scroll_max = 10 * frame_line_height; else scroll_max = 0; @@ -14585,7 +14633,7 @@ either that ypos or PT, whichever comes first. */ start_display (&it, w, startp); scroll_margin_y = it.last_visible_y - this_scroll_margin - - FRAME_LINE_HEIGHT (f) * extra_scroll_margin_lines; + - frame_line_height * extra_scroll_margin_lines; move_it_to (&it, PT, -1, scroll_margin_y - 1, -1, (MOVE_TO_POS | MOVE_TO_Y)); @@ -14597,7 +14645,7 @@ the user limited scrolling by a small number of lines, but always finds PT if scroll_conservatively is set to a large number, such as most-positive-fixnum. */ - int slack = max (scroll_max, 10 * FRAME_LINE_HEIGHT (f)); + int slack = max (scroll_max, 10 * frame_line_height); int y_to_move = it.last_visible_y + slack; /* Compute the distance from the scroll margin to PT or to @@ -14624,8 +14672,8 @@ move it down by scroll_step. */ if (arg_scroll_conservatively) amount_to_scroll - = min (max (dy, FRAME_LINE_HEIGHT (f)), - FRAME_LINE_HEIGHT (f) * arg_scroll_conservatively); + = min (max (dy, frame_line_height), + frame_line_height * arg_scroll_conservatively); else if (scroll_step || temp_scroll_step) amount_to_scroll = scroll_max; else @@ -14722,7 +14770,7 @@ start_display (&it, w, pos); y0 = it.current_y; y_to_move = max (it.last_visible_y, - max (scroll_max, 10 * FRAME_LINE_HEIGHT (f))); + max (scroll_max, 10 * frame_line_height)); move_it_to (&it, CHARPOS (scroll_margin_pos), 0, y_to_move, -1, MOVE_TO_POS | MOVE_TO_X | MOVE_TO_Y); @@ -14738,7 +14786,7 @@ start_display (&it, w, startp); if (arg_scroll_conservatively) - amount_to_scroll = max (dy, FRAME_LINE_HEIGHT (f) * + amount_to_scroll = max (dy, frame_line_height * max (scroll_step, temp_scroll_step)); else if (scroll_step || temp_scroll_step) amount_to_scroll = scroll_max; @@ -14958,6 +15006,9 @@ { int this_scroll_margin, top_scroll_margin; struct glyph_row *row = NULL; + int frame_line_height = default_line_pixel_height (w); + int window_total_lines + = WINDOW_TOTAL_LINES (w) * FRAME_LINE_HEIGHT (f) / frame_line_height; #ifdef GLYPH_DEBUG debug_method_add (w, "cursor movement"); @@ -14967,8 +15018,8 @@ of the window. This is a pixel value. */ if (scroll_margin > 0) { - this_scroll_margin = min (scroll_margin, WINDOW_TOTAL_LINES (w) / 4); - this_scroll_margin *= FRAME_LINE_HEIGHT (f); + this_scroll_margin = min (scroll_margin, window_total_lines / 4); + this_scroll_margin *= frame_line_height; } else this_scroll_margin = 0; @@ -15310,6 +15361,7 @@ int centering_position = -1; int last_line_misfit = 0; ptrdiff_t beg_unchanged, end_unchanged; + int frame_line_height; SET_TEXT_POS (lpoint, PT, PT_BYTE); opoint = lpoint; @@ -15324,6 +15376,7 @@ restart: reconsider_clip_changes (w, buffer); + frame_line_height = default_line_pixel_height (w); /* Has the mode line to be updated? */ update_mode_line = (w->update_mode_line @@ -15559,8 +15612,10 @@ /* Some people insist on not letting point enter the scroll margin, even though this part handles windows that didn't scroll at all. */ - int margin = min (scroll_margin, WINDOW_TOTAL_LINES (w) / 4); - int pixel_margin = margin * FRAME_LINE_HEIGHT (f); + int window_total_lines + = WINDOW_TOTAL_LINES (w) * FRAME_LINE_HEIGHT (f) / frame_line_height; + int margin = min (scroll_margin, window_total_lines / 4); + int pixel_margin = margin * frame_line_height; bool header_line = WINDOW_WANTS_HEADER_LINE_P (w); /* Note: We add an extra FRAME_LINE_HEIGHT, because the loop @@ -15571,7 +15626,7 @@ new_vpos = pixel_margin + (header_line ? CURRENT_HEADER_LINE_HEIGHT (w) - : 0) + FRAME_LINE_HEIGHT (f); + : 0) + frame_line_height; else { int window_height = window_box_height (w); @@ -15820,9 +15875,11 @@ it.current_y = it.last_visible_y; if (centering_position < 0) { + int window_total_lines + = WINDOW_TOTAL_LINES (w) * FRAME_LINE_HEIGHT (f) / frame_line_height; int margin = scroll_margin > 0 - ? min (scroll_margin, WINDOW_TOTAL_LINES (w) / 4) + ? min (scroll_margin, window_total_lines / 4) : 0; ptrdiff_t margin_pos = CHARPOS (startp); Lisp_Object aggressive; @@ -15844,7 +15901,7 @@ SAVE_IT (it1, it, it1data); start_display (&it1, w, startp); - move_it_vertically (&it1, margin * FRAME_LINE_HEIGHT (f)); + move_it_vertically (&it1, margin * frame_line_height); margin_pos = IT_CHARPOS (it1); RESTORE_IT (&it, &it, it1data); } @@ -15880,15 +15937,15 @@ if (pt_offset) centering_position -= pt_offset; centering_position -= - FRAME_LINE_HEIGHT (f) * (1 + margin + (last_line_misfit != 0)) + frame_line_height * (1 + margin + (last_line_misfit != 0)) + WINDOW_HEADER_LINE_HEIGHT (w); /* Don't let point enter the scroll margin near top of the window. */ - if (centering_position < margin * FRAME_LINE_HEIGHT (f)) - centering_position = margin * FRAME_LINE_HEIGHT (f); + if (centering_position < margin * frame_line_height) + centering_position = margin * frame_line_height; } else - centering_position = margin * FRAME_LINE_HEIGHT (f) + pt_offset; + centering_position = margin * frame_line_height + pt_offset; } else /* Set the window start half the height of the window backward @@ -15993,11 +16050,13 @@ make that row fully visible and out of the margin. */ if (scroll_conservatively > SCROLL_LIMIT) { + int window_total_lines + = WINDOW_TOTAL_LINES (w) * FRAME_LINE_HEIGHT (f) * frame_line_height; int margin = scroll_margin > 0 - ? min (scroll_margin, WINDOW_TOTAL_LINES (w) / 4) + ? min (scroll_margin, window_total_lines / 4) : 0; - int move_down = w->cursor.vpos >= WINDOW_TOTAL_LINES (w) / 2; + int move_down = w->cursor.vpos >= window_total_lines / 2; move_it_by_lines (&it, move_down ? margin + 1 : -(margin + 1)); clear_glyph_matrix (w->desired_matrix); @@ -16184,6 +16243,7 @@ struct it it; struct glyph_row *last_text_row = NULL; struct frame *f = XFRAME (w->frame); + int frame_line_height = default_line_pixel_height (w); /* Make POS the new window start. */ set_marker_both (w->start, Qnil, CHARPOS (pos), BYTEPOS (pos)); @@ -16209,11 +16269,13 @@ && !MINI_WINDOW_P (w)) { int this_scroll_margin; + int window_total_lines + = WINDOW_TOTAL_LINES (w) * FRAME_LINE_HEIGHT (f) / frame_line_height; if (scroll_margin > 0) { - this_scroll_margin = min (scroll_margin, WINDOW_TOTAL_LINES (w) / 4); - this_scroll_margin *= FRAME_LINE_HEIGHT (f); + this_scroll_margin = min (scroll_margin, window_total_lines / 4); + this_scroll_margin *= frame_line_height; } else this_scroll_margin = 0; @@ -17514,10 +17576,13 @@ /* Don't let the cursor end in the scroll margins. */ { int this_scroll_margin, cursor_height; + int frame_line_height = default_line_pixel_height (w); + int window_total_lines + = WINDOW_TOTAL_LINES (w) * FRAME_LINE_HEIGHT (it.f) / frame_line_height; this_scroll_margin = - max (0, min (scroll_margin, WINDOW_TOTAL_LINES (w) / 4)); - this_scroll_margin *= FRAME_LINE_HEIGHT (it.f); + max (0, min (scroll_margin, window_total_lines / 4)); + this_scroll_margin *= frame_line_height; cursor_height = MATRIX_ROW (w->desired_matrix, w->cursor.vpos)->height; if ((w->cursor.y < this_scroll_margin ------------------------------------------------------------ revno: 113299 committer: Juanma Barranquero branch nick: trunk timestamp: Sat 2013-07-06 11:37:29 +0200 message: etc/NEWS: Fix typos. diff: === modified file 'etc/NEWS' --- etc/NEWS 2013-07-06 09:35:37 +0000 +++ etc/NEWS 2013-07-06 09:37:29 +0000 @@ -268,7 +268,7 @@ *** `desktop-auto-save-timeout' defines the number of seconds between auto-saves of the desktop. -*** `desktop-restore-frames enables saving and restoring the window/frame +*** `desktop-restore-frames' enables saving and restoring the window/frame configuration. ** Dired @@ -436,7 +436,7 @@ ** Woman *** The commands `woman-default-faces' and `woman-monochrome-faces' -are obsolete. Customize the `woman-* faces instead. +are obsolete. Customize the `woman-*' faces instead. ** Eshell @@ -1058,7 +1058,7 @@ `DEL' (`dired-unmark-backward'), and `d' (`dired-flag-file-deletion') mark/unmark/flag all files in the active region. -*** The minibuffer default for `=' (`dired-diff) has changed. +*** The minibuffer default for `=' (`dired-diff') has changed. It is now the backup file for the file at point, if one exists. In Transient Mark mode the default is the file at the active mark. ------------------------------------------------------------ revno: 113298 committer: Juanma Barranquero branch nick: trunk timestamp: Sat 2013-07-06 11:35:37 +0200 message: lisp/simple.el (alternatives-define): New macro. etc/NEWS: Document new "generic commands" support. diff: === modified file 'etc/ChangeLog' --- etc/ChangeLog 2013-06-27 09:08:14 +0000 +++ etc/ChangeLog 2013-07-06 09:35:37 +0000 @@ -1,3 +1,7 @@ +2013-07-06 Juanma Barranquero + + * NEWS: Document new "generic commands" support. + 2013-06-27 Juanma Barranquero * NEWS: Document new Desktop option `desktop-save-windows'. === modified file 'etc/NEWS' --- etc/NEWS 2013-07-04 10:25:54 +0000 +++ etc/NEWS 2013-07-06 09:35:37 +0000 @@ -133,6 +133,10 @@ `x-display-pixel-width', `x-display-pixel-height', `display-mm-width', `display-mm-height', `x-display-mm-width', and `x-display-mm-height'. +** New macro `alternatives-define' can be used to define generic commands. +Generic commands are interactive functions whose implementation can be +selected among several alternatives, as a matter of user preference. + * Editing Changes in Emacs 24.4 === modified file 'lisp/ChangeLog' --- lisp/ChangeLog 2013-07-06 00:10:54 +0000 +++ lisp/ChangeLog 2013-07-06 09:35:37 +0000 @@ -1,3 +1,7 @@ +2013-07-06 Juanma Barranquero + + * simple.el (alternatives-define): New macro. + 2013-07-06 Stefan Monnier * subr.el (read-quoted-char): Use read-key. === modified file 'lisp/simple.el' --- lisp/simple.el 2013-06-26 00:50:50 +0000 +++ lisp/simple.el 2013-07-06 09:35:37 +0000 @@ -7346,6 +7346,67 @@ (with-eval-after-load pkg (bad-package-check pkg)))) + +;;; Generic dispatcher commands + +;; Macro `alternatives-define' is used to create generic commands. +;; Generic commands are these (like web, mail, news, encrypt, irc, etc.) +;; that can have different alternative implementations where choosing +;; among them is exclusively a matter of user preference. + +;; (alternatives-define COMMAND) creates a new interactive command +;; M-x COMMAND and a customizable variable COMMAND-alternatives. +;; Typically, the user will not need to customize this variable; packages +;; wanting to add alternative implementations should use +;; +;; ;;;###autoload (push '("My impl name" . my-impl-symbol) COMMAND-alternatives + +(defmacro alternatives-define (command &rest customizations) + "Define new command `COMMAND'. +The variable `COMMAND-alternatives' will contain alternative +implementations of COMMAND, so that running `C-u M-x COMMAND' +will allow the user to chose among them. +CUSTOMIZATIONS, if non-nil, should be composed of alternating +`defcustom' keywords and values to add to the declaration of +`COMMAND-alternatives' (typically to add new groups)." + (let* ((command-name (symbol-name command)) + (varalt-name (concat command-name "-alternatives")) + (varalt-sym (intern varalt-name)) + (varimp-sym (intern (concat command-name "--implementation")))) + `(progn + + (defcustom ,varalt-sym nil + ,(format "Alist of alternative implementations for the `%s' command. + +Each entry must be a pair (ALTNAME . ALTFUN), where: +ALTNAME - The name shown at user to describe the alternative implementation. +ALTFUN - The function called to implement this alternative." + command-name) + :type '(alist :key-type string :value-type function) + :group 'dispatcher + ,@customizations) + + (defvar ,varimp-sym nil "Internal use only.") + + (defun ,command (&optional arg) + ,(format "Run generic command `%s'. +If used for the first time, or with interactive ARG, ask the user which +implementation to use for `%s'. The variable `%s' +contains the list of implementations currently supported for this command." + command-name command-name varalt-name) + (interactive "P") + (when (or arg (null ,varimp-sym)) + (let ((val (completing-read + ,(format "Select implementation for command `%s': " command-name) + ,varalt-sym nil t))) + (unless (string-equal val "") + (customize-save-variable ',varimp-sym + (cdr (assoc-string val ,varalt-sym)))))) + (if ,varimp-sym + (funcall ,varimp-sym) + (message ,(format "No implementation selected for command `%s'" + command-name))))))) + (provide 'simple) ;;; simple.el ends here ------------------------------------------------------------ revno: 113297 committer: Eli Zaretskii branch nick: trunk timestamp: Sat 2013-07-06 11:05:21 +0300 message: Clarify documentation of multibyte-string-p. src/data.c (Fmultibyte_string_p): Doc fix. doc/lispref/nonascii.texi (Text Representations): Document that multibyte-string-p returns nil for non-string objects. diff: === modified file 'doc/lispref/ChangeLog' --- doc/lispref/ChangeLog 2013-07-06 01:39:21 +0000 +++ doc/lispref/ChangeLog 2013-07-06 08:05:21 +0000 @@ -1,3 +1,8 @@ +2013-07-06 Eli Zaretskii + + * nonascii.texi (Text Representations): Document that + multibyte-string-p returns nil for non-string objects. + 2013-07-06 Glenn Morris * elisp.texi (Top): Move WWW_GNU_ORG section outside @copying. === modified file 'doc/lispref/nonascii.texi' --- doc/lispref/nonascii.texi 2013-02-09 12:52:01 +0000 +++ doc/lispref/nonascii.texi 2013-07-06 08:05:21 +0000 @@ -124,7 +124,8 @@ @defun multibyte-string-p string Return @code{t} if @var{string} is a multibyte string, @code{nil} -otherwise. +otherwise. This function also returns @code{nil} if @var{string} is +some object other than a string. @end defun @defun string-bytes string === modified file 'src/ChangeLog' --- src/ChangeLog 2013-07-06 02:40:50 +0000 +++ src/ChangeLog 2013-07-06 08:05:21 +0000 @@ -1,3 +1,7 @@ +2013-07-06 Eli Zaretskii + + * data.c (Fmultibyte_string_p): Doc fix. + 2013-07-05 Paul Eggert Use emacs_open more consistently when opening files. === modified file 'src/data.c' --- src/data.c 2013-06-17 06:03:19 +0000 +++ src/data.c 2013-07-06 08:05:21 +0000 @@ -377,7 +377,8 @@ DEFUN ("multibyte-string-p", Fmultibyte_string_p, Smultibyte_string_p, 1, 1, 0, - doc: /* Return t if OBJECT is a multibyte string. */) + doc: /* Return t if OBJECT is a multibyte string. +Return nil if OBJECT is either a unibyte string, or not a string. */) (Lisp_Object object) { if (STRINGP (object) && STRING_MULTIBYTE (object)) ------------------------------------------------------------ revno: 113296 committer: Paul Eggert branch nick: trunk timestamp: Fri 2013-07-05 19:40:50 -0700 message: Use emacs_open more consistently when opening files. This handles EINTR more consistently now, and makes it easier to introduce other uniform changes to file descriptor handling. * src/systdio.h: New file. * src/buffer.c (mmap_init): * cygw32.c (chdir_to_default_directory): * dispnew.c (Fopen_termscript): * emacs.c (Fdaemon_initialized): * fileio.c (Fdo_auto_save): * image.c (slurp_file, png_load_body, jpeg_load_body): * keyboard.c (Fopen_dribble_file): * lread.c (Fload): * print.c (Fredirect_debugging_output): * sysdep.c (get_up_time, procfs_ttyname, procfs_get_total_memory): * termcap.c (tgetent): * unexaix.c, unexcoff.c (unexec, adjust_lnnoptrs): * unexcw.c, unexelf.c, unexhp9k800.c, unexmacosx.c (unexec): * w32term.c (w32_initialize) [CYGWIN]: * xfaces.c (Fx_load_color_file): Use emacs_open instead of plain open, and emacs_fopen instead of plain fopen. * dispnew.c, fileio.c, image.c, keyboard.c, lread.c, print.c, sysdep.c: * xfaces.c: Include sysstdio.h rather than stdio.h, for emacs_fopen. * callproc.c (default_output_mode): New constant. (Fcall_process): Use it to call emacs_open instead of plain creat. * dispnew.c (Fopen_termscript): Fix minor race in opening termscript. * sysdep.c (emacs_open): Add commentary and don't call file name "path". (emacs_fopen): New function. * unexaix.c, unexcoff.c, unexelf.c, unexhp9k800.c, unexmacosx.c: Include , for emacs_open. * unexelf.c (fatal): Remove decl; not needed with included. diff: === modified file 'src/ChangeLog' --- src/ChangeLog 2013-07-05 16:58:01 +0000 +++ src/ChangeLog 2013-07-06 02:40:50 +0000 @@ -1,5 +1,37 @@ 2013-07-05 Paul Eggert + Use emacs_open more consistently when opening files. + This handles EINTR more consistently now, and makes it easier + to introduce other uniform changes to file descriptor handling. + * src/systdio.h: New file. + * src/buffer.c (mmap_init): + * cygw32.c (chdir_to_default_directory): + * dispnew.c (Fopen_termscript): + * emacs.c (Fdaemon_initialized): + * fileio.c (Fdo_auto_save): + * image.c (slurp_file, png_load_body, jpeg_load_body): + * keyboard.c (Fopen_dribble_file): + * lread.c (Fload): + * print.c (Fredirect_debugging_output): + * sysdep.c (get_up_time, procfs_ttyname, procfs_get_total_memory): + * termcap.c (tgetent): + * unexaix.c, unexcoff.c (unexec, adjust_lnnoptrs): + * unexcw.c, unexelf.c, unexhp9k800.c, unexmacosx.c (unexec): + * w32term.c (w32_initialize) [CYGWIN]: + * xfaces.c (Fx_load_color_file): + Use emacs_open instead of plain open, and emacs_fopen instead of + plain fopen. + * dispnew.c, fileio.c, image.c, keyboard.c, lread.c, print.c, sysdep.c: + * xfaces.c: Include sysstdio.h rather than stdio.h, for emacs_fopen. + * callproc.c (default_output_mode): New constant. + (Fcall_process): Use it to call emacs_open instead of plain creat. + * dispnew.c (Fopen_termscript): Fix minor race in opening termscript. + * sysdep.c (emacs_open): Add commentary and don't call file name "path". + (emacs_fopen): New function. + * unexaix.c, unexcoff.c, unexelf.c, unexhp9k800.c, unexmacosx.c: + Include , for emacs_open. + * unexelf.c (fatal): Remove decl; not needed with included. + Remove duplicate #include directives. * alloc.c [GC_MARK_STACK == GC_USE_GCPROS_CHECK_ZOMBIES]: * xfaces.c: === modified file 'src/buffer.c' --- src/buffer.c 2013-07-05 16:58:01 +0000 +++ src/buffer.c 2013-07-06 02:40:50 +0000 @@ -4726,7 +4726,7 @@ if (mmap_fd <= 0) { /* No anonymous mmap -- we need the file descriptor. */ - mmap_fd = open ("/dev/zero", O_RDONLY); + mmap_fd = emacs_open ("/dev/zero", O_RDONLY, 0); if (mmap_fd == -1) fatal ("Cannot open /dev/zero: %s", emacs_strerror (errno)); } === modified file 'src/callproc.c' --- src/callproc.c 2013-06-27 14:47:52 +0000 +++ src/callproc.c 2013-07-06 02:40:50 +0000 @@ -186,6 +186,12 @@ return Qnil; } +#ifdef DOS_NT +static mode_t const default_output_mode = S_IREAD | S_IWRITE; +#else +static mode_t const default_output_mode = 0666; +#endif + DEFUN ("call-process", Fcall_process, Scall_process, 1, MANY, 0, doc: /* Call PROGRAM synchronously in separate process. The remaining arguments are optional. @@ -407,13 +413,9 @@ if (STRINGP (output_file)) { -#ifdef DOS_NT fd_output = emacs_open (SSDATA (output_file), - O_WRONLY | O_TRUNC | O_CREAT | O_TEXT, - S_IREAD | S_IWRITE); -#else /* not DOS_NT */ - fd_output = creat (SSDATA (output_file), 0666); -#endif /* not DOS_NT */ + O_WRONLY | O_CREAT | O_TRUNC | O_TEXT, + default_output_mode); if (fd_output < 0) { output_file = DECODE_FILE (output_file); @@ -492,7 +494,8 @@ strcat (tempfile, "/"); strcat (tempfile, "detmp.XXX"); mktemp (tempfile); - outfilefd = creat (tempfile, S_IREAD | S_IWRITE); + outfilefd = emacs_open (tempfile, O_WRONLY | O_CREAT | O_TRUNC, + S_IREAD | S_IWRITE); if (outfilefd < 0) { emacs_close (filefd); report_file_error ("Opening process output file", @@ -535,15 +538,9 @@ if (NILP (error_file)) fd_error = emacs_open (NULL_DEVICE, O_WRONLY, 0); else if (STRINGP (error_file)) - { -#ifdef DOS_NT - fd_error = emacs_open (SSDATA (error_file), - O_WRONLY | O_TRUNC | O_CREAT | O_TEXT, - S_IREAD | S_IWRITE); -#else /* not DOS_NT */ - fd_error = creat (SSDATA (error_file), 0666); -#endif /* not DOS_NT */ - } + fd_error = emacs_open (SSDATA (error_file), + O_WRONLY | O_CREAT | O_TRUNC | O_TEXT, + default_output_mode); if (fd_error < 0) { === modified file 'src/cygw32.c' --- src/cygw32.c 2013-01-02 16:13:04 +0000 +++ src/cygw32.c 2013-07-06 02:40:50 +0000 @@ -35,7 +35,7 @@ chdir_to_default_directory () { Lisp_Object new_cwd; - int old_cwd_fd = open (".", O_RDONLY | O_DIRECTORY); + int old_cwd_fd = emacs_open (".", O_RDONLY | O_DIRECTORY, 0); if (old_cwd_fd == -1) error ("could not open current directory: %s", strerror (errno)); === modified file 'src/dispnew.c' --- src/dispnew.c 2013-04-02 01:54:56 +0000 +++ src/dispnew.c 2013-07-06 02:40:50 +0000 @@ -22,7 +22,7 @@ #define DISPEXTERN_INLINE EXTERN_INLINE -#include +#include "sysstdio.h" #include #include "lisp.h" @@ -5605,17 +5605,17 @@ tty = CURTTY (); if (tty->termscript != 0) - { - block_input (); - fclose (tty->termscript); - unblock_input (); - } - tty->termscript = 0; + { + block_input (); + fclose (tty->termscript); + tty->termscript = 0; + unblock_input (); + } if (! NILP (file)) { file = Fexpand_file_name (file, Qnil); - tty->termscript = fopen (SSDATA (file), "w"); + tty->termscript = emacs_fopen (SSDATA (file), "w"); if (tty->termscript == 0) report_file_error ("Opening termscript", Fcons (file, Qnil)); } === modified file 'src/emacs.c' --- src/emacs.c 2013-07-04 06:20:55 +0000 +++ src/emacs.c 2013-07-06 02:40:50 +0000 @@ -2236,7 +2236,7 @@ error ("This function can only be called after loading the init files"); /* Get rid of stdin, stdout and stderr. */ - nfd = open ("/dev/null", O_RDWR); + nfd = emacs_open ("/dev/null", O_RDWR, 0); err |= nfd < 0; err |= dup2 (nfd, 0) < 0; err |= dup2 (nfd, 1) < 0; === modified file 'src/fileio.c' --- src/fileio.c 2013-07-05 16:58:01 +0000 +++ src/fileio.c 2013-07-06 02:40:50 +0000 @@ -20,7 +20,7 @@ #include #include #include -#include +#include "sysstdio.h" #include #include #include @@ -5618,7 +5618,7 @@ UNGCPRO; } - stream = fopen (SSDATA (listfile), "w"); + stream = emacs_fopen (SSDATA (listfile), "w"); } record_unwind_protect (do_auto_save_unwind, === modified file 'src/image.c' --- src/image.c 2013-07-04 15:25:54 +0000 +++ src/image.c 2013-07-06 02:40:50 +0000 @@ -18,7 +18,7 @@ along with GNU Emacs. If not, see . */ #include -#include +#include "sysstdio.h" #include #ifdef HAVE_PNG @@ -2274,7 +2274,7 @@ static unsigned char * slurp_file (char *file, ptrdiff_t *size) { - FILE *fp = fopen (file, "rb"); + FILE *fp = emacs_fopen (file, "rb"); unsigned char *buf = NULL; struct stat st; @@ -5723,7 +5723,7 @@ } /* Open the image file. */ - fp = fopen (SSDATA (file), "rb"); + fp = emacs_fopen (SSDATA (file), "rb"); if (!fp) { image_error ("Cannot open image file `%s'", file, Qnil); @@ -6484,7 +6484,7 @@ return 0; } - fp = fopen (SSDATA (file), "rb"); + fp = emacs_fopen (SSDATA (file), "rb"); if (fp == NULL) { image_error ("Cannot open `%s'", file, Qnil); === modified file 'src/keyboard.c' --- src/keyboard.c 2013-07-06 00:10:54 +0000 +++ src/keyboard.c 2013-07-06 02:40:50 +0000 @@ -23,7 +23,7 @@ #define BLOCKINPUT_INLINE EXTERN_INLINE #define KEYBOARD_INLINE EXTERN_INLINE -#include +#include "sysstdio.h" #include "lisp.h" #include "termchar.h" @@ -10129,7 +10129,7 @@ if (!NILP (file)) { file = Fexpand_file_name (file, Qnil); - dribble = fopen (SSDATA (file), "w"); + dribble = emacs_fopen (SSDATA (file), "w"); if (dribble == 0) report_file_error ("Opening dribble", Fcons (file, Qnil)); } === modified file 'src/lread.c' --- src/lread.c 2013-07-05 16:58:01 +0000 +++ src/lread.c 2013-07-06 02:40:50 +0000 @@ -20,7 +20,7 @@ #include -#include +#include "sysstdio.h" #include #include #include @@ -1297,7 +1297,7 @@ if (fd >= 0) { emacs_close (fd); - stream = fopen (SSDATA (efound), fmode); + stream = emacs_fopen (SSDATA (efound), fmode); } else stream = NULL; === modified file 'src/print.c' --- src/print.c 2013-07-02 03:41:16 +0000 +++ src/print.c 2013-07-06 02:40:50 +0000 @@ -20,7 +20,7 @@ #include -#include +#include "sysstdio.h" #include "lisp.h" #include "character.h" @@ -765,7 +765,7 @@ { file = Fexpand_file_name (file, Qnil); initial_stderr_stream = stderr; - stderr = fopen (SSDATA (file), NILP (append) ? "w" : "a"); + stderr = emacs_fopen (SSDATA (file), NILP (append) ? "w" : "a"); if (stderr == NULL) { stderr = initial_stderr_stream; === modified file 'src/sysdep.c' --- src/sysdep.c 2013-07-02 22:14:42 +0000 +++ src/sysdep.c 2013-07-06 02:40:50 +0000 @@ -22,7 +22,7 @@ #define SYSTIME_INLINE EXTERN_INLINE #include -#include +#include "sysstdio.h" #ifdef HAVE_PWD_H #include #include @@ -2151,15 +2151,29 @@ } #endif +/* Open FILE for Emacs use, using open flags OFLAG and mode MODE. + Do not fail merely because the open was interrupted by a signal. + Allow the user to quit. */ + int -emacs_open (const char *path, int oflag, int mode) -{ - register int rtnval; - - while ((rtnval = open (path, oflag, mode)) == -1 - && (errno == EINTR)) - QUIT; - return (rtnval); +emacs_open (const char *file, int oflags, int mode) +{ + int fd; + while ((fd = open (file, oflags, mode)) < 0 && errno == EINTR) + QUIT; + return fd; +} + +/* Open FILE as a stream for Emacs use, with mode MODE. + Act like emacs_open with respect to threads, signals, and quits. */ + +FILE * +emacs_fopen (char const *file, char const *mode) +{ + FILE *fp; + while (! (fp = fopen (file, mode)) && errno == EINTR) + QUIT; + return fp; } int @@ -2637,7 +2651,7 @@ EMACS_TIME up = make_emacs_time (0, 0); block_input (); - fup = fopen ("/proc/uptime", "r"); + fup = emacs_fopen ("/proc/uptime", "r"); if (fup) { @@ -2682,7 +2696,7 @@ char name[PATH_MAX]; block_input (); - fdev = fopen ("/proc/tty/drivers", "r"); + fdev = emacs_fopen ("/proc/tty/drivers", "r"); if (fdev) { @@ -2724,7 +2738,7 @@ unsigned long retval = 2 * 1024 * 1024; /* default: 2GB */ block_input (); - fmem = fopen ("/proc/meminfo", "r"); + fmem = emacs_fopen ("/proc/meminfo", "r"); if (fmem) { === added file 'src/sysstdio.h' --- src/sysstdio.h 1970-01-01 00:00:00 +0000 +++ src/sysstdio.h 2013-07-06 02:40:50 +0000 @@ -0,0 +1,2 @@ +#include +extern FILE *emacs_fopen (char const *, char const *); === modified file 'src/term.c' --- src/term.c 2013-06-03 19:28:13 +0000 +++ src/term.c 2013-07-06 02:40:50 +0000 @@ -2479,7 +2479,7 @@ const char *name; int fd; name = (const char *) ttyname (0); - fd = open (name, O_WRONLY); + fd = emacs_open (name, O_WRONLY, 0); SOME_FUNCTION (x, y, fd); close (fd); last_mouse_x = x; === modified file 'src/termcap.c' --- src/termcap.c 2013-02-02 17:14:24 +0000 +++ src/termcap.c 2013-07-06 02:40:50 +0000 @@ -427,11 +427,7 @@ /* Here we know we must search a file and termcap_name has its name. */ -#ifdef MSDOS - fd = open (termcap_name, O_RDONLY|O_TEXT, 0); -#else - fd = open (termcap_name, O_RDONLY, 0); -#endif + fd = emacs_open (termcap_name, O_RDONLY | O_TEXT, 0); if (fd < 0) return -1; === modified file 'src/unexaix.c' --- src/unexaix.c 2013-02-25 05:55:37 +0000 +++ src/unexaix.c 2013-07-06 02:40:50 +0000 @@ -42,6 +42,7 @@ #include #include "unexec.h" +#include "lisp.h" #define PERROR(file) report_error (file, new) #include @@ -132,11 +133,11 @@ { int new = -1, a_out = -1; - if (a_name && (a_out = open (a_name, O_RDONLY)) < 0) + if (a_name && (a_out = emacs_open (a_name, O_RDONLY, 0)) < 0) { PERROR (a_name); } - if ((new = creat (new_name, 0666)) < 0) + if ((new = emacs_open (new_name, O_WRONLY | O_CREAT | O_TRUNC, 0666)) < 0) { PERROR (new_name); } @@ -503,7 +504,7 @@ if (!lnnoptr || !f_hdr.f_symptr) return 0; - if ((new = open (new_name, O_RDWR)) < 0) + if ((new = emacs_open (new_name, O_RDWR, 0)) < 0) { PERROR (new_name); return -1; === modified file 'src/unexcoff.c' --- src/unexcoff.c 2013-02-25 05:55:37 +0000 +++ src/unexcoff.c 2013-07-06 02:40:50 +0000 @@ -52,6 +52,7 @@ #include #include "unexec.h" +#include "lisp.h" #define PERROR(file) report_error (file, new) @@ -486,7 +487,7 @@ #ifdef MSDOS if ((new = writedesc) < 0) #else - if ((new = open (new_name, O_RDWR)) < 0) + if ((new = emacs_open (new_name, O_RDWR, 0)) < 0) #endif { PERROR (new_name); @@ -525,11 +526,11 @@ { int new = -1, a_out = -1; - if (a_name && (a_out = open (a_name, O_RDONLY)) < 0) + if (a_name && (a_out = emacs_open (a_name, O_RDONLY, 0)) < 0) { PERROR (a_name); } - if ((new = creat (new_name, 0666)) < 0) + if ((new = emacs_open (new_name, O_WRONLY | O_CREAT | O_TRUNC, 0666)) < 0) { PERROR (new_name); } === modified file 'src/unexcw.c' --- src/unexcw.c 2013-03-22 16:52:31 +0000 +++ src/unexcw.c 2013-07-06 02:40:50 +0000 @@ -20,8 +20,8 @@ #include #include "unexec.h" +#include "lisp.h" -#include #include #include #include @@ -298,9 +298,9 @@ infile = add_exe_suffix_if_necessary (infile, infile_buffer); outfile = add_exe_suffix_if_necessary (outfile, outfile_buffer); - fd_in = open (infile, O_RDONLY | O_BINARY); + fd_in = emacs_open (infile, O_RDONLY | O_BINARY, 0); assert (fd_in >= 0); - fd_out = open (outfile, O_RDWR | O_TRUNC | O_CREAT | O_BINARY, 0755); + fd_out = emacs_open (outfile, O_RDWR | O_TRUNC | O_CREAT | O_BINARY, 0755); assert (fd_out >= 0); for (;;) { === modified file 'src/unexelf.c' --- src/unexelf.c 2013-05-07 20:55:47 +0000 +++ src/unexelf.c 2013-07-06 02:40:50 +0000 @@ -386,9 +386,8 @@ Instead we read the whole file, modify it, and write it out. */ #include -#include - -extern _Noreturn void fatal (const char *, ...) ATTRIBUTE_FORMAT_PRINTF (1, 2); +#include "unexec.h" +#include "lisp.h" #include #include @@ -672,7 +671,7 @@ /* Open the old file, allocate a buffer of the right size, and read in the file contents. */ - old_file = open (old_name, O_RDONLY); + old_file = emacs_open (old_name, O_RDONLY, 0); if (old_file < 0) fatal ("Can't open %s for reading: %s", old_name, strerror (errno)); @@ -681,7 +680,7 @@ fatal ("Can't fstat (%s): %s", old_name, strerror (errno)); #if MAP_ANON == 0 - mmap_fd = open ("/dev/zero", O_RDONLY); + mmap_fd = emacs_open ("/dev/zero", O_RDONLY, 0); if (mmap_fd < 0) fatal ("Can't open /dev/zero for reading: %s", strerror (errno)); #endif @@ -801,7 +800,7 @@ the image of the new file. Set pointers to various interesting objects. */ - new_file = open (new_name, O_RDWR | O_CREAT, 0666); + new_file = emacs_open (new_name, O_RDWR | O_CREAT, 0666); if (new_file < 0) fatal ("Can't creat (%s): %s", new_name, strerror (errno)); === modified file 'src/unexhp9k800.c' --- src/unexhp9k800.c 2011-07-10 08:20:10 +0000 +++ src/unexhp9k800.c 2013-07-06 02:40:50 +0000 @@ -51,6 +51,7 @@ #include #include "unexec.h" +#include "lisp.h" #include #include @@ -268,10 +269,10 @@ intact. NOT implemented. */ /* Open the input and output a.out files */ - old = open (old_name, O_RDONLY); + old = emacs_open (old_name, O_RDONLY, 0); if (old < 0) { perror (old_name); exit (1); } - new = open (new_name, O_CREAT|O_RDWR|O_TRUNC, 0777); + new = emacs_open (new_name, O_CREAT | O_RDWR | O_TRUNC, 0777); if (new < 0) { perror (new_name); exit (1); } === modified file 'src/unexmacosx.c' --- src/unexmacosx.c 2013-01-23 01:51:49 +0000 +++ src/unexmacosx.c 2013-07-06 02:40:50 +0000 @@ -97,6 +97,7 @@ #undef free #include "unexec.h" +#include "lisp.h" #include #include @@ -1322,13 +1323,13 @@ unexec_error ("Unexec from a dumped executable is not supported."); pagesize = getpagesize (); - infd = open (infile, O_RDONLY, 0); + infd = emacs_open (infile, O_RDONLY, 0); if (infd < 0) { unexec_error ("cannot open input file `%s'", infile); } - outfd = open (outfile, O_WRONLY | O_TRUNC | O_CREAT, 0755); + outfd = emacs_open (outfile, O_WRONLY | O_TRUNC | O_CREAT, 0755); if (outfd < 0) { close (infd); === modified file 'src/w32term.c' --- src/w32term.c 2013-07-04 10:25:54 +0000 +++ src/w32term.c 2013-07-06 02:40:50 +0000 @@ -6621,7 +6621,7 @@ } #ifdef CYGWIN - if ((w32_message_fd = open ("/dev/windows", O_RDWR | O_CLOEXEC)) == -1) + if ((w32_message_fd = emacs_open ("/dev/windows", O_RDWR, 0)) == -1) fatal ("opening /dev/windows: %s", strerror (errno)); #endif /* CYGWIN */ === modified file 'src/xfaces.c' --- src/xfaces.c 2013-07-05 16:58:01 +0000 +++ src/xfaces.c 2013-07-06 02:40:50 +0000 @@ -200,7 +200,7 @@ used to fill in unspecified attributes of the default face. */ #include -#include +#include "sysstdio.h" #include #include @@ -6290,7 +6290,7 @@ CHECK_STRING (filename); abspath = Fexpand_file_name (filename, Qnil); - fp = fopen (SSDATA (abspath), "rt"); + fp = emacs_fopen (SSDATA (abspath), "rt"); if (fp) { char buf[512];