Execute Scala code from within Emacs - scala

Scala REPL is great for short expressions, but multi-line expressions are difficult to edit, especially if there some syntax error somewhere, it requires reissuing the statements line by line.
On the other hand Emacs scala-mode2 looks nice, it would be awesome if I could just select a region of the buffer and send it to Scala REPL, and see the results in a minibuffer.
Is this possible? Googling didn't produce any positive answer.
or do you think this would be an useful feature?
If I were to implement this, what would be the best approach? I was thinking that I could just have a Scala REPL running in the background and interacting with it via std in/out from Emacs.

Just in case anyone is interested, the below Emacs script will evaluate the region in the Scala REPL.
(defun eval-scala (start end)
(interactive (list (point) (mark)))
;; start scala if it hasn't started yet
(unless (get-process "scala-repl")
(let ((process-connection-type nil)) ; use a pipe
(start-process "scala-repl" "*scala*" "scala"))
(set-buffer "*scala*")
(special-mode)
)
;; execute
(process-send-region "scala-repl" start end)
(process-send-string "scala-repl" "\n")
;;display buffer
(display-buffer
(get-buffer "*scala*")
'((display-buffer-reuse-window
display-buffer-pop-up-window
display-buffer-pop-up-frame)
(reusable-frames . 0)
(window-height . 8) (window-width . nil)
)
)
)
Bind the above eval-scala function to your preferred short-cut key, e.g.
(global-set-key (kbd "C-e") 'eval-scala)

Related

key chords in isearch

I really love key-chord.el. It's become an integral part of my workflow, but sometimes I wish I could have them in the minibuffer (for things like evil-search). Specifically, I'd like jj to exit out of evil-search and move down a line. Is this possible?
I know I can hack together a command that acts as both a prefix and a command (see this SO question), so I could bind j to a self inserting command, and jj to my special command. How would I be able to break the event loop after a specified idle time? I do type jj once in a blue moon, and I'd still like the flexibility of a timeout.
Is there any other way which I am unaware of to achieve what I want?
EDIT:
Origionally, this question was about the minibuffer in general. key-chord.el seems to work fine with minibuffer-local-map. It does not, however, work with isearch-mode-map. Binding a command to a single regular key like j does work in isearch. This is what I'm trying to solve.
I have found a solution which manually reproduces the behaviour of key-chord.el.
(defun isearch-exit-chord-worker (&optional arg)
(interactive "p")
(execute-kbd-macro (kbd "<backspace> <return>")))
(defun isearch-exit-chord (arg)
(interactive "p")
(isearch-printing-char)
(unless (fboundp 'smartrep-read-event-loop)
(require 'smartrep))
(run-at-time 0.3 nil 'keyboard-quit)
(condition-case e
(smartrep-read-event-loop
'(("j" . isearch-exit-chord-worker)
("k" . isearch-exit-chord-worker)))
(quit nil)))
;; example bindings
(define-key isearch-mode-map "j" 'isearch-exit-chord)
(define-key isearch-mode-map "k" 'isearch-exit-chord)
This approach actually has several advantages over key-chord.el.
It does not use an input method, so you can use a different input method in conjunction with this.
The first character is shown immediately, and retracted if it is incorrect, while key-chord.el only shows it after a delay.
I have found this to be useful:
(defun isearch-enable-key-chord ()
(key-chord-mode 1)
(key-chord-define isearch-mode-map "jj" 'isearch-cancel))
(add-hook 'isearch-mode-hook 'isearch-enable-key-chord)

difference between calling command directly and using keybinding

I'm new to elisp, so please forgive me if the following approach is totally clumsy.
In the team I'm currently working with, there is an usual convention of closing python blocks with a pass statement (if they aren't ended by closing keywords like else or except or such). While unusual, this has the advantage that one can always recover the original indentation of the program if it is unintentionally changed (using emacs indent-region).
To get existing code in line with this convention, I wrote a small elisp function:
(defun python-check-indent ()
"Check if automatic indentation changes current indent, insert pass keyword if it does."
(interactive)
(move-beginning-of-line 1)
(skip-chars-forward " ")
(if
(< 0
(let (original)
(setq original (point))
(indent-for-tab-command)
(- (point) original)
)
)
(progn
(insert "pass")
(newline)
(indent-for-tab-command)
)
)
(next-line)
)
(global-set-key (kbd "C-`") 'python-check-indent)
The idea is simply to test whether hitting TAB would change the indentation, and insert a pass statement in that case. To facilitate processing longer blocks of code, it then advances to the next line.
When I run it using M-x python-check-indent, it does what I want (except that it moves around empty lines slightly), also when running it repeatedly to process several lines. However, when I run it repeatedly using the C-` keybinding, it starts messing up the code from the second invocation on.
So here are my questions: What is the difference between invoking a command with M-x ... and using its keybinding? And how could I change the function to be not affected by this difference?
emacs-version: GNU Emacs 23.3.1 (x86_64-apple-darwin, NS apple-appkit-1038.35) of 2011-03-10 on black.porkrind.org
(edit) current workaround: I'm now wrapping it inside a keyboard-macro, so it's "bound" to C-x e, and behaves properly.
The general rule is that it is best to avoid complex interactive
commands in your functions because they could be affected by all sorts
of options.
(defun python-check-indent ()
"Check if automatic indentation changes current indent, insert pass keyword if it does."
(interactive)
(goto-char (line-beginning-position))
(skip-chars-forward " ")
(when (< 0
(let (original)
(setq original (point))
(python-indent-line)
(- (point) original)))
(insert "pass\n")
(python-indent-line))
(forward-line))
However, even this is probably not good because python-indent-line's behavior depends on last-command and python-indent-trigger-commands. I think it would be best if you replaced the first invocation of python-indent-line with the code which computes the target indentation instead of actually indenting, something like (nth python-indent-current-level python-indent-levels).
PS. If you still have problems, I suggest that you use edebug and step through the function.

AUCTeX: Run Compile Command n-times

I'd like to have a function that asks for a number n and executes the default compile command n-times afterwards. That is to say unlike C-c C-c (i.e. TeX-command-master) I don't want to be asked which command to run, it should select the default compile command based on the AUCTeX settings. Naturally if any error occurs the execution should stop.
I know about TeX-texify, however, this doesn't statisfy my needs because sometimes I just want emacs to run pdflatex five times indepent of what the AUCTeX parser thinks is adequate.
Any help is much appreciated!
Edit: I have looked into this a little further and using code from the above reference I have started writing a function that does this. However, it has one major flaw. Let me first give you the code:
(defcustom TeX-MultiTeX-Command "LaTeX" "Default MultiTeX command" :type 'string :group 'TeX-command)
(defun TeX-MultiTeX (n)
"Run TeX-command n-times"
(interactive "nRun TeX/LaTeX how many times: ")
(while (> n 0)
(TeX-command TeX-MultiTeX-Command 'TeX-master-file)
(setq n (- n 1))))
As you can see, I have implemented a config variable for selecting the correct compilation command. Now let me present the problem:
The compilation of the LaTeX document takes some time, however, my function instantly calls the second (and following) executions of the compile command. Maybe someone can provide help in finding a solution that checks whether compilation has finished successfully prior to executing (TeX-command TeX-MultiTeX-Command 'TeX-master-file), then executes said function or prints some error message if compilation finished with an error.
With the help of the code of the TeX-texify function I have developed a function that does what I want, the code is given below.
I'd like to thank user4815162342; although this solution is not based on his suggestion, I think his solution might be of use for a different problem. Also I'd like to thank TN, the author of TeX-texify, I shamelessly took and adapted his code for my problem. ;)
(defcustom TeX-MultiTeX-Command "LaTeX"
"Default MultiTeX command"
:type 'string :group 'TeX-command)
(defun TeX-MultiTeX-sentinel (&optional proc sentinel)
"Non-interactive! Call the standard-sentinel of the current LaTeX-process.
If there is still something left do do start the next latex-command."
(set-buffer (process-buffer proc))
(funcall TeX-MultiTeX-sentinel proc sentinel)
(let ((case-fold-search nil))
(when (string-match "\\(finished\\|exited\\)" sentinel)
(set-buffer TeX-command-buffer)
(unless (plist-get TeX-error-report-switches (intern (TeX-master-file)))
(TeX-MultiTeX TeX-MultiTeX-num-left)))))
(defun TeX-MultiTeX (n)
"Run TeX-command n-times"
(interactive "nRun TeX/LaTeX how many times: ")
(when (or (called-interactively-p 'any)
(null (boundp 'TeX-MultiTeX-num-left)))
(setq TeX-MultiTeX-num-left n))
(if (>= TeX-MultiTeX-num-left 1)
(progn
(TeX-command TeX-MultiTeX-Command 'TeX-master-file)
(setq TeX-MultiTeX-num-left (- TeX-MultiTeX-num-left 1))
(setq proc (get-buffer-process (current-buffer)))
(setq TeX-MultiTeX-sentinel (process-sentinel proc))
(set-process-sentinel proc 'TeX-MultiTeX-sentinel))))
It seems that you need a synchronous way to run TeX-command. I haven't word with TeX-command, but if it uses the compilation API, it can be made to wait for the compilation to finish, although it's not exactly obvious how to do that. Here is an example that uses compilation-finish-functions to achieve the desired effect:
(require 'cl) ; for lexical-let
(defun compile-and-wait (compilefun)
(interactive)
(lexical-let ((done nil) finish-callback)
(setq finish-callback
;; when the compilation is done, remove the callback from
;; compilation-finish-functions and interrupt the wait
(lambda (buf msg)
(setq compilation-finish-functions
(delq finish-callback compilation-finish-functions))
(setq done t)))
(push finish-callback compilation-finish-functions)
(funcall compilefun)
(while (not done)
(sleep-for .1))))
EDIT
AUC TeX is not using compilation mode to spawn TeX, so the above cannot work. Since it's still useful for other compilation buffers, I'm leaving it in the answer. Another way to implement TeX-MultiTeX is by binding TeX-process-asynchronous to nil, which should ensure that AUC TeX waits for the command to finish.

switch buffer settings using python-mode in emacs?

I have been using emacs for a while but not so familiar with lisp programming. Its been just couple of days I started coding Python on emacs. I found python-mode to be quite useful and I want to explore it further. I found a few emacs lips functions on internet, tewaked them a bit to make the interface userfriendly. I am trying to achieve following actions
I usually start emacs with 2 vertical windows, one with python source and other is a shell. I should be able to do following using keyboard bindings
switch between buffers (working)
execute a region (working)
but replaces the source buffer with shell buffer. I want to execute selected region in original shell buffer.
execute a line (working)
but same issue as above. when i pres say , the line should be executed in python shell without replacing any buffers. so copy the line, switch to python shell, execute line, switch back to python source buffer.
I am not able to achieve switching action above. Following is my code from my init.el file
(defun goto-python-shell ()
"Go to the python command window (start it if needed)"
(interactive)
(setq current-python-script-buffer (current-buffer))
(if (boundp 'current-python-shell-buffer)
(switch-to-buffer-other-window current-python-shell-buffer)
(py-shell))
(end-of-buffer)
)
(defun goto-python-source ()
"switch back to source window"
(interactive)
(setq current-python-shell-buffer (current-buffer))
(switch-to-buffer-other-window current-python-script-buffer)
)
(defun py-execute-statement-and-step ()
"select a statement, submit as a region and then step forward"
(interactive)
(beginning-of-line 1)
(let ((beg (point)))
(py-next-statement 1)
; if last statement.
(if (= (point) beg) (end-of-buffer ))
; (switch-to-buffer-other-window current-python-shell-buffer)
(py-execute-region beg (point))
(switch-to-buffer-other-window current-python-script-buffer)
)
)
; some key bindings
(define-key python-mode-map (quote [f9]) 'py-execute-statement-and-step)
;(define-key python-mode-map (quote [f10]) `py-execute-region)
;py-shell-switch-buffers-on-execute
(define-key python-mode-map (quote [f10]) `py-shell-switch-buffers-on-execute)
(define-key python-mode-map (quote [f11]) `py-execute-buffer)
(define-key python-mode-map (quote [f12]) `goto-python-shell)
(define-key py-shell-map (quote [f12]) `goto-python-source)
Please advice.
Also since i am new to python-mode, can someone share nice initializations for using python-mode similar to above?
thanks much for your help.
Regards,
AJ
You should take a look at the first answer to this question and customize the py-shell-switch-buffers-on-execute variable.
This way you won't need all your custom functions to make python-mode work like you want (i.e. keeping the source buffer active)
I think that you are trying to reinvent what is available in Emacs 24 (at least with evaluation stuff). Try Emacs 24. When you are editing a Python source code, you can press C-c C-c to evaluate a buffer and press C-c C-r to evaluate a region. You don't have to explicitly start a Python shell.
I don't think that there is a direct support for evaluate a line and step. You can achieve it by the keystrokes C-SPC C-n C-c C-r. Your focus will remain in the source code and there is no need to switch explicitly between the source code and the shell.
FWIW, I have been using Emacs 24 for a reasonable amount of time on a daily basis and I haven't encountered any stability issues.
following changes are working like a charm. f9 does line by line execute and f10 does region based execution. curser remains in the script window after i disabled py-shell-switch-buffers-on-execute.
(defun py-execute-statement-and-step ()
"select a statement, submit as a region and then step forward"
(interactive)
(beginning-of-line 1)
(let ((beg (point)))
(py-next-statement 1)
; if last statement.
(if (= (point) beg) (end-of-buffer ))
(py-execute-region beg (point))
(next-line)
)
)
(custom-set-variables
'(py-shell-switch-buffers-on-execute nil))
(define-key python-mode-map (quote [f9]) 'py-execute-statement-and-step)
(define-key python-mode-map (quote [f10]) `py-execute-region)

Copy Character Down in Emacs

I wrote an interactive function which inserts the "character above the point" in to the current line. For instance, given a line containing "12345" followed by a line "abcdef" and the point sitting at the letter "c", copy-down would make the second line become "ab3cdef". copy-down again would make the second line become "ab34cdef".
My function fails (using GNU Emacs 23.3.1 under windows 7) the second time I invoke it by inserting the text from the first invocation and not advancing properly. If I put any emacs "manipulations" in-between invocations, it works fine. (For instance if I do a copy-down, "left arrow", "right arrow", copy-down it works fine for both invocations.)
Here's my function:
(defun copy-down ()
"Grab the character in the line above and insert at the current location."
(interactive)
(let ((beg (progn (previous-line 1) (point)))
(end (progn (forward-char) (point))))
(backward-char)
(next-line 1)
(insert-buffer-substring (current-buffer) beg end)))
If it matters, I usually tie my function to a key: (global-set-key [f5] 'copy-down)
PS. I got used to using this capability in the editor I used before switching to emacs many years ago and I miss it in GNU Emacs. :-(
What you have works just fine for me. That said, previous-line has interaction with other settings (specifically goal-column) and generally shouldn't be used when writing elisp. Instead you should use (forward-line -1). But, of course, your code relies on the goal-column... You can test this by running Emacs without your other configurations, ala emacs -q.
Here's a slightly different version of your code that doesn't rely on goal-column:
(defun copy-down ()
"Grab the character in the line above and insert at the current location."
(interactive)
(let* ((col (current-column))
(to-insert (save-excursion
(forward-line -1)
(move-to-column col)
(buffer-substring-no-properties (point) (1+ (point))))))
(insert to-insert)))
If the problem isn't with using previous-line, then I don't imagine my code would make much of a difference.
Another option you have is to try running it in the debugger to see where your code breaks down. Move the point inside the defun for copy-down and type M-x edebug-defun, and the next time you run it you'll be able to step through the code. Docs for edebug can be found here.
You need to use let* instead of let. The former allows you to use earlier values in later forms in the same statement.
BTW, that's an unconventional way to write elisp, you might want to look at some other code samples.
EDIT:
Hey, someone completely rearranged your function! It might work now.
Try
(defun copy-down (arg)
(interactive "p")
(let ((p (+ (current-column) (point-at-bol 0))))
(insert-buffer-substring (current-buffer) p (+ p arg))))
which has the additional functionality of taking a prefix argument to copy n (default to 1) characters down.