简体   繁体   English

从emacs运行交互式python脚本

[英]Running interactive python script from emacs

I am a fairly proficient vim user, but friends of mine told me so much good stuff about emacs that I decided to give it a try -- especially after finding about the aptly-named evil mode... 我是一个相当熟练的vim用户,但是我的朋友告诉我关于emacs的这么多好东西,我决定尝试一下 - 特别是在找到适当命名的邪恶模式之后......

Anyways, I am currently working on a python script that requires user input (a subclass of cmd.Cmd). 无论如何,我目前正在开发一个需要用户输入的python脚本(cmd.Cmd的子类)。 In vim, if I wanted to try it, I could simply do :!python % and then could interact with my script, until it quits. 在vim中,如果我想尝试它,我可以简单地执行:!python %然后可以与我的脚本交互,直到它退出。 In emacs, I tried M-! python script.py 在emacs中,我试过M-! python script.py M-! python script.py , which would indeed run the script in a separate buffer, but then RETURNs seems not to be sent back to the script, but are caught by the emacs buffer instead. M-! python script.py ,它确实会在一个单独的缓冲区中运行脚本,但是RETURN似乎不会被发送回脚本,而是被emacs缓冲区捕获。 I also tried to have a look at python-mode's Cc Cc , but this runs the script in some temporary directory, whereas I just want to run it in (pwd) . 我还试着看看python-mode的Cc Cc ,但是这会在一些临时目录中运行脚本,而我只想在(pwd)运行它。

So, is there any canonical way of doing that? 那么,有没有任何规范的方法呢?

I don't know about canonical , but if I needed to interact with a script I'd do M - x shell RET and run the script from there. 我不知道规范 ,但如果我需要与脚本交互,我会做M - x shell RET并从那里运行脚本。

There's also M - x terminal-emulator for more serious terminal emulation, not just shell stuff. 还有M - x terminal-emulator用于更严肃的终端仿真,而不仅仅是shell的东西。

I like to use the Emacs "compile" command to test/run my python scripts. 我喜欢使用Emacs“compile”命令来测试/运行我的python脚本。 M - X compile RET will pull up the default "make -k" but if you delete that and put in the command line for your script (including options), subsequent "compiles" will provide the new "compile" command automatically. M - X编译RET将提取默认的“make -k”,但是如果删除它并放入脚本的命令行(包括选项),后续的“编译”将自动提供新的“编译”命令。 All the output from your script will appear in the compile buffer. 脚本的所有输出都将出现在编译缓冲区中。 (As opposed to the shell, this provides a nice clean buffer each time it is invoked. Good for searching and such. If you forget to save your script before your run, compile will ask you if you would like to save the file.) (与shell相反,每次调用时都会提供一个很好的干净缓冲区。很适合搜索等。如果你忘记在运行之前保存脚本,编译会询问你是否要保存文件。)

You will lose your the command line when you restart Emacs. 重新启动Emacs时将丢失命令行。 But you can get Emacs to set the compile-command for the buffer holding your script by putting at the bottom of the python script this sort of code (actually a python comment): 但是你可以通过在python脚本的底部放置这种代码(实际上是python注释)来让Emacs为保存脚本的缓冲区设置编译命令:

 # Trigger emacs to run this script using the "compile" command
 # ;;; Local Variables: ***
 # ;;; compile-command: "my_cool_script.py --complicated_option some_filename.txt" ***
 # ;;; end: ***

This is handy for scripts with complicated invocations. 这对于具有复杂调用的脚本非常方便。 Note: The python comment character '#' protects this from the python interpreter while Emacs knows to set these variables because it looks at the bottom of every file when it opens them. 注意:python注释字符'#'保护python解释器,而Emacs知道设置这些变量,因为它在打开它们时查看每个文件的底部。

I'd love to be able to jump to 'compile errors' in my python script the way the compile command does when you use it for compiling C code but I'm too lazy to create the Emacs regular expression to make this work. 我希望能够像编译命令一样在我的python脚本中跳转到'编译错误',当你使用它来编译C代码时,我却懒得创建Emacs正则表达式来使其工作。 Perhaps that would make another great question for stack overflow! 也许这会成为堆栈溢出的另一个很好的问题!

I currently use these hook to define my compilation commands: 我目前使用这些钩子来定义我的编译命令:

