help-gnu-emacs
[Top][All Lists]
Advanced

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

Re: code folding with <backtab> ?


From: Michael Heerdegen
Subject: Re: code folding with <backtab> ?
Date: Mon, 09 Apr 2012 03:00:59 +0200
User-agent: Gnus/5.13 (Gnus v5.13) Emacs/24.0.95 (gnu/linux)

Hello Yagnesh,

if you decide to use "hideshow", then you can use what follows.  I like
hideshow very much for elisp, although the standard keys for
`hs-minor-mode' are horrible.

> To begin with elisp, can anybody tell me how to make backtab to show
> the outline of the buffer at least for two levels. I mean first press
> would show me buffer folded upto top level comments, defuns,
> defcustoms and defvars and the second press would show me entire
> buffer.

Use hideshow-org, which implements exactly that:

$ git clone git://github.com/secelis/hideshow-org.git

It also lets you do hide/unhide comfortably with TAB, like in org.

Note that you can also always (un)hide with `hs-mouse-toggle-hiding'
(bound to <S-mouse-2>) when you use hideshow.

Some more stuff to try:

1. WRT choosing default hiding level, you can use something like that:

(eval-after-load "hideshow"
  '(make-variable-buffer-local 'hs-hide-all-non-comment-function))

(add-hook
 'hs-minor-mode-hook
 (lambda ()
   (easy-menu-add-item
    nil '("Hide/Show")
    '("\"Hide All\" method"
      ["Default"
       (setq hs-hide-all-non-comment-function nil)
       :style toggle
       :selected (null hs-hide-all-non-comment-function)]
      ["Level 1"
       (setq hs-hide-all-non-comment-function 'my-hs-hide-level-1)
       :style toggle
       :selected (eq hs-hide-all-non-comment-function
                  'my-hs-hide-level-1)]
      ["Level 2"
       (setq hs-hide-all-non-comment-function 'my-hs-hide-level-2)
       :style toggle
       :selected (eq hs-hide-all-non-comment-function
                  'my-hs-hide-level-2)]
      ["Level 3"
       (setq hs-hide-all-non-comment-function 'my-hs-hide-level-3)
       :style toggle
       :selected (eq hs-hide-all-non-comment-function
                  'my-hs-hide-level-3)]))))

(defun my-hs-hide-level-1 ()
  (hs-hide-level 1)
  (forward-sexp 1))
(defun my-hs-hide-level-2 ()
  (hs-hide-level 2)
  (forward-sexp 1))
(defun my-hs-hide-level-3 ()
  (hs-hide-level 3)
  (forward-sexp 1))

It adds an entry to the "Hide/Show" minor mode menu that lets you choose
the default hiding level if you do "Hide All" (C-c @ C-M-h, or <backtab>
when using hideshow-org).



2. You can control how the hide ellipsis should look like.  I myself use
this configuration, which adds a count of the number of lines hidden, a
tooltip, and uses a different color:

(defun my-hs-ellipsis (ov)
  (when (eq 'code (overlay-get ov 'hs))
    (overlay-put ov 'display
                 (propertize
                  (format " ... / %d"
                          (count-lines (overlay-start ov)
                                       (overlay-end ov)))
                  'help-echo (format "Toggle visibility: %s"
                                     (where-is-internal 'hs-mouse-toggle-hiding
                                                        nil 'FIRST-ONLY))
                  'face 'font-lock-preprocessor-face))))

(eval-after-load "hideshow"
  '(setq hs-set-up-overlay 'my-hs-ellipsis))


3.  This defines <C-tab> to show a nice fisheye like view of the current
top level form, adjusted to the current position of point (= the
cursor).

(defun hs-fisheye-1 (position level minp maxp)
  (goto-char minp)
  (while (progn
           (forward-comment (buffer-size))
           (and (< (point) maxp)
                (re-search-forward hs-block-start-regexp maxp t)))
    (when (save-match-data
            (not (nth 8 (syntax-ppss)))) ; not inside comments or strings
      (goto-char (match-beginning hs-block-start-mdata-select))
      (let ((end-of-sexp (save-excursion
                            (forward-comment (buffer-size))
                            (when (< (point) maxp)
                              (funcall hs-forward-sexp-func)
                              (1- (point))))))
        (if (and (<= (point) position)
                 end-of-sexp
                 (<= position end-of-sexp))
            (hs-fisheye-1 position level (1+ (point)) end-of-sexp)
          (case level
            ((0) (hs-hide-block))
            (t   (hs-hide-level level))))
        (goto-char end-of-sexp)))))

(defun hs-fisheye (level)
  "Hide current top-level block recursivly, revealing context of point.

The prefix arg determines the hiding level for each block hidden.
With prefix arg < 0, show the whole current top level sexp."
  (interactive "p")
  (if (< level 0)
      (save-excursion
        (goto-char (syntax-ppss-toplevel-pos (syntax-ppss)))
        (hs-show-block))
    (let* ((minp (or (syntax-ppss-toplevel-pos (syntax-ppss))
                     (error "%s" "Not inside a toplevel form")))
           (maxp (save-excursion (goto-char minp) (funcall 
hs-forward-sexp-func) (point))))
      (unless hs-allow-nesting
        (hs-discard-overlays minp maxp))
      (save-excursion (hs-fisheye-1 (point) level minp maxp)))))

(add-hook 'hs-minor-mode-hook
  #'(lambda () (define-key hs-minor-mode-map [(control tab)]
  'hs-fisheye)))

4. If you want to have some more colorful views, also have a look at
rainbow-delimiters.el:

 EmacsWiki: http://www.emacswiki.org/emacs/RainbowDelimiters
 Github: http://github.com/jlr/rainbow-delimiters


Michael



reply via email to

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