Add marker support and buffer-local parser override

This commit is contained in:
Greg Sexton 2015-08-22 12:50:02 +01:00
commit 56140b4d3f
3 changed files with 48 additions and 29 deletions

View File

@ -163,10 +163,10 @@ surprisingly well for most major-modes and is great for folding text.
It should be trivial to add support for any language that uses braces
to delimit blocks. Just add to `origami-parser-alist` something like:
`(mode-name . origami-c-style-parser)`. Adding support for another
lisp dialect should be almost as simple. With a little bit of effort
it shouldn't be too hard to create a parser for anything with start
and end delimiters (similar to braces). See the
`origami-c-style-parser` function for how to define this.
lisp dialect should be almost as simple. You can also easily define a
parser for anything with start and end delimiters (similar to braces).
Use the `origami-markers-parser` function for this. There's an example
defined for triple-braces in `origami-parser-alist`.
I'm happy to work on parsers for other languages if interest is
expressed. Cut an issue and I'll see what I can do.
@ -188,6 +188,15 @@ While I work on writing better documentation for parsing, I suggest
starting by looking at the current parsers in origami-parsers.el to
see how they work.
# Can I override the folding parser for an individual file?
You most certainly can. Just add a buffer-local variable that
references a key in `origami-parser-alist`. Something like:
;; -*- origami-fold-style: triple-braces -*-
This will add fold-marker support to that file.
# How is this different from [yafolding](https://github.com/zenozeng/yafolding.el)?
I wasn't aware of yafolding before writing this. It looks like origami
@ -209,12 +218,11 @@ folding operations easy.
# How is this different from [folding.el](http://www.emacswiki.org/emacs/folding.el)?
Folding.el uses markers in the buffer to annotate folds. It should be
very easy to add support for this to origami if anyone is looking for
this feature?
Folding.el uses markers in the buffer to annotate folds. Origami also
supports this and more.
# How is this different from folding implemented by a specific mode?
It's general purpose and concentrates only on providing a decent
It's general purpose and concentrates only on providing a great
folding solution. You need only write a parser for origami to get all
of its folding features for free.
of its fold-manipulating features for free.

View File

@ -33,25 +33,6 @@
(require 'cl)
(require 'dash)
(defcustom origami-parser-alist
'((java-mode . origami-java-parser)
(c-mode . origami-c-style-parser)
(c++-mode . origami-c-style-parser)
(perl-mode . origami-c-style-parser)
(cperl-mode . origami-c-style-parser)
(js-mode . origami-c-style-parser)
(js2-mode . origami-c-style-parser)
(js3-mode . origami-c-style-parser)
(go-mode . origami-c-style-parser)
(php-mode . origami-c-style-parser)
(python-mode . origami-indent-parser)
(emacs-lisp-mode . origami-elisp-parser)
(lisp-interaction-mode . origami-elisp-parser)
(clojure-mode . origami-clj-parser))
"alist mapping major-mode to parser function."
:type 'hook
:group 'origami)
(defun origami-get-positions (content regex)
"Returns a list of positions where REGEX matches in CONTENT. A
position is a cons cell of the character and the numerical
@ -217,6 +198,34 @@ position in the CONTENT."
(defun origami-clj-parser (create)
(origami-lisp-parser create "(def\\(\\w\\|-\\)*\\s-*\\(\\s_\\|\\w\\|[?!]\\)*\\([ \\t]*\\[.*?\\]\\)?"))
(defun origami-markers-parser (start-marker end-marker)
"Create a parser for simple start and end markers."
(let ((regex (rx-to-string `(or ,start-marker ,end-marker))))
(lambda (create)
(lambda (content)
(let ((positions (origami-get-positions content regex)))
(origami-build-pair-tree create start-marker end-marker positions))))))
(defcustom origami-parser-alist
`((java-mode . origami-java-parser)
(c-mode . origami-c-style-parser)
(c++-mode . origami-c-style-parser)
(perl-mode . origami-c-style-parser)
(cperl-mode . origami-c-style-parser)
(js-mode . origami-c-style-parser)
(js2-mode . origami-c-style-parser)
(js3-mode . origami-c-style-parser)
(go-mode . origami-c-style-parser)
(php-mode . origami-c-style-parser)
(python-mode . origami-indent-parser)
(emacs-lisp-mode . origami-elisp-parser)
(lisp-interaction-mode . origami-elisp-parser)
(clojure-mode . origami-clj-parser)
(triple-braces . ,(origami-markers-parser "{{{" "}}}")))
"alist mapping major-mode to parser function."
:type 'hook
:group 'origami)
(provide 'origami-parsers)
;;; origami-parsers.el ends here

View File

@ -380,7 +380,9 @@ was last built."
-last-item
origami-fold-data)
(origami-create-overlay beg end offset buffer)))))))
(-when-let (parser-gen (or (cdr (assoc (buffer-local-value 'major-mode buffer)
(-when-let (parser-gen (or (cdr (assoc (if (local-variable-p 'origami-fold-style)
(buffer-local-value 'origami-fold-style buffer)
(buffer-local-value 'major-mode buffer))
origami-parser-alist))
'origami-indent-parser))
(funcall parser-gen create))))