Make some org-sections read-only
Posted September 13, 2014 at 01:50 PM | categories: orgmode, emacs | tags:
There are times where I want an org-file to be partly read-only. For example, there might be instructions that should not be modified. In this post we consider how to implement that. For now, we only want an org-section to be read-only, and we will designate those sections by a tag readonly. Then, the idea is that a hook function would be run when the org-file is loaded, and mark regions of text as read-only before the user can do anything.
In Emacs, you can mark a section of text, and set it to have a property of read-only. So, we can just map over the entries, and any heading that is tagged as readonly can be made read-only!
Here we set the first few characters of this buffer to be read-only.
(add-text-properties 1 8 '(read-only t))
t
Emacs is semi-serious about what read-only means. You cannot even change properties of read-only text, unless you set inhibit-read-only as a variable.
(let ((inhibit-read-only t))
(remove-text-properties 1 8 '(read-only t)))
t
Now, we can map over the entries in this buffer, and set any heading tagged readonly to actually be that way like this.
(org-map-entries (lambda () (let* ((element (org-element-at-point)) (begin (org-element-property :begin element)) (end (org-element-property :end element))) (add-text-properties begin end '(read-only t)))) "read_only")
t |
To get this to work when org-mode is turned on, we just wrap it in a function, add the function to a hook, and a function to undo the read-only behavior. I found that if I use the end reported by org-element-at-point, it includes the first character of the next section, we take one away from the end to avoid that.
(defun org-mark-readonly () (interactive) (org-map-entries (lambda () (let* ((element (org-element-at-point)) (begin (org-element-property :begin element)) (end (org-element-property :end element))) (add-text-properties begin (- end 1) '(read-only t)))) "read_only") (message "Made readonly!")) (defun org-remove-readonly () (interactive) (org-map-entries (lambda () (let* ((element (org-element-at-point)) (begin (org-element-property :begin element)) (end (org-element-property :end element)) (inhibit-read-only t)) (remove-text-properties begin (- end 1) '(read-only t)))) "read_only")) (add-hook 'org-mode-hook 'org-mark-readonly)
That seem to be all there is. After executing the code above, when I open this file, the next section is read-only! I can use the other function to remove that if I need to edit it. Score one for Emacs + org-mode!
1 Read-only section read_only
This text is so important, it should be read-only.
2 Editable section
You can do what you want here. Like add text.
Copyright (C) 2014 by John Kitchin. See the License for information about copying.
Org-mode version = 8.2.7c