Org-mode mailing list
 help / color / mirror / Atom feed
* [PATCH] New "project" option for org-link-file-path-type
@ 2020-10-29  0:46 Jack Kamm
  2020-11-02  5:41 ` Kyle Meyer
  0 siblings, 1 reply; 5+ messages in thread
From: Jack Kamm @ 2020-10-29  0:46 UTC (permalink / raw)
  To: emacs-orgmode

[-- Attachment #1: Type: text/plain, Size: 412 bytes --]

The attached patch adds a "project" option for org-link-file-path-type.

When this is set, links to files under the current project root will be
relative, while links elsewhere are absolute.

It relies on project.el, which appears to have been added in emacs 25. I
used fboundp to check whether the functionality is available, and to
silence compiler warnings. I'm not sure if this is the correct way to do
it.


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: 0001-ol.el-New-option-project-for-org-link-file-path-type.patch --]
[-- Type: text/x-patch, Size: 2735 bytes --]

From c5f9d4043a6cf6a325d122be24214356f36446f1 Mon Sep 17 00:00:00 2001
From: Jack Kamm <jackkamm@gmail.com>
Date: Wed, 28 Oct 2020 17:29:04 -0700
Subject: [PATCH] ol.el: New option "project" for org-link-file-path-type

* lisp/ol.el (org-link-file-path-type): Add new option.
(org-insert-link): Handle project option for org-link-file-path-type.
---
 etc/ORG-NEWS |  8 ++++++++
 lisp/ol.el   | 17 +++++++++++++++--
 2 files changed, 23 insertions(+), 2 deletions(-)

diff --git a/etc/ORG-NEWS b/etc/ORG-NEWS
index 7f935bf52..b9adc9089 100644
--- a/etc/ORG-NEWS
+++ b/etc/ORG-NEWS
@@ -88,6 +88,14 @@ package, to convert pandas Dataframes into orgmode tables:
 | 2 | 3 | 6 |
 #+end_src
 
+*** New option to use relative paths for links in same project
+
+If =org-link-file-path-type= is =project=, inserted links under the
+current project root will use relative paths.
+
+If not in a project, or if =project.el= is not available (as in older
+versions of Emacs), links behave as default (=adaptive=).
+
 * Version 9.4
 ** Incompatible changes
 *** Possibly broken internal file links: please check and fix
diff --git a/lisp/ol.el b/lisp/ol.el
index 951bb74e7..9c48bd9b5 100644
--- a/lisp/ol.el
+++ b/lisp/ol.el
@@ -212,13 +212,17 @@ (defcustom org-link-file-path-type 'adaptive
 absolute  Absolute path, if possible with ~ for home directory.
 noabbrev  Absolute path, no abbreviation of home directory.
 adaptive  Use relative path for files in the current directory and sub-
-          directories of it.  For other files, use an absolute path."
+          directories of it.  For other files, use an absolute path.
+project   Use relative path for files in the current project and sub-
+          directories of it. For other files, usue an absolute path.
+          If project.el is not available, behave as adaptive."
   :group 'org-link
   :type '(choice
 	  (const relative)
 	  (const absolute)
 	  (const noabbrev)
-	  (const adaptive))
+	  (const adaptive)
+	  (const project))
   :safe #'symbolp)
 
 (defcustom org-link-abbrev-alist nil
@@ -1876,6 +1880,15 @@ (defun org-insert-link (&optional complete-file link-location description)
 	    (setq path (expand-file-name path)))
 	   ((eq org-link-file-path-type 'relative)
 	    (setq path (file-relative-name path)))
+	   ((and (fboundp 'project-current)
+		 (fboundp 'project-root)
+		 (project-current)
+		 (eq org-link-file-path-type 'project))
+	    (if (string-prefix-p (expand-file-name (project-root
+						    (project-current)))
+				 (expand-file-name path))
+		(setq path (file-relative-name path))
+	      (setq path (abbreviate-file-name (expand-file-name path)))))
 	   (t
 	    (save-match-data
 	      (if (string-match (concat "^" (regexp-quote
-- 
2.29.1


^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH] New "project" option for org-link-file-path-type
  2020-10-29  0:46 [PATCH] New "project" option for org-link-file-path-type Jack Kamm
@ 2020-11-02  5:41 ` Kyle Meyer
  2020-11-04 18:11   ` Jack Kamm
  0 siblings, 1 reply; 5+ messages in thread
From: Kyle Meyer @ 2020-11-02  5:41 UTC (permalink / raw)
  To: Jack Kamm; +Cc: emacs-orgmode

Jack Kamm writes:

> The attached patch adds a "project" option for org-link-file-path-type.
>
> When this is set, links to files under the current project root will be
> relative, while links elsewhere are absolute.

Thanks, that sounds useful.

> It relies on project.el, which appears to have been added in emacs 25. I
> used fboundp to check whether the functionality is available, and to
> silence compiler warnings. I'm not sure if this is the correct way to do
> it.

Functionally I think your current patch would only support Emacs's
unreleased master, unless the user installed a new project.el via ELPA.
More on that below.

> Subject: [PATCH] ol.el: New option "project" for org-link-file-path-type
[...]
> @@ -212,13 +212,17 @@ (defcustom org-link-file-path-type 'adaptive
>  absolute  Absolute path, if possible with ~ for home directory.
>  noabbrev  Absolute path, no abbreviation of home directory.
>  adaptive  Use relative path for files in the current directory and sub-
> -          directories of it.  For other files, use an absolute path."
> +          directories of it.  For other files, use an absolute path.
> +project   Use relative path for files in the current project and sub-
> +          directories of it. For other files, usue an absolute path.

s/usue/use/

> +          If project.el is not available, behave as adaptive."
>    :group 'org-link
>    :type '(choice
>  	  (const relative)
>  	  (const absolute)
>  	  (const noabbrev)
> -	  (const adaptive))
> +	  (const adaptive)
> +	  (const project))
>    :safe #'symbolp)

The :package-version keyword should be added to signal the change in
value.

>  (defcustom org-link-abbrev-alist nil
> @@ -1876,6 +1880,15 @@ (defun org-insert-link (&optional complete-file link-location description)
>  	    (setq path (expand-file-name path)))
>  	   ((eq org-link-file-path-type 'relative)
>  	    (setq path (file-relative-name path)))
> +	   ((and (fboundp 'project-current)
> +		 (fboundp 'project-root)
> +		 (project-current)
> +		 (eq org-link-file-path-type 'project))

Minor: the org-link-file-path-type check would be better positioned at
the top, or at least before the project-current call, to avoid
needlessly finding the project when the option is at its default value
of adaptive.

Also, I think it'd be good to let-bind the project-current result to
avoid a repeated call.

> +	    (if (string-prefix-p (expand-file-name (project-root
> +						    (project-current)))
> +				 (expand-file-name path))

It looks like project-root isn't available until 5044c19001 (project.el:
A project has only one main root now, 2020-05-23), which isn't yet part
of an Emacs release.  Before that, it'd be (car (project-roots ...), I
think.  Do you think it's worth adding a compatibility kludge here?

As a projectile user, I'm tempted to suggest that, instead of the adding
the `project' value, org-insert-link could learn to call
org-link-file-path-type if it is a function and, if that returns
non-nil, do the prefix check.  Then projectile users could set it to
projectile-project-root.  It seems project.el doesn't have a similar
function that could be called without any arguments, but I guess we
could add a simple ol- wrapper.  I'm not sure that's a good idea,
though.

