如何在Emacs中删除光标处的引用字符串?

7

我希望能够在不需要标记字符串开头和使用kill-region的情况下,仅通过将光标放置在引号内部并按下快捷键来删除源文件中的引用字符串。

我尝试编写elisp函数实现此功能,但我发现文件需要从开头到光标处全部解析以确定光标是否在引号内部,并找到引号字符串的边界(同时处理\”)......

但是,该文件已经被font-lock解析过了,所以现在我可以确定是否在引号字符串中:

(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)

欢迎提出任何改进IT技术相关内容的建议。
3个回答

4

不要依赖于font-lock,您可以使用底层解析器的数据。字符串开始位置(如果有)在点周围可用,如(nth 8 (syntax-ppss))。然后,您可以使用(forward-sexp 1)跳过字符串以找到其结尾。


3

您可以使用previous-property-changenext-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))))

1

在Stefan的建议基础上,使用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表达式(在这种情况下,我们想要删除的字符串)。您无需进行任何区域计算。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接