Clojure使用Emacs和苹果汁进行编码

时间:2021-10-18 01:35:17

I am new to Clojure coding and went through a number of articles to set up Emacs for development.
The setup itself works as designed, but I have been running server from Cider session and killing Emacs entirely when making any code change. Or, I need to find the server process from shell session, and kill it from there. This is far from ideal.

我是Clojure编码的新手,我阅读了许多关于设置Emacs以进行开发的文章。设置本身按照设计工作,但我一直在运行服务器,从Cider会话,并杀死Emacs,当进行任何代码更改。或者,我需要从shell会话中找到服务器进程,然后从那里终止它。这远非理想。

clojure-getting-started/web.clj

clojure-getting-started / web.clj

(defn -main [& [port]]
  (let [port (Integer. (or port (env :port) 5000))]
    (jetty/run-jetty (site #'app) {:port port :join? false})))

Cider session

苹果酒的会话

clojure-getting-started.web> (defonce server (-main))

After starting the server, I will get the below error with (server) function:

启动服务器后,我将使用(server)函数获得以下错误:

1. Unhandled java.lang.ClassCastException
   org.eclipse.jetty.server.Server cannot be cast to clojure.lang.IFn


The error message makes sense, but how can I refresh my code base using just Emacs?
I suppose (and hope) there is a better way than starting shell session on Emacs and kill the process there...

错误消息是有意义的,但是如何使用Emacs刷新代码库呢?我想(也希望)有一种比在Emacs上启动shell会话并终止进程更好的方法……

3 个解决方案

#1


3  

Assuming what you are wanting is to run a jetty server and have it load or reload your code when you change it from within emacs. While the advice already given is good, it may be more complex than you need when getting started. My advice is to take advantage of some of the templates out there for lein which will setup a default environment and workflow for you to begin with. You can then refine this default as you learn more until you get the workflow which suits you. My recommendation would be to start witht the default compojure template i.e.

假设您想要的是运行一个jetty服务器,当您从emacs中更改代码时,让它加载或重新加载您的代码。虽然已经给出的建议是好的,但是它可能比您开始时需要的要复杂得多。我的建议是利用lein的一些模板,它将设置一个默认的环境和工作流。然后您可以细化这个默认值,直到得到适合您的工作流。我的建议是从默认的复合模板开始。

lein new compojure my-project

This creates a bare bones project with the basic ring and compojure libraries and lein plugins as well as a simple dev profile.

这就创建了一个简单的项目,包括基本的环和复合库、lein插件以及一个简单的开发概要文件。

Edit the src/my_project/handler.clj file and add the ring.middleware.reload middleware e.g.

编辑src / my_project /处理程序。clj文件并添加ring.中间件。重载的中间件。

(ns my-project.handler
  (:require [compojure.core :refer :all]
            [compojure.route :as route]
            [ring.middleware.reload :refer [wrap-reload]]
            [ring.middleware.defaults :refer [wrap-defaults site-defaults]]))

(defroutes app-routes
  (GET "/" [] "Hello World")
  (route/not-found "Not Found"))

(def app
  (-> app-routes
      wrap-reload
      (wrap-defaults site-defaults)))

The wrap-reload middleware will cause your code to be reloaded when it is modified. You won't need to restart the jetty server for your code changes to take effect - just reload the page.

wrap-reload中间件会在修改代码时重新加载代码。要使代码更改生效,您不需要重新启动jetty服务器——只需重新加载页面。

In a terminal run either

在终端运行

lein ring server

or

lein ring server-headless

This will start a jetty server listening on port 3000. Then from within emacs, you can just open a cider repl to use while writing your code. You won't need to restart the server process unless you make changes to your project.clj file. Same with the cider process.

这将启动一个jetty服务器监听端口3000。然后,在emacs中,您可以在编写代码时打开一个cider repl。除非对项目进行更改,否则不需要重新启动服务器进程。clj文件。苹果酒也是如此。

Then, once your comfortable with this, look at the lein-ring documentation. There you will find information on how to setup a repl.clj file within the project. Once you do that, you will be able to do something like

然后,一旦您对此感到满意,请查看lein-ring文档。在那里您将找到如何设置repl的信息。项目中的clj文件。一旦你这样做了,你就可以做类似的事情

lein repl

and then from within that repl, do something like

然后从这个repl内部,做一些类似的事情

(start-server)

which will start the server. You can then switch to emacs and instead of running cider-jack-in, you can do a cider-connect, which will connect tot he already running repl rather than starting a second repl session. Later, if you decide to start also looking at clojurescript, you can look at some of the default templates for clojure+clojurescript apps. I quite like figwheel and use reagent a fair bit, so I also find the reagent template quite good.

这将启动服务器。然后,您可以切换到emacs,而不是运行“输入-插入”,您可以执行“输入-连接”,这将连接到他已经在运行repl而不是启动第二个repl会话。稍后,如果您决定开始查看clojurescript,您可以查看clojure+clojurescript应用程序的一些默认模板。我比较喜欢figwheel,使用了一些试剂,所以我也觉得试剂模板比较好。

There are quite a few lein templates out there and I find it really useful to just run them and have a look at what they do. I then tend to cherry pick the features/options I like.

有很多lein模板,我发现运行它们并查看它们的功能是非常有用的。然后我倾向于挑选我喜欢的功能/选项。

#2


0  

Here's most of the answer I just gave to a similar question:

下面是我给出的一个类似问题的答案:


Try the (refresh) function in the clojure.tools.namespace.repl namespace:

尝试clojures .tools.namespace.repl名称空间中的(refresh)函数:

The refresh function will scan all the directories on the classpath for Clojure source files, read their ns declarations, build a graph of their dependencies, and load them in dependency order.

refresh函数将扫描Clojure源文件的类路径上的所有目录,读取它们的ns声明,构建它们的依赖关系图,并按依赖关系顺序加载它们。

https://github.com/clojure/tools.namespace#reloading-code-usage

https://github.com/clojure/tools.namespace reloading-code-usage

We generally add that plus a few other useful things to the user namespace, so it's loaded into the REPL on startup:

我们通常会在用户命名空间中添加一些其他有用的东西,因此在启动时将其加载到REPL中:

(ns user
  (:require [clojure.tools.namespace.repl :refer [refresh]]
            [clojure.repl :refer [doc source]]
            [clojure.pprint :refer [pprint pp]]
            [midje.repl :as midje]
            [clojure.stacktrace :as st]))

To keep that code separate from your main and test sources, put that in a file at <project root>/dev/user.clj, then add the following to your lein project.clj file:

要将代码与主源代码和测试源代码分开,请将其放在 /dev/user的文件中。clj,然后在lein项目中添加以下内容。clj文件:

:profiles {:dev {:source-paths ["dev"]}}

#3


0  

Concerning the ClassCastException - server needs to be a function of 1 param:

关于ClassCastException—服务器需要具有一个参数的函数:

(defonce server (fn [request] (-main)))

#1


3  

Assuming what you are wanting is to run a jetty server and have it load or reload your code when you change it from within emacs. While the advice already given is good, it may be more complex than you need when getting started. My advice is to take advantage of some of the templates out there for lein which will setup a default environment and workflow for you to begin with. You can then refine this default as you learn more until you get the workflow which suits you. My recommendation would be to start witht the default compojure template i.e.

假设您想要的是运行一个jetty服务器,当您从emacs中更改代码时,让它加载或重新加载您的代码。虽然已经给出的建议是好的,但是它可能比您开始时需要的要复杂得多。我的建议是利用lein的一些模板,它将设置一个默认的环境和工作流。然后您可以细化这个默认值,直到得到适合您的工作流。我的建议是从默认的复合模板开始。

lein new compojure my-project

This creates a bare bones project with the basic ring and compojure libraries and lein plugins as well as a simple dev profile.

这就创建了一个简单的项目,包括基本的环和复合库、lein插件以及一个简单的开发概要文件。

Edit the src/my_project/handler.clj file and add the ring.middleware.reload middleware e.g.

编辑src / my_project /处理程序。clj文件并添加ring.中间件。重载的中间件。

(ns my-project.handler
  (:require [compojure.core :refer :all]
            [compojure.route :as route]
            [ring.middleware.reload :refer [wrap-reload]]
            [ring.middleware.defaults :refer [wrap-defaults site-defaults]]))

(defroutes app-routes
  (GET "/" [] "Hello World")
  (route/not-found "Not Found"))

(def app
  (-> app-routes
      wrap-reload
      (wrap-defaults site-defaults)))

The wrap-reload middleware will cause your code to be reloaded when it is modified. You won't need to restart the jetty server for your code changes to take effect - just reload the page.

wrap-reload中间件会在修改代码时重新加载代码。要使代码更改生效,您不需要重新启动jetty服务器——只需重新加载页面。

In a terminal run either

在终端运行

lein ring server

or

lein ring server-headless

This will start a jetty server listening on port 3000. Then from within emacs, you can just open a cider repl to use while writing your code. You won't need to restart the server process unless you make changes to your project.clj file. Same with the cider process.

这将启动一个jetty服务器监听端口3000。然后,在emacs中,您可以在编写代码时打开一个cider repl。除非对项目进行更改,否则不需要重新启动服务器进程。clj文件。苹果酒也是如此。

Then, once your comfortable with this, look at the lein-ring documentation. There you will find information on how to setup a repl.clj file within the project. Once you do that, you will be able to do something like

然后,一旦您对此感到满意,请查看lein-ring文档。在那里您将找到如何设置repl的信息。项目中的clj文件。一旦你这样做了,你就可以做类似的事情

lein repl

and then from within that repl, do something like

然后从这个repl内部,做一些类似的事情

(start-server)

which will start the server. You can then switch to emacs and instead of running cider-jack-in, you can do a cider-connect, which will connect tot he already running repl rather than starting a second repl session. Later, if you decide to start also looking at clojurescript, you can look at some of the default templates for clojure+clojurescript apps. I quite like figwheel and use reagent a fair bit, so I also find the reagent template quite good.

这将启动服务器。然后,您可以切换到emacs,而不是运行“输入-插入”,您可以执行“输入-连接”,这将连接到他已经在运行repl而不是启动第二个repl会话。稍后,如果您决定开始查看clojurescript,您可以查看clojure+clojurescript应用程序的一些默认模板。我比较喜欢figwheel,使用了一些试剂,所以我也觉得试剂模板比较好。

There are quite a few lein templates out there and I find it really useful to just run them and have a look at what they do. I then tend to cherry pick the features/options I like.

有很多lein模板,我发现运行它们并查看它们的功能是非常有用的。然后我倾向于挑选我喜欢的功能/选项。

#2


0  

Here's most of the answer I just gave to a similar question:

下面是我给出的一个类似问题的答案:


Try the (refresh) function in the clojure.tools.namespace.repl namespace:

尝试clojures .tools.namespace.repl名称空间中的(refresh)函数:

The refresh function will scan all the directories on the classpath for Clojure source files, read their ns declarations, build a graph of their dependencies, and load them in dependency order.

refresh函数将扫描Clojure源文件的类路径上的所有目录,读取它们的ns声明,构建它们的依赖关系图,并按依赖关系顺序加载它们。

https://github.com/clojure/tools.namespace#reloading-code-usage

https://github.com/clojure/tools.namespace reloading-code-usage

We generally add that plus a few other useful things to the user namespace, so it's loaded into the REPL on startup:

我们通常会在用户命名空间中添加一些其他有用的东西,因此在启动时将其加载到REPL中:

(ns user
  (:require [clojure.tools.namespace.repl :refer [refresh]]
            [clojure.repl :refer [doc source]]
            [clojure.pprint :refer [pprint pp]]
            [midje.repl :as midje]
            [clojure.stacktrace :as st]))

To keep that code separate from your main and test sources, put that in a file at <project root>/dev/user.clj, then add the following to your lein project.clj file:

要将代码与主源代码和测试源代码分开,请将其放在 /dev/user的文件中。clj,然后在lein项目中添加以下内容。clj文件:

:profiles {:dev {:source-paths ["dev"]}}

#3


0  

Concerning the ClassCastException - server needs to be a function of 1 param:

关于ClassCastException—服务器需要具有一个参数的函数:

(defonce server (fn [request] (-main)))