2013-02-09 48 views
1

我是Emacs中的一員。我在本月初開始使用Emacs。我想要一個elisp腳本在光標下執行一行Python

我想將小Vim腳本移植到Emacs。這些腳本將使我們能夠在Emacs中像這樣計算。

http://www.youtube.com/watch?v=yDR0dTPu6M4

我試圖端口下面寫的Vim腳本。

function! s:ExecPySf_1liner() 
    let l:strAt = getline(".") 
    call writefile([strAt], "temp.pysf") 

    let l:strAt = system("python -u -m sfPP -fl temp.pysf") 
    if @0 == 0 
     let @0 = l:strAt 
    else 
     let @0 = l:strAt 
    endif 

    let @" = @0 
    if match(&clipboard, "unnamed") >= 0 
     let @* = @0 
    endif 
    echo @0 
endfunction   

但我已經筋疲力盡了。我花了整整3天的時間寫下下面的代碼。

(defun ExecPySf_1liner() 
    (let ( (strAt 
      (buffer-substring-no-properties (point-at-bol) (point-at-eol)) 
      ) 
     ) 
    ) 
) 

我用魔杖讓Emacs做下面的動作。

1 read one line under the cursor. 
2 write down the one line string into temp.pysf file in current directory 
3 execute "python -u -m sfPP -fl temp.pysf" in a shell. 
4 display the returned calculated string in echo arear 
5 and copy the string in the clipboard to enable a user to past the calculated result. 

請指出相應的elisp函數或代碼。

在此先感謝

===============================

克里斯 - 嗨。我修改了下面的代碼。

(defun __getLineOmittingComment() 
    "Get position after ';;' string. If there is no ;; then return line-beginning-posiion" 
    (interactive) 
    (goto-char (line-beginning-position)) 
    (let ((posAt (search-forward ";;" (line-end-position) t))) 
    (if (equal posAt nil) (line-beginning-position) posAt) 
    ) 
) 

(defun ExecPySf_1liner() 
    "Evaluates the current line in PythonSf, then copies the result to the clipboard." 
    (interactive) 
    (write-region (__getLineOmittingComment) (line-end-position) "temp.pysf" nil) 

    (let ((strAt 
      (shell-command-to-string "python -u -m sfPP -fl temp.pysf") 
     )) 
     (message strAt) 
     (kill-new strAt))) 

ExecPySf_1liner()計算勒讓德符號:http://en.wikipedia.org/wiki/Legendre_symbol如下。

