New minor mode org-indent-mode

This mode implements outline indentation similar to clean view, but in
a dynamic and virtual way, at display time.
This commit is contained in:
Carsten Dominik 2009-06-30 07:24:57 +02:00
parent 7cb52cfb7e
commit 31ceed47ff
17 changed files with 436 additions and 269 deletions

View File

@ -1,3 +1,9 @@
2009-08-03 Carsten Dominik <carsten.dominik@gmail.com>
* UTILITIES/mansplit.pl: Fix short contents.
* Makefile (LISPF): Add org-indent.el.
2009-07-07 Tassilo Horn <tassilo@member.fsf.org>
* org-gnus.el (org-gnus-store-link): Skip mbox specific first line

View File

@ -79,6 +79,7 @@ LISPF = org.el \
org-html.el \
org-icalendar.el \
org-id.el \
org-indent.el \
org-info.el \
org-inlinetask.el \
org-jsinfo.el \
@ -349,6 +350,7 @@ lisp/org-gnus.elc: lisp/org.el
lisp/org-html.elc: lisp/org-exp.el
lisp/org-icalendar.elc: lisp/org-exp.el
lisp/org-id.elc: lisp/org.el
lisp/org-indent.elc: lisp/org.el lisp/org-macs.el lisp/org-compat.el
lisp/org-info.elc: lisp/org.el
lisp/org-inlinetask.elc:
lisp/org-irc.elc: lisp/org.el

View File

@ -28,9 +28,8 @@ $contents = <<EOF;
<li><a name="toc_Exporting" href="Exporting.html#Exporting">12 Exporting</a>
<li><a name="toc_Publishing" href="Publishing.html#Publishing">13 Publishing</a>
<li><a name="toc_Miscellaneous" href="Miscellaneous.html#Miscellaneous">14 Miscellaneous</a>
<li><a name="toc_Extensions" href="Extensions.html#Extensions">A Extensions</a>
<li><a name="toc_Hacking" href="Hacking.html#Hacking">B Hacking</a>
<li><a name="toc_History-and-Acknowledgments" href="History-and-Acknowledgments.html#History-and-Acknowledgments">C History and Acknowledgments</a>
<li><a name="toc_Hacking" href="Hacking.html#Hacking">A Hacking</a>
<li><a name="toc_History-and-Acknowledgments" href="History-and-Acknowledgments.html#History-and-Acknowledgments">B History and Acknowledgments</a>
<li><a name="toc_Main-Index" href="Main-Index.html#Main-Index">Main Index</a>
<li><a name="toc_Key-Index" href="Key-Index.html#Key-Index">Key Index</a>
</li></ul>

View File

@ -1,3 +1,7 @@
2009-08-03 Carsten Dominik <carsten.dominik@gmail.com>
* lisp/org-indent.el: File removed.
2009-07-21 Wes Hardaker <wjhns209@hardakers.net> (tiny change)
* lisp/org-export-generic.el (org-export-generic-format): Fix

View File

