1

Being more familiar with Python then elisp, I'd like to evaluate the selection as as Python snipped - as a short-cut to opening a calculator or Python prompt and copy-pasting between them.

Is there a convenient way to evaluate the selection as a Python expression?

So I could type for eg 11**13//7 and replace it with 4931816020561

  • python-mode.el available at Melpa comes with a variable py-return-result-p - when t it stores the result in kill-ring. From there replace an active-region with. – Andreas Röhler Nov 22 '17 at 7:22
1

Posting own answer which mostly works as I'd like (needed some special consideration for evil mode and fci).

While it works well for basic usage, errors will also replace the selection, ideally a nonzero exit code would display as a message instead of putting the error into the editor.

;; See: https://emacs.stackexchange.com/a/34900/2418
;; Wrapper for 'shell-command-on-region', keeps the selection.
(defun shell-command-on-region-and-select
    (start end command
           &optional output-buffer replace
           error-buffer display-error-buffer
           region-noncontiguous-p)
  "Wrapper for 'shell-command-on-region', re-selecting the output.

        Useful when called with a selection, so it can be modified in-place"
  (interactive)
  (let ((buffer-size-init (buffer-size)))
    (when fci-mode-enabled (turn-off-fci-mode))
    (shell-command-on-region
     start end command output-buffer replace
     error-buffer display-error-buffer
     region-noncontiguous-p)
    (setq deactivate-mark nil)
    (setq end (+ end (- (buffer-size) buffer-size-init)))
    (set-mark start)
    (goto-char end)
    (activate-mark)
    ;; needed for evil line mode
    (when (string= evil-state "visual")
      (when (eq (evil-visual-type) evil-visual-line)
        (evil-visual-select start end 'line)))))

(defmacro without-fci-mode (&rest body)
  "Run expression without fci mode, evaluates to the result of 'body'"
  `(let ((fci-mode-enabled (bound-and-true-p fci-mode)))
     (when fci-mode-enabled (turn-off-fci-mode))
     (let ((result ,@body))
       (when fci-mode-enabled (turn-on-fci-mode))
       result)))

(defun eval-region-as-py ()
  "Evaluate selection as a python expression, replacing it with the result"
  (interactive)
  (without-fci-mode
   (shell-command-on-region-and-select
    (region-beginning)
    (region-end)
    "python -c 'import sys; sys.stdout.write(str((eval(sys.stdin.read()))))'" 0 t)))

(define-key evil-visual-state-map (kbd "RET") 'eval-region-as-py)
0

Just select your code and then

C-u M-|   python

or

C-u M-x shell-command-on-region   python
  • This outputs (Shell command succeeded with no output) unless you add print() around every expression. – ideasman42 Nov 23 '17 at 14:14
  • of course you need to print the result – djangoliv Nov 23 '17 at 14:20
  • Not necessarily, this can be setup so the result is always printed. – ideasman42 Nov 23 '17 at 15:00

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.