Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add org-attach feature #878

Draft
wants to merge 7 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
240 changes: 240 additions & 0 deletions docs/configuration.org
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ This page contains information about all configuration that can be provided to t
- [[#agenda-settings][Agenda settings]]
- [[#calendar-settings][Calendar settings]]
- [[#tags-settings][Tags settings]]
- [[#attachment-settings][Attachments settings]]
- [[#mappings][Mappings]]
- [[#features][Features]]
- [[#user-interface][User interface]]
Expand Down Expand Up @@ -555,6 +556,36 @@ See [[https://orgmode.org/manual/Property-Inheritance.html][Property Inheritance
- Default: ~{ [':tangle'] = 'no', [':noweb'] = no }~
Default header args for extracting source code. See [[#extract-source-code-tangle][Extract source code (tangle)]] for more details.

*** org_resource_download_policy
:PROPERTIES:
:CUSTOM_ID: org_resource_download_policy
:END:
- Type: ='always' | 'prompt' | 'safe' | 'never'=
- Default: ='prompt'=
Policy applied to requests to obtain remote resources.

- =always= - Always download remote resources (dangerous!)
- =prompt= - Prompt before downloading an unsafe resource
- =safe= - Only download resources allowed by [[#org_safe_remote_resources][org_safe_remote_resources]]
- =never= - Never download any resources

In Emacs Orgmode, this affects keywords like =#+setupfile= and =#+include=
on export, =org-persist-write:url=; and =org-attach-url= in non-interactive
sessions. Nvim Orgmode currently does not use this option, but defines it
for future use.

*** org_safe_remote_resources
:PROPERTIES:
:CUSTOM_ID: org_safe_remote_resources
:END:
- Type: =string[]=
- Default: ={}=

List of regex patterns matching safe URIs. URI regexps are applied to both
URLs and Org files requesting remote resources. The test uses
=vim.regex()=, so the regexes are always interpreted as magic and
case-sensitive.

*** calendar_week_start_day
:PROPERTIES:
:CUSTOM_ID: calendar_week_start_day
Expand Down Expand Up @@ -1122,6 +1153,171 @@ Using the example above, setting this variable to ={'MYTAG'}=, second
and third headline would have only =CHILDTAG=, where =MYTAG= would not
be inherited.

** Attachments settings
:PROPERTIES:
:CUSTOM_ID: attachment-settings
:END:

*** org_attach_id_dir
:PROPERTIES:
:CUSTOM_ID: org_attach_id_dir
:END:
- Type: =string=
- Default: ='./data/'=

The directory where attachments are stored. If this is a relative path, it
will be interpreted relative to the directory where the Org file lives.

*** org_attach_dir_relative
:PROPERTIES:
:CUSTOM_ID: org_attach_dir_relative
:END:
- Type: =boolean=
- Default: =false=

If =true=, whenever you add a =DIR= property to a headline, it is added as
a relative path. The default is to only add absolute paths.

*** org_attach_auto_tag
:PROPERTIES:
:CUSTOM_ID: org_attach_auto_tag
:END:
- Type: =string=
- Default: ='ATTACH'=

Tag that is added automatically when attaching files to a headline.

*** org_attach_preferred_new_method
:PROPERTIES:
:CUSTOM_ID: org_attach_preferred_new_method
:END:
- Type: ='id'|'dir'|'ask'|false=
- Default: ='id'=

This setting is used when attaching files to nodes that have neither an
=ID= nor a =DIR= property.

- =id= - create and use an =ID= property
- =dir= - create and use a =DIR= property
- =ask= - ask the user which method to use
- =false= - don't create a property; the user has to define it explicitly before attaching files

*** org_attach_method
:PROPERTIES:
:CUSTOM_ID: org_attach_method
:END:
- Type: ='cp'|'mv'|'ln'|'lns'=
- Default: ='cp'=

The preferred method to add files to the attachment directory.

- =mv= - move (rename) the file
- =cp= - copy the file
- =ln= - create a hard link; not supported on all systems
- =lns= - create a symbol link; not supported on all systems; on Windows, this always creates a /junction/

*** org_attach_copy_directory_create_symlink
:PROPERTIES:
:CUSTOM_ID: org_attach_copy_directory_create_symlink
:END:
- Type: =boolean=
- Default: =false=

If =true=, whenever the attachments directory itself is a symlink, and it
is copied due to the [[https://orgmode.org/manual/Attachment-defaults-and-dispatcher.html*index-C_002dc-C_002da-s][set_directory]] or [[https://orgmode.org/manual/Attachment-defaults-and-dispatcher.html*index-C_002dc-C_002da-S][unset_directory]] action, copy the
symlink itself. The default is to treat the symlink transparently as
a directory.

*** org_attach_visit_command
:PROPERTIES:
:CUSTOM_ID: org_attach_visit_command
:END:
- Type: =string|fun(path: string)=
- Default: ='edit'=

Command or function used to open a directory. The default opens NetRW if it
is available.

*** org_attach_use_inheritance
:PROPERTIES:
:CUSTOM_ID: org_attach_use_inheritance
:END:
- Type: ='always'|'selective'|'never'=
- Default: ='selective'=

Attachment inheritance for the outline.

Enabling inheritance implies two things:
1. Attachment links will look through all parent headlines until they find
the linked attachment.
2. Running =attach= inside a node without attachments will operate on the
first parent headline that has an attachment.

Possible values are:

- =always= - inherit attachments
- =selective= - respect [[#org_use_property_inheritance][org_use_property_inheritance]] for the properties =DIR= and =ID=
- =never= - don't inherit attachments

*** org_attach_store_link_p
:PROPERTIES:
:CUSTOM_ID: org_attach_store_link_p
:END:
- Type: ='attached' | 'file' | 'original' | false=
- Default: ='attached'=

If not =false=, store a link with [[#org_store_link][org_store_link]] when attaching a file.

- =attach= - store a =[[attachment:name]]= link
- =file= - store a =[[file:attach_dir/name]]= link
- =original= - store a =[[file:original/location]]= link

*** org_attach_archive_delete
:PROPERTIES:
:CUSTOM_ID: org_attach_archive_delete
:END:
- Type: ='always' | 'ask' | 'never'=
- Default: ='never'=

Determines whether attachments are deleted automatically whenever a subtree
is moved to an archive file. The value ='ask'= means to ask the user.

*** org_attach_id_to_path_function_list
:PROPERTIES:
:CUSTOM_ID: org_attach_id_to_path_function_list
:END:
- Type: =(string | fun(id: string): (string|nil))[]=
- Default: ={ 'uuid_folder_format', 'ts_folder_format', 'fallback_folder_format' }=

List of functions that are tried sequentially to derive an attachment path
from an =ID= property. The functions are called with a single =id= argument
until the return value is an existing folder. The ID format passed to the
functions is usually defined by [[#org_id_method][org_id_method]].

If no folder has been created yet for the given ID, then the first truthy
value defines the path of the folder to be created.

The default functions avoid putting all attachment directories directly
inside [[#org_attach_id_dir][org_attach_id_dir]]. Some file systems have performance issues in
such scenarios.

Be careful when changing this setting. If you remove a function, previously
created attachment folders may be no longer mapped correctly and Org may be
unable to detect them.

*** org_attach_sync_delete_empty_dir
:PROPERTIES:
:CUSTOM_ID: org_attach_sync_delete_empty_dir
:END:
- Type: ='always'|'ask'|'never'=
- Default: ='ask'=

Determines whether to delete empty directories during [[https://orgmode.org/manual/Attachment-defaults-and-dispatcher.html*index-C_002dc-C_002da-z][org_attach_sync]].

- =never= - never delete empty directories
- =ask= - ask the user whether to delete
- =always= - delete empty directories without asking

** Mappings
:PROPERTIES:
:CUSTOM_ID: mappings
Expand Down Expand Up @@ -2032,6 +2228,13 @@ See [[#clocking][Clocking]] for more details.
- Mapped to: =<leader>obt=
Tangle current file. See [[#extract-source-code-tangle][Extract source code (tangle)]] for more details.

**** org_attach
:PROPERTIES:
:CUSTOM_ID: org_attach
:END:
- Mapped to: =<Leader>o<C-A>=
Open the attach dispatcher. See [[#attachments][Attachments]] for more details.

**** org_show_help
:PROPERTIES:
:CUSTOM_ID: org_show_help
Expand Down Expand Up @@ -2790,6 +2993,43 @@ Running [[#org_babel_tangle][org_babel_tangle]] will create file =~/org/my_tangl
=print('Headline 1')=
=#+end_src=

*** Attachments
:PROPERTIES:
:CUSTOM_ID: attachments
:END:

There is almost complete support for file attachments (Orgmode link:
[[https://orgmode.org/manual/Attachments.html][Attachments]]). You can use [[#org_attach][org_attach]] to open the dispatcher and attach
files to an "attachment node" (either a headline or an entire org
file).

Attaching a file puts it in a directory associated with the attachment node.
Based on [[#org_attach_preferred_new_method][org_attach_preferred_new_method]], this either uses the =ID= or
the =DIR= property. See also [[#org_attach_id_dir][org_attach_id_dir]],
[[#org_attach_dir_relative][org_attach_dir_relative]], [[#org_attach_id_to_path_function_list][org_attach_id_to_path_function_list]] and
[[#org_attach_use_inheritance][org_attach_use_inheritance]] on how to further customize the attachments
directory.

Attachment links are supported. A link like =[[attachment:file.txt]]=
looks up =file.txt= in the current node's attachments directory and opens
it. Attaching a file stores a link to the attachment. See
[[#org_attach_store_link_p][org_attach_store_link_p]] on how to configure this behavior.

You can also attach files from a different buffer. The following
mapping attaches the path under the cursor to the current headline of the
most recently open org file:

#+begin_src lua
vim.keymap.set('n', '<Leader>o+', function()
local file = vim.fn.expand('<cfile>')
local org = require('orgmode')
org.attach:attach_to_other_buffer(file)
end)
#+end_src

The only missing feature is expansion of attachment links before exporting
a file with [[#org_export][org_exporting]].

** User interface
:PROPERTIES:
:CUSTOM_ID: user-interface
Expand Down
3 changes: 3 additions & 0 deletions docs/index.org
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ List of available actions:
- =:Org helpgrep= - Open search agenda view that allows searching through the documentation
- =:Org agenda {type?}= - Open agenda view by the shortcut, for example =:Org agenda M= will open =tags_todo= view. When =type= is omitted, it opens up Agenda view.
- =:Org capture {type?}= - Open capture template by the shortcut, for example =:Org capture t=. When =type= is omitted, it opens up Capture prompt.
- =:Org attach {type?}= - Take attachment action by the shortcut, for example =:Org attach o= will prompt for an attached file to open. When =type= is omitted, it opens up Attach prompt.
- =:Org install_treesitter_grammar= - Install the treesitter grammar for Orgmode. If installed, prompt to reinstall. Grammar is installed automatically
on first run, but this is useful in case when there are issues with the grammar.

Expand All @@ -75,3 +76,5 @@ All of the commands above can be executed through the global Lua =Org= variable.
- =Org.agenda.m()= - Opens =tags= view
- =Org.capture()= - Opens capture prompt
- =Org.capture.t()= - Opens capture template for =t= shortcut
- =Org.attach()= - Opens attach prompt
- =Org.attach.c()= - Opens attach template for =c= shortcut
Loading
Loading