Function: org--get-expected-indentation

org--get-expected-indentation is a byte-compiled function defined in org.el.gz.

Signature

(org--get-expected-indentation ELEMENT CONTENTSP)

Documentation

Expected indentation column for current line, according to ELEMENT.

ELEMENT is an element containing point. CONTENTSP is non-nil when indentation is to be computed according to contents of ELEMENT.

Source Code

;; Defined in /usr/src/emacs/lisp/org/org.el.gz
(defun org--get-expected-indentation (element contentsp)
  "Expected indentation column for current line, according to ELEMENT.
ELEMENT is an element containing point.  CONTENTSP is non-nil
when indentation is to be computed according to contents of
ELEMENT."
  (let ((type (org-element-type element))
	(start (org-element-property :begin element))
	(post-affiliated (org-element-property :post-affiliated element)))
    (org-with-wide-buffer
     (cond
      (contentsp
       (cl-case type
	 ((diary-sexp footnote-definition) 0)
         (section
          (org--get-expected-indentation
           (org-element-property :parent element)
           t))
	 ((headline inlinetask nil)
	  (if (not org-adapt-indentation) 0
	    (let ((level (org-current-level)))
	      (if level (1+ level) 0))))
	 ((item plain-list) (org-list-item-body-column post-affiliated))
	 (t
	  (goto-char start)
	  (current-indentation))))
      ((memq type '(headline inlinetask nil))
       (if (org-match-line "[ \t]*$")
	   (org--get-expected-indentation element t)
	 0))
      ((memq type '(diary-sexp footnote-definition)) 0)
      ;; First paragraph of a footnote definition or an item.
      ;; Indent like parent.
      ((< (line-beginning-position) start)
       (org--get-expected-indentation
	(org-element-property :parent element) t))
      ;; At first line: indent according to previous sibling, if any,
      ;; ignoring footnote definitions and inline tasks, or parent's
      ;; contents.  If `org-adapt-indentation' is `headline-data', ignore
      ;; previous headline data siblings.
      ((= (line-beginning-position) start)
       (catch 'exit
	 (while t
	   (if (= (point-min) start) (throw 'exit 0)
	     (goto-char (1- start))
	     (let* ((previous (org-element-at-point))
		    (parent previous))
	       (while (and parent (<= (org-element-property :end parent) start))
		 (setq previous parent
		       parent (org-element-property :parent parent)))
	       (cond
		((not previous) (throw 'exit 0))
		((> (org-element-property :end previous) start)
		 (throw 'exit (org--get-expected-indentation previous t)))
		((memq (org-element-type previous)
		       '(footnote-definition inlinetask))
		 (setq start (org-element-property :begin previous)))
                ;; Do not indent like previous when the previous
                ;; element is headline data and `org-adapt-indentation'
                ;; is set to `headline-data'.
                ((and (eq 'headline-data org-adapt-indentation)
                      (not (org--at-headline-data-p start element))
                      (or (org-at-heading-p)
                          (org--at-headline-data-p (1- start) previous)))
                 (throw 'exit 0))
		(t (goto-char (org-element-property :begin previous))
		   (throw 'exit
			  (if (bolp) (current-indentation)
			    ;; At first paragraph in an item or
			    ;; a footnote definition.
			    (org--get-expected-indentation
			     (org-element-property :parent previous) t))))))))))
      ;; Otherwise, move to the first non-blank line above.
      (t
       (beginning-of-line)
       (let ((pos (point)))
	 (skip-chars-backward " \r\t\n")
	 (cond
	  ;; Two blank lines end a footnote definition or a plain
	  ;; list.  When we indent an empty line after them, the
	  ;; containing list or footnote definition is over, so it
	  ;; qualifies as a previous sibling.  Therefore, we indent
	  ;; like its first line.
	  ((and (memq type '(footnote-definition plain-list))
		(> (count-lines (point) pos) 2))
	   (goto-char start)
	   (current-indentation))
	  ;; Line above is the first one of a paragraph at the
	  ;; beginning of an item or a footnote definition.  Indent
	  ;; like parent.
	  ((< (line-beginning-position) start)
	   (org--get-expected-indentation
	    (org-element-property :parent element) t))
	  ;; Line above is the beginning of an element, i.e., point
	  ;; was originally on the blank lines between element's start
	  ;; and contents.
	  ((= (line-beginning-position) post-affiliated)
	   (org--get-expected-indentation element t))
	  ;; POS is after contents in a greater element.  Indent like
	  ;; the beginning of the element.
	  ((and (memq type org-element-greater-elements)
		(let ((cend (org-element-property :contents-end element)))
		  (and cend (<= cend pos))))
	   ;; As a special case, if point is at the end of a footnote
	   ;; definition or an item, indent like the very last element
	   ;; within.  If that last element is an item, indent like
	   ;; its contents.
	   (if (memq type '(footnote-definition item plain-list))
	       (let ((last (org-element-at-point)))
		 (goto-char pos)
		 (org--get-expected-indentation
		  last (eq (org-element-type last) 'item)))
	     (goto-char start)
	     (current-indentation)))
	  ;; In any other case, indent like the current line.
	  (t (current-indentation)))))
      ;; Finally, no indentation is needed, fall back to 0.
      (t (current-indentation))))))