branch: elpa/evil-matchit commit b4163c71c3b2b3530c81ddb6160a3423bb691529 Author: Chen Bin <chenbin...@gmail.com> Commit: Chen Bin <chenbin...@gmail.com>
support org-mode --- evil-matchit-latex.el | 1 - evil-matchit-org.el | 107 ++++++++++++++++++++++++++++++++++++++++++++++++++ evil-matchit-sdk.el | 8 ++-- evil-matchit.el | 13 +++--- 4 files changed, 119 insertions(+), 10 deletions(-) diff --git a/evil-matchit-latex.el b/evil-matchit-latex.el index 76b1d987ea..7bfb67c4aa 100644 --- a/evil-matchit-latex.el +++ b/evil-matchit-latex.el @@ -103,7 +103,6 @@ The third column contains the closed tags(s).") (setq cur-tag-type (nth 1 cur-tag-info)) ;; we need more strict tag match strategy because tex is really wierd (when (= (car cur-tag-info) (car orig-tag-info)) - ;; (message "orig-tag-type=%d cur-tag-type=%d keyword=%s" orig-tag-type cur-tag-type keyword) (cond ;; handle open tag ;; open (0) -> mid (1) found when level is one else ignore diff --git a/evil-matchit-org.el b/evil-matchit-org.el new file mode 100644 index 0000000000..411ecb65fd --- /dev/null +++ b/evil-matchit-org.el @@ -0,0 +1,107 @@ +;;; evil-matchit-org.el --- org-mode plugin of evil-matchit + +;; Copyright (C) 2014 Chen Bin <chenbin...@gmail.com> + +;; Author: Chen Bin <chenbin...@gmail.com> + +;; This file is not part of GNU Emacs. + +;;; License: + +;; This file is part of evil-matchit +;; +;; evil-matchit is free software: you can redistribute it and/or +;; modify it under the terms of the GNU General Public License as published +;; by the Free Software Foundation, either version 3 of the License, or +;; (at your option) any later version. +;; +;; evil-matchit is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. +;; +;; You should have received a copy of the GNU General Public License +;; along with this program. If not, see <http://www.gnu.org/licenses/>. + + +;;; Code: + +;; OPTIONAL, you don't need SDK to write a plugin for evil-matchit +;; but SDK don make you write less code, isn't it? +;; All you need to do is just define the match-tags for SDK algorithm to lookup. +(require 'evil-matchit-sdk) + +(defvar evilmi-org-extract-keyword-howtos + '(("^[ \t]*#\\+\\([a-zA-Z_]+\\).*$" 1) + ) + "The list of HOWTO on extracting keyword from current line. +Each howto is actually a pair. The first element of pair is the regular +expression to match the current line. The second is the index of sub-matches +to extract the keyword which starts from one. The sub-match is the match defined +between '\\(' and '\\)' in regular expression. +" + ) +;; ruby/bash/lua/vimrc +(defvar evilmi-org-match-tags + '((("begin_src" "BEGIN_SRC") () ( "end_src" "END_SRC")) + (("begin_example" "BEGIN_EXAMPLE") () ( "end_example" "END_EXAMPLE")) + (("begin_html" "BEGIN_HTML") () ( "end_html" "END_HTML")) + ) + "The table we look up match tags. This is a three column table. +The first column contains the open tag(s). +The second column contains the middle tag(s). +The third column contains the closed tags(s). +" + ) + +(defun evilmi--get-embedded-language-major-mode () + (let ((info (org-edit-src-find-region-and-lang)) + lang + lang-f) + (if info + (progn + (setq lang (or (cdr (assoc (nth 2 info) org-src-lang-modes)) + (nth 2 info))) + (setq lang (if (symbolp lang) (symbol-name lang) lang)) + (setq lang-f (intern (concat lang "-mode"))) + )) + lang-f)) + +;;;###autoload +(defun evilmi-org-get-tag () + (let (rlt) + (setq rlt (evilmi-sdk-get-tag evilmi-org-match-tags evilmi-org-extract-keyword-howtos)) + (if (not rlt) + (setq rlt '(-1)) ;; evilmi-org-jump knows what -1 means + ) + rlt + )) + +;;;###autoload +(defun evilmi-org-jump (rlt NUM) + (if (< (car rlt) 0) + (let (where-to-jump-in-theory + jumped + plugin + info + (lang-f (evilmi--get-embedded-language-major-mode))) + (when lang-f + (setq plugin (plist-get evilmi-plugins lang-f)) + (when plugin + (mapc + (lambda (elem) + (setq info (funcall (nth 0 elem))) + (when (and info (not jumped)) + ;; before jump, we may need some operation + (setq where-to-jump-in-theory (funcall (nth 1 elem) info NUM)) + ;; jump only once if the jump is successful + (setq jumped t) + )) + plugin + )) + ) + ) + (evilmi-sdk-jump rlt NUM evilmi-org-match-tags evilmi-org-extract-keyword-howtos) + )) + +(provide 'evil-matchit-org) diff --git a/evil-matchit-sdk.el b/evil-matchit-sdk.el index 41974f7f1f..eb3d8d7d4f 100644 --- a/evil-matchit-sdk.el +++ b/evil-matchit-sdk.el @@ -67,7 +67,6 @@ between '\\(' and '\\)' in regular expression. (setq i 0) (while (and (not keyword) (< i (length howtos))) (setq howto (nth i howtos)) - (when (string-match (nth 0 howto) cur-line) (setq keyword (match-string (nth 1 howto) cur-line)) @@ -82,13 +81,17 @@ between '\\(' and '\\)' in regular expression. ;;;###autoload (defun evilmi-sdk-get-tag (match-tags howtos) + "return '(start-point tag-info) +" (let (rlt keyword (cur-line (buffer-substring-no-properties (line-beginning-position) (line-end-position))) tag-info) + (when (setq keyword (evilmi--sdk-extract-keyword cur-line match-tags howtos)) + ;; since we mixed ruby and lua mode here ;; maybe we should be strict at the keyword (if (setq tag-info (evilmi-sdk-get-tag-info keyword match-tags)) @@ -133,8 +136,6 @@ between '\\(' and '\\)' in regular expression. (setq cur-tag-info (evilmi-sdk-get-tag-info keyword match-tags)) (setq cur-tag-type (nth 1 cur-tag-info)) - ;; (message "cur-tag-info=%s orig-tag-info=%s keyword=%s" cur-tag-info orig-tag-info keyword) - ;; key algorithm (cond ;; handle open tag @@ -187,7 +188,6 @@ between '\\(' and '\\)' in regular expression. ;; now handle closed tag ;; closed (2) -> mid (1) ignore,impossible ((and (= orig-tag-type 2) (= cur-tag-type 1)) - (message "impossible to be here") ) ;; closed (2) -> closed (2) level++ ((and (= orig-tag-type 2) (= cur-tag-type 2)) diff --git a/evil-matchit.el b/evil-matchit.el index f1a9ece346..6eaad01fff 100644 --- a/evil-matchit.el +++ b/evil-matchit.el @@ -46,7 +46,7 @@ (defun evilmi--operate-on-item (NUM &optional FUNC) (let (plugin rlt - (jumped nil) + jumped where-to-jump-in-theory ) @@ -63,11 +63,9 @@ (setq where-to-jump-in-theory (funcall (nth 1 elem) rlt NUM)) ;; jump only once if the jump is successful (setq jumped t) - ) - ) + )) plugin - ) - ) + )) (when (not jumped) (if FUNC (funcall FUNC (list (point)))) @@ -102,6 +100,11 @@ ) '(web-mode html-mode nxml-mode nxhtml-mode sgml-mode)) + ;; Emacs Org-mode + (autoload 'evilmi-org-get-tag "evil-matchit-org" nil) + (autoload 'evilmi-org-jump "evil-matchit-org" nil t) + (plist-put evilmi-plugins 'org-mode '((evilmi-org-get-tag evilmi-org-jump))) + ;; Latex (autoload 'evilmi-latex-get-tag "evil-matchit-latex" nil) (autoload 'evilmi-latex-jump "evil-matchit-latex" nil t)