Mercurial > emacs
changeset 82993:0abaf12fa706
Merged in changes from CVS HEAD
Patches applied:
* miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-10
Update from CVS
* miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-11
Update from CVS
* miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-12
Add section on button package to lisp reference manual
* miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-13
Minor tweaks to Buttons section in lispref/display.texi
* miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-14
Update from CVS
git-archimport-id: lorentey@elte.hu--2004/emacs--multi-tty--0--patch-33
author | Karoly Lorentey <lorentey@elte.hu> |
---|---|
date | Fri, 02 Jan 2004 04:37:46 +0000 |
parents | 5de4189e659d (current diff) e93d01ecd023 (diff) |
children | 44ffe551079c |
files | lisp/ChangeLog src/print.c src/process.c src/w32term.c |
diffstat | 18 files changed, 741 insertions(+), 120 deletions(-) [+] |
line wrap: on
line diff
--- a/etc/NEWS Fri Jan 02 04:22:23 2004 +0000 +++ b/etc/NEWS Fri Jan 02 04:37:46 2004 +0000 @@ -1,5 +1,5 @@ GNU Emacs NEWS -- history of user-visible changes. 2003-05-21 -Copyright (C) 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc. +Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc. See the end for copying conditions. Please send Emacs bug reports to bug-gnu-emacs@gnu.org. @@ -104,7 +104,10 @@ ** Help mode now only makes hyperlinks for faces when the face name is preceded or followed by the word `face'. It no longer makes hyperlinks for variables without variable documentation, unless -preceded by one of the words `variable' or `option'. +preceded by one of the words `variable' or `option'. It now makes +hyperlinks to Info anchors (or nodes) if the anchor (or node) name is +enclosed in single quotes and preceded by `info anchor' or `Info +anchor' (in addition to earlier `info node' and `Info node'). ** The max size of buffers and integers has been doubled. On 32bit machines, it is now 256M (i.e. 268435455). @@ -2520,6 +2523,17 @@ The new low-level functions process-plist and set-process-plist are used to access and replace the entire property list of a process. +??? +*** Adaptive read buffering of subprocess output. + +On some systems, when emacs reads the output from a subprocess, the +output data is read in very small blocks, potentially resulting in +very poor performance. This behaviour can be remedied to some extent +by setting the new variable process-adaptive-read-buffering to a +non-nil value (the default), as it will automatically delay reading +from such processes, to allowing them to produce more output before +emacs tries to read it. + +++ ** Enhanced networking support.
--- a/lisp/ChangeLog Fri Jan 02 04:22:23 2004 +0000 +++ b/lisp/ChangeLog Fri Jan 02 04:37:46 2004 +0000 @@ -1,3 +1,23 @@ +2003-12-31 John Paul Wallington <jpw@gnu.org> + + * bindings.el (completion-ignored-extensions): Add .pfsl. + +2003-12-31 Kim F. Storm <storm@cua.dk> + + * ido.el (ido-nonreadable-directory-p): New defun to check for + nonreadable directory without activating tramp (to avoid problems + with checking incomplete tramp paths. + (ido-set-current-directory, ido-file-internal) + (ido-file-name-all-completions1): Use it. + +2003-12-30 Luc Teirlinck <teirllm@auburn.edu> + + * help-mode.el (help-xref-info-regexp): Make hyperlinks to Info + documentation if the anchor (or node) name is preceded by `info + anchor' or `Info anchor' in addition to earlier `info node' and + `Info node'. + (help-make-xrefs): Adapt to new value of `help-xref-info-regexp'. + 2003-12-30 Eli Zaretskii <eliz@elta.co.il> * mail/rmail.el (rmail-convert-to-babyl-format): Fix off-by-one
--- a/lisp/bindings.el Fri Jan 02 04:22:23 2004 +0000 +++ b/lisp/bindings.el Fri Jan 02 04:37:46 2004 +0000 @@ -258,14 +258,14 @@ (defvar mode-line-modes nil "Mode-line control for displaying major and minor modes.") -(defvar mode-line-major-mode-keymap +(defvar mode-line-major-mode-keymap (let ((map (make-sparse-keymap))) (define-key map [mode-line mouse-2] 'describe-mode) (define-key map [mode-line down-mouse-3] 'mode-line-mode-menu-1) map) "\ Keymap to display on major mode.") -(defvar mode-line-minor-mode-keymap +(defvar mode-line-minor-mode-keymap (let ((map (make-sparse-keymap))) (define-key map [mode-line mouse-2] 'mode-line-minor-mode-help) (define-key map [mode-line down-mouse-3] 'mode-line-mode-menu-1) @@ -314,7 +314,7 @@ (setq-default mode-line-position `((-3 ,(propertize "%p" 'help-echo help-echo)) - (size-indication-mode + (size-indication-mode (8 ,(propertize " of %I" 'help-echo help-echo))) (line-number-mode ((column-number-mode @@ -511,8 +511,8 @@ ".fas" ".lib" ".mem" ;; CMUCL ".x86f" ".sparcf" - ;; Other CL implementations (Allegro, LispWorks) - ".fasl" ".ufsl" ".fsl" ".dxl" + ;; Other CL implementations (Allegro, LispWorks, OpenMCL) + ".fasl" ".ufsl" ".fsl" ".dxl" ".pfsl" ;; Libtool ".lo" ".la" ;; Gettext
--- a/lisp/help-mode.el Fri Jan 02 04:22:23 2004 +0000 +++ b/lisp/help-mode.el Fri Jan 02 04:37:46 2004 +0000 @@ -231,7 +231,7 @@ (defconst help-xref-info-regexp - (purecopy "\\<[Ii]nfo[ \t\n]+node[ \t\n]+`\\([^']+\\)'") + (purecopy "\\<[Ii]nfo[ \t\n]+\\(node\\|anchor\\)[ \t\n]+`\\([^']+\\)'") "Regexp matching doc string references to an Info node.") ;;;###autoload @@ -310,11 +310,11 @@ ;; Info references (save-excursion (while (re-search-forward help-xref-info-regexp nil t) - (let ((data (match-string 1))) + (let ((data (match-string 2))) (save-match-data (unless (string-match "^([^)]+)" data) (setq data (concat "(emacs)" data)))) - (help-xref-button 1 'help-info data)))) + (help-xref-button 2 'help-info data)))) ;; Mule related keywords. Do this before trying ;; `help-xref-symbol-regexp' because some of Mule ;; keywords have variable or function definitions.
--- a/lisp/ido.el Fri Jan 02 04:22:23 2004 +0000 +++ b/lisp/ido.el Fri Jan 02 04:37:46 2004 +0000 @@ -1397,6 +1397,15 @@ (substring s 0 l) s))) +(defun ido-nonreadable-directory-p (dir) + ;; Return t if dir is a directory, but not readable + ;; Do not check for non-readable directories via tramp, as this causes a premature + ;; connect on incomplete tramp paths (after entring just method:). + (let ((ido-enable-tramp-completion nil)) + (and (ido-final-slash dir) + (file-directory-p dir) + (not (file-readable-p dir))))) + (defun ido-set-current-directory (dir &optional subdir no-merge) ;; Set ido's current directory to DIR or DIR/SUBDIR (setq dir (ido-final-slash dir t)) @@ -1410,7 +1419,7 @@ (setq ido-current-directory dir) (if (get-buffer ido-completion-buffer) (kill-buffer ido-completion-buffer)) - (setq ido-directory-nonreadable (not (file-readable-p dir))) + (setq ido-directory-nonreadable (ido-nonreadable-directory-p dir)) t)) (defun ido-set-current-home (&optional dir) @@ -1867,7 +1876,7 @@ (unless item (setq item 'file)) (let* ((ido-current-directory (ido-expand-directory default)) - (ido-directory-nonreadable (not (file-readable-p ido-current-directory))) + (ido-directory-nonreadable (ido-nonreadable-directory-p ido-current-directory)) filename) (cond @@ -2706,7 +2715,7 @@ (defun ido-file-name-all-completions1 (dir) (cond - ((not (file-readable-p dir)) '()) + ((ido-nonreadable-directory-p dir) '()) ((and ido-enable-tramp-completion (string-match "\\`/\\([^/:]+:\\([^/:@]+@\\)?\\)\\'" dir))
--- a/lispref/ChangeLog Fri Jan 02 04:22:23 2004 +0000 +++ b/lispref/ChangeLog Fri Jan 02 04:37:46 2004 +0000 @@ -1,3 +1,32 @@ +2004-01-01 Miles Bader <miles@gnu.org> + + * display.texi (Buttons): New section. + +2003-12-31 Andreas Schwab <schwab@suse.de> + + * numbers.texi (Math Functions): sqrt reports a domain-error + error. + (Float Basics): Use `(/ 0.0 0.0)' instead of `(sqrt -1.0)'. + +2003-12-30 Luc Teirlinck <teirllm@auburn.edu> + + * tips.texi (Documentation Tips): Update item on hyperlinks in + documentation strings. + + * errors.texi (Standard Errors): Various small corrections and + additions. + + * control.texi: Various small changes in addition to the + following. + (Signaling Errors): Provide some more details on how `signal' + constructs the error message. Add anchor to the definition of + `signal'. + (Error Symbols): Describe special treatment of `quit'. + (Cleanups): Rename BODY argument of `unwind-protect' to BODY-FORM + to emphasize that it has to be a single form. + + * buffers.texi: Add anchor. + 2003-12-29 Richard M. Stallman <rms@gnu.org> * windows.texi (Choosing Window): Add same-window-p, special-display-p. @@ -16,9 +45,9 @@ * os.texi (Time of Day): Add set-time-zone-rule. * numbers.texi (Math Functions): asin, acos, log, log10 - report domain-error errors. + report domain-error errors. - * nonascii.texi (Converting Representations): + * nonascii.texi (Converting Representations): Add multibyte-char-to-unibyte and unibyte-char-to-multibyte. (Encoding and I/O): Add file-name-coding-system. @@ -36,7 +65,7 @@ * frames.texi (Frames and Windows): Add set-frame-selected-window and frame-root-window. - * files.texi (Contents of Directories): + * files.texi (Contents of Directories): Add directory-files-and-attributes. * display.texi (Refresh Screen): Add force-window-update. @@ -81,7 +110,7 @@ mention `eval-current-buffer' as an alias for `current-buffer'. Correct the description and mention all optional arguments. - * nonascii.texi : Various small changes in addition to the + * nonascii.texi: Various small changes in addition to the following. (Converting Representations): Clarify behavior of `string-make-multibyte' and `string-to-multibyte' for unibyte all
--- a/lispref/buffers.texi Fri Jan 02 04:22:23 2004 +0000 +++ b/lispref/buffers.texi Fri Jan 02 04:37:46 2004 +0000 @@ -223,6 +223,7 @@ abnormal exit via @code{throw} or error (@pxref{Nonlocal Exits}). @end defmac +@anchor{Definition of with-temp-buffer} @defmac with-temp-buffer body... The @code{with-temp-buffer} macro evaluates the @var{body} forms with a temporary buffer as the current buffer. It saves the identity of
--- a/lispref/control.texi Fri Jan 02 04:22:23 2004 +0000 +++ b/lispref/control.texi Fri Jan 02 04:37:46 2004 +0000 @@ -496,7 +496,7 @@ (inclusive) to @var{count} (exclusive), using the variable @var{var} to hold the integer for the current iteration. Then it returns the value of evaluating @var{result}, or @code{nil} if @var{result} is omitted. -Here is an example of using @code{dotimes} do something 100 times: +Here is an example of using @code{dotimes} to do something 100 times: @example (dotimes (i 100) @@ -757,7 +757,7 @@ @defun error format-string &rest args This function signals an error with an error message constructed by -applying @code{format} (@pxref{String Conversion}) to +applying @code{format} (@pxref{Formatting Strings}) to @var{format-string} and @var{args}. These examples show typical uses of @code{error}: @@ -784,6 +784,7 @@ undesirable results. Instead, use @code{(error "%s" @var{string})}. @end defun +@anchor{Definition of signal} @defun signal error-symbol data This function signals an error named by @var{error-symbol}. The argument @var{data} is a list of additional Lisp objects relevant to the @@ -792,19 +793,26 @@ The argument @var{error-symbol} must be an @dfn{error symbol}---a symbol bearing a property @code{error-conditions} whose value is a list of condition names. This is how Emacs Lisp classifies different sorts of -errors. +errors. @xref{Error Symbols}, for a description of error symbols, +error conditions and condition names. + +If the error is not handled, the two arguments are used in printing +the error message. Normally, this error message is provided by the +@code{error-message} property of @var{error-symbol}. If @var{data} is +non-@code{nil}, this is followed by a colon and a comma separated list +of the unevaluated elements of @var{data}. For @code{error}, the +error message is the @sc{car} of @var{data} (that must be a string). +Subcategories of @code{file-error} are handled specially. The number and significance of the objects in @var{data} depends on @var{error-symbol}. For example, with a @code{wrong-type-arg} error, there should be two objects in the list: a predicate that describes the type that was expected, and the object that failed to fit that type. -@xref{Error Symbols}, for a description of error symbols. Both @var{error-symbol} and @var{data} are available to any error handlers that handle the error: @code{condition-case} binds a local variable to a list of the form @code{(@var{error-symbol} .@: -@var{data})} (@pxref{Handling Errors}). If the error is not handled, -these two values are used in printing the error message. +@var{data})} (@pxref{Handling Errors}). The function @code{signal} never returns (though in older Emacs versions it could sometimes return). @@ -989,7 +997,7 @@ @defun error-message-string error-description This function returns the error message string for a given error descriptor. It is useful if you want to handle an error by printing the -usual error message for that error. +usual error message for that error. @xref{Definition of signal}. @end defun @cindex @code{arith-error} example @@ -1071,10 +1079,10 @@ names}. The narrowest such classes belong to the error symbols themselves: each error symbol is also a condition name. There are also condition names for more extensive classes, up to the condition name -@code{error} which takes in all kinds of errors. Thus, each error has -one or more condition names: @code{error}, the error symbol if that -is distinct from @code{error}, and perhaps some intermediate -classifications. +@code{error} which takes in all kinds of errors (but not @code{quit}). +Thus, each error has one or more condition names: @code{error}, the +error symbol if that is distinct from @code{error}, and perhaps some +intermediate classifications. In order for a symbol to be an error symbol, it must have an @code{error-conditions} property which gives a list of condition names. @@ -1082,13 +1090,16 @@ (The error symbol itself, and the symbol @code{error}, should always be members of this list.) Thus, the hierarchy of condition names is defined by the @code{error-conditions} properties of the error symbols. +Because quitting is not considered an error, the value of the +@code{error-conditions} property of @code{quit} is just @code{(quit)}. +@cindex peculiar error In addition to the @code{error-conditions} list, the error symbol should have an @code{error-message} property whose value is a string to be printed when that error is signaled but not handled. If the +error symbol has no @code{error-message} property or if the @code{error-message} property exists, but is not a string, the error -message @samp{peculiar error} is used. -@cindex peculiar error +message @samp{peculiar error} is used. @xref{Definition of signal}. Here is how we define a new error symbol, @code{new-error}: @@ -1114,8 +1125,8 @@ not end with a period. This is for consistency with the rest of Emacs. Naturally, Emacs will never signal @code{new-error} on its own; only -an explicit call to @code{signal} (@pxref{Signaling Errors}) in your -code can do this: +an explicit call to @code{signal} (@pxref{Definition of signal}) in +your code can do this: @example @group @@ -1158,32 +1169,34 @@ temporarily put a data structure in an inconsistent state; it permits you to make the data consistent again in the event of an error or throw. -@defspec unwind-protect body cleanup-forms@dots{} +@defspec unwind-protect body-form cleanup-forms@dots{} @cindex cleanup forms @cindex protected forms @cindex error cleanup @cindex unwinding -@code{unwind-protect} executes the @var{body} with a guarantee that the -@var{cleanup-forms} will be evaluated if control leaves @var{body}, no -matter how that happens. The @var{body} may complete normally, or -execute a @code{throw} out of the @code{unwind-protect}, or cause an -error; in all cases, the @var{cleanup-forms} will be evaluated. +@code{unwind-protect} executes @var{body-form} with a guarantee that +the @var{cleanup-forms} will be evaluated if control leaves +@var{body-form}, no matter how that happens. @var{body-form} may +complete normally, or execute a @code{throw} out of the +@code{unwind-protect}, or cause an error; in all cases, the +@var{cleanup-forms} will be evaluated. -If the @var{body} forms finish normally, @code{unwind-protect} returns -the value of the last @var{body} form, after it evaluates the -@var{cleanup-forms}. If the @var{body} forms do not finish, -@code{unwind-protect} does not return any value in the normal sense. +If @var{body-form} finishes normally, @code{unwind-protect} returns the +value of @var{body-form}, after it evaluates the @var{cleanup-forms}. +If @var{body-form} does not finish, @code{unwind-protect} does not +return any value in the normal sense. -Only the @var{body} is protected by the @code{unwind-protect}. If any +Only @var{body-form} is protected by the @code{unwind-protect}. If any of the @var{cleanup-forms} themselves exits nonlocally (via a @code{throw} or an error), @code{unwind-protect} is @emph{not} guaranteed to evaluate the rest of them. If the failure of one of the -@var{cleanup-forms} has the potential to cause trouble, then protect it -with another @code{unwind-protect} around that form. +@var{cleanup-forms} has the potential to cause trouble, then protect +it with another @code{unwind-protect} around that form. The number of currently active @code{unwind-protect} forms counts, together with the number of local variable bindings, against the limit -@code{max-specpdl-size} (@pxref{Local Variables}). +@code{max-specpdl-size} (@pxref{Definition of max-specpdl-size,, Local +Variables}). @end defspec For example, here we make an invisible buffer for temporary use, and @@ -1195,7 +1208,7 @@ (let ((buffer (get-buffer-create " *temp*"))) (set-buffer buffer) (unwind-protect - @var{body} + @var{body-form} (kill-buffer buffer)))) @end group @end smallexample @@ -1203,15 +1216,16 @@ @noindent You might think that we could just as well write @code{(kill-buffer (current-buffer))} and dispense with the variable @code{buffer}. -However, the way shown above is safer, if @var{body} happens to get an -error after switching to a different buffer! (Alternatively, you could -write another @code{save-excursion} around the body, to ensure that the -temporary buffer becomes current again in time to kill it.) +However, the way shown above is safer, if @var{body-form} happens to +get an error after switching to a different buffer! (Alternatively, +you could write another @code{save-excursion} around @var{body-form}, +to ensure that the temporary buffer becomes current again in time to +kill it.) Emacs includes a standard macro called @code{with-temp-buffer} which -expands into more or less the code shown above (@pxref{Current Buffer}). -Several of the macros defined in this manual use @code{unwind-protect} -in this way. +expands into more or less the code shown above (@pxref{Definition of +with-temp-buffer,, Current Buffer}). Several of the macros defined in +this manual use @code{unwind-protect} in this way. @findex ftp-login Here is an actual example derived from an FTP package. It creates a
--- a/lispref/display.texi Fri Jan 02 04:22:23 2004 +0000 +++ b/lispref/display.texi Fri Jan 02 04:37:46 2004 +0000 @@ -20,18 +20,19 @@ * Selective Display:: Hiding part of the buffer text (the old way). * Overlay Arrow:: Display of an arrow to indicate position. * Temporary Displays:: Displays that go away automatically. -* Overlays:: Use overlays to highlight parts of the buffer. +* Overlays:: Use overlays to highlight parts of the buffer. * Width:: How wide a character or string is on the screen. -* Faces:: A face defines a graphics style for text characters: +* Faces:: A face defines a graphics style for text characters: font, colors, etc. * Fringes:: Controlling window fringes. * Scroll Bars:: Controlling vertical scroll bars. * Display Property:: Enabling special display features. * Images:: Displaying images in Emacs buffers. +* Buttons:: Adding clickable buttons to Emacs buffers. * Blinking:: How Emacs shows the matching open parenthesis. -* Inverse Video:: Specifying how the screen looks. -* Usual Display:: The usual conventions for displaying nonprinting chars. -* Display Tables:: How to specify other conventions. +* Inverse Video:: Specifying how the screen looks. +* Usual Display:: The usual conventions for displaying nonprinting chars. +* Display Tables:: How to specify other conventions. * Beeping:: Audible signal to the user. * Window Systems:: Which window system is being used. @end menu @@ -966,7 +967,7 @@ these affect the display of the text within the overlay. @menu -* Overlay Properties:: How to read and set properties. +* Overlay Properties:: How to read and set properties. What properties do to the screen display. * Managing Overlays:: Creating and moving overlays. * Finding Overlays:: Searching for overlays. @@ -1424,10 +1425,10 @@ * Standard Faces:: The faces Emacs normally comes with. * Defining Faces:: How to define a face with @code{defface}. * Face Attributes:: What is in a face? -* Attribute Functions:: Functions to examine and set face attributes. -* Merging Faces:: How Emacs combines the faces specified for a character. +* Attribute Functions:: Functions to examine and set face attributes. +* Merging Faces:: How Emacs combines the faces specified for a character. * Font Selection:: Finding the best available font for a face. -* Face Functions:: How to define and examine faces. +* Face Functions:: How to define and examine faces. * Auto Faces:: Hook for automatic face assignment. * Font Lookup:: Looking up the names of available fonts and information about them. @@ -2639,12 +2640,12 @@ they mean. @menu -* Specified Space:: Displaying one space with a specified width. -* Other Display Specs:: Displaying an image; magnifying text; moving it +* Specified Space:: Displaying one space with a specified width. +* Other Display Specs:: Displaying an image; magnifying text; moving it up or down on the page; adjusting the width of spaces within text. * Display Margins:: Displaying text or images to the side of the main text. -* Conditional Display:: Making any of the above features conditional +* Conditional Display:: Making any of the above features conditional depending on some Lisp expression. @end menu @@ -3401,6 +3402,348 @@ are cleared. @end defun +@node Buttons +@section Buttons +@cindex buttons +@cindex buttons in buffers +@cindex clickable buttons in buffers + + The @emph{button} package defines functions for inserting and +manipulating clickable (with the mouse, or via keyboard commands) +buttons in Emacs buffers, such as might be used for help hyper-links, +etc. Emacs uses buttons for the hyper-links in help text and the like. + +A button is essentially a set of properties attached (via text +properties or overlays) to a region of text in an emacs buffer, which +are called its button properties. @xref{Button Properties}. + +One of the these properties (@code{action}) is a function, which will +be called when the user invokes it using the keyboard or the mouse. +The invoked function may then examine the button and use its other +properties as desired. + +In some ways the emacs button package duplicates functionality offered +by the widget package (@pxref{Top, , Introduction, widget, The Emacs +Widget Library}), but the button package has the advantage that it is +much faster, much smaller, and much simpler to use (for elisp +programmers---for users, the result is about the same). The extra +speed and space savings are useful mainly if you need to create many +buttons in a buffer (for instance an @code{*Apropos*} buffer uses +buttons to make entries clickable, and may contain many thousands of +entries). + +@menu +* Button Properties:: Button properties with special meanings. +* Button Types:: Defining common properties for classes of buttons. +* Making Buttons:: Adding buttons to emacs buffers. +* Manipulating Buttons:: Getting and setting properties of buttons. +* Button Buffer Commands:: Buffer-wide commands and bindings for buttons. +* Manipulating Button Types:: +@end menu + +@node Button Properties +@subsection Button Properties +@cindex button properties + + Buttons have an associated list of properties defining their +appearance and behavior, and other arbitrary properties may be used +for application specific purposes. + +Some properties that have special meaning to the button package +include: + +@table @code + +@item action +@kindex action @r{(button property)} +The function to call when the user invokes the button, which is passed +the single argument @var{button}. By default this is @code{ignore}, +which does nothing. + +@item mouse-action +@kindex mouse-action @r{(button property)} +This is similar to @code{action}, and when present, will be used +instead of @code{action} for button invocations resulting from +mouse-clicks (instead of the user hitting @key{RET}). If not +present, mouse-clicks use @code{action} instead. + +@item face +@kindex face @r{(button property)} +This is an emacs face controlling how buttons of this type are +displayed; by default this is the @code{button} face. + +@item mouse-face +@kindex mouse-face @r{(button property)} +This is an additional face which controls appearance during +mouse-overs (merged with the usual button face); by default this is +the usual emacs @code{highlight} face. + +@item keymap +@kindex keymap @r{(button property)} +The button's keymap, defining bindings active within the button +region. By default this is the usual button region keymap, stored +in the variable @code{button-map}, which defines @key{RET} and +@key{down-mouse-1} to invoke the button. + +@item type +@kindex type @r{(button property)} +The button-type of the button. When creating a button, this is +usually specified using the @code{:type} keyword argument. +@xref{Button Types}. + +@item help-echo +@kindex help-index @r{(button property)} +A string displayed by the emacs tool-tip help system; by default, +@code{"mouse-2, RET: Push this button"}. + +@item button +@kindex button @r{(button property)} +All buttons have a non-@code{nil} @code{button} property, which may be useful +in finding regions of text that comprise buttons (which is what the +standard button functions do). +@end table + +There are other properties defined for the regions of text in a +button, but these are not generally interesting for typical uses. + +@node Button Types +@subsection Button Types +@cindex button types + + Every button has a button @emph{type}, which defines default values +for the button's properties. Button types are arranged in a +hierarchy, with specialized types inheriting from more general types, +so that it's easy to define special-purpose types of buttons for +specific tasks. + +@defun define-button-type name &rest properties +@tindex define-button-type +Define a `button type' called @var{name}. The remaining arguments +form a sequence of @var{property value} pairs, specifying default +property values for buttons with this type (a button's type may be set +by giving it a @code{type} property when creating the button, using +the @code{:type} keyword argument). + +In addition, the keyword argument @code{:supertype} may be used to +specify a button-type from which @var{name} inherits its default +property values. Note that this inheritance happens only when +@var{name} is defined; subsequent changes to a supertype are not +reflected in its subtypes. +@end defun + +Using @code{define-button-type} to define default properties for +buttons is not necessary---buttons without any specified type use the +built-in button-type @code{button}---but it is is encouraged, since +doing so usually makes the resulting code clearer and more efficient. + +@node Making Buttons +@subsection Making Buttons +@cindex making buttons + + Buttons are associated with a region of text, using an overlay or +text-properties to hold button-specific information, all of which are +initialized from the button's type (which defaults to the built-in +button type @code{button}). Like all emacs text, the appearance of +the button is governed by the @code{face} property; by default (via +the @code{face} property inherited from the @code{button} button-type) +this is a simple underline, like a typical web-page link. + +For convenience, there are two sorts of button-creation functions, +those that add button properties to an existing region of a buffer, +called @code{make-...button}, and those also insert the button text, +called @code{insert-...button}. + +The button-creation functions all take the @code{&rest} argument +@var{properties}, which should be a sequence of @var{property value} +pairs, specifying properties to add to the button; see @ref{Button +Properties}. In addition, the keyword argument @code{:type} may be +used to specify a button-type from which to inherit other properties; +see @ref{Button Types}. Any properties not explicitly specified +during creation will be inherited from the button's type (if the type +defines such a property). + +The following functions add a button using an overlay +(@pxref{Overlays}) to hold the button properties: + +@defun make-button beg end &rest properties +@tindex make-button +Make a button from @var{beg} to @var{end} in the current buffer. +@end defun + +@defun insert-button label &rest properties +@tindex insert-button +Insert a button with the label @var{label}. +@end defun + +The following functions are similar, but use emacs text-properties +(@pxref{Text Properties}) to hold the button properties, making the +button actually part of the text instead of being a property of the +buffer (using text-properties is usually faster than using overlays, +so this may be preferable when creating large numbers of buttons): + +@defun make-text-button beg end &rest properties +@tindex make-text-button +Make a button from @var{beg} to @var{end} in the current buffer, using +text-properties. +@end defun + +@defun insert-text-button label &rest properties +@tindex insert-text-button +Insert a button with the label @var{label}, using text-properties. +@end defun + +Buttons using text-properties retain no markers into the buffer are +retained, which is important for speed in cases where there are +extremely large numbers of buttons. + +@node Manipulating Buttons +@subsection Manipulating Buttons +@cindex manipulating buttons + +These are functions for getting and setting properties of buttons. +Often these are used by a button's invocation function to determine +what to do. + +Where a @var{button} parameter is specified, it means an object +referring to a specific button, either an overlay (for overlay +buttons), or a buffer-position or marker (for text property buttons). +Such an object is passed as the first argument to a button's +invocation function when it is invoked. + +@defun button-start button +@tindex button-start +Return the position at which @var{button} starts. +@end defun + +@defun button-end button +@tindex button-end +Return the position at which @var{button} ends. +@end defun + +@defun button-get button prop +@tindex button-get +Get the property of button @var{button} named @var{prop}. +@end defun + +@defun button-put button prop val +@tindex button-put +Set @var{button}'s @var{prop} property to @var{val}. +@end defun + +@defun button-activate button &optional use-mouse-action +@tindex button-activate +Call @var{button}'s @code{action} property (i.e., invoke it). If +@var{use-mouse-action} is non-@code{nil}, try to invoke the button's +@code{mouse-action} property instead of @code{action}; if the button +has no @code{mouse-action} property, use @code{action} as normal. +@end defun + +@defun button-label button +@tindex button-label +Return @var{button}'s text label. +@end defun + +@defun button-type button +@tindex button-type +Return @var{button}'s button-type. +@end defun + +@defun button-has-type-p button type +@tindex button-has-type-p +Return @code{t} if @var{button} has button-type @var{type}, or one of +@var{type}'s subtypes. +@end defun + +@defun button-at pos +@tindex button-at +Return the button at position @var{pos} in the current buffer, or @code{nil}. +@end defun + +@node Button Buffer Commands +@subsection Button Buffer Commands +@cindex button buffer commands + +These are commands and functions for locating and operating on +buttons in an emacs buffer. + +@code{push-button} is the command that a user uses to actually `push' +a button, and is bound by default in the button itself to @key{RET} +and to @key{mouse-down-1} using a region-specific keymap. Commands +that are useful outside the buttons itself, such as +@code{forward-button} and @code{backward-button} are additionally +available in the keymap stored in @code{button-buffer-map}; a mode +which uses buttons may want to use @code{button-buffer-map} as a +parent keymap for its keymap. + +@deffn Command push-button &optional pos use-mouse-action +@tindex push-button +Perform the action specified by a button at location @var{pos}. +@var{pos} may be either a buffer position or a mouse-event. If +@var{use-mouse-action} is non-@code{nil}, or @var{pos} is a +mouse-event (@pxref{Mouse Events}), try to invoke the button's +@code{mouse-action} property instead of @code{action}; if the button +has no @code{mouse-action} property, use @code{action} as normal. +@var{pos} defaults to point, except when @code{push-button} is invoked +interactively as the result of a mouse-event, in which case, the mouse +event's position is used. If there's no button at @var{pos}, do +nothing and return @code{nil}, otherwise return @code{t}. +@end deffn + +@deffn Command forward-button n &optional wrap display-message +@tindex forward-button +Move to the @var{n}th next button, or @var{n}th previous button if +@var{n} is negative. If @var{n} is zero, move to the start of any +button at point. If @var{wrap} is non-@code{nil}, moving past either +end of the buffer continues from the other end. If +@var{display-message} is non-@code{nil}, the button's help-echo string +is displayed. Any button with a non-@code{nil} @code{skip} property +is skipped over. Returns the button found. +@end deffn + +@deffn Command backward-button n &optional wrap display-message +@tindex backward-button +Move to the @var{n}th previous button, or @var{n}th next button if +@var{n} is negative. If @var{n} is zero, move to the start of any +button at point. If @var{wrap} is non-@code{nil}, moving past either +end of the buffer continues from the other end. If +@var{display-message} is non-@code{nil}, the button's help-echo string +is displayed. Any button with a non-@code{nil} @code{skip} property +is skipped over. Returns the button found. +@end deffn + +@defun next-button pos &optional count-current +@tindex next-button +Return the next button after position @var{pos} in the current buffer. +If @var{count-current} is non-@code{nil}, count any button at +@var{pos} in the search, instead of starting at the next button. +@end defun + +@defun previous-button pos &optional count-current +@tindex previous-button +Return the @var{n}th button before position @var{pos} in the current +buffer. If @var{count-current} is non-@code{nil}, count any button at +@var{pos} in the search, instead of starting at the next button. +@end defun + +@node Manipulating Button Types +@subsection Manipulating Button Types +@cindex manipulating button types + +@defun button-type-put type prop val +@tindex button-type-put +Set the button-type @var{type}'s @var{prop} property to @var{val}. +@end defun + +@defun button-type-get type prop +@tindex button-type-get +Get the property of button-type @var{type} named @var{prop}. +@end defun + +@defun button-type-subtype-p type supertype +@tindex button-type-subtype-p +Return @code{t} if button-type @var{type} is a subtype of @var{supertype}. +@end defun + @node Blinking @section Blinking Parentheses @cindex parenthesis matching @@ -3595,9 +3938,9 @@ @code{force-mode-line-update} (@pxref{Mode Line Format}). @menu -* Display Table Format:: What a display table consists of. -* Active Display Table:: How Emacs selects a display table to use. -* Glyphs:: How to define a glyph, and what glyphs mean. +* Display Table Format:: What a display table consists of. +* Active Display Table:: How Emacs selects a display table to use. +* Glyphs:: How to define a glyph, and what glyphs mean. @end menu @node Display Table Format
--- a/lispref/errors.texi Fri Jan 02 04:22:23 2004 +0000 +++ b/lispref/errors.texi Fri Jan 02 04:37:46 2004 +0000 @@ -69,7 +69,7 @@ @item end-of-file @code{"End of file during parsing"}@* Note that this is not a subcategory of @code{file-error}, -because it pertains to the Lisp reader, not to file I/O. +because it pertains to the Lisp reader, not to file I/O.@* @xref{Input Functions}. @item file-already-exists @@ -79,12 +79,16 @@ @item file-date-error This is a subcategory of @code{file-error}. It occurs when @code{copy-file} tries and fails to set the last-modification time of -the output file. @xref{Changing Files}. +the output file.@* +@xref{Changing Files}. @item file-error -This error and its subcategories do not have error-strings, because the -error message is constructed from the data items alone when the error -condition @code{file-error} is present.@* +We do not list the error-strings of this error and its subcategories, +because the error message is normally constructed from the data items +alone when the error condition @code{file-error} is present. Thus, +the error-strings are not very relevant. However, these error symbols +do have @code{error-message} properties, and if no data is provided, +the @code{error-message} property @emph{is} used.@* @xref{Files}. @item file-locked @@ -113,7 +117,7 @@ @xref{Regular Expressions}. @item mark-inactive -@code{"Mark inactive"}@* +@code{"The mark is not active now"}@* @xref{The Mark}. @item no-catch @@ -139,6 +143,7 @@ @item text-read-only @code{"Text is read-only"}@* +This is a subcategory of @code{buffer-read-only}.@* @xref{Special Properties}. @item undefined-color @@ -173,6 +178,7 @@ @item overflow-error @code{"Arithmetic overflow error"}@* +This is a subcategory of @code{domain-error}.@* @xref{Math Functions}. @item range-error @@ -181,10 +187,12 @@ @item singularity-error @code{"Arithmetic singularity error"}@* +This is a subcategory of @code{domain-error}.@* @xref{Math Functions}. @item underflow-error @code{"Arithmetic underflow error"}@* +This is a subcategory of @code{domain-error}.@* @xref{Math Functions}. @end table
--- a/lispref/numbers.texi Fri Jan 02 04:22:23 2004 +0000 +++ b/lispref/numbers.texi Fri Jan 02 04:37:46 2004 +0000 @@ -172,7 +172,7 @@ which provides for positive infinity and negative infinity as floating point values. It also provides for a class of values called NaN or ``not-a-number''; numerical functions return such values in cases where -there is no correct answer. For example, @code{(sqrt -1.0)} returns a +there is no correct answer. For example, @code{(/ 0.0 0.0)} returns a NaN. For practical purposes, there's no significant difference between different NaN values in Emacs Lisp, and there's no rule for precisely which NaN value should be used in a particular case, so Emacs Lisp @@ -1146,7 +1146,7 @@ @defun sqrt arg This returns the square root of @var{arg}. If @var{arg} is negative, -the value is a NaN. +it signals a @code{domain-error} error. @end defun @node Random Numbers
--- a/lispref/tips.texi Fri Jan 02 04:22:23 2004 +0000 +++ b/lispref/tips.texi Fri Jan 02 04:37:46 2004 +0000 @@ -707,8 +707,9 @@ variable or as a function. To make a hyperlink to Info documentation, write the name of the Info -node in single quotes, preceded by @samp{info node} or @samp{Info -node}. The Info file name defaults to @samp{emacs}. For example, +node (or anchor) in single quotes, preceded by @samp{info node}, +@samp{Info node}, @samp{info anchor} or @samp{Info anchor}. The Info +file name defaults to @samp{emacs}. For example, @smallexample See Info node `Font Lock' and Info node `(elisp)Font Lock Basics'.
--- a/src/ChangeLog Fri Jan 02 04:22:23 2004 +0000 +++ b/src/ChangeLog Fri Jan 02 04:37:46 2004 +0000 @@ -1,3 +1,40 @@ +2004-01-02 Kim F. Storm <storm@cua.dk> + + * process.h (struct Lisp_Process): New members for adaptive read + buffering: adaptive_read_buffering, read_output_delay, and + read_output_skip. + + * process.c (ADAPTIVE_READ_BUFFERING): New conditional. + (READ_OUTPUT_DELAY_INCREMENT, READ_OUTPUT_DELAY_MAX) + (READ_OUTPUT_DELAY_MAX_MAX): New constants. + (process_output_delay_count, process_output_skip): New vars. + (Vprocess_adaptive_read_buffering): New variable. + (make_process): Initialize adaptive read buffering members. + (Fstart_process): Set adaptive_read_buffering member. + (deactivate_process): Cleanup adaptive read buffering. + (wait_reading_process_input): Temporarily omit delayed + subprocesses from the set of file descriptors to read from; + adjust the select timeout if we skipped any subprocesses. + (read_process_output): Increase adaptive read buffering delay if + we read less than a full buffer; reduce delay when we read a + full buffer. + (send_process): Simplify using local Lisp_Process var. + Reset adaptive read buffering delay after write. + (init_process): Initialize process_output_delay_count and + process_output_skip. + (syms_of_process): DEFVAR_LISP Vprocess_adaptive_read_buffering. + +2004-01-01 Jason Rumney <jasonr@gnu.org> + + * w32term.c (w32_text_out): Use s->font, for consistency with + callers. + +2003-12-30 Luc Teirlinck <teirllm@auburn.edu> + + * print.c (Ferror_message_string): Add hyperlink in the docstring + to the definition of `signal' in the Elisp manual. + * eval.c (Fsignal): Ditto. + 2003-12-29 James Clark <jjc@jclark.com> (tiny change) * fns.c (internal_equal): Return t for two NaN arguments.
--- a/src/eval.c Fri Jan 02 04:22:23 2004 +0000 +++ b/src/eval.c Fri Jan 02 04:37:46 2004 +0000 @@ -1436,6 +1436,8 @@ The symbol `error' should normally be one of them. DATA should be a list. Its elements are printed as part of the error message. +See Info anchor `(elisp)Definition of signal' for some details on how this +error message is constructed. If the signal is handled, DATA is made available to the handler. See also the function `condition-case'. */) (error_symbol, data)
--- a/src/print.c Fri Jan 02 04:22:23 2004 +0000 +++ b/src/print.c Fri Jan 02 04:37:46 2004 +0000 @@ -967,7 +967,9 @@ DEFUN ("error-message-string", Ferror_message_string, Serror_message_string, 1, 1, 0, - doc: /* Convert an error value (ERROR-SYMBOL . DATA) to an error message. */) + doc: /* Convert an error value (ERROR-SYMBOL . DATA) to an error message. +See Info anchor `(elisp)Definition of signal' for some details on how this +error message is constructed. */) (obj) Lisp_Object obj; {
--- a/src/process.c Fri Jan 02 04:22:23 2004 +0000 +++ b/src/process.c Fri Jan 02 04:37:46 2004 +0000 @@ -260,6 +260,33 @@ #undef DATAGRAM_SOCKETS #endif +#if !defined (ADAPTIVE_READ_BUFFERING) && !defined (NO_ADAPTIVE_READ_BUFFERING) +#ifdef EMACS_HAS_USECS +#define ADAPTIVE_READ_BUFFERING +#endif +#endif + +#ifdef ADAPTIVE_READ_BUFFERING +#define READ_OUTPUT_DELAY_INCREMENT 10000 +#define READ_OUTPUT_DELAY_MAX (READ_OUTPUT_DELAY_INCREMENT * 5) +#define READ_OUTPUT_DELAY_MAX_MAX (READ_OUTPUT_DELAY_INCREMENT * 7) + +/* Number of processes which might be delayed. */ + +static int process_output_delay_count; + +/* Non-zero if any process has non-nil process_output_skip. */ + +static int process_output_skip; + +/* Non-nil means to delay reading process output to improve buffering. + A value of t means that delay is reset after each send, any other + non-nil value does not reset the delay. */ +static Lisp_Object Vprocess_adaptive_read_buffering; +#else +#define process_output_delay_count 0 +#endif + #include "sysselect.h" @@ -573,6 +600,12 @@ p->status = Qrun; p->mark = Fmake_marker (); +#ifdef ADAPTIVE_READ_BUFFERING + p->adaptive_read_buffering = Qnil; + XSETFASTINT (p->read_output_delay, 0); + p->read_output_skip = Qnil; +#endif + /* If name is already in use, modify it until it is unused. */ name1 = name; @@ -1501,6 +1534,10 @@ = buffer_defaults.enable_multibyte_characters; XPROCESS (proc)->command = Flist (nargs - 2, args + 2); +#ifdef ADAPTIVE_READ_BUFFERING + XPROCESS (proc)->adaptive_read_buffering = Vprocess_adaptive_read_buffering; +#endif + /* Make the process marker point into the process buffer (if any). */ if (!NILP (buffer)) set_marker_both (XPROCESS (proc)->mark, buffer, @@ -3588,6 +3625,16 @@ inchannel = XINT (p->infd); outchannel = XINT (p->outfd); +#ifdef ADAPTIVE_READ_BUFFERING + if (XINT (p->read_output_delay) > 0) + { + if (--process_output_delay_count < 0) + process_output_delay_count = 0; + XSETINT (p->read_output_delay, 0); + p->read_output_skip = Qnil; + } +#endif + if (inchannel >= 0) { /* Beware SIGCHLD hereabouts. */ @@ -3973,7 +4020,7 @@ register int channel, nfds; static SELECT_TYPE Available; static SELECT_TYPE Connecting; - int check_connect, no_avail; + int check_connect, check_delay, no_avail; int xerrno; Lisp_Object proc; EMACS_TIME timeout, end_time; @@ -4202,7 +4249,7 @@ if (!NILP (wait_for_cell)) { Available = non_process_wait_mask; - check_connect = 0; + check_connect = check_delay = 0; } else { @@ -4211,6 +4258,7 @@ else Available = input_wait_mask; check_connect = (num_pending_connects > 0); + check_delay = process_output_delay_count; } /* If frame size has changed or the window is newly mapped, @@ -4236,6 +4284,34 @@ { if (check_connect) Connecting = connect_wait_mask; + +#ifdef ADAPTIVE_READ_BUFFERING + if (process_output_skip && check_delay > 0) + { + int usecs = EMACS_USECS (timeout); + if (EMACS_SECS (timeout) > 0 || usecs > READ_OUTPUT_DELAY_MAX) + usecs = READ_OUTPUT_DELAY_MAX; + for (channel = 0; check_delay > 0 && channel <= max_process_desc; channel++) + { + proc = chan_process[channel]; + if (NILP (proc)) + continue; + if (XPROCESS (proc)->read_output_delay > 0) + { + check_delay--; + if (NILP (XPROCESS (proc)->read_output_skip)) + continue; + FD_CLR (channel, &Available); + XPROCESS (proc)->read_output_skip = Qnil; + if (XINT (XPROCESS (proc)->read_output_delay) < usecs) + usecs = XINT (XPROCESS (proc)->read_output_delay); + } + } + EMACS_SET_SECS_USECS (timeout, 0, usecs); + process_output_skip = 0; + } +#endif + nfds = select (max (max_process_desc, max_keyboard_desc) + 1, &Available, (check_connect ? &Connecting : (SELECT_TYPE *)0), @@ -4689,7 +4765,36 @@ else #endif if (proc_buffered_char[channel] < 0) - nbytes = emacs_read (channel, chars + carryover, readmax - carryover); + { + nbytes = emacs_read (channel, chars + carryover, readmax - carryover); +#ifdef ADAPTIVE_READ_BUFFERING + if (!NILP (p->adaptive_read_buffering)) + { + int delay = XINT (p->read_output_delay); + if (nbytes < readmax - carryover) + { + if (delay < READ_OUTPUT_DELAY_MAX_MAX) + { + if (delay == 0) + process_output_delay_count++; + delay += READ_OUTPUT_DELAY_INCREMENT * 2; + } + } + else if (delay > 0) + { + delay -= READ_OUTPUT_DELAY_INCREMENT; + if (delay == 0) + process_output_delay_count--; + } + XSETINT (p->read_output_delay, delay); + if (delay) + { + p->read_output_skip = Qt; + process_output_skip = 1; + } + } +#endif + } else { chars[carryover] = proc_buffered_char[channel]; @@ -4991,6 +5096,7 @@ volatile Lisp_Object object; { /* Use volatile to protect variables from being clobbered by longjmp. */ + struct Lisp_Process *p = XPROCESS (proc); int rv; struct coding_system *coding; struct gcpro gcpro1; @@ -4998,20 +5104,17 @@ GCPRO1 (object); #ifdef VMS - struct Lisp_Process *p = XPROCESS (proc); VMS_PROC_STUFF *vs, *get_vms_process_pointer(); #endif /* VMS */ - if (! NILP (XPROCESS (proc)->raw_status_low)) - update_status (XPROCESS (proc)); - if (! EQ (XPROCESS (proc)->status, Qrun)) - error ("Process %s not running", - SDATA (XPROCESS (proc)->name)); - if (XINT (XPROCESS (proc)->outfd) < 0) - error ("Output file descriptor of %s is closed", - SDATA (XPROCESS (proc)->name)); - - coding = proc_encode_coding_system[XINT (XPROCESS (proc)->outfd)]; + if (! NILP (p->raw_status_low)) + update_status (p); + if (! EQ (p->status, Qrun)) + error ("Process %s not running", SDATA (p->name)); + if (XINT (p->outfd) < 0) + error ("Output file descriptor of %s is closed", SDATA (p->name)); + + coding = proc_encode_coding_system[XINT (p->outfd)]; Vlast_coding_system_used = coding->symbol; if ((STRINGP (object) && STRING_MULTIBYTE (object)) @@ -5019,13 +5122,12 @@ && !NILP (XBUFFER (object)->enable_multibyte_characters)) || EQ (object, Qt)) { - if (!EQ (coding->symbol, XPROCESS (proc)->encode_coding_system)) + if (!EQ (coding->symbol, p->encode_coding_system)) /* The coding system for encoding was changed to raw-text because we sent a unibyte text previously. Now we are sending a multibyte text, thus we must encode it by the - original coding system specified for the current - process. */ - setup_coding_system (XPROCESS (proc)->encode_coding_system, coding); + original coding system specified for the current process. */ + setup_coding_system (p->encode_coding_system, coding); /* src_multibyte should be set to 1 _after_ a call to setup_coding_system, since it resets src_multibyte to zero. */ @@ -5076,15 +5178,15 @@ coding->composing = COMPOSITION_DISABLED; } - if (SBYTES (XPROCESS (proc)->encoding_buf) < require) - XPROCESS (proc)->encoding_buf = make_uninit_string (require); + if (SBYTES (p->encoding_buf) < require) + p->encoding_buf = make_uninit_string (require); if (from_byte >= 0) buf = (BUFFERP (object) ? BUF_BYTE_ADDRESS (XBUFFER (object), from_byte) : SDATA (object) + from_byte); - object = XPROCESS (proc)->encoding_buf; + object = p->encoding_buf; encode_coding (coding, (char *) buf, SDATA (object), len, SBYTES (object)); len = coding->produced; @@ -5102,8 +5204,7 @@ if (pty_max_bytes == 0) { #if defined (HAVE_FPATHCONF) && defined (_PC_MAX_CANON) - pty_max_bytes = fpathconf (XFASTINT (XPROCESS (proc)->outfd), - _PC_MAX_CANON); + pty_max_bytes = fpathconf (XFASTINT (p->outfd), _PC_MAX_CANON); if (pty_max_bytes < 0) pty_max_bytes = 250; #else @@ -5126,7 +5227,7 @@ /* Decide how much data we can send in one batch. Long lines need to be split into multiple batches. */ - if (!NILP (XPROCESS (proc)->pty_flag)) + if (!NILP (p->pty_flag)) { /* Starting this at zero is always correct when not the first iteration because the previous iteration ended by sending C-d. @@ -5155,7 +5256,7 @@ /* Send this batch, using one or more write calls. */ while (this > 0) { - int outfd = XINT (XPROCESS (proc)->outfd); + int outfd = XINT (p->outfd); old_sigpipe = (SIGTYPE (*) ()) signal (SIGPIPE, send_process_trap); #ifdef DATAGRAM_SOCKETS if (DATAGRAM_CHAN_P (outfd)) @@ -5168,7 +5269,18 @@ } else #endif - rv = emacs_write (outfd, (char *) buf, this); + { + rv = emacs_write (outfd, (char *) buf, this); +#ifdef ADAPTIVE_READ_BUFFERING + if (XINT (p->read_output_delay) > 0 + && EQ (p->adaptive_read_buffering, Qt)) + { + XSETFASTINT (p->read_output_delay, 0); + process_output_delay_count--; + p->read_output_skip = Qnil; + } +#endif + } signal (SIGPIPE, old_sigpipe); if (rv < 0) @@ -5209,8 +5321,7 @@ if (errno == EAGAIN) { int flags = FWRITE; - ioctl (XINT (XPROCESS (proc)->outfd), TIOCFLUSH, - &flags); + ioctl (XINT (p->outfd), TIOCFLUSH, &flags); } #endif /* BROKEN_PTY_READ_AFTER_EAGAIN */ @@ -5255,18 +5366,17 @@ { #ifndef VMS proc = process_sent_to; -#endif - XPROCESS (proc)->raw_status_low = Qnil; - XPROCESS (proc)->raw_status_high = Qnil; - XPROCESS (proc)->status = Fcons (Qexit, Fcons (make_number (256), Qnil)); - XSETINT (XPROCESS (proc)->tick, ++process_tick); + p = XPROCESS (proc); +#endif + p->raw_status_low = Qnil; + p->raw_status_high = Qnil; + p->status = Fcons (Qexit, Fcons (make_number (256), Qnil)); + XSETINT (p->tick, ++process_tick); deactivate_process (proc); #ifdef VMS - error ("Error writing to process %s; closed it", - SDATA (XPROCESS (proc)->name)); + error ("Error writing to process %s; closed it", SDATA (p->name)); #else - error ("SIGPIPE raised on process %s; closed it", - SDATA (XPROCESS (proc)->name)); + error ("SIGPIPE raised on process %s; closed it", SDATA (p->name)); #endif } @@ -6493,6 +6603,11 @@ FD_ZERO (&non_process_wait_mask); max_process_desc = 0; +#ifdef ADAPTIVE_READ_BUFFERING + process_output_delay_count = 0; + process_output_skip = 0; +#endif + FD_SET (0, &input_wait_mask); Vprocess_alist = Qnil; @@ -6626,6 +6741,20 @@ The value takes effect when `start-process' is called. */); Vprocess_connection_type = Qt; +#ifdef ADAPTIVE_READ_BUFFERING + DEFVAR_LISP ("process-adaptive-read-buffering", &Vprocess_adaptive_read_buffering, + doc: /* If non-nil, improve receive buffering by delaying after short reads. +On some systems, when emacs reads the output from a subprocess, the output data +is read in very small blocks, potentially resulting in very poor performance. +This behaviour can be remedied to some extent by setting this variable to a +non-nil value, as it will automatically delay reading from such processes, to +allowing them to produce more output before emacs tries to read it. +If the value is t, the delay is reset after each write to the process; any other +non-nil value means that the delay is not reset on write. +The variable takes effect when `start-process' is called. */); + Vprocess_adaptive_read_buffering = Qt; +#endif + defsubr (&Sprocessp); defsubr (&Sget_process); defsubr (&Sget_buffer_process);
--- a/src/process.h Fri Jan 02 04:22:23 2004 +0000 +++ b/src/process.h Fri Jan 02 04:37:46 2004 +0000 @@ -101,6 +101,18 @@ generated, and can be changed by the function `set-process-fileter-multibyte'. */ Lisp_Object filter_multibyte; + /* Should we delay reading output from this process. + Initialized from `Vprocess_adaptive_read_buffering'. */ + Lisp_Object adaptive_read_buffering; + /* Hysteresis to try to read process output in larger blocks. + On some systems, e.g. the Linux kernel, emacs is seen as + an interactive app also when reading process output, meaning + that process output can be read in as little as 1 byte at a + time. Value is micro-seconds to delay reading output from + this process. Range is 0 .. 50000. */ + Lisp_Object read_output_delay; + /* Skip reading this process on next read. */ + Lisp_Object read_output_skip; }; /* Every field in the preceding structure except for the first two
--- a/src/w32term.c Fri Jan 02 04:22:23 2004 +0000 +++ b/src/w32term.c Fri Jan 02 04:37:46 2004 +0000 @@ -1121,9 +1121,9 @@ wchar_t * chars; int nchars; { - int charset_dim = w32_font_is_double_byte (s->gc->font) ? 2 : 1; - if (s->gc->font->bdf) - w32_BDF_TextOut (s->gc->font->bdf, s->hdc, + int charset_dim = w32_font_is_double_byte (s->font) ? 2 : 1; + if (s->font->bdf) + w32_BDF_TextOut (s->font->bdf, s->hdc, x, y, (char *) chars, charset_dim, nchars * charset_dim, 0); else if (s->first_glyph->font_type == UNICODE_FONT)