瀏覽代碼

Handle inline tasks when marking a subtree

* org-inlinetask.el (org-inlinetask-outline-regexp): new function
* org-inlinetask.el (org-inlinetask-goto-beginning): new function
* org-inlinetask.el (org-inlinetask-goto-end): new function
* org.el (org-mark-subtree): new command
* org.el (org-speed-commands-default, org-mode-map): make use of new command
Nicolas Goaziou 14 年之前
父節點
當前提交
5ecd79ea74
共有 2 個文件被更改,包括 69 次插入10 次删除
  1. 41 9
      lisp/org-inlinetask.el
  2. 28 1
      lisp/org.el

+ 41 - 9
lisp/org-inlinetask.el

@@ -131,24 +131,56 @@ If prefix arg NO-STATE is set, ignore `org-inlinetask-default-state'."
   (end-of-line -1))
 (define-key org-mode-map "\C-c\C-xt" 'org-inlinetask-insert-task)
 
+(defun org-inlinetask-outline-regexp ()
+  "Return string matching an inline task heading.
+The number of levels is controlled by `org-inlinetask-min-level'."
+  (let ((nstars (if org-odd-levels-only
+		    (1- (* org-inlinetask-min-level 2))
+		  org-inlinetask-min-level)))
+    (format "^\\(\\*\\{%d,\\}\\)[ \t]+" nstars)))
+
 (defun org-inlinetask-in-task-p ()
   "Return true if point is inside an inline task."
   (save-excursion
-    (let* ((nstars (if org-odd-levels-only
-		       (1- (* 2 (or org-inlinetask-min-level 200)))
-		     (or org-inlinetask-min-level 200)))
-	   (stars-re (concat "^\\(?:\\*\\{"
-			     (format "%d" (- nstars 1))
-			     ",\\}\\)[ \t]+"))
+    (let* ((stars-re (org-inlinetask-outline-regexp))
 	   (task-beg-re (concat stars-re "\\(?:.*\\)"))
-	   (task-end-re (concat stars-re "\\(?:END\\|end\\)")))
+	   (task-end-re (concat stars-re "\\(?:END\\|end\\)[ \t]*$")))
       (beginning-of-line)
       (or (looking-at task-beg-re)
 	  (and (re-search-forward "^\\*+[ \t]+" nil t)
 	       (progn (beginning-of-line) (looking-at task-end-re)))))))
 
-(defvar htmlp)  ; dynamically scoped into the next function
-(defvar latexp) ; dynamically scoped into the next function
+(defun org-inlinetask-goto-beginning ()
+  "Go to the beginning of the inline task at point."
+  (end-of-line)
+  (re-search-backward (org-inlinetask-outline-regexp) nil t)
+  (when (org-looking-at-p (concat (org-inlinetask-outline-regexp) "END[ \t]*$"))
+    (re-search-backward (org-inlinetask-outline-regexp) nil t)))
+
+(defun org-inlinetask-goto-end ()
+  "Go to the end of the inline task at point."
+  (beginning-of-line)
+  (cond
+   ((org-looking-at-p (concat (org-inlinetask-outline-regexp) "END[ \t]*$"))
+    (forward-line 1))
+   ((org-looking-at-p (org-inlinetask-outline-regexp))
+    (forward-line 1)
+    (when (org-inlinetask-in-task-p)
+      (re-search-forward (org-inlinetask-outline-regexp) nil t)
+      (forward-line 1)))
+   (t
+    (re-search-forward (org-inlinetask-outline-regexp) nil t)
+    (forward-line 1))))
+
+(defun org-inlinetask-get-task-level ()
+  "Get the level of the inline task around.
+This assumes the point is inside an inline task."
+  (save-excursion
+    (end-of-line)
+    (re-search-backward (org-inlinetask-outline-regexp) nil t)
+    (- (match-end 1) (match-beginning 1))))
+
+(defvar backend) ; dynamically scoped into the next function
 (defun org-inlinetask-export-handler ()
   "Handle headlines with level larger or equal to `org-inlinetask-min-level'.
 Either remove headline and meta data, or do special formatting."

+ 28 - 1
lisp/org.el

@@ -3570,6 +3570,8 @@ Normal means, no org-mode-specific context."
 		  "org-agenda" (&optional end))
 (declare-function org-inlinetask-remove-END-maybe "org-inlinetask" ())
 (declare-function org-inlinetask-in-task-p "org-inlinetask" ())
+(declare-function org-inlinetask-goto-beginning "org-inlinetask" ())
+(declare-function org-inlinetask-goto-end "org-inlinetask" ())
 (declare-function org-indent-mode "org-indent" (&optional arg))
 (declare-function parse-time-string "parse-time" (string))
 (declare-function org-attach-reveal "org-attach" (&optional if-exists))
@@ -16353,6 +16355,7 @@ BEG and END default to the buffer boundaries."
 (org-defkey org-mode-map "\C-c\C-xf"    'org-footnote-action)
 (org-defkey org-mode-map "\C-c\C-x\C-mg"    'org-mobile-pull)
 (org-defkey org-mode-map "\C-c\C-x\C-mp"    'org-mobile-push)
+(org-defkey org-mode-map "\C-c@" 'org-mark-subtree)
 (org-defkey org-mode-map [?\C-c (control ?*)] 'org-list-make-subtree)
 ;;(org-defkey org-mode-map [?\C-c (control ?-)] 'org-list-make-list-from-subtree)
 
@@ -16426,7 +16429,7 @@ BEG and END default to the buffer boundaries."
     ("^" . org-sort)
     ("w" . org-refile)
     ("a" . org-archive-subtree-default-with-confirmation)
-    ("." . outline-mark-subtree)
+    ("." . org-mark-subtree)
     ("Clock Commands")
     ("I" . org-clock-in)
     ("O" . org-clock-out)
@@ -18576,6 +18579,30 @@ which make use of the date at the cursor."
   (message
    "Entry marked for action; press `k' at desired date in agenda or calendar"))
 
+(defun org-mark-subtree ()
+  "Mark the current subtree.
+This puts point at the start of the current subtree, and mark at the end.
+
+If point is in an inline task, mark that task instead."
+  (interactive)
+  (let ((inline-task-p
+	 (and (featurep 'org-inlinetask)
+	      (org-inlinetask-in-task-p)))
+	(beg))
+    ;; Get beginning of subtree
+    (cond
+     (inline-task-p (org-inlinetask-goto-beginning))
+     ((org-at-heading-p) (beginning-of-line))
+     (t (outline-previous-visible-heading 1)))
+    (setq beg (point))
+    ;; Get end of it
+    (if	inline-task-p
+	(org-inlinetask-goto-end)
+      (org-end-of-subtree))
+    ;; Mark zone
+    (push-mark (point) nil t)
+    (goto-char beg)))
+
 ;;; Paragraph filling stuff.
 ;; We want this to be just right, so use the full arsenal.