qemacs-commit
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Qemacs-commit] qemacs orgmode.c


From: Charlie Gordon
Subject: [Qemacs-commit] qemacs orgmode.c
Date: Fri, 10 Jan 2014 14:00:09 +0000

CVSROOT:        /sources/qemacs
Module name:    qemacs
Changes by:     Charlie Gordon <chqrlie>        14/01/10 14:00:09

Modified files:
        .              : orgmode.c 

Log message:
        improve org mode, add new functions
        
        * simplify org_next/prev_heading:
          - always return valid offset
          - level = 0 if not heading found
          - pointer to level can be NULL
        * add new functions:
          - do_outline_next_vsible_heading      (C-c C-n)
          - do_outline_previous_vsible_heading  (C-c C-p)
          - do_outline_up_heading               (C-c C-u)
          - do_org_backward_same_level          (C-c C-b)
          - do_org_forward_same_level           (C-c C-f)
          - do_org_goto                         (C-c C-j)
          - org-insert-heading-respect-content  (C-enter)
          - org-insert-todo-heading-respect-content
        * add flags in do_org_insert_heading

CVSWeb URLs:
http://cvs.savannah.gnu.org/viewcvs/qemacs/orgmode.c?cvsroot=qemacs&r1=1.3&r2=1.4

Patches:
Index: orgmode.c
===================================================================
RCS file: /sources/qemacs/qemacs/orgmode.c,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -b -r1.3 -r1.4
--- orgmode.c   10 Jan 2014 01:25:14 -0000      1.3
+++ orgmode.c   10 Jan 2014 14:00:08 -0000      1.4
@@ -315,6 +315,13 @@
     *statep = colstate;
 }
 
+static int org_is_header_line(EditState *s, int offset)
+{
+    /* Check if line starts with '*' */
+    /* XXX: should ignore blocks using colorstate */
+    return eb_nextc(s->b, eb_goto_bol(s->b, offset), &offset) == '*';
+}
+
 static int org_find_heading(EditState *s, int offset, int *level)
 {
     int offset1, nb, c;
@@ -344,19 +351,22 @@
 
     for (;;) {
         offset = eb_next_line(s->b, offset);
-        if (offset >= s->b->total_size)
+        if (offset >= s->b->total_size) {
+            nb = 0;
             break;
+        }
         /* XXX: should ignore blocks using colorstate */
         if (eb_nextc(s->b, offset, &offset1) == '*') {
             for (nb = 1; (c = eb_nextc(s->b, offset1, &offset1)) == '*'; nb++)
                 continue;
             if (c == ' ' && nb <= target) {
-                *level = nb;
-                return offset;
+                break;
             }
         }
     }
-    return -1;
+    if (level)
+        *level = nb;
+    return offset;
 }
 
 static int org_prev_heading(EditState *s, int offset, int target, int *level)
@@ -364,20 +374,111 @@
     int offset1, nb, c;
 
     for (;;) {
-        if (offset == 0)
+        if (offset == 0) {
+            nb = 0;
             break;
+        }
         offset = eb_prev_line(s->b, offset);
         /* XXX: should ignore blocks using colorstate */
         if (eb_nextc(s->b, offset, &offset1) == '*') {
             for (nb = 1; (c = eb_nextc(s->b, offset1, &offset1)) == '*'; nb++)
                 continue;
             if (c == ' ' && nb <= target) {
+                break;
+            }
+        }
+    }
+    if (level)
                 *level = nb;
                 return offset;
