[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[nongnu] elpa/inf-ruby 60f9cfa181 001/265: Initial revision.
From: |
ELPA Syncer |
Subject: |
[nongnu] elpa/inf-ruby 60f9cfa181 001/265: Initial revision. |
Date: |
Sat, 9 Jul 2022 21:59:09 -0400 (EDT) |
branch: elpa/inf-ruby
commit 60f9cfa1818f279b281fa1f1db27028136c04de0
Author: Cornelius Mika <cornelius.mika@gmail.com>
Commit: Cornelius Mika <cornelius.mika@gmail.com>
Initial revision.
---
inf-ruby.el | 350 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 350 insertions(+)
diff --git a/inf-ruby.el b/inf-ruby.el
new file mode 100755
index 0000000000..182d93a32d
--- /dev/null
+++ b/inf-ruby.el
@@ -0,0 +1,350 @@
+;;; inf-ruby.el --- Run a ruby process in a buffer
+
+;; Copyright (C) 1999-2008 Yukihiro Matsumoto, Nobuyoshi Nakada
+
+;; Authors: Yukihiro Matsumoto, Nobuyoshi Nakada
+;; URL: http://www.emacswiki.org/cgi-bin/wiki/RubyMode
+;; Created: 8 April 1998
+;; Keywords: languages ruby
+;; Version: 2.1
+;; Package-Requires: ((ruby-mode "1.1"))
+
+;;; Commentary:
+;;
+;; inf-ruby.el provides a REPL buffer connected to an IRB subprocess.
+;;
+;; If you're installing manually, you'll need to:
+;; * drop the file somewhere on your load path (perhaps ~/.emacs.d)
+;; * Add the following lines to your .emacs file:
+;; (autoload 'inf-ruby "inf-ruby" "Run an inferior Ruby process" t)
+;; (autoload 'inf-ruby-keys "inf-ruby" "" t)
+;; (eval-after-load 'ruby-mode
+;; '(add-hook 'ruby-mode-hook 'inf-ruby-keys))
+
+;;; TODO:
+;;
+;; inferior-ruby-error-regexp-alist doesn't match this example
+;; SyntaxError: /home/eschulte/united/org/work/arf/arf/lib/cluster.rb:35:
syntax error, unexpected '~', expecting kEND
+;; similarity = comparison_cache[m][n] ||= clusters[m] ~
clusters[n]
+;;
+;; M-p skips the first entry in the input ring.
+;;
+
+(require 'comint)
+(require 'compile)
+(require 'ruby-mode)
+
+(defvar inf-ruby-default-implementation "ruby"
+ "Which ruby implementation to use if none is specified.")
+
+(defvar inf-ruby-first-prompt-pattern "^irb(.*)[0-9:]+0> *"
+ "First prompt regex pattern of ruby interpreter.")
+
+(defvar inf-ruby-prompt-pattern "^\\(irb(.*)[0-9:]+[>*\"'] *\\)+"
+ "Prompt regex pattern of ruby interpreter.")
+
+(defvar inf-ruby-mode-hook nil
+ "*Hook for customising inf-ruby mode.")
+
+(defvar inf-ruby-mode-map
+ (let ((map (copy-keymap comint-mode-map)))
+ (define-key map (kbd "C-c C-l") 'inf-ruby-load-file)
+ (define-key map (kbd "C-x C-e") 'ruby-send-last-sexp)
+ (define-key map (kbd "TAB") 'inf-ruby-complete-or-tab)
+ map)
+ "*Mode map for inf-ruby-mode")
+
+(defvar inf-ruby-implementations
+ '(("ruby" . "irb --inf-ruby-mode -r irb/completion")
+ ("jruby" . "jruby -S irb -r irb/completion")
+ ("rubinius" . "rbx -r irb/completion")
+ ("yarv" . "irb1.9 --inf-ruby-mode -r irb/completion")) ;; TODO:
ironruby?
+ "An alist of ruby implementations to irb executable names.")
+
+;; TODO: do we need these two defvars?
+(defvar ruby-source-modes '(ruby-mode)
+ "*Used to determine if a buffer contains Ruby source code.
+If it's loaded into a buffer that is in one of these major modes, it's
+considered a ruby source file by ruby-load-file.
+Used by these commands to determine defaults.")
+
+(defvar ruby-prev-l/c-dir/file nil
+ "Caches the last (directory . file) pair.
+Caches the last pair used in the last ruby-load-file command.
+Used for determining the default in the
+next one.")
+
+(defconst inf-ruby-error-regexp-alist
+ '(("SyntaxError: compile error\n^\\([^\(].*\\):\\([1-9][0-9]*\\):" 1 2)
+ ("^\tfrom \\([^\(].*\\):\\([1-9][0-9]*\\)\\(:in `.*'\\)?$" 1 2)))
+
+;;;###autoload
+(defun inf-ruby-keys ()
+ "Set local key defs to invoke inf-ruby from ruby-mode."
+ (define-key ruby-mode-map "\M-\C-x" 'ruby-send-definition)
+ (define-key ruby-mode-map "\C-x\C-e" 'ruby-send-last-sexp)
+ (define-key ruby-mode-map "\C-c\C-b" 'ruby-send-block)
+ (define-key ruby-mode-map "\C-c\M-b" 'ruby-send-block-and-go)
+ (define-key ruby-mode-map "\C-c\C-x" 'ruby-send-definition)
+ (define-key ruby-mode-map "\C-c\M-x" 'ruby-send-definition-and-go)
+ (define-key ruby-mode-map "\C-c\C-r" 'ruby-send-region)
+ (define-key ruby-mode-map "\C-c\M-r" 'ruby-send-region-and-go)
+ (define-key ruby-mode-map "\C-c\C-z" 'ruby-switch-to-inf)
+ (define-key ruby-mode-map "\C-c\C-l" 'ruby-load-file)
+ (define-key ruby-mode-map "\C-c\C-s" 'inf-ruby))
+
+(defvar inf-ruby-buffer nil "Current irb process buffer.")
+
+(defun inf-ruby-mode ()
+ "Major mode for interacting with an inferior ruby (irb) process.
+
+The following commands are available:
+\\{inf-ruby-mode-map}
+
+A ruby process can be fired up with M-x inf-ruby.
+
+Customisation: Entry to this mode runs the hooks on comint-mode-hook and
+inf-ruby-mode-hook (in that order).
+
+You can send text to the inferior ruby process from other buffers containing
+Ruby source.
+ ruby-switch-to-inf switches the current buffer to the ruby process buffer.
+ ruby-send-definition sends the current definition to the ruby process.
+ ruby-send-region sends the current region to the ruby process.
+
+ ruby-send-definition-and-go, ruby-send-region-and-go,
+ switch to the ruby process buffer after sending their text.
+
+Commands:
+Return after the end of the process' output sends the text from the
+ end of process to point.
+Return before the end of the process' output copies the sexp ending at point
+ to the end of the process' output, and sends it.
+Delete converts tabs to spaces as it moves back.
+Tab indents for ruby; with arugment, shifts rest
+ of expression rigidly with the current line.
+C-M-q does Tab on each line starting within following expression.
+Paragraphs are separated only by blank lines. # start comments.
+If you accidentally suspend your process, use \\[comint-continue-subjob]
+to continue it."
+ (interactive)
+ (comint-mode)
+ (setq comint-prompt-regexp inf-ruby-prompt-pattern)
+ (ruby-mode-variables)
+ (setq major-mode 'inf-ruby-mode)
+ (setq mode-name "Inf-Ruby")
+ (setq mode-line-process '(":%s"))
+ (use-local-map inf-ruby-mode-map)
+ (setq comint-input-filter (function inf-ruby-input-filter))
+ (setq comint-get-old-input (function inf-ruby-get-old-input))
+ (make-local-variable 'compilation-error-regexp-alist)
+ (setq compilation-error-regexp-alist inf-ruby-error-regexp-alist)
+ (compilation-shell-minor-mode t)
+ (run-hooks 'inf-ruby-mode-hook))
+
+(defvar inf-ruby-filter-regexp "\\`\\s *\\S ?\\S ?\\s *\\'"
+ "*Input matching this regexp are not saved on the history list.
+Defaults to a regexp ignoring all inputs of 0, 1, or 2 letters.")
+
+(defun inf-ruby-input-filter (str)
+ "Don't save anything matching inf-ruby-filter-regexp"
+ (not (string-match inf-ruby-filter-regexp str)))
+
+;; adapted from replace-in-string in XEmacs (subr.el)
+(defun inf-ruby-remove-in-string (str regexp)
+ "Remove all matches in STR for REGEXP and returns the new string."
+ (let ((rtn-str "") (start 0) match prev-start)
+ (while (setq match (string-match regexp str start))
+ (setq prev-start start
+ start (match-end 0)
+ rtn-str (concat rtn-str (substring str prev-start match))))
+ (concat rtn-str (substring str start))))
+
+(defun inf-ruby-get-old-input ()
+ "Snarf the sexp ending at point"
+ (save-excursion
+ (let ((end (point)))
+ (re-search-backward inf-ruby-first-prompt-pattern)
+ (inf-ruby-remove-in-string (buffer-substring (point) end)
+ inf-ruby-prompt-pattern))))
+
+;;;###autoload
+(defun inf-ruby (&optional impl)
+ "Run an inferior Ruby process in a buffer.
+With prefix argument, prompts for which Ruby implementation
+\(from the list `inf-ruby-implementations') to use. Runs the
+hooks `inf-ruby-mode-hook' \(after the `comint-mode-hook' is
+run)."
+
+ (interactive (list (if current-prefix-arg
+ (completing-read "Ruby Implementation: "
+ (mapc #'car
inf-ruby-implementations))
+ inf-ruby-default-implementation)))
+ (setq impl (or impl "ruby"))
+
+ (let ((command (cdr (assoc impl inf-ruby-implementations))))
+ (run-ruby command impl)))
+
+;;;###autoload
+(defun run-ruby (&optional command name)
+ "Run an inferior Ruby process, input and output via buffer *ruby*.
+If there is a process already running in `*ruby*', switch to that buffer.
+With argument, allows you to edit the command line (default is value
+of `ruby-program-name'). Runs the hooks `inferior-ruby-mode-hook'
+\(after the `comint-mode-hook' is run).
+\(Type \\[describe-mode] in the process buffer for a list of commands.)"
+
+ (interactive)
+ (setq command (or command (cdr (assoc inf-ruby-default-implementation
+ inf-ruby-implementations))))
+ (setq name (or name "ruby"))
+
+ (if (not (comint-check-proc inf-ruby-buffer))
+ (let ((commandlist (split-string command)))
+ (set-buffer (apply 'make-comint name (car commandlist)
+ nil (cdr commandlist)))
+ (inf-ruby-mode)))
+ (pop-to-buffer (setq inf-ruby-buffer (format "*%s*" name))))
+
+(defun inf-ruby-proc ()
+ "Returns the current IRB process. See variable inf-ruby-buffer."
+ (or (get-buffer-process (if (eq major-mode 'inf-ruby-mode)
+ (current-buffer)
+ inf-ruby-buffer))
+ (error "No current process. See variable inf-ruby-buffer")))
+
+;; These commands are added to the ruby-mode keymap:
+
+(defconst ruby-send-terminator "--inf-ruby-%x-%d-%d-%d--"
+ "Template for irb here document terminator.
+Must not contain ruby meta characters.")
+
+(defconst ruby-eval-separator "")
+
+(defun ruby-send-region (start end)
+ "Send the current region to the inferior Ruby process."
+ (interactive "r")
+ (let (term (file (buffer-file-name)) line)
+ (save-excursion
+ (save-restriction
+ (widen)
+ (goto-char start)
+ (setq line (+ start (forward-line (- start)) 1))
+ (goto-char start)
+ (while (progn
+ (setq term (apply 'format ruby-send-terminator (random)
(current-time)))
+ (re-search-forward (concat "^" (regexp-quote term) "$") end
t)))))
+ ;; compilation-parse-errors parses from second line.
+ (save-excursion
+ (let ((m (process-mark (inf-ruby-proc))))
+ (set-buffer (marker-buffer m))
+ (goto-char m)
+ (insert ruby-eval-separator "\n")
+ (set-marker m (point))))
+ (comint-send-string (inf-ruby-proc) (format "eval <<'%s', nil, %S, %d\n"
term file line))
+ (comint-send-region (inf-ruby-proc) start end)
+ (comint-send-string (inf-ruby-proc) (concat "\n" term "\n"))))
+
+(defun ruby-send-definition ()
+ "Send the current definition to the inferior Ruby process."
+ (interactive)
+ (save-excursion
+ (ruby-end-of-defun)
+ (let ((end (point)))
+ (ruby-beginning-of-defun)
+ (ruby-send-region (point) end))))
+
+(defun ruby-send-last-sexp ()
+ "Send the previous sexp to the inferior Ruby process."
+ (interactive)
+ (ruby-send-region (save-excursion (backward-sexp) (point)) (point)))
+
+(defun ruby-send-block ()
+ "Send the current block to the inferior Ruby process."
+ (interactive)
+ (save-excursion
+ (ruby-end-of-block)
+ (end-of-line)
+ (let ((end (point)))
+ (ruby-beginning-of-block)
+ (ruby-send-region (point) end))))
+
+(defun ruby-switch-to-inf (eob-p)
+ "Switch to the ruby process buffer.
+With argument, positions cursor at end of buffer."
+ (interactive "P")
+ (if (get-buffer inf-ruby-buffer)
+ (pop-to-buffer inf-ruby-buffer)
+ (error "No current process buffer. See variable inf-ruby-buffer."))
+ (cond (eob-p
+ (push-mark)
+ (goto-char (point-max)))))
+
+(defun ruby-send-region-and-go (start end)
+ "Send the current region to the inferior Ruby process.
+Then switch to the process buffer."
+ (interactive "r")
+ (ruby-send-region start end)
+ (ruby-switch-to-inf t))
+
+(defun ruby-send-definition-and-go ()
+ "Send the current definition to the inferior Ruby.
+Then switch to the process buffer."
+ (interactive)
+ (ruby-send-definition)
+ (ruby-switch-to-inf t))
+
+(defun ruby-send-block-and-go ()
+ "Send the current block to the inferior Ruby.
+Then switch to the process buffer."
+ (interactive)
+ (ruby-send-block)
+ (ruby-switch-to-inf t))
+
+(defun ruby-load-file (file-name)
+ "Load a Ruby file into the inferior Ruby process."
+ (interactive (comint-get-source "Load Ruby file: " ruby-prev-l/c-dir/file
+ ruby-source-modes t)) ;; T because LOAD
needs an exact name
+ (comint-check-source file-name) ; Check to see if buffer needs saved.
+ (setq ruby-prev-l/c-dir/file (cons (file-name-directory file-name)
+ (file-name-nondirectory file-name)))
+ (comint-send-string (inf-ruby-proc) (concat "(load \""
+ file-name
+ "\"\)\n")))
+
+(defun inf-ruby-completions (seed)
+ "Return a list of completions for the line of ruby code starting with SEED."
+ (let* ((proc (get-buffer-process inf-ruby-buffer))
+ (comint-filt (process-filter proc))
+ (kept "") completions)
+ (set-process-filter proc (lambda (proc string) (setf kept (concat kept
string))))
+ (process-send-string proc (format "puts
IRB::InputCompletor::CompletionProc.call('%s').compact\n" seed))
+ (while (not (string-match inf-ruby-prompt-pattern kept))
(accept-process-output proc))
+ (if (string-match "^[[:alpha:]]+?Error: " kept) (error kept))
+ (setf completions (butlast (split-string kept "[\r\n]") 2))
+ (set-process-filter proc comint-filt)
+ completions))
+
+(defun inf-ruby-complete-or-tab (&optional command)
+ "Either complete the ruby code at point or call
+`indent-for-tab-command' if no completion is available. Relies
+on the irb/completion Module used by readline when running irb
+through a terminal."
+ (interactive (list (let* ((curr (thing-at-point 'line))
+ (completions (inf-ruby-completions curr)))
+ (case (length completions)
+ (0 nil)
+ (1 (car completions))
+ (t (completing-read "possible completions: "
completions nil 'confirm-only curr))))))
+ (if (not command)
+ (call-interactively 'indent-for-tab-command)
+ (move-beginning-of-line 1)
+ (kill-line 1)
+ (insert command)))
+
+;;;###autoload
+(eval-after-load 'ruby-mode
+ '(add-hook 'ruby-mode-hook 'inf-ruby-keys))
+
+(provide 'inf-ruby)
+;;; inf-ruby.el ends here
- [nongnu] branch elpa/inf-ruby created (now 4ddf6b3889), ELPA Syncer, 2022/07/09
- [nongnu] elpa/inf-ruby c9a24aee52 005/265: Bugfix: Exclude input to IRB from the completion result., ELPA Syncer, 2022/07/09
- [nongnu] elpa/inf-ruby 6ad10268b3 007/265: Bugfix: Remove meaningless error check which causes a more severe error in the first place by not restoring the comint-filter., ELPA Syncer, 2022/07/09
- [nongnu] elpa/inf-ruby 5e9912fadb 002/265: Allow sending code from non-file buffers., ELPA Syncer, 2022/07/09
- [nongnu] elpa/inf-ruby 13c0040b6e 009/265: Create non-indenting completion function 'inf-ruby-complete'., ELPA Syncer, 2022/07/09
- [nongnu] elpa/inf-ruby b5aa6c51fe 027/265: [Refactor] Use defsubst for 'inf-ruby-fix-completions-on-windows', ELPA Syncer, 2022/07/09
- [nongnu] elpa/inf-ruby fe0547b16d 032/265: [Refactor] Use 'kbd' macro for key bindings, ELPA Syncer, 2022/07/09
- [nongnu] elpa/inf-ruby 60f9cfa181 001/265: Initial revision.,
ELPA Syncer <=
- [nongnu] elpa/inf-ruby c63972e2de 014/265: Package header: Don't require ruby-mode., ELPA Syncer, 2022/07/09
- [nongnu] elpa/inf-ruby 5fa2849dd0 028/265: Store non-whitespace input in the REPL history, regardless of character length., ELPA Syncer, 2022/07/09
- [nongnu] elpa/inf-ruby 89147d2ab1 056/265: inf-ruby-completions: Get rid of the last semicolon, ELPA Syncer, 2022/07/09
- [nongnu] elpa/inf-ruby c08bb93df2 040/265: inf-ruby-load-file is not defined, ELPA Syncer, 2022/07/09
- [nongnu] elpa/inf-ruby 90762203f3 055/265: inf-ruby-switch-from-compilation: Change the process filter, ELPA Syncer, 2022/07/09
- [nongnu] elpa/inf-ruby 4873a66a4d 054/265: inf-ruby-completions: Use 'then' instead of semicolons, ELPA Syncer, 2022/07/09
- [nongnu] elpa/inf-ruby 7fc1e32ae7 050/265: Bump the version, ELPA Syncer, 2022/07/09
- [nongnu] elpa/inf-ruby 530ac4f2fc 036/265: inf-ruby-mode: Modify the docstring, ELPA Syncer, 2022/07/09
- [nongnu] elpa/inf-ruby 98fac55a80 049/265: Define inf-ruby-switch-from-compilation, ELPA Syncer, 2022/07/09
- [nongnu] elpa/inf-ruby fc1dffaeed 052/265: inf-ruby-prompt-format: Include debugger prompt, ELPA Syncer, 2022/07/09