Is there a way to toggle a string between single and double quotes in emacs?

I am looking for an emacs command that will toggle surrounding quotation marks in the line below the dot, for example. using the cursor in the line "bar", press the key and change it:

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

For bonus points it will be:

  • handle toggles Python knit strings ( ''' <---> """ )

  • automatically changes the backslash in a string.

eg.

 foo = 'bar "quote"' <---> foo = "bar \"quote\"" 
+4
source share
4 answers

Here's a quick hack to get you started:

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

The function reverses the inner quotation marks, which is close to bonus 2.

+4
source

This might be a little more reliable:

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

It will use the syntax information from the buffer to find the quotation marks at the beginning of the line (which indicates that the lines are quoted), and also try to flip the quotes inside the line unless they are flushed with a backslash - which looks like a normal case.

PS. I just realized that you also wanted him to find the triple quotation marks, so she leaves.

+6
source

There is something more reliable here, since it does not remove all text between quotation marks (this prevents the save-excursion from saving the point where it was, which is a pain). Also handles (un) backslash nested quotes.

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

Here, the function I created for JavaScript can help?

 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) 
-2
source

All Articles