Uzyskaj link organizacji, aby automatycznie wstawić opis linku?

11

P: Jak mogę uzyskać niestandardową orgfunkcję linku do automatycznego wstawiania opisu?

Chciałbym przechowywać orglinki do plików w diredbuforze, ale wolałbym, aby opis linku był ścieżką bez nazwy pliku, niż zgłosić pełną ścieżkę, tj .:

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

Teraz: org-store-linktwarde kody łączy z, diredaby podać wartość domyślną. Zamiast tego napisałem niestandardową funkcję (cribbing z funkcji zakodowanej na stałe) i dodałem ją do 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)

Jak dotąd tak dobrze i działa zgodnie z oczekiwaniami, ale z jednej strony:

  • Podczas wywoływania org-insert-linkz wbudowanym domyślnym zachowaniem, po prostu wstawia link, nie pytając mnie o opis.
  • Podczas wywoływania za org-insert-linkpomocą mojej funkcji niestandardowej monituje mnie o wprowadzenie opisu (który poprawnie wypełnia nazwą pliku zapisaną we :descriptionwłaściwości).

Wolałbym nie być monitowany o opis za każdym razem i chcę org-insert-linkużyć wartości :descriptiontego zestawu funkcji niestandardowych.

Jak przekonać org-insert-linkdo korzystania z :descriptiontrybu automatycznego bez monitowania mnie o to?

Dan
źródło
Czy opcjonalne argumenty link-locationlub default-descriptionfunkcja org-insert-linkpomagają? Jeśli parametr LINK-LOCATION ma wartość inną niż zero, ta wartość zostanie użyta jako lokalizacja łącza zamiast odczytu jednego interaktywnie. Jeśli parametr DEFAULT-DESCRIPTION ma wartość inną niż zero, ta wartość zostanie użyta jako opis domyślny.
prawnik
@lawlist: dziękuję za sugestię, chociaż nie jestem pewien, jak ustawiłbym to w interaktywnym użyciu bez zawijania w innej funkcji. Zmusiło mnie to jednak do dokładniejszego przeczytania dokumentacji, co doprowadziło mnie do pewnego rodzaju odpowiedzi.
Dan

Odpowiedzi:

4

Na dole dokumentu org-insert-linkznajduje się uwaga, że:

Jeśli wartość org-make-link-description-functionjest różna od zera, ta funkcja zostanie wywołana z celem łącza, a wynikiem będzie domyślny opis łącza.

Najwyraźniej orgwyrzuca wiele informacji w procesie przechowywania linku, więc pozostaje org-stored-linkstylko lista wpisów formularza (link description). O ile wcześniejsza funkcja ma nazwę pliku łącza, wygląda to następująco:

(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)

To trochę hacky i nie testowałem go dokładnie, ale wydaje się, że do tej pory działa. Oczywiście z radością zobaczyłbym bardziej eleganckie rozwiązanie.

Dan
źródło
2
Teraz, kiedy znasz już tę funkcję, nie możesz porzucić jej dired-store-linki po prostu użyć jej do stworzenia pożądanego opisu? Myślę, że skończyłoby to znacznie krócej.
Malabarba
1
@Malabarba: prawdopodobnie masz rację - tę funkcję można przepisać, aby sprawdzić łącze do pliku i postępować odpowiednio. Wypróbuję to, kiedy będę miał wolną chwilę.
Dan
3

Używam org 9.1.6 i ku mojemu przerażeniu wydaje się, że org-store-link-functionsjest to teraz wbudowana funkcja org (a nie hook), więc oryginalne rozwiązanie już nie działa. Może być obejście problemu org-link-parameters, ale zamiast tego używam następującego małego hacka, który wydaje się załatwić:

(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)

Jako bonus nie wyświetla monitu o opis, ponieważ przekazany opis org-stored-linksjest inny niż zero.

Matt Kramer
źródło