aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--lisp/dired-x.el141
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.
1402For example, 2K is expanded to 2048.0. The caller should make
1403sure 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
1425to mark all zero length files." 1441to mark all zero length files.
1442
1443There's an ambiguity when a single integer not followed by a unit
1444prefix precedes the file mode: It is then parsed as inode number
1445and not as block size (this always works for GNU coreutils ls).
1446
1447Another limitation is that the uid field is needed for the
1448function to work correctly. In particular, the field is not
1449present for some values of `ls-lisp-emulation'.
1450
1451This function operates only on the buffer content and does not
1452refer 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)