6

I'm using Julia within emacs, and I've found that despite the existence of ess and julia-mode, the best way for me to do that seems to be to use ansi-term and execute:

ipython3 console --kernel=julia-0.5

This way, I get behavior identical to the IJulia console opened in a regular terminal. Compared to run-julia, I get better shell and help support and will presumably eventually include magic as IJulia matures.

To save time, I'd like to make a definition in my .emacs file so that I can write a function and bind a key that opens ansi-term and executes the command above. How would I go about doing that?

Thanks in advance.

Zorgoth
  • 810
  • 6
  • 14

2 Answers2

7

This sort of thing?

(defun my-foo-console ()
  "Runs foo in a `term' buffer."
  (interactive)
  (require 'term)
  (let* ((cmd "foo")
         (args "--args for --command")
         (switches (split-string-and-unquote args))
         (termbuf (apply 'make-term "foo console" cmd nil switches)))
    (set-buffer termbuf)
    (term-mode)
    (term-char-mode)
    (switch-to-buffer termbuf)))

(global-set-key (kbd "C-c s f") 'my-foo-console)

Note that this is just a slight elaboration on what the term command does.

As another example (one that I use extremely regularly):

(defvar my-ssh-history nil)

(defun my-ssh (args)
  "Connect to a remote host by SSH."
  (interactive
   (list (read-from-minibuffer "ssh " nil nil nil 'my-ssh-history)))
  (let* ((switches (split-string-and-unquote args))
         (name (concat "ssh " args))
         (termbuf (apply 'make-term name "ssh" nil switches)))
    (set-buffer termbuf)
    (term-mode)
    (term-char-mode)
    (switch-to-buffer termbuf)))

(global-set-key (kbd "C-c s h") 'my-ssh)

(savehist-mode 1) ;; remembers minibuffer histories between sessions

(I use C-c s as a prefix for all my shell/console type bindings, if you thought that seemed odd.)

Edit: It just occurred to me to write this variant for ad-hoc use:

(defvar my-terminal-run-history nil)

(defun my-terminal-run (command &optional name)
  "Runs COMMAND in a `term' buffer."
  (interactive
   (list (read-from-minibuffer "$ " nil nil nil 'my-terminal-run-history)))
  (let* ((name (or name command))
         (switches (split-string-and-unquote command))
         (command (pop switches))
         (termbuf (apply 'make-term name command nil switches)))
    (set-buffer termbuf)
    (term-mode)
    (term-char-mode)
    (switch-to-buffer termbuf)))

(global-set-key (kbd "C-c s c") 'my-terminal-run)
phils
  • 48,657
  • 3
  • 76
  • 115
1

Here is what I put in my .emacs based on phils' answer, for reference:

(defun ijulia-console ()
  "Runs IJulia in a `term' buffer."
  (interactive)
  (require 'term)
  (let* ((rawjversion (shell-command-to-string "julia --version"))
         (jversion (replace-regexp-in-string " version \\([^.]*[.][^.]*\\).*\n$" "-\\1" rawjversion))
         (cmd "ipython3")
         (args (concat "console --kernel=" jversion))
         (switches (split-string-and-unquote args))
         (termbuf (apply 'make-term "IJulia Console" cmd nil switches)))
    (set-buffer termbuf)
    (term-mode)
    (term-char-mode)
    (switch-to-buffer termbuf)))

The code I added asks for the Julia version in order to make sure that the correct Julia kernel is called.

Zorgoth
  • 810
  • 6
  • 14