emacs-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Emacs-diffs] /srv/bzr/emacs/trunk r111083: * lisp/sort.el (delete-dupli


From: Juri Linkov
Subject: [Emacs-diffs] /srv/bzr/emacs/trunk r111083: * lisp/sort.el (delete-duplicate-lines): New command.
Date: Tue, 04 Dec 2012 01:49:08 +0200
User-agent: Bazaar (2.5.0)

------------------------------------------------------------
revno: 111083
fixes bug: http://debbugs.gnu.org/13032
committer: Juri Linkov <address@hidden>
branch nick: trunk
timestamp: Tue 2012-12-04 01:49:08 +0200
message:
  * lisp/sort.el (delete-duplicate-lines): New command.
modified:
  etc/NEWS
  lisp/ChangeLog
  lisp/sort.el
=== modified file 'etc/NEWS'
--- a/etc/NEWS  2012-12-03 01:08:31 +0000
+++ b/etc/NEWS  2012-12-03 23:49:08 +0000
@@ -69,6 +69,11 @@
   name and arguments.  Useful to trace the value of (current-buffer) or
   (point) when the function is invoked.
 
+** New command `delete-duplicate-lines' has two types of operation:
+when its arg ADJACENT is non-nil (when called interactively with C-u C-u)
+it works like the utility `uniq'.  Otherwise by default it deletes
+duplicate lines everywhere in the region without regard to adjacency.
+
 ** Woman
 
 *** The commands `woman-default-faces' and `woman-monochrome-faces'

=== modified file 'lisp/ChangeLog'
--- a/lisp/ChangeLog    2012-12-03 17:23:42 +0000
+++ b/lisp/ChangeLog    2012-12-03 23:49:08 +0000
@@ -1,3 +1,7 @@
+2012-12-03  Juri Linkov  <address@hidden>
+
+       * sort.el (delete-duplicate-lines): New command.  (Bug#13032)
+
 2012-12-03  Agustín Martín Domingo  <address@hidden>
 
        * textmodes/ispell.el (ispell-init-process)

=== modified file 'lisp/sort.el'
--- a/lisp/sort.el      2012-08-03 08:15:24 +0000
+++ b/lisp/sort.el      2012-12-03 23:49:08 +0000
@@ -562,6 +562,62 @@
        (setq ll (cdr ll)))
       (insert (car ll)))))
 
+;;;###autoload
+(defun delete-duplicate-lines (beg end &optional reverse adjacent interactive)
+  "Delete duplicate lines in the region between BEG and END.
+
+If REVERSE is nil, search and delete duplicates forward keeping the first
+occurrence of duplicate lines.  If REVERSE is non-nil (when called
+interactively with C-u prefix), search and delete duplicates backward
+keeping the last occurrence of duplicate lines.
+
+If ADJACENT is non-nil (when called interactively with two C-u prefixes),
+delete repeated lines only if they are adjacent.  It works like the utility
+`uniq' and is useful when lines are already sorted in a large file since
+this is more efficient in performance and memory usage than when ADJACENT
+is nil that uses additional memory to remember previous lines.
+
+When called from Lisp and INTERACTIVE is omitted or nil, return the number
+of deleted duplicate lines, do not print it; if INTERACTIVE is t, the
+function behaves in all respects as if it had been called interactively."
+  (interactive
+   (progn
+     (barf-if-buffer-read-only)
+     (list (region-beginning) (region-end)
+          (equal current-prefix-arg '(4))
+          (equal current-prefix-arg '(16))
+          t)))
+  (let ((lines (unless adjacent (make-hash-table :weakness 'key :test 'equal)))
+       line prev-line
+       (count 0)
+       (beg (copy-marker beg))
+       (end (copy-marker end)))
+    (save-excursion
+      (goto-char (if reverse end beg))
+      (if (and reverse (bolp)) (forward-char -1))
+      (while (if reverse
+                (and (> (point) beg) (not (bobp)))
+              (and (< (point) end) (not (eobp))))
+       (setq line (buffer-substring-no-properties
+                   (line-beginning-position) (line-end-position)))
+       (if (if adjacent (equal line prev-line) (gethash line lines))
+           (progn
+             (delete-region (progn (forward-line 0) (point))
+                            (progn (forward-line 1) (point)))
+             (if reverse (forward-line -1))
+             (setq count (1+ count)))
+         (if adjacent (setq prev-line line) (puthash line t lines))
+         (forward-line (if reverse -1 1)))))
+    (set-marker beg nil)
+    (set-marker end nil)
+    (when interactive
+      (message "Deleted %d %sduplicate line%s%s"
+              count
+              (if adjacent "adjacent " "")
+              (if (= count 1) "" "s")
+              (if reverse " backward" "")))
+    count))
+
 (provide 'sort)
 
 ;;; sort.el ends here


reply via email to

[Prev in Thread] Current Thread [Next in Thread]