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.
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))))