7

我想在源文件中终止带引号的字符串,而不必标记字符串的开头和终止区域,而只需将点放在带引号的字符串内的任何位置并按下快捷方式即可。

我试图为此在elisp中编写一个函数,但我发现需要从头到尾解析文件以确定该点是否在引用字符串内,并找到引用字符串的边界(也处理 \")...

但是该文件已经被字体锁解析了。所以现在我可以确定我是否在引号内:

(defun inside-quoted-string? ()
  (interactive)
  (print (find 'font-lock-doc-face (text-properties-at (point)))))

但是我如何获得字符串的边界?font-lock 知道它,因为它很好地用蓝色突出显示它,但我如何得到它?

编辑:感谢您的回答。我想出了这段代码,它完全符合我的要求——在不选择区域甚至移动到代码开头的情况下移动代码。

(defun kill-at-point ()
  "Kill 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)
      (kill-sexp))
      (progn
    (up-list)
    (let ((beg (point)))
      (backward-list)
      (kill-region beg (point)))))))
(global-set-key (kbd "C-,") 'kill-at-point)

欢迎任何改进它的建议。

4

3 回答 3

5

您可以使用底层解析器的数据,而不是依赖字体锁定。围绕点(如果有)的字符串的开头可用作(nth 8 (syntax-ppss)). 然后,您可以使用(forward-sexp 1)跳过字符串以找到它的结尾。

于 2012-07-04T16:10:29.320 回答
3

previous-property-change您可以使用和找到属性的边界next-property-change。例如:

(defun kill-by-property (arg)
  (interactive "d")
  (kill-region
    (previous-property-change arg nil (point-min))
    (next-property-change arg nil (point-max))))
于 2012-07-04T15:25:40.570 回答
1

根据 Stefan 的建议 using syntax-ppss,以下应该可以解决问题

(defun kill-string ()
  (interactive)
  (let ((string-start (nth 8 (syntax-ppss))))
    (goto-char string-start)
    (kill-sexp)))

它用于(nth 8 (syntax-ppss))查找字符串的开头,跳转到那里,然后使用内置kill-sexp函数杀死点处的 s 表达式(在这种情况下,我们想要删除的字符串)。完全不需要您进行任何类型的区域计算。

于 2012-07-05T13:52:09.543 回答