From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mp10.migadu.com ([2001:41d0:2:bcc0::]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)) by ms5.migadu.com with LMTPS id oGnXLYQ5x2ILBwAAbAwnHQ (envelope-from ) for ; Thu, 07 Jul 2022 21:52:36 +0200 Received: from aspmx1.migadu.com ([2001:41d0:2:bcc0::]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)) by mp10.migadu.com with LMTPS id gM7ULIQ5x2L1cwAAG6o9tA (envelope-from ) for ; Thu, 07 Jul 2022 21:52:36 +0200 Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by aspmx1.migadu.com (Postfix) with ESMTPS id 3CCE2A102 for ; Thu, 7 Jul 2022 21:52:35 +0200 (CEST) Received: from localhost ([::1]:48672 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1o9XY9-0006sy-8l for larch@yhetil.org; Thu, 07 Jul 2022 15:52:33 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:37064) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1o9XXT-0006qk-QX for emacs-orgmode@gnu.org; Thu, 07 Jul 2022 15:51:51 -0400 Received: from [2a01:c0:2:6:225:90ff:fed2:2b47] (port=41242 helo=mail.oa5.com) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1o9XXQ-00028h-9q for emacs-orgmode@gnu.org; Thu, 07 Jul 2022 15:51:51 -0400 Received: from hugoLaptop (localhost.localdomain [127.0.0.1]) hugo@heagren.com (authenticated bits=0) by mail.oa5.com (8.14.4/8.12.11) with ESMTP id 267Jpb1f026067 sender hugo@heagren.com for ; Thu, 7 Jul 2022 20:51:38 +0100 DKIM-Signature: v=1; a=rsa-sha1; c=relaxed/relaxed; d=heagren.com; h= Message-ID:From:Subject:Date:To:MIME-Version:Content-Type; s= 202207; bh=+Kvcv99T67UFd/l8lq6y+J0iKZA=; b=Zbj7fXBb9x0DtxQCL/MHg IGnacCmdtOe7APPnNaZSoqo2xCN+idIET8YWFXpnGTupun5CmL1oX6KgPVETpltF mJ34fk37WvobVAwLyiBsWnmChUtS9wVyNBGe7eh0gEg5+NKbrgD26IuPwEnXciVh D2lZzrlmN97gbGaHC8RLND6YI6CK4GeWrHZ+cndNCKRYziuniCI2k8IL39IsysH+ uFivSLueT3duwChFrDFpHSbJaDmp82FAyZ7Apbo3u2O X-Assp-Version: 2.6.7(22137) on ASSP.OA5.COM X-Assp-ID: ASSP.OA5.COM X-Assp-Session: 7F4176C465B0 (mail 1) X-Assp-Envelope-From: hugo@heagren.com X-Assp-Intended-For: emacs-orgmode@gnu.org X-Assp-Client-TLS: yes Received: from global-5-153.nat-2.net.cam.ac.uk ([131.111.5.153] helo=hugoLaptop) by ASSP.OA5.COM with SMTPSA(TLSv1_2 ECDHE-RSA-AES128-GCM-SHA256) (2.6.7); 7 Jul 2022 20:51:37 +0100 From: Hugo Heagren To: emacs-orgmode@gnu.org Subject: [PATCH v4] ol.el: add description format parameter to org-link-parameters References: <87zgl1npow.fsf@localhost> <20220405192931.6747-1-hugo@heagren.com> <87a6cx79xn.fsf@localhost> <87zgi6fckr.fsf@heagren.com> <871qvixhfw.fsf@gmail.com> Date: Thu, 07 Jul 2022 20:57:01 +0100 Message-ID: <87v8s8n1bm.fsf@heagren.com> MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="=-=-=" X-Host-Lookup-Failed: Reverse DNS lookup failed for 2a01:c0:2:6:225:90ff:fed2:2b47 (failed) Received-SPF: pass client-ip=2a01:c0:2:6:225:90ff:fed2:2b47; envelope-from=hugo@heagren.com; helo=mail.oa5.com X-Spam_score_int: -12 X-Spam_score: -1.3 X-Spam_bar: - X-Spam_report: (-1.3 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RDNS_NONE=0.793, SPF_HELO_PASS=-0.001, SPF_PASS=-0.001, T_SCC_BODY_TEXT_LINE=-0.01 autolearn=no autolearn_force=no X-Spam_action: no action X-BeenThere: emacs-orgmode@gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: "General discussions about Org-mode." List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: emacs-orgmode-bounces+larch=yhetil.org@gnu.org Sender: "Emacs-orgmode" X-Migadu-Flow: FLOW_IN X-Migadu-To: larch@yhetil.org X-Migadu-Country: US ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=yhetil.org; s=key1; t=1657223556; h=from:from:sender:sender:reply-to:subject:subject:date:date: message-id:message-id:to:to:cc:mime-version:mime-version: content-type:content-type:references:references:list-id:list-help: list-unsubscribe:list-subscribe:list-post:dkim-signature; bh=9n4KajYl6+FQw8zaGhAjnssSwt+quj3LStUgHxckucc=; b=X7+1O8x/1WGCjtNXdDXa/V33SCY0o/yHmwIcOOvW3bIPP04XiuglwRwU1rF21JD/vc3ghs mJFDtLCdW6goIt3riAmeEbPzeLzp9e2V1kggS+MRAC6XbYyHX3Iy4A2xYZYRT1h3nGIi78 KSciDXyO4sPTEKEFcBTEIRMsNjOjYCJzds1XAWuXlMgn93XNq1THDcgpG6Cc5Gt9pwVLBM W/Nmweu3wSlUKuw6z1/Ic3FyRw2pvd18RIEhGNwRzGOrAjw/b7RHlPvvuP6WIWCIgkZT1u g9VsTAZnRCcHQWTcvq8Ul1I2Niw8ApAwL5O0umFgWEbQJd1NAcXkkDrtuiy+dQ== ARC-Seal: i=1; s=key1; d=yhetil.org; t=1657223556; a=rsa-sha256; cv=none; b=crB8d0hf9eA0Eh6j64AWS6G4W0xD4QOEABKVhpYp4xj8ywZMBnGlkVibv1a9BIs6n8faLr YaEfJH/9CoARVGKc0CKtmRWWXk4dg+cYg83Gk27zIl8dt0c522woWRG76FpPo/sWw/SVsu EnP4iDT8LucUIT8EWmOfaAzsCkTU0O9kLFvOmjH9J/FMh/UQvhKtxxohI7ePJojJZaAfgH cuQMnSduYAHoRPTbZSHwja6T+gcOuBXNJ6WbBjxJ0RYigYITi2kZASkp/7c+NDzDnaQGuh 8TeodbtKpU/WELB0RiqiZEZ+BRGLCd1ipb8GESg7EYtViQ+9Gx4SYYjGp5pD2w== ARC-Authentication-Results: i=1; aspmx1.migadu.com; dkim=pass header.d=heagren.com header.s=202207 header.b=Zbj7fXBb; dmarc=pass (policy=quarantine) header.from=heagren.com; spf=pass (aspmx1.migadu.com: domain of "emacs-orgmode-bounces+larch=yhetil.org@gnu.org" designates 209.51.188.17 as permitted sender) smtp.mailfrom="emacs-orgmode-bounces+larch=yhetil.org@gnu.org" X-Migadu-Spam-Score: -2.45 Authentication-Results: aspmx1.migadu.com; dkim=pass header.d=heagren.com header.s=202207 header.b=Zbj7fXBb; dmarc=pass (policy=quarantine) header.from=heagren.com; spf=pass (aspmx1.migadu.com: domain of "emacs-orgmode-bounces+larch=yhetil.org@gnu.org" designates 209.51.188.17 as permitted sender) smtp.mailfrom="emacs-orgmode-bounces+larch=yhetil.org@gnu.org" X-Migadu-Queue-Id: 3CCE2A102 X-Spam-Score: -2.45 X-Migadu-Scanner: scn1.migadu.com X-TUID: OHgng9TJzKSQ --=-=-= Content-Type: text/plain Content-Disposition: inline Since the last version of this patch, I have: - moved the code which sets `type' in `org-insert-link' to a position where it covers more cases - rewritten the macros used in the tests, so that always (and correctly) restore the original state after running, even after errors. Thanks to Max Nikulin for suggesting using `condition-case' There is only one thing left which I am not happy with. Currently, the test fails in the case where :default-description is 'ignore. This was intended to test for situations where the parameter is set to a function, but the function doesn't return a string (I used ignore because it returns 'nil). Accordingly, the test is a `should-error' (because the function *should* return a string, so we should error if it doesn't, right?). But the error condition is inside the error clause of a condition case---which is only triggered if the code errors. Calling 'ignore with any arguments and getting 'nil back doesn't cause any errors, so the error clause is never triggered, and 'nil is just used as the default description (which is then ignored, because it is 'nil -- other non-string values like numbers would not be ignored). I'd like some input on what to do about this: I could rewrite the tests so that a nil-value doesn't matter. In the case of this test, a non-interactive call would just insert a link without a description. Alternatively I could rewrite the function so that if the :default-description parameter returns something, we error unless it is a string. tl;dr The question is: what is the Good Behaviour when :default-description is set to something, which is meant to return a string and returns 'nil instead? Should it be treated like an empty string, or as an error? Thanks, Hugo --=-=-= Content-Type: text/x-diff Content-Disposition: attachment; filename=0002-test-ol-tests-for-default-description-param-when-ins.patch >From ae17e87436def764f99b24add4debb5d7a481e1a Mon Sep 17 00:00:00 2001 From: Hugo Heagren Date: Tue, 21 Jun 2022 12:45:50 +0100 Subject: [PATCH 2/2] test-ol: tests for default-description param when inserting links Add tests for various values of `:default-description' in `org-link-parameters'. --- testing/lisp/test-ol.el | 92 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 92 insertions(+) diff --git a/testing/lisp/test-ol.el b/testing/lisp/test-ol.el index 429bb52ee..9114c6497 100644 --- a/testing/lisp/test-ol.el +++ b/testing/lisp/test-ol.el @@ -625,5 +625,97 @@ See https://github.com/yantar92/org/issues/4." (test-ol-parse-link-in-text "The http://foo.com/(something)?after=parens link")))) +;;; Insert Links + +(defmacro test-ol-with-link-parameters-as (type parameters &rest body) + "Pass TYPE/PARAMETERS to `org-link-parameters' and execute BODY. + +Save the original value of `org-link-parameters', execute +`org-link-set-parameters' with the relevant args, execute BODY +and restore `org-link-parameters'. + +TYPE is as in `org-link-set-parameters'. PARAMETERS is a plist to +be passed to `org-link-set-parameters'." + ;; Copy all keys in `parameters' and their original values to + ;; `orig-parameters'. For `parity': nil = odd, non-nill = even + `(let (parity orig-parameters) + (dolist (p ',parameters) + (unless parity + (setq orig-parameters + (plist-put orig-parameters p (org-link-get-parameter ,type p)))) + (setq parity (not parity))) + ;; Set `parameters' values + (condition-case err + (let ((_ (org-link-set-parameters ,type ,@parameters)) + ;; Do body + (rtn (progn ,@body))) + ;; Restore original values + (apply 'org-link-set-parameters ,type orig-parameters) + ;; Return whatever the body returned + rtn) + ;; In case of error, restore state anyway AND really error + (error + (apply 'org-link-set-parameters ,type orig-parameters) + (signal (car err) (cdr err)))))) + +(defun test-ol-insert-link-get-desc (&optional link-location description) + "Insert link in temp buffer, return description. + +LINK-LOCATION and DESCRIPTION are passed to +`org-insert-link' (COMPLETE-FILE is always nil)." + (org-test-with-temp-text "" + (org-insert-link nil link-location description) + (save-match-data + (when (and + (org-in-regexp org-link-bracket-re 1) + (match-end 2)) + (match-string-no-properties 2))))) + +(defun test-ol/return-foobar (_link-test _desc) + "Return string \"foobar\". + +Take (and ignore) arguments conforming to `:default-description' +API in `org-link-parameters'. Used in test +`test-ol/insert-link-default-description', for the case where +`:default-description' is a function symbol." + "foobar") + +(ert-deftest test-ol/insert-link-default-description () + "Test `:default-description' parameter handling." + ;; String case + (should + (string= + "foobar" + (test-ol-with-link-parameters-as + "id" (:default-description "foobar") + (test-ol-insert-link-get-desc "id:foo-bar")))) + ;; Lambda case + (should + (string= + "foobar" + (test-ol-with-link-parameters-as + "id" (:default-description (lambda (_link-test _desc) "foobar")) + (test-ol-insert-link-get-desc "id:foo-bar")))) + ;; Function symbol case + (should + (string= + "foobar" + (test-ol-with-link-parameters-as + "id" (:default-description #'test-ol/return-foobar) + (test-ol-insert-link-get-desc "id:foo-bar")))) + ;; `:default-description' parameter is defined, but doesn't return a + ;; string + (should-error + (test-ol-with-link-parameters-as + "id" (:default-description #'ignore) + (test-ol-insert-link-get-desc "id:foo-bar"))) + ;; Description argument should override `:default-description' + (should + (string= + "notfoobar" + (test-ol-with-link-parameters-as + "id" (:default-description "foobar") + (test-ol-insert-link-get-desc "id:foo-bar" "notfoobar"))))) + (provide 'test-ol) ;;; test-ol.el ends here -- 2.20.1 --=-=-= Content-Type: text/x-diff Content-Disposition: attachment; filename=0001-ol.el-add-description-format-parameter-to-org-link-p.patch >From 12726d18487298907ff63374120d17ee733383a7 Mon Sep 17 00:00:00 2001 From: Hugo Heagren Date: Mon, 28 Mar 2022 23:18:45 +0100 Subject: [PATCH 1/2] ol.el: add description format parameter to org-link-parameters * ol.el (org-link-parameters): add parameter `:default-description', a string or a function. * (org-insert-link): if no description is provided (pre-existing or as an argument), next option is to use the `:default-description' (if non-nil) parameter to generate one. Default descriptions are predictable within a link type, but because link types are quite diverse, are NOT predictable across many types. A type-parameter is thus a good place to store information on the default description. --- lisp/ol.el | 53 ++++++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 42 insertions(+), 11 deletions(-) diff --git a/lisp/ol.el b/lisp/ol.el index d4bd0e40c..00f3bce5c 100644 --- a/lisp/ol.el +++ b/lisp/ol.el @@ -141,6 +141,15 @@ link. Function that inserts a link with completion. The function takes one optional prefix argument. +`:default-description' + + String or function used as a default when prompting users for a + link's description. A string is used as-is, a function is + called with two arguments: the full link text, and the + description generated by `org-insert-link'. It should return + the description to use (this reflects the behaviour of + `org-link-make-description-function'). + `:display' Value for `invisible' text property on the hidden parts of the @@ -1804,11 +1813,14 @@ prefix negates `org-link-keep-stored-after-insertion'. If the LINK-LOCATION parameter is non-nil, this value will be used as the link location instead of reading one interactively. -If the DESCRIPTION parameter is non-nil, this value will be used as the -default description. Otherwise, if `org-link-make-description-function' -is non-nil, this function will be called with the link target, and the -result will be the default link description. When called non-interactively, -don't allow to edit the default description." +If the DESCRIPTION parameter is non-nil, this value will be used +as the default description. If not, and the chosen link type has +a non-nil `:default-description' parameter, that is used to +generate a description as described in `org-link-parameters' +docstring. Otherwise, if `org-link-make-description-function' is +non-nil, this function will be called with the link target, and +the result will be the default link description. When called +non-interactively, don't allow to edit the default description." (interactive "P") (let* ((wcf (current-window-configuration)) (origbuf (current-buffer)) @@ -1818,7 +1830,10 @@ don't allow to edit the default description." (desc region) (link link-location) (abbrevs org-link-abbrev-alist-local) - entry all-prefixes auto-desc) + (all-prefixes (append (mapcar #'car abbrevs) + (mapcar #'car org-link-abbrev-alist) + (org-link-types))) + entry auto-desc type) (cond (link-location) ; specified by arg, just use it. ((org-in-regexp org-link-bracket-re 1) @@ -1859,9 +1874,6 @@ Use TAB to complete link prefixes, then RET for type-specific completion support (unless (pos-visible-in-window-p (point-max)) (org-fit-window-to-buffer)) (and (window-live-p cw) (select-window cw)))) - (setq all-prefixes (append (mapcar #'car abbrevs) - (mapcar #'car org-link-abbrev-alist) - (org-link-types))) (unwind-protect ;; Fake a link history, containing the stored links. (let ((org-link--history @@ -1893,6 +1905,13 @@ Use TAB to complete link prefixes, then RET for type-specific completion support (or entry (push link org-link--insert-history)) (setq desc (or desc (nth 1 entry))))) + (setq type + (cond + ((string-match (rx-to-string `(: string-start (submatch (or ,@all-prefixes)) ":")) link) + (match-string 1 link)) + ((file-name-absolute-p link) "file") + ((string-match "\\`\\.\\.?/" link) "file"))) + (when (funcall (if (equal complete-file '(64)) 'not 'identity) (not org-link-keep-stored-after-insertion)) (setq org-stored-links (delq (assoc link org-stored-links) @@ -1961,12 +1980,24 @@ Use TAB to complete link prefixes, then RET for type-specific completion support (let ((initial-input (cond (description) - ((not org-link-make-description-function) desc) + (desc) + ((org-link-get-parameter type :default-description) + (let ((def (org-link-get-parameter type :default-description))) + (condition-case nil + (cond + ((stringp def) def) + ((functionp def) + (funcall def link desc))) + (error + (message "Can't get link description from org link parameter `:default-description': %S" + def) + (sit-for 2) + nil)))) (t (condition-case nil (funcall org-link-make-description-function link desc) (error (message "Can't get link description from %S" - (symbol-name org-link-make-description-function)) + org-link-make-description-function) (sit-for 2) nil)))))) (setq desc (if (called-interactively-p 'any) -- 2.20.1 --=-=-=--