Вот что я обычно использую. Почему-то мне удобнее убить сбалансированное выражение, чем копировать. Если вместо этого мне нужна копия, я сначала убиваю, а потом отменяю.
Эта функция уничтожает строку, если точка находится внутри строки, в противном случае используется сбалансированное выражение, т.е. ()
,[]
,{}
,<>
или что-то другое, определенное синтаксисом.
(defun kill-at-point ()
"Kill the quoted string or the list that includes the point"
(interactive)
(let ((p (nth 8 (syntax-ppss))))
(cond
;; string
((eq (char-after p) ?\")
(goto-char p)
(kill-sexp))
;; list
((ignore-errors (when (eq (char-after) ?\()
(forward-char))
(up-list)
t)
(let ((beg (point)))
(backward-list)
(kill-region beg (point)))))))
Я также попытался добавить особый случай, когда точка находится внутри комментария, но я не смог найти общий способ определить границы комментария в точке. Если кто-нибудь знает, пожалуйста, скажите мне.
Эта другая функция также может иметь значение. Он метит, а не убивает, как предыдущий. Приятно то, что он расширяет регион каждый раз, когда он вызывается. Я связываю первый с C-,, а второй с C-M-,.
(defun mark-at-point ()
"Mark the quoted string or the list that includes the point"
(interactive)
(let ((p (nth 8 (syntax-ppss))))
(if (eq (char-after p) ?\")
(progn
(goto-char p)
(set-mark (point))
(forward-sexp))
(progn
(when (eq (char-after) 40)
(forward-char))
(condition-case nil
(progn
(up-list)
(set-mark (point))
(let ((beg (point)))
(backward-list)
(exchange-point-and-mark)))
(error
(when (looking-back "}")
(exchange-point-and-mark)
;; assumes functions are separated by one empty line
(re-search-backward "^[^A-Z-a-z]" nil t)
(forward-char))))))))
person
abo-abo
schedule
26.08.2013