> +		(setq path (file-relative-name path))
> +	      (setq path (abbreviate-file-name (expand-file-name path)))))

A cosmetic preference that you can take or leave: the condition can be
moved inside the setq form:

  (setq path (if ...))

And another: let-binding (expand-file-name path) would avoid a repeating
the expand-file-name in the abbreviate-file-name case.


^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH] New "project" option for org-link-file-path-type
  2020-11-02  5:41 ` Kyle Meyer
@ 2020-11-04 18:11   ` Jack Kamm
  2020-11-06  3:33     ` Kyle Meyer
  0 siblings, 1 reply; 5+ messages in thread
From: Jack Kamm @ 2020-11-04 18:11 UTC (permalink / raw)
  To: Kyle Meyer; +Cc: emacs-orgmode

[-- Attachment #1: Type: text/plain, Size: 1841 bytes --]

Hi Kyle,

> As a projectile user, I'm tempted to suggest that, instead of the adding
> the `project' value, org-insert-link could learn to call
> org-link-file-path-type if it is a function and, if that returns
> non-nil, do the prefix check.  Then projectile users could set it to
> projectile-project-root.  It seems project.el doesn't have a similar
> function that could be called without any arguments, but I guess we
> could add a simple ol- wrapper.  I'm not sure that's a good idea,
> though.

