original_url
https://scripter.co/splitting-an-org-block-into-two/
url
https://scripter.co/splitting-an-org-block-into-two/
type
html
title
Splitting an Org block into two
description
I ventured out to start writing about a 100+ line Emacs Lisp snippet in my config, and then I thought - Wouldn’t it be nice if I can quickly split out that huge snippet into smaller Org Src blocks? And so this blog post happened.
safe
True
provider_url
https://scripter.co
provider_name
Scripter
provider_display
scripter.co
favicon_url
https://scripter.co/favicon-16x16.30da33df67e4ae4a58e94188d1d05862d27dbaaf5d2dd661b3b31810ea0005ee.png
language
en
published
1534974420000
offset
-14400000
authors
0
name
Kaushal Modi
url
None
lead
content
<div> <p>If I have a huge Org Src block, I'd like to split it into multiple Org Src blocks so that I can write my explanations in-between.</p> <p>So I'd like to quickly split up:</p> <p>into:</p> <p>&#9757; <em>Click for animation.</em></p> <h2>Action Plan <a href='https://scripter.co/splitting-an-org-block-into-two/#action-plan'>#</a> </h2> <ol> <li>Write a function to return <em>non-nil</em> if point is in <strong>any</strong> Org block - Not just 'src', 'example', 'export' or any of the inbuilt Org blocks.. but also any Org Special block like<code>#+begin_foo .. #+end_foo</code>.</li> <li>Write a function that does this imagined block splitting.</li> <li>Overload the <kbd>M-return</kbd> binding so that this block splitting function gets called only when the point is inside an Org block (detected using that first function).</li> </ol> <p> Thanks to the comment by reader <strong>Mankoff</strong>, I learnt about the <code>org-babel-demarcate-block</code> function (bound by default to <kbd>C-c C-v d</kbd> and <kbd>C-c C-v C-d</kbd>).</p> <p>This function varies from the solution in this post in at least two ways:</p> <ol> <li>It works only for Org Src blocks.</li> <li>It splits the block exactly at where the point is, whereas I would like to always split only at EOL or BOL.</li> </ol> <p>But I can see that <code>org-babel-demarcate-block</code> can cover most of the block splitting use cases.</p> <h2>Am I in an Org block? <a href='https://scripter.co/splitting-an-org-block-into-two/#org-in-any-block-p'>#</a> </h2> <p>Before venturing into writing this function, I looked at these existing ones, but none did what I exactly wanted:</p> <p></p><dt><code>org-in-src-block-p</code></dt><dd>Returns <em>non-nil</em> only if the point is in a<code>#+begin_src .. #+end_src</code> block; not when point is in any other Org block.</dd><dt><code>org-in-block-p</code></dt><dd>Returns <em>non-nil</em> only if the point is in one of the pre-defined block names passed as a list (<code>'('src' 'example' 'quote' ..)</code>). So this again won't work as I cannot pre-define all Org Special blocks.</dd> <p>So I define the below <code>modi/org-in-any-block-p</code> function that returns <em>non-nil</em> if the point is in-between any <code>#+begin_FOOBAR .. #+end_FOOBAR</code>. Thankfully, I was able to reuse a lot of logic from the <code>org-between-regexps-p</code> function ( <code>org-in-block-p</code> uses that function internally).</p> <ul> <li> <code>(case-fold-search t)</code> ensures that either <code>#+BEGIN_ ..</code> or <code>#+begin_ ..</code> match.</li> <li>The regular expression in <code>block-begin-re</code> matches with<code>'#+begin_src foo'</code> or <code>' #+begin_src foo'</code> or <code>'#+BEGIN_EXAMPLE'</code> or<code>'#+begin_FOOBAR'</code> or ..</li> <li>The <code>limit-up</code> and <code>limit-down</code> are set to the buffer locations of the previous and next Org headings. The following regexp searches are limited to happen in those bounds for better performance.</li> <li>The <code>block-end-re</code> is dynamically constructed based on the string matched using<code>block-begin-re</code>. This is so that if <code>'#+begin_quote'</code> is found initially, it matches the block ending with specifically<code>'#+end_quote'</code> and not something like <code>'#+end_src'</code>.</li> <li> <em>nil</em> is returned if the point is not between <code>#+begin_FOOBAR .. #+end_FOOBAR</code>.</li> </ul> <dl> <dt>Caveat</dt> <dd>I haven't gone extra lengths to support nested block cases, specifically where the point is outside the inner-most block, but still inside the outer block:</dd> </dl> <h2>If so, split the block <a href='https://scripter.co/splitting-an-org-block-into-two/#org-block-split'>#</a> </h2> <ol> <li> <p>If the point is anywhere on the line, but not at the beginning of the line (BOL),</p> <ul> <p>Go to the end of the line, and then split the block.</p> <p>So if the point is after the first <code>message</code> identifier, or at the end of that first <code>message</code> line:</p> <p>Split the block at the point <strong>after</strong> <code>(message 'one')</code> and move the point to between the split blocks:</p> </ul> </li> <li> <p>Otherwise (if point is at BOL),</p> <ul> <p>Split the block exactly at that point.</p> <p>So if the point is at the beginning of the second <code>message</code> line:</p> <p>Split the block at the point <strong>before</strong> <code>(message 'two')</code> and move the point to between the split blocks:</p> </ul> </li> </ol> <p>With the 'point in an Org block' detection working, I now needed the split to happen with these rules:</p> <ul> <li>The regexp for extracting <code>block-start</code> is the same as<code>block-begin-re</code> in <a href='https://scripter.co/splitting-an-org-block-into-two/#code-snippet--modi-org-in-any-block-p'>Code Snippet 1</a>, but with different sub-grouping.</li> <li>The <code>block-end</code> string is derived from sub-group 1 of <code>block-start</code> string - just replacing 'begin_' with 'end_'.</li> <li>And then based on if the point was initially at BOL (<code>at-bol</code>), the insertion of newlines and movement of point is done accordingly.</li> </ul> <p>So here's the code that follows that spec:</p> <h2>Now make <kbd>M-return</kbd> do that <a href='https://scripter.co/splitting-an-org-block-into-two/#M-return-split-block-dwim'>#</a> </h2> <p>With these two functions evaluated, <code>M-x modi/org-split-block</code> will work right away.</p> <p> But where's the fun in that?<br></p> <ul> <li>By default, <kbd>M-return</kbd> is used to either create new headings, or do other things like insert an item, wrap a region in table, etc. based on the context. See the doc-string of<code>org-meta-return</code> (function bound to this key by default) for more info.</li> <li>But it doesn't have a context for 'point in an Org block'. So it tries to create a heading when inside a block too, which doesn't make much sense.</li> <li>So fix that by adding that context.</li> </ul> <p>I needed to have the Org block splitting happen with an intuitive binding - like <kbd>M-return</kbd>.</p> <p>So I <strong>advise</strong> <code>org-meta-return</code> to call <code>modi/org-split-block</code> when the point is inside an Org block.</p> <em>You can tweak the precedence of this new context by moving the <code>((modi/org-in-any-block-p) #'modi/org-split-block)</code> form in that<code>cond</code> form.</em> <p>The advising function <code>modi/org-meta-return</code> is the same as the advised function <code>org-meta-return</code> (as of ), except that a new context<code>(modi/org-in-any-block-p)</code> is added.</p> <p>Now with the point in <strong>any</strong> Org block, <kbd>M-return</kbd> away!</p> <p>Look for the source of <code>modi/org-split-block</code> (and dependent functions) added to<a href='https://github.com/kaushalmodi/.emacs.d/blob/master/setup-files/setup-org.el'><code>setup-org.el</code></a> in my Emacs config.</p> </div>

