diff options
| author | Karoly Lorentey | 2004-03-01 14:27:16 +0000 |
|---|---|---|
| committer | Karoly Lorentey | 2004-03-01 14:27:16 +0000 |
| commit | 29cd19501134dfde15743f8c5fbdc8b012ed693e (patch) | |
| tree | eab1530a8589ab50de84bcd188b1f8d8dda518db /lisp | |
| parent | 057a9ab495a5fd334f9bd3c7704176502e5219c4 (diff) | |
| parent | 3f383e4ad7884aad8767d3a6c26c6f3bab5f8f93 (diff) | |
| download | emacs-29cd19501134dfde15743f8c5fbdc8b012ed693e.tar.gz emacs-29cd19501134dfde15743f8c5fbdc8b012ed693e.zip | |
Merged in changes from CVS HEAD
Patches applied:
* miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-121
Update from CVS
* miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-122
Update from CVS
* miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-123
Update from CVS
* miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-124
Update from CVS
* miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-125
Update from CVS
git-archimport-id: lorentey@elte.hu--2004/emacs--multi-tty--0--patch-108
Diffstat (limited to 'lisp')
| -rw-r--r-- | lisp/ChangeLog | 184 | ||||
| -rw-r--r-- | lisp/ffap.el | 61 | ||||
| -rw-r--r-- | lisp/net/tramp-ftp.el | 17 | ||||
| -rw-r--r-- | lisp/net/tramp-smb.el | 137 | ||||
| -rw-r--r-- | lisp/net/tramp.el | 766 | ||||
| -rw-r--r-- | lisp/net/trampver.el | 2 | ||||
| -rw-r--r-- | lisp/progmodes/ebnf-abn.el | 4 | ||||
| -rw-r--r-- | lisp/progmodes/ebnf-bnf.el | 38 | ||||
| -rw-r--r-- | lisp/progmodes/ebnf2ps.el | 58 | ||||
| -rw-r--r-- | lisp/thumbs.el | 737 |
10 files changed, 1618 insertions, 386 deletions
diff --git a/lisp/ChangeLog b/lisp/ChangeLog index 328cc3e8986..b945703cb57 100644 --- a/lisp/ChangeLog +++ b/lisp/ChangeLog | |||
| @@ -1,6 +1,131 @@ | |||
| 1 | 2004-02-29 Kai Grossjohann <kai.grossjohann@gmx.net> | ||
| 2 | |||
| 3 | Version 2.0.39 of Tramp released. | ||
| 4 | |||
| 5 | * net/tramp.el (tramp-handle-file-local-copy) | ||
| 6 | (tramp-handle-write-region, tramp-open-connection-rsh): Variable | ||
| 7 | name typo. Small change. From Patrick Tullmann | ||
| 8 | <tullmann@flux.utah.edu>. | ||
| 9 | (tramp-process-connection-type): New variable. | ||
| 10 | (tramp-maybe-open-connection): Use it. | ||
| 11 | (tramp-do-copy-or-rename-via-buffer): Handle KEEP-DATE arg, if | ||
| 12 | possible. | ||
| 13 | (tramp-touch): Set last-modified time of a remote file. | ||
| 14 | (tramp-handle-write-region): Say which function is used when | ||
| 15 | encoding. | ||
| 16 | |||
| 17 | 2004-02-29 Michael Albinus <Michael.Albinus@alcatel.de> | ||
| 18 | |||
| 19 | * net/tramp-smb.el (tramp-smb-handle-file-writable-p): Handle the | ||
| 20 | case of non-existing filename, too. Reported by Christoph Bauer | ||
| 21 | <c_bauer@informatik.uni-kl.de>. | ||
| 22 | (tramp-smb-get-file-entries): The directory in question should | ||
| 23 | have permissions "drwxrwxrwx". Just virtual, because we don't | ||
| 24 | know the real permissions. Don't we know? | ||
| 25 | (tramp-smb-prompt): Add virtual prompt from listing shares, too. | ||
| 26 | (tramp-smb-errors): Add "NT_STATUS_ACCOUNT_LOCKED_OUT". | ||
| 27 | (tramp-smb-wait-for-output): Optimize algorithm getting pending | ||
| 28 | output. If it was received chunkwise, there have been problems. | ||
| 29 | Remove the "prompt not found" error message; it is obvious. | ||
| 30 | Simplify algorithm. | ||
| 31 | (tramp-smb-process-running): Removed. Since we acknowledge the | ||
| 32 | virtual prompt for shares, there's no need for distinction of | ||
| 33 | reading shares (process ends afterwards) and interactive mode of | ||
| 34 | smblient. | ||
| 35 | (tramp-smb-open-connection): Setting process sentinel removed. | ||
| 36 | (tramp-smb-errors): Add "NT_STATUS_WRONG_PASSWORD" and | ||
| 37 | "NT_STATUS_NETWORK_ACCESS_DENIED". | ||
| 38 | (tramp-smb-maybe-open-connection): Set `process-connection-type' | ||
| 39 | to 'pty. Suggested by Piet van Oostrum <piet@cs.uu.nl>. | ||
| 40 | (top-level): Setting default value in `tramp-default-method-alist' | ||
| 41 | corrected. Order of USER and HOST have been wrong. Nobody | ||
| 42 | claimed for months ... | ||
| 43 | (tramp-smb-maybe-open-connection): Use | ||
| 44 | `tramp-process-connection-type'. | ||
| 45 | (tramp-smb-open-connection): Clear password cache if login has | ||
| 46 | failed. | ||
| 47 | |||
| 48 | * net/tramp.el (tramp-completion-mode) Don't check for 'xemacs but | ||
| 49 | `tramp-unified-filenames'. | ||
| 50 | (tramp-completion-mode): Make test for XEmacs explicitely. | ||
| 51 | `event-to-character' can exists in Emacs packages too. Reported | ||
| 52 | by Matt Swift <swift@alum.mit.edu>. | ||
| 53 | (tramp-buffer-name): Buffer name must contain the user if exists. | ||
| 54 | Reported by Adrian Phillips <a.phillips@met.no>. | ||
| 55 | (tramp-do-copy-or-rename-file): Handle out-of-band methods. Call | ||
| 56 | `tramp-do-copy-or-rename-file-out-of-band' this case. | ||
| 57 | (tramp-do-copy-or-rename-file-out-of-band): Renamed from | ||
| 58 | `tramp-do-copy-or-rename-file-one-local', because it handles also | ||
| 59 | the case both files use the same out-of-band method. | ||
| 60 | Implementation added. | ||
| 61 | (tramp-handle-file-local-copy, tramp-handle-write-region): | ||
| 62 | Out-of-band handling removed. `copy-file' called instead, which | ||
| 63 | calls `tramp-do-copy-or-rename-file-out-of-band'. | ||
| 64 | (tramp-action-password): Check for out-of-band method removed. | ||
| 65 | This function is used for 'login-program. | ||
| 66 | (tramp-post-connection): Use `tramp-method-out-of-band-p' when | ||
| 67 | appropriate. | ||
| 68 | (tramp-completion-function-alist-ssh): Add `tramp-parse-shostkeys' | ||
| 69 | and `tramp-parse-sknownhosts'. | ||
| 70 | (tramp-completion-function-alist): It's a defvar now, because we | ||
| 71 | want to apply the optimized `tramp-set-completion-function' | ||
| 72 | instead of a static list. | ||
| 73 | (tramp-set-completion-function): Implementation tuned. Avoid | ||
| 74 | double entries, and entries where the function or the | ||
| 75 | file/directory doesn't exist. | ||
| 76 | (tramp-parse-shostkeys, tramp-parse-sknownhosts): New functions | ||
| 77 | for SSH2. | ||
| 78 | (tramp-file-name-handler-alist): Add `dired-compress-file' entry. | ||
| 79 | (tramp-handle-dired-compress-file): New function. | ||
| 80 | (tramp-async-proc): New variable. | ||
| 81 | (tramp-handle-shell-command): Adding asynchronous processes. They | ||
| 82 | are far from being perfect, but it works at least for | ||
| 83 | `find-grep-dired' and `find-name-dired' in Emacs 21.4. | ||
| 84 | (top-level): Require password.el if visible. Should be mandatory | ||
| 85 | once No Gnus has found its way into (X)Emacs. | ||
| 86 | (tramp-read-passwd): Invoke `password-read' if available, | ||
| 87 | `read-passwd' otherwise. `ange-ftp-read-passwd' isn't used as | ||
| 88 | fallback any longer. | ||
| 89 | (tramp-clear-passwd): New function. | ||
| 90 | (tramp-process-actions, tramp-process-multi-actions): Clear | ||
| 91 | password cache if login has failed. | ||
| 92 | |||
| 93 | * net/tramp-ftp.el (Commentary): Remove pointer to EFS. It has | ||
| 94 | its own module. | ||
| 95 | (tramp-ftp-file-name-handler): Unset `ange-ftp-ftp-name-arg' and | ||
| 96 | `ange-ftp-ftp-name-res'. There could be incorrect values from | ||
| 97 | previous calls in case the "ftp" method is used in the Tramp file | ||
| 98 | name. Reported by Katsumi Yamaoka <yamaoka@jpl.org>. | ||
| 99 | |||
| 100 | 2004-02-28 Richard M. Stallman <rms@gnu.org> | ||
| 101 | |||
| 102 | * term.el (term-mouse-paste): Call mouse-set-point. | ||
| 103 | |||
| 104 | * thumbs.el: New file. | ||
| 105 | |||
| 106 | 2004-02-28 Vinicius Jose Latorre <viniciusjl@ig.com.br> | ||
| 107 | |||
| 108 | * ebnf-abn.el: Doc fix. | ||
| 109 | |||
| 110 | * ebnf-bnf.el: Doc fix. | ||
| 111 | (ebnf-repeat): Code fix. | ||
| 112 | |||
| 113 | * ebnf2ps.el: Doc fix. | ||
| 114 | (ebnf-syntax-directory, ebnf-syntax-file): New funs. | ||
| 115 | |||
| 116 | 2004-02-28 Juri Linkov <juri@jurta.org> | ||
| 117 | |||
| 118 | * ffap.el (dired-at-point): Additional writability test for | ||
| 119 | relative directory names. | ||
| 120 | (dired-at-point-prompter): Treat directories as a directory, get | ||
| 121 | the directory component from files. | ||
| 122 | (ffap-string-at-point): Return string from region if region is | ||
| 123 | active. | ||
| 124 | (ffap-file-at-point): Remove redundant code. | ||
| 125 | |||
| 1 | 2004-02-28 Kim F. Storm <storm@cua.dk> | 126 | 2004-02-28 Kim F. Storm <storm@cua.dk> |
| 2 | 127 | ||
| 3 | * gdb-ui.el (breakpoint-enabled-icon, breakpoint-disabled-icon): | 128 | * gdb-ui.el (breakpoint-enabled-icon, breakpoint-disabled-icon): |
| 4 | Initialize margin area images to nil. | 129 | Initialize margin area images to nil. |
| 5 | (breakpoint-bitmap): New defvar for breakpoint fringe bitmaps. | 130 | (breakpoint-bitmap): New defvar for breakpoint fringe bitmaps. |
| 6 | (breakpoint-enabled-bitmap-face) | 131 | (breakpoint-enabled-bitmap-face) |
| @@ -37,19 +162,19 @@ | |||
| 37 | 162 | ||
| 38 | 2004-02-27 Dan Nicolaescu <dann@ics.uci.edu> | 163 | 2004-02-27 Dan Nicolaescu <dann@ics.uci.edu> |
| 39 | 164 | ||
| 40 | * faces.el (face-spec-set-match-display): Add a new attribute, | 165 | * faces.el (face-spec-set-match-display): Add a new attribute, |
| 41 | `min-colors'. | 166 | `min-colors'. |
| 42 | (region, highlight, secondary-selection): Use `min-colors`. | 167 | (region, highlight, secondary-selection): Use `min-colors'. |
| 43 | 168 | ||
| 44 | * custom.el (defface): Add documentation for `min-colors'. | 169 | * custom.el (defface): Add documentation for `min-colors'. |
| 45 | 170 | ||
| 46 | * font-lock.el (font-lock-comment-face, font-lock-string-face) | 171 | * font-lock.el (font-lock-comment-face, font-lock-string-face) |
| 47 | (font-lock-keyword-face, font-lock-function-name-face) | 172 | (font-lock-keyword-face, font-lock-function-name-face) |
| 48 | (font-lock-variable-name-face, font-lock-constant-face): Use | 173 | (font-lock-variable-name-face, font-lock-constant-face): Use |
| 49 | `min-colors`. | 174 | `min-colors'. |
| 50 | 175 | ||
| 51 | * isearch.el (isearch, isearch-lazy-highlight-face): Use | 176 | * isearch.el (isearch, isearch-lazy-highlight-face): Use |
| 52 | `min-colors'. | 177 | `min-colors'. |
| 53 | 178 | ||
| 54 | 2004-02-25 Vinicius Jose Latorre <viniciusjl@ig.com.br> | 179 | 2004-02-25 Vinicius Jose Latorre <viniciusjl@ig.com.br> |
| 55 | 180 | ||
| @@ -198,7 +323,7 @@ | |||
| 198 | 2004-02-19 Glenn Morris <gmorris@ast.cam.ac.uk> | 323 | 2004-02-19 Glenn Morris <gmorris@ast.cam.ac.uk> |
| 199 | 324 | ||
| 200 | * calendar/appt.el (appt-display-format): Change default to | 325 | * calendar/appt.el (appt-display-format): Change default to |
| 201 | 'ignore, for backwards compatability. | 326 | 'ignore, for backwards compatibility. |
| 202 | (appt-display-message): If appt-display-format is 'ignore, | 327 | (appt-display-message): If appt-display-format is 'ignore, |
| 203 | respect old vars appt-msg-window and appt-visible. | 328 | respect old vars appt-msg-window and appt-visible. |
| 204 | (appt-activate): Don't depend on return value of cancel-timer. | 329 | (appt-activate): Don't depend on return value of cancel-timer. |
| @@ -304,7 +429,7 @@ | |||
| 304 | * loadhist.el (unload-feature): Doc fix. Rename flist to | 429 | * loadhist.el (unload-feature): Doc fix. Rename flist to |
| 305 | unload-hook-features-list. | 430 | unload-hook-features-list. |
| 306 | 431 | ||
| 307 | 2004-02-16 Jay Belanger <belanger@truman.edu> (tiny change). | 432 | 2004-02-16 Jay Belanger <belanger@truman.edu> (tiny change) |
| 308 | 433 | ||
| 309 | * calc/calc-embed.el (calc-do-embedded-activate): Add autoload | 434 | * calc/calc-embed.el (calc-do-embedded-activate): Add autoload |
| 310 | cookie. Don't check if we are looking-at open-formula. | 435 | cookie. Don't check if we are looking-at open-formula. |
| @@ -1091,7 +1216,7 @@ | |||
| 1091 | 1216 | ||
| 1092 | 2004-01-05 Karl Berry <karl@gnu.org> | 1217 | 2004-01-05 Karl Berry <karl@gnu.org> |
| 1093 | 1218 | ||
| 1094 | * emacs-lisp/copyright.el (copyright-regexp): might as well allow | 1219 | * emacs-lisp/copyright.el (copyright-regexp): Might as well allow |
| 1095 | / and *, too. | 1220 | / and *, too. |
| 1096 | 1221 | ||
| 1097 | 2003-12-31 Simon Josefsson <jas@extundo.com> | 1222 | 2003-12-31 Simon Josefsson <jas@extundo.com> |
| @@ -1111,7 +1236,7 @@ | |||
| 1111 | 1236 | ||
| 1112 | 2004-01-04 Karl Berry <karl@gnu.org> | 1237 | 2004-01-04 Karl Berry <karl@gnu.org> |
| 1113 | 1238 | ||
| 1114 | * emacs-lisp/copyright.el (copyright-regexp): allow the common | 1239 | * emacs-lisp/copyright.el (copyright-regexp): Allow the common |
| 1115 | comment characters % and # in the copyright year notice, | 1240 | comment characters % and # in the copyright year notice, |
| 1116 | as well as ;. | 1241 | as well as ;. |
| 1117 | 1242 | ||
| @@ -1165,7 +1290,7 @@ | |||
| 1165 | 1290 | ||
| 1166 | * ido.el (ido-nonreadable-directory-p): New defun to check for | 1291 | * ido.el (ido-nonreadable-directory-p): New defun to check for |
| 1167 | nonreadable directory without activating tramp (to avoid problems | 1292 | nonreadable directory without activating tramp (to avoid problems |
| 1168 | with checking incomplete tramp paths. | 1293 | with checking incomplete tramp paths). |
| 1169 | (ido-set-current-directory, ido-file-internal) | 1294 | (ido-set-current-directory, ido-file-internal) |
| 1170 | (ido-file-name-all-completions1): Use it. | 1295 | (ido-file-name-all-completions1): Use it. |
| 1171 | 1296 | ||
| @@ -1290,7 +1415,7 @@ | |||
| 1290 | 1415 | ||
| 1291 | * files.el (kill-some-buffers): Doc fix. | 1416 | * files.el (kill-some-buffers): Doc fix. |
| 1292 | 1417 | ||
| 1293 | 2003-12-29 David Herring <sdh6@ra.msstate.edu> (tiny change) | 1418 | 2003-12-29 David Herring <sdh6@ra.msstate.edu> (tiny change) |
| 1294 | 1419 | ||
| 1295 | * comint.el (comint-watch-for-password-prompt): Pass `string' as | 1420 | * comint.el (comint-watch-for-password-prompt): Pass `string' as |
| 1296 | arg to send-invisible | 1421 | arg to send-invisible |
| @@ -1308,16 +1433,16 @@ | |||
| 1308 | 1433 | ||
| 1309 | * xml.el (xml-get-attribute-or-nil): Doc fix. | 1434 | * xml.el (xml-get-attribute-or-nil): Doc fix. |
| 1310 | 1435 | ||
| 1311 | 2003-12-29 Peter 'Luna' Runestig <peter@runestig.com> | 1436 | 2003-12-29 Peter 'Luna' Runestig <peter@runestig.com> |
| 1312 | 1437 | ||
| 1313 | * net/zone-mode.el (zone-mode): Use write-file-functions, not | 1438 | * net/zone-mode.el (zone-mode): Use write-file-functions, not |
| 1314 | write-file-hooks. | 1439 | write-file-hooks. |
| 1315 | 1440 | ||
| 1316 | 2003-12-29 Eric Hanchrow <offby1@blarg.net> (tiny change) | 1441 | 2003-12-29 Eric Hanchrow <offby1@blarg.net> (tiny change) |
| 1317 | 1442 | ||
| 1318 | * autorevert.el (auto-revert-interval): Doc fix. | 1443 | * autorevert.el (auto-revert-interval): Doc fix. |
| 1319 | 1444 | ||
| 1320 | 2003-12-29 Mark A. Hershberger <mah@everybody.org> | 1445 | 2003-12-29 Mark A. Hershberger <mah@everybody.org> |
| 1321 | 1446 | ||
| 1322 | * xml.el (xml-get-attribute-or-nil): New function, like | 1447 | * xml.el (xml-get-attribute-or-nil): New function, like |
| 1323 | xml-get-attribute, but returns nil if the attribute was not found. | 1448 | xml-get-attribute, but returns nil if the attribute was not found. |
| @@ -1328,12 +1453,12 @@ | |||
| 1328 | 1453 | ||
| 1329 | * emacs-lisp/easymenu.el (easy-menu-define): Doc fix. | 1454 | * emacs-lisp/easymenu.el (easy-menu-define): Doc fix. |
| 1330 | 1455 | ||
| 1331 | 2003-12-29 Alex Schroeder <alex@emacswiki.org> (tiny change) | 1456 | 2003-12-29 Alex Schroeder <alex@emacswiki.org> (tiny change) |
| 1332 | 1457 | ||
| 1333 | * custom.el (custom-declare-theme): Use `value' when putting | 1458 | * custom.el (custom-declare-theme): Use `value' when putting |
| 1334 | properties on `theme'. | 1459 | properties on `theme'. |
| 1335 | 1460 | ||
| 1336 | 2003-12-29 Takaaki Ota <Takaaki.Ota@am.sony.com> | 1461 | 2003-12-29 Takaaki Ota <Takaaki.Ota@am.sony.com> |
| 1337 | 1462 | ||
| 1338 | * subr.el (insert-for-yank): Call insert-for-yank-1 repetitively | 1463 | * subr.el (insert-for-yank): Call insert-for-yank-1 repetitively |
| 1339 | for each yank-handler segment. | 1464 | for each yank-handler segment. |
| @@ -1344,7 +1469,7 @@ | |||
| 1344 | (table--put-cell-indicator-property): Put yank-handler property | 1469 | (table--put-cell-indicator-property): Put yank-handler property |
| 1345 | that indicates the yank handler for the table cell. | 1470 | that indicates the yank handler for the table cell. |
| 1346 | 1471 | ||
| 1347 | 2003-12-29 Jesper Harder <harder@ifa.au.dk> (tiny change) | 1472 | 2003-12-29 Jesper Harder <harder@ifa.au.dk> (tiny change) |
| 1348 | 1473 | ||
| 1349 | * generic-x.el (etc-modules-conf-generic-mode): A more complete | 1474 | * generic-x.el (etc-modules-conf-generic-mode): A more complete |
| 1350 | set of keywords. | 1475 | set of keywords. |
| @@ -1417,7 +1542,7 @@ | |||
| 1417 | 1542 | ||
| 1418 | * ffap.el (ffap-read-file-or-url): Revert previous change. | 1543 | * ffap.el (ffap-read-file-or-url): Revert previous change. |
| 1419 | 1544 | ||
| 1420 | 2003-12-25 Robert J. Chassell <bob@rattlesnake.com> | 1545 | 2003-12-25 Robert J. Chassell <bob@rattlesnake.com> |
| 1421 | 1546 | ||
| 1422 | * textmodes/texnfo-upd.el (texinfo-multi-file-update): Create a | 1547 | * textmodes/texnfo-upd.el (texinfo-multi-file-update): Create a |
| 1423 | new list of included files called `files-with-node-lines', that | 1548 | new list of included files called `files-with-node-lines', that |
| @@ -1497,7 +1622,7 @@ | |||
| 1497 | * info.el (Info-unescape-quotes, Info-split-parameter-string) | 1622 | * info.el (Info-unescape-quotes, Info-split-parameter-string) |
| 1498 | (Info-goto-emacs-command-node): Doc fixes. | 1623 | (Info-goto-emacs-command-node): Doc fixes. |
| 1499 | 1624 | ||
| 1500 | 2003-12-12 Jesper Harder <harder@ifa.au.dk> | 1625 | 2003-12-12 Jesper Harder <harder@ifa.au.dk> |
| 1501 | 1626 | ||
| 1502 | * cus-edit.el (custom-add-parent-links): Define "many". | 1627 | * cus-edit.el (custom-add-parent-links): Define "many". |
| 1503 | 1628 | ||
| @@ -1588,7 +1713,6 @@ | |||
| 1588 | value "'integer". Otherwise, don't use that parameter (default is | 1713 | value "'integer". Otherwise, don't use that parameter (default is |
| 1589 | integer format). | 1714 | integer format). |
| 1590 | 1715 | ||
| 1591 | |||
| 1592 | 2003-11-30 Luc Teirlinck <teirllm@auburn.edu> | 1716 | 2003-11-30 Luc Teirlinck <teirllm@auburn.edu> |
| 1593 | 1717 | ||
| 1594 | * help.el (help-map): Bind `display-local-help' to `C-h .'. | 1718 | * help.el (help-map): Bind `display-local-help' to `C-h .'. |
| @@ -1882,7 +2006,7 @@ | |||
| 1882 | 2006 | ||
| 1883 | * descr-text.el (describe-char): Fix typo. | 2007 | * descr-text.el (describe-char): Fix typo. |
| 1884 | 2008 | ||
| 1885 | 2003-11-08 Kailash C. Chowksey <klchxbec@m-net.arbornet.org> | 2009 | 2003-11-08 Kailash C. Chowksey <klchxbec@m-net.arbornet.org> |
| 1886 | 2010 | ||
| 1887 | These changes are to support Kannada language/script. | 2011 | These changes are to support Kannada language/script. |
| 1888 | 2012 | ||
| @@ -1939,7 +2063,7 @@ | |||
| 1939 | (xml-ns-parse-ns-attrs, xml-ns-expand-el) | 2063 | (xml-ns-parse-ns-attrs, xml-ns-expand-el) |
| 1940 | (xml-ns-expand-attr): New functions to do namespace handling. | 2064 | (xml-ns-expand-attr): New functions to do namespace handling. |
| 1941 | (xml-intern-attrlist): Back-compatible handling of attribute names. | 2065 | (xml-intern-attrlist): Back-compatible handling of attribute names. |
| 1942 | (xml-parse-tag): Move namespace handling to seperate functions. | 2066 | (xml-parse-tag): Move namespace handling to separate functions. |
| 1943 | Now produces elements in the form ((:ns . "element") (attr-list) | 2067 | Now produces elements in the form ((:ns . "element") (attr-list) |
| 1944 | children) instead of ('ns:element (attr-list) children). | 2068 | children) instead of ('ns:element (attr-list) children). |
| 1945 | (xml-parse-attlist): Fix attribute parsing. | 2069 | (xml-parse-attlist): Fix attribute parsing. |
| @@ -2450,7 +2574,7 @@ | |||
| 2450 | (mode-line-position): Change cons cell into proper list in | 2574 | (mode-line-position): Change cons cell into proper list in |
| 2451 | initialization. | 2575 | initialization. |
| 2452 | 2576 | ||
| 2453 | 2003-09-29 SAITO Takuya <tabmore@rivo.mediatti.net> (tiny change) | 2577 | 2003-09-29 SAITO Takuya <tabmore@rivo.mediatti.net> (tiny change) |
| 2454 | 2578 | ||
| 2455 | * international/mule.el (decode-coding-inserted-region): Use car | 2579 | * international/mule.el (decode-coding-inserted-region): Use car |
| 2456 | of the return value of find-operation-coding-system. | 2580 | of the return value of find-operation-coding-system. |
| @@ -2500,7 +2624,7 @@ | |||
| 2500 | is non-nil, initialize an empty `file-name-history' with the | 2624 | is non-nil, initialize an empty `file-name-history' with the |
| 2501 | recent list. | 2625 | recent list. |
| 2502 | 2626 | ||
| 2503 | 2003-09-28 Evgeni Dobrev <evgeni_dobrev@developer.bg> (tiny patch) | 2627 | 2003-09-28 Evgeni Dobrev <evgeni_dobrev@developer.bg> (tiny change) |
| 2504 | 2628 | ||
| 2505 | * man.el (Man-default-man-entry): Remove the leading `*' from the | 2629 | * man.el (Man-default-man-entry): Remove the leading `*' from the |
| 2506 | word at point. | 2630 | word at point. |
| @@ -2710,7 +2834,7 @@ | |||
| 2710 | (bootstrap-clean-CMD, bootstrap-clean-SH): Recreate loaddefs.el | 2834 | (bootstrap-clean-CMD, bootstrap-clean-SH): Recreate loaddefs.el |
| 2711 | from loaddefs-boot.el if necessary. | 2835 | from loaddefs-boot.el if necessary. |
| 2712 | 2836 | ||
| 2713 | 2003-09-15 Zoltan Kemenczy <kemenczy@rogers.com> | 2837 | 2003-09-15 Zoltan Kemenczy <kemenczy@rogers.com> |
| 2714 | 2838 | ||
| 2715 | * progmodes/gud.el (gud-find-class): Make jdb work again since | 2839 | * progmodes/gud.el (gud-find-class): Make jdb work again since |
| 2716 | cc-mode changed the syntactic information. | 2840 | cc-mode changed the syntactic information. |
| @@ -2741,7 +2865,7 @@ | |||
| 2741 | 2865 | ||
| 2742 | * emacs-lisp/tq.el (tq-create): Fix mixed up unquote style. | 2866 | * emacs-lisp/tq.el (tq-create): Fix mixed up unquote style. |
| 2743 | 2867 | ||
| 2744 | 2003-09-12 Eric Hanchrow <offby1@blarg.net> (tiny change) | 2868 | 2003-09-12 Eric Hanchrow <offby1@blarg.net> (tiny change) |
| 2745 | 2869 | ||
| 2746 | * dired.el (dired-mode-map): Fix typo. | 2870 | * dired.el (dired-mode-map): Fix typo. |
| 2747 | 2871 | ||
| @@ -2879,7 +3003,7 @@ | |||
| 2879 | * international/fontset.el (setup-default-fontset): For Thai | 3003 | * international/fontset.el (setup-default-fontset): For Thai |
| 2880 | font, specify "*" family. | 3004 | font, specify "*" family. |
| 2881 | 3005 | ||
| 2882 | 2003-09-01 Kevin Rodgers <ihs_4664@yahoo.com> (tiny change) | 3006 | 2003-09-01 Kevin Rodgers <ihs_4664@yahoo.com> (tiny change) |
| 2883 | 3007 | ||
| 2884 | * progmodes/compile.el (previous-error): Accept a prefix | 3008 | * progmodes/compile.el (previous-error): Accept a prefix |
| 2885 | argument, similarly to next-error. | 3009 | argument, similarly to next-error. |
| @@ -2920,7 +3044,7 @@ | |||
| 2920 | * simple.el (blink-matching-open): Work correctly on chars that | 3044 | * simple.el (blink-matching-open): Work correctly on chars that |
| 2921 | are designated as parens through the syntax-table text property. | 3045 | are designated as parens through the syntax-table text property. |
| 2922 | 3046 | ||
| 2923 | 2003-08-29 Thierry Emery <thierry.emery@club-internet.fr> (tiny change) | 3047 | 2003-08-29 Thierry Emery <thierry.emery@club-internet.fr> (tiny change) |
| 2924 | 3048 | ||
| 2925 | * kinsoku.el (kinsoku-longer, kinsoku-shorter): Do not choose a | 3049 | * kinsoku.el (kinsoku-longer, kinsoku-shorter): Do not choose a |
| 2926 | line break position in the middle of a non-kinsoku (e.g. latin) | 3050 | line break position in the middle of a non-kinsoku (e.g. latin) |
| @@ -2970,7 +3094,7 @@ | |||
| 2970 | * progmodes/cc-engine.el (c-just-after-func-arglist-p): | 3094 | * progmodes/cc-engine.el (c-just-after-func-arglist-p): |
| 2971 | Safeguard against unbalanced sexps. | 3095 | Safeguard against unbalanced sexps. |
| 2972 | 3096 | ||
| 2973 | 2003-08-26 Terje Rosten <terjeros@phys.ntnu.no> | 3097 | 2003-08-26 Terje Rosten <terjeros@phys.ntnu.no> |
| 2974 | 3098 | ||
| 2975 | * version.el (emacs-version): Check for gtk. Include gtk version info. | 3099 | * version.el (emacs-version): Check for gtk. Include gtk version info. |
| 2976 | 3100 | ||
diff --git a/lisp/ffap.el b/lisp/ffap.el index 27abd52f563..38f7f92405e 100644 --- a/lisp/ffap.el +++ b/lisp/ffap.el | |||
| @@ -1,7 +1,7 @@ | |||
| 1 | ;; ffap.el --- find file (or url) at point | 1 | ;;; ffap.el --- find file (or url) at point |
| 2 | ;; | 2 | |
| 3 | ;; Copyright (C) 1995, 96, 97, 2000 Free Software Foundation, Inc. | 3 | ;; Copyright (C) 1995, 96, 97, 2000, 2004 Free Software Foundation, Inc. |
| 4 | ;; | 4 | |
| 5 | ;; Author: Michelangelo Grigni <mic@mathcs.emory.edu> | 5 | ;; Author: Michelangelo Grigni <mic@mathcs.emory.edu> |
| 6 | ;; Maintainer: Rajesh Vaidheeswarran <rv@gnu.org> | 6 | ;; Maintainer: Rajesh Vaidheeswarran <rv@gnu.org> |
| 7 | ;; Created: 29 Mar 1993 | 7 | ;; Created: 29 Mar 1993 |
| @@ -701,7 +701,7 @@ kpathsea, a library used by some versions of TeX." | |||
| 701 | 701 | ||
| 702 | (defun ffap-locate-file (file &optional nosuffix path dir-ok) | 702 | (defun ffap-locate-file (file &optional nosuffix path dir-ok) |
| 703 | ;; The Emacs 20 version of locate-library could almost replace this, | 703 | ;; The Emacs 20 version of locate-library could almost replace this, |
| 704 | ;; except it does not let us overrride the suffix list. The | 704 | ;; except it does not let us override the suffix list. The |
| 705 | ;; compression-suffixes search moved to ffap-file-exists-string. | 705 | ;; compression-suffixes search moved to ffap-file-exists-string. |
| 706 | "A generic path-searching function, mimics `load' by default. | 706 | "A generic path-searching function, mimics `load' by default. |
| 707 | Returns path to file that \(load FILE\) would load, or nil. | 707 | Returns path to file that \(load FILE\) would load, or nil. |
| @@ -966,6 +966,7 @@ possibly a major-mode name, or one of the symbol | |||
| 966 | MODE (defaults to value of `major-mode') is a symbol used to look up string | 966 | MODE (defaults to value of `major-mode') is a symbol used to look up string |
| 967 | syntax parameters in `ffap-string-at-point-mode-alist'. | 967 | syntax parameters in `ffap-string-at-point-mode-alist'. |
| 968 | If MODE is not found, we use `file' instead of MODE. | 968 | If MODE is not found, we use `file' instead of MODE. |
| 969 | If the region is active, return a string from the region. | ||
| 969 | Sets `ffap-string-at-point' and `ffap-string-at-point-region'." | 970 | Sets `ffap-string-at-point' and `ffap-string-at-point-region'." |
| 970 | (let* ((args | 971 | (let* ((args |
| 971 | (cdr | 972 | (cdr |
| @@ -973,15 +974,19 @@ Sets `ffap-string-at-point' and `ffap-string-at-point-region'." | |||
| 973 | (assq 'file ffap-string-at-point-mode-alist)))) | 974 | (assq 'file ffap-string-at-point-mode-alist)))) |
| 974 | (pt (point)) | 975 | (pt (point)) |
| 975 | (str | 976 | (str |
| 976 | (buffer-substring | 977 | (if (and transient-mark-mode mark-active) |
| 977 | (save-excursion | 978 | (buffer-substring |
| 978 | (skip-chars-backward (car args)) | 979 | (setcar ffap-string-at-point-region (region-beginning)) |
| 979 | (skip-chars-forward (nth 1 args) pt) | 980 | (setcar (cdr ffap-string-at-point-region) (region-end))) |
| 980 | (setcar ffap-string-at-point-region (point))) | 981 | (buffer-substring |
| 981 | (save-excursion | 982 | (save-excursion |
| 982 | (skip-chars-forward (car args)) | 983 | (skip-chars-backward (car args)) |
| 983 | (skip-chars-backward (nth 2 args) pt) | 984 | (skip-chars-forward (nth 1 args) pt) |
| 984 | (setcar (cdr ffap-string-at-point-region) (point)))))) | 985 | (setcar ffap-string-at-point-region (point))) |
| 986 | (save-excursion | ||
| 987 | (skip-chars-forward (car args)) | ||
| 988 | (skip-chars-backward (nth 2 args) pt) | ||
| 989 | (setcar (cdr ffap-string-at-point-region) (point))))))) | ||
| 985 | (set-text-properties 0 (length str) nil str) | 990 | (set-text-properties 0 (length str) nil str) |
| 986 | (setq ffap-string-at-point str))) | 991 | (setq ffap-string-at-point str))) |
| 987 | 992 | ||
| @@ -1128,9 +1133,6 @@ which may actually result in an url rather than a filename." | |||
| 1128 | ((and ffap-shell-prompt-regexp | 1133 | ((and ffap-shell-prompt-regexp |
| 1129 | (not abs) (string-match ffap-shell-prompt-regexp name) | 1134 | (not abs) (string-match ffap-shell-prompt-regexp name) |
| 1130 | (ffap-file-exists-string (substring name (match-end 0))))) | 1135 | (ffap-file-exists-string (substring name (match-end 0))))) |
| 1131 | ;; Immediately test local filenames. If default-directory is | ||
| 1132 | ;; remote, you probably already have a connection. | ||
| 1133 | ((and (not abs) (ffap-file-exists-string name))) | ||
| 1134 | ;; Accept remote names without actual checking (too slow): | 1136 | ;; Accept remote names without actual checking (too slow): |
| 1135 | ((if abs | 1137 | ((if abs |
| 1136 | (ffap-file-remote-p name) | 1138 | (ffap-file-remote-p name) |
| @@ -1675,7 +1677,9 @@ ffap most of the time." | |||
| 1675 | (if (file-directory-p filename) | 1677 | (if (file-directory-p filename) |
| 1676 | (dired (expand-file-name filename)) | 1678 | (dired (expand-file-name filename)) |
| 1677 | (dired (concat (expand-file-name filename) "*")))) | 1679 | (dired (concat (expand-file-name filename) "*")))) |
| 1678 | ((and (file-writable-p (file-name-directory filename)) | 1680 | ((and (file-writable-p |
| 1681 | (or (file-name-directory (directory-file-name filename)) | ||
| 1682 | filename)) | ||
| 1679 | (y-or-n-p "Directory does not exist, create it? ")) | 1683 | (y-or-n-p "Directory does not exist, create it? ")) |
| 1680 | (make-directory filename) | 1684 | (make-directory filename) |
| 1681 | (dired filename)) | 1685 | (dired filename)) |
| @@ -1688,9 +1692,24 @@ ffap most of the time." | |||
| 1688 | (ffap-read-file-or-url | 1692 | (ffap-read-file-or-url |
| 1689 | (if ffap-url-regexp "Dired file or URL: " "Dired file: ") | 1693 | (if ffap-url-regexp "Dired file or URL: " "Dired file: ") |
| 1690 | (prog1 | 1694 | (prog1 |
| 1691 | (setq guess (or guess (ffap-guesser))) | 1695 | (setq guess (or guess |
| 1692 | (and guess (ffap-highlight)) | 1696 | (let ((guess (ffap-guesser))) |
| 1693 | )) | 1697 | (if (or (not guess) |
| 1698 | (ffap-url-p guess) | ||
| 1699 | (ffap-file-remote-p guess)) | ||
| 1700 | guess | ||
| 1701 | (setq guess (abbreviate-file-name | ||
| 1702 | (expand-file-name guess))) | ||
| 1703 | (cond | ||
| 1704 | ;; Interpret local directory as a directory. | ||
| 1705 | ((file-directory-p guess) | ||
| 1706 | (file-name-as-directory guess)) | ||
| 1707 | ;; Get directory component from local files. | ||
| 1708 | ((file-regular-p guess) | ||
| 1709 | (file-name-directory guess)) | ||
| 1710 | (guess)))) | ||
| 1711 | )) | ||
| 1712 | (and guess (ffap-highlight)))) | ||
| 1694 | (ffap-highlight t))) | 1713 | (ffap-highlight t))) |
| 1695 | 1714 | ||
| 1696 | ;;; Offer default global bindings (`ffap-bindings'): | 1715 | ;;; Offer default global bindings (`ffap-bindings'): |
diff --git a/lisp/net/tramp-ftp.el b/lisp/net/tramp-ftp.el index c81e49bf77c..3be891a49f8 100644 --- a/lisp/net/tramp-ftp.el +++ b/lisp/net/tramp-ftp.el | |||
| @@ -1,6 +1,6 @@ | |||
| 1 | ;;; tramp-ftp.el --- Tramp convenience functions for Ange-FTP and EFS -*- coding: iso-8859-1; -*- | 1 | ;;; tramp-ftp.el --- Tramp convenience functions for Ange-FTP and EFS -*- coding: iso-8859-1; -*- |
| 2 | 2 | ||
| 3 | ;; Copyright (C) 2002, 2003 Free Software Foundation, Inc. | 3 | ;; Copyright (C) 2002, 2003, 2004 Free Software Foundation, Inc. |
| 4 | 4 | ||
| 5 | ;; Author: Michael Albinus <Michael.Albinus@alcatel.de> | 5 | ;; Author: Michael Albinus <Michael.Albinus@alcatel.de> |
| 6 | ;; Keywords: comm, processes | 6 | ;; Keywords: comm, processes |
| @@ -24,8 +24,8 @@ | |||
| 24 | 24 | ||
| 25 | ;;; Commentary: | 25 | ;;; Commentary: |
| 26 | 26 | ||
| 27 | ;; Convenience functions for calling Ange-FTP (and maybe EFS, later on) | 27 | ;; Convenience functions for calling Ange-FTP from Tramp. |
| 28 | ;; from Tramp. Most of them are displaced from tramp.el. | 28 | ;; Most of them are displaced from tramp.el. |
| 29 | 29 | ||
| 30 | ;;; Code: | 30 | ;;; Code: |
| 31 | 31 | ||
| @@ -98,9 +98,16 @@ pass to the OPERATION." | |||
| 98 | (list (nth 0 tramp-file-name-structure) | 98 | (list (nth 0 tramp-file-name-structure) |
| 99 | (nth 3 tramp-file-name-structure) | 99 | (nth 3 tramp-file-name-structure) |
| 100 | (nth 2 tramp-file-name-structure) | 100 | (nth 2 tramp-file-name-structure) |
| 101 | (nth 4 tramp-file-name-structure)))) | 101 | (nth 4 tramp-file-name-structure))) |
| 102 | ;; ange-ftp uses `ange-ftp-ftp-name-arg' and `ange-ftp-ftp-name-res' | ||
| 103 | ;; for optimization in `ange-ftp-ftp-name'. If Tramp wasn't active, | ||
| 104 | ;; there could be incorrect values from previous calls in case the | ||
| 105 | ;; "ftp" method is used in the Tramp file name. So we unset | ||
| 106 | ;; those values. | ||
| 107 | (ange-ftp-ftp-name-arg "") | ||
| 108 | (ange-ftp-ftp-name-res nil)) | ||
| 102 | (cond | 109 | (cond |
| 103 | ;; If argument is a symlink, 'file-directory-p` and 'file-exists-p` | 110 | ;; If argument is a symlink, `file-directory-p' and `file-exists-p' |
| 104 | ;; call the traversed file recursively. So we cannot disable the | 111 | ;; call the traversed file recursively. So we cannot disable the |
| 105 | ;; file-name-handler this case. | 112 | ;; file-name-handler this case. |
| 106 | ((memq operation '(file-directory-p file-exists-p)) | 113 | ((memq operation '(file-directory-p file-exists-p)) |
diff --git a/lisp/net/tramp-smb.el b/lisp/net/tramp-smb.el index 95f3fb330c4..ab6ad3310c1 100644 --- a/lisp/net/tramp-smb.el +++ b/lisp/net/tramp-smb.el | |||
| @@ -1,6 +1,6 @@ | |||
| 1 | ;;; tramp-smb.el --- Tramp access functions for SMB servers -*- coding: iso-8859-1; -*- | 1 | ;;; tramp-smb.el --- Tramp access functions for SMB servers -*- coding: iso-8859-1; -*- |
| 2 | 2 | ||
| 3 | ;; Copyright (C) 2002, 2003 Free Software Foundation, Inc. | 3 | ;; Copyright (C) 2002, 2003, 2004 Free Software Foundation, Inc. |
| 4 | 4 | ||
| 5 | ;; Author: Michael Albinus <Michael.Albinus@alcatel.de> | 5 | ;; Author: Michael Albinus <Michael.Albinus@alcatel.de> |
| 6 | ;; Keywords: comm, processes | 6 | ;; Keywords: comm, processes |
| @@ -50,7 +50,7 @@ | |||
| 50 | ;; Add a default for `tramp-default-method-alist'. Rule: If there is | 50 | ;; Add a default for `tramp-default-method-alist'. Rule: If there is |
| 51 | ;; a domain in USER, it must be the SMB method. | 51 | ;; a domain in USER, it must be the SMB method. |
| 52 | (add-to-list 'tramp-default-method-alist | 52 | (add-to-list 'tramp-default-method-alist |
| 53 | (list "%" "" tramp-smb-method)) | 53 | (list "" "%" tramp-smb-method)) |
| 54 | 54 | ||
| 55 | ;; Add completion function for SMB method. | 55 | ;; Add completion function for SMB method. |
| 56 | (tramp-set-completion-function | 56 | (tramp-set-completion-function |
| @@ -62,7 +62,7 @@ | |||
| 62 | :group 'tramp | 62 | :group 'tramp |
| 63 | :type 'string) | 63 | :type 'string) |
| 64 | 64 | ||
| 65 | (defconst tramp-smb-prompt "^smb: \\S-+> " | 65 | (defconst tramp-smb-prompt "^smb: \\S-+> \\|^\\s-+Server\\s-+Comment$" |
| 66 | "Regexp used as prompt in smbclient.") | 66 | "Regexp used as prompt in smbclient.") |
| 67 | 67 | ||
| 68 | (defconst tramp-smb-errors | 68 | (defconst tramp-smb-errors |
| @@ -71,8 +71,8 @@ | |||
| 71 | '(; Connection error | 71 | '(; Connection error |
| 72 | "Connection to \\S-+ failed" | 72 | "Connection to \\S-+ failed" |
| 73 | ; Samba | 73 | ; Samba |
| 74 | "ERRSRV" | ||
| 75 | "ERRDOS" | 74 | "ERRDOS" |
| 75 | "ERRSRV" | ||
| 76 | "ERRbadfile" | 76 | "ERRbadfile" |
| 77 | "ERRbadpw" | 77 | "ERRbadpw" |
| 78 | "ERRfilexists" | 78 | "ERRfilexists" |
| @@ -81,13 +81,16 @@ | |||
| 81 | "ERRnosuchshare" | 81 | "ERRnosuchshare" |
| 82 | ; Windows NT 4.0, Windows 5.0 (Windows 2000), Windows 5.1 (Windows XP) | 82 | ; Windows NT 4.0, Windows 5.0 (Windows 2000), Windows 5.1 (Windows XP) |
| 83 | "NT_STATUS_ACCESS_DENIED" | 83 | "NT_STATUS_ACCESS_DENIED" |
| 84 | "NT_STATUS_ACCOUNT_LOCKED_OUT" | ||
| 84 | "NT_STATUS_BAD_NETWORK_NAME" | 85 | "NT_STATUS_BAD_NETWORK_NAME" |
| 85 | "NT_STATUS_CANNOT_DELETE" | 86 | "NT_STATUS_CANNOT_DELETE" |
| 86 | "NT_STATUS_LOGON_FAILURE" | 87 | "NT_STATUS_LOGON_FAILURE" |
| 88 | "NT_STATUS_NETWORK_ACCESS_DENIED" | ||
| 87 | "NT_STATUS_NO_SUCH_FILE" | 89 | "NT_STATUS_NO_SUCH_FILE" |
| 88 | "NT_STATUS_OBJECT_NAME_INVALID" | 90 | "NT_STATUS_OBJECT_NAME_INVALID" |
| 89 | "NT_STATUS_OBJECT_NAME_NOT_FOUND" | 91 | "NT_STATUS_OBJECT_NAME_NOT_FOUND" |
| 90 | "NT_STATUS_SHARING_VIOLATION") | 92 | "NT_STATUS_SHARING_VIOLATION" |
| 93 | "NT_STATUS_WRONG_PASSWORD") | ||
| 91 | "\\|") | 94 | "\\|") |
| 92 | "Regexp for possible error strings of SMB servers. | 95 | "Regexp for possible error strings of SMB servers. |
| 93 | Used instead of analyzing error codes of commands.") | 96 | Used instead of analyzing error codes of commands.") |
| @@ -102,12 +105,6 @@ This variable is local to each buffer.") | |||
| 102 | This variable is local to each buffer.") | 105 | This variable is local to each buffer.") |
| 103 | (make-variable-buffer-local 'tramp-smb-share-cache) | 106 | (make-variable-buffer-local 'tramp-smb-share-cache) |
| 104 | 107 | ||
| 105 | (defvar tramp-smb-process-running nil | ||
| 106 | "Flag whether a corresponding process is still running. | ||
| 107 | Will be changed by corresponding `process-sentinel'. | ||
| 108 | This variable is local to each buffer.") | ||
| 109 | (make-variable-buffer-local 'tramp-smb-process-running) | ||
| 110 | |||
| 111 | (defvar tramp-smb-inodes nil | 108 | (defvar tramp-smb-inodes nil |
| 112 | "Keeps virtual inodes numbers for SMB files.") | 109 | "Keeps virtual inodes numbers for SMB files.") |
| 113 | 110 | ||
| @@ -452,19 +449,23 @@ KEEP-DATE is not handled in case NEWNAME resides on an SMB server." | |||
| 452 | 449 | ||
| 453 | (defun tramp-smb-handle-file-writable-p (filename) | 450 | (defun tramp-smb-handle-file-writable-p (filename) |
| 454 | "Like `file-writable-p' for tramp files." | 451 | "Like `file-writable-p' for tramp files." |
| 455 | ; (with-parsed-tramp-file-name filename nil | 452 | (if (not (file-exists-p filename)) |
| 456 | (let (user host localname) | 453 | (let ((dir (file-name-directory filename))) |
| 457 | (with-parsed-tramp-file-name filename l | 454 | (and (file-exists-p dir) |
| 458 | (setq user l-user host l-host localname l-localname)) | 455 | (file-writable-p dir))) |
| 459 | (save-excursion | 456 | ; (with-parsed-tramp-file-name filename nil |
| 460 | (let* ((share (tramp-smb-get-share localname)) | 457 | (let (user host localname) |
| 461 | (file (tramp-smb-get-localname localname nil)) | 458 | (with-parsed-tramp-file-name filename l |
| 462 | (entries (tramp-smb-get-file-entries user host share file)) | 459 | (setq user l-user host l-host localname l-localname)) |
| 463 | (entry (and entries | 460 | (save-excursion |
| 464 | (assoc (file-name-nondirectory file) entries)))) | 461 | (let* ((share (tramp-smb-get-share localname)) |
| 465 | (and entry | 462 | (file (tramp-smb-get-localname localname nil)) |
| 466 | (string-match "w" (nth 1 entry)) | 463 | (entries (tramp-smb-get-file-entries user host share file)) |
| 467 | t))))) | 464 | (entry (and entries |
| 465 | (assoc (file-name-nondirectory file) entries)))) | ||
| 466 | (and share entry | ||
| 467 | (string-match "w" (nth 1 entry)) | ||
| 468 | t)))))) | ||
| 468 | 469 | ||
| 469 | (defun tramp-smb-handle-insert-directory | 470 | (defun tramp-smb-handle-insert-directory |
| 470 | (filename switches &optional wildcard full-directory-p) | 471 | (filename switches &optional wildcard full-directory-p) |
| @@ -733,9 +734,12 @@ Result is a list of (LOCALNAME MODE SIZE MONTH DAY TIME YEAR)." | |||
| 733 | ;; Cache share entries | 734 | ;; Cache share entries |
| 734 | (setq tramp-smb-share-cache res))) | 735 | (setq tramp-smb-share-cache res))) |
| 735 | 736 | ||
| 736 | |||
| 737 | ;; Add directory itself | 737 | ;; Add directory itself |
| 738 | (add-to-list 'res '("" "dr-xr-xr-x" 0 (0 0))) | 738 | (add-to-list 'res '("" "drwxrwxrwx" 0 (0 0))) |
| 739 | |||
| 740 | ;; There's a very strange error (debugged with XEmacs 21.4.14) | ||
| 741 | ;; If there's no short delay, it returns nil. No idea about | ||
| 742 | (when (featurep 'xemacs) (sleep-for 0.01)) | ||
| 739 | 743 | ||
| 740 | ;; Check for matching entries | 744 | ;; Check for matching entries |
| 741 | (delq nil (mapcar | 745 | (delq nil (mapcar |
| @@ -913,7 +917,8 @@ there has been an error message from smbclient." | |||
| 913 | "Maybe open a connection to HOST, logging in as USER, using `tramp-smb-program'. | 917 | "Maybe open a connection to HOST, logging in as USER, using `tramp-smb-program'. |
| 914 | Does not do anything if a connection is already open, but re-opens the | 918 | Does not do anything if a connection is already open, but re-opens the |
| 915 | connection if a previous connection has died for some reason." | 919 | connection if a previous connection has died for some reason." |
| 916 | (let ((p (get-buffer-process | 920 | (let ((process-connection-type tramp-process-connection-type) |
| 921 | (p (get-buffer-process | ||
| 917 | (tramp-get-buffer nil tramp-smb-method user host)))) | 922 | (tramp-get-buffer nil tramp-smb-method user host)))) |
| 918 | (save-excursion | 923 | (save-excursion |
| 919 | (set-buffer (tramp-get-buffer nil tramp-smb-method user host)) | 924 | (set-buffer (tramp-get-buffer nil tramp-smb-method user host)) |
| @@ -987,11 +992,7 @@ Domain names in USER and port numbers in HOST are acknowledged." | |||
| 987 | (tramp-message 9 "Started process %s" (process-command p)) | 992 | (tramp-message 9 "Started process %s" (process-command p)) |
| 988 | (process-kill-without-query p) | 993 | (process-kill-without-query p) |
| 989 | (set-buffer buffer) | 994 | (set-buffer buffer) |
| 990 | (set-process-sentinel | 995 | (setq tramp-smb-share share) |
| 991 | p (lambda (proc str) (setq tramp-smb-process-running nil))) | ||
| 992 | ; If no share is given, the process will terminate | ||
| 993 | (setq tramp-smb-process-running share | ||
| 994 | tramp-smb-share share) | ||
| 995 | 996 | ||
| 996 | ; send password | 997 | ; send password |
| 997 | (when real-user | 998 | (when real-user |
| @@ -1000,54 +1001,44 @@ Domain names in USER and port numbers in HOST are acknowledged." | |||
| 1000 | (tramp-enter-password p pw-prompt))) | 1001 | (tramp-enter-password p pw-prompt))) |
| 1001 | 1002 | ||
| 1002 | (unless (tramp-smb-wait-for-output user host) | 1003 | (unless (tramp-smb-wait-for-output user host) |
| 1004 | (tramp-clear-passwd user host) | ||
| 1003 | (error "Cannot open connection //%s@%s/%s" | 1005 | (error "Cannot open connection //%s@%s/%s" |
| 1004 | user host (or share ""))))))) | 1006 | user host (or share ""))))))) |
| 1005 | 1007 | ||
| 1006 | ;; We don't use timeouts. If needed, the caller shall wrap around. | 1008 | ;; We don't use timeouts. If needed, the caller shall wrap around. |
| 1007 | (defun tramp-smb-wait-for-output (user host) | 1009 | (defun tramp-smb-wait-for-output (user host) |
| 1008 | "Wait for output from smbclient command. | 1010 | "Wait for output from smbclient command. |
| 1009 | Sets position to begin of buffer. | ||
| 1010 | Returns nil if an error message has appeared." | 1011 | Returns nil if an error message has appeared." |
| 1011 | (save-excursion | 1012 | (let ((proc (get-buffer-process (current-buffer))) |
| 1012 | (let ((proc (get-buffer-process (current-buffer))) | 1013 | (found (progn (goto-char (point-min)) |
| 1013 | (found (progn (goto-char (point-max)) | 1014 | (re-search-forward tramp-smb-prompt nil t))) |
| 1014 | (beginning-of-line) | 1015 | (err (progn (goto-char (point-min)) |
| 1015 | (looking-at tramp-smb-prompt))) | 1016 | (re-search-forward tramp-smb-errors nil t)))) |
| 1016 | err) | 1017 | |
| 1017 | (save-match-data | 1018 | ;; Algorithm: get waiting output. See if last line contains |
| 1018 | ;; Algorithm: get waiting output. See if last line contains | 1019 | ;; tramp-smb-prompt sentinel or tramp-smb-errors strings. |
| 1019 | ;; tramp-smb-prompt sentinel, or process has exited. | 1020 | ;; If not, wait a bit and again get waiting output. |
| 1020 | ;; If not, wait a bit and again get waiting output. | 1021 | (while (and (not found) (not err)) |
| 1021 | (while (and (not found) tramp-smb-process-running) | 1022 | |
| 1022 | (accept-process-output proc) | 1023 | ;; Accept pending output. |
| 1023 | (goto-char (point-max)) | 1024 | (accept-process-output proc) |
| 1024 | (beginning-of-line) | 1025 | |
| 1025 | (setq found (looking-at tramp-smb-prompt))) | 1026 | ;; Search for prompt. |
| 1026 | |||
| 1027 | ;; There might be pending output. If tramp-smb-prompt sentinel | ||
| 1028 | ;; hasn't been found, the process has died already. We should | ||
| 1029 | ;; give it a chance. | ||
| 1030 | (when (not found) (accept-process-output nil 1)) | ||
| 1031 | |||
| 1032 | ;; Search for errors. | ||
| 1033 | (goto-char (point-min)) | ||
| 1034 | (setq err (re-search-forward tramp-smb-errors nil t))) | ||
| 1035 | |||
| 1036 | ;; Add output to debug buffer if appropriate. | ||
| 1037 | (when tramp-debug-buffer | ||
| 1038 | (append-to-buffer | ||
| 1039 | (tramp-get-debug-buffer nil tramp-smb-method user host) | ||
| 1040 | (point-min) (point-max)) | ||
| 1041 | (when (and (not found) tramp-smb-process-running) | ||
| 1042 | (save-excursion | ||
| 1043 | (set-buffer | ||
| 1044 | (tramp-get-debug-buffer nil tramp-smb-method user host)) | ||
| 1045 | (goto-char (point-max)) | ||
| 1046 | (insert (format "[[Remote prompt `%s' not found]]\n" | ||
| 1047 | tramp-smb-prompt))))) | ||
| 1048 | (goto-char (point-min)) | 1027 | (goto-char (point-min)) |
| 1049 | ;; Return value is whether no error message has appeared. | 1028 | (setq found (re-search-forward tramp-smb-prompt nil t)) |
| 1050 | (not err)))) | 1029 | |
| 1030 | ;; Search for errors. | ||
| 1031 | (goto-char (point-min)) | ||
| 1032 | (setq err (re-search-forward tramp-smb-errors nil t))) | ||
| 1033 | |||
| 1034 | ;; Add output to debug buffer if appropriate. | ||
| 1035 | (when tramp-debug-buffer | ||
| 1036 | (append-to-buffer | ||
| 1037 | (tramp-get-debug-buffer nil tramp-smb-method user host) | ||
| 1038 | (point-min) (point-max))) | ||
| 1039 | |||
| 1040 | ;; Return value is whether no error message has appeared. | ||
| 1041 | (not err))) | ||
| 1051 | 1042 | ||
| 1052 | 1043 | ||
| 1053 | ;; Snarfed code from time-date.el and parse-time.el | 1044 | ;; Snarfed code from time-date.el and parse-time.el |
| @@ -1125,8 +1116,6 @@ Return the difference in the format of a time value." | |||
| 1125 | ;; * Provide a local smb.conf. The default one might not be readable. | 1116 | ;; * Provide a local smb.conf. The default one might not be readable. |
| 1126 | ;; * Error handling in case password is wrong. | 1117 | ;; * Error handling in case password is wrong. |
| 1127 | ;; * Read password from "~/.netrc". | 1118 | ;; * Read password from "~/.netrc". |
| 1128 | ;; * Use different buffers for different shares. By this, the password | ||
| 1129 | ;; won't be requested again when changing shares on the same host. | ||
| 1130 | ;; * Return more comprehensive file permission string. Think whether it is | 1119 | ;; * Return more comprehensive file permission string. Think whether it is |
| 1131 | ;; possible to implement `set-file-modes'. | 1120 | ;; possible to implement `set-file-modes'. |
| 1132 | ;; * Handle WILDCARD and FULL-DIRECTORY-P in | 1121 | ;; * Handle WILDCARD and FULL-DIRECTORY-P in |
diff --git a/lisp/net/tramp.el b/lisp/net/tramp.el index 949d76364fc..cd6ed337927 100644 --- a/lisp/net/tramp.el +++ b/lisp/net/tramp.el | |||
| @@ -1,7 +1,7 @@ | |||
| 1 | ;;; -*- mode: Emacs-Lisp; coding: iso-2022-7bit; -*- | 1 | ;;; -*- mode: Emacs-Lisp; coding: iso-2022-7bit; -*- |
| 2 | ;;; tramp.el --- Transparent Remote Access, Multiple Protocol | 2 | ;;; tramp.el --- Transparent Remote Access, Multiple Protocol |
| 3 | 3 | ||
| 4 | ;; Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc. | 4 | ;; Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc. |
| 5 | 5 | ||
| 6 | ;; Author: kai.grossjohann@gmx.net | 6 | ;; Author: kai.grossjohann@gmx.net |
| 7 | ;; Keywords: comm, processes | 7 | ;; Keywords: comm, processes |
| @@ -72,6 +72,12 @@ | |||
| 72 | 72 | ||
| 73 | (require 'timer) | 73 | (require 'timer) |
| 74 | (require 'format-spec) ;from Gnus 5.8, also in tar ball | 74 | (require 'format-spec) ;from Gnus 5.8, also in tar ball |
| 75 | ;; As long as password.el is not part of (X)Emacs, it shouldn't | ||
| 76 | ;; be mandatory | ||
| 77 | (if (featurep 'xemacs) | ||
| 78 | (load "password" 'noerror) | ||
| 79 | (require 'password nil 'noerror)) ;from No Gnus, also in tar ball | ||
| 80 | |||
| 75 | ;; The explicit check is not necessary in Emacs, which provides the | 81 | ;; The explicit check is not necessary in Emacs, which provides the |
| 76 | ;; feature even if implemented in C, but it appears to be necessary | 82 | ;; feature even if implemented in C, but it appears to be necessary |
| 77 | ;; in XEmacs. | 83 | ;; in XEmacs. |
| @@ -628,14 +634,18 @@ See `tramp-methods' for a list of possibilities for METHOD." | |||
| 628 | ;; Default values for non-Unices seeked | 634 | ;; Default values for non-Unices seeked |
| 629 | (defconst tramp-completion-function-alist-ssh | 635 | (defconst tramp-completion-function-alist-ssh |
| 630 | (unless (memq system-type '(windows-nt)) | 636 | (unless (memq system-type '(windows-nt)) |
| 631 | '((tramp-parse-rhosts "/etc/hosts.equiv") | 637 | '((tramp-parse-rhosts "/etc/hosts.equiv") |
| 632 | (tramp-parse-rhosts "/etc/shosts.equiv") | 638 | (tramp-parse-rhosts "/etc/shosts.equiv") |
| 633 | (tramp-parse-shosts "/etc/ssh_known_hosts") | 639 | (tramp-parse-shosts "/etc/ssh_known_hosts") |
| 634 | (tramp-parse-sconfig "/etc/ssh_config") | 640 | (tramp-parse-sconfig "/etc/ssh_config") |
| 635 | (tramp-parse-rhosts "~/.rhosts") | 641 | (tramp-parse-shostkeys "/etc/ssh2/hostkeys") |
| 636 | (tramp-parse-rhosts "~/.shosts") | 642 | (tramp-parse-sknownhosts "/etc/ssh2/knownhosts") |
| 637 | (tramp-parse-shosts "~/.ssh/known_hosts") | 643 | (tramp-parse-rhosts "~/.rhosts") |
| 638 | (tramp-parse-sconfig "~/.ssh/config"))) | 644 | (tramp-parse-rhosts "~/.shosts") |
| 645 | (tramp-parse-shosts "~/.ssh/known_hosts") | ||
| 646 | (tramp-parse-sconfig "~/.ssh/config") | ||
| 647 | (tramp-parse-shostkeys "~/.ssh2/hostkeys") | ||
| 648 | (tramp-parse-sknownhosts "~/.ssh2/knownhosts"))) | ||
| 639 | "Default list of (FUNCTION FILE) pairs to be examined for ssh methods.") | 649 | "Default list of (FUNCTION FILE) pairs to be examined for ssh methods.") |
| 640 | 650 | ||
| 641 | ;; Default values for non-Unices seeked | 651 | ;; Default values for non-Unices seeked |
| @@ -650,53 +660,79 @@ See `tramp-methods' for a list of possibilities for METHOD." | |||
| 650 | '((tramp-parse-passwd "/etc/passwd"))) | 660 | '((tramp-parse-passwd "/etc/passwd"))) |
| 651 | "Default list of (FUNCTION FILE) pairs to be examined for su methods.") | 661 | "Default list of (FUNCTION FILE) pairs to be examined for su methods.") |
| 652 | 662 | ||
| 653 | (defcustom tramp-completion-function-alist | 663 | (defvar tramp-completion-function-alist nil |
| 654 | (list (cons "rcp" tramp-completion-function-alist-rsh) | ||
| 655 | (cons "scp" tramp-completion-function-alist-ssh) | ||
| 656 | (cons "scp1" tramp-completion-function-alist-ssh) | ||
| 657 | (cons "scp2" tramp-completion-function-alist-ssh) | ||
| 658 | (cons "scp1_old" tramp-completion-function-alist-ssh) | ||
| 659 | (cons "scp2_old" tramp-completion-function-alist-ssh) | ||
| 660 | (cons "rsync" tramp-completion-function-alist-rsh) | ||
| 661 | (cons "remcp" tramp-completion-function-alist-rsh) | ||
| 662 | (cons "rsh" tramp-completion-function-alist-rsh) | ||
| 663 | (cons "ssh" tramp-completion-function-alist-ssh) | ||
| 664 | (cons "ssh1" tramp-completion-function-alist-ssh) | ||
| 665 | (cons "ssh2" tramp-completion-function-alist-ssh) | ||
| 666 | (cons "ssh1_old" tramp-completion-function-alist-ssh) | ||
| 667 | (cons "ssh2_old" tramp-completion-function-alist-ssh) | ||
| 668 | (cons "remsh" tramp-completion-function-alist-rsh) | ||
| 669 | (cons "telnet" tramp-completion-function-alist-telnet) | ||
| 670 | (cons "su" tramp-completion-function-alist-su) | ||
| 671 | (cons "sudo" tramp-completion-function-alist-su) | ||
| 672 | (cons "multi" nil) | ||
| 673 | (cons "scpx" tramp-completion-function-alist-ssh) | ||
| 674 | (cons "sshx" tramp-completion-function-alist-ssh) | ||
| 675 | (cons "krlogin" tramp-completion-function-alist-rsh) | ||
| 676 | (cons "plink" tramp-completion-function-alist-ssh) | ||
| 677 | (cons "plink1" tramp-completion-function-alist-ssh) | ||
| 678 | (cons "pscp" tramp-completion-function-alist-ssh) | ||
| 679 | (cons "fcp" tramp-completion-function-alist-ssh) | ||
| 680 | ) | ||
| 681 | "*Alist of methods for remote files. | 664 | "*Alist of methods for remote files. |
| 682 | This is a list of entries of the form (NAME PAIR1 PAIR2 ...). | 665 | This is a list of entries of the form (NAME PAIR1 PAIR2 ...). |
| 683 | Each NAME stands for a remote access method. Each PAIR is of the form | 666 | Each NAME stands for a remote access method. Each PAIR is of the form |
| 684 | \(FUNCTION FILE). FUNCTION is responsible to extract user names and host | 667 | \(FUNCTION FILE). FUNCTION is responsible to extract user names and host |
| 685 | names from FILE for completion. The following predefined FUNCTIONs exists: | 668 | names from FILE for completion. The following predefined FUNCTIONs exists: |
| 686 | 669 | ||
| 687 | * `tramp-parse-rhosts' for \"~/.rhosts\" like files, | 670 | * `tramp-parse-rhosts' for \"~/.rhosts\" like files, |
| 688 | * `tramp-parse-shosts' for \"~/.ssh/known_hosts\" like files, | 671 | * `tramp-parse-shosts' for \"~/.ssh/known_hosts\" like files, |
| 689 | * `tramp-parse-sconfig' for \"~/.ssh/config\" like files, | 672 | * `tramp-parse-sconfig' for \"~/.ssh/config\" like files, |
| 690 | * `tramp-parse-hosts' for \"/etc/hosts\" like files, and | 673 | * `tramp-parse-shostkeys' for \"~/.ssh2/hostkeys/*\" like files, |
| 691 | * `tramp-parse-passwd' for \"/etc/passwd\" like files. | 674 | * `tramp-parse-sknownhosts' for \"~/.ssh2/knownhosts/*\" like files, |
| 692 | * `tramp-parse-netrc' for \"~/.netrc\" like files. | 675 | * `tramp-parse-hosts' for \"/etc/hosts\" like files, |
| 693 | 676 | * `tramp-parse-passwd' for \"/etc/passwd\" like files. | |
| 694 | FUNCTION can also see a customer defined function. For more details see | 677 | * `tramp-parse-netrc' for \"~/.netrc\" like files. |
| 695 | the info pages." | 678 | |
| 696 | :group 'tramp | 679 | FUNCTION can also be a customer defined function. For more details see |
| 697 | :type '(repeat | 680 | the info pages.") |
| 698 | (cons string | 681 | |
| 699 | (choice (const nil) (repeat (list function file)))))) | 682 | (eval-after-load "tramp" |
| 683 | '(progn | ||
| 684 | (tramp-set-completion-function | ||
| 685 | "rcp" tramp-completion-function-alist-rsh) | ||
| 686 | (tramp-set-completion-function | ||
| 687 | "scp" tramp-completion-function-alist-ssh) | ||
| 688 | (tramp-set-completion-function | ||
| 689 | "scp1" tramp-completion-function-alist-ssh) | ||
| 690 | (tramp-set-completion-function | ||
| 691 | "scp2" tramp-completion-function-alist-ssh) | ||
| 692 | (tramp-set-completion-function | ||
| 693 | "scp1_old" tramp-completion-function-alist-ssh) | ||
| 694 | (tramp-set-completion-function | ||
| 695 | "scp2_old" tramp-completion-function-alist-ssh) | ||
| 696 | (tramp-set-completion-function | ||
| 697 | "rsync" tramp-completion-function-alist-rsh) | ||
| 698 | (tramp-set-completion-function | ||
| 699 | "remcp" tramp-completion-function-alist-rsh) | ||
| 700 | (tramp-set-completion-function | ||
| 701 | "rsh" tramp-completion-function-alist-rsh) | ||
| 702 | (tramp-set-completion-function | ||
| 703 | "ssh" tramp-completion-function-alist-ssh) | ||
| 704 | (tramp-set-completion-function | ||
| 705 | "ssh1" tramp-completion-function-alist-ssh) | ||
| 706 | (tramp-set-completion-function | ||
| 707 | "ssh2" tramp-completion-function-alist-ssh) | ||
| 708 | (tramp-set-completion-function | ||
| 709 | "ssh1_old" tramp-completion-function-alist-ssh) | ||
| 710 | (tramp-set-completion-function | ||
| 711 | "ssh2_old" tramp-completion-function-alist-ssh) | ||
| 712 | (tramp-set-completion-function | ||
| 713 | "remsh" tramp-completion-function-alist-rsh) | ||
| 714 | (tramp-set-completion-function | ||
| 715 | "telnet" tramp-completion-function-alist-telnet) | ||
| 716 | (tramp-set-completion-function | ||
| 717 | "su" tramp-completion-function-alist-su) | ||
| 718 | (tramp-set-completion-function | ||
| 719 | "sudo" tramp-completion-function-alist-su) | ||
| 720 | (tramp-set-completion-function | ||
| 721 | "multi" nil) | ||
| 722 | (tramp-set-completion-function | ||
| 723 | "scpx" tramp-completion-function-alist-ssh) | ||
| 724 | (tramp-set-completion-function | ||
| 725 | "sshx" tramp-completion-function-alist-ssh) | ||
| 726 | (tramp-set-completion-function | ||
| 727 | "krlogin" tramp-completion-function-alist-rsh) | ||
| 728 | (tramp-set-completion-function | ||
| 729 | "plink" tramp-completion-function-alist-ssh) | ||
| 730 | (tramp-set-completion-function | ||
| 731 | "plink1" tramp-completion-function-alist-ssh) | ||
| 732 | (tramp-set-completion-function | ||
| 733 | "pscp" tramp-completion-function-alist-ssh) | ||
| 734 | (tramp-set-completion-function | ||
| 735 | "fcp" tramp-completion-function-alist-ssh))) | ||
| 700 | 736 | ||
| 701 | (defcustom tramp-rsh-end-of-line "\n" | 737 | (defcustom tramp-rsh-end-of-line "\n" |
| 702 | "*String used for end of line in rsh connections. | 738 | "*String used for end of line in rsh connections. |
| @@ -1267,6 +1303,17 @@ this variable to be set as well." | |||
| 1267 | :group 'tramp | 1303 | :group 'tramp |
| 1268 | :type '(choice (const nil) integer)) | 1304 | :type '(choice (const nil) integer)) |
| 1269 | 1305 | ||
| 1306 | ;; Logging in to a remote host normally requires obtaining a pty. But | ||
| 1307 | ;; Emacs on MacOS X has process-connection-type set to nil by default, | ||
| 1308 | ;; so on those systems Tramp doesn't obtain a pty. Here, we allow | ||
| 1309 | ;; for an override of the system default. | ||
| 1310 | (defcustom tramp-process-connection-type t | ||
| 1311 | "Overrides `process-connection-type' for connections from Tramp. | ||
| 1312 | Tramp binds process-connection-type to the value given here before | ||
| 1313 | opening a connection to a remote host." | ||
| 1314 | :group 'tramp | ||
| 1315 | :type '(choice (const nil) (const t) (const pty))) | ||
| 1316 | |||
| 1270 | ;;; Internal Variables: | 1317 | ;;; Internal Variables: |
| 1271 | 1318 | ||
| 1272 | (defvar tramp-buffer-file-attributes nil | 1319 | (defvar tramp-buffer-file-attributes nil |
| @@ -1638,6 +1685,7 @@ on the FILENAME argument, even if VISIT was a string.") | |||
| 1638 | (insert-file-contents . tramp-handle-insert-file-contents) | 1685 | (insert-file-contents . tramp-handle-insert-file-contents) |
| 1639 | (write-region . tramp-handle-write-region) | 1686 | (write-region . tramp-handle-write-region) |
| 1640 | (unhandled-file-name-directory . tramp-handle-unhandled-file-name-directory) | 1687 | (unhandled-file-name-directory . tramp-handle-unhandled-file-name-directory) |
| 1688 | (dired-compress-file . tramp-handle-dired-compress-file) | ||
| 1641 | (dired-call-process . tramp-handle-dired-call-process) | 1689 | (dired-call-process . tramp-handle-dired-call-process) |
| 1642 | (dired-recursive-delete-directory | 1690 | (dired-recursive-delete-directory |
| 1643 | . tramp-handle-dired-recursive-delete-directory) | 1691 | . tramp-handle-dired-recursive-delete-directory) |
| @@ -1761,15 +1809,30 @@ Example: | |||
| 1761 | '((tramp-parse-sconfig \"/etc/ssh_config\") | 1809 | '((tramp-parse-sconfig \"/etc/ssh_config\") |
| 1762 | (tramp-parse-sconfig \"~/.ssh/config\")))" | 1810 | (tramp-parse-sconfig \"~/.ssh/config\")))" |
| 1763 | 1811 | ||
| 1764 | (let ((v (cdr (assoc method tramp-completion-function-alist)))) | 1812 | (let ((r function-list) |
| 1765 | (if v (setcdr v function-list) | 1813 | (v function-list)) |
| 1814 | (setq tramp-completion-function-alist | ||
| 1815 | (delete (assoc method tramp-completion-function-alist) | ||
| 1816 | tramp-completion-function-alist)) | ||
| 1817 | |||
| 1818 | (while v | ||
| 1819 | ;; Remove double entries | ||
| 1820 | (when (member (car v) (cdr v)) | ||
| 1821 | (setcdr v (delete (car v) (cdr v)))) | ||
| 1822 | ;; Check for function and file | ||
| 1823 | (unless (and (functionp (nth 0 (car v))) | ||
| 1824 | (file-exists-p (nth 1 (car v)))) | ||
| 1825 | (setq r (delete (car v) r))) | ||
| 1826 | (setq v (cdr v))) | ||
| 1827 | |||
| 1828 | (when r | ||
| 1766 | (add-to-list 'tramp-completion-function-alist | 1829 | (add-to-list 'tramp-completion-function-alist |
| 1767 | (cons method function-list))))) | 1830 | (cons method r))))) |
| 1768 | 1831 | ||
| 1769 | (defun tramp-get-completion-function (method) | 1832 | (defun tramp-get-completion-function (method) |
| 1770 | "Returns list of completion functions for METHOD. | 1833 | "Returns list of completion functions for METHOD. |
| 1771 | For definition of that list see `tramp-set-completion-function'." | 1834 | For definition of that list see `tramp-set-completion-function'." |
| 1772 | (cdr (assoc method tramp-completion-function-alist))) | 1835 | (cdr (assoc method tramp-completion-function-alist))) |
| 1773 | 1836 | ||
| 1774 | ;;; File Name Handler Functions: | 1837 | ;;; File Name Handler Functions: |
| 1775 | 1838 | ||
| @@ -2586,44 +2649,86 @@ and `rename'. FILENAME and NEWNAME must be absolute file names." | |||
| 2586 | (signal 'file-already-exists | 2649 | (signal 'file-already-exists |
| 2587 | (list newname)))) | 2650 | (list newname)))) |
| 2588 | (let ((t1 (tramp-tramp-file-p filename)) | 2651 | (let ((t1 (tramp-tramp-file-p filename)) |
| 2589 | (t2 (tramp-tramp-file-p newname))) | 2652 | (t2 (tramp-tramp-file-p newname)) |
| 2653 | v1-multi-method v1-method v1-user v1-host v1-localname | ||
| 2654 | v2-multi-method v2-method v2-user v2-host v2-localname) | ||
| 2655 | |||
| 2590 | ;; Check which ones of source and target are Tramp files. | 2656 | ;; Check which ones of source and target are Tramp files. |
| 2657 | ;; We cannot invoke `with-parsed-tramp-file-name'; | ||
| 2658 | ;; it fails if the file isn't a Tramp file name. | ||
| 2659 | (if t1 | ||
| 2660 | (with-parsed-tramp-file-name filename l | ||
| 2661 | (setq v1-multi-method l-multi-method | ||
| 2662 | v1-method l-method | ||
| 2663 | v1-user l-user | ||
| 2664 | v1-host l-host | ||
| 2665 | v1-localname l-localname)) | ||
| 2666 | (setq v1-localname filename)) | ||
| 2667 | (if t2 | ||
| 2668 | (with-parsed-tramp-file-name newname l | ||
| 2669 | (setq v2-multi-method l-multi-method | ||
| 2670 | v2-method l-method | ||
| 2671 | v2-user l-user | ||
| 2672 | v2-host l-host | ||
| 2673 | v2-localname l-localname)) | ||
| 2674 | (setq v2-localname newname)) | ||
| 2675 | |||
| 2591 | (cond | 2676 | (cond |
| 2677 | ;; Both are Tramp files. | ||
| 2592 | ((and t1 t2) | 2678 | ((and t1 t2) |
| 2593 | ;; Both are Tramp files. | 2679 | (cond |
| 2594 | (with-parsed-tramp-file-name filename v1 | 2680 | ;; Shortcut: if method, host, user are the same for both |
| 2595 | (with-parsed-tramp-file-name newname v2 | 2681 | ;; files, we invoke `cp' or `mv' on the remote host |
| 2596 | ;; Check if we can use a shortcut. | 2682 | ;; directly. |
| 2597 | (if (and (equal v1-multi-method v2-multi-method) | 2683 | ((and (equal v1-multi-method v2-multi-method) |
| 2598 | (equal v1-method v2-method) | 2684 | (equal v1-method v2-method) |
| 2599 | (equal v1-host v2-host) | 2685 | (equal v1-user v2-user) |
| 2600 | (equal v1-user v2-user)) | 2686 | (equal v1-host v2-host)) |
| 2601 | ;; Shortcut: if method, host, user are the same for both | 2687 | (tramp-do-copy-or-rename-file-directly |
| 2602 | ;; files, we invoke `cp' or `mv' on the remote host | 2688 | op v1-multi-method v1-method v1-user v1-host |
| 2603 | ;; directly. | 2689 | v1-localname v2-localname keep-date)) |
| 2604 | (tramp-do-copy-or-rename-file-directly | 2690 | ;; If both source and target are Tramp files, |
| 2605 | op v1-multi-method v1-method v1-user v1-host | 2691 | ;; both are using the same copy-program, then we |
| 2606 | v1-localname v2-localname keep-date) | 2692 | ;; can invoke rcp directly. Note that |
| 2607 | ;; The shortcut was not possible. So we copy the | 2693 | ;; default-directory should point to a local |
| 2608 | ;; file first. If the operation was `rename', we go | 2694 | ;; directory if we want to invoke rcp. |
| 2609 | ;; back and delete the original file (if the copy was | 2695 | ((and (not v1-multi-method) |
| 2610 | ;; successful). The approach is simple-minded: we | 2696 | (not v2-multi-method) |
| 2611 | ;; create a new buffer, insert the contents of the | 2697 | (equal v1-method v2-method) |
| 2612 | ;; source file into it, then write out the buffer to | 2698 | (tramp-method-out-of-band-p |
| 2613 | ;; the target file. The advantage is that it doesn't | 2699 | v1-multi-method v1-method v1-user v1-host) |
| 2614 | ;; matter which filename handlers are used for the | 2700 | (not (string-match "\\([^#]*\\)#\\(.*\\)" v1-host)) |
| 2615 | ;; source and target file. | 2701 | (not (string-match "\\([^#]*\\)#\\(.*\\)" v2-host))) |
| 2616 | 2702 | (tramp-do-copy-or-rename-file-out-of-band | |
| 2617 | ;; CCC: If both source and target are Tramp files, | 2703 | op filename newname keep-date)) |
| 2618 | ;; and both are using the same copy-program, then we | 2704 | ;; No shortcut was possible. So we copy the |
| 2619 | ;; can invoke rcp directly. Note that | 2705 | ;; file first. If the operation was `rename', we go |
| 2620 | ;; default-directory should point to a local | 2706 | ;; back and delete the original file (if the copy was |
| 2621 | ;; directory if we want to invoke rcp. | 2707 | ;; successful). The approach is simple-minded: we |
| 2622 | (tramp-do-copy-or-rename-via-buffer | 2708 | ;; create a new buffer, insert the contents of the |
| 2623 | op filename newname keep-date))))) | 2709 | ;; source file into it, then write out the buffer to |
| 2710 | ;; the target file. The advantage is that it doesn't | ||
| 2711 | ;; matter which filename handlers are used for the | ||
| 2712 | ;; source and target file. | ||
| 2713 | (t | ||
| 2714 | (tramp-do-copy-or-rename-via-buffer | ||
| 2715 | op filename newname keep-date)))) | ||
| 2716 | |||
| 2717 | ;; One file is a Tramp file, the other one is local. | ||
| 2624 | ((or t1 t2) | 2718 | ((or t1 t2) |
| 2625 | ;; Use the generic method via a Tramp buffer. | 2719 | ;; If the Tramp file has an out-of-band method, the corresponding |
| 2626 | (tramp-do-copy-or-rename-via-buffer op filename newname keep-date)) | 2720 | ;; copy-program can be invoked. |
| 2721 | (if (and (not v1-multi-method) | ||
| 2722 | (not v2-multi-method) | ||
| 2723 | (or (tramp-method-out-of-band-p | ||
| 2724 | v1-multi-method v1-method v1-user v1-host) | ||
| 2725 | (tramp-method-out-of-band-p | ||
| 2726 | v2-multi-method v2-method v2-user v2-host))) | ||
| 2727 | (tramp-do-copy-or-rename-file-out-of-band | ||
| 2728 | op filename newname keep-date) | ||
| 2729 | ;; Use the generic method via a Tramp buffer. | ||
| 2730 | (tramp-do-copy-or-rename-via-buffer op filename newname keep-date))) | ||
| 2731 | |||
| 2627 | (t | 2732 | (t |
| 2628 | ;; One of them must be a Tramp file. | 2733 | ;; One of them must be a Tramp file. |
| 2629 | (error "Tramp implementation says this cannot happen"))))) | 2734 | (error "Tramp implementation says this cannot happen"))))) |
| @@ -2634,8 +2739,9 @@ and `rename'. FILENAME and NEWNAME must be absolute file names." | |||
| 2634 | First arg OP is either `copy' or `rename' and indicates the operation. | 2739 | First arg OP is either `copy' or `rename' and indicates the operation. |
| 2635 | FILENAME is the source file, NEWNAME the target file. | 2740 | FILENAME is the source file, NEWNAME the target file. |
| 2636 | KEEP-DATE is non-nil if NEWNAME should have the same timestamp as FILENAME." | 2741 | KEEP-DATE is non-nil if NEWNAME should have the same timestamp as FILENAME." |
| 2637 | (let ((trampbuf (get-buffer-create "*tramp output*"))) | 2742 | (let ((trampbuf (get-buffer-create "*tramp output*")) |
| 2638 | (when keep-date | 2743 | (modtime (nth 5 (file-attributes filename)))) |
| 2744 | (when (and keep-date (or (null modtime) (equal modtime '(0 0)))) | ||
| 2639 | (tramp-message | 2745 | (tramp-message |
| 2640 | 1 (concat "Warning: cannot preserve file time stamp" | 2746 | 1 (concat "Warning: cannot preserve file time stamp" |
| 2641 | " with inline copying across machines"))) | 2747 | " with inline copying across machines"))) |
| @@ -2646,7 +2752,12 @@ KEEP-DATE is non-nil if NEWNAME should have the same timestamp as FILENAME." | |||
| 2646 | ;; `jka-compr-inhibit' to t. | 2752 | ;; `jka-compr-inhibit' to t. |
| 2647 | (let ((coding-system-for-write 'binary) | 2753 | (let ((coding-system-for-write 'binary) |
| 2648 | (jka-compr-inhibit t)) | 2754 | (jka-compr-inhibit t)) |
| 2649 | (write-region (point-min) (point-max) newname))) | 2755 | (write-region (point-min) (point-max) newname)) |
| 2756 | ;; KEEP-DATE handling. | ||
| 2757 | (when (and keep-date | ||
| 2758 | (not (null modtime)) | ||
| 2759 | (not (equal modtime '(0 0)))) | ||
| 2760 | (tramp-touch newname modtime))) | ||
| 2650 | ;; If the operation was `rename', delete the original file. | 2761 | ;; If the operation was `rename', delete the original file. |
| 2651 | (unless (eq op 'copy) | 2762 | (unless (eq op 'copy) |
| 2652 | (delete-file filename)))) | 2763 | (delete-file filename)))) |
| @@ -2676,13 +2787,112 @@ If KEEP-DATE is non-nil, preserve the time stamp when copying." | |||
| 2676 | "Copying directly failed, see buffer `%s' for details." | 2787 | "Copying directly failed, see buffer `%s' for details." |
| 2677 | (buffer-name))))) | 2788 | (buffer-name))))) |
| 2678 | 2789 | ||
| 2679 | (defun tramp-do-copy-or-rename-file-one-local | 2790 | (defun tramp-do-copy-or-rename-file-out-of-band (op filename newname keep-date) |
| 2680 | (op filename newname keep-date) | ||
| 2681 | "Invoke rcp program to copy. | 2791 | "Invoke rcp program to copy. |
| 2682 | One of FILENAME and NEWNAME must be a Tramp name, the other must | 2792 | One of FILENAME and NEWNAME must be a Tramp name, the other must |
| 2683 | be a local filename. The method used must be an out-of-band method." | 2793 | be a local filename. The method used must be an out-of-band method." |
| 2684 | ;; CCC | 2794 | (let ((trampbuf (get-buffer-create "*tramp output*")) |
| 2685 | ) | 2795 | (t1 (tramp-tramp-file-p filename)) |
| 2796 | (t2 (tramp-tramp-file-p newname)) | ||
| 2797 | v1-multi-method v1-method v1-user v1-host v1-localname | ||
| 2798 | v2-multi-method v2-method v2-user v2-host v2-localname | ||
| 2799 | method copy-program copy-args source target) | ||
| 2800 | |||
| 2801 | ;; Check which ones of source and target are Tramp files. | ||
| 2802 | ;; We cannot invoke `with-parsed-tramp-file-name'; | ||
| 2803 | ;; it fails if the file isn't a Tramp file name. | ||
| 2804 | (if t1 | ||
| 2805 | (with-parsed-tramp-file-name filename l | ||
| 2806 | (setq v1-multi-method l-multi-method | ||
| 2807 | v1-method l-method | ||
| 2808 | v1-user l-user | ||
| 2809 | v1-host l-host | ||
| 2810 | v1-localname l-localname | ||
| 2811 | method (tramp-find-method | ||
| 2812 | v1-multi-method v1-method v1-user v1-host) | ||
| 2813 | copy-program (tramp-get-method-parameter | ||
| 2814 | v1-multi-method method | ||
| 2815 | v1-user v1-host 'tramp-copy-program) | ||
| 2816 | copy-args (tramp-get-method-parameter | ||
| 2817 | v1-multi-method method | ||
| 2818 | v1-user v1-host 'tramp-copy-args))) | ||
| 2819 | (setq v1-localname filename)) | ||
| 2820 | |||
| 2821 | (if t2 | ||
| 2822 | (with-parsed-tramp-file-name newname l | ||
| 2823 | (setq v2-multi-method l-multi-method | ||
| 2824 | v2-method l-method | ||
| 2825 | v2-user l-user | ||
| 2826 | v2-host l-host | ||
| 2827 | v2-localname l-localname | ||
| 2828 | method (tramp-find-method | ||
| 2829 | v2-multi-method v2-method v2-user v2-host) | ||
| 2830 | copy-program (tramp-get-method-parameter | ||
| 2831 | v2-multi-method method | ||
| 2832 | v2-user v2-host 'tramp-copy-program) | ||
| 2833 | copy-args (tramp-get-method-parameter | ||
| 2834 | v2-multi-method method | ||
| 2835 | v2-user v2-host 'tramp-copy-args))) | ||
| 2836 | (setq v2-localname newname)) | ||
| 2837 | |||
| 2838 | ;; The following should be changed. We need a more general | ||
| 2839 | ;; mechanism to parse extra host args. | ||
| 2840 | (if (not t1) | ||
| 2841 | (setq source v1-localname) | ||
| 2842 | (when (string-match "\\([^#]*\\)#\\(.*\\)" v1-host) | ||
| 2843 | (setq copy-args (cons "-P" (cons (match-string 2 v1-host) copy-args))) | ||
| 2844 | (setq v1-host (match-string 1 v1-host))) | ||
| 2845 | (setq source | ||
| 2846 | (tramp-make-copy-program-file-name | ||
| 2847 | v1-user v1-host | ||
| 2848 | (tramp-shell-quote-argument v1-localname)))) | ||
| 2849 | |||
| 2850 | (if (not t2) | ||
| 2851 | (setq target v2-localname) | ||
| 2852 | (when (string-match "\\([^#]*\\)#\\(.*\\)" v2-host) | ||
| 2853 | (setq copy-args (cons "-P" (cons (match-string 2 v2-host) copy-args))) | ||
| 2854 | (setq v2-host (match-string 1 v2-host))) | ||
| 2855 | (setq target | ||
| 2856 | (tramp-make-copy-program-file-name | ||
| 2857 | v2-user v2-host | ||
| 2858 | (tramp-shell-quote-argument v2-localname)))) | ||
| 2859 | |||
| 2860 | ;; Handle keep-date argument | ||
| 2861 | (when keep-date | ||
| 2862 | (if t1 | ||
| 2863 | (setq copy-args | ||
| 2864 | (cons (tramp-get-method-parameter | ||
| 2865 | v1-multi-method method | ||
| 2866 | v1-user v1-host 'tramp-copy-keep-date-arg) | ||
| 2867 | copy-args)) | ||
| 2868 | (setq copy-args | ||
| 2869 | (cons (tramp-get-method-parameter | ||
| 2870 | v2-multi-method method | ||
| 2871 | v2-user v2-host 'tramp-copy-keep-date-arg) | ||
| 2872 | copy-args)))) | ||
| 2873 | |||
| 2874 | (setq copy-args (append copy-args (list source target))) | ||
| 2875 | |||
| 2876 | ;; Use rcp-like program for file transfer. | ||
| 2877 | (tramp-message | ||
| 2878 | 5 "Transferring %s to file %s..." filename newname) | ||
| 2879 | (save-excursion (set-buffer trampbuf) (erase-buffer)) | ||
| 2880 | (unless (equal | ||
| 2881 | 0 | ||
| 2882 | (apply #'call-process copy-program | ||
| 2883 | nil trampbuf nil copy-args)) | ||
| 2884 | (pop-to-buffer trampbuf) | ||
| 2885 | (error | ||
| 2886 | (concat | ||
| 2887 | "tramp-do-copy-or-rename-file-out-of-band: `%s' didn't work, " | ||
| 2888 | "see buffer `%s' for details") | ||
| 2889 | copy-program trampbuf)) | ||
| 2890 | (tramp-message | ||
| 2891 | 5 "Transferring %s to file %s...done" filename newname) | ||
| 2892 | |||
| 2893 | ;; If the operation was `rename', delete the original file. | ||
| 2894 | (unless (eq op 'copy) | ||
| 2895 | (delete-file filename)))) | ||
| 2686 | 2896 | ||
| 2687 | ;; mkdir | 2897 | ;; mkdir |
| 2688 | (defun tramp-handle-make-directory (dir &optional parents) | 2898 | (defun tramp-handle-make-directory (dir &optional parents) |
| @@ -2745,7 +2955,6 @@ This is like `dired-recursive-delete-directory' for tramp files." | |||
| 2745 | (and (tramp-handle-file-exists-p filename) | 2955 | (and (tramp-handle-file-exists-p filename) |
| 2746 | (error "Failed to recusively delete %s" filename)))) | 2956 | (error "Failed to recusively delete %s" filename)))) |
| 2747 | 2957 | ||
| 2748 | |||
| 2749 | (defun tramp-handle-dired-call-process (program discard &rest arguments) | 2958 | (defun tramp-handle-dired-call-process (program discard &rest arguments) |
| 2750 | "Like `dired-call-process' for tramp files." | 2959 | "Like `dired-call-process' for tramp files." |
| 2751 | (with-parsed-tramp-file-name default-directory nil | 2960 | (with-parsed-tramp-file-name default-directory nil |
| @@ -2767,6 +2976,59 @@ This is like `dired-recursive-delete-directory' for tramp files." | |||
| 2767 | (tramp-send-command-and-check multi-method method user host nil) | 2976 | (tramp-send-command-and-check multi-method method user host nil) |
| 2768 | (tramp-send-command multi-method method user host "cd") | 2977 | (tramp-send-command multi-method method user host "cd") |
| 2769 | (tramp-wait-for-output))))) | 2978 | (tramp-wait-for-output))))) |
| 2979 | |||
| 2980 | (defun tramp-handle-dired-compress-file (file &rest ok-flag) | ||
| 2981 | "Like `dired-compress-file' for tramp files." | ||
| 2982 | ;; OK-FLAG is valid for XEmacs only, but not implemented. | ||
| 2983 | ;; Code stolen mainly from dired-aux.el. | ||
| 2984 | (with-parsed-tramp-file-name file nil | ||
| 2985 | (save-excursion | ||
| 2986 | (let ((suffixes | ||
| 2987 | (if (not (featurep 'xemacs)) | ||
| 2988 | ;; Emacs case | ||
| 2989 | (symbol-value 'dired-compress-file-suffixes) | ||
| 2990 | ;; XEmacs has `dired-compression-method-alist', which is | ||
| 2991 | ;; transformed into `dired-compress-file-suffixes' structure. | ||
| 2992 | (mapcar | ||
| 2993 | '(lambda (x) | ||
| 2994 | (list (concat (regexp-quote (nth 1 x)) "\\'") | ||
| 2995 | nil | ||
| 2996 | (mapconcat 'identity (nth 3 x) " "))) | ||
| 2997 | (symbol-value 'dired-compression-method-alist)))) | ||
| 2998 | suffix) | ||
| 2999 | ;; See if any suffix rule matches this file name. | ||
| 3000 | (while suffixes | ||
| 3001 | (let (case-fold-search) | ||
| 3002 | (if (string-match (car (car suffixes)) localname) | ||
| 3003 | (setq suffix (car suffixes) suffixes nil)) | ||
| 3004 | (setq suffixes (cdr suffixes)))) | ||
| 3005 | |||
| 3006 | (cond ((file-symlink-p file) | ||
| 3007 | nil) | ||
| 3008 | ((and suffix (nth 2 suffix)) | ||
| 3009 | ;; We found an uncompression rule. | ||
| 3010 | (message "Uncompressing %s..." file) | ||
| 3011 | (when (zerop (tramp-send-command-and-check | ||
| 3012 | multi-method method user host | ||
| 3013 | (concat (nth 2 suffix) " " localname))) | ||
| 3014 | (message "Uncompressing %s...done" file) | ||
| 3015 | (dired-remove-file file) | ||
| 3016 | (string-match (car suffix) file) | ||
| 3017 | (concat (substring file 0 (match-beginning 0))))) | ||
| 3018 | (t | ||
| 3019 | ;; We don't recognize the file as compressed, so compress it. | ||
| 3020 | ;; Try gzip. | ||
| 3021 | (message "Compressing %s..." file) | ||
| 3022 | (when (zerop (tramp-send-command-and-check | ||
| 3023 | multi-method method user host | ||
| 3024 | (concat "gzip -f " localname))) | ||
| 3025 | (message "Compressing %s...done" file) | ||
| 3026 | (dired-remove-file file) | ||
| 3027 | (cond ((file-exists-p (concat file ".gz")) | ||
| 3028 | (concat file ".gz")) | ||
| 3029 | ((file-exists-p (concat file ".z")) | ||
| 3030 | (concat file ".z")) | ||
| 3031 | (t nil))))))))) | ||
| 2770 | 3032 | ||
| 2771 | ;; Pacify byte-compiler. The function is needed on XEmacs only. I'm | 3033 | ;; Pacify byte-compiler. The function is needed on XEmacs only. I'm |
| 2772 | ;; not sure at all that this is the right way to do it, but let's hope | 3034 | ;; not sure at all that this is the right way to do it, but let's hope |
| @@ -2961,17 +3223,40 @@ the result will be a local, non-Tramp, filename." | |||
| 2961 | 3223 | ||
| 2962 | ;; Remote commands. | 3224 | ;; Remote commands. |
| 2963 | 3225 | ||
| 3226 | (defvar tramp-async-proc nil | ||
| 3227 | "Global variable keeping asyncronous process object. | ||
| 3228 | Used in `tramp-handle-shell-command'") | ||
| 3229 | |||
| 2964 | (defun tramp-handle-shell-command (command &optional output-buffer error-buffer) | 3230 | (defun tramp-handle-shell-command (command &optional output-buffer error-buffer) |
| 2965 | "Like `shell-command' for tramp files. | 3231 | "Like `shell-command' for tramp files. |
| 2966 | This will break if COMMAND prints a newline, followed by the value of | 3232 | This will break if COMMAND prints a newline, followed by the value of |
| 2967 | `tramp-end-of-output', followed by another newline." | 3233 | `tramp-end-of-output', followed by another newline." |
| 3234 | ;; Asynchronous processes are far from being perfect. But it works at least | ||
| 3235 | ;; for `find-grep-dired' and `find-name-dired' in Emacs 21.4. | ||
| 2968 | (if (tramp-tramp-file-p default-directory) | 3236 | (if (tramp-tramp-file-p default-directory) |
| 2969 | (with-parsed-tramp-file-name default-directory nil | 3237 | (with-parsed-tramp-file-name default-directory nil |
| 2970 | (let (status) | 3238 | (let ((asynchronous (string-match "[ \t]*&[ \t]*\\'" command)) |
| 2971 | (when (string-match "&[ \t]*\\'" command) | 3239 | status) |
| 2972 | (error "Tramp doesn't grok asynchronous shell commands, yet")) | 3240 | (unless output-buffer |
| 2973 | ;; (when error-buffer | 3241 | (setq output-buffer |
| 2974 | ;; (error "Tramp doesn't grok optional third arg ERROR-BUFFER, yet")) | 3242 | (get-buffer-create |
| 3243 | (if asynchronous | ||
| 3244 | "*Async Shell Command*" | ||
| 3245 | "*Shell Command Output*"))) | ||
| 3246 | (set-buffer output-buffer) | ||
| 3247 | (erase-buffer)) | ||
| 3248 | (unless (bufferp output-buffer) | ||
| 3249 | (setq output-buffer (current-buffer))) | ||
| 3250 | (set-buffer output-buffer) | ||
| 3251 | ;; Tramp doesn't handle the asynchronous case by an asynchronous | ||
| 3252 | ;; process. Instead of, another asynchronous process is opened | ||
| 3253 | ;; which gets the output of the (synchronous) Tramp process | ||
| 3254 | ;; via process-filter. ERROR-BUFFER is disabled. | ||
| 3255 | (when asynchronous | ||
| 3256 | (setq command (substring command 0 (match-beginning 0)) | ||
| 3257 | error-buffer nil | ||
| 3258 | tramp-async-proc (start-process (buffer-name output-buffer) | ||
| 3259 | output-buffer "cat"))) | ||
| 2975 | (save-excursion | 3260 | (save-excursion |
| 2976 | (tramp-barf-unless-okay | 3261 | (tramp-barf-unless-okay |
| 2977 | multi-method method user host | 3262 | multi-method method user host |
| @@ -2979,23 +3264,39 @@ This will break if COMMAND prints a newline, followed by the value of | |||
| 2979 | nil 'file-error | 3264 | nil 'file-error |
| 2980 | "tramp-handle-shell-command: Couldn't `cd %s'" | 3265 | "tramp-handle-shell-command: Couldn't `cd %s'" |
| 2981 | (tramp-shell-quote-argument localname)) | 3266 | (tramp-shell-quote-argument localname)) |
| 3267 | ;; Define the process filter | ||
| 3268 | (when asynchronous | ||
| 3269 | (set-process-filter | ||
| 3270 | (get-buffer-process | ||
| 3271 | (tramp-get-buffer multi-method method user host)) | ||
| 3272 | '(lambda (process string) | ||
| 3273 | ;; Write the output into the Tramp Process | ||
| 3274 | (save-current-buffer | ||
| 3275 | (set-buffer (process-buffer process)) | ||
| 3276 | (goto-char (point-max)) | ||
| 3277 | (insert string)) | ||
| 3278 | ;; Hand-over output to asynchronous process. | ||
| 3279 | (let ((end | ||
| 3280 | (string-match | ||
| 3281 | (regexp-quote tramp-end-of-output) string))) | ||
| 3282 | (when end | ||
| 3283 | (setq string | ||
| 3284 | (substring string 0 (1- (match-beginning 0))))) | ||
| 3285 | (process-send-string tramp-async-proc string) | ||
| 3286 | (when end | ||
| 3287 | (set-process-filter process nil) | ||
| 3288 | (process-send-eof tramp-async-proc)))))) | ||
| 3289 | ;; Send the command | ||
| 2982 | (tramp-send-command | 3290 | (tramp-send-command |
| 2983 | multi-method method user host | 3291 | multi-method method user host |
| 2984 | (if error-buffer | 3292 | (if error-buffer |
| 2985 | (format "( %s ) 2>/tmp/tramp.$$.err; tramp_old_status=$?" | 3293 | (format "( %s ) 2>/tmp/tramp.$$.err; tramp_old_status=$?" |
| 2986 | command) | 3294 | command) |
| 2987 | (format "%s ;tramp_old_status=$?" command))) | 3295 | (format "%s; tramp_old_status=$?" command))) |
| 2988 | ;; This will break if the shell command prints "/////" | 3296 | (unless asynchronous |
| 2989 | ;; somewhere. Let's just hope for the best... | 3297 | (tramp-wait-for-output))) |
| 2990 | (tramp-wait-for-output)) | 3298 | (unless asynchronous |
| 2991 | (unless output-buffer | 3299 | (insert-buffer (tramp-get-buffer multi-method method user host))) |
| 2992 | (setq output-buffer (get-buffer-create "*Shell Command Output*")) | ||
| 2993 | (set-buffer output-buffer) | ||
| 2994 | (erase-buffer)) | ||
| 2995 | (unless (bufferp output-buffer) | ||
| 2996 | (setq output-buffer (current-buffer))) | ||
| 2997 | (set-buffer output-buffer) | ||
| 2998 | (insert-buffer (tramp-get-buffer multi-method method user host)) | ||
| 2999 | (when error-buffer | 3300 | (when error-buffer |
| 3000 | (save-excursion | 3301 | (save-excursion |
| 3001 | (unless (bufferp error-buffer) | 3302 | (unless (bufferp error-buffer) |
| @@ -3010,17 +3311,19 @@ This will break if COMMAND prints a newline, followed by the value of | |||
| 3010 | multi-method method user host "rm -f /tmp/tramp.$$.err"))) | 3311 | multi-method method user host "rm -f /tmp/tramp.$$.err"))) |
| 3011 | (save-excursion | 3312 | (save-excursion |
| 3012 | (tramp-send-command multi-method method user host "cd") | 3313 | (tramp-send-command multi-method method user host "cd") |
| 3013 | (tramp-wait-for-output) | 3314 | (unless asynchronous |
| 3315 | (tramp-wait-for-output)) | ||
| 3014 | (tramp-send-command | 3316 | (tramp-send-command |
| 3015 | multi-method method user host | 3317 | multi-method method user host |
| 3016 | (concat "tramp_set_exit_status $tramp_old_status;" | 3318 | (concat "tramp_set_exit_status $tramp_old_status;" |
| 3017 | " echo tramp_exit_status $?")) | 3319 | " echo tramp_exit_status $?")) |
| 3018 | (tramp-wait-for-output) | 3320 | (unless asynchronous |
| 3019 | (goto-char (point-max)) | 3321 | (tramp-wait-for-output) |
| 3020 | (unless (search-backward "tramp_exit_status " nil t) | 3322 | (goto-char (point-max)) |
| 3021 | (error "Couldn't find exit status of `%s'" command)) | 3323 | (unless (search-backward "tramp_exit_status " nil t) |
| 3022 | (skip-chars-forward "^ ") | 3324 | (error "Couldn't find exit status of `%s'" command)) |
| 3023 | (setq status (read (current-buffer)))) | 3325 | (skip-chars-forward "^ ") |
| 3326 | (setq status (read (current-buffer))))) | ||
| 3024 | (unless (zerop (buffer-size)) | 3327 | (unless (zerop (buffer-size)) |
| 3025 | (display-buffer output-buffer)) | 3328 | (display-buffer output-buffer)) |
| 3026 | status)) | 3329 | status)) |
| @@ -3041,16 +3344,7 @@ This will break if COMMAND prints a newline, followed by the value of | |||
| 3041 | (defun tramp-handle-file-local-copy (filename) | 3344 | (defun tramp-handle-file-local-copy (filename) |
| 3042 | "Like `file-local-copy' for tramp files." | 3345 | "Like `file-local-copy' for tramp files." |
| 3043 | (with-parsed-tramp-file-name filename nil | 3346 | (with-parsed-tramp-file-name filename nil |
| 3044 | (let ((output-buf (get-buffer-create "*tramp output*")) | 3347 | (let ((tramp-buf (tramp-get-buffer multi-method method user host)) |
| 3045 | (tramp-buf (tramp-get-buffer multi-method method user host)) | ||
| 3046 | (copy-program (tramp-get-method-parameter | ||
| 3047 | multi-method | ||
| 3048 | (tramp-find-method multi-method method user host) | ||
| 3049 | user host 'tramp-copy-program)) | ||
| 3050 | (copy-args (tramp-get-method-parameter | ||
| 3051 | multi-method | ||
| 3052 | (tramp-find-method multi-method method user host) | ||
| 3053 | user host 'tramp-copy-args)) | ||
| 3054 | ;; We used to bind the following as late as possible. | 3348 | ;; We used to bind the following as late as possible. |
| 3055 | ;; loc-enc and loc-dec were bound directly before the if | 3349 | ;; loc-enc and loc-dec were bound directly before the if |
| 3056 | ;; statement that checks them. But the functions | 3350 | ;; statement that checks them. But the functions |
| @@ -3066,37 +3360,12 @@ This will break if COMMAND prints a newline, followed by the value of | |||
| 3066 | (error "Cannot make local copy of non-existing file `%s'" | 3360 | (error "Cannot make local copy of non-existing file `%s'" |
| 3067 | filename)) | 3361 | filename)) |
| 3068 | (setq tmpfil (tramp-make-temp-file)) | 3362 | (setq tmpfil (tramp-make-temp-file)) |
| 3069 | (cond (copy-program | 3363 | |
| 3070 | ;; The following should be changed. We need a more general | 3364 | |
| 3071 | ;; mechanism to parse extra host args. | 3365 | (cond ((tramp-method-out-of-band-p multi-method method user host) |
| 3072 | (when (string-match "\\([^#]*\\)#\\(.*\\)" host) | 3366 | ;; `copy-file' handles out-of-band methods |
| 3073 | (setq copy-args (cons "-p" (cons (match-string 2 host) | 3367 | (copy-file filename tmpfil t t)) |
| 3074 | rsh-args))) | 3368 | |
| 3075 | (setq host (match-string 1 host))) | ||
| 3076 | ;; Use rcp-like program for file transfer. | ||
| 3077 | (tramp-message-for-buffer | ||
| 3078 | multi-method method user host | ||
| 3079 | 5 "Fetching %s to tmp file %s..." filename tmpfil) | ||
| 3080 | (save-excursion (set-buffer output-buf) (erase-buffer)) | ||
| 3081 | (unless (equal | ||
| 3082 | 0 | ||
| 3083 | (apply #'call-process | ||
| 3084 | copy-program | ||
| 3085 | nil output-buf nil | ||
| 3086 | (append copy-args | ||
| 3087 | (list | ||
| 3088 | (tramp-make-copy-program-file-name | ||
| 3089 | user host | ||
| 3090 | (tramp-shell-quote-argument localname)) | ||
| 3091 | tmpfil)))) | ||
| 3092 | (pop-to-buffer output-buf) | ||
| 3093 | (error | ||
| 3094 | (concat "tramp-handle-file-local-copy: `%s' didn't work, " | ||
| 3095 | "see buffer `%s' for details") | ||
| 3096 | copy-program output-buf)) | ||
| 3097 | (tramp-message-for-buffer | ||
| 3098 | multi-method method user host | ||
| 3099 | 5 "Fetching %s to tmp file %s...done" filename tmpfil)) | ||
| 3100 | ((and rem-enc rem-dec) | 3369 | ((and rem-enc rem-dec) |
| 3101 | ;; Use inline encoding for file transfer. | 3370 | ;; Use inline encoding for file transfer. |
| 3102 | (save-excursion | 3371 | (save-excursion |
| @@ -3225,14 +3494,6 @@ This will break if COMMAND prints a newline, followed by the value of | |||
| 3225 | (error "File not overwritten"))) | 3494 | (error "File not overwritten"))) |
| 3226 | (with-parsed-tramp-file-name filename nil | 3495 | (with-parsed-tramp-file-name filename nil |
| 3227 | (let ((curbuf (current-buffer)) | 3496 | (let ((curbuf (current-buffer)) |
| 3228 | (copy-program (tramp-get-method-parameter | ||
| 3229 | multi-method | ||
| 3230 | (tramp-find-method multi-method method user host) | ||
| 3231 | user host 'tramp-copy-program)) | ||
| 3232 | (copy-args (tramp-get-method-parameter | ||
| 3233 | multi-method | ||
| 3234 | (tramp-find-method multi-method method user host) | ||
| 3235 | user host 'tramp-copy-args)) | ||
| 3236 | (rem-enc (tramp-get-remote-encoding multi-method method user host)) | 3497 | (rem-enc (tramp-get-remote-encoding multi-method method user host)) |
| 3237 | (rem-dec (tramp-get-remote-decoding multi-method method user host)) | 3498 | (rem-dec (tramp-get-remote-decoding multi-method method user host)) |
| 3238 | (loc-enc (tramp-get-local-encoding multi-method method user host)) | 3499 | (loc-enc (tramp-get-local-encoding multi-method method user host)) |
| @@ -3267,44 +3528,10 @@ This will break if COMMAND prints a newline, followed by the value of | |||
| 3267 | ;; decoding command must be specified. However, if the method | 3528 | ;; decoding command must be specified. However, if the method |
| 3268 | ;; _also_ specifies an encoding function, then that is used for | 3529 | ;; _also_ specifies an encoding function, then that is used for |
| 3269 | ;; encoding the contents of the tmp file. | 3530 | ;; encoding the contents of the tmp file. |
| 3270 | (cond (copy-program | 3531 | (cond ((tramp-method-out-of-band-p multi-method method user host) |
| 3271 | ;; The following should be changed. We need a more general | 3532 | ;; `copy-file' handles out-of-band methods |
| 3272 | ;; mechanism to parse extra host args. | 3533 | (copy-file tmpfil filename t t)) |
| 3273 | (when (string-match "\\([^#]*\\)#\\(.*\\)" host) | 3534 | |
| 3274 | (setq copy-args (cons "-p" (cons (match-string 2 host) | ||
| 3275 | rsh-args))) | ||
| 3276 | (setq host (match-string 1 host))) | ||
| 3277 | |||
| 3278 | ;; use rcp-like program for file transfer | ||
| 3279 | (let ((argl (append copy-args | ||
| 3280 | (list | ||
| 3281 | tmpfil | ||
| 3282 | (tramp-make-copy-program-file-name | ||
| 3283 | user host | ||
| 3284 | (tramp-shell-quote-argument localname)))))) | ||
| 3285 | (tramp-message-for-buffer | ||
| 3286 | multi-method method user host | ||
| 3287 | 6 "Writing tmp file using `%s'..." copy-program) | ||
| 3288 | (save-excursion (set-buffer trampbuf) (erase-buffer)) | ||
| 3289 | (when tramp-debug-buffer | ||
| 3290 | (save-excursion | ||
| 3291 | (set-buffer (tramp-get-debug-buffer multi-method | ||
| 3292 | method user host)) | ||
| 3293 | (goto-char (point-max)) | ||
| 3294 | (tramp-insert-with-face | ||
| 3295 | 'bold (format "$ %s %s\n" copy-program | ||
| 3296 | (mapconcat 'identity argl " "))))) | ||
| 3297 | (unless (equal 0 | ||
| 3298 | (apply #'call-process | ||
| 3299 | copy-program nil trampbuf nil argl)) | ||
| 3300 | (pop-to-buffer trampbuf) | ||
| 3301 | (error | ||
| 3302 | "Cannot write region to file `%s', command `%s' failed" | ||
| 3303 | filename copy-program)) | ||
| 3304 | (tramp-message-for-buffer | ||
| 3305 | multi-method method user host | ||
| 3306 | 6 "Transferring file using `%s'...done" | ||
| 3307 | copy-program))) | ||
| 3308 | ((and rem-enc rem-dec) | 3535 | ((and rem-enc rem-dec) |
| 3309 | ;; Use inline file transfer | 3536 | ;; Use inline file transfer |
| 3310 | (let ((tmpbuf (get-buffer-create " *tramp file transfer*"))) | 3537 | (let ((tmpbuf (get-buffer-create " *tramp file transfer*"))) |
| @@ -3319,7 +3546,8 @@ This will break if COMMAND prints a newline, followed by the value of | |||
| 3319 | (progn | 3546 | (progn |
| 3320 | (tramp-message-for-buffer | 3547 | (tramp-message-for-buffer |
| 3321 | multi-method method user host | 3548 | multi-method method user host |
| 3322 | 6 "Encoding region using function...") | 3549 | 6 "Encoding region using function `%s'..." |
| 3550 | (symbol-name loc-enc)) | ||
| 3323 | (insert-file-contents-literally tmpfil) | 3551 | (insert-file-contents-literally tmpfil) |
| 3324 | ;; CCC. The following `let' is a workaround for | 3552 | ;; CCC. The following `let' is a workaround for |
| 3325 | ;; the base64.el that comes with pgnus-0.84. If | 3553 | ;; the base64.el that comes with pgnus-0.84. If |
| @@ -3685,11 +3913,12 @@ necessary anymore." | |||
| 3685 | ;; shouldn't have partial tramp file name syntax. Maybe another variable should | 3913 | ;; shouldn't have partial tramp file name syntax. Maybe another variable should |
| 3686 | ;; be introduced overwriting this check in such cases. Or we change tramp | 3914 | ;; be introduced overwriting this check in such cases. Or we change tramp |
| 3687 | ;; file name syntax in order to avoid ambiguities, like in XEmacs ... | 3915 | ;; file name syntax in order to avoid ambiguities, like in XEmacs ... |
| 3688 | ;; In case of XEmacs it can be always true (and wouldn't be necessary). | 3916 | ;; In case of non unified file names it can be always true (and wouldn't be |
| 3917 | ;; necessary, because there are different regexp). | ||
| 3689 | (defun tramp-completion-mode (file) | 3918 | (defun tramp-completion-mode (file) |
| 3690 | "Checks whether method / user name / host name completion is active." | 3919 | "Checks whether method / user name / host name completion is active." |
| 3691 | (cond | 3920 | (cond |
| 3692 | ((featurep 'xemacs) t) | 3921 | ((not tramp-unified-filenames) t) |
| 3693 | ((string-match "^/.*:.*:$" file) nil) | 3922 | ((string-match "^/.*:.*:$" file) nil) |
| 3694 | ((string-match | 3923 | ((string-match |
| 3695 | (concat tramp-prefix-regexp | 3924 | (concat tramp-prefix-regexp |
| @@ -3697,11 +3926,21 @@ necessary anymore." | |||
| 3697 | file) | 3926 | file) |
| 3698 | (member (match-string 1 file) (mapcar 'car tramp-methods))) | 3927 | (member (match-string 1 file) (mapcar 'car tramp-methods))) |
| 3699 | ((or (equal last-input-event 'tab) | 3928 | ((or (equal last-input-event 'tab) |
| 3929 | ;; Emacs | ||
| 3700 | (and (integerp last-input-event) | 3930 | (and (integerp last-input-event) |
| 3701 | (not (event-modifiers last-input-event)) | 3931 | (not (event-modifiers last-input-event)) |
| 3702 | (or (char-equal last-input-event ?\?) | 3932 | (or (char-equal last-input-event ?\?) |
| 3703 | (char-equal last-input-event ?\t) ; handled by 'tab already? | 3933 | (char-equal last-input-event ?\t) ; handled by 'tab already? |
| 3704 | (char-equal last-input-event ?\ )))) | 3934 | (char-equal last-input-event ?\ ))) |
| 3935 | ;; XEmacs | ||
| 3936 | (and (featurep 'xemacs) | ||
| 3937 | (not (event-modifiers last-input-event)) | ||
| 3938 | (or (char-equal | ||
| 3939 | (funcall 'event-to-character last-input-event) ?\?) | ||
| 3940 | (char-equal | ||
| 3941 | (funcall 'event-to-character last-input-event) ?\t) | ||
| 3942 | (char-equal | ||
| 3943 | (funcall 'event-to-character last-input-event) ?\ )))) | ||
| 3705 | t))) | 3944 | t))) |
| 3706 | 3945 | ||
| 3707 | (defun tramp-completion-handle-file-exists-p (filename) | 3946 | (defun tramp-completion-handle-file-exists-p (filename) |
| @@ -4050,6 +4289,35 @@ User is always nil." | |||
| 4050 | (forward-line 1)) | 4289 | (forward-line 1)) |
| 4051 | result)) | 4290 | result)) |
| 4052 | 4291 | ||
| 4292 | (defun tramp-parse-shostkeys (dirname) | ||
| 4293 | "Return a list of (user host) tuples allowed to access. | ||
| 4294 | User is always nil." | ||
| 4295 | |||
| 4296 | (let ((regexp (concat "^key_[0-9]+_\\(" tramp-host-regexp "\\)\\.pub$")) | ||
| 4297 | (files (when (file-directory-p dirname) (directory-files dirname))) | ||
| 4298 | result) | ||
| 4299 | |||
| 4300 | (while files | ||
| 4301 | (when (string-match regexp (car files)) | ||
| 4302 | (push (list nil (match-string 1 (car files))) result)) | ||
| 4303 | (setq files (cdr files))) | ||
| 4304 | result)) | ||
| 4305 | |||
| 4306 | (defun tramp-parse-sknownhosts (dirname) | ||
| 4307 | "Return a list of (user host) tuples allowed to access. | ||
| 4308 | User is always nil." | ||
| 4309 | |||
| 4310 | (let ((regexp (concat "^\\(" tramp-host-regexp | ||
| 4311 | "\\)\\.ssh-\\(dss\\|rsa\\)\\.pub$")) | ||
| 4312 | (files (when (file-directory-p dirname) (directory-files dirname))) | ||
| 4313 | result) | ||
| 4314 | |||
| 4315 | (while files | ||
| 4316 | (when (string-match regexp (car files)) | ||
| 4317 | (push (list nil (match-string 1 (car files))) result)) | ||
| 4318 | (setq files (cdr files))) | ||
| 4319 | result)) | ||
| 4320 | |||
| 4053 | (defun tramp-parse-hosts (filename) | 4321 | (defun tramp-parse-hosts (filename) |
| 4054 | "Return a list of (user host) tuples allowed to access. | 4322 | "Return a list of (user host) tuples allowed to access. |
| 4055 | User is always nil." | 4323 | User is always nil." |
| @@ -4206,14 +4474,29 @@ hosts, or files, disagree." | |||
| 4206 | (or switch "") | 4474 | (or switch "") |
| 4207 | (tramp-shell-quote-argument localname2)))))) | 4475 | (tramp-shell-quote-argument localname2)))))) |
| 4208 | 4476 | ||
| 4477 | (defun tramp-touch (file time) | ||
| 4478 | "Set the last-modified timestamp of the given file. | ||
| 4479 | TIME is an Emacs internal time value as returned by `current-time'." | ||
| 4480 | (let ((touch-time (format-time-string "%Y%m%d%H%M.%S" time))) | ||
| 4481 | (with-parsed-tramp-file-name file nil | ||
| 4482 | (let ((buf (tramp-get-buffer multi-method method user host))) | ||
| 4483 | (unless (zerop (tramp-send-command-and-check | ||
| 4484 | multi-method method user host | ||
| 4485 | (format "touch -t %s %s" | ||
| 4486 | touch-time | ||
| 4487 | localname))) | ||
| 4488 | (pop-to-buffer buf) | ||
| 4489 | (error "tramp-touch: touch failed, see buffer `%s' for details" | ||
| 4490 | buf)))))) | ||
| 4491 | |||
| 4209 | (defun tramp-buffer-name (multi-method method user host) | 4492 | (defun tramp-buffer-name (multi-method method user host) |
| 4210 | "A name for the connection buffer for USER at HOST using METHOD." | 4493 | "A name for the connection buffer for USER at HOST using METHOD." |
| 4211 | (if multi-method | 4494 | (if multi-method |
| 4212 | (tramp-buffer-name-multi-method "tramp" multi-method method user host) | 4495 | (tramp-buffer-name-multi-method "tramp" multi-method method user host) |
| 4213 | (let ((method (tramp-find-method multi-method method user host))) | 4496 | (let ((method (tramp-find-method multi-method method user host))) |
| 4214 | (if user | 4497 | (if user |
| 4215 | (format "*tramp/%s %s@%s*" method user host)) | 4498 | (format "*tramp/%s %s@%s*" method user host) |
| 4216 | (format "*tramp/%s %s*" method host)))) | 4499 | (format "*tramp/%s %s*" method host))))) |
| 4217 | 4500 | ||
| 4218 | (defun tramp-buffer-name-multi-method (prefix multi-method method user host) | 4501 | (defun tramp-buffer-name-multi-method (prefix multi-method method user host) |
| 4219 | "A name for the multi method connection buffer. | 4502 | "A name for the multi method connection buffer. |
| @@ -4482,11 +4765,6 @@ Returns nil if none was found, else the command is returned." | |||
| 4482 | (defun tramp-action-password (p multi-method method user host) | 4765 | (defun tramp-action-password (p multi-method method user host) |
| 4483 | "Query the user for a password." | 4766 | "Query the user for a password." |
| 4484 | (let ((pw-prompt (match-string 0))) | 4767 | (let ((pw-prompt (match-string 0))) |
| 4485 | (when (tramp-method-out-of-band-p multi-method method user host) | ||
| 4486 | (kill-process (get-buffer-process (current-buffer))) | ||
| 4487 | (error (concat "Out of band method `%s' not applicable " | ||
| 4488 | "for remote shell asking for a password") | ||
| 4489 | method)) | ||
| 4490 | (tramp-message 9 "Sending password") | 4768 | (tramp-message 9 "Sending password") |
| 4491 | (tramp-enter-password p pw-prompt))) | 4769 | (tramp-enter-password p pw-prompt))) |
| 4492 | 4770 | ||
| @@ -4597,6 +4875,7 @@ The terminal type can be configured with `tramp-terminal-type'." | |||
| 4597 | p multi-method method user host actions) | 4875 | p multi-method method user host actions) |
| 4598 | nil))) | 4876 | nil))) |
| 4599 | (unless (eq exit 'ok) | 4877 | (unless (eq exit 'ok) |
| 4878 | (tramp-clear-passwd user host) | ||
| 4600 | (error "Login failed")))) | 4879 | (error "Login failed")))) |
| 4601 | 4880 | ||
| 4602 | ;; For multi-actions. | 4881 | ;; For multi-actions. |
| @@ -4632,6 +4911,7 @@ The terminal type can be configured with `tramp-terminal-type'." | |||
| 4632 | (tramp-process-one-multi-action p method user host actions) | 4911 | (tramp-process-one-multi-action p method user host actions) |
| 4633 | nil))) | 4912 | nil))) |
| 4634 | (unless (eq exit 'ok) | 4913 | (unless (eq exit 'ok) |
| 4914 | (tramp-clear-passwd user host) | ||
| 4635 | (error "Login failed")))) | 4915 | (error "Login failed")))) |
| 4636 | 4916 | ||
| 4637 | ;; Functions to execute when we have seen the remote shell prompt but | 4917 | ;; Functions to execute when we have seen the remote shell prompt but |
| @@ -4768,7 +5048,7 @@ arguments, and xx will be used as the host name to connect to. | |||
| 4768 | ;; The following should be changed. We need a more general | 5048 | ;; The following should be changed. We need a more general |
| 4769 | ;; mechanism to parse extra host args. | 5049 | ;; mechanism to parse extra host args. |
| 4770 | (when (string-match "\\([^#]*\\)#\\(.*\\)" host) | 5050 | (when (string-match "\\([^#]*\\)#\\(.*\\)" host) |
| 4771 | (setq login-args (cons "-p" (cons (match-string 2 host) rsh-args))) | 5051 | (setq login-args (cons "-p" (cons (match-string 2 host) login-args))) |
| 4772 | (setq host (match-string 1 host))) | 5052 | (setq host (match-string 1 host))) |
| 4773 | (setenv "TERM" tramp-terminal-type) | 5053 | (setenv "TERM" tramp-terminal-type) |
| 4774 | (let* ((default-directory (tramp-temporary-file-directory)) | 5054 | (let* ((default-directory (tramp-temporary-file-directory)) |
| @@ -5308,10 +5588,7 @@ locale to C and sets up the remote shell search path." | |||
| 5308 | " -e '" tramp-perl-file-attributes "' $1 $2 2>/dev/null\n" | 5588 | " -e '" tramp-perl-file-attributes "' $1 $2 2>/dev/null\n" |
| 5309 | "}")) | 5589 | "}")) |
| 5310 | (tramp-wait-for-output) | 5590 | (tramp-wait-for-output) |
| 5311 | (unless (tramp-get-method-parameter | 5591 | (unless (tramp-method-out-of-band-p multi-method method user host) |
| 5312 | multi-method | ||
| 5313 | (tramp-find-method multi-method method user host) | ||
| 5314 | user host 'tramp-copy-program) | ||
| 5315 | (tramp-message 5 "Sending the Perl `mime-encode' implementations.") | 5592 | (tramp-message 5 "Sending the Perl `mime-encode' implementations.") |
| 5316 | (tramp-send-string | 5593 | (tramp-send-string |
| 5317 | multi-method method user host | 5594 | multi-method method user host |
| @@ -5350,10 +5627,7 @@ locale to C and sets up the remote shell search path." | |||
| 5350 | (tramp-set-connection-property "ln" ln multi-method method user host))) | 5627 | (tramp-set-connection-property "ln" ln multi-method method user host))) |
| 5351 | (erase-buffer) | 5628 | (erase-buffer) |
| 5352 | ;; Find the right encoding/decoding commands to use. | 5629 | ;; Find the right encoding/decoding commands to use. |
| 5353 | (unless (tramp-get-method-parameter | 5630 | (unless (tramp-method-out-of-band-p multi-method method user host) |
| 5354 | multi-method | ||
| 5355 | (tramp-find-method multi-method method user host) | ||
| 5356 | user host 'tramp-copy-program) | ||
| 5357 | (tramp-find-inline-encoding multi-method method user host)) | 5631 | (tramp-find-inline-encoding multi-method method user host)) |
| 5358 | ;; If encoding/decoding command are given, test to see if they work. | 5632 | ;; If encoding/decoding command are given, test to see if they work. |
| 5359 | ;; CCC: Maybe it would be useful to run the encoder both locally and | 5633 | ;; CCC: Maybe it would be useful to run the encoder both locally and |
| @@ -5566,11 +5840,12 @@ connection if a previous connection has died for some reason." | |||
| 5566 | (unless (and p (processp p) (memq (process-status p) '(run open))) | 5840 | (unless (and p (processp p) (memq (process-status p) '(run open))) |
| 5567 | (when (and p (processp p)) | 5841 | (when (and p (processp p)) |
| 5568 | (delete-process p)) | 5842 | (delete-process p)) |
| 5569 | (funcall (tramp-get-method-parameter | 5843 | (let ((process-connection-type tramp-process-connection-type)) |
| 5570 | multi-method | 5844 | (funcall (tramp-get-method-parameter |
| 5571 | (tramp-find-method multi-method method user host) | 5845 | multi-method |
| 5572 | user host 'tramp-connection-function) | 5846 | (tramp-find-method multi-method method user host) |
| 5573 | multi-method method user host)))) | 5847 | user host 'tramp-connection-function) |
| 5848 | multi-method method user host))))) | ||
| 5574 | 5849 | ||
| 5575 | (defun tramp-send-command | 5850 | (defun tramp-send-command |
| 5576 | (multi-method method user host command &optional noerase neveropen) | 5851 | (multi-method method user host command &optional noerase neveropen) |
| @@ -6223,10 +6498,28 @@ this is the function `temp-directory'." | |||
| 6223 | 6498 | ||
| 6224 | (defun tramp-read-passwd (prompt) | 6499 | (defun tramp-read-passwd (prompt) |
| 6225 | "Read a password from user (compat function). | 6500 | "Read a password from user (compat function). |
| 6226 | Invokes `read-passwd' if that is defined, else `ange-ftp-read-passwd'." | 6501 | Invokes `password-read' if available, `read-passwd' else." |
| 6227 | (apply | 6502 | (if (functionp 'password-read) |
| 6228 | (if (fboundp 'read-passwd) #'read-passwd #'ange-ftp-read-passwd) | 6503 | (let* ((user (or tramp-current-user (user-login-name))) |
| 6229 | (list prompt))) | 6504 | (host (or tramp-current-host (system-name))) |
| 6505 | (key (concat user "@" host)) | ||
| 6506 | (password (apply #'password-read (list prompt key)))) | ||
| 6507 | (apply #'password-cache-add (list key password)) | ||
| 6508 | password) | ||
| 6509 | (read-passwd prompt))) | ||
| 6510 | |||
| 6511 | (defun tramp-clear-passwd (&optional user host) | ||
| 6512 | "Clear password cache for connection related to current-buffer." | ||
| 6513 | (interactive) | ||
| 6514 | (let ((filename (or buffer-file-name list-buffers-directory ""))) | ||
| 6515 | (when (and (functionp 'password-cache-remove) | ||
| 6516 | (or (and user host) (tramp-tramp-file-p filename))) | ||
| 6517 | (let* ((v (when (tramp-tramp-file-p filename) | ||
| 6518 | (tramp-dissect-file-name filename))) | ||
| 6519 | (luser (or user (tramp-file-name-user v) (user-login-name))) | ||
| 6520 | (lhost (or host (tramp-file-name-host v) (system-name))) | ||
| 6521 | (key (concat luser "@" lhost))) | ||
| 6522 | (apply #'password-cache-remove (list key)))))) | ||
| 6230 | 6523 | ||
| 6231 | (defun tramp-time-diff (t1 t2) | 6524 | (defun tramp-time-diff (t1 t2) |
| 6232 | "Return the difference between the two times, in seconds. | 6525 | "Return the difference between the two times, in seconds. |
| @@ -6477,7 +6770,6 @@ report. | |||
| 6477 | 6770 | ||
| 6478 | ;;; TODO: | 6771 | ;;; TODO: |
| 6479 | 6772 | ||
| 6480 | ;; * tramp-copy-keep-date-arg is not used! | ||
| 6481 | ;; * Allow putting passwords in the filename. | 6773 | ;; * Allow putting passwords in the filename. |
| 6482 | ;; This should be implemented via a general mechanism to add | 6774 | ;; This should be implemented via a general mechanism to add |
| 6483 | ;; parameters in filenames. There is currently a kludge for | 6775 | ;; parameters in filenames. There is currently a kludge for |
diff --git a/lisp/net/trampver.el b/lisp/net/trampver.el index 72c8c97899a..b3223d7a46e 100644 --- a/lisp/net/trampver.el +++ b/lisp/net/trampver.el | |||
| @@ -30,7 +30,7 @@ | |||
| 30 | ;; are auto-frobbed from configure.ac, so you should edit that file and run | 30 | ;; are auto-frobbed from configure.ac, so you should edit that file and run |
| 31 | ;; "autoconf && ./configure" to change them. | 31 | ;; "autoconf && ./configure" to change them. |
| 32 | 32 | ||
| 33 | (defconst tramp-version "2.0.38" | 33 | (defconst tramp-version "2.0.39" |
| 34 | "This version of Tramp.") | 34 | "This version of Tramp.") |
| 35 | 35 | ||
| 36 | (defconst tramp-bug-report-address "tramp-devel@mail.freesoftware.fsf.org" | 36 | (defconst tramp-bug-report-address "tramp-devel@mail.freesoftware.fsf.org" |
diff --git a/lisp/progmodes/ebnf-abn.el b/lisp/progmodes/ebnf-abn.el index ec96109e0a0..9c341c5181c 100644 --- a/lisp/progmodes/ebnf-abn.el +++ b/lisp/progmodes/ebnf-abn.el | |||
| @@ -4,7 +4,7 @@ | |||
| 4 | 4 | ||
| 5 | ;; Author: Vinicius Jose Latorre <viniciusjl@ig.com.br> | 5 | ;; Author: Vinicius Jose Latorre <viniciusjl@ig.com.br> |
| 6 | ;; Maintainer: Vinicius Jose Latorre <viniciusjl@ig.com.br> | 6 | ;; Maintainer: Vinicius Jose Latorre <viniciusjl@ig.com.br> |
| 7 | ;; Time-stamp: <2004/02/23 22:38:59 vinicius> | 7 | ;; Time-stamp: <2004/02/28 17:40:41 vinicius> |
| 8 | ;; Keywords: wp, ebnf, PostScript | 8 | ;; Keywords: wp, ebnf, PostScript |
| 9 | ;; Version: 1.0 | 9 | ;; Version: 1.0 |
| 10 | 10 | ||
| @@ -41,6 +41,8 @@ | |||
| 41 | ;; ----------- | 41 | ;; ----------- |
| 42 | ;; | 42 | ;; |
| 43 | ;; See the URL: | 43 | ;; See the URL: |
| 44 | ;; `http://www.ietf.org/rfc/rfc2234.txt' | ||
| 45 | ;; or | ||
| 44 | ;; `http://www.faqs.org/rfcs/rfc2234.html' | 46 | ;; `http://www.faqs.org/rfcs/rfc2234.html' |
| 45 | ;; or | 47 | ;; or |
| 46 | ;; `http://www.rnp.br/ietf/rfc/rfc2234.txt' | 48 | ;; `http://www.rnp.br/ietf/rfc/rfc2234.txt' |
diff --git a/lisp/progmodes/ebnf-bnf.el b/lisp/progmodes/ebnf-bnf.el index 41bd0cd0d49..4f0ef6099c8 100644 --- a/lisp/progmodes/ebnf-bnf.el +++ b/lisp/progmodes/ebnf-bnf.el | |||
| @@ -5,7 +5,7 @@ | |||
| 5 | 5 | ||
| 6 | ;; Author: Vinicius Jose Latorre <viniciusjl@ig.com.br> | 6 | ;; Author: Vinicius Jose Latorre <viniciusjl@ig.com.br> |
| 7 | ;; Maintainer: Vinicius Jose Latorre <viniciusjl@ig.com.br> | 7 | ;; Maintainer: Vinicius Jose Latorre <viniciusjl@ig.com.br> |
| 8 | ;; Time-stamp: <2004/02/22 14:25:06 vinicius> | 8 | ;; Time-stamp: <2004/02/28 18:25:52 vinicius> |
| 9 | ;; Keywords: wp, ebnf, PostScript | 9 | ;; Keywords: wp, ebnf, PostScript |
| 10 | ;; Version: 1.8 | 10 | ;; Version: 1.8 |
| 11 | 11 | ||
| @@ -54,7 +54,10 @@ | |||
| 54 | ;; C D sequence (C occurs before D) | 54 | ;; C D sequence (C occurs before D) |
| 55 | ;; C | D alternative (C or D occurs) | 55 | ;; C | D alternative (C or D occurs) |
| 56 | ;; A - B exception (A excluding B, B without any non-terminal) | 56 | ;; A - B exception (A excluding B, B without any non-terminal) |
| 57 | ;; n * A repetition (A repeats n (integer) times) | 57 | ;; n * A repetition (A repeats at least n (integer) times) |
| 58 | ;; n * n A repetition (A repeats exactly n (integer) times) | ||
| 59 | ;; n * m A repetition (A repeats at least n (integer) and at most | ||
| 60 | ;; m (integer) times) | ||
| 58 | ;; (C) group (expression C is grouped together) | 61 | ;; (C) group (expression C is grouped together) |
| 59 | ;; [C] optional (C may or not occurs) | 62 | ;; [C] optional (C may or not occurs) |
| 60 | ;; C+ one or more occurrences of C | 63 | ;; C+ one or more occurrences of C |
| @@ -78,7 +81,7 @@ | |||
| 78 | ;; | 81 | ;; |
| 79 | ;; exception = repeat [ "-" repeat]. ;; exception | 82 | ;; exception = repeat [ "-" repeat]. ;; exception |
| 80 | ;; | 83 | ;; |
| 81 | ;; repeat = [ integer "*" ] term. ;; repetition | 84 | ;; repeat = [ integer "*" [ integer ]] term. ;; repetition |
| 82 | ;; | 85 | ;; |
| 83 | ;; term = factor | 86 | ;; term = factor |
| 84 | ;; | [factor] "+" ;; one-or-more | 87 | ;; | [factor] "+" ;; one-or-more |
| @@ -96,14 +99,30 @@ | |||
| 96 | ;; . | 99 | ;; . |
| 97 | ;; | 100 | ;; |
| 98 | ;; non_terminal = "[!#%&'*-,0-:<>@-Z\\\\^-z~\\240-\\377]+". | 101 | ;; non_terminal = "[!#%&'*-,0-:<>@-Z\\\\^-z~\\240-\\377]+". |
| 102 | ;; ;; that is, a valid non_terminal accepts decimal digits, letters (upper | ||
| 103 | ;; ;; and lower), 8-bit accentuated characters, | ||
| 104 | ;; ;; "!", "#", "%", "&", "'", "*", "+", ",", ":", | ||
| 105 | ;; ;; "<", ">", "@", "\", "^", "_", "`" and "~". | ||
| 99 | ;; | 106 | ;; |
| 100 | ;; terminal = "\\([^\"\\]\\|\\\\[ -~\\240-\\377]\\)+". | 107 | ;; terminal = "\\([^\"\\]\\|\\\\[ -~\\240-\\377]\\)+". |
| 108 | ;; ;; that is, a valid terminal accepts any printable character (including | ||
| 109 | ;; ;; 8-bit accentuated characters) except `"', as `"' is used to delimit a | ||
| 110 | ;; ;; terminal. Also, accepts escaped characters, that is, a character | ||
| 111 | ;; ;; pair starting with `\' followed by a printable character, for | ||
| 112 | ;; ;; example: \", \\. | ||
| 101 | ;; | 113 | ;; |
| 102 | ;; special = "[^?\\n\\000-\\010\\016-\\037\\177-\\237]*". | 114 | ;; special = "[^?\\000-\\010\\012-\\037\\177-\\237]*". |
| 115 | ;; ;; that is, a valid special accepts any printable character (including | ||
| 116 | ;; ;; 8-bit accentuated characters) and tabs except `?', as `?' is used to | ||
| 117 | ;; ;; delimit a special. | ||
| 103 | ;; | 118 | ;; |
| 104 | ;; integer = "[0-9]+". | 119 | ;; integer = "[0-9]+". |
| 120 | ;; ;; that is, an integer is a sequence of one or more decimal digits. | ||
| 105 | ;; | 121 | ;; |
| 106 | ;; comment = ";" "[^\\n\\000-\\010\\016-\\037\\177-\\237]*" "\\n". | 122 | ;; comment = ";" "[^\\n\\000-\\010\\016-\\037\\177-\\237]*" "\\n". |
| 123 | ;; ;; that is, a comment starts with the character `;' and terminates at end | ||
| 124 | ;; ;; of line. Also, it only accepts printable characters (including 8-bit | ||
| 125 | ;; ;; accentuated characters) and tabs. | ||
| 107 | ;; | 126 | ;; |
| 108 | ;; | 127 | ;; |
| 109 | ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | 128 | ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
| @@ -234,15 +253,20 @@ | |||
| 234 | )))) | 253 | )))) |
| 235 | 254 | ||
| 236 | 255 | ||
| 237 | ;;; repeat = [ integer "*" ] term. | 256 | ;;; repeat = [ integer "*" [ integer ]] term. |
| 238 | 257 | ||
| 239 | (defun ebnf-repeat (token) | 258 | (defun ebnf-repeat (token) |
| 240 | (if (not (eq token 'integer)) | 259 | (if (not (eq token 'integer)) |
| 241 | (ebnf-term token) | 260 | (ebnf-term token) |
| 242 | (let ((times ebnf-bnf-lex)) | 261 | (let ((times ebnf-bnf-lex) |
| 262 | upper) | ||
| 243 | (or (eq (ebnf-bnf-lex) 'repeat) | 263 | (or (eq (ebnf-bnf-lex) 'repeat) |
| 244 | (error "Missing `*'")) | 264 | (error "Missing `*'")) |
| 245 | (ebnf-token-repeat times (ebnf-term (ebnf-bnf-lex)))))) | 265 | (setq token (ebnf-bnf-lex)) |
| 266 | (when (eq token 'integer) | ||
| 267 | (setq upper ebnf-bnf-lex | ||
| 268 | token (ebnf-bnf-lex))) | ||
| 269 | (ebnf-token-repeat times (ebnf-term token) upper)))) | ||
| 246 | 270 | ||
| 247 | 271 | ||
| 248 | ;;; term = factor | 272 | ;;; term = factor |
diff --git a/lisp/progmodes/ebnf2ps.el b/lisp/progmodes/ebnf2ps.el index d13ed80fe5c..96ec53ac501 100644 --- a/lisp/progmodes/ebnf2ps.el +++ b/lisp/progmodes/ebnf2ps.el | |||
| @@ -5,7 +5,7 @@ | |||
| 5 | 5 | ||
| 6 | ;; Author: Vinicius Jose Latorre <viniciusjl@ig.com.br> | 6 | ;; Author: Vinicius Jose Latorre <viniciusjl@ig.com.br> |
| 7 | ;; Maintainer: Vinicius Jose Latorre <viniciusjl@ig.com.br> | 7 | ;; Maintainer: Vinicius Jose Latorre <viniciusjl@ig.com.br> |
| 8 | ;; Time-stamp: <2004/02/25 20:17:43 vinicius> | 8 | ;; Time-stamp: <2004/02/29 14:06:59 vinicius> |
| 9 | ;; Keywords: wp, ebnf, PostScript | 9 | ;; Keywords: wp, ebnf, PostScript |
| 10 | ;; Version: 4.0 | 10 | ;; Version: 4.0 |
| 11 | ;; X-URL: http://www.cpqd.com.br/~vinicius/emacs/ | 11 | ;; X-URL: http://www.cpqd.com.br/~vinicius/emacs/ |
| @@ -28,7 +28,7 @@ | |||
| 28 | ;; Boston, MA 02111-1307, USA. | 28 | ;; Boston, MA 02111-1307, USA. |
| 29 | 29 | ||
| 30 | (defconst ebnf-version "4.0" | 30 | (defconst ebnf-version "4.0" |
| 31 | "ebnf2ps.el, v 4.0 <2004/02/24 vinicius> | 31 | "ebnf2ps.el, v 4.0 <2004/02/28 vinicius> |
| 32 | 32 | ||
| 33 | Vinicius's last change version. When reporting bugs, please also | 33 | Vinicius's last change version. When reporting bugs, please also |
| 34 | report the version of Emacs, if any, that ebnf2ps was running with. | 34 | report the version of Emacs, if any, that ebnf2ps was running with. |
| @@ -70,8 +70,8 @@ Please send all bug fixes and enhancements to | |||
| 70 | ;; Using ebnf2ps | 70 | ;; Using ebnf2ps |
| 71 | ;; ------------- | 71 | ;; ------------- |
| 72 | ;; | 72 | ;; |
| 73 | ;; ebnf2ps provides six commands for generating PostScript syntactic chart | 73 | ;; ebnf2ps provides the following commands for generating PostScript syntactic |
| 74 | ;; images of Emacs buffers: | 74 | ;; chart images of Emacs buffers: |
| 75 | ;; | 75 | ;; |
| 76 | ;; ebnf-print-directory | 76 | ;; ebnf-print-directory |
| 77 | ;; ebnf-print-file | 77 | ;; ebnf-print-file |
| @@ -193,7 +193,10 @@ Please send all bug fixes and enhancements to | |||
| 193 | ;; C D sequence (C occurs before D) | 193 | ;; C D sequence (C occurs before D) |
| 194 | ;; C | D alternative (C or D occurs) | 194 | ;; C | D alternative (C or D occurs) |
| 195 | ;; A - B exception (A excluding B, B without any non-terminal) | 195 | ;; A - B exception (A excluding B, B without any non-terminal) |
| 196 | ;; n * A repetition (A repeats n (integer) times) | 196 | ;; n * A repetition (A repeats at least n (integer) times) |
| 197 | ;; n * n A repetition (A repeats exactly n (integer) times) | ||
| 198 | ;; n * m A repetition (A repeats at least n (integer) and at most | ||
| 199 | ;; m (integer) times) | ||
| 197 | ;; (C) group (expression C is grouped together) | 200 | ;; (C) group (expression C is grouped together) |
| 198 | ;; [C] optional (C may or not occurs) | 201 | ;; [C] optional (C may or not occurs) |
| 199 | ;; C+ one or more occurrences of C | 202 | ;; C+ one or more occurrences of C |
| @@ -217,7 +220,7 @@ Please send all bug fixes and enhancements to | |||
| 217 | ;; | 220 | ;; |
| 218 | ;; exception = repeat [ "-" repeat]. ;; exception | 221 | ;; exception = repeat [ "-" repeat]. ;; exception |
| 219 | ;; | 222 | ;; |
| 220 | ;; repeat = [ integer "*" ] term. ;; repetition | 223 | ;; repeat = [ integer "*" [ integer ]] term. ;; repetition |
| 221 | ;; | 224 | ;; |
| 222 | ;; term = factor | 225 | ;; term = factor |
| 223 | ;; | [factor] "+" ;; one-or-more | 226 | ;; | [factor] "+" ;; one-or-more |
| @@ -302,7 +305,7 @@ Please send all bug fixes and enhancements to | |||
| 302 | ;; `ebnf-lex-comment-char' and `ebnf-lex-eop-char'. | 305 | ;; `ebnf-lex-comment-char' and `ebnf-lex-eop-char'. |
| 303 | ;; | 306 | ;; |
| 304 | ;; `abnf' ebnf2ps recognizes the syntax described in the URL: | 307 | ;; `abnf' ebnf2ps recognizes the syntax described in the URL: |
| 305 | ;; `http://www.faqs.org/rfcs/rfc2234.html' | 308 | ;; `http://www.ietf.org/rfc/rfc2234.txt' |
| 306 | ;; ("Augmented BNF for Syntax Specifications: ABNF"). | 309 | ;; ("Augmented BNF for Syntax Specifications: ABNF"). |
| 307 | ;; | 310 | ;; |
| 308 | ;; `iso-ebnf' ebnf2ps recognizes the syntax described in the URL: | 311 | ;; `iso-ebnf' ebnf2ps recognizes the syntax described in the URL: |
| @@ -514,6 +517,12 @@ Please send all bug fixes and enhancements to | |||
| 514 | ;; | 517 | ;; |
| 515 | ;; `ebnf-setup' returns the current setup. | 518 | ;; `ebnf-setup' returns the current setup. |
| 516 | ;; | 519 | ;; |
| 520 | ;; `ebnf-syntax-directory' does a syntactic analysis of your EBNF files in the | ||
| 521 | ;; given directory. | ||
| 522 | ;; | ||
| 523 | ;; `ebnf-syntax-file' does a syntactic analysis of your EBNF in the given | ||
| 524 | ;; file. | ||
| 525 | ;; | ||
| 517 | ;; `ebnf-syntax-buffer' does a syntactic analysis of your EBNF in the current | 526 | ;; `ebnf-syntax-buffer' does a syntactic analysis of your EBNF in the current |
| 518 | ;; buffer. | 527 | ;; buffer. |
| 519 | ;; | 528 | ;; |
| @@ -522,8 +531,9 @@ Please send all bug fixes and enhancements to | |||
| 522 | ;; | 531 | ;; |
| 523 | ;; `ebnf-customize' activates a customization buffer for ebnf2ps options. | 532 | ;; `ebnf-customize' activates a customization buffer for ebnf2ps options. |
| 524 | ;; | 533 | ;; |
| 525 | ;; `ebnf-syntax-buffer', `ebnf-syntax-region' and `ebnf-customize' can be bound | 534 | ;; `ebnf-syntax-directory', `ebnf-syntax-file', `ebnf-syntax-buffer', |
| 526 | ;; to keys in the same way as `ebnf-' commands. | 535 | ;; `ebnf-syntax-region' and `ebnf-customize' can be bound to keys in the same |
| 536 | ;; way as `ebnf-' commands. | ||
| 527 | ;; | 537 | ;; |
| 528 | ;; | 538 | ;; |
| 529 | ;; Hooks | 539 | ;; Hooks |
| @@ -1654,7 +1664,7 @@ Valid values are: | |||
| 1654 | `ebnf-lex-comment-char' and `ebnf-lex-eop-char'. | 1664 | `ebnf-lex-comment-char' and `ebnf-lex-eop-char'. |
| 1655 | 1665 | ||
| 1656 | `abnf' ebnf2ps recognizes the syntax described in the URL: | 1666 | `abnf' ebnf2ps recognizes the syntax described in the URL: |
| 1657 | `http://www.faqs.org/rfcs/rfc2234.html' | 1667 | `http://www.ietf.org/rfc/rfc2234.txt' |
| 1658 | (\"Augmented BNF for Syntax Specifications: ABNF\"). | 1668 | (\"Augmented BNF for Syntax Specifications: ABNF\"). |
| 1659 | 1669 | ||
| 1660 | `iso-ebnf' ebnf2ps recognizes the syntax described in the URL: | 1670 | `iso-ebnf' ebnf2ps recognizes the syntax described in the URL: |
| @@ -2061,6 +2071,34 @@ WARNING: It's *NOT* asked any confirmation to override an existing file." | |||
| 2061 | 2071 | ||
| 2062 | 2072 | ||
| 2063 | ;;;###autoload | 2073 | ;;;###autoload |
| 2074 | (defun ebnf-syntax-directory (&optional directory) | ||
| 2075 | "Does a syntactic analysis of the files in DIRECTORY. | ||
| 2076 | |||
| 2077 | If DIRECTORY is nil, it's used `default-directory'. | ||
| 2078 | |||
| 2079 | The files in DIRECTORY that matches `ebnf-file-suffix-regexp' (which see) are | ||
| 2080 | processed. | ||
| 2081 | |||
| 2082 | See also `ebnf-syntax-buffer'." | ||
| 2083 | (interactive | ||
| 2084 | (list (read-file-name "Directory containing EBNF files (syntax): " | ||
| 2085 | nil default-directory))) | ||
| 2086 | (ebnf-directory 'ebnf-syntax-buffer directory)) | ||
| 2087 | |||
| 2088 | |||
| 2089 | ;;;###autoload | ||
| 2090 | (defun ebnf-syntax-file (file &optional do-not-kill-buffer-when-done) | ||
| 2091 | "Does a syntactic analysis of the FILE. | ||
| 2092 | |||
| 2093 | If optional arg DO-NOT-KILL-BUFFER-WHEN-DONE is non-nil, the buffer isn't | ||
| 2094 | killed after syntax checking. | ||
| 2095 | |||
| 2096 | See also `ebnf-syntax-buffer'." | ||
| 2097 | (interactive "fEBNF file to check syntax: ") | ||
| 2098 | (ebnf-file 'ebnf-syntax-buffer file do-not-kill-buffer-when-done)) | ||
| 2099 | |||
| 2100 | |||
| 2101 | ;;;###autoload | ||
| 2064 | (defun ebnf-syntax-buffer () | 2102 | (defun ebnf-syntax-buffer () |
| 2065 | "Does a syntactic analysis of the current buffer." | 2103 | "Does a syntactic analysis of the current buffer." |
| 2066 | (interactive) | 2104 | (interactive) |
diff --git a/lisp/thumbs.el b/lisp/thumbs.el new file mode 100644 index 00000000000..cc692c1f975 --- /dev/null +++ b/lisp/thumbs.el | |||
| @@ -0,0 +1,737 @@ | |||
| 1 | ;;; thumbs.el --- Thumbnails previewer for images files | ||
| 2 | ;;; | ||
| 3 | ;; Author: Jean-Philippe Theberge <jphiltheberge@videotron.ca> | ||
| 4 | ;; | ||
| 5 | ;; Thanks: Alex Schroeder <alex@gnu.org> for maintaining the package at some time | ||
| 6 | ;; The peoples at #emacs@freenode.net for numerous help | ||
| 7 | ;; RMS for emacs and the GNU project. | ||
| 8 | ;; | ||
| 9 | ;; Keywords: Multimedia | ||
| 10 | |||
| 11 | (defconst thumbs-version "2.0") | ||
| 12 | |||
| 13 | ;; This file is part of GNU Emacs. | ||
| 14 | |||
| 15 | ;; GNU Emacs is free software; you can redistribute it and/or modify | ||
| 16 | ;; it under the terms of the GNU General Public License as published by | ||
| 17 | ;; the Free Software Foundation; either version 2, or (at your option) | ||
| 18 | ;; any later version. | ||
| 19 | |||
| 20 | ;; GNU Emacs is distributed in the hope that it will be useful, | ||
| 21 | ;; but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 22 | ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 23 | ;; GNU General Public License for more details. | ||
| 24 | |||
| 25 | ;; You should have received a copy of the GNU General Public License | ||
| 26 | ;; along with GNU Emacs; see the file COPYING. If not, write to the | ||
| 27 | ;; Free Software Foundation, Inc., 59 Temple Place - Suite 330, | ||
| 28 | ;; Boston, MA 02111-1307, USA. | ||
| 29 | |||
| 30 | ;;; Commentary: | ||
| 31 | |||
| 32 | ;; This package create two new mode: thumbs-mode and | ||
| 33 | ;; thumbs-view-image-mode. It is used for images browsing and viewing | ||
| 34 | ;; from within emacs. Minimal image manipulation functions are also | ||
| 35 | ;; available via external programs. | ||
| 36 | ;; | ||
| 37 | ;; The 'convert' program from 'ImageMagick' | ||
| 38 | ;; [URL:http://www.imagemagick.org/] is required. | ||
| 39 | ;; | ||
| 40 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | ||
| 41 | ;; CHANGELOG | ||
| 42 | ;; | ||
| 43 | ;; This is version 2.0 | ||
| 44 | ;; | ||
| 45 | ;; USAGE | ||
| 46 | ;; | ||
| 47 | ;; Type M-x thumbs RET DIR RET to view the directory DIR in Thumbs mode. | ||
| 48 | ;; That should be a directory containing image files. | ||
| 49 | ;; from dired, C-t m enter in thumbs-mode with all marked files | ||
| 50 | ;; C-t a enter in thumbs-mode with all files in current-directory | ||
| 51 | ;; In thumbs-mode, pressing <return> on a image will bring you in image view mode | ||
| 52 | ;; for that image. C-h m will give you a list of available keybinding. | ||
| 53 | |||
| 54 | ;;; History: | ||
| 55 | ;; | ||
| 56 | |||
| 57 | ;;; Code: | ||
| 58 | |||
| 59 | (require 'dired) | ||
| 60 | |||
| 61 | ;; Abort if in-line imaging isn't supported (i.e. Emacs-20.7) | ||
| 62 | |||
| 63 | (when (not (display-images-p)) | ||
| 64 | (error "Your Emacs version (%S) doesn't support in-line images, | ||
| 65 | was not compiled with image support or is run in console mode. | ||
| 66 | Upgrade to Emacs 21.1 or newer, compile it with image support | ||
| 67 | or use a window-system" | ||
| 68 | emacs-version)) | ||
| 69 | |||
| 70 | ;; CUSTOMIZATIONS | ||
| 71 | |||
| 72 | (defgroup thumbs nil | ||
| 73 | "Thumbnails previewer." | ||
| 74 | :group 'multimedia) | ||
| 75 | |||
| 76 | (defcustom thumbs-thumbsdir | ||
| 77 | (expand-file-name "~/.emacs-thumbs") | ||
| 78 | "*Directory to store thumbnails." | ||
| 79 | :type 'directory | ||
| 80 | :group 'thumbs) | ||
| 81 | |||
| 82 | (defcustom thumbs-geometry "100x100" | ||
| 83 | "*Size of thumbnails." | ||
| 84 | :type 'string | ||
| 85 | :group 'thumbs) | ||
| 86 | |||
| 87 | (defcustom thumbs-per-line 5 | ||
| 88 | "*Number of thumbnails per line to show in directory." | ||
| 89 | :type 'string | ||
| 90 | :group 'thumbs) | ||
| 91 | |||
| 92 | (defcustom thumbs-thumbsdir-max-size 50000000 | ||
| 93 | "Max size for thumbnails directory. | ||
| 94 | When it reach that size (in bytes), a warning is send." | ||
| 95 | :type 'string | ||
| 96 | :group 'thumbs) | ||
| 97 | |||
| 98 | (defcustom thumbs-conversion-program | ||
| 99 | (if (equal 'windows-nt system-type) | ||
| 100 | "convert.exe" | ||
| 101 | (or (executable-find "convert") | ||
| 102 | "/usr/X11R6/bin/convert")) | ||
| 103 | "*Name of conversion program for thumbnails generation. | ||
| 104 | It must be 'convert'." | ||
| 105 | :type 'string | ||
| 106 | :group 'thumbs) | ||
| 107 | |||
| 108 | (defcustom thumbs-setroot-command | ||
| 109 | "xloadimage -onroot -fullscreen *" | ||
| 110 | "Command to set the root window." | ||
| 111 | :type 'string | ||
| 112 | :group 'thumbs) | ||
| 113 | |||
| 114 | (defcustom thumbs-relief 5 | ||
| 115 | "*Size of button-like border around thumbnails." | ||
| 116 | :type 'string | ||
| 117 | :group 'thumbs) | ||
| 118 | |||
| 119 | (defcustom thumbs-margin 2 | ||
| 120 | "*Size of the margin around thumbnails. | ||
| 121 | This is where you see the cursor." | ||
| 122 | :type 'string | ||
| 123 | :group 'thumbs) | ||
| 124 | |||
| 125 | (defcustom thumbs-thumbsdir-auto-clean t | ||
| 126 | "If set, delete older file in the thumbnails directory. | ||
| 127 | Deletion is done at load time when the directory size is bigger | ||
| 128 | than 'thumbs-thumbsdir-max-size'." | ||
| 129 | :type 'boolean | ||
| 130 | :group 'thumbs) | ||
| 131 | |||
| 132 | (defcustom thumbs-image-resizing-step 10 | ||
| 133 | "Step by wich to resize image." | ||
| 134 | :type 'string | ||
| 135 | :group 'thumbs) | ||
| 136 | |||
| 137 | (defcustom thumbs-temp-dir | ||
| 138 | "/tmp/" | ||
| 139 | "Temporary directory to use. | ||
| 140 | Leaving it to default '/tmp/' can let another user | ||
| 141 | see some of your images." | ||
| 142 | :type 'directory | ||
| 143 | :group 'thumbs) | ||
| 144 | |||
| 145 | (defcustom thumbs-temp-prefix "emacsthumbs" | ||
| 146 | "Prefix to add to temp files." | ||
| 147 | :type 'string | ||
| 148 | :group 'thumbs) | ||
| 149 | |||
| 150 | ;; Initialize some variable, for later use. | ||
| 151 | (defvar thumbs-temp-file | ||
| 152 | (concat thumbs-temp-dir thumbs-temp-prefix) | ||
| 153 | "Temporary filesname for images.") | ||
| 154 | |||
| 155 | (defvar thumbs-current-tmp-filename | ||
| 156 | nil | ||
| 157 | "Temporary filename of current image.") | ||
| 158 | (defvar thumbs-current-image-filename | ||
| 159 | nil | ||
| 160 | "Filename of current image.") | ||
| 161 | (defvar thumbs-current-image-size | ||
| 162 | nil | ||
| 163 | "Size of current image.") | ||
| 164 | (defvar thumbs-image-num | ||
| 165 | nil | ||
| 166 | "Number of current image.") | ||
| 167 | (defvar thumbs-current-dir | ||
| 168 | nil | ||
| 169 | "Current directory.") | ||
| 170 | (defvar thumbs-markedL | ||
| 171 | nil | ||
| 172 | "List of marked files.") | ||
| 173 | |||
| 174 | ;; Make sure auto-image-file-mode is ON. | ||
| 175 | (auto-image-file-mode t) | ||
| 176 | |||
| 177 | ;; Create the thumbs directory if it does not exists. | ||
| 178 | (setq thumbs-thumbsdir (expand-file-name thumbs-thumbsdir)) | ||
| 179 | |||
| 180 | (when (not (file-directory-p thumbs-thumbsdir)) | ||
| 181 | (progn | ||
| 182 | (make-directory thumbs-thumbsdir) | ||
| 183 | (message "Creating thumbnails directory"))) | ||
| 184 | |||
| 185 | (when (not (fboundp 'ignore-errors)) | ||
| 186 | (defmacro ignore-errors (&rest body) | ||
| 187 | "Execute FORMS; if anz error occurs, return nil. | ||
| 188 | Otherwise, return result of last FORM." | ||
| 189 | (let ((err (thumbs-gensym))) | ||
| 190 | (list 'condition-case err (cons 'progn body) '(error nil))))) | ||
| 191 | |||
| 192 | (when (not (fboundp 'time-less-p)) | ||
| 193 | (defun time-less-p (t1 t2) | ||
| 194 | "Say whether time T1 is less than time T2." | ||
| 195 | (or (< (car t1) (car t2)) | ||
| 196 | (and (= (car t1) (car t2)) | ||
| 197 | (< (nth 1 t1) (nth 1 t2)))))) | ||
| 198 | |||
| 199 | (when (not (fboundp 'caddar)) | ||
| 200 | (defun caddar (x) | ||
| 201 | "Return the `car' of the `cdr' of the `cdr' of the `car' of X." | ||
| 202 | (car (cdr (cdr (car x)))))) | ||
| 203 | |||
| 204 | (defvar thumbs-gensym-counter 0) | ||
| 205 | |||
| 206 | (defun thumbs-gensym (&optional arg) | ||
| 207 | "Generate a new uninterned symbol. | ||
| 208 | The name is made by appending a number to PREFIX, default \"Thumbs\"." | ||
| 209 | (let ((prefix (if (stringp arg) arg "Thumbs")) | ||
| 210 | (num (if (integerp arg) arg | ||
| 211 | (prog1 | ||
| 212 | thumbs-gensym-counter | ||
| 213 | (setq thumbs-gensym-counter (1+ thumbs-gensym-counter)))))) | ||
| 214 | (make-symbol (format "%s%d" prefix num)))) | ||
| 215 | |||
| 216 | (defun thumbs-cleanup-thumbsdir () | ||
| 217 | "Clean the thumbnails directory. | ||
| 218 | If the total size of all files in 'thumbs-thumbsdir' is bigger than | ||
| 219 | 'thumbs-thumbsdir-max-size', files are deleted until the max size is | ||
| 220 | reached." | ||
| 221 | (let* ((filesL | ||
| 222 | (sort | ||
| 223 | (mapcar | ||
| 224 | (lambda (f) | ||
| 225 | (let ((fattribsL (file-attributes f))) | ||
| 226 | `(,(nth 4 fattribsL) ,(nth 7 fattribsL) ,f))) | ||
| 227 | (directory-files thumbs-thumbsdir t (image-file-name-regexp))) | ||
| 228 | '(lambda (l1 l2) (time-less-p (car l1)(car l2))))) | ||
| 229 | (dirsize (apply '+ (mapcar (lambda (x) (cadr x)) filesL)))) | ||
| 230 | (while (> dirsize thumbs-thumbsdir-max-size) | ||
| 231 | (progn | ||
| 232 | (message "Deleting file %s" (caddar filesL))) | ||
| 233 | (delete-file (caddar filesL)) | ||
| 234 | (setq dirsize (- dirsize (cadar filesL))) | ||
| 235 | (setq filesL (cdr filesL))))) | ||
| 236 | |||
| 237 | ;; Check the thumbsnail directory size and clean it if necessary. | ||
| 238 | (when thumbs-thumbsdir-auto-clean | ||
| 239 | (thumbs-cleanup-thumbsdir)) | ||
| 240 | |||
| 241 | (defun thumbs-call-convert (filein fileout action | ||
| 242 | &optional arg output-format action-prefix) | ||
| 243 | "Call the convert program. | ||
| 244 | FILEIN is the input file, | ||
| 245 | FILEOUT is the output file, | ||
| 246 | ACTION is the command to send to convert. | ||
| 247 | Optional argument are: | ||
| 248 | ARG any arguments to the ACTION command, | ||
| 249 | OUTPUT-FORMAT is the file format to output, default is jpeg | ||
| 250 | ACTION-PREFIX is the symbol to place before the ACTION command | ||
| 251 | (default to '-' but can sometime be '+')." | ||
| 252 | (let ((command (format "%s %s%s %s \"%s\" \"%s:%s\"" | ||
| 253 | thumbs-conversion-program | ||
| 254 | (or action-prefix "-") | ||
| 255 | action | ||
| 256 | (or arg "") | ||
| 257 | filein | ||
| 258 | (or output-format "jpeg") | ||
| 259 | fileout))) | ||
| 260 | (shell-command command))) | ||
| 261 | |||
| 262 | (defun thumbs-increment-image-size-element (n d) | ||
| 263 | "Increment number N by D percent." | ||
| 264 | (round (+ n (/ (* d n) 100)))) | ||
| 265 | |||
| 266 | (defun thumbs-decrement-image-size-element (n d) | ||
| 267 | "Decrement number N by D percent." | ||
| 268 | (round (- n (/ (* d n) 100)))) | ||
| 269 | |||
| 270 | (defun thumbs-increment-image-size (s) | ||
| 271 | "Increment S (a cons of width x heigh)." | ||
| 272 | (cons | ||
| 273 | (thumbs-increment-image-size-element (car s) | ||
| 274 | thumbs-image-resizing-step) | ||
| 275 | (thumbs-increment-image-size-element (cdr s) | ||
| 276 | thumbs-image-resizing-step))) | ||
| 277 | |||
| 278 | (defun thumbs-decrement-image-size (s) | ||
| 279 | "Decrement S (a cons of width x heigh)." | ||
| 280 | (cons | ||
| 281 | (thumbs-decrement-image-size-element (car s) | ||
| 282 | thumbs-image-resizing-step) | ||
| 283 | (thumbs-decrement-image-size-element (cdr s) | ||
| 284 | thumbs-image-resizing-step))) | ||
| 285 | |||
| 286 | (defun thumbs-resize-image (&optional increment size) | ||
| 287 | "Resize image in current buffer. | ||
| 288 | if INCREMENT is set, make the image bigger, else smaller. | ||
| 289 | Or, alternatively, a SIZE may be specified." | ||
| 290 | (interactive) | ||
| 291 | ;; cleaning of old temp file | ||
| 292 | (ignore-errors | ||
| 293 | (apply 'delete-file | ||
| 294 | (directory-files | ||
| 295 | thumbs-temp-dir t | ||
| 296 | thumbs-temp-prefix))) | ||
| 297 | (let ((buffer-read-only nil) | ||
| 298 | (x (if size | ||
| 299 | size | ||
| 300 | (if increment | ||
| 301 | (thumbs-increment-image-size | ||
| 302 | thumbs-current-image-size) | ||
| 303 | (thumbs-decrement-image-size | ||
| 304 | thumbs-current-image-size)))) | ||
| 305 | (tmp (format "%s%s.jpg" thumbs-temp-file (thumbs-gensym)))) | ||
| 306 | (erase-buffer) | ||
| 307 | (thumbs-call-convert thumbs-current-image-filename | ||
| 308 | tmp "sample" | ||
| 309 | (concat (number-to-string (car x)) "x" | ||
| 310 | (number-to-string (cdr x)))) | ||
| 311 | (thumbs-insert-image tmp 'jpeg 0) | ||
| 312 | (setq thumbs-current-tmp-filename tmp))) | ||
| 313 | |||
| 314 | (defun thumbs-resize-interactive (width height) | ||
| 315 | "Resize Image interactively to specified WIDTH and HEIGHT." | ||
| 316 | (interactive "nWidth: \nnHeight: ") | ||
| 317 | (thumbs-resize-image nil (cons width height))) | ||
| 318 | |||
| 319 | (defun thumbs-resize-image-size-down () | ||
| 320 | "Resize image (smaller)." | ||
| 321 | (interactive) | ||
| 322 | (thumbs-resize-image nil)) | ||
| 323 | |||
| 324 | (defun thumbs-resize-image-size-up () | ||
| 325 | "Resize image (bigger)." | ||
| 326 | (interactive) | ||
| 327 | (thumbs-resize-image t)) | ||
| 328 | |||
| 329 | (defun thumbs-subst-char-in-string (orig rep string) | ||
| 330 | "Replace occurrences of character ORIG with character REP in STRING. | ||
| 331 | Return the resulting (new) string. -- (defun borowed to Dave Love)" | ||
| 332 | (let ((string (copy-sequence string)) | ||
| 333 | (l (length string)) | ||
| 334 | (i 0)) | ||
| 335 | (while (< i l) | ||
| 336 | (if (= (aref string i) orig) | ||
| 337 | (aset string i rep)) | ||
| 338 | (setq i (1+ i))) | ||
| 339 | string)) | ||
| 340 | |||
| 341 | (defun thumbs-thumbname (img) | ||
| 342 | "Return a thumbnail name for the image IMG." | ||
| 343 | (concat thumbs-thumbsdir "/" | ||
| 344 | (thumbs-subst-char-in-string | ||
| 345 | ?\ ?\_ | ||
| 346 | (apply | ||
| 347 | 'concat | ||
| 348 | (split-string | ||
| 349 | (expand-file-name img) "/"))))) | ||
| 350 | |||
| 351 | (defun thumbs-make-thumb (img) | ||
| 352 | "Create the thumbnail for IMG." | ||
| 353 | (let* ((fn (expand-file-name img)) | ||
| 354 | (tn (thumbs-thumbname img))) | ||
| 355 | (if (or (not (file-exists-p tn)) | ||
| 356 | (not (equal (thumbs-file-size tn) thumbs-geometry))) | ||
| 357 | (thumbs-call-convert fn tn "sample" thumbs-geometry)) | ||
| 358 | tn)) | ||
| 359 | |||
| 360 | (defun thumbs-image-type (img) | ||
| 361 | "Return image type from filename IMG." | ||
| 362 | (cond ((string-match ".*\\.jpe?g\\'" img) 'jpeg) | ||
| 363 | ((string-match ".*\\.xpm\\'" img) 'xpm) | ||
| 364 | ((string-match ".*\\.xbm\\'" img) 'xbm) | ||
| 365 | ((string-match ".*\\.gif\\'" img) 'gif) | ||
| 366 | ((string-match ".*\\.bmp\\'" img) 'bmp) | ||
| 367 | ((string-match ".*\\.png\\'" img) 'png) | ||
| 368 | ((string-match ".*\\.tiff?\\'" img) 'tiff))) | ||
| 369 | |||
| 370 | (defun thumbs-file-size (img) | ||
| 371 | (let ((i (image-size (find-image `((:type ,(thumbs-image-type img) :file ,img))) t))) | ||
| 372 | (concat (number-to-string (round (car i))) | ||
| 373 | "x" | ||
| 374 | (number-to-string (round (cdr i)))))) | ||
| 375 | |||
| 376 | ;;;###autoload | ||
| 377 | (defun thumbs-find-thumb (img) | ||
| 378 | "Display the thumbnail for IMG." | ||
| 379 | (interactive "f") | ||
| 380 | (find-file (thumbs-make-thumb img))) | ||
| 381 | |||
| 382 | (defun thumbs-insert-image (img type relief &optional marked) | ||
| 383 | "Insert image IMG at point. | ||
| 384 | TYPE and RELIEF will be used in constructing the image; see `image' | ||
| 385 | in the emacs-lisp manual for further documentation. | ||
| 386 | if MARKED is non-nil, the image is marked." | ||
| 387 | (let ((i `(image :type ,type | ||
| 388 | :file ,img | ||
| 389 | :relief ,relief | ||
| 390 | :conversion ,(if marked 'disabled) | ||
| 391 | :margin ,thumbs-margin))) | ||
| 392 | (insert-image i) | ||
| 393 | (setq thumbs-current-image-size | ||
| 394 | (image-size i t)))) | ||
| 395 | |||
| 396 | (defun thumbs-insert-thumb (img &optional marked) | ||
| 397 | "Insert the thumbnail for IMG at point. | ||
| 398 | if MARKED is non-nil, the image is marked" | ||
| 399 | (thumbs-insert-image | ||
| 400 | (thumbs-make-thumb img) 'jpeg thumbs-relief marked)) | ||
| 401 | |||
| 402 | (defun thumbs-do-thumbs-insertion (L) | ||
| 403 | "Insert all thumbs in list L." | ||
| 404 | (setq thumbs-fileL nil) | ||
| 405 | (let ((i 0)) | ||
| 406 | (while L | ||
| 407 | (when (= 0 (mod (setq i (1+ i)) thumbs-per-line)) | ||
| 408 | (newline)) | ||
| 409 | (setq thumbs-fileL (cons (cons (point) | ||
| 410 | (car L)) | ||
| 411 | thumbs-fileL)) | ||
| 412 | (thumbs-insert-thumb (car L) | ||
| 413 | (member (car L) thumbs-markedL)) | ||
| 414 | (setq L (cdr L))))) | ||
| 415 | |||
| 416 | (defun thumbs-show-thumbs-list (L &optional buffer-name same-window) | ||
| 417 | (funcall (if same-window 'switch-to-buffer 'pop-to-buffer) | ||
| 418 | (or buffer-name "*THUMB-View*")) | ||
| 419 | (let ((inhibit-read-only t)) | ||
| 420 | (erase-buffer) | ||
| 421 | (thumbs-mode) | ||
| 422 | (make-variable-buffer-local 'thumbs-fileL) | ||
| 423 | (setq thumbs-fileL nil) | ||
| 424 | (thumbs-do-thumbs-insertion L) | ||
| 425 | (goto-char (point-min)) | ||
| 426 | (setq thumbs-current-dir default-directory) | ||
| 427 | (make-variable-buffer-local 'thumbs-current-dir))) | ||
| 428 | |||
| 429 | ;;;###autoload | ||
| 430 | (defun thumbs-show-all-from-dir (dir &optional reg same-window) | ||
| 431 | "Make a preview buffer for all images in DIR. | ||
| 432 | Optional argument REG to select file matching a regexp, | ||
| 433 | and SAME-WINDOW to show thumbs in the same window." | ||
| 434 | (interactive "DDir: ") | ||
| 435 | (thumbs-show-thumbs-list | ||
| 436 | (directory-files dir t | ||
| 437 | (or reg (image-file-name-regexp))) | ||
| 438 | (concat "*Thumbs: " dir) same-window)) | ||
| 439 | |||
| 440 | ;;;###autoload | ||
| 441 | (defun thumbs-dired-show-marked () | ||
| 442 | "In Dired, make a thumbs buffer with all marked files." | ||
| 443 | (interactive) | ||
| 444 | (thumbs-show-thumbs-list (dired-get-marked-files) nil t)) | ||
| 445 | |||
| 446 | ;;;###autoload | ||
| 447 | (defun thumbs-dired-show-all () | ||
| 448 | "In dired, make a thumbs buffer with all files in current directory." | ||
| 449 | (interactive) | ||
| 450 | (thumbs-show-all-from-dir default-directory nil t)) | ||
| 451 | |||
| 452 | ;;;###autoload | ||
| 453 | (defalias 'thumbs 'thumbs-show-all-from-dir) | ||
| 454 | |||
| 455 | (defun thumbs-find-image (img L &optional num otherwin) | ||
| 456 | (funcall | ||
| 457 | (if otherwin 'switch-to-buffer-other-window 'switch-to-buffer) | ||
| 458 | (concat "*Image: " (file-name-nondirectory img) " - " | ||
| 459 | (number-to-string (or num 0)) "*")) | ||
| 460 | (thumbs-view-image-mode) | ||
| 461 | (let ((inhibit-read-only t)) | ||
| 462 | (setq thumbs-current-image-filename img | ||
| 463 | thumbs-current-tmp-filename nil | ||
| 464 | thumbs-image-num (or num 0)) | ||
| 465 | (make-variable-buffer-local 'thumbs-current-image-filename) | ||
| 466 | (make-variable-buffer-local 'thumbs-current-tmp-filename) | ||
| 467 | (make-variable-buffer-local 'thumbs-current-image-size) | ||
| 468 | (make-variable-buffer-local 'thumbs-image-num) | ||
| 469 | (make-variable-buffer-local 'thumbs-fileL) | ||
| 470 | (setq thumbs-fileL L) | ||
| 471 | (delete-region (point-min)(point-max)) | ||
| 472 | (thumbs-insert-image img (thumbs-image-type img) 0))) | ||
| 473 | |||
| 474 | (defun thumbs-find-image-at-point (&optional img otherwin) | ||
| 475 | "Display image IMG for thumbnail at point. | ||
| 476 | use another window it OTHERWIN is t." | ||
| 477 | (interactive) | ||
| 478 | (let* ((L thumbs-fileL) | ||
| 479 | (n (point)) | ||
| 480 | (i (or img (cdr (assoc n L))))) | ||
| 481 | (thumbs-find-image i L n otherwin))) | ||
| 482 | |||
| 483 | (defun thumbs-find-image-at-point-other-window () | ||
| 484 | "Display image for thumbnail at point in the preview buffer. | ||
| 485 | Open another window." | ||
| 486 | (interactive) | ||
| 487 | (thumbs-find-image-at-point nil t)) | ||
| 488 | |||
| 489 | (defun thumbs-call-setroot-command (img) | ||
| 490 | "Call the setroot program for IMG." | ||
| 491 | (run-hooks 'thumbs-before-setroot-hook) | ||
| 492 | (shell-command (replace-regexp-in-string | ||
| 493 | "\\*" | ||
| 494 | (shell-quote-argument (expand-file-name img)) | ||
| 495 | thumbs-setroot-command nil t)) | ||
| 496 | (run-hooks 'thumbs-after-setroot-hook)) | ||
| 497 | |||
| 498 | (defun thumbs-set-image-at-point-to-root-window () | ||
| 499 | "Set the image at point as the desktop wallpaper." | ||
| 500 | (interactive) | ||
| 501 | (thumbs-call-setroot-command (cdr (assoc (point) thumbs-fileL)))) | ||
| 502 | |||
| 503 | (defun thumbs-set-root () | ||
| 504 | "Set the current image as root." | ||
| 505 | (interactive) | ||
| 506 | (thumbs-call-setroot-command | ||
| 507 | (or thumbs-current-tmp-filename | ||
| 508 | thumbs-current-image-filename))) | ||
| 509 | |||
| 510 | (defun thumbs-delete-images () | ||
| 511 | "Delete the image at point (and it's thumbnail) (or marked files if any)." | ||
| 512 | (interactive) | ||
| 513 | (let ((f (or thumbs-markedL (list (cdr (assoc (point) thumbs-fileL)))))) | ||
| 514 | (if (yes-or-no-p "Really delete %d files?" (length f)) | ||
| 515 | (progn | ||
| 516 | (mapcar (lambda (x) | ||
| 517 | (setq thumbs-fileL (delete (rassoc x thumbs-fileL) thumbs-fileL)) | ||
| 518 | (delete-file x) | ||
| 519 | (delete-file (thumbs-thumbname x))) f) | ||
| 520 | (thumbs-redraw-buffer))))) | ||
| 521 | |||
| 522 | (defun thumbs-kill-buffer () | ||
| 523 | "Kill the current buffer." | ||
| 524 | (interactive) | ||
| 525 | (let ((buffer (current-buffer))) | ||
| 526 | (ignore-errors (delete-window (selected-window))) | ||
| 527 | (kill-buffer buffer))) | ||
| 528 | |||
| 529 | (defun thumbs-show-image-num (num) | ||
| 530 | "Show the image with number NUM." | ||
| 531 | (let ((inhibit-read-only t)) | ||
| 532 | (delete-region (point-min)(point-max)) | ||
| 533 | (let ((i (cdr (assoc num thumbs-fileL)))) | ||
| 534 | (thumbs-insert-image i (thumbs-image-type i) 0) | ||
| 535 | (sleep-for 2) | ||
| 536 | (rename-buffer (concat "*Image: " | ||
| 537 | (file-name-nondirectory i) | ||
| 538 | " - " | ||
| 539 | (number-to-string num) "*"))) | ||
| 540 | (setq thumbs-image-num num | ||
| 541 | thumbs-current-image-filename i))) | ||
| 542 | |||
| 543 | (defun thumbs-next-image () | ||
| 544 | "Show next image." | ||
| 545 | (interactive) | ||
| 546 | (let* ((i (1+ thumbs-image-num)) | ||
| 547 | (l (caar thumbs-fileL)) | ||
| 548 | (num | ||
| 549 | (cond ((assoc i thumbs-fileL) i) | ||
| 550 | ((>= i l) 1) | ||
| 551 | (t (1+ i))))) | ||
| 552 | (thumbs-show-image-num num))) | ||
| 553 | |||
| 554 | (defun thumbs-previous-image () | ||
| 555 | "Show the previous image." | ||
| 556 | (interactive) | ||
| 557 | (let* ((i (- thumbs-image-num 1)) | ||
| 558 | (l (caar thumbs-fileL)) | ||
| 559 | (num | ||
| 560 | (cond ((assoc i thumbs-fileL) i) | ||
| 561 | ((<= i 1) l) | ||
| 562 | (t (- i 1))))) | ||
| 563 | (thumbs-show-image-num num))) | ||
| 564 | |||
| 565 | (defun thumbs-redraw-buffer () | ||
| 566 | "Redraw the current thumbs buffer." | ||
| 567 | (let ((p (point)) | ||
| 568 | (inhibit-read-only t)) | ||
| 569 | (delete-region (point-min)(point-max)) | ||
| 570 | (thumbs-do-thumbs-insertion (reverse (mapcar 'cdr thumbs-fileL))) | ||
| 571 | (goto-char (1+ p)))) | ||
| 572 | |||
| 573 | (defun thumbs-mark () | ||
| 574 | "Mark the image at point." | ||
| 575 | (interactive) | ||
| 576 | (setq thumbs-markedL (cons (cdr (assoc (point) thumbs-fileL)) thumbs-markedL)) | ||
| 577 | (let ((inhibit-read-only t)) | ||
| 578 | (delete-char 1) | ||
| 579 | (thumbs-insert-thumb (cdr (assoc (point) thumbs-fileL)) t)) | ||
| 580 | (when (eolp)(forward-char))) | ||
| 581 | |||
| 582 | ;; Image modification routines | ||
| 583 | |||
| 584 | (defun thumbs-modify-image (action &optional arg) | ||
| 585 | "Call convert to do ACTION on image with argument ARG. | ||
| 586 | ACTION and ARG should be legal convert command." | ||
| 587 | (interactive "sAction: \nsValue: ") | ||
| 588 | ;; cleaning of old temp file | ||
| 589 | (mapc 'delete-file | ||
| 590 | (directory-files | ||
| 591 | thumbs-temp-dir | ||
| 592 | t | ||
| 593 | thumbs-temp-prefix)) | ||
| 594 | (let ((buffer-read-only nil) | ||
| 595 | (tmp (format "%s%s.jpg" thumbs-temp-file (thumbs-gensym)))) | ||
| 596 | (erase-buffer) | ||
| 597 | (thumbs-call-convert thumbs-current-image-filename | ||
| 598 | tmp | ||
| 599 | action | ||
| 600 | (or arg "")) | ||
| 601 | (thumbs-insert-image tmp 'jpeg 0) | ||
| 602 | (setq thumbs-current-tmp-filename tmp))) | ||
| 603 | |||
| 604 | (defun thumbs-emboss-image (emboss) | ||
| 605 | "Emboss the image with value EMBOSS." | ||
| 606 | (interactive "nEmboss value: ") | ||
| 607 | (if (or (< emboss 3)(> emboss 31)(evenp emboss)) | ||
| 608 | (error "Arg must be a odd number between 3 and 31")) | ||
| 609 | (thumbs-modify-image "emboss" (number-to-string emboss))) | ||
| 610 | |||
| 611 | (defun thumbs-monochrome-image () | ||
| 612 | "Turn the image to monochrome." | ||
| 613 | (interactive) | ||
| 614 | (thumbs-modify-image "monochrome")) | ||
| 615 | |||
| 616 | (defun thumbs-negate-image () | ||
| 617 | "Negate the image." | ||
| 618 | (interactive) | ||
| 619 | (thumbs-modify-image "negate")) | ||
| 620 | |||
| 621 | (defun thumbs-rotate-left () | ||
| 622 | "Rotate the image 90 degrees counter-clockwise." | ||
| 623 | (interactive) | ||
| 624 | (thumbs-modify-image "rotate" "270")) | ||
| 625 | |||
| 626 | (defun thumbs-rotate-right () | ||
| 627 | "Rotate the image 90 degrees clockwise." | ||
| 628 | (interactive) | ||
| 629 | (thumbs-modify-image "rotate" "90")) | ||
| 630 | |||
| 631 | (defun thumbs-forward-char () | ||
| 632 | "Move forward one image." | ||
| 633 | (interactive) | ||
| 634 | (forward-char) | ||
| 635 | (when (eolp)(forward-char)) | ||
| 636 | (thumbs-show-name)) | ||
| 637 | |||
| 638 | (defun thumbs-backward-char () | ||
| 639 | "Move backward one image." | ||
| 640 | (interactive) | ||
| 641 | (forward-char -1) | ||
| 642 | (thumbs-show-name)) | ||
| 643 | |||
| 644 | (defun thumbs-forward-line () | ||
| 645 | "Move down one line." | ||
| 646 | (interactive) | ||
| 647 | (forward-line 1) | ||
| 648 | (thumbs-show-name)) | ||
| 649 | |||
| 650 | (defun thumbs-backward-line () | ||
| 651 | "Move up one line." | ||
| 652 | (interactive) | ||
| 653 | (forward-line -1) | ||
| 654 | (thumbs-show-name)) | ||
| 655 | |||
| 656 | (defun thumbs-show-name () | ||
| 657 | "Show the name of the current file." | ||
| 658 | (interactive) | ||
| 659 | (let ((f (cdr (assoc (point) thumbs-fileL)))) | ||
| 660 | (message "%s [%s]" f (thumbs-file-size f)))) | ||
| 661 | |||
| 662 | (defun thumbs-save-current-image () | ||
| 663 | "Save the current image." | ||
| 664 | (interactive) | ||
| 665 | (let ((f (or thumbs-current-tmp-filename | ||
| 666 | thumbs-current-image-filename)) | ||
| 667 | (sa (read-from-minibuffer "save file as: " | ||
| 668 | thumbs-current-image-filename))) | ||
| 669 | (copy-file f sa))) | ||
| 670 | |||
| 671 | (defun thumbs-dired () | ||
| 672 | "Use `dired' on the current thumbs directory." | ||
| 673 | (interactive) | ||
| 674 | (dired thumbs-current-dir)) | ||
| 675 | |||
| 676 | ;; thumbs-mode | ||
| 677 | |||
| 678 | (defvar thumbs-mode-map | ||
| 679 | (let ((map (make-sparse-keymap))) | ||
| 680 | (define-key map [return] 'thumbs-find-image-at-point) | ||
| 681 | (define-key map [(meta return)] 'thumbs-find-image-at-point-other-window) | ||
| 682 | (define-key map [(control return)] 'thumbs-set-image-at-point-to-root-window) | ||
| 683 | (define-key map [delete] 'thumbs-delete-images) | ||
| 684 | (define-key map [right] 'thumbs-forward-char) | ||
| 685 | (define-key map [left] 'thumbs-backward-char) | ||
| 686 | (define-key map [up] 'thumbs-backward-line) | ||
| 687 | (define-key map [down] 'thumbs-forward-line) | ||
| 688 | (define-key map "d" 'thumbs-dired) | ||
| 689 | (define-key map "m" 'thumbs-mark) | ||
| 690 | (define-key map "s" 'thumbs-show-name) | ||
| 691 | (define-key map "q" 'thumbs-kill-buffer) | ||
| 692 | map) | ||
| 693 | "Keymap for `thumbs-mode'.") | ||
| 694 | |||
| 695 | (define-derived-mode thumbs-mode | ||
| 696 | fundamental-mode "thumbs" | ||
| 697 | "Preview images in a thumbnails buffer" | ||
| 698 | (make-variable-buffer-local 'thumbs-markedL) | ||
| 699 | (setq thumbs-markedL nil)) | ||
| 700 | |||
| 701 | (defvar thumbs-view-image-mode-map | ||
| 702 | (let ((map (make-sparse-keymap))) | ||
| 703 | (define-key map [prior] 'thumbs-previous-image) | ||
| 704 | (define-key map [next] 'thumbs-next-image) | ||
| 705 | (define-key map "-" 'thumbs-resize-image-size-down) | ||
| 706 | (define-key map "+" 'thumbs-resize-image-size-up) | ||
| 707 | (define-key map "<" 'thumbs-rotate-left) | ||
| 708 | (define-key map ">" 'thumbs-rotate-right) | ||
| 709 | (define-key map "e" 'thumbs-emboss-image) | ||
| 710 | (define-key map "r" 'thumbs-resize-interactive) | ||
| 711 | (define-key map "s" 'thumbs-save-current-image) | ||
| 712 | (define-key map "q" 'thumbs-kill-buffer) | ||
| 713 | (define-key map "w" 'thunbs-set-root) | ||
| 714 | map) | ||
| 715 | "Keymap for `thumbs-view-image-mode'.") | ||
| 716 | |||
| 717 | ;; thumbs-view-image-mode | ||
| 718 | (define-derived-mode thumbs-view-image-mode | ||
| 719 | fundamental-mode "image-view-mode") | ||
| 720 | |||
| 721 | ;;;###autoload | ||
| 722 | (defun thumbs-dired-setroot () | ||
| 723 | "In dired, Call the setroot program on the image at point." | ||
| 724 | (interactive) | ||
| 725 | (thumbs-call-setroot-command (dired-get-filename))) | ||
| 726 | |||
| 727 | ;; Modif to dired mode map | ||
| 728 | (define-key dired-mode-map "\C-ta" 'thumbs-dired-show-all) | ||
| 729 | (define-key dired-mode-map "\C-tm" 'thumbs-dired-show-marked) | ||
| 730 | (define-key dired-mode-map "\C-tw" 'thumbs-dired-setroot) | ||
| 731 | |||
| 732 | (provide 'thumbs) | ||
| 733 | |||
| 734 | ;;; thumbs.el ends here | ||
| 735 | |||
| 736 | |||
| 737 | ;;; arch-tag: f9ac1ef8-83fc-42c0-8069-1fae43fd2e5c | ||