[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[nongnu] elpa/evil-matchit 130941b1a4 193/244: can jump from end of html
From: |
ELPA Syncer |
Subject: |
[nongnu] elpa/evil-matchit 130941b1a4 193/244: can jump from end of html self closing tag |
Date: |
Thu, 6 Jan 2022 02:59:01 -0500 (EST) |
branch: elpa/evil-matchit
commit 130941b1a436f100cdab0f28b3f67d0f85224d4f
Author: Chen Bin <chenbin.sh@gmail.com>
Commit: Chen Bin <chenbin.sh@gmail.com>
can jump from end of html self closing tag
---
evil-matchit-html.el | 60 +++++++++++++++-----------
evil-matchit-javascript.el | 2 +-
evil-matchit-sdk.el | 68 ++++++++++++++++++++++--------
evil-matchit-simple.el | 21 ++++++----
evil-matchit.el | 102 +++++++++++----------------------------------
5 files changed, 125 insertions(+), 128 deletions(-)
diff --git a/evil-matchit-html.el b/evil-matchit-html.el
index 33ae906795..c4dd715dbd 100644
--- a/evil-matchit-html.el
+++ b/evil-matchit-html.el
@@ -39,24 +39,27 @@ It starts from POSITION and possibly ends at line end."
(buffer-substring position (line-end-position)))))
(car (split-string partial-line "[ \t]+"))))
-;;;###autoload
-(defun evilmi-html-get-tag ()
- "Get current tag."
- (let* ((b (line-beginning-position))
- (e (line-end-position))
+(defun evilmi-html--detect-self-closing-tag-end (char position)
+ "Use CHAR at POSITION to test if it's the end of self closing tag.
+If at the end of self closing tag, "
+ (when (or (and (eq char ?>)
+ (eq (evilmi-sdk-get-char (1- position)) ?/))
+ (and (eq char ?/)
+ (eq (evilmi-sdk-get-char (1+ position)) ?>)))
+ (list (if (eq char ?>) position (1+ position)) 1 "")))
+
+(defun evilmi-html--detect-normal-tags (char position)
+ "Test one of matched tags or beginning of self closing tag."
+ (let* ((begin (line-beginning-position))
+ (end (line-end-position))
(looping t)
- (char (following-char))
- (p (point))
(found_tag -1))
-
- (if evilmi-debug (message "evilmi-html-get-tag called. p=%s" p))
(save-excursion
;; search backward for "<"
(unless (eq char ?<)
- (while (and looping (<= b (point)) (not (eq char ?<)))
+ (while (and looping (<= begin (point)) (not (eq char ?<)))
(setq char (following-char))
- (setq p (point))
- (if (eq p (point-min))
+ (if (eq (setq position (point)) (point-min))
;; need get out of loop anyway
(setq looping nil)
(backward-char))))
@@ -64,20 +67,20 @@ It starts from POSITION and possibly ends at line end."
;; search forward for "<"
(unless (eq char ?<)
(save-excursion
- (while (and (>= e (point)) (not (eq char ?<)))
+ (while (and (>= end (point)) (not (eq char ?<)))
(setq char (following-char))
- (setq p (point))
+ (setq position (point))
(forward-char))))
;; a valid html tag should be like <[^;]
(unless (and (eq char ?<)
;; html tags should not contain " ,;"
- (string-match "^<[^ ;,]+$" (evilmi-html--open-tag-candidate
p)))
+ (string-match "^<[^ ;,]+$" (evilmi-html--open-tag-candidate
position)))
(setq char nil))
;; is end tag?
- (when (and (eq char ?<) (< p e))
- (goto-char p)
+ (when (and (eq char ?<) (< position end))
+ (goto-char position)
(forward-char)
(cond
((eq (following-char) ?/)
@@ -89,24 +92,33 @@ It starts from POSITION and possibly ends at line end."
;; < , looks fine
(backward-char)
(setq found_tag 0)))
- (setq p (point))))
+ (setq position (point))))
(when (eq found_tag 0)
- ;; sgml-skip-tag-forward can't handle the open html tag whose attribute
containing "<" or ">" character
- ;; UNLESS the start position is above "<" character
- (goto-char p) ; move to the closest "<"
+ ;; `sgml-skip-tag-forward' can't handle the open html tag whose
attribute containing "<" or ">" character
+ ;; unless the start position is above "<" character
+ (goto-char position) ; move to the closest "<"
(when (or (evilmi-among-fonts-p (point) evilmi-ignored-fonts)
;; In `rjsx-mode', the attribute value's font face could be nil
;; like <Component a1={3 > 2} />
(and (eq ?< (following-char))
;; if it's html tag, the character next "<" should
;; have some font face
- (not (get-text-property (1+ p) 'face))))
+ (not (get-text-property (1+ position) 'face))))
;; since current "<" is not part of open html tag,
;; skip backward to move cursor over the "<" of open html tag
(sgml-skip-tag-backward 1)
- (setq p (point))))
- (list p found_tag "")))
+ (setq position (point))))
+ (list position found_tag "")))
+
+;;;###autoload
+(defun evilmi-html-get-tag ()
+ "Get current tag."
+ (let* ((char (following-char))
+ (position (point)))
+ (if evilmi-debug (message "evilmi-html-get-tag called. position" position))
+ (or (evilmi-html--detect-self-closing-tag-end char position)
+ (evilmi-html--detect-normal-tags char position))))
;;;###autoload
(defun evilmi-html-jump (info num)
diff --git a/evil-matchit-javascript.el b/evil-matchit-javascript.el
index 3a8477361a..3949502b37 100644
--- a/evil-matchit-javascript.el
+++ b/evil-matchit-javascript.el
@@ -100,7 +100,7 @@
evilmi-javascript-match-tags
evilmi-javascript-extract-keyword-howtos))
(t
- (evilmi--simple-jump)
+ (evilmi-sdk-simple-jump)
(let* ((cur-line (evilmi-sdk-curline)))
;; hack for javascript
(if (or (string-match "^[ \t]*}\)\(.*\)\; *$" cur-line)
diff --git a/evil-matchit-sdk.el b/evil-matchit-sdk.el
index 1526cc3627..0f22e387a2 100644
--- a/evil-matchit-sdk.el
+++ b/evil-matchit-sdk.el
@@ -1,6 +1,10 @@
(defvar evilmi-debug nil
"Debug flag.")
+(defvar evilmi-forward-chars (string-to-list "[{("))
+(defvar evilmi-backward-chars (string-to-list "]})"))
+(defvar evilmi-quote-chars (string-to-list "'\"/"))
+
(defvar evilmi-ignored-fonts
'(web-mode-html-attr-value-face
font-lock-string-face
@@ -17,15 +21,41 @@ 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.")
-;; slower but I don't care
-;; @see http://ergoemacs.org/emacs/modernization_elisp_lib_problem.html
-(defun evilmi-sdk-trim-string (string)
- (replace-regexp-in-string "\\`[ \t\n]*" "" (replace-regexp-in-string "[
\t\n]*\\'" "" string)))
-
-(defun evilmi-sdk-keyword (info)
- (nth 3 info))
-
-(defun evilmi-sdk-tags-is-matched (level orig-tag-info cur-tag-info match-tags)
+(defmacro evilmi-sdk-keyword (info)
+ "Get keyword from INFO."
+ `(nth 3 ,info))
+
+(defun evilmi-sdk-jump-forward-p ()
+ "Return: (forward-direction font-face-under-cursor character-under-cursor).
+If font-face-under-cursor is NOT nil, the quoted string is being processed."
+ (let* ((ch (following-char))
+ (p (point))
+ ff
+ (rlt t))
+ (cond
+ ((memq ch evilmi-backward-chars)
+ (setq rlt nil))
+ ((and (memq ch evilmi-quote-chars))
+ (setq rlt (eq (setq ff (get-text-property p 'face))
+ (get-text-property (+ 1 p) 'face)))))
+
+ (when evilmi-debug
+ (message "evilmi-sdk-jump-forward-p => (%s %s %s)" rlt ff (string ch)))
+ (list rlt ff ch)))
+
+(defun evilmi-sdk-simple-jump ()
+ "Alternative for `evil-jump-item'."
+ (if evilmi-debug (message "evilmi-sdk-simple-jump called (point)=%d"
(point)))
+ (let* ((tmp (evilmi-sdk-jump-forward-p))
+ (jump-forward (car tmp))
+ ;; if ff is not nil, it's jump between quotes
+ ;; so we should not use (scan-sexps)
+ (ff (nth 1 tmp))
+ (ch (nth 2 tmp)))
+ (goto-char (evilmi--find-position-to-jump ff jump-forward ch))
+ (evilmi--tweak-selected-region ff jump-forward)))
+
+(defun evilmi-sdk-tags-matched-p (level orig-tag-info cur-tag-info match-tags)
(let* (rlt
(orig-keyword (evilmi-sdk-keyword orig-tag-info))
(cur-keyword (evilmi-sdk-keyword cur-tag-info))
@@ -131,14 +161,14 @@ is-function-exit-point could be unknown status"
rlt))
(defun evilmi--sdk-extract-keyword (cur-line match-tags howtos)
- "Extract keyword from CUR-LINE. Keyword is defined in MATCH-TAGS."
+ "Extract keyword from CUR-LINE. Keyword is defined in MATCH-TAGS.
+Rule is looked up in HOWTOS."
(let* (keyword howto (i 0))
(while (and (not keyword) (< i (length howtos)))
(setq howto (nth i howtos))
(when (string-match (nth 0 howto) cur-line)
;; keyword should be trimmed because FORTRAN use "else if"
- (setq keyword (evilmi-sdk-trim-string (match-string (nth 1 howto)
- cur-line)))
+ (setq keyword (string-trim (match-string (nth 1 howto) cur-line)))
;; keep search keyword by using next howto (regex and match-string
index)
(unless (evilmi-sdk-member keyword match-tags) (setq keyword nil)))
(setq i (1+ i)))
@@ -166,6 +196,10 @@ is-function-exit-point could be unknown status"
(setq rlt t)))
rlt))
+(defmacro evilmi-sdk-get-char (position)
+ "Get character at POSITION."
+ `(char-after ,position))
+
;;;###autoload
(defun evilmi-sdk-get-tag (match-tags howtos)
"Return '(start-point ((row column is-function-exit-point keyword))."
@@ -214,14 +248,14 @@ after calling this function."
;; handle open tag
;; open (0) -> mid (1) found when level is one else ignore
((and (= orig-tag-type 0) (= cur-tag-type 1))
- (when (evilmi-sdk-tags-is-matched level orig-tag-info cur-tag-info
match-tags)
+ (when (evilmi-sdk-tags-matched-p level orig-tag-info cur-tag-info
match-tags)
(back-to-indentation)
(setq ideal-dest (1- (line-beginning-position)))
(setq found t)))
;; open (0) -> closed (2) found when level is zero, level--
((and (= orig-tag-type 0) (= cur-tag-type 2))
- (when (evilmi-sdk-tags-is-matched level orig-tag-info cur-tag-info
match-tags)
+ (when (evilmi-sdk-tags-matched-p level orig-tag-info cur-tag-info
match-tags)
(goto-char (line-end-position))
(setq ideal-dest (line-end-position))
(setq found t))
@@ -239,14 +273,14 @@ after calling this function."
;; level is one means we are not in some embedded loop/conditional
statements
((and (= orig-tag-type 1) (= cur-tag-type 1))
- (when (evilmi-sdk-tags-is-matched level orig-tag-info cur-tag-info
match-tags)
+ (when (evilmi-sdk-tags-matched-p level orig-tag-info cur-tag-info
match-tags)
(back-to-indentation)
(setq ideal-dest (1- (line-beginning-position)))
(setq found t)))
;; mid (1) -> closed (2) found when level is zero, level --
((and (= orig-tag-type 1) (= cur-tag-type 2))
- (when (evilmi-sdk-tags-is-matched level orig-tag-info cur-tag-info
match-tags)
+ (when (evilmi-sdk-tags-matched-p level orig-tag-info cur-tag-info
match-tags)
(goto-char (line-end-position))
(setq ideal-dest (line-end-position))
(setq found t))
@@ -266,7 +300,7 @@ after calling this function."
;; closed (2) -> open (0) found when level is zero, level--
((and (= orig-tag-type 2) (= cur-tag-type 0))
- (when (evilmi-sdk-tags-is-matched level orig-tag-info cur-tag-info
match-tags)
+ (when (evilmi-sdk-tags-matched-p level orig-tag-info cur-tag-info
match-tags)
(setq ideal-dest (line-beginning-position))
(back-to-indentation)
(setq found t))
diff --git a/evil-matchit-simple.el b/evil-matchit-simple.el
index 9e2f972239..3a2808efe9 100644
--- a/evil-matchit-simple.el
+++ b/evil-matchit-simple.el
@@ -65,13 +65,9 @@
(defun evilmi-simple-get-tag ()
"Get current tag in simple language."
(let* (forward-line-num
- ;; Only handle open tag
- (tmp (evilmi--get-char-under-cursor))
- (ch (if tmp (car tmp)))
+ (ch (following-char))
rlt)
- (if evilmi-debug (message "evilmi-simple-get-tag called => ch=%s
(point)=%d" ch (point)))
-
(cond
;; In evil-visual-state, the (preceding-char) is actually the character
under cursor
((not (evilmi--char-is-simple ch))
@@ -82,16 +78,23 @@
(forward-line (1- forward-line-num))
(search-forward "{" nil nil)
(backward-char)))
+ ((and (memq ch evilmi-quote-chars)
+ (eq ch ?/)
+ (not (eq ?* (evilmi-sdk-get-char (1- (point)))))
+ (not (eq ?* (evilmi-sdk-get-char (1+ (point))))))
+ ;; character at point is not "/*" or "*/"
+ (setq rlt nil))
(t
- ;; use evil's own evilmi--simple-jump
+ ;; use evil's own evilmi-sdk-simple-jump
(setq rlt (list (point)))))
- (if (and evilmi-debug rlt) (message "evilmi-simple-get-tag called rlt=%s"
rlt))
+ (if (and evilmi-debug rlt) (message "evilmi-simple-get-tag called char=%s
=> %s" ch rlt))
rlt))
;;;###autoload
(defun evilmi-simple-jump (info num)
- "Use INFO of current tag ot jump to matching tag. NUM is ignored."
+ "Use INFO of current tag to jump to matching tag. NUM is ignored."
+ (ignore num)
(when info
(if evilmi-debug (message "evilmi-simple-jump called (point)=%d" (point)))
@@ -101,7 +104,7 @@
((memq major-mode '(latex-mode))
(evil-jump-item))
(t
- (evilmi--simple-jump)))
+ (evilmi-sdk-simple-jump)))
;; hack for javascript
(cond
diff --git a/evil-matchit.el b/evil-matchit.el
index 81d56f14d8..6d2e9ef0c3 100644
--- a/evil-matchit.el
+++ b/evil-matchit.el
@@ -67,64 +67,26 @@ Some people prefer using \"m\" instead.")
"`major-mode' like `python-mode' use optimized algorithm by default.
If it's t, use simple jump.")
-(defvar evilmi-forward-chars (string-to-list "[{("))
-(defvar evilmi-backward-chars (string-to-list "]})"))
-(defvar evilmi-quote-chars (string-to-list "'\"/"))
-
(defun evilmi--char-is-simple (ch)
"Special handling of character CH for `python-mode'."
- (let* (rlt)
- (cond
- ((and (not evilmi-always-simple-jump)
- (memq major-mode '(python-mode))
- ;; in evil-visual-state, (point) could equal to (line-end-position)
- (>= (point) (1- (line-end-position))))
- ;; handle follow python code,
- ;;
- ;; if true:
- ;; a = "hello world"
- ;;
- ;; If current cursor is at end of line, rlt should be nil!
- ;; or else, matching algorithm can't work in above python sample
- (setq rlt nil))
- (t
- (setq rlt (or (memq ch evilmi-forward-chars)
- (memq ch evilmi-backward-chars)
- ;; sorry we could not jump between ends of string in
python-mode
- (memq ch evilmi-quote-chars)))))
- rlt))
-
-(defun evilmi--get-char-at-position (pos)
- "Get character at POS."
- (let* ((ch (char-after pos)))
- (if evilmi-debug (message "evilmi--get-char-at-position called. Return:
%s" (string ch)))
- ch))
-
-(defun evilmi--get-char-under-cursor ()
- "Return: (character position)."
- (let* ((ch (following-char))
- (p (point)))
- (if evilmi-debug (message "evilmi--get-char-under-cursor called. Return:
(%d %s)" ch p))
- (list ch p)))
-
-(defun evilmi--is-jump-forward ()
- "Return: (forward-direction font-face-under-cursor character-under-cursor).
-If font-face-under-cursor is NOT nil, the quoted string is being processed."
- (if evilmi-debug (message "evilmi--is-jump-forward called"))
- (let* ((tmp (evilmi--get-char-under-cursor))
- (ch (car tmp))
- (p (cadr tmp))
- ff
- (rlt t))
- (cond
- ((memq ch evilmi-backward-chars)
- (setq rlt nil))
- ((memq ch evilmi-quote-chars)
- (setq rlt (eq (setq ff (get-text-property p 'face))
- (get-text-property (+ 1 p) 'face)))))
-
- (if evilmi-debug (message "evilmi--is-jump-forward return (%s %s %s)" rlt
ff (string ch)))
- (list rlt ff ch)))
+ (cond
+ ((and (not evilmi-always-simple-jump)
+ (memq major-mode '(python-mode))
+ ;; in evil-visual-state, (point) could equal to (line-end-position)
+ (>= (point) (1- (line-end-position))))
+ ;; handle follow python code,
+ ;;
+ ;; if true:
+ ;; a = "hello world"
+ ;;
+ ;; If current cursor is at end of line, rlt should be nil!
+ ;; or else, matching algorithm can't work in above python sample
+ nil)
+ (t
+ (or (memq ch evilmi-forward-chars)
+ (memq ch evilmi-backward-chars)
+ ;; sorry we could not jump between ends of string in python-mode
+ (memq ch evilmi-quote-chars)))))
(defun evilmi-in-comment-p (pos)
"Check character at POS is comment by comparing font face."
@@ -132,11 +94,11 @@ If font-face-under-cursor is NOT nil, the quoted string is
being processed."
;; @see https://github.com/redguardtoo/evil-matchit/issues/92
((eq major-mode 'tuareg-mode)
(evilmi-among-fonts-p pos '(font-lock-comment-face
- font-lock-comment-delimiter-face
- font-lock-doc-face)))
+ font-lock-comment-delimiter-face
+ font-lock-doc-face)))
(t
(evilmi-among-fonts-p pos '(font-lock-comment-face
-
font-lock-comment-delimiter-face)))))
+ font-lock-comment-delimiter-face)))))
(defun evilmi--scan-sexps (is-forward)
"Get the position of matching tag.
@@ -195,7 +157,7 @@ If IS-FORWARD is t, jump forward; or else jump backward."
(while (not got)
(cond
((or (= pos end)
- (and (= char (evilmi--get-char-at-position (- pos delta)))
+ (and (= char (evilmi-sdk-get-char (- pos delta)))
(not (eq font-face (get-text-property pos 'face)))))
(setq rlt (if is-forward pos (+ 1 pos)))
(setq got t))
@@ -213,11 +175,10 @@ If IS-FORWARD is t, jump forward; or else jump backward."
;; @see
http://emacs.stackexchange.com/questions/13222/a-elisp-function-to-jump-between-matched-pair
(defun evilmi--find-position-to-jump (ff is-forward ch)
- (if evilmi-debug (message "evilmi--find-position-to-jump called => %s %s %s
%d" ff is-forward ch (point)))
"Non-nil ff means jumping between quotes"
(let* ((rlt (if ff (evilmi--find-the-other-quote-char ff is-forward ch)
(evilmi--scan-sexps is-forward))))
- (if evilmi-debug (message "evilmi--find-position-to-jump return %s"
(evilmi--adjust-jumpto is-forward rlt)))
+ (if evilmi-debug (message "evilmi--find-position-to-jump => %s"
(evilmi--adjust-jumpto is-forward rlt)))
(evilmi--adjust-jumpto is-forward rlt)))
(defun evilmi--tweak-selected-region (font-face jump-forward)
@@ -228,19 +189,6 @@ If IS-FORWARD is t, jump forward; or else jump backward."
;; so hack to workaround scan-sexps is NOT necessary
(evil-backward-char)))
-(defun evilmi--simple-jump ()
- "Alternative for `evil-jump-item'."
- (interactive)
- (if evilmi-debug (message "evilmi--simple-jump called (point)=%d" (point)))
- (let* ((tmp (evilmi--is-jump-forward))
- (jump-forward (car tmp))
- ;; if ff is not nil, it's jump between quotes
- ;; so we should not use (scan-sexps)
- (ff (nth 1 tmp))
- (ch (nth 2 tmp)))
- (goto-char (evilmi--find-position-to-jump ff jump-forward ch))
- (evilmi--tweak-selected-region ff jump-forward)))
-
(defun evilmi--operate-on-item (num &optional func)
"Jump NUM times and apply function FUNC."
(when evilmi-debug
@@ -268,10 +216,10 @@ If IS-FORWARD is t, jump forward; or else jump backward."
(when evilmi-debug
(message "rlt=%s rule=%s p=%s jumped=%s" rlt rule (point) jumped))))
- ;; give `evilmi--simple-jump' a second chance
+ ;; give `evilmi-sdk-simple-jump' a second chance
(unless jumped
(if func (funcall func (list (point))))
- (evilmi--simple-jump)
+ (evilmi-sdk-simple-jump)
(setq ideal-dest (point)))
(if evilmi-debug (message "evilmi--operate-on-item called. Return: %s"
ideal-dest))
- [nongnu] elpa/evil-matchit 2df3a62a8b 222/244: Add a regression test, (continued)
- [nongnu] elpa/evil-matchit 2df3a62a8b 222/244: Add a regression test, ELPA Syncer, 2022/01/06
- [nongnu] elpa/evil-matchit d7ad7f712b 235/244: emacs 28 changed API define-obsolete-function-alias. It is EVIL code. Not my code, ELPA Syncer, 2022/01/06
- [nongnu] elpa/evil-matchit d1f59ad941 225/244: Merge pull request #131 from nbfalcon/bugfix/evilmi-sdk-simple-jump-whitespace, ELPA Syncer, 2022/01/06
- [nongnu] elpa/evil-matchit ccc2cc8a62 221/244: `evilmi-sdk-simple-jump': skip whitespace, ELPA Syncer, 2022/01/06
- [nongnu] elpa/evil-matchit 8862d8ea15 079/244: support for statement in lua-mode, ELPA Syncer, 2022/01/06
- [nongnu] elpa/evil-matchit 79ec08d921 113/244: add more verilog keywords, ELPA Syncer, 2022/01/06
- [nongnu] elpa/evil-matchit e9f77f7d6a 115/244: user can use less optimized algorithm, ELPA Syncer, 2022/01/06
- [nongnu] elpa/evil-matchit 304f22100e 136/244: handle ruby statement after assign operator, ELPA Syncer, 2022/01/06
- [nongnu] elpa/evil-matchit 6cfdbe895f 153/244: [chen] add support for react-mode and typescript-tsx-mode, ELPA Syncer, 2022/01/06
- [nongnu] elpa/evil-matchit e137a380ee 148/244: Merge pull request #91 from Khady/ocaml-check-keywords, ELPA Syncer, 2022/01/06
- [nongnu] elpa/evil-matchit 130941b1a4 193/244: can jump from end of html self closing tag,
ELPA Syncer <=
- [nongnu] elpa/evil-matchit 1c758b5b52 227/244: Fix byte compiling, ELPA Syncer, 2022/01/06
- [nongnu] elpa/evil-matchit 2b9b68770a 219/244: fixed: cannot jump back from the line end in visual mode, ELPA Syncer, 2022/01/06
- [nongnu] elpa/evil-matchit 69807cf829 241/244: use semantic api to improve simple jump algorithm, ELPA Syncer, 2022/01/06
- [nongnu] elpa/evil-matchit 6254f7c812 220/244: fixed CI, ELPA Syncer, 2022/01/06