diff options
| -rw-r--r-- | lisp/dired-x.el | 141 |
1 files changed, 98 insertions, 43 deletions
diff --git a/lisp/dired-x.el b/lisp/dired-x.el index eebfa91bb82..c90306aacbf 100644 --- a/lisp/dired-x.el +++ b/lisp/dired-x.el | |||
| @@ -1396,6 +1396,22 @@ Considers buffers closer to the car of `buffer-list' to be more recent." | |||
| 1396 | ;; result)) | 1396 | ;; result)) |
| 1397 | 1397 | ||
| 1398 | 1398 | ||
| 1399 | ;; Needed if ls -lh is supported and also for GNU ls -ls. | ||
| 1400 | (defun dired-x--string-to-number (str) | ||
| 1401 | "Like `string-to-number' but recognize a trailing unit prefix. | ||
| 1402 | For example, 2K is expanded to 2048.0. The caller should make | ||
| 1403 | sure that a trailing letter in STR is one of BKkMGTPEZY." | ||
| 1404 | (let* ((val (string-to-number str)) | ||
| 1405 | (u (unless (zerop val) | ||
| 1406 | (aref str (1- (length str)))))) | ||
| 1407 | (when (and u (> u ?9)) | ||
| 1408 | (when (= u ?k) | ||
| 1409 | (setq u ?K)) | ||
| 1410 | (let ((units '(?B ?K ?M ?G ?T ?P ?E ?Z ?Y))) | ||
| 1411 | (while (and units (/= (pop units) u)) | ||
| 1412 | (setq val (* 1024.0 val))))) | ||
| 1413 | val)) | ||
| 1414 | |||
| 1399 | ;; Does anyone use this? - lrd 6/29/93. | 1415 | ;; Does anyone use this? - lrd 6/29/93. |
| 1400 | ;; Apparently people do use it. - lrd 12/22/97. | 1416 | ;; Apparently people do use it. - lrd 12/22/97. |
| 1401 | 1417 | ||
| @@ -1422,7 +1438,19 @@ For example, use | |||
| 1422 | 1438 | ||
| 1423 | (equal 0 size) | 1439 | (equal 0 size) |
| 1424 | 1440 | ||
| 1425 | to mark all zero length files." | 1441 | to mark all zero length files. |
| 1442 | |||
| 1443 | There's an ambiguity when a single integer not followed by a unit | ||
| 1444 | prefix precedes the file mode: It is then parsed as inode number | ||
| 1445 | and not as block size (this always works for GNU coreutils ls). | ||
| 1446 | |||
| 1447 | Another limitation is that the uid field is needed for the | ||
| 1448 | function to work correctly. In particular, the field is not | ||
| 1449 | present for some values of `ls-lisp-emulation'. | ||
| 1450 | |||
| 1451 | This function operates only on the buffer content and does not | ||
| 1452 | refer at all to the underlying file system. Contrast this with | ||
| 1453 | `find-dired', which might be preferable for the task at hand." | ||
| 1426 | ;; Using sym="" instead of nil avoids the trap of | 1454 | ;; Using sym="" instead of nil avoids the trap of |
| 1427 | ;; (string-match "foo" sym) into which a user would soon fall. | 1455 | ;; (string-match "foo" sym) into which a user would soon fall. |
| 1428 | ;; Give `equal' instead of `=' in the example, as this works on | 1456 | ;; Give `equal' instead of `=' in the example, as this works on |
| @@ -1442,23 +1470,23 @@ to mark all zero length files." | |||
| 1442 | ;; to nil or the appropriate value, so they need not be initialized. | 1470 | ;; to nil or the appropriate value, so they need not be initialized. |
| 1443 | ;; Moves point within the current line. | 1471 | ;; Moves point within the current line. |
| 1444 | (dired-move-to-filename) | 1472 | (dired-move-to-filename) |
| 1445 | (let (pos | 1473 | (let ((mode-len 10) ; length of mode string |
| 1446 | (mode-len 10) ; length of mode string | 1474 | ;; like in dired.el, but with subexpressions \1=inode, \2=s: |
| 1447 | ;; like in dired.el, but with subexpressions \1=inode, \2=s: | 1475 | ;; GNU ls -hs suffixes the block count with a unit and |
| 1448 | (dired-re-inode-size "\\s *\\([0-9]*\\)\\s *\\([0-9]*\\) ?")) | 1476 | ;; prints it as a float, FreeBSD does neither. |
| 1449 | (beginning-of-line) | 1477 | (dired-re-inode-size "\\=\\s *\\([0-9]+\\s +\\)?\ |
| 1450 | (forward-char 2) | 1478 | \\(?:\\([0-9]+\\(?:\\.[0-9]*\\)?[BkKMGTPEZY]?\\)? ?\\)")) |
| 1451 | (if (looking-at dired-re-inode-size) | 1479 | (beginning-of-line) |
| 1452 | (progn | 1480 | (forward-char 2) |
| 1453 | (goto-char (match-end 0)) | 1481 | (search-forward-regexp dired-re-inode-size nil t) |
| 1454 | (setq inode (string-to-number | 1482 | ;; XXX Might be a size not followed by a unit prefix. |
| 1455 | (buffer-substring (match-beginning 1) | 1483 | ;; We could set s to inode if it were otherwise nil, |
| 1456 | (match-end 1))) | 1484 | ;; with a similar reasoning as below for setting gid to uid, |
| 1457 | s (string-to-number | 1485 | ;; but it would be even more whimsical. |
| 1458 | (buffer-substring (match-beginning 2) | 1486 | (setq inode (when (match-string 1) |
| 1459 | (match-end 2))))) | 1487 | (string-to-number (match-string 1)))) |
| 1460 | (setq inode nil | 1488 | (setq s (when (match-string 2) |
| 1461 | s nil)) | 1489 | (dired-x--string-to-number (match-string 2)))) |
| 1462 | (setq mode (buffer-substring (point) (+ mode-len (point)))) | 1490 | (setq mode (buffer-substring (point) (+ mode-len (point)))) |
| 1463 | (forward-char mode-len) | 1491 | (forward-char mode-len) |
| 1464 | ;; Skip any extended attributes marker ("." or "+"). | 1492 | ;; Skip any extended attributes marker ("." or "+"). |
| @@ -1466,33 +1494,60 @@ to mark all zero length files." | |||
| 1466 | (forward-char 1)) | 1494 | (forward-char 1)) |
| 1467 | (setq nlink (read (current-buffer))) | 1495 | (setq nlink (read (current-buffer))) |
| 1468 | ;; Karsten Wenger <kw@cis.uni-muenchen.de> fixed uid. | 1496 | ;; Karsten Wenger <kw@cis.uni-muenchen.de> fixed uid. |
| 1469 | (setq uid (buffer-substring (1+ (point)) | 1497 | ;; Another issue is that GNU ls -n right-justifies numerical |
| 1470 | (progn (forward-word 1) (point)))) | 1498 | ;; UIDs and GIDs, while FreeBSD left-justifies them, so |
| 1471 | (re-search-forward directory-listing-before-filename-regexp) | 1499 | ;; don't rely on a specific whitespace layout. Both of them |
| 1472 | (goto-char (match-beginning 1)) | 1500 | ;; right-justify all other numbers, though. |
| 1473 | (forward-char -1) | 1501 | ;; XXX Return a number if the uid or gid seems to be |
| 1474 | (setq size (string-to-number | 1502 | ;; numerical? |
| 1475 | (buffer-substring (save-excursion | 1503 | (setq uid (buffer-substring (progn |
| 1476 | (backward-word 1) | 1504 | (skip-chars-forward " \t") |
| 1477 | (setq pos (point))) | 1505 | (point)) |
| 1506 | (progn | ||
| 1507 | (skip-chars-forward "^ \t") | ||
| 1478 | (point)))) | 1508 | (point)))) |
| 1479 | (goto-char pos) | 1509 | (dired-move-to-filename) |
| 1480 | (backward-word 1) | 1510 | (save-excursion |
| 1481 | ;; if no gid is displayed, gid will be set to uid | 1511 | (setq time |
| 1482 | ;; but user will then not reference it anyway in PREDICATE. | 1512 | ;; The regexp below tries to match from the last |
| 1483 | (setq gid (buffer-substring (save-excursion | 1513 | ;; digit of the size field through a space after the |
| 1484 | (forward-word 1) (point)) | 1514 | ;; date. Also, dates may have different formats |
| 1515 | ;; depending on file age, so the date column need | ||
| 1516 | ;; not be aligned to the right. | ||
| 1517 | (buffer-substring (save-excursion | ||
| 1518 | (skip-chars-backward " \t") | ||
| 1485 | (point)) | 1519 | (point)) |
| 1486 | time (buffer-substring (match-beginning 1) | 1520 | (progn |
| 1487 | (1- (dired-move-to-filename))) | 1521 | (re-search-backward |
| 1488 | name (buffer-substring (point) | 1522 | directory-listing-before-filename-regexp) |
| 1489 | (or | 1523 | (skip-chars-forward "^ \t") |
| 1490 | (dired-move-to-end-of-filename t) | 1524 | (1+ (point)))) |
| 1491 | (point))) | 1525 | size (dired-x--string-to-number |
| 1492 | sym (if (looking-at-p " -> ") | 1526 | ;; We know that there's some kind of number |
| 1493 | (buffer-substring (progn (forward-char 4) (point)) | 1527 | ;; before point because the regexp search |
| 1494 | (line-end-position)) | 1528 | ;; above succeeded. I don't think it's worth |
| 1495 | "")) | 1529 | ;; doing an extra check for leading garbage. |
| 1530 | (buffer-substring (point) | ||
| 1531 | (progn | ||
| 1532 | (skip-chars-backward "^ \t") | ||
| 1533 | (point)))) | ||
| 1534 | ;; If no gid is displayed, gid will be set to uid | ||
| 1535 | ;; but the user will then not reference it anyway in | ||
| 1536 | ;; PREDICATE. | ||
| 1537 | gid (buffer-substring (progn | ||
| 1538 | (skip-chars-backward " \t") | ||
| 1539 | (point)) | ||
| 1540 | (progn | ||
| 1541 | (skip-chars-backward "^ \t") | ||
| 1542 | (point))))) | ||
| 1543 | (setq name (buffer-substring (point) | ||
| 1544 | (or | ||
| 1545 | (dired-move-to-end-of-filename t) | ||
| 1546 | (point))) | ||
| 1547 | sym (if (looking-at " -> ") | ||
| 1548 | (buffer-substring (progn (forward-char 4) (point)) | ||
| 1549 | (line-end-position)) | ||
| 1550 | "")) | ||
| 1496 | t) | 1551 | t) |
| 1497 | (eval predicate | 1552 | (eval predicate |
| 1498 | `((inode . ,inode) | 1553 | `((inode . ,inode) |