aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJuri Linkov2012-12-04 01:49:08 +0200
committerJuri Linkov2012-12-04 01:49:08 +0200
commitc38a186c2e06e0a351d166c5ef06d7307e145f45 (patch)
tree21c24e9ae0de6c192f0b00e0386b3e14d4bc8eae
parent9320b007d5518a4e1966e168286a3a3182e9e4d8 (diff)
downloademacs-c38a186c2e06e0a351d166c5ef06d7307e145f45.tar.gz
emacs-c38a186c2e06e0a351d166c5ef06d7307e145f45.zip
* lisp/sort.el (delete-duplicate-lines): New command.
Fixes: debbugs:13032
-rw-r--r--etc/NEWS5
-rw-r--r--lisp/ChangeLog4
-rw-r--r--lisp/sort.el56
3 files changed, 65 insertions, 0 deletions
diff --git a/etc/NEWS b/etc/NEWS
index fd1e5bb2a21..b175843828d 100644
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -69,6 +69,11 @@ New features include:
69 name and arguments. Useful to trace the value of (current-buffer) or 69 name and arguments. Useful to trace the value of (current-buffer) or
70 (point) when the function is invoked. 70 (point) when the function is invoked.
71 71
72** New command `delete-duplicate-lines' has two types of operation:
73when its arg ADJACENT is non-nil (when called interactively with C-u C-u)
74it works like the utility `uniq'. Otherwise by default it deletes
75duplicate lines everywhere in the region without regard to adjacency.
76
72** Woman 77** Woman
73 78
74*** The commands `woman-default-faces' and `woman-monochrome-faces' 79*** The commands `woman-default-faces' and `woman-monochrome-faces'
diff --git a/lisp/ChangeLog b/lisp/ChangeLog
index 891e6771503..f4963a07a92 100644
--- a/lisp/ChangeLog
+++ b/lisp/ChangeLog
@@ -1,3 +1,7 @@
12012-12-03 Juri Linkov <juri@jurta.org>
2
3 * sort.el (delete-duplicate-lines): New command. (Bug#13032)
4
12012-12-03 Agustín Martín Domingo <agustin.martin@hispalinux.es> 52012-12-03 Agustín Martín Domingo <agustin.martin@hispalinux.es>
2 6
3 * textmodes/ispell.el (ispell-init-process) 7 * textmodes/ispell.el (ispell-init-process)
diff --git a/lisp/sort.el b/lisp/sort.el
index 44f90fff379..cd0b4433ab3 100644
--- a/lisp/sort.el
+++ b/lisp/sort.el
@@ -562,6 +562,62 @@ From a program takes two point or marker arguments, BEG and END."
562 (setq ll (cdr ll))) 562 (setq ll (cdr ll)))
563 (insert (car ll))))) 563 (insert (car ll)))))
564 564
565;;;###autoload
566(defun delete-duplicate-lines (beg end &optional reverse adjacent interactive)
567 "Delete duplicate lines in the region between BEG and END.
568
569If REVERSE is nil, search and delete duplicates forward keeping the first
570occurrence of duplicate lines. If REVERSE is non-nil (when called
571interactively with C-u prefix), search and delete duplicates backward
572keeping the last occurrence of duplicate lines.
573
574If ADJACENT is non-nil (when called interactively with two C-u prefixes),
575delete repeated lines only if they are adjacent. It works like the utility
576`uniq' and is useful when lines are already sorted in a large file since
577this is more efficient in performance and memory usage than when ADJACENT
578is nil that uses additional memory to remember previous lines.
579
580When called from Lisp and INTERACTIVE is omitted or nil, return the number
581of deleted duplicate lines, do not print it; if INTERACTIVE is t, the
582function behaves in all respects as if it had been called interactively."
583 (interactive
584 (progn
585 (barf-if-buffer-read-only)
586 (list (region-beginning) (region-end)
587 (equal current-prefix-arg '(4))
588 (equal current-prefix-arg '(16))
589 t)))
590 (let ((lines (unless adjacent (make-hash-table :weakness 'key :test 'equal)))
591 line prev-line
592 (count 0)
593 (beg (copy-marker beg))
594 (end (copy-marker end)))
595 (save-excursion
596 (goto-char (if reverse end beg))
597 (if (and reverse (bolp)) (forward-char -1))
598 (while (if reverse
599 (and (> (point) beg) (not (bobp)))
600 (and (< (point) end) (not (eobp))))
601 (setq line (buffer-substring-no-properties
602 (line-beginning-position) (line-end-position)))
603 (if (if adjacent (equal line prev-line) (gethash line lines))
604 (progn
605 (delete-region (progn (forward-line 0) (point))
606 (progn (forward-line 1) (point)))
607 (if reverse (forward-line -1))
608 (setq count (1+ count)))
609 (if adjacent (setq prev-line line) (puthash line t lines))
610 (forward-line (if reverse -1 1)))))
611 (set-marker beg nil)
612 (set-marker end nil)
613 (when interactive
614 (message "Deleted %d %sduplicate line%s%s"
615 count
616 (if adjacent "adjacent " "")
617 (if (= count 1) "" "s")
618 (if reverse " backward" "")))
619 count))
620
565(provide 'sort) 621(provide 'sort)
566 622
567;;; sort.el ends here 623;;; sort.el ends here