5

我正在寻找一个emacs命令,该命令将在该点下的字符串上切换周围的引号字符,例如,将光标放在字符串'bar'中,点击一个键并将其更改为:

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

对于奖励积分,它将:

  • 处理切换 Python 三引号字符串 ( '''<---> """)

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

例如

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

4 回答 4

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。我刚刚意识到你也希望它找到三引号,所以她去了。

于 2013-03-24T21:16:41.367 回答
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。

于 2013-03-22T23:18:39.980 回答
1

这是更强大的东西,因为它不会删除引号之间的整个文本(这样做可以防止save-excursion保持原来的位置,这是一种痛苦)。还处理(非)反斜杠嵌套引号。

(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)))))))))
于 2016-12-10T19:05:57.613 回答
-2

这是我为 JavaScript 制作的函数,可能有帮助吗?

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)

于 2016-01-11T17:50:18.480 回答