The following code advices delete-duplicate-lines
to get what you want but retains as much of the behavior of the original version as possible.
EDIT: Note, that delete-region
is replaced by the corresponding subroutine in the compiled lisp file sort.elc
. So we need to reload the source code sort.el.gz
to advice delete-region
within delete-duplicate-lines
.
Make sure that you have have emacs24-el
installed on your system.
If you have sort.el
instead of sort.el.gz
you should adapt the load-library
line in the code.
You can detect where delete-duplicate-lines
is defined by C-h f delete-duplicate-lines
. If it just says compiled lisp function
but does not give you a source file name then you have only the byte compiled file sort.elc
. If you wanted to try the code below you need to get the corresponding source in some way. If the help page tells you that delete-duplicate-line
is defined in sort.el
, then click the corresponding link. It may be that the link leads you to sort.el
or sort.el.gz
anyway. In this case you are good with the code below.
(eval-when-compile
(require 'cl-macs))
(defun delete-duplicate-lines-interactive (oldfun &rest args)
"Make `delete-region' interactive in `delete-duplicate-lines'."
(let ((reverse (nth 2 args))
(adjacent (nth 3 args))
(arg-interactive (nth 5 args)))
(if arg-interactive
(let ((ol (make-overlay 1 1)))
(overlay-put ol 'face 'secondary-selection) ;; could be customizable
(unwind-protect
(let (continue
(deleted-lines 0))
(catch :quit
(advice-add 'delete-region
:around
(lambda (delete-region-original start end)
(if continue
(funcall delete-region-original start end)
(recenter)
(move-overlay ol start end)
(cl-case (let (mark-active) (read-key "Delete line? ([y]es, [n]ext, [!] all, [q]uit, any other key is equivalent to next):"))
(?y
(funcall delete-region-original start end)
(setq deleted-lines (1+ deleted-lines)))
(?!
(setq continue t)
(funcall delete-region-original start end)
(setq deleted-lines (1+ deleted-lines)))
(?q
(throw :quit nil))))
(when reverse (goto-char start)))
'((name . interactive)))
(apply oldfun args))
(message "Deleted %d %sduplicate line%s%s"
deleted-lines
(if adjacent "adjacent " "")
(if (= deleted-lines 1) "" "s")
(if reverse " backward" "")))
(advice-remove 'delete-region 'interactive))
(delete-overlay ol))
(apply oldfun args) ;; non-interactive case
)))
(advice-add 'delete-duplicate-lines :around
#'delete-duplicate-lines-interactive)
(load-library "sort.el") ;; Somehow `delete-region` is replaced in "sort.elc". Therefore load the source version again.
(defun delete-duplicate-lines-keep-blanks ()
(interactive)
(delete-duplicate-lines (region-beginning) (region-end) nil nil t t))