en mode org, comment supprimer un lien?

11

Comment supprimer un lien hypertexte existant sans avoir à entrer et supprimer manuellement un groupe de crochets? Lorsque j'essaie de org-insert-linksupprimer le lien existant, je reçois Lisp error: (error "Empty link").

Je souhaite supprimer le lien et conserver le texte (c'est-à-dire la description).

incandescentman
la source

Réponses:

7

La fonction elisp suivante prendra un lien autour du point actuel comme reconnu par org-bracket-link-regexp, donc soit [[Link][Description]]ou [[Link]], et le remplacera par Descriptiondans le premier cas ou Linkdans le second cas.

(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
la source
Voilà une solution compacte très soignée! J'ai également mis à jour ma réponse pour prendre en charge les [[LINK]]liens de format d'organisation. J'ai entendu parler de match-beginninget match-endde votre réponse.
Kaushal Modi
5

J'ai essayé d'ajouter ceci à la réponse de @Andrew, mais c'était trop long pour un commentaire ...

J'ai vraiment aimé sa solution, sauf qu'elle a déplacé le curseur. (Techniquement, je suppose que cela a fait bouger le sujet. Quoi qu'il en soit ...) Heureusement, il a été facile d'ajouter save-excursionpour éviter cela:

(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
la source
4

Appelez cette commande lorsque le point se trouve n'importe où après les premières [[crochets d'un lien organisationnel (ou n'importe où sur / après un lien organisationnel hyper-lié).

Un lien organisationnel sera supprimé s'il est au format [[LINK][DESCRIPTION]]ou [[LINK]]dans un org-modetampon; sinon rien ne se passera.

Pour des raisons de sécurité, le LIEN rejeté de org-link est enregistré kill-ringdans le cas où un besoin surviendrait d'utiliser ce lien ailleurs.

(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
la source
1

Le plus rapide peut être de placer le curseur avant le lien, puis de taper C-M-space( mark-sexp), qui marquera tout le lien. Ensuite, supprimez-le en tapant un retour arrière (si vous utilisez delete-selection-mode) ou C-w.

Harald Hanche-Olsen
la source
1
Cela semble supprimer le lien entier, mais je veux supprimer le lien et conserver le texte (c'est-à-dire la description).
incandescentman
1
Désolé, je suppose que j'ai mal compris votre question.
Harald Hanche-Olsen
1
Pour les downvoters là-bas: La question était ambiguë quand j'ai répondu. Il a été modifié depuis lors, levant l'ambiguïté. Je laisse la réponse, cependant, car cela semble toujours le moyen le plus simple de supprimer le lien, la description et tout.
Harald Hanche-Olsen
1

Il existe une solution qui évite d'utiliser une analyse personnalisée avec des expressions rationnelles et utilise directement l' org-elementAPI intégrée :

(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)))))))
user22270
la source
Pouvez-vous ajouter comment lier votre commande à une clé pour qu'elle soit suffisante pour les novices?
DoMiNeLa10
Cela semble supprimer les espaces blancs après le lien. Une idée de comment les garder?
Timm
0

Cette macro très rapide et très sale serait une façon, pas la meilleure:

(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
la source