branch: elpa/evil-matchit commit 7d65b4167b1f0086c2b42b3aec805e47a0d355c4 Author: Chen Bin <chenbin...@gmail.com> Commit: Chen Bin <chenbin...@gmail.com>
clean plugins setup code - clean setup code - update README - add new API `evilmi-load-rule` - requires emacs 24.4 and evil 1.2 - clean compiler warning --- README.org | 85 ++++++----------------- evil-matchit-markdown.el | 2 +- evil-matchit-ocaml.el | 7 +- evil-matchit-org.el | 1 + evil-matchit-sdk.el | 4 ++ evil-matchit.el | 175 +++++++++++++++++++---------------------------- pkg.sh | 2 +- 7 files changed, 100 insertions(+), 176 deletions(-) diff --git a/README.org b/README.org index 6d10526d16..42cb71da89 100644 --- a/README.org +++ b/README.org @@ -1,4 +1,4 @@ -* evil-matchit (v2.2.8) +* evil-matchit (v2.2.9) [[http://melpa.org/#/evil-matchit][file:http://melpa.org/packages/evil-matchit-badge.svg]] [[http://stable.melpa.org/#/evil-matchit][file:http://stable.melpa.org/packages/evil-matchit-badge.svg]] @@ -86,16 +86,14 @@ This is actually an advantage of Emacs, you can tweak the select region without ** Support new major modes In order to apply three matching rules =evilmi-template=, =evilmi-simple=, and =evilmi-html= on =mhtml-mode=, please insert below code *after* your evil-nerd-commenter setup: #+begin_src elisp -(plist-put evilmi-plugins 'mhtml-mode '((evilmi-template-get-tag evilmi-template-jump) - (evilmi-simple-get-tag evilmi-simple-jump) - (evilmi-html-get-tag evilmi-html-jump) +(evilmi-load-plugin-rules '(mhtml-mode) '(template simple html)) #+end_src ** Use evilmi-select-items instead press '%' in evil-visual-state evilmi-select-items is more robust and provides more functionality. It works even when evil-mode is not loaded. So you'd better stick to evilmi-select-items if possible. ** Add new tags into existing languages -I use ruby as an example. +Use ruby as an example. If you want to add more tags into ruby, you can do two thing: - You need define the regular expression to extract keyword @@ -118,31 +116,6 @@ So you setup in ~/.emacs is as below: )) #+end_src -** Support more major modes -Let's use html tag matching as an example. - -html tags are automatically supported in sgml-mode, nxml-mode, web-mode, html-mode and nxhtml-mode,. - -You want a new major-mode "my-mode" to do the html tag matching? Easy. Please add below code into your ~/.emacs: - -#+BEGIN_SRC elisp -(plist-put evilmi-plugins my-mode '((evilmi-simple-get-tag evilmi-simple-jump) - (evilmi-html-get-tag evilmi-html-jump))) -#+END_SRC - -Further explanation: "evilmi-html-get-tag" and "evilmi-html-jump" are existing APIs which are defined in evil-matchit-html.el. - -The above line means that use "evilmi-html-get-tag" to find open/closed tag in current line and use "evilmi-html-jump" to jump to matched closed/open tag. - -"evilmi-simple-get-tag" and "evilmi-simple-jump" provide generic rules shared by most major modes. For example, jumping between two end of the string, between brackets, etc. -** Mixed languages in one html template file is supported -If you embed python language in a html file. You can match both html tags and python statement by inserting below code into your ~/.emacs: -#+BEGIN_SRC elisp -(plist-put evilmi-plugins web-mode - '((evilmi-python-get-tag evilmi-python-jump) - (evilmi-html-get-tag evilmi-html-jump) - )) -#+END_SRC ** Re-define keybinding You can define your own key bindings instead using evil-matchit default key binding. @@ -171,15 +144,11 @@ You can turn on =evilmi-always-simple-jump= to match brackets at first. Thus you disable our *advanced algorithm* which I highly recommend. Some people may prefer simpler algorithm in =python-mode=. -** APIs you can use -- evilmi-current-font-among-fonts-p -- evilmi-in-comment-p -- evilmi-in-string-or-doc-p * Developer guide -** Write Emacs Lisp to support new language +** Create plugin to support new language Simple. You only need define two functions and tell evil-matchit in which major-mode they should be used. -Here is a complete sample: +A complete setup: #+BEGIN_SRC elisp ;; detect tag in current line and return the result in variable rlt ;; the rlt will be used by evilmi-mylang-jump as the first parameter. @@ -207,20 +176,17 @@ Here is a complete sample: ;; If you need know where is the end of the region for region operation, ;; you need return the end of region at the end of function ;; region operation means selection/deletion of region. - 888 - ) + 888) -;; notify evil-matchit how to use above functions -(plist-put evilmi-plugins mylang-mode '((evilmi-mylang-get-tag evilmi-mylang-jump))) +;; Notify evil-matchit how to use above functions +(evilmi-load-plugin-rules '(mylang-mode) '(mylan)) #+END_SRC -Place above code into your ~/.emacs, after the line "(global-evil-matchit-mode 1)" +Place above code into your =~/.emacs=, after the line "(global-evil-matchit-mode 1)" ** Use SDK -Please note SDK is *OPTIONAL*! You don't need SDK to write a plugin for evil-matchit. - -You can check the evil-matchit-script.el for the sample on how to use SDK. +For example, it only takes 3 steps to create a new rule =script= to match tags in script like Ruby/Lua/Bash/VimScript, -I attached the full content of evil-matchit-script.el here: +Step 1, create =evil-matchit-script.el=, #+BEGIN_SRC elisp (require 'evil-matchit-sdk) @@ -230,8 +196,7 @@ I attached the full content of evil-matchit-script.el here: ("begin" ("rescue" "ensure") "end") ("case" ("when" "else") ("esac" "end")) (("fun!" "function!" "class" "def" "while" "function" "do") () ("end" "endfun" "endfunction")) - ("repeat" () "until") - ) + ("repeat" () "until")) "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). @@ -254,26 +219,16 @@ The forth *optional* column defines the relationship between open and close tags (provide 'evil-matchit-script) #+END_SRC -Simple, eh? - -Basically you just need: -- copy the content of evil-matchit-script.el to your ~/.emacs -- Search and replace the string "_script" with "_mylang" to respect the name space -- Update the value of evilmi--mylang-match-tags -- Notify the evil-matchit about support for new commands. As I mentioned before, it's just one line code in ~/.emacs +Step 2, make sure the directory of =evil-matchit-script.el= is add into =load-path=. +Step 3, add below code to =~/.emacs.=, #+BEGIN_SRC lisp -(plist-put evilmi-plugins mylang-mode '((evilmi-mylang-get-tag evilmi-mylang-jump))) +(evilmi-load-plugin-rules '(ruby-mode lua-mode) '(script)) #+END_SRC - -** Share your code to the world -Convert your code to a plugin and ask me to merge it into upstream. - -Please check "evil-matchit-latex.el" for technical details about plugin. - -Key points about code quality of plugin: -- minimum dependency. For example, if your plugin for html template files is only some web-mode API wrapper, it will break when user don't have web-mode -- support emacs 23 -- performance is the first priority +** APIs +- evilmi-load-plugin-rules +- evilmi-current-font-among-fonts-p +- evilmi-in-comment-p +- evilmi-in-string-or-doc-p * Contact me Report bugs at [[https://github.com/redguardtoo/evil-matchit]]. diff --git a/evil-matchit-markdown.el b/evil-matchit-markdown.el index d5921e787a..7908a61277 100644 --- a/evil-matchit-markdown.el +++ b/evil-matchit-markdown.el @@ -42,7 +42,7 @@ Return (list start-position tag)." (let* ((str (match-string 1 cur-line)) (prefix (buffer-substring-no-properties (point-min) (line-beginning-position))) - (forward-direction (evenp (evilmi-count-matches str prefix)))) + (forward-direction (evilmi-evenp (evilmi-count-matches str prefix)))) (setq rlt (list (if forward-direction (line-beginning-position) (line-end-position)) forward-direction diff --git a/evil-matchit-ocaml.el b/evil-matchit-ocaml.el index 6b0549921f..e0858a70b6 100644 --- a/evil-matchit-ocaml.el +++ b/evil-matchit-ocaml.el @@ -26,6 +26,7 @@ ;;; Code: +(require 'cl-lib) (require 'evil-matchit-sdk) (defvar evilmi-ocaml-keywords @@ -88,11 +89,11 @@ such keyword is available." (defun evilmi-ocaml-is-keyword (l keyword) "Checks if the keyword belongs to a row." - (find-if (lambda (w) (string-equal w keyword)) (apply 'append l))) + (cl-find-if (lambda (w) (string-equal w keyword)) (apply 'append l))) (defun evilmi-ocaml-get-tag-info (keyword) "Find the row in the evilmi-ocaml-keywords." - (find-if (lambda (l) (evilmi-ocaml-is-keyword l keyword)) evilmi-ocaml-keywords)) + (cl-find-if (lambda (l) (evilmi-ocaml-is-keyword l keyword)) evilmi-ocaml-keywords)) ;; 0 - forward ;; 1 - backward @@ -114,7 +115,7 @@ such keyword is available." (if bounds (goto-char (car bounds))) (let ((next-keyword (save-excursion - (if (find word evilmi-ocaml-all-keywords :test 'equal) + (if (cl-find word evilmi-ocaml-all-keywords :test 'equal) (point) (evilmi-ocaml-next-keyword 0) (if (< (point) line-end) (point)))))) diff --git a/evil-matchit-org.el b/evil-matchit-org.el index bd7d749e2e..5d73e8037c 100644 --- a/evil-matchit-org.el +++ b/evil-matchit-org.el @@ -29,6 +29,7 @@ ;; OPTIONAL, you don't need SDK to write a plugin for evil-matchit ;; but SDK do 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 'org) (require 'evil-matchit-sdk) (defvar evilmi-org-extract-keyword-howtos diff --git a/evil-matchit-sdk.el b/evil-matchit-sdk.el index 9d5c24f87e..8108879538 100644 --- a/evil-matchit-sdk.el +++ b/evil-matchit-sdk.el @@ -317,6 +317,10 @@ after calling this function." (evilmi-current-font-among-fonts-p pos '(font-lock-string-face font-lock-doc-face))) +;;;###autoload +(defun evilmi-evenp (num) + (= (% num 2) 0)) + (defun evilmi-count-matches (regexp str) (let* ((count 0) (start 0)) diff --git a/evil-matchit.el b/evil-matchit.el index 6c2379d067..84d2338b99 100644 --- a/evil-matchit.el +++ b/evil-matchit.el @@ -1,12 +1,12 @@ ;;; evil-matchit.el --- Vim matchit ported to Evil -;; Copyright (C) 2014-2017 Chen Bin <chenbin...@gmail.com> +;; Copyright (C) 2014-2018 Chen Bin <chenbin...@gmail.com> ;; Author: Chen Bin <chenbin...@gmail.com> ;; URL: http://github.com/redguardtoo/evil-matchit -;; Version: 2.2.8 +;; Version: 2.2.9 ;; Keywords: matchit vim evil -;; Package-Requires: ((evil "1.0.7")) +;; Package-Requires: ((evil "1.2.0") (emacs "24.4")) ;; ;; This file is not part of GNU Emacs. @@ -261,139 +261,102 @@ If IS-FORWARD is t, jump forward; or else jump backward." (defun evilmi--push-mark (rlt) (push-mark (nth 0 rlt) t t)) +;;;###autoload +(defun evilmi-load-plugin-rules(modes rules) + "Load MODES's plugin RULES." + (dolist (mode modes) + (setq evilmi-plugins + (plist-put evilmi-plugins + mode + (mapcar (lambda (rule) + (let* ((rule-filename (concat "evil-matchit-" (symbol-name rule))) + (fn-prefix (concat "evilmi-" (symbol-name rule))) + (get-tag-function (intern (concat fn-prefix "-get-tag"))) + (jump-function (intern (concat fn-prefix "-jump")))) + (autoload get-tag-function rule-filename nil) + (autoload jump-function rule-filename nil) + (list get-tag-function jump-function))) + rules))))) + +;;;###autoload (defun evilmi-init-plugins () - "Load Matrix." + "Load plugins." (interactive) ;; simple matching for languages containing "{([" - (autoload 'evilmi-simple-get-tag "evil-matchit-simple" nil) - (autoload 'evilmi-simple-jump "evil-matchit-simple" nil) - (mapc (lambda (mode) - (plist-put evilmi-plugins mode '((evilmi-simple-get-tag evilmi-simple-jump)))) - '(java-mode perl-mode cperl-mode go-mode)) + (evilmi-load-plugin-rules '(java-mode perl-mode cperl-mode go-mode) + '(simple)) ;; Javascript/Typescript - (autoload 'evilmi-javascript-get-tag "evil-matchit-javascript" nil) - (autoload 'evilmi-javascript-jump "evil-matchit-javascript" nil) - (autoload 'evilmi-html-get-tag "evil-matchit-html" nil) - (autoload 'evilmi-html-jump "evil-matchit-html" nil) - (mapc (lambda (mode) - (plist-put evilmi-plugins mode '((evilmi-simple-get-tag evilmi-simple-jump) - (evilmi-javascript-get-tag evilmi-javascript-jump) - (evilmi-html-get-tag evilmi-html-jump)))) - '(js-mode json-mode js2-mode js3-mode javascript-mode rjsx-mode react-mode typescript-mode typescript-tsx-mode)) + (evilmi-load-plugin-rules '(js-mode + json-mode + js2-mode + js3-mode + javascript-mode + rjsx-mode + react-mode + typescript-mode + typescript-tsx-mode) + '(simple javascript html)) ;; Html - (autoload 'evilmi-template-get-tag "evil-matchit-template" nil) - (autoload 'evilmi-template-jump "evil-matchit-template" nil) - (mapc (lambda (mode) - (plist-put evilmi-plugins mode '((evilmi-template-get-tag evilmi-template-jump) - (evilmi-simple-get-tag evilmi-simple-jump) - (evilmi-html-get-tag evilmi-html-jump)))) - '(web-mode html-mode nxml-mode nxhtml-mode sgml-mode message-mode mhtml-mode)) + (evilmi-load-plugin-rules '(web-mode + html-mode + nxml-mode + nxhtml-mode + sgml-mode + message-mode + mhtml-mode) + '(template simple html)) ;; Emacs Org-mode - (autoload 'evilmi-org-get-tag "evil-matchit-org" nil) - (autoload 'evilmi-org-jump "evil-matchit-org" nil) - (plist-put evilmi-plugins 'org-mode '((evilmi-org-get-tag evilmi-org-jump))) - + (evilmi-load-plugin-rules '(org-mode) '(org)) ;; Markdown - (autoload 'evilmi-markdown-get-tag "evil-matchit-markdown" nil) - (autoload 'evilmi-markdown-jump "evil-matchit-markdown" nil) - (plist-put evilmi-plugins 'markdown-mode '((evilmi-markdown-get-tag evilmi-markdown-jump))) + (evilmi-load-plugin-rules '(markdown-mode) '(markdown)) ;; Latex - (autoload 'evilmi-latex-get-tag "evil-matchit-latex" nil) - (autoload 'evilmi-latex-jump "evil-matchit-latex" nil t) - (plist-put evilmi-plugins 'latex-mode '((evilmi-latex-get-tag evilmi-latex-jump) - (evilmi-simple-get-tag evilmi-simple-jump))) + (evilmi-load-plugin-rules '(latex-mode) '(latex simple)) - ;; ocaml - (autoload 'evilmi-ocaml-get-tag "evil-matchit-ocaml" nil) - (autoload 'evilmi-ocaml-jump "evil-matchit-ocaml" nil t) - (plist-put evilmi-plugins 'tuareg-mode '((evilmi-simple-get-tag evilmi-simple-jump) - (evilmi-ocaml-get-tag evilmi-ocaml-jump))) + ;; Ocaml + (evilmi-load-plugin-rules '(tuareg-mode) '(simple ocaml)) ;; Python - (autoload 'evilmi-python-get-tag "evil-matchit-python" nil) - (autoload 'evilmi-python-jump "evil-matchit-python" nil) - (plist-put evilmi-plugins 'python-mode '((evilmi-simple-get-tag evilmi-simple-jump) - (evilmi-python-get-tag evilmi-python-jump))) + (evilmi-load-plugin-rules '(python-mode) '(simple python)) ;; SQL - (autoload 'evilmi-sql-get-tag "evil-matchit-sql" nil) - (autoload 'evilmi-sql-jump "evil-matchit-sql" nil) - (plist-put evilmi-plugins 'sql-mode '((evilmi-simple-get-tag evilmi-simple-jump) - (evilmi-sql-get-tag evilmi-sql-jump))) + (evilmi-load-plugin-rules '(sql-mode) '(simple sql)) ;; C/C++ - (autoload 'evilmi-c-get-tag "evil-matchit-c" nil) - (autoload 'evilmi-c-jump "evil-matchit-c" nil) - (mapc (lambda (mode) - (plist-put evilmi-plugins mode '((evilmi-c-get-tag evilmi-c-jump) - (evilmi-simple-get-tag evilmi-simple-jump)))) - '(c-mode c++-mode)) - - ;; diff/patch - (autoload 'evilmi-diff-get-tag "evil-matchit-diff" nil) - (autoload 'evilmi-diff-jump "evil-matchit-diff" nil) - (mapc (lambda (mode) - (plist-put evilmi-plugins mode '((evilmi-simple-get-tag evilmi-simple-jump) - (evilmi-diff-get-tag evilmi-diff-jump)))) - '(diff-mode ffip-diff-mode magit-diff-mode)) + (evilmi-load-plugin-rules '(c-mode c++-mode) '(c simple)) + + ;; Diff/Patch + (evilmi-load-plugin-rules '(diff-mode ffip-diff-mode magit-diff-mode) + '(simple diff)) + ;; Fortran - (autoload 'evilmi-fortran-get-tag "evil-matchit-fortran" nil) - (autoload 'evilmi-fortran-jump "evil-matchit-fortran" nil) - (mapc (lambda (mode) - (plist-put evilmi-plugins mode '((evilmi-fortran-get-tag evilmi-fortran-jump)))) - '(f90-mode fortran-mode)) + (evilmi-load-plugin-rules '(f90 fortran-mode) '(fortran)) ;; CMake (http://www.cmake.org) - (autoload 'evilmi-cmake-get-tag "evil-matchit-cmake" nil) - (autoload 'evilmi-cmake-jump "evil-matchit-cmake" nil) - (plist-put evilmi-plugins 'cmake-mode '((evilmi-cmake-get-tag evilmi-cmake-jump))) + (evilmi-load-plugin-rules '(cmake-mode) '(cmake)) ;; sh-mode - (autoload 'evilmi-sh-get-tag "evil-matchit-sh" nil) - (autoload 'evilmi-sh-jump "evil-matchit-sh" nil) - (plist-put evilmi-plugins 'sh-mode '((evilmi-sh-get-tag evilmi-sh-jump))) + (evilmi-load-plugin-rules '(sh-mode) '(sh)) ;; verilog-mode - (autoload 'evilmi-verilog-get-tag "evil-matchit-verilog" nil) - (autoload 'evilmi-verilog-jump "evil-matchit-verilog" nil) - (plist-put evilmi-plugins 'verilog-mode '((evilmi-verilog-get-tag evilmi-verilog-jump))) - - ;; Lua or any fine script - (autoload 'evilmi-script-get-tag "evil-matchit-script" nil) - (autoload 'evilmi-script-jump "evil-matchit-script" nil) - (mapc (lambda (mode) - (plist-put evilmi-plugins mode '((evilmi-simple-get-tag evilmi-simple-jump) - (evilmi-script-get-tag evilmi-script-jump)))) - '(lua-mode vimrc-mode)) + (evilmi-load-plugin-rules '(verilog-mode) '(verilog)) + + ;; Lua or script + (evilmi-load-plugin-rules '(lua-mode vimrc-mode) '(simple script)) ;; css/scss/less - (mapc (lambda (mode) - (plist-put evilmi-plugins mode '((evilmi-simple-get-tag evilmi-simple-jump)))) - '(css-mode less-mode scss-mode)) + (evilmi-load-plugin-rules '(css-mode less-mode scss-mode) '(simple)) ;; Ruby - (autoload 'evilmi-ruby-get-tag "evil-matchit-ruby" nil) - (autoload 'evilmi-ruby-jump "evil-matchit-ruby" nil) - ;; @see https://github.com/syl20bnr/spacemacs/issues/2093 - ;; spacemacs use enh-ruby-mode - (mapc (lambda (mode) - (plist-put evilmi-plugins mode '((evilmi-simple-get-tag evilmi-simple-jump) - (evilmi-ruby-get-tag evilmi-ruby-jump)))) - '(ruby-mode enh-ruby-mode))) - - (autoload 'evilmi-elixir-get-tag "evil-matchit-elixir" nil) - (autoload 'evilmi-elixir-jump "evil-matchit-elixir" nil) - ;; @see https://github.com/syl20bnr/spacemacs/issues/2093 - ;; spacemacs use enh-elixir-mode - (mapc (lambda (mode) - (plist-put evilmi-plugins mode '((evilmi-simple-get-tag evilmi-simple-jump) - (evilmi-elixir-get-tag evilmi-elixir-jump)))) - '(elixir-mode)) + (evilmi-load-plugin-rules '(ruby-mode enh-ruby-mode) '(simple ruby)) + + ;; Elixir + (evilmi-load-plugin-rules '(elixir-mode enh-elixir-mode) '(simple elixir))) + (defun evilmi--region-to-select-or-delete (num &optional is-inner) (let* (where-to-jump-in-theory b e) @@ -487,7 +450,7 @@ If IS-FORWARD is t, jump forward; or else jump backward." ;;;###autoload (defun evilmi-version() (interactive) - (message "2.2.8")) + (message "2.2.9")) ;;;###autoload (define-minor-mode evil-matchit-mode diff --git a/pkg.sh b/pkg.sh index 372dae4c3d..2fef271baf 100755 --- a/pkg.sh +++ b/pkg.sh @@ -1,6 +1,6 @@ #!/bin/bash name=evil-matchit -version=2.2.8 +version=2.2.9 pkg=$name-$version mkdir $pkg cp README.org $pkg