hacer que `delete-duplicate-lines` ignore las líneas en blanco y ciertas palabras

9

Estoy editando un texto en modo org, varias líneas se repiten ya que formaban parte de diferentes archivos del mismo tema.

Quiero usar delete-duplicate-linespara eliminar las líneas repetidas, sin embargo, el comando también elimina las líneas en blanco, que es algo que no quiero (¡de lo contrario no tendría párrafos!). Quiero ignorar ciertas palabras que existen solo en líneas, por ejemplo, "Reanudar" , se repite muchas veces en el texto, pero quiero mantenerlo ya que es obligatorio.

Shackra
fuente

Respuestas:

5

Ignorando líneas en blanco

Puede decir delete-duplicate-linesque ignore las líneas en blanco llamándolo a través de

C-u C-u C-u M-x delete-duplicate-lines RET

Si no desea tener que presionar C-utantas veces cuando llama delete-duplicate-lines, puede ajustarlo en un comando personalizado y vincular ese comando a una secuencia de teclas de su elección:

(defun delete-duplicate-lines-keep-blanks ()
  (interactive)
  (delete-duplicate-lines (region-beginning) (region-end) nil nil t))

(global-set-key (kbd "C-c d") 'delete-duplicate-lines-keep-blanks)

Ignorando líneas que coinciden con expresiones regulares

En cuanto a la segunda parte de su pregunta, no creo que pueda lograr lo que desea con la versión integrada de delete-duplicate-lines. Sin embargo, puede usar una versión modificada del comando (que también mantiene líneas en blanco de forma predeterminada):

(defun delete-duplicate-lines
    (beg end keep &optional reverse adjacent keep-blanks interactive)
  (interactive
   (progn
     (barf-if-buffer-read-only)
     (list (region-beginning) (region-end)
           (read-string "Keep lines matching regexp: ") ; Prompt for regexp to keep
           (equal current-prefix-arg '(4))
           (equal current-prefix-arg '(16))
           t                                            ; Keep blanks by default
           t)))
  (let ((lines (unless adjacent (make-hash-table :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 (or (and keep-blanks (string= "" line))
                (string-match keep line))               ; Ignore line if it
                                                        ; matches regexp to keep
            (forward-line 1)
          (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))

Esta versión de delete-duplicate-linesle pedirá una expresión regular y mantendrá todas las líneas que coincidan con la expresión regular. Por ejemplo, para mantener todas las líneas que consisten en la palabra Resumeque haría:

M-x delete-duplicate-lines RET ^Resume$ RET

itsjeyd
fuente