【问题标题】:Is there a way to toggle a string between single and double quotes in emacs?有没有办法在emacs中切换单引号和双引号之间的字符串?
【发布时间】:2013-03-22 22:34:00
【问题描述】:

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

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

对于奖励积分,它会:

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

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

例如

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

【问题讨论】:

    标签: emacs


    【解决方案1】:

    这可能更健壮一些:

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

    【讨论】:

      【解决方案2】:

      这里有一个快速入门的技巧:

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

      【讨论】:

        【解决方案3】:

        这里有一些更强大的东西,因为它不会删除引号之间的整个文本(这样做会阻止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)))))))))
        

        【讨论】:

          【解决方案4】:

          这是我为 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)

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2011-12-07
            • 2015-10-29
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多