-
Notifications
You must be signed in to change notification settings - Fork 31
/
evil-matchit-org.el
114 lines (96 loc) · 3.78 KB
/
evil-matchit-org.el
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
;;; evil-matchit-org.el --- org-mode plugin of evil-matchit -*- lexical-binding: t; -*-
;; Copyright (C) 2014-2021 Chen Bin
;; Author: Chen Bin
;; 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/>.
;;; Commentary:
;;
;;; Code:
;; 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
'(("^[ \t]*#\\+\\([a-zA-Z_]+\\).*$" 1)
("^[ \t]*\\:\\([a-zA-Z_]+\\)\\:$" 1))
"How to extract keyword from current line. Each howto is a pair.
First item of pair is regex to match current line.
Second is index of sub-match to extract keyword.
Sub-match is the match defined between '\\(' and '\\)' in regular expression.")
(defvar evilmi-org-match-tags
'((("begin_src") () ("end_src") "MONOGAMY")
(("begin_example") () ("end_example") "MONOGAMY")
(("begin_html") () ("end_html") "MONOGAMY")
(("begin_quote") () ("end_quote") "MONOGAMY")
(("begin_export") () ("end_export") "MONOGAMY")
(("begin_verse") () ("end_verse") "MONOGAMY")
(("begin_center") () ("end_center") "MONOGAMY")
(("begin_comment") () ("end_comment") "MONOGAMY")
(("begin_export") () ("end_export") "MONOGAMY")
(("begin_justifyleft") () ("end_justifyleft") "MONOGAMY")
(("begin_justifyright") () ("end_justifyright") "MONOGAMY")
(("results") () ("end") "MONOGAMY"))
"Match tags in org file.")
(defun evilmi--element-property (property element)
"Extract the value from the PROPERTY of an ELEMENT."
(unless (stringp element)
;; `org-element-property' is not used because it's
;; available only in 24.4+
(plist-get (nth 1 element) property)))
(defun evilmi--get-embedded-language-major-mode ()
"Get major of embedded snippet."
(let* ((lang (evilmi--element-property :language (org-element-at-point))))
(when lang
(cond
((string= lang "elisp")
'emacs-lisp-mode)
(t
(intern (concat lang "-mode")))))))
;;;###autoload
(defun evilmi-org-get-tag ()
"Get current tag in org file."
(let* ((rlt (evilmi-sdk-get-tag evilmi-org-match-tags
evilmi-org-extract-keyword-howtos)))
;; evilmi-org-jump knows what -1 means
(unless rlt (setq rlt '(-1)))
rlt))
(defvar evilmi-plugins)
;;;###autoload
(defun evilmi-org-jump (info num)
"Jump to the matching tag using INFO and NUM."
(cond
((< (car info) 0)
(let* (jumped
info
(lang-f (evilmi--get-embedded-language-major-mode))
(plugin (and lang-f (plist-get evilmi-plugins lang-f))))
(when plugin
(mapc
(lambda (elem)
(setq info (funcall (nth 0 elem)))
(when (and info (not jumped))
;; jump only once if the jump is successful
(setq jumped t)))
plugin))))
(t
(evilmi-sdk-jump info
num
evilmi-org-match-tags
evilmi-org-extract-keyword-howtos))))
(provide 'evil-matchit-org)
;;; evil-matchit-org.el ends here