en modo org, ¿cómo eliminar un enlace?

11

¿Cómo elimino un hipervínculo existente sin tener que vadear y eliminar manualmente un par de paréntesis? Cuando intento org-insert-linky simplemente elimino el enlace existente, obtengo Lisp error: (error "Empty link").

Quiero eliminar el enlace y preservar el texto (es decir, la descripción).

hombre incandescente
fuente

Respuestas:

7

La siguiente función elisp tomará un enlace alrededor del punto actual como se reconoce por org-bracket-link-regexp, por lo tanto , [[Link][Description]]o [[Link]], y lo reemplazará por Descriptionen el primer caso o Linken el segundo caso.

(defun afs/org-replace-link-by-link-description ()
    "Replace an org link by its description or if empty its address"
  (interactive)
  (if (org-in-regexp org-bracket-link-regexp 1)
      (let ((remove (list (match-beginning 0) (match-end 0)))
        (description (if (match-end 3) 
                 (org-match-string-no-properties 3)
                 (org-match-string-no-properties 1))))
    (apply 'delete-region remove)
    (insert description))))
Andrew Swann
fuente
¡Esa es una solución compacta muy ordenada! También actualicé mi respuesta para admitir [[LINK]]enlaces de organización de formato. Aprendí sobre match-beginningy match-endde tu respuesta.
Kaushal Modi
5

Traté de agregar esto a la respuesta de @Andrew, pero fue demasiado largo para un comentario ...

Realmente me gustó su solución, excepto que movió el cursor. (Técnicamente supongo que movió el punto. De todos modos ...) Afortunadamente, fue fácil agregarlo save-excursionpara evitar eso:

(defun afs/org-replace-link-by-link-description ()
  "Replace an org link by its description or if empty its address"
  (interactive)
  (if (org-in-regexp org-bracket-link-regexp 1)
      (save-excursion
        (let ((remove (list (match-beginning 0) (match-end 0)))
              (description (if (match-end 3) 
                               (org-match-string-no-properties 3)
                             (org-match-string-no-properties 1))))
          (apply 'delete-region remove)
          (insert description)))))
Chris
fuente
4

Llame a este comando cuando el punto esté en cualquier lugar después de los primeros [[corchetes de un enlace de organización (o en cualquier lugar en / después de un enlace de organización hipervinculado).

Se eliminará un enlace de organización si tiene el formato [[LINK][DESCRIPTION]]o está [[LINK]]en un org-modebúfer; de lo contrario no pasará nada.

Por seguridad, el ENLACE descartado de org-link se guarda kill-ringen el caso de que surja la necesidad de usar ese enlace en otro lugar.

(defun my/org-delete-link ()
  "Replace an org link of the format [[LINK][DESCRIPTION]] with DESCRIPTION.
If the link is of the format [[LINK]], delete the whole org link.

In both the cases, save the LINK to the kill-ring.

Execute this command while the point is on or after the hyper-linked org link."
  (interactive)
  (when (derived-mode-p 'org-mode)
    (let ((search-invisible t) start end)
      (save-excursion
        (when (re-search-backward "\\[\\[" nil :noerror)
          (when (re-search-forward "\\[\\[\\(.*?\\)\\(\\]\\[.*?\\)*\\]\\]" nil :noerror)
            (setq start (match-beginning 0))
            (setq end   (match-end 0))
            (kill-new (match-string-no-properties 1)) ; Save the link to kill-ring
            (replace-regexp "\\[\\[.*?\\(\\]\\[\\(.*?\\)\\)*\\]\\]" "\\2" nil start end)))))))
Kaushal Modi
fuente
1

Lo más rápido puede ser colocar el cursor antes del enlace, luego escribir C-M-space( mark-sexp), que marcará el enlace completo. Luego bórrelo escribiendo un retroceso (si lo usa delete-selection-mode) o C-w.

Harald Hanche-Olsen
fuente
1
Esto parece eliminar todo el enlace, pero quiero eliminar el enlace y preservar el texto (es decir, la descripción).
incandescentman
1
Lo siento, supongo que no entendí tu pregunta.
Harald Hanche-Olsen
1
Para los que votaron por ahí: la pregunta fue ambigua cuando la respondí. Ha sido editado desde entonces, eliminando la ambigüedad. Sin embargo, dejo la respuesta, ya que todavía parece la forma más fácil de eliminar todo el enlace, la descripción y todo.
Harald Hanche-Olsen
1

Hay una solución que evita el uso de análisis personalizados con expresiones regulares y utiliza directamente la org-elementAPI incorporada :

(defun org-link-delete-link ()
  "Remove the link part of an org-mode link at point and keep
only the description"
  (interactive)
  (let ((elem (org-element-context)))
    (if (eq (car elem) 'link)
        (let* ((content-begin (org-element-property :contents-begin elem))
               (content-end  (org-element-property :contents-end elem))
               (link-begin (org-element-property :begin elem))
               (link-end (org-element-property :end elem)))
          (if (and content-begin content-end)
              (let ((content (buffer-substring-no-properties content-begin content-end)))
                (delete-region link-begin link-end)
                (insert content)))))))
usuario22270
fuente
¿Puedes agregar cómo vincular tu comando a una tecla para que sea suficiente para los principiantes?
DoMiNeLa10
Esto parece eliminar espacios en blanco después del enlace. ¿Alguna idea de cómo mantenerlos?
Timm
0

Esta macro muy rápida y muy sucia sería unidireccional, no la mejor:

(fset 'my/org-remove-link
   [?\M-a delete delete ?\M-x ?z ?a ?p ?- ?t ?o ?- ?c ?h ?a ?r return ?\[ ?\C-e backspace backspace ?\C-x])
Brian Z
fuente