diff options
Diffstat (limited to 'lisp')
58 files changed, 2337 insertions, 1064 deletions
diff --git a/lisp/ChangeLog b/lisp/ChangeLog index 86a27f9b5bd..5451abc2119 100644 --- a/lisp/ChangeLog +++ b/lisp/ChangeLog | |||
| @@ -1,3 +1,441 @@ | |||
| 1 | 2013-07-13 Dmitry Gutov <dgutov@yandex.ru> | ||
| 2 | |||
| 3 | * progmodes/ruby-mode.el (ruby-font-lock-keywords): Highlight | ||
| 4 | conversion methods on Kernel. | ||
| 5 | |||
| 6 | 2013-07-13 Alan Mackenzie <acm@muc.de> | ||
| 7 | |||
| 8 | * progmodes/cc-engine.el (c-forward-decl-or-cast-1): Label CASE 13 | ||
| 9 | and comment it out. This out-commenting enables certain C++ | ||
| 10 | declarations to be parsed correctly. | ||
| 11 | |||
| 12 | 2013-07-13 Eli Zaretskii <eliz@gnu.org> | ||
| 13 | |||
| 14 | * international/mule.el (define-coding-system): Doc fix. | ||
| 15 | |||
| 16 | * simple.el (default-font-height): Don't call font-info if the | ||
| 17 | frame's default font didn't change since the frame was created. | ||
| 18 | (Bug#14838) | ||
| 19 | |||
| 20 | 2013-07-13 Leo Liu <sdl.web@gmail.com> | ||
| 21 | |||
| 22 | * ido.el (ido-read-file-name): Guard against non-symbol value. | ||
| 23 | |||
| 24 | 2013-07-13 Fabián Ezequiel Gallina <fgallina@gnu.org> | ||
| 25 | |||
| 26 | * progmodes/python.el (python-imenu--build-tree): Fix corner case | ||
| 27 | in nested defuns. | ||
| 28 | |||
| 29 | 2013-07-13 Leo Liu <sdl.web@gmail.com> | ||
| 30 | |||
| 31 | * ido.el (ido-exhibit): Handle ido-enter-matching-directory before | ||
| 32 | ido-set-matches call. (Bug#6852) | ||
| 33 | |||
| 34 | 2013-07-12 Dmitry Gutov <dgutov@yandex.ru> | ||
| 35 | |||
| 36 | * progmodes/ruby-mode.el (ruby-percent-literals-beg-re): | ||
| 37 | (ruby-syntax-expansion-allowed-p): Support array of symbols, for | ||
| 38 | Ruby 2.0. | ||
| 39 | (ruby-font-lock-keywords): Distinguish calls to functions with | ||
| 40 | module-like names from module references. Highlight character | ||
| 41 | literals. | ||
| 42 | |||
| 43 | 2013-07-12 Sergio Durigan Junior <sergiodj@riseup.net> (tiny change) | ||
| 44 | |||
| 45 | * progmodes/gdb-mi.el (gdb-strip-string-backslash): New function. | ||
| 46 | (gdb-send): Handle continued commands. (Bug#14847) | ||
| 47 | |||
| 48 | 2013-07-12 Juanma Barranquero <lekktu@gmail.com> | ||
| 49 | |||
| 50 | * desktop.el (desktop--v2s): Remove unused local variable. | ||
| 51 | (desktop-save-buffer): Make defvar-local; adjust docstring. | ||
| 52 | (desktop-auto-save-timeout, desktop-owner): Use ignore-errors. | ||
| 53 | (desktop-clear, desktop-save-buffer-p): Use string-match-p. | ||
| 54 | |||
| 55 | 2013-07-12 Andreas Schwab <schwab@linux-m68k.org> | ||
| 56 | |||
| 57 | * emacs-lisp/map-ynp.el (map-y-or-n-p): Fix last change. | ||
| 58 | |||
| 59 | 2013-07-12 Eli Zaretskii <eliz@gnu.org> | ||
| 60 | |||
| 61 | * simple.el (next-line, previous-line): Document TRY-VSCROLL and ARG. | ||
| 62 | (Bug#14842) | ||
| 63 | |||
| 64 | 2013-07-12 Glenn Morris <rgm@gnu.org> | ||
| 65 | |||
| 66 | * doc-view.el: Require cl-lib at runtime too. | ||
| 67 | (doc-view-remove-if): Remove. | ||
| 68 | (doc-view-search-next-match, doc-view-search-previous-match): | ||
| 69 | Use cl-remove-if. | ||
| 70 | |||
| 71 | * edmacro.el: Require cl-lib at runtime too. | ||
| 72 | (edmacro-format-keys, edmacro-parse-keys): Use cl-mismatch, cl-subseq. | ||
| 73 | (edmacro-mismatch, edmacro-subseq): Remove. | ||
| 74 | |||
| 75 | * shadowfile.el: Require cl-lib. | ||
| 76 | (shadow-remove-if): Remove. | ||
| 77 | (shadow-set-cluster, shadow-shadows-of-1, shadow-remove-from-todo): | ||
| 78 | Use cl-remove-if. | ||
| 79 | |||
| 80 | * wid-edit.el: Require cl-lib. | ||
| 81 | (widget-choose): Use cl-remove-if. | ||
| 82 | (widget-remove-if): Remove. | ||
| 83 | |||
| 84 | * progmodes/ebrowse.el: Require cl-lib at runtime too. | ||
| 85 | (ebrowse-delete-if-not): Remove. | ||
| 86 | (ebrowse-browser-buffer-list, ebrowse-member-buffer-list) | ||
| 87 | (ebrowse-tree-buffer-list, ebrowse-same-tree-member-buffer-list): | ||
| 88 | Use cl-delete-if-not. | ||
| 89 | |||
| 90 | 2013-07-12 Juanma Barranquero <lekktu@gmail.com> | ||
| 91 | |||
| 92 | * emacs-lisp/cl-macs.el (cl-multiple-value-bind, cl-multiple-value-setq) | ||
| 93 | (cl-the, cl-declare, cl-defstruct): Fix typos in docstrings. | ||
| 94 | |||
| 95 | 2013-07-12 Leo Liu <sdl.web@gmail.com> | ||
| 96 | |||
| 97 | * ido.el (dired-do-copy, dired): Set 'ido property. (Bug#11954) | ||
| 98 | |||
| 99 | 2013-07-11 Glenn Morris <rgm@gnu.org> | ||
| 100 | |||
| 101 | * emacs-lisp/edebug.el: Require cl-lib at run-time too. | ||
| 102 | (edebug-gensym-index, edebug-gensym): | ||
| 103 | Remove reimplementation of cl-gensym. | ||
| 104 | (edebug-make-enter-wrapper, edebug-make-form-wrapper): Use cl-gensym. | ||
| 105 | |||
| 106 | * thumbs.el: Require cl-lib at run-time too. | ||
| 107 | (thumbs-gensym-counter, thumbs-gensym): | ||
| 108 | Remove reimplementation of cl-gensym. | ||
| 109 | (thumbs-temp-file): Use cl-gensym. | ||
| 110 | |||
| 111 | * emacs-lisp/ert.el: Require cl-lib at runtime too. | ||
| 112 | (ert--cl-do-remf, ert--remprop, ert--remove-if-not) | ||
| 113 | (ert--intersection, ert--set-difference, ert--set-difference-eq) | ||
| 114 | (ert--union, ert--gensym-counter, ert--gensym-counter) | ||
| 115 | (ert--coerce-to-vector, ert--remove*, ert--string-position) | ||
| 116 | (ert--mismatch, ert--subseq): Remove reimplementations of cl funcs. | ||
| 117 | (ert-make-test-unbound, ert--expand-should-1) | ||
| 118 | (ert--expand-should, ert--should-error-handle-error) | ||
| 119 | (should-error, ert--explain-equal-rec) | ||
| 120 | (ert--plist-difference-explanation, ert-select-tests) | ||
| 121 | (ert--make-stats, ert--remove-from-list, ert--string-first-line): | ||
| 122 | Use cl-lib functions rather than reimplementations. | ||
| 123 | |||
| 124 | 2013-07-11 Michael Albinus <michael.albinus@gmx.de> | ||
| 125 | |||
| 126 | * net/tramp.el (tramp-methods): Extend docstring. | ||
| 127 | (tramp-connection-timeout): New defcustom. | ||
| 128 | (tramp-error-with-buffer): Reset timestamp only when appropriate. | ||
| 129 | (with-tramp-progress-reporter): Simplify. | ||
| 130 | (tramp-process-actions): Improve messages. | ||
| 131 | |||
| 132 | * net/tramp-gvfs.el (tramp-gvfs-maybe-open-connection): | ||
| 133 | * net/tramp-sh.el (tramp-maybe-open-connection): | ||
| 134 | Use `tramp-connection-timeout'. | ||
| 135 | (tramp-methods) [su, sudo, ksu]: Add method specific timeouts. | ||
| 136 | (Bug#14808) | ||
| 137 | |||
| 138 | 2013-07-11 Leo Liu <sdl.web@gmail.com> | ||
| 139 | |||
| 140 | * ido.el (ido-read-file-name): Conform to the requirements of | ||
| 141 | read-file-name. (Bug#11861) | ||
| 142 | (ido-read-directory-name): Conform to the requirements of | ||
| 143 | read-directory-name. | ||
| 144 | |||
| 145 | 2013-07-11 Juanma Barranquero <lekktu@gmail.com> | ||
| 146 | |||
| 147 | * subr.el (delay-warning): New function. | ||
| 148 | |||
| 149 | 2013-07-10 Eli Zaretskii <eliz@gnu.org> | ||
| 150 | |||
| 151 | * simple.el (default-line-height): New function. | ||
| 152 | (line-move-partial, line-move): Use it instead of computing the | ||
| 153 | line height inline. | ||
| 154 | (line-move-partial): Always compute ROWH. If the last line is | ||
| 155 | partially-visible, but its text is completely visible, allow | ||
| 156 | cursor to enter such a partially-visible line. | ||
| 157 | |||
| 158 | 2013-07-10 Michael Albinus <michael.albinus@gmx.de> | ||
| 159 | |||
| 160 | Improve error messages. (Bug#14808) | ||
| 161 | |||
| 162 | * net/tramp.el (tramp-current-connection): New defvar, moved from | ||
| 163 | tramp-sh.el. | ||
| 164 | (tramp-message-show-progress-reporter-message): Removed, not | ||
| 165 | needed anymore. | ||
| 166 | (tramp-error-with-buffer): Show message in minibuffer. Discard | ||
| 167 | input before waiting. Reset connection timestamp. | ||
| 168 | (with-tramp-progress-reporter): Improve messages. | ||
| 169 | (tramp-process-actions): Use progress reporter. Delete process in | ||
| 170 | case of error. Improve messages. | ||
| 171 | |||
| 172 | * net/tramp-sh.el (tramp-barf-if-no-shell-prompt): Use | ||
| 173 | condition-case. Call `tramp-error-with-buffer' with vector and buffer. | ||
| 174 | (tramp-current-connection): Removed. | ||
| 175 | (tramp-maybe-open-connection): The car of | ||
| 176 | `tramp-current-connection' are the first 3 slots of the vector. | ||
| 177 | |||
| 178 | 2013-07-10 Teodor Zlatanov <tzz@lifelogs.com> | ||
| 179 | |||
| 180 | * progmodes/cfengine.el (cfengine3-indent-line): Do not indent | ||
| 181 | inside continued strings. | ||
| 182 | |||
| 183 | 2013-07-10 Paul Eggert <eggert@cs.ucla.edu> | ||
| 184 | |||
| 185 | Timestamp fixes for undo (Bug#14824). | ||
| 186 | * files.el (clear-visited-file-modtime): Move here from fileio.c. | ||
| 187 | |||
| 188 | 2013-07-10 Leo Liu <sdl.web@gmail.com> | ||
| 189 | |||
| 190 | * files.el (require-final-newline): Allow safe local value. | ||
| 191 | (Bug#14834) | ||
| 192 | |||
| 193 | 2013-07-09 Leo Liu <sdl.web@gmail.com> | ||
| 194 | |||
| 195 | * ido.el (ido-read-directory-name): Handle fallback. | ||
| 196 | (ido-read-file-name): Update DIR to ido-current-directory. | ||
| 197 | (Bug#1516) | ||
| 198 | (ido-add-virtual-buffers-to-list): Robustify. (Bug#14552) | ||
| 199 | |||
| 200 | 2013-07-09 Dmitry Gutov <dgutov@yandex.ru> | ||
| 201 | |||
| 202 | * progmodes/ruby-mode.el (ruby-font-lock-keywords): Remove extra | ||
| 203 | "autoload". Remove "warn lower camel case" section, previously | ||
| 204 | commented out. Highlight negation char. Do not highlight the | ||
| 205 | target in singleton method definitions. | ||
| 206 | |||
| 207 | 2013-07-08 Stefan Monnier <monnier@iro.umontreal.ca> | ||
| 208 | |||
| 209 | * faces.el (tty-setup-hook): Declare the hook. | ||
| 210 | |||
| 211 | * emacs-lisp/pcase.el (pcase--split-pred): Add `vars' argument to try | ||
| 212 | and detect when a guard/pred depends on local vars (bug#14773). | ||
| 213 | (pcase--u1): Adjust caller. | ||
| 214 | |||
| 215 | 2013-07-08 Eli Zaretskii <eliz@gnu.org> | ||
| 216 | |||
| 217 | * simple.el (line-move-partial, line-move): Account for | ||
| 218 | line-spacing. | ||
| 219 | (line-move-partial): Avoid setting vscroll when the last | ||
| 220 | partially-visible line in window is of default height. | ||
| 221 | |||
| 222 | 2013-07-08 Lars Magne Ingebrigtsen <larsi@gnus.org> | ||
| 223 | |||
| 224 | * net/shr.el (shr-map): Reinstate the `u' key binding, since it's | ||
| 225 | been used a while. | ||
| 226 | |||
| 227 | 2013-07-07 Juanma Barranquero <lekktu@gmail.com> | ||
| 228 | |||
| 229 | * subr.el (read-quoted-char): Remove unused local variable `char'. | ||
| 230 | |||
| 231 | 2013-07-07 Michael Kifer <kifer@cs.stonybrook.edu> | ||
| 232 | |||
| 233 | * ediff.el (ediff-version): Version update. | ||
| 234 | (ediff-files-command, ediff3-files-command, ediff-merge-command) | ||
| 235 | (ediff-merge-with-ancestor-command, ediff-directories-command) | ||
| 236 | (ediff-directories3-command, ediff-merge-directories-command) | ||
| 237 | (ediff-merge-directories-with-ancestor-command): New functions. | ||
| 238 | All are command-line interfaces to ediff: to facilitate calling | ||
| 239 | Emacs with the appropriate ediff functions invoked. | ||
| 240 | |||
| 241 | * viper-cmd.el (viper-del-forward-char-in-insert): New function. | ||
| 242 | (viper-save-kill-buffer): Check if buffer is modified. | ||
| 243 | |||
| 244 | * viper.el (viper-version): Version update. | ||
| 245 | (viper-emacs-state-mode-list): Add egg-status-buffer-mode. | ||
| 246 | |||
| 247 | 2013-07-07 Stefan Monnier <monnier@iro.umontreal.ca> | ||
| 248 | |||
| 249 | * faces.el (tty-run-terminal-initialization): Run new tty-setup-hook. | ||
| 250 | * viper-cmd.el (viper-envelop-ESC-key): Remove function. | ||
| 251 | (viper-intercept-ESC-key): Simplify. | ||
| 252 | * viper-keym.el (viper-ESC-key): Make it a constant, don't use kbd. | ||
| 253 | * viper.el (viper--tty-ESC-filter, viper--lookup-key) | ||
| 254 | (viper-catch-tty-ESC, viper-uncatch-tty-ESC) | ||
| 255 | (viper-setup-ESC-to-escape): New functions. | ||
| 256 | (viper-go-away, viper-set-hooks): Call viper-setup-ESC-to-escape. | ||
| 257 | (viper-set-hooks): Do not modify flyspell-mode-hook. (Bug#13793) | ||
| 258 | |||
| 259 | 2013-07-07 Eli Zaretskii <eliz@gnu.org> | ||
| 260 | |||
| 261 | * simple.el (default-font-height, window-screen-lines): | ||
| 262 | New functions. | ||
| 263 | (line-move, line-move-partial): Use them instead of | ||
| 264 | frame-char-height and window-text-height. This makes scrolling | ||
| 265 | text smoother when the buffer's default face uses a font that is | ||
| 266 | different from the frame's default font. | ||
| 267 | |||
| 268 | 2013-07-06 Jan Djärv <jan.h.d@swipnet.se> | ||
| 269 | |||
| 270 | * files.el (write-file): Do not display confirm dialog for NS, | ||
| 271 | it does its own dialog, which can't be cancelled (Bug#14578). | ||
| 272 | |||
| 273 | 2013-07-06 Eli Zaretskii <eliz@gnu.org> | ||
| 274 | |||
| 275 | * simple.el (line-move-partial): Adjust the row returned by | ||
| 276 | posn-at-point for the current window-vscroll. (Bug#14567) | ||
| 277 | |||
| 278 | 2013-07-06 Michael Albinus <michael.albinus@gmx.de> | ||
| 279 | |||
| 280 | * net/tramp-sh.el (tramp-sh-file-gvfs-monitor-dir-process-filter): | ||
| 281 | (tramp-sh-file-inotifywait-process-filter): Handle file names with | ||
| 282 | spaces. | ||
| 283 | |||
| 284 | 2013-07-06 Martin Rudalics <rudalics@gmx.at> | ||
| 285 | |||
| 286 | * window.el (window-state-put-stale-windows): New variable. | ||
| 287 | (window--state-put-2): Save list of windows without matching buffer. | ||
| 288 | (window-state-put): Remove "bufferless" windows if possible. | ||
| 289 | |||
| 290 | 2013-07-06 Juanma Barranquero <lekktu@gmail.com> | ||
| 291 | |||
| 292 | * simple.el (alternatives-define): Remove leftover :group keyword. | ||
| 293 | Tweak docstring. | ||
| 294 | |||
| 295 | 2013-07-06 Leo Liu <sdl.web@gmail.com> | ||
| 296 | |||
| 297 | * ido.el (ido-use-virtual-buffers): Allow new value 'auto. | ||
| 298 | (ido-enable-virtual-buffers): New variable. | ||
| 299 | (ido-buffer-internal, ido-toggle-virtual-buffers) | ||
| 300 | (ido-make-buffer-list): Use it. | ||
| 301 | (ido-exhibit): Support turning on and off virtual buffers | ||
| 302 | automatically. | ||
| 303 | |||
| 304 | 2013-07-06 Juanma Barranquero <lekktu@gmail.com> | ||
| 305 | |||
| 306 | * simple.el (alternatives-define): New macro. | ||
| 307 | |||
| 308 | 2013-07-06 Stefan Monnier <monnier@iro.umontreal.ca> | ||
| 309 | |||
| 310 | * subr.el (read-quoted-char): Use read-key. | ||
| 311 | (sit-for): Let read-event decode tty input (bug#14782). | ||
| 312 | |||
| 313 | 2013-07-05 Stephen Berman <stephen.berman@gmx.net> | ||
| 314 | |||
| 315 | * calendar/todo-mode.el: Add handling of file deletion, both by | ||
| 316 | mode command and externally. Fix various related bugs. | ||
| 317 | Clarify Commentary and improve some documentation strings and code. | ||
| 318 | (todo-delete-file): New command. | ||
| 319 | (todo-check-file): New function. | ||
| 320 | (todo-show): Handle external deletion of the file we're trying to | ||
| 321 | show (bug#14688). Replace called-interactively-p by an optional | ||
| 322 | prefix argument to avoid problematic interaction with catch form | ||
| 323 | when byte compiled (bug#14702). | ||
| 324 | (todo-quit): Handle external deletion of the archive's todo file. | ||
| 325 | Make sure the buffer that was visiting the archive file is still | ||
| 326 | live before trying to bury it. | ||
| 327 | (todo-category-completions): Handle external deletion of any | ||
| 328 | category completion files. | ||
| 329 | (todo-jump-to-category, todo-basic-insert-item): Recalculate list | ||
| 330 | of todo files, in case of external deletion. | ||
| 331 | (todo-add-file): Replace unnecessary setq by let-binding. | ||
| 332 | (todo-find-archive): Check whether there are any archives. | ||
| 333 | Replace unnecessary setq by let-binding. | ||
| 334 | (todo-archive-done-item): Use find-file-noselect to get the | ||
| 335 | archive buffer whether or not the archive already exists. | ||
| 336 | Remove superfluous code. Use file size instead of buffer-file-name to | ||
| 337 | check if the archive is new; if it is, update list of archives. | ||
| 338 | (todo-default-todo-file): Allow nil to be a valid value for when | ||
| 339 | there are no todo files. | ||
| 340 | (todo-reevaluate-default-file-defcustom): Use corrected definition | ||
| 341 | of todo-default-todo-file. | ||
| 342 | (todo-key-bindings-t+a+f): Add key binding for todo-delete-file. | ||
| 343 | (todo-delete-category, todo-show-categories-table) | ||
| 344 | (todo-category-number): Clarify comment. | ||
| 345 | (todo-filter-items): Clarify documentation string. | ||
| 346 | (todo-show-current-file, todo-display-as-todo-file) | ||
| 347 | (todo-reset-and-enable-done-separator): Tweak documentation string. | ||
| 348 | (todo-done-separator): Make separator length window-width, since | ||
| 349 | bug#2749 is now fixed. | ||
| 350 | |||
| 351 | 2013-07-05 Michael Albinus <michael.albinus@gmx.de> | ||
| 352 | |||
| 353 | * net/tramp-sh.el (tramp-sh-handle-file-notify-add-watch): | ||
| 354 | Support both "gvfs-monitor-dir" and "inotifywait". | ||
| 355 | (tramp-sh-file-inotifywait-process-filter): Rename from | ||
| 356 | `tramp-sh-file-notify-process-filter'. | ||
| 357 | (tramp-sh-file-gvfs-monitor-dir-process-filter) | ||
| 358 | (tramp-get-remote-gvfs-monitor-dir): New defuns. | ||
| 359 | |||
| 360 | 2013-07-05 Leo Liu <sdl.web@gmail.com> | ||
| 361 | |||
| 362 | * autoinsert.el (auto-insert-alist): Default to lexical-binding. | ||
| 363 | |||
| 364 | 2013-07-04 YAMAMOTO Mitsuharu <mituharu@math.s.chiba-u.ac.jp> | ||
| 365 | |||
| 366 | * frame.el (display-pixel-height, display-pixel-width) | ||
| 367 | (display-mm-height, display-mm-width): Mention behavior on | ||
| 368 | multi-monitor setups in docstrings. | ||
| 369 | (w32-display-monitor-attributes-list): Declare function. | ||
| 370 | (display-monitor-attributes-list): Use it. | ||
| 371 | |||
| 372 | 2013-07-04 Michael Albinus <michael.albinus@gmx.de> | ||
| 373 | |||
| 374 | * filenotify.el: New package. | ||
| 375 | |||
| 376 | * autorevert.el (top): Require filenotify.el. | ||
| 377 | (auto-revert-notify-enabled): Remove. Use `file-notify-support' | ||
| 378 | instead. | ||
| 379 | (auto-revert-notify-rm-watch, auto-revert-notify-add-watch) | ||
| 380 | (auto-revert-notify-handler): Use `file-notify-*' functions. | ||
| 381 | |||
| 382 | * subr.el (file-notify-handle-event): Move function to filenotify.el. | ||
| 383 | |||
| 384 | * net/tramp.el (tramp-file-name-for-operation): | ||
| 385 | Handle `file-notify-add-watch' and `file-notify-rm-watch'. | ||
| 386 | |||
| 387 | * net/tramp-sh.el (tramp-sh-file-name-handler-alist): Add handler | ||
| 388 | for `file-notify-add-watch' and `file-notify-rm-watch'. | ||
| 389 | (tramp-process-sentinel): Improve trace. | ||
| 390 | (tramp-sh-handle-file-notify-add-watch) | ||
| 391 | (tramp-sh-file-notify-process-filter) | ||
| 392 | (tramp-sh-handle-file-notify-rm-watch) | ||
| 393 | (tramp-get-remote-inotifywait): New defuns. | ||
| 394 | |||
| 395 | 2013-07-03 Juri Linkov <juri@jurta.org> | ||
| 396 | |||
| 397 | * buff-menu.el (Buffer-menu-multi-occur): Add args and move the | ||
| 398 | call of `occur-read-primary-args' to interactive spec. | ||
| 399 | |||
| 400 | * ibuffer.el (ibuffer-mode-map): Bind "M-s a C-o" to | ||
| 401 | `ibuffer-do-occur' like in buff-menu.el. (Bug#14673) | ||
| 402 | |||
| 403 | 2013-07-03 Matthias Meulien <orontee@gmail.com> | ||
| 404 | |||
| 405 | * buff-menu.el (Buffer-menu-mode-map): Bind "M-s a C-o" to | ||
| 406 | `Buffer-menu-multi-occur'. Add it to the menu. | ||
| 407 | (Buffer-menu-mode): Document it in docstring. | ||
| 408 | (Buffer-menu-multi-occur): New command. (Bug#14673) | ||
| 409 | |||
| 410 | 2013-07-03 Dmitry Gutov <dgutov@yandex.ru> | ||
| 411 | |||
| 412 | * progmodes/ruby-mode.el (ruby-font-lock-keywords): Highlight more | ||
| 413 | keywords and built-ins. | ||
| 414 | |||
| 415 | 2013-07-03 Glenn Morris <rgm@gnu.org> | ||
| 416 | |||
| 417 | * subr.el (y-or-n-p): Handle empty prompts. (Bug#14770) | ||
| 418 | |||
| 419 | Make info-xref checks case-sensitive by default | ||
| 420 | * info.el (Info-find-node, Info-find-in-tag-table) | ||
| 421 | (Info-find-node-in-buffer, Info-find-node-2, Info-goto-node): | ||
| 422 | Add option for exact case matching of nodes. | ||
| 423 | * info-xref.el (info-xref): New custom group. | ||
| 424 | (info-xref-case-fold): New option. | ||
| 425 | (info-xref-goto-node-p): Pass info-xref-case-fold to Info-goto-node. | ||
| 426 | |||
| 427 | 2013-07-03 Leo Liu <sdl.web@gmail.com> | ||
| 428 | |||
| 429 | * ido.el (ido-delete-file-at-head): Respect delete-by-moving-to-trash. | ||
| 430 | |||
| 431 | 2013-07-03 Dmitry Gutov <dgutov@yandex.ru> | ||
| 432 | |||
| 433 | * progmodes/ruby-mode.el (ruby-move-to-block): When we're at a | ||
| 434 | middle of block statement initially, lower the depth. Remove | ||
| 435 | FIXME comment, not longer valid. Remove middle of block statement | ||
| 436 | detection, no need to do that anymore since we've been using | ||
| 437 | `ruby-parse-region' here. | ||
| 438 | |||
| 1 | 2013-07-02 Jan Djärv <jan.h.d@swipnet.se> | 439 | 2013-07-02 Jan Djärv <jan.h.d@swipnet.se> |
| 2 | 440 | ||
| 3 | * term/ns-win.el (display-format-alist): Use .* (Bug#14765). | 441 | * term/ns-win.el (display-format-alist): Use .* (Bug#14765). |
| @@ -255,12 +693,12 @@ | |||
| 255 | 693 | ||
| 256 | 2013-06-25 Rüdiger Sonderfeld <ruediger@c-plusplus.de> | 694 | 2013-06-25 Rüdiger Sonderfeld <ruediger@c-plusplus.de> |
| 257 | 695 | ||
| 258 | * lisp/textmodes/bibtex.el (bibtex-generate-url-list): Add support | 696 | * textmodes/bibtex.el (bibtex-generate-url-list): Add support |
| 259 | for DOI URLs. | 697 | for DOI URLs. |
| 260 | 698 | ||
| 261 | 2013-06-25 Rüdiger Sonderfeld <ruediger@c-plusplus.de> | 699 | 2013-06-25 Rüdiger Sonderfeld <ruediger@c-plusplus.de> |
| 262 | 700 | ||
| 263 | * lisp/textmodes/bibtex.el (bibtex-mode, bibtex-set-dialect): | 701 | * textmodes/bibtex.el (bibtex-mode, bibtex-set-dialect): |
| 264 | Update imenu-support when dialect changes. | 702 | Update imenu-support when dialect changes. |
| 265 | 703 | ||
| 266 | 2013-06-25 Leo Liu <sdl.web@gmail.com> | 704 | 2013-06-25 Leo Liu <sdl.web@gmail.com> |
| @@ -361,7 +799,7 @@ | |||
| 361 | * emacs-lock.el (emacs-lock-mode, emacs-lock--old-mode) | 799 | * emacs-lock.el (emacs-lock-mode, emacs-lock--old-mode) |
| 362 | (emacs-lock--try-unlocking): Make defvar-local. | 800 | (emacs-lock--try-unlocking): Make defvar-local. |
| 363 | 801 | ||
| 364 | 2013-06-22 Glenn Morris <rgm@fencepost.gnu.org> | 802 | 2013-06-22 Glenn Morris <rgm@gnu.org> |
| 365 | 803 | ||
| 366 | * play/cookie1.el (cookie-apropos): Minor simplification. | 804 | * play/cookie1.el (cookie-apropos): Minor simplification. |
| 367 | 805 | ||
| @@ -827,7 +1265,7 @@ | |||
| 827 | 1265 | ||
| 828 | * net/shr.el (shr-map): Bind [down-mouse-1] to browse URLs. | 1266 | * net/shr.el (shr-map): Bind [down-mouse-1] to browse URLs. |
| 829 | 1267 | ||
| 830 | 2013-06-19 Glenn Morris <rgm@fencepost.gnu.org> | 1268 | 2013-06-19 Glenn Morris <rgm@gnu.org> |
| 831 | 1269 | ||
| 832 | * emacs-lisp/eieio.el (defclass): Make it eval-and-compile once more. | 1270 | * emacs-lisp/eieio.el (defclass): Make it eval-and-compile once more. |
| 833 | 1271 | ||
| @@ -970,6 +1408,7 @@ | |||
| 970 | 2013-06-18 Matthias Meulien <orontee@gmail.com> | 1408 | 2013-06-18 Matthias Meulien <orontee@gmail.com> |
| 971 | 1409 | ||
| 972 | * tabify.el (untabify, tabify): With prefix, apply to entire buffer. | 1410 | * tabify.el (untabify, tabify): With prefix, apply to entire buffer. |
| 1411 | <http://lists.gnu.org/archive/html/emacs-devel/2013-03/msg00545.html> | ||
| 973 | 1412 | ||
| 974 | 2013-06-18 Glenn Morris <rgm@gnu.org> | 1413 | 2013-06-18 Glenn Morris <rgm@gnu.org> |
| 975 | 1414 | ||
diff --git a/lisp/autoinsert.el b/lisp/autoinsert.el index c45d64e1cd9..daa654889b6 100644 --- a/lisp/autoinsert.el +++ b/lisp/autoinsert.el | |||
| @@ -164,7 +164,10 @@ If this contains a %s, that will be replaced by the matching rule." | |||
| 164 | 164 | ||
| 165 | (("\\.el\\'" . "Emacs Lisp header") | 165 | (("\\.el\\'" . "Emacs Lisp header") |
| 166 | "Short description: " | 166 | "Short description: " |
| 167 | ";;; " (file-name-nondirectory (buffer-file-name)) " --- " str " | 167 | ";;; " (file-name-nondirectory (buffer-file-name)) " --- " str |
| 168 | (make-string (max 2 (- 80 (current-column) 27)) ?\s) | ||
| 169 | "-*- lexical-binding: t; -*-" | ||
| 170 | " | ||
| 168 | 171 | ||
| 169 | ;; Copyright (C) " (format-time-string "%Y") " " | 172 | ;; Copyright (C) " (format-time-string "%Y") " " |
| 170 | (getenv "ORGANIZATION") | (progn user-full-name) " | 173 | (getenv "ORGANIZATION") | (progn user-full-name) " |
diff --git a/lisp/autorevert.el b/lisp/autorevert.el index 4a6d4cb4cc0..00e88fc4a3d 100644 --- a/lisp/autorevert.el +++ b/lisp/autorevert.el | |||
| @@ -103,6 +103,7 @@ | |||
| 103 | 103 | ||
| 104 | (eval-when-compile (require 'cl-lib)) | 104 | (eval-when-compile (require 'cl-lib)) |
| 105 | (require 'timer) | 105 | (require 'timer) |
| 106 | (require 'filenotify) | ||
| 106 | 107 | ||
| 107 | ;; Custom Group: | 108 | ;; Custom Group: |
| 108 | ;; | 109 | ;; |
| @@ -270,21 +271,17 @@ This variable becomes buffer local when set in any fashion.") | |||
| 270 | :type 'boolean | 271 | :type 'boolean |
| 271 | :version "24.4") | 272 | :version "24.4") |
| 272 | 273 | ||
| 273 | (defconst auto-revert-notify-enabled | 274 | (defcustom auto-revert-use-notify (and file-notify-support t) |
| 274 | (or (featurep 'gfilenotify) (featurep 'inotify) (featurep 'w32notify)) | ||
| 275 | "Non-nil when Emacs has been compiled with file notification support.") | ||
| 276 | |||
| 277 | (defcustom auto-revert-use-notify auto-revert-notify-enabled | ||
| 278 | "If non-nil Auto Revert Mode uses file notification functions. | 275 | "If non-nil Auto Revert Mode uses file notification functions. |
| 279 | This requires Emacs being compiled with file notification | 276 | This requires Emacs being compiled with file notification |
| 280 | support (see `auto-revert-notify-enabled'). You should set this | 277 | support (see `file-notify-support'). You should set this variable |
| 281 | variable through Custom." | 278 | through Custom." |
| 282 | :group 'auto-revert | 279 | :group 'auto-revert |
| 283 | :type 'boolean | 280 | :type 'boolean |
| 284 | :set (lambda (variable value) | 281 | :set (lambda (variable value) |
| 285 | (set-default variable (and auto-revert-notify-enabled value)) | 282 | (set-default variable (and file-notify-support value)) |
| 286 | (unless (symbol-value variable) | 283 | (unless (symbol-value variable) |
| 287 | (when auto-revert-notify-enabled | 284 | (when file-notify-support |
| 288 | (dolist (buf (buffer-list)) | 285 | (dolist (buf (buffer-list)) |
| 289 | (with-current-buffer buf | 286 | (with-current-buffer buf |
| 290 | (when (symbol-value 'auto-revert-notify-watch-descriptor) | 287 | (when (symbol-value 'auto-revert-notify-watch-descriptor) |
| @@ -502,12 +499,7 @@ will use an up-to-date value of `auto-revert-interval'" | |||
| 502 | (puthash key value auto-revert-notify-watch-descriptor-hash-list) | 499 | (puthash key value auto-revert-notify-watch-descriptor-hash-list) |
| 503 | (remhash key auto-revert-notify-watch-descriptor-hash-list) | 500 | (remhash key auto-revert-notify-watch-descriptor-hash-list) |
| 504 | (ignore-errors | 501 | (ignore-errors |
| 505 | (funcall | 502 | (file-notify-rm-watch auto-revert-notify-watch-descriptor))))) |
| 506 | (cond | ||
| 507 | ((fboundp 'gfile-rm-watch) 'gfile-rm-watch) | ||
| 508 | ((fboundp 'inotify-rm-watch) 'inotify-rm-watch) | ||
| 509 | ((fboundp 'w32notify-rm-watch) 'w32notify-rm-watch)) | ||
| 510 | auto-revert-notify-watch-descriptor))))) | ||
| 511 | auto-revert-notify-watch-descriptor-hash-list) | 503 | auto-revert-notify-watch-descriptor-hash-list) |
| 512 | (remove-hook 'kill-buffer-hook 'auto-revert-notify-rm-watch)) | 504 | (remove-hook 'kill-buffer-hook 'auto-revert-notify-rm-watch)) |
| 513 | (setq auto-revert-notify-watch-descriptor nil | 505 | (setq auto-revert-notify-watch-descriptor nil |
| @@ -522,100 +514,58 @@ will use an up-to-date value of `auto-revert-interval'" | |||
| 522 | 514 | ||
| 523 | (when (and buffer-file-name auto-revert-use-notify | 515 | (when (and buffer-file-name auto-revert-use-notify |
| 524 | (not auto-revert-notify-watch-descriptor)) | 516 | (not auto-revert-notify-watch-descriptor)) |
| 525 | (let ((func | 517 | (setq auto-revert-notify-watch-descriptor |
| 526 | (cond | 518 | (ignore-errors |
| 527 | ((fboundp 'gfile-add-watch) 'gfile-add-watch) | 519 | (file-notify-add-watch |
| 528 | ((fboundp 'inotify-add-watch) 'inotify-add-watch) | 520 | (expand-file-name buffer-file-name default-directory) |
| 529 | ((fboundp 'w32notify-add-watch) 'w32notify-add-watch))) | 521 | '(change attribute-change) 'auto-revert-notify-handler))) |
| 530 | (aspect | 522 | (if auto-revert-notify-watch-descriptor |
| 531 | (cond | 523 | (progn |
| 532 | ((fboundp 'gfile-add-watch) '(watch-mounts)) | 524 | (puthash |
| 533 | ;; `attrib' is needed for file modification time. | 525 | auto-revert-notify-watch-descriptor |
| 534 | ((fboundp 'inotify-add-watch) '(attrib create modify moved-to)) | 526 | (cons (current-buffer) |
| 535 | ((fboundp 'w32notify-add-watch) '(size last-write-time)))) | 527 | (gethash auto-revert-notify-watch-descriptor |
| 536 | (file (if (or (fboundp 'gfile-add-watch) (fboundp 'inotify-add-watch)) | 528 | auto-revert-notify-watch-descriptor-hash-list)) |
| 537 | (directory-file-name (expand-file-name default-directory)) | 529 | auto-revert-notify-watch-descriptor-hash-list) |
| 538 | (buffer-file-name)))) | 530 | (add-hook (make-local-variable 'kill-buffer-hook) |
| 539 | (setq auto-revert-notify-watch-descriptor | 531 | 'auto-revert-notify-rm-watch)) |
| 540 | (ignore-errors | 532 | ;; Fallback to file checks. |
| 541 | (funcall func file aspect 'auto-revert-notify-handler))) | 533 | (set (make-local-variable 'auto-revert-use-notify) nil)))) |
| 542 | (if auto-revert-notify-watch-descriptor | ||
| 543 | (progn | ||
| 544 | (puthash | ||
| 545 | auto-revert-notify-watch-descriptor | ||
| 546 | (cons (current-buffer) | ||
| 547 | (gethash auto-revert-notify-watch-descriptor | ||
| 548 | auto-revert-notify-watch-descriptor-hash-list)) | ||
| 549 | auto-revert-notify-watch-descriptor-hash-list) | ||
| 550 | (add-hook (make-local-variable 'kill-buffer-hook) | ||
| 551 | 'auto-revert-notify-rm-watch)) | ||
| 552 | ;; Fallback to file checks. | ||
| 553 | (set (make-local-variable 'auto-revert-use-notify) nil))))) | ||
| 554 | |||
| 555 | (defun auto-revert-notify-event-p (event) | ||
| 556 | "Check that event is a file notification event." | ||
| 557 | (and (listp event) | ||
| 558 | (cond ((featurep 'gfilenotify) | ||
| 559 | (and (>= (length event) 3) (stringp (nth 2 event)))) | ||
| 560 | ((featurep 'inotify) | ||
| 561 | (= (length event) 4)) | ||
| 562 | ((featurep 'w32notify) | ||
| 563 | (and (= (length event) 3) (stringp (nth 2 event))))))) | ||
| 564 | |||
| 565 | (defun auto-revert-notify-event-descriptor (event) | ||
| 566 | "Return watch descriptor of file notification event, or nil." | ||
| 567 | (and (auto-revert-notify-event-p event) (car event))) | ||
| 568 | |||
| 569 | (defun auto-revert-notify-event-action (event) | ||
| 570 | "Return action of file notification event, or nil." | ||
| 571 | (and (auto-revert-notify-event-p event) (nth 1 event))) | ||
| 572 | |||
| 573 | (defun auto-revert-notify-event-file-name (event) | ||
| 574 | "Return file name of file notification event, or nil." | ||
| 575 | (and (auto-revert-notify-event-p event) | ||
| 576 | (cond ((featurep 'gfilenotify) (nth 2 event)) | ||
| 577 | ((featurep 'inotify) (nth 3 event)) | ||
| 578 | ((featurep 'w32notify) (nth 2 event))))) | ||
| 579 | 534 | ||
| 580 | (defun auto-revert-notify-handler (event) | 535 | (defun auto-revert-notify-handler (event) |
| 581 | "Handle an EVENT returned from file notification." | 536 | "Handle an EVENT returned from file notification." |
| 582 | (when (auto-revert-notify-event-p event) | 537 | (ignore-errors |
| 583 | (let* ((descriptor (auto-revert-notify-event-descriptor event)) | 538 | (let* ((descriptor (car event)) |
| 584 | (action (auto-revert-notify-event-action event)) | 539 | (action (nth 1 event)) |
| 585 | (file (auto-revert-notify-event-file-name event)) | 540 | (file (nth 2 event)) |
| 541 | (file1 (nth 3 event)) ;; Target of `renamed'. | ||
| 586 | (buffers (gethash descriptor | 542 | (buffers (gethash descriptor |
| 587 | auto-revert-notify-watch-descriptor-hash-list))) | 543 | auto-revert-notify-watch-descriptor-hash-list))) |
| 588 | (ignore-errors | 544 | ;; Check, that event is meant for us. |
| 589 | ;; Check, that event is meant for us. | 545 | (cl-assert descriptor) |
| 590 | ;; TODO: Filter events which stop watching, like `move' or `removed'. | 546 | ;; We do not handle `deleted', because nothing has to be refreshed. |
| 591 | (cl-assert descriptor) | 547 | (cl-assert (memq action '(attribute-changed changed created renamed)) t) |
| 592 | (cond | 548 | ;; Since we watch a directory, a file name must be returned. |
| 593 | ((featurep 'gfilenotify) | 549 | (cl-assert (stringp file)) |
| 594 | (cl-assert (memq action '(attribute-changed changed created deleted | 550 | (when (eq action 'renamed) (cl-assert (stringp file1))) |
| 595 | ;; FIXME: I keep getting this action, so I | 551 | ;; Loop over all buffers, in order to find the intended one. |
| 596 | ;; added it here, but I have no idea what | 552 | (dolist (buffer buffers) |
| 597 | ;; I'm doing. --Stef | 553 | (when (buffer-live-p buffer) |
| 598 | changes-done-hint)) | 554 | (with-current-buffer buffer |
| 599 | t)) | 555 | (when (and (stringp buffer-file-name) |
| 600 | ((featurep 'inotify) | 556 | (or |
| 601 | (cl-assert (or (memq 'attrib action) | 557 | (and (memq action '(attribute-changed changed created)) |
| 602 | (memq 'create action) | 558 | (string-equal |
| 603 | (memq 'modify action) | 559 | (file-name-nondirectory file) |
| 604 | (memq 'moved-to action)))) | 560 | (file-name-nondirectory buffer-file-name))) |
| 605 | ((featurep 'w32notify) (cl-assert (eq 'modified action)))) | 561 | (and (eq action 'renamed) |
| 606 | ;; Since we watch a directory, a file name must be returned. | 562 | (string-equal |
| 607 | (cl-assert (stringp file)) | 563 | (file-name-nondirectory file1) |
| 608 | (dolist (buffer buffers) | 564 | (file-name-nondirectory buffer-file-name))))) |
| 609 | (when (buffer-live-p buffer) | 565 | ;; Mark buffer modified. |
| 610 | (with-current-buffer buffer | 566 | (setq auto-revert-notify-modified-p t) |
| 611 | (when (and (stringp buffer-file-name) | 567 | ;; No need to check other buffers. |
| 612 | (string-equal | 568 | (cl-return)))))))) |
| 613 | (file-name-nondirectory file) | ||
| 614 | (file-name-nondirectory buffer-file-name))) | ||
| 615 | ;; Mark buffer modified. | ||
| 616 | (setq auto-revert-notify-modified-p t) | ||
| 617 | ;; No need to check other buffers. | ||
| 618 | (cl-return))))))))) | ||
| 619 | 569 | ||
| 620 | (defun auto-revert-active-p () | 570 | (defun auto-revert-active-p () |
| 621 | "Check if auto-revert is active (in current buffer or globally)." | 571 | "Check if auto-revert is active (in current buffer or globally)." |
diff --git a/lisp/buff-menu.el b/lisp/buff-menu.el index 6c02233e1e2..1db9b7229f3 100644 --- a/lisp/buff-menu.el +++ b/lisp/buff-menu.el | |||
| @@ -129,6 +129,7 @@ commands.") | |||
| 129 | (define-key map "T" 'Buffer-menu-toggle-files-only) | 129 | (define-key map "T" 'Buffer-menu-toggle-files-only) |
| 130 | (define-key map (kbd "M-s a C-s") 'Buffer-menu-isearch-buffers) | 130 | (define-key map (kbd "M-s a C-s") 'Buffer-menu-isearch-buffers) |
| 131 | (define-key map (kbd "M-s a M-C-s") 'Buffer-menu-isearch-buffers-regexp) | 131 | (define-key map (kbd "M-s a M-C-s") 'Buffer-menu-isearch-buffers-regexp) |
| 132 | (define-key map (kbd "M-s a C-o") 'Buffer-menu-multi-occur) | ||
| 132 | 133 | ||
| 133 | (define-key map [mouse-2] 'Buffer-menu-mouse-select) | 134 | (define-key map [mouse-2] 'Buffer-menu-mouse-select) |
| 134 | (define-key map [follow-link] 'mouse-face) | 135 | (define-key map [follow-link] 'mouse-face) |
| @@ -169,6 +170,9 @@ commands.") | |||
| 169 | (bindings--define-key menu-map [ir] | 170 | (bindings--define-key menu-map [ir] |
| 170 | '(menu-item "Isearch Marked Buffers..." Buffer-menu-isearch-buffers | 171 | '(menu-item "Isearch Marked Buffers..." Buffer-menu-isearch-buffers |
| 171 | :help "Search for a string through all marked buffers using Isearch")) | 172 | :help "Search for a string through all marked buffers using Isearch")) |
| 173 | (bindings--define-key menu-map [mo] | ||
| 174 | '(menu-item "Multi Occur Marked Buffers..." Buffer-menu-multi-occur | ||
| 175 | :help "Show lines matching a regexp in marked buffers using Occur")) | ||
| 172 | (bindings--define-key menu-map [s3] menu-bar-separator) | 176 | (bindings--define-key menu-map [s3] menu-bar-separator) |
| 173 | (bindings--define-key menu-map [by] | 177 | (bindings--define-key menu-map [by] |
| 174 | '(menu-item "Bury" Buffer-menu-bury | 178 | '(menu-item "Bury" Buffer-menu-bury |
| @@ -226,6 +230,7 @@ In Buffer Menu mode, the following commands are defined: | |||
| 226 | buffer selected before this one in another window. | 230 | buffer selected before this one in another window. |
| 227 | \\[Buffer-menu-isearch-buffers] Incremental search in the marked buffers. | 231 | \\[Buffer-menu-isearch-buffers] Incremental search in the marked buffers. |
| 228 | \\[Buffer-menu-isearch-buffers-regexp] Isearch for regexp in the marked buffers. | 232 | \\[Buffer-menu-isearch-buffers-regexp] Isearch for regexp in the marked buffers. |
| 233 | \\[Buffer-menu-multi-occur] Show lines matching regexp in the marked buffers. | ||
| 229 | \\[Buffer-menu-visit-tags-table] visit-tags-table this buffer. | 234 | \\[Buffer-menu-visit-tags-table] visit-tags-table this buffer. |
| 230 | \\[Buffer-menu-not-modified] Clear modified-flag on that buffer. | 235 | \\[Buffer-menu-not-modified] Clear modified-flag on that buffer. |
| 231 | \\[Buffer-menu-save] Mark that buffer to be saved, and move down. | 236 | \\[Buffer-menu-save] Mark that buffer to be saved, and move down. |
| @@ -477,6 +482,11 @@ If UNMARK is non-nil, unmark them." | |||
| 477 | (interactive) | 482 | (interactive) |
| 478 | (multi-isearch-buffers-regexp (Buffer-menu-marked-buffers))) | 483 | (multi-isearch-buffers-regexp (Buffer-menu-marked-buffers))) |
| 479 | 484 | ||
| 485 | (defun Buffer-menu-multi-occur (regexp &optional nlines) | ||
| 486 | "Show all lines in marked buffers containing a match for a regexp." | ||
| 487 | (interactive (occur-read-primary-args)) | ||
| 488 | (multi-occur (Buffer-menu-marked-buffers) regexp nlines)) | ||
| 489 | |||
| 480 | 490 | ||
| 481 | (defun Buffer-menu-visit-tags-table () | 491 | (defun Buffer-menu-visit-tags-table () |
| 482 | "Visit the tags table in the buffer on this line. See `visit-tags-table'." | 492 | "Visit the tags table in the buffer on this line. See `visit-tags-table'." |
diff --git a/lisp/calendar/todo-mode.el b/lisp/calendar/todo-mode.el index a497f759e87..934dfb92a57 100644 --- a/lisp/calendar/todo-mode.el +++ b/lisp/calendar/todo-mode.el | |||
| @@ -37,11 +37,14 @@ | |||
| 37 | ;; can edit todo items, reprioritize them within their category, move | 37 | ;; can edit todo items, reprioritize them within their category, move |
| 38 | ;; them to another category, delete them, or mark items as done and | 38 | ;; them to another category, delete them, or mark items as done and |
| 39 | ;; store them separately from the not yet done items in a category. | 39 | ;; store them separately from the not yet done items in a category. |
| 40 | ;; You can add new todo files and categories, rename categories, move | 40 | ;; You can add new todo files, edit and delete them. You can add new |
| 41 | ;; them to another file or delete them. You can also display summary | 41 | ;; categories, rename and delete them, move categories to another file |
| 42 | ;; tables of the categories in a file and the types of items they | 42 | ;; and merge the items of two categories. You can also reorder the |
| 43 | ;; contain. And you can build cross-category lists of items that | 43 | ;; sequence of categories in a todo file for the purpose of |
| 44 | ;; satisfy various criteria. | 44 | ;; navigation. You can display summary tables of the categories in a |
| 45 | ;; file and the types of items they contain. And you can compile | ||
| 46 | ;; lists of existing items from multiple categories in one or more | ||
| 47 | ;; todo files, which are filtered by various criteria. | ||
| 45 | 48 | ||
| 46 | ;; To get started, load this package and type `M-x todo-show'. This | 49 | ;; To get started, load this package and type `M-x todo-show'. This |
| 47 | ;; will prompt you for the name of the first todo file, its first | 50 | ;; will prompt you for the name of the first todo file, its first |
| @@ -169,12 +172,7 @@ the value of `todo-done-separator'." | |||
| 169 | "Return string used as value of variable `todo-done-separator'." | 172 | "Return string used as value of variable `todo-done-separator'." |
| 170 | (let ((sep todo-done-separator-string)) | 173 | (let ((sep todo-done-separator-string)) |
| 171 | (propertize (if (= 1 (length sep)) | 174 | (propertize (if (= 1 (length sep)) |
| 172 | ;; Until bug#2749 is fixed, if separator's length | 175 | (make-string (window-width) (string-to-char sep)) |
| 173 | ;; is window-width and todo-wrap-lines is | ||
| 174 | ;; non-nil, an indented empty line appears between | ||
| 175 | ;; the separator and the first done item. | ||
| 176 | ;; (make-string (window-width) (string-to-char sep)) | ||
| 177 | (make-string (1- (window-width)) (string-to-char sep)) | ||
| 178 | todo-done-separator-string) | 176 | todo-done-separator-string) |
| 179 | 'face 'todo-done-sep))) | 177 | 'face 'todo-done-sep))) |
| 180 | 178 | ||
| @@ -578,11 +576,12 @@ This lacks the extension and directory components." | |||
| 578 | (file-name-sans-extension (file-name-nondirectory file)))) | 576 | (file-name-sans-extension (file-name-nondirectory file)))) |
| 579 | 577 | ||
| 580 | (defcustom todo-default-todo-file (todo-short-file-name | 578 | (defcustom todo-default-todo-file (todo-short-file-name |
| 581 | (car (funcall todo-files-function))) | 579 | (car (funcall todo-files-function))) |
| 582 | "Todo file visited by first session invocation of `todo-show'." | 580 | "Todo file visited by first session invocation of `todo-show'." |
| 583 | :type `(radio ,@(mapcar (lambda (f) (list 'const f)) | 581 | :type (when todo-files |
| 584 | (mapcar 'todo-short-file-name | 582 | `(radio ,@(mapcar (lambda (f) (list 'const f)) |
| 585 | (funcall todo-files-function)))) | 583 | (mapcar 'todo-short-file-name |
| 584 | (funcall todo-files-function))))) | ||
| 586 | :group 'todo) | 585 | :group 'todo) |
| 587 | 586 | ||
| 588 | (defcustom todo-show-current-file t | 587 | (defcustom todo-show-current-file t |
| @@ -630,7 +629,7 @@ Otherwise, `todo-show' always visits `todo-default-todo-file'." | |||
| 630 | :group 'todo) | 629 | :group 'todo) |
| 631 | 630 | ||
| 632 | ;;;###autoload | 631 | ;;;###autoload |
| 633 | (defun todo-show (&optional solicit-file) | 632 | (defun todo-show (&optional solicit-file interactive) |
| 634 | "Visit a todo file and display one of its categories. | 633 | "Visit a todo file and display one of its categories. |
| 635 | 634 | ||
| 636 | When invoked in Todo mode, prompt for which todo file to visit. | 635 | When invoked in Todo mode, prompt for which todo file to visit. |
| @@ -668,117 +667,124 @@ and done items are always shown on visiting a category. | |||
| 668 | 667 | ||
| 669 | Invoking this command in Todo Archive mode visits the | 668 | Invoking this command in Todo Archive mode visits the |
| 670 | corresponding todo file, displaying the corresponding category." | 669 | corresponding todo file, displaying the corresponding category." |
| 671 | (interactive "P") | 670 | (interactive "P\np") |
| 671 | (when todo-default-todo-file | ||
| 672 | (todo-check-file (todo-absolute-file-name todo-default-todo-file))) | ||
| 672 | (catch 'shown | 673 | (catch 'shown |
| 673 | ;; If there is a legacy todo file but no todo file in the current | 674 | ;; Before initializing the first todo first, check if there is a |
| 674 | ;; format, offer to convert the legacy file and show it. | 675 | ;; legacy todo file and if so, offer to convert to the current |
| 676 | ;; format and make it the first new todo file. | ||
| 675 | (unless todo-default-todo-file | 677 | (unless todo-default-todo-file |
| 676 | (let ((legacy-todo-file (if (boundp 'todo-file-do) | 678 | (let ((legacy-todo-file (if (boundp 'todo-file-do) |
| 677 | todo-file-do | 679 | todo-file-do |
| 678 | (locate-user-emacs-file "todo-do" ".todo-do")))) | 680 | (locate-user-emacs-file "todo-do" ".todo-do")))) |
| 679 | (when (and (file-exists-p legacy-todo-file) | 681 | (when (and (file-exists-p legacy-todo-file) |
| 680 | (y-or-n-p (concat "Do you want to convert a copy of your " | 682 | (y-or-n-p (concat "Do you want to convert a copy of your " |
| 681 | "old todo file to the new format? "))) | 683 | "old todo file to the new format? "))) |
| 682 | (when (todo-convert-legacy-files) | 684 | (when (todo-convert-legacy-files) |
| 683 | (throw 'shown nil))))) | 685 | (throw 'shown nil))))) |
| 684 | (let* ((cat) | 686 | (catch 'end |
| 685 | (show-first todo-show-first) | 687 | (let* ((cat) |
| 686 | (file (cond ((or solicit-file | 688 | (show-first todo-show-first) |
| 687 | (and (called-interactively-p 'any) | 689 | (file (cond ((or solicit-file |
| 688 | (memq major-mode '(todo-mode | 690 | (and interactive |
| 689 | todo-archive-mode | 691 | (memq major-mode '(todo-mode |
| 690 | todo-filtered-items-mode)))) | 692 | todo-archive-mode |
| 691 | (if (funcall todo-files-function) | 693 | todo-filtered-items-mode)))) |
| 692 | (todo-read-file-name "Choose a todo file to visit: " | 694 | (if (funcall todo-files-function) |
| 693 | nil t) | 695 | (todo-read-file-name "Choose a todo file to visit: " |
| 694 | (user-error "There are no todo files"))) | 696 | nil t) |
| 695 | ((and (eq major-mode 'todo-archive-mode) | 697 | (user-error "There are no todo files"))) |
| 696 | ;; Called noninteractively via todo-quit | 698 | ((and (eq major-mode 'todo-archive-mode) |
| 697 | ;; to jump to corresponding category in | 699 | ;; Called noninteractively via todo-quit |
| 698 | ;; todo file. | 700 | ;; to jump to corresponding category in |
| 699 | (not (called-interactively-p 'any))) | 701 | ;; todo file. |
| 700 | (setq cat (todo-current-category)) | 702 | (not interactive)) |
| 701 | (concat (file-name-sans-extension | 703 | (setq cat (todo-current-category)) |
| 702 | todo-current-todo-file) ".todo")) | 704 | (concat (file-name-sans-extension |
| 703 | (t | 705 | todo-current-todo-file) ".todo")) |
| 704 | (or todo-current-todo-file | 706 | (t |
| 705 | (and todo-show-current-file | 707 | (or todo-current-todo-file |
| 706 | todo-global-current-todo-file) | 708 | (and todo-show-current-file |
| 707 | (todo-absolute-file-name todo-default-todo-file) | 709 | todo-global-current-todo-file) |
| 708 | (todo-add-file))))) | 710 | (todo-absolute-file-name todo-default-todo-file) |
| 709 | add-item first-file) | 711 | (todo-add-file))))) |
| 710 | (unless todo-default-todo-file | 712 | add-item first-file) |
| 711 | ;; We just initialized the first todo file, so make it the default. | 713 | (unless todo-default-todo-file |
| 712 | (setq todo-default-todo-file (todo-short-file-name file) | 714 | ;; We just initialized the first todo file, so make it the default. |
| 713 | first-file t) | 715 | (setq todo-default-todo-file (todo-short-file-name file) |
| 714 | (todo-reevaluate-default-file-defcustom)) | 716 | first-file t) |
| 715 | (unless (member file todo-visited) | 717 | (todo-reevaluate-default-file-defcustom)) |
| 716 | ;; Can't setq t-c-t-f here, otherwise wrong file shown when | 718 | (unless (member file todo-visited) |
| 717 | ;; todo-show is called from todo-show-categories-table. | 719 | ;; Can't setq t-c-t-f here, otherwise wrong file shown when |
| 718 | (let ((todo-current-todo-file file)) | 720 | ;; todo-show is called from todo-show-categories-table. |
| 719 | (cond ((eq todo-show-first 'table) | 721 | (let ((todo-current-todo-file file)) |
| 720 | (todo-show-categories-table)) | 722 | (cond ((eq todo-show-first 'table) |
| 721 | ((memq todo-show-first '(top diary regexp)) | 723 | (todo-show-categories-table)) |
| 722 | (let* ((shortf (todo-short-file-name file)) | 724 | ((memq todo-show-first '(top diary regexp)) |
| 723 | (fi-file (todo-absolute-file-name | 725 | (let* ((shortf (todo-short-file-name file)) |
| 724 | shortf todo-show-first))) | 726 | (fi-file (todo-absolute-file-name |
| 725 | (when (eq todo-show-first 'regexp) | 727 | shortf todo-show-first))) |
| 726 | (let ((rxfiles (directory-files todo-directory t | 728 | (when (eq todo-show-first 'regexp) |
| 727 | ".*\\.todr$" t))) | 729 | (let ((rxfiles (directory-files todo-directory t |
| 728 | (when (and rxfiles (> (length rxfiles) 1)) | 730 | ".*\\.todr$" t))) |
| 729 | (let ((rxf (mapcar 'todo-short-file-name rxfiles))) | 731 | (when (and rxfiles (> (length rxfiles) 1)) |
| 730 | (setq fi-file (todo-absolute-file-name | 732 | (let ((rxf (mapcar 'todo-short-file-name rxfiles))) |
| 731 | (completing-read | 733 | (setq fi-file (todo-absolute-file-name |
| 732 | "Choose a regexp items file: " | 734 | (completing-read |
| 733 | rxf) 'regexp)))))) | 735 | "Choose a regexp items file: " |
| 734 | (if (file-exists-p fi-file) | 736 | rxf) 'regexp)))))) |
| 735 | (set-window-buffer | 737 | (if (file-exists-p fi-file) |
| 736 | (selected-window) | 738 | (set-window-buffer |
| 737 | (set-buffer (find-file-noselect fi-file 'nowarn))) | 739 | (selected-window) |
| 738 | (message "There is no %s file for %s" | 740 | (set-buffer (find-file-noselect fi-file 'nowarn))) |
| 739 | (cond ((eq todo-show-first 'top) | 741 | (message "There is no %s file for %s" |
| 740 | "top priorities") | 742 | (cond ((eq todo-show-first 'top) |
| 741 | ((eq todo-show-first 'diary) | 743 | "top priorities") |
| 742 | "diary items") | 744 | ((eq todo-show-first 'diary) |
| 743 | ((eq todo-show-first 'regexp) | 745 | "diary items") |
| 744 | "regexp items")) | 746 | ((eq todo-show-first 'regexp) |
| 745 | shortf) | 747 | "regexp items")) |
| 746 | (setq todo-show-first 'first))))))) | 748 | shortf) |
| 747 | (when (or (member file todo-visited) | 749 | (setq todo-show-first 'first))))))) |
| 748 | (eq todo-show-first 'first)) | 750 | (when (or (member file todo-visited) |
| 749 | (set-window-buffer (selected-window) | 751 | (eq todo-show-first 'first)) |
| 750 | (set-buffer (find-file-noselect file 'nowarn))) | 752 | (unless (todo-check-file file) (throw 'end nil)) |
| 751 | ;; When quitting an archive file, show the corresponding | 753 | (set-window-buffer (selected-window) |
| 752 | ;; category in the corresponding todo file, if it exists. | 754 | (set-buffer (find-file-noselect file 'nowarn))) |
| 753 | (when (assoc cat todo-categories) | 755 | ;; When quitting an archive file, show the corresponding |
| 754 | (setq todo-category-number (todo-category-number cat))) | 756 | ;; category in the corresponding todo file, if it exists. |
| 755 | ;; If this is a new todo file, add its first category. | 757 | (when (assoc cat todo-categories) |
| 756 | (when (zerop (buffer-size)) | 758 | (setq todo-category-number (todo-category-number cat))) |
| 757 | (let (cat-added) | 759 | ;; If this is a new todo file, add its first category. |
| 758 | (unwind-protect | 760 | (when (zerop (buffer-size)) |
| 759 | (setq todo-category-number | 761 | (let (cat-added) |
| 760 | (todo-add-category todo-current-todo-file "") | 762 | (unwind-protect |
| 761 | add-item todo-add-item-if-new-category | 763 | (setq todo-category-number |
| 762 | cat-added t) | 764 | (todo-add-category todo-current-todo-file "") |
| 763 | (if cat-added | 765 | add-item todo-add-item-if-new-category |
| 764 | ;; If the category was added, save the file now, so we | 766 | cat-added t) |
| 765 | ;; don't risk having an empty todo file, which would | 767 | (if cat-added |
| 766 | ;; signal an error if we tried to visit it later, | 768 | ;; If the category was added, save the file now, so we |
| 767 | ;; since doing that looks for category boundaries. | 769 | ;; don't risk having an empty todo file, which would |
| 768 | (save-buffer 0) | 770 | ;; signal an error if we tried to visit it later, |
| 769 | ;; If user cancels before adding the category, clean up | 771 | ;; since doing that looks for category boundaries. |
| 770 | ;; and exit, so we have a fresh slate the next time. | 772 | (save-buffer 0) |
| 771 | (delete-file file) | 773 | ;; If user cancels before adding the category, clean up |
| 772 | (setq todo-files (delete file todo-files)) | 774 | ;; and exit, so we have a fresh slate the next time. |
| 773 | (when first-file | 775 | (delete-file file) |
| 774 | (setq todo-default-todo-file nil | 776 | ;; (setq todo-files (funcall todo-files-function)) |
| 775 | todo-current-todo-file nil)) | 777 | (setq todo-files (delete file todo-files)) |
| 776 | (kill-buffer) | 778 | (when first-file |
| 777 | (keyboard-quit))))) | 779 | (setq todo-default-todo-file nil |
| 778 | (save-excursion (todo-category-select)) | 780 | todo-current-todo-file nil) |
| 779 | (when add-item (todo-basic-insert-item))) | 781 | (todo-reevaluate-default-file-defcustom)) |
| 780 | (setq todo-show-first show-first) | 782 | (kill-buffer) |
| 781 | (add-to-list 'todo-visited file)))) | 783 | (keyboard-quit))))) |
| 784 | (save-excursion (todo-category-select)) | ||
| 785 | (when add-item (todo-basic-insert-item))) | ||
| 786 | (setq todo-show-first show-first) | ||
| 787 | (add-to-list 'todo-visited file))))) | ||
| 782 | 788 | ||
| 783 | (defun todo-save () | 789 | (defun todo-save () |
| 784 | "Save the current todo file." | 790 | "Save the current todo file." |
| @@ -814,8 +820,15 @@ buries it and restores state as needed." | |||
| 814 | ;; Have to write a newly created archive to file to avoid | 820 | ;; Have to write a newly created archive to file to avoid |
| 815 | ;; subsequent errors. | 821 | ;; subsequent errors. |
| 816 | (todo-save) | 822 | (todo-save) |
| 817 | (todo-show) | 823 | (let ((todo-file (concat todo-directory |
| 818 | (bury-buffer buf)) | 824 | (todo-short-file-name todo-current-todo-file) |
| 825 | ".todo"))) | ||
| 826 | (if (todo-check-file todo-file) | ||
| 827 | (todo-show) | ||
| 828 | (message "There is no todo file for this archive"))) | ||
| 829 | ;; When todo-check-file runs in todo-show, it kills the | ||
| 830 | ;; buffer if the archive file was deleted externally. | ||
| 831 | (when (buffer-live-p buf) (bury-buffer buf))) | ||
| 819 | ((eq major-mode 'todo-mode) | 832 | ((eq major-mode 'todo-mode) |
| 820 | (todo-save) | 833 | (todo-save) |
| 821 | ;; If we just quit archive mode, just burying the buffer | 834 | ;; If we just quit archive mode, just burying the buffer |
| @@ -893,7 +906,7 @@ Categories mode." | |||
| 893 | (interactive "P") | 906 | (interactive "P") |
| 894 | ;; If invoked outside of Todo mode and there is not yet any Todo | 907 | ;; If invoked outside of Todo mode and there is not yet any Todo |
| 895 | ;; file, initialize one. | 908 | ;; file, initialize one. |
| 896 | (if (null todo-files) | 909 | (if (null (funcall todo-files-function)) |
| 897 | (todo-show) | 910 | (todo-show) |
| 898 | (let* ((archive (eq where 'archive)) | 911 | (let* ((archive (eq where 'archive)) |
| 899 | (cat (unless archive where)) | 912 | (cat (unless archive where)) |
| @@ -1069,10 +1082,9 @@ option `todo-add-item-if-new-category' is non-nil (the default), | |||
| 1069 | prompt for the first item. | 1082 | prompt for the first item. |
| 1070 | Noninteractively, return the name of the new file." | 1083 | Noninteractively, return the name of the new file." |
| 1071 | (interactive) | 1084 | (interactive) |
| 1072 | (let ((prompt (concat "Enter name of new todo file " | 1085 | (let* ((prompt (concat "Enter name of new todo file " |
| 1073 | "(TAB or SPC to see current names): ")) | 1086 | "(TAB or SPC to see current names): ")) |
| 1074 | file) | 1087 | (file (todo-read-file-name prompt))) |
| 1075 | (setq file (todo-read-file-name prompt)) | ||
| 1076 | (with-current-buffer (get-buffer-create file) | 1088 | (with-current-buffer (get-buffer-create file) |
| 1077 | (erase-buffer) | 1089 | (erase-buffer) |
| 1078 | (write-region (point-min) (point-max) file nil 'nomessage nil t) | 1090 | (write-region (point-min) (point-max) file nil 'nomessage nil t) |
| @@ -1087,6 +1099,55 @@ Noninteractively, return the name of the new file." | |||
| 1087 | (todo-show)) | 1099 | (todo-show)) |
| 1088 | file))) | 1100 | file))) |
| 1089 | 1101 | ||
| 1102 | (defun todo-delete-file () | ||
| 1103 | "Delete the current todo, archive or filtered items file. | ||
| 1104 | If the todo file has a corresponding archive file, or vice versa, | ||
| 1105 | prompt whether to delete that as well. Also kill the buffers | ||
| 1106 | visiting the deleted files." | ||
| 1107 | (interactive) | ||
| 1108 | (let* ((file1 (buffer-file-name)) | ||
| 1109 | (todo (eq major-mode 'todo-mode)) | ||
| 1110 | (archive (eq major-mode 'todo-archive-mode)) | ||
| 1111 | (filtered (eq major-mode 'todo-filtered-items-mode)) | ||
| 1112 | (file1-sn (todo-short-file-name file1)) | ||
| 1113 | (file2 (concat todo-directory file1-sn (cond (todo ".toda") | ||
| 1114 | (archive ".todo")))) | ||
| 1115 | (buf1 (current-buffer)) | ||
| 1116 | (buf2 (when file2 (find-buffer-visiting file2))) | ||
| 1117 | (prompt1 (concat "Delete " (cond (todo "todo") | ||
| 1118 | (archive "archive") | ||
| 1119 | (filtered "filtered items")) | ||
| 1120 | " file \"%s\"? ")) | ||
| 1121 | (prompt2 (concat "Also delete the corresponding " | ||
| 1122 | (cond (todo "archive") (archive "todo")) " file " | ||
| 1123 | (when buf2 "and kill the buffer visiting it? "))) | ||
| 1124 | (delete1 (yes-or-no-p (format prompt1 file1-sn))) | ||
| 1125 | (delete2 (when (and delete1 (or (file-exists-p file2) buf2)) | ||
| 1126 | (yes-or-no-p prompt2)))) | ||
| 1127 | (when delete1 | ||
| 1128 | (when (file-exists-p file1) (delete-file file1)) | ||
| 1129 | (setq todo-visited (delete file1 todo-visited)) | ||
| 1130 | (kill-buffer buf1) | ||
| 1131 | (when delete2 | ||
| 1132 | (when (file-exists-p file2) (delete-file file2)) | ||
| 1133 | (setq todo-visited (delete file2 todo-visited)) | ||
| 1134 | (and buf2 (kill-buffer buf2))) | ||
| 1135 | (setq todo-files (funcall todo-files-function) | ||
| 1136 | todo-archives (funcall todo-files-function t)) | ||
| 1137 | (when (or (string= file1-sn todo-default-todo-file) | ||
| 1138 | (and delete2 (string= file1-sn todo-default-todo-file))) | ||
| 1139 | (setq todo-default-todo-file (todo-short-file-name (car todo-files)))) | ||
| 1140 | (when (or (string= file1 todo-global-current-todo-file) | ||
| 1141 | (and delete2 (string= file2 todo-global-current-todo-file))) | ||
| 1142 | (setq todo-global-current-todo-file nil)) | ||
| 1143 | (todo-reevaluate-filelist-defcustoms) | ||
| 1144 | (message (concat (cond (todo "Todo") (archive "Archive")) " file \"%s\" " | ||
| 1145 | (when delete2 | ||
| 1146 | (concat "and its " | ||
| 1147 | (cond (todo "archive") (archive "todo")) | ||
| 1148 | " file ")) | ||
| 1149 | "deleted") file1-sn)))) | ||
| 1150 | |||
| 1090 | (defvar todo-edit-buffer "*Todo Edit*" | 1151 | (defvar todo-edit-buffer "*Todo Edit*" |
| 1091 | "Name of current buffer in Todo Edit mode.") | 1152 | "Name of current buffer in Todo Edit mode.") |
| 1092 | 1153 | ||
| @@ -1190,9 +1251,9 @@ category there as well." | |||
| 1190 | (save-excursion (todo-category-select))) | 1251 | (save-excursion (todo-category-select))) |
| 1191 | 1252 | ||
| 1192 | (defun todo-delete-category (&optional arg) | 1253 | (defun todo-delete-category (&optional arg) |
| 1193 | "Delete current todo category provided it is empty. | 1254 | "Delete current todo category provided it contains no items. |
| 1194 | With ARG non-nil delete the category unconditionally, | 1255 | With prefix ARG delete the category even if it does contain |
| 1195 | i.e. including all existing todo and done items." | 1256 | todo or done items." |
| 1196 | (interactive "P") | 1257 | (interactive "P") |
| 1197 | (let* ((file todo-current-todo-file) | 1258 | (let* ((file todo-current-todo-file) |
| 1198 | (cat (todo-current-category)) | 1259 | (cat (todo-current-category)) |
| @@ -1723,7 +1784,7 @@ the new item: | |||
| 1723 | the item accordingly." | 1784 | the item accordingly." |
| 1724 | ;; If invoked outside of Todo mode and there is not yet any Todo | 1785 | ;; If invoked outside of Todo mode and there is not yet any Todo |
| 1725 | ;; file, initialize one. | 1786 | ;; file, initialize one. |
| 1726 | (if (null todo-files) | 1787 | (if (null (funcall todo-files-function)) |
| 1727 | (todo-show) | 1788 | (todo-show) |
| 1728 | (let ((region (eq region-or-here 'region)) | 1789 | (let ((region (eq region-or-here 'region)) |
| 1729 | (here (eq region-or-here 'here))) | 1790 | (here (eq region-or-here 'here))) |
| @@ -2958,31 +3019,32 @@ first visit in a session displays the first category in the | |||
| 2958 | archive, subsequent visits return to the last category | 3019 | archive, subsequent visits return to the last category |
| 2959 | displayed." | 3020 | displayed." |
| 2960 | (interactive) | 3021 | (interactive) |
| 2961 | (let* ((cat (todo-current-category)) | 3022 | (if (null (funcall todo-files-function t)) |
| 2962 | (count (todo-get-count 'archived cat)) | 3023 | (message "There are no archive files") |
| 2963 | (archive (concat (file-name-sans-extension todo-current-todo-file) | 3024 | (let* ((cat (todo-current-category)) |
| 2964 | ".toda")) | 3025 | (count (todo-get-count 'archived cat)) |
| 2965 | place) | 3026 | (archive (concat (file-name-sans-extension todo-current-todo-file) |
| 2966 | (setq place (cond (ask 'other-archive) | 3027 | ".toda")) |
| 2967 | ((file-exists-p archive) 'this-archive) | 3028 | (place (cond (ask 'other-archive) |
| 2968 | (t (when (todo-y-or-n-p | 3029 | ((file-exists-p archive) 'this-archive) |
| 2969 | (concat "This file has no archive; " | 3030 | (t (when (todo-y-or-n-p |
| 2970 | "visit another archive? ")) | 3031 | (concat "This file has no archive; " |
| 2971 | 'other-archive)))) | 3032 | "visit another archive? ")) |
| 2972 | (when (eq place 'other-archive) | 3033 | 'other-archive))))) |
| 2973 | (setq archive (todo-read-file-name "Choose a todo archive: " t t))) | 3034 | (when (eq place 'other-archive) |
| 2974 | (when (and (eq place 'this-archive) (zerop count)) | 3035 | (setq archive (todo-read-file-name "Choose a todo archive: " t t))) |
| 2975 | (setq place (when (todo-y-or-n-p | 3036 | (when (and (eq place 'this-archive) (zerop count)) |
| 2976 | (concat "This category has no archived items;" | 3037 | (setq place (when (todo-y-or-n-p |
| 2977 | " visit archive anyway? ")) | 3038 | (concat "This category has no archived items;" |
| 2978 | 'other-cat))) | 3039 | " visit archive anyway? ")) |
| 2979 | (when place | 3040 | 'other-cat))) |
| 2980 | (set-window-buffer (selected-window) | 3041 | (when place |
| 2981 | (set-buffer (find-file-noselect archive))) | 3042 | (set-window-buffer (selected-window) |
| 2982 | (if (member place '(other-archive other-cat)) | 3043 | (set-buffer (find-file-noselect archive))) |
| 2983 | (setq todo-category-number 1) | 3044 | (if (member place '(other-archive other-cat)) |
| 2984 | (todo-category-number cat)) | 3045 | (setq todo-category-number 1) |
| 2985 | (todo-category-select)))) | 3046 | (todo-category-number cat)) |
| 3047 | (todo-category-select))))) | ||
| 2986 | 3048 | ||
| 2987 | (defun todo-choose-archive () | 3049 | (defun todo-choose-archive () |
| 2988 | "Choose an archive and visit it." | 3050 | "Choose an archive and visit it." |
| @@ -3010,9 +3072,7 @@ this category does not exist in the archive, it is created." | |||
| 3010 | (marked (assoc cat todo-categories-with-marks)) | 3072 | (marked (assoc cat todo-categories-with-marks)) |
| 3011 | (afile (concat (file-name-sans-extension | 3073 | (afile (concat (file-name-sans-extension |
| 3012 | todo-current-todo-file) ".toda")) | 3074 | todo-current-todo-file) ".toda")) |
| 3013 | (archive (if (file-exists-p afile) | 3075 | (archive (find-file-noselect afile t)) |
| 3014 | (find-file-noselect afile t) | ||
| 3015 | (get-buffer-create afile))) | ||
| 3016 | (item (and (todo-done-item-p) | 3076 | (item (and (todo-done-item-p) |
| 3017 | (concat (todo-item-string) "\n"))) | 3077 | (concat (todo-item-string) "\n"))) |
| 3018 | (count 0) | 3078 | (count 0) |
| @@ -3056,7 +3116,6 @@ this category does not exist in the archive, it is created." | |||
| 3056 | (if (not (or marked all item)) | 3116 | (if (not (or marked all item)) |
| 3057 | (throw 'end (message "Only done items can be archived")) | 3117 | (throw 'end (message "Only done items can be archived")) |
| 3058 | (with-current-buffer archive | 3118 | (with-current-buffer archive |
| 3059 | (unless buffer-file-name (erase-buffer)) | ||
| 3060 | (let (buffer-read-only) | 3119 | (let (buffer-read-only) |
| 3061 | (widen) | 3120 | (widen) |
| 3062 | (goto-char (point-min)) | 3121 | (goto-char (point-min)) |
| @@ -3076,11 +3135,13 @@ this category does not exist in the archive, it is created." | |||
| 3076 | (item))) | 3135 | (item))) |
| 3077 | (todo-update-count 'done (if (or marked all) count 1) cat) | 3136 | (todo-update-count 'done (if (or marked all) count 1) cat) |
| 3078 | (todo-update-categories-sexp) | 3137 | (todo-update-categories-sexp) |
| 3079 | ;; If archive is new, save to file now (using write-region in | 3138 | ;; If archive is new, save to file now (with |
| 3080 | ;; order not to get prompted for file to save to), to let | 3139 | ;; write-region to avoid prompt for file to save to) |
| 3081 | ;; auto-mode-alist take effect below. | 3140 | ;; to update todo-archives, and to let auto-mode-alist |
| 3082 | (unless buffer-file-name | 3141 | ;; take effect below on visiting the archive. |
| 3083 | (write-region nil nil afile) | 3142 | (unless (nth 7 (file-attributes afile)) |
| 3143 | (write-region nil nil afile t t) | ||
| 3144 | (setq todo-archives (funcall todo-files-function t)) | ||
| 3084 | (kill-buffer)))) | 3145 | (kill-buffer)))) |
| 3085 | (with-current-buffer tbuf | 3146 | (with-current-buffer tbuf |
| 3086 | (cond | 3147 | (cond |
| @@ -3286,19 +3347,24 @@ categories display according to priority." | |||
| 3286 | (defun todo-show-categories-table () | 3347 | (defun todo-show-categories-table () |
| 3287 | "Display a table of the current file's categories and item counts. | 3348 | "Display a table of the current file's categories and item counts. |
| 3288 | 3349 | ||
| 3289 | In the initial display the categories are numbered, indicating | 3350 | In the initial display the lines of the table are numbered, |
| 3290 | their current order for navigating by \\[todo-forward-category] | 3351 | indicating the current order of the categories when sequentially |
| 3291 | and \\[todo-backward-category]. You can permanently change the | 3352 | navigating through the todo file with `\\[todo-forward-category]' |
| 3292 | order of the category at point by typing | 3353 | and `\\[todo-backward-category]'. You can reorder the lines, and |
| 3293 | \\[todo-set-category-number], \\[todo-raise-category] or | 3354 | hence the category sequence, by typing `\\[todo-raise-category]' |
| 3294 | \\[todo-lower-category]. | 3355 | or `\\[todo-lower-category]' to raise or lower the category at |
| 3356 | point, or by typing `\\[todo-set-category-number]' and entering a | ||
| 3357 | number at the prompt or by typing `\\[todo-set-category-number]' | ||
| 3358 | with a numeric prefix. If you save the todo file after | ||
| 3359 | reordering the categories, the new order persists in subsequent | ||
| 3360 | Emacs sessions. | ||
| 3295 | 3361 | ||
| 3296 | The labels above the category names and item counts are buttons, | 3362 | The labels above the category names and item counts are buttons, |
| 3297 | and clicking these changes the display: sorted by category name | 3363 | and clicking these changes the display: sorted by category name |
| 3298 | or by the respective item counts (alternately descending or | 3364 | or by the respective item counts (alternately descending or |
| 3299 | ascending). In these displays the categories are not numbered | 3365 | ascending). In these displays the categories are not numbered |
| 3300 | and \\[todo-set-category-number], \\[todo-raise-category] and | 3366 | and `\\[todo-set-category-number]', `\\[todo-raise-category]' and |
| 3301 | \\[todo-lower-category] are disabled. (Programmatically, the | 3367 | `\\[todo-lower-category]' are disabled. (Programmatically, the |
| 3302 | sorting is triggered by passing a non-nil SORTKEY argument.) | 3368 | sorting is triggered by passing a non-nil SORTKEY argument.) |
| 3303 | 3369 | ||
| 3304 | In addition, the lines with the category names and item counts | 3370 | In addition, the lines with the category names and item counts |
| @@ -4019,15 +4085,15 @@ regexp items." | |||
| 4019 | "Buffer type string for `todo-filter-items'.") | 4085 | "Buffer type string for `todo-filter-items'.") |
| 4020 | 4086 | ||
| 4021 | (defun todo-filter-items (filter &optional new multifile) | 4087 | (defun todo-filter-items (filter &optional new multifile) |
| 4022 | "Display a cross-category list of items filtered by FILTER. | 4088 | "Display a list of items filtered by FILTER. |
| 4023 | The values of FILTER can be `top' for top priority items, a cons | 4089 | The values of FILTER can be `top' for top priority items, a cons |
| 4024 | of `top' and a number passed by the caller, `diary' for diary | 4090 | of `top' and a number passed by the caller, `diary' for diary |
| 4025 | items, or `regexp' for items matching a regular expression entered | 4091 | items, or `regexp' for items matching a regular expression |
| 4026 | by the user. The items can be from any categories in the current | 4092 | entered by the user. The items can come from any categories in |
| 4027 | todo file or, with non-nil MULTIFILE, from several files. If NEW | 4093 | the current todo file or, with non-nil MULTIFILE, from several |
| 4028 | is nil, visit an appropriate file containing the list of filtered | 4094 | files. If NEW is nil, visit an appropriate file containing the |
| 4029 | items; if there is no such file, or with non-nil NEW, build the | 4095 | list of filtered items; if there is no such file, or with non-nil |
| 4030 | list and display it. | 4096 | NEW, build the list and display it. |
| 4031 | 4097 | ||
| 4032 | See the documentation strings of the commands | 4098 | See the documentation strings of the commands |
| 4033 | `todo-filter-top-priorities', `todo-filter-diary-items', | 4099 | `todo-filter-top-priorities', `todo-filter-diary-items', |
| @@ -4699,14 +4765,57 @@ short todo archive or top priorities file name, respectively." | |||
| 4699 | ((eq type 'regexp) ".todr") | 4765 | ((eq type 'regexp) ".todr") |
| 4700 | (t ".todo")))))) | 4766 | (t ".todo")))))) |
| 4701 | 4767 | ||
| 4768 | (defun todo-check-file (file) | ||
| 4769 | "Check the state associated with FILE and update it if necessary. | ||
| 4770 | If FILE exists, return t. If it does not exist and there is no | ||
| 4771 | live buffer with its content, return nil; if there is such a | ||
| 4772 | buffer and the user tries to show it, ask whether to restore | ||
| 4773 | FILE, and if confirmed, do so and return t; else delete the | ||
| 4774 | buffer, clean up the state and return nil." | ||
| 4775 | (setq todo-files (funcall todo-files-function)) | ||
| 4776 | (setq todo-archives (funcall todo-files-function t)) | ||
| 4777 | (if (file-exists-p file) | ||
| 4778 | t | ||
| 4779 | (setq todo-visited (delete file todo-visited)) | ||
| 4780 | (let ((buf (find-buffer-visiting file))) | ||
| 4781 | (if (and buf | ||
| 4782 | (y-or-n-p | ||
| 4783 | (concat | ||
| 4784 | (format (concat "Todo file \"%s\" has been deleted but " | ||
| 4785 | "its content is still in a buffer!\n") | ||
| 4786 | (todo-short-file-name file)) | ||
| 4787 | "Save that buffer and restore the todo file? "))) | ||
| 4788 | (progn | ||
| 4789 | (with-current-buffer buf (save-buffer)) | ||
| 4790 | (setq todo-files (funcall todo-files-function)) | ||
| 4791 | (setq todo-archives (funcall todo-files-function t)) | ||
| 4792 | t) | ||
| 4793 | (let* ((files (append todo-files todo-archives)) | ||
| 4794 | (tctf todo-current-todo-file) | ||
| 4795 | (tgctf todo-global-current-todo-file) | ||
| 4796 | (tdtf (todo-absolute-file-name todo-default-todo-file))) | ||
| 4797 | (unless (or (not todo-current-todo-file) | ||
| 4798 | (member todo-current-todo-file files)) | ||
| 4799 | (setq todo-current-todo-file nil)) | ||
| 4800 | (unless (or (not todo-global-current-todo-file) | ||
| 4801 | (member todo-global-current-todo-file files)) | ||
| 4802 | (setq todo-global-current-todo-file nil)) | ||
| 4803 | (unless (or (not todo-default-todo-file) | ||
| 4804 | (member todo-default-todo-file files)) | ||
| 4805 | (setq todo-default-todo-file (todo-short-file-name | ||
| 4806 | (car todo-files)))) | ||
| 4807 | (todo-reevaluate-filelist-defcustoms) | ||
| 4808 | (when buf (kill-buffer buf)) | ||
| 4809 | nil))))) | ||
| 4810 | |||
| 4702 | (defun todo-category-number (cat) | 4811 | (defun todo-category-number (cat) |
| 4703 | "Return the number of category CAT in this todo file. | 4812 | "Return the number of category CAT in this todo file. |
| 4704 | The buffer-local variable `todo-category-number' holds this | 4813 | The buffer-local variable `todo-category-number' holds this |
| 4705 | number as its value." | 4814 | number as its value." |
| 4706 | (let ((categories (mapcar 'car todo-categories))) | 4815 | (let ((categories (mapcar 'car todo-categories))) |
| 4707 | (setq todo-category-number | 4816 | (setq todo-category-number |
| 4708 | ;; Increment by one, so that the highest priority category in Todo | 4817 | ;; Increment by one, so that the number of the first |
| 4709 | ;; Categories mode is numbered one rather than zero. | 4818 | ;; category is one rather than zero. |
| 4710 | (1+ (- (length categories) | 4819 | (1+ (- (length categories) |
| 4711 | (length (member cat categories))))))) | 4820 | (length (member cat categories))))))) |
| 4712 | 4821 | ||
| @@ -5384,7 +5493,27 @@ Each element of the list is a cons of a category name and the | |||
| 5384 | file or list of files (as short file names) it is in. The files | 5493 | file or list of files (as short file names) it is in. The files |
| 5385 | are either the current (or if there is none, the default) todo | 5494 | are either the current (or if there is none, the default) todo |
| 5386 | file plus the files listed in `todo-category-completions-files', | 5495 | file plus the files listed in `todo-category-completions-files', |
| 5387 | or, with non-nil ARCHIVE, the current archive file." | 5496 | or, with non-nil ARCHIVE, the current archive file. |
| 5497 | |||
| 5498 | Before calculating the completions, update the value of | ||
| 5499 | `todo-category-completions-files' in case any files named in it | ||
| 5500 | have been removed." | ||
| 5501 | (let (deleted) | ||
| 5502 | (dolist (f todo-category-completions-files) | ||
| 5503 | (unless (file-exists-p (todo-absolute-file-name f)) | ||
| 5504 | (setq todo-category-completions-files | ||
| 5505 | (delete f todo-category-completions-files)) | ||
| 5506 | (push f deleted))) | ||
| 5507 | (when deleted | ||
| 5508 | (let ((pl (> (length deleted) 1)) | ||
| 5509 | (names (mapconcat (lambda (f) (concat "\"" f "\"")) deleted ", "))) | ||
| 5510 | (message (concat "File" (if pl "s" "") " " names " ha" (if pl "ve" "s") | ||
| 5511 | " been deleted and removed from\n" | ||
| 5512 | "the list of category completion files"))) | ||
| 5513 | (todo-reevaluate-category-completions-files-defcustom) | ||
| 5514 | (custom-set-default 'todo-category-completions-files | ||
| 5515 | (symbol-value 'todo-category-completions-files)) | ||
| 5516 | (sleep-for 1.5))) | ||
| 5388 | (let* ((curfile (or todo-current-todo-file | 5517 | (let* ((curfile (or todo-current-todo-file |
| 5389 | (and todo-show-current-file | 5518 | (and todo-show-current-file |
| 5390 | todo-global-current-todo-file) | 5519 | todo-global-current-todo-file) |
| @@ -5435,6 +5564,7 @@ MUSTMATCH the name of an existing file must be chosen; | |||
| 5435 | otherwise, a new file name is allowed." | 5564 | otherwise, a new file name is allowed." |
| 5436 | (let* ((completion-ignore-case todo-completion-ignore-case) | 5565 | (let* ((completion-ignore-case todo-completion-ignore-case) |
| 5437 | (files (mapcar 'todo-short-file-name | 5566 | (files (mapcar 'todo-short-file-name |
| 5567 | ;; (funcall todo-files-function archive))) | ||
| 5438 | (if archive todo-archives todo-files))) | 5568 | (if archive todo-archives todo-files))) |
| 5439 | (file (completing-read prompt files nil mustmatch nil nil | 5569 | (file (completing-read prompt files nil mustmatch nil nil |
| 5440 | (if files | 5570 | (if files |
| @@ -5529,7 +5659,7 @@ categories from `todo-category-completions-files'." | |||
| 5529 | ;; Validate only against completion categories. | 5659 | ;; Validate only against completion categories. |
| 5530 | (let ((todo-categories categories)) | 5660 | (let ((todo-categories categories)) |
| 5531 | (setq cat (todo-validate-name cat 'category))) | 5661 | (setq cat (todo-validate-name cat 'category))) |
| 5532 | ;; When user enters a nonexistest category name by jumping or | 5662 | ;; When user enters a nonexistent category name by jumping or |
| 5533 | ;; moving, confirm that it should be added, then validate. | 5663 | ;; moving, confirm that it should be added, then validate. |
| 5534 | (unless add | 5664 | (unless add |
| 5535 | (if (todo-y-or-n-p (format "Add new category \"%s\" to file \"%s\"? " | 5665 | (if (todo-y-or-n-p (format "Add new category \"%s\" to file \"%s\"? " |
| @@ -5867,13 +5997,24 @@ the empty string (i.e., no time string)." | |||
| 5867 | 5997 | ||
| 5868 | (defun todo-reevaluate-default-file-defcustom () | 5998 | (defun todo-reevaluate-default-file-defcustom () |
| 5869 | "Reevaluate defcustom of `todo-default-todo-file'. | 5999 | "Reevaluate defcustom of `todo-default-todo-file'. |
| 5870 | Called after adding or deleting a todo file." | 6000 | Called after adding or deleting a todo file. If the value of |
| 5871 | (eval (defcustom todo-default-todo-file (car (funcall todo-files-function)) | 6001 | `todo-default-todo-file' before calling this function was |
| 5872 | "Todo file visited by first session invocation of `todo-show'." | 6002 | associated with an existing file, keep that value." |
| 5873 | :type `(radio ,@(mapcar (lambda (f) (list 'const f)) | 6003 | ;; (let ((curval todo-default-todo-file)) |
| 5874 | (mapcar 'todo-short-file-name | 6004 | (eval |
| 5875 | (funcall todo-files-function)))) | 6005 | (defcustom todo-default-todo-file (todo-short-file-name |
| 5876 | :group 'todo))) | 6006 | (car (funcall todo-files-function))) |
| 6007 | "Todo file visited by first session invocation of `todo-show'." | ||
| 6008 | :type (when todo-files | ||
| 6009 | `(radio ,@(mapcar (lambda (f) (list 'const f)) | ||
| 6010 | (mapcar 'todo-short-file-name | ||
| 6011 | (funcall todo-files-function))))) | ||
| 6012 | :group 'todo)) | ||
| 6013 | ;; (when (and curval (file-exists-p (todo-absolute-file-name curval))) | ||
| 6014 | ;; (custom-set-default 'todo-default-todo-file curval) | ||
| 6015 | ;; ;; (custom-reevaluate-setting 'todo-default-todo-file) | ||
| 6016 | ;; ))) | ||
| 6017 | ) | ||
| 5877 | 6018 | ||
| 5878 | (defun todo-reevaluate-category-completions-files-defcustom () | 6019 | (defun todo-reevaluate-category-completions-files-defcustom () |
| 5879 | "Reevaluate defcustom of `todo-category-completions-files'. | 6020 | "Reevaluate defcustom of `todo-category-completions-files'. |
| @@ -6060,6 +6201,7 @@ Filtered Items mode following todo (not done) items." | |||
| 6060 | ("Cu" todo-unmark-category) | 6201 | ("Cu" todo-unmark-category) |
| 6061 | ("Fh" todo-toggle-item-header) | 6202 | ("Fh" todo-toggle-item-header) |
| 6062 | ("h" todo-toggle-item-header) | 6203 | ("h" todo-toggle-item-header) |
| 6204 | ("Fk" todo-delete-file) | ||
| 6063 | ("Fe" todo-edit-file) | 6205 | ("Fe" todo-edit-file) |
| 6064 | ("FH" todo-toggle-item-highlighting) | 6206 | ("FH" todo-toggle-item-highlighting) |
| 6065 | ("H" todo-toggle-item-highlighting) | 6207 | ("H" todo-toggle-item-highlighting) |
| @@ -6226,12 +6368,13 @@ Filtered Items mode following todo (not done) items." | |||
| 6226 | 6368 | ||
| 6227 | (defun todo-show-current-file () | 6369 | (defun todo-show-current-file () |
| 6228 | "Visit current instead of default todo file with `todo-show'. | 6370 | "Visit current instead of default todo file with `todo-show'. |
| 6229 | This function is added to `pre-command-hook' when user option | 6371 | Added to `pre-command-hook' in Todo mode when user option |
| 6230 | `todo-show-current-file' is set to non-nil." | 6372 | `todo-show-current-file' is set to non-nil." |
| 6231 | (setq todo-global-current-todo-file todo-current-todo-file)) | 6373 | (setq todo-global-current-todo-file todo-current-todo-file)) |
| 6232 | 6374 | ||
| 6233 | (defun todo-display-as-todo-file () | 6375 | (defun todo-display-as-todo-file () |
| 6234 | "Show todo files correctly when visited from outside of Todo mode." | 6376 | "Show todo files correctly when visited from outside of Todo mode. |
| 6377 | Added to `find-file-hook' in Todo mode and Todo Archive mode." | ||
| 6235 | (and (member this-command todo-visit-files-commands) | 6378 | (and (member this-command todo-visit-files-commands) |
| 6236 | (= (- (point-max) (point-min)) (buffer-size)) | 6379 | (= (- (point-max) (point-min)) (buffer-size)) |
| 6237 | (member major-mode '(todo-mode todo-archive-mode)) | 6380 | (member major-mode '(todo-mode todo-archive-mode)) |
| @@ -6265,7 +6408,7 @@ This function is added to `kill-buffer-hook' in Todo mode." | |||
| 6265 | 6408 | ||
| 6266 | (defun todo-reset-and-enable-done-separator () | 6409 | (defun todo-reset-and-enable-done-separator () |
| 6267 | "Show resized done items separator overlay after window change. | 6410 | "Show resized done items separator overlay after window change. |
| 6268 | Added to `window-configuration-change-hook' in `todo-mode'." | 6411 | Added to `window-configuration-change-hook' in Todo mode." |
| 6269 | (when (= 1 (length todo-done-separator-string)) | 6412 | (when (= 1 (length todo-done-separator-string)) |
| 6270 | (let ((sep todo-done-separator)) | 6413 | (let ((sep todo-done-separator)) |
| 6271 | (setq todo-done-separator (todo-done-separator)) | 6414 | (setq todo-done-separator (todo-done-separator)) |
diff --git a/lisp/cedet/ChangeLog b/lisp/cedet/ChangeLog index 7a2c5755cc0..705277c97a0 100644 --- a/lisp/cedet/ChangeLog +++ b/lisp/cedet/ChangeLog | |||
| @@ -2,7 +2,7 @@ | |||
| 2 | 2 | ||
| 3 | * data-debug.el, cedet-idutils.el: Neuter the "Version:" header. | 3 | * data-debug.el, cedet-idutils.el: Neuter the "Version:" header. |
| 4 | 4 | ||
| 5 | 2013-06-19 Glenn Morris <rgm@fencepost.gnu.org> | 5 | 2013-06-19 Glenn Morris <rgm@gnu.org> |
| 6 | 6 | ||
| 7 | * semantic/idle.el (define-semantic-idle-service): | 7 | * semantic/idle.el (define-semantic-idle-service): |
| 8 | No need to use eval-and-compile, progn will do. | 8 | No need to use eval-and-compile, progn will do. |
diff --git a/lisp/desktop.el b/lisp/desktop.el index db77d7c3f5a..fcd032a64d0 100644 --- a/lisp/desktop.el +++ b/lisp/desktop.el | |||
| @@ -196,9 +196,7 @@ Zero or nil means disable timer-based auto-saving." | |||
| 196 | (integer :tag "Seconds")) | 196 | (integer :tag "Seconds")) |
| 197 | :set (lambda (symbol value) | 197 | :set (lambda (symbol value) |
| 198 | (set-default symbol value) | 198 | (set-default symbol value) |
| 199 | (condition-case nil | 199 | (ignore-errors (desktop-auto-save-set-timer))) |
| 200 | (desktop-auto-save-set-timer) | ||
| 201 | (error nil))) | ||
| 202 | :group 'desktop | 200 | :group 'desktop |
| 203 | :version "24.4") | 201 | :version "24.4") |
| 204 | 202 | ||
| @@ -416,9 +414,8 @@ See `desktop-restore-eager'." | |||
| 416 | :version "22.1") | 414 | :version "22.1") |
| 417 | 415 | ||
| 418 | ;;;###autoload | 416 | ;;;###autoload |
| 419 | (defvar desktop-save-buffer nil | 417 | (defvar-local desktop-save-buffer nil |
| 420 | "When non-nil, save buffer status in desktop file. | 418 | "When non-nil, save buffer status in desktop file. |
| 421 | This variable becomes buffer local when set. | ||
| 422 | 419 | ||
| 423 | If the value is a function, it is called by `desktop-save' with argument | 420 | If the value is a function, it is called by `desktop-save' with argument |
| 424 | DESKTOP-DIRNAME to obtain auxiliary information to save in the desktop | 421 | DESKTOP-DIRNAME to obtain auxiliary information to save in the desktop |
| @@ -430,7 +427,6 @@ When file names are returned, they should be formatted using the call | |||
| 430 | Later, when `desktop-read' evaluates the desktop file, auxiliary information | 427 | Later, when `desktop-read' evaluates the desktop file, auxiliary information |
| 431 | is passed as the argument DESKTOP-BUFFER-MISC to functions in | 428 | is passed as the argument DESKTOP-BUFFER-MISC to functions in |
| 432 | `desktop-buffer-mode-handlers'.") | 429 | `desktop-buffer-mode-handlers'.") |
| 433 | (make-variable-buffer-local 'desktop-save-buffer) | ||
| 434 | (make-obsolete-variable 'desktop-buffer-modes-to-save | 430 | (make-obsolete-variable 'desktop-buffer-modes-to-save |
| 435 | 'desktop-save-buffer "22.1") | 431 | 'desktop-save-buffer "22.1") |
| 436 | (make-obsolete-variable 'desktop-buffer-misc-functions | 432 | (make-obsolete-variable 'desktop-buffer-misc-functions |
| @@ -582,15 +578,15 @@ Used to detect desktop file conflicts.") | |||
| 582 | "Return the PID of the Emacs process that owns the desktop file in DIRNAME. | 578 | "Return the PID of the Emacs process that owns the desktop file in DIRNAME. |
| 583 | Return nil if no desktop file found or no Emacs process is using it. | 579 | Return nil if no desktop file found or no Emacs process is using it. |
| 584 | DIRNAME omitted or nil means use `desktop-dirname'." | 580 | DIRNAME omitted or nil means use `desktop-dirname'." |
| 585 | (let (owner) | 581 | (let (owner |
| 586 | (and (file-exists-p (desktop-full-lock-name dirname)) | 582 | (file (desktop-full-lock-name dirname))) |
| 587 | (condition-case nil | 583 | (and (file-exists-p file) |
| 588 | (with-temp-buffer | 584 | (ignore-errors |
| 589 | (insert-file-contents-literally (desktop-full-lock-name dirname)) | 585 | (with-temp-buffer |
| 590 | (goto-char (point-min)) | 586 | (insert-file-contents-literally file) |
| 591 | (setq owner (read (current-buffer))) | 587 | (goto-char (point-min)) |
| 592 | (integerp owner)) | 588 | (setq owner (read (current-buffer))) |
| 593 | (error nil)) | 589 | (integerp owner))) |
| 594 | owner))) | 590 | owner))) |
| 595 | 591 | ||
| 596 | (defun desktop-claim-lock (&optional dirname) | 592 | (defun desktop-claim-lock (&optional dirname) |
| @@ -636,7 +632,7 @@ Furthermore, it clears the variables listed in `desktop-globals-to-clear'." | |||
| 636 | (let ((bufname (buffer-name (car buffers)))) | 632 | (let ((bufname (buffer-name (car buffers)))) |
| 637 | (or | 633 | (or |
| 638 | (null bufname) | 634 | (null bufname) |
| 639 | (string-match preserve-regexp bufname) | 635 | (string-match-p preserve-regexp bufname) |
| 640 | ;; Don't kill buffers made for internal purposes. | 636 | ;; Don't kill buffers made for internal purposes. |
| 641 | (and (not (equal bufname "")) (eq (aref bufname 0) ?\s)) | 637 | (and (not (equal bufname "")) (eq (aref bufname 0) ?\s)) |
| 642 | (kill-buffer (car buffers)))) | 638 | (kill-buffer (car buffers)))) |
| @@ -758,8 +754,7 @@ QUOTE may be `may' (value may be quoted), | |||
| 758 | ((consp value) | 754 | ((consp value) |
| 759 | (let ((p value) | 755 | (let ((p value) |
| 760 | newlist | 756 | newlist |
| 761 | use-list* | 757 | use-list*) |
| 762 | anynil) | ||
| 763 | (while (consp p) | 758 | (while (consp p) |
| 764 | (let ((q.sexp (desktop--v2s (car p)))) | 759 | (let ((q.sexp (desktop--v2s (car p)))) |
| 765 | (push q.sexp newlist)) | 760 | (push q.sexp newlist)) |
| @@ -841,17 +836,17 @@ MODE is the major mode. | |||
| 841 | dired-skip) | 836 | dired-skip) |
| 842 | (and (not (and (stringp desktop-buffers-not-to-save) | 837 | (and (not (and (stringp desktop-buffers-not-to-save) |
| 843 | (not filename) | 838 | (not filename) |
| 844 | (string-match desktop-buffers-not-to-save bufname))) | 839 | (string-match-p desktop-buffers-not-to-save bufname))) |
| 845 | (not (memq mode desktop-modes-not-to-save)) | 840 | (not (memq mode desktop-modes-not-to-save)) |
| 846 | ;; FIXME this is broken if desktop-files-not-to-save is nil. | 841 | ;; FIXME this is broken if desktop-files-not-to-save is nil. |
| 847 | (or (and filename | 842 | (or (and filename |
| 848 | (stringp desktop-files-not-to-save) | 843 | (stringp desktop-files-not-to-save) |
| 849 | (not (string-match desktop-files-not-to-save filename))) | 844 | (not (string-match-p desktop-files-not-to-save filename))) |
| 850 | (and (memq mode '(dired-mode vc-dir-mode)) | 845 | (and (memq mode '(dired-mode vc-dir-mode)) |
| 851 | (with-current-buffer bufname | 846 | (with-current-buffer bufname |
| 852 | (not (setq dired-skip | 847 | (not (setq dired-skip |
| 853 | (string-match desktop-files-not-to-save | 848 | (string-match-p desktop-files-not-to-save |
| 854 | default-directory))))) | 849 | default-directory))))) |
| 855 | (and (null filename) | 850 | (and (null filename) |
| 856 | (null dired-skip) ; bug#5755 | 851 | (null dired-skip) ; bug#5755 |
| 857 | (with-current-buffer bufname desktop-save-buffer)))))) | 852 | (with-current-buffer bufname desktop-save-buffer)))))) |
diff --git a/lisp/doc-view.el b/lisp/doc-view.el index e4434c3a0d8..10968f7f8dd 100644 --- a/lisp/doc-view.el +++ b/lisp/doc-view.el | |||
| @@ -136,7 +136,7 @@ | |||
| 136 | 136 | ||
| 137 | ;;; Code: | 137 | ;;; Code: |
| 138 | 138 | ||
| 139 | (eval-when-compile (require 'cl-lib)) | 139 | (require 'cl-lib) |
| 140 | (require 'dired) | 140 | (require 'dired) |
| 141 | (require 'image-mode) | 141 | (require 'image-mode) |
| 142 | (require 'jka-compr) | 142 | (require 'jka-compr) |
| @@ -698,14 +698,6 @@ It's a subdirectory of `doc-view-cache-directory'." | |||
| 698 | (md5 (current-buffer))))) | 698 | (md5 (current-buffer))))) |
| 699 | doc-view-cache-directory))))) | 699 | doc-view-cache-directory))))) |
| 700 | 700 | ||
| 701 | (defun doc-view-remove-if (predicate list) | ||
| 702 | "Return LIST with all items removed that satisfy PREDICATE." | ||
| 703 | (let (new-list) | ||
| 704 | (dolist (item list) | ||
| 705 | (when (not (funcall predicate item)) | ||
| 706 | (setq new-list (cons item new-list)))) | ||
| 707 | (nreverse new-list))) | ||
| 708 | |||
| 709 | ;;;###autoload | 701 | ;;;###autoload |
| 710 | (defun doc-view-mode-p (type) | 702 | (defun doc-view-mode-p (type) |
| 711 | "Return non-nil if document type TYPE is available for `doc-view'. | 703 | "Return non-nil if document type TYPE is available for `doc-view'. |
| @@ -1488,7 +1480,7 @@ If BACKWARD is non-nil, jump to the previous match." | |||
| 1488 | (defun doc-view-search-next-match (arg) | 1480 | (defun doc-view-search-next-match (arg) |
| 1489 | "Go to the ARGth next matching page." | 1481 | "Go to the ARGth next matching page." |
| 1490 | (interactive "p") | 1482 | (interactive "p") |
| 1491 | (let* ((next-pages (doc-view-remove-if | 1483 | (let* ((next-pages (cl-remove-if |
| 1492 | (lambda (i) (<= (car i) (doc-view-current-page))) | 1484 | (lambda (i) (<= (car i) (doc-view-current-page))) |
| 1493 | doc-view--current-search-matches)) | 1485 | doc-view--current-search-matches)) |
| 1494 | (page (car (nth (1- arg) next-pages)))) | 1486 | (page (car (nth (1- arg) next-pages)))) |
| @@ -1502,7 +1494,7 @@ If BACKWARD is non-nil, jump to the previous match." | |||
| 1502 | (defun doc-view-search-previous-match (arg) | 1494 | (defun doc-view-search-previous-match (arg) |
| 1503 | "Go to the ARGth previous matching page." | 1495 | "Go to the ARGth previous matching page." |
| 1504 | (interactive "p") | 1496 | (interactive "p") |
| 1505 | (let* ((prev-pages (doc-view-remove-if | 1497 | (let* ((prev-pages (cl-remove-if |
| 1506 | (lambda (i) (>= (car i) (doc-view-current-page))) | 1498 | (lambda (i) (>= (car i) (doc-view-current-page))) |
| 1507 | doc-view--current-search-matches)) | 1499 | doc-view--current-search-matches)) |
| 1508 | (page (car (nth (1- arg) (nreverse prev-pages))))) | 1500 | (page (car (nth (1- arg) (nreverse prev-pages))))) |
diff --git a/lisp/edmacro.el b/lisp/edmacro.el index 6ef2e29dc83..67992d16527 100644 --- a/lisp/edmacro.el +++ b/lisp/edmacro.el | |||
| @@ -62,9 +62,8 @@ | |||
| 62 | ;; macro in a more concise way that omits the comments. | 62 | ;; macro in a more concise way that omits the comments. |
| 63 | 63 | ||
| 64 | ;;; Code: | 64 | ;;; Code: |
| 65 | |||
| 66 | (eval-when-compile (require 'cl-lib)) | ||
| 67 | 65 | ||
| 66 | (require 'cl-lib) | ||
| 68 | (require 'kmacro) | 67 | (require 'kmacro) |
| 69 | 68 | ||
| 70 | ;;; The user-level commands for editing macros. | 69 | ;;; The user-level commands for editing macros. |
| @@ -444,14 +443,14 @@ doubt, use whitespace." | |||
| 444 | (let* ((prefix | 443 | (let* ((prefix |
| 445 | (or (and (integerp (aref rest-mac 0)) | 444 | (or (and (integerp (aref rest-mac 0)) |
| 446 | (memq (aref rest-mac 0) mdigs) | 445 | (memq (aref rest-mac 0) mdigs) |
| 447 | (memq (key-binding (edmacro-subseq rest-mac 0 1)) | 446 | (memq (key-binding (cl-subseq rest-mac 0 1)) |
| 448 | '(digit-argument negative-argument)) | 447 | '(digit-argument negative-argument)) |
| 449 | (let ((i 1)) | 448 | (let ((i 1)) |
| 450 | (while (memq (aref rest-mac i) (cdr mdigs)) | 449 | (while (memq (aref rest-mac i) (cdr mdigs)) |
| 451 | (cl-incf i)) | 450 | (cl-incf i)) |
| 452 | (and (not (memq (aref rest-mac i) pkeys)) | 451 | (and (not (memq (aref rest-mac i) pkeys)) |
| 453 | (prog1 (vconcat "M-" (edmacro-subseq rest-mac 0 i) " ") | 452 | (prog1 (vconcat "M-" (cl-subseq rest-mac 0 i) " ") |
| 454 | (cl-callf edmacro-subseq rest-mac i))))) | 453 | (cl-callf cl-subseq rest-mac i))))) |
| 455 | (and (eq (aref rest-mac 0) ?\C-u) | 454 | (and (eq (aref rest-mac 0) ?\C-u) |
| 456 | (eq (key-binding [?\C-u]) 'universal-argument) | 455 | (eq (key-binding [?\C-u]) 'universal-argument) |
| 457 | (let ((i 1)) | 456 | (let ((i 1)) |
| @@ -459,7 +458,7 @@ doubt, use whitespace." | |||
| 459 | (cl-incf i)) | 458 | (cl-incf i)) |
| 460 | (and (not (memq (aref rest-mac i) pkeys)) | 459 | (and (not (memq (aref rest-mac i) pkeys)) |
| 461 | (prog1 (cl-loop repeat i concat "C-u ") | 460 | (prog1 (cl-loop repeat i concat "C-u ") |
| 462 | (cl-callf edmacro-subseq rest-mac i))))) | 461 | (cl-callf cl-subseq rest-mac i))))) |
| 463 | (and (eq (aref rest-mac 0) ?\C-u) | 462 | (and (eq (aref rest-mac 0) ?\C-u) |
| 464 | (eq (key-binding [?\C-u]) 'universal-argument) | 463 | (eq (key-binding [?\C-u]) 'universal-argument) |
| 465 | (let ((i 1)) | 464 | (let ((i 1)) |
| @@ -469,18 +468,18 @@ doubt, use whitespace." | |||
| 469 | '(?0 ?1 ?2 ?3 ?4 ?5 ?6 ?7 ?8 ?9)) | 468 | '(?0 ?1 ?2 ?3 ?4 ?5 ?6 ?7 ?8 ?9)) |
| 470 | (cl-incf i)) | 469 | (cl-incf i)) |
| 471 | (and (not (memq (aref rest-mac i) pkeys)) | 470 | (and (not (memq (aref rest-mac i) pkeys)) |
| 472 | (prog1 (vconcat "C-u " (edmacro-subseq rest-mac 1 i) " ") | 471 | (prog1 (vconcat "C-u " (cl-subseq rest-mac 1 i) " ") |
| 473 | (cl-callf edmacro-subseq rest-mac i))))))) | 472 | (cl-callf cl-subseq rest-mac i))))))) |
| 474 | (bind-len (apply 'max 1 | 473 | (bind-len (apply 'max 1 |
| 475 | (cl-loop for map in maps | 474 | (cl-loop for map in maps |
| 476 | for b = (lookup-key map rest-mac) | 475 | for b = (lookup-key map rest-mac) |
| 477 | when b collect b))) | 476 | when b collect b))) |
| 478 | (key (edmacro-subseq rest-mac 0 bind-len)) | 477 | (key (cl-subseq rest-mac 0 bind-len)) |
| 479 | (fkey nil) tlen tkey | 478 | (fkey nil) tlen tkey |
| 480 | (bind (or (cl-loop for map in maps for b = (lookup-key map key) | 479 | (bind (or (cl-loop for map in maps for b = (lookup-key map key) |
| 481 | thereis (and (not (integerp b)) b)) | 480 | thereis (and (not (integerp b)) b)) |
| 482 | (and (setq fkey (lookup-key local-function-key-map rest-mac)) | 481 | (and (setq fkey (lookup-key local-function-key-map rest-mac)) |
| 483 | (setq tlen fkey tkey (edmacro-subseq rest-mac 0 tlen) | 482 | (setq tlen fkey tkey (cl-subseq rest-mac 0 tlen) |
| 484 | fkey (lookup-key local-function-key-map tkey)) | 483 | fkey (lookup-key local-function-key-map tkey)) |
| 485 | (cl-loop for map in maps | 484 | (cl-loop for map in maps |
| 486 | for b = (lookup-key map fkey) | 485 | for b = (lookup-key map fkey) |
| @@ -507,7 +506,7 @@ doubt, use whitespace." | |||
| 507 | (> first 32) (<= first maxkey) (/= first 92) | 506 | (> first 32) (<= first maxkey) (/= first 92) |
| 508 | (progn | 507 | (progn |
| 509 | (if (> text 30) (setq text 30)) | 508 | (if (> text 30) (setq text 30)) |
| 510 | (setq desc (concat (edmacro-subseq rest-mac 0 text))) | 509 | (setq desc (concat (cl-subseq rest-mac 0 text))) |
| 511 | (when (string-match "^[ACHMsS]-." desc) | 510 | (when (string-match "^[ACHMsS]-." desc) |
| 512 | (setq text 2) | 511 | (setq text 2) |
| 513 | (cl-callf substring desc 0 2)) | 512 | (cl-callf substring desc 0 2)) |
| @@ -524,7 +523,7 @@ doubt, use whitespace." | |||
| 524 | (> text bind-len) | 523 | (> text bind-len) |
| 525 | (memq (aref rest-mac text) '(return 13)) | 524 | (memq (aref rest-mac text) '(return 13)) |
| 526 | (progn | 525 | (progn |
| 527 | (setq desc (concat (edmacro-subseq rest-mac bind-len text))) | 526 | (setq desc (concat (cl-subseq rest-mac bind-len text))) |
| 528 | (commandp (intern-soft desc)))) | 527 | (commandp (intern-soft desc)))) |
| 529 | (if (commandp (intern-soft desc)) (setq bind desc)) | 528 | (if (commandp (intern-soft desc)) (setq bind desc)) |
| 530 | (setq desc (format "<<%s>>" desc)) | 529 | (setq desc (format "<<%s>>" desc)) |
| @@ -562,14 +561,14 @@ doubt, use whitespace." | |||
| 562 | (setq desc (concat (edmacro-sanitize-for-string prefix) desc))) | 561 | (setq desc (concat (edmacro-sanitize-for-string prefix) desc))) |
| 563 | (unless (string-match " " desc) | 562 | (unless (string-match " " desc) |
| 564 | (let ((times 1) (pos bind-len)) | 563 | (let ((times 1) (pos bind-len)) |
| 565 | (while (not (edmacro-mismatch rest-mac rest-mac | 564 | (while (not (cl-mismatch rest-mac rest-mac |
| 566 | 0 bind-len pos (+ bind-len pos))) | 565 | 0 bind-len pos (+ bind-len pos))) |
| 567 | (cl-incf times) | 566 | (cl-incf times) |
| 568 | (cl-incf pos bind-len)) | 567 | (cl-incf pos bind-len)) |
| 569 | (when (> times 1) | 568 | (when (> times 1) |
| 570 | (setq desc (format "%d*%s" times desc)) | 569 | (setq desc (format "%d*%s" times desc)) |
| 571 | (setq bind-len (* bind-len times))))) | 570 | (setq bind-len (* bind-len times))))) |
| 572 | (setq rest-mac (edmacro-subseq rest-mac bind-len)) | 571 | (setq rest-mac (cl-subseq rest-mac bind-len)) |
| 573 | (if verbose | 572 | (if verbose |
| 574 | (progn | 573 | (progn |
| 575 | (unless (equal res "") (cl-callf concat res "\n")) | 574 | (unless (equal res "") (cl-callf concat res "\n")) |
| @@ -590,50 +589,6 @@ doubt, use whitespace." | |||
| 590 | (cl-incf len (length desc))))) | 589 | (cl-incf len (length desc))))) |
| 591 | res)) | 590 | res)) |
| 592 | 591 | ||
| 593 | (defun edmacro-mismatch (cl-seq1 cl-seq2 cl-start1 cl-end1 cl-start2 cl-end2) | ||
| 594 | "Compare SEQ1 with SEQ2, return index of first mismatching element. | ||
| 595 | Return nil if the sequences match. If one sequence is a prefix of the | ||
| 596 | other, the return value indicates the end of the shorted sequence. | ||
| 597 | \n(fn SEQ1 SEQ2 START1 END1 START2 END2)" | ||
| 598 | (or cl-end1 (setq cl-end1 (length cl-seq1))) | ||
| 599 | (or cl-end2 (setq cl-end2 (length cl-seq2))) | ||
| 600 | (let ((cl-p1 (and (listp cl-seq1) (nthcdr cl-start1 cl-seq1))) | ||
| 601 | (cl-p2 (and (listp cl-seq2) (nthcdr cl-start2 cl-seq2)))) | ||
| 602 | (while (and (< cl-start1 cl-end1) (< cl-start2 cl-end2) | ||
| 603 | (eql (if cl-p1 (car cl-p1) | ||
| 604 | (aref cl-seq1 cl-start1)) | ||
| 605 | (if cl-p2 (car cl-p2) | ||
| 606 | (aref cl-seq2 cl-start2)))) | ||
| 607 | (setq cl-p1 (cdr cl-p1) cl-p2 (cdr cl-p2) | ||
| 608 | cl-start1 (1+ cl-start1) cl-start2 (1+ cl-start2))) | ||
| 609 | (and (or (< cl-start1 cl-end1) (< cl-start2 cl-end2)) | ||
| 610 | cl-start1))) | ||
| 611 | |||
| 612 | (defun edmacro-subseq (seq start &optional end) | ||
| 613 | "Return the subsequence of SEQ from START to END. | ||
| 614 | If END is omitted, it defaults to the length of the sequence. | ||
| 615 | If START or END is negative, it counts from the end." | ||
| 616 | (if (stringp seq) (substring seq start end) | ||
| 617 | (let (len) | ||
| 618 | (and end (< end 0) (setq end (+ end (setq len (length seq))))) | ||
| 619 | (if (< start 0) (setq start (+ start (or len (setq len (length seq)))))) | ||
| 620 | (cond ((listp seq) | ||
| 621 | (if (> start 0) (setq seq (nthcdr start seq))) | ||
| 622 | (if end | ||
| 623 | (let ((res nil)) | ||
| 624 | (while (>= (setq end (1- end)) start) | ||
| 625 | (push (pop seq) res)) | ||
| 626 | (nreverse res)) | ||
| 627 | (copy-sequence seq))) | ||
| 628 | (t | ||
| 629 | (or end (setq end (or len (length seq)))) | ||
| 630 | (let ((res (make-vector (max (- end start) 0) nil)) | ||
| 631 | (i 0)) | ||
| 632 | (while (< start end) | ||
| 633 | (aset res i (aref seq start)) | ||
| 634 | (setq i (1+ i) start (1+ start))) | ||
| 635 | res)))))) | ||
| 636 | |||
| 637 | (defun edmacro-sanitize-for-string (seq) | 592 | (defun edmacro-sanitize-for-string (seq) |
| 638 | "Convert a key sequence vector SEQ into a string. | 593 | "Convert a key sequence vector SEQ into a string. |
| 639 | The string represents the same events; Meta is indicated by bit 7. | 594 | The string represents the same events; Meta is indicated by bit 7. |
| @@ -760,7 +715,7 @@ This function assumes that the events can be stored in a string." | |||
| 760 | (eq (aref res 1) ?\() | 715 | (eq (aref res 1) ?\() |
| 761 | (eq (aref res (- (length res) 2)) ?\C-x) | 716 | (eq (aref res (- (length res) 2)) ?\C-x) |
| 762 | (eq (aref res (- (length res) 1)) ?\))) | 717 | (eq (aref res (- (length res) 1)) ?\))) |
| 763 | (setq res (edmacro-subseq res 2 -2))) | 718 | (setq res (cl-subseq res 2 -2))) |
| 764 | (if (and (not need-vector) | 719 | (if (and (not need-vector) |
| 765 | (cl-loop for ch across res | 720 | (cl-loop for ch across res |
| 766 | always (and (characterp ch) | 721 | always (and (characterp ch) |
diff --git a/lisp/emacs-lisp/.gitignore b/lisp/emacs-lisp/.gitignore deleted file mode 100644 index 133e79e817a..00000000000 --- a/lisp/emacs-lisp/.gitignore +++ /dev/null | |||
| @@ -1,2 +0,0 @@ | |||
| 1 | !*-loaddefs.el | ||
| 2 | |||
diff --git a/lisp/emacs-lisp/cl-macs.el b/lisp/emacs-lisp/cl-macs.el index 3cf744f1245..c47c9b61030 100644 --- a/lisp/emacs-lisp/cl-macs.el +++ b/lisp/emacs-lisp/cl-macs.el | |||
| @@ -1957,7 +1957,7 @@ by EXPANSION, and (setq NAME ...) will act like (setf EXPANSION ...). | |||
| 1957 | "Collect multiple return values. | 1957 | "Collect multiple return values. |
| 1958 | FORM must return a list; the BODY is then executed with the first N elements | 1958 | FORM must return a list; the BODY is then executed with the first N elements |
| 1959 | of this list bound (`let'-style) to each of the symbols SYM in turn. This | 1959 | of this list bound (`let'-style) to each of the symbols SYM in turn. This |
| 1960 | is analogous to the Common Lisp `cl-multiple-value-bind' macro, using lists to | 1960 | is analogous to the Common Lisp `multiple-value-bind' macro, using lists to |
| 1961 | simulate true multiple return values. For compatibility, (cl-values A B C) is | 1961 | simulate true multiple return values. For compatibility, (cl-values A B C) is |
| 1962 | a synonym for (list A B C). | 1962 | a synonym for (list A B C). |
| 1963 | 1963 | ||
| @@ -1975,7 +1975,7 @@ a synonym for (list A B C). | |||
| 1975 | "Collect multiple return values. | 1975 | "Collect multiple return values. |
| 1976 | FORM must return a list; the first N elements of this list are stored in | 1976 | FORM must return a list; the first N elements of this list are stored in |
| 1977 | each of the symbols SYM in turn. This is analogous to the Common Lisp | 1977 | each of the symbols SYM in turn. This is analogous to the Common Lisp |
| 1978 | `cl-multiple-value-setq' macro, using lists to simulate true multiple return | 1978 | `multiple-value-setq' macro, using lists to simulate true multiple return |
| 1979 | values. For compatibility, (cl-values A B C) is a synonym for (list A B C). | 1979 | values. For compatibility, (cl-values A B C) is a synonym for (list A B C). |
| 1980 | 1980 | ||
| 1981 | \(fn (SYM...) FORM)" | 1981 | \(fn (SYM...) FORM)" |
| @@ -2002,7 +2002,7 @@ values. For compatibility, (cl-values A B C) is a synonym for (list A B C). | |||
| 2002 | (cons 'progn body)) | 2002 | (cons 'progn body)) |
| 2003 | ;;;###autoload | 2003 | ;;;###autoload |
| 2004 | (defmacro cl-the (_type form) | 2004 | (defmacro cl-the (_type form) |
| 2005 | "At present this ignores _TYPE and is simply equivalent to FORM." | 2005 | "At present this ignores TYPE and is simply equivalent to FORM." |
| 2006 | (declare (indent 1) (debug (cl-type-spec form))) | 2006 | (declare (indent 1) (debug (cl-type-spec form))) |
| 2007 | form) | 2007 | form) |
| 2008 | 2008 | ||
| @@ -2059,7 +2059,7 @@ values. For compatibility, (cl-values A B C) is a synonym for (list A B C). | |||
| 2059 | "Declare SPECS about the current function while compiling. | 2059 | "Declare SPECS about the current function while compiling. |
| 2060 | For instance | 2060 | For instance |
| 2061 | 2061 | ||
| 2062 | \(cl-declare (warn 0)) | 2062 | (cl-declare (warn 0)) |
| 2063 | 2063 | ||
| 2064 | will turn off byte-compile warnings in the function. | 2064 | will turn off byte-compile warnings in the function. |
| 2065 | See Info node `(cl)Declarations' for details." | 2065 | See Info node `(cl)Declarations' for details." |
| @@ -2279,8 +2279,8 @@ KEYWORD can be one of :conc-name, :constructor, :copier, :predicate, | |||
| 2279 | Each SLOT may instead take the form (SNAME SDEFAULT SOPTIONS...), where | 2279 | Each SLOT may instead take the form (SNAME SDEFAULT SOPTIONS...), where |
| 2280 | SDEFAULT is the default value of that slot and SOPTIONS are keyword-value | 2280 | SDEFAULT is the default value of that slot and SOPTIONS are keyword-value |
| 2281 | pairs for that slot. | 2281 | pairs for that slot. |
| 2282 | Currently, only one keyword is supported, `:read-only'. If this has a non-nil | 2282 | Currently, only one keyword is supported, `:read-only'. If this has a |
| 2283 | value, that slot cannot be set via `setf'. | 2283 | non-nil value, that slot cannot be set via `setf'. |
| 2284 | 2284 | ||
| 2285 | \(fn NAME SLOTS...)" | 2285 | \(fn NAME SLOTS...)" |
| 2286 | (declare (doc-string 2) (indent 1) | 2286 | (declare (doc-string 2) (indent 1) |
diff --git a/lisp/emacs-lisp/edebug.el b/lisp/emacs-lisp/edebug.el index 319af588eac..36c72f3a3bd 100644 --- a/lisp/emacs-lisp/edebug.el +++ b/lisp/emacs-lisp/edebug.el | |||
| @@ -53,7 +53,7 @@ | |||
| 53 | ;;; Code: | 53 | ;;; Code: |
| 54 | 54 | ||
| 55 | (require 'macroexp) | 55 | (require 'macroexp) |
| 56 | (eval-when-compile (require 'cl-lib)) | 56 | (require 'cl-lib) |
| 57 | (eval-when-compile (require 'pcase)) | 57 | (eval-when-compile (require 'pcase)) |
| 58 | 58 | ||
| 59 | ;;; Options | 59 | ;;; Options |
| @@ -263,26 +263,6 @@ An extant spec symbol is a symbol that is not a function and has a | |||
| 263 | 263 | ||
| 264 | ;;; Utilities | 264 | ;;; Utilities |
| 265 | 265 | ||
| 266 | ;; Define edebug-gensym - from old cl.el | ||
| 267 | (defvar edebug-gensym-index 0 | ||
| 268 | "Integer used by `edebug-gensym' to produce new names.") | ||
| 269 | |||
| 270 | (defun edebug-gensym (&optional prefix) | ||
| 271 | "Generate a fresh uninterned symbol. | ||
| 272 | There is an optional argument, PREFIX. PREFIX is the string | ||
| 273 | that begins the new name. Most people take just the default, | ||
| 274 | except when debugging needs suggest otherwise." | ||
| 275 | (if (null prefix) | ||
| 276 | (setq prefix "G")) | ||
| 277 | (let ((newsymbol nil) | ||
| 278 | (newname "")) | ||
| 279 | (while (not newsymbol) | ||
| 280 | (setq newname (concat prefix (int-to-string edebug-gensym-index))) | ||
| 281 | (setq edebug-gensym-index (+ edebug-gensym-index 1)) | ||
| 282 | (if (not (intern-soft newname)) | ||
| 283 | (setq newsymbol (make-symbol newname)))) | ||
| 284 | newsymbol)) | ||
| 285 | |||
| 286 | (defun edebug-lambda-list-keywordp (object) | 266 | (defun edebug-lambda-list-keywordp (object) |
| 287 | "Return t if OBJECT is a lambda list keyword. | 267 | "Return t if OBJECT is a lambda list keyword. |
| 288 | A lambda list keyword is a symbol that starts with `&'." | 268 | A lambda list keyword is a symbol that starts with `&'." |
| @@ -1186,7 +1166,7 @@ Maybe clear the markers and delete the symbol's edebug property?" | |||
| 1186 | ;; Uses the dynamically bound vars edebug-def-name and edebug-def-args. | 1166 | ;; Uses the dynamically bound vars edebug-def-name and edebug-def-args. |
| 1187 | ;; Do this after parsing since that may find a name. | 1167 | ;; Do this after parsing since that may find a name. |
| 1188 | (setq edebug-def-name | 1168 | (setq edebug-def-name |
| 1189 | (or edebug-def-name edebug-old-def-name (edebug-gensym "edebug-anon"))) | 1169 | (or edebug-def-name edebug-old-def-name (cl-gensym "edebug-anon"))) |
| 1190 | `(edebug-enter | 1170 | `(edebug-enter |
| 1191 | (quote ,edebug-def-name) | 1171 | (quote ,edebug-def-name) |
| 1192 | ,(if edebug-inside-func | 1172 | ,(if edebug-inside-func |
| @@ -1299,7 +1279,7 @@ expressions; a `progn' form will be returned enclosing these forms." | |||
| 1299 | 1279 | ||
| 1300 | ;; Set the name here if it was not set by edebug-make-enter-wrapper. | 1280 | ;; Set the name here if it was not set by edebug-make-enter-wrapper. |
| 1301 | (setq edebug-def-name | 1281 | (setq edebug-def-name |
| 1302 | (or edebug-def-name edebug-old-def-name (edebug-gensym "edebug-anon"))) | 1282 | (or edebug-def-name edebug-old-def-name (cl-gensym "edebug-anon"))) |
| 1303 | 1283 | ||
| 1304 | ;; Add this def as a dependent of containing def. Buggy. | 1284 | ;; Add this def as a dependent of containing def. Buggy. |
| 1305 | '(if (and edebug-containing-def-name | 1285 | '(if (and edebug-containing-def-name |
diff --git a/lisp/emacs-lisp/ert.el b/lisp/emacs-lisp/ert.el index 656cb0a6a14..1f5edefea08 100644 --- a/lisp/emacs-lisp/ert.el +++ b/lisp/emacs-lisp/ert.el | |||
| @@ -54,7 +54,7 @@ | |||
| 54 | 54 | ||
| 55 | ;;; Code: | 55 | ;;; Code: |
| 56 | 56 | ||
| 57 | (eval-when-compile (require 'cl-lib)) | 57 | (require 'cl-lib) |
| 58 | (require 'button) | 58 | (require 'button) |
| 59 | (require 'debug) | 59 | (require 'debug) |
| 60 | (require 'easymenu) | 60 | (require 'easymenu) |
| @@ -87,127 +87,6 @@ | |||
| 87 | 87 | ||
| 88 | ;;; Copies/reimplementations of cl functions. | 88 | ;;; Copies/reimplementations of cl functions. |
| 89 | 89 | ||
| 90 | (defun ert--cl-do-remf (plist tag) | ||
| 91 | "Copy of `cl-do-remf'. Modify PLIST by removing TAG." | ||
| 92 | (let ((p (cdr plist))) | ||
| 93 | (while (and (cdr p) (not (eq (car (cdr p)) tag))) (setq p (cdr (cdr p)))) | ||
| 94 | (and (cdr p) (progn (setcdr p (cdr (cdr (cdr p)))) t)))) | ||
| 95 | |||
| 96 | (defun ert--remprop (sym tag) | ||
| 97 | "Copy of `cl-remprop'. Modify SYM's plist by removing TAG." | ||
| 98 | (let ((plist (symbol-plist sym))) | ||
| 99 | (if (and plist (eq tag (car plist))) | ||
| 100 | (progn (setplist sym (cdr (cdr plist))) t) | ||
| 101 | (ert--cl-do-remf plist tag)))) | ||
| 102 | |||
| 103 | (defun ert--remove-if-not (ert-pred ert-list) | ||
| 104 | "A reimplementation of `remove-if-not'. | ||
| 105 | |||
| 106 | ERT-PRED is a predicate, ERT-LIST is the input list." | ||
| 107 | (cl-loop for ert-x in ert-list | ||
| 108 | if (funcall ert-pred ert-x) | ||
| 109 | collect ert-x)) | ||
| 110 | |||
| 111 | (defun ert--intersection (a b) | ||
| 112 | "A reimplementation of `intersection'. Intersect the sets A and B. | ||
| 113 | |||
| 114 | Elements are compared using `eql'." | ||
| 115 | (cl-loop for x in a | ||
| 116 | if (memql x b) | ||
| 117 | collect x)) | ||
| 118 | |||
| 119 | (defun ert--set-difference (a b) | ||
| 120 | "A reimplementation of `set-difference'. Subtract the set B from the set A. | ||
| 121 | |||
| 122 | Elements are compared using `eql'." | ||
| 123 | (cl-loop for x in a | ||
| 124 | unless (memql x b) | ||
| 125 | collect x)) | ||
| 126 | |||
| 127 | (defun ert--set-difference-eq (a b) | ||
| 128 | "A reimplementation of `set-difference'. Subtract the set B from the set A. | ||
| 129 | |||
| 130 | Elements are compared using `eq'." | ||
| 131 | (cl-loop for x in a | ||
| 132 | unless (memq x b) | ||
| 133 | collect x)) | ||
| 134 | |||
| 135 | (defun ert--union (a b) | ||
| 136 | "A reimplementation of `union'. Compute the union of the sets A and B. | ||
| 137 | |||
| 138 | Elements are compared using `eql'." | ||
| 139 | (append a (ert--set-difference b a))) | ||
| 140 | |||
| 141 | (eval-and-compile | ||
| 142 | (defvar ert--gensym-counter 0)) | ||
| 143 | |||
| 144 | (eval-and-compile | ||
| 145 | (defun ert--gensym (&optional prefix) | ||
| 146 | "Only allows string PREFIX, not compatible with CL." | ||
| 147 | (unless prefix (setq prefix "G")) | ||
| 148 | (make-symbol (format "%s%s" | ||
| 149 | prefix | ||
| 150 | (prog1 ert--gensym-counter | ||
| 151 | (cl-incf ert--gensym-counter)))))) | ||
| 152 | |||
| 153 | (defun ert--coerce-to-vector (x) | ||
| 154 | "Coerce X to a vector." | ||
| 155 | (when (char-table-p x) (error "Not supported")) | ||
| 156 | (if (vectorp x) | ||
| 157 | x | ||
| 158 | (vconcat x))) | ||
| 159 | |||
| 160 | (cl-defun ert--remove* (x list &key key test) | ||
| 161 | "Does not support all the keywords of remove*." | ||
| 162 | (unless key (setq key #'identity)) | ||
| 163 | (unless test (setq test #'eql)) | ||
| 164 | (cl-loop for y in list | ||
| 165 | unless (funcall test x (funcall key y)) | ||
| 166 | collect y)) | ||
| 167 | |||
| 168 | (defun ert--string-position (c s) | ||
| 169 | "Return the position of the first occurrence of C in S, or nil if none." | ||
| 170 | (cl-loop for i from 0 | ||
| 171 | for x across s | ||
| 172 | when (eql x c) return i)) | ||
| 173 | |||
| 174 | (defun ert--mismatch (a b) | ||
| 175 | "Return index of first element that differs between A and B. | ||
| 176 | |||
| 177 | Like `mismatch'. Uses `equal' for comparison." | ||
| 178 | (cond ((or (listp a) (listp b)) | ||
| 179 | (ert--mismatch (ert--coerce-to-vector a) | ||
| 180 | (ert--coerce-to-vector b))) | ||
| 181 | ((> (length a) (length b)) | ||
| 182 | (ert--mismatch b a)) | ||
| 183 | (t | ||
| 184 | (let ((la (length a)) | ||
| 185 | (lb (length b))) | ||
| 186 | (cl-assert (arrayp a) t) | ||
| 187 | (cl-assert (arrayp b) t) | ||
| 188 | (cl-assert (<= la lb) t) | ||
| 189 | (cl-loop for i below la | ||
| 190 | when (not (equal (aref a i) (aref b i))) return i | ||
| 191 | finally (cl-return (if (/= la lb) | ||
| 192 | la | ||
| 193 | (cl-assert (equal a b) t) | ||
| 194 | nil))))))) | ||
| 195 | |||
| 196 | (defun ert--subseq (seq start &optional end) | ||
| 197 | "Return a subsequence of SEQ from START to END." | ||
| 198 | (when (char-table-p seq) (error "Not supported")) | ||
| 199 | (let ((vector (substring (ert--coerce-to-vector seq) start end))) | ||
| 200 | (cl-etypecase seq | ||
| 201 | (vector vector) | ||
| 202 | (string (concat vector)) | ||
| 203 | (list (append vector nil)) | ||
| 204 | (bool-vector (cl-loop with result | ||
| 205 | = (make-bool-vector (length vector) nil) | ||
| 206 | for i below (length vector) do | ||
| 207 | (setf (aref result i) (aref vector i)) | ||
| 208 | finally (cl-return result))) | ||
| 209 | (char-table (cl-assert nil))))) | ||
| 210 | |||
| 211 | (defun ert-equal-including-properties (a b) | 90 | (defun ert-equal-including-properties (a b) |
| 212 | "Return t if A and B have similar structure and contents. | 91 | "Return t if A and B have similar structure and contents. |
| 213 | 92 | ||
| @@ -258,7 +137,7 @@ Emacs bug 6581 at URL `http://debbugs.gnu.org/cgi/bugreport.cgi?bug=6581'." | |||
| 258 | 137 | ||
| 259 | (defun ert-make-test-unbound (symbol) | 138 | (defun ert-make-test-unbound (symbol) |
| 260 | "Make SYMBOL name no test. Return SYMBOL." | 139 | "Make SYMBOL name no test. Return SYMBOL." |
| 261 | (ert--remprop symbol 'ert--test) | 140 | (cl-remprop symbol 'ert--test) |
| 262 | symbol) | 141 | symbol) |
| 263 | 142 | ||
| 264 | (defun ert--parse-keys-and-body (keys-and-body) | 143 | (defun ert--parse-keys-and-body (keys-and-body) |
| @@ -396,8 +275,8 @@ DATA is displayed to the user and should state the reason of the failure." | |||
| 396 | cl-macro-environment))))) | 275 | cl-macro-environment))))) |
| 397 | (cond | 276 | (cond |
| 398 | ((or (atom form) (ert--special-operator-p (car form))) | 277 | ((or (atom form) (ert--special-operator-p (car form))) |
| 399 | (let ((value (ert--gensym "value-"))) | 278 | (let ((value (cl-gensym "value-"))) |
| 400 | `(let ((,value (ert--gensym "ert-form-evaluation-aborted-"))) | 279 | `(let ((,value (cl-gensym "ert-form-evaluation-aborted-"))) |
| 401 | ,(funcall inner-expander | 280 | ,(funcall inner-expander |
| 402 | `(setq ,value ,form) | 281 | `(setq ,value ,form) |
| 403 | `(list ',whole :form ',form :value ,value) | 282 | `(list ',whole :form ',form :value ,value) |
| @@ -410,10 +289,10 @@ DATA is displayed to the user and should state the reason of the failure." | |||
| 410 | (and (consp fn-name) | 289 | (and (consp fn-name) |
| 411 | (eql (car fn-name) 'lambda) | 290 | (eql (car fn-name) 'lambda) |
| 412 | (listp (cdr fn-name))))) | 291 | (listp (cdr fn-name))))) |
| 413 | (let ((fn (ert--gensym "fn-")) | 292 | (let ((fn (cl-gensym "fn-")) |
| 414 | (args (ert--gensym "args-")) | 293 | (args (cl-gensym "args-")) |
| 415 | (value (ert--gensym "value-")) | 294 | (value (cl-gensym "value-")) |
| 416 | (default-value (ert--gensym "ert-form-evaluation-aborted-"))) | 295 | (default-value (cl-gensym "ert-form-evaluation-aborted-"))) |
| 417 | `(let ((,fn (function ,fn-name)) | 296 | `(let ((,fn (function ,fn-name)) |
| 418 | (,args (list ,@arg-forms))) | 297 | (,args (list ,@arg-forms))) |
| 419 | (let ((,value ',default-value)) | 298 | (let ((,value ',default-value)) |
| @@ -450,7 +329,7 @@ FORM-DESCRIPTION-FORM before it has called INNER-FORM." | |||
| 450 | (ert--expand-should-1 | 329 | (ert--expand-should-1 |
| 451 | whole form | 330 | whole form |
| 452 | (lambda (inner-form form-description-form value-var) | 331 | (lambda (inner-form form-description-form value-var) |
| 453 | (let ((form-description (ert--gensym "form-description-"))) | 332 | (let ((form-description (cl-gensym "form-description-"))) |
| 454 | `(let (,form-description) | 333 | `(let (,form-description) |
| 455 | ,(funcall inner-expander | 334 | ,(funcall inner-expander |
| 456 | `(unwind-protect | 335 | `(unwind-protect |
| @@ -491,7 +370,7 @@ and aborts the current test as failed if it doesn't." | |||
| 491 | (list type) | 370 | (list type) |
| 492 | (symbol (list type))))) | 371 | (symbol (list type))))) |
| 493 | (cl-assert signaled-conditions) | 372 | (cl-assert signaled-conditions) |
| 494 | (unless (ert--intersection signaled-conditions handled-conditions) | 373 | (unless (cl-intersection signaled-conditions handled-conditions) |
| 495 | (ert-fail (append | 374 | (ert-fail (append |
| 496 | (funcall form-description-fn) | 375 | (funcall form-description-fn) |
| 497 | (list | 376 | (list |
| @@ -528,8 +407,8 @@ failed." | |||
| 528 | `(should-error ,form ,@keys) | 407 | `(should-error ,form ,@keys) |
| 529 | form | 408 | form |
| 530 | (lambda (inner-form form-description-form value-var) | 409 | (lambda (inner-form form-description-form value-var) |
| 531 | (let ((errorp (ert--gensym "errorp")) | 410 | (let ((errorp (cl-gensym "errorp")) |
| 532 | (form-description-fn (ert--gensym "form-description-fn-"))) | 411 | (form-description-fn (cl-gensym "form-description-fn-"))) |
| 533 | `(let ((,errorp nil) | 412 | `(let ((,errorp nil) |
| 534 | (,form-description-fn (lambda () ,form-description-form))) | 413 | (,form-description-fn (lambda () ,form-description-form))) |
| 535 | (condition-case -condition- | 414 | (condition-case -condition- |
| @@ -591,7 +470,7 @@ Returns nil if they are." | |||
| 591 | `(proper-lists-of-different-length ,(length a) ,(length b) | 470 | `(proper-lists-of-different-length ,(length a) ,(length b) |
| 592 | ,a ,b | 471 | ,a ,b |
| 593 | first-mismatch-at | 472 | first-mismatch-at |
| 594 | ,(ert--mismatch a b)) | 473 | ,(cl-mismatch a b :test 'equal)) |
| 595 | (cl-loop for i from 0 | 474 | (cl-loop for i from 0 |
| 596 | for ai in a | 475 | for ai in a |
| 597 | for bi in b | 476 | for bi in b |
| @@ -611,7 +490,7 @@ Returns nil if they are." | |||
| 611 | ,a ,b | 490 | ,a ,b |
| 612 | ,@(unless (char-table-p a) | 491 | ,@(unless (char-table-p a) |
| 613 | `(first-mismatch-at | 492 | `(first-mismatch-at |
| 614 | ,(ert--mismatch a b)))) | 493 | ,(cl-mismatch a b :test 'equal)))) |
| 615 | (cl-loop for i from 0 | 494 | (cl-loop for i from 0 |
| 616 | for ai across a | 495 | for ai across a |
| 617 | for bi across b | 496 | for bi across b |
| @@ -656,8 +535,8 @@ key/value pairs in each list does not matter." | |||
| 656 | ;; work, so let's punt on it for now. | 535 | ;; work, so let's punt on it for now. |
| 657 | (let* ((keys-a (ert--significant-plist-keys a)) | 536 | (let* ((keys-a (ert--significant-plist-keys a)) |
| 658 | (keys-b (ert--significant-plist-keys b)) | 537 | (keys-b (ert--significant-plist-keys b)) |
| 659 | (keys-in-a-not-in-b (ert--set-difference-eq keys-a keys-b)) | 538 | (keys-in-a-not-in-b (cl-set-difference keys-a keys-b :test 'eq)) |
| 660 | (keys-in-b-not-in-a (ert--set-difference-eq keys-b keys-a))) | 539 | (keys-in-b-not-in-a (cl-set-difference keys-b keys-a :test 'eq))) |
| 661 | (cl-flet ((explain-with-key (key) | 540 | (cl-flet ((explain-with-key (key) |
| 662 | (let ((value-a (plist-get a key)) | 541 | (let ((value-a (plist-get a key)) |
| 663 | (value-b (plist-get b key))) | 542 | (value-b (plist-get b key))) |
| @@ -1090,7 +969,7 @@ contained in UNIVERSE." | |||
| 1090 | (cl-etypecase universe | 969 | (cl-etypecase universe |
| 1091 | ((member t) (mapcar #'ert-get-test | 970 | ((member t) (mapcar #'ert-get-test |
| 1092 | (apropos-internal selector #'ert-test-boundp))) | 971 | (apropos-internal selector #'ert-test-boundp))) |
| 1093 | (list (ert--remove-if-not (lambda (test) | 972 | (list (cl-remove-if-not (lambda (test) |
| 1094 | (and (ert-test-name test) | 973 | (and (ert-test-name test) |
| 1095 | (string-match selector | 974 | (string-match selector |
| 1096 | (ert-test-name test)))) | 975 | (ert-test-name test)))) |
| @@ -1123,13 +1002,13 @@ contained in UNIVERSE." | |||
| 1123 | (not | 1002 | (not |
| 1124 | (cl-assert (eql (length operands) 1)) | 1003 | (cl-assert (eql (length operands) 1)) |
| 1125 | (let ((all-tests (ert-select-tests 't universe))) | 1004 | (let ((all-tests (ert-select-tests 't universe))) |
| 1126 | (ert--set-difference all-tests | 1005 | (cl-set-difference all-tests |
| 1127 | (ert-select-tests (car operands) | 1006 | (ert-select-tests (car operands) |
| 1128 | all-tests)))) | 1007 | all-tests)))) |
| 1129 | (or | 1008 | (or |
| 1130 | (cl-case (length operands) | 1009 | (cl-case (length operands) |
| 1131 | (0 (ert-select-tests 'nil universe)) | 1010 | (0 (ert-select-tests 'nil universe)) |
| 1132 | (t (ert--union (ert-select-tests (car operands) universe) | 1011 | (t (cl-union (ert-select-tests (car operands) universe) |
| 1133 | (ert-select-tests `(or ,@(cdr operands)) | 1012 | (ert-select-tests `(or ,@(cdr operands)) |
| 1134 | universe))))) | 1013 | universe))))) |
| 1135 | (tag | 1014 | (tag |
| @@ -1141,7 +1020,7 @@ contained in UNIVERSE." | |||
| 1141 | universe))) | 1020 | universe))) |
| 1142 | (satisfies | 1021 | (satisfies |
| 1143 | (cl-assert (eql (length operands) 1)) | 1022 | (cl-assert (eql (length operands) 1)) |
| 1144 | (ert--remove-if-not (car operands) | 1023 | (cl-remove-if-not (car operands) |
| 1145 | (ert-select-tests 't universe)))))))) | 1024 | (ert-select-tests 't universe)))))))) |
| 1146 | 1025 | ||
| 1147 | (defun ert--insert-human-readable-selector (selector) | 1026 | (defun ert--insert-human-readable-selector (selector) |
| @@ -1285,7 +1164,7 @@ Also changes the counters in STATS to match." | |||
| 1285 | "Create a new `ert--stats' object for running TESTS. | 1164 | "Create a new `ert--stats' object for running TESTS. |
| 1286 | 1165 | ||
| 1287 | SELECTOR is the selector that was used to select TESTS." | 1166 | SELECTOR is the selector that was used to select TESTS." |
| 1288 | (setq tests (ert--coerce-to-vector tests)) | 1167 | (setq tests (cl-coerce tests 'vector)) |
| 1289 | (let ((map (make-hash-table :size (length tests)))) | 1168 | (let ((map (make-hash-table :size (length tests)))) |
| 1290 | (cl-loop for i from 0 | 1169 | (cl-loop for i from 0 |
| 1291 | for test across tests | 1170 | for test across tests |
| @@ -1548,10 +1427,10 @@ This can be used as an inverse of `add-to-list'." | |||
| 1548 | (unless key (setq key #'identity)) | 1427 | (unless key (setq key #'identity)) |
| 1549 | (unless test (setq test #'equal)) | 1428 | (unless test (setq test #'equal)) |
| 1550 | (setf (symbol-value list-var) | 1429 | (setf (symbol-value list-var) |
| 1551 | (ert--remove* element | 1430 | (cl-remove element |
| 1552 | (symbol-value list-var) | 1431 | (symbol-value list-var) |
| 1553 | :key key | 1432 | :key key |
| 1554 | :test test))) | 1433 | :test test))) |
| 1555 | 1434 | ||
| 1556 | 1435 | ||
| 1557 | ;;; Some basic interactive functions. | 1436 | ;;; Some basic interactive functions. |
| @@ -1810,7 +1689,7 @@ BEGIN and END specify a region in the current buffer." | |||
| 1810 | "Return the first line of S, or S if it contains no newlines. | 1689 | "Return the first line of S, or S if it contains no newlines. |
| 1811 | 1690 | ||
| 1812 | The return value does not include the line terminator." | 1691 | The return value does not include the line terminator." |
| 1813 | (substring s 0 (ert--string-position ?\n s))) | 1692 | (substring s 0 (cl-position ?\n s))) |
| 1814 | 1693 | ||
| 1815 | (defun ert-face-for-test-result (expectedp) | 1694 | (defun ert-face-for-test-result (expectedp) |
| 1816 | "Return a face that shows whether a test result was expected or unexpected. | 1695 | "Return a face that shows whether a test result was expected or unexpected. |
diff --git a/lisp/emacs-lisp/map-ynp.el b/lisp/emacs-lisp/map-ynp.el index 1919d47687b..56bfe04f9ce 100644 --- a/lisp/emacs-lisp/map-ynp.el +++ b/lisp/emacs-lisp/map-ynp.el | |||
| @@ -131,8 +131,9 @@ Returns the number of actions taken." | |||
| 131 | (unwind-protect | 131 | (unwind-protect |
| 132 | (progn | 132 | (progn |
| 133 | (if (stringp prompter) | 133 | (if (stringp prompter) |
| 134 | (setq prompter (lambda (object) | 134 | (setq prompter (let ((prompter prompter)) |
| 135 | (format prompter object)))) | 135 | (lambda (object) |
| 136 | (format prompter object))))) | ||
| 136 | (while (funcall next) | 137 | (while (funcall next) |
| 137 | (setq prompt (funcall prompter elt)) | 138 | (setq prompt (funcall prompter elt)) |
| 138 | (cond ((stringp prompt) | 139 | (cond ((stringp prompt) |
diff --git a/lisp/emacs-lisp/pcase.el b/lisp/emacs-lisp/pcase.el index e000c343721..511f1480099 100644 --- a/lisp/emacs-lisp/pcase.el +++ b/lisp/emacs-lisp/pcase.el | |||
| @@ -482,12 +482,19 @@ MATCH is the pattern that needs to be matched, of the form: | |||
| 482 | all)) | 482 | all)) |
| 483 | '(:pcase--succeed . nil)))) | 483 | '(:pcase--succeed . nil)))) |
| 484 | 484 | ||
| 485 | (defun pcase--split-pred (upat pat) | 485 | (defun pcase--split-pred (vars upat pat) |
| 486 | ;; FIXME: For predicates like (pred (> a)), two such predicates may | ||
| 487 | ;; actually refer to different variables `a'. | ||
| 488 | (let (test) | 486 | (let (test) |
| 489 | (cond | 487 | (cond |
| 490 | ((equal upat pat) '(:pcase--succeed . :pcase--fail)) | 488 | ((and (equal upat pat) |
| 489 | ;; For predicates like (pred (> a)), two such predicates may | ||
| 490 | ;; actually refer to different variables `a'. | ||
| 491 | (or (and (eq 'pred (car upat)) (symbolp (cadr upat))) | ||
| 492 | ;; FIXME: `vars' gives us the environment in which `upat' will | ||
| 493 | ;; run, but we don't have the environment in which `pat' will | ||
| 494 | ;; run, so we can't do a reliable verification. But let's try | ||
| 495 | ;; and catch at least the easy cases such as (bug#14773). | ||
| 496 | (not (pcase--fgrep (mapcar #'car vars) (cadr upat))))) | ||
| 497 | '(:pcase--succeed . :pcase--fail)) | ||
| 491 | ((and (eq 'pred (car upat)) | 498 | ((and (eq 'pred (car upat)) |
| 492 | (eq 'pred (car-safe pat)) | 499 | (eq 'pred (car-safe pat)) |
| 493 | (or (member (cons (cadr upat) (cadr pat)) | 500 | (or (member (cons (cadr upat) (cadr pat)) |
| @@ -589,7 +596,7 @@ Otherwise, it defers to REST which is a list of branches of the form | |||
| 589 | (if (eq (car upat) 'pred) (pcase--mark-used sym)) | 596 | (if (eq (car upat) 'pred) (pcase--mark-used sym)) |
| 590 | (let* ((splitrest | 597 | (let* ((splitrest |
| 591 | (pcase--split-rest | 598 | (pcase--split-rest |
| 592 | sym (lambda (pat) (pcase--split-pred upat pat)) rest)) | 599 | sym (lambda (pat) (pcase--split-pred vars upat pat)) rest)) |
| 593 | (then-rest (car splitrest)) | 600 | (then-rest (car splitrest)) |
| 594 | (else-rest (cdr splitrest))) | 601 | (else-rest (cdr splitrest))) |
| 595 | (pcase--if (if (and (eq (car upat) 'pred) (symbolp (cadr upat))) | 602 | (pcase--if (if (and (eq (car upat) 'pred) (symbolp (cadr upat))) |
diff --git a/lisp/emulation/viper-cmd.el b/lisp/emulation/viper-cmd.el index e7b371365e4..c39d896f3d3 100644 --- a/lisp/emulation/viper-cmd.el +++ b/lisp/emulation/viper-cmd.el | |||
| @@ -996,93 +996,7 @@ as a Meta key and any number of multiple escapes are allowed." | |||
| 996 | (suspend-emacs)) | 996 | (suspend-emacs)) |
| 997 | (viper-change-state-to-emacs))) | 997 | (viper-change-state-to-emacs))) |
| 998 | 998 | ||
| 999 | |||
| 1000 | ;; Intercept ESC sequences on dumb terminals. | ||
| 1001 | ;; Based on the idea contributed by Marcelino Veiga Tuimil <mveiga@dit.upm.es> | ||
| 1002 | |||
| 1003 | ;; Check if last key was ESC and if so try to reread it as a function key. | ||
| 1004 | ;; But only if there are characters to read during a very short time. | ||
| 1005 | ;; Returns the last event, if any. | ||
| 1006 | (defun viper-envelop-ESC-key () | ||
| 1007 | (let ((event last-input-event) | ||
| 1008 | (keyseq [nil]) | ||
| 1009 | (inhibit-quit t)) | ||
| 1010 | (if (viper-ESC-event-p event) | ||
| 1011 | (progn | ||
| 1012 | ;; Some versions of Emacs (eg., 22.50.8 (?)) have a bug, which makes | ||
| 1013 | ;; even a single ESC into a fast keyseq. To guard against this, we | ||
| 1014 | ;; added a check if there are other events as well. Keep the next | ||
| 1015 | ;; line for the next time the bug reappears, so that will remember to | ||
| 1016 | ;; report it. | ||
| 1017 | ;;(if (and (viper-fast-keysequence-p) unread-command-events) | ||
| 1018 | (if (viper-fast-keysequence-p) ;; for Emacsen without the above bug | ||
| 1019 | (progn | ||
| 1020 | (let (minor-mode-map-alist emulation-mode-map-alists) | ||
| 1021 | (viper-set-unread-command-events event) | ||
| 1022 | (setq keyseq (read-key-sequence nil 'continue-echo)) | ||
| 1023 | ) ; let | ||
| 1024 | ;; If keyseq translates into something that still has ESC | ||
| 1025 | ;; at the beginning, separate ESC from the rest of the seq. | ||
| 1026 | ;; In XEmacs we check for events that are keypress meta-key | ||
| 1027 | ;; and convert them into [escape key] | ||
| 1028 | ;; | ||
| 1029 | ;; This is needed for the following reason: | ||
| 1030 | ;; If ESC is the first symbol, we interpret it as if the | ||
| 1031 | ;; user typed ESC and then quickly some other symbols. | ||
| 1032 | ;; If ESC is not the first one, then the key sequence | ||
| 1033 | ;; entered was apparently translated into a function key or | ||
| 1034 | ;; something (e.g., one may have | ||
| 1035 | ;; (define-key function-key-map "\e[192z" [f11]) | ||
| 1036 | ;; which would translate the escape-sequence generated by | ||
| 1037 | ;; f11 in an xterm window into the symbolic key f11. | ||
| 1038 | ;; | ||
| 1039 | ;; If `first-key' is not an ESC event, we make it into the | ||
| 1040 | ;; last-command-event in order to pretend that this key was | ||
| 1041 | ;; pressed. This is needed to allow arrow keys to be bound to | ||
| 1042 | ;; macros. Otherwise, viper-exec-mapped-kbd-macro will think | ||
| 1043 | ;; that the last event was ESC and so it'll execute whatever is | ||
| 1044 | ;; bound to ESC. (Viper macros can't be bound to | ||
| 1045 | ;; ESC-sequences). | ||
| 1046 | (let* ((first-key (elt keyseq 0)) | ||
| 1047 | (key-mod (event-modifiers first-key))) | ||
| 1048 | (cond ((and (viper-ESC-event-p first-key) | ||
| 1049 | (not (viper-translate-all-ESC-keysequences))) | ||
| 1050 | ;; put keys following ESC on the unread list | ||
| 1051 | ;; and return ESC as the key-sequence | ||
| 1052 | (viper-set-unread-command-events (viper-subseq keyseq 1)) | ||
| 1053 | (setq last-input-event event | ||
| 1054 | keyseq (if (featurep 'emacs) | ||
| 1055 | "\e" | ||
| 1056 | (vector (character-to-event ?\e))))) | ||
| 1057 | ((and (featurep 'xemacs) | ||
| 1058 | (key-press-event-p first-key) | ||
| 1059 | (equal '(meta) key-mod)) | ||
| 1060 | (viper-set-unread-command-events | ||
| 1061 | (vconcat (vector | ||
| 1062 | (character-to-event (event-key first-key))) | ||
| 1063 | (viper-subseq keyseq 1))) | ||
| 1064 | (setq last-input-event event | ||
| 1065 | keyseq (vector (character-to-event ?\e)))) | ||
| 1066 | ((eventp first-key) | ||
| 1067 | (setq last-command-event | ||
| 1068 | (viper-copy-event first-key))) | ||
| 1069 | )) | ||
| 1070 | ) ; end progn | ||
| 1071 | |||
| 1072 | ;; this is escape event with nothing after it | ||
| 1073 | ;; put in unread-command-event and then re-read | ||
| 1074 | (viper-set-unread-command-events event) | ||
| 1075 | (setq keyseq (read-key-sequence nil)) | ||
| 1076 | )) | ||
| 1077 | ;; not an escape event | ||
| 1078 | (setq keyseq (vector event))) | ||
| 1079 | keyseq)) | ||
| 1080 | |||
| 1081 | |||
| 1082 | |||
| 1083 | ;; Listen to ESC key. | 999 | ;; Listen to ESC key. |
| 1084 | ;; If a sequence of keys starting with ESC is issued with very short delays, | ||
| 1085 | ;; interpret these keys in Emacs mode, so ESC won't be interpreted as a Vi key. | ||
| 1086 | (defun viper-intercept-ESC-key () | 1000 | (defun viper-intercept-ESC-key () |
| 1087 | "Function that implements ESC key in Viper emulation of Vi." | 1001 | "Function that implements ESC key in Viper emulation of Vi." |
| 1088 | (interactive) | 1002 | (interactive) |
| @@ -1090,13 +1004,7 @@ as a Meta key and any number of multiple escapes are allowed." | |||
| 1090 | ;; minor-mode map(s) have been temporarily disabled so the ESC | 1004 | ;; minor-mode map(s) have been temporarily disabled so the ESC |
| 1091 | ;; binding to viper-intercept-ESC-key doesn't hide the binding we're | 1005 | ;; binding to viper-intercept-ESC-key doesn't hide the binding we're |
| 1092 | ;; looking for (Bug#9146): | 1006 | ;; looking for (Bug#9146): |
| 1093 | (let* ((event (viper-envelop-ESC-key)) | 1007 | (let* ((cmd 'viper-intercept-ESC-key)) |
| 1094 | (cmd (cond ((equal event viper-ESC-key) | ||
| 1095 | 'viper-intercept-ESC-key) | ||
| 1096 | ((let ((emulation-mode-map-alists nil)) | ||
| 1097 | (key-binding event))) | ||
| 1098 | (t | ||
| 1099 | (error "Viper bell"))))) | ||
| 1100 | 1008 | ||
| 1101 | ;; call the actual function to execute ESC (if no other symbols followed) | 1009 | ;; call the actual function to execute ESC (if no other symbols followed) |
| 1102 | ;; or the key bound to the ESC sequence (if the sequence was issued | 1010 | ;; or the key bound to the ESC sequence (if the sequence was issued |
| @@ -4289,6 +4197,11 @@ cursor move past the beginning of line." | |||
| 4289 | (t | 4197 | (t |
| 4290 | (backward-char 1)))) | 4198 | (backward-char 1)))) |
| 4291 | 4199 | ||
| 4200 | (defun viper-del-forward-char-in-insert () | ||
| 4201 | "Delete 1 char forward if in insert or replace state." | ||
| 4202 | (interactive) | ||
| 4203 | ;; don't put on kill ring | ||
| 4204 | (delete-char 1 nil)) | ||
| 4292 | 4205 | ||
| 4293 | 4206 | ||
| 4294 | ;; join lines. | 4207 | ;; join lines. |
| @@ -4947,7 +4860,7 @@ Please, specify your level now: ") | |||
| 4947 | (interactive) | 4860 | (interactive) |
| 4948 | (if (< viper-expert-level 2) | 4861 | (if (< viper-expert-level 2) |
| 4949 | (save-buffers-kill-emacs) | 4862 | (save-buffers-kill-emacs) |
| 4950 | (save-buffer) | 4863 | (if (buffer-modified-p) (save-buffer)) |
| 4951 | (kill-buffer (current-buffer)))) | 4864 | (kill-buffer (current-buffer)))) |
| 4952 | 4865 | ||
| 4953 | 4866 | ||
diff --git a/lisp/emulation/viper-keym.el b/lisp/emulation/viper-keym.el index 0d9d300ab1a..d33b5f4ed58 100644 --- a/lisp/emulation/viper-keym.el +++ b/lisp/emulation/viper-keym.el | |||
| @@ -192,7 +192,7 @@ Enter as a sexp. Examples: \"\\C-z\", [(control ?z)]." | |||
| 192 | :type 'string | 192 | :type 'string |
| 193 | :group 'viper) | 193 | :group 'viper) |
| 194 | 194 | ||
| 195 | (defvar viper-ESC-key (kbd "ESC") | 195 | (defconst viper-ESC-key [escape] |
| 196 | "Key used to ESC.") | 196 | "Key used to ESC.") |
| 197 | 197 | ||
| 198 | 198 | ||
diff --git a/lisp/emulation/viper.el b/lisp/emulation/viper.el index 7f432cdc143..266af1abf2b 100644 --- a/lisp/emulation/viper.el +++ b/lisp/emulation/viper.el | |||
| @@ -14,7 +14,7 @@ | |||
| 14 | ;; filed in the Emacs bug reporting system against this file, a copy | 14 | ;; filed in the Emacs bug reporting system against this file, a copy |
| 15 | ;; of the bug report be sent to the maintainer's email address. | 15 | ;; of the bug report be sent to the maintainer's email address. |
| 16 | 16 | ||
| 17 | (defconst viper-version "3.14.1 of August 15, 2009" | 17 | (defconst viper-version "3.14.2 of July 4, 2013" |
| 18 | "The current version of Viper") | 18 | "The current version of Viper") |
| 19 | 19 | ||
| 20 | ;; This file is part of GNU Emacs. | 20 | ;; This file is part of GNU Emacs. |
| @@ -411,6 +411,7 @@ widget." | |||
| 411 | dired-mode | 411 | dired-mode |
| 412 | efs-mode | 412 | efs-mode |
| 413 | tar-mode | 413 | tar-mode |
| 414 | egg-status-buffer-mode | ||
| 414 | 415 | ||
| 415 | browse-kill-ring-mode | 416 | browse-kill-ring-mode |
| 416 | recentf-mode | 417 | recentf-mode |
| @@ -660,7 +661,7 @@ user customization, unrelated to Viper. For instance, if the user advised | |||
| 660 | undone. | 661 | undone. |
| 661 | It also can't undo some Viper settings." | 662 | It also can't undo some Viper settings." |
| 662 | (interactive) | 663 | (interactive) |
| 663 | 664 | (viper-setup-ESC-to-escape nil) | |
| 664 | ;; restore non-viper vars | 665 | ;; restore non-viper vars |
| 665 | (setq-default | 666 | (setq-default |
| 666 | next-line-add-newlines | 667 | next-line-add-newlines |
| @@ -825,6 +826,58 @@ It also can't undo some Viper settings." | |||
| 825 | (add-hook 'viper-post-command-hooks 'set-viper-state-in-major-mode t)) | 826 | (add-hook 'viper-post-command-hooks 'set-viper-state-in-major-mode t)) |
| 826 | 827 | ||
| 827 | 828 | ||
| 829 | ;;; Handling of tty's ESC event | ||
| 830 | |||
| 831 | ;; On a tty, an ESC event can either be the user hitting the escape key, or | ||
| 832 | ;; some element of a byte sequence used to encode for example cursor keys. | ||
| 833 | ;; So we try to recognize those events that correspond to the escape key and | ||
| 834 | ;; turn them into `escape' events (same as used under GUIs). The heuristic we | ||
| 835 | ;; use to distinguish the two cases is based, as usual, on a timeout, and on | ||
| 836 | ;; the fact that the special ESC=>escape mapping only takes place if the whole | ||
| 837 | ;; last key-sequence so far is just [?\e], i.e. either we're still in | ||
| 838 | ;; read-key-sequence, or the last read-key-sequence only read [?\e], which | ||
| 839 | ;; should ideally never happen because it should have been mapped to [escape]. | ||
| 840 | |||
| 841 | (defun viper--tty-ESC-filter (map) | ||
| 842 | (if (and (equal (this-single-command-keys) [?\e]) | ||
| 843 | (sit-for (/ viper-fast-keyseq-timeout 1000))) | ||
| 844 | [escape] map)) | ||
| 845 | |||
| 846 | (defun viper--lookup-key (map key) | ||
| 847 | "Kind of like `lookup-key'. | ||
| 848 | Two differences: | ||
| 849 | - KEY is a single key, not a sequence. | ||
| 850 | - the result is the \"raw\" binding, so it can be a `menu-item', rather than the | ||
| 851 | binding contained in that menu item." | ||
| 852 | (catch 'found | ||
| 853 | (map-keymap (lambda (k b) (if (equal key k) (throw 'found b))) map))) | ||
| 854 | |||
| 855 | (defun viper-catch-tty-ESC () | ||
| 856 | "Setup key mappings of current terminal to turn a tty's ESC into `escape'." | ||
| 857 | (when (memq (terminal-live-p (frame-terminal)) '(t pc)) | ||
| 858 | (let ((esc-binding (viper-uncatch-tty-ESC))) | ||
| 859 | (define-key input-decode-map | ||
| 860 | [?\e] `(menu-item "" ,esc-binding :filter viper--tty-ESC-filter))))) | ||
| 861 | |||
| 862 | (defun viper-uncatch-tty-ESC () | ||
| 863 | "Don't hack ESC into `escape' any more." | ||
| 864 | (let ((b (viper--lookup-key input-decode-map ?\e))) | ||
| 865 | (and (eq 'menu-item (car-safe b)) | ||
| 866 | (eq 'viper--tty-ESC-filter (nth 4 b)) | ||
| 867 | (define-key input-decode-map [?\e] (setq b (nth 2 b)))) | ||
| 868 | b)) | ||
| 869 | |||
| 870 | (defun viper-setup-ESC-to-escape (enable) | ||
| 871 | (if enable | ||
| 872 | (add-hook 'tty-setup-hook 'viper-catch-tty-ESC) | ||
| 873 | (remove-hook 'tty-setup-hook 'viper-catch-tty-ESC)) | ||
| 874 | (let ((seen ())) | ||
| 875 | (dolist (frame (frame-list)) | ||
| 876 | (let ((terminal (frame-terminal frame))) | ||
| 877 | (unless (memq terminal seen) | ||
| 878 | (push terminal seen) | ||
| 879 | (with-selected-frame frame | ||
| 880 | (if enable (viper-catch-tty-ESC) (viper-uncatch-tty-ESC)))))))) | ||
| 828 | 881 | ||
| 829 | ;; This sets major mode hooks to make them come up in vi-state. | 882 | ;; This sets major mode hooks to make them come up in vi-state. |
| 830 | (defun viper-set-hooks () | 883 | (defun viper-set-hooks () |
| @@ -837,6 +890,8 @@ It also can't undo some Viper settings." | |||
| 837 | (if (eq (default-value 'major-mode) 'fundamental-mode) | 890 | (if (eq (default-value 'major-mode) 'fundamental-mode) |
| 838 | (setq-default major-mode 'viper-mode)) | 891 | (setq-default major-mode 'viper-mode)) |
| 839 | 892 | ||
| 893 | (viper-setup-ESC-to-escape t) | ||
| 894 | |||
| 840 | (add-hook 'change-major-mode-hook 'viper-major-mode-change-sentinel) | 895 | (add-hook 'change-major-mode-hook 'viper-major-mode-change-sentinel) |
| 841 | (add-hook 'find-file-hooks 'set-viper-state-in-major-mode) | 896 | (add-hook 'find-file-hooks 'set-viper-state-in-major-mode) |
| 842 | 897 | ||
| @@ -847,13 +902,6 @@ It also can't undo some Viper settings." | |||
| 847 | (defvar emerge-startup-hook) | 902 | (defvar emerge-startup-hook) |
| 848 | (add-hook 'emerge-startup-hook 'viper-change-state-to-emacs) | 903 | (add-hook 'emerge-startup-hook 'viper-change-state-to-emacs) |
| 849 | 904 | ||
| 850 | ;; Zap bad bindings in flyspell-mouse-map, which prevent ESC from working | ||
| 851 | ;; over misspelled words (due to the overlay keymaps) | ||
| 852 | (defvar flyspell-mode-hook) | ||
| 853 | (defvar flyspell-mouse-map) | ||
| 854 | (add-hook 'flyspell-mode-hook | ||
| 855 | (lambda () | ||
| 856 | (define-key flyspell-mouse-map viper-ESC-key nil))) | ||
| 857 | ;; if viper is started from .emacs, it might be impossible to get certain | 905 | ;; if viper is started from .emacs, it might be impossible to get certain |
| 858 | ;; info about the display and windows until emacs initialization is complete | 906 | ;; info about the display and windows until emacs initialization is complete |
| 859 | ;; So do it via the window-setup-hook | 907 | ;; So do it via the window-setup-hook |
diff --git a/lisp/faces.el b/lisp/faces.el index 0a3f0551325..9a34aec2549 100644 --- a/lisp/faces.el +++ b/lisp/faces.el | |||
| @@ -2097,6 +2097,10 @@ the above example." | |||
| 2097 | nil)))) | 2097 | nil)))) |
| 2098 | type) | 2098 | type) |
| 2099 | 2099 | ||
| 2100 | (defvar tty-setup-hook nil | ||
| 2101 | "Hook run after running the initialization function of a new text terminal. | ||
| 2102 | This can be used to fine tune the `input-decode-map', for example.") | ||
| 2103 | |||
| 2100 | (defun tty-run-terminal-initialization (frame &optional type) | 2104 | (defun tty-run-terminal-initialization (frame &optional type) |
| 2101 | "Run the special initialization code for the terminal type of FRAME. | 2105 | "Run the special initialization code for the terminal type of FRAME. |
| 2102 | The optional TYPE parameter may be used to override the autodetected | 2106 | The optional TYPE parameter may be used to override the autodetected |
| @@ -2122,7 +2126,8 @@ terminal type to a different value." | |||
| 2122 | type) | 2126 | type) |
| 2123 | (when (fboundp term-init-func) | 2127 | (when (fboundp term-init-func) |
| 2124 | (funcall term-init-func)) | 2128 | (funcall term-init-func)) |
| 2125 | (set-terminal-parameter frame 'terminal-initted term-init-func))))) | 2129 | (set-terminal-parameter frame 'terminal-initted term-init-func) |
| 2130 | (run-hooks 'tty-setup-hook))))) | ||
| 2126 | 2131 | ||
| 2127 | ;; Called from C function init_display to initialize faces of the | 2132 | ;; Called from C function init_display to initialize faces of the |
| 2128 | ;; dumped terminal frame on startup. | 2133 | ;; dumped terminal frame on startup. |
diff --git a/lisp/filenotify.el b/lisp/filenotify.el new file mode 100644 index 00000000000..e170db2dd5f --- /dev/null +++ b/lisp/filenotify.el | |||
| @@ -0,0 +1,324 @@ | |||
| 1 | ;;; filenotify.el --- watch files for changes on disk | ||
| 2 | |||
| 3 | ;; Copyright (C) 2013 Free Software Foundation, Inc. | ||
| 4 | |||
| 5 | ;; Author: Michael Albinus <michael.albinus@gmx.de> | ||
| 6 | |||
| 7 | ;; This file is part of GNU Emacs. | ||
| 8 | |||
| 9 | ;; GNU Emacs is free software: you can redistribute it and/or modify | ||
| 10 | ;; it under the terms of the GNU General Public License as published by | ||
| 11 | ;; the Free Software Foundation, either version 3 of the License, or | ||
| 12 | ;; (at your option) any later version. | ||
| 13 | |||
| 14 | ;; GNU Emacs is distributed in the hope that it will be useful, | ||
| 15 | ;; but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 16 | ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 17 | ;; GNU General Public License for more details. | ||
| 18 | |||
| 19 | ;; You should have received a copy of the GNU General Public License | ||
| 20 | ;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. | ||
| 21 | |||
| 22 | ;;; Commentary | ||
| 23 | |||
| 24 | ;; This package is an abstraction layer from the different low-level | ||
| 25 | ;; file notification packages `gfilenotify', `inotify' and | ||
| 26 | ;; `w32notify'. | ||
| 27 | |||
| 28 | ;;; Code: | ||
| 29 | |||
| 30 | ;;;###autoload | ||
| 31 | (defconst file-notify-support | ||
| 32 | (cond | ||
| 33 | ((featurep 'gfilenotify) 'gfilenotify) | ||
| 34 | ((featurep 'inotify) 'inotify) | ||
| 35 | ((featurep 'w32notify) 'w32notify)) | ||
| 36 | "Non-nil when Emacs has been compiled with file notification support. | ||
| 37 | The value is the name of the low-level file notification package | ||
| 38 | to be used for local file systems. Remote file notifications | ||
| 39 | could use another implementation.") | ||
| 40 | |||
| 41 | (defvar file-notify-descriptors (make-hash-table :test 'equal) | ||
| 42 | "Hash table for registered file notification descriptors. | ||
| 43 | A key in this hash table is the descriptor as returned from | ||
| 44 | `gfilenotify', `inotify', `w32notify' or a file name handler. | ||
| 45 | The value in the hash table is the cons cell (DIR FILE CALLBACK).") | ||
| 46 | |||
| 47 | ;; This function is used by `gfilenotify', `inotify' and `w32notify' events. | ||
| 48 | ;;;###autoload | ||
| 49 | (defun file-notify-handle-event (event) | ||
| 50 | "Handle file system monitoring event. | ||
| 51 | If EVENT is a filewatch event, call its callback. | ||
| 52 | Otherwise, signal a `file-notify-error'." | ||
| 53 | (interactive "e") | ||
| 54 | (if (and (eq (car event) 'file-notify) | ||
| 55 | (>= (length event) 3)) | ||
| 56 | (funcall (nth 2 event) (nth 1 event)) | ||
| 57 | (signal 'file-notify-error | ||
| 58 | (cons "Not a valid file-notify event" event)))) | ||
| 59 | |||
| 60 | (defvar file-notify--pending-events nil | ||
| 61 | "List of pending file notification events for a future `renamed' action. | ||
| 62 | The entries are a list (DESCRIPTOR ACTION FILE COOKIE). ACTION | ||
| 63 | is either `moved-from' or `renamed-from'.") | ||
| 64 | |||
| 65 | (defun file-notify--event-file-name (event) | ||
| 66 | "Return file name of file notification event, or nil." | ||
| 67 | (expand-file-name | ||
| 68 | (or (and (stringp (nth 2 event)) (nth 2 event)) "") | ||
| 69 | (car (gethash (car event) file-notify-descriptors)))) | ||
| 70 | |||
| 71 | ;; Only `gfilenotify' could return two file names. | ||
| 72 | (defun file-notify--event-file1-name (event) | ||
| 73 | "Return second file name of file notification event, or nil. | ||
| 74 | This is available in case a file has been moved." | ||
| 75 | (and (stringp (nth 3 event)) | ||
| 76 | (expand-file-name | ||
| 77 | (nth 3 event) (car (gethash (car event) file-notify-descriptors))))) | ||
| 78 | |||
| 79 | ;; Cookies are offered by `inotify' only. | ||
| 80 | (defun file-notify--event-cookie (event) | ||
| 81 | "Return cookie of file notification event, or nil. | ||
| 82 | This is available in case a file has been moved." | ||
| 83 | (nth 3 event)) | ||
| 84 | |||
| 85 | ;; The callback function used to map between specific flags of the | ||
| 86 | ;; respective file notifications, and the ones we return. | ||
| 87 | (defun file-notify-callback (event) | ||
| 88 | "Handle an EVENT returned from file notification. | ||
| 89 | EVENT is the same one as in `file-notify-handle-event' except the | ||
| 90 | car of that event, which is the symbol `file-notify'." | ||
| 91 | (let* ((desc (car event)) | ||
| 92 | (registered (gethash desc file-notify-descriptors)) | ||
| 93 | (pending-event (assoc desc file-notify--pending-events)) | ||
| 94 | (actions (nth 1 event)) | ||
| 95 | (file (file-notify--event-file-name event)) | ||
| 96 | file1 cookie callback) | ||
| 97 | |||
| 98 | ;; Make actions a list. | ||
| 99 | (unless (consp actions) (setq actions (cons actions nil))) | ||
| 100 | |||
| 101 | ;; Check, that event is meant for us. | ||
| 102 | (unless (setq callback (nth 2 registered)) | ||
| 103 | (setq actions nil)) | ||
| 104 | |||
| 105 | ;; Loop over actions. In fact, more than one action happens only | ||
| 106 | ;; for `inotify'. | ||
| 107 | (dolist (action actions) | ||
| 108 | |||
| 109 | ;; Send pending event, if it doesn't match. | ||
| 110 | (when (and pending-event | ||
| 111 | ;; The cookie doesn't match. | ||
| 112 | (not (eq (file-notify--event-cookie pending-event) | ||
| 113 | (file-notify--event-cookie event))) | ||
| 114 | (or | ||
| 115 | ;; inotify. | ||
| 116 | (and (eq (nth 1 pending-event) 'moved-from) | ||
| 117 | (not (eq action 'moved-to))) | ||
| 118 | ;; w32notify. | ||
| 119 | (and (eq (nth 1 pending-event) 'renamed-from) | ||
| 120 | (not (eq action 'renamed-to))))) | ||
| 121 | (funcall callback | ||
| 122 | (list desc 'deleted | ||
| 123 | (file-notify--event-file-name pending-event))) | ||
| 124 | (setq file-notify--pending-events | ||
| 125 | (delete pending-event file-notify--pending-events))) | ||
| 126 | |||
| 127 | ;; Map action. We ignore all events which cannot be mapped. | ||
| 128 | (setq action | ||
| 129 | (cond | ||
| 130 | ;; gfilenotify. | ||
| 131 | ((memq action '(attribute-changed changed created deleted)) action) | ||
| 132 | ((eq action 'moved) | ||
| 133 | (setq file1 (file-notify--event-file1-name event)) | ||
| 134 | 'renamed) | ||
| 135 | |||
| 136 | ;; inotify. | ||
| 137 | ((eq action 'attrib) 'attribute-changed) | ||
| 138 | ((eq action 'create) 'created) | ||
| 139 | ((eq action 'modify) 'changed) | ||
| 140 | ((memq action '(delete 'delete-self move-self)) 'deleted) | ||
| 141 | ;; Make the event pending. | ||
| 142 | ((eq action 'moved-from) | ||
| 143 | (add-to-list 'file-notify--pending-events | ||
| 144 | (list desc action file | ||
| 145 | (file-notify--event-cookie event))) | ||
| 146 | nil) | ||
| 147 | ;; Look for pending event. | ||
| 148 | ((eq action 'moved-to) | ||
| 149 | (if (null pending-event) | ||
| 150 | 'created | ||
| 151 | (setq file1 file | ||
| 152 | file (file-notify--event-file-name pending-event) | ||
| 153 | file-notify--pending-events | ||
| 154 | (delete pending-event file-notify--pending-events)) | ||
| 155 | 'renamed)) | ||
| 156 | |||
| 157 | ;; w32notify. | ||
| 158 | ((eq action 'added) 'created) | ||
| 159 | ((eq action 'modified) 'changed) | ||
| 160 | ((eq action 'removed) 'deleted) | ||
| 161 | ;; Make the event pending. | ||
| 162 | ((eq 'renamed-from action) | ||
| 163 | (add-to-list 'file-notify--pending-events | ||
| 164 | (list desc action file | ||
| 165 | (file-notify--event-cookie event))) | ||
| 166 | nil) | ||
| 167 | ;; Look for pending event. | ||
| 168 | ((eq 'renamed-to action) | ||
| 169 | (if (null pending-event) | ||
| 170 | 'created | ||
| 171 | (setq file1 file | ||
| 172 | file (file-notify--event-file-name pending-event) | ||
| 173 | file-notify--pending-events | ||
| 174 | (delete pending-event file-notify--pending-events)) | ||
| 175 | 'renamed)))) | ||
| 176 | |||
| 177 | ;; Apply callback. | ||
| 178 | (when (and action | ||
| 179 | (or | ||
| 180 | ;; If there is no relative file name for that watch, | ||
| 181 | ;; we watch the whole directory. | ||
| 182 | (null (nth 1 registered)) | ||
| 183 | ;; File matches. | ||
| 184 | (string-equal | ||
| 185 | (nth 1 registered) (file-name-nondirectory file)) | ||
| 186 | ;; File1 matches. | ||
| 187 | (and (stringp file1) | ||
| 188 | (string-equal | ||
| 189 | (nth 1 registered) (file-name-nondirectory file1))))) | ||
| 190 | (if file1 | ||
| 191 | (funcall callback (list desc action file file1)) | ||
| 192 | (funcall callback (list desc action file))))))) | ||
| 193 | |||
| 194 | (defun file-notify-add-watch (file flags callback) | ||
| 195 | "Add a watch for filesystem events pertaining to FILE. | ||
| 196 | This arranges for filesystem events pertaining to FILE to be reported | ||
| 197 | to Emacs. Use `file-notify-rm-watch' to cancel the watch. | ||
| 198 | |||
| 199 | The returned value is a descriptor for the added watch. If the | ||
| 200 | file cannot be watched for some reason, this function signals a | ||
| 201 | `file-notify-error' error. | ||
| 202 | |||
| 203 | FLAGS is a list of conditions to set what will be watched for. It can | ||
| 204 | include the following symbols: | ||
| 205 | |||
| 206 | `change' -- watch for file changes | ||
| 207 | `attribute-change' -- watch for file attributes changes, like | ||
| 208 | permissions or modification time | ||
| 209 | |||
| 210 | If FILE is a directory, 'change' watches for file creation or | ||
| 211 | deletion in that directory. | ||
| 212 | |||
| 213 | When any event happens, Emacs will call the CALLBACK function passing | ||
| 214 | it a single argument EVENT, which is of the form | ||
| 215 | |||
| 216 | (DESCRIPTOR ACTION FILE [FILE1]) | ||
| 217 | |||
| 218 | DESCRIPTOR is the same object as the one returned by this function. | ||
| 219 | ACTION is the description of the event. It could be any one of the | ||
| 220 | following: | ||
| 221 | |||
| 222 | `created' -- FILE was created | ||
| 223 | `deleted' -- FILE was deleted | ||
| 224 | `changed' -- FILE has changed | ||
| 225 | `renamed' -- FILE has been renamed to FILE1 | ||
| 226 | `attribute-changed' -- a FILE attribute was changed | ||
| 227 | |||
| 228 | FILE is the name of the file whose event is being reported." | ||
| 229 | ;; Check arguments. | ||
| 230 | (unless (stringp file) | ||
| 231 | (signal 'wrong-type-argument (list file))) | ||
| 232 | (setq file (expand-file-name file)) | ||
| 233 | (unless (and (consp flags) | ||
| 234 | (null (delq 'change (delq 'attribute-change (copy-tree flags))))) | ||
| 235 | (signal 'wrong-type-argument (list flags))) | ||
| 236 | (unless (functionp callback) | ||
| 237 | (signal 'wrong-type-argument (list callback))) | ||
| 238 | |||
| 239 | (let* ((handler (find-file-name-handler file 'file-notify-add-watch)) | ||
| 240 | (dir (directory-file-name | ||
| 241 | (if (or (and (not handler) (eq file-notify-support 'w32notify)) | ||
| 242 | (file-directory-p file)) | ||
| 243 | file | ||
| 244 | (file-name-directory file)))) | ||
| 245 | desc func l-flags) | ||
| 246 | |||
| 247 | ;; Check, whether this has been registered already. | ||
| 248 | ; (maphash | ||
| 249 | ; (lambda (key value) | ||
| 250 | ; (when (equal (cons file callback) value) (setq desc key))) | ||
| 251 | ; file-notify-descriptors) | ||
| 252 | |||
| 253 | (unless desc | ||
| 254 | (if handler | ||
| 255 | ;; A file name handler could exist even if there is no local | ||
| 256 | ;; file notification support. | ||
| 257 | (setq desc (funcall | ||
| 258 | handler 'file-notify-add-watch dir flags callback)) | ||
| 259 | |||
| 260 | ;; Check, whether Emacs has been compiled with file | ||
| 261 | ;; notification support. | ||
| 262 | (unless file-notify-support | ||
| 263 | (signal 'file-notify-error | ||
| 264 | '("No file notification package available"))) | ||
| 265 | |||
| 266 | ;; Determine low-level function to be called. | ||
| 267 | (setq func (cond | ||
| 268 | ((eq file-notify-support 'gfilenotify) 'gfile-add-watch) | ||
| 269 | ((eq file-notify-support 'inotify) 'inotify-add-watch) | ||
| 270 | ((eq file-notify-support 'w32notify) 'w32notify-add-watch))) | ||
| 271 | |||
| 272 | ;; Determine respective flags. | ||
| 273 | (if (eq file-notify-support 'gfilenotify) | ||
| 274 | (setq l-flags '(watch-mounts send-moved)) | ||
| 275 | (when (memq 'change flags) | ||
| 276 | (setq | ||
| 277 | l-flags | ||
| 278 | (cond | ||
| 279 | ((eq file-notify-support 'inotify) '(create modify move delete)) | ||
| 280 | ((eq file-notify-support 'w32notify) | ||
| 281 | '(file-name directory-name size last-write-time))))) | ||
| 282 | (when (memq 'attribute-change flags) | ||
| 283 | (add-to-list | ||
| 284 | 'l-flags | ||
| 285 | (cond | ||
| 286 | ((eq file-notify-support 'inotify) 'attrib) | ||
| 287 | ((eq file-notify-support 'w32notify) 'attributes))))) | ||
| 288 | |||
| 289 | ;; Call low-level function. | ||
| 290 | (setq desc (funcall func dir l-flags 'file-notify-callback)))) | ||
| 291 | |||
| 292 | ;; Return descriptor. | ||
| 293 | (puthash desc | ||
| 294 | (list (directory-file-name | ||
| 295 | (if (file-directory-p dir) dir (file-name-directory dir))) | ||
| 296 | (unless (file-directory-p file) | ||
| 297 | (file-name-nondirectory file)) | ||
| 298 | callback) | ||
| 299 | file-notify-descriptors) | ||
| 300 | desc)) | ||
| 301 | |||
| 302 | (defun file-notify-rm-watch (descriptor) | ||
| 303 | "Remove an existing watch specified by its DESCRIPTOR. | ||
| 304 | DESCRIPTOR should be an object returned by `file-notify-add-watch'." | ||
| 305 | (let ((file (car (gethash descriptor file-notify-descriptors))) | ||
| 306 | handler) | ||
| 307 | |||
| 308 | (when (stringp file) | ||
| 309 | (setq handler (find-file-name-handler file 'file-notify-rm-watch)) | ||
| 310 | (if handler | ||
| 311 | (funcall handler 'file-notify-rm-watch descriptor) | ||
| 312 | (funcall | ||
| 313 | (cond | ||
| 314 | ((eq file-notify-support 'gfilenotify) 'gfile-rm-watch) | ||
| 315 | ((eq file-notify-support 'inotify) 'inotify-rm-watch) | ||
| 316 | ((eq file-notify-support 'w32notify) 'w32notify-rm-watch)) | ||
| 317 | descriptor))) | ||
| 318 | |||
| 319 | (remhash descriptor file-notify-descriptors))) | ||
| 320 | |||
| 321 | ;; The end: | ||
| 322 | (provide 'filenotify) | ||
| 323 | |||
| 324 | ;;; filenotify.el ends here | ||
diff --git a/lisp/files.el b/lisp/files.el index e59a9acb7b9..ff4ccec2279 100644 --- a/lisp/files.el +++ b/lisp/files.el | |||
| @@ -316,6 +316,7 @@ A value of nil means don't add newlines. | |||
| 316 | 316 | ||
| 317 | Certain major modes set this locally to the value obtained | 317 | Certain major modes set this locally to the value obtained |
| 318 | from `mode-require-final-newline'." | 318 | from `mode-require-final-newline'." |
| 319 | :safe #'symbolp | ||
| 319 | :type '(choice (const :tag "When visiting" visit) | 320 | :type '(choice (const :tag "When visiting" visit) |
| 320 | (const :tag "When saving" t) | 321 | (const :tag "When saving" t) |
| 321 | (const :tag "When visiting or saving" visit-save) | 322 | (const :tag "When visiting or saving" visit-save) |
| @@ -3878,6 +3879,10 @@ Interactively, confirmation is required unless you supply a prefix argument." | |||
| 3878 | (or buffer-file-name (buffer-name)))))) | 3879 | (or buffer-file-name (buffer-name)))))) |
| 3879 | (and confirm | 3880 | (and confirm |
| 3880 | (file-exists-p filename) | 3881 | (file-exists-p filename) |
| 3882 | ;; NS does its own confirm dialog. | ||
| 3883 | (not (and (eq (framep-on-display) 'ns) | ||
| 3884 | (listp last-nonmenu-event) | ||
| 3885 | use-dialog-box)) | ||
| 3881 | (or (y-or-n-p (format "File `%s' exists; overwrite? " filename)) | 3886 | (or (y-or-n-p (format "File `%s' exists; overwrite? " filename)) |
| 3882 | (error "Canceled"))) | 3887 | (error "Canceled"))) |
| 3883 | (set-visited-file-name filename (not confirm)))) | 3888 | (set-visited-file-name filename (not confirm)))) |
| @@ -4912,6 +4917,11 @@ change the additional actions you can take on files." | |||
| 4912 | (length autosaved-buffers) | 4917 | (length autosaved-buffers) |
| 4913 | (mapconcat 'identity autosaved-buffers ", ")))))))) | 4918 | (mapconcat 'identity autosaved-buffers ", ")))))))) |
| 4914 | 4919 | ||
| 4920 | (defun clear-visited-file-modtime () | ||
| 4921 | "Clear out records of last mod time of visited file. | ||
| 4922 | Next attempt to save will certainly not complain of a discrepancy." | ||
| 4923 | (set-visited-file-modtime 0)) | ||
| 4924 | |||
| 4915 | (defun not-modified (&optional arg) | 4925 | (defun not-modified (&optional arg) |
| 4916 | "Mark current buffer as unmodified, not needing to be saved. | 4926 | "Mark current buffer as unmodified, not needing to be saved. |
| 4917 | With prefix ARG, mark buffer as modified, so \\[save-buffer] will save. | 4927 | With prefix ARG, mark buffer as modified, so \\[save-buffer] will save. |
diff --git a/lisp/filesets.el b/lisp/filesets.el index 978512bd3a4..fbf28dbecbc 100644 --- a/lisp/filesets.el +++ b/lisp/filesets.el | |||
| @@ -149,7 +149,7 @@ is loaded before custom.el, set this variable to t.") | |||
| 149 | (defun filesets-filter-list (lst cond-fn) | 149 | (defun filesets-filter-list (lst cond-fn) |
| 150 | "Remove all elements not conforming to COND-FN from list LST. | 150 | "Remove all elements not conforming to COND-FN from list LST. |
| 151 | COND-FN takes one argument: the current element." | 151 | COND-FN takes one argument: the current element." |
| 152 | ; (remove* 'dummy lst :test (lambda (dummy elt) | 152 | ; (cl-remove 'dummy lst :test (lambda (dummy elt) |
| 153 | ; (not (funcall cond-fn elt))))) | 153 | ; (not (funcall cond-fn elt))))) |
| 154 | (let ((rv nil)) | 154 | (let ((rv nil)) |
| 155 | (dolist (elt lst rv) | 155 | (dolist (elt lst rv) |
| @@ -175,7 +175,7 @@ Like `some', return the first value of FSS-PRED that is non-nil." | |||
| 175 | (let ((fss-rv (funcall fss-pred fss-this))) | 175 | (let ((fss-rv (funcall fss-pred fss-this))) |
| 176 | (when fss-rv | 176 | (when fss-rv |
| 177 | (throw 'exit fss-rv)))))) | 177 | (throw 'exit fss-rv)))))) |
| 178 | ;(fset 'filesets-some 'some) ;; or use the cl function | 178 | ;(fset 'filesets-some 'cl-some) ;; or use the cl function |
| 179 | 179 | ||
| 180 | (defun filesets-member (fsm-item fsm-lst &rest fsm-keys) | 180 | (defun filesets-member (fsm-item fsm-lst &rest fsm-keys) |
| 181 | "Find the first occurrence of FSM-ITEM in FSM-LST. | 181 | "Find the first occurrence of FSM-ITEM in FSM-LST. |
| @@ -186,7 +186,7 @@ key is supported." | |||
| 186 | (filesets-ormap (lambda (fsm-this) | 186 | (filesets-ormap (lambda (fsm-this) |
| 187 | (funcall fsm-test fsm-item fsm-this)) | 187 | (funcall fsm-test fsm-item fsm-this)) |
| 188 | fsm-lst))) | 188 | fsm-lst))) |
| 189 | ;(fset 'filesets-member 'member*) ;; or use the cl function | 189 | ;(fset 'filesets-member 'cl-member) ;; or use the cl function |
| 190 | 190 | ||
| 191 | (defun filesets-sublist (lst beg &optional end) | 191 | (defun filesets-sublist (lst beg &optional end) |
| 192 | "Get the sublist of LST from BEG to END - 1." | 192 | "Get the sublist of LST from BEG to END - 1." |
diff --git a/lisp/frame.el b/lisp/frame.el index 0f8fc523a1b..3ac24a509a0 100644 --- a/lisp/frame.el +++ b/lisp/frame.el | |||
| @@ -1365,7 +1365,11 @@ frame's display)." | |||
| 1365 | 1365 | ||
| 1366 | (defun display-pixel-height (&optional display) | 1366 | (defun display-pixel-height (&optional display) |
| 1367 | "Return the height of DISPLAY's screen in pixels. | 1367 | "Return the height of DISPLAY's screen in pixels. |
| 1368 | For character terminals, each character counts as a single pixel." | 1368 | For character terminals, each character counts as a single pixel. |
| 1369 | For graphical terminals, note that on \"multi-monitor\" setups this | ||
| 1370 | refers to the pixel height for all physical monitors associated | ||
| 1371 | with DISPLAY. To get information for each physical monitor, use | ||
| 1372 | `display-monitor-attributes-list'." | ||
| 1369 | (let ((frame-type (framep-on-display display))) | 1373 | (let ((frame-type (framep-on-display display))) |
| 1370 | (cond | 1374 | (cond |
| 1371 | ((memq frame-type '(x w32 ns)) | 1375 | ((memq frame-type '(x w32 ns)) |
| @@ -1377,7 +1381,11 @@ For character terminals, each character counts as a single pixel." | |||
| 1377 | 1381 | ||
| 1378 | (defun display-pixel-width (&optional display) | 1382 | (defun display-pixel-width (&optional display) |
| 1379 | "Return the width of DISPLAY's screen in pixels. | 1383 | "Return the width of DISPLAY's screen in pixels. |
| 1380 | For character terminals, each character counts as a single pixel." | 1384 | For character terminals, each character counts as a single pixel. |
| 1385 | For graphical terminals, note that on \"multi-monitor\" setups this | ||
| 1386 | refers to the pixel width for all physical monitors associated | ||
| 1387 | with DISPLAY. To get information for each physical monitor, use | ||
| 1388 | `display-monitor-attributes-list'." | ||
| 1381 | (let ((frame-type (framep-on-display display))) | 1389 | (let ((frame-type (framep-on-display display))) |
| 1382 | (cond | 1390 | (cond |
| 1383 | ((memq frame-type '(x w32 ns)) | 1391 | ((memq frame-type '(x w32 ns)) |
| @@ -1408,7 +1416,11 @@ displays not explicitly specified." | |||
| 1408 | (defun display-mm-height (&optional display) | 1416 | (defun display-mm-height (&optional display) |
| 1409 | "Return the height of DISPLAY's screen in millimeters. | 1417 | "Return the height of DISPLAY's screen in millimeters. |
| 1410 | System values can be overridden by `display-mm-dimensions-alist'. | 1418 | System values can be overridden by `display-mm-dimensions-alist'. |
| 1411 | If the information is unavailable, value is nil." | 1419 | If the information is unavailable, value is nil. |
| 1420 | For graphical terminals, note that on \"multi-monitor\" setups this | ||
| 1421 | refers to the height in millimeters for all physical monitors | ||
| 1422 | associated with DISPLAY. To get information for each physical | ||
| 1423 | monitor, use `display-monitor-attributes-list'." | ||
| 1412 | (and (memq (framep-on-display display) '(x w32 ns)) | 1424 | (and (memq (framep-on-display display) '(x w32 ns)) |
| 1413 | (or (cddr (assoc (or display (frame-parameter nil 'display)) | 1425 | (or (cddr (assoc (or display (frame-parameter nil 'display)) |
| 1414 | display-mm-dimensions-alist)) | 1426 | display-mm-dimensions-alist)) |
| @@ -1420,7 +1432,11 @@ If the information is unavailable, value is nil." | |||
| 1420 | (defun display-mm-width (&optional display) | 1432 | (defun display-mm-width (&optional display) |
| 1421 | "Return the width of DISPLAY's screen in millimeters. | 1433 | "Return the width of DISPLAY's screen in millimeters. |
| 1422 | System values can be overridden by `display-mm-dimensions-alist'. | 1434 | System values can be overridden by `display-mm-dimensions-alist'. |
| 1423 | If the information is unavailable, value is nil." | 1435 | If the information is unavailable, value is nil. |
| 1436 | For graphical terminals, note that on \"multi-monitor\" setups this | ||
| 1437 | refers to the width in millimeters for all physical monitors | ||
| 1438 | associated with DISPLAY. To get information for each physical | ||
| 1439 | monitor, use `display-monitor-attributes-list'." | ||
| 1424 | (and (memq (framep-on-display display) '(x w32 ns)) | 1440 | (and (memq (framep-on-display display) '(x w32 ns)) |
| 1425 | (or (cadr (assoc (or display (frame-parameter nil 'display)) | 1441 | (or (cadr (assoc (or display (frame-parameter nil 'display)) |
| 1426 | display-mm-dimensions-alist)) | 1442 | display-mm-dimensions-alist)) |
| @@ -1495,6 +1511,8 @@ The value is one of the symbols `static-gray', `gray-scale', | |||
| 1495 | 1511 | ||
| 1496 | (declare-function x-display-monitor-attributes-list "xfns.c" | 1512 | (declare-function x-display-monitor-attributes-list "xfns.c" |
| 1497 | (&optional terminal)) | 1513 | (&optional terminal)) |
| 1514 | (declare-function w32-display-monitor-attributes-list "w32fns.c" | ||
| 1515 | (&optional display)) | ||
| 1498 | (declare-function ns-display-monitor-attributes-list "nsfns.m" | 1516 | (declare-function ns-display-monitor-attributes-list "nsfns.m" |
| 1499 | (&optional terminal)) | 1517 | (&optional terminal)) |
| 1500 | 1518 | ||
| @@ -1530,6 +1548,8 @@ monitors." | |||
| 1530 | (cond | 1548 | (cond |
| 1531 | ((eq frame-type 'x) | 1549 | ((eq frame-type 'x) |
| 1532 | (x-display-monitor-attributes-list display)) | 1550 | (x-display-monitor-attributes-list display)) |
| 1551 | ((eq frame-type 'w32) | ||
| 1552 | (w32-display-monitor-attributes-list display)) | ||
| 1533 | ((eq frame-type 'ns) | 1553 | ((eq frame-type 'ns) |
| 1534 | (ns-display-monitor-attributes-list display)) | 1554 | (ns-display-monitor-attributes-list display)) |
| 1535 | (t | 1555 | (t |
diff --git a/lisp/gnus/ChangeLog b/lisp/gnus/ChangeLog index 49b45380575..eade6273e95 100644 --- a/lisp/gnus/ChangeLog +++ b/lisp/gnus/ChangeLog | |||
| @@ -1,3 +1,58 @@ | |||
| 1 | 2013-07-10 David Engster <deng@randomsample.de> | ||
| 2 | |||
| 3 | * gnus-start.el (gnus-clean-old-newsrc): Always remove 'unexist' marks | ||
| 4 | if `gnus-newsrc-file-version' does not match `gnus-version'. This | ||
| 5 | fixes a bug in Emacs trunk where the 'unexist' marks were always | ||
| 6 | removed at startup because "Gnus v5.13" was considered smaller than "Ma | ||
| 7 | Gnus v0.03". | ||
| 8 | |||
| 9 | 2013-07-10 Tassilo Horn <tsdh@gnu.org> | ||
| 10 | |||
| 11 | * gnus.el (gnus-summary-line-format): Reference | ||
| 12 | `gnus-user-date-format-alist' for the &user-date; format, not | ||
| 13 | `gnus-summary-user-date-format-alist'. | ||
| 14 | |||
| 15 | 2013-07-08 Lars Magne Ingebrigtsen <larsi@gnus.org> | ||
| 16 | |||
| 17 | * nnml.el (nnml-request-compact-group): Don't bug out if we can't | ||
| 18 | delete files (bug#13481). | ||
| 19 | |||
| 20 | 2013-07-08 Tassilo Horn <tsdh@gnu.org> | ||
| 21 | |||
| 22 | * gnus-registry.el (gnus-registry-remove-extra-data): New function. | ||
| 23 | |||
| 24 | 2013-07-06 Lars Ingebrigtsen <larsi@gnus.org> | ||
| 25 | |||
| 26 | * gnus-art.el (gnus-block-private-groups): Allow `global' methods to | ||
| 27 | display images. | ||
| 28 | |||
| 29 | * gnus.el (gnus-valid-select-methods): Mark nnrss as global. | ||
| 30 | |||
| 31 | * message.el (message-cancel-news): According to | ||
| 32 | <mailman.216.1372942181.12400.help-gnu-emacs@gnu.org>, "cancel" is | ||
| 33 | preferred over "cmsg cancel" in the Subject. | ||
| 34 | |||
| 35 | * nnir.el (nnir-engines): Note that the group specs are regexps | ||
| 36 | (bug#13238). | ||
| 37 | |||
| 38 | * gnus-msg.el (gnus-copy-article-buffer): If the article buffer has | ||
| 39 | gotten read-only text properties, ensure that those aren't heeded when | ||
| 40 | copying stuff over (bug#13434). | ||
| 41 | |||
| 42 | * mm-view.el (mm-inline-text-html): Don't bug out on multipart messages | ||
| 43 | (bug#13762). | ||
| 44 | |||
| 45 | 2013-07-05 David Kastrup <dak@gnu.org> | ||
| 46 | |||
| 47 | * auth-source.el (auth-source-netrc-parse-one): Allow empty strings in | ||
| 48 | authinfo file again (important for blank passwords). This had been | ||
| 49 | broken with 2013-06-15 change. | ||
| 50 | |||
| 51 | 2013-07-03 Katsumi Yamaoka <yamaoka@jpl.org> | ||
| 52 | |||
| 53 | * gnus-sum.el (gnus-summary-from-or-to-or-newsgroups): | ||
| 54 | Revert 2013-01-14 change. | ||
| 55 | |||
| 1 | 2013-07-02 David Engster <deng@randomsample.de> | 56 | 2013-07-02 David Engster <deng@randomsample.de> |
| 2 | 57 | ||
| 3 | * gnus-sum.el (gnus-update-marks): Do not remove empty 'unexist' | 58 | * gnus-sum.el (gnus-update-marks): Do not remove empty 'unexist' |
| @@ -88,7 +143,7 @@ | |||
| 88 | 2013-07-02 Lars Magne Ingebrigtsen <larsi@gnus.org> | 143 | 2013-07-02 Lars Magne Ingebrigtsen <larsi@gnus.org> |
| 89 | 144 | ||
| 90 | * gnus-sum.el (gnus-summary-insert-old-articles): | 145 | * gnus-sum.el (gnus-summary-insert-old-articles): |
| 91 | Don't include unexistent messages. | 146 | Don't include unexisting messages. |
| 92 | 147 | ||
| 93 | 2013-07-02 Lars Magne Ingebrigtsen <larsi@gnus.org> | 148 | 2013-07-02 Lars Magne Ingebrigtsen <larsi@gnus.org> |
| 94 | 149 | ||
diff --git a/lisp/gnus/auth-source.el b/lisp/gnus/auth-source.el index 8cef741cda2..54429b5cfda 100644 --- a/lisp/gnus/auth-source.el +++ b/lisp/gnus/auth-source.el | |||
| @@ -1048,8 +1048,8 @@ Note that the MAX parameter is used so we can exit the parse early." | |||
| 1048 | "Read one thing from the current buffer." | 1048 | "Read one thing from the current buffer." |
| 1049 | (auth-source-netrc-parse-next-interesting) | 1049 | (auth-source-netrc-parse-next-interesting) |
| 1050 | 1050 | ||
| 1051 | (when (or (looking-at "'\\([^']+\\)'") | 1051 | (when (or (looking-at "'\\([^']*\\)'") |
| 1052 | (looking-at "\"\\([^\"]+\\)\"") | 1052 | (looking-at "\"\\([^\"]*\\)\"") |
| 1053 | (looking-at "\\([^ \t\n]+\\)")) | 1053 | (looking-at "\\([^ \t\n]+\\)")) |
| 1054 | (forward-char (length (match-string 0))) | 1054 | (forward-char (length (match-string 0))) |
| 1055 | (auth-source-netrc-parse-next-interesting) | 1055 | (auth-source-netrc-parse-next-interesting) |
diff --git a/lisp/gnus/gnus-art.el b/lisp/gnus/gnus-art.el index 5840aacd7a3..b41ff9c0550 100644 --- a/lisp/gnus/gnus-art.el +++ b/lisp/gnus/gnus-art.el | |||
| @@ -6947,7 +6947,8 @@ If given a prefix, show the hidden text instead." | |||
| 6947 | (set-buffer buf)))))) | 6947 | (set-buffer buf)))))) |
| 6948 | 6948 | ||
| 6949 | (defun gnus-block-private-groups (group) | 6949 | (defun gnus-block-private-groups (group) |
| 6950 | (if (gnus-news-group-p group) | 6950 | (if (or (gnus-news-group-p group) |
| 6951 | (gnus-member-of-valid 'global group)) | ||
| 6951 | ;; Block nothing in news groups. | 6952 | ;; Block nothing in news groups. |
| 6952 | nil | 6953 | nil |
| 6953 | ;; Block everything anywhere else. | 6954 | ;; Block everything anywhere else. |
diff --git a/lisp/gnus/gnus-msg.el b/lisp/gnus/gnus-msg.el index fce9a3633c2..e3f18662af4 100644 --- a/lisp/gnus/gnus-msg.el +++ b/lisp/gnus/gnus-msg.el | |||
| @@ -920,6 +920,7 @@ header line with the old Message-ID." | |||
| 920 | (with-current-buffer article-buffer | 920 | (with-current-buffer article-buffer |
| 921 | (let ((gnus-newsgroup-charset (or gnus-article-charset | 921 | (let ((gnus-newsgroup-charset (or gnus-article-charset |
| 922 | gnus-newsgroup-charset)) | 922 | gnus-newsgroup-charset)) |
| 923 | (inhibit-read-only t) | ||
| 923 | (gnus-newsgroup-ignored-charsets | 924 | (gnus-newsgroup-ignored-charsets |
| 924 | (or gnus-article-ignored-charsets | 925 | (or gnus-article-ignored-charsets |
| 925 | gnus-newsgroup-ignored-charsets))) | 926 | gnus-newsgroup-ignored-charsets))) |
diff --git a/lisp/gnus/gnus-registry.el b/lisp/gnus/gnus-registry.el index 5a7dfd82d28..6f2fe78c3d8 100644 --- a/lisp/gnus/gnus-registry.el +++ b/lisp/gnus/gnus-registry.el | |||
| @@ -1186,6 +1186,29 @@ data stored in the registry." | |||
| 1186 | (gnus-select-group-with-message-id group message-id) t) | 1186 | (gnus-select-group-with-message-id group message-id) t) |
| 1187 | (throw 'found t)))))))) | 1187 | (throw 'found t)))))))) |
| 1188 | 1188 | ||
| 1189 | (defun gnus-registry-remove-extra-data (extra) | ||
| 1190 | "Remove tracked EXTRA data from the gnus registry. | ||
| 1191 | EXTRA is a list of symbols. Valid symbols are those contained in | ||
| 1192 | the docs of `gnus-registry-track-extra'. This command is useful | ||
| 1193 | when you stop tracking some extra data and now want to purge it | ||
| 1194 | from your existing entries." | ||
| 1195 | (interactive (list (mapcar 'intern | ||
| 1196 | (completing-read-multiple | ||
| 1197 | "Extra data: " | ||
| 1198 | '("subject" "sender" "recipient"))))) | ||
| 1199 | (when extra | ||
| 1200 | (let ((db gnus-registry-db)) | ||
| 1201 | (registry-reindex db) | ||
| 1202 | (loop for k being the hash-keys of (oref db :data) | ||
| 1203 | using (hash-value v) | ||
| 1204 | do (let ((newv (delq nil (mapcar #'(lambda (entry) | ||
| 1205 | (unless (member (car entry) extra) | ||
| 1206 | entry)) | ||
| 1207 | v)))) | ||
| 1208 | (registry-delete db (list k) nil) | ||
| 1209 | (gnus-registry-insert db k newv))) | ||
| 1210 | (registry-reindex db)))) | ||
| 1211 | |||
| 1189 | ;; TODO: a few things | 1212 | ;; TODO: a few things |
| 1190 | 1213 | ||
| 1191 | (provide 'gnus-registry) | 1214 | (provide 'gnus-registry) |
diff --git a/lisp/gnus/gnus-start.el b/lisp/gnus/gnus-start.el index 084af884930..94803800e0b 100644 --- a/lisp/gnus/gnus-start.el +++ b/lisp/gnus/gnus-start.el | |||
| @@ -2314,8 +2314,9 @@ If FORCE is non-nil, the .newsrc file is read." | |||
| 2314 | (gnus-info-set-marks | 2314 | (gnus-info-set-marks |
| 2315 | info (delete exist (gnus-info-marks info)))))) | 2315 | info (delete exist (gnus-info-marks info)))))) |
| 2316 | (when (or force | 2316 | (when (or force |
| 2317 | (< (gnus-continuum-version gnus-newsrc-file-version) | 2317 | (not (string= gnus-newsrc-file-version gnus-version))) |
| 2318 | (gnus-continuum-version "Ma Gnus v0.03"))) | 2318 | (message (concat "Removing unexist marks because newsrc " |
| 2319 | "version does not match Gnus version.")) | ||
| 2319 | ;; Remove old `exist' marks from old nnimap groups. | 2320 | ;; Remove old `exist' marks from old nnimap groups. |
| 2320 | (dolist (info (cdr gnus-newsrc-alist)) | 2321 | (dolist (info (cdr gnus-newsrc-alist)) |
| 2321 | (let ((exist (assoc 'unexist (gnus-info-marks info)))) | 2322 | (let ((exist (assoc 'unexist (gnus-info-marks info)))) |
diff --git a/lisp/gnus/gnus-sum.el b/lisp/gnus/gnus-sum.el index e136d4f8173..f3918b0a215 100644 --- a/lisp/gnus/gnus-sum.el +++ b/lisp/gnus/gnus-sum.el | |||
| @@ -1525,7 +1525,7 @@ This list will always be a subset of gnus-newsgroup-undownloaded.") | |||
| 1525 | "Range of seen articles in the current newsgroup.") | 1525 | "Range of seen articles in the current newsgroup.") |
| 1526 | 1526 | ||
| 1527 | (defvar gnus-newsgroup-unexist nil | 1527 | (defvar gnus-newsgroup-unexist nil |
| 1528 | "Range of unexistent articles in the current newsgroup.") | 1528 | "Range of unexisting articles in the current newsgroup.") |
| 1529 | 1529 | ||
| 1530 | (defvar gnus-newsgroup-articles nil | 1530 | (defvar gnus-newsgroup-articles nil |
| 1531 | "List of articles in the current newsgroup.") | 1531 | "List of articles in the current newsgroup.") |
| @@ -3657,18 +3657,17 @@ buffer that was in action when the last article was fetched." | |||
| 3657 | (or (car (funcall gnus-extract-address-components from)) | 3657 | (or (car (funcall gnus-extract-address-components from)) |
| 3658 | from)) | 3658 | from)) |
| 3659 | 3659 | ||
| 3660 | (defun gnus-summary-from-or-to-or-newsgroups (header from) | 3660 | (defun gnus-summary-from-or-to-or-newsgroups (header gnus-tmp-from) |
| 3661 | (let ((mail-parse-charset gnus-newsgroup-charset) | 3661 | (let ((mail-parse-charset gnus-newsgroup-charset) |
| 3662 | (ignored-from-addresses (gnus-ignored-from-addresses)) | 3662 | (ignored-from-addresses (gnus-ignored-from-addresses)) |
| 3663 | ;; Is it really necessary to do this next part for each summary line? | 3663 | ;; Is it really necessary to do this next part for each summary line? |
| 3664 | ;; Luckily, doesn't seem to slow things down much. | 3664 | ;; Luckily, doesn't seem to slow things down much. |
| 3665 | (mail-parse-ignored-charsets | 3665 | (mail-parse-ignored-charsets |
| 3666 | (with-current-buffer gnus-summary-buffer | 3666 | (with-current-buffer gnus-summary-buffer |
| 3667 | gnus-newsgroup-ignored-charsets)) | 3667 | gnus-newsgroup-ignored-charsets))) |
| 3668 | (address (cadr (gnus-extract-address-components from)))) | ||
| 3669 | (or | 3668 | (or |
| 3670 | (and ignored-from-addresses | 3669 | (and ignored-from-addresses |
| 3671 | (string-match ignored-from-addresses address) | 3670 | (string-match ignored-from-addresses gnus-tmp-from) |
| 3672 | (let ((extra-headers (mail-header-extra header)) | 3671 | (let ((extra-headers (mail-header-extra header)) |
| 3673 | to | 3672 | to |
| 3674 | newsgroups) | 3673 | newsgroups) |
| @@ -3683,11 +3682,13 @@ buffer that was in action when the last article was fetched." | |||
| 3683 | (cdr (assq 'Newsgroups extra-headers)) | 3682 | (cdr (assq 'Newsgroups extra-headers)) |
| 3684 | (and | 3683 | (and |
| 3685 | (memq 'Newsgroups gnus-extra-headers) | 3684 | (memq 'Newsgroups gnus-extra-headers) |
| 3686 | (eq (car (gnus-find-method-for-group | 3685 | (eq (car (gnus-find-method-for-group |
| 3687 | gnus-newsgroup-name)) 'nntp) | 3686 | gnus-newsgroup-name)) 'nntp) |
| 3688 | (gnus-group-real-name gnus-newsgroup-name)))) | 3687 | (gnus-group-real-name gnus-newsgroup-name)))) |
| 3689 | (concat gnus-summary-newsgroup-prefix newsgroups))))) | 3688 | (concat gnus-summary-newsgroup-prefix newsgroups))))) |
| 3690 | (gnus-string-mark-left-to-right (gnus-summary-extract-address-component from))))) | 3689 | (gnus-string-mark-left-to-right |
| 3690 | (inline | ||
| 3691 | (gnus-summary-extract-address-component gnus-tmp-from)))))) | ||
| 3691 | 3692 | ||
| 3692 | (defun gnus-summary-insert-line (gnus-tmp-header | 3693 | (defun gnus-summary-insert-line (gnus-tmp-header |
| 3693 | gnus-tmp-level gnus-tmp-current | 3694 | gnus-tmp-level gnus-tmp-current |
diff --git a/lisp/gnus/gnus.el b/lisp/gnus/gnus.el index 9a927a1cfab..8741a03b54d 100644 --- a/lisp/gnus/gnus.el +++ b/lisp/gnus/gnus.el | |||
| @@ -1628,7 +1628,7 @@ slower." | |||
| 1628 | ("nnfolder" mail respool address) | 1628 | ("nnfolder" mail respool address) |
| 1629 | ("nngateway" post-mail address prompt-address physical-address) | 1629 | ("nngateway" post-mail address prompt-address physical-address) |
| 1630 | ("nnweb" none) | 1630 | ("nnweb" none) |
| 1631 | ("nnrss" none) | 1631 | ("nnrss" none global) |
| 1632 | ("nnagent" post-mail) | 1632 | ("nnagent" post-mail) |
| 1633 | ("nnimap" post-mail address prompt-address physical-address respool | 1633 | ("nnimap" post-mail address prompt-address physical-address respool |
| 1634 | server-marks) | 1634 | server-marks) |
| @@ -3007,7 +3007,7 @@ with some simple extensions. | |||
| 3007 | summary just like information from any other summary | 3007 | summary just like information from any other summary |
| 3008 | specifier. | 3008 | specifier. |
| 3009 | &user-date; Age sensitive date format. Various date format is | 3009 | &user-date; Age sensitive date format. Various date format is |
| 3010 | defined in `gnus-summary-user-date-format-alist'. | 3010 | defined in `gnus-user-date-format-alist'. |
| 3011 | 3011 | ||
| 3012 | 3012 | ||
| 3013 | The %U (status), %R (replied) and %z (zcore) specs have to be handled | 3013 | The %U (status), %R (replied) and %z (zcore) specs have to be handled |
diff --git a/lisp/gnus/message.el b/lisp/gnus/message.el index c6f5d904677..b35eb9dca12 100644 --- a/lisp/gnus/message.el +++ b/lisp/gnus/message.el | |||
| @@ -7145,7 +7145,7 @@ If ARG, allow editing of the cancellation message." | |||
| 7145 | (erase-buffer) | 7145 | (erase-buffer) |
| 7146 | (insert "Newsgroups: " newsgroups "\n" | 7146 | (insert "Newsgroups: " newsgroups "\n" |
| 7147 | "From: " from "\n" | 7147 | "From: " from "\n" |
| 7148 | "Subject: cmsg cancel " message-id "\n" | 7148 | "Subject: cancel " message-id "\n" |
| 7149 | "Control: cancel " message-id "\n" | 7149 | "Control: cancel " message-id "\n" |
| 7150 | (if distribution | 7150 | (if distribution |
| 7151 | (concat "Distribution: " distribution "\n") | 7151 | (concat "Distribution: " distribution "\n") |
diff --git a/lisp/gnus/mm-view.el b/lisp/gnus/mm-view.el index b1cba27c335..9512a411d81 100644 --- a/lisp/gnus/mm-view.el +++ b/lisp/gnus/mm-view.el | |||
| @@ -419,16 +419,18 @@ | |||
| 419 | (buffer-string))))) | 419 | (buffer-string))))) |
| 420 | 420 | ||
| 421 | (defun mm-inline-text-html (handle) | 421 | (defun mm-inline-text-html (handle) |
| 422 | (let* ((func mm-text-html-renderer) | 422 | (if (stringp (car handle)) |
| 423 | (entry (assq func mm-text-html-renderer-alist)) | 423 | (mapcar 'mm-inline-text-html (cdr handle)) |
| 424 | (inhibit-read-only t)) | 424 | (let* ((func mm-text-html-renderer) |
| 425 | (if entry | 425 | (entry (assq func mm-text-html-renderer-alist)) |
| 426 | (setq func (cdr entry))) | 426 | (inhibit-read-only t)) |
| 427 | (cond | 427 | (if entry |
| 428 | ((functionp func) | 428 | (setq func (cdr entry))) |
| 429 | (funcall func handle)) | 429 | (cond |
| 430 | (t | 430 | ((functionp func) |
| 431 | (apply (car func) handle (cdr func)))))) | 431 | (funcall func handle)) |
| 432 | (t | ||
| 433 | (apply (car func) handle (cdr func))))))) | ||
| 432 | 434 | ||
| 433 | (defun mm-inline-text-vcard (handle) | 435 | (defun mm-inline-text-vcard (handle) |
| 434 | (let ((inhibit-read-only t)) | 436 | (let ((inhibit-read-only t)) |
diff --git a/lisp/gnus/nnir.el b/lisp/gnus/nnir.el index 22dee30e8fa..4dd123bf2c7 100644 --- a/lisp/gnus/nnir.el +++ b/lisp/gnus/nnir.el | |||
| @@ -548,15 +548,15 @@ that it is for notmuch, not Namazu." | |||
| 548 | (gmane nnir-run-gmane | 548 | (gmane nnir-run-gmane |
| 549 | ((gmane-author . "Gmane Author: "))) | 549 | ((gmane-author . "Gmane Author: "))) |
| 550 | (swish++ nnir-run-swish++ | 550 | (swish++ nnir-run-swish++ |
| 551 | ((swish++-group . "Swish++ Group spec: "))) | 551 | ((swish++-group . "Swish++ Group spec (regexp): "))) |
| 552 | (swish-e nnir-run-swish-e | 552 | (swish-e nnir-run-swish-e |
| 553 | ((swish-e-group . "Swish-e Group spec: "))) | 553 | ((swish-e-group . "Swish-e Group spec (regexp): "))) |
| 554 | (namazu nnir-run-namazu | 554 | (namazu nnir-run-namazu |
| 555 | ()) | 555 | ()) |
| 556 | (notmuch nnir-run-notmuch | 556 | (notmuch nnir-run-notmuch |
| 557 | ()) | 557 | ()) |
| 558 | (hyrex nnir-run-hyrex | 558 | (hyrex nnir-run-hyrex |
| 559 | ((hyrex-group . "Hyrex Group spec: "))) | 559 | ((hyrex-group . "Hyrex Group spec (regexp): "))) |
| 560 | (find-grep nnir-run-find-grep | 560 | (find-grep nnir-run-find-grep |
| 561 | ((grep-options . "Grep options: ")))) | 561 | ((grep-options . "Grep options: ")))) |
| 562 | "Alist of supported search engines. | 562 | "Alist of supported search engines. |
diff --git a/lisp/gnus/nnml.el b/lisp/gnus/nnml.el index 64e1ee11977..05d0c902340 100644 --- a/lisp/gnus/nnml.el +++ b/lisp/gnus/nnml.el | |||
| @@ -1094,7 +1094,10 @@ Use the nov database for the current group if available." | |||
| 1094 | (concat group ":" new-number-string))) | 1094 | (concat group ":" new-number-string))) |
| 1095 | ;; Save to the new file: | 1095 | ;; Save to the new file: |
| 1096 | (nnmail-write-region (point-min) (point-max) newfile)) | 1096 | (nnmail-write-region (point-min) (point-max) newfile)) |
| 1097 | (funcall nnmail-delete-file-function oldfile)) | 1097 | (condition-case () |
| 1098 | (funcall nnmail-delete-file-function oldfile) | ||
| 1099 | (file-error | ||
| 1100 | (message "Couldn't delete %s" oldfile)))) | ||
| 1098 | ;; 2/ Update all marks for this article: | 1101 | ;; 2/ Update all marks for this article: |
| 1099 | ;; #### NOTE: it is possible that the new article number | 1102 | ;; #### NOTE: it is possible that the new article number |
| 1100 | ;; #### already belongs to a range, whereas the corresponding | 1103 | ;; #### already belongs to a range, whereas the corresponding |
diff --git a/lisp/ibuffer.el b/lisp/ibuffer.el index 8f7d584d00b..a4f18201a3f 100644 --- a/lisp/ibuffer.el +++ b/lisp/ibuffer.el | |||
| @@ -462,6 +462,7 @@ directory, like `default-directory'." | |||
| 462 | (define-key map (kbd "M-g") 'ibuffer-jump-to-buffer) | 462 | (define-key map (kbd "M-g") 'ibuffer-jump-to-buffer) |
| 463 | (define-key map (kbd "M-s a C-s") 'ibuffer-do-isearch) | 463 | (define-key map (kbd "M-s a C-s") 'ibuffer-do-isearch) |
| 464 | (define-key map (kbd "M-s a M-C-s") 'ibuffer-do-isearch-regexp) | 464 | (define-key map (kbd "M-s a M-C-s") 'ibuffer-do-isearch-regexp) |
| 465 | (define-key map (kbd "M-s a C-o") 'ibuffer-do-occur) | ||
| 465 | (define-key map (kbd "DEL") 'ibuffer-unmark-backward) | 466 | (define-key map (kbd "DEL") 'ibuffer-unmark-backward) |
| 466 | (define-key map (kbd "M-DEL") 'ibuffer-unmark-all) | 467 | (define-key map (kbd "M-DEL") 'ibuffer-unmark-all) |
| 467 | (define-key map (kbd "* *") 'ibuffer-unmark-all) | 468 | (define-key map (kbd "* *") 'ibuffer-unmark-all) |
diff --git a/lisp/ido.el b/lisp/ido.el index 4a4ecdcdb1a..43a0cc0a665 100644 --- a/lisp/ido.el +++ b/lisp/ido.el | |||
| @@ -782,21 +782,29 @@ remaining completion. If absent, elements 5 and 6 are used instead." | |||
| 782 | :group 'ido) | 782 | :group 'ido) |
| 783 | 783 | ||
| 784 | (defcustom ido-use-virtual-buffers nil | 784 | (defcustom ido-use-virtual-buffers nil |
| 785 | "If non-nil, refer to past buffers as well as existing ones. | 785 | "Specify how virtual buffers should be used. |
| 786 | The value can be one of the following: | ||
| 787 | |||
| 788 | nil: No virtual buffers are used. | ||
| 789 | auto: Use virtual bufferw when the current input matches no | ||
| 790 | existing buffers. | ||
| 791 | t: Always use virtual buffers. | ||
| 792 | |||
| 786 | Essentially it works as follows: Say you are visiting a file and | 793 | Essentially it works as follows: Say you are visiting a file and |
| 787 | the buffer gets cleaned up by midnight.el. Later, you want to | 794 | the buffer gets cleaned up by midnight.el. Later, you want to |
| 788 | switch to that buffer, but find it's no longer open. With | 795 | switch to that buffer, but find it's no longer open. With virtual |
| 789 | virtual buffers enabled, the buffer name stays in the buffer | 796 | buffers enabled, the buffer name stays in the buffer list (using |
| 790 | list (using the `ido-virtual' face, and always at the end), and if | 797 | the `ido-virtual' face, and always at the end), and if you select |
| 791 | you select it, it opens the file back up again. This allows you | 798 | it, it opens the file back up again. This allows you to think |
| 792 | to think less about whether recently opened files are still open | 799 | less about whether recently opened files are still open or not. |
| 793 | or not. Most of the time you can quit Emacs, restart, and then | 800 | Most of the time you can quit Emacs, restart, and then switch to |
| 794 | switch to a file buffer that was previously open as if it still | 801 | a file buffer that was previously open as if it still were. This |
| 795 | were. | 802 | feature relies upon the `recentf' package, which will be enabled |
| 796 | This feature relies upon the `recentf' package, which will be | 803 | if this variable is configured to a non-nil value." |
| 797 | enabled if this variable is configured to a non-nil value." | 804 | :version "24.4" |
| 798 | :version "24.1" | 805 | :type '(choice (const :tag "Always" t) |
| 799 | :type 'boolean | 806 | (const :tag "Automatic" auto) |
| 807 | (const :tag "Never" nil)) | ||
| 800 | :group 'ido) | 808 | :group 'ido) |
| 801 | 809 | ||
| 802 | (defcustom ido-use-faces t | 810 | (defcustom ido-use-faces t |
| @@ -1103,6 +1111,9 @@ Only used if `ido-use-virtual-buffers' is non-nil.") | |||
| 1103 | ;; Don't process ido-ignore- lists once. | 1111 | ;; Don't process ido-ignore- lists once. |
| 1104 | (defvar ido-process-ignore-lists-inhibit) | 1112 | (defvar ido-process-ignore-lists-inhibit) |
| 1105 | 1113 | ||
| 1114 | ;; Is ido using virtual buffers? | ||
| 1115 | (defvar ido-enable-virtual-buffers) | ||
| 1116 | |||
| 1106 | ;; Buffer from which ido was entered. | 1117 | ;; Buffer from which ido was entered. |
| 1107 | (defvar ido-entry-buffer) | 1118 | (defvar ido-entry-buffer) |
| 1108 | 1119 | ||
| @@ -2202,7 +2213,8 @@ If cursor is not at the end of the user input, move to end of input." | |||
| 2202 | (ido-current-directory nil) | 2213 | (ido-current-directory nil) |
| 2203 | (ido-directory-nonreadable nil) | 2214 | (ido-directory-nonreadable nil) |
| 2204 | (ido-directory-too-big nil) | 2215 | (ido-directory-too-big nil) |
| 2205 | (ido-use-virtual-buffers ido-use-virtual-buffers) | 2216 | (ido-enable-virtual-buffers (and ido-use-virtual-buffers |
| 2217 | (not (eq ido-use-virtual-buffers 'auto)))) | ||
| 2206 | (require-match (confirm-nonexistent-file-or-buffer)) | 2218 | (require-match (confirm-nonexistent-file-or-buffer)) |
| 2207 | (buf (ido-read-internal 'buffer (or prompt "Buffer: ") 'ido-buffer-history default | 2219 | (buf (ido-read-internal 'buffer (or prompt "Buffer: ") 'ido-buffer-history default |
| 2208 | require-match initial)) | 2220 | require-match initial)) |
| @@ -2243,7 +2255,8 @@ If cursor is not at the end of the user input, move to end of input." | |||
| 2243 | (ido-visit-buffer buf method t))) | 2255 | (ido-visit-buffer buf method t))) |
| 2244 | 2256 | ||
| 2245 | ;; check for a virtual buffer reference | 2257 | ;; check for a virtual buffer reference |
| 2246 | ((and ido-use-virtual-buffers ido-virtual-buffers | 2258 | ((and ido-enable-virtual-buffers |
| 2259 | ido-virtual-buffers | ||
| 2247 | (setq filename (assoc buf ido-virtual-buffers))) | 2260 | (setq filename (assoc buf ido-virtual-buffers))) |
| 2248 | (ido-visit-buffer (find-file-noselect (cdr filename)) method t)) | 2261 | (ido-visit-buffer (find-file-noselect (cdr filename)) method t)) |
| 2249 | 2262 | ||
| @@ -2734,7 +2747,11 @@ C-x C-f ... C-d enter `dired' on current directory." | |||
| 2734 | See `ido-use-virtual-buffers' for explanation of virtual buffer." | 2747 | See `ido-use-virtual-buffers' for explanation of virtual buffer." |
| 2735 | (interactive) | 2748 | (interactive) |
| 2736 | (when (and ido-mode (eq ido-cur-item 'buffer)) | 2749 | (when (and ido-mode (eq ido-cur-item 'buffer)) |
| 2737 | (setq ido-use-virtual-buffers (not ido-use-virtual-buffers)) | 2750 | (setq ido-enable-virtual-buffers |
| 2751 | (if ido-enable-virtual-buffers | ||
| 2752 | nil | ||
| 2753 | ;; Use `always' instead of t for `ido-exhibit'. | ||
| 2754 | 'always)) | ||
| 2738 | (setq ido-text-init ido-text) | 2755 | (setq ido-text-init ido-text) |
| 2739 | (setq ido-exit 'refresh) | 2756 | (setq ido-exit 'refresh) |
| 2740 | (exit-minibuffer))) | 2757 | (exit-minibuffer))) |
| @@ -3427,9 +3444,9 @@ it is put to the start of the list." | |||
| 3427 | (nconc ido-temp-list ido-current-buffers) | 3444 | (nconc ido-temp-list ido-current-buffers) |
| 3428 | (setq ido-temp-list ido-current-buffers)) | 3445 | (setq ido-temp-list ido-current-buffers)) |
| 3429 | (if default | 3446 | (if default |
| 3430 | (setq ido-temp-list | 3447 | (setq ido-temp-list |
| 3431 | (cons default (delete default ido-temp-list)))) | 3448 | (cons default (delete default ido-temp-list)))) |
| 3432 | (if ido-use-virtual-buffers | 3449 | (if (bound-and-true-p ido-enable-virtual-buffers) |
| 3433 | (ido-add-virtual-buffers-to-list)) | 3450 | (ido-add-virtual-buffers-to-list)) |
| 3434 | (run-hooks 'ido-make-buffer-list-hook) | 3451 | (run-hooks 'ido-make-buffer-list-hook) |
| 3435 | ido-temp-list)) | 3452 | ido-temp-list)) |
| @@ -3444,8 +3461,14 @@ This is to make them appear as if they were \"virtual buffers\"." | |||
| 3444 | (setq ido-virtual-buffers nil) | 3461 | (setq ido-virtual-buffers nil) |
| 3445 | (let (name) | 3462 | (let (name) |
| 3446 | (dolist (head recentf-list) | 3463 | (dolist (head recentf-list) |
| 3447 | (and (setq name (file-name-nondirectory head)) | 3464 | (setq name (file-name-nondirectory head)) |
| 3448 | (null (get-file-buffer head)) | 3465 | ;; In case HEAD is a directory with trailing /. See bug#14552. |
| 3466 | (when (equal name "") | ||
| 3467 | (setq name (file-name-nondirectory (directory-file-name head)))) | ||
| 3468 | (when (equal name "") | ||
| 3469 | (setq name head)) | ||
| 3470 | (and (not (equal name "")) | ||
| 3471 | (null (get-file-buffer head)) | ||
| 3449 | (not (assoc name ido-virtual-buffers)) | 3472 | (not (assoc name ido-virtual-buffers)) |
| 3450 | (not (member name ido-temp-list)) | 3473 | (not (member name ido-temp-list)) |
| 3451 | (not (ido-ignore-item-p name ido-ignore-buffers)) | 3474 | (not (ido-ignore-item-p name ido-ignore-buffers)) |
| @@ -3986,6 +4009,7 @@ If cursor is not at the end of the user input, delete to end of input." | |||
| 3986 | ;;; DELETE CURRENT FILE | 4009 | ;;; DELETE CURRENT FILE |
| 3987 | (defun ido-delete-file-at-head () | 4010 | (defun ido-delete-file-at-head () |
| 3988 | "Delete the file at the head of `ido-matches'. | 4011 | "Delete the file at the head of `ido-matches'. |
| 4012 | Trash the file if `delete-by-moving-to-trash' is non-nil. | ||
| 3989 | If cursor is not at the end of the user input, delete to end of input." | 4013 | If cursor is not at the end of the user input, delete to end of input." |
| 3990 | (interactive) | 4014 | (interactive) |
| 3991 | (if (not (eobp)) | 4015 | (if (not (eobp)) |
| @@ -3998,8 +4022,9 @@ If cursor is not at the end of the user input, delete to end of input." | |||
| 3998 | (file-exists-p file) | 4022 | (file-exists-p file) |
| 3999 | (not (file-directory-p file)) | 4023 | (not (file-directory-p file)) |
| 4000 | (file-writable-p ido-current-directory) | 4024 | (file-writable-p ido-current-directory) |
| 4001 | (yes-or-no-p (concat "Delete " file "? "))) | 4025 | (or delete-by-moving-to-trash |
| 4002 | (delete-file file) | 4026 | (yes-or-no-p (concat "Delete " file "? ")))) |
| 4027 | (delete-file file 'trash) | ||
| 4003 | ;; Check if file still exists. | 4028 | ;; Check if file still exists. |
| 4004 | (if (file-exists-p file) | 4029 | (if (file-exists-p file) |
| 4005 | ;; file could not be deleted | 4030 | ;; file could not be deleted |
| @@ -4457,11 +4482,6 @@ For details of keybindings, see `ido-find-file'." | |||
| 4457 | (setq ido-exit 'refresh) | 4482 | (setq ido-exit 'refresh) |
| 4458 | (exit-minibuffer)) | 4483 | (exit-minibuffer)) |
| 4459 | 4484 | ||
| 4460 | ;; Update the list of matches | ||
| 4461 | (setq ido-text contents) | ||
| 4462 | (ido-set-matches) | ||
| 4463 | (ido-trace "new " ido-matches) | ||
| 4464 | |||
| 4465 | (when (and ido-enter-matching-directory | 4485 | (when (and ido-enter-matching-directory |
| 4466 | ido-matches | 4486 | ido-matches |
| 4467 | (or (eq ido-enter-matching-directory 'first) | 4487 | (or (eq ido-enter-matching-directory 'first) |
| @@ -4475,6 +4495,32 @@ For details of keybindings, see `ido-find-file'." | |||
| 4475 | (setq ido-exit 'refresh) | 4495 | (setq ido-exit 'refresh) |
| 4476 | (exit-minibuffer)) | 4496 | (exit-minibuffer)) |
| 4477 | 4497 | ||
| 4498 | ;; Update the list of matches | ||
| 4499 | (setq ido-text contents) | ||
| 4500 | (ido-set-matches) | ||
| 4501 | (ido-trace "new " ido-matches) | ||
| 4502 | |||
| 4503 | (when (and (boundp 'ido-enable-virtual-buffers) | ||
| 4504 | (not (eq ido-enable-virtual-buffers 'always)) | ||
| 4505 | (eq ido-cur-item 'buffer) | ||
| 4506 | (eq ido-use-virtual-buffers 'auto)) | ||
| 4507 | |||
| 4508 | (when (and (not ido-enable-virtual-buffers) | ||
| 4509 | (not ido-matches)) | ||
| 4510 | (setq ido-text-init ido-text) | ||
| 4511 | (setq ido-enable-virtual-buffers t) | ||
| 4512 | (setq ido-exit 'refresh) | ||
| 4513 | (exit-minibuffer)) | ||
| 4514 | |||
| 4515 | ;; If input matches real buffers turn off virtual buffers. | ||
| 4516 | (when (and ido-enable-virtual-buffers | ||
| 4517 | ido-matches | ||
| 4518 | (ido-set-matches-1 (ido-make-buffer-list-1))) | ||
| 4519 | (setq ido-enable-virtual-buffers nil) | ||
| 4520 | (setq ido-text-init ido-text) | ||
| 4521 | (setq ido-exit 'refresh) | ||
| 4522 | (exit-minibuffer))) | ||
| 4523 | |||
| 4478 | (when (and (not ido-matches) | 4524 | (when (and (not ido-matches) |
| 4479 | (not ido-directory-nonreadable) | 4525 | (not ido-directory-nonreadable) |
| 4480 | (not ido-directory-too-big) | 4526 | (not ido-directory-too-big) |
| @@ -4681,9 +4727,12 @@ Modified from `icomplete-completions'." | |||
| 4681 | 4727 | ||
| 4682 | ;;; Helper functions for other programs | 4728 | ;;; Helper functions for other programs |
| 4683 | 4729 | ||
| 4684 | (put 'dired-do-rename 'ido 'ignore) | ||
| 4685 | (put 'ibuffer-find-file 'ido 'find-file) | 4730 | (put 'ibuffer-find-file 'ido 'find-file) |
| 4731 | (put 'dired 'ido 'dir) | ||
| 4686 | (put 'dired-other-window 'ido 'dir) | 4732 | (put 'dired-other-window 'ido 'dir) |
| 4733 | ;; See http://debbugs.gnu.org/11954 for reasons. | ||
| 4734 | (put 'dired-do-copy 'ido 'ignore) | ||
| 4735 | (put 'dired-do-rename 'ido 'ignore) | ||
| 4687 | 4736 | ||
| 4688 | ;;;###autoload | 4737 | ;;;###autoload |
| 4689 | (defun ido-read-buffer (prompt &optional default require-match) | 4738 | (defun ido-read-buffer (prompt &optional default require-match) |
| @@ -4711,18 +4760,20 @@ See `read-file-name' for additional parameters." | |||
| 4711 | (let (filename) | 4760 | (let (filename) |
| 4712 | (cond | 4761 | (cond |
| 4713 | ((or (eq predicate 'file-directory-p) | 4762 | ((or (eq predicate 'file-directory-p) |
| 4714 | (eq (get this-command 'ido) 'dir) | 4763 | (eq (and (symbolp this-command) |
| 4764 | (get this-command 'ido)) 'dir) | ||
| 4715 | (memq this-command ido-read-file-name-as-directory-commands)) | 4765 | (memq this-command ido-read-file-name-as-directory-commands)) |
| 4716 | (setq filename | 4766 | (setq filename |
| 4717 | (ido-read-directory-name prompt dir default-filename mustmatch initial)) | 4767 | (ido-read-directory-name prompt dir default-filename mustmatch initial))) |
| 4718 | (if (eq ido-exit 'fallback) | 4768 | ((and (not (eq (and (symbolp this-command) |
| 4719 | (setq filename 'fallback))) | 4769 | (get this-command 'ido)) 'ignore)) |
| 4720 | ((and (not (eq (get this-command 'ido) 'ignore)) | ||
| 4721 | (not (memq this-command ido-read-file-name-non-ido)) | 4770 | (not (memq this-command ido-read-file-name-non-ido)) |
| 4722 | (or (null predicate) (eq predicate 'file-exists-p))) | 4771 | (or (null predicate) (eq predicate 'file-exists-p))) |
| 4723 | (let* (ido-saved-vc-hb | 4772 | (let* (ido-saved-vc-hb |
| 4724 | (ido-context-switch-command | 4773 | (ido-context-switch-command |
| 4725 | (if (eq (get this-command 'ido) 'find-file) nil 'ignore)) | 4774 | (if (eq (and (symbolp this-command) |
| 4775 | (get this-command 'ido)) 'find-file) | ||
| 4776 | nil 'ignore)) | ||
| 4726 | (vc-handled-backends (and (boundp 'vc-handled-backends) vc-handled-backends)) | 4777 | (vc-handled-backends (and (boundp 'vc-handled-backends) vc-handled-backends)) |
| 4727 | (minibuffer-completing-file-name t) | 4778 | (minibuffer-completing-file-name t) |
| 4728 | (ido-current-directory (ido-expand-directory dir)) | 4779 | (ido-current-directory (ido-expand-directory dir)) |
| @@ -4736,7 +4787,15 @@ See `read-file-name' for additional parameters." | |||
| 4736 | (ido-find-literal nil)) | 4787 | (ido-find-literal nil)) |
| 4737 | (setq ido-exit nil) | 4788 | (setq ido-exit nil) |
| 4738 | (setq filename | 4789 | (setq filename |
| 4739 | (ido-read-internal 'file prompt 'ido-file-history default-filename mustmatch initial)) | 4790 | (ido-read-internal 'file prompt 'ido-file-history |
| 4791 | (cond ; Bug#11861. | ||
| 4792 | ((stringp default-filename) default-filename) | ||
| 4793 | ((consp default-filename) (car default-filename)) | ||
| 4794 | ((and (not default-filename) initial) | ||
| 4795 | (expand-file-name initial dir)) | ||
| 4796 | (buffer-file-name buffer-file-name)) | ||
| 4797 | mustmatch initial)) | ||
| 4798 | (setq dir ido-current-directory) ; See bug#1516. | ||
| 4740 | (cond | 4799 | (cond |
| 4741 | ((eq ido-exit 'fallback) | 4800 | ((eq ido-exit 'fallback) |
| 4742 | (setq filename 'fallback)) | 4801 | (setq filename 'fallback)) |
| @@ -4768,12 +4827,21 @@ See `read-directory-name' for additional parameters." | |||
| 4768 | (ido-directory-too-big-p ido-current-directory))) | 4827 | (ido-directory-too-big-p ido-current-directory))) |
| 4769 | (ido-work-directory-index -1) | 4828 | (ido-work-directory-index -1) |
| 4770 | (ido-work-file-index -1)) | 4829 | (ido-work-file-index -1)) |
| 4771 | (setq filename | 4830 | (setq filename (ido-read-internal |
| 4772 | (ido-read-internal 'dir prompt 'ido-file-history default-dirname mustmatch initial)) | 4831 | 'dir prompt 'ido-file-history |
| 4773 | (if filename | 4832 | (or default-dirname ; Bug#11861. |
| 4774 | (if (and (stringp filename) (string-equal filename ".")) | 4833 | (if initial |
| 4775 | ido-current-directory | 4834 | (expand-file-name initial ido-current-directory) |
| 4776 | (concat ido-current-directory filename))))) | 4835 | ido-current-directory)) |
| 4836 | mustmatch initial)) | ||
| 4837 | (cond | ||
| 4838 | ((eq ido-exit 'fallback) | ||
| 4839 | (let ((read-file-name-function nil)) | ||
| 4840 | (run-hook-with-args 'ido-before-fallback-functions 'read-directory-name) | ||
| 4841 | (read-directory-name prompt ido-current-directory | ||
| 4842 | default-dirname mustmatch initial))) | ||
| 4843 | ((equal filename ".") ido-current-directory) | ||
| 4844 | (t (concat ido-current-directory filename))))) | ||
| 4777 | 4845 | ||
| 4778 | ;;;###autoload | 4846 | ;;;###autoload |
| 4779 | (defun ido-completing-read (prompt choices &optional _predicate require-match | 4847 | (defun ido-completing-read (prompt choices &optional _predicate require-match |
diff --git a/lisp/info-xref.el b/lisp/info-xref.el index c38e23bab8a..21fb592ff19 100644 --- a/lisp/info-xref.el +++ b/lisp/info-xref.el | |||
| @@ -45,7 +45,25 @@ | |||
| 45 | ;;; Code: | 45 | ;;; Code: |
| 46 | 46 | ||
| 47 | (require 'info) | 47 | (require 'info) |
| 48 | (eval-when-compile (require 'cl-lib)) ;; for `incf' | 48 | (eval-when-compile (require 'cl-lib)) ; for `cl-incf' |
| 49 | |||
| 50 | (defgroup info-xref nil | ||
| 51 | "Check external cross-references in Info documents." | ||
| 52 | :group 'docs) ; FIXME right parent? | ||
| 53 | |||
| 54 | ;; Should this even be an option? | ||
| 55 | (defcustom info-xref-case-fold nil | ||
| 56 | "Non-nil means node checks should ignore case. | ||
| 57 | When following cross-references, the Emacs Info reader first tries a | ||
| 58 | case-sensitive match, then if that fails a case-insensitive one. | ||
| 59 | The standalone Info reader does not do this, nor does this work | ||
| 60 | for links in the html versions of Texinfo manuals. Therefore | ||
| 61 | to ensure your cross-references work on the widest range of platforms, | ||
| 62 | you should set this variable to nil." | ||
| 63 | :group 'info-xref | ||
| 64 | :type 'boolean | ||
| 65 | :version "24.4") | ||
| 66 | |||
| 49 | 67 | ||
| 50 | ;;----------------------------------------------------------------------------- | 68 | ;;----------------------------------------------------------------------------- |
| 51 | ;; vaguely generic | 69 | ;; vaguely generic |
| @@ -204,7 +222,8 @@ buffer's line and column of point." | |||
| 204 | (Info-goto-node node | 222 | (Info-goto-node node |
| 205 | (when (get-buffer "*info*") | 223 | (when (get-buffer "*info*") |
| 206 | (set-buffer "*info*") | 224 | (set-buffer "*info*") |
| 207 | "xref - temporary")) | 225 | "xref - temporary") |
| 226 | (not info-xref-case-fold)) | ||
| 208 | t) | 227 | t) |
| 209 | (error nil)) | 228 | (error nil)) |
| 210 | (unless (equal (current-buffer) oldbuf) | 229 | (unless (equal (current-buffer) oldbuf) |
diff --git a/lisp/info.el b/lisp/info.el index f9851a0c1e8..0e0a11753ba 100644 --- a/lisp/info.el +++ b/lisp/info.el | |||
| @@ -920,10 +920,14 @@ just return nil (no error)." | |||
| 920 | (error "Info file %s does not exist" filename))) | 920 | (error "Info file %s does not exist" filename))) |
| 921 | filename)))) | 921 | filename)))) |
| 922 | 922 | ||
| 923 | (defun Info-find-node (filename nodename &optional no-going-back) | 923 | (defun Info-find-node (filename nodename &optional no-going-back strict-case) |
| 924 | "Go to an Info node specified as separate FILENAME and NODENAME. | 924 | "Go to an Info node specified as separate FILENAME and NODENAME. |
| 925 | NO-GOING-BACK is non-nil if recovering from an error in this function; | 925 | NO-GOING-BACK is non-nil if recovering from an error in this function; |
| 926 | it says do not attempt further (recursive) error recovery." | 926 | it says do not attempt further (recursive) error recovery. |
| 927 | |||
| 928 | This function first looks for a case-sensitive match for NODENAME; | ||
| 929 | if none is found it then tries a case-insensitive match (unless | ||
| 930 | STRICT-CASE is non-nil)." | ||
| 927 | (info-initialize) | 931 | (info-initialize) |
| 928 | (setq filename (Info-find-file filename)) | 932 | (setq filename (Info-find-file filename)) |
| 929 | ;; Go into Info buffer. | 933 | ;; Go into Info buffer. |
| @@ -933,7 +937,7 @@ it says do not attempt further (recursive) error recovery." | |||
| 933 | Info-current-file | 937 | Info-current-file |
| 934 | (push (list Info-current-file Info-current-node (point)) | 938 | (push (list Info-current-file Info-current-node (point)) |
| 935 | Info-history)) | 939 | Info-history)) |
| 936 | (Info-find-node-2 filename nodename no-going-back)) | 940 | (Info-find-node-2 filename nodename no-going-back strict-case)) |
| 937 | 941 | ||
| 938 | ;;;###autoload | 942 | ;;;###autoload |
| 939 | (defun Info-on-current-buffer (&optional nodename) | 943 | (defun Info-on-current-buffer (&optional nodename) |
| @@ -1010,7 +1014,7 @@ which the match was found." | |||
| 1010 | (+ (point-min) (read (current-buffer))) | 1014 | (+ (point-min) (read (current-buffer))) |
| 1011 | major-mode))))) | 1015 | major-mode))))) |
| 1012 | 1016 | ||
| 1013 | (defun Info-find-in-tag-table (marker regexp) | 1017 | (defun Info-find-in-tag-table (marker regexp &optional strict-case) |
| 1014 | "Find a node in a tag table. | 1018 | "Find a node in a tag table. |
| 1015 | MARKER specifies the buffer and position to start searching at. | 1019 | MARKER specifies the buffer and position to start searching at. |
| 1016 | REGEXP is a regular expression matching nodes or references. Its first | 1020 | REGEXP is a regular expression matching nodes or references. Its first |
| @@ -1020,10 +1024,11 @@ FOUND-ANCHOR is non-nil if a `Ref:' was matched, POS is the position | |||
| 1020 | where the match was found, and MODE is `major-mode' of the buffer in | 1024 | where the match was found, and MODE is `major-mode' of the buffer in |
| 1021 | which the match was found. | 1025 | which the match was found. |
| 1022 | This function tries to find a case-sensitive match first, then a | 1026 | This function tries to find a case-sensitive match first, then a |
| 1023 | case-insensitive match is tried." | 1027 | case-insensitive match is tried (unless optional argument STRICT-CASE |
| 1028 | is non-nil)." | ||
| 1024 | (let ((result (Info-find-in-tag-table-1 marker regexp nil))) | 1029 | (let ((result (Info-find-in-tag-table-1 marker regexp nil))) |
| 1025 | (when (null (car result)) | 1030 | (or strict-case (car result) |
| 1026 | (setq result (Info-find-in-tag-table-1 marker regexp t))) | 1031 | (setq result (Info-find-in-tag-table-1 marker regexp t))) |
| 1027 | result)) | 1032 | result)) |
| 1028 | 1033 | ||
| 1029 | (defun Info-find-node-in-buffer-1 (regexp case-fold) | 1034 | (defun Info-find-node-in-buffer-1 (regexp case-fold) |
| @@ -1046,17 +1051,19 @@ Value is the position at which a match was found, or nil if not found." | |||
| 1046 | (setq found (line-beginning-position))))))) | 1051 | (setq found (line-beginning-position))))))) |
| 1047 | found)) | 1052 | found)) |
| 1048 | 1053 | ||
| 1049 | (defun Info-find-node-in-buffer (regexp) | 1054 | (defun Info-find-node-in-buffer (regexp &optional strict-case) |
| 1050 | "Find a node or anchor in the current buffer. | 1055 | "Find a node or anchor in the current buffer. |
| 1051 | REGEXP is a regular expression matching nodes or references. Its first | 1056 | REGEXP is a regular expression matching nodes or references. Its first |
| 1052 | group should match `Node:' or `Ref:'. | 1057 | group should match `Node:' or `Ref:'. |
| 1053 | Value is the position at which a match was found, or nil if not found. | 1058 | Value is the position at which a match was found, or nil if not found. |
| 1054 | This function looks for a case-sensitive match first. If none is found, | 1059 | This function looks for a case-sensitive match first. If none is found, |
| 1055 | a case-insensitive match is tried." | 1060 | a case-insensitive match is tried (unless optional argument STRICT-CASE |
| 1061 | is non-nil)." | ||
| 1056 | (or (Info-find-node-in-buffer-1 regexp nil) | 1062 | (or (Info-find-node-in-buffer-1 regexp nil) |
| 1057 | (Info-find-node-in-buffer-1 regexp t))) | 1063 | (and (not strict-case) |
| 1064 | (Info-find-node-in-buffer-1 regexp t)))) | ||
| 1058 | 1065 | ||
| 1059 | (defun Info-find-node-2 (filename nodename &optional no-going-back) | 1066 | (defun Info-find-node-2 (filename nodename &optional no-going-back strict-case) |
| 1060 | (buffer-disable-undo (current-buffer)) | 1067 | (buffer-disable-undo (current-buffer)) |
| 1061 | (or (eq major-mode 'Info-mode) | 1068 | (or (eq major-mode 'Info-mode) |
| 1062 | (Info-mode)) | 1069 | (Info-mode)) |
| @@ -1167,7 +1174,7 @@ a case-insensitive match is tried." | |||
| 1167 | ;; First, search a tag table, if any | 1174 | ;; First, search a tag table, if any |
| 1168 | (when (marker-position Info-tag-table-marker) | 1175 | (when (marker-position Info-tag-table-marker) |
| 1169 | (let* ((m Info-tag-table-marker) | 1176 | (let* ((m Info-tag-table-marker) |
| 1170 | (found (Info-find-in-tag-table m regexp))) | 1177 | (found (Info-find-in-tag-table m regexp strict-case))) |
| 1171 | 1178 | ||
| 1172 | (when found | 1179 | (when found |
| 1173 | ;; FOUND is (ANCHOR POS MODE). | 1180 | ;; FOUND is (ANCHOR POS MODE). |
| @@ -1194,7 +1201,7 @@ a case-insensitive match is tried." | |||
| 1194 | ;; buffer) to find the actual node. First, check | 1201 | ;; buffer) to find the actual node. First, check |
| 1195 | ;; whether the node is right where we are, in case the | 1202 | ;; whether the node is right where we are, in case the |
| 1196 | ;; buffer begins with a node. | 1203 | ;; buffer begins with a node. |
| 1197 | (let ((pos (Info-find-node-in-buffer regexp))) | 1204 | (let ((pos (Info-find-node-in-buffer regexp strict-case))) |
| 1198 | (when pos | 1205 | (when pos |
| 1199 | (goto-char pos) | 1206 | (goto-char pos) |
| 1200 | (throw 'foo t))) | 1207 | (throw 'foo t))) |
| @@ -1701,7 +1708,7 @@ escaped (\\\",\\\\)." | |||
| 1701 | ;; Don't autoload this function: the correct entry point for other packages | 1708 | ;; Don't autoload this function: the correct entry point for other packages |
| 1702 | ;; to use is `info'. --Stef | 1709 | ;; to use is `info'. --Stef |
| 1703 | ;; ;;;###autoload | 1710 | ;; ;;;###autoload |
| 1704 | (defun Info-goto-node (nodename &optional fork) | 1711 | (defun Info-goto-node (nodename &optional fork strict-case) |
| 1705 | "Go to Info node named NODENAME. Give just NODENAME or (FILENAME)NODENAME. | 1712 | "Go to Info node named NODENAME. Give just NODENAME or (FILENAME)NODENAME. |
| 1706 | If NODENAME is of the form (FILENAME)NODENAME, the node is in the Info file | 1713 | If NODENAME is of the form (FILENAME)NODENAME, the node is in the Info file |
| 1707 | FILENAME; otherwise, NODENAME should be in the current Info file (or one of | 1714 | FILENAME; otherwise, NODENAME should be in the current Info file (or one of |
| @@ -1711,7 +1718,11 @@ in the Info file FILENAME after the closing parenthesis in (FILENAME). | |||
| 1711 | Empty NODENAME in (FILENAME) defaults to the Top node. | 1718 | Empty NODENAME in (FILENAME) defaults to the Top node. |
| 1712 | If FORK is non-nil (interactively with a prefix arg), show the node in | 1719 | If FORK is non-nil (interactively with a prefix arg), show the node in |
| 1713 | a new Info buffer. | 1720 | a new Info buffer. |
| 1714 | If FORK is a string, it is the name to use for the new buffer." | 1721 | If FORK is a string, it is the name to use for the new buffer. |
| 1722 | |||
| 1723 | This function first looks for a case-sensitive match for the node part | ||
| 1724 | of NODENAME; if none is found it then tries a case-insensitive match | ||
| 1725 | \(unless STRICT-CASE is non-nil)." | ||
| 1715 | (interactive (list (Info-read-node-name "Go to node: ") current-prefix-arg)) | 1726 | (interactive (list (Info-read-node-name "Go to node: ") current-prefix-arg)) |
| 1716 | (info-initialize) | 1727 | (info-initialize) |
| 1717 | (if fork | 1728 | (if fork |
| @@ -1730,7 +1741,7 @@ If FORK is a string, it is the name to use for the new buffer." | |||
| 1730 | (if trim (setq nodename (substring nodename 0 trim)))) | 1741 | (if trim (setq nodename (substring nodename 0 trim)))) |
| 1731 | (if transient-mark-mode (deactivate-mark)) | 1742 | (if transient-mark-mode (deactivate-mark)) |
| 1732 | (Info-find-node (if (equal filename "") nil filename) | 1743 | (Info-find-node (if (equal filename "") nil filename) |
| 1733 | (if (equal nodename "") "Top" nodename)))) | 1744 | (if (equal nodename "") "Top" nodename) nil strict-case))) |
| 1734 | 1745 | ||
| 1735 | (defvar Info-read-node-completion-table) | 1746 | (defvar Info-read-node-completion-table) |
| 1736 | 1747 | ||
diff --git a/lisp/international/mule.el b/lisp/international/mule.el index 3577e0e9152..28542835a5f 100644 --- a/lisp/international/mule.el +++ b/lisp/international/mule.el | |||
| @@ -672,7 +672,7 @@ is unsuitable for the top-level media type \"text\". | |||
| 672 | 672 | ||
| 673 | VALUE must be a list of symbols that control the ISO-2022 converter. | 673 | VALUE must be a list of symbols that control the ISO-2022 converter. |
| 674 | Each must be a member of the list `coding-system-iso-2022-flags' | 674 | Each must be a member of the list `coding-system-iso-2022-flags' |
| 675 | \(which see). This attribute has a meaning only when `:coding-type' | 675 | \(which see). This attribute is meaningful only when `:coding-type' |
| 676 | is `iso-2022'. | 676 | is `iso-2022'. |
| 677 | 677 | ||
| 678 | `:designation' | 678 | `:designation' |
| @@ -692,7 +692,7 @@ to GN. If the list contains 96, any charsets whose whose ranges are | |||
| 692 | 96 long can be designated to GN. If the first element is a charset, | 692 | 96 long can be designated to GN. If the first element is a charset, |
| 693 | that charset is initially designated to GN. | 693 | that charset is initially designated to GN. |
| 694 | 694 | ||
| 695 | This attribute has a meaning only when `:coding-type' is `iso-2022'. | 695 | This attribute is meaningful only when `:coding-type' is `iso-2022'. |
| 696 | 696 | ||
| 697 | `:bom' | 697 | `:bom' |
| 698 | 698 | ||
| @@ -712,7 +712,7 @@ are 0xFF 0xFE, use the cdr part coding system of the value. | |||
| 712 | Otherwise, treat them as bytes for a normal character. On encoding, | 712 | Otherwise, treat them as bytes for a normal character. On encoding, |
| 713 | produce BOM bytes according to the value of `:endian'. | 713 | produce BOM bytes according to the value of `:endian'. |
| 714 | 714 | ||
| 715 | This attribute has a meaning only when `:coding-type' is `utf-16' or | 715 | This attribute is meaningful only when `:coding-type' is `utf-16' or |
| 716 | `utf-8'. | 716 | `utf-8'. |
| 717 | 717 | ||
| 718 | `:endian' | 718 | `:endian' |
| @@ -720,37 +720,37 @@ This attribute has a meaning only when `:coding-type' is `utf-16' or | |||
| 720 | VALUE must be `big' or `little' specifying big-endian and | 720 | VALUE must be `big' or `little' specifying big-endian and |
| 721 | little-endian respectively. The default value is `big'. | 721 | little-endian respectively. The default value is `big'. |
| 722 | 722 | ||
| 723 | This attribute has a meaning only when `:coding-type' is `utf-16'. | 723 | This attribute is meaningful only when `:coding-type' is `utf-16'. |
| 724 | 724 | ||
| 725 | `:ccl-decoder' | 725 | `:ccl-decoder' |
| 726 | 726 | ||
| 727 | VALUE is a symbol representing the registered CCL program used for | 727 | VALUE is a symbol representing the registered CCL program used for |
| 728 | decoding. This attribute has a meaning only when `:coding-type' is | 728 | decoding. This attribute is meaningful only when `:coding-type' is |
| 729 | `ccl'. | 729 | `ccl'. |
| 730 | 730 | ||
| 731 | `:ccl-encoder' | 731 | `:ccl-encoder' |
| 732 | 732 | ||
| 733 | VALUE is a symbol representing the registered CCL program used for | 733 | VALUE is a symbol representing the registered CCL program used for |
| 734 | encoding. This attribute has a meaning only when `:coding-type' is | 734 | encoding. This attribute is meaningful only when `:coding-type' is |
| 735 | `ccl'. | 735 | `ccl'. |
| 736 | 736 | ||
| 737 | :inhibit-null-byte-detection | 737 | `:inhibit-null-byte-detection' |
| 738 | 738 | ||
| 739 | VALUE non-nil means Emacs ignore null bytes on code detection. | 739 | VALUE non-nil means Emacs ignore null bytes on code detection. |
| 740 | See the variable `inhibit-null-byte-detection'. This attribute | 740 | See the variable `inhibit-null-byte-detection'. This attribute |
| 741 | has a meaning only when `:coding-type' is `undecided'. | 741 | is meaningful only when `:coding-type' is `undecided'. |
| 742 | 742 | ||
| 743 | :inhibit-iso-escape-detection | 743 | `:inhibit-iso-escape-detection' |
| 744 | 744 | ||
| 745 | VALUE non-nil means Emacs ignores ISO-2022 escape sequences on | 745 | VALUE non-nil means Emacs ignores ISO-2022 escape sequences on |
| 746 | code detection. See the variable `inhibit-iso-escape-detection'. | 746 | code detection. See the variable `inhibit-iso-escape-detection'. |
| 747 | This attribute has a meaning only when `:coding-type' is | 747 | This attribute is meaningful only when `:coding-type' is |
| 748 | `undecided'. | 748 | `undecided'. |
| 749 | 749 | ||
| 750 | :prefer-utf-8 | 750 | `:prefer-utf-8' |
| 751 | 751 | ||
| 752 | VALUE non-nil means Emacs prefers UTF-8 on code detection for | 752 | VALUE non-nil means Emacs prefers UTF-8 on code detection for |
| 753 | non-ASCII files. This attribute has a meaning only when | 753 | non-ASCII files. This attribute is meaningful only when |
| 754 | `:coding-type' is `undecided'." | 754 | `:coding-type' is `undecided'." |
| 755 | (let* ((common-attrs (mapcar 'list | 755 | (let* ((common-attrs (mapcar 'list |
| 756 | '(:mnemonic | 756 | '(:mnemonic |
diff --git a/lisp/net/shr.el b/lisp/net/shr.el index bdc30bc9292..4506ede8722 100644 --- a/lisp/net/shr.el +++ b/lisp/net/shr.el | |||
| @@ -145,6 +145,7 @@ cid: URL as the argument.") | |||
| 145 | (define-key map [follow-link] 'mouse-face) | 145 | (define-key map [follow-link] 'mouse-face) |
| 146 | (define-key map "I" 'shr-insert-image) | 146 | (define-key map "I" 'shr-insert-image) |
| 147 | (define-key map "w" 'shr-copy-url) | 147 | (define-key map "w" 'shr-copy-url) |
| 148 | (define-key map "u" 'shr-copy-url) | ||
| 148 | (define-key map "v" 'shr-browse-url) | 149 | (define-key map "v" 'shr-browse-url) |
| 149 | (define-key map "o" 'shr-save-contents) | 150 | (define-key map "o" 'shr-save-contents) |
| 150 | (define-key map "\r" 'shr-browse-url) | 151 | (define-key map "\r" 'shr-browse-url) |
diff --git a/lisp/net/tramp-cache.el b/lisp/net/tramp-cache.el index 4c6141fe42b..f7f570590c8 100644 --- a/lisp/net/tramp-cache.el +++ b/lisp/net/tramp-cache.el | |||
| @@ -38,9 +38,11 @@ | |||
| 38 | ;; | 38 | ;; |
| 39 | ;; - localname is a string. This are temporary properties, which are | 39 | ;; - localname is a string. This are temporary properties, which are |
| 40 | ;; related to the file localname is referring to. Examples: | 40 | ;; related to the file localname is referring to. Examples: |
| 41 | ;; "file-exists-p" is t or nile, depending on the file existence, or | 41 | ;; "file-exists-p" is t or nil, depending on the file existence, or |
| 42 | ;; "file-attributes" caches the result of the function | 42 | ;; "file-attributes" caches the result of the function |
| 43 | ;; `file-attributes'. | 43 | ;; `file-attributes'. These entries have a timestamp, and they |
| 44 | ;; expire after `remote-file-name-inhibit-cache' seconds if this | ||
| 45 | ;; variable is set. | ||
| 44 | ;; | 46 | ;; |
| 45 | ;; - The key is a process. This are temporary properties related to | 47 | ;; - The key is a process. This are temporary properties related to |
| 46 | ;; an open connection. Examples: "scripts" keeps shell script | 48 | ;; an open connection. Examples: "scripts" keeps shell script |
diff --git a/lisp/net/tramp-gvfs.el b/lisp/net/tramp-gvfs.el index 6ba055b8bb8..c2fdc0491b6 100644 --- a/lisp/net/tramp-gvfs.el +++ b/lisp/net/tramp-gvfs.el | |||
| @@ -1539,7 +1539,8 @@ connection if a previous connection has died for some reason." | |||
| 1539 | ;; indicated by the "mounted" signal, i.e. the "fuse-mountpoint" | 1539 | ;; indicated by the "mounted" signal, i.e. the "fuse-mountpoint" |
| 1540 | ;; file property. | 1540 | ;; file property. |
| 1541 | (with-timeout | 1541 | (with-timeout |
| 1542 | (60 | 1542 | ((or (tramp-get-method-parameter method 'tramp-connection-timeout) |
| 1543 | tramp-connection-timeout) | ||
| 1543 | (if (zerop (length (tramp-file-name-user vec))) | 1544 | (if (zerop (length (tramp-file-name-user vec))) |
| 1544 | (tramp-error | 1545 | (tramp-error |
| 1545 | vec 'file-error | 1546 | vec 'file-error |
diff --git a/lisp/net/tramp-sh.el b/lisp/net/tramp-sh.el index 387084a807b..281f497692d 100644 --- a/lisp/net/tramp-sh.el +++ b/lisp/net/tramp-sh.el | |||
| @@ -222,21 +222,24 @@ detected as prompt when being sent on echoing hosts, therefore.") | |||
| 222 | (tramp-login-program "su") | 222 | (tramp-login-program "su") |
| 223 | (tramp-login-args (("-") ("%u"))) | 223 | (tramp-login-args (("-") ("%u"))) |
| 224 | (tramp-remote-shell "/bin/sh") | 224 | (tramp-remote-shell "/bin/sh") |
| 225 | (tramp-remote-shell-args ("-c")))) | 225 | (tramp-remote-shell-args ("-c")) |
| 226 | (tramp-connection-timeout 10))) | ||
| 226 | ;;;###tramp-autoload | 227 | ;;;###tramp-autoload |
| 227 | (add-to-list 'tramp-methods | 228 | (add-to-list 'tramp-methods |
| 228 | '("sudo" | 229 | '("sudo" |
| 229 | (tramp-login-program "sudo") | 230 | (tramp-login-program "sudo") |
| 230 | (tramp-login-args (("-u" "%u") ("-s") ("-H") ("-p" "Password:"))) | 231 | (tramp-login-args (("-u" "%u") ("-s") ("-H") ("-p" "Password:"))) |
| 231 | (tramp-remote-shell "/bin/sh") | 232 | (tramp-remote-shell "/bin/sh") |
| 232 | (tramp-remote-shell-args ("-c")))) | 233 | (tramp-remote-shell-args ("-c")) |
| 234 | (tramp-connection-timeout 10))) | ||
| 233 | ;;;###tramp-autoload | 235 | ;;;###tramp-autoload |
| 234 | (add-to-list 'tramp-methods | 236 | (add-to-list 'tramp-methods |
| 235 | '("ksu" | 237 | '("ksu" |
| 236 | (tramp-login-program "ksu") | 238 | (tramp-login-program "ksu") |
| 237 | (tramp-login-args (("%u") ("-q"))) | 239 | (tramp-login-args (("%u") ("-q"))) |
| 238 | (tramp-remote-shell "/bin/sh") | 240 | (tramp-remote-shell "/bin/sh") |
| 239 | (tramp-remote-shell-args ("-c")))) | 241 | (tramp-remote-shell-args ("-c")) |
| 242 | (tramp-connection-timeout 10))) | ||
| 240 | ;;;###tramp-autoload | 243 | ;;;###tramp-autoload |
| 241 | (add-to-list 'tramp-methods | 244 | (add-to-list 'tramp-methods |
| 242 | '("krlogin" | 245 | '("krlogin" |
| @@ -862,7 +865,9 @@ of command line.") | |||
| 862 | (set-file-selinux-context . tramp-sh-handle-set-file-selinux-context) | 865 | (set-file-selinux-context . tramp-sh-handle-set-file-selinux-context) |
| 863 | (file-acl . tramp-sh-handle-file-acl) | 866 | (file-acl . tramp-sh-handle-file-acl) |
| 864 | (set-file-acl . tramp-sh-handle-set-file-acl) | 867 | (set-file-acl . tramp-sh-handle-set-file-acl) |
| 865 | (vc-registered . tramp-sh-handle-vc-registered)) | 868 | (vc-registered . tramp-sh-handle-vc-registered) |
| 869 | (file-notify-add-watch . tramp-sh-handle-file-notify-add-watch) | ||
| 870 | (file-notify-rm-watch . tramp-sh-handle-file-notify-rm-watch)) | ||
| 866 | "Alist of handler functions. | 871 | "Alist of handler functions. |
| 867 | Operations not mentioned here will be handled by the normal Emacs functions.") | 872 | Operations not mentioned here will be handled by the normal Emacs functions.") |
| 868 | 873 | ||
| @@ -2669,7 +2674,7 @@ the result will be a local, non-Tramp, filename." | |||
| 2669 | (unless (memq (process-status proc) '(run open)) | 2674 | (unless (memq (process-status proc) '(run open)) |
| 2670 | (let ((vec (tramp-get-connection-property proc "vector" nil))) | 2675 | (let ((vec (tramp-get-connection-property proc "vector" nil))) |
| 2671 | (when vec | 2676 | (when vec |
| 2672 | (tramp-message vec 5 "Sentinel called: `%s' `%s'" proc event) | 2677 | (tramp-message vec 5 "Sentinel called: `%S' `%s'" proc event) |
| 2673 | (tramp-flush-connection-property proc) | 2678 | (tramp-flush-connection-property proc) |
| 2674 | (tramp-flush-directory-property vec ""))))) | 2679 | (tramp-flush-directory-property vec ""))))) |
| 2675 | 2680 | ||
| @@ -3376,6 +3381,122 @@ Fall back to normal file name handler if no Tramp handler exists." | |||
| 3376 | ;; Default file name handlers, we don't care. | 3381 | ;; Default file name handlers, we don't care. |
| 3377 | (t (tramp-run-real-handler operation args))))))) | 3382 | (t (tramp-run-real-handler operation args))))))) |
| 3378 | 3383 | ||
| 3384 | (defun tramp-sh-handle-file-notify-add-watch (file-name flags callback) | ||
| 3385 | "Like `file-notify-add-watch' for Tramp files." | ||
| 3386 | (setq file-name (expand-file-name file-name)) | ||
| 3387 | (with-parsed-tramp-file-name file-name nil | ||
| 3388 | (let* ((default-directory (file-name-directory file-name)) | ||
| 3389 | command events filter p) | ||
| 3390 | (cond | ||
| 3391 | ;; gvfs-monitor-dir. | ||
| 3392 | ((setq command (tramp-get-remote-gvfs-monitor-dir v)) | ||
| 3393 | (setq filter 'tramp-sh-file-gvfs-monitor-dir-process-filter | ||
| 3394 | p (start-file-process | ||
| 3395 | "gvfs-monitor-dir" (generate-new-buffer " *gvfs-monitor-dir*") | ||
| 3396 | command localname))) | ||
| 3397 | ;; inotifywait. | ||
| 3398 | ((setq command (tramp-get-remote-inotifywait v)) | ||
| 3399 | (setq filter 'tramp-sh-file-inotifywait-process-filter | ||
| 3400 | events | ||
| 3401 | (cond | ||
| 3402 | ((and (memq 'change flags) (memq 'attribute-change flags)) | ||
| 3403 | "create,modify,move,delete,attrib") | ||
| 3404 | ((memq 'change flags) "create,modify,move,delete") | ||
| 3405 | ((memq 'attribute-change flags) "attrib")) | ||
| 3406 | p (start-file-process | ||
| 3407 | "inotifywait" (generate-new-buffer " *inotifywait*") | ||
| 3408 | command "-mq" "-e" events localname))) | ||
| 3409 | ;; None. | ||
| 3410 | (t (tramp-error | ||
| 3411 | v 'file-notify-error | ||
| 3412 | "No file notification program found on %s" | ||
| 3413 | (file-remote-p file-name)))) | ||
| 3414 | ;; Return the process object as watch-descriptor. | ||
| 3415 | (if (not (processp p)) | ||
| 3416 | (tramp-error | ||
| 3417 | v 'file-notify-error "`%s' failed to start on remote host" command) | ||
| 3418 | (tramp-compat-set-process-query-on-exit-flag p nil) | ||
| 3419 | (set-process-filter p filter) | ||
| 3420 | p)))) | ||
| 3421 | |||
| 3422 | (defun tramp-sh-file-gvfs-monitor-dir-process-filter (proc string) | ||
| 3423 | "Read output from \"gvfs-monitor-dir\" and add corresponding file-notify events." | ||
| 3424 | (let ((remote-prefix | ||
| 3425 | (with-current-buffer (process-buffer proc) | ||
| 3426 | (file-remote-p default-directory))) | ||
| 3427 | (rest-string (tramp-compat-process-get proc 'rest-string))) | ||
| 3428 | (when rest-string | ||
| 3429 | (tramp-message proc 10 (format "Previous string:\n%s" rest-string))) | ||
| 3430 | (tramp-message proc 6 (format "%S\n%s" proc string)) | ||
| 3431 | (setq string (concat rest-string string) | ||
| 3432 | ;; Attribute change is returned in unused wording. | ||
| 3433 | string (replace-regexp-in-string | ||
| 3434 | "ATTRIB CHANGED" "ATTRIBUTE_CHANGED" string)) | ||
| 3435 | |||
| 3436 | (while (string-match | ||
| 3437 | (concat "^[\n\r]*" | ||
| 3438 | "Directory Monitor Event:[\n\r]+" | ||
| 3439 | "Child = \\([^\n\r]+\\)[\n\r]+" | ||
| 3440 | "\\(Other = \\([^\n\r]+\\)[\n\r]+\\)?" | ||
| 3441 | "Event = \\([^[:blank:]]+\\)[\n\r]+") | ||
| 3442 | string) | ||
| 3443 | (let ((object | ||
| 3444 | (list | ||
| 3445 | proc | ||
| 3446 | (intern-soft | ||
| 3447 | (replace-regexp-in-string | ||
| 3448 | "_" "-" (downcase (match-string 4 string)))) | ||
| 3449 | ;; File names are returned as absolute paths. We must | ||
| 3450 | ;; add the remote prefix. | ||
| 3451 | (concat remote-prefix (match-string 1 string)) | ||
| 3452 | (when (match-string 3 string) | ||
| 3453 | (concat remote-prefix (match-string 3 string)))))) | ||
| 3454 | (setq string (replace-match "" nil nil string)) | ||
| 3455 | ;; Usually, we would add an Emacs event now. Unfortunately, | ||
| 3456 | ;; `unread-command-events' does not accept several events at | ||
| 3457 | ;; once. Therefore, we apply the callback directly. | ||
| 3458 | (tramp-compat-funcall 'file-notify-callback object))) | ||
| 3459 | |||
| 3460 | ;; Save rest of the string. | ||
| 3461 | (when (zerop (length string)) (setq string nil)) | ||
| 3462 | (when string (tramp-message proc 10 (format "Rest string:\n%s" string))) | ||
| 3463 | (tramp-compat-process-put proc 'rest-string string))) | ||
| 3464 | |||
| 3465 | (defun tramp-sh-file-inotifywait-process-filter (proc string) | ||
| 3466 | "Read output from \"inotifywait\" and add corresponding file-notify events." | ||
| 3467 | (tramp-message proc 6 (format "%S\n%s" proc string)) | ||
| 3468 | (dolist (line (split-string string "[\n\r]+" 'omit-nulls)) | ||
| 3469 | ;; Check, whether there is a problem. | ||
| 3470 | (unless | ||
| 3471 | (string-match | ||
| 3472 | (concat "^[^[:blank:]]+" | ||
| 3473 | "[[:blank:]]+\\([^[:blank:]]+\\)+" | ||
| 3474 | "\\([[:blank:]]+\\([^\n\r]+\\)\\)?") | ||
| 3475 | line) | ||
| 3476 | (tramp-error proc 'file-notify-error "%s" line)) | ||
| 3477 | |||
| 3478 | (let ((object | ||
| 3479 | (list | ||
| 3480 | proc | ||
| 3481 | (mapcar | ||
| 3482 | (lambda (x) | ||
| 3483 | (intern-soft (replace-regexp-in-string "_" "-" (downcase x)))) | ||
| 3484 | (split-string (match-string 1 line) "," 'omit-nulls)) | ||
| 3485 | (match-string 3 line)))) | ||
| 3486 | ;; Usually, we would add an Emacs event now. Unfortunately, | ||
| 3487 | ;; `unread-command-events' does not accept several events at | ||
| 3488 | ;; once. Therefore, we apply the callback directly. | ||
| 3489 | (tramp-compat-funcall 'file-notify-callback object)))) | ||
| 3490 | |||
| 3491 | (defvar file-notify-descriptors) | ||
| 3492 | (defun tramp-sh-handle-file-notify-rm-watch (proc) | ||
| 3493 | "Like `file-notify-rm-watch' for Tramp files." | ||
| 3494 | ;; The descriptor must be a process object. | ||
| 3495 | (unless (and (processp proc) (gethash proc file-notify-descriptors)) | ||
| 3496 | (tramp-error proc 'file-notify-error "Not a valid descriptor %S" proc)) | ||
| 3497 | (tramp-message proc 6 (format "Kill %S" proc)) | ||
| 3498 | (kill-process proc)) | ||
| 3499 | |||
| 3379 | ;;; Internal Functions: | 3500 | ;;; Internal Functions: |
| 3380 | 3501 | ||
| 3381 | (defun tramp-maybe-send-script (vec script name) | 3502 | (defun tramp-maybe-send-script (vec script name) |
| @@ -3634,12 +3755,16 @@ file exists and nonzero exit status otherwise." | |||
| 3634 | "Wait for shell prompt and barf if none appears. | 3755 | "Wait for shell prompt and barf if none appears. |
| 3635 | Looks at process PROC to see if a shell prompt appears in TIMEOUT | 3756 | Looks at process PROC to see if a shell prompt appears in TIMEOUT |
| 3636 | seconds. If not, it produces an error message with the given ERROR-ARGS." | 3757 | seconds. If not, it produces an error message with the given ERROR-ARGS." |
| 3637 | (unless | 3758 | (let ((vec (tramp-get-connection-property proc "vector" nil))) |
| 3638 | (tramp-wait-for-regexp | 3759 | (condition-case err |
| 3639 | proc timeout | 3760 | (tramp-wait-for-regexp |
| 3640 | (format | 3761 | proc timeout |
| 3641 | "\\(%s\\|%s\\)\\'" shell-prompt-pattern tramp-shell-prompt-pattern)) | 3762 | (format |
| 3642 | (apply 'tramp-error-with-buffer nil proc 'file-error error-args))) | 3763 | "\\(%s\\|%s\\)\\'" shell-prompt-pattern tramp-shell-prompt-pattern)) |
| 3764 | (error | ||
| 3765 | (delete-process proc) | ||
| 3766 | (apply 'tramp-error-with-buffer | ||
| 3767 | (tramp-get-connection-buffer vec) vec 'file-error error-args))))) | ||
| 3643 | 3768 | ||
| 3644 | (defun tramp-open-connection-setup-interactive-shell (proc vec) | 3769 | (defun tramp-open-connection-setup-interactive-shell (proc vec) |
| 3645 | "Set up an interactive shell. | 3770 | "Set up an interactive shell. |
| @@ -4214,9 +4339,6 @@ Gateway hops are already opened." | |||
| 4214 | ;; Result. | 4339 | ;; Result. |
| 4215 | target-alist)) | 4340 | target-alist)) |
| 4216 | 4341 | ||
| 4217 | (defvar tramp-current-connection nil | ||
| 4218 | "Last connection timestamp.") | ||
| 4219 | |||
| 4220 | (defun tramp-maybe-open-connection (vec) | 4342 | (defun tramp-maybe-open-connection (vec) |
| 4221 | "Maybe open a connection VEC. | 4343 | "Maybe open a connection VEC. |
| 4222 | Does not do anything if a connection is already open, but re-opens the | 4344 | Does not do anything if a connection is already open, but re-opens the |
| @@ -4230,7 +4352,7 @@ connection if a previous connection has died for some reason." | |||
| 4230 | ;; If Tramp opens the same connection within a short time frame, | 4352 | ;; If Tramp opens the same connection within a short time frame, |
| 4231 | ;; there is a problem. We shall signal this. | 4353 | ;; there is a problem. We shall signal this. |
| 4232 | (unless (or (and p (processp p) (memq (process-status p) '(run open))) | 4354 | (unless (or (and p (processp p) (memq (process-status p) '(run open))) |
| 4233 | (not (equal (butlast (append vec nil)) | 4355 | (not (equal (butlast (append vec nil) 2) |
| 4234 | (car tramp-current-connection))) | 4356 | (car tramp-current-connection))) |
| 4235 | (> (tramp-time-diff | 4357 | (> (tramp-time-diff |
| 4236 | (current-time) (cdr tramp-current-connection)) | 4358 | (current-time) (cdr tramp-current-connection)) |
| @@ -4315,7 +4437,7 @@ connection if a previous connection has died for some reason." | |||
| 4315 | (set-process-sentinel p 'tramp-process-sentinel) | 4437 | (set-process-sentinel p 'tramp-process-sentinel) |
| 4316 | (tramp-compat-set-process-query-on-exit-flag p nil) | 4438 | (tramp-compat-set-process-query-on-exit-flag p nil) |
| 4317 | (setq tramp-current-connection | 4439 | (setq tramp-current-connection |
| 4318 | (cons (butlast (append vec nil)) (current-time)) | 4440 | (cons (butlast (append vec nil) 2) (current-time)) |
| 4319 | tramp-current-host (system-name)) | 4441 | tramp-current-host (system-name)) |
| 4320 | 4442 | ||
| 4321 | (tramp-message | 4443 | (tramp-message |
| @@ -4323,8 +4445,8 @@ connection if a previous connection has died for some reason." | |||
| 4323 | 4445 | ||
| 4324 | ;; Check whether process is alive. | 4446 | ;; Check whether process is alive. |
| 4325 | (tramp-barf-if-no-shell-prompt | 4447 | (tramp-barf-if-no-shell-prompt |
| 4326 | p 60 | 4448 | p 10 |
| 4327 | "Couldn't find local shell prompt %s" tramp-encoding-shell) | 4449 | "Couldn't find local shell prompt for %s" tramp-encoding-shell) |
| 4328 | 4450 | ||
| 4329 | ;; Now do all the connections as specified. | 4451 | ;; Now do all the connections as specified. |
| 4330 | (while target-alist | 4452 | (while target-alist |
| @@ -4342,6 +4464,9 @@ connection if a previous connection has died for some reason." | |||
| 4342 | (async-args | 4464 | (async-args |
| 4343 | (tramp-get-method-parameter | 4465 | (tramp-get-method-parameter |
| 4344 | l-method 'tramp-async-args)) | 4466 | l-method 'tramp-async-args)) |
| 4467 | (connection-timeout | ||
| 4468 | (tramp-get-method-parameter | ||
| 4469 | l-method 'tramp-connection-timeout)) | ||
| 4345 | (gw-args | 4470 | (gw-args |
| 4346 | (tramp-get-method-parameter l-method 'tramp-gw-args)) | 4471 | (tramp-get-method-parameter l-method 'tramp-gw-args)) |
| 4347 | (gw (tramp-get-file-property hop "" "gateway" nil)) | 4472 | (gw (tramp-get-file-property hop "" "gateway" nil)) |
| @@ -4424,7 +4549,8 @@ connection if a previous connection has died for some reason." | |||
| 4424 | (tramp-message vec 3 "Sending command `%s'" command) | 4549 | (tramp-message vec 3 "Sending command `%s'" command) |
| 4425 | (tramp-send-command vec command t t) | 4550 | (tramp-send-command vec command t t) |
| 4426 | (tramp-process-actions | 4551 | (tramp-process-actions |
| 4427 | p vec pos tramp-actions-before-shell 60) | 4552 | p vec pos tramp-actions-before-shell |
| 4553 | (or connection-timeout tramp-connection-timeout)) | ||
| 4428 | (tramp-message | 4554 | (tramp-message |
| 4429 | vec 3 "Found remote shell prompt on `%s'" l-host)) | 4555 | vec 3 "Found remote shell prompt on `%s'" l-host)) |
| 4430 | ;; Next hop. | 4556 | ;; Next hop. |
| @@ -4864,6 +4990,17 @@ Return ATTR." | |||
| 4864 | (tramp-message vec 5 "Finding a suitable `trash' command") | 4990 | (tramp-message vec 5 "Finding a suitable `trash' command") |
| 4865 | (tramp-find-executable vec "trash" (tramp-get-remote-path vec)))) | 4991 | (tramp-find-executable vec "trash" (tramp-get-remote-path vec)))) |
| 4866 | 4992 | ||
| 4993 | (defun tramp-get-remote-gvfs-monitor-dir (vec) | ||
| 4994 | (with-tramp-connection-property vec "gvfs-monitor-dir" | ||
| 4995 | (tramp-message vec 5 "Finding a suitable `gvfs-monitor-dir' command") | ||
| 4996 | (tramp-find-executable | ||
| 4997 | vec "gvfs-monitor-dir" (tramp-get-remote-path vec) t t))) | ||
| 4998 | |||
| 4999 | (defun tramp-get-remote-inotifywait (vec) | ||
| 5000 | (with-tramp-connection-property vec "inotifywait" | ||
| 5001 | (tramp-message vec 5 "Finding a suitable `inotifywait' command") | ||
| 5002 | (tramp-find-executable vec "inotifywait" (tramp-get-remote-path vec) t t))) | ||
| 5003 | |||
| 4867 | (defun tramp-get-remote-id (vec) | 5004 | (defun tramp-get-remote-id (vec) |
| 4868 | (with-tramp-connection-property vec "id" | 5005 | (with-tramp-connection-property vec "id" |
| 4869 | (tramp-message vec 5 "Finding POSIX `id' command") | 5006 | (tramp-message vec 5 "Finding POSIX `id' command") |
diff --git a/lisp/net/tramp.el b/lisp/net/tramp.el index 4ec3a4b7829..3513701d20e 100644 --- a/lisp/net/tramp.el +++ b/lisp/net/tramp.el | |||
| @@ -252,6 +252,11 @@ pair of the form (KEY VALUE). The following KEYs are defined: | |||
| 252 | * `tramp-tmpdir' | 252 | * `tramp-tmpdir' |
| 253 | A directory on the remote host for temporary files. If not | 253 | A directory on the remote host for temporary files. If not |
| 254 | specified, \"/tmp\" is taken as default. | 254 | specified, \"/tmp\" is taken as default. |
| 255 | * `tramp-connection-timeout' | ||
| 256 | This is the maximum time to be spent for establishing a connection. | ||
| 257 | In general, the global default value shall be used, but for | ||
| 258 | some methods, like \"su\" or \"sudo\", a shorter timeout | ||
| 259 | might be desirable. | ||
| 255 | 260 | ||
| 256 | What does all this mean? Well, you should specify `tramp-login-program' | 261 | What does all this mean? Well, you should specify `tramp-login-program' |
| 257 | for all methods; this program is used to log in to the remote site. Then, | 262 | for all methods; this program is used to log in to the remote site. Then, |
| @@ -1034,6 +1039,13 @@ opening a connection to a remote host." | |||
| 1034 | :group 'tramp | 1039 | :group 'tramp |
| 1035 | :type '(choice (const nil) (const t) (const pty))) | 1040 | :type '(choice (const nil) (const t) (const pty))) |
| 1036 | 1041 | ||
| 1042 | (defcustom tramp-connection-timeout 60 | ||
| 1043 | "Defines the max time to wait for establishing a connection (in seconds). | ||
| 1044 | This can be overwritten for different connection types in `tramp-methods'." | ||
| 1045 | :group 'tramp | ||
| 1046 | :version "24.4" | ||
| 1047 | :type 'integer) | ||
| 1048 | |||
| 1037 | (defcustom tramp-connection-min-time-diff 5 | 1049 | (defcustom tramp-connection-min-time-diff 5 |
| 1038 | "Defines seconds between two consecutive connection attempts. | 1050 | "Defines seconds between two consecutive connection attempts. |
| 1039 | This is necessary as self defense mechanism, in order to avoid | 1051 | This is necessary as self defense mechanism, in order to avoid |
| @@ -1071,6 +1083,9 @@ means to use always cached values for the directory contents." | |||
| 1071 | (defvar tramp-current-host nil | 1083 | (defvar tramp-current-host nil |
| 1072 | "Remote host for this *tramp* buffer.") | 1084 | "Remote host for this *tramp* buffer.") |
| 1073 | 1085 | ||
| 1086 | (defvar tramp-current-connection nil | ||
| 1087 | "Last connection timestamp.") | ||
| 1088 | |||
| 1074 | ;;;###autoload | 1089 | ;;;###autoload |
| 1075 | (defconst tramp-completion-file-name-handler-alist | 1090 | (defconst tramp-completion-file-name-handler-alist |
| 1076 | '((file-name-all-completions . tramp-completion-handle-file-name-all-completions) | 1091 | '((file-name-all-completions . tramp-completion-handle-file-name-all-completions) |
| @@ -1464,10 +1479,6 @@ ARGS to actually emit the message (if applicable)." | |||
| 1464 | This variable is used to disable messages from `tramp-error'. | 1479 | This variable is used to disable messages from `tramp-error'. |
| 1465 | The messages are visible anyway, because an error is raised.") | 1480 | The messages are visible anyway, because an error is raised.") |
| 1466 | 1481 | ||
| 1467 | (defvar tramp-message-show-progress-reporter-message t | ||
| 1468 | "Show Tramp progress reporter message in the minibuffer. | ||
| 1469 | This variable is used to disable recursive progress reporter messages.") | ||
| 1470 | |||
| 1471 | (defsubst tramp-message (vec-or-proc level fmt-string &rest args) | 1482 | (defsubst tramp-message (vec-or-proc level fmt-string &rest args) |
| 1472 | "Emit a message depending on verbosity level. | 1483 | "Emit a message depending on verbosity level. |
| 1473 | VEC-OR-PROC identifies the Tramp buffer to use. It can be either a | 1484 | VEC-OR-PROC identifies the Tramp buffer to use. It can be either a |
| @@ -1536,23 +1547,32 @@ signal identifier to be raised, remaining args passed to | |||
| 1536 | If BUFFER is nil, show the connection buffer. Wait for 30\", or until | 1547 | If BUFFER is nil, show the connection buffer. Wait for 30\", or until |
| 1537 | an input event arrives. The other arguments are passed to `tramp-error'." | 1548 | an input event arrives. The other arguments are passed to `tramp-error'." |
| 1538 | (save-window-excursion | 1549 | (save-window-excursion |
| 1539 | (unwind-protect | 1550 | (let* ((buf (or (and (bufferp buffer) buffer) |
| 1540 | (apply 'tramp-error vec-or-proc signal fmt-string args) | 1551 | (and (processp vec-or-proc) (process-buffer vec-or-proc)) |
| 1541 | (when (and vec-or-proc | 1552 | (and (vectorp vec-or-proc) |
| 1542 | tramp-message-show-message | 1553 | (tramp-get-connection-buffer vec-or-proc)))) |
| 1543 | (not (zerop tramp-verbose)) | 1554 | (vec (or (and (vectorp vec-or-proc) vec-or-proc) |
| 1544 | (not (tramp-completion-mode-p))) | 1555 | (and buf (with-current-buffer buf |
| 1545 | (let ((enable-recursive-minibuffers t)) | 1556 | (tramp-dissect-file-name default-directory)))))) |
| 1546 | (pop-to-buffer | 1557 | (unwind-protect |
| 1547 | (or (and (bufferp buffer) buffer) | 1558 | (apply 'tramp-error vec-or-proc signal fmt-string args) |
| 1548 | (and (processp vec-or-proc) (process-buffer vec-or-proc)) | 1559 | ;; Save exit. |
| 1549 | (tramp-get-connection-buffer vec-or-proc))) | 1560 | (when (and buf |
| 1550 | (when (string-equal fmt-string "Process died") | 1561 | tramp-message-show-message |
| 1551 | (message | 1562 | (not (zerop tramp-verbose)) |
| 1552 | "%s\n %s" | 1563 | (not (tramp-completion-mode-p))) |
| 1553 | "Tramp failed to connect. If this happens repeatedly, try" | 1564 | (let ((enable-recursive-minibuffers t)) |
| 1554 | "`M-x tramp-cleanup-this-connection'")) | 1565 | ;; `tramp-error' does not show messages. So we must do it |
| 1555 | (sit-for 30)))))) | 1566 | ;; ourselves. |
| 1567 | (message fmt-string args) | ||
| 1568 | ;; Show buffer. | ||
| 1569 | (pop-to-buffer buf) | ||
| 1570 | (discard-input) | ||
| 1571 | (sit-for 30))) | ||
| 1572 | ;; Reset timestamp. It would be wrong after waiting for a while. | ||
| 1573 | (when (equal (butlast (append vec nil) 2) | ||
| 1574 | (car tramp-current-connection)) | ||
| 1575 | (setcdr tramp-current-connection (current-time))))))) | ||
| 1556 | 1576 | ||
| 1557 | (defmacro with-parsed-tramp-file-name (filename var &rest body) | 1577 | (defmacro with-parsed-tramp-file-name (filename var &rest body) |
| 1558 | "Parse a Tramp filename and make components available in the body. | 1578 | "Parse a Tramp filename and make components available in the body. |
| @@ -1596,16 +1616,15 @@ If VAR is nil, then we bind `v' to the structure and `method', `user', | |||
| 1596 | 1616 | ||
| 1597 | (defmacro with-tramp-progress-reporter (vec level message &rest body) | 1617 | (defmacro with-tramp-progress-reporter (vec level message &rest body) |
| 1598 | "Executes BODY, spinning a progress reporter with MESSAGE. | 1618 | "Executes BODY, spinning a progress reporter with MESSAGE. |
| 1599 | If LEVEL does not fit for visible messages, or if this is a | 1619 | If LEVEL does not fit for visible messages, there are only traces |
| 1600 | nested call of the macro, there are only traces without a visible | 1620 | without a visible progress reporter." |
| 1601 | progress reporter." | ||
| 1602 | (declare (indent 3) (debug t)) | 1621 | (declare (indent 3) (debug t)) |
| 1603 | `(let (pr tm) | 1622 | `(let ((result "failed") |
| 1623 | pr tm) | ||
| 1604 | (tramp-message ,vec ,level "%s..." ,message) | 1624 | (tramp-message ,vec ,level "%s..." ,message) |
| 1605 | ;; We start a pulsing progress reporter after 3 seconds. Feature | 1625 | ;; We start a pulsing progress reporter after 3 seconds. Feature |
| 1606 | ;; introduced in Emacs 24.1. | 1626 | ;; introduced in Emacs 24.1. |
| 1607 | (when (and tramp-message-show-progress-reporter-message | 1627 | (when (and tramp-message-show-message |
| 1608 | tramp-message-show-message | ||
| 1609 | ;; Display only when there is a minimum level. | 1628 | ;; Display only when there is a minimum level. |
| 1610 | (<= ,level (min tramp-verbose 3))) | 1629 | (<= ,level (min tramp-verbose 3))) |
| 1611 | (ignore-errors | 1630 | (ignore-errors |
| @@ -1613,14 +1632,11 @@ progress reporter." | |||
| 1613 | tm (when pr | 1632 | tm (when pr |
| 1614 | (run-at-time 3 0.1 'tramp-progress-reporter-update pr))))) | 1633 | (run-at-time 3 0.1 'tramp-progress-reporter-update pr))))) |
| 1615 | (unwind-protect | 1634 | (unwind-protect |
| 1616 | ;; Execute the body. Suppress concurrent progress reporter | 1635 | ;; Execute the body. |
| 1617 | ;; messages. | 1636 | (prog1 (progn ,@body) (setq result "done")) |
| 1618 | (let ((tramp-message-show-progress-reporter-message | ||
| 1619 | (and tramp-message-show-progress-reporter-message (not tm)))) | ||
| 1620 | ,@body) | ||
| 1621 | ;; Stop progress reporter. | 1637 | ;; Stop progress reporter. |
| 1622 | (if tm (tramp-compat-funcall 'cancel-timer tm)) | 1638 | (if tm (tramp-compat-funcall 'cancel-timer tm)) |
| 1623 | (tramp-message ,vec ,level "%s...done" ,message)))) | 1639 | (tramp-message ,vec ,level "%s...%s" ,message result)))) |
| 1624 | 1640 | ||
| 1625 | (tramp-compat-font-lock-add-keywords | 1641 | (tramp-compat-font-lock-add-keywords |
| 1626 | 'emacs-lisp-mode '("\\<with-tramp-progress-reporter\\>")) | 1642 | 'emacs-lisp-mode '("\\<with-tramp-progress-reporter\\>")) |
| @@ -1964,7 +1980,7 @@ ARGS are the arguments OPERATION has been called with." | |||
| 1964 | ;; Emacs 22+ only. | 1980 | ;; Emacs 22+ only. |
| 1965 | 'set-file-times | 1981 | 'set-file-times |
| 1966 | ;; Emacs 24+ only. | 1982 | ;; Emacs 24+ only. |
| 1967 | 'file-acl 'file-selinux-context | 1983 | 'file-acl 'file-notify-add-watch 'file-selinux-context |
| 1968 | 'set-file-acl 'set-file-selinux-context | 1984 | 'set-file-acl 'set-file-selinux-context |
| 1969 | ;; XEmacs only. | 1985 | ;; XEmacs only. |
| 1970 | 'abbreviate-file-name 'create-file-buffer | 1986 | 'abbreviate-file-name 'create-file-buffer |
| @@ -2018,6 +2034,10 @@ ARGS are the arguments OPERATION has been called with." | |||
| 2018 | ;; XEmacs only. | 2034 | ;; XEmacs only. |
| 2019 | 'dired-print-file 'dired-shell-call-process)) | 2035 | 'dired-print-file 'dired-shell-call-process)) |
| 2020 | default-directory) | 2036 | default-directory) |
| 2037 | ;; PROC. | ||
| 2038 | ((eq operation 'file-notify-rm-watch) | ||
| 2039 | (with-current-buffer (process-buffer (nth 0 args)) | ||
| 2040 | default-directory)) | ||
| 2021 | ;; Unknown file primitive. | 2041 | ;; Unknown file primitive. |
| 2022 | (t (error "unknown file I/O primitive: %s" operation)))) | 2042 | (t (error "unknown file I/O primitive: %s" operation)))) |
| 2023 | 2043 | ||
| @@ -3389,39 +3409,49 @@ The terminal type can be configured with `tramp-terminal-type'." | |||
| 3389 | PROC and VEC indicate the remote connection to be used. POS, if | 3409 | PROC and VEC indicate the remote connection to be used. POS, if |
| 3390 | set, is the starting point of the region to be deleted in the | 3410 | set, is the starting point of the region to be deleted in the |
| 3391 | connection buffer." | 3411 | connection buffer." |
| 3392 | ;; Preserve message for `progress-reporter'. | 3412 | ;; Enable `auth-source' and `password-cache'. We must use |
| 3393 | (tramp-compat-with-temp-message "" | 3413 | ;; tramp-current-* variables in case we have several hops. |
| 3394 | ;; Enable `auth-source' and `password-cache'. We must use | 3414 | (tramp-set-connection-property |
| 3395 | ;; tramp-current-* variables in case we have several hops. | 3415 | (tramp-dissect-file-name |
| 3396 | (tramp-set-connection-property | 3416 | (tramp-make-tramp-file-name |
| 3397 | (tramp-dissect-file-name | 3417 | tramp-current-method tramp-current-user tramp-current-host "")) |
| 3398 | (tramp-make-tramp-file-name | 3418 | "first-password-request" t) |
| 3399 | tramp-current-method tramp-current-user tramp-current-host "")) | 3419 | (save-restriction |
| 3400 | "first-password-request" t) | 3420 | (with-tramp-progress-reporter |
| 3401 | (save-restriction | 3421 | proc 3 "Waiting for prompts from remote shell" |
| 3402 | (let (exit) | 3422 | (let (exit) |
| 3403 | (while (not exit) | 3423 | (if timeout |
| 3404 | (tramp-message proc 3 "Waiting for prompts from remote shell") | 3424 | (with-timeout (timeout (setq exit 'timeout)) |
| 3405 | (setq exit | 3425 | (while (not exit) |
| 3406 | (catch 'tramp-action | 3426 | (setq exit |
| 3407 | (if timeout | 3427 | (catch 'tramp-action |
| 3408 | (with-timeout (timeout) | 3428 | (tramp-process-one-action proc vec actions))))) |
| 3409 | (tramp-process-one-action proc vec actions)) | 3429 | (while (not exit) |
| 3430 | (setq exit | ||
| 3431 | (catch 'tramp-action | ||
| 3410 | (tramp-process-one-action proc vec actions))))) | 3432 | (tramp-process-one-action proc vec actions))))) |
| 3411 | (with-current-buffer (tramp-get-connection-buffer vec) | 3433 | (with-current-buffer (tramp-get-connection-buffer vec) |
| 3412 | (widen) | 3434 | (widen) |
| 3413 | (tramp-message vec 6 "\n%s" (buffer-string))) | 3435 | (tramp-message vec 6 "\n%s" (buffer-string))) |
| 3414 | (unless (eq exit 'ok) | 3436 | (unless (eq exit 'ok) |
| 3415 | (tramp-clear-passwd vec) | 3437 | (tramp-clear-passwd vec) |
| 3438 | (delete-process proc) | ||
| 3416 | (tramp-error-with-buffer | 3439 | (tramp-error-with-buffer |
| 3417 | nil vec 'file-error | 3440 | (tramp-get-connection-buffer vec) vec 'file-error |
| 3418 | (cond | 3441 | (cond |
| 3419 | ((eq exit 'permission-denied) "Permission denied") | 3442 | ((eq exit 'permission-denied) "Permission denied") |
| 3420 | ((eq exit 'process-died) "Process died") | 3443 | ((eq exit 'process-died) |
| 3421 | (t "Login failed")))) | 3444 | (concat |
| 3422 | (when (numberp pos) | 3445 | "Tramp failed to connect. If this happens repeatedly, try\n" |
| 3423 | (with-current-buffer (tramp-get-connection-buffer vec) | 3446 | " `M-x tramp-cleanup-this-connection'")) |
| 3424 | (let (buffer-read-only) (delete-region pos (point))))))))) | 3447 | ((eq exit 'timeout) |
| 3448 | (format | ||
| 3449 | "Timeout reached, see buffer `%s' for details" | ||
| 3450 | (tramp-get-connection-buffer vec))) | ||
| 3451 | (t "Login failed"))))) | ||
| 3452 | (when (numberp pos) | ||
| 3453 | (with-current-buffer (tramp-get-connection-buffer vec) | ||
| 3454 | (let (buffer-read-only) (delete-region pos (point)))))))) | ||
| 3425 | 3455 | ||
| 3426 | :;; Utility functions: | 3456 | :;; Utility functions: |
| 3427 | 3457 | ||
| @@ -4156,6 +4186,9 @@ Only works for Bourne-like shells." | |||
| 4156 | ;; * Run emerge on two remote files. Bug is described here: | 4186 | ;; * Run emerge on two remote files. Bug is described here: |
| 4157 | ;; <http://www.mail-archive.com/tramp-devel@nongnu.org/msg01041.html>. | 4187 | ;; <http://www.mail-archive.com/tramp-devel@nongnu.org/msg01041.html>. |
| 4158 | ;; (Bug#6850) | 4188 | ;; (Bug#6850) |
| 4189 | ;; * Use also port to distinguish connections. This is needed for | ||
| 4190 | ;; different hosts sitting behind a single router (distinguished by | ||
| 4191 | ;; different port numbers). (Tzvi Edelman) | ||
| 4159 | 4192 | ||
| 4160 | ;;; tramp.el ends here | 4193 | ;;; tramp.el ends here |
| 4161 | 4194 | ||
diff --git a/lisp/progmodes/cc-engine.el b/lisp/progmodes/cc-engine.el index 9077bdbb513..a3bd000a4f3 100644 --- a/lisp/progmodes/cc-engine.el +++ b/lisp/progmodes/cc-engine.el | |||
| @@ -6892,7 +6892,7 @@ comment at the start of cc-engine.el for more info." | |||
| 6892 | (while (and (looking-at c-type-decl-prefix-key) | 6892 | (while (and (looking-at c-type-decl-prefix-key) |
| 6893 | (if (and (c-major-mode-is 'c++-mode) | 6893 | (if (and (c-major-mode-is 'c++-mode) |
| 6894 | (match-beginning 3)) | 6894 | (match-beginning 3)) |
| 6895 | ;; If the second submatch matches in C++ then | 6895 | ;; If the third submatch matches in C++ then |
| 6896 | ;; we're looking at an identifier that's a | 6896 | ;; we're looking at an identifier that's a |
| 6897 | ;; prefix only if it specifies a member pointer. | 6897 | ;; prefix only if it specifies a member pointer. |
| 6898 | (when (setq got-identifier (c-forward-name)) | 6898 | (when (setq got-identifier (c-forward-name)) |
| @@ -7193,19 +7193,23 @@ comment at the start of cc-engine.el for more info." | |||
| 7193 | ;; uncommon (e.g. some placements of "const" in C++) it's not worth | 7193 | ;; uncommon (e.g. some placements of "const" in C++) it's not worth |
| 7194 | ;; the effort to look for them.) | 7194 | ;; the effort to look for them.) |
| 7195 | 7195 | ||
| 7196 | (unless (or at-decl-end (looking-at "=[^=]")) | 7196 | ;;; 2008-04-16: commented out the next form, to allow the function to recognize |
| 7197 | ;; If this is a declaration it should end here or its initializer(*) | 7197 | ;;; "foo (int bar)" in CC (an implicit type (in class foo) without a semicolon) |
| 7198 | ;; should start here, so check for allowed separation tokens. Note | 7198 | ;;; as a(n almost complete) declaration, enabling it to be fontified. |
| 7199 | ;; that this rule doesn't work e.g. with a K&R arglist after a | 7199 | ;; CASE 13 |
| 7200 | ;; function header. | 7200 | ;; (unless (or at-decl-end (looking-at "=[^=]")) |
| 7201 | ;; | 7201 | ;; If this is a declaration it should end here or its initializer(*) |
| 7202 | ;; *) Don't check for C++ style initializers using parens | 7202 | ;; should start here, so check for allowed separation tokens. Note |
| 7203 | ;; since those already have been matched as suffixes. | 7203 | ;; that this rule doesn't work e.g. with a K&R arglist after a |
| 7204 | ;; | 7204 | ;; function header. |
| 7205 | ;; If `at-decl-or-cast' is then we've found some other sign that | 7205 | ;; |
| 7206 | ;; it's a declaration or cast, so then it's probably an | 7206 | ;; *) Don't check for C++ style initializers using parens |
| 7207 | ;; invalid/unfinished one. | 7207 | ;; since those already have been matched as suffixes. |
| 7208 | (throw 'at-decl-or-cast at-decl-or-cast)) | 7208 | ;; |
| 7209 | ;; If `at-decl-or-cast' is then we've found some other sign that | ||
| 7210 | ;; it's a declaration or cast, so then it's probably an | ||
| 7211 | ;; invalid/unfinished one. | ||
| 7212 | ;; (throw 'at-decl-or-cast at-decl-or-cast)) | ||
| 7209 | 7213 | ||
| 7210 | ;; Below are tests that only should be applied when we're certain to | 7214 | ;; Below are tests that only should be applied when we're certain to |
| 7211 | ;; not have parsed halfway through an expression. | 7215 | ;; not have parsed halfway through an expression. |
diff --git a/lisp/progmodes/cfengine.el b/lisp/progmodes/cfengine.el index 55d5b8b0be7..85a9074760d 100644 --- a/lisp/progmodes/cfengine.el +++ b/lisp/progmodes/cfengine.el | |||
| @@ -387,10 +387,10 @@ Intended as the value of `indent-line-function'." | |||
| 387 | (skip-chars-forward " \t") | 387 | (skip-chars-forward " \t") |
| 388 | (current-column))) | 388 | (current-column))) |
| 389 | (error nil))) | 389 | (error nil))) |
| 390 | ;; Inside a string and it starts before this line. | 390 | ;; Inside a string and it starts before this line: do nothing. |
| 391 | ((and (nth 3 parse) | 391 | ((and (nth 3 parse) |
| 392 | (< (nth 8 parse) (save-excursion (beginning-of-line) (point)))) | 392 | (< (nth 8 parse) (save-excursion (beginning-of-line) (point)))) |
| 393 | (indent-line-to 0)) | 393 | ) |
| 394 | 394 | ||
| 395 | ;; Inside a defun, but not a nested list (depth is 1). This is | 395 | ;; Inside a defun, but not a nested list (depth is 1). This is |
| 396 | ;; a promise, usually. | 396 | ;; a promise, usually. |
diff --git a/lisp/progmodes/ebrowse.el b/lisp/progmodes/ebrowse.el index 4957b58d469..6a71ab330a8 100644 --- a/lisp/progmodes/ebrowse.el +++ b/lisp/progmodes/ebrowse.el | |||
| @@ -33,12 +33,12 @@ | |||
| 33 | 33 | ||
| 34 | ;;; Code: | 34 | ;;; Code: |
| 35 | 35 | ||
| 36 | (require 'cl-lib) | ||
| 36 | (require 'easymenu) | 37 | (require 'easymenu) |
| 37 | (require 'view) | 38 | (require 'view) |
| 38 | (require 'ebuff-menu) | 39 | (require 'ebuff-menu) |
| 39 | 40 | ||
| 40 | (eval-when-compile | 41 | (eval-when-compile |
| 41 | (require 'cl-lib) | ||
| 42 | (require 'helper)) | 42 | (require 'helper)) |
| 43 | 43 | ||
| 44 | 44 | ||
| @@ -233,19 +233,6 @@ Compare items with `eq' or TEST if specified." | |||
| 233 | found)) | 233 | found)) |
| 234 | 234 | ||
| 235 | 235 | ||
| 236 | (defun ebrowse-delete-if-not (predicate list) | ||
| 237 | "Remove elements not satisfying PREDICATE from LIST and return the result. | ||
| 238 | This is a destructive operation." | ||
| 239 | (let (result) | ||
| 240 | (while list | ||
| 241 | (let ((next (cdr list))) | ||
| 242 | (when (funcall predicate (car list)) | ||
| 243 | (setq result (nconc result list)) | ||
| 244 | (setf (cdr list) nil)) | ||
| 245 | (setq list next))) | ||
| 246 | result)) | ||
| 247 | |||
| 248 | |||
| 249 | (defmacro ebrowse-output (&rest body) | 236 | (defmacro ebrowse-output (&rest body) |
| 250 | "Eval BODY with a writable current buffer. | 237 | "Eval BODY with a writable current buffer. |
| 251 | Preserve buffer's modified state." | 238 | Preserve buffer's modified state." |
| @@ -1310,17 +1297,17 @@ With PREFIX, insert that many filenames." | |||
| 1310 | 1297 | ||
| 1311 | (defun ebrowse-browser-buffer-list () | 1298 | (defun ebrowse-browser-buffer-list () |
| 1312 | "Return a list of all tree or member buffers." | 1299 | "Return a list of all tree or member buffers." |
| 1313 | (ebrowse-delete-if-not 'ebrowse-buffer-p (buffer-list))) | 1300 | (cl-delete-if-not 'ebrowse-buffer-p (buffer-list))) |
| 1314 | 1301 | ||
| 1315 | 1302 | ||
| 1316 | (defun ebrowse-member-buffer-list () | 1303 | (defun ebrowse-member-buffer-list () |
| 1317 | "Return a list of all member buffers." | 1304 | "Return a list of all member buffers." |
| 1318 | (ebrowse-delete-if-not 'ebrowse-member-buffer-p (buffer-list))) | 1305 | (cl-delete-if-not 'ebrowse-member-buffer-p (buffer-list))) |
| 1319 | 1306 | ||
| 1320 | 1307 | ||
| 1321 | (defun ebrowse-tree-buffer-list () | 1308 | (defun ebrowse-tree-buffer-list () |
| 1322 | "Return a list of all tree buffers." | 1309 | "Return a list of all tree buffers." |
| 1323 | (ebrowse-delete-if-not 'ebrowse-tree-buffer-p (buffer-list))) | 1310 | (cl-delete-if-not 'ebrowse-tree-buffer-p (buffer-list))) |
| 1324 | 1311 | ||
| 1325 | 1312 | ||
| 1326 | (defun ebrowse-known-class-trees-buffer-list () | 1313 | (defun ebrowse-known-class-trees-buffer-list () |
| @@ -1341,7 +1328,7 @@ one buffer. Prefer tree buffers over member buffers." | |||
| 1341 | 1328 | ||
| 1342 | (defun ebrowse-same-tree-member-buffer-list () | 1329 | (defun ebrowse-same-tree-member-buffer-list () |
| 1343 | "Return a list of members buffers with same tree as current buffer." | 1330 | "Return a list of members buffers with same tree as current buffer." |
| 1344 | (ebrowse-delete-if-not | 1331 | (cl-delete-if-not |
| 1345 | (lambda (buffer) | 1332 | (lambda (buffer) |
| 1346 | (eq (buffer-local-value 'ebrowse--tree buffer) | 1333 | (eq (buffer-local-value 'ebrowse--tree buffer) |
| 1347 | ebrowse--tree)) | 1334 | ebrowse--tree)) |
diff --git a/lisp/progmodes/gdb-mi.el b/lisp/progmodes/gdb-mi.el index 2c4d6a0e3d7..10472ec5815 100644 --- a/lisp/progmodes/gdb-mi.el +++ b/lisp/progmodes/gdb-mi.el | |||
| @@ -1759,6 +1759,9 @@ static char *magick[] = { | |||
| 1759 | As long as GDB is in the recursive reading loop, it does not expect | 1759 | As long as GDB is in the recursive reading loop, it does not expect |
| 1760 | commands to be prefixed by \"-interpreter-exec console\".") | 1760 | commands to be prefixed by \"-interpreter-exec console\".") |
| 1761 | 1761 | ||
| 1762 | (defun gdb-strip-string-backslash (string) | ||
| 1763 | (replace-regexp-in-string "\\\\$" "" string)) | ||
| 1764 | |||
| 1762 | (defun gdb-send (proc string) | 1765 | (defun gdb-send (proc string) |
| 1763 | "A comint send filter for gdb." | 1766 | "A comint send filter for gdb." |
| 1764 | (with-current-buffer gud-comint-buffer | 1767 | (with-current-buffer gud-comint-buffer |
| @@ -1766,10 +1769,15 @@ commands to be prefixed by \"-interpreter-exec console\".") | |||
| 1766 | (remove-text-properties (point-min) (point-max) '(face)))) | 1769 | (remove-text-properties (point-min) (point-max) '(face)))) |
| 1767 | ;; mimic <RET> key to repeat previous command in GDB | 1770 | ;; mimic <RET> key to repeat previous command in GDB |
| 1768 | (if (not (string= "" string)) | 1771 | (if (not (string= "" string)) |
| 1769 | (setq gdb-last-command string) | 1772 | (if gdb-continuation |
| 1770 | (if gdb-last-command (setq string gdb-last-command))) | 1773 | (setq gdb-last-command (concat gdb-continuation |
| 1771 | (if (or (string-match "^-" string) | 1774 | (gdb-strip-string-backslash string) |
| 1772 | (> gdb-control-level 0)) | 1775 | " ")) |
| 1776 | (setq gdb-last-command (gdb-strip-string-backslash string))) | ||
| 1777 | (if gdb-last-command (setq string gdb-last-command)) | ||
| 1778 | (setq gdb-continuation nil)) | ||
| 1779 | (if (and (not gdb-continuation) (or (string-match "^-" string) | ||
| 1780 | (> gdb-control-level 0))) | ||
| 1773 | ;; Either MI command or we are feeding GDB's recursive reading loop. | 1781 | ;; Either MI command or we are feeding GDB's recursive reading loop. |
| 1774 | (progn | 1782 | (progn |
| 1775 | (setq gdb-first-done-or-error t) | 1783 | (setq gdb-first-done-or-error t) |
| @@ -1779,10 +1787,13 @@ commands to be prefixed by \"-interpreter-exec console\".") | |||
| 1779 | (setq gdb-control-level (1- gdb-control-level)))) | 1787 | (setq gdb-control-level (1- gdb-control-level)))) |
| 1780 | ;; CLI command | 1788 | ;; CLI command |
| 1781 | (if (string-match "\\\\$" string) | 1789 | (if (string-match "\\\\$" string) |
| 1782 | (setq gdb-continuation (concat gdb-continuation string "\n")) | 1790 | (setq gdb-continuation |
| 1791 | (concat gdb-continuation (gdb-strip-string-backslash | ||
| 1792 | string) | ||
| 1793 | " ")) | ||
| 1783 | (setq gdb-first-done-or-error t) | 1794 | (setq gdb-first-done-or-error t) |
| 1784 | (let ((to-send (concat "-interpreter-exec console " | 1795 | (let ((to-send (concat "-interpreter-exec console " |
| 1785 | (gdb-mi-quote string) | 1796 | (gdb-mi-quote (concat gdb-continuation string " ")) |
| 1786 | "\n"))) | 1797 | "\n"))) |
| 1787 | (if gdb-enable-debug | 1798 | (if gdb-enable-debug |
| 1788 | (push (cons 'mi-send to-send) gdb-debug-log)) | 1799 | (push (cons 'mi-send to-send) gdb-debug-log)) |
diff --git a/lisp/progmodes/python.el b/lisp/progmodes/python.el index 915b52ce04d..62870f9085b 100644 --- a/lisp/progmodes/python.el +++ b/lisp/progmodes/python.el | |||
| @@ -3091,7 +3091,12 @@ you are doing." | |||
| 3091 | ;; Stop collecting nodes after moving to a position with | 3091 | ;; Stop collecting nodes after moving to a position with |
| 3092 | ;; indentation equaling min-indent. This is specially | 3092 | ;; indentation equaling min-indent. This is specially |
| 3093 | ;; useful for navigating nested definitions recursively. | 3093 | ;; useful for navigating nested definitions recursively. |
| 3094 | tree) | 3094 | (if (> num-children 0) |
| 3095 | tree | ||
| 3096 | ;; When there are no children, the collected tree is a | ||
| 3097 | ;; single node intended to be added in the list of defuns | ||
| 3098 | ;; of its parent. | ||
| 3099 | (car tree))) | ||
| 3095 | (t | 3100 | (t |
| 3096 | (python-imenu--build-tree | 3101 | (python-imenu--build-tree |
| 3097 | min-indent | 3102 | min-indent |
| @@ -3131,7 +3136,7 @@ you are doing." | |||
| 3131 | (cons | 3136 | (cons |
| 3132 | (prog1 | 3137 | (prog1 |
| 3133 | (python-imenu--build-tree | 3138 | (python-imenu--build-tree |
| 3134 | prev-indent indent 1 (list (cons label pos))) | 3139 | prev-indent indent 0 (list (cons label pos))) |
| 3135 | ;; Adjustment: after scanning backwards | 3140 | ;; Adjustment: after scanning backwards |
| 3136 | ;; for all deeper children, we need to | 3141 | ;; for all deeper children, we need to |
| 3137 | ;; continue our scan for a parent from | 3142 | ;; continue our scan for a parent from |
diff --git a/lisp/progmodes/ruby-mode.el b/lisp/progmodes/ruby-mode.el index 0292e40b986..0b83921504b 100644 --- a/lisp/progmodes/ruby-mode.el +++ b/lisp/progmodes/ruby-mode.el | |||
| @@ -990,13 +990,14 @@ calculating indentation on the lines after it." | |||
| 990 | (defun ruby-move-to-block (n) | 990 | (defun ruby-move-to-block (n) |
| 991 | "Move to the beginning (N < 0) or the end (N > 0) of the | 991 | "Move to the beginning (N < 0) or the end (N > 0) of the |
| 992 | current block, a sibling block, or an outer block. Do that (abs N) times." | 992 | current block, a sibling block, or an outer block. Do that (abs N) times." |
| 993 | (back-to-indentation) | ||
| 993 | (let ((signum (if (> n 0) 1 -1)) | 994 | (let ((signum (if (> n 0) 1 -1)) |
| 994 | (backward (< n 0)) | 995 | (backward (< n 0)) |
| 995 | (depth (or (nth 2 (ruby-parse-region (line-beginning-position) | 996 | (depth (or (nth 2 (ruby-parse-region (point) (line-end-position))) 0)) |
| 996 | (line-end-position))) | ||
| 997 | 0)) | ||
| 998 | case-fold-search | 997 | case-fold-search |
| 999 | down done) | 998 | down done) |
| 999 | (when (looking-at ruby-block-mid-re) | ||
| 1000 | (setq depth (+ depth signum))) | ||
| 1000 | (when (< (* depth signum) 0) | 1001 | (when (< (* depth signum) 0) |
| 1001 | ;; Moving end -> end or beginning -> beginning. | 1002 | ;; Moving end -> end or beginning -> beginning. |
| 1002 | (setq depth 0)) | 1003 | (setq depth 0)) |
| @@ -1033,22 +1034,16 @@ current block, a sibling block, or an outer block. Do that (abs N) times." | |||
| 1033 | (unless (car state) ; Line ends with unfinished string. | 1034 | (unless (car state) ; Line ends with unfinished string. |
| 1034 | (setq depth (+ (nth 2 state) depth)))) | 1035 | (setq depth (+ (nth 2 state) depth)))) |
| 1035 | (cond | 1036 | (cond |
| 1036 | ;; Deeper indentation, we found a block. | 1037 | ;; Increased depth, we found a block. |
| 1037 | ;; FIXME: We can't recognize empty blocks this way. | ||
| 1038 | ((> (* signum depth) 0) | 1038 | ((> (* signum depth) 0) |
| 1039 | (setq down t)) | 1039 | (setq down t)) |
| 1040 | ;; Block found, and same indentation as when started, stop. | 1040 | ;; We're at the same depth as when we started, and we've |
| 1041 | ;; encountered a block before. Stop. | ||
| 1041 | ((and down (zerop depth)) | 1042 | ((and down (zerop depth)) |
| 1042 | (setq done t)) | 1043 | (setq done t)) |
| 1043 | ;; Shallower indentation, means outer block, can stop now. | 1044 | ;; Lower depth, means outer block, can stop now. |
| 1044 | ((< (* signum depth) 0) | 1045 | ((< (* signum depth) 0) |
| 1045 | (setq done t))))) | 1046 | (setq done t))))))) |
| 1046 | (if done | ||
| 1047 | (save-excursion | ||
| 1048 | (back-to-indentation) | ||
| 1049 | ;; Not really at the first or last line of the block, move on. | ||
| 1050 | (if (looking-at (concat "\\<\\(" ruby-block-mid-re "\\)\\>")) | ||
| 1051 | (setq done nil)))))) | ||
| 1052 | (back-to-indentation))) | 1047 | (back-to-indentation))) |
| 1053 | 1048 | ||
| 1054 | (defun ruby-beginning-of-block (&optional arg) | 1049 | (defun ruby-beginning-of-block (&optional arg) |
| @@ -1356,7 +1351,7 @@ If the result is do-end block, it will always be multiline." | |||
| 1356 | (progn | 1351 | (progn |
| 1357 | (eval-and-compile | 1352 | (eval-and-compile |
| 1358 | (defconst ruby-percent-literal-beg-re | 1353 | (defconst ruby-percent-literal-beg-re |
| 1359 | "\\(%\\)[qQrswWx]?\\([[:punct:]]\\)" | 1354 | "\\(%\\)[qQrswWxIi]?\\([[:punct:]]\\)" |
| 1360 | "Regexp to match the beginning of percent literal.") | 1355 | "Regexp to match the beginning of percent literal.") |
| 1361 | 1356 | ||
| 1362 | (defconst ruby-syntax-methods-before-regexp | 1357 | (defconst ruby-syntax-methods-before-regexp |
| @@ -1392,7 +1387,7 @@ It will be properly highlighted even when the call omits parens.") | |||
| 1392 | (funcall | 1387 | (funcall |
| 1393 | (syntax-propertize-rules | 1388 | (syntax-propertize-rules |
| 1394 | ;; $' $" $` .... are variables. | 1389 | ;; $' $" $` .... are variables. |
| 1395 | ;; ?' ?" ?` are ascii codes. | 1390 | ;; ?' ?" ?` are character literals (one-char strings in 1.9+). |
| 1396 | ("\\([?$]\\)[#\"'`]" | 1391 | ("\\([?$]\\)[#\"'`]" |
| 1397 | (1 (unless (save-excursion | 1392 | (1 (unless (save-excursion |
| 1398 | ;; Not within a string. | 1393 | ;; Not within a string. |
| @@ -1523,7 +1518,7 @@ It will be properly highlighted even when the call omits parens.") | |||
| 1523 | (save-match-data | 1518 | (save-match-data |
| 1524 | (save-excursion | 1519 | (save-excursion |
| 1525 | (goto-char (nth 8 parse-state)) | 1520 | (goto-char (nth 8 parse-state)) |
| 1526 | (looking-at "%\\(?:[QWrx]\\|\\W\\)"))))))) | 1521 | (looking-at "%\\(?:[QWrxI]\\|\\W\\)"))))))) |
| 1527 | 1522 | ||
| 1528 | (defun ruby-syntax-propertize-expansions (start end) | 1523 | (defun ruby-syntax-propertize-expansions (start end) |
| 1529 | (save-excursion | 1524 | (save-excursion |
| @@ -1726,7 +1721,7 @@ See `font-lock-syntax-table'.") | |||
| 1726 | (defconst ruby-font-lock-keywords | 1721 | (defconst ruby-font-lock-keywords |
| 1727 | (list | 1722 | (list |
| 1728 | ;; functions | 1723 | ;; functions |
| 1729 | '("^\\s *def\\s +\\([^( \t\n]+\\)" | 1724 | '("^\\s *def\\s +\\(?:[^( \t\n.]*\\.\\)?\\([^( \t\n]+\\)" |
| 1730 | 1 font-lock-function-name-face) | 1725 | 1 font-lock-function-name-face) |
| 1731 | (list (concat | 1726 | (list (concat |
| 1732 | "\\(^\\|[^.@$]\\|\\.\\.\\)\\(" | 1727 | "\\(^\\|[^.@$]\\|\\.\\.\\)\\(" |
| @@ -1767,31 +1762,66 @@ See `font-lock-syntax-table'.") | |||
| 1767 | "yield") | 1762 | "yield") |
| 1768 | 'symbols) | 1763 | 'symbols) |
| 1769 | "\\|" | 1764 | "\\|" |
| 1770 | ;; keyword-like methods on Kernel and Module | ||
| 1771 | (regexp-opt | 1765 | (regexp-opt |
| 1772 | '("alias_method" | 1766 | ;; built-in methods on Kernel |
| 1767 | '("__callee__" | ||
| 1768 | "__dir__" | ||
| 1769 | "__method__" | ||
| 1770 | "abort" | ||
| 1771 | "at_exit" | ||
| 1773 | "autoload" | 1772 | "autoload" |
| 1773 | "autoload?" | ||
| 1774 | "binding" | ||
| 1775 | "block_given?" | ||
| 1776 | "caller" | ||
| 1777 | "catch" | ||
| 1778 | "eval" | ||
| 1779 | "exec" | ||
| 1780 | "exit" | ||
| 1781 | "exit!" | ||
| 1782 | "fail" | ||
| 1783 | "fork" | ||
| 1784 | "format" | ||
| 1785 | "lambda" | ||
| 1786 | "load" | ||
| 1787 | "loop" | ||
| 1788 | "open" | ||
| 1789 | "p" | ||
| 1790 | "print" | ||
| 1791 | "printf" | ||
| 1792 | "proc" | ||
| 1793 | "putc" | ||
| 1794 | "puts" | ||
| 1795 | "raise" | ||
| 1796 | "rand" | ||
| 1797 | "readline" | ||
| 1798 | "readlines" | ||
| 1799 | "require" | ||
| 1800 | "require_relative" | ||
| 1801 | "sleep" | ||
| 1802 | "spawn" | ||
| 1803 | "sprintf" | ||
| 1804 | "srand" | ||
| 1805 | "syscall" | ||
| 1806 | "system" | ||
| 1807 | "throw" | ||
| 1808 | "trap" | ||
| 1809 | "warn" | ||
| 1810 | ;; keyword-like private methods on Module | ||
| 1811 | "alias_method" | ||
| 1774 | "attr" | 1812 | "attr" |
| 1775 | "attr_accessor" | 1813 | "attr_accessor" |
| 1776 | "attr_reader" | 1814 | "attr_reader" |
| 1777 | "attr_writer" | 1815 | "attr_writer" |
| 1778 | "catch" | ||
| 1779 | "define_method" | 1816 | "define_method" |
| 1780 | "extend" | 1817 | "extend" |
| 1781 | "fail" | ||
| 1782 | "include" | 1818 | "include" |
| 1783 | "lambda" | ||
| 1784 | "loop" | ||
| 1785 | "module_function" | 1819 | "module_function" |
| 1820 | "prepend" | ||
| 1786 | "private" | 1821 | "private" |
| 1787 | "proc" | ||
| 1788 | "protected" | 1822 | "protected" |
| 1789 | "public" | 1823 | "public" |
| 1790 | "raise" | ||
| 1791 | "refine" | 1824 | "refine" |
| 1792 | "require" | ||
| 1793 | "require_relative" | ||
| 1794 | "throw" | ||
| 1795 | "using") | 1825 | "using") |
| 1796 | 'symbols) | 1826 | 'symbols) |
| 1797 | "\\)") | 1827 | "\\)") |
| @@ -1799,12 +1829,16 @@ See `font-lock-syntax-table'.") | |||
| 1799 | '(if (match-beginning 4) | 1829 | '(if (match-beginning 4) |
| 1800 | font-lock-builtin-face | 1830 | font-lock-builtin-face |
| 1801 | font-lock-keyword-face)) | 1831 | font-lock-keyword-face)) |
| 1832 | ;; Perl-ish keywords | ||
| 1833 | "\\_<\\(?:BEGIN\\|END\\)\\_>\\|^__END__$" | ||
| 1802 | ;; here-doc beginnings | 1834 | ;; here-doc beginnings |
| 1803 | `(,ruby-here-doc-beg-re 0 (unless (ruby-singleton-class-p (match-beginning 0)) | 1835 | `(,ruby-here-doc-beg-re 0 (unless (ruby-singleton-class-p (match-beginning 0)) |
| 1804 | 'font-lock-string-face)) | 1836 | 'font-lock-string-face)) |
| 1805 | ;; variables | 1837 | ;; variables |
| 1806 | '("\\(^\\|[^.@$]\\|\\.\\.\\)\\_<\\(nil\\|self\\|true\\|false\\)\\>" | 1838 | '("\\(^\\|[^.@$]\\|\\.\\.\\)\\_<\\(nil\\|self\\|true\\|false\\)\\>" |
| 1807 | 2 font-lock-variable-name-face) | 1839 | 2 font-lock-variable-name-face) |
| 1840 | ;; keywords that evaluate to certain values | ||
| 1841 | '("\\_<__\\(?:LINE\\|ENCODING\\|FILE\\)__\\_>" 0 font-lock-variable-name-face) | ||
| 1808 | ;; symbols | 1842 | ;; symbols |
| 1809 | '("\\(^\\|[^:]\\)\\(:\\([-+~]@?\\|[/%&|^`]\\|\\*\\*?\\|<\\(<\\|=>?\\)?\\|>[>=]?\\|===?\\|=~\\|![~=]?\\|\\[\\]=?\\|@?\\(\\w\\|_\\)+\\([!?=]\\|\\b_*\\)\\|#{[^}\n\\\\]*\\(\\\\.[^}\n\\\\]*\\)*}\\)\\)" | 1843 | '("\\(^\\|[^:]\\)\\(:\\([-+~]@?\\|[/%&|^`]\\|\\*\\*?\\|<\\(<\\|=>?\\)?\\|>[>=]?\\|===?\\|=~\\|![~=]?\\|\\[\\]=?\\|@?\\(\\w\\|_\\)+\\([!?=]\\|\\b_*\\)\\|#{[^}\n\\\\]*\\(\\\\.[^}\n\\\\]*\\)*}\\)\\)" |
| 1810 | 2 font-lock-constant-face) | 1844 | 2 font-lock-constant-face) |
| @@ -1815,14 +1849,22 @@ See `font-lock-syntax-table'.") | |||
| 1815 | 0 font-lock-variable-name-face) | 1849 | 0 font-lock-variable-name-face) |
| 1816 | ;; constants | 1850 | ;; constants |
| 1817 | '("\\(?:\\_<\\|::\\)\\([A-Z]+\\(\\w\\|_\\)*\\)" | 1851 | '("\\(?:\\_<\\|::\\)\\([A-Z]+\\(\\w\\|_\\)*\\)" |
| 1818 | 1 font-lock-type-face) | 1852 | 1 (unless (eq ?\( (char-after)) font-lock-type-face)) |
| 1819 | '("\\(^\\s *\\|[\[\{\(,]\\s *\\|\\sw\\s +\\)\\(\\(\\sw\\|_\\)+\\):[^:]" 2 font-lock-constant-face) | 1853 | '("\\(^\\s *\\|[\[\{\(,]\\s *\\|\\sw\\s +\\)\\(\\(\\sw\\|_\\)+\\):[^:]" 2 font-lock-constant-face) |
| 1854 | ;; conversion methods on Kernel | ||
| 1855 | (list (concat "\\(?:^\\|[^.@$]\\|\\.\\.\\)" | ||
| 1856 | (regexp-opt '("Array" "Complex" "Float" "Hash" | ||
| 1857 | "Integer" "Rational" "String") 'symbols)) | ||
| 1858 | 1 font-lock-builtin-face) | ||
| 1820 | ;; expression expansion | 1859 | ;; expression expansion |
| 1821 | '(ruby-match-expression-expansion | 1860 | '(ruby-match-expression-expansion |
| 1822 | 2 font-lock-variable-name-face t) | 1861 | 2 font-lock-variable-name-face t) |
| 1823 | ;; warn lower camel case | 1862 | ;; negation char |
| 1824 | ;'("\\<[a-z]+[a-z0-9]*[A-Z][A-Za-z0-9]*\\([!?]?\\|\\>\\)" | 1863 | '("[^[:alnum:]_]\\(!\\)[^=]" |
| 1825 | ; 0 font-lock-warning-face) | 1864 | 1 font-lock-negation-char-face) |
| 1865 | ;; character literals | ||
| 1866 | ;; FIXME: Support longer escape sequences. | ||
| 1867 | '("\\?\\\\?\\S " 0 font-lock-string-face) | ||
| 1826 | ) | 1868 | ) |
| 1827 | "Additional expressions to highlight in Ruby mode.") | 1869 | "Additional expressions to highlight in Ruby mode.") |
| 1828 | 1870 | ||
diff --git a/lisp/shadowfile.el b/lisp/shadowfile.el index ec6e6e7ff10..3e7789069f9 100644 --- a/lisp/shadowfile.el +++ b/lisp/shadowfile.el | |||
| @@ -74,6 +74,7 @@ | |||
| 74 | 74 | ||
| 75 | ;;; Code: | 75 | ;;; Code: |
| 76 | 76 | ||
| 77 | (require 'cl-lib) | ||
| 77 | (require 'ange-ftp) | 78 | (require 'ange-ftp) |
| 78 | 79 | ||
| 79 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | 80 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
| @@ -180,15 +181,6 @@ created by `shadow-define-regexp-group'.") | |||
| 180 | (setq list (cdr list))) | 181 | (setq list (cdr list))) |
| 181 | (car list)) | 182 | (car list)) |
| 182 | 183 | ||
| 183 | (defun shadow-remove-if (func list) | ||
| 184 | "Remove elements satisfying FUNC from LIST. | ||
| 185 | Nondestructive; actually returns a copy of the list with the elements removed." | ||
| 186 | (if list | ||
| 187 | (if (funcall func (car list)) | ||
| 188 | (shadow-remove-if func (cdr list)) | ||
| 189 | (cons (car list) (shadow-remove-if func (cdr list)))) | ||
| 190 | nil)) | ||
| 191 | |||
| 192 | (defun shadow-regexp-superquote (string) | 184 | (defun shadow-regexp-superquote (string) |
| 193 | "Like `regexp-quote', but includes the ^ and $. | 185 | "Like `regexp-quote', but includes the ^ and $. |
| 194 | This makes sure regexp matches nothing but STRING." | 186 | This makes sure regexp matches nothing but STRING." |
| @@ -238,9 +230,8 @@ instead." | |||
| 238 | Replace old definition, if any. PRIMARY and REGEXP are the | 230 | Replace old definition, if any. PRIMARY and REGEXP are the |
| 239 | information defining the cluster. For interactive use, call | 231 | information defining the cluster. For interactive use, call |
| 240 | `shadow-define-cluster' instead." | 232 | `shadow-define-cluster' instead." |
| 241 | (let ((rest (shadow-remove-if | 233 | (let ((rest (cl-remove-if (lambda (x) (equal name (car x))) |
| 242 | (function (lambda (x) (equal name (car x)))) | 234 | shadow-clusters))) |
| 243 | shadow-clusters))) | ||
| 244 | (setq shadow-clusters | 235 | (setq shadow-clusters |
| 245 | (cons (shadow-make-cluster name primary regexp) | 236 | (cons (shadow-make-cluster name primary regexp) |
| 246 | rest)))) | 237 | rest)))) |
| @@ -602,9 +593,8 @@ and to are absolute file names." | |||
| 602 | Consider them as regular expressions if third arg REGEXP is true." | 593 | Consider them as regular expressions if third arg REGEXP is true." |
| 603 | (if groups | 594 | (if groups |
| 604 | (let ((nonmatching | 595 | (let ((nonmatching |
| 605 | (shadow-remove-if | 596 | (cl-remove-if (lambda (x) (shadow-file-match x file regexp)) |
| 606 | (function (lambda (x) (shadow-file-match x file regexp))) | 597 | (car groups)))) |
| 607 | (car groups)))) | ||
| 608 | (append (cond ((equal nonmatching (car groups)) nil) | 598 | (append (cond ((equal nonmatching (car groups)) nil) |
| 609 | (regexp | 599 | (regexp |
| 610 | (let ((realname (nth 2 (shadow-parse-fullname file)))) | 600 | (let ((realname (nth 2 (shadow-parse-fullname file)))) |
| @@ -635,8 +625,7 @@ Consider them as regular expressions if third arg REGEXP is true." | |||
| 635 | "Remove PAIR from `shadow-files-to-copy'. | 625 | "Remove PAIR from `shadow-files-to-copy'. |
| 636 | PAIR must be `eq' to one of the elements of that list." | 626 | PAIR must be `eq' to one of the elements of that list." |
| 637 | (setq shadow-files-to-copy | 627 | (setq shadow-files-to-copy |
| 638 | (shadow-remove-if (function (lambda (s) (eq s pair))) | 628 | (cl-remove-if (lambda (s) (eq s pair)) shadow-files-to-copy))) |
| 639 | shadow-files-to-copy))) | ||
| 640 | 629 | ||
| 641 | (defun shadow-read-files () | 630 | (defun shadow-read-files () |
| 642 | "Visit and load `shadow-info-file' and `shadow-todo-file'. | 631 | "Visit and load `shadow-info-file' and `shadow-todo-file'. |
diff --git a/lisp/simple.el b/lisp/simple.el index 61f32363dbe..3e3ff485c5e 100644 --- a/lisp/simple.el +++ b/lisp/simple.el | |||
| @@ -4602,6 +4602,12 @@ for it.") | |||
| 4602 | (defun next-line (&optional arg try-vscroll) | 4602 | (defun next-line (&optional arg try-vscroll) |
| 4603 | "Move cursor vertically down ARG lines. | 4603 | "Move cursor vertically down ARG lines. |
| 4604 | Interactively, vscroll tall lines if `auto-window-vscroll' is enabled. | 4604 | Interactively, vscroll tall lines if `auto-window-vscroll' is enabled. |
| 4605 | Non-interactively, use TRY-VSCROLL to control whether to vscroll tall | ||
| 4606 | lines: if either `auto-window-vscroll' or TRY-VSCROLL is nil, this | ||
| 4607 | function will not vscroll. | ||
| 4608 | |||
| 4609 | ARG defaults to 1. | ||
| 4610 | |||
| 4605 | If there is no character in the target line exactly under the current column, | 4611 | If there is no character in the target line exactly under the current column, |
| 4606 | the cursor is positioned after the character in that line which spans this | 4612 | the cursor is positioned after the character in that line which spans this |
| 4607 | column, or at the end of the line if it is not long enough. | 4613 | column, or at the end of the line if it is not long enough. |
| @@ -4646,6 +4652,12 @@ and more reliable (no dependence on goal column, etc.)." | |||
| 4646 | (defun previous-line (&optional arg try-vscroll) | 4652 | (defun previous-line (&optional arg try-vscroll) |
| 4647 | "Move cursor vertically up ARG lines. | 4653 | "Move cursor vertically up ARG lines. |
| 4648 | Interactively, vscroll tall lines if `auto-window-vscroll' is enabled. | 4654 | Interactively, vscroll tall lines if `auto-window-vscroll' is enabled. |
| 4655 | Non-interactively, use TRY-VSCROLL to control whether to vscroll tall | ||
| 4656 | lines: if either `auto-window-vscroll' or TRY-VSCROLL is nil, this | ||
| 4657 | function will not vscroll. | ||
| 4658 | |||
| 4659 | ARG defaults to 1. | ||
| 4660 | |||
| 4649 | If there is no character in the target line exactly over the current column, | 4661 | If there is no character in the target line exactly over the current column, |
| 4650 | the cursor is positioned after the character in that line which spans this | 4662 | the cursor is positioned after the character in that line which spans this |
| 4651 | column, or at the end of the line if it is not long enough. | 4663 | column, or at the end of the line if it is not long enough. |
| @@ -4725,33 +4737,81 @@ lines." | |||
| 4725 | :group 'editing-basics | 4737 | :group 'editing-basics |
| 4726 | :version "23.1") | 4738 | :version "23.1") |
| 4727 | 4739 | ||
| 4740 | (defun default-font-height () | ||
| 4741 | "Return the height in pixels of the current buffer's default face font." | ||
| 4742 | (let ((default-font (face-font 'default))) | ||
| 4743 | (cond | ||
| 4744 | ((and (display-multi-font-p) | ||
| 4745 | ;; Avoid calling font-info if the frame's default font was | ||
| 4746 | ;; not changed since the frame was created. That's because | ||
| 4747 | ;; font-info is expensive for some fonts, see bug #14838. | ||
| 4748 | (not (string= (frame-parameter nil 'font) default-font))) | ||
| 4749 | (aref (font-info default-font) 3)) | ||
| 4750 | (t (frame-char-height))))) | ||
| 4751 | |||
| 4752 | (defun default-line-height () | ||
| 4753 | "Return the pixel height of current buffer's default-face text line. | ||
| 4754 | |||
| 4755 | The value includes `line-spacing', if any, defined for the buffer | ||
| 4756 | or the frame." | ||
| 4757 | (let ((dfh (default-font-height)) | ||
| 4758 | (lsp (if (display-graphic-p) | ||
| 4759 | (or line-spacing | ||
| 4760 | (default-value 'line-spacing) | ||
| 4761 | (frame-parameter nil 'line-spacing) | ||
| 4762 | 0) | ||
| 4763 | 0))) | ||
| 4764 | (if (floatp lsp) | ||
| 4765 | (setq lsp (* dfh lsp))) | ||
| 4766 | (+ dfh lsp))) | ||
| 4767 | |||
| 4768 | (defun window-screen-lines () | ||
| 4769 | "Return the number of screen lines in the text area of the selected window. | ||
| 4770 | |||
| 4771 | This is different from `window-text-height' in that this function counts | ||
| 4772 | lines in units of the height of the font used by the default face displayed | ||
| 4773 | in the window, not in units of the frame's default font, and also accounts | ||
| 4774 | for `line-spacing', if any, defined for the window's buffer or frame. | ||
| 4775 | |||
| 4776 | The value is a floating-point number." | ||
| 4777 | (let ((canonical (window-text-height)) | ||
| 4778 | (fch (frame-char-height)) | ||
| 4779 | (dlh (default-line-height))) | ||
| 4780 | (/ (* (float canonical) fch) dlh))) | ||
| 4781 | |||
| 4728 | ;; Returns non-nil if partial move was done. | 4782 | ;; Returns non-nil if partial move was done. |
| 4729 | (defun line-move-partial (arg noerror to-end) | 4783 | (defun line-move-partial (arg noerror to-end) |
| 4730 | (if (< arg 0) | 4784 | (if (< arg 0) |
| 4731 | ;; Move backward (up). | 4785 | ;; Move backward (up). |
| 4732 | ;; If already vscrolled, reduce vscroll | 4786 | ;; If already vscrolled, reduce vscroll |
| 4733 | (let ((vs (window-vscroll nil t))) | 4787 | (let ((vs (window-vscroll nil t)) |
| 4734 | (when (> vs (frame-char-height)) | 4788 | (dlh (default-line-height))) |
| 4735 | (set-window-vscroll nil (- vs (frame-char-height)) t))) | 4789 | (when (> vs dlh) |
| 4790 | (set-window-vscroll nil (- vs dlh) t))) | ||
| 4736 | 4791 | ||
| 4737 | ;; Move forward (down). | 4792 | ;; Move forward (down). |
| 4738 | (let* ((lh (window-line-height -1)) | 4793 | (let* ((lh (window-line-height -1)) |
| 4794 | (rowh (car lh)) | ||
| 4739 | (vpos (nth 1 lh)) | 4795 | (vpos (nth 1 lh)) |
| 4740 | (ypos (nth 2 lh)) | 4796 | (ypos (nth 2 lh)) |
| 4741 | (rbot (nth 3 lh)) | 4797 | (rbot (nth 3 lh)) |
| 4742 | (this-lh (window-line-height)) | 4798 | (this-lh (window-line-height)) |
| 4743 | (this-height (nth 0 this-lh)) | 4799 | (this-height (car this-lh)) |
| 4744 | (this-ypos (nth 2 this-lh)) | 4800 | (this-ypos (nth 2 this-lh)) |
| 4745 | (fch (frame-char-height)) | 4801 | (dlh (default-line-height)) |
| 4746 | py vs) | 4802 | (wslines (window-screen-lines)) |
| 4803 | py vs last-line) | ||
| 4804 | (if (> (mod wslines 1.0) 0.0) | ||
| 4805 | (setq wslines (round (+ wslines 0.5)))) | ||
| 4747 | (when (or (null lh) | 4806 | (when (or (null lh) |
| 4748 | (>= rbot fch) | 4807 | (>= rbot dlh) |
| 4749 | (<= ypos (- fch)) | 4808 | (<= ypos (- dlh)) |
| 4750 | (null this-lh) | 4809 | (null this-lh) |
| 4751 | (<= this-ypos (- fch))) | 4810 | (<= this-ypos (- dlh))) |
| 4752 | (unless lh | 4811 | (unless lh |
| 4753 | (let ((wend (pos-visible-in-window-p t nil t))) | 4812 | (let ((wend (pos-visible-in-window-p t nil t))) |
| 4754 | (setq rbot (nth 3 wend) | 4813 | (setq rbot (nth 3 wend) |
| 4814 | rowh (nth 4 wend) | ||
| 4755 | vpos (nth 5 wend)))) | 4815 | vpos (nth 5 wend)))) |
| 4756 | (unless this-lh | 4816 | (unless this-lh |
| 4757 | (let ((wstart (pos-visible-in-window-p nil nil t))) | 4817 | (let ((wstart (pos-visible-in-window-p nil nil t))) |
| @@ -4759,38 +4819,63 @@ lines." | |||
| 4759 | this-height (nth 4 wstart)))) | 4819 | this-height (nth 4 wstart)))) |
| 4760 | (setq py | 4820 | (setq py |
| 4761 | (or (nth 1 this-lh) | 4821 | (or (nth 1 this-lh) |
| 4762 | (let ((ppos (posn-at-point))) | 4822 | (let ((ppos (posn-at-point)) |
| 4763 | (cdr (or (posn-actual-col-row ppos) | 4823 | col-row) |
| 4764 | (posn-col-row ppos)))))) | 4824 | (setq col-row (posn-actual-col-row ppos)) |
| 4825 | (if col-row | ||
| 4826 | (- (cdr col-row) (window-vscroll)) | ||
| 4827 | (cdr (posn-col-row ppos)))))) | ||
| 4828 | ;; VPOS > 0 means the last line is only partially visible. | ||
| 4829 | ;; But if the part that is visible is at least as tall as the | ||
| 4830 | ;; default font, that means the line is actually fully | ||
| 4831 | ;; readable, and something like line-spacing is hidden. So in | ||
| 4832 | ;; that case we accept the last line in the window as still | ||
| 4833 | ;; visible, and consider the margin as starting one line | ||
| 4834 | ;; later. | ||
| 4835 | (if (and vpos (> vpos 0)) | ||
| 4836 | (if (and rowh | ||
| 4837 | (>= rowh (default-font-height)) | ||
| 4838 | (< rowh dlh)) | ||
| 4839 | (setq last-line (min (- wslines scroll-margin) vpos)) | ||
| 4840 | (setq last-line (min (- wslines scroll-margin 1) (1- vpos))))) | ||
| 4765 | (cond | 4841 | (cond |
| 4766 | ;; If last line of window is fully visible, and vscrolling | 4842 | ;; If last line of window is fully visible, and vscrolling |
| 4767 | ;; more would make this line invisible, move forward. | 4843 | ;; more would make this line invisible, move forward. |
| 4768 | ((and (or (< (setq vs (window-vscroll nil t)) fch) | 4844 | ((and (or (< (setq vs (window-vscroll nil t)) dlh) |
| 4769 | (null this-height) | 4845 | (null this-height) |
| 4770 | (<= this-height fch)) | 4846 | (<= this-height dlh)) |
| 4771 | (or (null rbot) (= rbot 0))) | 4847 | (or (null rbot) (= rbot 0))) |
| 4772 | nil) | 4848 | nil) |
| 4773 | ;; If cursor is not in the bottom scroll margin, and the | 4849 | ;; If cursor is not in the bottom scroll margin, and the |
| 4774 | ;; current line is is not too tall, move forward. | 4850 | ;; current line is is not too tall, move forward. |
| 4775 | ((and (or (null this-height) (<= this-height fch)) | 4851 | ((and (or (null this-height) (<= this-height dlh)) |
| 4776 | vpos | 4852 | vpos |
| 4777 | (> vpos 0) | 4853 | (> vpos 0) |
| 4778 | (< py | 4854 | (< py last-line)) |
| 4779 | (min (- (window-text-height) scroll-margin 1) (1- vpos)))) | ||
| 4780 | nil) | 4855 | nil) |
| 4781 | ;; When already vscrolled, we vscroll some more if we can, | 4856 | ;; When already vscrolled, we vscroll some more if we can, |
| 4782 | ;; or clear vscroll and move forward at end of tall image. | 4857 | ;; or clear vscroll and move forward at end of tall image. |
| 4783 | ((> vs 0) | 4858 | ((> vs 0) |
| 4784 | (when (or (and rbot (> rbot 0)) | 4859 | (when (or (and rbot (> rbot 0)) |
| 4785 | (and this-height (> this-height fch))) | 4860 | (and this-height (> this-height dlh))) |
| 4786 | (set-window-vscroll nil (+ vs fch) t))) | 4861 | (set-window-vscroll nil (+ vs dlh) t))) |
| 4787 | ;; If cursor just entered the bottom scroll margin, move forward, | 4862 | ;; If cursor just entered the bottom scroll margin, move forward, |
| 4788 | ;; but also vscroll one line so redisplay won't recenter. | 4863 | ;; but also optionally vscroll one line so redisplay won't recenter. |
| 4789 | ((and vpos | 4864 | ((and vpos |
| 4790 | (> vpos 0) | 4865 | (> vpos 0) |
| 4791 | (= py (min (- (window-text-height) scroll-margin 1) | 4866 | (= py last-line)) |
| 4792 | (1- vpos)))) | 4867 | ;; Don't vscroll if the partially-visible line at window |
| 4793 | (set-window-vscroll nil (frame-char-height) t) | 4868 | ;; bottom has the default height (a.k.a. "just one more text |
| 4869 | ;; line"): in that case, we do want redisplay to behave | ||
| 4870 | ;; normally, i.e. recenter or whatever. | ||
| 4871 | ;; | ||
| 4872 | ;; Note: ROWH + RBOT from the value returned by | ||
| 4873 | ;; pos-visible-in-window-p give the total height of the | ||
| 4874 | ;; partially-visible glyph row at the end of the window. As | ||
| 4875 | ;; we are dealing with floats, we disregard sub-pixel | ||
| 4876 | ;; discrepancies between that and DLH. | ||
| 4877 | (if (and rowh rbot (>= (- (+ rowh rbot) dlh) 1)) | ||
| 4878 | (set-window-vscroll nil dlh t)) | ||
| 4794 | (line-move-1 arg noerror to-end) | 4879 | (line-move-1 arg noerror to-end) |
| 4795 | t) | 4880 | t) |
| 4796 | ;; If there are lines above the last line, scroll-up one line. | 4881 | ;; If there are lines above the last line, scroll-up one line. |
| @@ -4799,7 +4884,7 @@ lines." | |||
| 4799 | t) | 4884 | t) |
| 4800 | ;; Finally, start vscroll. | 4885 | ;; Finally, start vscroll. |
| 4801 | (t | 4886 | (t |
| 4802 | (set-window-vscroll nil (frame-char-height) t))))))) | 4887 | (set-window-vscroll nil dlh t))))))) |
| 4803 | 4888 | ||
| 4804 | 4889 | ||
| 4805 | ;; This is like line-move-1 except that it also performs | 4890 | ;; This is like line-move-1 except that it also performs |
| @@ -4832,11 +4917,14 @@ lines." | |||
| 4832 | (prog1 (line-move-visual arg noerror) | 4917 | (prog1 (line-move-visual arg noerror) |
| 4833 | ;; If we moved into a tall line, set vscroll to make | 4918 | ;; If we moved into a tall line, set vscroll to make |
| 4834 | ;; scrolling through tall images more smooth. | 4919 | ;; scrolling through tall images more smooth. |
| 4835 | (let ((lh (line-pixel-height))) | 4920 | (let ((lh (line-pixel-height)) |
| 4921 | (dlh (default-line-height))) | ||
| 4836 | (if (and (< arg 0) | 4922 | (if (and (< arg 0) |
| 4837 | (< (point) (window-start)) | 4923 | (< (point) (window-start)) |
| 4838 | (> lh (frame-char-height))) | 4924 | (> lh dlh)) |
| 4839 | (set-window-vscroll nil (- lh (frame-char-height)) t)))) | 4925 | (set-window-vscroll |
| 4926 | nil | ||
| 4927 | (- lh dlh) t)))) | ||
| 4840 | (line-move-1 arg noerror to-end))))) | 4928 | (line-move-1 arg noerror to-end))))) |
| 4841 | 4929 | ||
| 4842 | ;; Display-based alternative to line-move-1. | 4930 | ;; Display-based alternative to line-move-1. |
| @@ -7346,6 +7434,66 @@ warning using STRING as the message.") | |||
| 7346 | (with-eval-after-load pkg | 7434 | (with-eval-after-load pkg |
| 7347 | (bad-package-check pkg)))) | 7435 | (bad-package-check pkg)))) |
| 7348 | 7436 | ||
| 7437 | |||
| 7438 | ;;; Generic dispatcher commands | ||
| 7439 | |||
| 7440 | ;; Macro `alternatives-define' is used to create generic commands. | ||
| 7441 | ;; Generic commands are these (like web, mail, news, encrypt, irc, etc.) | ||
| 7442 | ;; that can have different alternative implementations where choosing | ||
| 7443 | ;; among them is exclusively a matter of user preference. | ||
| 7444 | |||
| 7445 | ;; (alternatives-define COMMAND) creates a new interactive command | ||
| 7446 | ;; M-x COMMAND and a customizable variable COMMAND-alternatives. | ||
| 7447 | ;; Typically, the user will not need to customize this variable; packages | ||
| 7448 | ;; wanting to add alternative implementations should use | ||
| 7449 | ;; | ||
| 7450 | ;; ;;;###autoload (push '("My impl name" . my-impl-symbol) COMMAND-alternatives | ||
| 7451 | |||
| 7452 | (defmacro alternatives-define (command &rest customizations) | ||
| 7453 | "Define new command `COMMAND'. | ||
| 7454 | The variable `COMMAND-alternatives' will contain alternative | ||
| 7455 | implementations of COMMAND, so that running `C-u M-x COMMAND' | ||
| 7456 | will allow the user to chose among them. | ||
| 7457 | CUSTOMIZATIONS, if non-nil, should be composed of alternating | ||
| 7458 | `defcustom' keywords and values to add to the declaration of | ||
| 7459 | `COMMAND-alternatives' (typically :group and :version)." | ||
| 7460 | (let* ((command-name (symbol-name command)) | ||
| 7461 | (varalt-name (concat command-name "-alternatives")) | ||
| 7462 | (varalt-sym (intern varalt-name)) | ||
| 7463 | (varimp-sym (intern (concat command-name "--implementation")))) | ||
| 7464 | `(progn | ||
| 7465 | |||
| 7466 | (defcustom ,varalt-sym nil | ||
| 7467 | ,(format "Alist of alternative implementations for the `%s' command. | ||
| 7468 | |||
| 7469 | Each entry must be a pair (ALTNAME . ALTFUN), where: | ||
| 7470 | ALTNAME - The name shown at user to describe the alternative implementation. | ||
| 7471 | ALTFUN - The function called to implement this alternative." | ||
| 7472 | command-name) | ||
| 7473 | :type '(alist :key-type string :value-type function) | ||
| 7474 | ,@customizations) | ||
| 7475 | |||
| 7476 | (defvar ,varimp-sym nil "Internal use only.") | ||
| 7477 | |||
| 7478 | (defun ,command (&optional arg) | ||
| 7479 | ,(format "Run generic command `%s'. | ||
| 7480 | If used for the first time, or with interactive ARG, ask the user which | ||
| 7481 | implementation to use for `%s'. The variable `%s' | ||
| 7482 | contains the list of implementations currently supported for this command." | ||
| 7483 | command-name command-name varalt-name) | ||
| 7484 | (interactive "P") | ||
| 7485 | (when (or arg (null ,varimp-sym)) | ||
| 7486 | (let ((val (completing-read | ||
| 7487 | ,(format "Select implementation for command `%s': " command-name) | ||
| 7488 | ,varalt-sym nil t))) | ||
| 7489 | (unless (string-equal val "") | ||
| 7490 | (customize-save-variable ',varimp-sym | ||
| 7491 | (cdr (assoc-string val ,varalt-sym)))))) | ||
| 7492 | (if ,varimp-sym | ||
| 7493 | (funcall ,varimp-sym) | ||
| 7494 | (message ,(format "No implementation selected for command `%s'" | ||
| 7495 | command-name))))))) | ||
| 7496 | |||
| 7349 | (provide 'simple) | 7497 | (provide 'simple) |
| 7350 | 7498 | ||
| 7351 | ;;; simple.el ends here | 7499 | ;;; simple.el ends here |
diff --git a/lisp/subr.el b/lisp/subr.el index b8a62023805..b6ee96f879e 100644 --- a/lisp/subr.el +++ b/lisp/subr.el | |||
| @@ -1980,7 +1980,7 @@ any other terminator is used itself as input. | |||
| 1980 | The optional argument PROMPT specifies a string to use to prompt the user. | 1980 | The optional argument PROMPT specifies a string to use to prompt the user. |
| 1981 | The variable `read-quoted-char-radix' controls which radix to use | 1981 | The variable `read-quoted-char-radix' controls which radix to use |
| 1982 | for numeric input." | 1982 | for numeric input." |
| 1983 | (let ((message-log-max nil) done (first t) (code 0) char translated) | 1983 | (let ((message-log-max nil) done (first t) (code 0) translated) |
| 1984 | (while (not done) | 1984 | (while (not done) |
| 1985 | (let ((inhibit-quit first) | 1985 | (let ((inhibit-quit first) |
| 1986 | ;; Don't let C-h get the help message--only help function keys. | 1986 | ;; Don't let C-h get the help message--only help function keys. |
| @@ -1990,20 +1990,14 @@ for numeric input." | |||
| 1990 | or the octal character code. | 1990 | or the octal character code. |
| 1991 | RET terminates the character code and is discarded; | 1991 | RET terminates the character code and is discarded; |
| 1992 | any other non-digit terminates the character code and is then used as input.")) | 1992 | any other non-digit terminates the character code and is then used as input.")) |
| 1993 | (setq char (read-event (and prompt (format "%s-" prompt)) t)) | 1993 | (setq translated (read-key (and prompt (format "%s-" prompt)))) |
| 1994 | (if inhibit-quit (setq quit-flag nil))) | 1994 | (if inhibit-quit (setq quit-flag nil))) |
| 1995 | ;; Translate TAB key into control-I ASCII character, and so on. | ||
| 1996 | ;; Note: `read-char' does it using the `ascii-character' property. | ||
| 1997 | ;; We should try and use read-key instead. | ||
| 1998 | (let ((translation (lookup-key local-function-key-map (vector char)))) | ||
| 1999 | (setq translated (if (arrayp translation) | ||
| 2000 | (aref translation 0) | ||
| 2001 | char))) | ||
| 2002 | (if (integerp translated) | 1995 | (if (integerp translated) |
| 2003 | (setq translated (char-resolve-modifiers translated))) | 1996 | (setq translated (char-resolve-modifiers translated))) |
| 2004 | (cond ((null translated)) | 1997 | (cond ((null translated)) |
| 2005 | ((not (integerp translated)) | 1998 | ((not (integerp translated)) |
| 2006 | (setq unread-command-events (list char) | 1999 | (setq unread-command-events |
| 2000 | (listify-key-sequence (this-single-command-raw-keys)) | ||
| 2007 | done t)) | 2001 | done t)) |
| 2008 | ((/= (logand translated ?\M-\^@) 0) | 2002 | ((/= (logand translated ?\M-\^@) 0) |
| 2009 | ;; Turn a meta-character into a character with the 0200 bit set. | 2003 | ;; Turn a meta-character into a character with the 0200 bit set. |
| @@ -2022,7 +2016,8 @@ any other non-digit terminates the character code and is then used as input.")) | |||
| 2022 | ((and (not first) (eq translated ?\C-m)) | 2016 | ((and (not first) (eq translated ?\C-m)) |
| 2023 | (setq done t)) | 2017 | (setq done t)) |
| 2024 | ((not first) | 2018 | ((not first) |
| 2025 | (setq unread-command-events (list char) | 2019 | (setq unread-command-events |
| 2020 | (listify-key-sequence (this-single-command-raw-keys)) | ||
| 2026 | done t)) | 2021 | done t)) |
| 2027 | (t (setq code translated | 2022 | (t (setq code translated |
| 2028 | done t))) | 2023 | done t))) |
| @@ -2186,6 +2181,7 @@ An obsolete, but still supported form is | |||
| 2186 | where the optional arg MILLISECONDS specifies an additional wait period, | 2181 | where the optional arg MILLISECONDS specifies an additional wait period, |
| 2187 | in milliseconds; this was useful when Emacs was built without | 2182 | in milliseconds; this was useful when Emacs was built without |
| 2188 | floating point support." | 2183 | floating point support." |
| 2184 | (declare (advertised-calling-convention (seconds &optional nodisp) "22.1")) | ||
| 2189 | (if (numberp nodisp) | 2185 | (if (numberp nodisp) |
| 2190 | (setq seconds (+ seconds (* 1e-3 nodisp)) | 2186 | (setq seconds (+ seconds (* 1e-3 nodisp)) |
| 2191 | nodisp obsolete) | 2187 | nodisp obsolete) |
| @@ -2200,7 +2196,10 @@ floating point support." | |||
| 2200 | (or nodisp (redisplay))) | 2196 | (or nodisp (redisplay))) |
| 2201 | (t | 2197 | (t |
| 2202 | (or nodisp (redisplay)) | 2198 | (or nodisp (redisplay)) |
| 2203 | (let ((read (read-event nil nil seconds))) | 2199 | ;; FIXME: we should not read-event here at all, because it's much too |
| 2200 | ;; difficult to reliably "undo" a read-event by pushing it onto | ||
| 2201 | ;; unread-command-events. | ||
| 2202 | (let ((read (read-event nil t seconds))) | ||
| 2204 | (or (null read) | 2203 | (or (null read) |
| 2205 | (progn | 2204 | (progn |
| 2206 | ;; If last command was a prefix arg, e.g. C-u, push this event onto | 2205 | ;; If last command was a prefix arg, e.g. C-u, push this event onto |
| @@ -2210,7 +2209,6 @@ floating point support." | |||
| 2210 | (setq read (cons t read))) | 2209 | (setq read (cons t read))) |
| 2211 | (push read unread-command-events) | 2210 | (push read unread-command-events) |
| 2212 | nil)))))) | 2211 | nil)))))) |
| 2213 | (set-advertised-calling-convention 'sit-for '(seconds &optional nodisp) "22.1") | ||
| 2214 | 2212 | ||
| 2215 | (defun y-or-n-p (prompt) | 2213 | (defun y-or-n-p (prompt) |
| 2216 | "Ask user a \"y or n\" question. Return t if answer is \"y\". | 2214 | "Ask user a \"y or n\" question. Return t if answer is \"y\". |
| @@ -2240,7 +2238,8 @@ is nil and `use-dialog-box' is non-nil." | |||
| 2240 | (cond | 2238 | (cond |
| 2241 | (noninteractive | 2239 | (noninteractive |
| 2242 | (setq prompt (concat prompt | 2240 | (setq prompt (concat prompt |
| 2243 | (if (eq ?\s (aref prompt (1- (length prompt)))) | 2241 | (if (or (zerop (length prompt)) |
| 2242 | (eq ?\s (aref prompt (1- (length prompt))))) | ||
| 2244 | "" " ") | 2243 | "" " ") |
| 2245 | "(y or n) ")) | 2244 | "(y or n) ")) |
| 2246 | (let ((temp-prompt prompt)) | 2245 | (let ((temp-prompt prompt)) |
| @@ -2257,7 +2256,8 @@ is nil and `use-dialog-box' is non-nil." | |||
| 2257 | (x-popup-dialog t `(,prompt ("Yes" . act) ("No" . skip))))) | 2256 | (x-popup-dialog t `(,prompt ("Yes" . act) ("No" . skip))))) |
| 2258 | (t | 2257 | (t |
| 2259 | (setq prompt (concat prompt | 2258 | (setq prompt (concat prompt |
| 2260 | (if (eq ?\s (aref prompt (1- (length prompt)))) | 2259 | (if (or (zerop (length prompt)) |
| 2260 | (eq ?\s (aref prompt (1- (length prompt))))) | ||
| 2261 | "" " ") | 2261 | "" " ") |
| 2262 | "(y or n) ")) | 2262 | "(y or n) ")) |
| 2263 | (while | 2263 | (while |
| @@ -2449,11 +2449,12 @@ If MESSAGE is nil, instructions to type EXIT-CHAR are displayed there." | |||
| 2449 | (recenter (/ (window-height) 2)))) | 2449 | (recenter (/ (window-height) 2)))) |
| 2450 | (message (or message "Type %s to continue editing.") | 2450 | (message (or message "Type %s to continue editing.") |
| 2451 | (single-key-description exit-char)) | 2451 | (single-key-description exit-char)) |
| 2452 | (let ((event (read-event))) | 2452 | (let ((event (read-key))) |
| 2453 | ;; `exit-char' can be an event, or an event description list. | 2453 | ;; `exit-char' can be an event, or an event description list. |
| 2454 | (or (eq event exit-char) | 2454 | (or (eq event exit-char) |
| 2455 | (eq event (event-convert-list exit-char)) | 2455 | (eq event (event-convert-list exit-char)) |
| 2456 | (setq unread-command-events (list event))))) | 2456 | (setq unread-command-events |
| 2457 | (append (this-single-command-raw-keys)))))) | ||
| 2457 | (delete-overlay ol)))) | 2458 | (delete-overlay ol)))) |
| 2458 | 2459 | ||
| 2459 | 2460 | ||
| @@ -3852,6 +3853,7 @@ FILE should be the name of a library, with no directory name." | |||
| 3852 | (declare (obsolete eval-after-load "23.2")) | 3853 | (declare (obsolete eval-after-load "23.2")) |
| 3853 | (eval-after-load file (read))) | 3854 | (eval-after-load file (read))) |
| 3854 | 3855 | ||
| 3856 | |||
| 3855 | (defun display-delayed-warnings () | 3857 | (defun display-delayed-warnings () |
| 3856 | "Display delayed warnings from `delayed-warnings-list'. | 3858 | "Display delayed warnings from `delayed-warnings-list'. |
| 3857 | Used from `delayed-warnings-hook' (which see)." | 3859 | Used from `delayed-warnings-hook' (which see)." |
| @@ -3885,6 +3887,12 @@ By default, this hook contains functions to consolidate the | |||
| 3885 | warnings listed in `delayed-warnings-list', display them, and set | 3887 | warnings listed in `delayed-warnings-list', display them, and set |
| 3886 | `delayed-warnings-list' back to nil.") | 3888 | `delayed-warnings-list' back to nil.") |
| 3887 | 3889 | ||
| 3890 | (defun delay-warning (type message &optional level buffer-name) | ||
| 3891 | "Display a delayed warning. | ||
| 3892 | Aside from going through `delayed-warnings-list', this is equivalent | ||
| 3893 | to `display-warning'." | ||
| 3894 | (push (list type message level buffer-name) delayed-warnings-list)) | ||
| 3895 | |||
| 3888 | 3896 | ||
| 3889 | ;;;; invisibility specs | 3897 | ;;;; invisibility specs |
| 3890 | 3898 | ||
| @@ -4494,20 +4502,6 @@ convenience wrapper around `make-progress-reporter' and friends. | |||
| 4494 | nil ,@(cdr (cdr spec))))) | 4502 | nil ,@(cdr (cdr spec))))) |
| 4495 | 4503 | ||
| 4496 | 4504 | ||
| 4497 | ;;;; Support for watching filesystem events. | ||
| 4498 | |||
| 4499 | (defun file-notify-handle-event (event) | ||
| 4500 | "Handle file system monitoring event. | ||
| 4501 | If EVENT is a filewatch event, call its callback. | ||
| 4502 | Otherwise, signal a `filewatch-error'." | ||
| 4503 | (interactive "e") | ||
| 4504 | (if (and (eq (car event) 'file-notify) | ||
| 4505 | (>= (length event) 3)) | ||
| 4506 | (funcall (nth 2 event) (nth 1 event)) | ||
| 4507 | (signal 'filewatch-error | ||
| 4508 | (cons "Not a valid file-notify event" event)))) | ||
| 4509 | |||
| 4510 | |||
| 4511 | ;;;; Comparing version strings. | 4505 | ;;;; Comparing version strings. |
| 4512 | 4506 | ||
| 4513 | (defconst version-separator "." | 4507 | (defconst version-separator "." |
diff --git a/lisp/thumbs.el b/lisp/thumbs.el index 3d591303414..8032de85b01 100644 --- a/lisp/thumbs.el +++ b/lisp/thumbs.el | |||
| @@ -57,6 +57,7 @@ | |||
| 57 | ;;; Code: | 57 | ;;; Code: |
| 58 | 58 | ||
| 59 | (require 'dired) | 59 | (require 'dired) |
| 60 | (require 'cl-lib) ; for cl-gensym | ||
| 60 | 61 | ||
| 61 | ;; CUSTOMIZATIONS | 62 | ;; CUSTOMIZATIONS |
| 62 | 63 | ||
| @@ -179,21 +180,6 @@ this value can let another user see some of your images." | |||
| 179 | (make-variable-buffer-local 'thumbs-marked-list) | 180 | (make-variable-buffer-local 'thumbs-marked-list) |
| 180 | (put 'thumbs-marked-list 'permanent-local t) | 181 | (put 'thumbs-marked-list 'permanent-local t) |
| 181 | 182 | ||
| 182 | (defalias 'thumbs-gensym | ||
| 183 | (if (fboundp 'gensym) | ||
| 184 | 'gensym | ||
| 185 | ;; Copied from cl-macs.el | ||
| 186 | (defvar thumbs-gensym-counter 0) | ||
| 187 | (lambda (&optional prefix) | ||
| 188 | "Generate a new uninterned symbol. | ||
| 189 | The name is made by appending a number to PREFIX, default \"G\"." | ||
| 190 | (let ((pfix (if (stringp prefix) prefix "G")) | ||
| 191 | (num (if (integerp prefix) prefix | ||
| 192 | (prog1 thumbs-gensym-counter | ||
| 193 | (setq thumbs-gensym-counter | ||
| 194 | (1+ thumbs-gensym-counter)))))) | ||
| 195 | (make-symbol (format "%s%d" pfix num)))))) | ||
| 196 | |||
| 197 | (defsubst thumbs-temp-dir () | 183 | (defsubst thumbs-temp-dir () |
| 198 | (file-name-as-directory (expand-file-name thumbs-temp-dir))) | 184 | (file-name-as-directory (expand-file-name thumbs-temp-dir))) |
| 199 | 185 | ||
| @@ -202,7 +188,7 @@ The name is made by appending a number to PREFIX, default \"G\"." | |||
| 202 | (format "%s%s-%s.jpg" | 188 | (format "%s%s-%s.jpg" |
| 203 | (thumbs-temp-dir) | 189 | (thumbs-temp-dir) |
| 204 | thumbs-temp-prefix | 190 | thumbs-temp-prefix |
| 205 | (thumbs-gensym "T"))) | 191 | (cl-gensym "T"))) |
| 206 | 192 | ||
| 207 | (defun thumbs-thumbsdir () | 193 | (defun thumbs-thumbsdir () |
| 208 | "Return the current thumbnails directory (from `thumbs-thumbsdir'). | 194 | "Return the current thumbnails directory (from `thumbs-thumbsdir'). |
diff --git a/lisp/vc/ediff.el b/lisp/vc/ediff.el index 7a8f399a6ce..e9a6a97409c 100644 --- a/lisp/vc/ediff.el +++ b/lisp/vc/ediff.el | |||
| @@ -12,8 +12,8 @@ | |||
| 12 | ;; filed in the Emacs bug reporting system against this file, a copy | 12 | ;; filed in the Emacs bug reporting system against this file, a copy |
| 13 | ;; of the bug report be sent to the maintainer's email address. | 13 | ;; of the bug report be sent to the maintainer's email address. |
| 14 | 14 | ||
| 15 | (defconst ediff-version "2.81.4" "The current version of Ediff") | 15 | (defconst ediff-version "2.81.5" "The current version of Ediff") |
| 16 | (defconst ediff-date "December 7, 2009" "Date of last update") | 16 | (defconst ediff-date "July 4, 2013" "Date of last update") |
| 17 | 17 | ||
| 18 | 18 | ||
| 19 | ;; This file is part of GNU Emacs. | 19 | ;; This file is part of GNU Emacs. |
| @@ -1560,6 +1560,75 @@ With optional NODE, goes to that node." | |||
| 1560 | (add-to-list 'debug-ignored-errors mess)) | 1560 | (add-to-list 'debug-ignored-errors mess)) |
| 1561 | 1561 | ||
| 1562 | 1562 | ||
| 1563 | |||
| 1564 | ;;; Command line interface | ||
| 1565 | |||
| 1566 | ;;;###autoload | ||
| 1567 | (defun ediff-files-command () | ||
| 1568 | (let ((file-a (nth 0 command-line-args-left)) | ||
| 1569 | (file-b (nth 1 command-line-args-left))) | ||
| 1570 | (setq command-line-args-left (nthcdr 2 command-line-args-left)) | ||
| 1571 | (ediff file-a file-b))) | ||
| 1572 | |||
| 1573 | ;;;###autoload | ||
| 1574 | (defun ediff3-files-command () | ||
| 1575 | (let ((file-a (nth 0 command-line-args-left)) | ||
| 1576 | (file-b (nth 1 command-line-args-left)) | ||
| 1577 | (file-c (nth 2 command-line-args-left))) | ||
| 1578 | (setq command-line-args-left (nthcdr 3 command-line-args-left)) | ||
| 1579 | (ediff3 file-a file-b file-c))) | ||
| 1580 | |||
| 1581 | ;;;###autoload | ||
| 1582 | (defun ediff-merge-command () | ||
| 1583 | (let ((file-a (nth 0 command-line-args-left)) | ||
| 1584 | (file-b (nth 1 command-line-args-left))) | ||
| 1585 | (setq command-line-args-left (nthcdr 2 command-line-args-left)) | ||
| 1586 | (ediff-merge-files file-a file-b))) | ||
| 1587 | |||
| 1588 | ;;;###autoload | ||
| 1589 | (defun ediff-merge-with-ancestor-command () | ||
| 1590 | (let ((file-a (nth 0 command-line-args-left)) | ||
| 1591 | (file-b (nth 1 command-line-args-left)) | ||
| 1592 | (ancestor (nth 2 command-line-args-left))) | ||
| 1593 | (setq command-line-args-left (nthcdr 3 command-line-args-left)) | ||
| 1594 | (ediff-merge-files-with-ancestor file-a file-b ancestor))) | ||
| 1595 | |||
| 1596 | ;;;###autoload | ||
| 1597 | (defun ediff-directories-command () | ||
| 1598 | (let ((file-a (nth 0 command-line-args-left)) | ||
| 1599 | (file-b (nth 1 command-line-args-left)) | ||
| 1600 | (regexp (nth 2 command-line-args-left))) | ||
| 1601 | (setq command-line-args-left (nthcdr 3 command-line-args-left)) | ||
| 1602 | (ediff-directories file-a file-b regexp))) | ||
| 1603 | |||
| 1604 | ;;;###autoload | ||
| 1605 | (defun ediff-directories3-command () | ||
| 1606 | (let ((file-a (nth 0 command-line-args-left)) | ||
| 1607 | (file-b (nth 1 command-line-args-left)) | ||
| 1608 | (file-c (nth 2 command-line-args-left)) | ||
| 1609 | (regexp (nth 3 command-line-args-left))) | ||
| 1610 | (setq command-line-args-left (nthcdr 4 command-line-args-left)) | ||
| 1611 | (ediff-directories3 file-a file-b file-c regexp))) | ||
| 1612 | |||
| 1613 | ;;;###autoload | ||
| 1614 | (defun ediff-merge-directories-command () | ||
| 1615 | (let ((file-a (nth 0 command-line-args-left)) | ||
| 1616 | (file-b (nth 1 command-line-args-left)) | ||
| 1617 | (regexp (nth 2 command-line-args-left))) | ||
| 1618 | (setq command-line-args-left (nthcdr 3 command-line-args-left)) | ||
| 1619 | (ediff-merge-directories file-a file-b regexp))) | ||
| 1620 | |||
| 1621 | ;;;###autoload | ||
| 1622 | (defun ediff-merge-directories-with-ancestor-command () | ||
| 1623 | (let ((file-a (nth 0 command-line-args-left)) | ||
| 1624 | (file-b (nth 1 command-line-args-left)) | ||
| 1625 | (ancestor (nth 2 command-line-args-left)) | ||
| 1626 | (regexp (nth 3 command-line-args-left))) | ||
| 1627 | (setq command-line-args-left (nthcdr 4 command-line-args-left)) | ||
| 1628 | (ediff-merge-directories-with-ancestor file-a file-b ancestor regexp))) | ||
| 1629 | |||
| 1630 | |||
| 1631 | |||
| 1563 | (require 'ediff-util) | 1632 | (require 'ediff-util) |
| 1564 | 1633 | ||
| 1565 | (run-hooks 'ediff-load-hook) | 1634 | (run-hooks 'ediff-load-hook) |
diff --git a/lisp/wid-edit.el b/lisp/wid-edit.el index 2dc1e502171..b351d896911 100644 --- a/lisp/wid-edit.el +++ b/lisp/wid-edit.el | |||
| @@ -55,6 +55,7 @@ | |||
| 55 | ;; See `widget.el'. | 55 | ;; See `widget.el'. |
| 56 | 56 | ||
| 57 | ;;; Code: | 57 | ;;; Code: |
| 58 | (require 'cl-lib) | ||
| 58 | 59 | ||
| 59 | ;;; Compatibility. | 60 | ;;; Compatibility. |
| 60 | 61 | ||
| @@ -221,7 +222,7 @@ minibuffer." | |||
| 221 | ((or widget-menu-minibuffer-flag | 222 | ((or widget-menu-minibuffer-flag |
| 222 | (> (length items) widget-menu-max-shortcuts)) | 223 | (> (length items) widget-menu-max-shortcuts)) |
| 223 | ;; Read the choice of name from the minibuffer. | 224 | ;; Read the choice of name from the minibuffer. |
| 224 | (setq items (widget-remove-if 'stringp items)) | 225 | (setq items (cl-remove-if 'stringp items)) |
| 225 | (let ((val (completing-read (concat title ": ") items nil t))) | 226 | (let ((val (completing-read (concat title ": ") items nil t))) |
| 226 | (if (stringp val) | 227 | (if (stringp val) |
| 227 | (let ((try (try-completion val items))) | 228 | (let ((try (try-completion val items))) |
| @@ -295,14 +296,6 @@ minibuffer." | |||
| 295 | (error "Canceled")) | 296 | (error "Canceled")) |
| 296 | value)))) | 297 | value)))) |
| 297 | 298 | ||
| 298 | (defun widget-remove-if (predicate list) | ||
| 299 | (let (result (tail list)) | ||
| 300 | (while tail | ||
| 301 | (or (funcall predicate (car tail)) | ||
| 302 | (setq result (cons (car tail) result))) | ||
| 303 | (setq tail (cdr tail))) | ||
| 304 | (nreverse result))) | ||
| 305 | |||
| 306 | ;;; Widget text specifications. | 299 | ;;; Widget text specifications. |
| 307 | ;; | 300 | ;; |
| 308 | ;; These functions are for specifying text properties. | 301 | ;; These functions are for specifying text properties. |
diff --git a/lisp/window.el b/lisp/window.el index fc50bbb0d49..a2acd2a81b0 100644 --- a/lisp/window.el +++ b/lisp/window.el | |||
| @@ -4347,6 +4347,9 @@ value can be also stored on disk and read back in a new session." | |||
| 4347 | (defvar window-state-put-list nil | 4347 | (defvar window-state-put-list nil |
| 4348 | "Helper variable for `window-state-put'.") | 4348 | "Helper variable for `window-state-put'.") |
| 4349 | 4349 | ||
| 4350 | (defvar window-state-put-stale-windows nil | ||
| 4351 | "Helper variable for `window-state-put'.") | ||
| 4352 | |||
| 4350 | (defun window--state-put-1 (state &optional window ignore totals) | 4353 | (defun window--state-put-1 (state &optional window ignore totals) |
| 4351 | "Helper function for `window-state-put'." | 4354 | "Helper function for `window-state-put'." |
| 4352 | (let ((type (car state))) | 4355 | (let ((type (car state))) |
| @@ -4429,9 +4432,14 @@ value can be also stored on disk and read back in a new session." | |||
| 4429 | (set-window-parameter window (car parameter) (cdr parameter)))) | 4432 | (set-window-parameter window (car parameter) (cdr parameter)))) |
| 4430 | ;; Process buffer related state. | 4433 | ;; Process buffer related state. |
| 4431 | (when state | 4434 | (when state |
| 4432 | ;; We don't want to raise an error here so we create a buffer if | 4435 | ;; We don't want to raise an error in case the buffer does not |
| 4433 | ;; there's none. | 4436 | ;; exist anymore, so we switch to a previous one and save the |
| 4434 | (set-window-buffer window (get-buffer-create (car state))) | 4437 | ;; window with the intention of deleting it later if possible. |
| 4438 | (let ((buffer (get-buffer (car state)))) | ||
| 4439 | (if buffer | ||
| 4440 | (set-window-buffer window buffer) | ||
| 4441 | (switch-to-prev-buffer window) | ||
| 4442 | (push window window-state-put-stale-windows))) | ||
| 4435 | (with-current-buffer (window-buffer window) | 4443 | (with-current-buffer (window-buffer window) |
| 4436 | (set-window-hscroll window (cdr (assq 'hscroll state))) | 4444 | (set-window-hscroll window (cdr (assq 'hscroll state))) |
| 4437 | (apply 'set-window-fringes | 4445 | (apply 'set-window-fringes |
| @@ -4491,6 +4499,7 @@ Optional argument IGNORE non-nil means ignore minimum window | |||
| 4491 | sizes and fixed size restrictions. IGNORE equal `safe' means | 4499 | sizes and fixed size restrictions. IGNORE equal `safe' means |
| 4492 | windows can get as small as `window-safe-min-height' and | 4500 | windows can get as small as `window-safe-min-height' and |
| 4493 | `window-safe-min-width'." | 4501 | `window-safe-min-width'." |
| 4502 | (setq window-state-put-stale-windows nil) | ||
| 4494 | (setq window (window-normalize-window window t)) | 4503 | (setq window (window-normalize-window window t)) |
| 4495 | (let* ((frame (window-frame window)) | 4504 | (let* ((frame (window-frame window)) |
| 4496 | (head (car state)) | 4505 | (head (car state)) |
| @@ -4539,6 +4548,10 @@ windows can get as small as `window-safe-min-height' and | |||
| 4539 | (set-window-buffer window (current-buffer)) | 4548 | (set-window-buffer window (current-buffer)) |
| 4540 | (window--state-put-1 state window nil totals) | 4549 | (window--state-put-1 state window nil totals) |
| 4541 | (window--state-put-2 ignore)) | 4550 | (window--state-put-2 ignore)) |
| 4551 | (while window-state-put-stale-windows | ||
| 4552 | (let ((window (pop window-state-put-stale-windows))) | ||
| 4553 | (when (eq (window-deletable-p window) t) | ||
| 4554 | (delete-window window)))) | ||
| 4542 | (window--check frame)))) | 4555 | (window--check frame)))) |
| 4543 | 4556 | ||
| 4544 | (defun display-buffer-record-window (type window buffer) | 4557 | (defun display-buffer-record-window (type window buffer) |