1

I have bound the eval-region function to H-x

I would like to use this to simply highlight selected code and evaluate - simple.

Working in a Python script I have the following code:

def test(this, that):
    output = this * that
    return output

print test(2,4)

When I highlight it and press H-x, I get the error message: "Symbols' value as variable is void: def"

Still having the same code highlighted, in the Python dropdown in the menu bar I click on "eval region" and I get the expected output (i.e. 8).

I have seen an explanation of void variables, but I don't really understand it all - I just want H-x to perform eval-region as clicking on the menu-bar version does.

Does anyone know a fix, work-around or the required setup?

  • 3
    eval-region evaluates only elisp code AFAIK. To see exactly what command is called by the dropdown menu, first hit C-h c or C-h k and then click that menu item. – Kaushal Modi Oct 15 '15 at 23:29
  • Thanks - it executes (in this case) python-shell-send-region. @kaushalmodi - do you how I could best get the functionality I am looking for? – n1k31t4 Oct 15 '15 at 23:32
7

What you want is to change what H-x does when in python-mode so that instead of running eval-region (which only works on elisp) it calls python-shell-send-region. You can use define-key to do this:

(with-eval-after-load 'python
  (define-key python-mode-map (kbd "H-x") #'python-shell-send-region))
  • Is having this in my .emacs a bad idea, as it is causing an error which I cannot solve. "Symbol's value as variable is void: python-mode-map". It seems to require a python session to already be in existence - it works if I evaluate at that point. How can I get around this in emacs' initialisation? – n1k31t4 Oct 16 '15 at 16:16
  • 1
    @DexterMorgan: The problem is that the variable python-mode-map is defined when python-mode is loaded, and your .emacs executes this line before that happened. Please see this answer to a recent question. The comments to this answer address exactly the issue you describe. – Constantine Oct 16 '15 at 16:34
0

The answer from @erikstokes is the correct one (hence why I have accepted it), however in order to get it to work in my init (.emacs) file, I had to define it first as a hook.

(add-hook 'python-mode-hook
          (lambda ()
            (define-key python-mode-map (kbd "H-x")
                        'python-shell-send-region)))

This allows it to load and then be called upon in python-mode, and doesn't require a python-mode to already be active (hence making in work from my one large init file. [I know it makes sense to break an init file up into sub-files, but I haven't got round to that yet]

  • You simply need to first require the package before calling this add-hook. If you are using use-package, you add that add-hook in the :config block of use-package. – Kaushal Modi Oct 16 '15 at 17:38
  • Or.. you can put that add-hook in (with-eval-after-load 'PACKAGE-NAME .. ). – Kaushal Modi Oct 16 '15 at 17:40
  • Is there a big difference/benefit to your suggestion? My way wouldn't require anything at intialisation and so I would expect faster...? – n1k31t4 Oct 16 '15 at 19:36
  • with-eval-after-load doesn't need any initialization.. it's just one wrapper around the define-key (I realized that I wrote add-hook in my earlier 2 comments instead of define-key; that was a mistake.) .. Adding that define-key to python-mode-hook will unnecessary run that define-key each time you switch to a python-mode buffer or even simply revert that buffer. I find that very inefficient. define-key wrapped with with-eval-after-load will look very much cleaner and will execute just once when the python-mode gets loaded. – Kaushal Modi Oct 16 '15 at 19:50
  • 1
    I have updated the answer by @erikstokes with with-eval-after-load. – Kaushal Modi Oct 16 '15 at 19:52

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.