summaryrefslogtreecommitdiff
path: root/misc/ruby-electric.el
diff options
context:
space:
mode:
Diffstat (limited to 'misc/ruby-electric.el')
-rw-r--r--misc/ruby-electric.el230
1 files changed, 151 insertions, 79 deletions
diff --git a/misc/ruby-electric.el b/misc/ruby-electric.el
index b8897e7163..e6fb90d626 100644
--- a/misc/ruby-electric.el
+++ b/misc/ruby-electric.el
@@ -10,7 +10,7 @@
;; URL: https://github.com/knu/ruby-electric.el
;; Keywords: languages ruby
;; License: The same license terms as Ruby
-;; Version: 2.1.1
+;; Version: 2.2.1
;;; Commentary:
;;
@@ -172,6 +172,7 @@ instead."
(define-key map [remap delete-backward-char] 'ruby-electric-delete-backward-char)
(define-key map [remap newline] 'ruby-electric-space/return)
(define-key map [remap newline-and-indent] 'ruby-electric-space/return)
+ (define-key map [remap electric-newline-and-maybe-indent] 'ruby-electric-space/return)
(dolist (x ruby-electric-delimiters-alist)
(let* ((delim (car x))
(plist (cdr x))
@@ -247,8 +248,11 @@ enabled."
(interactive "*P")
(and (boundp 'sp-last-operation)
(setq sp-delayed-pair nil))
- (cond (arg
- (insert (make-string (prefix-numeric-value arg) last-command-event)))
+ (cond ((or arg
+ (region-active-p))
+ (or (= last-command-event ?\s)
+ (setq last-command-event ?\n))
+ (ruby-electric-replace-region-or-insert))
((ruby-electric-space/return-can-be-expanded-p)
(let (action)
(save-excursion
@@ -310,131 +314,198 @@ enabled."
(and (ruby-electric-code-at-point-p)
(looking-back ruby-electric-expandable-keyword-re)))
-(defun ruby-electric-cua-replace-region-maybe()
- (let ((func (key-binding [remap self-insert-command])))
- (when (memq func '(cua-replace-region
- sp--cua-replace-region))
- (setq this-original-command 'self-insert-command)
- (funcall (setq this-command func))
- t)))
+(defun ruby-electric-replace-region-or-insert ()
+ (and (region-active-p)
+ (bound-and-true-p delete-selection-mode)
+ (fboundp 'delete-selection-helper)
+ (delete-selection-helper (get 'self-insert-command 'delete-selection)))
+ (insert (make-string (prefix-numeric-value current-prefix-arg)
+ last-command-event))
+ (setq this-command 'self-insert-command))
(defmacro ruby-electric-insert (arg &rest body)
- `(cond ((ruby-electric-cua-replace-region-maybe))
- ((and
+ `(cond ((and
(null ,arg)
(ruby-electric-command-char-expandable-punct-p last-command-event))
- (insert last-command-event)
- ,@body)
- (t
- (setq this-command 'self-insert-command)
- (insert (make-string (prefix-numeric-value ,arg) last-command-event)))))
-
-(defun ruby-electric-curlies(arg)
+ (let ((region-beginning
+ (cond ((region-active-p)
+ (prog1
+ (save-excursion
+ (goto-char (region-beginning))
+ (insert last-command-event)
+ (point))
+ (goto-char (region-end))))
+ (t
+ (insert last-command-event)
+ nil))))
+ ,@body
+ (and region-beginning
+ ;; If no extra character is inserted, go back to the
+ ;; region beginning.
+ (eq this-command 'self-insert-command)
+ (goto-char region-beginning))))
+ ((ruby-electric-replace-region-or-insert))))
+
+(defun ruby-electric-curlies (arg)
(interactive "*P")
(ruby-electric-insert
arg
(cond
((ruby-electric-code-at-point-p)
- (insert "}")
- (backward-char 1)
- (redisplay)
+ (save-excursion
+ (insert "}")
+ (font-lock-fontify-region (line-beginning-position) (point)))
(cond
((ruby-electric-string-at-point-p) ;; %w{}, %r{}, etc.
- t)
+ (if region-beginning
+ (forward-char 1)))
(ruby-electric-newline-before-closing-bracket
- (insert " ")
- (save-excursion
- (newline)
- (ruby-indent-line t)))
+ (cond (region-beginning
+ (save-excursion
+ (goto-char region-beginning)
+ (newline))
+ (newline)
+ (forward-char 1)
+ (indent-region region-beginning (line-end-position)))
+ (t
+ (insert " ")
+ (save-excursion
+ (newline)
+ (ruby-indent-line t)))))
(t
- (insert " ")
- (backward-char 1))))
+ (if region-beginning
+ (save-excursion
+ (goto-char region-beginning)
+ (insert " "))
+ (insert " "))
+ (insert " ")
+ (and region-beginning
+ (forward-char 1)))))
((ruby-electric-string-at-point-p)
- (save-excursion
- (backward-char 1)
+ (let ((start-position (1- (or region-beginning (point)))))
(cond
- ((char-equal ?\# (preceding-char))
+ ((char-equal ?\# (char-before start-position))
(unless (save-excursion
- (backward-char 1)
+ (goto-char (1- start-position))
(ruby-electric-escaped-p))
- (forward-char 1)
- (insert "}")))
+ (insert "}")
+ (or region-beginning
+ (backward-char 1))))
((or
(ruby-electric-command-char-expandable-punct-p ?\#)
- (ruby-electric-escaped-p))
+ (save-excursion
+ (goto-char start-position)
+ (ruby-electric-escaped-p)))
+ (if region-beginning
+ (goto-char region-beginning))
(setq this-command 'self-insert-command))
(t
- (insert "#")
- (forward-char 1)
- (insert "}")))))
+ (save-excursion
+ (goto-char start-position)
+ (insert "#"))
+ (insert "}")
+ (or region-beginning
+ (backward-char 1))))))
(t
- (setq this-command 'self-insert-command)))))
+ (delete-char -1)
+ (ruby-electric-replace-region-or-insert)))))
-(defun ruby-electric-hash(arg)
+(defun ruby-electric-hash (arg)
(interactive "*P")
(ruby-electric-insert
arg
- (and (ruby-electric-string-at-point-p)
- (or (char-equal (following-char) ?') ;; likely to be in ''
- (save-excursion
- (backward-char 1)
- (ruby-electric-escaped-p))
- (progn
- (insert "{}")
- (backward-char 1))))))
-
-(defmacro ruby-electric-avoid-eob(&rest body)
- `(if (eobp)
- (save-excursion
- (insert "\n")
- (backward-char)
- ,@body
- (prog1
- (ruby-electric-string-at-point-p)
- (delete-char 1)))
- ,@body))
-
-(defun ruby-electric-matching-char(arg)
+ (if (ruby-electric-string-at-point-p)
+ (let ((start-position (1- (or region-beginning (point)))))
+ (cond
+ ((char-equal (following-char) ?')) ;; likely to be in ''
+ ((save-excursion
+ (goto-char start-position)
+ (ruby-electric-escaped-p)))
+ (region-beginning
+ (save-excursion
+ (goto-char (1+ start-position))
+ (insert "{"))
+ (insert "}"))
+ (t
+ (insert "{")
+ (save-excursion
+ (insert "}")))))
+ (delete-char -1)
+ (ruby-electric-replace-region-or-insert))))
+
+(defun ruby-electric-matching-char (arg)
(interactive "*P")
(ruby-electric-insert
arg
(let ((closing (cdr (assoc last-command-event
ruby-electric-matching-delimeter-alist))))
(cond
+ ;; quotes
((char-equal closing last-command-event)
- (if (and (not (ruby-electric-string-at-point-p))
- (ruby-electric-avoid-eob
- (redisplay)
- (ruby-electric-string-at-point-p)))
- (save-excursion (insert closing))
- (and (eq last-command 'ruby-electric-matching-char)
- (char-equal (following-char) closing) ;; repeated quotes
- (delete-forward-char 1))
- (setq this-command 'self-insert-command)))
+ (cond ((let ((start-position (or region-beginning (point))))
+ ;; check if this quote has just started a string
+ (and
+ (unwind-protect
+ (save-excursion
+ (subst-char-in-region (1- start-position) start-position
+ last-command-event ?\s)
+ (goto-char (1- start-position))
+ (save-excursion
+ (font-lock-fontify-region (line-beginning-position) (1+ (point))))
+ (not (ruby-electric-string-at-point-p)))
+ (subst-char-in-region (1- start-position) start-position
+ ?\s last-command-event))
+ (save-excursion
+ (goto-char (1- start-position))
+ (save-excursion
+ (font-lock-fontify-region (line-beginning-position) (1+ (point))))
+ (ruby-electric-string-at-point-p))))
+ (if region-beginning
+ ;; escape quotes of the same kind, backslash and hash
+ (let ((re (format "[%c\\%s]"
+ last-command-event
+ (if (char-equal last-command-event ?\")
+ "#" "")))
+ (bound (point)))
+ (save-excursion
+ (goto-char region-beginning)
+ (while (re-search-forward re bound t)
+ (let ((end (point)))
+ (replace-match "\\\\\\&")
+ (setq bound (+ bound (- (point) end))))))))
+ (insert closing)
+ (or region-beginning
+ (backward-char 1)))
+ (t
+ (and (eq last-command 'ruby-electric-matching-char)
+ (char-equal (following-char) closing) ;; repeated quotes
+ (delete-char 1))
+ (setq this-command 'self-insert-command))))
((ruby-electric-code-at-point-p)
- (save-excursion (insert closing)))))))
+ (insert closing)
+ (or region-beginning
+ (backward-char 1)))))))
(defun ruby-electric-closing-char(arg)
(interactive "*P")
(cond
- ((ruby-electric-cua-replace-region-maybe))
(arg
- (setq this-command 'self-insert-command)
- (insert (make-string (prefix-numeric-value arg) last-command-event)))
+ (ruby-electric-replace-region-or-insert))
((and
(eq last-command 'ruby-electric-curlies)
- (= last-command-event ?})) ;; {}
+ (= last-command-event ?})
+ (not (char-equal (preceding-char) last-command-event))) ;; {}
(if (char-equal (following-char) ?\n) (delete-char 1))
(delete-horizontal-space)
(forward-char))
((and
(= last-command-event (following-char))
+ (not (char-equal (preceding-char) last-command-event))
(memq last-command '(ruby-electric-matching-char
ruby-electric-closing-char))) ;; ()/[] and (())/[[]]
(forward-char))
(t
- (setq this-command 'self-insert-command)
- (self-insert-command 1)
+ (ruby-electric-replace-region-or-insert)
(if ruby-electric-autoindent-on-closing-char
(ruby-indent-line)))))
@@ -446,7 +517,8 @@ enabled."
(looking-back ruby-electric-expandable-bar-re))
(save-excursion (insert "|")))
(t
- (setq this-command 'self-insert-command)))))
+ (delete-char -1)
+ (ruby-electric-replace-region-or-insert)))))
(defun ruby-electric-delete-backward-char(arg)
(interactive "*p")