2010-08-12 59 views
5

我目前正在向現有的J2EE Web應用程序添加功能的過程中,在Tomcat容器中,並且正在使用Clojure編寫我的添加程序。我的設置很簡單:我只是將調用添加到由clojure生成的靜態方法中,並從clojure一側編碼所有的辛苦工作。構建過程包括編譯clojure代碼(lein uberjar),然後在類路徑中使用該jar編譯java代碼。如何將一個clojure源文件連接到Emacs上正在運行的clojure repl?

在webapp init中,我調用了一個生成的類,該類激活了一個(swank/start-repl)的swank服務器。我希望能夠將我的Aquamacs的粘液連接到該服務器,並從那裏交互式地工作(直到某一點,我不會嘗試任何需要Java端重新編譯的東西)。但我有一個我不太明白的情況。如果我做了一個\M-x slime-connect,我得到了一個REPL提示符(在被通知沒有低劣的lisp進程後,我認爲它沒問題,因爲劣勢lisp進程在emacs控制之外運行)。我可以完美地評估表格,我甚至可以檢查諸如my.own.namespace/my-var之類的東西。但是,如果我訪問一個已經編譯好的clojure代碼的文件,我似乎無法讓史萊姆認出它來源。舉一個簡單的Clojure文件:

(ns my.namespace 
    (:gen-class 
    :name my.namespace 
    :methods [#^{:static true} [testFunc [] void]])) 

(def *secret* "shhhh") 

(defn -testFunc [] 
    (println (str "our secret is: " secret))) 

假設這是由web應用程序加載的uberjar編譯在內,我可以EVAL /檢查my.namespace/*secret*。但是,如果我嘗試在代碼緩衝區內進行評估,Slime認爲我處於user命名空間(這甚至可以說是有道理的!)。但現在我剩下一個工作選項 - 我必須逐個評估 - 文件中的所有表單! \C-c \C-l(加載源文件)將不會執行任何操作 - 顯然只是返回nil而不輸出其他內容。編譯一切似乎只是這樣做的 - 它編譯,如果發現它們會顯示錯誤,但不會更改我的名稱空間。最奇怪的是\C-~(同步包和目錄),它使用Common Lisp它只是我想要的,但它在這裏凍結了clojure REPL。

總是可以選擇切換到REPL,輸入(in-ns 'my.namespace),然後所有工作都正常。但是,當clojure文件數量增長時(因爲代碼緩衝區的名稱空間不會自動改變!),這根本就不夠實際!

我的問題是,我是否缺乏基本的命令/配置 - 或者如果這種行爲發生的明顯原因如此。

+0

引用這個問題:「編譯一切似乎只是這樣做」 - 你是什麼意思?也就是說,加載Clojure代碼的方法是指當你說「編譯所有東西」時(Clojure代碼總是被編譯的,但是你可能有一些SLIME函數)。另外,你期望的結果究竟是什麼? – 2010-08-12 19:14:46

+0

「編譯所有內容」 - 點擊「Cc Ck」將編譯emacs文件緩衝區中的所有表單,在這些表單上顯示錯誤,並有效地使重定義(和新定義的)表單動態可用(例如,將使用webapp調用這個新編譯的代碼)。對不起,我沒有那麼清楚。 – Edgar 2010-08-13 01:10:38

+0

我期待的行爲類似於我用'Mx swank-clojure-project'開始SLIME時看到的行爲:當切換到文件緩衝區時,名稱空間會自動更改,因此評估某些內容時不會使用'user'命名空間。或者,當使用'C-c C-k' /'C-c C-l'編譯/加載緩衝區時,應該評估所有格式,包括最初的'(ns ...)',從而切換到特定的命名空間並使所有後續變量都屬於它。這不是標準設置中的預期行爲嗎? (我可能會以錯誤的方式看待它......) – Edgar 2010-08-13 01:11:13

回答

1

我剛剛發現刪除這個問題的罪魁禍首:slime-redirect-inferior-output,來自slime-repl.el,是從我設置的鉤子中調用的。事實證明,如果沒有一個劣等lisp進程(讀取,從emacs內部啓動一個swank服務器),它就不會運行良好。

因此,一個快速的解決方法是刪除該函數的error表單,如this。現在鉤子繼續了,名稱空間自動計算。如預期。不過謝謝你的建議,他們讓我接觸到這個解決方案!

5

我可能誤解了你的問題,但是你不能(在emacs中訪問這個假設的緩衝區時),點擊C-c C-k來編譯當前Clojure實例中的緩衝區(Slime連接到哪個緩衝區)?

然後,在Slime緩衝區中,使用(in-ns 'my.namespace)切換到此名稱空間。然後你應該可以訪問你在那個名字空間中編譯的東西。

+0

嗯,正如我在一個問題的評論中寫的那樣,編譯會起作用,但我的觀點是,我習慣於'(in-ns)my .namespace)'在編譯/加載文件後隱含。它在我用SLIME,IIRC的每個Common Lisp實現中都以這種方式工作;另外,不得不在10個或更多的文件項目中手動切換命名空間(特別是使用超過理想的clojure重啓時間)會導致疲勞 - 並且之後短時間,精神錯亂:) - 所以如果我沒有做錯什麼,並且交互I應該是這樣的,我會編寫一個解決方法! – Edgar 2010-08-13 01:17:55

+0

呵呵,另外,如果在.clj文件緩衝區中進行了適當的評估,'(in-ns'my.namespace)'根本就不起作用 - 我必須在REPL上執行它,然後該文件的緩衝區會切換其命名空間。對我而言,這也不太明顯。 – Edgar 2010-08-13 01:22:09

+0

你完全正確 - 這是一個痛苦的屁股。我想我已經習慣了,並且在Clojure之前沒有用Slime/Swank編碼。讓我知道你是否得到解決辦法!我認爲現在事情正在爲你工作?還有什麼還沒有答案? (不是我回答了什麼,但是我想知道我是否仍然可以幫助!) – Isaac 2010-08-13 03:16:48

2

在swank-clojure中自動切換命名空間並不是swank-clojure的默認選項,儘管它可能是一個與Clojure一起使用的可選Slime特性。但是C-C M-p將repl切換到當前緩衝區的名稱空間一直對我有效,我從來沒有聽說過有人遇到過任何問題。

您是否正在運行最新的clojure-mode和slime-repl的穩定版本?你有安裝swank-clojure.el嗎? (你不應該需要它。)這聽起來可能是由於elisp庫的版本不匹配造成的。如果這不是問題,它可能是一個Aquamacs錯誤; swank-clojure被設計爲與GNU Emacs一起工作。如果你使用trunk,而不是最新的elpa版本,它也可能是一個bug。

+1

幾個小時前,我已經意識到'C-C M-p'在我的設置(Aquamacs,clojure-mode和slime-repl,clojure-1.2-rc1的最新穩定版本)上完美工作。懸而未決的是'C-c〜',但我猜SLIME命令只適用於Common Lisp實現。我期望的工作是在一個文件上做一個「C-C C-l」(加載) - 我希望命名空間可以改變,但它不會! 爲了未來讀者的利益,我在http://gist.github.com/522706中勾畫的函數也可以工作,但它並不要求命名空間 - 它從第一個'(ns ...) '緩衝區中的表格。 – Edgar 2010-08-13 18:06:50