1

The documentation says:

(org-set-property PROPERTY VALUE)

When called interactively, this will prompt for a property name, offering completion on existing and default properties. And then it will prompt for a value, offering completion either on allowed values (via an inherited xxx_ALL property) or on existing values in other instances of this property in the current file.

And indeed, if I omit the value, it prompts me upon invoking the mapping (defined via map! from doom):

(map! :desc "Set ID property" "lI"
      '(lambda ()
         (interactive)
         (org-set-property "ID")))

prompt

But if I supply a value, it takes it directly and does not open the prompt for customization:

(map! :desc "Set ID property" "lI"
      '(lambda ()
         (interactive)
         (org-set-property "ID" "default-value")))

Can I pass a default value that can still be interactively adjusted?

xeruf
  • 344
  • 1
  • 13

2 Answers2

2

No. org-set-property does exactly what the documentation says: it only prompts for a value if no value is specified as an argument. Because it says nothing about specifying a default value for that prompt, there is no default value for that prompt.

However, you could modify it fairly easily to support your use–case. If you look in org.el, you will find how it deals with the value argument:

(let ((value (or value (org-read-property-value property)))
      …)
  …)

As you can see, if value is nil then it calls org-read-property-value. If you look at the documentation for org-read-property-value, you will see that it does take an extra argument that specifies the default value for the input:

(org-read-property-value PROPERTY &optional POM DEFAULT)

Documentation Read value for PROPERTY, as a string.

When optional argument POM is non-nil, completion uses additional information, i.e., allowed or existing values at point or marker POM. Optional argument DEFAULT provides a default value for PROPERTY.

So you could change the argument list of org-set-property to (property value &optional default-value), then pass that information along like this:

(let ((value (or value (org-read-property-value property nil default-value)))
      …)
  …)

Note that you don’t actually need to modify org.el; you can instead use advice to override the definition of this function. See chapter 13.11 Advising Emacs Lisp Functions for more information about how to do this.

Edit:

Oh, and as a commenter mentioned, you don’t need a quote ' in front of a lambda expression. Write your keybinding like this instead:

(map! :desc "Set ID property" "lI"
      (lambda ()
        (interactive)
        (org-set-property "ID")))

Of course, that has nothing to do with your question. It’s just that the quote prevents the Elisp compiler from optimizing your code. It is unlikely that you would notice a performance different though.

db48x
  • 17,977
  • 1
  • 22
  • 28
  • 1
    thank you very much, this is undoubtedly insightful! But somehow the DEFAULT parameter does not work, if I invoke the following: (org-read-property-value "id" nil "test") I still get an empty prompt. – xeruf May 16 '22 at 20:03
  • 1
    Oh, interesting. If you look at the code for org-read-property-value, it only uses the supplied default value if it can compute a list of allowed values for the property. Otherwise it supplies a list of all existing values for completion, with the default value being the current property value if any. In that case the initial-text of the prompt is left empty, so that the user can change the value without deleting that text first. – db48x May 16 '22 at 20:19
  • So if you were doing this for the TODO property, your default value would be respected since it has a well–defined list of allowable TODO keywords for every org file. But that doesn’t apply to the ID property, which can be anything the user wants. – db48x May 16 '22 at 20:21
  • maybe I can temporarily set the xxx_ALL property mentioned in the docs? – xeruf May 16 '22 at 20:33
  • aha, setting (add-to-list 'org-global-properties-fixed '("ID_ALL" . "test")) globally fixes it - the value does not matter, it simply needs to be there :) – xeruf May 16 '22 at 20:53
  • nope, still not correct - when ID_ALL is set, I can't change the default, the allowed values are restricted :/ – xeruf Jun 01 '22 at 12:14
0

This was a bug, and is now fixed: https://lists.gnu.org/archive/html/emacs-orgmode/2023-02/msg00109.html

xeruf
  • 344
  • 1
  • 13