diff options
| -rw-r--r-- | lisp/arc-mode.el | 140 |
1 files changed, 97 insertions, 43 deletions
diff --git a/lisp/arc-mode.el b/lisp/arc-mode.el index 8f3ebd1f439..ca5d6185337 100644 --- a/lisp/arc-mode.el +++ b/lisp/arc-mode.el | |||
| @@ -690,6 +690,7 @@ is visible (and the real data of the buffer is hidden). | |||
| 690 | Optional argument SHUT-UP, if non-nil, means don't print messages | 690 | Optional argument SHUT-UP, if non-nil, means don't print messages |
| 691 | when parsing the archive." | 691 | when parsing the archive." |
| 692 | (widen) | 692 | (widen) |
| 693 | (set-buffer-multibyte nil) | ||
| 693 | (let (buffer-read-only) | 694 | (let (buffer-read-only) |
| 694 | (or shut-up | 695 | (or shut-up |
| 695 | (message "Parsing archive file...")) | 696 | (message "Parsing archive file...")) |
| @@ -827,6 +828,41 @@ using `make-temp-name', and the generated name is returned." | |||
| 827 | ;; ------------------------------------------------------------------------- | 828 | ;; ------------------------------------------------------------------------- |
| 828 | ;; Section: Member extraction | 829 | ;; Section: Member extraction |
| 829 | 830 | ||
| 831 | (defun archive-file-name-handler (op &rest args) | ||
| 832 | (or (eq op 'file-exists-p) | ||
| 833 | (let ((file-name-handler-alist nil)) | ||
| 834 | (apply op args)))) | ||
| 835 | |||
| 836 | (defun archive-set-buffer-as-visiting-file (filename) | ||
| 837 | "Set the current buffer as if it were visiting FILENAME." | ||
| 838 | (save-excursion | ||
| 839 | (goto-char (point-min)) | ||
| 840 | (let ((coding | ||
| 841 | (or coding-system-for-read | ||
| 842 | (and set-auto-coding-function | ||
| 843 | (funcall set-auto-coding-function | ||
| 844 | (- (point-max) (point-min)))) | ||
| 845 | ;; dos-w32.el defines find-operation-coding-system for | ||
| 846 | ;; DOS/Windows systems which preserves the coding-system | ||
| 847 | ;; of existing files. We want it to act here as if the | ||
| 848 | ;; extracted file existed. | ||
| 849 | (let ((file-name-handler-alist | ||
| 850 | '(("" . archive-file-name-handler)))) | ||
| 851 | (car (find-operation-coding-system 'insert-file-contents | ||
| 852 | filename t)))))) | ||
| 853 | (if (and (not coding-system-for-read) | ||
| 854 | (not enable-multibyte-characters)) | ||
| 855 | (setq coding | ||
| 856 | (coding-system-change-text-conversion coding 'raw-text))) | ||
| 857 | (if (and coding | ||
| 858 | (not (eq coding 'no-conversion))) | ||
| 859 | (decode-coding-region (point-min) (point-max) coding) | ||
| 860 | (setq last-coding-system-used coding)) | ||
| 861 | (set-buffer-modified-p nil) | ||
| 862 | (kill-local-variable 'buffer-file-coding-system) | ||
| 863 | (after-insert-file-set-buffer-file-coding-system (- (point-max) | ||
| 864 | (point-min)))))) | ||
| 865 | |||
| 830 | (defun archive-mouse-extract (event) | 866 | (defun archive-mouse-extract (event) |
| 831 | "Extract a file whose name you click on." | 867 | "Extract a file whose name you click on." |
| 832 | (interactive "e") | 868 | (interactive "e") |
| @@ -876,27 +912,26 @@ using `make-temp-name', and the generated name is returned." | |||
| 876 | (setq archive-subfile-mode descr) | 912 | (setq archive-subfile-mode descr) |
| 877 | (if (and | 913 | (if (and |
| 878 | (null | 914 | (null |
| 879 | (condition-case err | 915 | (let (;; We may have to encode file name arguement for |
| 880 | (if (fboundp extractor) | 916 | ;; external programs. |
| 881 | (funcall extractor archive ename) | 917 | (coding-system-for-write file-name-coding-system) |
| 882 | (archive-*-extract archive ename | 918 | ;; We read an archive member by no-conversion at |
| 883 | (symbol-value extractor))) | 919 | ;; first, then decode appropriately by calling |
| 884 | (error | 920 | ;; archive-set-buffer-as-visiting-file later. |
| 885 | (ding (message "%s" (error-message-string err))) | 921 | (coding-system-for-read 'no-conversion)) |
| 886 | nil))) | 922 | (condition-case err |
| 923 | (if (fboundp extractor) | ||
| 924 | (funcall extractor archive ename) | ||
| 925 | (archive-*-extract archive ename | ||
| 926 | (symbol-value extractor))) | ||
| 927 | (error | ||
| 928 | (ding (message "%s" (error-message-string err))) | ||
| 929 | nil)))) | ||
| 887 | just-created) | 930 | just-created) |
| 888 | (progn | 931 | (progn |
| 889 | (set-buffer-modified-p nil) | 932 | (set-buffer-modified-p nil) |
| 890 | (kill-buffer buffer)) | 933 | (kill-buffer buffer)) |
| 891 | ;; If Emacs were to visit the file we've extracted, it would make | 934 | (archive-set-buffer-as-visiting-file ename) |
| 892 | ;; the buffer be unibyte if the detected coding-system is | ||
| 893 | ;; no-conversion or raw-text-*. We want the same behavior here | ||
| 894 | ;; as if we were visiting the file, even though some extractors | ||
| 895 | ;; read the file's contents from a pipe. | ||
| 896 | (if (or (eq last-coding-system-used 'no-conversion) | ||
| 897 | ;; type 5 is raw-text | ||
| 898 | (eq (coding-system-type last-coding-system-used) 5)) | ||
| 899 | (set-buffer-multibyte nil)) | ||
| 900 | (goto-char (point-min)) | 935 | (goto-char (point-min)) |
| 901 | (rename-buffer bufname) | 936 | (rename-buffer bufname) |
| 902 | (setq buffer-read-only read-only-p) | 937 | (setq buffer-read-only read-only-p) |
| @@ -955,17 +990,12 @@ using `make-temp-name', and the generated name is returned." | |||
| 955 | success)) | 990 | success)) |
| 956 | 991 | ||
| 957 | (defun archive-extract-by-stdout (archive name command) | 992 | (defun archive-extract-by-stdout (archive name command) |
| 958 | ;; We need the coding system of the output of the extract program, | 993 | (apply 'call-process |
| 959 | ;; including the EOL encoding, be decoded dynamically, since what | 994 | (car command) |
| 960 | ;; the extract program outputs is the contents of some file. | 995 | nil |
| 961 | (let ((coding-system-for-read (or coding-system-for-read 'undecided)) | 996 | t |
| 962 | (inherit-process-coding-system t)) | 997 | nil |
| 963 | (apply 'call-process | 998 | (append (cdr command) (list archive name)))) |
| 964 | (car command) | ||
| 965 | nil | ||
| 966 | t | ||
| 967 | nil | ||
| 968 | (append (cdr command) (list archive name))))) | ||
| 969 | 999 | ||
| 970 | (defun archive-extract-other-window () | 1000 | (defun archive-extract-other-window () |
| 971 | "In archive mode, find this member in another window." | 1001 | "In archive mode, find this member in another window." |
| @@ -1068,6 +1098,7 @@ using `make-temp-name', and the generated name is returned." | |||
| 1068 | (if (aref descr 3) | 1098 | (if (aref descr 3) |
| 1069 | ;; Set the file modes, but make sure we can read it. | 1099 | ;; Set the file modes, but make sure we can read it. |
| 1070 | (set-file-modes tmpfile (logior ?\400 (aref descr 3)))) | 1100 | (set-file-modes tmpfile (logior ?\400 (aref descr 3)))) |
| 1101 | (setq ename (encode-coding-string ename file-name-coding-system)) | ||
| 1071 | (let ((exitcode (apply 'call-process | 1102 | (let ((exitcode (apply 'call-process |
| 1072 | (car command) | 1103 | (car command) |
| 1073 | nil | 1104 | nil |
| @@ -1245,7 +1276,9 @@ as a relative change like \"g+rw\" as for chmod(2)" | |||
| 1245 | (descr (archive-get-descr))) | 1276 | (descr (archive-get-descr))) |
| 1246 | (if (fboundp func) | 1277 | (if (fboundp func) |
| 1247 | (progn | 1278 | (progn |
| 1248 | (funcall func (buffer-file-name) newname descr) | 1279 | (funcall func (buffer-file-name) |
| 1280 | (encode-coding-string newname file-name-coding-system) | ||
| 1281 | descr) | ||
| 1249 | (archive-resummarize)) | 1282 | (archive-resummarize)) |
| 1250 | (error "Renaming is not supported for this archive type")))) | 1283 | (error "Renaming is not supported for this archive type")))) |
| 1251 | 1284 | ||
| @@ -1255,6 +1288,7 @@ as a relative change like \"g+rw\" as for chmod(2)" | |||
| 1255 | (setq archive-files nil) | 1288 | (setq archive-files nil) |
| 1256 | (let ((revert-buffer-function nil) | 1289 | (let ((revert-buffer-function nil) |
| 1257 | (coding-system-for-read 'no-conversion)) | 1290 | (coding-system-for-read 'no-conversion)) |
| 1291 | (set-buffer-multibyte nil) | ||
| 1258 | (revert-buffer t t)) | 1292 | (revert-buffer t t)) |
| 1259 | (archive-mode) | 1293 | (archive-mode) |
| 1260 | (goto-char archive-file-list-start) | 1294 | (goto-char archive-file-list-start) |
| @@ -1327,6 +1361,7 @@ This doesn't recover lost files, it just undoes changes in the buffer itself." | |||
| 1327 | (save-restriction | 1361 | (save-restriction |
| 1328 | (save-excursion | 1362 | (save-excursion |
| 1329 | (widen) | 1363 | (widen) |
| 1364 | (set-buffer-multibyte nil) | ||
| 1330 | (goto-char (+ archive-proper-file-start (aref descr 4) 2)) | 1365 | (goto-char (+ archive-proper-file-start (aref descr 4) 2)) |
| 1331 | (delete-char 13) | 1366 | (delete-char 13) |
| 1332 | (insert name))))) | 1367 | (insert name))))) |
| @@ -1348,9 +1383,13 @@ This doesn't recover lost files, it just undoes changes in the buffer itself." | |||
| 1348 | (moddate (archive-l-e (+ p 17) 2)) | 1383 | (moddate (archive-l-e (+ p 17) 2)) |
| 1349 | (hdrlvl (char-after (+ p 20))) | 1384 | (hdrlvl (char-after (+ p 20))) |
| 1350 | (fnlen (char-after (+ p 21))) | 1385 | (fnlen (char-after (+ p 21))) |
| 1351 | (efnname (buffer-substring (+ p 22) (+ p 22 fnlen))) | 1386 | (efnname (let ((str (buffer-substring (+ p 22) (+ p 22 fnlen)))) |
| 1387 | (if file-name-coding-system | ||
| 1388 | (decode-coding-string str file-name-coding-system) | ||
| 1389 | (string-as-multibyte str)))) | ||
| 1352 | (fiddle (string= efnname (upcase efnname))) | 1390 | (fiddle (string= efnname (upcase efnname))) |
| 1353 | (ifnname (if fiddle (downcase efnname) efnname)) | 1391 | (ifnname (if fiddle (downcase efnname) efnname)) |
| 1392 | (width (string-width ifnname)) | ||
| 1354 | (p2 (+ p 22 fnlen)) | 1393 | (p2 (+ p 22 fnlen)) |
| 1355 | (creator (if (>= (- hsize fnlen) 24) (char-after (+ p2 2)) 0)) | 1394 | (creator (if (>= (- hsize fnlen) 24) (char-after (+ p2 2)) 0)) |
| 1356 | mode modestr uid gid text path prname | 1395 | mode modestr uid gid text path prname |
| @@ -1395,7 +1434,7 @@ This doesn't recover lost files, it just undoes changes in the buffer itself." | |||
| 1395 | (archive-dosdate moddate) | 1434 | (archive-dosdate moddate) |
| 1396 | (archive-dostime modtime) | 1435 | (archive-dostime modtime) |
| 1397 | ifnname))) | 1436 | ifnname))) |
| 1398 | (setq maxlen (max maxlen fnlen) | 1437 | (setq maxlen (max maxlen width) |
| 1399 | totalsize (+ totalsize ucsize) | 1438 | totalsize (+ totalsize ucsize) |
| 1400 | visual (cons (vector text | 1439 | visual (cons (vector text |
| 1401 | (- (length text) (length ifnname)) | 1440 | (- (length text) (length ifnname)) |
| @@ -1405,6 +1444,7 @@ This doesn't recover lost files, it just undoes changes in the buffer itself." | |||
| 1405 | files) | 1444 | files) |
| 1406 | p (+ p hsize 2 csize)))) | 1445 | p (+ p hsize 2 csize)))) |
| 1407 | (goto-char (point-min)) | 1446 | (goto-char (point-min)) |
| 1447 | (set-buffer-multibyte default-enable-multibyte-characters) | ||
| 1408 | (let ((dash (concat (if archive-alternate-display | 1448 | (let ((dash (concat (if archive-alternate-display |
| 1409 | "- -------- ----- ----- " | 1449 | "- -------- ----- ----- " |
| 1410 | "- ---------- -------- ----------- -------- ") | 1450 | "- ---------- -------- ----------- -------- ") |
| @@ -1443,6 +1483,7 @@ This doesn't recover lost files, it just undoes changes in the buffer itself." | |||
| 1443 | (save-restriction | 1483 | (save-restriction |
| 1444 | (save-excursion | 1484 | (save-excursion |
| 1445 | (widen) | 1485 | (widen) |
| 1486 | (set-buffer-multibyte nil) | ||
| 1446 | (let* ((p (+ archive-proper-file-start (aref descr 4))) | 1487 | (let* ((p (+ archive-proper-file-start (aref descr 4))) |
| 1447 | (oldhsize (char-after p)) | 1488 | (oldhsize (char-after p)) |
| 1448 | (oldfnlen (char-after (+ p 21))) | 1489 | (oldfnlen (char-after (+ p 21))) |
| @@ -1462,6 +1503,7 @@ This doesn't recover lost files, it just undoes changes in the buffer itself." | |||
| 1462 | (save-restriction | 1503 | (save-restriction |
| 1463 | (save-excursion | 1504 | (save-excursion |
| 1464 | (widen) | 1505 | (widen) |
| 1506 | (set-buffer-multibyte nil) | ||
| 1465 | (while files | 1507 | (while files |
| 1466 | (let* ((fil (car files)) | 1508 | (let* ((fil (car files)) |
| 1467 | (p (+ archive-proper-file-start (aref fil 4))) | 1509 | (p (+ archive-proper-file-start (aref fil 4))) |
| @@ -1516,7 +1558,10 @@ This doesn't recover lost files, it just undoes changes in the buffer itself." | |||
| 1516 | (exlen (archive-l-e (+ p 30) 2)) | 1558 | (exlen (archive-l-e (+ p 30) 2)) |
| 1517 | (fclen (archive-l-e (+ p 32) 2)) | 1559 | (fclen (archive-l-e (+ p 32) 2)) |
| 1518 | (lheader (archive-l-e (+ p 42) 4)) | 1560 | (lheader (archive-l-e (+ p 42) 4)) |
| 1519 | (efnname (buffer-substring (+ p 46) (+ p 46 fnlen))) | 1561 | (efnname (let ((str (buffer-substring (+ p 46) (+ p 46 fnlen)))) |
| 1562 | (if file-name-coding-system | ||
| 1563 | (decode-coding-string str file-name-coding-system) | ||
| 1564 | (string-as-multibyte str)))) | ||
| 1520 | (isdir (and (= ucsize 0) | 1565 | (isdir (and (= ucsize 0) |
| 1521 | (string= (file-name-nondirectory efnname) ""))) | 1566 | (string= (file-name-nondirectory efnname) ""))) |
| 1522 | (mode (cond ((memq creator '(2 3)) ; Unix + VMS | 1567 | (mode (cond ((memq creator '(2 3)) ; Unix + VMS |
| @@ -1533,13 +1578,14 @@ This doesn't recover lost files, it just undoes changes in the buffer itself." | |||
| 1533 | (not (not (memq creator '(0 2 4 5 9)))) | 1578 | (not (not (memq creator '(0 2 4 5 9)))) |
| 1534 | (string= (upcase efnname) efnname))) | 1579 | (string= (upcase efnname) efnname))) |
| 1535 | (ifnname (if fiddle (downcase efnname) efnname)) | 1580 | (ifnname (if fiddle (downcase efnname) efnname)) |
| 1581 | (width (string-width ifnname)) | ||
| 1536 | (text (format " %10s %8d %-11s %-8s %s" | 1582 | (text (format " %10s %8d %-11s %-8s %s" |
| 1537 | modestr | 1583 | modestr |
| 1538 | ucsize | 1584 | ucsize |
| 1539 | (archive-dosdate moddate) | 1585 | (archive-dosdate moddate) |
| 1540 | (archive-dostime modtime) | 1586 | (archive-dostime modtime) |
| 1541 | ifnname))) | 1587 | ifnname))) |
| 1542 | (setq maxlen (max maxlen fnlen) | 1588 | (setq maxlen (max maxlen width) |
| 1543 | totalsize (+ totalsize ucsize) | 1589 | totalsize (+ totalsize ucsize) |
| 1544 | visual (cons (vector text | 1590 | visual (cons (vector text |
| 1545 | (- (length text) (length ifnname)) | 1591 | (- (length text) (length ifnname)) |
| @@ -1581,6 +1627,7 @@ This doesn't recover lost files, it just undoes changes in the buffer itself." | |||
| 1581 | (save-restriction | 1627 | (save-restriction |
| 1582 | (save-excursion | 1628 | (save-excursion |
| 1583 | (widen) | 1629 | (widen) |
| 1630 | (set-buffer-multibyte nil) | ||
| 1584 | (while files | 1631 | (while files |
| 1585 | (let* ((fil (car files)) | 1632 | (let* ((fil (car files)) |
| 1586 | (p (+ archive-proper-file-start (car (aref fil 4)))) | 1633 | (p (+ archive-proper-file-start (car (aref fil 4)))) |
| @@ -1619,23 +1666,30 @@ This doesn't recover lost files, it just undoes changes in the buffer itself." | |||
| 1619 | (lfnlen (if (= dirtype 2) (char-after (+ p 56)) 0)) | 1666 | (lfnlen (if (= dirtype 2) (char-after (+ p 56)) 0)) |
| 1620 | (ldirlen (if (= dirtype 2) (char-after (+ p 57)) 0)) | 1667 | (ldirlen (if (= dirtype 2) (char-after (+ p 57)) 0)) |
| 1621 | (fnlen (or (string-match "\0" namefld) 13)) | 1668 | (fnlen (or (string-match "\0" namefld) 13)) |
| 1622 | (efnname (concat | 1669 | (efnname (let ((str |
| 1623 | (if (> ldirlen 0) | 1670 | (concat |
| 1624 | (concat (buffer-substring | 1671 | (if (> ldirlen 0) |
| 1625 | (+ p 58 lfnlen) (+ p 58 lfnlen ldirlen -1)) | 1672 | (concat (buffer-substring |
| 1626 | "/") | 1673 | (+ p 58 lfnlen) |
| 1627 | "") | 1674 | (+ p 58 lfnlen ldirlen -1)) |
| 1628 | (if (> lfnlen 0) | 1675 | "/") |
| 1629 | (buffer-substring (+ p 58) (+ p 58 lfnlen -1)) | 1676 | "") |
| 1630 | (substring namefld 0 fnlen)))) | 1677 | (if (> lfnlen 0) |
| 1678 | (buffer-substring (+ p 58) | ||
| 1679 | (+ p 58 lfnlen -1)) | ||
| 1680 | (substring namefld 0 fnlen))))) | ||
| 1681 | (if file-name-coding-system | ||
| 1682 | (decode-coding-string str file-name-coding-system) | ||
| 1683 | (string-as-multibyte str)))) | ||
| 1631 | (fiddle (and (= lfnlen 0) (string= efnname (upcase efnname)))) | 1684 | (fiddle (and (= lfnlen 0) (string= efnname (upcase efnname)))) |
| 1632 | (ifnname (if fiddle (downcase efnname) efnname)) | 1685 | (ifnname (if fiddle (downcase efnname) efnname)) |
| 1686 | (width (string-width ifnname)) | ||
| 1633 | (text (format " %8d %-11s %-8s %s" | 1687 | (text (format " %8d %-11s %-8s %s" |
| 1634 | ucsize | 1688 | ucsize |
| 1635 | (archive-dosdate moddate) | 1689 | (archive-dosdate moddate) |
| 1636 | (archive-dostime modtime) | 1690 | (archive-dostime modtime) |
| 1637 | ifnname))) | 1691 | ifnname))) |
| 1638 | (setq maxlen (max maxlen (length ifnname)) | 1692 | (setq maxlen (max maxlen (length width)) |
| 1639 | totalsize (+ totalsize ucsize) | 1693 | totalsize (+ totalsize ucsize) |
| 1640 | visual (cons (vector text | 1694 | visual (cons (vector text |
| 1641 | (- (length text) (length ifnname)) | 1695 | (- (length text) (length ifnname)) |