有没有办法在emacs中的单引号和双引号之间切换字符串?

时间:2013-03-22 22:34:00

标签: emacs

我正在寻找一个emacs命令,用于切换该点下字符串的周围引号字符,例如将光标放在字符串'bar'中,点击一个键并在以下位置之间进行更改:

foo = 'bar'   <--->   foo = "bar"

对于奖励积分,它会:

  • 处理切换Python三重引号字符串('''&lt; ---&gt; """

  • 根据需要自动更改字符串中的反斜杠。

e.g。

foo = 'bar "quote"'   <--->   foo = "bar \"quote\""

4 个答案:

答案 0 :(得分:6)

这可能会更强大:

(defun toggle-quotes ()
  (interactive)
  (save-excursion
    (let ((start (nth 8 (syntax-ppss)))
          (quote-length 0) sub kind replacement)
      (goto-char start)
      (setq sub (buffer-substring start (progn (forward-sexp) (point)))
            kind (aref sub 0))
      (while (char-equal kind (aref sub 0))
        (setq sub (substring sub 1)
              quote-length (1+ quote-length)))
      (setq sub (substring sub 0 (- (length sub) quote-length)))
      (goto-char start)
      (delete-region start (+ start (* 2 quote-length) (length sub)))
      (setq kind (if (char-equal kind ?\") ?\' ?\"))
      (loop for i from 0
            for c across sub
            for slash = (char-equal c ?\\)
            then (if (and (not slash) (char-equal c ?\\)) t nil) do
            (unless slash
              (when (member c '(?\" ?\'))
                (aset sub i
                      (if (char-equal kind ?\") ?\' ?\")))))
      (setq replacement (make-string quote-length kind))
      (insert replacement sub replacement))))

它将使用缓冲区中的语法信息来查找字符串开头的引号(假设字符串被引用),并且还会尝试在字符串中翻转引号,除非它们使用反斜杠进行转义 - 这看起来很常见。

PS。我刚刚意识到你也希望它能找到三重引号,所以她就去了。

答案 1 :(得分:4)

这是一个让你入门的快速黑客:

(defun toggle-quotes ()
  "Toggle single quoted string to double or vice versa, and
  flip the internal quotes as well.  Best to run on the first
  character of the string."
  (interactive)
  (save-excursion
    (re-search-backward "[\"']")
    (let* ((start (point))
           (old-c (char-after start))
           new-c)
      (setq new-c 
            (case old-c
              (?\" "'")
              (?\' "\"")))
      (setq old-c (char-to-string old-c))
      (delete-char 1)
      (insert new-c)
      (re-search-forward old-c)
      (backward-char 1)
      (let ((end (point)))
        (delete-char 1)
        (insert new-c)
        (replace-string new-c old-c nil (1+ start) end)))))

该函数将内部引号交换到相反的位置,接近奖金2.

答案 2 :(得分:0)

这里的内容更加强大,因为它不会删除引号之间的整个文本(这样做会阻止save-excursion保持原点,这很痛苦) 。还处理(un)反斜杠嵌套引号。

(defun toggle-quotes ()
  (interactive)
  (let* ((beg (nth 8 (syntax-ppss)))
         (orig-quote (char-after beg))
         (new-quote (case orig-quote
                      (?\' ?\")
                      (?\" ?\'))))
    (save-restriction
     (widen)
     (save-excursion
      (catch 'done
        (unless new-quote
          (message "Not inside a string")
          (throw 'done nil))
        (goto-char beg)
        (delete-char 1)
        (insert-char new-quote)
        (while t
          (cond ((eobp)
                 (throw 'done nil))
                ((= (char-after) orig-quote)
                 (delete-char 1)
                 (insert-char new-quote)
                 (throw 'done nil))
                ((= (char-after) ?\\)
                 (forward-char 1)
                 (when (= (char-after) orig-quote)
                   (delete-char -1))
                 (forward-char 1))
                ((= (char-after) new-quote)
                 (insert-char ?\\)
                 (forward-char 1))
                (t (forward-char 1)))))))))

答案 3 :(得分:-2)

这是我为JavaScript制作的一个功能,可能有帮助吗?

&#13;
&#13;
function swap_str(e, r, t) {
  return e = e.split(r).join("WHAK_a_SWAP"), e = e.split(t).join("WHAK_b_SWAP"), e = e.split("WHAK_a_SWAP").join(t), 
  e = e.split("WHAK_b_SWAP").join(r);
}
//test 1
var str = 'this is "test" of a \'test\' of swapping strings';
var manipulated = swap_str(str,"'",'"');
document.writeln(manipulated)
//test 2
manipulated = swap_str(manipulated,"'",'"');
document.writeln('<hr>'+manipulated)
&#13;
&#13;
&#13;