Now on revision 113753. ------------------------------------------------------------ revno: 113753 committer: Dmitry Antipov branch nick: trunk timestamp: Thu 2013-08-08 08:42:40 +0400 message: Do not reset window modification event counters excessively. These leftovers and poor man's tricky methods to catch extra redisplay's attention are no longer needed. * frame.c (set_menu_bar_lines_1): * minibuf.c (read_minibuf_unwind): * window.c (Fset_window_start, set_window_buffer, window_resize_apply) (grow_mini_window, shrink_mini_window, window_scroll_pixel_based) (window_scroll_line_based, Fset_window_configuration): * xdisp.c (redisplay_window): Do not reset last_modified and last_overlay_modified counters. diff: === modified file 'src/ChangeLog' --- src/ChangeLog 2013-08-07 17:03:46 +0000 +++ src/ChangeLog 2013-08-08 04:42:40 +0000 @@ -1,3 +1,16 @@ +2013-08-08 Dmitry Antipov + + Do not reset window modification event counters excessively. + These leftovers and poor man's tricky methods to catch extra + redisplay's attention are no longer needed. + * frame.c (set_menu_bar_lines_1): + * minibuf.c (read_minibuf_unwind): + * window.c (Fset_window_start, set_window_buffer, window_resize_apply) + (grow_mini_window, shrink_mini_window, window_scroll_pixel_based) + (window_scroll_line_based, Fset_window_configuration): + * xdisp.c (redisplay_window): Do not reset last_modified and + last_overlay_modified counters. + 2013-08-07 Jan Djärv * xselect.c (x_send_client_event): Set send_event and serial, memset === modified file 'src/frame.c' --- src/frame.c 2013-08-05 18:05:46 +0000 +++ src/frame.c 2013-08-08 04:42:40 +0000 @@ -185,7 +185,6 @@ { struct window *w = XWINDOW (window); - w->last_modified = 0; w->top_line += n; w->total_lines -= n; === modified file 'src/minibuf.c' --- src/minibuf.c 2013-08-05 04:14:43 +0000 +++ src/minibuf.c 2013-08-08 04:42:40 +0000 @@ -870,10 +870,8 @@ if (minibuf_level == 0) resize_mini_window (XWINDOW (window), 0); - /* Make sure minibuffer window is erased, not ignored. */ + /* Enforce full redisplay. FIXME: make it more selective. */ windows_or_buffers_changed++; - XWINDOW (window)->last_modified = 0; - XWINDOW (window)->last_overlay_modified = 0; /* In case the previous minibuffer displayed in this miniwindow is dead, we may keep displaying this buffer (tho it's inactive), so reset it, === modified file 'src/window.c' --- src/window.c 2013-08-07 13:21:59 +0000 +++ src/window.c 2013-08-08 04:42:40 +0000 @@ -1614,9 +1614,8 @@ if (NILP (noforce)) w->force_start = 1; w->update_mode_line = 1; - w->last_modified = 0; - w->last_overlay_modified = 0; if (!EQ (window, selected_window)) + /* Enforce full redisplay. FIXME: make it more selective. */ windows_or_buffers_changed++; return pos; @@ -3215,8 +3214,6 @@ buffer); w->start_at_line_beg = 0; w->force_start = 0; - w->last_modified = 0; - w->last_overlay_modified = 0; } /* Maybe we could move this into the `if' but it's not obviously safe and I doubt it's worth the trouble. */ @@ -3677,10 +3674,6 @@ c = NILP (c->next) ? 0 : XWINDOW (c->next); } } - - /* Clear out some redisplay caches. */ - w->last_modified = 0; - w->last_overlay_modified = 0; } @@ -4199,9 +4192,7 @@ /* Grow the mini-window. */ w->top_line = r->top_line + r->total_lines; w->total_lines -= XINT (value); - w->last_modified = 0; - w->last_overlay_modified = 0; - + /* Enforce full redisplay. FIXME: make it more selective. */ windows_or_buffers_changed++; adjust_glyphs (f); unblock_input (); @@ -4235,10 +4226,7 @@ /* Shrink the mini-window. */ w->top_line = r->top_line + r->total_lines; w->total_lines = 1; - - w->last_modified = 0; - w->last_overlay_modified = 0; - + /* Enforce full redisplay. FIXME: make it more selective. */ windows_or_buffers_changed++; adjust_glyphs (f); unblock_input (); @@ -4464,8 +4452,6 @@ w->contents); w->start_at_line_beg = 1; w->update_mode_line = 1; - w->last_modified = 0; - w->last_overlay_modified = 0; /* Set force_start so that redisplay_window will run the window-scroll-functions. */ w->force_start = 1; @@ -4610,8 +4596,6 @@ bytepos = marker_byte_position (w->start); w->start_at_line_beg = (pos == BEGV || FETCH_BYTE (bytepos - 1) == '\n'); w->update_mode_line = 1; - w->last_modified = 0; - w->last_overlay_modified = 0; /* Set force_start so that redisplay_window will run the window-scroll-functions. */ w->force_start = 1; @@ -4810,8 +4794,6 @@ set_marker_restricted_both (w->start, w->contents, pos, pos_byte); w->start_at_line_beg = !NILP (bolp); w->update_mode_line = 1; - w->last_modified = 0; - w->last_overlay_modified = 0; /* Set force_start so that redisplay_window will run the window-scroll-functions. */ w->force_start = 1; @@ -5743,9 +5725,6 @@ } } - w->last_modified = 0; - w->last_overlay_modified = 0; - if (BUFFERP (p->buffer) && BUFFER_LIVE_P (XBUFFER (p->buffer))) /* If saved buffer is alive, install it. */ { === modified file 'src/xdisp.c' --- src/xdisp.c 2013-08-07 15:14:23 +0000 +++ src/xdisp.c 2013-08-08 04:42:40 +0000 @@ -15555,8 +15555,6 @@ startp = run_window_scroll_functions (window, startp); } - w->last_modified = 0; - w->last_overlay_modified = 0; if (CHARPOS (startp) < BEGV) SET_TEXT_POS (startp, BEGV, BEGV_BYTE); else if (CHARPOS (startp) > ZV) @@ -15802,9 +15800,6 @@ try_to_scroll: - w->last_modified = 0; - w->last_overlay_modified = 0; - /* Redisplay the mode line. Select the buffer properly for that. */ if (!update_mode_line) { ------------------------------------------------------------ revno: 113752 committer: Juanma Barranquero branch nick: trunk timestamp: Thu 2013-08-08 05:54:41 +0200 message: lisp/frameset.el (frameset-p, frameset-prop): Doc fixes. diff: === modified file 'lisp/ChangeLog' --- lisp/ChangeLog 2013-08-08 01:37:47 +0000 +++ lisp/ChangeLog 2013-08-08 03:54:41 +0000 @@ -1,3 +1,7 @@ +2013-08-08 Juanma Barranquero + + * frameset.el (frameset-p, frameset-prop): Doc fixes. + 2013-08-08 Stefan Monnier * emacs-lisp/bytecomp.el (byte-compile-function-warn): New function, === modified file 'lisp/frameset.el' --- lisp/frameset.el 2013-08-08 01:19:11 +0000 +++ lisp/frameset.el 2013-08-08 03:54:41 +0000 @@ -104,8 +104,7 @@ ;;;###autoload (defun frameset-p (object) - "If OBJECT is a frameset, return its version number. -Else return nil." + "Return non-nil if OBJECT is a frameset, nil otherwise." (and (vectorp object) ; a vector (eq (aref object 0) 'frameset) ; tagged as `frameset' (integerp (aref object 1)) ; version is an int @@ -122,7 +121,7 @@ Properties can be set with - (setf (frameset-prop FRAMESET PROP) NEW-VALUE)" + (setf (frameset-prop FRAMESET PROPERTY) NEW-VALUE)" (plist-get (frameset-properties frameset) property)) (gv-define-setter frameset-prop (val fs prop) ------------------------------------------------------------ revno: 113751 committer: Stefan Monnier branch nick: trunk timestamp: Wed 2013-08-07 21:37:47 -0400 message: * lisp/emacs-lisp/bytecomp.el (byte-compile-function-warn): New function, extracted from byte-compile-callargs-warn and byte-compile-normal-call. (byte-compile-callargs-warn, byte-compile-function-form): Use it. (byte-compile-normal-call): Remove obsolescence check. diff: === modified file 'lisp/ChangeLog' --- lisp/ChangeLog 2013-08-08 01:19:11 +0000 +++ lisp/ChangeLog 2013-08-08 01:37:47 +0000 @@ -1,3 +1,10 @@ +2013-08-08 Stefan Monnier + + * emacs-lisp/bytecomp.el (byte-compile-function-warn): New function, + extracted from byte-compile-callargs-warn and byte-compile-normal-call. + (byte-compile-callargs-warn, byte-compile-function-form): Use it. + (byte-compile-normal-call): Remove obsolescence check. + 2013-08-08 Juanma Barranquero * frameset.el (frameset-restore): Doc fix. === modified file 'lisp/emacs-lisp/bytecomp.el' --- lisp/emacs-lisp/bytecomp.el 2013-08-07 17:33:30 +0000 +++ lisp/emacs-lisp/bytecomp.el 2013-08-08 01:37:47 +0000 @@ -1224,6 +1224,24 @@ (format "%d" (car signature))) (t (format "%d-%d" (car signature) (cdr signature))))) +(defun byte-compile-function-warn (f nargs def) + (when (get f 'byte-obsolete-info) + (byte-compile-warn-obsolete f)) + + ;; Check to see if the function will be available at runtime + ;; and/or remember its arity if it's unknown. + (or (and (or def (fboundp f)) ; might be a subr or autoload. + (not (memq f byte-compile-noruntime-functions))) + (eq f byte-compile-current-form) ; ## This doesn't work + ; with recursion. + ;; It's a currently-undefined function. + ;; Remember number of args in call. + (let ((cons (assq f byte-compile-unresolved-functions))) + (if cons + (or (memq nargs (cdr cons)) + (push nargs (cdr cons))) + (push (list f nargs) + byte-compile-unresolved-functions))))) ;; Warn if the form is calling a function with the wrong number of arguments. (defun byte-compile-callargs-warn (form) @@ -1261,21 +1279,7 @@ "accepts only") (byte-compile-arglist-signature-string sig)))) (byte-compile-format-warn form) - ;; Check to see if the function will be available at runtime - ;; and/or remember its arity if it's unknown. - (or (and (or def (fboundp (car form))) ; might be a subr or autoload. - (not (memq (car form) byte-compile-noruntime-functions))) - (eq (car form) byte-compile-current-form) ; ## This doesn't work - ; with recursion. - ;; It's a currently-undefined function. - ;; Remember number of args in call. - (let ((cons (assq (car form) byte-compile-unresolved-functions)) - (n (length (cdr form)))) - (if cons - (or (memq n (cdr cons)) - (push n (cdr cons))) - (push (list (car form) n) - byte-compile-unresolved-functions)))))) + (byte-compile-function-warn (car form) (length (cdr form)) def))) (defun byte-compile-format-warn (form) "Warn if FORM is `format'-like with inconsistent args. @@ -2960,8 +2964,6 @@ '(custom-declare-group custom-declare-variable custom-declare-face)) (byte-compile-nogroup-warn form)) - (when (get (car form) 'byte-obsolete-info) - (byte-compile-warn-obsolete (car form))) (byte-compile-callargs-warn form)) (if byte-compile-generate-call-tree (byte-compile-annotate-call-tree form)) @@ -3573,24 +3575,7 @@ (let ((f (nth 1 form))) (when (and (symbolp f) (byte-compile-warning-enabled-p 'callargs)) - (when (get f 'byte-obsolete-info) - (byte-compile-warn-obsolete (car form))) - - ;; Check to see if the function will be available at runtime - ;; and/or remember its arity if it's unknown. - (or (and (or (fboundp f) ; Might be a subr or autoload. - (byte-compile-fdefinition (car form) nil)) - (not (memq f byte-compile-noruntime-functions))) - (eq f byte-compile-current-form) ; ## This doesn't work - ; with recursion. - ;; It's a currently-undefined function. - ;; Remember number of args in call. - (let ((cons (assq f byte-compile-unresolved-functions))) - (if cons - (or (memq t (cdr cons)) - (push t (cdr cons))) - (push (list f t) - byte-compile-unresolved-functions))))) + (byte-compile-function-warn f t (byte-compile-fdefinition f nil))) (byte-compile-constant (if (eq 'lambda (car-safe f)) (byte-compile-lambda f) ------------------------------------------------------------ revno: 113750 committer: Juanma Barranquero branch nick: trunk timestamp: Thu 2013-08-08 03:19:11 +0200 message: lisp/frameset.el (frameset-restore): Doc fix. diff: === modified file 'lisp/ChangeLog' --- lisp/ChangeLog 2013-08-08 00:44:22 +0000 +++ lisp/ChangeLog 2013-08-08 01:19:11 +0000 @@ -1,5 +1,7 @@ 2013-08-08 Juanma Barranquero + * frameset.el (frameset-restore): Doc fix. + * register.el (frameset-frame-id, frameset-frame-with-id) (frameset-p, frameset-restore, frameset-save): Declare. (register-alist): Document framesets. === modified file 'lisp/frameset.el' --- lisp/frameset.el 2013-08-07 22:54:08 +0000 +++ lisp/frameset.el 2013-08-08 01:19:11 +0000 @@ -55,21 +55,21 @@ of the frameset struct. Currently its value is 1. timestamp A read-only timestamp, the output of `current-time'. app A symbol, or a list whose first element is a symbol, which - identifies the creator of the frameset and related info; - for example, desktop.el sets this slot to a list - `(desktop . ,desktop-file-version). + identifies the creator of the frameset and related info; + for example, desktop.el sets this slot to a list + `(desktop . ,desktop-file-version). name A string, the name of the frameset instance. description A string, a description for user consumption (to show in - menus, messages, etc). + menus, messages, etc). properties A property list, to store both frameset-specific and user-defined serializable data. states A list of items (FRAME-PARAMETERS . WINDOW-STATE), in no particular order. Each item represents a frame to be restored. FRAME-PARAMETERS is a frame's parameter alist, extracted with (frame-parameters FRAME) and filtered - through `frameset-filter-params'. + through `frameset-filter-params'. WINDOW-STATE is the output of `window-state-get' applied - to the root window of the frame. + to the root window of the frame. To avoid collisions, it is recommended that applications wanting to add private serializable data to `properties' either store all info under a @@ -969,7 +969,7 @@ ;;;###autoload (cl-defun frameset-restore (frameset &key predicate filters reuse-frames - force-display force-onscreen) + force-display force-onscreen) "Restore a FRAMESET into the current display(s). PREDICATE is a function called with two arguments, the parameter alist @@ -1009,8 +1009,8 @@ It must return non-nil to force the frame onscreen, nil otherwise. Note the timing and scope of the operations described above: REUSE-FRAMES -affects existing frames, FILTERS and FORCE-DISPLAY affect the frame being -restored before that happens, and FORCE-ONSCREEN affects the frame once +affects existing frames; PREDICATE, FILTERS and FORCE-DISPLAY affect the frame +being restored before that happens; and FORCE-ONSCREEN affects the frame once it has been restored. All keyword parameters default to nil." ------------------------------------------------------------ revno: 113749 committer: Juanma Barranquero branch nick: trunk timestamp: Thu 2013-08-08 02:46:48 +0200 message: etc/NEWS: Document new keybinding of `C-x r f' to frameset-to-register. diff: === modified file 'etc/ChangeLog' --- etc/ChangeLog 2013-08-06 16:33:14 +0000 +++ etc/ChangeLog 2013-08-08 00:46:48 +0000 @@ -1,3 +1,7 @@ +2013-08-08 Juanma Barranquero + + * NEWS: Document new keybinding of `C-x r f' to frameset-to-register. + 2013-08-06 Dmitry Antipov * NEWS: Mention `cache-long-scans'. === modified file 'etc/NEWS' --- etc/NEWS 2013-08-06 23:53:49 +0000 +++ etc/NEWS 2013-08-08 00:46:48 +0000 @@ -131,6 +131,11 @@ Also timers for blinking are stopped when no blinking is done, so Emacs does not consume CPU cycles. +** New command `frameset-to-register' is now bound to `C-x r f', replacing +`frame-configuration-to-register'. It offers similar functionality, plus +some enhancements, like the ability to restore deleted frames. Command +`frame-configuration-to-register' is still available, but unbound. + * Editing Changes in Emacs 24.4 @@ -284,9 +289,9 @@ auto-saves of the desktop. *** `desktop-restore-frames', enabled by default, allows saving and -restoring the window/frame configuration. Additional options +restoring the frame/window configuration (frameset). Additional options `desktop-restore-in-current-display', `desktop-restore-reuses-frames' -and `desktop-restore-forces-onscreen' allow further customization. +and `desktop-restore-forces-onscreen' offer further customization. ** Dired ------------------------------------------------------------ revno: 113748 committer: Juanma Barranquero branch nick: trunk timestamp: Thu 2013-08-08 02:44:22 +0200 message: * lisp/bindings.el (ctl-x-r-map): Bind ?f to frameset-to-register. * lisp/register.el: Add support for framesets. (frameset-frame-id, frameset-frame-with-id) (frameset-p, frameset-restore, frameset-save): Declare. (register-alist): Document framesets. (frameset-session-filter-alist): Declare. (frameset-to-register): New function. (jump-to-register): Implement jumping to framesets. Doc fix. (describe-register-1): Describe framesets. diff: === modified file 'lisp/ChangeLog' --- lisp/ChangeLog 2013-08-07 22:54:08 +0000 +++ lisp/ChangeLog 2013-08-08 00:44:22 +0000 @@ -1,3 +1,15 @@ +2013-08-08 Juanma Barranquero + + * register.el (frameset-frame-id, frameset-frame-with-id) + (frameset-p, frameset-restore, frameset-save): Declare. + (register-alist): Document framesets. + (frameset-session-filter-alist): Declare. + (frameset-to-register): New function. + (jump-to-register): Implement jumping to framesets. Doc fix. + (describe-register-1): Describe framesets. + + * bindings.el (ctl-x-r-map): Bind ?f to frameset-to-register. + 2013-08-07 Juanma Barranquero * desktop.el (desktop-save-frameset): Use new frameset-save args. === modified file 'lisp/bindings.el' --- lisp/bindings.el 2013-06-30 14:49:33 +0000 +++ lisp/bindings.el 2013-08-08 00:44:22 +0000 @@ -1220,7 +1220,7 @@ (define-key map "n" 'number-to-register) (define-key map "+" 'increment-register) (define-key map "w" 'window-configuration-to-register) - (define-key map "f" 'frame-configuration-to-register) + (define-key map "f" 'frameset-to-register) map) "Keymap for subcommands of C-x r.") (define-key ctl-x-map "r" ctl-x-r-map) === modified file 'lisp/register.el' --- lisp/register.el 2013-03-26 02:49:05 +0000 +++ lisp/register.el 2013-08-08 00:44:22 +0000 @@ -31,6 +31,12 @@ (eval-when-compile (require 'cl-lib)) +(declare-function frameset-frame-id "frameset" (frame)) +(declare-function frameset-frame-with-id "frameset" (id &optional frame-list)) +(declare-function frameset-p "frameset" (frameset)) +(declare-function frameset-restore "frameset" (frameset &rest keys) t) +(declare-function frameset-save "frameset" (frame-list &rest keys) t) + ;;; Code: (cl-defstruct @@ -71,7 +77,9 @@ A list of the form (WINDOW-CONFIGURATION POSITION) represents a saved window configuration plus a saved value of point. A list of the form (FRAME-CONFIGURATION POSITION) - represents a saved frame configuration plus a saved value of point.") + represents a saved frame configuration plus a saved value of point. +A list of the form (FRAMESET FRAME-ID POSITION) + represents a saved frameset plus the value of point in frame FRAME-ID.") (defgroup register nil "Register commands." @@ -132,16 +140,32 @@ ;; of point in the current buffer, so record that separately. (set-register register (list (current-frame-configuration) (point-marker)))) +(defvar frameset-session-filter-alist) + +(defun frameset-to-register (register &optional _arg) + "Store the current frameset in register REGISTER. +Use \\[jump-to-register] to restore the frameset. +Argument is a character, naming the register." + (interactive "cFrameset to register: \nP") + (set-register register + (list (frameset-save nil + :app 'register + :filters frameset-session-filter-alist) + ;; frameset-save does not include the value of point + ;; in the current buffer, so record that separately. + (frameset-frame-id nil) + (point-marker)))) + (defalias 'register-to-point 'jump-to-register) (defun jump-to-register (register &optional delete) "Move point to location stored in a register. If the register contains a file name, find that file. \(To put a file name in a register, you must use `set-register'.) -If the register contains a window configuration (one frame) or a frame -configuration (all frames), restore that frame or all frames accordingly. +If the register contains a window configuration (one frame) or a frameset +\(all frames), restore that frame or all frames accordingly. First argument is a character, naming the register. Optional second arg non-nil (interactively, prefix argument) says to -delete any existing frames that the frame configuration doesn't mention. +delete any existing frames that the frameset doesn't mention. \(Otherwise, these frames are iconified.)" (interactive "cJump to register: \nP") (let ((val (get-register register))) @@ -157,6 +181,16 @@ ((and (consp val) (window-configuration-p (car val))) (set-window-configuration (car val)) (goto-char (cadr val))) + ((and (consp val) (frameset-p (car val))) + (let ((iconify-list (if delete nil (frame-list))) + frame) + (frameset-restore (car val) + :filters frameset-session-filter-alist + :reuse-frames (if delete t :keep)) + (mapc #'iconify-frame iconify-list) + (when (setq frame (frameset-frame-with-id (cadr val))) + (select-frame-set-input-focus frame) + (goto-char (nth 2 val))))) ((markerp val) (or (marker-buffer val) (error "That register's buffer no longer exists")) @@ -269,6 +303,9 @@ ((and (consp val) (frame-configuration-p (car val))) (princ "a frame configuration.")) + ((and (consp val) (frameset-p (car val))) + (princ "a frameset.")) + ((and (consp val) (eq (car val) 'file)) (princ "the file ") (prin1 (cdr val)) ------------------------------------------------------------ revno: 113747 committer: Juanma Barranquero branch nick: trunk timestamp: Thu 2013-08-08 00:54:08 +0200 message: lisp/frameset.el: Convert `frameset' to vector and add new slots. (frameset): Use type vector, not list (incompatible change). Do not declare a new constructor, use the default one. Upgrade suggested properties `app', `name' and `desc' to slots `app', `name' and `description', respectively, and add read-only slot `timestamp'. Doc fixes. (frameset-copy, frameset-persistent-filter-alist) (frameset-filter-alist, frameset-switch-to-gui-p) (frameset-switch-to-tty-p, frameset-filter-tty-to-GUI) (frameset-filter-sanitize-color, frameset-filter-minibuffer) (frameset-filter-iconified, frameset-keep-original-display-p): Doc fixes. (frameset-filter-shelve-param, frameset-filter-unshelve-param): Rename from frameset-filter-(save|restore)-param. All callers changed. Doc fix. (frameset-p): Adapt to change to vector and be more thorough. Change arg name to OBJECT. Doc fix. (frameset-prop): Rename arg PROP to PROPERTY. Doc fix. (frameset-session-filter-alist): Rename from frameset-live-filter-alist. All callers changed. (frameset-frame-with-id): Rename from frameset-locate-frame-id. All callers changed. (frameset--record-minibuffer-relationships): Rename from frameset--process-minibuffer-frames. All callers changed. (frameset-save): Add new keyword arguments APP, NAME and DESCRIPTION. Use new default constructor (again). Doc fix. (frameset--find-frame-if): Rename from `frameset--find-frame. All callers changed. (frameset--reuse-frame): Rename arg FRAME-CFG to PARAMETERS. (frameset--initial-params): Rename arg FRAME-CFG to PARAMETERS. Doc fix. (frameset--restore-frame): Rename args FRAME-CFG and WINDOW-CFG to PARAMETERS and WINDOW-STATE, respectively. (frameset-restore): Add new keyword argument PREDICATE. Reset frameset--target-display to nil. Doc fix. lisp/desktop.el (desktop-save-frameset): Use new frameset-save args. Use lexical-binding. diff: === modified file 'lisp/ChangeLog' --- lisp/ChangeLog 2013-08-07 22:53:18 +0000 +++ lisp/ChangeLog 2013-08-07 22:54:08 +0000 @@ -1,3 +1,43 @@ +2013-08-07 Juanma Barranquero + + * desktop.el (desktop-save-frameset): Use new frameset-save args. + Use lexical-binding. + + * frameset.el (frameset): Use type vector, not list (incompatible + change). Do not declare a new constructor, use the default one. + Upgrade suggested properties `app', `name' and `desc' to slots `app', + `name' and `description', respectively, and add read-only slot + `timestamp'. Doc fixes. + (frameset-copy, frameset-persistent-filter-alist) + (frameset-filter-alist, frameset-switch-to-gui-p) + (frameset-switch-to-tty-p, frameset-filter-tty-to-GUI) + (frameset-filter-sanitize-color, frameset-filter-minibuffer) + (frameset-filter-iconified, frameset-keep-original-display-p): + Doc fixes. + (frameset-filter-shelve-param, frameset-filter-unshelve-param): + Rename from frameset-filter-(save|restore)-param. All callers changed. + Doc fix. + (frameset-p): Adapt to change to vector and be more thorough. + Change arg name to OBJECT. Doc fix. + (frameset-prop): Rename arg PROP to PROPERTY. Doc fix. + (frameset-session-filter-alist): Rename from frameset-live-filter-alist. + All callers changed. + (frameset-frame-with-id): Rename from frameset-locate-frame-id. + All callers changed. + (frameset--record-minibuffer-relationships): Rename from + frameset--process-minibuffer-frames. All callers changed. + (frameset-save): Add new keyword arguments APP, NAME and DESCRIPTION. + Use new default constructor (again). Doc fix. + (frameset--find-frame-if): Rename from `frameset--find-frame. + All callers changed. + (frameset--reuse-frame): Rename arg FRAME-CFG to PARAMETERS. + (frameset--initial-params): Rename arg FRAME-CFG to PARAMETERS. + Doc fix. + (frameset--restore-frame): Rename args FRAME-CFG and WINDOW-CFG to + PARAMETERS and WINDOW-STATE, respectively. + (frameset-restore): Add new keyword argument PREDICATE. + Reset frameset--target-display to nil. Doc fix. + 2013-08-07 Stefan Monnier * progmodes/bat-mode.el (bat--syntax-propertize): New var. === modified file 'lisp/desktop.el' --- lisp/desktop.el 2013-08-05 04:45:17 +0000 +++ lisp/desktop.el 2013-08-07 22:54:08 +0000 @@ -1,4 +1,4 @@ -;;; desktop.el --- save partial status of Emacs when killed +;;; desktop.el --- save partial status of Emacs when killed -*- lexical-binding: t -*- ;; Copyright (C) 1993-1995, 1997, 2000-2013 Free Software Foundation, ;; Inc. @@ -910,12 +910,10 @@ Frames with a non-nil `desktop-dont-save' parameter are not saved." (setq desktop-saved-frameset (and desktop-restore-frames - (let ((name (concat user-login-name "@" system-name - (format-time-string " %Y-%m-%d %T")))) - (frameset-save nil - :predicate #'desktop--check-dont-save - :properties (list :app desktop--app-id - :name name)))))) + (frameset-save nil + :app desktop--app-id + :name (concat user-login-name "@" system-name) + :predicate #'desktop--check-dont-save)))) ;;;###autoload (defun desktop-save (dirname &optional release auto-save) === modified file 'lisp/frameset.el' --- lisp/frameset.el 2013-08-06 12:18:43 +0000 +++ lisp/frameset.el 2013-08-07 22:54:08 +0000 @@ -41,41 +41,35 @@ (require 'cl-lib) -(cl-defstruct (frameset (:type list) :named +(cl-defstruct (frameset (:type vector) :named ;; Copier and predicate functions are defined below. (:copier nil) - (:predicate nil) - ;; A BOA constructor, not the default "keywordy" one. - ;; This is for internal use; to create a frameset, - ;; the "right" way to do it is with frameset-save. - (:constructor make-frameset (properties states))) + (:predicate nil)) "A frameset encapsulates a serializable view of a set of frames and windows. It contains the following slots, which can be accessed with \(frameset-SLOT fs) and set with (setf (frameset-SLOT fs) VALUE): - version A non-modifiable version number, identifying the format - of the frameset struct. Currently its value is 1. + version A read-only version number, identifying the format + of the frameset struct. Currently its value is 1. + timestamp A read-only timestamp, the output of `current-time'. + app A symbol, or a list whose first element is a symbol, which + identifies the creator of the frameset and related info; + for example, desktop.el sets this slot to a list + `(desktop . ,desktop-file-version). + name A string, the name of the frameset instance. + description A string, a description for user consumption (to show in + menus, messages, etc). properties A property list, to store both frameset-specific and - user-defined serializable data (see suggestions below). - states An alist of items (FRAME-PARAMETERS . WINDOW-STATE), in no - particular order. Each item represents a frame to be + user-defined serializable data. + states A list of items (FRAME-PARAMETERS . WINDOW-STATE), in no + particular order. Each item represents a frame to be restored. FRAME-PARAMETERS is a frame's parameter alist, - extracted with (frame-parameters FRAME) and filtered through - `frame-parameters-alist' or a similar filter alist. - WINDOW-STATE is the output of `window-state-get', when - applied to the root window of the frame. - -Some suggested properties: - - :app APPINFO Can be used by applications and packages to indicate the - intended (but by no means exclusive) use of the frameset. - Freeform. For example, currently desktop.el framesets set - :app to `(desktop . ,desktop-file-version). - :name NAME The name of the frameset instance; a string. - :desc TEXT A description for user consumption (to show in a menu to - choose among framesets, etc.); a string. + extracted with (frame-parameters FRAME) and filtered + through `frameset-filter-params'. + WINDOW-STATE is the output of `window-state-get' applied + to the root window of the frame. To avoid collisions, it is recommended that applications wanting to add private serializable data to `properties' either store all info under a @@ -95,31 +89,41 @@ `properties' slot. - The `frameset-SLOT' accessors described above." - (version 1 :read-only t) - properties states) + (version 1 :read-only t) + (timestamp (current-time) :read-only t) + (app nil) + (name nil) + (description nil) + (properties nil) + (states nil)) (defun frameset-copy (frameset) - "Return a copy of FRAMESET. -This is a deep copy done with `copy-tree'." + "Return a deep copy of FRAMESET. +FRAMESET is copied with `copy-tree'." (copy-tree frameset t)) ;;;###autoload -(defun frameset-p (frameset) - "If FRAMESET is a frameset, return its version number. +(defun frameset-p (object) + "If OBJECT is a frameset, return its version number. Else return nil." - (and (eq (car-safe frameset) 'frameset) ; is a list - (integerp (nth 1 frameset)) ; version is an int - (nth 3 frameset) ; states is non-null - (nth 1 frameset))) ; return version + (and (vectorp object) ; a vector + (eq (aref object 0) 'frameset) ; tagged as `frameset' + (integerp (aref object 1)) ; version is an int + (consp (aref object 2)) ; timestamp is a non-null list + (stringp (or (aref object 4) "")) ; name is a string or null + (stringp (or (aref object 5) "")) ; description is a string or null + (listp (aref object 6)) ; properties is a list + (consp (aref object 7)) ; and states is non-null + (aref object 1))) ; return version ;; A setf'able accessor to the frameset's properties -(defun frameset-prop (frameset prop) - "Return the value of the PROP property of FRAMESET. +(defun frameset-prop (frameset property) + "Return the value for FRAMESET of PROPERTY. Properties can be set with (setf (frameset-prop FRAMESET PROP) NEW-VALUE)" - (plist-get (frameset-properties frameset) prop)) + (plist-get (frameset-properties frameset) property)) (gv-define-setter frameset-prop (val fs prop) (macroexp-let2 nil v val @@ -131,8 +135,261 @@ ;; Filtering +;; What's the deal with these "filter alists"? +;; +;; Let's say that Emacs' frame parameters were never designed as a tool to +;; precisely record (or restore) a frame's state. They grew organically, +;; and their uses and behaviors reflect their history. In using them to +;; implement framesets, the unwary implementor, or the prospective package +;; writer willing to use framesets in their code, might fall victim of some +;; unexpected... oddities. +;; +;; You can find frame parameters that: +;; +;; - can be used to get and set some data from the frame's current state +;; (`height', `width') +;; - can be set at creation time, and setting them afterwards has no effect +;; (`window-state', `minibuffer') +;; - can be set at creation time, and setting them afterwards will fail with +;; an error, *unless* you set it to the same value, a noop (`border-width') +;; - act differently when passed at frame creation time, and when set +;; afterwards (`height') +;; - affect the value of other parameters (`name', `visibility') +;; - can be ignored by window managers (most positional args, like `height', +;; `width', `left' and `top', and others, like `auto-raise', `auto-lower') +;; - can be set externally in X resources or Window registry (again, most +;; positional parameters, and also `toolbar-lines', `menu-bar-lines' etc.) +;, - can contain references to live objects (`buffer-list', `minibuffer') or +;; code (`buffer-predicate') +;; - are set automatically, and cannot be changed (`window-id', `parent-id'), +;; but setting them produces no error +;; - have a noticeable effect in some window managers, and are ignored in +;; others (`menu-bar-lines') +;; - can not be safely set in a tty session and then copied back to a GUI +;; session (`font', `background-color', `foreground-color') +;; +;; etc etc. +;; +;; Which means that, in order to save a parameter alist to disk and read it +;; back later to reconstruct a frame, some processing must be done. That's +;; what `frameset-filter-params' and the `frameset-*-filter-alist' variables +;; are for. +;; +;; First, a clarification: the word "filter" in these names refers to both +;; common meanings of filter: to filter out (i.e., to remove), and to pass +;; through a transformation function (think `filter-buffer-substring'). +;; +;; `frameset-filter-params' takes a parameter alist PARAMETERS, a filtering +;; alist FILTER-ALIST, and a flag SAVING to indicate whether we are filtering +;; parameters with the intent of saving a frame or restoring it. It then +;; accumulates an output list, FILTERED, by checking each parameter in +;; PARAMETERS against FILTER-ALIST and obeying any rule found there. The +;; absence of a rule just means the parameter/value pair (called CURRENT in +;; filtering functions) is copied to FILTERED as is. Keyword values :save, +;; :restore and :never tell the function to copy CURRENT to FILTERED in the +;; respective situations, that is, when saving, restoring, or never at all. +;; Values :save and :restore are not used in this package, because usually if +;; you don't want to save a parameter, you don't want to restore it either. +;; But they can be useful, for example, if you already have a saved frameset +;; created with some intent, and want to reuse it for a different objective +;; where the expected parameter list has different requirements. +;; +;; Finally, the value can also be a filtering function, or a filtering +;; function plus some arguments. The function is called for each matching +;; parameter, and receives CURRENT (the parameter/value pair being processed), +;; FILTERED (the output alist so far), PARAMETERS (the full parameter alist), +;; SAVING (the save/restore flag), plus any additional ARGS set along the +;; function in the `frameset-*-filter-alist' entry. The filtering function +;; then has the possibility to pass along CURRENT, or reject it altogether, +;; or pass back a (NEW-PARAM . NEW-VALUE) pair, which does not even need to +;; refer to the same parameter (so you can filter `width' and return `height' +;; and vice versa, if you're feeling silly and want to mess with the user's +;; mind). As a help in deciding what to do, the filtering function has +;; access to PARAMETERS, but must not change it in any way. It also has +;; access to FILTERED, which can be modified at will. This allows two or +;; more filters to coordinate themselves, because in general there's no way +;; to predict the order in which they will be run. +;; +;; So, which parameters are filtered by default, and why? Let's see. +;; +;; - `buffer-list', `buried-buffer-list', `buffer-predicate': They contain +;; references to live objects, or in the case of `buffer-predicate', it +;; could also contain an fbound symbol (a predicate function) that could +;; not be defined in a later session. +;; +;; - `window-id', `outer-window-id', `parent-id': They are assigned +;; automatically and cannot be set, so keeping them is harmless, but they +;; add clutter. `window-system' is similar: it's assigned at frame +;; creation, and does not serve any useful purpose later. +;; +;; - `left', `top': Only problematic when saving an iconified frame, because +;; when the frame is iconified they are set to (- 32000), which doesn't +;; really help in restoring the frame. Better to remove them and let the +;; window manager choose a default position for the frame. +;; +;; - `background-color', `foreground-color': In tty frames they can be set +;; to "unspecified-bg" and "unspecified-fg", which aren't understood on +;; GUI sessions. They have to be filtered out when switching from tty to +;; a graphical display. +;; +;; - `tty', `tty-type': These are tty-specific. When switching to a GUI +;; display they do no harm, but they clutter the parameter list. +;; +;; - `minibuffer': It can contain a reference to a live window, which cannot +;; be serialized. Because of Emacs' idiosyncratic treatment of this +;; parameter, frames created with (minibuffer . t) have a parameter +;; (minibuffer . #), while frames created with +;; (minibuffer . #) have (minibuffer . nil), which is madness +;; but helps to differentiate between minibufferless and "normal" frames. +;; So, changing (minibuffer . #) to (minibuffer . t) allows +;; Emacs to set up the new frame correctly. Nice, uh? +;; +;; - `name': If this parameter is directly set, `explicit-name' is +;; automatically set to t, and then `name' no longer changes dynamically. +;; So, in general, not saving `name' is the right thing to do, though +;; surely there are applications that will want to override this filter. +;; +;; - `font', `fullscreen', `height' and `width': These parameters suffer +;; from the fact that they are badly manged when going through a +;; tty session, though not all in the same way. When saving a GUI frame +;; and restoring it in a tty, the height and width of the new frame are +;; those of the tty screen (let's say 80x25, for example); going back +;; to a GUI session means getting frames of the tty screen size (so all +;; your frames are 80 cols x 25 rows). For `fullscreen' there's a +;; similar problem, because a tty frame cannot really be fullscreen or +;; maximized, so the state is lost. The problem with `font' is a bit +;; different, because a valid GUI font spec in `font' turns into +;; (font . "tty") in a tty frame, and when read back into a GUI session +;; it fails because `font's value is no longer a valid font spec. +;; +;; In most cases, the filtering functions just do the obvious thing: remove +;; CURRENT when it is meaningless to keep it, or pass a modified copy if +;; that helps (as in the case of `minibuffer'). +;; +;; The exception are the parameters in the last set, which should survive +;; the roundtrip though tty-land. The answer is to add "stashing +;; parameters", working in pairs, to shelve the GUI-specific contents and +;; restore it once we're back in pixel country. That's what functions +;; `frameset-filter-shelve-param' and `frameset-unshelve-param' do. +;; +;; Basically, if you set `frameset-filter-shelve-param' as the filter for +;; a parameter P, it will detect when it is restoring a GUI frame into a +;; tty session, and save P's value in the custom parameter X:P, but only +;; if X:P does not exist already (so it is not overwritten if you enter +;; the tty session more than once). If you're not switching to a tty +;; frame, the filter just passes CURRENT along. +;; +;; The parameter X:P, on the other hand, must have been setup to be +;; filtered by `frameset-filter-unshelve-param', which unshelves the +;; value: if we're entering a GUI session, returns P instead of CURRENT, +;; while in other cases it just passes it along. +;; +;; The only additional trick is that `frameset-filter-shelve-param' does +;; not set P if switching back to GUI and P already has a value, because +;; it assumes that `frameset-filter-unshelve-param' did set it up. And +;; `frameset-filter-unshelve-param', when unshelving P, must look into +;; FILTERED to determine if P has already been set and if so, modify it; +;; else just returns P. +;; +;; Currently, the value of X in X:P is `GUI', but you can use any prefix, +;; by passing its symbol as argument in the filter: +;; +;; (my-parameter frameset-filter-shelve-param MYPREFIX) +;; +;; instead of +;; +;; (my-parameter . frameset-filter-shelve-param) +;; +;; Note that `frameset-filter-unshelve-param' does not need MYPREFIX +;; because it is available from the parameter name in CURRENT. Also note +;; that the colon between the prefix and the parameter name is hardcoded. +;; The reason is that X:P is quite readable, and that the colon is a +;; very unusual character in symbol names, other than in initial position +;; in keywords (emacs -Q has only two such symbols, and one of them is a +;; URL). So the probability of a collision with existing or future +;; symbols is quite insignificant. +;; +;; Now, what about the filter alists? There are three of them, though +;; only two sets of parameters: +;; +;; - `frameset-session-filter-alist' contains these filters that allow to +;; save and restore framesets in-session, without the need to serialize +;; the frameset or save it to disk (for example, to save a frameset in a +;; register and restore it later). Filters in this list do not remove +;; live objects, except in `minibuffer', which is dealt especially by +;; `frameset-save' / `frameset-restore'. +;; +;; - `frameset-persistent-filter-alist' is the whole deal. It does all +;; the filtering described above, and the result is ready to be saved on +;; disk without loss of information. That's the format used by the +;; desktop.el package, for example. +;; +;; IMPORTANT: These variables share structure and should never be modified. +;; +;; - `frameset-filter-alist': The value of this variable is the default +;; value for the FILTERS arguments of `frameset-save' and +;; `frameset-restore'. It is set to `frameset-persistent-filter-alist', +;; though it can be changed by specific applications. +;; +;; How to use them? +;; +;; The simplest way is just do nothing. The default should work +;; reasonably and sensibly enough. But, what if you really need a +;; customized filter alist? Then you can create your own variable +;; +;; (defvar my-filter-alist +;; '((my-param1 . :never) +;; (my-param2 . :save) +;; (my-param3 . :restore) +;; (my-param4 . my-filtering-function-without-args) +;; (my-param5 my-filtering-function-with arg1 arg2) +;; ;;; many other parameters +;; ) +;; "My customized parameter filter alist.") +;; +;; or, if you're only changing a few items, +;; +;; (defvar my-filter-alist +;; (nconc '((my-param1 . :never) +;; (my-param2 . my-filtering-function)) +;; frameset-filter-alist) +;; "My brief customized parameter filter alist.") +;; +;; and pass it to the FILTER arg of the save/restore functions, +;; ALWAYS taking care of not modifying the original lists; if you're +;; going to do any modifying of my-filter-alist, please use +;; +;; (nconc '((my-param1 . :never) ...) +;; (copy-sequence frameset-filter-alist)) +;; +;; One thing you shouldn't forget is that they are alists, so searching +;; in them is sequential. If you just want to change the default of +;; `name' to allow it to be saved, you can set (name . nil) in your +;; customized filter alist; it will take precedence over the latter +;; setting. In case you decide that you *always* want to save `name', +;; you can add it to `frameset-filter-alist': +;; +;; (push '(name . nil) frameset-filter-alist) +;; +;; In certain applications, having a parameter filtering function like +;; `frameset-filter-params' can be useful, even if you're not using +;; framesets. The interface of `frameset-filter-params' is generic +;; and does not depend of global state, with one exception: it uses +;; the internal variable `frameset--target-display' to decide if, and +;; how, to modify the `display' parameter of FILTERED. But that +;; should not represent any problem, because it's only meaningful +;; when restoring, and customized uses of `frameset-filter-params' +;; are likely to use their own filter alist and just call +;; +;; (setq my-filtered (frameset-filter-params my-params my-filters t)) +;; +;; In case you want to use it with the standard filters, you can +;; wrap the call to `frameset-filter-params' in a let form to bind +;; `frameset--target-display' to nil or the desired value. +;; + ;;;###autoload -(defvar frameset-live-filter-alist +(defvar frameset-session-filter-alist '((name . :never) (left . frameset-filter-iconified) (minibuffer . frameset-filter-minibuffer) @@ -147,33 +404,35 @@ (buffer-list . :never) (buffer-predicate . :never) (buried-buffer-list . :never) - (font . frameset-filter-save-param) + (font . frameset-filter-shelve-param) (foreground-color . frameset-filter-sanitize-color) - (fullscreen . frameset-filter-save-param) - (GUI:font . frameset-filter-restore-param) - (GUI:fullscreen . frameset-filter-restore-param) - (GUI:height . frameset-filter-restore-param) - (GUI:width . frameset-filter-restore-param) - (height . frameset-filter-save-param) + (fullscreen . frameset-filter-shelve-param) + (GUI:font . frameset-filter-unshelve-param) + (GUI:fullscreen . frameset-filter-unshelve-param) + (GUI:height . frameset-filter-unshelve-param) + (GUI:width . frameset-filter-unshelve-param) + (height . frameset-filter-shelve-param) (outer-window-id . :never) (parent-id . :never) (tty . frameset-filter-tty-to-GUI) (tty-type . frameset-filter-tty-to-GUI) - (width . frameset-filter-save-param) + (width . frameset-filter-shelve-param) (window-id . :never) (window-system . :never)) - frameset-live-filter-alist) - "Recommended set of parameters to filter for persistent framesets. + frameset-session-filter-alist) + "Parameters to filter for persistent framesets. See `frameset-filter-alist' for a full description.") ;;;###autoload (defvar frameset-filter-alist frameset-persistent-filter-alist "Alist of frame parameters and filtering functions. -This alist is the default value of the :filters arguments of -`frameset-save' and `frameset-restore' (which see). On saving, -PARAMETERS is the parameter alist of each frame processed, and -FILTERED is the parameter alist that gets saved to the frameset. +This alist is the default value of the FILTERS argument of +`frameset-save' and `frameset-restore' (which see). + +On saving, PARAMETERS is the parameter alist of each frame processed, +and FILTERED is the parameter alist that gets saved to the frameset. + On restoring, PARAMETERS is the parameter alist extracted from the frameset, and FILTERED is the resulting frame parameter alist used to restore the frame. @@ -200,7 +459,7 @@ FILTERED The resulting alist (so far). PARAMETERS The complete alist of parameters being filtered, SAVING Non-nil if filtering before saving state, nil if filtering - before restoring it. + before restoring it. ARGS Any additional arguments specified in the ACTION. FILTER-FUN is allowed to modify items in FILTERED, but no other arguments. @@ -223,20 +482,20 @@ (defun frameset-switch-to-gui-p (parameters) "True when switching to a graphic display. -Return t if PARAMETERS describes a text-only terminal and -the target is a graphic display; otherwise return nil. -Only meaningful when called from a filtering function in -`frameset-filter-alist'." +Return non-nil if the parameter alist PARAMETERS describes a frame on a +text-only terminal, and the frame is being restored on a graphic display; +otherwise return nil. Only meaningful when called from a filtering +function in `frameset-filter-alist'." (and frameset--target-display ; we're switching (null (cdr (assq 'display parameters))) ; from a tty (cdr frameset--target-display))) ; to a GUI display (defun frameset-switch-to-tty-p (parameters) "True when switching to a text-only terminal. -Return t if PARAMETERS describes a graphic display and -the target is a text-only terminal; otherwise return nil. -Only meaningful when called from a filtering function in -`frameset-filter-alist'." +Return non-nil if the parameter alist PARAMETERS describes a frame on a +graphic display, and the frame is being restored on a text-only terminal; +otherwise return nil. Only meaningful when called from a filtering +function in `frameset-filter-alist'." (and frameset--target-display ; we're switching (cdr (assq 'display parameters)) ; from a GUI display (null (cdr frameset--target-display)))) ; to a tty @@ -245,7 +504,7 @@ "Remove CURRENT when switching from tty to a graphic display. For the meaning of CURRENT, FILTERED, PARAMETERS and SAVING, -see the docstring of `frameset-filter-alist'." +see `frameset-filter-alist'." (or saving (not (frameset-switch-to-gui-p parameters)))) @@ -254,30 +513,30 @@ Useful as a filter function for tty-specific parameters. For the meaning of CURRENT, FILTERED, PARAMETERS and SAVING, -see the docstring of `frameset-filter-alist'." +see `frameset-filter-alist'." (or saving (not (frameset-switch-to-gui-p parameters)) (not (stringp (cdr current))) (not (string-match-p "^unspecified-[fb]g$" (cdr current))))) (defun frameset-filter-minibuffer (current _filtered _parameters saving) - "When saving, convert (minibuffer . #) parameter to (minibuffer . t). + "When saving, convert (minibuffer . #) to (minibuffer . t). For the meaning of CURRENT, FILTERED, PARAMETERS and SAVING, -see the docstring of `frameset-filter-alist'." +see `frameset-filter-alist'." (or (not saving) (if (windowp (cdr current)) '(minibuffer . t) t))) -(defun frameset-filter-save-param (current _filtered parameters saving - &optional prefix) +(defun frameset-filter-shelve-param (current _filtered parameters saving + &optional prefix) "When switching to a tty frame, save parameter P as PREFIX:P. -The parameter can be later restored with `frameset-filter-restore-param'. +The parameter can be later restored with `frameset-filter-unshelve-param'. PREFIX defaults to `GUI'. For the meaning of CURRENT, FILTERED, PARAMETERS and SAVING, -see the docstring of `frameset-filter-alist'." +see `frameset-filter-alist'." (unless prefix (setq prefix 'GUI)) (cond (saving t) ((frameset-switch-to-tty-p parameters) @@ -289,12 +548,12 @@ (not (assq (intern (format "%s:%s" prefix (car current))) parameters))) (t t))) -(defun frameset-filter-restore-param (current filtered parameters saving) +(defun frameset-filter-unshelve-param (current filtered parameters saving) "When switching to a GUI frame, restore PREFIX:P parameter as P. CURRENT must be of the form (PREFIX:P . value). For the meaning of CURRENT, FILTERED, PARAMETERS and SAVING, -see the docstring of `frameset-filter-alist'." +see `frameset-filter-alist'." (or saving (not (frameset-switch-to-gui-p parameters)) (let* ((prefix:p (symbol-name (car current))) @@ -314,7 +573,7 @@ default position. For the meaning of CURRENT, FILTERED, PARAMETERS and SAVING, -see the docstring of `frameset-filter-alist'." +see `frameset-filter-alist'." (not (and saving (eq (cdr (assq 'visibility parameters)) 'icon)))) (defun frameset-filter-params (parameters filter-alist saving) @@ -382,7 +641,7 @@ (string= (frameset-frame-id frame) id)) ;;;###autoload -(defun frameset-locate-frame-id (id &optional frame-list) +(defun frameset-frame-with-id (id &optional frame-list) "Return the live frame with id ID, if exists; else nil. If FRAME-LIST is a list of frames, check these frames only. If nil, check all live frames." @@ -394,7 +653,7 @@ ;; Saving framesets -(defun frameset--process-minibuffer-frames (frame-list) +(defun frameset--record-minibuffer-relationships (frame-list) "Process FRAME-LIST and record minibuffer relationships. FRAME-LIST is a list of frames. Internal use only." ;; Record frames with their own minibuffer @@ -423,11 +682,16 @@ (cons nil id))))))) ;;;###autoload -(cl-defun frameset-save (frame-list &key filters predicate properties) - "Return the frameset of FRAME-LIST, a list of frames. +(cl-defun frameset-save (frame-list + &key app name description + filters predicate properties) + "Return a frameset for FRAME-LIST, a list of frames. Dead frames and non-frame objects are silently removed from the list. If nil, FRAME-LIST defaults to the output of `frame-list' (all live frames). -FILTERS is an alist of parameter filters, or `frameset-filter-alist' if nil. +APP, NAME and DESCRIPTION are optional data; see the docstring of the +`frameset' defstruct for details. +FILTERS is an alist of parameter filters; if nil, the value of the variable +`frameset-filter-alist' is used instead. PREDICATE is a predicate function, which must return non-nil for frames that should be saved; if PREDICATE is nil, all frames from FRAME-LIST are saved. PROPERTIES is a user-defined property list to add to the frameset." @@ -436,16 +700,20 @@ (if predicate (cl-delete-if-not predicate list) list)))) - (frameset--process-minibuffer-frames frames) - (make-frameset properties - (mapcar - (lambda (frame) - (cons - (frameset-filter-params (frame-parameters frame) - (or filters frameset-filter-alist) - t) - (window-state-get (frame-root-window frame) t))) - frames)))) + (frameset--record-minibuffer-relationships frames) + (make-frameset :app app + :name name + :description description + :properties properties + :states (mapcar + (lambda (frame) + (cons + (frameset-filter-params (frame-parameters frame) + (or filters + frameset-filter-alist) + t) + (window-state-get (frame-root-window frame) t))) + frames)))) ;; Restoring framesets @@ -534,7 +802,7 @@ (when params (modify-frame-parameters frame params)))))) -(defun frameset--find-frame (predicate display &rest args) +(defun frameset--find-frame-if (predicate display &rest args) "Find a frame in `frameset--reuse-list' satisfying PREDICATE. Look through available frames whose display property matches DISPLAY and return the first one for which (PREDICATE frame ARGS) returns t. @@ -545,9 +813,9 @@ (apply predicate frame args)))) frameset--reuse-list)) -(defun frameset--reuse-frame (display frame-cfg) - "Look for an existing frame to reuse. -DISPLAY is the display where the frame will be shown, and FRAME-CFG +(defun frameset--reuse-frame (display parameters) + "Return an existing frame to reuse, or nil if none found. +DISPLAY is the display where the frame will be shown, and PARAMETERS is the parameter alist of the frame being restored. Internal use only." (let ((frame nil) mini) @@ -561,19 +829,19 @@ ;; will usually have only one frame, and should already work. (cond ((null display) ;; When the target is tty, every existing frame is reusable. - (setq frame (frameset--find-frame nil display))) - ((car (setq mini (cdr (assq 'frameset--mini frame-cfg)))) + (setq frame (frameset--find-frame-if nil display))) + ((car (setq mini (cdr (assq 'frameset--mini parameters)))) ;; If the frame has its own minibuffer, let's see whether ;; that frame has already been loaded (which can happen after ;; M-x desktop-read). - (setq frame (frameset--find-frame + (setq frame (frameset--find-frame-if (lambda (f id) (frameset-frame-id-equal-p f id)) - display (cdr (assq 'frameset--id frame-cfg)))) + display (cdr (assq 'frameset--id parameters)))) ;; If it has not been loaded, and it is not a minibuffer-only frame, ;; let's look for an existing non-minibuffer-only frame to reuse. - (unless (or frame (eq (cdr (assq 'minibuffer frame-cfg)) 'only)) - (setq frame (frameset--find-frame + (unless (or frame (eq (cdr (assq 'minibuffer parameters)) 'only)) + (setq frame (frameset--find-frame-if (lambda (f) (let ((w (frame-parameter f 'minibuffer))) (and (window-live-p w) @@ -583,39 +851,38 @@ (mini ;; For minibufferless frames, check whether they already exist, ;; and that they are linked to the right minibuffer frame. - (setq frame (frameset--find-frame + (setq frame (frameset--find-frame-if (lambda (f id mini-id) (and (frameset-frame-id-equal-p f id) (frameset-frame-id-equal-p (window-frame (minibuffer-window f)) mini-id))) - display (cdr (assq 'frameset--id frame-cfg)) (cdr mini)))) + display (cdr (assq 'frameset--id parameters)) (cdr mini)))) (t ;; Default to just finding a frame in the same display. - (setq frame (frameset--find-frame nil display)))) + (setq frame (frameset--find-frame-if nil display)))) ;; If found, remove from the list. (when frame (setq frameset--reuse-list (delq frame frameset--reuse-list))) frame)) -(defun frameset--initial-params (frame-cfg) - "Return parameters from FRAME-CFG that should not be changed later. +(defun frameset--initial-params (parameters) + "Return a list of PARAMETERS that must be set when creating the frame. Setting position and size parameters as soon as possible helps reducing -flickering; other parameters, like `minibuffer' and `border-width', must -be set when creating the frame because they can not be changed later. -Internal use only." +flickering; other parameters, like `minibuffer' and `border-width', can +not be changed once the frame has been created. Internal use only." (cl-loop for param in '(left top with height border-width minibuffer) - collect (assq param frame-cfg))) + collect (assq param parameters))) -(defun frameset--restore-frame (frame-cfg window-cfg filters force-onscreen) +(defun frameset--restore-frame (parameters window-state filters force-onscreen) "Set up and return a frame according to its saved state. That means either reusing an existing frame or creating one anew. -FRAME-CFG is the frame's parameter alist; WINDOW-CFG is its window state. +PARAMETERS is the frame's parameter alist; WINDOW-STATE is its window state. For the meaning of FILTERS and FORCE-ONSCREEN, see `frameset-restore'. Internal use only." - (let* ((fullscreen (cdr (assq 'fullscreen frame-cfg))) - (lines (assq 'tool-bar-lines frame-cfg)) - (filtered-cfg (frameset-filter-params frame-cfg filters nil)) + (let* ((fullscreen (cdr (assq 'fullscreen parameters))) + (lines (assq 'tool-bar-lines parameters)) + (filtered-cfg (frameset-filter-params parameters filters nil)) (display (cdr (assq 'display filtered-cfg))) ;; post-filtering alt-cfg frame) @@ -673,7 +940,7 @@ (when lines (push lines alt-cfg)) (when alt-cfg (modify-frame-parameters frame alt-cfg)) ;; Now restore window state. - (window-state-put window-cfg (frame-root-window frame) 'safe) + (window-state-put window-state (frame-root-window frame) 'safe) frame)) (defun frameset--minibufferless-last-p (state1 state2) @@ -689,7 +956,8 @@ (t t)))) (defun frameset-keep-original-display-p (force-display) - "True if saved frames' displays should be honored." + "True if saved frames' displays should be honored. +For the meaning of FORCE-DISPLAY, see `frameset-restore'." (cond ((daemonp) t) ((eq system-type 'windows-nt) nil) ;; Does ns support more than one display? (t (not force-display)))) @@ -700,26 +968,35 @@ ;;;###autoload (cl-defun frameset-restore (frameset - &key filters reuse-frames force-display force-onscreen) + &key predicate filters reuse-frames + force-display force-onscreen) "Restore a FRAMESET into the current display(s). -FILTERS is an alist of parameter filters; defaults to `frameset-filter-alist'. +PREDICATE is a function called with two arguments, the parameter alist +and the window-state of the frame being restored, in that order (see +the docstring of the `frameset' defstruct for additional details). +If PREDICATE returns nil, the frame described by that parameter alist +and window-state is not restored. + +FILTERS is an alist of parameter filters; if nil, the value of +`frameset-filter-alist' is used instead. REUSE-FRAMES selects the policy to use to reuse frames when restoring: - t Reuse any existing frame if possible; delete leftover frames. + t Reuse existing frames if possible, and delete those not reused. nil Restore frameset in new frames and delete existing frames. :keep Restore frameset in new frames and keep the existing ones. - LIST A list of frames to reuse; only these are reused (if possible), - and any leftover ones are deleted; other frames not on this - list are left untouched. + LIST A list of frames to reuse; only these are reused (if possible). + Remaining frames in this list are deleted; other frames not + included on the list are left untouched. FORCE-DISPLAY can be: t Frames are restored in the current display. nil Frames are restored, if possible, in their original displays. :delete Frames in other displays are deleted instead of restored. - PRED A function called with one argument, the parameter alist; - it must return t, nil or `:delete', as above but affecting - only the frame that will be created from that parameter alist. + PRED A function called with two arguments, the parameter alist and + the window state (in that order). It must return t, nil or + `:delete', as above but affecting only the frame that will + be created from that parameter alist. FORCE-ONSCREEN can be: t Force onscreen only those frames that are fully offscreen. @@ -736,7 +1013,7 @@ restored before that happens, and FORCE-ONSCREEN affects the frame once it has been restored. -All keywords default to nil." +All keyword parameters default to nil." (cl-assert (frameset-p frameset)) @@ -751,8 +1028,8 @@ ((pred consp) (setq frameset--reuse-list (copy-sequence reuse-frames) other-frames (cl-delete-if (lambda (frame) - (memq frame frameset--reuse-list)) - (frame-list)))) + (memq frame frameset--reuse-list)) + (frame-list)))) (_ (setq frameset--reuse-list (frame-list) other-frames nil))) @@ -761,73 +1038,74 @@ ;; after the frames that contain their minibuffer windows. (dolist (state (sort (copy-sequence (frameset-states frameset)) #'frameset--minibufferless-last-p)) - (condition-case-unless-debug err - (pcase-let* ((`(,frame-cfg . ,window-cfg) state) - ((and d-mini `(,hasmini . ,mb-id)) - (cdr (assq 'frameset--mini frame-cfg))) - (default (and (booleanp mb-id) mb-id)) - (force-display (if (functionp force-display) - (funcall force-display frame-cfg) - force-display)) - (frame nil) (to-tty nil)) - ;; Only set target if forcing displays and the target display is different. - (cond ((frameset-keep-original-display-p force-display) - (setq frameset--target-display nil)) - ((eq (frame-parameter nil 'display) (cdr (assq 'display frame-cfg))) - (setq frameset--target-display nil)) - (t - (setq frameset--target-display (cons 'display - (frame-parameter nil 'display)) - to-tty (null (cdr frameset--target-display))))) - ;; Time to restore frames and set up their minibuffers as they were. - ;; We only skip a frame (thus deleting it) if either: - ;; - we're switching displays, and the user chose the option to delete, or - ;; - we're switching to tty, and the frame to restore is minibuffer-only. - (unless (and frameset--target-display - (or (eq force-display :delete) - (and to-tty - (eq (cdr (assq 'minibuffer frame-cfg)) 'only)))) - ;; If keeping non-reusable frames, and the frameset--id of one of them - ;; matches the id of a frame being restored (because, for example, the - ;; frameset has already been read in the same session), remove the - ;; frameset--id from the non-reusable frame, which is not useful anymore. - (when (and other-frames - (or (eq reuse-frames :keep) (consp reuse-frames))) - (let ((dup (frameset-locate-frame-id (cdr (assq 'frameset--id frame-cfg)) - other-frames))) - (when dup - (set-frame-parameter dup 'frameset--id nil)))) - ;; Restore minibuffers. Some of this stuff could be done in a filter - ;; function, but it would be messy because restoring minibuffers affects - ;; global state; it's best to do it here than add a bunch of global - ;; variables to pass info back-and-forth to/from the filter function. - (cond - ((null d-mini)) ;; No frameset--mini. Process as normal frame. - (to-tty) ;; Ignore minibuffer stuff and process as normal frame. - (hasmini ;; Frame has minibuffer (or it is minibuffer-only). - (when (eq (cdr (assq 'minibuffer frame-cfg)) 'only) - (setq frame-cfg (append '((tool-bar-lines . 0) (menu-bar-lines . 0)) - frame-cfg)))) - (t ;; Frame depends on other frame's minibuffer window. - (let* ((mb-frame (or (frameset-locate-frame-id mb-id) - (error "Minibuffer frame %S not found" mb-id))) - (mb-param (assq 'minibuffer frame-cfg)) - (mb-window (minibuffer-window mb-frame))) - (unless (and (window-live-p mb-window) - (window-minibuffer-p mb-window)) - (error "Not a minibuffer window %s" mb-window)) - (if mb-param - (setcdr mb-param mb-window) - (push (cons 'minibuffer mb-window) frame-cfg))))) - ;; OK, we're ready at last to create (or reuse) a frame and - ;; restore the window config. - (setq frame (frameset--restore-frame frame-cfg window-cfg - (or filters frameset-filter-alist) - force-onscreen)) - ;; Set default-minibuffer if required. - (when default (setq default-minibuffer-frame frame)))) - (error - (delay-warning 'frameset (error-message-string err) :error)))) + (pcase-let ((`(,frame-cfg . ,window-cfg) state)) + (when (or (null predicate) (funcall predicate frame-cfg window-cfg)) + (condition-case-unless-debug err + (let* ((d-mini (cdr (assq 'frameset--mini frame-cfg))) + (mb-id (cdr d-mini)) + (default (and (booleanp mb-id) mb-id)) + (force-display (if (functionp force-display) + (funcall force-display frame-cfg window-cfg) + force-display)) + frame to-tty) + ;; Only set target if forcing displays and the target display is different. + (cond ((frameset-keep-original-display-p force-display) + (setq frameset--target-display nil)) + ((eq (frame-parameter nil 'display) (cdr (assq 'display frame-cfg))) + (setq frameset--target-display nil)) + (t + (setq frameset--target-display (cons 'display + (frame-parameter nil 'display)) + to-tty (null (cdr frameset--target-display))))) + ;; Time to restore frames and set up their minibuffers as they were. + ;; We only skip a frame (thus deleting it) if either: + ;; - we're switching displays, and the user chose the option to delete, or + ;; - we're switching to tty, and the frame to restore is minibuffer-only. + (unless (and frameset--target-display + (or (eq force-display :delete) + (and to-tty + (eq (cdr (assq 'minibuffer frame-cfg)) 'only)))) + ;; If keeping non-reusable frames, and the frameset--id of one of them + ;; matches the id of a frame being restored (because, for example, the + ;; frameset has already been read in the same session), remove the + ;; frameset--id from the non-reusable frame, which is not useful anymore. + (when (and other-frames + (or (eq reuse-frames :keep) (consp reuse-frames))) + (let ((dup (frameset-frame-with-id (cdr (assq 'frameset--id frame-cfg)) + other-frames))) + (when dup + (set-frame-parameter dup 'frameset--id nil)))) + ;; Restore minibuffers. Some of this stuff could be done in a filter + ;; function, but it would be messy because restoring minibuffers affects + ;; global state; it's best to do it here than add a bunch of global + ;; variables to pass info back-and-forth to/from the filter function. + (cond + ((null d-mini)) ;; No frameset--mini. Process as normal frame. + (to-tty) ;; Ignore minibuffer stuff and process as normal frame. + ((car d-mini) ;; Frame has minibuffer (or it is minibuffer-only). + (when (eq (cdr (assq 'minibuffer frame-cfg)) 'only) + (setq frame-cfg (append '((tool-bar-lines . 0) (menu-bar-lines . 0)) + frame-cfg)))) + (t ;; Frame depends on other frame's minibuffer window. + (let* ((mb-frame (or (frameset-frame-with-id mb-id) + (error "Minibuffer frame %S not found" mb-id))) + (mb-param (assq 'minibuffer frame-cfg)) + (mb-window (minibuffer-window mb-frame))) + (unless (and (window-live-p mb-window) + (window-minibuffer-p mb-window)) + (error "Not a minibuffer window %s" mb-window)) + (if mb-param + (setcdr mb-param mb-window) + (push (cons 'minibuffer mb-window) frame-cfg))))) + ;; OK, we're ready at last to create (or reuse) a frame and + ;; restore the window config. + (setq frame (frameset--restore-frame frame-cfg window-cfg + (or filters frameset-filter-alist) + force-onscreen)) + ;; Set default-minibuffer if required. + (when default (setq default-minibuffer-frame frame)))) + (error + (delay-warning 'frameset (error-message-string err) :error)))))) ;; In case we try to delete the initial frame, we want to make sure that ;; other frames are already visible (discussed in thread for bug#14841). @@ -845,7 +1123,8 @@ (delete-frame frame) (error (delay-warning 'frameset (error-message-string err)))))) - (setq frameset--reuse-list nil) + (setq frameset--reuse-list nil + frameset--target-display nil) ;; Make sure there's at least one visible frame. (unless (or (daemonp) (visible-frame-list)) ------------------------------------------------------------ revno: 113746 committer: Stefan Monnier branch nick: trunk timestamp: Wed 2013-08-07 18:53:18 -0400 message: * lisp/progmodes/bat-mode.el (bat--syntax-propertize): New var. (bat-mode): Use it. (bat-mode-syntax-table): Mark \n as end-of-comment. (bat-font-lock-keywords): Remove comment rule. diff: === modified file 'lisp/ChangeLog' --- lisp/ChangeLog 2013-08-07 22:42:44 +0000 +++ lisp/ChangeLog 2013-08-07 22:53:18 +0000 @@ -1,5 +1,10 @@ 2013-08-07 Stefan Monnier + * progmodes/bat-mode.el (bat--syntax-propertize): New var. + (bat-mode): Use it. + (bat-mode-syntax-table): Mark \n as end-of-comment. + (bat-font-lock-keywords): Remove comment rule. + * progmodes/bat-mode.el: Rename from dos.el. Use "bat-" prefix. (dos-mode-help): Remove. Use describe-mode (C-h m) instead. === modified file 'lisp/progmodes/bat-mode.el' --- lisp/progmodes/bat-mode.el 2013-08-07 22:42:44 +0000 +++ lisp/progmodes/bat-mode.el 2013-08-07 22:53:18 +0000 @@ -80,8 +80,6 @@ '("bash" "cat" "cp" "fgrep" "grep" "ls" "sed" "sh" "mv" "rm"))) `(("\\<_\\(call\\|goto\\)\\_>[ \t]+%?\\([A-Za-z0-9-_\\:.]+\\)%?" (2 font-lock-constant-face t)) - ("^[ \t]*\\(@?rem\\_>\\|::\\).*" - (0 font-lock-comment-face t)) ("^:[^:].*" . 'bat-label-face) ("\\<_\\(defined\\|set\\)\\_>[ \t]*\\(\\w+\\)" @@ -121,6 +119,7 @@ (defvar bat-mode-syntax-table (let ((table (make-syntax-table))) + (modify-syntax-entry ?\n ">" table) ;; Beware: `w' should not be used for non-alphabetic chars. (modify-syntax-entry ?~ "_" table) (modify-syntax-entry ?% "." table) @@ -132,6 +131,10 @@ (modify-syntax-entry ?\\ "." table) table)) +(defconst bat--syntax-propertize + (syntax-propertize-rules + ("^[ \t]*\\(?:\\(@?r\\)em\\_>\\|\\(?1::\\):\\).*" (1 "<")))) + ;; 4 User functions (defun bat-cmd-help (cmd) @@ -171,6 +174,7 @@ Run script using `bat-run' and `bat-run-args'.\n \\{bat-mode-map}" (setq-local comment-start "rem ") + (setq-local syntax-propertize-function bat--syntax-propertize) (setq-local font-lock-defaults '(bat-font-lock-keywords nil t)) ; case-insensitive keywords (setq-local imenu-generic-expression '((nil "^:[^:].*" 0))) ------------------------------------------------------------ revno: 113745 committer: Stefan Monnier branch nick: trunk timestamp: Wed 2013-08-07 18:42:44 -0400 message: * lisp/progmodes/bat-mode.el: Rename from dos.el. Use "bat-" prefix. (dos-mode-help): Remove. Use describe-mode (C-h m) instead. diff: === modified file 'lisp/ChangeLog' --- lisp/ChangeLog 2013-08-07 17:33:30 +0000 +++ lisp/ChangeLog 2013-08-07 22:42:44 +0000 @@ -1,5 +1,8 @@ 2013-08-07 Stefan Monnier + * progmodes/bat-mode.el: Rename from dos.el. Use "bat-" prefix. + (dos-mode-help): Remove. Use describe-mode (C-h m) instead. + * emacs-lisp/bytecomp.el: Check existence of f in #'f. (byte-compile-callargs-warn): Use `push'. (byte-compile-arglist-warn): Ignore higher-order "calls". === modified file 'lisp/generic-x.el' --- lisp/generic-x.el 2013-08-07 15:43:57 +0000 +++ lisp/generic-x.el 2013-08-07 22:42:44 +0000 @@ -460,7 +460,7 @@ ;;; DOS/Windows BAT files (when (memq 'bat-generic-mode generic-extras-enable-list) - (define-obsolete-function-alias 'bat-generic-mode 'dos-mode "24.4")) + (define-obsolete-function-alias 'bat-generic-mode 'bat-mode "24.4")) ;;; Mailagent ;; Mailagent is a Unix mail filtering program. Anyone wanna do a === renamed file 'lisp/progmodes/dos.el' => 'lisp/progmodes/bat-mode.el' --- lisp/progmodes/dos.el 2013-08-07 16:37:04 +0000 +++ lisp/progmodes/bat-mode.el 2013-08-07 22:42:44 +0000 @@ -1,4 +1,4 @@ -;;; dos.el --- Major mode for editing Dos scripts +;;; bat-mode.el --- Major mode for editing DOS/Windows scripts ;; Copyright (C) 2003, 2008-2013 Free Software Foundation, Inc. @@ -22,13 +22,13 @@ ;;; Commentary: ;; -;; Major mode for editing Dos scripts (batch files). Provides syntax -;; highlighting, a basic template, access to Dos help pages, imenu/outline +;; Major mode for editing DOS/Windows scripts (batch files). Provides syntax +;; highlighting, a basic template, access to DOS help pages, imenu/outline ;; navigation, and the ability to run scripts from within Emacs. The syntax ;; groups for highlighting are: ;; ;; Face Example -;; dos-label-face :LABEL +;; bat-label-face :LABEL ;; font-lock-comment-face rem ;; font-lock-builtin-face copy ;; font-lock-keyword-face goto @@ -39,7 +39,7 @@ ;; ;; Usage: ;; -;; See documentation of function `dos-mode'. +;; See documentation of function `bat-mode'. ;; ;; Separate package `dos-indent' (Matthew Fidler) provides rudimentary ;; indentation, see http://www.emacswiki.org/emacs/dos-indent.el. @@ -52,20 +52,19 @@ ;; 1 Preamble -(defgroup dos nil +(defgroup bat-mode nil "Major mode for editing DOS/Windows batch files." :link '(custom-group-link :tag "Font Lock Faces group" font-lock-faces) :group 'languages) ;; 2 User variables -(defface dos-label-face '((t :weight bold)) - "Font Lock mode face used to highlight labels in batch files." - :group 'dos) +(defface bat-label-face '((t :weight bold)) + "Font Lock mode face used to highlight labels in batch files.") ;; 3 Internal variables -(defvar dos-font-lock-keywords +(defvar bat-font-lock-keywords (eval-when-compile (let ((COMMANDS '("assoc" "at" "attrib" "cd" "cls" "color" "copy" "date" "del" "dir" @@ -84,7 +83,7 @@ ("^[ \t]*\\(@?rem\\_>\\|::\\).*" (0 font-lock-comment-face t)) ("^:[^:].*" - . 'dos-label-face) + . 'bat-label-face) ("\\<_\\(defined\\|set\\)\\_>[ \t]*\\(\\w+\\)" (2 font-lock-variable-name-face)) ("%\\(\\w+\\)%?" @@ -99,30 +98,28 @@ (,(concat "\\_<" (regexp-opt UNIX) "\\_>") . font-lock-warning-face))))) -(defvar dos-menu - '("Dos" - ["Run" dos-run :help "Run script"] - ["Run with Args" dos-run-args :help "Run script with args"] +(defvar bat-menu + '("Bat" + ["Run" bat-run :help "Run script"] + ["Run with Args" bat-run-args :help "Run script with args"] "--" ["Imenu" imenu :help "Navigate with imenu"] "--" - ["Template" dos-template :help "Insert template"] + ["Template" bat-template :help "Insert template"] "--" - ["Help (Command)" dos-cmd-help :help "Show help page for Dos command"] - ["Help (Mode)" dos-mode-help :help "Show help page for Emacs Dos Mode"])) + ["Help (Command)" bat-cmd-help :help "Show help page for DOS command"])) -(defvar dos-mode-map +(defvar bat-mode-map (let ((map (make-sparse-keymap))) - (easy-menu-define nil map nil dos-menu) - (define-key map [?\C-c ?\C-.] 'dos-mode-help) - (define-key map [?\C-c ?\C-/] 'dos-cmd-help) ;FIXME: Why not C-c C-? ? - (define-key map [?\C-c ?\C-a] 'dos-run-args) - (define-key map [?\C-c ?\C-c] 'dos-run) - (define-key map [?\C-c ?\C-t] 'dos-template) - (define-key map [?\C-c ?\C-v] 'dos-run) + (easy-menu-define nil map nil bat-menu) + (define-key map [?\C-c ?\C-/] 'bat-cmd-help) ;FIXME: Why not C-c C-? ? + (define-key map [?\C-c ?\C-a] 'bat-run-args) + (define-key map [?\C-c ?\C-c] 'bat-run) + (define-key map [?\C-c ?\C-t] 'bat-template) + (define-key map [?\C-c ?\C-v] 'bat-run) map)) -(defvar dos-mode-syntax-table +(defvar bat-mode-syntax-table (let ((table (make-syntax-table))) ;; Beware: `w' should not be used for non-alphabetic chars. (modify-syntax-entry ?~ "_" table) @@ -137,55 +134,48 @@ ;; 4 User functions -(defun dos-cmd-help (cmd) +(defun bat-cmd-help (cmd) "Show help for batch file command CMD." (interactive "sHelp: ") (if (string-equal cmd "net") ;; FIXME: liable to quoting nightmare. Use call-process? (shell-command "net /?") (shell-command (concat "help " cmd)))) -(defun dos-mode-help () - "Show help page for `dos-mode'." - (interactive) - (describe-function 'dos-mode) - (switch-to-buffer "*Help*") (delete-other-windows) (message nil)) - -(defun dos-run () +(defun bat-run () "Run a batch file." (interactive) ;; FIXME: liable to quoting nightmare. Use call/start-process? (save-buffer) (shell-command buffer-file-name)) -(defun dos-run-args (args) +(defun bat-run-args (args) "Run a batch file with ARGS." (interactive "sArgs: ") ;; FIXME: Use `compile'? (shell-command (concat buffer-file-name " " args))) -(defun dos-template () +(defun bat-template () "Insert minimal batch file template." (interactive) (goto-char (point-min)) (insert "@echo off\nsetlocal\n\n")) ;;;###autoload -(add-to-list 'auto-mode-alist '("\\.\\(bat\\|cmd\\)\\'" . dos-mode)) +(add-to-list 'auto-mode-alist '("\\.\\(bat\\|cmd\\)\\'" . bat-mode)) ;; 5 Main function ;;;###autoload -(define-derived-mode dos-mode prog-mode "Dos" +(define-derived-mode bat-mode prog-mode "Bat" "Major mode for editing DOS/Windows batch files.\n -The `dos-mode-help' command shows this page.\n -Start a new script from `dos-template'. Read help pages for Dos commands -with `dos-cmd-help'. Navigate between sections using `imenu'. -Run script using `dos-run' and `dos-run-args'.\n -\\{dos-mode-map}" +Start a new script from `bat-template'. Read help pages for DOS commands +with `bat-cmd-help'. Navigate between sections using `imenu'. +Run script using `bat-run' and `bat-run-args'.\n +\\{bat-mode-map}" (setq-local comment-start "rem ") (setq-local font-lock-defaults - '(dos-font-lock-keywords nil t)) ; case-insensitive keywords + '(bat-font-lock-keywords nil t)) ; case-insensitive keywords (setq-local imenu-generic-expression '((nil "^:[^:].*" 0))) (setq-local outline-regexp ":[^:]")) -(provide 'dos) +(provide 'bat-mode) -;;; dos.el ends here +;;; bat-mode.el ends here ------------------------------------------------------------ revno: 113744 committer: Stefan Monnier branch nick: trunk timestamp: Wed 2013-08-07 13:33:30 -0400 message: * lisp/emacs-lisp/bytecomp.el: Check existence of f in #'f. (byte-compile-callargs-warn): Use `push'. (byte-compile-arglist-warn): Ignore higher-order "calls". (byte-compile-file-form-autoload): Use `pcase'. (byte-compile-function-form): If quoting a symbol, check that it exists. diff: === modified file 'lisp/ChangeLog' --- lisp/ChangeLog 2013-08-07 16:37:04 +0000 +++ lisp/ChangeLog 2013-08-07 17:33:30 +0000 @@ -1,3 +1,11 @@ +2013-08-07 Stefan Monnier + + * emacs-lisp/bytecomp.el: Check existence of f in #'f. + (byte-compile-callargs-warn): Use `push'. + (byte-compile-arglist-warn): Ignore higher-order "calls". + (byte-compile-file-form-autoload): Use `pcase'. + (byte-compile-function-form): If quoting a symbol, check that it exists. + 2013-08-07 Eli Zaretskii * progmodes/dos.el (dos-font-lock-keywords): Rename LINUX to UNIX === modified file 'lisp/emacs-lisp/byte-run.el' --- lisp/emacs-lisp/byte-run.el 2013-03-13 02:19:31 +0000 +++ lisp/emacs-lisp/byte-run.el 2013-08-07 17:33:30 +0000 @@ -83,7 +83,6 @@ (list 'quote f) (list 'quote new-name) (list 'quote when)))) (list 'compiler-macro #'(lambda (f args compiler-function) - ;; FIXME: Make it possible to just reuse `args'. `(eval-and-compile (put ',f 'compiler-macro ,(if (eq (car-safe compiler-function) 'lambda) === modified file 'lisp/emacs-lisp/bytecomp.el' --- lisp/emacs-lisp/bytecomp.el 2013-06-19 07:35:00 +0000 +++ lisp/emacs-lisp/bytecomp.el 2013-08-07 17:33:30 +0000 @@ -1273,7 +1273,7 @@ (n (length (cdr form)))) (if cons (or (memq n (cdr cons)) - (setcdr cons (cons n (cdr cons)))) + (push n (cdr cons))) (push (list (car form) n) byte-compile-unresolved-functions)))))) @@ -1364,7 +1364,10 @@ ;; This is the first definition. See if previous calls are compatible. (let ((calls (assq name byte-compile-unresolved-functions)) nums sig min max) - (when calls + (setq byte-compile-unresolved-functions + (delq calls byte-compile-unresolved-functions)) + (setq calls (delq t calls)) ;Ignore higher-order uses of the function. + (when (cdr calls) (when (and (symbolp name) (eq (function-get name 'byte-optimizer) 'byte-compile-inline-expand)) @@ -1382,10 +1385,7 @@ name (byte-compile-arglist-signature-string sig) (if (equal sig '(1 . 1)) " arg" " args") - (byte-compile-arglist-signature-string (cons min max)))) - - (setq byte-compile-unresolved-functions - (delq calls byte-compile-unresolved-functions))))))) + (byte-compile-arglist-signature-string (cons min max))))))))) (defvar byte-compile-cl-functions nil "List of functions defined in CL.") @@ -2214,37 +2214,33 @@ (defun byte-compile-file-form-autoload (form) (and (let ((form form)) (while (if (setq form (cdr form)) (macroexp-const-p (car form)))) - (null form)) ;Constants only + (null form)) ;Constants only (memq (eval (nth 5 form)) '(t macro)) ;Macro - (eval form)) ;Define the autoload. + (eval form)) ;Define the autoload. ;; Avoid undefined function warnings for the autoload. - (when (and (consp (nth 1 form)) - (eq (car (nth 1 form)) 'quote) - (consp (cdr (nth 1 form))) - (symbolp (nth 1 (nth 1 form)))) - ;; Don't add it if it's already defined. Otherwise, it might - ;; hide the actual definition. However, do remove any entry from - ;; byte-compile-noruntime-functions, in case we have an autoload - ;; of foo-func following an (eval-when-compile (require 'foo)). - (unless (fboundp (nth 1 (nth 1 form))) - (push (cons (nth 1 (nth 1 form)) - (cons 'autoload (cdr (cdr form)))) - byte-compile-function-environment)) - ;; If an autoload occurs _before_ the first call to a function, - ;; byte-compile-callargs-warn does not add an entry to - ;; byte-compile-unresolved-functions. Here we mimic the logic - ;; of byte-compile-callargs-warn so as not to warn if the - ;; autoload comes _after_ the function call. - ;; Alternatively, similar logic could go in - ;; byte-compile-warn-about-unresolved-functions. - (if (memq (nth 1 (nth 1 form)) byte-compile-noruntime-functions) - (setq byte-compile-noruntime-functions - (delq (nth 1 (nth 1 form)) byte-compile-noruntime-functions) - byte-compile-noruntime-functions) - (setq byte-compile-unresolved-functions - (delq (assq (nth 1 (nth 1 form)) - byte-compile-unresolved-functions) - byte-compile-unresolved-functions)))) + (pcase (nth 1 form) + (`',(and (pred symbolp) funsym) + ;; Don't add it if it's already defined. Otherwise, it might + ;; hide the actual definition. However, do remove any entry from + ;; byte-compile-noruntime-functions, in case we have an autoload + ;; of foo-func following an (eval-when-compile (require 'foo)). + (unless (fboundp funsym) + (push (cons funsym (cons 'autoload (cdr (cdr form)))) + byte-compile-function-environment)) + ;; If an autoload occurs _before_ the first call to a function, + ;; byte-compile-callargs-warn does not add an entry to + ;; byte-compile-unresolved-functions. Here we mimic the logic + ;; of byte-compile-callargs-warn so as not to warn if the + ;; autoload comes _after_ the function call. + ;; Alternatively, similar logic could go in + ;; byte-compile-warn-about-unresolved-functions. + (if (memq funsym byte-compile-noruntime-functions) + (setq byte-compile-noruntime-functions + (delq funsym byte-compile-noruntime-functions) + byte-compile-noruntime-functions) + (setq byte-compile-unresolved-functions + (delq (assq funsym byte-compile-unresolved-functions) + byte-compile-unresolved-functions))))) (if (stringp (nth 3 form)) form ;; No doc string, so we can compile this as a normal form. @@ -3574,10 +3570,32 @@ ;; and (funcall (function foo)) will lose with autoloads. (defun byte-compile-function-form (form) - (byte-compile-constant (if (eq 'lambda (car-safe (nth 1 form))) - (byte-compile-lambda (nth 1 form)) - (nth 1 form)))) - + (let ((f (nth 1 form))) + (when (and (symbolp f) + (byte-compile-warning-enabled-p 'callargs)) + (when (get f 'byte-obsolete-info) + (byte-compile-warn-obsolete (car form))) + + ;; Check to see if the function will be available at runtime + ;; and/or remember its arity if it's unknown. + (or (and (or (fboundp f) ; Might be a subr or autoload. + (byte-compile-fdefinition (car form) nil)) + (not (memq f byte-compile-noruntime-functions))) + (eq f byte-compile-current-form) ; ## This doesn't work + ; with recursion. + ;; It's a currently-undefined function. + ;; Remember number of args in call. + (let ((cons (assq f byte-compile-unresolved-functions))) + (if cons + (or (memq t (cdr cons)) + (push t (cdr cons))) + (push (list f t) + byte-compile-unresolved-functions))))) + + (byte-compile-constant (if (eq 'lambda (car-safe f)) + (byte-compile-lambda f) + f)))) + (defun byte-compile-indent-to (form) (let ((len (length form))) (cond ((= len 2) ------------------------------------------------------------ revno: 113743 committer: Dmitry Antipov branch nick: trunk timestamp: Wed 2013-08-07 21:03:46 +0400 message: Fix typo in ChangeLog entry. diff: === modified file 'src/ChangeLog' --- src/ChangeLog 2013-08-07 16:59:23 +0000 +++ src/ChangeLog 2013-08-07 17:03:46 +0000 @@ -36,7 +36,7 @@ * xdisp.c (reconsider_clip_changes): Remove prototype, drop 2nd arg and always assume window's buffer. (redisplay_window): Adjust user. - (redisplay_internal): Call to reconsider_clip_change once and + (redisplay_internal): Call to reconsider_clip_changes once and check whether mode line should be updated only if selected window shows current buffer. (run_window_scroll_functions): Use eassert for debugging check. ------------------------------------------------------------ revno: 113742 fixes bug: http://debbugs.gnu.org/15034 committer: Jan D. branch nick: trunk timestamp: Wed 2013-08-07 18:59:23 +0200 message: * xselect.c (x_send_client_event): Set send_event and serial, memset data.l as it might be bigger than data.b. Use 24 bit mask to XSendEvent. diff: === modified file 'src/ChangeLog' --- src/ChangeLog 2013-08-07 13:49:47 +0000 +++ src/ChangeLog 2013-08-07 16:59:23 +0000 @@ -1,3 +1,9 @@ +2013-08-07 Jan Djärv + + * xselect.c (x_send_client_event): Set send_event and serial, memset + data.l as it might be bigger than data.b. Use 24 bit mask to + XSendEvent (Bug#15034). + 2013-08-07 Eli Zaretskii * xdisp.c (prepare_menu_bars): Don't call x_consider_frame_title === modified file 'src/xselect.c' --- src/xselect.c 2013-08-03 03:29:03 +0000 +++ src/xselect.c 2013-08-07 16:59:23 +0000 @@ -2628,6 +2628,8 @@ block_input (); + event.xclient.send_event = True; + event.xclient.serial = 0; event.xclient.message_type = message_type; event.xclient.display = dpyinfo->display; @@ -2635,19 +2637,19 @@ when sending to the root window. */ event.xclient.window = to_root ? FRAME_OUTER_WINDOW (f) : wdest; - - memset (event.xclient.data.b, 0, sizeof (event.xclient.data.b)); + memset (event.xclient.data.l, 0, sizeof (event.xclient.data.l)); x_fill_property_data (dpyinfo->display, values, event.xclient.data.b, event.xclient.format); /* If event mask is 0 the event is sent to the client that created the destination window. But if we are sending to the root window, - there is no such client. Then we set the event mask to 0xffff. The + there is no such client. Then we set the event mask to 0xffffff. The event then goes to clients selecting for events on the root window. */ x_catch_errors (dpyinfo->display); { int propagate = to_root ? False : True; - unsigned mask = to_root ? 0xffff : 0; + long mask = to_root ? 0xffffff : 0; + XSendEvent (dpyinfo->display, wdest, propagate, mask, &event); XFlush (dpyinfo->display); } ------------------------------------------------------------ revno: 113741 committer: Eli Zaretskii branch nick: trunk timestamp: Wed 2013-08-07 19:37:04 +0300 message: Minor fixes in lisp/progmodes/dos.el. lisp/progmodes/dos.el (dos-font-lock-keywords): Rename LINUX to UNIX and add a few popular commands found in batch files. (dos, dos-label-face, dos-cmd-help, dos-run, dos-run-args) (dos-mode): Doc fixes. diff: === modified file 'lisp/ChangeLog' --- lisp/ChangeLog 2013-08-07 15:50:16 +0000 +++ lisp/ChangeLog 2013-08-07 16:37:04 +0000 @@ -1,3 +1,10 @@ +2013-08-07 Eli Zaretskii + + * progmodes/dos.el (dos-font-lock-keywords): Rename LINUX to UNIX + and add a few popular commands found in batch files. + (dos, dos-label-face, dos-cmd-help, dos-run, dos-run-args) + (dos-mode): Doc fixes. + 2013-08-07 Stefan Monnier * progmodes/dos.el (auto-mode-alist): Add entries for dos-mode. === modified file 'lisp/progmodes/dos.el' --- lisp/progmodes/dos.el 2013-08-07 15:50:16 +0000 +++ lisp/progmodes/dos.el 2013-08-07 16:37:04 +0000 @@ -53,14 +53,14 @@ ;; 1 Preamble (defgroup dos nil - "Major mode for editing Dos scripts." + "Major mode for editing DOS/Windows batch files." :link '(custom-group-link :tag "Font Lock Faces group" font-lock-faces) :group 'languages) ;; 2 User variables (defface dos-label-face '((t :weight bold)) - "Font Lock mode face used to highlight Dos labels." + "Font Lock mode face used to highlight labels in batch files." :group 'dos) ;; 3 Internal variables @@ -77,8 +77,8 @@ (CONTROLFLOW '("call" "cmd" "defined" "do" "else" "equ" "exist" "exit" "for" "geq" "goto" "gtr" "if" "in" "leq" "lss" "neq" "not" "start")) - (LINUX - '("cat" "cp" "ls" "mv" "rm"))) + (UNIX + '("bash" "cat" "cp" "fgrep" "grep" "ls" "sed" "sh" "mv" "rm"))) `(("\\<_\\(call\\|goto\\)\\_>[ \t]+%?\\([A-Za-z0-9-_\\:.]+\\)%?" (2 font-lock-constant-face t)) ("^[ \t]*\\(@?rem\\_>\\|::\\).*" @@ -96,7 +96,7 @@ (,(concat "\\_<" (regexp-opt COMMANDS) "\\_>") . font-lock-builtin-face) (,(concat "\\_<" (regexp-opt CONTROLFLOW) "\\_>") . font-lock-keyword-face) - (,(concat "\\_<" (regexp-opt LINUX) "\\_>") + (,(concat "\\_<" (regexp-opt UNIX) "\\_>") . font-lock-warning-face))))) (defvar dos-menu @@ -138,7 +138,7 @@ ;; 4 User functions (defun dos-cmd-help (cmd) - "Show help for Dos command CMD." + "Show help for batch file command CMD." (interactive "sHelp: ") (if (string-equal cmd "net") ;; FIXME: liable to quoting nightmare. Use call-process? @@ -151,19 +151,19 @@ (switch-to-buffer "*Help*") (delete-other-windows) (message nil)) (defun dos-run () - "Run Dos script." + "Run a batch file." (interactive) ;; FIXME: liable to quoting nightmare. Use call/start-process? (save-buffer) (shell-command buffer-file-name)) (defun dos-run-args (args) - "Run Dos script with ARGS." + "Run a batch file with ARGS." (interactive "sArgs: ") ;; FIXME: Use `compile'? (shell-command (concat buffer-file-name " " args))) (defun dos-template () - "Insert minimal Dos template." + "Insert minimal batch file template." (interactive) (goto-char (point-min)) (insert "@echo off\nsetlocal\n\n")) @@ -174,11 +174,11 @@ ;;;###autoload (define-derived-mode dos-mode prog-mode "Dos" - "Major mode for editing Dos scripts.\n + "Major mode for editing DOS/Windows batch files.\n The `dos-mode-help' command shows this page.\n -Start a new script from `dos-template'. Read help pages for Dos commands with -`dos-cmd-help'. Navigate between sections using `imenu'. Run script using -`dos-run' and `dos-run-args'.\n +Start a new script from `dos-template'. Read help pages for Dos commands +with `dos-cmd-help'. Navigate between sections using `imenu'. +Run script using `dos-run' and `dos-run-args'.\n \\{dos-mode-map}" (setq-local comment-start "rem ") (setq-local font-lock-defaults ------------------------------------------------------------ revno: 113740 committer: Stefan Monnier branch nick: trunk timestamp: Wed 2013-08-07 11:50:16 -0400 message: * lisp/progmodes/dos.el (auto-mode-alist): Add entries for dos-mode. (dos-mode): Use setq-local. Add space after "rem". (dos-mode-syntax-table): Don't use "w" for symbol chars. (dos-font-lock-keywords): Try to adjust font-lock rules accordingly. diff: === modified file 'lisp/ChangeLog' --- lisp/ChangeLog 2013-08-07 15:43:57 +0000 +++ lisp/ChangeLog 2013-08-07 15:50:16 +0000 @@ -1,3 +1,10 @@ +2013-08-07 Stefan Monnier + + * progmodes/dos.el (auto-mode-alist): Add entries for dos-mode. + (dos-mode): Use setq-local. Add space after "rem". + (dos-mode-syntax-table): Don't use "w" for symbol chars. + (dos-font-lock-keywords): Try to adjust font-lock rules accordingly. + 2013-08-07 Arni Magnusson * progmodes/dos.el: New file. === modified file 'lisp/progmodes/dos.el' --- lisp/progmodes/dos.el 2013-08-07 15:43:57 +0000 +++ lisp/progmodes/dos.el 2013-08-07 15:50:16 +0000 @@ -22,9 +22,9 @@ ;;; Commentary: ;; -;; Major mode for editing Dos scripts (batch files). Provides syntax +;; Major mode for editing Dos scripts (batch files). Provides syntax ;; highlighting, a basic template, access to Dos help pages, imenu/outline -;; navigation, and the ability to run scripts from within Emacs. The syntax +;; navigation, and the ability to run scripts from within Emacs. The syntax ;; groups for highlighting are: ;; ;; Face Example @@ -79,24 +79,25 @@ "goto" "gtr" "if" "in" "leq" "lss" "neq" "not" "start")) (LINUX '("cat" "cp" "ls" "mv" "rm"))) - (list - '("\\<\\(call\\|goto\\)\\>[ \t]+%?\\([A-Za-z0-9-_\\:.]+\\)%?" + `(("\\<_\\(call\\|goto\\)\\_>[ \t]+%?\\([A-Za-z0-9-_\\:.]+\\)%?" (2 font-lock-constant-face t)) - '("^[ \t]*\\(@?rem\\>\\|::\\).*" + ("^[ \t]*\\(@?rem\\_>\\|::\\).*" (0 font-lock-comment-face t)) - '("^:[^:].*" + ("^:[^:].*" . 'dos-label-face) - '("\\<\\(defined\\|set\\)\\>[ \t]*\\(\\w+\\)" + ("\\<_\\(defined\\|set\\)\\_>[ \t]*\\(\\w+\\)" (2 font-lock-variable-name-face)) - '("%\\(\\w+\\)%?" - (1 font-lock-variable-name-face)) - '("!\\(\\w+\\)!?" ; delayed-expansion !variable! - (1 font-lock-variable-name-face)) - '("[ =][-/]+\\(\\w+\\)" + ("%\\(\\w+\\)%?" + (1 font-lock-variable-name-face)) + ("!\\(\\w+\\)!?" ; delayed-expansion !variable! + (1 font-lock-variable-name-face)) + ("[ =][-/]+\\(\\w+\\)" (1 font-lock-type-face append)) - (cons (regexp-opt COMMANDS 'words) font-lock-builtin-face) - (cons (regexp-opt CONTROLFLOW 'words) font-lock-keyword-face) - (cons (regexp-opt LINUX 'words) font-lock-warning-face))))) + (,(concat "\\_<" (regexp-opt COMMANDS) "\\_>") . font-lock-builtin-face) + (,(concat "\\_<" (regexp-opt CONTROLFLOW) "\\_>") + . font-lock-keyword-face) + (,(concat "\\_<" (regexp-opt LINUX) "\\_>") + . font-lock-warning-face))))) (defvar dos-menu '("Dos" @@ -114,7 +115,7 @@ (let ((map (make-sparse-keymap))) (easy-menu-define nil map nil dos-menu) (define-key map [?\C-c ?\C-.] 'dos-mode-help) - (define-key map [?\C-c ?\C-/] 'dos-cmd-help) + (define-key map [?\C-c ?\C-/] 'dos-cmd-help) ;FIXME: Why not C-c C-? ? (define-key map [?\C-c ?\C-a] 'dos-run-args) (define-key map [?\C-c ?\C-c] 'dos-run) (define-key map [?\C-c ?\C-t] 'dos-template) @@ -123,21 +124,24 @@ (defvar dos-mode-syntax-table (let ((table (make-syntax-table))) - (modify-syntax-entry ?~ "w" table) + ;; Beware: `w' should not be used for non-alphabetic chars. + (modify-syntax-entry ?~ "_" table) (modify-syntax-entry ?% "." table) - (modify-syntax-entry ?- "w" table) - (modify-syntax-entry ?_ "w" table) - (modify-syntax-entry ?{ "w" table) - (modify-syntax-entry ?} "w" table) + (modify-syntax-entry ?- "_" table) + (modify-syntax-entry ?_ "_" table) + ;; FIXME: { and } can appear in identifiers? Really? + (modify-syntax-entry ?{ "_" table) + (modify-syntax-entry ?} "_" table) (modify-syntax-entry ?\\ "." table) table)) ;; 4 User functions (defun dos-cmd-help (cmd) - "Show help for Dos command." + "Show help for Dos command CMD." (interactive "sHelp: ") (if (string-equal cmd "net") + ;; FIXME: liable to quoting nightmare. Use call-process? (shell-command "net /?") (shell-command (concat "help " cmd)))) (defun dos-mode-help () @@ -149,11 +153,13 @@ (defun dos-run () "Run Dos script." (interactive) + ;; FIXME: liable to quoting nightmare. Use call/start-process? (save-buffer) (shell-command buffer-file-name)) (defun dos-run-args (args) "Run Dos script with ARGS." (interactive "sArgs: ") + ;; FIXME: Use `compile'? (shell-command (concat buffer-file-name " " args))) (defun dos-template () @@ -161,6 +167,9 @@ (interactive) (goto-char (point-min)) (insert "@echo off\nsetlocal\n\n")) +;;;###autoload +(add-to-list 'auto-mode-alist '("\\.\\(bat\\|cmd\\)\\'" . dos-mode)) + ;; 5 Main function ;;;###autoload @@ -171,12 +180,11 @@ `dos-cmd-help'. Navigate between sections using `imenu'. Run script using `dos-run' and `dos-run-args'.\n \\{dos-mode-map}" - (set (make-local-variable 'comment-start) "rem") - (set (make-local-variable 'font-lock-defaults) + (setq-local comment-start "rem ") + (setq-local font-lock-defaults '(dos-font-lock-keywords nil t)) ; case-insensitive keywords - (set (make-local-variable 'imenu-generic-expression) '((nil "^:[^:].*" 0))) - (set (make-local-variable 'outline-regexp) ":[^:]") - (set-syntax-table dos-mode-syntax-table)) + (setq-local imenu-generic-expression '((nil "^:[^:].*" 0))) + (setq-local outline-regexp ":[^:]")) (provide 'dos) ------------------------------------------------------------ revno: 113739 author: Arni Magnusson committer: Stefan Monnier branch nick: trunk timestamp: Wed 2013-08-07 11:43:57 -0400 message: * lisp/progmodes/dos.el: New file. * lisp/generic-x.el (bat-generic-mode): Redefine as an obsolete alias to dos-mode. diff: === modified file 'lisp/ChangeLog' --- lisp/ChangeLog 2013-08-07 00:06:43 +0000 +++ lisp/ChangeLog 2013-08-07 15:43:57 +0000 @@ -1,3 +1,9 @@ +2013-08-07 Arni Magnusson + + * progmodes/dos.el: New file. + * generic-x.el (bat-generic-mode): Redefine as an obsolete alias to + dos-mode. + 2013-08-06 Glenn Morris * calendar/calendar.el: Add new faces, and day-header-array. === modified file 'lisp/generic-x.el' --- lisp/generic-x.el 2013-06-18 07:43:46 +0000 +++ lisp/generic-x.el 2013-08-07 15:43:57 +0000 @@ -460,130 +460,7 @@ ;;; DOS/Windows BAT files (when (memq 'bat-generic-mode generic-extras-enable-list) - -(define-generic-mode bat-generic-mode - nil - nil - (eval-when-compile - (list - ;; Make this one first in the list, otherwise comments will - ;; be over-written by other variables - '("^[@ \t]*\\([rR][eE][mM][^\n\r]*\\)" 1 font-lock-comment-face t) - '("^[ \t]*\\(::.*\\)" 1 font-lock-comment-face t) - '("^[@ \t]*\\([bB][rR][eE][aA][kK]\\|[vV][eE][rR][iI][fF][yY]\\)[ \t]+\\([oO]\\([nN]\\|[fF][fF]\\)\\)" - (1 font-lock-builtin-face) - (2 font-lock-constant-face t t)) - ;; Any text (except ON/OFF) following ECHO is a string. - '("^[@ \t]*\\([eE][cC][hH][oO]\\)[ \t]+\\(\\([oO]\\([nN]\\|[fF][fF]\\)\\)\\|\\([^>|\r\n]+\\)\\)" - (1 font-lock-builtin-face) - (3 font-lock-constant-face t t) - (5 font-lock-string-face t t)) - ;; These keywords appear as the first word on a line. (Actually, they - ;; can also appear after "if ..." or "for ..." clause, but since they - ;; are frequently used in simple text, we punt.) - ;; In `generic-bat-mode-setup-function' we make the keywords - ;; case-insensitive - '("^[@ \t]*\\_<\\(for\\|if\\)\\_>" 1 font-lock-keyword-face) - ;; These keywords can be anywhere on a line - ;; In `generic-bat-mode-setup-function' we make the keywords - ;; case-insensitive - (list (regexp-opt '("do" "exist" "errorlevel" "goto" "not") 'symbols) - 1 font-lock-keyword-face) - ;; These are built-in commands. Only frequently-used ones are listed. - (list (concat "[ \t|\n]" - (regexp-opt '("CALL" "call" "Call" - "CD" "cd" "Cd" - "CLS" "cls" "Cls" - "COPY" "copy" "Copy" - "DEL" "del" "Del" - "ECHO" "echo" "Echo" - "MD" "md" "Md" - "PATH" "path" "Path" - "PAUSE" "pause" "Pause" - "PROMPT" "prompt" "Prompt" - "RD" "rd" "Rd" - "REN" "ren" "Ren" - "SET" "set" "Set" - "START" "start" "Start" - "SHIFT" "shift" "Shift") 'symbols)) - 1 font-lock-builtin-face) - '("^[ \t]*\\(:\\sw+\\)" 1 font-lock-function-name-face t) - '("\\(%\\sw+%\\)" 1 font-lock-variable-name-face t) - '("\\(%[0-9]\\)" 1 font-lock-variable-name-face t) - '("[\t ]+\\([+-/][^\t\n\" ]+\\)" 1 font-lock-type-face) - '("[ \t\n|]\\<\\([gG][oO][tT][oO]\\)\\>[ \t]*\\(\\sw+\\)?" - (1 font-lock-keyword-face) - (2 font-lock-function-name-face nil t)) - '("[ \t\n|]\\<\\([sS][eE][tT]\\)\\>[ \t]*\\(\\sw+\\)?[ \t]*=?" - (1 font-lock-builtin-face) - (2 font-lock-variable-name-face t t)))) - '("\\.[bB][aA][tT]\\'" - "\\.[cC][mM][dD]\\'" - "\\`[cC][oO][nN][fF][iI][gG]\\." - "\\`[aA][uU][tT][oO][eE][xX][eE][cC]\\.") - '(generic-bat-mode-setup-function) - "Generic mode for MS-Windows batch files.") - -(defvar bat-generic-mode-syntax-table nil - "Syntax table in use in `bat-generic-mode' buffers.") - -(defvar bat-generic-mode-keymap (make-sparse-keymap) - "Keymap for `bat-generic-mode'.") - -(defun bat-generic-mode-compile () - "Run the current BAT file in a compilation buffer." - (interactive) - (let ((compilation-buffer-name-function - (function - (lambda (_ign) - (concat "*" (buffer-file-name) "*"))))) - (compile - (concat (w32-shell-name) " -c " (buffer-file-name))))) - -(declare-function comint-mode "comint" ()) -(declare-function comint-exec "comint" (buffer name command startfile switches)) - -(defun bat-generic-mode-run-as-comint () - "Run the current BAT file in a comint buffer." - (interactive) - (require 'comint) - (let* ((file (buffer-file-name)) - (buf-name (concat "*" file "*"))) - (with-current-buffer (get-buffer-create buf-name) - (erase-buffer) - (comint-mode) - (comint-exec - buf-name - file - (w32-shell-name) - nil - (list "-c" file)) - (display-buffer buf-name)))) - -(define-key bat-generic-mode-keymap "\C-c\C-c" 'bat-generic-mode-compile) - -;; Make underscores count as words -(unless bat-generic-mode-syntax-table - (setq bat-generic-mode-syntax-table (make-syntax-table)) - (modify-syntax-entry ?_ "w" bat-generic-mode-syntax-table)) - -;; bat-generic-mode doesn't use the comment functionality of -;; define-generic-mode because it has a three-letter comment-string, -;; so we do it here manually instead -(defun generic-bat-mode-setup-function () - (make-local-variable 'parse-sexp-ignore-comments) - (make-local-variable 'comment-start) - (make-local-variable 'comment-start-skip) - (make-local-variable 'comment-end) - (setq imenu-generic-expression '((nil "^:\\(\\sw+\\)" 1)) - parse-sexp-ignore-comments t - comment-end "" - comment-start "REM " - comment-start-skip "[Rr][Ee][Mm] *") - (set-syntax-table bat-generic-mode-syntax-table) - ;; Make keywords case-insensitive - (setq font-lock-defaults '(generic-font-lock-keywords nil t)) - (use-local-map bat-generic-mode-keymap))) + (define-obsolete-function-alias 'bat-generic-mode 'dos-mode "24.4")) ;;; Mailagent ;; Mailagent is a Unix mail filtering program. Anyone wanna do a === added file 'lisp/progmodes/dos.el' --- lisp/progmodes/dos.el 1970-01-01 00:00:00 +0000 +++ lisp/progmodes/dos.el 2013-08-07 15:43:57 +0000 @@ -0,0 +1,183 @@ +;;; dos.el --- Major mode for editing Dos scripts + +;; Copyright (C) 2003, 2008-2013 Free Software Foundation, Inc. + +;; Author: Arni Magnusson +;; Keywords: languages + +;; This file is part of GNU Emacs. + +;; GNU Emacs is free software: you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation, either version 3 of the License, or +;; (at your option) any later version. + +;; GNU Emacs is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. + +;; You should have received a copy of the GNU General Public License +;; along with GNU Emacs. If not, see . + +;;; Commentary: +;; +;; Major mode for editing Dos scripts (batch files). Provides syntax +;; highlighting, a basic template, access to Dos help pages, imenu/outline +;; navigation, and the ability to run scripts from within Emacs. The syntax +;; groups for highlighting are: +;; +;; Face Example +;; dos-label-face :LABEL +;; font-lock-comment-face rem +;; font-lock-builtin-face copy +;; font-lock-keyword-face goto +;; font-lock-warning-face cp +;; font-lock-constant-face [call] prog +;; font-lock-variable-name-face %var% +;; font-lock-type-face -option +;; +;; Usage: +;; +;; See documentation of function `dos-mode'. +;; +;; Separate package `dos-indent' (Matthew Fidler) provides rudimentary +;; indentation, see http://www.emacswiki.org/emacs/dos-indent.el. +;; +;; Acknowledgements: +;; +;; Inspired by `batch-mode' (Agnar Renolen) and `cmd-mode' (Tadamegu Furukawa). + +;;; Code: + +;; 1 Preamble + +(defgroup dos nil + "Major mode for editing Dos scripts." + :link '(custom-group-link :tag "Font Lock Faces group" font-lock-faces) + :group 'languages) + +;; 2 User variables + +(defface dos-label-face '((t :weight bold)) + "Font Lock mode face used to highlight Dos labels." + :group 'dos) + +;; 3 Internal variables + +(defvar dos-font-lock-keywords + (eval-when-compile + (let ((COMMANDS + '("assoc" "at" "attrib" "cd" "cls" "color" "copy" "date" "del" "dir" + "doskey" "echo" "endlocal" "erase" "fc" "find" "findstr" "format" + "ftype" "label" "md" "mkdir" "more" "move" "net" "path" "pause" + "popd" "prompt" "pushd" "rd" "ren" "rename" "replace" "rmdir" "set" + "setlocal" "shift" "sort" "subst" "time" "title" "tree" "type" + "ver" "vol" "xcopy")) + (CONTROLFLOW + '("call" "cmd" "defined" "do" "else" "equ" "exist" "exit" "for" "geq" + "goto" "gtr" "if" "in" "leq" "lss" "neq" "not" "start")) + (LINUX + '("cat" "cp" "ls" "mv" "rm"))) + (list + '("\\<\\(call\\|goto\\)\\>[ \t]+%?\\([A-Za-z0-9-_\\:.]+\\)%?" + (2 font-lock-constant-face t)) + '("^[ \t]*\\(@?rem\\>\\|::\\).*" + (0 font-lock-comment-face t)) + '("^:[^:].*" + . 'dos-label-face) + '("\\<\\(defined\\|set\\)\\>[ \t]*\\(\\w+\\)" + (2 font-lock-variable-name-face)) + '("%\\(\\w+\\)%?" + (1 font-lock-variable-name-face)) + '("!\\(\\w+\\)!?" ; delayed-expansion !variable! + (1 font-lock-variable-name-face)) + '("[ =][-/]+\\(\\w+\\)" + (1 font-lock-type-face append)) + (cons (regexp-opt COMMANDS 'words) font-lock-builtin-face) + (cons (regexp-opt CONTROLFLOW 'words) font-lock-keyword-face) + (cons (regexp-opt LINUX 'words) font-lock-warning-face))))) + +(defvar dos-menu + '("Dos" + ["Run" dos-run :help "Run script"] + ["Run with Args" dos-run-args :help "Run script with args"] + "--" + ["Imenu" imenu :help "Navigate with imenu"] + "--" + ["Template" dos-template :help "Insert template"] + "--" + ["Help (Command)" dos-cmd-help :help "Show help page for Dos command"] + ["Help (Mode)" dos-mode-help :help "Show help page for Emacs Dos Mode"])) + +(defvar dos-mode-map + (let ((map (make-sparse-keymap))) + (easy-menu-define nil map nil dos-menu) + (define-key map [?\C-c ?\C-.] 'dos-mode-help) + (define-key map [?\C-c ?\C-/] 'dos-cmd-help) + (define-key map [?\C-c ?\C-a] 'dos-run-args) + (define-key map [?\C-c ?\C-c] 'dos-run) + (define-key map [?\C-c ?\C-t] 'dos-template) + (define-key map [?\C-c ?\C-v] 'dos-run) + map)) + +(defvar dos-mode-syntax-table + (let ((table (make-syntax-table))) + (modify-syntax-entry ?~ "w" table) + (modify-syntax-entry ?% "." table) + (modify-syntax-entry ?- "w" table) + (modify-syntax-entry ?_ "w" table) + (modify-syntax-entry ?{ "w" table) + (modify-syntax-entry ?} "w" table) + (modify-syntax-entry ?\\ "." table) + table)) + +;; 4 User functions + +(defun dos-cmd-help (cmd) + "Show help for Dos command." + (interactive "sHelp: ") + (if (string-equal cmd "net") + (shell-command "net /?") (shell-command (concat "help " cmd)))) + +(defun dos-mode-help () + "Show help page for `dos-mode'." + (interactive) + (describe-function 'dos-mode) + (switch-to-buffer "*Help*") (delete-other-windows) (message nil)) + +(defun dos-run () + "Run Dos script." + (interactive) + (save-buffer) (shell-command buffer-file-name)) + +(defun dos-run-args (args) + "Run Dos script with ARGS." + (interactive "sArgs: ") + (shell-command (concat buffer-file-name " " args))) + +(defun dos-template () + "Insert minimal Dos template." + (interactive) + (goto-char (point-min)) (insert "@echo off\nsetlocal\n\n")) + +;; 5 Main function + +;;;###autoload +(define-derived-mode dos-mode prog-mode "Dos" + "Major mode for editing Dos scripts.\n +The `dos-mode-help' command shows this page.\n +Start a new script from `dos-template'. Read help pages for Dos commands with +`dos-cmd-help'. Navigate between sections using `imenu'. Run script using +`dos-run' and `dos-run-args'.\n +\\{dos-mode-map}" + (set (make-local-variable 'comment-start) "rem") + (set (make-local-variable 'font-lock-defaults) + '(dos-font-lock-keywords nil t)) ; case-insensitive keywords + (set (make-local-variable 'imenu-generic-expression) '((nil "^:[^:].*" 0))) + (set (make-local-variable 'outline-regexp) ":[^:]") + (set-syntax-table dos-mode-syntax-table)) + +(provide 'dos) + +;;; dos.el ends here === modified file 'lisp/subr.el' --- lisp/subr.el 2013-08-04 20:18:11 +0000 +++ lisp/subr.el 2013-08-07 15:43:57 +0000 @@ -2755,7 +2755,7 @@ (let ((def (indirect-function object t))) (when (consp def) (or (eq 'macro (car def)) - (and (eq 'autoload (car def)) (memq (nth 4 def) '(macro t))))))) + (and (autoloadp def) (memq (nth 4 def) '(macro t))))))) (defun field-at-pos (pos) "Return the field at position POS, taking stickiness etc into account." ------------------------------------------------------------ revno: 113738 committer: Eli Zaretskii branch nick: trunk timestamp: Wed 2013-08-07 18:14:23 +0300 message: xdisp.c: Fix a typo in a comment for the last commit. diff: === modified file 'src/xdisp.c' --- src/xdisp.c 2013-08-07 13:49:47 +0000 +++ src/xdisp.c 2013-08-07 15:14:23 +0000 @@ -11173,7 +11173,7 @@ || FRAME_VISIBLE_P (f) == 1 /* Exclude TTY frames that are obscured because they are not the top frame on their console. This is - because x_consider_frame_title actually swit6ches + because x_consider_frame_title actually switches to the frame, which for TTY frames means it is marked as garbaged, and will be completely redrawn on the next redisplay cycle. This causes ------------------------------------------------------------ revno: 113737 committer: Eli Zaretskii branch nick: trunk timestamp: Wed 2013-08-07 17:15:23 +0300 message: Minor fixes in the ToDo Mode manual. doc/misc/todo-mode.texi: Update @dircategory. (Overview, Todo Items as Diary Entries, Todo Mode Entry Points) (File Editing, Marked Items, Item Prefix): Fix usage of @xref and @ref. diff: === modified file 'doc/misc/ChangeLog' --- doc/misc/ChangeLog 2013-08-07 13:19:48 +0000 +++ doc/misc/ChangeLog 2013-08-07 14:15:23 +0000 @@ -1,3 +1,10 @@ +2013-08-07 Eli Zaretskii + + * todo-mode.texi: Update @dircategory. + (Overview, Todo Items as Diary Entries, Todo Mode Entry Points) + (File Editing, Marked Items, Item Prefix): Fix usage of @xref and + @ref. + 2013-08-07 Xue Fuqiao * sc.texi (Introduction): Fix index. === modified file 'doc/misc/todo-mode.texi' --- doc/misc/todo-mode.texi 2013-08-04 21:27:49 +0000 +++ doc/misc/todo-mode.texi 2013-08-07 14:15:23 +0000 @@ -23,7 +23,7 @@ @end quotation @end copying -@dircategory Emacs +@dircategory Emacs misc features @direntry * Todo Mode: (todo-mode). Make and maintain todo lists. @end direntry @@ -138,7 +138,7 @@ This version of Todo mode greatly expands on, and in significant ways differs from, the original version; for details and consequences of the -most important differences, @xref{Legacy Todo Mode Files}. +most important differences, @ref{Legacy Todo Mode Files}. @menu * Levels of Organization:: @@ -192,8 +192,8 @@ Fancy Diary display will show those todo items that are not marked with @code{todo-nondiary-marker}. This effectively augments the Emacs diary with categorized diary entries. For the various options available for -making a todo item a diary entry, @ref{Inserting New Items} and -@xref{Editing Item Headers and Text}. +making a todo item a diary entry, see @ref{Inserting New Items} and +@ref{Editing Item Headers and Text}. To ensure the proper display of todo items in the Fancy Diary display, they must have the format of diary entries, i.e., they have to begin @@ -244,9 +244,9 @@ If you want to enter Todo mode and go directly to a specific category instead the first or current category in the current or default todo -file, use the command @code{todo-jump-to-category}; @ref{Navigation} for +file, use the command @code{todo-jump-to-category}; @ref{Navigation}, for details. You can also enter Todo mode by invoking a todo item insertion -command; @ref{Inserting New Items} for details. +command; @ref{Inserting New Items}, for details. The most convenient way to use these commands to enter Todo mode is to define global key bindings for them in your init file. Good choices are @@ -421,7 +421,7 @@ @samp{.todo} extension (so you should not include the extension in the name you enter). The command also prompts for the file's first category and, if option @code{todo-add-item-if-new-category} is enabled (the default), -for that category's first item. +for that category's first item. @item F r Rename the current todo file (@code{todo-rename-file}). If called with @@ -461,7 +461,7 @@ since it runs a file format check, signaling an error if the format has become invalid. However, this check cannot tell if the number of items changed, which could result in the file containing inconsistent -information (see the cautionary note in @ref{Reordering Categories} for +information (see the cautionary note in @ref{Reordering Categories}, for more details). For this reason @kbd{F e} should be used with caution. @end table @@ -1139,7 +1139,7 @@ already marked (@code{todo-toggle-mark-item}). The mark is a string specified by the option @code{todo-item-mark} (by default @samp{*}) appended in front of the item header (more precisely, in front of the -item's priority number or prefix; @pxref{Todo Display Features} for +item's priority number or prefix; see @ref{Todo Display Features}, for details of the latter). After marking the current item, the command advances point to the next item. It also accepts a numeric prefix argument, which allows toggling the mark of multiple consecutive items. @@ -1332,7 +1332,7 @@ @table @kbd @item S -This command (@code{todo-search}; the key is capital `S') prompts for a +This command (@code{todo-search}; the key is capital @kbd{S}) prompts for a regular expression, searches from the beginning of the current todo file and displays the category containing the first match it finds, with the match highlighted. If there are further matches, a message saying how @@ -1355,7 +1355,7 @@ A more powerful alternative to sequential searching is item filtering, by which items from different categories that match specified criteria are gathered and displayed in a new buffer as a kind of virtual -category in a distinct mode, Todo Filtered Items mode. +category in a distinct mode, Todo Filtered Items mode. @menu * Filtering Items:: @@ -1612,7 +1612,7 @@ In the todo items section of each Todo mode category, the item prefix (whether a priority number or a fixed string) of the top priority items -(determined as specified in @ref{Filtering Items}) is displayed in a +(determined as specified in @pxref{Filtering Items}) is displayed in a different face from the prefix of the other items, so you see at a glance how many items in the category are top priorities. ------------------------------------------------------------ revno: 113736 fixes bug: http://debbugs.gnu.org/15038 committer: Eli Zaretskii branch nick: trunk timestamp: Wed 2013-08-07 16:58:41 +0300 message: Fix bug #15038 with incorrect Texinfo in Emacs Lisp Intro manual. doc/lispintro/emacs-lisp-intro.texi (Beginning init File): Rename from "Beginning a .emacs File", since a node name cannot include a period. (Top, Emacs Initialization, Change a defun): All references changed. diff: === modified file 'doc/lispintro/ChangeLog' --- doc/lispintro/ChangeLog 2013-08-02 02:33:12 +0000 +++ doc/lispintro/ChangeLog 2013-08-07 13:58:41 +0000 @@ -1,3 +1,11 @@ +2013-08-07 Eli Zaretskii + + * emacs-lisp-intro.texi (Beginning init File): Rename from + "Beginning a .emacs File", since a node name cannot include a + period. + (Top, Emacs Initialization, Change a defun): All references + changed. (Bug#15038) + 2013-08-02 Xue Fuqiao * emacs-lisp-intro.texi (zap-to-char): Remove obsolete stuff. === modified file 'doc/lispintro/emacs-lisp-intro.texi' --- doc/lispintro/emacs-lisp-intro.texi 2013-08-02 02:33:12 +0000 +++ doc/lispintro/emacs-lisp-intro.texi 2013-08-07 13:58:41 +0000 @@ -648,7 +648,7 @@ * Default Configuration:: * Site-wide Init:: You can write site-wide init files. * defcustom:: Emacs will write code for you. -* Beginning a .emacs File:: How to write a @code{.emacs file}. +* Beginning init File:: How to write a @file{.emacs} init file. * Text and Auto-fill:: Automatically wrap lines. * Mail Aliases:: Use abbreviations for email addresses. * Indent Tabs Mode:: Don't use tabs with @TeX{} @@ -3260,7 +3260,7 @@ end of the comment. To stretch a comment over two or more lines, begin each line with a semicolon. -@xref{Beginning a .emacs File, , Beginning a @file{.emacs} +@xref{Beginning init File, , Beginning a @file{.emacs} File}, and @ref{Comments, , Comments, elisp, The GNU Emacs Lisp Reference Manual}, for more about comments. @@ -16706,7 +16706,7 @@ * Default Configuration:: * Site-wide Init:: You can write site-wide init files. * defcustom:: Emacs will write code for you. -* Beginning a .emacs File:: How to write a @code{.emacs file}. +* Beginning init File:: How to write a @file{.emacs} init file. * Text and Auto-fill:: Automatically wrap lines. * Mail Aliases:: Use abbreviations for email addresses. * Indent Tabs Mode:: Don't use tabs with @TeX{} @@ -16977,7 +16977,7 @@ set by @code{defconst}. (You can change it; the value set is a variable; but please do not.) -@node Beginning a .emacs File +@node Beginning init File @section Beginning a @file{.emacs} File @cindex @file{.emacs} file, beginning of ------------------------------------------------------------ revno: 113735 fixes bug: http://debbugs.gnu.org/14616 committer: Eli Zaretskii branch nick: trunk timestamp: Wed 2013-08-07 16:49:47 +0300 message: Fix bug #14616 with unnecessary redrawing of TTY frames. src/xdisp.c (prepare_menu_bars): Don't call x_consider_frame_title for TTY frames that are not the top frame on their console. diff: === modified file 'src/ChangeLog' --- src/ChangeLog 2013-08-07 13:34:17 +0000 +++ src/ChangeLog 2013-08-07 13:49:47 +0000 @@ -1,3 +1,9 @@ +2013-08-07 Eli Zaretskii + + * xdisp.c (prepare_menu_bars): Don't call x_consider_frame_title + for TTY frames that are not the top frame on their console. + (Bug#14616) + 2013-08-07 Martin Rudalics * w32term.c (w32fullscreen_hook): Really maximize frame when === modified file 'src/xdisp.c' --- src/xdisp.c 2013-08-07 10:32:08 +0000 +++ src/xdisp.c 2013-08-07 13:49:47 +0000 @@ -11169,7 +11169,18 @@ { f = XFRAME (frame); if (!EQ (frame, tooltip_frame) - && (FRAME_VISIBLE_P (f) || FRAME_ICONIFIED_P (f))) + && (FRAME_ICONIFIED_P (f) + || FRAME_VISIBLE_P (f) == 1 + /* Exclude TTY frames that are obscured because they + are not the top frame on their console. This is + because x_consider_frame_title actually swit6ches + to the frame, which for TTY frames means it is + marked as garbaged, and will be completely + redrawn on the next redisplay cycle. This causes + TTY frames to be completely redrawn, when there + are more than one of them, even though nothing + should be changed on display. */ + || (FRAME_VISIBLE_P (f) == 2 && FRAME_WINDOW_P (f)))) x_consider_frame_title (frame); } } ------------------------------------------------------------ revno: 113734 committer: martin rudalics branch nick: trunk timestamp: Wed 2013-08-07 15:34:17 +0200 message: In w32fullscreen_hook really maximize frame when asked for (Bug#14841). * w32term.c (w32fullscreen_hook): Really maximize frame when asked for (Bug#14841). diff: === modified file 'src/ChangeLog' --- src/ChangeLog 2013-08-07 13:21:59 +0000 +++ src/ChangeLog 2013-08-07 13:34:17 +0000 @@ -1,3 +1,8 @@ +2013-08-07 Martin Rudalics + + * w32term.c (w32fullscreen_hook): Really maximize frame when + asked for (Bug#14841). + 2013-08-07 Dmitry Antipov Prefer selected_window to Fselected_window, likewise for frames. === modified file 'src/w32term.c' --- src/w32term.c 2013-08-03 03:29:03 +0000 +++ src/w32term.c 2013-08-07 13:34:17 +0000 @@ -5717,7 +5717,9 @@ w32_fullscreen_rect (hwnd, f->want_fullscreen, FRAME_NORMAL_PLACEMENT (f).rcNormalPosition, &rect); FRAME_PREV_FSMODE (f) = f->want_fullscreen; - if (f->want_fullscreen == FULLSCREEN_BOTH) + if (f->want_fullscreen == FULLSCREEN_MAXIMIZED) + PostMessage (FRAME_W32_WINDOW (f), WM_SYSCOMMAND, 0xf030, 0); + else if (f->want_fullscreen == FULLSCREEN_BOTH) { SetWindowLong (hwnd, GWL_STYLE, dwStyle & ~WS_OVERLAPPEDWINDOW); SetWindowPos (hwnd, HWND_TOP, rect.left, rect.top, ------------------------------------------------------------ revno: 113733 committer: Dmitry Antipov branch nick: trunk timestamp: Wed 2013-08-07 17:21:59 +0400 message: Prefer selected_window to Fselected_window, likewise for frames. * buffer.c (Fbuffer_swap_text): * data.c (Fvariable_binding_locus): * window.c (run_window_configuration_change_hook): Adjust users. * w16select.c (Fw16_set_clipboard_data, Fw16_get_clipboard_data): Use decode_live_frame. diff: === modified file 'src/ChangeLog' --- src/ChangeLog 2013-08-07 10:32:08 +0000 +++ src/ChangeLog 2013-08-07 13:21:59 +0000 @@ -1,5 +1,14 @@ 2013-08-07 Dmitry Antipov + Prefer selected_window to Fselected_window, likewise for frames. + * buffer.c (Fbuffer_swap_text): + * data.c (Fvariable_binding_locus): + * window.c (run_window_configuration_change_hook): Adjust users. + * w16select.c (Fw16_set_clipboard_data, Fw16_get_clipboard_data): + Use decode_live_frame. + +2013-08-07 Dmitry Antipov + Be more careful if selected window shows the buffer other than current, use window_outdated only if this is not so. This change should also address some weird issues discussed in Bug#13012. === modified file 'src/buffer.c' --- src/buffer.c 2013-08-06 06:53:09 +0000 +++ src/buffer.c 2013-08-07 13:21:59 +0000 @@ -2409,7 +2409,7 @@ live window points to that window's buffer. So since we just swapped the markers between the two buffers, we need to undo the effect of this swap for window markers. */ - Lisp_Object w = Fselected_window (), ws = Qnil; + Lisp_Object w = selected_window, ws = Qnil; Lisp_Object buf1, buf2; XSETBUFFER (buf1, current_buffer); XSETBUFFER (buf2, other_buffer); === modified file 'src/data.c' --- src/data.c 2013-08-05 04:14:43 +0000 +++ src/data.c 2013-08-07 13:21:59 +0000 @@ -1975,7 +1975,7 @@ { union Lisp_Fwd *valcontents = SYMBOL_FWD (sym); if (KBOARD_OBJFWDP (valcontents)) - return Fframe_terminal (Fselected_frame ()); + return Fframe_terminal (selected_frame); else if (!BUFFER_OBJFWDP (valcontents)) return Qnil; } === modified file 'src/w16select.c' --- src/w16select.c 2013-01-23 20:07:28 +0000 +++ src/w16select.c 2013-08-07 13:21:59 +0000 @@ -452,11 +452,7 @@ CHECK_STRING (string); - if (NILP (frame)) - frame = Fselected_frame (); - - CHECK_LIVE_FRAME (frame); - if ( !FRAME_MSDOS_P (XFRAME (frame))) + if (!FRAME_MSDOS_P (decode_live_frame (frame))) goto done; block_input (); @@ -558,11 +554,7 @@ Lisp_Object ret = Qnil; int require_decoding = 0; - if (NILP (frame)) - frame = Fselected_frame (); - - CHECK_LIVE_FRAME (frame); - if ( !FRAME_MSDOS_P (XFRAME (frame))) + if (!FRAME_MSDOS_P (decode_live_frame (frame))) goto done; block_input (); === modified file 'src/window.c' --- src/window.c 2013-08-07 10:32:08 +0000 +++ src/window.c 2013-08-07 13:21:59 +0000 @@ -3128,7 +3128,7 @@ if (SELECTED_FRAME () != f) { - record_unwind_protect (select_frame_norecord, Fselected_frame ()); + record_unwind_protect (select_frame_norecord, selected_frame); select_frame_norecord (frame); } @@ -3143,7 +3143,7 @@ buffer))) { ptrdiff_t inner_count = SPECPDL_INDEX (); - record_unwind_protect (select_window_norecord, Fselected_window ()); + record_unwind_protect (select_window_norecord, selected_window); select_window_norecord (window); run_funs (Fbuffer_local_value (Qwindow_configuration_change_hook, buffer)); ------------------------------------------------------------ revno: 113732 committer: Xue Fuqiao branch nick: trunk timestamp: Wed 2013-08-07 21:19:48 +0800 message: Index and whitespace fixes for doc/misc/sc.texi. * sc.texi (Introduction): Fix indexes. (Usage Overview): (Citations, Citation Elements, Recognizing Citations) (Information Keys and the Info Alist, Reference Headers) (The Built-in Header Rewrite Functions) (Electric References, Reply Buffer Initialization) (Filling Cited Text, Selecting an Attribution) (Attribution Preferences) (Anonymous Attributions, Author Names) (Using Regi, Post-yank Formatting Commands) (Citing Commands, Insertion Commands) (Mail Field Commands) (Hints to MUA Authors, Thanks and History): Change from one space between sentences to two. diff: === modified file 'doc/misc/ChangeLog' --- doc/misc/ChangeLog 2013-08-07 12:44:16 +0000 +++ doc/misc/ChangeLog 2013-08-07 13:19:48 +0000 @@ -1,5 +1,20 @@ 2013-08-07 Xue Fuqiao + * sc.texi (Introduction): Fix index. + (Usage Overview): + (Citations, Citation Elements, Recognizing Citations) + (Information Keys and the Info Alist, Reference Headers) + (The Built-in Header Rewrite Functions) + (Electric References, Reply Buffer Initialization) + (Filling Cited Text, Selecting an Attribution) + (Attribution Preferences) + (Anonymous Attributions, Author Names) + (Using Regi, Post-yank Formatting Commands) + (Citing Commands, Insertion Commands) + (Mail Field Commands) + (Hints to MUA Authors, Thanks and History): Change from one space + between sentences to two. + * newsticker.texi (Usage): Use @key for RET. * cl.texi (Argument Lists): @@ -205,7 +220,7 @@ 2013-05-25 Xue Fuqiao - * flymake.texi: Changing from one space between sentences to two. + * flymake.texi: Change from one space between sentences to two. 2013-05-04 Stefan Monnier === modified file 'doc/misc/sc.texi' --- doc/misc/sc.texi 2013-01-01 09:11:05 +0000 +++ doc/misc/sc.texi 2013-08-07 13:19:48 +0000 @@ -84,12 +84,15 @@ @node Introduction @chapter Introduction -Supercite is a GNU Emacs package written entirely in Emacs Lisp. It +@cindex MUA +@cindex NUA +Supercite is a GNU Emacs package written entirely in Emacs Lisp. It interfaces to most of the commonly used Emacs mail user agents (@dfn{MUAs}) and news user agents (@dfn{NUAs}), and provides sophisticated facilities for the citing and attributing of message -replies. Supercite has a very specific and limited role in the process -of composing replies to both USENET network news and electronic mail. +replies. Supercite has a very specific and limited role in the +process of composing replies to both USENET network news and +electronic mail. The preferred way to spell Supercite is with a capital @samp{S}, lowercase @samp{upercite}. @@ -100,8 +103,7 @@ * What Supercite Does:: @end menu -@cindex MUA -@cindex NUA +@c FIXME: move it above the menu? --xfq Supercite is only useful in conjunction with MUAs and NUAs such as VM, Gnus, RMAIL, MH-E, etc. Supercite is typically called by the MUA after a reply buffer has been setup. Thereafter, Supercite's many commands and @@ -118,21 +120,22 @@ @cindex cite, citing @cindex attribute, attributing -Typical usage is as follows. You want to reply or followup to a message -in your MUA@. You will probably hit @kbd{r} (i.e., ``reply'') or @kbd{f} -(i.e., ``forward'') to begin composing the reply. In response, the MUA -will create a reply buffer and initialize the outgoing mail headers -appropriately. The body of the reply will usually be empty at this -point. You now decide that you would like to include part of the -original message in your reply. To do this, you @dfn{yank} the original -message into the reply buffer, typically with a key stroke such as -@kbd{C-c C-y}. This sequence will invoke an MUA-specific function which -fills the body of the reply with the original message and then -@dfn{attributes} this text to its author. This is called @dfn{citing} -and its effect is to prefix every line from the original message with a -special text tag. Most MUAs provide some default style of citing; by -using Supercite you gain a wider flexibility in the look and style of -citations. Supercite's only job is to cite the original message. +Typical usage is as follows. You want to reply or followup to a +message in your MUA@. You will probably hit @kbd{r} (i.e., ``reply'') +or @kbd{f} (i.e., ``forward'') to begin composing the reply. In +response, the MUA will create a reply buffer and initialize the +outgoing mail headers appropriately. The body of the reply will +usually be empty at this point. You now decide that you would like to +include part of the original message in your reply. To do this, you +@dfn{yank} the original message into the reply buffer, typically with +a key stroke such as @kbd{C-c C-y}. This sequence will invoke an +MUA-specific function which fills the body of the reply with the +original message and then @dfn{attributes} this text to its author. +This is called @dfn{citing} and its effect is to prefix every line +from the original message with a special text tag. Most MUAs provide +some default style of citing; by using Supercite you gain a wider +flexibility in the look and style of citations. Supercite's only job +is to cite the original message. @node What Supercite Does Not Do @section What Supercite Doesn't Do @@ -253,10 +256,10 @@ @cindex non-nested citations In @dfn{non-nested citations}, each cited line begins with an -informative string attributing that line to the original author. Only -the first level of attribution will be shown; subsequent citations don't -nest the citation strings. The above dialog might look like this when -non-nested citations are used: +informative string attributing that line to the original author. Only +the first level of attribution will be shown; subsequent citations +don't nest the citation strings. The above dialog might look like +this when non-nested citations are used: @example John> John originally wrote this @@ -272,19 +275,20 @@ @vindex sc-nested-citation-p @vindex nested-citation-p (sc-) Supercite supports both styles of citation, and the variable -@code{sc-nested-citation-p} controls which style it will use when citing -previously uncited text. When this variable is @code{nil} (the default), -non-nested citations are used. When non-@code{nil}, nested citations -are used. +@code{sc-nested-citation-p} controls which style it will use when +citing previously uncited text. When this variable is @code{nil} (the +default), non-nested citations are used. When non-@code{nil}, nested +citations are used. @node Citation Elements @section Citation Elements @cindex citation string -@dfn{Citation strings} are composed of one or more elements. Non-nested -citations are composed of four elements, three of which are directly -user definable. The elements are concatenated together, in this order: +@dfn{Citation strings} are composed of one or more elements. +Non-nested citations are composed of four elements, three of which are +directly user definable. The elements are concatenated together, in +this order: @cindex citation leader @vindex citation-leader (sc-) @@ -337,10 +341,10 @@ @section Recognizing Citations Supercite also recognizes citations in the original article, and can -transform these already cited lines in a number of ways. This is how +transform these already cited lines in a number of ways. This is how Supercite suppresses the multiple citing of non-nested citations. -Recognition of cited lines is controlled by variables analogous to those -that make up the citation string as mentioned previously. +Recognition of cited lines is controlled by variables analogous to +those that make up the citation string as mentioned previously. @vindex sc-citation-leader-regexp @vindex citation-leader-regexp (sc-) @@ -387,16 +391,16 @@ @dfn{Mail header information keys} are nuggets of information that Supercite extracts from the various mail headers of the original -message, placed in the reply buffer by the MUA@. Information is kept in -the @dfn{Info Alist} as key-value pairs, and can be retrieved for use in -various places within Supercite, such as in header rewrite functions and -attribution selection. Other bits of data, composed and created by -Supercite, are also kept as key-value pairs in this alist. In the case -of mail fields, the key is the name of the field, omitting the trailing -colon. Info keys are always case insensitive (as are mail headers), and -the value for a corresponding key can be retrieved from the alist with -the @code{sc-mail-field} function. Thus, if the following fields were -present in the original article:@refill +message, placed in the reply buffer by the MUA@. Information is kept +in the @dfn{Info Alist} as key-value pairs, and can be retrieved for +use in various places within Supercite, such as in header rewrite +functions and attribution selection. Other bits of data, composed and +created by Supercite, are also kept as key-value pairs in this alist. +In the case of mail fields, the key is the name of the field, omitting +the trailing colon. Info keys are always case insensitive (as are +mail headers), and the value for a corresponding key can be retrieved +from the alist with the @code{sc-mail-field} function. Thus, if the +following fields were present in the original article:@refill @example Date:@: 08 April 1991, 17:32:09 EST @@ -419,7 +423,7 @@ Since the argument to @code{sc-mail-field} can be any string, it is possible that the mail field will not be present on the info alist (possibly because the mail header was not present in the original -message). In this case, @code{sc-mail-field} will return the value of +message). In this case, @code{sc-mail-field} will return the value of the variable @code{sc-mumble}. Supercite always places all mail fields found in the yanked original @@ -510,8 +514,8 @@ @vindex sc-rewrite-header-list @vindex rewrite-header-list (sc-) There are a number of built-in @dfn{header rewrite functions} supplied -by Supercite, but you can write your own custom header rewrite functions -(perhaps using the built-in ones as examples). The variable +by Supercite, but you can write your own custom header rewrite +functions (perhaps using the built-in ones as examples). The variable @code{sc-rewrite-header-list} contains the list of such header rewrite functions. This list is consulted both when inserting the initial reference header, and when displaying @dfn{electric references}. @@ -521,7 +525,7 @@ @vindex preferred-header-style (sc-) When Supercite is initially run on a reply buffer (via @code{sc-cite-original}), it will automatically call one of these -functions. The one it uses is defined in the variable +functions. The one it uses is defined in the variable @code{sc-preferred-header-style}. The value of this variable is an integer which is an index into the @code{sc-rewrite-header-list}, beginning at zero. @@ -556,9 +560,9 @@ @findex sc-no-header @findex no-header (sc-) @item sc-no-header -This function produces no header. It should be used instead of -@code{nil} to produce a blank header. This header can possibly contain -a blank line after the @code{mail-header-separator} line. +This function produces no header. It should be used instead of +@code{nil} to produce a blank header. This header can possibly +contain a blank line after the @code{mail-header-separator} line. @item sc-no-blank-line-or-header @findex sc-no-blank-line-or-header @@ -612,11 +616,11 @@ By default, when Supercite cites the original message for the first time, it just goes ahead and inserts the reference header indexed by @code{sc-preferred-header-style}. However, you may want to select -different reference headers based on the type of reply or forwarding you -are doing. You may also want to preview the reference header before -deciding whether to insert it into the reply buffer or not. Supercite -provides an optional @dfn{electric reference} mode which you can drop -into to give you this functionality. +different reference headers based on the type of reply or forwarding +you are doing. You may also want to preview the reference header +before deciding whether to insert it into the reply buffer or +not. Supercite provides an optional @dfn{electric reference} mode +which you can drop into to give you this functionality. @vindex sc-electric-references-p @vindex electric-references-p (sc-) @@ -629,7 +633,7 @@ @code{sc-rewrite-header-list}. You can also set a new preferred header style, jump to any header, or -jump to the preferred header. The header will be shown in the electric +jump to the preferred header. The header will be shown in the electric reference buffer and the header index and function name will appear in the echo area. @@ -643,7 +647,7 @@ @kindex n @vindex sc-electric-circular-p @vindex electric-circular-p (sc-) -Displays the next reference header in the electric reference buffer. If +Displays the next reference header in the electric reference buffer. If the variable @code{sc-electric-circular-p} is non-@code{nil}, invoking @code{sc-eref-next} while viewing the last reference header in the list will wrap around to the first header.@refill @@ -854,7 +858,7 @@ @vindex mail-warn-if-non-rfc822-p (sc-) All previously retrieved info key-value pairs are deleted from the info alist, then the mail headers in the body of the yanked message are -scanned. Info key-value pairs are created for each header found. Also, +scanned. Info key-value pairs are created for each header found. Also, such useful information as the author's name and email address are extracted. If the variable @code{sc-mail-warn-if-non-rfc822-p} is non-@code{nil}, then Supercite will warn you if it finds a mail header @@ -931,7 +935,7 @@ non-@code{nil}, blank lines will be cited just like non-blank lines. Otherwise, blank lines will be treated as paragraph separators. -Citing of the original message is highly configurable. Supercite's +Citing of the original message is highly configurable. Supercite's default setup does a pretty good job of citing many common forms of previously cited messages. But there are as many citation styles out there as people on the net, or just about! It would be impossible for @@ -945,8 +949,8 @@ @vindex sc-post-hook @vindex post-hook (sc-) This variable is very similar to @code{sc-pre-hook}, except that it runs -after @code{sc-cite-original} is finished. This hook is provided mostly -for completeness and backward compatibility. Perhaps it could be used to +after @code{sc-cite-original} is finished. This hook is provided mostly +for completeness and backward compatibility. Perhaps it could be used to reset certain variables set in @code{sc-pre-hook}.@refill @end enumerate @@ -1012,7 +1016,7 @@ @pxref{Post-yank Formatting Commands}).@refill You will noticed that the minor mode string will -show the state of these variables as qualifier characters. When both +show the state of these variables as qualifier characters. When both variables are @code{nil}, the Supercite minor mode string will display @samp{SC}. When just @code{sc-auto-fill-region-p} is non-@code{nil}, the string will display @samp{SC:f}, and when just @@ -1036,11 +1040,11 @@ @vindex preferred-attribution-list (sc-) As you know, the attribution string is the part of the author's name -that will be used to composed a non-nested citation string. Supercite +that will be used to composed a non-nested citation string. Supercite scans the various mail headers present in the original article and uses a number of heuristics to extract strings which it puts into the -@dfn{attribution association list} or @dfn{attribution alist}. This is -analogous, but different than, the info alist previously mentioned. Each +@dfn{attribution association list} or @dfn{attribution alist}. This is +analogous, but different than, the info alist previously mentioned. Each element in the attribution alist is a key-value pair containing such information as the author's first name, middle names, and last name, the author's initials, and the author's email terminus. @@ -1083,7 +1087,7 @@ the author's first middle name. @item "sc-lastchoice" -the last attribution string you have selected. This is useful when you +the last attribution string you have selected. This is useful when you recite paragraphs in the reply.@refill @item "sc-consult" @@ -1094,7 +1098,7 @@ key. See below for details. @item "x-attribution" -the original author's suggestion for attribution string choice. See below +the original author's suggestion for attribution string choice. See below for details.@refill @end table @@ -1141,7 +1145,7 @@ @findex sc-mail-field @findex mail-field (sc-) where @var{infokey} is a key for @code{sc-mail-field} and @var{regexp} -is a regular expression to match against the @var{infokey}'s value. If +is a regular expression to match against the @var{infokey}'s value. If @var{regexp} matches the @var{infokey}'s value, the @var{attribution} is used as the attribution string. Actually, @var{attribution} can be a string or a list; if it is a list, it is @code{eval}uated and the return @@ -1166,7 +1170,7 @@ @code{sc-default-author-name} and the fallback attribution string is contained in the variable @code{sc-default-attribution}. Default values for these variables are @code{"Anonymous"} and @code{"Anon"}, -respectively. Note that in most circumstances, getting the default +respectively. Note that in most circumstances, getting the default author name or attribution is a sign that something is set up incorrectly. @@ -1174,7 +1178,7 @@ @vindex use-only-preference-p (sc-) Also, if the preferred attribution, which you specified in your @code{sc-preferred-attribution-list} variable cannot be found, a -secondary method can be employed to find a valid attribution string. The +secondary method can be employed to find a valid attribution string. The variable @code{sc-use-only-preference-p} controls what happens in this case. If the variable's value is non-@code{nil}, then @code{sc-default-author-name} and @code{sc-default-attribution} are @@ -1209,11 +1213,11 @@ @vindex sc-confirm-always-p @vindex confirm-always-p (sc-) Once the attribution string has been automatically selected, a number of -things can happen. If the variable @code{sc-confirm-always-p} is +things can happen. If the variable @code{sc-confirm-always-p} is non-@code{nil}, you are queried for confirmation of the chosen -attribution string. The possible values for completion are those strings +attribution string. The possible values for completion are those strings in the attribution alist, however you are not limited to these choices. -You can type any arbitrary string at the confirmation prompt. The string +You can type any arbitrary string at the confirmation prompt. The string you enter becomes the value associated with the @code{"sc-lastchoice"} key in the attribution alist. @@ -1279,7 +1283,7 @@ Also, some companies prepend or append the name of the division, organization, or project on the author's name. All of these titles are noise which should be ignored. The variable @code{sc-name-filter-alist} -is used for this purpose. As implied by its name, this variable is an +is used for this purpose. As implied by its name, this variable is an association list, where each element is a cons cell of the form: @example @@ -1290,7 +1294,7 @@ where @var{regexp} is a regular expression that is matched (using @code{string-match}) against each element of the @samp{From:@:} field's author name. @var{position} is a position indicator, starting at zero. -Thus to strip out all titles of ``Dr.'', ``Mr.'', etc. from the name, +Thus to strip out all titles of ``Dr.'', ``Mr.'', etc. from the name, @code{sc-name-filter-alist} would have an entry such as: @example @@ -1380,10 +1384,10 @@ @item t Always produces a true outcome. @item begin -Always executed before the frame is interpreted. This can be used to +Always executed before the frame is interpreted. This can be used to initialize some global variables for example. @item end -Always executed after frame interpreting is completed. This can be used +Always executed after frame interpreting is completed. This can be used to perform any necessary post-processing. @item every Executes whenever the frame is reset, usually after the entire frame has @@ -1406,12 +1410,12 @@ @table @asis @item the symbol @code{continue} This tells Regi to continue processing entries after a match, instead of -resetting the frame and moving @samp{point}. In this way, lines of text +resetting the frame and moving @samp{point}. In this way, lines of text can have multiple matches, but you have to be careful to avoid entering infinite loops. @item the symbol @code{abort} -This tells Regi to terminate frame processing. However, any @code{end} +This tells Regi to terminate frame processing. However, any @code{end} entry is still processed. @item the list @code{(frame . @var{newframe})} @@ -1422,7 +1426,7 @@ @item the list @code{(step . @var{step})} Tells Regi to move @var{step} number of lines forward as it continues -processing. By default, Regi moves forward one line. @var{step} can be +processing. By default, Regi moves forward one line. @var{step} can be zero or negative of course, but watch out for infinite loops.@refill @end table @@ -1510,12 +1514,12 @@ Once the original message has been yanked into the reply buffer, and @code{sc-cite-original} has had a chance to do its thing, a number of -useful Supercite commands will be available to you. Since there is wide +useful Supercite commands will be available to you. Since there is wide variety in the keymaps that MUAs set up in their reply buffers, it is next to impossible for Supercite to properly sprinkle its commands into the existing keymap. For this reason Supercite places its commands on a separate keymap, putting this keymap onto a prefix key in the reply -buffer. You can customize the prefix key Supercite uses by changing the +buffer. You can customize the prefix key Supercite uses by changing the variable @code{sc-mode-map-prefix}. By default, the @code{sc-mode-map-prefix} is @kbd{C-c C-p}; granted, not a great choice, but unfortunately the best general solution so far. In the rest of this @@ -1536,7 +1540,7 @@ Probably the three most common post-yank formatting operations that you will perform will be the manual citing, reciting, and unciting of -regions of text in the reply buffer. Often you may want to recite a +regions of text in the reply buffer. Often you may want to recite a paragraph to use a nickname, or manually cite a message when setting @code{sc-cite-region-limit} to @code{nil}. The following commands perform these functions on the region of text between @samp{point} and @@ -1582,7 +1586,7 @@ @item @code{sc-recite-region} (@kbd{C-c C-p r}) This command recites each line the region by interpreting the selected frame from @code{sc-recite-frame-alist}, or the default reciting frame -@code{sc-default-recite-frame}. It runs the hook +@code{sc-default-recite-frame}. It runs the hook @code{sc-pre-recite-hook} before interpreting the frame. @xref{Configuring the Citation Engine}.@refill @@ -1606,7 +1610,7 @@ @vindex preferred-header-style (sc-) Inserts a reference header into the reply buffer at @samp{point}. With no arguments, the header indexed by @code{sc-preferred-header-style} is -inserted. An optional numeric argument is the index into +inserted. An optional numeric argument is the index into @code{sc-rewrite-header-list} indicating which reference header to write.@refill @@ -1719,7 +1723,7 @@ key-value pairs. With no argument, you are prompted (with completion) for a info key. The value associated with that key is displayed in the minibuffer. With an argument, this command will first ask if you want -to view, modify, add, or delete an info key. Viewing is identical to +to view, modify, add, or delete an info key. Viewing is identical to running the command with no arguments. If you want to modify the value of a key, Supercite will first prompt @@ -1770,7 +1774,7 @@ @chapter Hints to MUA Authors In June of 1989, some discussion was held between the various MUA -authors, the Supercite author, and other Supercite users. These +authors, the Supercite author, and other Supercite users. These discussions centered around the need for a standard interface between MUAs and Supercite (or any future Supercite-like packages). This interface was formally proposed by Martin Neitzel on Fri, 23 Jun 89, in @@ -1810,14 +1814,14 @@ If you are writing a new MUA package, or maintaining an existing MUA package, you should make it conform to this interface so that your users -will be able to link Supercite easily and seamlessly. To do this, when +will be able to link Supercite easily and seamlessly. To do this, when setting up a reply or forward buffer, your MUA should follow these steps: @enumerate @item Insert the original message, including the mail headers into the reply -buffer. At this point you should not modify the raw text in any way +buffer. At this point you should not modify the raw text in any way (except for any necessary decoding, e.g., of quoted-printable text), and you should place all the original headers into the body of the reply. This means that many of the mail headers will be duplicated, one copy @@ -1826,7 +1830,7 @@ @item Set @samp{point} to the beginning of the line containing the first mail -header in the body of the reply. Set @samp{mark} at the end of the +header in the body of the reply. Set @samp{mark} at the end of the message text. It is very important that the region be set around the text Supercite is to modify and that the mail headers are within this region. Supercite will not venture outside the region for any reason, @@ -1834,7 +1838,7 @@ @strong{must} remain unchanged inside the region.@refill @item -Run the hook @code{mail-citation-hook}. You will probably want to +Run the hook @code{mail-citation-hook}. You will probably want to provide some kind of default citation functions in cases where the user does not have Supercite installed. By default, your MUA should @code{defvar} @code{mail-citation-hook} to @code{nil}, and in your @@ -1853,9 +1857,9 @@ The Supercite package was derived from its predecessor Superyank 1.11 which was inspired by various bits of code and ideas from Martin Neitzel -and Ashwin Ram. They were the folks who came up with the idea of +and Ashwin Ram. They were the folks who came up with the idea of non-nested citations and implemented some rough code to provide this -style. Superyank and Supercite version 2 evolved to the point where much +style. Superyank and Supercite version 2 evolved to the point where much of the attribution selection mechanism was automatic, and features have been continuously added through the comments and suggestions of the Supercite mailing list participants. ------------------------------------------------------------ revno: 113731 committer: Xue Fuqiao branch nick: trunk timestamp: Wed 2013-08-07 20:44:16 +0800 message: * doc/misc/newsticker.texi (Usage): Use @key for RET. diff: === modified file 'doc/misc/ChangeLog' --- doc/misc/ChangeLog 2013-08-07 07:01:54 +0000 +++ doc/misc/ChangeLog 2013-08-07 12:44:16 +0000 @@ -1,5 +1,7 @@ 2013-08-07 Xue Fuqiao + * newsticker.texi (Usage): Use @key for RET. + * cl.texi (Argument Lists): (For Clauses): (Macros): Add indexes. === modified file 'doc/misc/newsticker.texi' --- doc/misc/newsticker.texi 2013-07-04 01:55:25 +0000 +++ doc/misc/newsticker.texi 2013-08-07 12:44:16 +0000 @@ -169,9 +169,9 @@ @samp{*newsticker*} buffer informs you whenever new headlines have arrived. @end itemize -In both views clicking mouse-button 2 or pressing RET on a headline -will call @code{browse-url} to load the corresponding news story in -your favorite web browser. +In both views clicking mouse-button 2 or pressing @key{RET} on a +headline will call @code{browse-url} to load the corresponding news +story in your favorite web browser. @findex newsticker-start-ticker @findex newsticker-stop-ticker === modified file 'etc/TODO' --- etc/TODO 2013-08-03 02:57:00 +0000 +++ etc/TODO 2013-08-07 12:44:16 +0000 @@ -76,7 +76,8 @@ ** Convert all defvars with leading `*' in the doc-strings into defcustoms of appropriate :type and :group. -** Remove any leading `*'s from defcustom doc-strings. [done?] +** Remove any leading `*'s from defcustom doc-strings. +[done?] [A lot of them are in CC Mode.] ** Remove unnecessary autoload cookies from defcustoms. This needs a bit of care, since often people have become used to ------------------------------------------------------------ revno: 113730 committer: Dmitry Antipov branch nick: trunk timestamp: Wed 2013-08-07 14:32:08 +0400 message: Be more careful if selected window shows the buffer other than current, use window_outdated only if this is not so. This change should also address some weird issues discussed in Bug#13012. * window.h (window_outdated): New prototype. * window.c (window_outdated): Now here. Convert from static and always assume window's buffer. (Fwindow_end, Fwindow_line_height): Use it. * xdisp.c (reconsider_clip_changes): Remove prototype, drop 2nd arg and always assume window's buffer. (redisplay_window): Adjust user. (redisplay_internal): Call to reconsider_clip_change once and check whether mode line should be updated only if selected window shows current buffer. (run_window_scroll_functions): Use eassert for debugging check. (Fmove_point_visually, note_mouse_highlight): Use window_outdated. diff: === modified file 'src/ChangeLog' --- src/ChangeLog 2013-08-06 16:51:41 +0000 +++ src/ChangeLog 2013-08-07 10:32:08 +0000 @@ -1,3 +1,21 @@ +2013-08-07 Dmitry Antipov + + Be more careful if selected window shows the buffer other than current, + use window_outdated only if this is not so. This change should also + address some weird issues discussed in Bug#13012. + * window.h (window_outdated): New prototype. + * window.c (window_outdated): Now here. Convert from static and + always assume window's buffer. + (Fwindow_end, Fwindow_line_height): Use it. + * xdisp.c (reconsider_clip_changes): Remove prototype, drop 2nd arg + and always assume window's buffer. + (redisplay_window): Adjust user. + (redisplay_internal): Call to reconsider_clip_change once and + check whether mode line should be updated only if selected window + shows current buffer. + (run_window_scroll_functions): Use eassert for debugging check. + (Fmove_point_visually, note_mouse_highlight): Use window_outdated. + 2013-08-06 Dmitry Antipov * window.c (window_scroll, window_scroll_pixel_based) === modified file 'src/window.c' --- src/window.c 2013-08-06 16:51:41 +0000 +++ src/window.c 2013-08-07 10:32:08 +0000 @@ -239,6 +239,17 @@ w->horizontal = horflag; } +/* Nonzero if leaf window W doesn't reflect the actual state + of displayed buffer due to its text or overlays change. */ + +bool +window_outdated (struct window *w) +{ + struct buffer *b = XBUFFER (w->contents); + return (w->last_modified < BUF_MODIFF (b) + || w->last_overlay_modified < BUF_OVERLAY_MODIFF (b)); +} + struct window * decode_live_window (register Lisp_Object window) { @@ -1506,8 +1517,7 @@ || !w->window_end_valid || b->clip_changed || b->prevent_redisplay_optimizations_p - || w->last_modified < BUF_MODIFF (b) - || w->last_overlay_modified < BUF_OVERLAY_MODIFF (b)) + || window_outdated (w)) && !noninteractive) { struct text_pos startp; @@ -1720,8 +1730,7 @@ || windows_or_buffers_changed || b->clip_changed || b->prevent_redisplay_optimizations_p - || w->last_modified < BUF_MODIFF (b) - || w->last_overlay_modified < BUF_OVERLAY_MODIFF (b)) + || window_outdated (w)) return Qnil; if (NILP (line)) === modified file 'src/window.h' --- src/window.h 2013-07-16 21:35:45 +0000 +++ src/window.h 2013-08-07 10:32:08 +0000 @@ -973,6 +973,7 @@ extern void replace_buffer_in_windows_safely (Lisp_Object); /* This looks like a setter, but it is a bit special. */ extern void wset_buffer (struct window *, Lisp_Object); +extern bool window_outdated (struct window *); extern void init_window_once (void); extern void init_window (void); extern void syms_of_window (void); === modified file 'src/xdisp.c' --- src/xdisp.c 2013-08-03 18:16:43 +0000 +++ src/xdisp.c 2013-08-07 10:32:08 +0000 @@ -804,7 +804,6 @@ static void pint2hrstr (char *, int, ptrdiff_t); static struct text_pos run_window_scroll_functions (Lisp_Object, struct text_pos); -static void reconsider_clip_changes (struct window *, struct buffer *); static int text_outside_line_unchanged_p (struct window *, ptrdiff_t, ptrdiff_t); static void store_mode_line_noprop_char (char); @@ -10850,17 +10849,6 @@ && UNCHANGED_MODIFIED < MODIFF); } -/* Nonzero if W doesn't reflect the actual state of current buffer due - to its text or overlays change. FIXME: this may be called when - XBUFFER (w->contents) != current_buffer, which looks suspicious. */ - -static int -window_outdated (struct window *w) -{ - return (w->last_modified < MODIFF - || w->last_overlay_modified < OVERLAY_MODIFF); -} - /* Nonzero if W's buffer was changed but not saved or Transient Mark mode is enabled and mark of W's buffer was changed since last W's update. */ @@ -12866,13 +12854,13 @@ && start < pt && end > pt); } - -/* Reconsider the setting of B->clip_changed which is displayed - in window W. */ +/* Reconsider the clip changes of buffer which is displayed in W. */ static void -reconsider_clip_changes (struct window *w, struct buffer *b) +reconsider_clip_changes (struct window *w) { + struct buffer *b = XBUFFER (w->contents); + if (b->clip_changed && w->window_end_valid && w->current_matrix->buffer == b @@ -12885,24 +12873,17 @@ we set b->clip_changed to 1 to force updating the screen. If b->clip_changed has already been set to 1, we can skip this check. */ - if (!b->clip_changed && BUFFERP (w->contents) && w->window_end_valid) + if (!b->clip_changed && w->window_end_valid) { - ptrdiff_t pt; - - if (w == XWINDOW (selected_window)) - pt = PT; - else - pt = marker_position (w->pointm); - - if ((w->current_matrix->buffer != XBUFFER (w->contents) - || pt != w->last_point) + ptrdiff_t pt = (w == XWINDOW (selected_window) + ? PT : marker_position (w->pointm)); + + if ((w->current_matrix->buffer != b || pt != w->last_point) && check_point_in_composition (w->current_matrix->buffer, - w->last_point, - XBUFFER (w->contents), pt)) + w->last_point, b, pt)) b->clip_changed = 1; } } - #define STOP_POLLING \ do { if (! polling_stopped_here) stop_polling (); \ @@ -12923,10 +12904,10 @@ struct window *sw; struct frame *fr; int pending; - int must_finish = 0; + bool must_finish = 0, match_p; struct text_pos tlbufpos, tlendpos; int number_of_visible_frames; - ptrdiff_t count, count1; + ptrdiff_t count; struct frame *sf; int polling_stopped_here = 0; Lisp_Object tail, frame; @@ -12983,7 +12964,6 @@ sw = w; pending = 0; - reconsider_clip_changes (w, current_buffer); last_escape_glyph_frame = NULL; last_escape_glyph_face_id = (1 << FACE_ID_BITS); last_glyphless_glyph_frame = NULL; @@ -13038,10 +13018,7 @@ /* do_pending_window_change could change the selected_window due to frame resizing which makes the selected window too small. */ if (WINDOWP (selected_window) && (w = XWINDOW (selected_window)) != sw) - { - sw = w; - reconsider_clip_changes (w, current_buffer); - } + sw = w; /* Clear frames marked as garbaged. */ clear_garbaged_frames (); @@ -13053,23 +13030,32 @@ if (windows_or_buffers_changed) update_mode_lines++; - /* Detect case that we need to write or remove a star in the mode line. */ - if ((SAVE_MODIFF < MODIFF) != w->last_had_star) + reconsider_clip_changes (w); + + /* In most cases selected window displays current buffer. */ + match_p = XBUFFER (w->contents) == current_buffer; + if (match_p) { - w->update_mode_line = 1; - if (buffer_shared_and_changed ()) - update_mode_lines++; + ptrdiff_t count1; + + /* Detect case that we need to write or remove a star in the mode line. */ + if ((SAVE_MODIFF < MODIFF) != w->last_had_star) + { + w->update_mode_line = 1; + if (buffer_shared_and_changed ()) + update_mode_lines++; + } + + /* Avoid invocation of point motion hooks by `current_column' below. */ + count1 = SPECPDL_INDEX (); + specbind (Qinhibit_point_motion_hooks, Qt); + + if (mode_line_update_needed (w)) + w->update_mode_line = 1; + + unbind_to (count1, Qnil); } - /* Avoid invocation of point motion hooks by `current_column' below. */ - count1 = SPECPDL_INDEX (); - specbind (Qinhibit_point_motion_hooks, Qt); - - if (mode_line_update_needed (w)) - w->update_mode_line = 1; - - unbind_to (count1, Qnil); - consider_all_windows_p = (update_mode_lines || buffer_shared_and_changed () || cursor_type_changed); @@ -13167,7 +13153,7 @@ && !FRAME_OBSCURED_P (XFRAME (w->frame)) /* Make sure recorded data applies to current buffer, etc. */ && this_line_buffer == current_buffer - && current_buffer == XBUFFER (w->contents) + && match_p && !w->force_start && !w->optional_new_start /* Point must be on the line that we have info recorded about. */ @@ -14458,8 +14444,7 @@ struct window *w = XWINDOW (window); SET_MARKER_FROM_TEXT_POS (w->start, startp); - if (current_buffer != XBUFFER (w->contents)) - emacs_abort (); + eassert (current_buffer == XBUFFER (w->contents)); if (!NILP (Vwindow_scroll_functions)) { @@ -15360,7 +15345,7 @@ eassert (XMARKER (w->pointm)->buffer == buffer); restart: - reconsider_clip_changes (w, buffer); + reconsider_clip_changes (w); frame_line_height = default_line_pixel_height (w); /* Has the mode line to be updated? */ @@ -20115,7 +20100,7 @@ (Lisp_Object direction) { struct window *w = XWINDOW (selected_window); - struct buffer *b = NULL; + struct buffer *b = XBUFFER (w->contents); struct glyph_row *row; int dir; Lisp_Object paragraph_dir; @@ -20135,9 +20120,6 @@ else dir = -1; - if (BUFFERP (w->contents)) - b = XBUFFER (w->contents); - /* If current matrix is up-to-date, we can use the information recorded in the glyphs, at least as long as the goal is on the screen. */ @@ -20146,8 +20128,7 @@ && b && !b->clip_changed && !b->prevent_redisplay_optimizations_p - && w->last_modified >= BUF_MODIFF (b) - && w->last_overlay_modified >= BUF_OVERLAY_MODIFF (b) + && !window_outdated (w) && w->cursor.vpos >= 0 && w->cursor.vpos < w->current_matrix->nrows && (row = MATRIX_ROW (w->current_matrix, w->cursor.vpos))->enabled_p) @@ -28142,10 +28123,7 @@ /* Are we in a window whose display is up to date? And verify the buffer's text has not changed. */ b = XBUFFER (w->contents); - if (part == ON_TEXT - && w->window_end_valid - && w->last_modified == BUF_MODIFF (b) - && w->last_overlay_modified == BUF_OVERLAY_MODIFF (b)) + if (part == ON_TEXT && w->window_end_valid && !window_outdated (w)) { int hpos, vpos, dx, dy, area = LAST_AREA; ptrdiff_t pos; ------------------------------------------------------------ revno: 113729 committer: Xue Fuqiao branch nick: trunk timestamp: Wed 2013-08-07 15:01:54 +0800 message: doc/misc/cl.texi: Add index for compiler macro. diff: === modified file 'doc/misc/ChangeLog' --- doc/misc/ChangeLog 2013-08-07 02:25:52 +0000 +++ doc/misc/ChangeLog 2013-08-07 07:01:54 +0000 @@ -1,7 +1,8 @@ 2013-08-07 Xue Fuqiao * cl.texi (Argument Lists): - (For Clauses): Add indexes. + (For Clauses): + (Macros): Add indexes. 2013-08-05 Xue Fuqiao === modified file 'doc/misc/cl.texi' --- doc/misc/cl.texi 2013-08-07 02:25:52 +0000 +++ doc/misc/cl.texi 2013-08-07 07:01:54 +0000 @@ -2506,6 +2506,8 @@ or with incorrect keyword arguments. @end defmac +@cindex compiler macros +@cindex define compiler macros This package also includes the Common Lisp @code{define-compiler-macro} facility, which allows you to define compile-time expansions and optimizations for your functions. ------------------------------------------------------------ revno: 113728 committer: Xue Fuqiao branch nick: trunk timestamp: Wed 2013-08-07 10:25:52 +0800 message: doc/misc/cl.texi: Add indexes. * doc/misc/cl.texi (Argument Lists): (For Clauses): Add indexes. diff: === modified file 'doc/lispref/display.texi' --- doc/lispref/display.texi 2013-08-06 06:53:09 +0000 +++ doc/lispref/display.texi 2013-08-07 02:25:52 +0000 @@ -1243,6 +1243,7 @@ @node Overlays @section Overlays @cindex overlays +@c FIXME: mention intervals in this section? You can use @dfn{overlays} to alter the appearance of a buffer's text on the screen, for the sake of presentation features. An overlay is an === modified file 'doc/misc/ChangeLog' --- doc/misc/ChangeLog 2013-08-05 13:28:29 +0000 +++ doc/misc/ChangeLog 2013-08-07 02:25:52 +0000 @@ -1,3 +1,8 @@ +2013-08-07 Xue Fuqiao + + * cl.texi (Argument Lists): + (For Clauses): Add indexes. + 2013-08-05 Xue Fuqiao * cl.texi (Blocks and Exits): Add an index. === modified file 'doc/misc/cl.texi' --- doc/misc/cl.texi 2013-08-05 13:28:29 +0000 +++ doc/misc/cl.texi 2013-08-07 02:25:52 +0000 @@ -461,6 +461,7 @@ @var{body})) @end example +@cindex destructuring, in argument list Argument lists support @dfn{destructuring}. In Common Lisp, destructuring is only allowed with @code{defmacro}; this package allows it with @code{cl-defun} and other argument lists as well. @@ -2140,6 +2141,7 @@ based on the value of @code{x} left over from the previous time through the loop. +@cindex destructuring, in cl-loop Another feature of the @code{cl-loop} macro is @emph{destructuring}, similar in concept to the destructuring provided by @code{defmacro} (@pxref{Argument Lists}).