+}
+
+static void do_outline_next_vsible_heading(EditState *s)
+{
+    s->offset = org_next_heading(s, s->offset, MAX_LEVEL, NULL);
+}
+
+static void do_outline_previous_vsible_heading(EditState *s)
+{
+    s->offset = org_prev_heading(s, s->offset, MAX_LEVEL, NULL);
+}
+
+static void do_outline_up_heading(EditState *s)
+{
+    int offset, level;
+
+    offset = org_find_heading(s, s->offset, &level);
+    if (offset < 0) {
+        put_status(s, "before first heading");
+        return;
+    }
+    if (level <= 1) {
+        put_status(s, "already at top level of the outline");
+        return;
+    }
+
+    s->offset = org_prev_heading(s, offset, level - 1, &level);
+}
+
+static void do_org_backward_same_level(EditState *s)
+{
+    int offset, level, level1;
+
+    offset = org_find_heading(s, s->offset, &level);
+    if (offset < 0) {
+        put_status(s, "before first heading");
+        return;
             }
+    offset = org_prev_heading(s, offset, level, &level1);
+    if (level1 != level) {
+        put_status(s, "no previous same-level heading");
+        return;
         }
+    s->offset = offset;
+}
+
+static void do_org_forward_same_level(EditState *s)
+{
+    int offset, level, level1;
+
+    offset = org_find_heading(s, s->offset, &level);
+    if (offset < 0) {
+        put_status(s, "before first heading");
+        return;
     }
-    return -1;
+    offset = org_next_heading(s, offset, level, &level1);
+    if (level1 != level) {
+        put_status(s, "no following same-level heading");
+        return;
+    }
+    s->offset = offset;
+}
+
+static void do_org_goto(EditState *s, const char *dest)
+{
+    int offset, level, level1, nb;
+    const char *p = dest;
+
+    /* XXX: Should pop up a window with numbered outline index
+     * and let the user select the target interactively.
+     */
+
+    /* Jump to numbered destination. */
+    for (offset = 0, level = 0; qe_isdigit(*p); ) {
+        nb = strtol(p, (char **)&p, 10);
+        if (*p == '.')
+            p++;
+        level++;
+        for (; nb > 0; nb--) {
+            offset = org_next_heading(s, offset, level, &level1);
+            if (level != level1) {
+                put_status(s, "heading not found");
+                return;
+            }
+        }
+    }
+    if (level)
+        s->offset = offset;
 }
 
 static void do_org_todo(EditState *s)
@@ -413,14 +514,7 @@
     }
 }
 
-static int org_is_header_line(EditState *s, int offset)
-{
-    /* Check if line starts with '*' */
-    /* XXX: should ignore blocks using colorstate */
-    return eb_nextc(s->b, eb_goto_bol(s->b, offset), &offset) == '*';
-}
-
-static void do_org_insert_heading(EditState *s)
+static void do_org_insert_heading(EditState *s, int flags)
 {
     int offset, offset0, offset1, level = 1;
 
@@ -435,6 +529,12 @@
      * if in the middle of a heading line, split the heading,
      * otherwise, make the current line a heading line at current level.
      */
+    if (flags & 2) {
+        /* respect-content: insert heading at end of subtree */
+        offset = org_next_heading(s, offset, level, NULL);
+        eb_insert_uchar(s->b, offset, '\n');
+        eb_insert_uchar(s->b, offset, '\n');
+    } else
     if (s->offset <= offset + level + 1) {
         eb_insert_uchar(s->b, offset, '\n');
     } else
@@ -452,15 +552,10 @@
     }
     offset += eb_insert_uchar(s->b, offset, ' ');
     s->offset = eb_goto_eol(s->b, offset);
-}
-
-static void do_org_insert_todo_heading(EditState *s)
-{
-    if (check_read_only(s))
-        return;
-
-    do_org_insert_heading(s);
+    if (flags & 1) {
+        /* insert-todo-heading */
     do_org_todo(s);
+    }
 }
 
 static void do_org_promote(EditState *s, int dir)
@@ -512,7 +607,7 @@
             }
         }
         offset = org_next_heading(s, offset, MAX_LEVEL, &level1);
-        if (offset < 0 || level1 <= level)
+        if (level1 <= level)
             break;
     }
 }
@@ -537,13 +632,11 @@
     }
     
     offset1 = org_next_heading(s, offset, level, &level1);