import sympy as ts; Lgndr=lambda a,b:(lambda c=a%b:0 if ts.gcd(c,b)!=1 else 1 if any((c-k^2)%b==0 for k in range(1,b//2+2)) else -1)(); [Lgndr(3,p) for p in ts.primerange(3,100)] 
=============================== 
[0, -1, -1, 1, 1, -1, -1, 1, -1, -1, 1, -1, -1, 1, -1, 1, 1, -1, 1, 1, -1, 1, -1, 1] 

你應該看看IPython的。它帶有一個Emacs模式,可以完成所有這些工作以及更多

我可以理解你的意見。但是你可能會忽略這樣一個事實,即Python單線程是功能性編程,並且是以單線形式完成的。因爲如果其他語法不使用它們。他們必須使用lambda函數並且不使用def函數。雖然它們不是嚴格透明的,但它們是功能性編程,就像elisp腳本一樣。數學問題很容易用上Legendre Symbol的函數式編程風格編寫。

IPython中能夠保存他們的筆記,MATLAB,數學,你可以重新使用它們。但是筆記的內容整體糾結在一起。普通人在許多糟糕的表情之後寫出一個有價值的表達。有價值的表達在很多情況下依賴於一些前向表達。並且將所依賴的表達式彙集在一起​​非常麻煩。所以這張紙條留下了糾結。

一年後,當您想重新使用寶貴的表達,你會忘了注意細節,這將是難以再利用的寶貴表達。因爲你必須記住整個細節。

但是,每個Python單行本身是完整的。即使經過幾年,您也可以輕鬆地重複使用它們。您可以輕鬆地合併Python單行程序,因爲它們是功能性編程。

您可能能夠單行更容易對付的Python比IPython的Python表達式。


我從修改您的elisp代碼中學到了很多東西。我成爲elisp愛人。我可能會比Vim腳本更加熟悉elisp。非常感謝。

============================================== =================================

你應該看看IPython :)。它配備了Emacs模式,可以完成所有這些工作。 :)? 我能理解你的意見。但我聲稱使用Emacs AS IPython比使用IPython AS Emacs要好。

我稍微擴展了Python的數學。 sfPP.py是一個預處理器,它會按照以下代碼更改一行代碼。您不需要寫「打印」,因爲sfPP.py添加了打印指令。

' xy"' in 'abcd"xy"efg' 
=============================== 
False 

type __tempConverted.py 
from __future__ import division 
# -*- encoding: utf-8 -*- 
from pysf.sfFnctns import * 
setDctGlobals(globals()) 
from pysf.customize import * 
if os.path.exists('./sfCrrntIni.py'): 
    from sfCrrntIni import * 
rightSideValueAt__= ' xy"' in 'abcd"xy"efg' 
print "===============================" 
print rightSideValueAt__ 
putPv(rightSideValueAt__, '_dt') 

'"xy"' in 'abcd"xy"efg' 
=============================== 
True 

(這個例子的代碼也表明,爲什麼我敢用時間的單行文件。智能克里斯就會明白其中的道理。)

您可以輕鬆地在Emacs看Python源代碼如下所示。

source(np.source) 
In file: C:\Python27\lib\site-packages\numpy\lib\utils.py 

def source(object, output=sys.stdout): 
     snipped 
    import inspect 
    try: 
     print >> output, "In file: %s\n" % inspect.getsourcefile(object) 
     print >> output, inspect.getsource(object) 
    except: 
     print >> output, "Not available for this object." 

=============================== 
None 

你應該看看IPython的 我一直在看IPython的YouTube視頻:IPython的深度由位寫了一篇文章: 「使用VIM/Emacs的爲IPython的」

你同意我使用Emacs作爲IPython?


最後一個問題。 我想推接受按鈕。但我不知道它在哪裏。 「這個帖子對你有用嗎?是/否按鈕」可能不是那個。

+0

我不知道有足夠的瞭解的emacs或elisp的回答這個問題,但如果你的目標是用Python腳本有一個全功能的文本編輯器,你可能要考慮嘗試HTTP:// WWW .sublimetext.com/ – GrandOpener 2013-02-09 04:18:11

+0

如果我的回答很有用,請考慮點擊接受它。 :) – 2013-02-09 21:16:01

回答

2

這裏的東西我颳起了:

(defun get-current-line() 
    (buffer-substring-no-properties (line-beginning-position) 
            (line-end-position))) 

(defun run-python-command (str) 
    (shell-command-to-string 
    (concat "/usr/bin/env python -u -m sfPP -c " 
      (shell-quote-argument (concat "print(" str ")"))))) 

(defun eval-line-in-python() 
    "Evaluates the current line in python, then copies the result to the clipboard." 
    (interactive) 
    (let ((str (run-python-command (get-current-line)))) 
    (message str) 
    (kill-new str))) 

你可以用M-x eval-line-in-python運行它。

我改變它,以便它不使用臨時文件,而是直接評估該行。如果你仍然想寫一個臨時文件,這是一個微不足道的變化。

+1

你應該看看[IPython](http://ipython.org/)。它配備了Emacs模式,可以完成所有這些工作。 :) – 2013-02-09 04:41:25

+1

http://ipython.org/ipython-doc/stable/config/editors.html#x-emacs – 2013-02-09 04:42:44

+0

嗨GrandOpener,並感謝您的建議sublimetext。但我的目標是將我的Vim腳本移植到Emacs。 – 2013-02-10 01:56:24

0

對於任何其他人而言,我修改了@Chris Barrett以防止python的print追加換行符。此外,出於某種原因,導入模塊-m module使命令返回無輸出,所以我在文字命令中導入模塊。

(defun run-python-command (str) 
    (shell-command-to-string 
    (concat "/usr/bin/python -c " 
      (shell-quote-argument (concat "from myutils import *; import sys; sys.stdout.write(" str ")"))))) 
相關問題