* autoloads not working correctly for org-table.el?
@ 2015-02-27 10:12 Eric Abrahamsen
2015-02-27 10:35 ` Nicolas Richard
0 siblings, 1 reply; 13+ messages in thread
From: Eric Abrahamsen @ 2015-02-27 10:12 UTC (permalink / raw)
To: emacs-orgmode
Hi,
I've got this in my message-mode-hook:
'turn-on-orgstruct++
It does just what I want, except the variable orgtbl-line-start-regexp
isn't loaded, which wrecks auto-fill. Line 22894 of org.el has this:
(defvar orgtbl-line-start-regexp) ; From org-table.el
But that doesn't actually *load* the value of that variable, so using
orgstruct++ mode gives me a bunch of these:
Symbol's value as variable is void: orgtbl-line-start-regexp
every time point gets past fill column, and the filling thing kicks in.
I don't actually know what the right thing to do is. Maybe just a
(require 'org-table) inside `orgstruct++-mode'? Autoload doesn't seem to
work for variables, nor is there a `declare-variable'...
Eric
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: autoloads not working correctly for org-table.el?
2015-02-27 10:12 autoloads not working correctly for org-table.el? Eric Abrahamsen
@ 2015-02-27 10:35 ` Nicolas Richard
2015-02-27 17:28 ` Nicolas Goaziou
0 siblings, 1 reply; 13+ messages in thread
From: Nicolas Richard @ 2015-02-27 10:35 UTC (permalink / raw)
To: Eric Abrahamsen; +Cc: emacs-orgmode
Eric Abrahamsen <eric@ericabrahamsen.net> writes:
> I don't actually know what the right thing to do is. Maybe just a
> (require 'org-table) inside `orgstruct++-mode'? Autoload doesn't seem to
> work for variables, nor is there a `declare-variable'...
Either (require 'org-table) in org-adaptive-fill-function or applying
the following patch should fix your problem.
I don't know what is the right thing either © e.g. I have no idea why
this function has special-casing for 'message-mode (it should perhaps
have special casing for when orgstruct++-mode is active, instead ?)
--- a/lisp/org.el
+++ b/lisp/org.el
@@ -22953,7 +22953,8 @@ (defun org-adaptive-fill-function ()
(save-excursion
(beginning-of-line)
(cond ((or (not (message-in-body-p))
- (looking-at orgtbl-line-start-regexp))
+ (and (boundp 'orgtbl-line-start-regexp)
+ (looking-at orgtbl-line-start-regexp)))
(throw 'exit nil))
((looking-at message-cite-prefix-regexp)
(throw 'exit (match-string-no-properties 0)))
--
Nicolas Richard
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: autoloads not working correctly for org-table.el?
2015-02-27 10:35 ` Nicolas Richard
@ 2015-02-27 17:28 ` Nicolas Goaziou
2015-02-28 0:39 ` Eric Abrahamsen
2015-03-04 9:28 ` Eric Abrahamsen
0 siblings, 2 replies; 13+ messages in thread
From: Nicolas Goaziou @ 2015-02-27 17:28 UTC (permalink / raw)
To: Nicolas Richard; +Cc: Eric Abrahamsen, emacs-orgmode
Hello,
Nicolas Richard <theonewiththeevillook@yahoo.fr> writes:
> Eric Abrahamsen <eric@ericabrahamsen.net> writes:
>> I don't actually know what the right thing to do is. Maybe just a
>> (require 'org-table) inside `orgstruct++-mode'? Autoload doesn't seem to
>> work for variables, nor is there a `declare-variable'...
>
> Either (require 'org-table) in org-adaptive-fill-function or applying
> the following patch should fix your problem.
Thank you. However, I eventually applied a different patch.
> I don't know what is the right thing either © e.g. I have no idea why
> this function has special-casing for 'message-mode (it should perhaps
> have special casing for when orgstruct++-mode is active, instead ?)
Ideally, we should extract all orgstruct code from Org core
("org-footnote.el" also contains code related to Message mode) and move
it to an "org-struct.el" or some such library.
Regards,
--
Nicolas Goaziou
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: autoloads not working correctly for org-table.el?
2015-02-27 17:28 ` Nicolas Goaziou
@ 2015-02-28 0:39 ` Eric Abrahamsen
2015-03-04 9:28 ` Eric Abrahamsen
1 sibling, 0 replies; 13+ messages in thread
From: Eric Abrahamsen @ 2015-02-28 0:39 UTC (permalink / raw)
To: emacs-orgmode
Nicolas Goaziou <mail@nicolasgoaziou.fr> writes:
> Hello,
>
> Nicolas Richard <theonewiththeevillook@yahoo.fr> writes:
>
>> Eric Abrahamsen <eric@ericabrahamsen.net> writes:
>>> I don't actually know what the right thing to do is. Maybe just a
>>> (require 'org-table) inside `orgstruct++-mode'? Autoload doesn't seem to
>>> work for variables, nor is there a `declare-variable'...
>>
>> Either (require 'org-table) in org-adaptive-fill-function or applying
>> the following patch should fix your problem.
>
> Thank you. However, I eventually applied a different patch.
>
>> I don't know what is the right thing either © e.g. I have no idea why
>> this function has special-casing for 'message-mode (it should perhaps
>> have special casing for when orgstruct++-mode is active, instead ?)
>
> Ideally, we should extract all orgstruct code from Org core
> ("org-footnote.el" also contains code related to Message mode) and move
> it to an "org-struct.el" or some such library.
>
>
> Regards,
Thanks!
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: autoloads not working correctly for org-table.el?
2015-02-27 17:28 ` Nicolas Goaziou
2015-02-28 0:39 ` Eric Abrahamsen
@ 2015-03-04 9:28 ` Eric Abrahamsen
2015-03-04 15:23 ` Eric S Fraga
1 sibling, 1 reply; 13+ messages in thread
From: Eric Abrahamsen @ 2015-03-04 9:28 UTC (permalink / raw)
To: emacs-orgmode
Nicolas Goaziou <mail@nicolasgoaziou.fr> writes:
> Hello,
>
> Nicolas Richard <theonewiththeevillook@yahoo.fr> writes:
>
>> Eric Abrahamsen <eric@ericabrahamsen.net> writes:
>>> I don't actually know what the right thing to do is. Maybe just a
>>> (require 'org-table) inside `orgstruct++-mode'? Autoload doesn't seem to
>>> work for variables, nor is there a `declare-variable'...
>>
>> Either (require 'org-table) in org-adaptive-fill-function or applying
>> the following patch should fix your problem.
>
> Thank you. However, I eventually applied a different patch.
I'm still seeing an issue where, if I start right off typing a big
paragraph of text at the top of the message (no salutation or anything),
all the lines *after* the first line are indented by one tab. Subsequent
paragraphs are unaffected.
Sorry, I should be hunting down these bugs myself, but it's been an ugly
couple of days writing work emails all day long, and with nearly every
one I write I am reminded of the problem...
>> I don't know what is the right thing either © e.g. I have no idea why
>> this function has special-casing for 'message-mode (it should perhaps
>> have special casing for when orgstruct++-mode is active, instead ?)
>
> Ideally, we should extract all orgstruct code from Org core
> ("org-footnote.el" also contains code related to Message mode) and move
> it to an "org-struct.el" or some such library.
>
>
> Regards,
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: autoloads not working correctly for org-table.el?
2015-03-04 9:28 ` Eric Abrahamsen
@ 2015-03-04 15:23 ` Eric S Fraga
2015-03-05 1:36 ` Eric Abrahamsen
0 siblings, 1 reply; 13+ messages in thread
From: Eric S Fraga @ 2015-03-04 15:23 UTC (permalink / raw)
To: Eric Abrahamsen; +Cc: emacs-orgmode
On Wednesday, 4 Mar 2015 at 17:28, Eric Abrahamsen wrote:
[...]
> I'm still seeing an issue where, if I start right off typing a big
> paragraph of text at the top of the message (no salutation or anything),
> all the lines *after* the first line are indented by one tab. Subsequent
> paragraphs are unaffected.
Hi Eric,
I had this problem for a long time. It disappeared a some time ago now
and I have no idea why. However, while I had the problem, I trained
myself to always start an email (that was not a response like this one)
with some form of salutation! More polite as well as avoiding the bug
:)
--
: Eric S Fraga (0xFFFCF67D), Emacs 24.4.1, Org release_8.3beta-820-gd92ef9
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: autoloads not working correctly for org-table.el?
2015-03-04 15:23 ` Eric S Fraga
@ 2015-03-05 1:36 ` Eric Abrahamsen
2015-03-10 2:15 ` [PATCH] " Eric Abrahamsen
0 siblings, 1 reply; 13+ messages in thread
From: Eric Abrahamsen @ 2015-03-05 1:36 UTC (permalink / raw)
To: emacs-orgmode
Eric S Fraga <e.fraga@ucl.ac.uk> writes:
> On Wednesday, 4 Mar 2015 at 17:28, Eric Abrahamsen wrote:
>
> [...]
>
>> I'm still seeing an issue where, if I start right off typing a big
>> paragraph of text at the top of the message (no salutation or anything),
>> all the lines *after* the first line are indented by one tab. Subsequent
>> paragraphs are unaffected.
>
> Hi Eric,
>
> I had this problem for a long time. It disappeared a some time ago now
> and I have no idea why. However, while I had the problem, I trained
> myself to always start an email (that was not a response like this one)
> with some form of salutation! More polite as well as avoiding the bug
> :)
Well, sure :) I guess I'll try being politer!
I just poked around a little bit, edebugging
`org-adaptive-fill-function'. I looked at the call to
`fill-context-prefix' two-thirds of the way down. I tested this with the
last email I sent, and I see that calling `org-adaptive-fill-function'
on the first paragraph results in `fill-context-prefix' being called
with the arguments 1 (the post-affiliated arg), and 447 (the end
position of the first paragraph). The result of that call is a tab.
If I move to the second paragraph and do the same thing, the
post-affiliated arg was 447, and the end position is 475. The result of
that call was nil, which is probably what I wanted.
My value of adaptive-fill-regexp, in this case is:
"\\(\\([ ]*[_.[:word:]]+>+\\|[ ]*[]>|]\\)+\\)[ ]*\\|[
]*\\([-–!|#%;>*·•‣⁃◦]+[ ]*\\)*"
I will poke further as time allows. I don't know much about filling (and
have never understood what "post-affiliated" actually means), but assume
I can eventually get to the bottom of it...
E
^ permalink raw reply [flat|nested] 13+ messages in thread
* [PATCH] Re: autoloads not working correctly for org-table.el?
2015-03-05 1:36 ` Eric Abrahamsen
@ 2015-03-10 2:15 ` Eric Abrahamsen
2015-03-10 3:07 ` Eric Abrahamsen
0 siblings, 1 reply; 13+ messages in thread
From: Eric Abrahamsen @ 2015-03-10 2:15 UTC (permalink / raw)
To: emacs-orgmode
[-- Attachment #1: Type: text/plain, Size: 2493 bytes --]
Eric Abrahamsen <eric@ericabrahamsen.net> writes:
> Eric S Fraga <e.fraga@ucl.ac.uk> writes:
>
>> On Wednesday, 4 Mar 2015 at 17:28, Eric Abrahamsen wrote:
>>
>> [...]
>>
>>> I'm still seeing an issue where, if I start right off typing a big
>>> paragraph of text at the top of the message (no salutation or anything),
>>> all the lines *after* the first line are indented by one tab. Subsequent
>>> paragraphs are unaffected.
>>
>> Hi Eric,
>>
>> I had this problem for a long time. It disappeared a some time ago now
>> and I have no idea why. However, while I had the problem, I trained
>> myself to always start an email (that was not a response like this one)
>> with some form of salutation! More polite as well as avoiding the bug
>> :)
>
> Well, sure :) I guess I'll try being politer!
>
> I just poked around a little bit, edebugging
> `org-adaptive-fill-function'. I looked at the call to
> `fill-context-prefix' two-thirds of the way down. I tested this with the
> last email I sent, and I see that calling `org-adaptive-fill-function'
> on the first paragraph results in `fill-context-prefix' being called
> with the arguments 1 (the post-affiliated arg), and 447 (the end
> position of the first paragraph). The result of that call is a tab.
>
> If I move to the second paragraph and do the same thing, the
> post-affiliated arg was 447, and the end position is 475. The result of
> that call was nil, which is probably what I wanted.
>
> My value of adaptive-fill-regexp, in this case is:
>
> "\\(\\([ ]*[_.[:word:]]+>+\\|[ ]*[]>|]\\)+\\)[ ]*\\|[
> ]*\\([-–!|#%;>*·•‣⁃◦]+[ ]*\\)*"
>
> I will poke further as time allows. I don't know much about filling (and
> have never understood what "post-affiliated" actually means), but assume
> I can eventually get to the bottom of it...
>
> E
It looks like the problem was that all the message headers are parsed as
though they were part of the first paragraph of message body text. Why
that should result in a secondary TAB indent I don't know, but
regardless, Org probably should only be looking at the message body, and
nothing else.
The attached patch is a hack that adds the `mail-header-separator'
regexp to the `org-element-paragraph-separate' regexp. That means it
will only work for paragraphs, so there might still be weirdness if a
message body starts with a list or what have you.
Perhaps a better solution would be to narrow to the body of the message
before doing the fill prefix calculation.
Eric
[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: 0001-Change-paragraph-boundaries-in-message-mode.patch --]
[-- Type: text/x-diff, Size: 982 bytes --]
From cb65e1b8adad54e6fc72c1eddb79efa644abbfc0 Mon Sep 17 00:00:00 2001
From: Eric Abrahamsen <eric@ericabrahamsen.net>
Date: Tue, 10 Mar 2015 10:08:24 +0800
Subject: [PATCH] Change paragraph boundaries in message mode
* lisp/org.el (org-adaptive-fill-function): The value of
`mail-header-separator' should count as a paragraph separator.
---
lisp/org.el | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/lisp/org.el b/lisp/org.el
index c566152..4f32e35 100755
--- a/lisp/org.el
+++ b/lisp/org.el
@@ -23017,6 +23017,11 @@ matches in paragraphs or comments, use it."
(org-with-wide-buffer
(unless (org-at-heading-p)
(let* ((p (line-beginning-position))
+ (org-element-paragraph-separate
+ (if (derived-mode-p 'message-mode)
+ (concat org-element-paragraph-separate
+ "\\|" mail-header-separator)
+ org-element-paragraph-separate))
(element (save-excursion
(beginning-of-line)
(org-element-at-point)))
--
2.3.2
^ permalink raw reply related [flat|nested] 13+ messages in thread
* Re: [PATCH] Re: autoloads not working correctly for org-table.el?
2015-03-10 2:15 ` [PATCH] " Eric Abrahamsen
@ 2015-03-10 3:07 ` Eric Abrahamsen
2015-03-10 8:24 ` Nicolas Goaziou
0 siblings, 1 reply; 13+ messages in thread
From: Eric Abrahamsen @ 2015-03-10 3:07 UTC (permalink / raw)
To: emacs-orgmode
[-- Attachment #1: Type: text/plain, Size: 2701 bytes --]
Eric Abrahamsen <eric@ericabrahamsen.net> writes:
> Eric Abrahamsen <eric@ericabrahamsen.net> writes:
>
>> Eric S Fraga <e.fraga@ucl.ac.uk> writes:
>>
>>> On Wednesday, 4 Mar 2015 at 17:28, Eric Abrahamsen wrote:
>>>
>>> [...]
>>>
>>>> I'm still seeing an issue where, if I start right off typing a big
>>>> paragraph of text at the top of the message (no salutation or anything),
>>>> all the lines *after* the first line are indented by one tab. Subsequent
>>>> paragraphs are unaffected.
>>>
>>> Hi Eric,
>>>
>>> I had this problem for a long time. It disappeared a some time ago now
>>> and I have no idea why. However, while I had the problem, I trained
>>> myself to always start an email (that was not a response like this one)
>>> with some form of salutation! More polite as well as avoiding the bug
>>> :)
>>
>> Well, sure :) I guess I'll try being politer!
>>
>> I just poked around a little bit, edebugging
>> `org-adaptive-fill-function'. I looked at the call to
>> `fill-context-prefix' two-thirds of the way down. I tested this with the
>> last email I sent, and I see that calling `org-adaptive-fill-function'
>> on the first paragraph results in `fill-context-prefix' being called
>> with the arguments 1 (the post-affiliated arg), and 447 (the end
>> position of the first paragraph). The result of that call is a tab.
>>
>> If I move to the second paragraph and do the same thing, the
>> post-affiliated arg was 447, and the end position is 475. The result of
>> that call was nil, which is probably what I wanted.
>>
>> My value of adaptive-fill-regexp, in this case is:
>>
>> "\\(\\([ ]*[_.[:word:]]+>+\\|[ ]*[]>|]\\)+\\)[ ]*\\|[
>> ]*\\([-–!|#%;>*·•‣⁃◦]+[ ]*\\)*"
>>
>> I will poke further as time allows. I don't know much about filling (and
>> have never understood what "post-affiliated" actually means), but assume
>> I can eventually get to the bottom of it...
>>
>> E
>
> It looks like the problem was that all the message headers are parsed as
> though they were part of the first paragraph of message body text. Why
> that should result in a secondary TAB indent I don't know, but
> regardless, Org probably should only be looking at the message body, and
> nothing else.
>
> The attached patch is a hack that adds the `mail-header-separator'
> regexp to the `org-element-paragraph-separate' regexp. That means it
> will only work for paragraphs, so there might still be weirdness if a
> message body starts with a list or what have you.
>
> Perhaps a better solution would be to narrow to the body of the message
> before doing the fill prefix calculation.
>
> Eric
And just for the heck of it, here's another patch that does it with
narrowing.
E
[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: 0001-Narrow-to-message-body-when-filling-in-message-mode.patch --]
[-- Type: text/x-diff, Size: 1062 bytes --]
From c51cdb35453ae8c2964508fc1e98b89e6c709abb Mon Sep 17 00:00:00 2001
From: Eric Abrahamsen <eric@ericabrahamsen.net>
Date: Tue, 10 Mar 2015 11:03:23 +0800
Subject: [PATCH] Narrow to message body when filling in message mode
* lisp/org.el (org-adaptive-fill-function): Only take the message body
into account when calculating the fill prefix.
---
lisp/org.el | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/lisp/org.el b/lisp/org.el
index c566152..cf952ad 100755
--- a/lisp/org.el
+++ b/lisp/org.el
@@ -23015,6 +23015,12 @@ matches in paragraphs or comments, use it."
((looking-at org-outline-regexp)
(throw 'exit (make-string (length (match-string 0)) ?\s))))))
(org-with-wide-buffer
+ (when (derived-mode-p 'message-mode)
+ (save-excursion
+ (goto-char (point-min))
+ (when (re-search-forward mail-header-separator)
+ (narrow-to-region
+ (line-beginning-position 2) (point-max)))))
(unless (org-at-heading-p)
(let* ((p (line-beginning-position))
(element (save-excursion
--
2.3.2
^ permalink raw reply related [flat|nested] 13+ messages in thread
* Re: [PATCH] Re: autoloads not working correctly for org-table.el?
2015-03-10 3:07 ` Eric Abrahamsen
@ 2015-03-10 8:24 ` Nicolas Goaziou
2015-03-10 8:48 ` Eric Abrahamsen
0 siblings, 1 reply; 13+ messages in thread
From: Nicolas Goaziou @ 2015-03-10 8:24 UTC (permalink / raw)
To: Eric Abrahamsen; +Cc: emacs-orgmode
Hello,
Eric Abrahamsen <eric@ericabrahamsen.net> writes:
> And just for the heck of it, here's another patch that does it with
> narrowing.
Thanks for the patch.
However, I don't think it belongs to `org-adaptive-fill-function' to
handle this. All this Message mode processing should probably be
delegated to the orgstruct level.
Regards,
--
Nicolas Goaziou
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH] Re: autoloads not working correctly for org-table.el?
2015-03-10 8:24 ` Nicolas Goaziou
@ 2015-03-10 8:48 ` Eric Abrahamsen
2015-03-10 11:02 ` Nicolas Goaziou
0 siblings, 1 reply; 13+ messages in thread
From: Eric Abrahamsen @ 2015-03-10 8:48 UTC (permalink / raw)
To: emacs-orgmode
Nicolas Goaziou <mail@nicolasgoaziou.fr> writes:
> Hello,
>
> Eric Abrahamsen <eric@ericabrahamsen.net> writes:
>
>> And just for the heck of it, here's another patch that does it with
>> narrowing.
>
> Thanks for the patch.
>
> However, I don't think it belongs to `org-adaptive-fill-function' to
> handle this. All this Message mode processing should probably be
> delegated to the orgstruct level.
Makes sense!
If we really want to get all the message-specific stuff refactored into
orgstruct++ mode, I guess we could (in the `orgstruct++-mode' function)
bind `normal-auto-fill-function' and `adaptive-fill-function' to new
functions, which first check for message-mode specific stuff (and any
other modes that need to be handled), then delegate to
`org-auto-fill-function' and `org-adaptive-fill-function'.
Actually, all `org-auto-fill-function' does is conditionally call
`org-adaptive-fill-function', so maybe we could just have one new
function, `orgstruct++-auto-fill-function', that does everything.
How does that sound?
Eric
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH] Re: autoloads not working correctly for org-table.el?
2015-03-10 8:48 ` Eric Abrahamsen
@ 2015-03-10 11:02 ` Nicolas Goaziou
2015-03-22 13:52 ` Eric Abrahamsen
0 siblings, 1 reply; 13+ messages in thread
From: Nicolas Goaziou @ 2015-03-10 11:02 UTC (permalink / raw)
To: Eric Abrahamsen; +Cc: emacs-orgmode
Eric Abrahamsen <eric@ericabrahamsen.net> writes:
> If we really want to get all the message-specific stuff refactored into
> orgstruct++ mode, I guess we could (in the `orgstruct++-mode' function)
> bind `normal-auto-fill-function' and `adaptive-fill-function' to new
> functions, which first check for message-mode specific stuff (and any
> other modes that need to be handled),then delegate to
> `org-auto-fill-function' and `org-adaptive-fill-function'.
Indeed. There's also `org-fill-paragraph' to purge from Message mode
stuff.
Ultimately, Orgstruct minor mode could be moved into its own library,
e.g., "org-struct.el".
> Actually, all `org-auto-fill-function' does is conditionally call
> `org-adaptive-fill-function', so maybe we could just have one new
> function, `orgstruct++-auto-fill-function', that does everything.
Probably, yes.
> How does that sound?
It sounds good.
Regards,
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH] Re: autoloads not working correctly for org-table.el?
2015-03-10 11:02 ` Nicolas Goaziou
@ 2015-03-22 13:52 ` Eric Abrahamsen
0 siblings, 0 replies; 13+ messages in thread
From: Eric Abrahamsen @ 2015-03-22 13:52 UTC (permalink / raw)
To: emacs-orgmode
[-- Attachment #1: Type: text/plain, Size: 2027 bytes --]
Nicolas Goaziou <mail@nicolasgoaziou.fr> writes:
> Eric Abrahamsen <eric@ericabrahamsen.net> writes:
>
>> If we really want to get all the message-specific stuff refactored into
>> orgstruct++ mode, I guess we could (in the `orgstruct++-mode' function)
>> bind `normal-auto-fill-function' and `adaptive-fill-function' to new
>> functions, which first check for message-mode specific stuff (and any
>> other modes that need to be handled),then delegate to
>> `org-auto-fill-function' and `org-adaptive-fill-function'.
>
> Indeed. There's also `org-fill-paragraph' to purge from Message mode
> stuff.
>
> Ultimately, Orgstruct minor mode could be moved into its own library,
> e.g., "org-struct.el".
>
>> Actually, all `org-auto-fill-function' does is conditionally call
>> `org-adaptive-fill-function', so maybe we could just have one new
>> function, `orgstruct++-auto-fill-function', that does everything.
>
> Probably, yes.
>
>> How does that sound?
>
> It sounds good.
Okay, here's my first attempt at this.
So far as I can tell, it works. By which I mean "it works, but I don't
understand why". I don't have any experience twiddling with the filling
mechanism, and I found it very baffling, but in all my tests so far this
patch does what it is supposed to.
Likely areas of ugliness:
1. I haven't succeeded in merging `orgstruct-auto-fill-function' with
`orgstruct-adaptive-fill-function', mostly because I don't really
understand what "adaptive fill" actually means.
2. I have overridden the `org-element-paragraph-separate' altogether,
rather than adding message-mode stuff to it. And yet, it works okay,
to wit: the plain list I'm currently typing.
3. There's almost certainly refactoring that could be done.
Oops, it doesn't work okay after all -- when I hit RET at the end of the
third list item, it indented itself.
So obviously this isn't quite there yet. I'll keep working at it, which
means actually learning how filling works. In the meantime, any code
comments would be appreciated.
Eric
[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: 0001-First-stab-at-independent-orgstruct-mode.patch --]
[-- Type: text/x-diff, Size: 39521 bytes --]
From c93dc652d998978a070d7ea39bbd5ee14041f531 Mon Sep 17 00:00:00 2001
From: Eric Abrahamsen <eric@ericabrahamsen.net>
Date: Wed, 11 Mar 2015 18:48:52 +0800
Subject: [PATCH] First stab at independent orgstruct mode
---
lisp/org-element.el | 2 +
lisp/org-struct.el | 364 ++++++++++++++++++++++++++++++
lisp/org.el | 632 ++++++++++++++--------------------------------------
3 files changed, 531 insertions(+), 467 deletions(-)
create mode 100644 lisp/org-struct.el
diff --git a/lisp/org-element.el b/lisp/org-element.el
index b0e4e5c..8c95bcc 100644
--- a/lisp/org-element.el
+++ b/lisp/org-element.el
@@ -4856,6 +4856,8 @@ This function assumes `org-element--cache' is a valid AVL tree."
;;;; Tools
+(defvar orgstruct-mode nil)
+
(defsubst org-element--cache-active-p ()
"Non-nil when cache is active in current buffer."
(and org-element-use-cache
diff --git a/lisp/org-struct.el b/lisp/org-struct.el
new file mode 100644
index 0000000..3acfbc0
--- /dev/null
+++ b/lisp/org-struct.el
@@ -0,0 +1,364 @@
+;;; org-struct.el --- Org-style editing in non-Org buffers -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2015 Free Software Foundation, Inc.
+
+;; Author: Carsten Dominik <carsten at orgmode dot org>
+;; Keywords: outlines
+
+;; This program 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 of the License, or
+;; (at your option) any later version.
+
+;; This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;; This file provides two minor modes for using Org-style editing
+;; commands in buffers that aren't in Org mode. The first mode,
+;; orgstruct-mode, defines key-bindings for structural editing
+;; commands like inserting headings and manipulating list items. The
+;; second minor mode, orgstruct++-mode, builds on the first, adding
+;; functions to handle filling and indentation.
+
+;; The basic orgstruct-mode is a bit of a hack: it hijacks all the
+;; keys it needs for structure editing, and wraps them in a function
+;; (`orgstruct-make-binding') that checks the context around point.
+;; If the text around point looks like Org text, the relevant Org
+;; command is run. If it doesn't, the function checks to see if the
+;; currently-active major or minor modes have commands bound to those
+;; keys, and, if so, calls those commands.
+
+;; The second minor mode, orgstruct++, special-cases various major
+;; modes, such as message-mode, to make sure that Org text structures
+;; are filled and indented properly.
+
+;; in orgstruct++ mode, we need to set custom values for
+;; indent-line-function, adaptive-fill-function,
+;; normal-auto-fill-function, and fill-paragraph-function
+
+;;; Code:
+
+(require 'org)
+
+(declare-function message-goto-body "message" ())
+
+(defvar message-cite-prefix-regexp) ; From message.el
+
+(defcustom orgstruct-heading-prefix-regexp ""
+ "Regexp that matches the custom prefix of Org headlines in
+orgstruct(++)-mode."
+ :group 'org
+ :version "24.4"
+ :package-version '(Org . "8.3")
+ :type 'regexp)
+;;;###autoload(put 'orgstruct-heading-prefix-regexp 'safe-local-variable 'stringp)
+
+(defcustom orgstruct-setup-hook nil
+ "Hook run after orgstruct-mode-map is filled."
+ :group 'org
+ :version "24.4"
+ :package-version '(Org . "8.0")
+ :type 'hook)
+
+(defvar orgstruct-initialized nil)
+
+;;;###autoload
+(define-minor-mode orgstruct-mode
+ "Toggle the minor mode `orgstruct-mode'.
+This mode is for using Org-mode structure commands in other
+modes. The following keys behave as if Org-mode were active, if
+the cursor is on a headline, or on a plain list item (both as
+defined by Org-mode)."
+ nil " OrgStruct" (make-sparse-keymap)
+ (funcall (if orgstruct-mode
+ 'add-to-invisibility-spec
+ 'remove-from-invisibility-spec)
+ '(outline . t))
+ (when orgstruct-mode
+ (org-load-modules-maybe)
+ (unless orgstruct-initialized
+ (orgstruct-setup)
+ (setq orgstruct-initialized t))))
+
+;;;###autoload
+(defun turn-on-orgstruct ()
+ "Unconditionally turn on `orgstruct-mode'."
+ (orgstruct-mode 1))
+
+(defvar org-fb-vars nil)
+(make-variable-buffer-local 'org-fb-vars)
+
+(defun orgstruct-error ()
+ "Error when there is no default binding for a structure key."
+ (interactive)
+ (funcall (if (fboundp 'user-error)
+ 'user-error
+ 'error)
+ "This key has no function outside structure elements"))
+
+(defun orgstruct-setup ()
+ "Setup orgstruct keymap."
+ (dolist (cell '((org-demote . t)
+ (org-metaleft . t)
+ (org-metaright . t)
+ (org-promote . t)
+ (org-shiftmetaleft . t)
+ (org-shiftmetaright . t)
+ org-backward-element
+ org-backward-heading-same-level
+ org-ctrl-c-ret
+ org-ctrl-c-minus
+ org-ctrl-c-star
+ org-cycle
+ org-forward-heading-same-level
+ org-insert-heading
+ org-insert-heading-respect-content
+ org-kill-note-or-show-branches
+ org-mark-subtree
+ org-meta-return
+ org-metadown
+ org-metaup
+ org-narrow-to-subtree
+ org-promote-subtree
+ org-reveal
+ org-shiftdown
+ org-shiftleft
+ org-shiftmetadown
+ org-shiftmetaup
+ org-shiftright
+ org-shifttab
+ org-shifttab
+ org-shiftup
+ org-show-subtree
+ org-sort
+ org-up-element
+ outline-demote
+ outline-next-visible-heading
+ outline-previous-visible-heading
+ outline-promote
+ outline-up-heading
+ show-children))
+ (let ((f (or (car-safe cell) cell))
+ (disable-when-heading-prefix (cdr-safe cell)))
+ (when (fboundp f)
+ (let ((new-bindings))
+ (dolist (binding (nconc (where-is-internal f org-mode-map)
+ (where-is-internal f outline-mode-map)))
+ (push binding new-bindings)
+ ;; TODO use local-function-key-map
+ (dolist (rep '(("<tab>" . "TAB")
+ ("<return>" . "RET")
+ ("<escape>" . "ESC")
+ ("<delete>" . "DEL")))
+ (setq binding (read-kbd-macro
+ (let ((case-fold-search))
+ (replace-regexp-in-string
+ (regexp-quote (cdr rep))
+ (car rep)
+ (key-description binding)))))
+ (pushnew binding new-bindings :test 'equal)))
+ (dolist (binding new-bindings)
+ (let ((key (lookup-key orgstruct-mode-map binding)))
+ (when (or (not key) (numberp key))
+ (ignore-errors
+ (org-defkey orgstruct-mode-map
+ binding
+ (orgstruct-make-binding
+ f binding disable-when-heading-prefix))))))))))
+ (run-hooks 'orgstruct-setup-hook))
+
+(defun orgstruct-make-binding (fun key disable-when-heading-prefix)
+ "Create a function for binding in the structure minor mode.
+FUN is the command to call inside a table. KEY is the key that
+should be checked in for a command to execute outside of tables.
+Non-nil `disable-when-heading-prefix' means to disable the command
+if `orgstruct-heading-prefix-regexp' is not empty."
+ (let ((name (concat "orgstruct-hijacker-" (symbol-name fun))))
+ (let ((nname name)
+ (i 0))
+ (while (fboundp (intern nname))
+ (setq nname (format "%s-%d" name (setq i (1+ i)))))
+ (setq name (intern nname)))
+ (eval
+ (let ((bindings '((org-heading-regexp
+ (concat "^"
+ orgstruct-heading-prefix-regexp
+ "\\(\\*+\\)\\(?: +\\(.*?\\)\\)?[ ]*$"))
+ (org-outline-regexp
+ (concat orgstruct-heading-prefix-regexp "\\*+ "))
+ (org-outline-regexp-bol
+ (concat "^" org-outline-regexp))
+ (outline-regexp org-outline-regexp)
+ (outline-heading-end-regexp "\n")
+ (outline-level 'org-outline-level)
+ (outline-heading-alist))))
+ `(defun ,name (arg)
+ ,(concat "In Structure, run `" (symbol-name fun) "'.\n"
+ "Outside of structure, run the binding of `"
+ (key-description key) "'."
+ (when disable-when-heading-prefix
+ (concat
+ "\nIf `orgstruct-heading-prefix-regexp' is not empty, this command will always fall\n"
+ "back to the default binding due to limitations of Org's implementation of\n"
+ "`" (symbol-name fun) "'.")))
+ (interactive "p")
+ (let* ((disable
+ ,(and disable-when-heading-prefix
+ '(not (string= orgstruct-heading-prefix-regexp ""))))
+ (fallback
+ (or disable
+ (not
+ (let* ,bindings
+ (org-context-p 'headline 'item
+ ,(when (memq fun
+ '(org-insert-heading
+ org-insert-heading-respect-content
+ org-meta-return))
+ '(when orgstruct-is-++
+ 'item-body))))))))
+ (if fallback
+ (let* ((orgstruct-mode)
+ (binding
+ (let ((key ,key))
+ (catch 'exit
+ (dolist
+ (rep
+ '(nil
+ ("<\\([^>]*\\)tab>" . "\\1TAB")
+ ("<\\([^>]*\\)return>" . "\\1RET")
+ ("<\\([^>]*\\)escape>" . "\\1ESC")
+ ("<\\([^>]*\\)delete>" . "\\1DEL"))
+ nil)
+ (when rep
+ (setq key (read-kbd-macro
+ (let ((case-fold-search))
+ (replace-regexp-in-string
+ (car rep)
+ (cdr rep)
+ (key-description key))))))
+ (when (key-binding key)
+ (throw 'exit (key-binding key))))))))
+ (if (keymapp binding)
+ (org-set-transient-map binding)
+ (let ((func (or binding
+ (unless disable
+ 'orgstruct-error))))
+ (when func
+ (call-interactively func)))))
+ (org-run-like-in-org-mode
+ (lambda ()
+ (interactive)
+ (let* ,bindings
+ (call-interactively ',fun)))))))))
+ name))
+
+(defun orgstruct++-mode (&optional arg)
+ "Toggle `orgstruct-mode', the enhanced version of it.
+In addition to setting orgstruct-mode, this also exports all
+indentation and autofilling variables from org-mode into the
+buffer. It will also recognize item context in multiline items."
+ (interactive "P")
+ (setq arg (prefix-numeric-value (or arg (if orgstruct-mode -1 1))))
+ (if (< arg 1)
+ (progn (orgstruct-mode -1)
+ (mapc (lambda(v)
+ (org-set-local (car v)
+ (if (eq (car-safe (cadr v)) 'quote) (cadadr v) (cadr v))))
+ org-fb-vars))
+ (orgstruct-mode 1)
+ (setq org-fb-vars nil)
+ (unless org-local-vars
+ (setq org-local-vars (org-get-local-variables)))
+ (let (var val)
+ (mapc
+ (lambda (x)
+ (when (string-match
+ "^\\(paragraph-\\|auto-fill\\|normal-auto-fill\\|fill-paragraph\\|fill-prefix\\|indent-\\)"
+ (symbol-name (car x)))
+ (setq var (car x) val (nth 1 x))
+ (push (list var `(quote ,(eval var))) org-fb-vars)
+ (org-set-local var (if (eq (car-safe val) 'quote) (nth 1 val) val))))
+ org-local-vars)
+ (org-set-local 'fill-paragraph-function 'orgstruct-fill-paragraph)
+ (org-set-local 'adaptive-fill-function 'orgstruct-adaptive-fill-function)
+ (org-set-local 'auto-fill-function 'orgstruct-auto-fill-function)
+ (org-set-local 'indent-line-function 'orgstruct-indent-line-function)
+ (org-set-local 'orgstruct-is-++ t))))
+
+(defvar orgstruct-is-++ nil
+ "Is `orgstruct-mode' in ++ version in the current-buffer?")
+(make-variable-buffer-local 'orgstruct-is-++)
+
+;;;###autoload
+(defun turn-on-orgstruct++ ()
+ "Unconditionally turn on `orgstruct++-mode'."
+ (orgstruct++-mode 1))
+
+(defun orgstruct-fill-paragraph (&optional justify)
+ (interactive)
+ (cond
+ ((and (derived-mode-p 'message-mode)
+ (or (not (message-in-body-p))
+ (save-excursion (move-beginning-of-line 1)
+ (looking-at message-cite-prefix-regexp))))
+ ;; Set appropriate variables for message-mode
+ (let ((fill-paragraph-function
+ (cadadr (assoc 'fill-paragraph-function org-fb-vars)))
+ (fill-prefix (cadadr (assoc 'fill-prefix org-fb-vars)))
+ (paragraph-start (cadadr (assoc 'paragraph-start org-fb-vars)))
+ (paragraph-separate (cadadr (assoc 'paragraph-separate org-fb-vars)))
+ (org-element-paragraph-separate (cadadr (assoc 'paragraph-separate org-fb-vars))))
+ (org-fill-paragraph)))
+ (t
+ (org-fill-paragraph))))
+
+(defun orgstruct-adaptive-fill-function ()
+ "Find the appropriate fill prefix for the current major mode."
+ (cond ((derived-mode-p 'message-mode)
+ (save-excursion
+ (beginning-of-line)
+ (cond ((not (message-in-body-p)) nil)
+ ((org-looking-at-p org-table-line-regexp) nil)
+ ((looking-at message-cite-prefix-regexp)
+ (match-string-no-properties 0))
+ ((looking-at org-outline-regexp)
+ (make-string (length (match-string 0)) ?\s))
+ ((message-in-body-p)
+ (let ((fill-paragraph-function
+ (cadadr (assoc 'fill-paragraph-function org-fb-vars)))
+ (fill-prefix (cadadr (assoc 'fill-prefix org-fb-vars)))
+ (paragraph-start (cadadr (assoc 'paragraph-start org-fb-vars)))
+ (paragraph-separate (cadadr (assoc 'paragraph-separate org-fb-vars)))
+ (org-element-paragraph-separate (cadadr (assoc 'paragraph-separate org-fb-vars))))
+ (org-adaptive-fill-function))))))
+ (t
+ (org-adaptive-fill-function))))
+
+(defun orgstruct-auto-fill-function ()
+ (let ((fc (current-fill-column)))
+ (when (and fc (> (current-column) fc))
+ (let* ((fill-prefix (orgstruct-adaptive-fill-function))
+ ;; Enforce empty fill prefix, if required. Otherwise, it
+ ;; will be computed again.
+ (adaptive-fill-mode (not (equal fill-prefix ""))))
+ (when fill-prefix (do-auto-fill))))))
+
+(defun orgstruct-indent-line-function ()
+ (interactive)
+ (cond
+ (orgstruct-is-++
+ (let ((indent-line-function
+ (cadadr (assq 'indent-line-function org-fb-vars))))
+ (indent-according-to-mode)))
+ (t
+ (org-indent-line))))
+
+(provide 'org-struct)
+;;; org-struct.el ends here
diff --git a/lisp/org.el b/lisp/org.el
index 72be8ee..90f2207 100755
--- a/lisp/org.el
+++ b/lisp/org.el
@@ -7924,8 +7924,6 @@ When NO-TODO is non-nil, don't include TODO keywords."
(t (looking-at org-heading-regexp)
(match-string 2)))))
-(defvar orgstruct-mode) ; defined below
-
(defun org-heading-components ()
"Return the components of the current heading.
This is a list with the following elements:
@@ -7939,22 +7937,22 @@ This is a list with the following elements:
(org-back-to-heading t)
(if (let (case-fold-search)
(looking-at
- (if orgstruct-mode
- org-heading-regexp
- org-complex-heading-regexp)))
- (if orgstruct-mode
+ (if (derived-mode-p 'org-mode)
+ org-complex-heading-regexp
+ org-heading-regexp)))
+ (if (derived-mode-p 'org-mode)
(list (length (match-string 1))
- (org-reduced-level (length (match-string 1)))
- nil
- nil
- (match-string 2)
- nil)
+ (org-reduced-level (length (match-string 1)))
+ (org-match-string-no-properties 2)
+ (and (match-end 3) (aref (match-string 3) 2))
+ (org-match-string-no-properties 4)
+ (org-match-string-no-properties 5))
(list (length (match-string 1))
- (org-reduced-level (length (match-string 1)))
- (org-match-string-no-properties 2)
- (and (match-end 3) (aref (match-string 3) 2))
- (org-match-string-no-properties 4)
- (org-match-string-no-properties 5))))))
+ (org-reduced-level (length (match-string 1)))
+ nil
+ nil
+ (match-string 2)
+ nil)))))
(defun org-get-entry ()
"Get the entry text, after heading, entire subtree."
@@ -9071,273 +9069,6 @@ When sorting is done, call `org-after-sorting-entries-or-items-hook'."
(move-marker org-clock-marker (point))))
(message "Sorting entries...done")))
-;;; The orgstruct minor mode
-
-;; Define a minor mode which can be used in other modes in order to
-;; integrate the org-mode structure editing commands.
-
-;; This is really a hack, because the org-mode structure commands use
-;; keys which normally belong to the major mode. Here is how it
-;; works: The minor mode defines all the keys necessary to operate the
-;; structure commands, but wraps the commands into a function which
-;; tests if the cursor is currently at a headline or a plain list
-;; item. If that is the case, the structure command is used,
-;; temporarily setting many Org-mode variables like regular
-;; expressions for filling etc. However, when any of those keys is
-;; used at a different location, function uses `key-binding' to look
-;; up if the key has an associated command in another currently active
-;; keymap (minor modes, major mode, global), and executes that
-;; command. There might be problems if any of the keys is otherwise
-;; used as a prefix key.
-
-(defcustom orgstruct-heading-prefix-regexp ""
- "Regexp that matches the custom prefix of Org headlines in
-orgstruct(++)-mode."
- :group 'org
- :version "24.4"
- :package-version '(Org . "8.3")
- :type 'regexp)
-;;;###autoload(put 'orgstruct-heading-prefix-regexp 'safe-local-variable 'stringp)
-
-(defcustom orgstruct-setup-hook nil
- "Hook run after orgstruct-mode-map is filled."
- :group 'org
- :version "24.4"
- :package-version '(Org . "8.0")
- :type 'hook)
-
-(defvar orgstruct-initialized nil)
-
-(defvar org-local-vars nil
- "List of local variables, for use by `orgstruct-mode'.")
-
-;;;###autoload
-(define-minor-mode orgstruct-mode
- "Toggle the minor mode `orgstruct-mode'.
-This mode is for using Org-mode structure commands in other
-modes. The following keys behave as if Org-mode were active, if
-the cursor is on a headline, or on a plain list item (both as
-defined by Org-mode)."
- nil " OrgStruct" (make-sparse-keymap)
- (funcall (if orgstruct-mode
- 'add-to-invisibility-spec
- 'remove-from-invisibility-spec)
- '(outline . t))
- (when orgstruct-mode
- (org-load-modules-maybe)
- (unless orgstruct-initialized
- (orgstruct-setup)
- (setq orgstruct-initialized t))))
-
-;;;###autoload
-(defun turn-on-orgstruct ()
- "Unconditionally turn on `orgstruct-mode'."
- (orgstruct-mode 1))
-
-(defvar org-fb-vars nil)
-(make-variable-buffer-local 'org-fb-vars)
-(defun orgstruct++-mode (&optional arg)
- "Toggle `orgstruct-mode', the enhanced version of it.
-In addition to setting orgstruct-mode, this also exports all
-indentation and autofilling variables from org-mode into the
-buffer. It will also recognize item context in multiline items."
- (interactive "P")
- (setq arg (prefix-numeric-value (or arg (if orgstruct-mode -1 1))))
- (if (< arg 1)
- (progn (orgstruct-mode -1)
- (mapc (lambda(v)
- (org-set-local (car v)
- (if (eq (car-safe (cadr v)) 'quote) (cadadr v) (cadr v))))
- org-fb-vars))
- (orgstruct-mode 1)
- (setq org-fb-vars nil)
- (unless org-local-vars
- (setq org-local-vars (org-get-local-variables)))
- (let (var val)
- (mapc
- (lambda (x)
- (when (string-match
- "^\\(paragraph-\\|auto-fill\\|normal-auto-fill\\|fill-paragraph\\|fill-prefix\\|indent-\\)"
- (symbol-name (car x)))
- (setq var (car x) val (nth 1 x))
- (push (list var `(quote ,(eval var))) org-fb-vars)
- (org-set-local var (if (eq (car-safe val) 'quote) (nth 1 val) val))))
- org-local-vars)
- (org-set-local 'orgstruct-is-++ t))))
-
-(defvar orgstruct-is-++ nil
- "Is `orgstruct-mode' in ++ version in the current-buffer?")
-(make-variable-buffer-local 'orgstruct-is-++)
-
-;;;###autoload
-(defun turn-on-orgstruct++ ()
- "Unconditionally turn on `orgstruct++-mode'."
- (orgstruct++-mode 1))
-
-(defun orgstruct-error ()
- "Error when there is no default binding for a structure key."
- (interactive)
- (funcall (if (fboundp 'user-error)
- 'user-error
- 'error)
- "This key has no function outside structure elements"))
-
-(defun orgstruct-setup ()
- "Setup orgstruct keymap."
- (dolist (cell '((org-demote . t)
- (org-metaleft . t)
- (org-metaright . t)
- (org-promote . t)
- (org-shiftmetaleft . t)
- (org-shiftmetaright . t)
- org-backward-element
- org-backward-heading-same-level
- org-ctrl-c-ret
- org-ctrl-c-minus
- org-ctrl-c-star
- org-cycle
- org-forward-heading-same-level
- org-insert-heading
- org-insert-heading-respect-content
- org-kill-note-or-show-branches
- org-mark-subtree
- org-meta-return
- org-metadown
- org-metaup
- org-narrow-to-subtree
- org-promote-subtree
- org-reveal
- org-shiftdown
- org-shiftleft
- org-shiftmetadown
- org-shiftmetaup
- org-shiftright
- org-shifttab
- org-shifttab
- org-shiftup
- org-show-subtree
- org-sort
- org-up-element
- outline-demote
- outline-next-visible-heading
- outline-previous-visible-heading
- outline-promote
- outline-up-heading
- show-children))
- (let ((f (or (car-safe cell) cell))
- (disable-when-heading-prefix (cdr-safe cell)))
- (when (fboundp f)
- (let ((new-bindings))
- (dolist (binding (nconc (where-is-internal f org-mode-map)
- (where-is-internal f outline-mode-map)))
- (push binding new-bindings)
- ;; TODO use local-function-key-map
- (dolist (rep '(("<tab>" . "TAB")
- ("<return>" . "RET")
- ("<escape>" . "ESC")
- ("<delete>" . "DEL")))
- (setq binding (read-kbd-macro
- (let ((case-fold-search))
- (replace-regexp-in-string
- (regexp-quote (cdr rep))
- (car rep)
- (key-description binding)))))
- (pushnew binding new-bindings :test 'equal)))
- (dolist (binding new-bindings)
- (let ((key (lookup-key orgstruct-mode-map binding)))
- (when (or (not key) (numberp key))
- (ignore-errors
- (org-defkey orgstruct-mode-map
- binding
- (orgstruct-make-binding
- f binding disable-when-heading-prefix))))))))))
- (run-hooks 'orgstruct-setup-hook))
-
-(defun orgstruct-make-binding (fun key disable-when-heading-prefix)
- "Create a function for binding in the structure minor mode.
-FUN is the command to call inside a table. KEY is the key that
-should be checked in for a command to execute outside of tables.
-Non-nil `disable-when-heading-prefix' means to disable the command
-if `orgstruct-heading-prefix-regexp' is not empty."
- (let ((name (concat "orgstruct-hijacker-" (symbol-name fun))))
- (let ((nname name)
- (i 0))
- (while (fboundp (intern nname))
- (setq nname (format "%s-%d" name (setq i (1+ i)))))
- (setq name (intern nname)))
- (eval
- (let ((bindings '((org-heading-regexp
- (concat "^"
- orgstruct-heading-prefix-regexp
- "\\(\\*+\\)\\(?: +\\(.*?\\)\\)?[ ]*$"))
- (org-outline-regexp
- (concat orgstruct-heading-prefix-regexp "\\*+ "))
- (org-outline-regexp-bol
- (concat "^" org-outline-regexp))
- (outline-regexp org-outline-regexp)
- (outline-heading-end-regexp "\n")
- (outline-level 'org-outline-level)
- (outline-heading-alist))))
- `(defun ,name (arg)
- ,(concat "In Structure, run `" (symbol-name fun) "'.\n"
- "Outside of structure, run the binding of `"
- (key-description key) "'."
- (when disable-when-heading-prefix
- (concat
- "\nIf `orgstruct-heading-prefix-regexp' is not empty, this command will always fall\n"
- "back to the default binding due to limitations of Org's implementation of\n"
- "`" (symbol-name fun) "'.")))
- (interactive "p")
- (let* ((disable
- ,(and disable-when-heading-prefix
- '(not (string= orgstruct-heading-prefix-regexp ""))))
- (fallback
- (or disable
- (not
- (let* ,bindings
- (org-context-p 'headline 'item
- ,(when (memq fun
- '(org-insert-heading
- org-insert-heading-respect-content
- org-meta-return))
- '(when orgstruct-is-++
- 'item-body))))))))
- (if fallback
- (let* ((orgstruct-mode)
- (binding
- (let ((key ,key))
- (catch 'exit
- (dolist
- (rep
- '(nil
- ("<\\([^>]*\\)tab>" . "\\1TAB")
- ("<\\([^>]*\\)return>" . "\\1RET")
- ("<\\([^>]*\\)escape>" . "\\1ESC")
- ("<\\([^>]*\\)delete>" . "\\1DEL"))
- nil)
- (when rep
- (setq key (read-kbd-macro
- (let ((case-fold-search))
- (replace-regexp-in-string
- (car rep)
- (cdr rep)
- (key-description key))))))
- (when (key-binding key)
- (throw 'exit (key-binding key))))))))
- (if (keymapp binding)
- (org-set-transient-map binding)
- (let ((func (or binding
- (unless disable
- 'orgstruct-error))))
- (when func
- (call-interactively func)))))
- (org-run-like-in-org-mode
- (lambda ()
- (interactive)
- (let* ,bindings
- (call-interactively ',fun)))))))))
- name))
-
(defun org-contextualize-keys (alist contexts)
"Return valid elements in ALIST depending on CONTEXTS.
@@ -9462,6 +9193,10 @@ Optional argument REGEXP selects variables to clone."
(cdr pair))))
(buffer-local-variables from-buffer)))
+(defvar org-local-vars nil
+ "List of Org-mode local variables, for using Org commands in
+ non-org-mode buffers.")
+
;;;###autoload
(defun org-run-like-in-org-mode (cmd)
"Run a command, pretending that the current buffer is in Org-mode.
@@ -22891,10 +22626,6 @@ list structure. Instead, use \\<org-mode-map>\\[org-shiftmetaleft] or \
Also align node properties according to `org-property-format'."
(interactive)
(cond
- (orgstruct-is-++
- (let ((indent-line-function
- (cadadr (assq 'indent-line-function org-fb-vars))))
- (indent-according-to-mode)))
((org-at-heading-p) 'noindent)
(t
(let* ((element (save-excursion (beginning-of-line) (org-element-at-point)))
@@ -23122,71 +22853,59 @@ assumed to be significant there."
Return fill prefix, as a string, or nil if current line isn't
meant to be filled. For convenience, if `adaptive-fill-regexp'
matches in paragraphs or comments, use it."
- (catch 'exit
- (when (derived-mode-p 'message-mode)
- (save-excursion
- (beginning-of-line)
- (cond ((not (message-in-body-p)) (throw 'exit nil))
- ((org-looking-at-p org-table-line-regexp) (throw 'exit nil))
- ((looking-at message-cite-prefix-regexp)
- (throw 'exit (match-string-no-properties 0)))
- ((looking-at org-outline-regexp)
- (throw 'exit (make-string (length (match-string 0)) ?\s))))))
- (org-with-wide-buffer
- (unless (org-at-heading-p)
- (let* ((p (line-beginning-position))
- (element (save-excursion
- (beginning-of-line)
- (org-element-at-point)))
- (type (org-element-type element))
- (post-affiliated (org-element-property :post-affiliated element)))
- (unless (< p post-affiliated)
- (case type
- (comment
+ (org-with-wide-buffer
+ (unless (org-at-heading-p)
+ (let* ((p (line-beginning-position))
+ (element (save-excursion
+ (beginning-of-line)
+ (org-element-at-point)))
+ (type (org-element-type element))
+ (post-affiliated (org-element-property :post-affiliated element)))
+ (unless (< p post-affiliated)
+ (case type
+ (comment
+ (save-excursion
+ (beginning-of-line)
+ (looking-at "[ \t]*")
+ (concat (match-string 0) "# ")))
+ (footnote-definition "")
+ ((item plain-list)
+ (make-string (org-list-item-body-column post-affiliated) ?\s))
+ (paragraph
+ ;; Fill prefix is usually the same as the current line,
+ ;; unless the paragraph is at the beginning of an item.
+ (let ((parent (org-element-property :parent element)))
(save-excursion
(beginning-of-line)
- (looking-at "[ \t]*")
- (concat (match-string 0) "# ")))
- (footnote-definition "")
- ((item plain-list)
- (make-string (org-list-item-body-column post-affiliated) ?\s))
- (paragraph
- ;; Fill prefix is usually the same as the current line,
- ;; unless the paragraph is at the beginning of an item.
- (let ((parent (org-element-property :parent element)))
- (save-excursion
- (beginning-of-line)
- (cond ((eq (org-element-type parent) 'item)
- (make-string (org-list-item-body-column
- (org-element-property :begin parent))
- ?\s))
- ((and adaptive-fill-regexp
- ;; Locally disable
- ;; `adaptive-fill-function' to let
- ;; `fill-context-prefix' handle
- ;; `adaptive-fill-regexp' variable.
- (let (adaptive-fill-function)
- (fill-context-prefix
- post-affiliated
- (org-element-property :end element)))))
- ((looking-at "[ \t]+") (match-string 0))
- (t "")))))
- (comment-block
- ;; Only fill contents if P is within block boundaries.
- (let* ((cbeg (save-excursion (goto-char post-affiliated)
- (forward-line)
- (point)))
- (cend (save-excursion
- (goto-char (org-element-property :end element))
- (skip-chars-backward " \r\t\n")
- (line-beginning-position))))
- (when (and (>= p cbeg) (< p cend))
- (if (save-excursion (beginning-of-line) (looking-at "[ \t]+"))
- (match-string 0)
- "")))))))))))
-
-(declare-function message-goto-body "message" ())
-(defvar message-cite-prefix-regexp) ; From message.el
+ (cond ((eq (org-element-type parent) 'item)
+ (make-string (org-list-item-body-column
+ (org-element-property :begin parent))
+ ?\s))
+ ((and adaptive-fill-regexp
+ ;; Locally disable
+ ;; `adaptive-fill-function' to let
+ ;; `fill-context-prefix' handle
+ ;; `adaptive-fill-regexp' variable.
+ (let (adaptive-fill-function)
+ (fill-context-prefix
+ post-affiliated
+ (org-element-property :end element)))))
+ ((looking-at "[ \t]+") (match-string 0))
+ (t "")))))
+ (comment-block
+ ;; Only fill contents if P is within block boundaries.
+ (let* ((cbeg (save-excursion (goto-char post-affiliated)
+ (forward-line)
+ (point)))
+ (cend (save-excursion
+ (goto-char (org-element-property :end element))
+ (skip-chars-backward " \r\t\n")
+ (line-beginning-position))))
+ (when (and (>= p cbeg) (< p cend))
+ (if (save-excursion (beginning-of-line) (looking-at "[ \t]+"))
+ (match-string 0)
+ ""))))))))))
+
(defun org-fill-paragraph (&optional justify)
"Fill element at point, when applicable.
@@ -23203,125 +22922,104 @@ width for filling.
For convenience, when point is at a plain list, an item or
a footnote definition, try to fill the first paragraph within."
(interactive)
- (if (and (derived-mode-p 'message-mode)
- (or (not (message-in-body-p))
- (save-excursion (move-beginning-of-line 1)
- (looking-at message-cite-prefix-regexp))))
- ;; First ensure filling is correct in message-mode.
- (let ((fill-paragraph-function
- (cadadr (assoc 'fill-paragraph-function org-fb-vars)))
- (fill-prefix (cadadr (assoc 'fill-prefix org-fb-vars)))
- (paragraph-start (cadadr (assoc 'paragraph-start org-fb-vars)))
- (paragraph-separate
- (cadadr (assoc 'paragraph-separate org-fb-vars))))
- (fill-paragraph nil))
- (with-syntax-table org-mode-transpose-word-syntax-table
- ;; Move to end of line in order to get the first paragraph
- ;; within a plain list or a footnote definition.
- (let ((element (save-excursion
- (end-of-line)
- (or (ignore-errors (org-element-at-point))
- (user-error "An element cannot be parsed line %d"
- (line-number-at-pos (point)))))))
- ;; First check if point is in a blank line at the beginning of
- ;; the buffer. In that case, ignore filling.
- (case (org-element-type element)
- ;; Use major mode filling function is src blocks.
- (src-block (org-babel-do-key-sequence-in-edit-buffer (kbd "M-q")))
- ;; Align Org tables, leave table.el tables as-is.
- (table-row (org-table-align) t)
- (table
- (when (eq (org-element-property :type element) 'org)
+ (with-syntax-table org-mode-transpose-word-syntax-table
+ ;; Move to end of line in order to get the first paragraph
+ ;; within a plain list or a footnote definition.
+ (let ((element (save-excursion
+ (end-of-line)
+ (or (ignore-errors (org-element-at-point))
+ (user-error "An element cannot be parsed line %d"
+ (line-number-at-pos (point)))))))
+ ;; First check if point is in a blank line at the beginning of
+ ;; the buffer. In that case, ignore filling.
+ (case (org-element-type element)
+ ;; Use major mode filling function is src blocks.
+ (src-block (org-babel-do-key-sequence-in-edit-buffer (kbd "M-q")))
+ ;; Align Org tables, leave table.el tables as-is.
+ (table-row (org-table-align) t)
+ (table
+ (when (eq (org-element-property :type element) 'org)
+ (save-excursion
+ (goto-char (org-element-property :post-affiliated element))
+ (org-table-align)))
+ t)
+ (paragraph
+ ;; Paragraphs may contain `line-break' type objects.
+ (let ((beg (max (point-min)
+ (org-element-property :contents-begin element)))
+ (end (min (point-max)
+ (org-element-property :contents-end element))))
+ ;; Do nothing if point is at an affiliated keyword.
+ (if (< (line-end-position) beg) t
+ ;; Fill paragraph, taking line breaks into account.
(save-excursion
- (goto-char (org-element-property :post-affiliated element))
- (org-table-align)))
- t)
- (paragraph
- ;; Paragraphs may contain `line-break' type objects.
- (let ((beg (max (point-min)
- (org-element-property :contents-begin element)))
- (end (min (point-max)
- (org-element-property :contents-end element))))
- ;; Do nothing if point is at an affiliated keyword.
- (if (< (line-end-position) beg) t
- (when (derived-mode-p 'message-mode)
- ;; In `message-mode', do not fill following citation
- ;; in current paragraph nor text before message body.
- (let ((body-start (save-excursion (message-goto-body))))
- (when body-start (setq beg (max body-start beg))))
- (when (save-excursion
- (re-search-forward
- (concat "^" message-cite-prefix-regexp) end t))
- (setq end (match-beginning 0))))
- ;; Fill paragraph, taking line breaks into account.
- (save-excursion
- (goto-char beg)
- (let ((cuts (list beg)))
- (while (re-search-forward "\\\\\\\\[ \t]*\n" end t)
- (when (eq 'line-break
- (org-element-type
- (save-excursion (backward-char)
- (org-element-context))))
- (push (point) cuts)))
- (dolist (c (delq end cuts))
- (fill-region-as-paragraph c end justify)
- (setq end c))))
- t)))
- ;; Contents of `comment-block' type elements should be
- ;; filled as plain text, but only if point is within block
- ;; markers.
- (comment-block
- (let* ((case-fold-search t)
- (beg (save-excursion
- (goto-char (org-element-property :begin element))
- (re-search-forward "^[ \t]*#\\+begin_comment" nil t)
- (forward-line)
- (point)))
- (end (save-excursion
- (goto-char (org-element-property :end element))
- (re-search-backward "^[ \t]*#\\+end_comment" nil t)
- (line-beginning-position))))
- (if (or (< (point) beg) (> (point) end)) t
- (fill-region-as-paragraph
- (save-excursion (end-of-line)
- (re-search-backward "^[ \t]*$" beg 'move)
- (line-beginning-position))
- (save-excursion (beginning-of-line)
- (re-search-forward "^[ \t]*$" end 'move)
- (line-beginning-position))
- justify))))
- ;; Fill comments.
- (comment
- (let ((begin (org-element-property :post-affiliated element))
- (end (org-element-property :end element)))
- (when (and (>= (point) begin) (<= (point) end))
- (let ((begin (save-excursion
- (end-of-line)
- (if (re-search-backward "^[ \t]*#[ \t]*$" begin t)
- (progn (forward-line) (point))
- begin)))
- (end (save-excursion
+ (goto-char beg)
+ (let ((cuts (list beg)))
+ (while (re-search-forward "\\\\\\\\[ \t]*\n" end t)
+ (when (eq 'line-break
+ (org-element-type
+ (save-excursion (backward-char)
+ (org-element-context))))
+ (push (point) cuts)))
+ (dolist (c (delq end cuts))
+ (fill-region-as-paragraph c end justify)
+ (setq end c))))
+ t)))
+ ;; Contents of `comment-block' type elements should be
+ ;; filled as plain text, but only if point is within block
+ ;; markers.
+ (comment-block
+ (let* ((case-fold-search t)
+ (beg (save-excursion
+ (goto-char (org-element-property :begin element))
+ (re-search-forward "^[ \t]*#\\+begin_comment" nil t)
+ (forward-line)
+ (point)))
+ (end (save-excursion
+ (goto-char (org-element-property :end element))
+ (re-search-backward "^[ \t]*#\\+end_comment" nil t)
+ (line-beginning-position))))
+ (if (or (< (point) beg) (> (point) end)) t
+ (fill-region-as-paragraph
+ (save-excursion (end-of-line)
+ (re-search-backward "^[ \t]*$" beg 'move)
+ (line-beginning-position))
+ (save-excursion (beginning-of-line)
+ (re-search-forward "^[ \t]*$" end 'move)
+ (line-beginning-position))
+ justify))))
+ ;; Fill comments.
+ (comment
+ (let ((begin (org-element-property :post-affiliated element))
+ (end (org-element-property :end element)))
+ (when (and (>= (point) begin) (<= (point) end))
+ (let ((begin (save-excursion
(end-of-line)
- (if (re-search-forward "^[ \t]*#[ \t]*$" end 'move)
- (1- (line-beginning-position))
- (skip-chars-backward " \r\t\n")
- (line-end-position)))))
- ;; Do not fill comments when at a blank line.
- (when (> end begin)
- (let ((fill-prefix
- (save-excursion
- (beginning-of-line)
- (looking-at "[ \t]*#")
- (let ((comment-prefix (match-string 0)))
- (goto-char (match-end 0))
- (if (looking-at adaptive-fill-regexp)
- (concat comment-prefix (match-string 0))
- (concat comment-prefix " "))))))
- (save-excursion
- (fill-region-as-paragraph begin end justify))))))
- t))
- ;; Ignore every other element.
- (otherwise t))))))
+ (if (re-search-backward "^[ \t]*#[ \t]*$" begin t)
+ (progn (forward-line) (point))
+ begin)))
+ (end (save-excursion
+ (end-of-line)
+ (if (re-search-forward "^[ \t]*#[ \t]*$" end 'move)
+ (1- (line-beginning-position))
+ (skip-chars-backward " \r\t\n")
+ (line-end-position)))))
+ ;; Do not fill comments when at a blank line.
+ (when (> end begin)
+ (let ((fill-prefix
+ (save-excursion
+ (beginning-of-line)
+ (looking-at "[ \t]*#")
+ (let ((comment-prefix (match-string 0)))
+ (goto-char (match-end 0))
+ (if (looking-at adaptive-fill-regexp)
+ (concat comment-prefix (match-string 0))
+ (concat comment-prefix " "))))))
+ (save-excursion
+ (fill-region-as-paragraph begin end justify))))))
+ t))
+ ;; Ignore every other element.
+ (otherwise t)))))
(defun org-auto-fill-function ()
"Auto-fill function."
--
2.3.3
^ permalink raw reply related [flat|nested] 13+ messages in thread
end of thread, other threads:[~2015-03-22 13:53 UTC | newest]
Thread overview: 13+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2015-02-27 10:12 autoloads not working correctly for org-table.el? Eric Abrahamsen
2015-02-27 10:35 ` Nicolas Richard
2015-02-27 17:28 ` Nicolas Goaziou
2015-02-28 0:39 ` Eric Abrahamsen
2015-03-04 9:28 ` Eric Abrahamsen
2015-03-04 15:23 ` Eric S Fraga
2015-03-05 1:36 ` Eric Abrahamsen
2015-03-10 2:15 ` [PATCH] " Eric Abrahamsen
2015-03-10 3:07 ` Eric Abrahamsen
2015-03-10 8:24 ` Nicolas Goaziou
2015-03-10 8:48 ` Eric Abrahamsen
2015-03-10 11:02 ` Nicolas Goaziou
2015-03-22 13:52 ` Eric Abrahamsen
Code repositories for project(s) associated with this public inbox
https://git.savannah.gnu.org/cgit/emacs/org-mode.git
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).