(defun convert-filename-to-executable (file)
  (if (eq system-type 'windows-nt)
      (concat (file-name-sans-extension file) ".exe")
    ;; linux
    (concat "./" (file-name-sans-extension file))))


(add-hook 'c++-mode-hook
          (lambda ()
            (unless (file-exists-p "Makefile")
              (set (make-local-variable 'compile-command)
                   (let* ((file (file-name-nondirectory buffer-    file-name))
                      (executable (convert-filename-to-executable file)))
                 (concat "g++ -g -Wall -o "
                         (file-name-sans-extension file)
                         " "
                         file
                         " && "
                         executable))))))

(add-hook 'c-mode-hook
      (lambda ()
        (unless (file-exists-p "Makefile")
          (set (make-local-variable 'compile-command)
               (let* ((file (file-name-nondirectory buffer-file-name))
                      (executable (convert-filename-to-executable file)))
                 (concat "gcc -g -ansi -Wall -Wpedantic -Wextra -Wc++-compat -Wconversion -o "
                         (file-name-sans-extension file)
                         " "
                         file
                         " && "
                         executable))))))    
(add-hook 'python-mode-hook
          (lambda ()
              (set (make-local-variable 'compile-command)
                   (concat "python " buffer-file-name))))

(add-hook 'perl-mode-hook
          (lambda ()
              (set (make-local-variable 'compile-command)
                   (concat "python " buffer-file-name))))

Together with this lambda set to call the compile function interactively: 与此lambda一起以交互方式调用编译函数:

(global-set-key (kbd "<f4>") (lambda () (interactive) (setq current-prefix-arg '(4)) (call-interactively 'compile)))

One button to rule them all! 一键统治他们!

If you press F4 (in my case, you can set the key yourself in the lambda for global-set-key ), then a file opened in C++ or C mode will be compiled and a file in python or perl mode will be run (interactively) 如果按F4 (在我的情况下,您可以在lambda中为global-set-key ),则将编译以C ++或C模式打开的文件,并运行python或perl模式的文件(交互)

The I think ansi-term has the most faithful emulation of a terminal. 我认为ansi-term对终端有最忠实的模仿。 But I don't see a way to pass arguments to the process. 但是我没有看到将参数传递给进程的方法。 You can of course just launch it from a shell inside the ansi-term buffer. 您当然可以从ansi-term缓冲区内的shell启动它。

But I think the best thing to do is to not use python-send-buffer , but instead to use a new function which does it "right", that is by sending the path to the current file instead of making a temp file. 但我认为最好的办法是不使用python-send-buffer ,而是使用一个“正确”的新函数,即通过将路径发送到当前文件而不是生成临时文件。 There are some slight differences of course in that you have to save the current file first, but the following should at least get you on the right track. 当然,您必须首先保存当前文件,但是以下内容应该至少让您走上正确的轨道。

(defun python-send-file ()
  (interactive)
  (save-buffer)
  (python-send-string (concat "execfile('" (buffer-file-name) "')")))

;; This overwrites the `python-send-buffer' binding so you may want to pick another key
(eval-after-load "python" 
  (define-key python-mode-map "\C-c\C-c" 'python-send-file))

I checked and this allows you to interact. 我查了一下,这可以让你互动。 To get tabs you have a few options. 要获得标签,您可以选择一些选项。

  • Cq TAB will always give you a literal tab Cq TAB将始终为您提供文字选项卡
  • You can rebind tab to be a literal tab in inferior-python-mode-map : 您可以将tab重新绑定为inferior-python-mode-map的文字选项卡:

     (define-key inferior-python-mode-map "\\Ci" 'self-insert-command) 
  • I'm sure there are others that I can't think of 我确信还有其他我无法想到的

If you use Cc Cc a buffer is created (look for inferior-python). 如果使用Cc Cc,则会创建一个缓冲区(查找inferior-python)。 Try changing to that buffer*, every time you hit Cc Cc the result is shown there, you need to see that buffer to get the results. 尝试更改到该缓冲区*,每次点击Cc Cc时显示结果,您需要查看该缓冲区以获得结果。 Use Cx 2 so you can see both buffers at the same time. 使用Cx 2,这样您就可以同时看到两个缓冲区。 Also try Cc Cz (switch to shell). 同时尝试Cc Cz(切换到shell)。

*I use Ibuffer to manage buffers, is very good. *我使用Ibuffer来管理缓冲区,非常好。 (btw, this http://tuhdo.github.io/index.html is an excelent place to learn some emacs) (顺便说一句,这个http://tuhdo.github.io/index.html是学习一些emacs的好地方)

EDIT: Have you tried Cc Cp ? 编辑:你试过Cc Cp吗?

Yet another option: 还有一个选择:

Using Cc Cc works nicely with fgallina's python.el -- pwd will be the location of the buffer's file. 使用Cc Cc可以很好地使用fgallina的python.el - pwd将是缓冲区文件的位置。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM