From 8eeb353a45521ab34cced37971e4455f870671c9 Mon Sep 17 00:00:00 2001 From: Max Nikulin Date: Mon, 7 Feb 2022 23:40:37 +0700 Subject: [PATCH] FAQ: Update suggestion for mailto: link handlers org-faq.org (mailto-links): Mention `org-link-mailto-program' as removed variable, recommend customization of `browse-url-mailto-function' or `org-link-parameters' instead. This change is prepared in cooperation with Robert Goldman , see https://list.orgmode.org/FEAD92A6-87DE-4CFF-8459-E3D012DD3F52@sift.net for the initial suggestion. --- org-faq.org | 104 ++++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 93 insertions(+), 11 deletions(-) diff --git a/org-faq.org b/org-faq.org index 4b34560c..323fba6b 100644 --- a/org-faq.org +++ b/org-faq.org @@ -1926,21 +1926,103 @@ For example: #+index: Link!Mailto -You can customize the function org-mode uses to open mailto links by -setting the variable =org-link-mailto-program=: +Org calls the ~browse-url~ function for =mailto:= links, so it should obey +your Emacs configuration. If something goes wrong then +[[info:emacs#Browse-URL][info "(emacs) Browse-URL"]] may be a good starting point. + +By default mail is composed in an Emacs buffer. If you prefer some +external application instead then set ~browse-url-mailto-function~ to +~nil~, e.g. using +[[elisp:(customize-variable 'browse-url-mailto-function)][=M-x customize-variable RET browse-url-mailto-function RET=]] +and =mailto:= links will be opened according to the value of +~browse-url~browser-function~. + +If you wish to compose messages in Emacs then consult +[[info:emacs#Mail Methods][info "(emacs) Mail Methods"]]. Check that ~browse-url-mailto-function~ +has its default value ~browse-url-mail~. Emacs has several mail +packages and the active one is determined by the ~mail-user-agent~ variable, +so the next step may be to configure it to, e.g., =gnus-user-agent= using +[[elisp:(customize-variable 'mail-user-agent)][=M-x customize-variable RET mail-user-agent RET=]]. + +If you prefer an external application that is /not/ the one configured +in your desktop environment, +then you should write a custom URL handler function. Be +careful, try to avoid using the shell (e.g. ~shell-command~ function) since it +is easy to mess up the escaping of the URL argument and allow +execution of arbitrary code: some parts of links may be treated as +shell specials. Choosing a proper function to invoke an external +application is a non-trivial task even for seasoned Emacs developers. +When possible use an option like double dash =--= before URLs that forces +interpreting following as arguments even when a string resembles some option +due to a leading dash. +For examples, consult the source code of ~browse-url-xdg-open~, +~browse-url-default-macosx-browser~, or +~browse-url-default-windows-browser~ for GNU/Linux, +Mac\nbsp{}OS\nbsp{}X, or MS\nbsp{}Windows platforms accordingly. -=M-x customize-variable org-link-mailto-program= - -The default function called is =browse-url=, which opens a mail -composition buffer within Emacs. The type of buffer opened by -browse-url depends on the setting of the variable =mail-user-agent=. -Thus, if you want to ensure that mailto links use Gnus to open a -message buffer, you could add the following to your =.emacs=: +#+begin_comment +A recurring source of pain for users is the interaction +of Emacs functions with the +=xdg-open=, =kde-open5=, and =gio open= utilities on Linux. While +~call-process~ with 0 as ~DESTINATION~ argument for +~browse-url-generic~ was settled in 2004, the introduced later +~browse-url-xdg-open~ function was evolving to similar code in 2011. +See commit history for earlier steps. Notice that with the ~call-process~ +approach the application has no chance to notify Emacs if it fails. + +Example of confusion with techniques to launch applications is comment +[[https://debbugs.gnu.org/cgi/bugreport.cgi?bug=9779#29]] +that falsely points out to missed =nohup= despite of usage the ~call-process~ function. +Its choice is not intuitive since normally ~call-process~ +waits till process completion. However with 0 (not ~nil~!) argument +it creates a completely detached process. +It is asynchronous ~start-process~ +and ~make~process~ functions that create a pty by default and so kill +children by =SIGHUP= signal when the main process exits after fork. +There was +a lengthy thread "& and M-& to run programs asynchronously" in 2009 +with a comment containing a strange conclusion that immediate exit is a bug +in the Gnome CLI utility launching MIME handler: +[[https://lists.gnu.org/archive/html/emacs-devel/2009-07/msg00279.html]]. + +~org-open-file~ and ~mailcap-view-mime~ functions create asynchronous processes to launch +applications (shell is required by mailcap RFC-1524 so the code does not follow the recommendation given above), +but they use pipe processes instead of default pty ones. +This approach has downsides as well. In some cases application can not run longer +than Emacs (a prompt to confirm its termination may appear on attempt to quit from Emacs). +Some applications might cause high CPU consumption by Emacs. See +https://debbugs.gnu.org/cgi/bugreport.cgi?bug=44824 and +https://debbugs.gnu.org/cgi/bugreport.cgi?bug=12972 for details. + +Keep these considerations in mind if you decide to add more examples. +#+end_comment -#+begin_src elisp -(setq mail-user-agent 'gnus-user-agent) +When you are ready with a function launching your preferred handler +for =mailto:= links, you should add it to ~browse-url-handlers~ +associations list for Emacs-28.1 and newer or to +~browse-url-browser-function~ for earlier versions by customizing the +suitable variable. + +If you are going to change handler just in Org mode in a way that does +not affect rest of Emacs than you can adjust it through +[[elisp:(customize-variable 'org-link-parameters)][=M-x customize-variable RET org-link-parameters RET=]], e.g. for +Mac\nbsp{}OS\nbsp{}X link property may be following (on Linux to avoid +silent failures add ~(process-connection-type nil)~ to ~let~ variables +or use ~call-process~ with =0= as the =DESTINATION= argument): + +#+begin_src elisp :results none +("mailto" + :follow (lambda (path) + (let ((url (concat "mailto:" path))) + ;; platform-specific choice of function + (start-process (concat "open " url) nil + "open" "-a" "Thunderbird" "--args" url)))) #+end_src +In earlier versions Org had ~org-link-mailto-program~ variable, but it +was removed, so its customization does not work any more. Update your +init file if you noticed this variable. + ** Can I use CamelCase links? :PROPERTIES: :CUSTOM_ID: CamelCase-links -- 2.25.1