Search code examples
emacsorg-modec-mode

Mixing org-mode and c-mode in emacs


I'd like to mix org-mode and c-mode in Emacs. Everything inside a comment should be org-mode, the rests should be default major-mode c-mode:

/*
Org-mode here
** Section 1
  text
** Section 2
  text
Org-mode should end here
*/

func1()
{
}

I tried using nXhtml multi-major-mode, I guess there are other modes that support multimodes too. My problem now is that if I type TAB on "section 2" then all below "Section 2" will be folded and made invisible. But I would like to contain the region that org-mode folds/unfolds to the comment section. The TAB should only fold/unfold till the "*/".

I wonder how I can achieve this?


Solution

  • I found a solution: http://lists.gnu.org/archive/html/emacs-orgmode/2011-01/msg00036.html lists a patch for org-mode:

    --- emacs-23.2/lisp/org/org.el  2010-04-04 00:26:08.000000000 +0200
    +++ src/c51/mk/org.el   2011-01-02 20:26:10.266860827 +0100
    @@ -5245,6 +5245,8 @@
     (defun org-cycle-internal-local ()
       "Do the local cycling action."
       (org-back-to-heading)
    +  (cond 
    +   ((not (looking-at (concat outline-regexp "\s*#" )))
       (let ((goal-column 0) eoh eol eos level has-children children-skipped)
         ;; First, some boundaries
         (save-excursion
    @@ -5318,7 +5320,7 @@
           (hide-subtree)
           (message "FOLDED")
           (setq org-cycle-subtree-status 'folded)
    -      (run-hook-with-args 'org-cycle-hook 'folded)))))
    +      (run-hook-with-args 'org-cycle-hook 'folded)))))))
    
     ;;;###autoload
     (defun org-global-cycle (&optional arg)
    --- emacs-23.2/lisp/outline.el  2010-04-04 00:26:04.000000000 +0200
    +++ src/c51/mk/outline.el   2011-01-02 20:35:17.303609833 +0100
    @@ -913,8 +913,15 @@
           ;; Then unhide the top level headers.
           (outline-map-region
            (lambda ()
    -    (if (<= (funcall outline-level) levels)
    -        (outline-show-heading)))
    +    (if (<= (funcall outline-level) level)
    +          (if (looking-at (concat outline-regexp "\s*#" ))
    +          (progn
    +            (outline-show-heading )
    +            (show-entry ))
    +        (outline-show-heading))))
    +;;       (lambda ()
    +;;  (if (<= (funcall outline-level) levels)
    +;;      (outline-show-heading)))
            beg end)))
       (run-hooks 'outline-view-change-hook))
    
    @@ -994,7 +1001,11 @@
           (outline-map-region
            (lambda ()
         (if (<= (funcall outline-level) level)
    -        (outline-show-heading)))
    +          (if (looking-at (concat outline-regexp "\s*#" ))
    +          (progn
    +            (outline-show-heading )
    +            (show-entry ))
    +          (outline-show-heading))))
            (point)
            (progn (outline-end-of-subtree)
              (if (eobp) (point-max) (1+ (point)))))))
    

    This patch has to be applied by hand, its not that difficult. It adds the marker *# that will break the indention. @bzg pointed out the M-x orgstruct-mode RET mode, credits to him. Now I can write in c.mode with orgstruct-mode in the background (no multi-major-mode needed any more):

    /*
    Org-mode here
    ** Section 1
      text
    ** Section 2
      text
    *#
    Org-mode should end here
    */
    

    And I will have org-mode in comments, The Section 1 and Section 2 will fold until the *# marker.