I want to switch between org-mode and c++-mode on top of a single file. I use org-mode syntax inside c++ comment blocks. In Org-mode I have foldable sections while in c++-mode I use hide/show for blocks. When switching mode the outline overlay is reset and everything is made visible. Is it possible to somehow prevent this and retain the visibility state?
I ended up using https://github.com/ShingoFukuyama/ov.el and syncing org-mode and c++-mode overlays. When switching between modes I replicate the other buffer's
invisible overlays. This is done on every mode switch:
(add-hook 'multi-select-mode-hook 'sync-buffer-overlays)
(require 'ov) (defun get-org-buffer () (cdr (assoc 'org-mode multi-indirect-buffers-alist))) (defun get-c++-buffer () (cdr (assoc 'c++-mode multi-indirect-buffers-alist))) ;; exclude the overlays marked with `ismultimode' from overlay list of buffer `buf' (defun get-real-ov (buf) (let ((org-ov)) (with-current-buffer buf (setq org-ov (seq-remove (lambda (x) (ov-val x 'ismultimode )) (ov-all)))) org-ov)) ;; remove all overlays marked with `ismultimode' from buffer (defun clean-intermediate-overlays (buf) (with-current-buffer buf (dolist (e (ov-all)) (if (ov-val e 'ismultimode ) (ov-reset e))))) (defun sync-buffer-overlays () (interactive) (let ((org-buf (get-org-buffer)) (c++-buf (get-c++-buffer)) (org-ov) (c++-ov) ) (clean-intermediate-overlays c++-buf) (clean-intermediate-overlays org-buf) (setq org-ov (get-real-ov org-buf)) (with-current-buffer c++-buf (dolist (e org-ov) (let ((beg (ov-beg e)) (end (ov-end e))) (ov beg end '(invisible hs ismultimode t))) )) (setq c++-ov (get-real-ov c++-buf)) (with-current-buffer org-buf (dolist (e c++-ov) (let ((beg (ov-beg e)) (end (ov-end e))) (ov beg end '(invisible outline ismultimode t))) )) ) )