Change the Emacs “send code to interpreter” C-c C-

2019-02-10 21:20发布

The question here is related (but NOT identical) and complementary to Change the "send code to interpreter" (C-c |) command in python-mode .

I work on a Mac 10.9.5, Emacs 24.4, Python 2.7.8 and IPython 2.2.0.

My idea is to change the C-c C-r emacs command to send a region/line of code in IPython mode to C-RET, as when using R. This is because I usually work with R, but from now on, I am going to be using R and Python (IPython in particular, which I really like), and C-RET --already the send code command in R-- seems more comfortable to me.

In the link cited at the beginning of this question they suggest to add the following lines to the .emacs file to change the C-c | command into C-c C-r:

(eval-after-load "python"
  '(progn
     (define-key python-mode-map (kbd "C-c C-r") 'python-shell-send-region)))

At the moment, my python/IPython configuration in my .emacs file looks like this:

;; Enable Python
(add-to-list 'load-path "/sw/lib/python-mode-1.0")
(load "python-mode")
(setq auto-mode-alist
      (cons '("\\.py$" . python-mode) auto-mode-alist))
(setq interpreter-mode-alist
  (cons '("python" . python-mode)
        interpreter-mode-alist))
(autoload 'python-mode "python-mode" "Python editing mode." t)

;; Ipython. This python-mode takes the Key-map and the menu
(when (executable-find "ipython")
  (setq
   python-shell-interpreter "ipython"
   python-shell-interpreter-args ""
   python-shell-prompt-regexp "In \\[[0-9]+\\]: "
   python-shell-prompt-output-regexp "Out\\[[0-9]+\\]: "
   python-shell-completion-setup-code
   "from IPython.core.completerlib import module_completion"
   python-shell-completion-module-string-code
   "';'.join(module_completion('''%s'''))\n"
   python-shell-completion-string-code
   "';'.join(get_ipython().Completer.all_completions('''%s'''))\n"))

Which are two python modes running in parallel and the second one (IPython, the one I use all the time) takes the key-map and the menu (by the way, any suggestion for a better configuration is welcome. The IPython section is based on: How to open IPython interpreter in emacs?).

I have tried to add the (eval-after-load "python" '(progn ... command described before at the end of my python configuration (of course, changing C-c C-r to C-RET or C-ret or even C-<return>).

I have also tried within the when (executable-find "ipython") ... chunk in different forms (such as simply (define-key python-mode-map (kbd "C-c C-r") 'python-shell-send-region) ). But nothing seems to work.

Therefore, my question would be: Given my Python/IPython configuration, what do I have to include in my .emacs file to change the C-c C-r command into (C-RET)

Many thanks in advance!

3条回答
劫难
2楼-- · 2019-02-10 21:41

Use (kbd "RET")

Try this with python.el

(eval-after-load "python"
  '(define-key python-mode-map [(control c)(kbd "RET")] 'python-shell-send-region))

WRT python-mode.el:

(eval-after-load "python-mode"
  '(define-key python-mode-map [(control c) (kbd "RET")] 'py-execute-region))

BTW unless IPython-exclusiv features are needed, recommend to execute code from Emacs through a common Python. IPython implements a bunch of cool things, which might appear orthogonal to Emacs, which also implements a bunch of cool things.

查看更多
Melony?
3楼-- · 2019-02-10 21:53

i did some hacking and here is what i have: by reading the code you should be able to tell how it works.

(defun block-line-end ()
    (setq indentation (current-indentation))
    (forward-line)
    (while (> (current-indentation) indentation)
      (forward-line))
    (forward-line -1)
    (line-end-position))  
(defun my-python-shell-send-region (&optional beg end)
    (interactive)
    (let ((beg (cond (beg beg)
                ((region-active-p) (region-beginning))
                (t (line-beginning-position))))
          (end (cond (end end)
                ((region-active-p) 
                 (copy-marker (region-end)))
                (t (block-line-end)))))
      (python-shell-send-region beg end))
    (forward-line))
查看更多
家丑人穷心不美
4楼-- · 2019-02-10 21:55

Here is something that was quickly cooked up to send a python line to python-shell. I tend to do it in R a lot as well. It's not completely automated yet but I might be useful.

Here are some that still remain to be made:

  1. Send line to dedicated process if necessary
  2. Assign a local key

    (defun my-python-line ()
     (interactive)
      (save-excursion
      (setq the_script_buffer (format (buffer-name)))
      (end-of-line)
      (kill-region (point) (progn (back-to-indentation) (point)))
      ;(setq the_py_buffer (format "*Python[%s]*" (buffer-file-name)))
      (setq the_py_buffer "*Python*")
      (switch-to-buffer-other-window  the_py_buffer)
      (goto-char (buffer-end 1))
      (yank)
      (comint-send-input)
      (switch-to-buffer-other-window the_script_buffer)
      (yank))
    )
    
    (global-set-key  (kbd "C-c n") 'my-python-line)
    

Update

I have improved the code a little bit more:

  1. possible to use the code directly to even if a python shell is not running yet.
  2. A local set key have been set

    Only the dedicated process remain to be made. Feel free to improve in the answer below

    (defun my-python-line ()
    (interactive)
    (save-excursion
      (setq the_script_buffer (format (buffer-name)))
      (end-of-line)
      (kill-region (point) (progn (back-to-indentation) (point)))
      (if  (get-buffer  "*Python*")
      (message "")
      (run-python "ipython" nil nil))
      ;; (setq the_py_buffer (format "*Python[%s]*" (buffer-file-name)))
      (setq the_py_buffer "*Python*")
      (switch-to-buffer-other-window  the_py_buffer)
      (goto-char (buffer-end 1))
      (yank)
      (comint-send-input)
      (switch-to-buffer-other-window the_script_buffer)
      (yank))
      (end-of-line)
      (next-line)
      )
    
    (add-hook 'python-mode-hook
        (lambda ()
      (define-key python-mode-map "\C-cn" 'my-python-line)))
    
查看更多
登录 后发表回答