@ -1,226 +0,0 @@
;;; org-indent.el --- Dynamic indentation for Org-mode
;; Copyright (C) 2008 Free Software Foundation, Inc.
;;
;; Author: Carsten Dominik <carsten at orgmode dot org>
;; Keywords: outlines, hypermedia, calendar, wp
;; Homepage: http://orgmode.org
;; Version: 0.07
;;
;; This file is not part of GNU Emacs.
;;
;; This file is free software; you can redistribute it and/or modify
;; it under the terms of the GNU General Public License as published by
;; the Free Software Foundation; either version 3, or (at your option)
;; any later version.
;; GNU Emacs is distributed in the hope that it will be useful,
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
;; GNU General Public License for more details.
;; You should have received a copy of the GNU General Public License
;; along with GNU Emacs; see the file COPYING. If not, write to the
;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
;; Boston, MA 02110-1301, USA.
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;
;;; Commentary:
;; This is an experimental implementation of dynamic virtual indentation.
;; It works by adding overlays to a buffer to make sure lines are
;; indented according to outline structure. While this works, there are
;; problems with the implementation: It uses overlays, which use markers,
;; and for large files, this is using too much resources. It might be
;; possible to com up with an implementation using text properties,
;; I believe this is less resource intensive. However, it does not work
;; to put the text property onto the newline, because that interferes with
;; outline visibility. Maybe this is a bug in outline?
;;; Indentation
(defcustom org-startup-indented nil
"Non-nil means, turn on `org-indent-mode' on startup.
This can also be configured on a per-file basis by adding one of
the following lines anywhere in the buffer:
#+STARTUP: localindent
#+STARTUP: indent
#+STARTUP: noindent"
:group 'org-structure
:type '(choice
(const :tag "Not" nil)
(const :tag "Locally" local)
(const :tag "Globally (slow on startup in large files)" t)))
(defconst org-indent-max 80
"Maximum indentation in characters")
(defconst org-indent-strings nil
"Vector with all indentation strings.
It is a const because it will be set only once in `org-indent-initialize'.")
(defvar org-indent-inhibit-after-change nil
"Inhibit the action of the indentation after-change-hook.
This variable should be scoped dynamically.")
(defcustom org-indent-boundary-char ?\ ; comment to protect space char
"The end of the virtual indentation strings, a single-character string.
The default is just a space, but if you wish, you can use \"|\" or so."
:group 'org-structure
:set (lambda (var val)
(set var val)
(and org-indent-strings (org-indent-initialize)))
:type 'character)
(defun org-indent-initialize ()
"Initialize the indentation strings and set the idle times."
(unless org-indent-strings
; (run-with-idle-timer 10 t 'org-indent-indent-buffer)
(run-with-idle-timer 0.5 t 'org-indent-refresh-section)
)
(setq org-indent-strings (make-vector (1+ org-indent-max) nil))
;; Initialize the indentation strings
(aset org-indent-strings 0 "")
(loop for i from 1 to org-indent-max do
(aset org-indent-strings i
(org-add-props
(concat (make-string (1- i) ?\ )
(char-to-string org-indent-boundary-char))
nil 'face 'org-indent))))
(define-minor-mode org-indent-mode
"Toggle the minor more `org-indent-mode'."
nil " Ind" nil
(if (org-bound-and-true-p org-inhibit-startup)
(setq org-indent-mode nil)
(if org-indent-mode
(progn
(or org-indent-strings (org-indent-initialize))
(org-set-local 'org-adapt-indentation nil)
(org-add-hook 'after-change-functions
'org-indent-after-change-function nil t)
(org-restart-font-lock)
(org-indent-indent-buffer))
(save-excursion
(save-restriction
(org-indent-remove-overlays (point-min) (point-max))
(remove-hook 'after-change-functions
'org-indent-after-change-function 'local)
(kill-local-variable 'org-adapt-indentation))))))
(defface org-indent
(org-compatible-face nil
'((((class color) (min-colors 16) (background dark)
(:underline nil :strike-through nil :foreground "grey10")))
(((class color) (min-colors 16) (background light))
(:underline nil :strike-through nil :foreground "grey90"))
(t (:underline nil :strike-through nil))))
"Face for outline indentation.
The default is to make it look like whitespace. But you may find it
useful to make it, for example, look like the fringes."
:group 'org-faces)
(defun org-indent-indent-buffer ()
"Add indentation overlays for the whole buffer."
(interactive)
(when org-indent-mode
(save-excursion
(save-restriction
(org-indent-remove-overlays (point-min) (point-max))
(org-indent-add-overlays (point-min) (point-max))))))
(defun org-indent-remove-overlays (beg end)
"Remove indentations between BEG and END."
(mapc (lambda (o)
(and (org-overlay-get o 'org-indent)
(org-delete-overlay o)))
(org-overlays-in beg end)))
(defun org-indent-add-overlays (beg end &optional n)
"Add indentation overlays between BEG and END.
Assumes that BEG is at the beginning of a line."
(when org-indent-mode
(let (o)
(save-excursion
(goto-char beg)
(while (and (<= (point) end) (not (eobp)))
(cond
((not (bolp)))
((looking-at outline-regexp)
(setq n (- (match-end 0) (match-beginning 0)))
(org-indent-remove-overlays (max (point-min) (1- (point))) (point)))
(n
(org-indent-indent-line n)))
(beginning-of-line 2))))))
(defun org-indent-indent-line (n)
"Add an indentation overlay with width N to the current line.
Point is assumed to be at the beginning of the line for this."
(let (ov)
(setq ov (org-make-overlay (1- (point)) (point)))
(org-overlay-put ov 'after-string (aref org-indent-strings n))
(org-overlay-put ov 'evaporate t)
(org-overlay-put ov 'org-indent n)
(org-unmodified
(put-text-property (max (point-min) (1- (point)))
(point-at-eol) 'org-indent-level n))))
(defun org-indent-after-change-function (beg end ndel)
(if (or (not org-indent-mode) (= beg end)
org-indent-inhibit-after-change)
() ; not in the mood to do anything here....
(let ((inhibit-quit t) n)
(save-match-data
(save-excursion
(save-restriction
(widen)
(goto-char beg)
(when (search-forward "\n" end t)
;; a newline was inserted
(setq n (or (get-text-property beg 'org-indent-level)
(get-text-property
(or (save-excursion (previous-single-property-change
beg 'org-indent-level))
(point-min))
'org-indent-level)
0))
(org-indent-local-refresh beg end n))))))))
(defun org-indent-local-refresh (beg end n)
"Refresh indentation locally from BEG to END, starting with indentation N."
(goto-char end)
(setq end (min (point-max) (1+ (point-at-eol))))
(goto-char beg)
(beginning-of-line 0)
(org-indent-remove-overlays (max (point-min) (1- (point))) end)
(org-indent-add-overlays (point) end n))
(defun org-indent-refresh-section ()
"Refresh indentation overlays in the current outline subtree."
(when org-indent-mode
(save-excursion
(let ((org-indent-inhibit-after-change t)
beg end)
(condition-case nil
(progn
(outline-back-to-heading t)
(setq beg (point)))
(error (progn
(goto-char (point-min))
(setq beg (point)))))
(outline-next-heading)
(setq end (point))
(org-indent-remove-overlays beg end)
(org-indent-add-overlays beg end)))))
(defun org-indent-refresh-subtree ()
"Refresh indentation overlays in the current outline subtree."
(when org-indent-mode
(save-excursion
(let ((org-indent-inhibit-after-change t)
beg end)
(setq beg (point))
(setq end (save-excursion (org-end-of-subtree t t)))
(org-indent-remove-overlays beg end)
(org-indent-add-overlays beg end)))))
(provide 'org-indent)
;;; org-indent.el ends here

View File

@ -1,3 +1,7 @@
2009-08-03 Carsten Dominik <carsten.dominik@gmail.com>
* org.texi (Clean view): Document `org-indent-mode'.
2009-07-26 Bastien Guerry <bzg@altern.org>
* org.texi (Clocking work time): Add documentation for the

View File

@ -871,6 +871,10 @@ the previously used indirect buffer.
@end table
@vindex org-startup-folded
@cindex @code{overview}, STARTUP keyword
@cindex @code{content}, STARTUP keyword
@cindex @code{showall}, STARTUP keyword
When Emacs first visits an Org file, the global state is set to
OVERVIEW, @ie only the top level headlines are visible. This can be
configured through the variable @code{org-startup-folded}, or on a
@ -10054,12 +10058,14 @@ any other Org mode file with internal setup. You can visit the file the
cursor is in the line with @kbd{C-c '}.
@item #+STARTUP:
@cindex #+STARTUP:
@vindex org-startup-folded
This line sets options to be used at startup of Org mode, when an
Org file is being visited. The first set of options deals with the
initial visibility of the outline tree. The corresponding variable for
global default settings is @code{org-startup-folded}, with a default
value @code{t}, which means @code{overview}.
Org file is being visited.
The first set of options deals with the initial visibility of the outline
tree. The corresponding variable for global default settings is
@code{org-startup-folded}, with a default value @code{t}, which means
@code{overview}.
@vindex org-startup-folded
@cindex @code{overview}, STARTUP keyword
@cindex @code{content}, STARTUP keyword
@cindex @code{showall}, STARTUP keyword
@ -10068,6 +10074,17 @@ overview @r{top-level headlines only}
content @r{all headlines}
showall @r{no folding at all, show everything}
@end example
@vindex org-startup-indented
@cindex @code{indent}, STARTUP keyword
@cindex @code{noindent}, STARTUP keyword
Dynamic virtual indentation is controlled by the variable
@code{org-startup-indented}@footnote{Emacs 23 and Org-mode 6.29 are required}
@example
indent @r{start with @code{org-indent-mode} turned on}
noindent @r{start with @code{org-indent-mode} turned off}
@end example
@vindex org-startup-align-all-tables
Then there are options for aligning tables upon visiting a file. This
is useful in files containing narrowed table columns. The corresponding
@ -10254,13 +10271,11 @@ block is updated.
@cindex odd-levels-only outlines
@cindex clean outline view
Some people find it noisy and distracting that the Org headlines start
with a potentially large number of stars, and that text below the headlines
is not indented. This is not really a problem when you are writing a book
where the outline headings are really section headlines. However, in a more
list-oriented outline, it is clear that an indented structure is a lot
cleaner, as can be seen by comparing the two columns in the following
example:
Some people find it noisy and distracting that the Org headlines start with a
potentially large number of stars, and that text below the headlines is not
indented. While this is no problem when writing a book where the outline
headings are really section headlines, in a more list-oriented outline,
indented structure is a lot cleaner:
@example
@group
@ -10275,8 +10290,28 @@ more text | more text
@end example
@noindent
It is non-trivial to make such a look work in Emacs, but Org contains three
separate features that, combined, achieve just that.
If you are using Emacs 23 and at least version 6.29 of Org, this kind of view
can be achieved dynamically at display time using @code{org-indent-mode}. In
this minor mode, all lines are prefixed for display with the necessary amount
of space. Also headlines are prefixed with additional stars, so that the
amount of indentation shifts by two@footnote{See the variable
@code{org-indent-indentation-per-level}.} spaces per level. All headline
stars but the last one are made invisible using the @code{org-hide}
face@footnote{Turning on @code{org-indent-mode} sets
@code{org-hide-leading-stars} to @code{t} and @code{org-adapt-indentation} to
@code{nil}.} - see below under @samp{2.} for more information on how this
works. You can turn on @code{org-indent-mode} for all files by customizing
the variable @code{org-startup-indented}, or you can turn it on for
individual files using
@example
#+STARTUP: indent
@end example
If you want a similar effect in earlier version of Emacs and/or Org, or if
you want the indentation to be hard space characters so that the plain text
file looks as similar as possible to the Emacs display, Org supports you in
the following way:
@enumerate
@item
@ -10290,13 +10325,9 @@ with the headline, like
@end example
@vindex org-adapt-indentation
A good way to get this indentation is by hand, and Org supports this with
paragraph filling, line wrapping, and structure editing@footnote{See also the
variable @code{org-adapt-indentation}.} preserving or adapting the
indentation as appropriate. A different approach would be to have a way to
automatically indent lines according to outline structure by adding overlays
or text properties. But I have not yet found a robust and efficient way to
do this in large files.
Org supports this with paragraph filling, line wrapping, and structure
editing@footnote{See also the variable @code{org-adapt-indentation}.},
preserving or adapting the indentation as appropriate.
@item
@vindex org-hide-leading-stars
@ -10307,11 +10338,9 @@ with
@example
#+STARTUP: hidestars
#+STARTUP: showstars
@end example
@noindent
Note that the opposite behavior is selected with @code{showstars}.
With hidden stars, the tree becomes:
@example
@ -10325,13 +10354,12 @@ With hidden stars, the tree becomes:
@noindent
@vindex org-hide @r{(face)}
Note that the leading stars are not truly replaced by whitespace, they
are only fontified with the face @code{org-hide} that uses the
background color as font color. If you are not using either white or
black background, you may have to customize this face to get the wanted
effect. Another possibility is to set this font such that the extra
stars are @i{almost} invisible, for example using the color
@code{grey90} on a white background.
The leading stars are not truly replaced by whitespace, they are only
fontified with the face @code{org-hide} that uses the background color as
font color. If you are not using either white or black background, you may
have to customize this face to get the wanted effect. Another possibility is
to set this font such that the extra stars are @i{almost} invisible, for
example using the color @code{grey90} on a white background.
@item
@vindex org-odd-levels-only

View File

@ -1,3 +1,25 @@
2009-08-03 Carsten Dominik <carsten.dominik@gmail.com>
* org.el (org-startup-indented): New option.
(org-startup-options): Add new options indent and noindent.
(org-unfontify-region): Remove line-prefix and wrap-prefix
properties.
(org-after-demote-entry-hook, org-after-promote-entry-hook): New
hooks.
(org-promote, org-demote): Run the new hooks.
* org-table.el (org-table-align): Replace leading \n as well.
* org-exp.el (org-export-push-to-kill-ring): Remove `line-prefix'
and `line-wrap' text properties.
* org-compat.el (org-kill-new): New function.
* org-agenda.el (org-format-agenda-item): Remove `line-prefix' and
`line-wrap' text properties.
* org-indent.el: New file.
2009-08-02 Carsten Dominik <carsten.dominik@gmail.com>
* org.el (org-provide-todo-statistics): Tweak docstring.

View File

@ -4292,6 +4292,7 @@ Any match of REMOVE-RE will be removed from TXT."
(setq rtn (concat (eval org-prefix-format-compiled) txt)))
;; And finally add the text properties
(remove-text-properties 0 (length rtn) '(line-prefix t wrap-prefix t) rtn)
(org-add-props rtn nil
'org-category (downcase category)
'tags (mapcar 'org-downcase-keep-props tags)

View File

@ -327,6 +327,11 @@ that can be added."
(setq n (1- n)))
n))
(defun org-kill-new (string &rest args)
(remove-text-properties 0 (length string) '(line-prefix t wrap-prefix t)
string)
(apply 'kill-new string args))
(provide 'org-compat)
;; arch-tag: a0a0579f-e68c-4bdf-9e55-93768b846bbe

View File

@ -2778,7 +2778,7 @@ stacked delimiters is N. Escaping delimiters is not possible."
"Push buffer content to kill ring.
The depends on the variable `org-export-copy-to-kill'."
(when org-export-copy-to-kill-ring
(kill-new (buffer-string))
(org-kill-new (buffer-string))
(when (fboundp 'x-set-selection)
(ignore-errors (x-set-selection 'PRIMARY (buffer-string)))
(ignore-errors (x-set-selection 'CLIPBOARD (buffer-string))))

View File

@ -202,7 +202,7 @@ With optional argument FORCE, force the creation of a new ID."
"Copy the ID of the entry at point to the kill ring.
Create an ID if necessary."
(interactive)
(kill-new (org-id-get nil 'create)))
(org-kill-new (org-id-get nil 'create)))
;;;###autoload
(defun org-id-get (&optional pom create prefix)

273
lisp/org-indent.el Normal file
View File

@ -0,0 +1,273 @@
;;; org-indent.el --- Dynamic indentation for Org-mode
;; Copyright (C) 2008 Free Software Foundation, Inc.
;;
;; Author: Carsten Dominik <carsten at orgmode dot org>
;; Keywords: outlines, hypermedia, calendar, wp
;; Homepage: http://orgmode.org
;; Version: 6.28trans
;;
;; This file is part of GNU Emacs.
;;
;; This file is free software; you can redistribute it and/or modify
;; it under the terms of the GNU General Public License as published by
;; the Free Software Foundation; either version 3, or (at your option)
;; any later version.
;; GNU Emacs is distributed in the hope that it will be useful,
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
;; GNU General Public License for more details.
;; You should have received a copy of the GNU General Public License
;; along with GNU Emacs; see the file COPYING. If not, write to the
;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
;; Boston, MA 02110-1301, USA.
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;
;;; Commentary:
;; This is an implementation of dynamic virtual indentation. It works
;; by adding text properties to a buffer to make sure lines are
;; indented according to outline structure.
(require 'org-macs)
(require 'org-compat)
(require 'org)
(eval-when-compile
(require 'cl))
(defgroup org-indent nil
"Options concerning dynamic virtual outline indentation."
:tag "Org Structure"
:group 'org)
(defconst org-indent-max 40
"Maximum indentation in characters")
(defconst org-indent-max-levels 40
"Maximum indentation in characters")
(defvar org-indent-strings nil
"Vector with all indentation strings.
It will be set in `org-indent-initialize'.")
(defvar org-indent-stars nil
"Vector with all indentation star strings.
It will be set in `org-indent-initialize'.")
(defcustom org-indent-boundary-char ?\ ; comment to protect space char
"The end of the virtual indentation strings, a single-character string.
The default is just a space, but if you wish, you can use \"|\" or so.
This can be useful on a terminal window - under a windowing system,
it may be prettier to customize the org-indent face."
:group 'org-indent
:set (lambda (var val)
(set var val)
(and org-indent-strings (org-indent-initialize)))
:type 'character)
(defcustom org-indent-mode-turns-off-org-adapt-indentation t
"Non-nil means, turning on org-indent-mode turns off indentation adaptation.
For details see the variable `org-adapt-indentation'."
:group 'org-indent
:type 'boolean)
(defcustom org-indent-mode-turns-on-hiding-stars t
"Non-nil means, turning on org-indent-mode turns on `org-hide-leading-stars'."
:group 'org-indent
:type 'boolean)
(defcustom org-indent-indentation-per-level 2
"Indentation per level in number of characters."
:group 'org-indent
:type 'integer)
(defcustom org-indent-fix-section-after-idle-time 0.2
"Seconds of idle time before fixing virtual indentation of section.
The hooking-in of virtual indentation is not yet perfect. Occasionally,
a change does not trigger to proper change of indentation. For this we
have a timer action that fixes indentation in the current section after
a short amount idle time. If we ever get the integration to work perfectly,
this variable can be set to nil to get rid of the timer."
:group 'org-indent
:type '(choice
(const "Do not install idle timer" nil)
(number :tag "Idle time")))
(defun org-indent-initialize ()
"Initialize the indentation strings and set the idle timer."
;; We use an idle timer to "repair" the current section, because the
;; redisplay seems to have some problems.
(unless org-indent-strings
(when org-indent-fix-section-after-idle-time
(run-with-idle-timer
org-indent-fix-section-after-idle-time
t 'org-indent-refresh-section)))
;; Initialize the indentation and star vectors
(setq org-indent-strings (make-vector (1+ org-indent-max) nil))
(setq org-indent-stars (make-vector (1+ org-indent-max) nil))
(aset org-indent-strings 0 "")
(aset org-indent-stars 0 "")
(loop for i from 1 to org-indent-max do
(aset org-indent-strings i
(org-add-props
(concat (make-string (1- i) ?\ )
(char-to-string org-indent-boundary-char))
nil 'face 'org-indent)))
(loop for i from 1 to org-indent-max-levels do
(aset org-indent-stars i
(org-add-props (make-string i ?*)
nil 'face 'org-hide))))
;;;###autoload
(define-minor-mode org-indent-mode
"When active, indent text according to outline structure.
Internally this works by adding `line-prefix' properties to all non-headlines.
These properties are updated locally in idle time.
FIXME: How to update when broken?"
nil " Ind" nil
(if (org-bound-and-true-p org-inhibit-startup)
(setq org-indent-mode nil)
(if org-indent-mode
(progn
(or org-indent-strings (org-indent-initialize))
(when org-indent-mode-turns-off-org-adapt-indentation
(org-set-local 'org-adapt-indentation nil))
(when org-indent-mode-turns-on-hiding-stars
(org-set-local 'org-hide-leading-stars t))
(make-local-variable 'buffer-substring-filters)
(add-to-list 'buffer-substring-filters
'org-indent-remove-properties-from-string)
(org-add-hook 'org-after-demote-entry-hook
'org-indent-refresh-section nil 'local)
(org-add-hook 'org-after-promote-entry-hook
'org-indent-refresh-section nil 'local)
(org-add-hook 'org-font-lock-hook
'org-indent-refresh-to nil 'local)
(and font-lock-mode (org-restart-font-lock))
)
(save-excursion
(save-restriction
(org-indent-remove-properties (point-min) (point-max))
(kill-local-variable 'org-adapt-indentation)
(setq buffer-substring-filters
(delq 'org-indent-remove-properties-from-string
buffer-substring-filters))
(remove-hook 'org-after-promote-entry-hook
'org-indent-refresh-section 'local)
(remove-hook 'org-after-demote-entry-hook
'org-indent-refresh-section 'local)
(and font-lock-mode (org-restart-font-lock))
(redraw-display))))))
(defface org-indent
(org-compatible-face nil nil)
"Face for outline indentation.
The default is to make it look like whitespace. But you may find it
useful to make it evver so slightly different."
:group 'org-faces)
(defun org-indent-indent-buffer ()
"Add indentation properties for the whole buffer."
(interactive)
(when org-indent-mode
(save-excursion
(save-restriction
(widen)
(org-indent-remove-properties (point-min) (point-max))
(org-indent-add-properties (point-min) (point-max))))))
(defun org-indent-remove-properties (beg end)
"Remove indentations between BEG and END."
(org-unmodified
(remove-text-properties beg end '(line-prefix nil wrap-prefix nil))))
(defun org-indent-remove-properties-from-string (string)
"Remove indentations between BEG and END."
(remove-text-properties 0 (length string)
'(line-prefix nil wrap-prefix nil) string)
string)
(defun org-indent-add-properties (beg end)
"Add indentation properties between BEG and END.
Assumes that BEG is at the beginning of a line."
(when (or t org-indent-mode)
(let (ov b e n level exit nstars)
(org-unmodified
(save-excursion
(goto-char beg)
(while (not exit)
(setq e end)
(if (not (re-search-forward org-outline-regexp nil t))
(setq e (point-max) exit t)
(setq e (match-beginning 0))
(if (>= e end) (setq exit t))
(setq level (- (match-end 0) (match-beginning 0) 1))
(setq nstars (- (* (1- level) org-indent-indentation-per-level)
(1- level)))
(add-text-properties
(point-at-bol) (point-at-eol)
(list 'line-prefix
(aref org-indent-stars nstars)
'wrap-prefix
(aref org-indent-strings
(* level org-indent-indentation-per-level)))))
(when (and b (> e b))
(add-text-properties
b e (list 'line-prefix (aref org-indent-strings n)
'wrap-prefix (aref org-indent-strings n))))
(setq b (1+ (point-at-eol))
n (* level org-indent-indentation-per-level))))))))
(defun org-indent-refresh-section ()
"Refresh indentation properties in the current outline section.
Point is assumed to be at the beginning of a headline."
(interactive)
(when org-indent-mode
(let (beg end)
(save-excursion
(when (ignore-errors (org-back-to-heading))
(setq beg (point))
(setq end (or (save-excursion (or (outline-next-heading) (point)))))
(org-indent-remove-properties beg end)
(org-indent-add-properties beg end))))))
(defun org-indent-refresh-to (limit)
"Refresh indentation properties in the current outline section.
Point is assumed to be at the beginning of a headline."
(interactive)
(when org-indent-mode
(let ((beg (point)) (end limit))
(save-excursion
(and (ignore-errors (org-back-to-heading t))
(setq beg (point))))
(org-indent-remove-properties beg end)
(org-indent-add-properties beg end)))
(goto-char limit))
(defun org-indent-refresh-subtree ()
"Refresh indentation properties in the current outline subtree.
Point is assumed to be at the beginning of a headline."
(interactive)
(when org-indent-mode
(save-excursion
(let (beg end)
(setq beg (point))
(setq end (save-excursion (org-end-of-subtree t t)))
(org-indent-remove-properties beg end)
(org-indent-add-properties beg end)))))
(defun org-indent-refresh-buffer ()
"Refresh indentation properties in the current outline subtree.
Point is assumed to be at the beginning of a headline."
(interactive)
(when org-indent-mode
(org-indent-mode -1)
(org-indent-mode 1)))
(provide 'org-indent)
;;; org-indent.el ends here

View File

@ -724,7 +724,7 @@ SCHEDULED: or DEADLINE: or ANYTHINGLIKETHIS:"
["Open" org-open-at-point t]
["Open in Emacs" (org-open-at-point t) t]
"--"
["Copy link" (kill-new (match-string 0))]
["Copy link" (org-kill-new (match-string 0))]
["Cut link"
(progn
(kill-region (match-beginning 0) (match-end 0))

View File

@ -721,6 +721,16 @@ When nil, simply write \"#ERROR\" in corrupted fields.")
;; Replace the old one
(delete-region beg end)
(move-marker end nil)
(if (equal (char-before) ?\n)
;; This hack is for org-indent, to force redisplay of the
;; line prefix of the first line. Apparently the redisplay
;; is tied to the newline, which is, I think, a bug.
;; To force this redisplay, we remove and re-insert the
;; newline, so that the redisplay engine thinks it belongs
;; to the changed text.
(progn
(backward-delete-char 1)
(insert "\n")))
(move-marker org-table-aligned-begin-marker (point))
(insert new)
(move-marker org-table-aligned-end-marker (point))

View File

@ -93,7 +93,7 @@ so that it can be yanked into an Org-mode buffer with links working correctly."
(setq return-content
(concat return-content
(buffer-substring (point) transform-end))))
(kill-new return-content)
(org-kill-new return-content)
(message "Transforming links...done, use C-y to insert text into Org-mode file")
(message "Copy with link transformation complete."))))

View File

@ -277,6 +277,18 @@ uninteresting. Also tables look terrible when wrapped."
:group 'org-startup
:type 'boolean)
(defcustom org-startup-indented nil
"Non-nil means, turn on `org-indent-mode' on startup.
This can also be configured on a per-file basis by adding one of
the following lines anywhere in the buffer:
#+STARTUP: indent
#+STARTUP: noindent"
:group 'org-structure
:type '(choice
(const :tag "Not" nil)
(const :tag "Globally (slow on startup in large files)" t)))
(defcustom org-startup-align-all-tables nil
"Non-nil means, align all tables when visiting a file.
This is useful when the column width in tables is forced with <N> cookies
@ -702,8 +714,8 @@ The following issues are influenced by this variable:
will be indented when this variable is set.
Note that this is all about true indentation, by adding and removing
spaces. See also `org-indent.el' which does level-dependent indentation
in a virtual way, i.e. only for display in Emacs."
space characters. See also `org-indent.el' which does level-dependent
indentation in a virtual way, i.e. at display time in Emacs."
:group 'org-edit-structure
:type 'boolean)
@ -2882,6 +2894,7 @@ Normal means, no org-mode-specific context."
(declare-function org-agenda-check-for-timestamp-as-reason-to-ignore-todo-item
"org-agenda" (&optional end))
(declare-function org-inlinetask-remove-END-maybe "org-inlinetask" ())
(declare-function org-indent-mode "org-indent" (arg))
(declare-function parse-time-string "parse-time" (string))
(declare-function remember "remember" (&optional initial))
(declare-function remember-buffer-desc "remember" ())
@ -3154,6 +3167,13 @@ If yes, offer to stop it and to save the buffer with the changes."
'(org-feed-update org-feed-update-all org-feed-goto-inbox)))
;; Autoload org-indent.el
(eval-and-compile
(org-autoload
"org-indent"
'(org-indent-mode)))
;; Autoload archiving code
;; The stuff that is needed for cycling and tags has to be defined here.
@ -3435,6 +3455,8 @@ After a match, the following groups carry important information:
("nofold" org-startup-folded nil)
("showall" org-startup-folded nil)
("content" org-startup-folded content)
("indent" org-startup-indented t)
("noindent" org-startup-indented nil)
("hidestars" org-hide-leading-stars t)
("showstars" org-hide-leading-stars nil)
("odd" org-odd-levels-only t)
@ -3981,6 +4003,9 @@ The following commands are available:
(let ((bmp (buffer-modified-p)))
(org-table-map-tables 'org-table-align)
(set-buffer-modified-p bmp)))
(when org-startup-indented
(require 'org-indent)
(org-indent-mode 1))
(org-set-startup-visibility)))
(put 'org-mode 'flyspell-mode-predicate 'org-mode-flyspell-verify)
@ -4624,6 +4649,7 @@ between words."
;; Description list items
'("^[ \t]*\\([-+*]\\|[0-9]+[.)]\\) +\\(.*? ::\\)"
2 'bold prepend)
;; ARCHIVEd headings
(list (concat "^\\*+ \\(.*:" org-archive-tag ":.*\\)")
'(1 'org-archived prepend))
;; Specials
@ -4711,6 +4737,7 @@ If KWD is a number, get the corresponding match group."
(remove-text-properties beg end
'(mouse-face t keymap t org-linked-text t
invisible t intangible t
line-prefix t wrap-prefix t
org-no-flyspell t))))
;;;; Visibility cycling, including org-goto and indirect buffer
@ -5787,6 +5814,16 @@ Works for outline headings and for plain lists alike."
;;; Promotion and Demotion
(defvar org-after-demote-entry-hook nil
"Hook run after an entry has been demoted.
The cursor will be at the beginning of the entry.
When a subtree is being demoted, the hook will be called for each node.")
(defvar org-after-promote-entry-hook nil
"Hook run after an entry has been promoted.
The cursor will be at the beginning of the entry.
When a subtree is being promoted, the hook will be called for each node.")
(defun org-promote-subtree ()
"Promote the entire subtree.
See also `org-promote'."
@ -5872,7 +5909,8 @@ in the region."
(replace-match up-head nil t)
;; Fixup tag positioning
(and org-auto-align-tags (org-set-tags nil t))
(if org-adapt-indentation (org-fixup-indentation (- diff)))))
(if org-adapt-indentation (org-fixup-indentation (- diff)))
(run-hooks 'org-after-promote-entry-hook)))
(defun org-demote ()
"Demote the current heading lower down the tree.
@ -5885,7 +5923,8 @@ in the region."
(replace-match down-head nil t)
;; Fixup tag positioning
(and org-auto-align-tags (org-set-tags nil t))
(if org-adapt-indentation (org-fixup-indentation diff))))
(if org-adapt-indentation (org-fixup-indentation diff))
(run-hooks 'org-after-demote-entry-hook)))
(defun org-map-tree (fun)
"Call FUN for every heading underneath the current one."
@ -8567,7 +8606,7 @@ See also `org-refile-use-outline-path' and `org-completion-use-ido'"
(org-show-context 'org-goto))
(if regionp
(progn
(kill-new (buffer-substring region-start region-end))
(org-kill-new (buffer-substring region-start region-end))
(org-save-markers-in-region region-start region-end))
(org-copy-subtree 1 nil t))
(save-excursion