From 4fca6b54b518724fab7466f891aa2525699d3ce5 Mon Sep 17 00:00:00 2001 From: Eric Schulte Date: Wed, 17 Nov 2010 13:04:10 -0700 Subject: [PATCH 1/8] org-babel-load-file can now be called interactively * lisp/ob-tangle.el (org-babel-load-file): Can be called interactively. --- lisp/ob-tangle.el | 1 + 1 file changed, 1 insertion(+) diff --git a/lisp/ob-tangle.el b/lisp/ob-tangle.el index e197ff37d..8e7367d79 100644 --- a/lisp/ob-tangle.el +++ b/lisp/ob-tangle.el @@ -125,6 +125,7 @@ evaluating BODY." This function exports the source code using `org-babel-tangle' and then loads the resulting file using `load-file'." + (interactive "fFile to load: ") (flet ((age (file) (float-time (time-subtract (current-time) From 88947588bc8436b5d36d76d6d24cc5d410ad9962 Mon Sep 17 00:00:00 2001 From: Eric Schulte Date: Wed, 17 Nov 2010 16:42:52 -0700 Subject: [PATCH 2/8] lists are now a data type recognized by code blocks * lisp/ob-ref.el (org-babel-ref-resolve): Recognize `list' as a unique type of data (org-babel-ref-at-ref-p): Recognize `list' as a unique type of data * lisp/ob.el (org-babel-read-result): Recognize `list' as a unique type of data (org-babel-read-list): A function to read a textual Org-mode list into an emacs-lisp list. (org-babel-insert-result): Recognizes the "list" result param to insert data as an Org-mode list. (org-babel-result-end): Find the end of an Org-mode list. (org-babel-merge-params): Add "list" as a result param. * doc/org.texi (results): Documentation of the new "list" results header argument. --- doc/org.texi | 7 +++++-- lisp/ob-ref.el | 2 ++ lisp/ob.el | 26 +++++++++++++++++++++----- 3 files changed, 28 insertions(+), 7 deletions(-) diff --git a/doc/org.texi b/doc/org.texi index bef8fa3a5..06583d731 100644 --- a/doc/org.texi +++ b/doc/org.texi @@ -11758,8 +11758,8 @@ another by commas, as shown in the following example. @node results, file, var, Specific header arguments @subsubsection @code{:results} -There are three classes of @code{:results} header argument. Only one option of -each type may be supplied per code block. +There are three classes of @code{:results} header argument. Only one option +per class may be supplied per code block. @itemize @bullet @item @@ -11802,6 +11802,9 @@ table or scalar depending on their value. The results should be interpreted as an Org-mode table. If a single value is returned, it will be converted into a table with one row and one column. E.g., @code{:results value table}. +@item @code{list} +The results should be interpreted as an Org-mode list. If a single scalar +value is returned it will be converted into a list with only one element. @item @code{scalar}, @code{verbatim} The results should be interpreted literally---they will not be converted into a table. The results will be inserted into the Org-mode diff --git a/lisp/ob-ref.el b/lisp/ob-ref.el index 3dee798b6..dd59b3977 100644 --- a/lisp/ob-ref.el +++ b/lisp/ob-ref.el @@ -147,6 +147,7 @@ the variable." (case type ('results-line (org-babel-read-result)) ('table (org-babel-read-table)) + ('list (org-babel-read-list)) ('file (org-babel-read-link)) ('source-block (org-babel-execute-src-block nil nil params)) ('lob (org-babel-execute-src-block nil lob-info params))))) @@ -214,6 +215,7 @@ to \"0:-1\"." Return nil if none of the supported reference types are found. Supported reference types are tables and source blocks." (cond ((org-at-table-p) 'table) + ((org-list-in-item-p-with-indent 0) 'list) ((looking-at "^[ \t]*#\\+BEGIN_SRC") 'source-block) ((looking-at org-bracket-link-regexp) 'file) ((looking-at org-babel-result-regexp) 'results-line))) diff --git a/lisp/ob.el b/lisp/ob.el index 3c6696345..afb3986e7 100644 --- a/lisp/ob.el +++ b/lisp/ob.el @@ -1307,6 +1307,7 @@ following the source block." (let ((case-fold-search t) result-string) (cond ((org-at-table-p) (org-babel-read-table)) + ((org-list-in-item-p-with-indent 0) (org-babel-read-list)) ((looking-at org-bracket-link-regexp) (org-babel-read-link)) ((looking-at org-block-regexp) (org-babel-trim (match-string 4))) ((looking-at "^[ \t]*: ") @@ -1332,6 +1333,10 @@ following the source block." (mapcar #'org-babel-read row))) (org-table-to-lisp))) +(defun org-babel-read-list () + "Read the list at `point' into emacs-lisp." + (mapcar #'org-babel-read (cdr (org-list-parse-list)))) + (defvar org-link-types-re) (defun org-babel-read-link () "Read the link at `point' into emacs-lisp. @@ -1365,7 +1370,9 @@ silent -- no results are inserted file ---- the results are interpreted as a file path, and are inserted into the buffer using the Org-mode file syntax -raw ----- results are added directly to the org-mode file. This +list ---- the results are interpreted as an Org-mode list. + +raw ----- results are added directly to the Org-mode file. This is a good option if you code block will output org-mode formatted text. @@ -1430,6 +1437,13 @@ code ---- the results are extracted in the syntax of the source (cond ;; do nothing for an empty result ((= (length result) 0)) + ;; insert a list if preferred + ((member "list" result-params) + (insert + (org-babel-trim + (org-list-to-generic (cons 'unordered + (if (listp result) result (list result))) + '(:splicep nil :istart "- " :iend "\n"))))) ;; assume the result is a table if it's not a string ((not (stringp result)) (insert (concat (orgtbl-to-orgtbl @@ -1482,8 +1496,10 @@ code ---- the results are extracted in the syntax of the source (defun org-babel-result-end () "Return the point at the end of the current set of results" (save-excursion - (if (org-at-table-p) - (progn (goto-char (org-table-end)) (point)) + (cond + ((org-at-table-p) (progn (goto-char (org-table-end)) (point))) + ((org-list-in-item-p-with-indent 0) (- (org-list-bottom-point) 1)) + (t (let ((case-fold-search t)) (cond ((looking-at "[ \t]*#\\+begin_latex") @@ -1500,7 +1516,7 @@ code ---- the results are extracted in the syntax of the source (forward-line 1)) (t (progn (while (looking-at "[ \t]*\\(: \\|\\[\\[\\)") (forward-line 1)))))) - (point)))) + (point))))) (defun org-babel-result-to-file (result) "Convert RESULT into an `org-mode' link. @@ -1550,7 +1566,7 @@ Later elements of PLISTS override the values of previous element. This takes into account some special considerations for certain parameters when merging lists." (let ((results-exclusive-groups - '(("file" "vector" "table" "scalar" "raw" "org" + '(("file" "list" "vector" "table" "scalar" "raw" "org" "html" "latex" "code" "pp") ("replace" "silent" "append" "prepend") ("output" "value"))) From 97f4c3f9a1bffef82593af25b43a87f0768f3f3c Mon Sep 17 00:00:00 2001 From: Eric Schulte Date: Wed, 17 Nov 2010 17:03:22 -0700 Subject: [PATCH 3/8] fixed (hopefully) error in compiled form of org-babel-map-src-blocks * lisp/ob.el (org-babel-map-src-blocks): Ensure that the file argument is only evaluated once. --- lisp/ob.el | 58 ++++++++++++++++++++++++++++-------------------------- 1 file changed, 30 insertions(+), 28 deletions(-) diff --git a/lisp/ob.el b/lisp/ob.el index afb3986e7..30f54b827 100644 --- a/lisp/ob.el +++ b/lisp/ob.el @@ -780,34 +780,36 @@ body ------------- string holding the body of the code block beg-body --------- point at the beginning of the body end-body --------- point at the end of the body" (declare (indent 1)) - `(let ((visited-p (or (null ,file) - (get-file-buffer (expand-file-name ,file)))) - (point (point)) to-be-removed) - (save-window-excursion - (when ,file (find-file ,file)) - (setq to-be-removed (current-buffer)) - (goto-char (point-min)) - (while (re-search-forward org-babel-src-block-regexp nil t) - (goto-char (match-beginning 0)) - (let ((full-block (match-string 0)) - (beg-block (match-beginning 0)) - (end-block (match-end 0)) - (lang (match-string 2)) - (beg-lang (match-beginning 2)) - (end-lang (match-end 2)) - (switches (match-string 3)) - (beg-switches (match-beginning 3)) - (end-switches (match-end 3)) - (header-args (match-string 4)) - (beg-header-args (match-beginning 4)) - (end-header-args (match-end 4)) - (body (match-string 5)) - (beg-body (match-beginning 5)) - (end-body (match-end 5))) - ,@body - (goto-char end-block)))) - (unless visited-p (kill-buffer to-be-removed)) - (goto-char point))) + (let ((tempvar (make-symbol "file"))) + `(let* ((,tempvar ,file) + (visited-p (or (null ,tempvar) + (get-file-buffer (expand-file-name ,tempvar)))) + (point (point)) to-be-removed) + (save-window-excursion + (when ,tempvar (find-file ,tempvar)) + (setq to-be-removed (current-buffer)) + (goto-char (point-min)) + (while (re-search-forward org-babel-src-block-regexp nil t) + (goto-char (match-beginning 0)) + (let ((full-block (match-string 0)) + (beg-block (match-beginning 0)) + (end-block (match-end 0)) + (lang (match-string 2)) + (beg-lang (match-beginning 2)) + (end-lang (match-end 2)) + (switches (match-string 3)) + (beg-switches (match-beginning 3)) + (end-switches (match-end 3)) + (header-args (match-string 4)) + (beg-header-args (match-beginning 4)) + (end-header-args (match-end 4)) + (body (match-string 5)) + (beg-body (match-beginning 5)) + (end-body (match-end 5))) + ,@body + (goto-char end-block)))) + (unless visited-p (kill-buffer to-be-removed)) + (goto-char point)))) (defvar org-file-properties) (defun org-babel-params-from-properties (&optional lang) From c538b0eeab5e9c62dfdc447acd9b5ce4cabd92f0 Mon Sep 17 00:00:00 2001 From: Nicolas Goaziou Date: Wed, 17 Nov 2010 23:08:15 +0100 Subject: [PATCH 4/8] Fix indentation of drawers, blocks and literal examples * lisp/org.el (org-indent-line-function): drawers and blocks have no influence on indentation of text below. Also fix indentation problem with a block at column 0 and add a special case for literal examples. --- lisp/org.el | 33 ++++++++++++++++++--------------- 1 file changed, 18 insertions(+), 15 deletions(-) diff --git a/lisp/org.el b/lisp/org.el index e45dab0c1..023e0195c 100644 --- a/lisp/org.el +++ b/lisp/org.el @@ -18671,7 +18671,7 @@ which make use of the date at the cursor." ;; We want this to be just right, so use the full arsenal. (defun org-indent-line-function () - "Indent line like previous, but further if previous was headline or item." + "Indent line depending on context." (interactive) (let* ((pos (point)) (itemp (org-at-item-p)) @@ -18680,13 +18680,15 @@ which make use of the date at the cursor." (inline-task-p (and (featurep 'org-inlinetask) (org-inlinetask-in-task-p))) column bpos bcol tpos tcol) - ;; Find the previous relevant line (beginning-of-line 1) (cond ;; Comments - ((looking-at "#") (setq column 0)) + ((looking-at "# ") (setq column 0)) ;; Headings ((looking-at "\\*+ ") (setq column 0)) + ;; Literal examples + ((looking-at "[ \t]*:[ \t]") + (setq column (org-get-indentation))) ; do nothing ;; Drawers ((and (looking-at "[ \t]*:END:") (save-excursion (re-search-backward org-drawer-regexp nil t))) @@ -18719,20 +18721,23 @@ which make use of the date at the cursor." (setq tcol (+ bcol 5))) (goto-char pos) (setq column (if itemp (org-get-indentation) tcol))) - ;; This line has nothing special, look upside to get a clue about - ;; what to do. + ;; This line has nothing special, look at the previous relevant + ;; line to compute indentation (t (beginning-of-line 0) (while (and (not (bobp)) + (not (looking-at org-drawer-regexp)) ;; skip comments, verbatim, empty lines, tables, - ;; inline tasks - (or (looking-at "[ \t]*[\n:#|]") + ;; inline tasks, lists, drawers and blocks + (or (and (looking-at "[ \t]*:END:") + (re-search-backward org-drawer-regexp nil t)) + (and (looking-at "[ \t]*#\\+end_") + (re-search-backward "[ \t]*#\\+begin_"nil t)) + (looking-at "[ \t]*[\n:#|]") (and (org-in-item-p) (goto-char (org-list-top-point))) (and (not inline-task-p) (featurep 'org-inlinetask) - (org-inlinetask-in-task-p))) - (not (looking-at "[ \t]*:END:")) - (not (looking-at org-drawer-regexp))) + (org-inlinetask-in-task-p)))) (beginning-of-line 0)) (cond ;; There was an heading above. @@ -18741,20 +18746,18 @@ which make use of the date at the cursor." (setq column 0) (goto-char (match-end 0)) (setq column (current-column)))) - ;; A drawer had started and is unfinished: indent consequently. + ;; A drawer had started and is unfinished ((looking-at org-drawer-regexp) (goto-char (1- (match-beginning 1))) (setq column (current-column))) - ;; The drawer had ended: indent like its :END: line. - ((looking-at "\\([ \t]*\\):END:") - (goto-char (match-end 1)) - (setq column (current-column))) ;; Else, nothing noticeable found: get indentation and go on. (t (setq column (org-get-indentation)))))) + ;; Now apply indentation and move cursor accordingly (goto-char pos) (if (<= (current-column) (current-indentation)) (org-indent-line-to column) (save-excursion (org-indent-line-to column))) + ;; Special polishing for properties, see `org-property-format' (setq column (current-column)) (beginning-of-line 1) (if (looking-at From 14b52a05fa9c0a560ed257d4dd3e1f9f6d27bfa0 Mon Sep 17 00:00:00 2001 From: Eric Schulte Date: Wed, 10 Nov 2010 14:00:53 -0700 Subject: [PATCH 5/8] ob-sqlite: pass the body to the sqlite command through a pipe * lisp/ob-sqlite.el (ob-eval): require ob-eval for external command execution (org-babel-execute:sqlite): no longer uses the init option for passing commands to sqlite --- lisp/ob-sqlite.el | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/lisp/ob-sqlite.el b/lisp/ob-sqlite.el index c744e4334..dd4ea87bb 100644 --- a/lisp/ob-sqlite.el +++ b/lisp/ob-sqlite.el @@ -28,6 +28,7 @@ ;;; Code: (require 'ob) +(require 'ob-eval) (require 'ob-ref) (declare-function org-fill-template "org" (template alist)) @@ -65,15 +66,10 @@ This function is called by `org-babel-execute-src-block'." (unless db (error "ob-sqlite: can't evaluate without a database.")) (with-temp-buffer (insert - (shell-command-to-string + (org-babel-eval (org-fill-template - "%cmd -init %body %header %separator %nullvalue %others %csv %db " + "%cmd %header %separator %nullvalue %others %csv %db " (list - (cons "body" ((lambda (sql-file) - (with-temp-file sql-file - (insert (org-babel-expand-body:sqlite body params))) - sql-file) - (org-babel-temp-file "sqlite-sql-"))) (cons "cmd" org-babel-sqlite3-command) (cons "header" (if headers-p "-header" "-noheader")) (cons "separator" @@ -90,7 +86,9 @@ This function is called by `org-babel-execute-src-block'." (member :html others) separator) "" "-csv")) - (cons "db " db))))) + (cons "db " db))) + ;; body of the code block + (org-babel-expand-body:sqlite body params))) (if (or (member "scalar" result-params) (member "html" result-params) (member "code" result-params) From e34033fec2c8bbfa000ac291a9889ca49fa5dc17 Mon Sep 17 00:00:00 2001 From: Eric Schulte Date: Thu, 18 Nov 2010 09:34:21 -0700 Subject: [PATCH 6/8] using higher level function for checking list membership Thanks to Nicolas Goaziou for pointing this out * lisp/ob-ref.el (org-babel-ref-at-ref-p): Use higher level function for testing list membership. * lisp/ob.el (org-babel-read-result): Use higher level function for testing list membership. (org-babel-result-end): Use higher level function for testing list membership. --- lisp/ob-ref.el | 2 +- lisp/ob.el | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/lisp/ob-ref.el b/lisp/ob-ref.el index dd59b3977..e482cb835 100644 --- a/lisp/ob-ref.el +++ b/lisp/ob-ref.el @@ -215,7 +215,7 @@ to \"0:-1\"." Return nil if none of the supported reference types are found. Supported reference types are tables and source blocks." (cond ((org-at-table-p) 'table) - ((org-list-in-item-p-with-indent 0) 'list) + ((org-in-item-p) 'list) ((looking-at "^[ \t]*#\\+BEGIN_SRC") 'source-block) ((looking-at org-bracket-link-regexp) 'file) ((looking-at org-babel-result-regexp) 'results-line))) diff --git a/lisp/ob.el b/lisp/ob.el index 30f54b827..96c274434 100644 --- a/lisp/ob.el +++ b/lisp/ob.el @@ -1309,7 +1309,7 @@ following the source block." (let ((case-fold-search t) result-string) (cond ((org-at-table-p) (org-babel-read-table)) - ((org-list-in-item-p-with-indent 0) (org-babel-read-list)) + ((org-in-item-p) (org-babel-read-list)) ((looking-at org-bracket-link-regexp) (org-babel-read-link)) ((looking-at org-block-regexp) (org-babel-trim (match-string 4))) ((looking-at "^[ \t]*: ") @@ -1500,7 +1500,7 @@ code ---- the results are extracted in the syntax of the source (save-excursion (cond ((org-at-table-p) (progn (goto-char (org-table-end)) (point))) - ((org-list-in-item-p-with-indent 0) (- (org-list-bottom-point) 1)) + ((org-in-item-p) (- (org-list-bottom-point) 1)) (t (let ((case-fold-search t)) (cond From 451acd11cef9db348aa26aa1bbc2a300c75cbe88 Mon Sep 17 00:00:00 2001 From: Eric Schulte Date: Fri, 19 Nov 2010 01:16:29 -0700 Subject: [PATCH 7/8] move ob-map-src-blocks up in ob.el and autoload it * lisp/ob.el (org-babel-map-src-blocks): Moved to earlier in the file and now autoloading. --- lisp/ob.el | 107 +++++++++++++++++++++++++++-------------------------- 1 file changed, 54 insertions(+), 53 deletions(-) diff --git a/lisp/ob.el b/lisp/ob.el index 96c274434..368961968 100644 --- a/lisp/ob.el +++ b/lisp/ob.el @@ -584,6 +584,60 @@ results already exist." (insert (echo-res results)))))) t))) +;;;###autoload +(defmacro org-babel-map-src-blocks (file &rest body) + "Evaluate BODY forms on each source-block in FILE. +If FILE is nil evaluate BODY forms on source blocks in current +buffer. During evaluation of BODY the following local variables +are set relative to the currently matched code block. + +full-block ------- string holding the entirety of the code block +beg-block -------- point at the beginning of the code block +end-block -------- point at the end of the matched code block +lang ------------- string holding the language of the code block +beg-lang --------- point at the beginning of the lang +end-lang --------- point at the end of the lang +switches --------- string holding the switches +beg-switches ----- point at the beginning of the switches +end-switches ----- point at the end of the switches +header-args ------ string holding the header-args +beg-header-args -- point at the beginning of the header-args +end-header-args -- point at the end of the header-args +body ------------- string holding the body of the code block +beg-body --------- point at the beginning of the body +end-body --------- point at the end of the body" + (declare (indent 1)) + (let ((tempvar (make-symbol "file"))) + `(let* ((,tempvar ,file) + (visited-p (or (null ,tempvar) + (get-file-buffer (expand-file-name ,tempvar)))) + (point (point)) to-be-removed) + (save-window-excursion + (when ,tempvar (find-file ,tempvar)) + (setq to-be-removed (current-buffer)) + (goto-char (point-min)) + (while (re-search-forward org-babel-src-block-regexp nil t) + (goto-char (match-beginning 0)) + (let ((full-block (match-string 0)) + (beg-block (match-beginning 0)) + (end-block (match-end 0)) + (lang (match-string 2)) + (beg-lang (match-beginning 2)) + (end-lang (match-end 2)) + (switches (match-string 3)) + (beg-switches (match-beginning 3)) + (end-switches (match-end 3)) + (header-args (match-string 4)) + (beg-header-args (match-beginning 4)) + (end-header-args (match-end 4)) + (body (match-string 5)) + (beg-body (match-beginning 5)) + (end-body (match-end 5))) + ,@body + (goto-char end-block)))) + (unless visited-p (kill-buffer to-be-removed)) + (goto-char point)))) + ;;;###autoload (defun org-babel-execute-buffer (&optional arg) "Execute source code blocks in a buffer. @@ -758,59 +812,6 @@ portions of results lines." (lambda () (org-add-hook 'change-major-mode-hook 'org-babel-show-result-all 'append 'local))) -(defmacro org-babel-map-src-blocks (file &rest body) - "Evaluate BODY forms on each source-block in FILE. -If FILE is nil evaluate BODY forms on source blocks in current -buffer. During evaluation of BODY the following local variables -are set relative to the currently matched code block. - -full-block ------- string holding the entirety of the code block -beg-block -------- point at the beginning of the code block -end-block -------- point at the end of the matched code block -lang ------------- string holding the language of the code block -beg-lang --------- point at the beginning of the lang -end-lang --------- point at the end of the lang -switches --------- string holding the switches -beg-switches ----- point at the beginning of the switches -end-switches ----- point at the end of the switches -header-args ------ string holding the header-args -beg-header-args -- point at the beginning of the header-args -end-header-args -- point at the end of the header-args -body ------------- string holding the body of the code block -beg-body --------- point at the beginning of the body -end-body --------- point at the end of the body" - (declare (indent 1)) - (let ((tempvar (make-symbol "file"))) - `(let* ((,tempvar ,file) - (visited-p (or (null ,tempvar) - (get-file-buffer (expand-file-name ,tempvar)))) - (point (point)) to-be-removed) - (save-window-excursion - (when ,tempvar (find-file ,tempvar)) - (setq to-be-removed (current-buffer)) - (goto-char (point-min)) - (while (re-search-forward org-babel-src-block-regexp nil t) - (goto-char (match-beginning 0)) - (let ((full-block (match-string 0)) - (beg-block (match-beginning 0)) - (end-block (match-end 0)) - (lang (match-string 2)) - (beg-lang (match-beginning 2)) - (end-lang (match-end 2)) - (switches (match-string 3)) - (beg-switches (match-beginning 3)) - (end-switches (match-end 3)) - (header-args (match-string 4)) - (beg-header-args (match-beginning 4)) - (end-header-args (match-end 4)) - (body (match-string 5)) - (beg-body (match-beginning 5)) - (end-body (match-end 5))) - ,@body - (goto-char end-block)))) - (unless visited-p (kill-buffer to-be-removed)) - (goto-char point)))) - (defvar org-file-properties) (defun org-babel-params-from-properties (&optional lang) "Retrieve parameters specified as properties. From 85501c06231d47078b3c05da6e8f925d7caf6244 Mon Sep 17 00:00:00 2001 From: Nicolas Goaziou Date: Fri, 19 Nov 2010 23:47:02 +0100 Subject: [PATCH 8/8] Fix cycling bullet with point not at column 0 * org-list.el (org-cycle-list-bullet): ensure point is at bol before checking item indentation. --- lisp/org-list.el | 59 ++++++++++++++++++++++++------------------------ 1 file changed, 30 insertions(+), 29 deletions(-) diff --git a/lisp/org-list.el b/lisp/org-list.el index e54c2a0eb..2290b4a9d 100644 --- a/lisp/org-list.el +++ b/lisp/org-list.el @@ -1629,35 +1629,36 @@ If WHICH is a valid string, use that as the new bullet. If WHICH is an integer, 0 means `-', 1 means `+' etc. If WHICH is 'previous, cycle backwards." (interactive "P") - (let* ((top (org-list-top-point)) - (bullet (save-excursion - (goto-char (org-get-beginning-of-list top)) - (org-get-bullet))) - (current (cond - ((string-match "\\." bullet) "1.") - ((string-match ")" bullet) "1)") - (t bullet))) - (bullet-rule-p (cdr (assq 'bullet org-list-automatic-rules))) - (bullet-list (append '("-" "+" ) - ;; *-bullets are not allowed at column 0 - (unless (and bullet-rule-p - (looking-at "\\S-")) '("*")) - ;; Description items cannot be numbered - (unless (and bullet-rule-p - (or (eq org-plain-list-ordered-item-terminator ?\)) - (org-at-item-description-p))) '("1.")) - (unless (and bullet-rule-p - (or (eq org-plain-list-ordered-item-terminator ?.) - (org-at-item-description-p))) '("1)")))) - (len (length bullet-list)) - (item-index (- len (length (member current bullet-list)))) - (get-value (lambda (index) (nth (mod index len) bullet-list))) - (new (cond - ((member which bullet-list) which) - ((numberp which) (funcall get-value which)) - ((eq 'previous which) (funcall get-value (1- item-index))) - (t (funcall get-value (1+ item-index)))))) - (org-list-repair new top))) + (save-excursion + (let* ((top (org-list-top-point)) + (bullet (progn + (goto-char (org-get-beginning-of-list top)) + (org-get-bullet))) + (current (cond + ((string-match "\\." bullet) "1.") + ((string-match ")" bullet) "1)") + (t bullet))) + (bullet-rule-p (cdr (assq 'bullet org-list-automatic-rules))) + (bullet-list (append '("-" "+" ) + ;; *-bullets are not allowed at column 0 + (unless (and bullet-rule-p + (looking-at "\\S-")) '("*")) + ;; Description items cannot be numbered + (unless (and bullet-rule-p + (or (eq org-plain-list-ordered-item-terminator ?\)) + (org-at-item-description-p))) '("1.")) + (unless (and bullet-rule-p + (or (eq org-plain-list-ordered-item-terminator ?.) + (org-at-item-description-p))) '("1)")))) + (len (length bullet-list)) + (item-index (- len (length (member current bullet-list)))) + (get-value (lambda (index) (nth (mod index len) bullet-list))) + (new (cond + ((member which bullet-list) which) + ((numberp which) (funcall get-value which)) + ((eq 'previous which) (funcall get-value (1- item-index))) + (t (funcall get-value (1+ item-index)))))) + (org-list-repair new top)))) ;;; Checkboxes