]> git.eshelyaron.com Git - emacs.git/commitdiff
Add a command for string quotes toggling to ruby-mode
authorBozhidar Batsov <bozhidar@tradeo.com>
Tue, 9 Dec 2014 17:43:24 +0000 (19:43 +0200)
committerBozhidar Batsov <bozhidar@tradeo.com>
Tue, 9 Dec 2014 17:45:03 +0000 (19:45 +0200)
* progmodes/ruby-mode.el (ruby-toggle-string-quotes): New command that
allows you to quickly toggle between single-quoted and double-quoted
string literals.

lisp/ChangeLog
lisp/progmodes/ruby-mode.el

index 5ed3e47c7d91a6d3fc804449ae171d27bce9c72c..3ab15aab2433f54da3316d2b3ebc5dcc70ee4ee8 100644 (file)
@@ -2,6 +2,8 @@
 
        * progmodes/ruby-mode.el (auto-mode-alist): Add .rabl, Berksfile
        and Puppetfile.
+       (ruby-toggle-string-quotes): New command that allows you to quickly
+       toggle between single-quoted and double-quoted string literals.
 
 2014-12-09  Eric S. Raymond  <esr@snark.thyrsus.com>
 
index 803bf579da3efe31aa0561b1ba6588a62061c446..225f1f626730a98c8bcde70f802b7b8ffc7285e7 100644 (file)
@@ -152,6 +152,7 @@ This should only be called after matching against `ruby-here-doc-beg-re'."
     (define-key map (kbd "M-C-p") 'ruby-beginning-of-block)
     (define-key map (kbd "M-C-n") 'ruby-end-of-block)
     (define-key map (kbd "C-c {") 'ruby-toggle-block)
+    (define-key map (kbd "C-c '") 'ruby-toggle-string-quotes)
     map)
   "Keymap used in Ruby mode.")
 
@@ -164,6 +165,8 @@ This should only be called after matching against `ruby-here-doc-beg-re'."
     ["End of Block" ruby-end-of-block t]
     ["Toggle Block" ruby-toggle-block t]
     "--"
+    ["Toggle String Quotes" ruby-toggle-string-quotes t]
+    "--"
     ["Backward Sexp" ruby-backward-sexp
      :visible (not ruby-use-smie)]
     ["Backward Sexp" backward-sexp
@@ -1763,6 +1766,48 @@ If the result is do-end block, it will always be multiline."
               (ruby-do-end-to-brace beg end)))
       (goto-char start))))
 
+(defun ruby--string-region ()
+  "Return region for string at point."
+  (let ((orig-point (point)) (regex "'\\(\\(\\\\'\\)\\|[^']\\)*'\\|\"\\(\\(\\\\\"\\)\\|[^\"]\\)*\"") beg end)
+    (save-excursion
+      (goto-char (line-beginning-position))
+      (while (and (re-search-forward regex (line-end-position) t) (not (and beg end)))
+        (let ((match-beg (match-beginning 0)) (match-end (match-end 0)))
+          (when (and
+                 (> orig-point match-beg)
+                 (< orig-point match-end))
+            (setq beg match-beg)
+            (setq end match-end))))
+      (and beg end (list beg end)))))
+
+(defun ruby-string-at-point-p ()
+  "Check if cursor is at a string or not."
+  (ruby--string-region))
+
+(defun ruby--inverse-string-quote (string-quote)
+  "Get the inverse string quoting for STRING-QUOTE."
+  (if (equal string-quote "\"") "'" "\""))
+
+(defun ruby-toggle-string-quotes ()
+  "Toggle string literal quoting between single and double."
+  (interactive)
+  (when (ruby-string-at-point-p)
+    (let* ((region (ruby--string-region))
+           (min (nth 0 region))
+           (max (nth 1 region))
+           (string-quote (ruby--inverse-string-quote (buffer-substring-no-properties min (1+ min))))
+           (content
+            (buffer-substring-no-properties (1+ min) (1- max))))
+      (setq content
+            (if (equal string-quote "\"")
+                (replace-regexp-in-string "\\\\\"" "\"" (replace-regexp-in-string "\\([^\\\\]\\)'" "\\1\\\\'" content))
+              (replace-regexp-in-string "\\\\\'" "'" (replace-regexp-in-string "\\([^\\\\]\\)\"" "\\1\\\\\"" content))))
+      (let ((orig-point (point)))
+        (delete-region min max)
+        (insert
+         (format "%s%s%s" string-quote content string-quote))
+        (goto-char orig-point)))))
+
 (eval-and-compile
   (defconst ruby-percent-literal-beg-re
     "\\(%\\)[qQrswWxIi]?\\([[:punct:]]\\)"