diff options
| author | Eli Zaretskii | 2014-09-01 18:03:45 +0300 |
|---|---|---|
| committer | Eli Zaretskii | 2014-09-01 18:03:45 +0300 |
| commit | cd6f709c4b2be2044df54969f8302278a6c8c42a (patch) | |
| tree | 430d463864fa90f6ff37b7099c872527cbcd193f | |
| parent | 0360ec583aa754eb746ca6772ca6ca0f0212d546 (diff) | |
| download | emacs-cd6f709c4b2be2044df54969f8302278a6c8c42a.tar.gz emacs-cd6f709c4b2be2044df54969f8302278a6c8c42a.zip | |
Implement the GNU ls -v switch in ls-lisp.el.
lisp/ls-lisp.el (ls-lisp-version-lessp): New function.
(ls-lisp-handle-switches): Use it to implement the -v switch of GNU ls.
(ls-lisp--insert-directory): Mention the -v switch in the doc string.
Fixes: debbugs:18051
| -rw-r--r-- | lisp/ChangeLog | 5 | ||||
| -rw-r--r-- | lisp/ls-lisp.el | 66 |
2 files changed, 70 insertions, 1 deletions
diff --git a/lisp/ChangeLog b/lisp/ChangeLog index 47185e01f5e..5f89308e597 100644 --- a/lisp/ChangeLog +++ b/lisp/ChangeLog | |||
| @@ -4,6 +4,11 @@ | |||
| 4 | (ls-lisp-UCA-like-collation): New defcustoms. | 4 | (ls-lisp-UCA-like-collation): New defcustoms. |
| 5 | (ls-lisp-string-lessp): Use them to control sorting by file | 5 | (ls-lisp-string-lessp): Use them to control sorting by file |
| 6 | names. (Bug#18051) | 6 | names. (Bug#18051) |
| 7 | (ls-lisp-version-lessp): New function. | ||
| 8 | (ls-lisp-handle-switches): Use it to implement the -v switch of | ||
| 9 | GNU ls. | ||
| 10 | (ls-lisp--insert-directory): Mention the -v switch in the doc | ||
| 11 | string. | ||
| 7 | 12 | ||
| 8 | 2014-08-31 Christoph Scholtes <cschol2112@gmail.com> | 13 | 2014-08-31 Christoph Scholtes <cschol2112@gmail.com> |
| 9 | 14 | ||
diff --git a/lisp/ls-lisp.el b/lisp/ls-lisp.el index 410b44999f6..b8ea8d07f05 100644 --- a/lisp/ls-lisp.el +++ b/lisp/ls-lisp.el | |||
| @@ -273,7 +273,7 @@ The Lisp emulation does not run any external programs or shells. It | |||
| 273 | supports ordinary shell wildcards if `ls-lisp-support-shell-wildcards' | 273 | supports ordinary shell wildcards if `ls-lisp-support-shell-wildcards' |
| 274 | is non-nil; otherwise, it interprets wildcards as regular expressions | 274 | is non-nil; otherwise, it interprets wildcards as regular expressions |
| 275 | to match file names. It does not support all `ls' switches -- those | 275 | to match file names. It does not support all `ls' switches -- those |
| 276 | that work are: A a B C c F G g h i n R r S s t U u X. The l switch | 276 | that work are: A a B C c F G g h i n R r S s t U u v X. The l switch |
| 277 | is assumed to be always present and cannot be turned off." | 277 | is assumed to be always present and cannot be turned off." |
| 278 | (if ls-lisp-use-insert-directory-program | 278 | (if ls-lisp-use-insert-directory-program |
| 279 | (funcall orig-fun | 279 | (funcall orig-fun |
| @@ -551,6 +551,67 @@ to a non-nil value." | |||
| 551 | (let ((u (compare-strings s1 0 nil s2 0 nil ls-lisp-ignore-case))) | 551 | (let ((u (compare-strings s1 0 nil s2 0 nil ls-lisp-ignore-case))) |
| 552 | (and (numberp u) (< u 0)))))) | 552 | (and (numberp u) (< u 0)))))) |
| 553 | 553 | ||
| 554 | (defun ls-lisp-version-lessp (s1 s2) | ||
| 555 | "Return t if versioned string S1 should sort before versioned string S2. | ||
| 556 | |||
| 557 | Case is significant if `ls-lisp-ignore-case' is nil. | ||
| 558 | This is the same as string-lessp (with the exception of case | ||
| 559 | insensitivity), but sequences of digits are compared numerically, | ||
| 560 | as a whole, in the same manner as the `strverscmp' function available | ||
| 561 | in some standard C libraries does." | ||
| 562 | (let ((i1 0) | ||
| 563 | (i2 0) | ||
| 564 | (len1 (length s1)) | ||
| 565 | (len2 (length s2)) | ||
| 566 | (val 0) | ||
| 567 | ni1 ni2 e1 e2 found-2-numbers-p) | ||
| 568 | (while (and (< i1 len1) (< i2 len2) (zerop val)) | ||
| 569 | (unless found-2-numbers-p | ||
| 570 | (setq ni1 (string-match "[0-9]+" s1 i1) | ||
| 571 | e1 (match-end 0)) | ||
| 572 | (setq ni2 (string-match "[0-9]+" s2 i2) | ||
| 573 | e2 (match-end 0))) | ||
| 574 | (cond | ||
| 575 | ((and ni1 ni2) | ||
| 576 | (cond | ||
| 577 | ((and (> ni1 i1) (> ni2 i2)) | ||
| 578 | ;; Compare non-numerical part as strings. | ||
| 579 | (setq val (compare-strings s1 i1 ni1 s2 i2 ni2 ls-lisp-ignore-case) | ||
| 580 | i1 ni1 | ||
| 581 | i2 ni2 | ||
| 582 | found-2-numbers-p t)) | ||
| 583 | ((and (= ni1 i1) (= ni2 i2)) | ||
| 584 | (setq found-2-numbers-p nil) | ||
| 585 | ;; Compare numerical parts as integral and/or fractional parts. | ||
| 586 | (let* ((sub1 (substring s1 ni1 e1)) | ||
| 587 | (sub2 (substring s2 ni2 e2)) | ||
| 588 | ;; "Fraction" is a numerical sequence with leading zeros. | ||
| 589 | (fr1 (string-match "\\`0+" sub1)) | ||
| 590 | (fr2 (string-match "\\`0+" sub2))) | ||
| 591 | (cond | ||
| 592 | ((and fr1 fr2) ; two fractions, the shortest wins | ||
| 593 | (setq val (- val (- (length sub1) (length sub2))))) | ||
| 594 | (fr1 ; a fraction is always less than an integral | ||
| 595 | (setq val (- ni1))) | ||
| 596 | (fr2 | ||
| 597 | (setq val ni2))) | ||
| 598 | (if (zerop val) ; fall back on numerical comparison | ||
| 599 | (setq val (- (string-to-number sub1) | ||
| 600 | (string-to-number sub2)))) | ||
| 601 | (setq i1 e1 | ||
| 602 | i2 e2))) | ||
| 603 | (t | ||
| 604 | (setq val (compare-strings s1 i1 nil s2 i2 nil ls-lisp-ignore-case) | ||
| 605 | i1 len1 | ||
| 606 | i2 len2)))) | ||
| 607 | (t (setq val (compare-strings s1 i1 nil s2 i2 nil ls-lisp-ignore-case) | ||
| 608 | i1 len1 | ||
| 609 | i2 len2))) | ||
| 610 | (and (eq val t) (setq val 0))) | ||
| 611 | (if (zerop val) | ||
| 612 | (setq val (- len1 len2))) | ||
| 613 | (< val 0))) | ||
| 614 | |||
| 554 | (defun ls-lisp-handle-switches (file-alist switches) | 615 | (defun ls-lisp-handle-switches (file-alist switches) |
| 555 | "Return new FILE-ALIST sorted according to SWITCHES. | 616 | "Return new FILE-ALIST sorted according to SWITCHES. |
| 556 | SWITCHES is a list of characters. Default sorting is alphabetic." | 617 | SWITCHES is a list of characters. Default sorting is alphabetic." |
| @@ -577,6 +638,9 @@ SWITCHES is a list of characters. Default sorting is alphabetic." | |||
| 577 | (ls-lisp-string-lessp | 638 | (ls-lisp-string-lessp |
| 578 | (ls-lisp-extension (car x)) | 639 | (ls-lisp-extension (car x)) |
| 579 | (ls-lisp-extension (car y))))) | 640 | (ls-lisp-extension (car y))))) |
| 641 | ((memq ?v switches) | ||
| 642 | (lambda (x y) ; sorted by version number | ||
| 643 | (ls-lisp-version-lessp (car x) (car y)))) | ||
| 580 | (t | 644 | (t |
| 581 | (lambda (x y) ; sorted alphabetically | 645 | (lambda (x y) ; sorted alphabetically |
| 582 | (ls-lisp-string-lessp (car x) (car y)))))))) | 646 | (ls-lisp-string-lessp (car x) (car y)))))))) |