我想在特殊字符之间删除封闭文本,如:[“{'<(等等。这样我就可以删除文本,例如”这是一个非常......很长的文字“使用简单的键盘快捷键。我正在寻找一些已经存在的模式,它执行类似的操作,但我没有找到任何类似的,所以我创建了一些在大多数情况下表现良好的lisp代码,但是它在所有情况下都无法正常工作。例如如果我有以下文本条目并且我将光标放在“^”位置,那么我将谎言删除所有包含的文本“但它不起作用:
“aaaaa”> [更多文字] aaaaa“
------------ ^
我的lisp代码如下:
;; returns the enclosing character for the character "c"
(defun get-enc-char (c) (cond
((string= c "(") ")")
((string= c "[") "]")
((string= c "{") "}")
((string= c ">") "<")
((string= c "<") ">")
((string= c "'") "'")
((string= c "\"") "\"")
(t nil)
)
)
(defun delete-enclosed-text ()
"Delete texts between any pair of delimiters."
(interactive)
(save-excursion
(let (p1 p2 mychar)
; look for one of those characters and store the cursor position
(skip-chars-backward "^([\'\"><{") (setq p1 (point))
; store the char at this point, look for its enclosed char and advance
; the cursor newly (this done to avoid the cases when the char and
; its enclosed-char are the same like " or ' chars.
(backward-char 1) (setq mychar (thing-at-point 'char)) (forward-char 1)
; look forward for the enclosed char
(skip-chars-forward (concatenate 'string "^" (get-enc-char mychar))) (setq p2 (point))
; only delete the region if we found the enclosed character
(if (looking-at "[\]\}\"\'\)<>]") (kill-region p1 p2)))))
答案 0 :(得分:1)
这是一个基于您的代码的解决方案
;; returns the enclosing character for the character "c"
(defun get-enc-char (c) (cond
((string= c "(") ")")
((string= c "[") "]")
((string= c "{") "}")
((string= c ">") "<")
((string= c "<") ">")
((string= c "'") "'")
((string= c "\"") "\"")
(t nil)
))
(defvar empty-enclose 0)
(defun delete-enclosed-text ()
"Delete texts between any pair of delimiters."
(interactive)
(setq empty-enclose 0)
(save-excursion
(let (p1 p2 orig)
(setq orig (point))
(setq p1 (point))
(setq p2 (point))
(setq find 0)
(setq mychar (thing-at-point 'char))
(if (-contains? '("(" "[" "{" "<" "'" "\"") mychar)
(progn
(setq left_encloser (thing-at-point 'char))
(backward-char -1)
(if (string-equal (thing-at-point 'char) (get-enc-char left_encloser))
(progn
(backward-char -1)
(setq p2 (point))
(setq find 1)
(setq empty-enclose 1)))))
(while (eq find 0)
(skip-chars-backward "^({[<>\"'")
(setq p1 (point))
(backward-char 1)
(setq left_encloser (thing-at-point 'char))
(goto-char orig)
(while (and (not (eobp)) (eq find 0))
(backward-char -1)
(skip-chars-forward "^)}]<>\"'")
(setq right_encloser (thing-at-point 'char))
(if (string-equal right_encloser (get-enc-char left_encloser))
(progn
(setq p2 (point))
(setq find 1))))
(goto-char p1)
(backward-char 1))
(delete-region p1 p2)))
(if (eq empty-enclose 0)
(backward-char 1)))
答案 1 :(得分:0)
我快速勾勒出一些东西,它并不完全符合您的要求,但我认为它可以以更舒适的方式满足相同的要求,试一试让我知道!选择区域后,此交互式函数称为,没有参数并要求您提供封闭标记:这可以是{{1}所有直接识别的字符串或字符串(直接使用replace-regex
,*
,.
等不是这种情况,但您仍然可以使用其他字符,例如[
,{{1}等等,甚至是类似HTML的标记,如{}
)。
该功能将删除所选区域内的所有文本,从标记的第一个显示到最后一个(即使它们有奇数),标记也会被删除。
%
然后,您可以将其全局绑定到您想要的任何键盘快捷键:
<idx>
或本地到您可能拥有的任何自定义挂钩:
(defun remove-enclosed-in-selection (beginning end)
"select a region, call this function and type any valid regex
markup. All characters from its first to its last appearance will
be removed (including the symbol itself. Example: try with § and %:
aaaa§bbbbcc%c§cc§ddddeeee§ffffgggghhhhiiii§jjjj§kkkkllll§mmmm%nnnn"
(interactive "r")
(let ((x (read-string "type enclosing mark: ")))
(narrow-to-region beginning end)
(replace-regexp (concat x ".*" x) "")
(widen)))
所以,总结:
(global-set-key (kbd "C-. <C-return>") 'remove-enclosed-in-selection)
或您的自定义按键(defun custom-whatever-hook ()
(local-set-key (kbd "C-. <C-return>")) 'remove-enclosed-in-selection)
(add-hook 'whatever-hook 'custom-whatever-hook)
,输入有效标记,然后按M-x remove-enclosed-in-selection