Obtenir un lien organisationnel pour insérer automatiquement la description du lien?

11

Q: Comment puis-je obtenir une orgfonction de lien personnalisé pour insérer automatiquement une description?

Je voudrais stocker des orgliens vers des fichiers dans un diredtampon, mais je préférerais que la description du lien soit le nom du fichier sans chemin plutôt que de signaler le chemin complet, c'est-à-dire:

file:~/the/full/path/myfile.ext     ; default, but no thanks
myfile.ext                          ; what I want

Maintenant: les org-store-linkcodes durs sont liés diredpour fournir la valeur par défaut. Au lieu de cela, j'ai écrit une fonction personnalisée (cribbing à partir de la fonction codée en dur) et l'ai ajoutée à org-store-link-functions:

(defun dired-store-link ()
  (when (derived-mode-p 'dired-mode)
    (let ((file (dired-get-filename nil t)))
      (setf file (if file
                     (abbreviate-file-name (expand-file-name file))
                   default-directory))
      (org-store-link-props :type        "dired"
                            :link        file
                            :description (file-name-nondirectory file))
      file)))

(add-to-list 'org-store-link-functions #'dired-store-link)

Jusqu'ici tout va bien, et cela fonctionne comme prévu, mais pour une chose:

  • Lors d'un appel org-insert-linkavec le comportement par défaut intégré, il insère simplement le lien sans me demander de description.
  • Lors de l'appel org-insert-linkavec ma fonction personnalisée, il m'invite à entrer une description (qu'il remplit correctement avec le nom de fichier stocké dans la :descriptionpropriété).

Je préfère ne pas être invité à entrer la description à chaque fois, et je souhaite org-insert-linkutiliser la valeur :descriptiondéfinie par la fonction personnalisée.

Comment puis-je convaincre org-insert-linkd'utiliser le :descriptionautomatiquement sans me le demander?

Dan
la source
Les arguments facultatifs link-locationou default-descriptiondans la fonction org-insert-linkaident-ils? Si le paramètre LINK-LOCATION n'est pas nul, cette valeur sera utilisée comme emplacement du lien au lieu de la lire de manière interactive. Si le paramètre DEFAULT-DESCRIPTION n'est pas nul, cette valeur sera utilisée comme description par défaut.
lawlist
@lawlist: merci pour la suggestion, même si je ne sais pas comment je la définirais en utilisation interactive sans l'envelopper dans une autre fonction. Cependant, cela m'a fait lire le docstring de plus près, ce qui m'a amené à une réponse en quelque sorte.
Dan

Réponses:

4

Enterré au bas de la docstring pour org-insert-linkest une note qui:

Si org-make-link-description-functionest non nul, cette fonction sera appelée avec la cible du lien et le résultat sera la description du lien par défaut.

Apparemment, orgjette beaucoup d'informations dans le processus de stockage d'un lien, il ne reste org-stored-linksdonc qu'une liste des entrées du formulaire (link description). Dans la mesure où la fonction antérieure a un nom de fichier pour le lien, cela ressemble aux travaux suivants:

(defun org-link-describe (link desc)
  (if (file-exists-p link)
      desc
    (read-string "Description: " desc)))

(setf org-make-link-description-function #'org-link-describe)

C'est un peu hacky, et je ne l'ai pas testé intensivement, mais cela semble fonctionner jusqu'à présent. Serait ravi de voir une solution plus élégante, bien sûr.

Dan
la source
2
Maintenant que vous connaissez cette fonction, ne pouvez-vous pas abandonner dired-store-linket simplement l'utiliser pour créer la description que vous voulez? Je pense que cela finirait par être beaucoup plus court.
Malabarba
1
@Malabarba: vous avez probablement raison - cette fonction pourrait être réécrite pour inspecter le lien d'un fichier et procéder en conséquence. Je vais l'essayer quand j'aurai un moment libre.
Dan
3

J'utilise org 9.1.6, et à ma grande consternation, il semble que ce org-store-link-functionssoit maintenant une fonction org intégrée (plutôt qu'un crochet), donc la solution d'origine ne fonctionne plus. Il peut y avoir une solution de contournement en utilisant org-link-parameters, mais à la place j'utilise le petit hack suivant, qui semble faire l'affaire:

(defun my//dired-store-link (orig-fun &rest args)
  (if (derived-mode-p 'dired-mode)
      (let ((file (dired-get-filename nil t)))
        (setf file (if file
                       (abbreviate-file-name (expand-file-name file))
                     default-directory))
        (let ((link (concat "file:" file))
              (desc (file-name-nondirectory file)))
          (push (list link desc) org-stored-links)
          (car org-stored-links)))
    (apply orig-fun args)))
(advice-add 'org-store-link :around #'my//dired-store-link)

En prime, cela ne demande pas de description, car la description poussée vers org-stored-linksest non nulle.

Matt Kramer
la source