π

UOMF: Easy Entering Values for Org Mode Properties

Show Sidebar

Silent update 2019-09-25: added to blog series "Using Org Mode Features"

Update 2019-11-15: Screencast demo

Please do read my "Using Org Mode Features" (UOMF) series page for explanations on articles of this series.

If you are using Org-mode you might find yourself in a position, where you want to set or update a property value for an existing property.

In my case, I frequently do this for my contacts. Whenever a phone number changes, I add a note to the heading of the corresponding contact. Additionally, I maintain phone numbers in properties as well. To do this in a sane way, I only mark the new phone number (region) and press a keyboard shortcut which calls an Elisp function. This function asks me for the name of a property (with tab completion). Then, the value of this property is set to the string of the region.

Very handy.

Here is the Elisp code of my-org-region-to-property() which was made possible with the help of Antoine R. Dumont:

(defun org-read-entry-property-name ()
  "Read a property name from the current entry."
  (let ((completion-ignore-case t)
        (default-prop (or (and (org-at-property-p)
                               (org-match-string-no-properties 2))
                          org-last-set-property)))
    (org-completing-read
     (format "Property [%s]: " (if default-prop default-prop ""))
     (org-entry-properties nil nil)
     nil nil nil nil default-prop)))

(defun my-org-region-to-property (&optional property)
  "Copies the region as value to an Org-mode property"
  (interactive)
  ;; if no region is defined, do nothing
  (if (use-region-p)
      ;; if a region string is found, ask for a property and set property to
      ;; the string in the region
      (let ((val (replace-regexp-in-string
                  "\\`[ \t\n]*" ""
                  (replace-regexp-in-string "[ \t\n]*\\'" ""
                                            (substring (buffer-string)
                                                       (- (region-beginning) 1)
                                                       (region-end))))
                 )
            ;; if none was stated by user, read property from user
            (prop (or property
                      (org-read-entry-property-name))))
        ;; set property
        (org-set-property prop val))))	  

In the following screencast, you can see how I am adding a new contact to my Org mode contacts.org and how I make use of my-org-region-to-property():


Related articles that link to this one:

Comment via email (persistent) or via Disqus (ephemeral) comments below: