aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBozhidar Batsov2014-12-09 19:43:24 +0200
committerBozhidar Batsov2014-12-09 19:45:03 +0200
commite8acfc7fb4a6c01d50ed121ca5ce2ed41f7b0db9 (patch)
treeec28e8b1842b88be5fd3fa371840aa675f11957a
parent9b185aa1ae060025f5479cf8d6d64548aff8dbe3 (diff)
downloademacs-e8acfc7fb4a6c01d50ed121ca5ce2ed41f7b0db9.tar.gz
emacs-e8acfc7fb4a6c01d50ed121ca5ce2ed41f7b0db9.zip
Add a command for string quotes toggling to ruby-mode
* progmodes/ruby-mode.el (ruby-toggle-string-quotes): New command that allows you to quickly toggle between single-quoted and double-quoted string literals.
-rw-r--r--lisp/ChangeLog2
-rw-r--r--lisp/progmodes/ruby-mode.el45
2 files changed, 47 insertions, 0 deletions
diff --git a/lisp/ChangeLog b/lisp/ChangeLog
index 5ed3e47c7d9..3ab15aab243 100644
--- a/lisp/ChangeLog
+++ b/lisp/ChangeLog
@@ -2,6 +2,8 @@
2 2
3 * progmodes/ruby-mode.el (auto-mode-alist): Add .rabl, Berksfile 3 * progmodes/ruby-mode.el (auto-mode-alist): Add .rabl, Berksfile
4 and Puppetfile. 4 and Puppetfile.
5 (ruby-toggle-string-quotes): New command that allows you to quickly
6 toggle between single-quoted and double-quoted string literals.
5 7
62014-12-09 Eric S. Raymond <esr@snark.thyrsus.com> 82014-12-09 Eric S. Raymond <esr@snark.thyrsus.com>
7 9
diff --git a/lisp/progmodes/ruby-mode.el b/lisp/progmodes/ruby-mode.el
index 803bf579da3..225f1f62673 100644
--- a/lisp/progmodes/ruby-mode.el
+++ b/lisp/progmodes/ruby-mode.el
@@ -152,6 +152,7 @@ This should only be called after matching against `ruby-here-doc-beg-re'."
152 (define-key map (kbd "M-C-p") 'ruby-beginning-of-block) 152 (define-key map (kbd "M-C-p") 'ruby-beginning-of-block)
153 (define-key map (kbd "M-C-n") 'ruby-end-of-block) 153 (define-key map (kbd "M-C-n") 'ruby-end-of-block)
154 (define-key map (kbd "C-c {") 'ruby-toggle-block) 154 (define-key map (kbd "C-c {") 'ruby-toggle-block)
155 (define-key map (kbd "C-c '") 'ruby-toggle-string-quotes)
155 map) 156 map)
156 "Keymap used in Ruby mode.") 157 "Keymap used in Ruby mode.")
157 158
@@ -164,6 +165,8 @@ This should only be called after matching against `ruby-here-doc-beg-re'."
164 ["End of Block" ruby-end-of-block t] 165 ["End of Block" ruby-end-of-block t]
165 ["Toggle Block" ruby-toggle-block t] 166 ["Toggle Block" ruby-toggle-block t]
166 "--" 167 "--"
168 ["Toggle String Quotes" ruby-toggle-string-quotes t]
169 "--"
167 ["Backward Sexp" ruby-backward-sexp 170 ["Backward Sexp" ruby-backward-sexp
168 :visible (not ruby-use-smie)] 171 :visible (not ruby-use-smie)]
169 ["Backward Sexp" backward-sexp 172 ["Backward Sexp" backward-sexp
@@ -1763,6 +1766,48 @@ If the result is do-end block, it will always be multiline."
1763 (ruby-do-end-to-brace beg end))) 1766 (ruby-do-end-to-brace beg end)))
1764 (goto-char start)))) 1767 (goto-char start))))
1765 1768
1769(defun ruby--string-region ()
1770 "Return region for string at point."
1771 (let ((orig-point (point)) (regex "'\\(\\(\\\\'\\)\\|[^']\\)*'\\|\"\\(\\(\\\\\"\\)\\|[^\"]\\)*\"") beg end)
1772 (save-excursion
1773 (goto-char (line-beginning-position))
1774 (while (and (re-search-forward regex (line-end-position) t) (not (and beg end)))
1775 (let ((match-beg (match-beginning 0)) (match-end (match-end 0)))
1776 (when (and
1777 (> orig-point match-beg)
1778 (< orig-point match-end))
1779 (setq beg match-beg)
1780 (setq end match-end))))
1781 (and beg end (list beg end)))))
1782
1783(defun ruby-string-at-point-p ()
1784 "Check if cursor is at a string or not."
1785 (ruby--string-region))
1786
1787(defun ruby--inverse-string-quote (string-quote)
1788 "Get the inverse string quoting for STRING-QUOTE."
1789 (if (equal string-quote "\"") "'" "\""))
1790
1791(defun ruby-toggle-string-quotes ()
1792 "Toggle string literal quoting between single and double."
1793 (interactive)
1794 (when (ruby-string-at-point-p)
1795 (let* ((region (ruby--string-region))
1796 (min (nth 0 region))
1797 (max (nth 1 region))
1798 (string-quote (ruby--inverse-string-quote (buffer-substring-no-properties min (1+ min))))
1799 (content
1800 (buffer-substring-no-properties (1+ min) (1- max))))
1801 (setq content
1802 (if (equal string-quote "\"")
1803 (replace-regexp-in-string "\\\\\"" "\"" (replace-regexp-in-string "\\([^\\\\]\\)'" "\\1\\\\'" content))
1804 (replace-regexp-in-string "\\\\\'" "'" (replace-regexp-in-string "\\([^\\\\]\\)\"" "\\1\\\\\"" content))))
1805 (let ((orig-point (point)))
1806 (delete-region min max)
1807 (insert
1808 (format "%s%s%s" string-quote content string-quote))
1809 (goto-char orig-point)))))
1810
1766(eval-and-compile 1811(eval-and-compile
1767 (defconst ruby-percent-literal-beg-re 1812 (defconst ruby-percent-literal-beg-re
1768 "\\(%\\)[qQrswWxIi]?\\([[:punct:]]\\)" 1813 "\\(%\\)[qQrswWxIi]?\\([[:punct:]]\\)"