-    if (offset1 < 0)
-        offset1 = s->b->total_size;
     size = offset1 - offset;
 
     if (dir < 0) {
         offset2 = org_prev_heading(s, offset, level, &level2);
-        if (offset2 < 0 || level2 < level) {
+        if (level2 < level) {
             put_status(s, "cannot move substree");
             return;
         }
@@ -553,8 +646,6 @@
             return;
         }
         offset2 = org_next_heading(s, offset1, level, &level2);
-        if (offset2 < 0)
-            offset2 = s->b->total_size;
     }
     b1 = eb_new("*tmp*", 0);
     eb_set_charset(b1, s->b->charset);
@@ -568,13 +659,13 @@
 
 static void do_org_meta_return(EditState *s)
 {
-    do_org_insert_heading(s);
+    do_org_insert_heading(s, 0);
 }
 
 static void do_org_metaleft(EditState *s)
 {
     if (org_is_header_line(s, s->offset))
-        do_org_promote(s, -1);
+        do_org_promote(s, +1);
     else
         do_word_right(s, -1);
 }
@@ -582,9 +673,9 @@
 static void do_org_metaright(EditState *s)
 {
     if (org_is_header_line(s, s->offset))
-        do_org_promote(s, 1);
+        do_org_promote(s, -1);
     else
-        do_word_right(s, 1);
+        do_word_right(s, +1);
 }
 
 static void do_org_metadown(EditState *s)
@@ -608,12 +699,31 @@
 
 /* Org mode specific commands */
 static CmdDef org_commands[] = {
+    /* Motion */
+    CMD2( KEY_CTRLC(KEY_CTRL('n')), KEY_NONE,   /* C-c C-n */
+          "outline-next-visible-heading", do_outline_next_vsible_heading, ES, 
"")
+    CMD2( KEY_CTRLC(KEY_CTRL('p')), KEY_NONE,   /* C-c C-p */
+          "outline-previous-visible-heading", 
do_outline_previous_vsible_heading, ES, "")
+    CMD2( KEY_CTRLC(KEY_CTRL('u')), KEY_NONE,   /* C-c C-u */
+          "outline-up-heading", do_outline_up_heading, ES, "")
+    CMD2( KEY_CTRLC(KEY_CTRL('b')), KEY_NONE,   /* C-c C-b */
+          "org-backward-same-level", do_org_backward_same_level, ES, "")
+    CMD2( KEY_CTRLC(KEY_CTRL('f')), KEY_NONE,   /* C-c C-f */
+          "org-forward-same-level", do_org_forward_same_level, ES, "")
+    CMD2( KEY_CTRLC(KEY_CTRL('j')), KEY_NONE,   /* C-c C-j */
+          "org-goto", do_org_goto, ESs,
+          "s{select location to jump to: }[orgjump]|orgjump|")
+    /* Editing */
     CMD2( KEY_CTRLC(KEY_CTRL('t')), KEY_NONE,   /* C-c C-t */
           "org-todo", do_org_todo, ES, "*")
-    CMD2( KEY_NONE, KEY_NONE,
-          "org-insert-heading", do_org_insert_heading, ES, "*")
-    CMD2( KEY_NONE, KEY_NONE,    /* actually M-S-RET and C-c C-x M */
-          "org-insert-todo-heading", do_org_insert_todo_heading, ES, "*")
+    CMD3( KEY_NONE, KEY_NONE,    /* indirect through M-RET */
+          "org-insert-heading", do_org_insert_heading, ESi, 0, "*v")
+    CMD3( KEY_NONE, KEY_NONE,    /* actually M-S-RET and C-c C-x M */
+          "org-insert-todo-heading", do_org_insert_heading, ESi, 1, "*v")
+    CMD3( KEY_CTRL('j'), KEY_NONE,    /* actually C-RET */
+          "org-insert-heading-respect-content", do_org_insert_heading, ESi, 2, 
"*v")
+    CMD3( KEY_NONE, KEY_NONE,    /* actually C-S-RET */
+          "org-insert-todo-heading-respect-content", do_org_insert_heading, 
ESi, 3, "*v")
     CMD3( KEY_NONE, KEY_NONE,
           "org-do-demote", do_org_promote, ESi, -1, "*v")
     CMD3( KEY_NONE, KEY_NONE,



reply via email to

[Prev in Thread] Current Thread [Next in Thread]