summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNicolas Goaziou <n.goaziou@gmail.com>2011-08-18 23:13:00 +0200
committerNicolas Goaziou <n.goaziou@gmail.com>2011-08-18 23:14:08 +0200
commit0c6b67c191e886b0a2162684e087cdd15a724907 (patch)
treed2cd485091c1f8680c542f5e6543cdf324781dd3
parent78e59a22d093f125a504983ac8a7dbe504e81c71 (diff)
downloadorg-mode-0c6b67c191e886b0a2162684e087cdd15a724907.tar.gz
org-indent: changes to the internals of initialization
* lisp/org-indent.el (org-indent-agent-timer, org-indent-agentized-buffers, org-indent-agent-resume-timer, org-indent-agent-process-duration, org-indent-agent-resume-delay): new variables. (org-indent-initial-marker): more accurate doc-string. (org-indent-initial-timer, org-indent-initial-resume-timer, org-indent-initial-process-duration, org-indent-initial-resume-delay, org-indent-initial-lock): removed variables. (org-indent-mode): set up an agent to watch current buffer, or add it to the list of already watched buffers. (org-indent-initialize-agent): new function. (org-indent-initialize-buffer): now requires a mandatory buffer argument. (org-indent-add-properties): reflect changes to variables. The resume timer is now global. This change was introduced because a buffer killed while initializing couldn't cancel its own initialization timer. Now, a global agent watches for buffers, starting or resuming their initialization when appropriate. It can cancel its own timer, thus killing itself, when no more buffers are being watched.
-rw-r--r--lisp/org-indent.el101
1 files changed, 58 insertions, 43 deletions
diff --git a/lisp/org-indent.el b/lisp/org-indent.el
index 44160d7..884d0f7 100644
--- a/lisp/org-indent.el
+++ b/lisp/org-indent.el
@@ -69,18 +69,19 @@ It will be set in `org-indent-initialize'.")
It will be set in `org-indent-initialize'.")
(defvar org-indent-inlinetask-first-star (org-add-props "*" '(face org-warning))
"First star of inline tasks, with correct face.")
+(defvar org-indent-agent-timer nil
+ "Timer running the initialize agent.")
+(defvar org-indent-agentized-buffers nil
+ "List of buffers watched by the initialize agent.")
+(defvar org-indent-agent-resume-timer nil
+ "Timer to reschedule agent after switching to other idle processes.")
+(defvar org-indent-agent-process-duration '(0 2 0)
+ "Time to run agent before switching to other idle processes.")
+(defvar org-indent-agent-resume-delay '(0 0 200000)
+ "Minimal time for other idle processes before switching back to agent.")
(defvar org-indent-initial-marker nil
- "Position of initialization before interrupt.")
-(defvar org-indent-initial-timer nil
- "Timer used for initialization.")
-(defvar org-indent-initial-resume-timer nil
- "Timer used to reschedule initialization process.")
-(defvar org-indent-initial-process-duration '(0 2 0)
- "How long before initialization gives hand to other idle processes.")
-(defvar org-indent-initial-resume-delay '(0 0 200000)
- "How long before resuming initialization process.")
-(defvar org-indent-initial-lock nil
- "Lock used of initialization.")
+ "Position of initialization before interrupt.
+This is used locally in each buffer being initialized.")
(defvar org-hide-leading-stars-before-indent-mode nil
"Used locally.")
(defvar org-indent-modified-headline-flag nil
@@ -173,8 +174,6 @@ during idle time." nil " Ind" nil
(org-set-local 'indent-tabs-mode nil)
(or org-indent-strings (org-indent-initialize))
(org-set-local 'org-indent-initial-marker (copy-marker 1))
- (org-set-local 'org-indent-initial-lock nil)
- (org-set-local 'org-indent-initial-resume-timer nil)
(when org-indent-mode-turns-off-org-adapt-indentation
(org-set-local 'org-adapt-indentation nil))
(when org-indent-mode-turns-on-hiding-stars
@@ -189,13 +188,19 @@ during idle time." nil " Ind" nil
'org-indent-notify-modified-headline nil 'local)
(and font-lock-mode (org-restart-font-lock))
(org-indent-remove-properties (point-min) (point-max))
- (org-set-local 'org-indent-initial-timer
- (run-with-idle-timer 0.2 t #'org-indent-initialize-buffer)))
+ ;; Submit current buffer to initialize agent. If it's the first
+ ;; buffer submitted, also start the agent. Current buffer is
+ ;; pushed in both cases to avoid a race condition.
+ (if org-indent-agentized-buffers
+ (push (current-buffer) org-indent-agentized-buffers)
+ (push (current-buffer) org-indent-agentized-buffers)
+ (setq org-indent-agent-timer
+ (run-with-idle-timer 0.2 t #'org-indent-initialize-agent))))
(t
;; mode was turned off (or we refused to turn it on)
(kill-local-variable 'org-adapt-indentation)
- (when (timerp org-indent-initial-timer)
- (cancel-timer org-indent-initial-timer))
+ (setq org-indent-agentized-buffers
+ (delq (current-buffer) org-indent-agentized-buffers))
(when (markerp org-indent-initial-marker)
(set-marker org-indent-initial-marker nil))
(when (boundp 'org-hide-leading-stars-before-indent-mode)
@@ -228,26 +233,36 @@ during idle time." nil " Ind" nil
'(line-prefix nil wrap-prefix nil) string)
string)
-(defun org-indent-initialize-buffer ()
- "Set virtual indentation for the whole buffer asynchronously."
- (when (and org-indent-mode (not org-indent-initial-lock))
- ;; Clean reschedule timer (cf `org-indent-add-properties').
- (when org-indent-initial-resume-timer
- (cancel-timer org-indent-initial-resume-timer))
- (org-with-wide-buffer
- (setq org-indent-initial-lock t)
- (let ((interruptp
- ;; Always nil unless interrupted.
- (catch 'interrupt
- (and org-indent-initial-marker
- (marker-position org-indent-initial-marker)
- (org-indent-add-properties org-indent-initial-marker
- (point-max) t)
- nil))))
- (move-marker org-indent-initial-marker interruptp)
- ;; Job is complete: stop idle timer.
- (unless interruptp (cancel-timer org-indent-initial-timer))))
- (setq org-indent-initial-lock nil)))
+(defun org-indent-initialize-agent ()
+ "Start or resume current buffer initialization.
+Only buffers in `org-indent-agentized-buffers' trigger an action.
+When no more buffer is being watched, the agent suppress itself."
+ (setq org-indent-agentized-buffers
+ (org-remove-if-not #'buffer-live-p org-indent-agentized-buffers))
+ (unless org-indent-agentized-buffers (cancel-timer org-indent-agent-timer))
+ (when org-indent-agent-resume-timer
+ (cancel-timer org-indent-agent-resume-timer))
+ (when (memq (current-buffer) org-indent-agentized-buffers)
+ (org-indent-initialize-buffer (current-buffer))))
+
+(defun org-indent-initialize-buffer (buffer)
+ "Set virtual indentation for the buffer BUFFER, asynchronously."
+ (with-current-buffer buffer
+ (when org-indent-mode
+ (org-with-wide-buffer
+ (let ((interruptp
+ ;; Always nil unless interrupted.
+ (catch 'interrupt
+ (and org-indent-initial-marker
+ (marker-position org-indent-initial-marker)
+ (org-indent-add-properties org-indent-initial-marker
+ (point-max) t)
+ nil))))
+ (move-marker org-indent-initial-marker interruptp)
+ ;; Job is complete: un-agentize buffer.
+ (unless interruptp
+ (setq org-indent-agentized-buffers
+ (delq buffer org-indent-agentized-buffers))))))))
(defsubst org-indent-set-line-properties (l w h)
"Set prefix properties on current line an move to next one.
@@ -304,7 +319,7 @@ you want to use this feature."
(+ (* org-indent-indentation-per-level
(1- (org-inlinetask-get-task-level))) 2)))
(time-limit (time-add (current-time)
- org-indent-initial-process-duration)))
+ org-indent-agent-process-duration)))
;; 2. For each line, set `line-prefix' and `wrap-prefix'
;; properties depending on the type of line (headline,
;; inline task, item or other).
@@ -314,15 +329,15 @@ you want to use this feature."
;; When in async mode, check if interrupt is required.
((and async (input-pending-p)) (throw 'interrupt (point)))
;; In async mode, take a break of
- ;; `org-indent-initial-resume-delay' every
- ;; `org-indent-initial-process-duration' to avoid blocking
+ ;; `org-indent-agent-resume-delay' every
+ ;; `org-indent-agent-process-duration' to avoid blocking
;; any other idle timer or process output.
((and async (time-less-p time-limit (current-time)))
- (setq org-indent-initial-resume-timer
+ (setq org-indent-agent-resume-timer
(run-with-idle-timer
(time-add (current-idle-time)
- org-indent-initial-resume-delay)
- nil #'org-indent-initialize-buffer))
+ org-indent-agent-resume-delay)
+ nil #'org-indent-initialize-agent))
(throw 'interrupt (point)))
;; Headline or inline task.
((looking-at org-outline-regexp)