I like the idea of letting org-link-file-path-type be a function.

However, it struck me that it might be too limiting to just have the
function return the project root. There's a lot more potential for
customization here -- for example, a user might want to combine the
noabbrev option with the adaptive option. If we could instead pass a
function that takes the filename as an argument and returns the path to
insert, that would allow for greater flexibility.

Other benefits are that the implementation is much simpler, and
subjectively I think it's more intuitive to explain the meaning of this
option (as opposed to an option where the user passes a function that
returns the project root).

The downside of this is that the user has to do a bit more work and
write some elisp to take advantage of the option.

I've attached an updated patch in this direction. What do you think? I
think the simplicity and flexibility outweighs the downside, but I'm not
sure.

> The :package-version keyword should be added to signal the change in
> value.

Thanks for the tip, I've added this.

> Functionally I think your current patch would only support Emacs's
> unreleased master, unless the user installed a new project.el via ELPA.
> More on that below.

Good catch. I didn't realize I was using project.el from ELPA but it
turns out I was.


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: 0001-ol.el-New-option-to-set-org-link-file-path-type-to-a.patch --]
[-- Type: text/x-patch, Size: 2887 bytes --]

From d156a9cfcdbfb9be72df39761111e2355f48cf10 Mon Sep 17 00:00:00 2001
From: Jack Kamm <jackkamm@gmail.com>
Date: Wed, 28 Oct 2020 17:29:04 -0700
Subject: [PATCH] ol.el: New option to set org-link-file-path-type to a
 function

* lisp/ol.el (org-link-file-path-type): Add new option.
(org-insert-link): Handle function option for org-link-file-path-type.
---
 etc/ORG-NEWS | 19 +++++++++++++++++++
 lisp/ol.el   | 12 ++++++++++--
 2 files changed, 29 insertions(+), 2 deletions(-)

diff --git a/etc/ORG-NEWS b/etc/ORG-NEWS
index 7f935bf52..891a680ae 100644
--- a/etc/ORG-NEWS
+++ b/etc/ORG-NEWS
@@ -35,6 +35,25 @@ omit a file description was to omit the header argument entirely,
 which made it difficult/impossible to provide a default value for
 =file-desc=.
 
+*** New option to set ~org-link-file-path-type~ to a function
+
+If ~org-link-file-path-type~ can now be set to a function that takes
+the full filename as an argument and returns the path to link to.
+
+For example, if you use ~project.el~, you can set this function to use
+relative links within a project as follows:
+
+#+begin_src emacs-lisp
+(setq (org-link-file-path-type
+       (lambda (path)
+         (let* ((proj (project-current))
+                (root (if proj (project-root proj) default-directory)))
+           (if (string-prefix-p (expand-file-name root) path)
+               (progn
+                 (file-relative-name path))
+             (abbreviate-file-name path))))))
+#+end_src
+
 ** New features
 *** =ob-python= improvements to =:return= header argument 
 