If I have a huge Org Src block, I'd like to split it into multiple Org Src blocks so that I can write my explanations in-between.

So I'd like to quickly split up:

into:

Click for animation.

Action Plan #

  1. Write a function to return non-nil if point is in any Org block - Not just 'src', 'example', 'export' or any of the inbuilt Org blocks.. but also any Org Special block like#+begin_foo .. #+end_foo.
  2. Write a function that does this imagined block splitting.
  3. Overload the M-return binding so that this block splitting function gets called only when the point is inside an Org block (detected using that first function).

Thanks to the comment by reader Mankoff, I learnt about the org-babel-demarcate-block function (bound by default to C-c C-v d and C-c C-v C-d).

This function varies from the solution in this post in at least two ways:

  1. It works only for Org Src blocks.
  2. It splits the block exactly at where the point is, whereas I would like to always split only at EOL or BOL.

But I can see that org-babel-demarcate-block can cover most of the block splitting use cases.

Am I in an Org block? #

Before venturing into writing this function, I looked at these existing ones, but none did what I exactly wanted:

org-in-src-block-p
Returns non-nil only if the point is in a#+begin_src .. #+end_src block; not when point is in any other Org block.
org-in-block-p
Returns non-nil only if the point is in one of the pre-defined block names passed as a list ('('src' 'example' 'quote' ..)). So this again won't work as I cannot pre-define all Org Special blocks.

So I define the below modi/org-in-any-block-p function that returns non-nil if the point is in-between any #+begin_FOOBAR .. #+end_FOOBAR. Thankfully, I was able to reuse a lot of logic from the org-between-regexps-p function ( org-in-block-p uses that function internally).

  • (case-fold-search t) ensures that either #+BEGIN_ .. or #+begin_ .. match.
  • The regular expression in block-begin-re matches with'#+begin_src foo' or ' #+begin_src foo' or '#+BEGIN_EXAMPLE' or'#+begin_FOOBAR' or ..
  • The limit-up and limit-down are set to the buffer locations of the previous and next Org headings. The following regexp searches are limited to happen in those bounds for better performance.
  • The block-end-re is dynamically constructed based on the string matched usingblock-begin-re. This is so that if '#+begin_quote' is found initially, it matches the block ending with specifically'#+end_quote' and not something like '#+end_src'.
  • nil is returned if the point is not between #+begin_FOOBAR .. #+end_FOOBAR.
Caveat
I haven't gone extra lengths to support nested block cases, specifically where the point is outside the inner-most block, but still inside the outer block:

If so, split the block #

  1. If the point is anywhere on the line, but not at the beginning of the line (BOL),

      Go to the end of the line, and then split the block.

      So if the point is after the first message identifier, or at the end of that first message line:

      Split the block at the point after (message 'one') and move the point to between the split blocks:

  2. Otherwise (if point is at BOL),

      Split the block exactly at that point.

      So if the point is at the beginning of the second message line:

      Split the block at the point before (message 'two') and move the point to between the split blocks:

With the 'point in an Org block' detection working, I now needed the split to happen with these rules:

  • The regexp for extracting block-start is the same asblock-begin-re in Code Snippet 1, but with different sub-grouping.
  • The block-end string is derived from sub-group 1 of block-start string - just replacing 'begin_' with 'end_'.
  • And then based on if the point was initially at BOL (at-bol), the insertion of newlines and movement of point is done accordingly.

So here's the code that follows that spec:

Now make M-return do that #

With these two functions evaluated, M-x modi/org-split-block will work right away.

But where's the fun in that?

  • By default, M-return is used to either create new headings, or do other things like insert an item, wrap a region in table, etc. based on the context. See the doc-string oforg-meta-return (function bound to this key by default) for more info.
  • But it doesn't have a context for 'point in an Org block'. So it tries to create a heading when inside a block too, which doesn't make much sense.
  • So fix that by adding that context.

I needed to have the Org block splitting happen with an intuitive binding - like M-return.

So I advise org-meta-return to call modi/org-split-block when the point is inside an Org block.

You can tweak the precedence of this new context by moving the ((modi/org-in-any-block-p) #'modi/org-split-block) form in thatcond form.

The advising function modi/org-meta-return is the same as the advised function org-meta-return (as of ), except that a new context(modi/org-in-any-block-p) is added.

Now with the point in any Org block, M-return away!

Look for the source of modi/org-split-block (and dependent functions) added tosetup-org.el in my Emacs config.

images
0
thumbnail_url
https://scripter.co/splitting-an-org-block-into-two/org-split-block.png
width
859
height
520
entropy
0.575297330799
colors
0
color
[39, 39, 39]
weight
0.940673828125
1
color
[183, 68, 68]
weight
0.030517578125
2
color
[120, 61, 61]
weight
0.017578125
3
color
[130, 133, 133]
weight
0.0087890625
4
color
[145, 222, 222]
weight
0.00244140625
1
thumbnail_url
https://scripter.co/images/me--optimized.1cdf3eb11e9bf7be99d0292930537426d0ffff3f03c0a489a4c45034aebbd5be.jpg
width
400
height
400
entropy
None
colors
entities
keywords
0
name
src-block
score
0
1
name
org-block
score
0
2
name
split
score
0
3
name
advice
score
0
4
name
emacs
score
0
5
name
org
score
0
6
name
elisp
score
0
related
media

{
    &quot;provider_url&quot;: &quot;https://scripter.co&quot;, 
    &quot;authors&quot;: [
        {
            &quot;url&quot;: null, 
            &quot;name&quot;: &quot;Kaushal Modi&quot;
        }
    ], 
    &quot;provider_display&quot;: &quot;scripter.co&quot;, 
    &quot;related&quot;: [], 
    &quot;favicon_url&quot;: &quot;https://scripter.co/favicon-16x16.30da33df67e4ae4a58e94188d1d05862d27dbaaf5d2dd661b3b31810ea0005ee.png&quot;, 
    &quot;keywords&quot;: [
        {
            &quot;score&quot;: 0, 
            &quot;name&quot;: &quot;src-block&quot;
        }, 
        {
            &quot;score&quot;: 0, 
            &quot;name&quot;: &quot;org-block&quot;
        }, 
        {
            &quot;score&quot;: 0, 
            &quot;name&quot;: &quot;split&quot;
        }, 
        {
            &quot;score&quot;: 0, 
            &quot;name&quot;: &quot;advice&quot;
        }, 
        {
            &quot;score&quot;: 0, 
            &quot;name&quot;: &quot;emacs&quot;
        }, 
        {
            &quot;score&quot;: 0, 
            &quot;name&quot;: &quot;org&quot;
        }, 
        {
            &quot;score&quot;: 0, 
            &quot;name&quot;: &quot;elisp&quot;
        }
    ], 
    &quot;app_links&quot;: [], 
    &quot;original_url&quot;: &quot;https://scripter.co/splitting-an-org-block-into-two/&quot;, 
    &quot;media&quot;: {}, 
    &quot;content&quot;: &quot;&lt;div&gt;\n&lt;p&gt;If I have a huge Org Src block, I&#39;d like to split it into multiple Org Src blocks so that I can write my explanations in-between.&lt;/p&gt;\n&lt;p&gt;So I&#39;d like to quickly split up:&lt;/p&gt;\n&lt;p&gt;into:&lt;/p&gt;\n&lt;p&gt;&amp;#9757; &lt;em&gt;Click for animation.&lt;/em&gt;&lt;/p&gt;\n&lt;h2&gt;Action Plan &lt;a href=\&quot;https://scripter.co/splitting-an-org-block-into-two/#action-plan\&quot;&gt;#&lt;/a&gt;\n&lt;/h2&gt;\n&lt;ol&gt;\n\t&lt;li&gt;Write a function to return &lt;em&gt;non-nil&lt;/em&gt; if point is in &lt;strong&gt;any&lt;/strong&gt; Org block - Not just \&quot;src\&quot;, \&quot;example\&quot;, \&quot;export\&quot; or any of the inbuilt Org blocks.. but also any Org Special block like&lt;code&gt;#+begin_foo .. #+end_foo&lt;/code&gt;.&lt;/li&gt;\n\t&lt;li&gt;Write a function that does this imagined block splitting.&lt;/li&gt;\n\t&lt;li&gt;Overload the &lt;kbd&gt;M-return&lt;/kbd&gt; binding so that this block splitting function gets called only when the point is inside an Org block (detected using that first function).&lt;/li&gt;\n&lt;/ol&gt; \n&lt;p&gt; Thanks to the comment by reader &lt;strong&gt;Mankoff&lt;/strong&gt;, I learnt about the &lt;code&gt;org-babel-demarcate-block&lt;/code&gt; function (bound by default to &lt;kbd&gt;C-c C-v d&lt;/kbd&gt; and &lt;kbd&gt;C-c C-v C-d&lt;/kbd&gt;).&lt;/p&gt;\n&lt;p&gt;This function varies from the solution in this post in at least two ways:&lt;/p&gt;\n&lt;ol&gt;\n\t&lt;li&gt;It works only for Org Src blocks.&lt;/li&gt;\n\t&lt;li&gt;It splits the block exactly at where the point is, whereas I would like to always split only at EOL or BOL.&lt;/li&gt;\n&lt;/ol&gt; \n&lt;p&gt;But I can see that &lt;code&gt;org-babel-demarcate-block&lt;/code&gt; can cover most of the block splitting use cases.&lt;/p&gt;\n&lt;h2&gt;Am I in an Org block? &lt;a href=\&quot;https://scripter.co/splitting-an-org-block-into-two/#org-in-any-block-p\&quot;&gt;#&lt;/a&gt;\n&lt;/h2&gt;\n&lt;p&gt;Before venturing into writing this function, I looked at these existing ones, but none did what I exactly wanted:&lt;/p&gt;\n&lt;p&gt;&lt;/p&gt;&lt;dt&gt;&lt;code&gt;org-in-src-block-p&lt;/code&gt;&lt;/dt&gt;&lt;dd&gt;Returns &lt;em&gt;non-nil&lt;/em&gt; only if the point is in a&lt;code&gt;#+begin_src .. #+end_src&lt;/code&gt; block; not when point is in any other Org block.&lt;/dd&gt;&lt;dt&gt;&lt;code&gt;org-in-block-p&lt;/code&gt;&lt;/dt&gt;&lt;dd&gt;Returns &lt;em&gt;non-nil&lt;/em&gt; only if the point is in one of the pre-defined block names passed as a list (&lt;code&gt;&#39;(\&quot;src\&quot; \&quot;example\&quot; \&quot;quote\&quot; ..)&lt;/code&gt;). So this again won&#39;t work as I cannot pre-define all Org Special blocks.&lt;/dd&gt; \n&lt;p&gt;So I define the below &lt;code&gt;modi/org-in-any-block-p&lt;/code&gt; function that returns &lt;em&gt;non-nil&lt;/em&gt; if the point is in-between any &lt;code&gt;#+begin_FOOBAR .. #+end_FOOBAR&lt;/code&gt;. Thankfully, I was able to reuse a lot of logic from the &lt;code&gt;org-between-regexps-p&lt;/code&gt; function ( &lt;code&gt;org-in-block-p&lt;/code&gt; uses that function internally).&lt;/p&gt;\n&lt;ul&gt;\n\t&lt;li&gt;\n&lt;code&gt;(case-fold-search t)&lt;/code&gt; ensures that either &lt;code&gt;#+BEGIN_ ..&lt;/code&gt; or &lt;code&gt;#+begin_ ..&lt;/code&gt; match.&lt;/li&gt;\n\t&lt;li&gt;The regular expression in &lt;code&gt;block-begin-re&lt;/code&gt; matches with&lt;code&gt;\&quot;#+begin_src foo\&quot;&lt;/code&gt; or &lt;code&gt;\&quot; #+begin_src foo\&quot;&lt;/code&gt; or &lt;code&gt;\&quot;#+BEGIN_EXAMPLE\&quot;&lt;/code&gt; or&lt;code&gt;\&quot;#+begin_FOOBAR\&quot;&lt;/code&gt; or ..&lt;/li&gt;\n\t&lt;li&gt;The &lt;code&gt;limit-up&lt;/code&gt; and &lt;code&gt;limit-down&lt;/code&gt; are set to the buffer locations of the previous and next Org headings. The following regexp searches are limited to happen in those bounds for better performance.&lt;/li&gt;\n\t&lt;li&gt;The &lt;code&gt;block-end-re&lt;/code&gt; is dynamically constructed based on the string matched using&lt;code&gt;block-begin-re&lt;/code&gt;. This is so that if &lt;code&gt;\&quot;#+begin_quote\&quot;&lt;/code&gt; is found initially, it matches the block ending with specifically&lt;code&gt;\&quot;#+end_quote\&quot;&lt;/code&gt; and not something like &lt;code&gt;\&quot;#+end_src\&quot;&lt;/code&gt;.&lt;/li&gt;\n\t&lt;li&gt;\n&lt;em&gt;nil&lt;/em&gt; is returned if the point is not between &lt;code&gt;#+begin_FOOBAR .. #+end_FOOBAR&lt;/code&gt;.&lt;/li&gt;\n&lt;/ul&gt;\n&lt;dl&gt;\n&lt;dt&gt;Caveat&lt;/dt&gt;\n&lt;dd&gt;I haven&#39;t gone extra lengths to support nested block cases, specifically where the point is outside the inner-most block, but still inside the outer block:&lt;/dd&gt;\n&lt;/dl&gt; &lt;h2&gt;If so, split the block &lt;a href=\&quot;https://scripter.co/splitting-an-org-block-into-two/#org-block-split\&quot;&gt;#&lt;/a&gt;\n&lt;/h2&gt;\n&lt;ol&gt;\n\t&lt;li&gt;\n&lt;p&gt;If the point is anywhere on the line, but not at the beginning of the line (BOL),&lt;/p&gt;\n&lt;ul&gt;\n&lt;p&gt;Go to the end of the line, and then split the block.&lt;/p&gt;\n&lt;p&gt;So if the point is after the first &lt;code&gt;message&lt;/code&gt; identifier, or at the end of that first &lt;code&gt;message&lt;/code&gt; line:&lt;/p&gt;\n&lt;p&gt;Split the block at the point &lt;strong&gt;after&lt;/strong&gt; &lt;code&gt;(message \&quot;one\&quot;)&lt;/code&gt; and move the point to between the split blocks:&lt;/p&gt; \n&lt;/ul&gt;\n&lt;/li&gt;\n\t&lt;li&gt;\n&lt;p&gt;Otherwise (if point is at BOL),&lt;/p&gt;\n&lt;ul&gt;\n&lt;p&gt;Split the block exactly at that point.&lt;/p&gt;\n&lt;p&gt;So if the point is at the beginning of the second &lt;code&gt;message&lt;/code&gt; line:&lt;/p&gt;\n&lt;p&gt;Split the block at the point &lt;strong&gt;before&lt;/strong&gt; &lt;code&gt;(message \&quot;two\&quot;)&lt;/code&gt; and move the point to between the split blocks:&lt;/p&gt; \n&lt;/ul&gt;\n&lt;/li&gt;\n&lt;/ol&gt; \n&lt;p&gt;With the \&quot;point in an Org block\&quot; detection working, I now needed the split to happen with these rules:&lt;/p&gt;\n&lt;ul&gt;\n\t&lt;li&gt;The regexp for extracting &lt;code&gt;block-start&lt;/code&gt; is the same as&lt;code&gt;block-begin-re&lt;/code&gt; in &lt;a href=\&quot;https://scripter.co/splitting-an-org-block-into-two/#code-snippet--modi-org-in-any-block-p\&quot;&gt;Code Snippet 1&lt;/a&gt;, but with different sub-grouping.&lt;/li&gt;\n\t&lt;li&gt;The &lt;code&gt;block-end&lt;/code&gt; string is derived from sub-group 1 of &lt;code&gt;block-start&lt;/code&gt; string - just replacing \&quot;begin_\&quot; with \&quot;end_\&quot;.&lt;/li&gt;\n\t&lt;li&gt;And then based on if the point was initially at BOL (&lt;code&gt;at-bol&lt;/code&gt;), the insertion of newlines and movement of point is done accordingly.&lt;/li&gt;\n&lt;/ul&gt; \n&lt;p&gt;So here&#39;s the code that follows that spec:&lt;/p&gt;\n&lt;h2&gt;Now make &lt;kbd&gt;M-return&lt;/kbd&gt; do that &lt;a href=\&quot;https://scripter.co/splitting-an-org-block-into-two/#M-return-split-block-dwim\&quot;&gt;#&lt;/a&gt;\n&lt;/h2&gt;\n&lt;p&gt;With these two functions evaluated, &lt;code&gt;M-x modi/org-split-block&lt;/code&gt; will work right away.&lt;/p&gt;\n&lt;p&gt;    But where&#39;s the fun in that?&lt;br&gt;&lt;/p&gt;\n&lt;ul&gt;\n\t&lt;li&gt;By default, &lt;kbd&gt;M-return&lt;/kbd&gt; is used to either create new headings, or do other things like insert an item, wrap a region in table, etc. based on the context. See the doc-string of&lt;code&gt;org-meta-return&lt;/code&gt; (function bound to this key by default) for more info.&lt;/li&gt;\n\t&lt;li&gt;But it doesn&#39;t have a context for \&quot;point in an Org block\&quot;. So it tries to create a heading when inside a block too, which doesn&#39;t make much sense.&lt;/li&gt;\n\t&lt;li&gt;So fix that by adding that context.&lt;/li&gt;\n&lt;/ul&gt; \n&lt;p&gt;I needed to have the Org block splitting happen with an intuitive binding - like &lt;kbd&gt;M-return&lt;/kbd&gt;.&lt;/p&gt;\n&lt;p&gt;So I &lt;strong&gt;advise&lt;/strong&gt; &lt;code&gt;org-meta-return&lt;/code&gt; to call &lt;code&gt;modi/org-split-block&lt;/code&gt; when the point is inside an Org block.&lt;/p&gt;\n&lt;em&gt;You can tweak the precedence of this new context by moving the &lt;code&gt;((modi/org-in-any-block-p) #&#39;modi/org-split-block)&lt;/code&gt; form in that&lt;code&gt;cond&lt;/code&gt; form.&lt;/em&gt; &lt;p&gt;The advising function &lt;code&gt;modi/org-meta-return&lt;/code&gt; is the same as the advised function &lt;code&gt;org-meta-return&lt;/code&gt; (as of ), except that a new context&lt;code&gt;(modi/org-in-any-block-p)&lt;/code&gt; is added.&lt;/p&gt;\n&lt;p&gt;Now with the point in &lt;strong&gt;any&lt;/strong&gt; Org block, &lt;kbd&gt;M-return&lt;/kbd&gt; away!&lt;/p&gt;\n&lt;p&gt;Look for the source of &lt;code&gt;modi/org-split-block&lt;/code&gt; (and dependent functions) added to&lt;a href=\&quot;https://github.com/kaushalmodi/.emacs.d/blob/master/setup-files/setup-org.el\&quot;&gt;&lt;code&gt;setup-org.el&lt;/code&gt;&lt;/a&gt; in my Emacs config.&lt;/p&gt;\n&lt;/div&gt;&quot;, 
    &quot;entities&quot;: [], 
    &quot;provider_name&quot;: &quot;Scripter&quot;, 
    &quot;type&quot;: &quot;html&quot;, 
    &quot;description&quot;: &quot;I ventured out to start writing about a 100+ line Emacs Lisp snippet in my config, and then I thought - Wouldn&amp;rsquo;t it be nice if I can quickly split out that huge snippet into smaller Org Src blocks? And so this blog post happened.&quot;, 
    &quot;embeds&quot;: [], 
    &quot;images&quot;: [
        {
            &quot;width&quot;: 859, 
            &quot;url&quot;: &quot;https://scripter.co/splitting-an-org-block-into-two/org-split-block.png&quot;, 
            &quot;height&quot;: 520, 
            &quot;caption&quot;: null, 
            &quot;colors&quot;: [
                {
                    &quot;color&quot;: [
                        39, 
                        39, 
                        39
                    ], 
                    &quot;weight&quot;: 0.940673828125
                }, 
                {
                    &quot;color&quot;: [
                        183, 
                        81, 
                        68
                    ], 
                    &quot;weight&quot;: 0.030517578125
                }, 
                {
                    &quot;color&quot;: [
                        120, 
                        68, 
                        61
                    ], 
                    &quot;weight&quot;: 0.017578125
                }, 
                {
                    &quot;color&quot;: [
                        130, 
                        134, 
                        133
                    ], 
                    &quot;weight&quot;: 0.0087890625
                }, 
                {
                    &quot;color&quot;: [
                        145, 
                        209, 
                        222
                    ], 
                    &quot;weight&quot;: 0.00244140625
                }
            ], 
            &quot;entropy&quot;: 0.575297330799, 
            &quot;size&quot;: 69082
        }, 
        {
            &quot;url&quot;: &quot;https://scripter.co/images/me--optimized.1cdf3eb11e9bf7be99d0292930537426d0ffff3f03c0a489a4c45034aebbd5be.jpg&quot;, 
            &quot;width&quot;: 400, 
            &quot;height&quot;: 400, 
            &quot;caption&quot;: null, 
            &quot;size&quot;: 14014
        }
    ], 
    &quot;safe&quot;: true, 
    &quot;offset&quot;: -14400000, 
    &quot;cache_age&quot;: 86400, 
    &quot;lead&quot;: null, 
    &quot;language&quot;: &quot;en&quot;, 
    &quot;url&quot;: &quot;https://scripter.co/splitting-an-org-block-into-two/&quot;, 
    &quot;title&quot;: &quot;Splitting an Org block into two&quot;, 
    &quot;favicon_colors&quot;: [
        {
            &quot;color&quot;: [
                0, 
                0, 
                0
            ], 
            &quot;weight&quot;: 0.000244140625
        }
    ], 
    &quot;published&quot;: 1534974420000
}


{
    &quot;provider_url&quot;: &quot;https://scripter.co&quot;, 
    &quot;authors&quot;: [
        {
            &quot;url&quot;: null, 
            &quot;name&quot;: &quot;Kaushal Modi&quot;
        }
    ], 
    &quot;provider_display&quot;: &quot;scripter.co&quot;, 
    &quot;related&quot;: [], 
    &quot;favicon_url&quot;: &quot;https://scripter.co/favicon-16x16.30da33df67e4ae4a58e94188d1d05862d27dbaaf5d2dd661b3b31810ea0005ee.png&quot;, 
    &quot;keywords&quot;: [
        {
            &quot;score&quot;: 0, 
            &quot;name&quot;: &quot;src-block&quot;
        }, 
        {
            &quot;score&quot;: 0, 
            &quot;name&quot;: &quot;org-block&quot;
        }, 
        {
            &quot;score&quot;: 0, 
            &quot;name&quot;: &quot;split&quot;
        }, 
        {
            &quot;score&quot;: 0, 
            &quot;name&quot;: &quot;advice&quot;
        }, 
        {
            &quot;score&quot;: 0, 
            &quot;name&quot;: &quot;emacs&quot;
        }, 
        {
            &quot;score&quot;: 0, 
            &quot;name&quot;: &quot;org&quot;
        }, 
        {
            &quot;score&quot;: 0, 
            &quot;name&quot;: &quot;elisp&quot;
        }
    ], 
    &quot;app_links&quot;: [], 
    &quot;original_url&quot;: &quot;https://scripter.co/splitting-an-org-block-into-two/&quot;, 
    &quot;media&quot;: {}, 
    &quot;content&quot;: &quot;&lt;div&gt;\n&lt;p&gt;If I have a huge Org Src block, I&#39;d like to split it into multiple Org Src blocks so that I can write my explanations in-between.&lt;/p&gt;\n&lt;p&gt;So I&#39;d like to quickly split up:&lt;/p&gt;\n&lt;p&gt;into:&lt;/p&gt;\n&lt;p&gt;&amp;#9757; &lt;em&gt;Click for animation.&lt;/em&gt;&lt;/p&gt;\n&lt;h2&gt;Action Plan &lt;a href=\&quot;https://scripter.co/splitting-an-org-block-into-two/#action-plan\&quot;&gt;#&lt;/a&gt;\n&lt;/h2&gt;\n&lt;ol&gt;\n\t&lt;li&gt;Write a function to return &lt;em&gt;non-nil&lt;/em&gt; if point is in &lt;strong&gt;any&lt;/strong&gt; Org block - Not just \&quot;src\&quot;, \&quot;example\&quot;, \&quot;export\&quot; or any of the inbuilt Org blocks.. but also any Org Special block like&lt;code&gt;#+begin_foo .. #+end_foo&lt;/code&gt;.&lt;/li&gt;\n\t&lt;li&gt;Write a function that does this imagined block splitting.&lt;/li&gt;\n\t&lt;li&gt;Overload the &lt;kbd&gt;M-return&lt;/kbd&gt; binding so that this block splitting function gets called only when the point is inside an Org block (detected using that first function).&lt;/li&gt;\n&lt;/ol&gt; \n&lt;p&gt; Thanks to the comment by reader &lt;strong&gt;Mankoff&lt;/strong&gt;, I learnt about the &lt;code&gt;org-babel-demarcate-block&lt;/code&gt; function (bound by default to &lt;kbd&gt;C-c C-v d&lt;/kbd&gt; and &lt;kbd&gt;C-c C-v C-d&lt;/kbd&gt;).&lt;/p&gt;\n&lt;p&gt;This function varies from the solution in this post in at least two ways:&lt;/p&gt;\n&lt;ol&gt;\n\t&lt;li&gt;It works only for Org Src blocks.&lt;/li&gt;\n\t&lt;li&gt;It splits the block exactly at where the point is, whereas I would like to always split only at EOL or BOL.&lt;/li&gt;\n&lt;/ol&gt; \n&lt;p&gt;But I can see that &lt;code&gt;org-babel-demarcate-block&lt;/code&gt; can cover most of the block splitting use cases.&lt;/p&gt;\n&lt;h2&gt;Am I in an Org block? &lt;a href=\&quot;https://scripter.co/splitting-an-org-block-into-two/#org-in-any-block-p\&quot;&gt;#&lt;/a&gt;\n&lt;/h2&gt;\n&lt;p&gt;Before venturing into writing this function, I looked at these existing ones, but none did what I exactly wanted:&lt;/p&gt;\n&lt;p&gt;&lt;/p&gt;&lt;dt&gt;&lt;code&gt;org-in-src-block-p&lt;/code&gt;&lt;/dt&gt;&lt;dd&gt;Returns &lt;em&gt;non-nil&lt;/em&gt; only if the point is in a&lt;code&gt;#+begin_src .. #+end_src&lt;/code&gt; block; not when point is in any other Org block.&lt;/dd&gt;&lt;dt&gt;&lt;code&gt;org-in-block-p&lt;/code&gt;&lt;/dt&gt;&lt;dd&gt;Returns &lt;em&gt;non-nil&lt;/em&gt; only if the point is in one of the pre-defined block names passed as a list (&lt;code&gt;&#39;(\&quot;src\&quot; \&quot;example\&quot; \&quot;quote\&quot; ..)&lt;/code&gt;). So this again won&#39;t work as I cannot pre-define all Org Special blocks.&lt;/dd&gt; \n&lt;p&gt;So I define the below &lt;code&gt;modi/org-in-any-block-p&lt;/code&gt; function that returns &lt;em&gt;non-nil&lt;/em&gt; if the point is in-between any &lt;code&gt;#+begin_FOOBAR .. #+end_FOOBAR&lt;/code&gt;. Thankfully, I was able to reuse a lot of logic from the &lt;code&gt;org-between-regexps-p&lt;/code&gt; function ( &lt;code&gt;org-in-block-p&lt;/code&gt; uses that function internally).&lt;/p&gt;\n&lt;ul&gt;\n\t&lt;li&gt;\n&lt;code&gt;(case-fold-search t)&lt;/code&gt; ensures that either &lt;code&gt;#+BEGIN_ ..&lt;/code&gt; or &lt;code&gt;#+begin_ ..&lt;/code&gt; match.&lt;/li&gt;\n\t&lt;li&gt;The regular expression in &lt;code&gt;block-begin-re&lt;/code&gt; matches with&lt;code&gt;\&quot;#+begin_src foo\&quot;&lt;/code&gt; or &lt;code&gt;\&quot; #+begin_src foo\&quot;&lt;/code&gt; or &lt;code&gt;\&quot;#+BEGIN_EXAMPLE\&quot;&lt;/code&gt; or&lt;code&gt;\&quot;#+begin_FOOBAR\&quot;&lt;/code&gt; or ..&lt;/li&gt;\n\t&lt;li&gt;The &lt;code&gt;limit-up&lt;/code&gt; and &lt;code&gt;limit-down&lt;/code&gt; are set to the buffer locations of the previous and next Org headings. The following regexp searches are limited to happen in those bounds for better performance.&lt;/li&gt;\n\t&lt;li&gt;The &lt;code&gt;block-end-re&lt;/code&gt; is dynamically constructed based on the string matched using&lt;code&gt;block-begin-re&lt;/code&gt;. This is so that if &lt;code&gt;\&quot;#+begin_quote\&quot;&lt;/code&gt; is found initially, it matches the block ending with specifically&lt;code&gt;\&quot;#+end_quote\&quot;&lt;/code&gt; and not something like &lt;code&gt;\&quot;#+end_src\&quot;&lt;/code&gt;.&lt;/li&gt;\n\t&lt;li&gt;\n&lt;em&gt;nil&lt;/em&gt; is returned if the point is not between &lt;code&gt;#+begin_FOOBAR .. #+end_FOOBAR&lt;/code&gt;.&lt;/li&gt;\n&lt;/ul&gt;\n&lt;dl&gt;\n&lt;dt&gt;Caveat&lt;/dt&gt;\n&lt;dd&gt;I haven&#39;t gone extra lengths to support nested block cases, specifically where the point is outside the inner-most block, but still inside the outer block:&lt;/dd&gt;\n&lt;/dl&gt; &lt;h2&gt;If so, split the block &lt;a href=\&quot;https://scripter.co/splitting-an-org-block-into-two/#org-block-split\&quot;&gt;#&lt;/a&gt;\n&lt;/h2&gt;\n&lt;ol&gt;\n\t&lt;li&gt;\n&lt;p&gt;If the point is anywhere on the line, but not at the beginning of the line (BOL),&lt;/p&gt;\n&lt;ul&gt;\n&lt;p&gt;Go to the end of the line, and then split the block.&lt;/p&gt;\n&lt;p&gt;So if the point is after the first &lt;code&gt;message&lt;/code&gt; identifier, or at the end of that first &lt;code&gt;message&lt;/code&gt; line:&lt;/p&gt;\n&lt;p&gt;Split the block at the point &lt;strong&gt;after&lt;/strong&gt; &lt;code&gt;(message \&quot;one\&quot;)&lt;/code&gt; and move the point to between the split blocks:&lt;/p&gt; \n&lt;/ul&gt;\n&lt;/li&gt;\n\t&lt;li&gt;\n&lt;p&gt;Otherwise (if point is at BOL),&lt;/p&gt;\n&lt;ul&gt;\n&lt;p&gt;Split the block exactly at that point.&lt;/p&gt;\n&lt;p&gt;So if the point is at the beginning of the second &lt;code&gt;message&lt;/code&gt; line:&lt;/p&gt;\n&lt;p&gt;Split the block at the point &lt;strong&gt;before&lt;/strong&gt; &lt;code&gt;(message \&quot;two\&quot;)&lt;/code&gt; and move the point to between the split blocks:&lt;/p&gt; \n&lt;/ul&gt;\n&lt;/li&gt;\n&lt;/ol&gt; \n&lt;p&gt;With the \&quot;point in an Org block\&quot; detection working, I now needed the split to happen with these rules:&lt;/p&gt;\n&lt;ul&gt;\n\t&lt;li&gt;The regexp for extracting &lt;code&gt;block-start&lt;/code&gt; is the same as&lt;code&gt;block-begin-re&lt;/code&gt; in &lt;a href=\&quot;https://scripter.co/splitting-an-org-block-into-two/#code-snippet--modi-org-in-any-block-p\&quot;&gt;Code Snippet 1&lt;/a&gt;, but with different sub-grouping.&lt;/li&gt;\n\t&lt;li&gt;The &lt;code&gt;block-end&lt;/code&gt; string is derived from sub-group 1 of &lt;code&gt;block-start&lt;/code&gt; string - just replacing \&quot;begin_\&quot; with \&quot;end_\&quot;.&lt;/li&gt;\n\t&lt;li&gt;And then based on if the point was initially at BOL (&lt;code&gt;at-bol&lt;/code&gt;), the insertion of newlines and movement of point is done accordingly.&lt;/li&gt;\n&lt;/ul&gt; \n&lt;p&gt;So here&#39;s the code that follows that spec:&lt;/p&gt;\n&lt;h2&gt;Now make &lt;kbd&gt;M-return&lt;/kbd&gt; do that &lt;a href=\&quot;https://scripter.co/splitting-an-org-block-into-two/#M-return-split-block-dwim\&quot;&gt;#&lt;/a&gt;\n&lt;/h2&gt;\n&lt;p&gt;With these two functions evaluated, &lt;code&gt;M-x modi/org-split-block&lt;/code&gt; will work right away.&lt;/p&gt;\n&lt;p&gt;    But where&#39;s the fun in that?&lt;br&gt;&lt;/p&gt;\n&lt;ul&gt;\n\t&lt;li&gt;By default, &lt;kbd&gt;M-return&lt;/kbd&gt; is used to either create new headings, or do other things like insert an item, wrap a region in table, etc. based on the context. See the doc-string of&lt;code&gt;org-meta-return&lt;/code&gt; (function bound to this key by default) for more info.&lt;/li&gt;\n\t&lt;li&gt;But it doesn&#39;t have a context for \&quot;point in an Org block\&quot;. So it tries to create a heading when inside a block too, which doesn&#39;t make much sense.&lt;/li&gt;\n\t&lt;li&gt;So fix that by adding that context.&lt;/li&gt;\n&lt;/ul&gt; \n&lt;p&gt;I needed to have the Org block splitting happen with an intuitive binding - like &lt;kbd&gt;M-return&lt;/kbd&gt;.&lt;/p&gt;\n&lt;p&gt;So I &lt;strong&gt;advise&lt;/strong&gt; &lt;code&gt;org-meta-return&lt;/code&gt; to call &lt;code&gt;modi/org-split-block&lt;/code&gt; when the point is inside an Org block.&lt;/p&gt;\n&lt;em&gt;You can tweak the precedence of this new context by moving the &lt;code&gt;((modi/org-in-any-block-p) #&#39;modi/org-split-block)&lt;/code&gt; form in that&lt;code&gt;cond&lt;/code&gt; form.&lt;/em&gt; &lt;p&gt;The advising function &lt;code&gt;modi/org-meta-return&lt;/code&gt; is the same as the advised function &lt;code&gt;org-meta-return&lt;/code&gt; (as of ), except that a new context&lt;code&gt;(modi/org-in-any-block-p)&lt;/code&gt; is added.&lt;/p&gt;\n&lt;p&gt;Now with the point in &lt;strong&gt;any&lt;/strong&gt; Org block, &lt;kbd&gt;M-return&lt;/kbd&gt; away!&lt;/p&gt;\n&lt;p&gt;Look for the source of &lt;code&gt;modi/org-split-block&lt;/code&gt; (and dependent functions) added to&lt;a href=\&quot;https://github.com/kaushalmodi/.emacs.d/blob/master/setup-files/setup-org.el\&quot;&gt;&lt;code&gt;setup-org.el&lt;/code&gt;&lt;/a&gt; in my Emacs config.&lt;/p&gt;\n&lt;/div&gt;&quot;, 
    &quot;entities&quot;: [], 
    &quot;provider_name&quot;: &quot;Scripter&quot;, 
    &quot;type&quot;: &quot;html&quot;, 
    &quot;description&quot;: &quot;I ventured out to start writing about a 100+ line Emacs Lisp snippet in my config, and then I thought - Wouldn&amp;rsquo;t it be nice if I can quickly split out that huge snippet into smaller Org Src blocks? And so this blog post happened.&quot;, 
    &quot;embeds&quot;: [], 
    &quot;images&quot;: [
        {
            &quot;width&quot;: 859, 
            &quot;url&quot;: &quot;https://scripter.co/splitting-an-org-block-into-two/org-split-block.png&quot;, 
            &quot;height&quot;: 520, 
            &quot;caption&quot;: null, 
            &quot;colors&quot;: [
                {
                    &quot;color&quot;: [
                        39, 
                        39, 
                        39
                    ], 
                    &quot;weight&quot;: 0.940673828125
                }, 
                {
                    &quot;color&quot;: [
                        183, 
                        81, 
                        68
                    ], 
                    &quot;weight&quot;: 0.030517578125
                }, 
                {
                    &quot;color&quot;: [
                        120, 
                        68, 
                        61
                    ], 
                    &quot;weight&quot;: 0.017578125
                }, 
                {
                    &quot;color&quot;: [
                        130, 
                        134, 
                        133
                    ], 
                    &quot;weight&quot;: 0.0087890625
                }, 
                {
                    &quot;color&quot;: [
                        145, 
                        209, 
                        222
                    ], 
                    &quot;weight&quot;: 0.00244140625
                }
            ], 
            &quot;entropy&quot;: 0.575297330799, 
            &quot;size&quot;: 69082
        }, 
        {
            &quot;url&quot;: &quot;https://scripter.co/images/me--optimized.1cdf3eb11e9bf7be99d0292930537426d0ffff3f03c0a489a4c45034aebbd5be.jpg&quot;, 
            &quot;width&quot;: 400, 
            &quot;height&quot;: 400, 
            &quot;caption&quot;: null, 
            &quot;size&quot;: 14014
        }
    ], 
    &quot;safe&quot;: true, 
    &quot;offset&quot;: -14400000, 
    &quot;cache_age&quot;: 86400, 
    &quot;lead&quot;: null, 
    &quot;language&quot;: &quot;en&quot;, 
    &quot;url&quot;: &quot;https://scripter.co/splitting-an-org-block-into-two/&quot;, 
    &quot;title&quot;: &quot;Splitting an Org block into two&quot;, 
    &quot;favicon_colors&quot;: [
        {
            &quot;color&quot;: [
                0, 
                0, 
                0
            ], 
            &quot;weight&quot;: 0.000244140625
        }
    ], 
    &quot;published&quot;: 1534974420000
}