Create your Gitee Account
Explore and code with more than 6 million developers,Free private repositories !:)
Sign up
Clone or download
sniem-operation.el 31.53 KB
Copy Edit Web IDE Raw Blame History
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891
;;; sniem-operation.el --- Simple united editing method -*- lexical-binding: t -*-
;; Author: SpringHan
;; Maintainer: SpringHan
;; This file is not part of GNU Emacs
;; This file 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, or (at your option)
;; any later version.
;; This program 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.
;; For a full copy of the GNU General Public License
;; see <http://www.gnu.org/licenses/>.
;;; Commentary:
;; Simple united editing method
;;; Code:
(require 'sniem-var)
(require 'sniem-macro)
(require 'sniem-common)
(declare-function sniem-object-catch--get-second-char "sniem-object-catch")
(declare-function sniem-current-mode "sniem")
(declare-function sniem-change-mode "sniem")
(declare-function sniem-mark-content "sniem")
(defun sniem-insert ()
"Insert at the current point or the beginning of mark region."
(interactive)
(unless (eq (sniem-current-mode) 'insert)
(when (region-active-p)
(goto-char (region-beginning))
(deactivate-mark))
(sniem-change-mode 'insert)))
(defun sniem-insert-line ()
"Insert at the beginning of line."
(interactive)
(if (region-active-p)
(goto-char (1+ (region-beginning)))
(back-to-indentation))
(sniem-insert))
(defun sniem-append ()
"Append at the next point or the end of mark region."
(interactive)
(if (region-active-p)
(progn
(goto-char (region-end))
(deactivate-mark))
(unless (= (line-end-position) (point))
(forward-char)))
(sniem-insert))
(defun sniem-append-line ()
"Append at the end of line."
(interactive)
(if (region-active-p)
(progn
(goto-char (1- (region-end)))
(deactivate-mark))
(end-of-line))
(sniem-insert))
(defun sniem-open-line ()
"Open new line."
(interactive)
(goto-char (line-end-position))
(insert "\n")
(indent-according-to-mode)
(sniem-insert))
(defun sniem-open-line-previous ()
"Open new line."
(interactive)
(beginning-of-line)
(insert "\n")
(if (bobp)
(goto-char (point-min))
(forward-line -1))
(indent-according-to-mode)
(sniem-insert))
(defun sniem-center (action)
"Center ACTION for sniem."
(interactive (list (read-char sniem-center-message)))
(pcase action
(122 (recenter nil t))
(116 (recenter-top-bottom 0))
(98 (recenter-top-bottom -1))))
(defun sniem-mark (type)
"Mark the object with action TYPE."
(interactive (list (read-char sniem-mark-message)))
(pcase type
(108
(beginning-of-line)
(push-mark (point) t t)
(end-of-line)
(setq-local sniem-mark-line t))
(112
(push-mark sniem-last-point t t)
(when sniem-last-point-locked
(sniem-lock-unlock-last-point)))
(109 (push-mark (point) t t))
(102 (mark-defun))
(98 (push-mark (point-min) t t)
(goto-char (point-max)))
(_
(let* ((space-mode (when (= type 32)
(progn
(setq type (read-char sniem-mark-message))
t)))
(thing (pcase type
(115 'symbol)
(119 'word)
(_ (user-error "[Sniem]: The %s type is error!" type))))
(points (bounds-of-thing-at-point thing)))
(when (and points space-mode
(save-mark-and-excursion
(let (l r)
(goto-char (car points))
(when (= (char-before) 32)
(setq l t))
(goto-char (cdr points))
(when (= (following-char) 32)
(setq r t))
(and l r))))
(setq points (cons (1- (car points)) (1+ (cdr points)))))
(when points
(goto-char (car points))
(push-mark (cdr points) t t))))))
(defun sniem-up-down-case ()
"Up or down case."
(interactive)
(if (region-active-p)
(let ((contents (buffer-substring-no-properties (region-beginning)
(region-end))))
(delete-region (region-beginning) (region-end))
(dolist (char (string-to-list contents))
(insert-char (if (eq (upcase char) char)
(downcase char)
(upcase char)))))
(let ((char (following-char)))
(delete-char 1)
(insert-char (if (eq (upcase char) char)
(downcase char)
(upcase char))))))
(defun sniem-replace-char (char)
"Replace the CHAR under cursor."
(interactive "c")
(delete-char 1)
(insert-char char)
(sniem-backward-char nil t))
(defun sniem-replace-word (&optional replace-word)
"Replace the word under cursor."
(interactive)
(let* ((word (if (region-active-p)
(buffer-substring-no-properties (region-beginning) (region-end))
(thing-at-point 'word t)))
(word-points (if (region-active-p)
(cons (region-beginning) (region-end))
(bounds-of-thing-at-point 'word)))
(marked-contents '("nil"))
replace-region-p replaced ov c-ov tmp)
(when (and (region-active-p)
sniem-mark-content-overlay
(listp sniem-mark-content-overlay)
(null replace-word))
(setq replace-region-p
(completing-read "Enter the marked-content or nil to input word: "
(progn
(dotimes (i (length sniem-mark-content-overlay))
(setq ov (nth i sniem-mark-content-overlay))
(setq marked-contents
(append marked-contents
(list (format
"%d- %s"
(1+ i)
(buffer-substring-no-properties
(overlay-start ov) (overlay-end ov)))))))
marked-contents))))
(if (and (not (string= "nil" replace-region-p))
(null replace-word))
(progn
(save-mark-and-excursion
(setq tmp (progn (string-match "^\\(.*\\)- \\(.*\\)" replace-region-p)
(match-string 1 replace-region-p))
c-ov (nth (1- (string-to-number tmp))
sniem-mark-content-overlay)) ;`tmp' is the number of the overlay, `c-ov' is the overlay needs to replace.
(goto-char (overlay-start c-ov))
(setq replaced (substring replace-region-p (+ 2 (length tmp)))) ;Set the rest of the contents for replace.
(delete-region (overlay-start c-ov)
(overlay-end c-ov))
(insert word)
(delete-overlay c-ov)
(setq-local sniem-mark-content-overlay
(append (list
(make-overlay (- (point) (length word)) (point)))
(delete c-ov sniem-mark-content-overlay)))
(overlay-put (car sniem-mark-content-overlay) 'face 'region))
(delete-region (region-beginning) (region-end))
(deactivate-mark))
(setq replaced (or replace-word
(read-string "Enter the new word: " word)))
(delete-region (car word-points) (cdr word-points)))
(insert replaced)))
(defun sniem-delete-char ()
"Delete the char under cursor."
(interactive)
(if (eolp)
(delete-char -1)
(unless (or (= (following-char) 32)
(= (following-char) 10))
(kill-ring-save (point) (1+ (point))))
(delete-char 1)))
(defun sniem-delete (action)
"Delete ACTION."
(interactive (list (if sniem-delete-edit
(progn
(setq-local sniem-delete-edit nil)
112)
(if (region-active-p)
t
(read-char sniem-delete-message)))))
(pcase action
((pred symbolp)
(sniem-delete-region
(region-beginning)
(if (save-mark-and-excursion
(sniem-end-of-mark t)
(and (not (eobp))
(= (point) (line-end-position))
sniem-mark-line))
(1+ (region-end))
(region-end))))
(100 (if (= (line-beginning-position) (line-end-position))
(progn
(if (bobp)
(delete-char 1)
(delete-char -1))
(forward-line))
(sniem-delete-region (line-beginning-position)
(if (= (line-end-position) (point-max))
(line-end-position)
(1+ (line-end-position)))))
(when (eobp)
(beginning-of-line)))
(68 (sniem-delete-region (line-beginning-position) (line-end-position)))
(112 (sniem-delete-region sniem-last-point (point))
(when sniem-last-point-locked
(sniem-lock-unlock-last-point)))
(101 (setq-local sniem-delete-edit t)
(sniem-lock-unlock-last-point t))))
(defun sniem-delete-in-region ()
"Delete in region."
(interactive)
(when (region-active-p)
(when (= (point) (region-beginning))
(sniem-end-of-mark))
(push-mark (1+ (region-beginning)) t t)
(goto-char (1- (region-end)))
(sniem-delete t)))
(defun sniem-delete-region (start end)
"Like `delete-region', but it will eval `kill-ring-save' to copy the region.
Argument START is the start point of the region.
Argument END is the end point of the region."
(kill-ring-save start end)
(delete-region start end))
(defun sniem-change (action)
"Change contents.
Argument ACTION is the action of change."
(interactive (list (if sniem-change-edit
(progn
(setq-local sniem-change-edit nil)
112)
(if (region-active-p)
t
(read-char sniem-change-message)))))
(pcase action
((pred symbolp) (sniem-delete t) (sniem-insert))
(99 (sniem-delete 68) (indent-according-to-mode) (sniem-insert))
(112 (sniem-delete 112) (sniem-insert))
(101 (setq-local sniem-change-edit t)
(sniem-lock-unlock-last-point t))))
(defun sniem-change-in-region ()
"Change in region."
(interactive)
(when (region-active-p)
(when (= (point) (region-beginning))
(sniem-end-of-mark))
(push-mark (1+ (region-beginning)) t t)
(goto-char (1- (region-end)))
(sniem-change t)))
(defun sniem-yank (action)
"Yank ACTION."
(interactive (list (if (region-active-p)
t
(read-char sniem-yank-message))))
(pcase action
((pred symbolp) (kill-ring-save (region-beginning) (region-end)))
(121 (kill-ring-save (line-beginning-position)
(if (= (point-max) (line-end-position))
(line-end-position)
(1+ (line-end-position)))))
(112 (kill-ring-save sniem-last-point (point))
(when sniem-last-point-locked
(sniem-lock-unlock-last-point)))))
(defun sniem-yank-in-region ()
"Yank in region."
(interactive)
(when (region-active-p)
(kill-ring-save (1+ (region-beginning)) (1- (region-end)))))
(defun sniem-paste (&optional n)
"Paste the N content in `kill-ring'."
(interactive "P")
(let ((i 0)
(regionp (when (region-active-p)
(cons (region-beginning) (region-end)))))
(unless n
(when
(catch 'n
(while (= 0
(string-to-number
(char-to-string
(setq n (read-char (format "%s:%d%s"
(sniem-paste--output-contents i)
(1+ (/ i 9))
(propertize "[n]: next page, [p]: prev page or 1, [1-9]: insert content, [q]: cancel"
'face 'font-lock-comment-face)))))))
(pcase n
(110 (setq i (+ i 9)))
(112 (if (>= i 9)
(setq i (- i 9))
(throw 'n t)))
(113 (keyboard-quit)))))
(setq n 49)))
(setq n (string-to-number (char-to-string n)))
(when regionp
(goto-char (cdr regionp))
(push-mark (car regionp) t t)
(sniem-delete t))
(insert (nth (if regionp
(+ n i)
(1- (+ n i)))
kill-ring))))
(defun sniem-paste--output-contents (n)
"Output contents for `sniem-paste'.
Argument N is the page of the contents."
(let (content c tmp)
(dotimes (i 9)
(setq c (format "%d: %s"
(1+ i)
(nth (+ i n) kill-ring))
content (concat content
(progn
(when (setq tmp (sniem-paste--include-ln-p c))
(setq c tmp))
(while (> (length c) (frame-width))
(setq c (concat (substring c 0 (1- (- (length c) (frame-width)))) "...")))
c)
"\n")))
content))
(defun sniem-paste--include-ln-p (string)
"Check if there has \n in STRING."
(let ((string-list (string-to-list string))
tmp)
(when (memq 10 string-list)
(setq tmp (delete 10 string-list)))
(when tmp
(eval `(string ,@tmp)))))
(defun sniem-paste-in-region ()
"Paste the `kill-ring' content in region."
(interactive)
(when (region-active-p)
(when (= (region-beginning) (point))
(sniem-end-of-mark))
(push-mark (1+ (region-beginning)) t t)
(goto-char (1- (region-end)))
(sniem-paste)))
(defun sniem-join ()
"Change LINE to one line."
(interactive)
(let ((last-point (point)))
(if (bolp)
(if (save-mark-and-excursion
(forward-line -1)
(= (line-beginning-position) (line-end-position)))
(forward-line -1)
(backward-char))
(backward-char)
(unless (or (= 10 (following-char))
(= 32 (following-char)))
(user-error "[Sniem]: The current position doesn't need join!")))
(while (or (= 10 (following-char))
(= 32 (following-char)))
(backward-char))
(forward-char)
(push-mark last-point t t)))
(defun sniem-macro (action)
"Macro ACTION."
(interactive (list (unless defining-kbd-macro
(read-char sniem-macro-message))))
(if defining-kbd-macro
(progn
(end-kbd-macro)
;; If the `sniem-kmacro-range' is exists, call the macro to the lines
(when sniem-kmacro-range
(let ((region-beg
(save-mark-and-excursion
(sniem-goto-line (car sniem-kmacro-range) t)
(line-beginning-position)))
(region-end
(save-mark-and-excursion
(sniem-goto-line (cdr sniem-kmacro-range) t)
(when (= (line-beginning-position) (line-end-position))
(forward-line))
(line-end-position))))
(apply-macro-to-region-lines region-beg region-end)
(setq-local sniem-kmacro-range nil))))
(when (region-active-p)
(if (= action 113)
(if (= (line-number-at-pos (region-beginning))
(line-number-at-pos (region-end)))
(setq-local sniem-kmacro-mark-content
(buffer-substring-no-properties (region-beginning) (region-end)))
(setq-local sniem-kmacro-range
(cons (1+ (line-number-at-pos (region-beginning)))
(line-number-at-pos (region-end))))
(deactivate-mark)
(goto-char (region-beginning)))
(setq-local sniem-kmacro-mark-content
(buffer-substring-no-properties (region-beginning) (region-end)))))
(pcase action
(113 (call-interactively #'start-kbd-macro))
(101 (call-last-kbd-macro))
(110 (call-interactively #'name-last-kbd-macro)))))
(defun sniem-pair (prefix &optional add)
"Modify the region's pair.
Argument PREFIX is the prefix of the pair.
Optional Argument ADD means forced to add the pair."
(interactive (list (let ((var (read-char)))
(cond ((= var 97)
(cons (read-char) t))
((= var 115)
(cons t 's))
(t var)))))
(if (eq (cdr-safe prefix) 's)
(save-mark-and-excursion
(sniem-space))
(when (cdr-safe prefix)
(setq add t
prefix (car prefix)))
(let ((second (unless (= 32 prefix)
(sniem-object-catch--get-second-char (char-to-string prefix))))
(prefix-point (region-beginning))
(second-point (region-end))
(prefix-char (buffer-substring-no-properties (region-beginning) (1+ (region-beginning)))))
(if (and (null second)
(/= prefix 32))
(user-error "[Sniem]: The pair is not exists in `sniem-object-catch-global-symbol-alist'!")
(save-mark-and-excursion
(goto-char prefix-point)
(when (and (null add)
(sniem-pair--pair-p prefix-char))
(delete-char 1))
(unless (= prefix 32)
(insert prefix))
(goto-char (if (= prefix 32)
(1- second-point)
second-point))
(if (and (null add)
(sniem-pair--pair-p prefix-char))
(delete-char -1)
(forward-char))
(unless (= prefix 32)
(insert second)))))))
(defun sniem-pair--pair-p (char-string)
"Check if the CHAR belongs to pair.
Argument CHAR-STRING is the string to compair."
(let ((alpha-list '("a" "A" "b" "B" "c" "C" "d" "D" "e" "E" "f" "F" "g" "G"
"h" "H" "i" "I" "j" "J" "k" "K" "l" "L" "m" "M" "n" "N"
"o" "O" "p" "P" "q" "Q" "r" "R" "s" "S" "t" "T" "u" "U"
"v" "V" "w" "W" "x" "X" "y" "Y" "z" "Z" "0" "1" "2" "3"
"4" "5" "6" "7" "8" "9")))
;; Write like this because `memq' and others can not work well.
(not (sniem--mems char-string alpha-list))))
(defun sniem-search (content)
"Search the CONTENT."
(interactive (list (completing-read "Enter the search content: "
search-ring)))
(sniem-next-word nil nil content)
(unless (ignore-errors
(sniem--string-equal
(buffer-substring-no-properties (region-beginning) (region-end))
content))
(sniem-prev-word nil nil content)
(unless (ignore-errors
(sniem--string-equal
(buffer-substring-no-properties (region-beginning) (region-end))
content))
(when sniem-search-result-tip
(delete-overlay sniem-search-result-tip)
(setq-local sniem-search-result-tip nil))
(message "[Sniem]: The content %S is not exsits in current buffer." content))))
(defun sniem--string-equal (string1 string2)
"Like `string-equal', but don't care the case.
STRING1 and STRING2 are the strings to compair."
(string-equal (downcase string1) (downcase string2)))
(defun sniem-space ()
"Add or delete space around the marked region."
(interactive)
(let ((marked-content (buffer-substring-no-properties
(region-beginning)
(region-end))))
(if (and (string-prefix-p " " marked-content)
(string-suffix-p " " marked-content))
(sniem-replace-word (substring marked-content 1 -1))
(sniem-replace-word (format " %s " marked-content)))))
;;; Motions
(sniem-define-motion sniem-beginning-of-line ()
"Beginning of line."
(beginning-of-line))
(sniem-define-motion sniem-end-of-line ()
"End of line."
(end-of-line))
(sniem-define-motion sniem-forward-char (&optional n)
"Forward char."
(interactive "P")
(setq n (or n 1))
(catch 'end
(while (/= n 0)
(if (eolp)
(throw 'end t)
(forward-char)
(setq n (1- n))))))
(sniem-define-motion sniem-5-forward-char ()
"Eval `sniem-forward-char' 5 times."
(sniem-forward-char 5 t))
(sniem-define-motion sniem-backward-char (&optional n)
"Backward char."
(interactive "P")
(setq n (or n 1))
(catch 'beg
(while (/= n 0)
(if (bolp)
(throw 'beg t)
(backward-char)
(setq n (1- n))))))
(sniem-define-motion sniem-5-backward-char ()
"Eval `sniem-backward-char' 5 times."
(sniem-backward-char 5 t))
(sniem-define-motion sniem-prev-line (&optional n)
"Previous line."
(interactive "P")
(let ((line (line-number-at-pos)))
(setq n (or n 1))
(unless (bobp)
(line-move (- n)))
(when (and (region-active-p) sniem-mark-line)
(when (= (line-number-at-pos) line)
(line-move -1))
(if (= (region-beginning) (point))
(beginning-of-line)
(end-of-line)))))
(sniem-define-motion sniem-5-prev-line ()
"Eval `sniem-prev-line' 5 times."
(sniem-prev-line 5 t))
(sniem-define-motion sniem-next-line (&optional n)
"Next line."
(interactive "P")
(let ((line (line-number-at-pos)))
(setq n (or n 1))
(unless (eobp)
(line-move n))
(when (and (region-active-p) sniem-mark-line)
(when (= (line-number-at-pos) line)
(line-move 1))
(if (= (region-beginning) (point))
(beginning-of-line)
(end-of-line)))))
(sniem-define-motion sniem-5-next-line ()
"Eval `sniem-next-line' 5 times."
(sniem-next-line 5 t))
(sniem-define-motion sniem-first-line ()
"Goto beginning of buffer."
(goto-char (point-min))
(when (and (region-active-p) sniem-mark-line)
(end-of-line)))
(sniem-define-motion sniem-goto-line (&optional n)
"Goto line with N."
(interactive "P")
(if (null n)
(with-no-warnings (end-of-buffer))
(goto-char (point-min))
(forward-line (1- n)))
(when (and (region-active-p) sniem-mark-line)
(end-of-line)))
(sniem-define-motion sniem-scroll-up-command (&optional n)
"Scroll up."
(interactive "P")
(scroll-up-command n)
(when (and (region-active-p) sniem-mark-line)
(end-of-line)))
(sniem-define-motion sniem-scroll-down-command (&optional n)
"Scroll down."
(interactive "P")
(scroll-down-command n)
(when (and (region-active-p) sniem-mark-line)
(end-of-line)))
(sniem-define-motion sniem-find-forward (&optional n c no-hint)
"Find CHAR forward."
(interactive "P")
(let ((char (if c
c
(read-char))))
(if n
(dotimes (_ n)
(sniem-find char 'forward))
(sniem-find char 'forward))
(when (region-active-p)
(sniem-forward-char nil t))
(unless no-hint
(sniem-motion-hint `(lambda () (interactive)
(sniem-find-forward nil ,char t t))))))
(sniem-define-motion sniem-find-backward (&optional n c no-hint)
"Find CHAR backward."
(interactive "P")
(let ((char (if c
c
(read-char))))
(if n
(dotimes (_ n)
(sniem-find char 'backward))
(sniem-find char 'backward))
(unless no-hint
(sniem-motion-hint `(lambda () (interactive)
(sniem-find-backward nil ,char t t))))))
(defun sniem-find (char direct)
"Find CHAR.
Argument DIRECT is the direction for find."
(let ((current-point (point))
(way (pcase direct
('forward 'sniem-forward-char)
('backward 'sniem-backward-char)
(_ (user-error "[Sniem]: The direction for finding is error!")))))
(funcall way nil t)
(while (not (or (eolp) (bolp) (eq (following-char) char)))
(funcall way nil t))
(when (/= char (following-char))
(goto-char current-point))))
(sniem-define-motion sniem-next-word (&optional n no-hint word)
"Move to next word. If the region is active, goto the next word which is same as it."
(interactive "P")
(if (or (region-active-p) word sniem-kmacro-mark-content)
(let ((word (cond (word word)
(sniem-kmacro-mark-content
(prog1 sniem-kmacro-mark-content
(setq-local sniem-kmacro-mark-content nil)))
(t (buffer-substring-no-properties (region-beginning)
(region-end)))))
tmp)
(when (region-active-p)
(when (= (point) (region-beginning))
(goto-char (region-end))))
(setq tmp (search-forward word nil t))
(if tmp
(progn
(when (region-active-p)
(deactivate-mark))
(push-mark (- (point) (length word)) t t)
(sniem-add-to-history word))
(when (= (point) (region-end))
(push-mark (- (point) (length word)) t t)))
(unless no-hint
(sniem-search--check-result word)))
(forward-word n))
(unless no-hint
(sniem-motion-hint `(lambda () (interactive)
(sniem-next-word ,n t ,word t)))))
(sniem-define-motion sniem-prev-word (&optional n no-hint word)
"Move to prev word. If the region is active, goto the prev word which is same as it."
(interactive "P")
(if (or (region-active-p) word sniem-kmacro-mark-content)
(let ((word (cond (word word)
(sniem-kmacro-mark-content
(prog1 sniem-kmacro-mark-content
(setq-local sniem-kmacro-mark-content nil)))
(t (buffer-substring-no-properties (region-beginning)
(region-end)))))
tmp)
(when (region-active-p)
(unless (= (point) (region-beginning))
(setq tmp (region-end))
(goto-char (region-beginning))
(push-mark tmp t t)))
(setq tmp (search-backward word nil t))
(when tmp
(when (region-active-p)
(deactivate-mark))
(push-mark (point) t t)
(goto-char (+ (point) (length word)))
(sniem-add-to-history word))
(unless no-hint
(sniem-search--check-result word)))
(backward-word n))
(unless no-hint
(sniem-motion-hint `(lambda () (interactive)
(sniem-prev-word ,n t ,word t)))))
(defun sniem-search--check-result (word)
"Check the search result.
WORD is the search content.
If it's the first, print first at the end of the line.
Else if it's the last, print last, or it's the only one, print only."
(when sniem-search-result-tip
(delete-overlay sniem-search-result-tip)
(setq-local sniem-search-result-tip nil))
(let ((first (save-mark-and-excursion
(goto-char (region-beginning))
(not (search-backward word nil t))))
(end (save-mark-and-excursion
(goto-char (region-end))
(not (search-forward word nil t)))))
(cond ((and first end)
(sniem-search--add-overlay " [ONLY]"))
(first
(sniem-search--add-overlay " [FIRST]"))
(end
(sniem-search--add-overlay " [END]")))))
(defun sniem-search--add-overlay (content)
"Add the tip overlay with CONTENT."
(let ((ov (make-overlay (line-end-position) (1+ (line-end-position)))))
(overlay-put ov 'face 'font-lock-comment-face)
(overlay-put ov 'display (concat content "\n"))
(setq-local sniem-search-result-tip ov)))
(defun sniem-add-to-history (search)
"Add the SEARCH content to the `search-ring'."
(if (sniem--mems (downcase search) search-ring)
(unless (string-equal (downcase search) (car search-ring))
(setq search-ring (delete (downcase search) search-ring))
(add-to-history 'search-ring (downcase search) search-ring-max))
(add-to-history 'search-ring (downcase search) search-ring-max)))
(sniem-define-motion sniem-next-symbol (&optional n)
"Move to next symbol."
(interactive "P")
(unless n
(setq n 1))
(forward-symbol n)
(sniem-motion-hint `(lambda () (interactive)
(forward-symbol ,n))))
(sniem-define-motion sniem-prev-symbol (&optional n)
"Move to previous symbol."
(interactive "P")
(unless n
(setq n 1))
(forward-symbol (- 0 n))
(sniem-motion-hint `(lambda () (interactive)
(forward-symbol (- 0 ,n)))))
(sniem-define-motion sniem-beg-of-mark ()
"Goto the beginning of mark."
(when (region-active-p)
(let ((end-point (region-end)))
(goto-char (region-beginning))
(push-mark end-point t t))))
(sniem-define-motion sniem-end-of-mark ()
"Goto the end of mark."
(when (region-active-p)
(let ((beg-point (region-beginning)))
(goto-char (region-end))
(push-mark beg-point t t))))
(sniem-define-motion sniem-goto-prev ()
"Goto prev lines with `sniem-digit-argument-get'."
(sniem-prev-line (sniem-digit-argument-get "Move up: ") t)
(when (and (region-active-p) sniem-mark-line)
(end-of-line)))
(sniem-define-motion sniem-goto-next ()
"Goto next lines with `sniem-digit-argument-get'."
(sniem-next-line (sniem-digit-argument-get "Move down: ") t)
(when (and (region-active-p) sniem-mark-line)
(end-of-line)))
(defun sniem-goto-last-point (&optional type non-point-set)
"Goto `sniem-last-point'.
Optional argument TYPE is the type of the point to go.
Optional argument NON-POINT-SET means not change the last-point."
(interactive "P")
(let ((current-point (point)))
(if (or (eq 0 type) (null sniem-mark-content-overlay))
(goto-char sniem-last-point)
(goto-char
(if (= 1 (length sniem-mark-content-overlay))
(overlay-start (car sniem-mark-content-overlay)) ;Goto the first marked-content if there's only one overlay.
(let ((current-ov (sniem--list-memq sniem-mark-content-overlay
(overlays-at (point)) 'index))
(notice (lambda (n)
(message "[Sniem]: Jumped to: %d" n)))
next-ov)
(cond ((and (numberp type)
(<= type (length sniem-mark-content-overlay)))
(funcall notice type)
(overlay-start (nth (1- type) sniem-mark-content-overlay)))
((null current-ov)
(funcall notice 1)
(overlay-start (car sniem-mark-content-overlay)))
((and (numberp type)
(> type (length sniem-mark-content-overlay)))
(user-error "[Sniem]: The number %d of marked-content can't be found!"
type))
(t (setq next-ov (nth (1+ current-ov) sniem-mark-content-overlay))
(if (null next-ov)
(progn
(funcall notice 1)
(overlay-start (car sniem-mark-content-overlay))) ;If the current overlay is the last, goto the first one.
(funcall notice (+ 2 current-ov))
(overlay-start next-ov))))))))
(unless (or sniem-last-point-locked non-point-set)
(setq-local sniem-last-point current-point))))
(provide 'sniem-operation)
;;; sniem-operation.el ends here

Comment ( 0 )

Sign in for post a comment