diff --git a/lisp/ol.el b/lisp/ol.el
index 951bb74e7..262a6c5ae 100644
--- a/lisp/ol.el
+++ b/lisp/ol.el
@@ -212,13 +212,18 @@ (defcustom org-link-file-path-type 'adaptive
 absolute  Absolute path, if possible with ~ for home directory.
 noabbrev  Absolute path, no abbreviation of home directory.
 adaptive  Use relative path for files in the current directory and sub-
-          directories of it.  For other files, use an absolute path."
+          directories of it.  For other files, use an absolute path.
+
+Alternatively, users may supply a custom function that takes the
+full filename as an argument and returns the path."
   :group 'org-link
   :type '(choice
 	  (const relative)
 	  (const absolute)
 	  (const noabbrev)
-	  (const adaptive))
+	  (const adaptive)
+	  (function))
+  :package-version '(Org . "9.5")
   :safe #'symbolp)
 
 (defcustom org-link-abbrev-alist nil
@@ -1876,6 +1881,9 @@ (defun org-insert-link (&optional complete-file link-location description)
 	    (setq path (expand-file-name path)))
 	   ((eq org-link-file-path-type 'relative)
 	    (setq path (file-relative-name path)))
+	   ((functionp org-link-file-path-type)
+	    (setq path (funcall org-link-file-path-type
+				(expand-file-name path))))
 	   (t
 	    (save-match-data
 	      (if (string-match (concat "^" (regexp-quote
-- 
2.29.2


^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH] New "project" option for org-link-file-path-type
  2020-11-04 18:11   ` Jack Kamm
@ 2020-11-06  3:33     ` Kyle Meyer
  2020-11-12  1:05       ` Jack Kamm
  0 siblings, 1 reply; 5+ messages in thread
From: Kyle Meyer @ 2020-11-06  3:33 UTC (permalink / raw)
  To: Jack Kamm; +Cc: emacs-orgmode

Jack Kamm writes:

> I like the idea of letting org-link-file-path-type be a function.
>
> However, it struck me that it might be too limiting to just have the
> function return the project root. There's a lot more potential for
> customization here -- for example, a user might want to combine the
> noabbrev option with the adaptive option. If we could instead pass a
> function that takes the filename as an argument and returns the path to
> insert, that would allow for greater flexibility.
>
> Other benefits are that the implementation is much simpler, and
> subjectively I think it's more intuitive to explain the meaning of this
> option (as opposed to an option where the user passes a function that
> returns the project root).
>
> The downside of this is that the user has to do a bit more work and
> write some elisp to take advantage of the option.
>
> I've attached an updated patch in this direction. What do you think? I
> think the simplicity and flexibility outweighs the downside, but I'm not
> sure.

I think that's a good direction to go (for the reasons you laid out, not
just because it lets me use this with projectile :).

> +++ b/etc/ORG-NEWS
> @@ -35,6 +35,25 @@ omit a file description was to omit the header argument entirely,
>  which made it difficult/impossible to provide a default value for
>  =file-desc=.
>  
> +*** New option to set ~org-link-file-path-type~ to a function
> +
> +If ~org-link-file-path-type~ can now be set to a function that takes
> +the full filename as an argument and returns the path to link to.

Drop "If"?

> +For example, if you use ~project.el~, you can set this function to use
> +relative links within a project as follows:
> +
> +#+begin_src emacs-lisp
> +(setq (org-link-file-path-type
> +       (lambda (path)
> +         (let* ((proj (project-current))
> +                (root (if proj (project-root proj) default-directory)))
> +           (if (string-prefix-p (expand-file-name root) path)
> +               (progn
> +                 (file-relative-name path))
> +             (abbreviate-file-name path))))))
> +#+end_src

superfluous progn


^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH] New "project" option for org-link-file-path-type
  2020-11-06  3:33     ` Kyle Meyer
@ 2020-11-12  1:05       ` Jack Kamm
  0 siblings, 0 replies; 5+ messages in thread
From: Jack Kamm @ 2020-11-12  1:05 UTC (permalink / raw)
  To: Kyle Meyer; +Cc: emacs-orgmode

Thanks, I've fixed the remaining issues you pointed out and pushed this
in 5371b30fe.

Cheers,
Jack


^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2020-11-12  1:07 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-10-29  0:46 [PATCH] New "project" option for org-link-file-path-type Jack Kamm
2020-11-02  5:41 ` Kyle Meyer
2020-11-04 18:11   ` Jack Kamm
2020-11-06  3:33     ` Kyle Meyer
2020-11-12  1:05       ` Jack Kamm

Org-mode mailing list

This inbox may be cloned and mirrored by anyone:

	git clone --mirror https://orgmode.org/list/0 list/git/0.git

	# If you have public-inbox 1.1+ installed, you may
	# initialize and index your mirror using the following commands:
	public-inbox-init -V2 list list/ https://orgmode.org/list \
		emacs-orgmode@gnu.org
	public-inbox-index list

Example config snippet for mirrors.
Newsgroups are available over NNTP:
	nntp://news.yhetil.org/yhetil.emacs.orgmode
	nntp://news.gmane.io/gmane.emacs.orgmode


AGPL code for this site: git clone https://public-inbox.org/public-inbox.git