Make RET and C-j obey `electric-indent-mode'
* lisp/org-compat.el (org-return-indent): Deprecate this command. * lisp/org-keys.el (org-mode-map): Rebind C-j to a command emulating `electric-newline-and-maybe-indent'. * lisp/org.el (org-cdlatex-environment-indent): Stop using the now obsolete function. (org--newline): New helper function. (org-return): Use it to transparently handle `electric-indent-mode'. (org-return-and-maybe-indent): New command to emulate `electric-newline-and-maybe-indent' while taking care of Org special cases (tables, links, timestamps). * testing/lisp/test-org.el (test-org/with-electric-indent, test-org/without-electric-indent): New tests. * testing/org-test.el (org-test-with-minor-mode): New helper to set a minor mode to a specific state, and reset it afterward.
This commit is contained in:
parent
b171ff02f6
commit
d3e6b58004
5 changed files with 158 additions and 17 deletions
33
etc/ORG-NEWS
33
etc/ORG-NEWS
|
@ -215,6 +215,32 @@ configured for ClojureScript will /not/ work.
|
||||||
Babel Java blocks recognize header argument =:cmdargs= and pass its
|
Babel Java blocks recognize header argument =:cmdargs= and pass its
|
||||||
value in call to =java=.
|
value in call to =java=.
|
||||||
|
|
||||||
|
*** =RET= and =C-j= now obey ~electric-indent-mode~
|
||||||
|
|
||||||
|
Since Emacs 24.4, ~electric-indent-mode~ is enabled by default. In
|
||||||
|
most major modes, this causes =RET= to reindent the current line and
|
||||||
|
indent the new line, and =C-j= to insert a newline without indenting.
|
||||||
|
|
||||||
|
Org mode now obeys this minor mode: when ~electric-indent-mode~ is
|
||||||
|
enabled, and point is neither in a table nor on a timestamp or a link:
|
||||||
|
|
||||||
|
- =RET= (bound to ~org-return~) reindents the current line and indents
|
||||||
|
the new line;
|
||||||
|
- =C-j= (bound to the new command ~org-return-and-maybe-indent~)
|
||||||
|
merely inserts a newline.
|
||||||
|
|
||||||
|
To get the previous behaviour back, disable ~electric-indent-mode~
|
||||||
|
explicitly:
|
||||||
|
|
||||||
|
#+begin_src emacs-lisp
|
||||||
|
(add-hook 'org-mode-hook (lambda () (electric-indent-mode -1)))
|
||||||
|
#+end_src
|
||||||
|
|
||||||
|
*** New optional numeric argument for ~org-return~
|
||||||
|
|
||||||
|
In situations where ~org-return~ calls ~newline~, multiple newlines
|
||||||
|
can now be inserted with this prefix argument.
|
||||||
|
|
||||||
** New commands
|
** New commands
|
||||||
*** ~org-table-header-line-mode~
|
*** ~org-table-header-line-mode~
|
||||||
|
|
||||||
|
@ -303,6 +329,13 @@ Use ~org-hide-block-toggle~ instead.
|
||||||
This function was not used in the code base, and has no clear use
|
This function was not used in the code base, and has no clear use
|
||||||
either. It has been marked for future removal. Please contact the
|
either. It has been marked for future removal. Please contact the
|
||||||
mailing list if you use this function.
|
mailing list if you use this function.
|
||||||
|
|
||||||
|
*** Deprecated ~org-return-indent~ function
|
||||||
|
|
||||||
|
In Elisp code, use ~(org-return t)~ instead. Interactively, =C-j= is
|
||||||
|
now bound to ~org-return-and-maybe-indent~, which indents the new line
|
||||||
|
when ~electric-indent-mode~ is disabled.
|
||||||
|
|
||||||
*** Removed ~org-maybe-keyword-time-regexp~
|
*** Removed ~org-maybe-keyword-time-regexp~
|
||||||
|
|
||||||
The variable was not used in the code base.
|
The variable was not used in the code base.
|
||||||
|
|
|
@ -678,6 +678,15 @@ an error. Return a non-nil value when toggling is successful."
|
||||||
(goto-char (match-beginning 0))
|
(goto-char (match-beginning 0))
|
||||||
(org-hide-block-toggle)))))))
|
(org-hide-block-toggle)))))))
|
||||||
|
|
||||||
|
(defun org-return-indent ()
|
||||||
|
"Goto next table row or insert a newline and indent.
|
||||||
|
Calls `org-table-next-row' or `newline-and-indent', depending on
|
||||||
|
context. See the individual commands for more information."
|
||||||
|
(declare (obsolete "use `org-return' with INDENT set to t instead."
|
||||||
|
"Org 9.4"))
|
||||||
|
(interactive)
|
||||||
|
(org-return t))
|
||||||
|
|
||||||
(defmacro org-with-silent-modifications (&rest body)
|
(defmacro org-with-silent-modifications (&rest body)
|
||||||
(declare (obsolete "use `with-silent-modifications' instead." "Org 9.2")
|
(declare (obsolete "use `with-silent-modifications' instead." "Org 9.2")
|
||||||
(debug (body)))
|
(debug (body)))
|
||||||
|
|
|
@ -618,7 +618,7 @@ COMMANDS is a list of alternating OLDDEF NEWDEF command names."
|
||||||
(org-defkey org-mode-map (kbd "C-c C-k") #'org-kill-note-or-show-branches)
|
(org-defkey org-mode-map (kbd "C-c C-k") #'org-kill-note-or-show-branches)
|
||||||
(org-defkey org-mode-map (kbd "C-c #") #'org-update-statistics-cookies)
|
(org-defkey org-mode-map (kbd "C-c #") #'org-update-statistics-cookies)
|
||||||
(org-defkey org-mode-map (kbd "RET") #'org-return)
|
(org-defkey org-mode-map (kbd "RET") #'org-return)
|
||||||
(org-defkey org-mode-map (kbd "C-j") #'org-return-indent)
|
(org-defkey org-mode-map (kbd "C-j") #'org-return-and-maybe-indent)
|
||||||
(org-defkey org-mode-map (kbd "C-c ?") #'org-table-field-info)
|
(org-defkey org-mode-map (kbd "C-c ?") #'org-table-field-info)
|
||||||
(org-defkey org-mode-map (kbd "C-c SPC") #'org-table-blank-field)
|
(org-defkey org-mode-map (kbd "C-c SPC") #'org-table-blank-field)
|
||||||
(org-defkey org-mode-map (kbd "C-c +") #'org-table-sum)
|
(org-defkey org-mode-map (kbd "C-c +") #'org-table-sum)
|
||||||
|
|
43
lisp/org.el
43
lisp/org.el
|
@ -15580,7 +15580,7 @@ environment remains unintended."
|
||||||
;; Get indentation of next line unless at column 0.
|
;; Get indentation of next line unless at column 0.
|
||||||
(let ((ind (if (bolp) 0
|
(let ((ind (if (bolp) 0
|
||||||
(save-excursion
|
(save-excursion
|
||||||
(org-return-indent)
|
(org-return t)
|
||||||
(prog1 (current-indentation)
|
(prog1 (current-indentation)
|
||||||
(when (progn (skip-chars-forward " \t") (eolp))
|
(when (progn (skip-chars-forward " \t") (eolp))
|
||||||
(delete-region beg (point)))))))
|
(delete-region beg (point)))))))
|
||||||
|
@ -17647,20 +17647,31 @@ call `open-line' on the very first character."
|
||||||
(org-table-insert-row)
|
(org-table-insert-row)
|
||||||
(open-line n)))
|
(open-line n)))
|
||||||
|
|
||||||
(defun org-return (&optional indent)
|
(defun org--newline (indent arg interactive)
|
||||||
|
"Call `newline-and-indent' or just `newline'.
|
||||||
|
If INDENT is non-nil, call `newline-and-indent' with ARG to
|
||||||
|
indent unconditionally; otherwise, call `newline' with ARG and
|
||||||
|
INTERACTIVE, which can trigger indentation if
|
||||||
|
`electric-indent-mode' is enabled."
|
||||||
|
(if indent
|
||||||
|
(newline-and-indent)
|
||||||
|
(newline arg interactive)))
|
||||||
|
|
||||||
|
(defun org-return (&optional indent arg interactive)
|
||||||
"Goto next table row or insert a newline.
|
"Goto next table row or insert a newline.
|
||||||
|
|
||||||
Calls `org-table-next-row' or `newline', depending on context.
|
Calls `org-table-next-row' or `newline', depending on context.
|
||||||
|
|
||||||
When optional INDENT argument is non-nil, call
|
When optional INDENT argument is non-nil, call
|
||||||
`newline-and-indent' instead of `newline'.
|
`newline-and-indent' with ARG, otherwise call `newline' with ARG
|
||||||
|
and INTERACTIVE.
|
||||||
|
|
||||||
When `org-return-follows-link' is non-nil and point is on
|
When `org-return-follows-link' is non-nil and point is on
|
||||||
a timestamp or a link, call `org-open-at-point'. However, it
|
a timestamp or a link, call `org-open-at-point'. However, it
|
||||||
will not happen if point is in a table or on a \"dead\"
|
will not happen if point is in a table or on a \"dead\"
|
||||||
object (e.g., within a comment). In these case, you need to use
|
object (e.g., within a comment). In these case, you need to use
|
||||||
`org-open-at-point' directly."
|
`org-open-at-point' directly."
|
||||||
(interactive)
|
(interactive "*i\nP\np")
|
||||||
(let ((context (if org-return-follows-link (org-element-context)
|
(let ((context (if org-return-follows-link (org-element-context)
|
||||||
(org-element-at-point))))
|
(org-element-at-point))))
|
||||||
(cond
|
(cond
|
||||||
|
@ -17711,30 +17722,30 @@ object (e.g., within a comment). In these case, you need to use
|
||||||
(t (org--align-tags-here tags-column))) ;preserve tags column
|
(t (org--align-tags-here tags-column))) ;preserve tags column
|
||||||
(end-of-line)
|
(end-of-line)
|
||||||
(org-show-entry)
|
(org-show-entry)
|
||||||
(if indent (newline-and-indent) (newline))
|
(org--newline indent arg interactive)
|
||||||
(when string (save-excursion (insert (org-trim string))))))
|
(when string (save-excursion (insert (org-trim string))))))
|
||||||
;; In a list, make sure indenting keeps trailing text within.
|
;; In a list, make sure indenting keeps trailing text within.
|
||||||
((and indent
|
((and (not (eolp))
|
||||||
(not (eolp))
|
|
||||||
(org-element-lineage context '(item)))
|
(org-element-lineage context '(item)))
|
||||||
(let ((trailing-data
|
(let ((trailing-data
|
||||||
(delete-and-extract-region (point) (line-end-position))))
|
(delete-and-extract-region (point) (line-end-position))))
|
||||||
(newline-and-indent)
|
(org--newline indent arg interactive)
|
||||||
(save-excursion (insert trailing-data))))
|
(save-excursion (insert trailing-data))))
|
||||||
(t
|
(t
|
||||||
;; Do not auto-fill when point is in an Org property drawer.
|
;; Do not auto-fill when point is in an Org property drawer.
|
||||||
(let ((auto-fill-function (and (not (org-at-property-p))
|
(let ((auto-fill-function (and (not (org-at-property-p))
|
||||||
auto-fill-function)))
|
auto-fill-function)))
|
||||||
(if indent
|
(org--newline indent arg interactive))))))
|
||||||
(newline-and-indent)
|
|
||||||
(newline)))))))
|
|
||||||
|
|
||||||
(defun org-return-indent ()
|
(defun org-return-and-maybe-indent ()
|
||||||
"Goto next table row or insert a newline and indent.
|
"Goto next table row, or insert a newline.
|
||||||
Calls `org-table-next-row' or `newline-and-indent', depending on
|
Call `org-table-next-row' or `org-return', depending on context.
|
||||||
context. See the individual commands for more information."
|
See the individual commands for more information.
|
||||||
|
|
||||||
|
When inserting a newline, indent the new line if
|
||||||
|
`electric-indent-mode' is disabled."
|
||||||
(interactive)
|
(interactive)
|
||||||
(org-return t))
|
(org-return (not electric-indent-mode)))
|
||||||
|
|
||||||
(defun org-ctrl-c-tab (&optional arg)
|
(defun org-ctrl-c-tab (&optional arg)
|
||||||
"Toggle columns width in a table, or show children.
|
"Toggle columns width in a table, or show children.
|
||||||
|
|
|
@ -1310,6 +1310,94 @@
|
||||||
(org-return)
|
(org-return)
|
||||||
(buffer-string)))))
|
(buffer-string)))))
|
||||||
|
|
||||||
|
(ert-deftest test-org/with-electric-indent ()
|
||||||
|
"Test RET and C-j specifications with `electric-indent-mode' on."
|
||||||
|
;; Call commands interactively, since this is how `newline' knows it
|
||||||
|
;; must run `post-self-insert-hook'.
|
||||||
|
;;
|
||||||
|
;; RET, like `newline', should indent.
|
||||||
|
(should
|
||||||
|
(equal " Para\n graph"
|
||||||
|
(org-test-with-temp-text " Para<point>graph"
|
||||||
|
(electric-indent-local-mode 1)
|
||||||
|
(call-interactively 'org-return)
|
||||||
|
(buffer-string))))
|
||||||
|
(should
|
||||||
|
(equal "- item1\n item2"
|
||||||
|
(org-test-with-temp-text "- item1<point>item2"
|
||||||
|
(electric-indent-local-mode 1)
|
||||||
|
(call-interactively 'org-return)
|
||||||
|
(buffer-string))))
|
||||||
|
(should
|
||||||
|
(equal "* heading\n body"
|
||||||
|
(org-test-with-temp-text "* heading<point>body"
|
||||||
|
(electric-indent-local-mode 1)
|
||||||
|
(call-interactively 'org-return)
|
||||||
|
(buffer-string))))
|
||||||
|
;; C-j, like `electric-newline-and-maybe-indent', should not indent.
|
||||||
|
(should
|
||||||
|
(equal " Para\ngraph"
|
||||||
|
(org-test-with-temp-text " Para<point>graph"
|
||||||
|
(electric-indent-local-mode 1)
|
||||||
|
(call-interactively 'org-return-and-maybe-indent)
|
||||||
|
(buffer-string))))
|
||||||
|
(should
|
||||||
|
(equal "- item1\nitem2"
|
||||||
|
(org-test-with-temp-text "- item1<point>item2"
|
||||||
|
(electric-indent-local-mode 1)
|
||||||
|
(call-interactively 'org-return-and-maybe-indent)
|
||||||
|
(buffer-string))))
|
||||||
|
(should
|
||||||
|
(equal "* heading\nbody"
|
||||||
|
(org-test-with-temp-text "* heading<point>body"
|
||||||
|
(electric-indent-local-mode 1)
|
||||||
|
(call-interactively 'org-return-and-maybe-indent)
|
||||||
|
(buffer-string)))))
|
||||||
|
|
||||||
|
(ert-deftest test-org/without-electric-indent ()
|
||||||
|
"Test RET and C-j specifications with `electric-indent-mode' off."
|
||||||
|
;; Call commands interactively, since this is how `newline' knows it
|
||||||
|
;; must run `post-self-insert-hook'.
|
||||||
|
;;
|
||||||
|
;; RET, like `newline', should not indent.
|
||||||
|
(should
|
||||||
|
(equal " Para\ngraph"
|
||||||
|
(org-test-with-temp-text " Para<point>graph"
|
||||||
|
(electric-indent-local-mode 0)
|
||||||
|
(call-interactively 'org-return)
|
||||||
|
(buffer-string))))
|
||||||
|
(should
|
||||||
|
(equal "- item1\nitem2"
|
||||||
|
(org-test-with-temp-text "- item1<point>item2"
|
||||||
|
(electric-indent-local-mode 0)
|
||||||
|
(call-interactively 'org-return)
|
||||||
|
(buffer-string))))
|
||||||
|
(should
|
||||||
|
(equal "* heading\nbody"
|
||||||
|
(org-test-with-temp-text "* heading<point>body"
|
||||||
|
(electric-indent-local-mode 0)
|
||||||
|
(call-interactively 'org-return)
|
||||||
|
(buffer-string))))
|
||||||
|
;; C-j, like `electric-newline-and-maybe-indent', should indent.
|
||||||
|
(should
|
||||||
|
(equal " Para\n graph"
|
||||||
|
(org-test-with-temp-text " Para<point>graph"
|
||||||
|
(electric-indent-local-mode 0)
|
||||||
|
(call-interactively 'org-return-and-maybe-indent)
|
||||||
|
(buffer-string))))
|
||||||
|
(should
|
||||||
|
(equal "- item1\n item2"
|
||||||
|
(org-test-with-temp-text "- item1<point>item2"
|
||||||
|
(electric-indent-local-mode 0)
|
||||||
|
(call-interactively 'org-return-and-maybe-indent)
|
||||||
|
(buffer-string))))
|
||||||
|
(should
|
||||||
|
(equal "* heading\n body"
|
||||||
|
(org-test-with-temp-text "* heading<point>body"
|
||||||
|
(electric-indent-local-mode 0)
|
||||||
|
(call-interactively 'org-return-and-maybe-indent)
|
||||||
|
(buffer-string)))))
|
||||||
|
|
||||||
(ert-deftest test-org/meta-return ()
|
(ert-deftest test-org/meta-return ()
|
||||||
"Test M-RET (`org-meta-return') specifications."
|
"Test M-RET (`org-meta-return') specifications."
|
||||||
;; In a table field insert a row above.
|
;; In a table field insert a row above.
|
||||||
|
|
Loading…
Reference in a new issue