Skip to content

Remove lsp4j #13

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 80 commits into from
Aug 9, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
80 commits
Select commit Hold shift + click to select a range
607a2fe
First pass at removing lsp4j
mainej Jul 8, 2022
1dc0dac
Share liveness probe
mainej Jul 8, 2022
7101970
Properly handle character encoding
mainej Jul 8, 2022
548fd5e
Extract JSON-RPC message helpers
mainej Jul 8, 2022
f51c577
Thread context through handlers
mainej Jul 8, 2022
229def7
Allow nil responses
mainej Jul 8, 2022
82b34b0
Trace method
mainej Jul 9, 2022
c6cbc76
Avoid accidental conversion to map
mainej Jul 9, 2022
f94eceb
Simplify client usage of error codes
mainej Jul 9, 2022
cbf1610
Content-Length is in bytes not chars
mainej Jul 9, 2022
4d34f0f
Rename
mainej Jul 10, 2022
4b122fe
Record plans
mainej Jul 10, 2022
b20d0a5
Make requests cancellable
mainej Jul 10, 2022
6521c7f
Docs and comments
mainej Jul 10, 2022
ac6579b
Be more careful to only cancel request once
mainej Jul 10, 2022
59a9787
Try different approach to shutdown
mainej Jul 10, 2022
9567155
Only block 10 seconds for close server to finish processing previous …
mainej Jul 10, 2022
a037776
Preserve case of keys that are already strings
mainej Jul 11, 2022
dcd6e42
Don't add empty data to error messages
mainej Jul 11, 2022
6d8929a
Remove alpha namespaces
mainej Jul 11, 2022
e9d18c0
Remove deps on lsp4j
mainej Jul 11, 2022
170a651
Revert arg order
mainej Jul 12, 2022
ce960f9
Language servers don't have to require endpoint protocol
mainej Jul 12, 2022
63a8ce0
Rename and improve docs
mainej Jul 12, 2022
be9d336
Include id in tracing
mainej Jul 12, 2022
bd18fcf
Hold more data on pending-request object
mainej Jul 12, 2022
1eb7279
Close input on exit
mainej Jul 12, 2022
b2c3399
Respect back pressure from clients that are slow to read
mainej Jul 13, 2022
01b25d1
Read and write in threads, to avoid blocking go threads
mainej Jul 13, 2022
61a2dc7
Improve trace messages
mainej Jul 13, 2022
88a8200
Rename receiver/sender; move pipeline draining to shutdown
mainej Jul 13, 2022
b828d68
Add tests for server and request
mainej Jul 13, 2022
32fd7cd
Send traces to channel
mainej Jul 13, 2022
c81ca1c
Log more errors; send logs to channel
mainej Jul 14, 2022
9b46f29
Reduce knowledge of log channel format
mainej Jul 14, 2022
f0f0b58
Move the logger protocol back to clojure-lsp
mainej Jul 14, 2022
bef2b0f
Merge server and protocols subprojects
mainej Jul 14, 2022
0534c09
Conform message only once
mainej Jul 14, 2022
4f1d4a4
Handle parse error and invalid request the same
mainej Jul 14, 2022
bfe7cc1
Cutomize input keywordization function
mainej Jul 14, 2022
7f2be73
Close owned channels
mainej Jul 14, 2022
c206597
Fix comment
mainej Jul 14, 2022
255f1d2
Remove unused protocol method
mainej Jul 14, 2022
6996fdb
Remove parallelism
mainej Jul 14, 2022
9865b1b
Clean up and fix tests
mainej Jul 14, 2022
ac2712d
Discard stdout while running server code
mainej Jul 14, 2022
e48f55d
Clean up tests
mainej Jul 14, 2022
0d97376
Simplify let
mainej Jul 14, 2022
38779d3
Add comment
mainej Jul 14, 2022
5d1c339
Prep for 1.0.0 release
mainej Jul 14, 2022
772f669
Changelog
mainej Jul 14, 2022
786837e
Fix typo
mainej Jul 14, 2022
423a8a4
Document usage in README
mainej Jul 15, 2022
9aefcf6
Ignore $/cancelRequest notifications
mainej Jul 15, 2022
0826be1
Expand usage docs
mainej Jul 15, 2022
68a5862
Copyedit README
mainej Jul 15, 2022
baa344f
Add type hints for Graal
mainej Jul 18, 2022
8b3731a
Correct function name
mainej Jul 18, 2022
a3595e1
Buffer input and output
mainej Jul 18, 2022
eed89cd
More carefully manage output; add tests for stdio->chan
mainej Jul 18, 2022
e58eda1
Ignore unexpected headers, instead of throwing
mainej Jul 18, 2022
20c4cbd
Tidy docs and naming
mainej Jul 19, 2022
597e91e
Adjust docs
mainej Jul 19, 2022
150115d
Customize error response trace
mainej Jul 19, 2022
48a15ca
Clarify tracing helpers
mainej Jul 19, 2022
f4e2cae
Further simplify tracing
mainej Jul 19, 2022
6d02043
Further simplify tracing
mainej Jul 19, 2022
f57870f
Default to generic progress token
mainej Jul 24, 2022
0d5a9c5
Make components example more generic
mainej Jul 24, 2022
0c5d06b
Extend test timeout; remove unused code
mainej Jul 25, 2022
9f631f2
Document source of error codes
mainej Jul 26, 2022
5dc8183
Be more careful to cancel request only once
mainej Jul 26, 2022
534d4d6
Document flow of reading headers
mainej Jul 26, 2022
d93fac0
Be more careful to only respond once
mainej Jul 26, 2022
b1a28ea
Emphasize server's responisibility for notifications
mainej Jul 26, 2022
117347e
Fix coercer indentation
mainej Aug 3, 2022
33401b1
Revert "Buffer input and output"
mainej Aug 7, 2022
d73a556
Treat trace lines more like log lines
mainej Aug 8, 2022
b36af24
Allow log and trace channels to be merged
mainej Aug 8, 2022
43294db
Rename test helper
mainej Aug 8, 2022
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .dir-locals.el
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
((clojure-mode
(cider-clojure-cli-aliases . "test")))
9 changes: 9 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,15 @@

## Unreleased

## v1.0.0

- Remove lsp4j, as per https://github.com/clojure-lsp/lsp4clj/issues/8
This is essentially a rewrite of lsp4clj. Users of lsp4clj v0.4.3 and earlier
are encouraged to upgrade. Bug fixes for these earlier versions will be
considered, but the lsp4j-based version of this library will not receive
long-term support. For an example of how to use the new version of the library,
see https://github.com/clojure-lsp/clojure-lsp/pull/1117

## v0.4.3

## v0.4.2
Expand Down
122 changes: 115 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,126 @@

A [Language Server Protocol](https://microsoft.github.io/language-server-protocol/) base for developing any LSP implementation in Clojure.

## Server
[![Clojars Project](https://img.shields.io/clojars/v/com.github.clojure-lsp/lsp4clj.svg)](https://clojars.org/com.github.clojure-lsp/lsp4clj)

[![Clojars Project](https://img.shields.io/clojars/v/com.github.clojure-lsp/lsp4clj-server.svg)](https://clojars.org/com.github.clojure-lsp/lsp4clj-server)
lsp4clj reads and writes from stdio, parsing JSON-RPC according to the LSP spec. It provides tools to allow server implementors to receive, process, and respond to any of the methods defined in the LSP spec, and to send their own requests and notifications to clients.

The lsp4clj-server has the necessary integration with Input/Output, LSP-JSON parsing, allowing for users of this lib to just code the entrypoints of each LSP method.
## Usage

## Protocols
### Create a server

[![Clojars Project](https://img.shields.io/clojars/v/com.github.clojure-lsp/lsp4clj-protocols.svg)](https://clojars.org/com.github.clojure-lsp/lsp4clj-protocols)
To initialize a server that will read from stdin and write to stdout:

The lsp4clj-protocols contains only the protocols/interfaces for servers that want to extend the official LSP protocol to provide more features, also, it is used by lsp4clj-server itself.
```clojure
(lsp4clj.server/stdio-server {:in System/in, :out System/out})
```

## Known LSPs users
The returned server will have a core.async `:log-ch`, from which you can read server logs (vectors beginning with a log level).

```clojure
(async/go-loop []
(when-let [[level & args] (async/<! (:log-ch server))]
(apply logger/log level args)
(recur)))
```

### Receive messages

To receive messages from a client, lsp4clj defines a pair of multimethods, `lsp4clj.server/receive-notification` and `lsp4clj.server/receive-request` that dispatch on the method name (as defined by the LSP spec) of an incoming JSON-RPC message.

Server implementors should create `defmethod`s for the messages they want to process. (Other methods will be logged and responded to with a generic "Method not found" response.)

These `defmethod`s receive 3 arguments, the method name, a "context", and the `params` of the [JSON-RPC request or notification object](https://www.jsonrpc.org/specification#request_object). The keys of the params will have been converted (recursively) to kebab-case keywords. Read on for an explanation of what a "context" is and how to set it.
Comment on lines +32 to +34
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One thing I think we lost using multimethods is that we can't require that clients implement specific methods like we had on protocol, the LSP spec has some methods that all server should provide, they are required methods, like initialize, diagnostics, definition etc. I'm ok for now with this, we can think on how to make required some methods in the future

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To be pedantic, you're not required to implement every method on a protocol, the docs just say that you should. If you don't, you don't get any compile time errors, though you do get a runtime error if you try to call the method you didn't define.

But I understand what you're saying—a protocol is a stronger indication of which methods you're expected to implement.

This is just one of the drawbacks to the multimethods. They also don't give you anywhere to hang extra data about handlers. I can imagine wanting to flag certain messages as cancellable, give them validators to apply to their input or output, or more generally give them middleware style wrappers, etc.

I think the best way to think about this is that one of the typical responsibilities of a server is to route requests. The multimethods work for that, but reitit, Compojure, et al. address the fact that there's more you might want to do with routing.

On the other hand, I haven't run into anything on the clojure-lsp side yet where I really regret the simplicity of the multimethods.

So, I guess my feeling is that multimethods might not be the best design long-term, but I'm not sure I have enough information to commit to another design either.

I've vaguely considered expressing the "router" as a hashmap, keyed by method name, which you pass in to the server when you create it. The server could validate that certain keys were present. That would also give us lots of flexibility about what the values of the hashmap are. They could be functions to call as the handler (much like a multimethod, which maps dispatch values to functions). Or they could be other hashmaps, with a handler function in each. We could add other data over time. If you feel strongly that this is a better solution, I can work on it.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To be pedantic, you're not required to implement every method on a protocol, the docs just say that you should. If you don't, you don't get any compile time errors, though you do get a runtime error if you try to call the method you didn't define.

yeah, the issue is that most clients expect that some methods are always available like diagnostics, but I agree it's best to be a little bit more loose than strict for now.

Or they could be other hashmaps, with a handler function in each. We could add other data over time. If you feel strongly that this is a better solution, I can work on it.

I think it would work well, but I'm ok trying the multimethods for now

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm also split on this. On the one hand, multimethods bring great simplicity, but our tooling for them is a lot worse. Previously I could find the implementation of the specific message handler with a "find reference", that's gone with multimethods. Additionally, there's no indication of all possible methods I could implement.
I still like the multimethod approach, but maybe this will drive us to add better multimethod stuff into clojure-lsp 😄

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Cyrik we improved a lot defmethods support on clojure-lsp, doesn't find implementations work for that case?

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The thing I'm missing from defmethods is a way of seeing references to a specific method. I know that this isn't possible in the general case, which is the whole point of defmethods, but often enough there are hardcoded calls to a specific method that could be shown as a direct reference. Something like (receive-request "shutdown").
The other thing is completeness, at least in this case.

But in I also fully agree with @mainej that we should leave this as is for now since these are very minor gripes with the system.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Cyrik let me see if I follow...

Suppose we have this multimethod:

(defmulti caps identity)

(defmethod caps "a" [_] "A")
(defmethod caps "b" [_] "B")

At call sites like the following, you know for certain that (defmethod caps "a" ...) is being called, not (defmethod caps "b" ...).

(caps "a")

In theory clojure-lsp could provide navigation tools to link the a defmethod to its usage.

Of course this isn't possible when it's ambiguous which defmethod is being called:

(let [lower (rand-nth ["a" "b"])]
  (caps lower))

In these situations clojure-lsp couldn't help.

Assuming I'm following, I agree, that makes it harder to understand how multimethods, or really any kind of polymorphism, is being used. Polymorphism limits tooling, and that's true of all editors and languages. Maybe the next generation of tooling will offer more insight into polymorphic calls!

For these particular lsp4clj multimethods—receive-request and receive-notification—I'd say the problem isn't very big. There's only one place that calls receive-request and one that calls receive-notification (both in lsp4clj), so there's not much need to find the call sites.

I think there's a stronger argument that the other main entrypoints into lsp4cljsend-request and send-notification—exhibit a similar problem, even though they aren't multimethods. They accept the JSON-RPC method as an argument, so it could be difficult to find all the places that, for example, call (lsp.server/send-notification server "$/progress" message). In clojure-lsp we've worked around this. We have only one place that calls $/progress, a function called publish-progress. If we want to find all the call sites, we can use find-references on publish-progress. And in fact, all the calls to send-request and send-notification are in similar wrapper functions, so it's pretty easy to find references.

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@mainej Yeah that's the exact case I'm talking about. In my experience, most multimethods are built in this way (using the first param for dispatch). But all of this is very much unrelated so we should probably stop the topic 😄

To your second point: you're correct that this happens more often, I just didn't notice the change yet. Previously it was easy to find references on the ILSPProducer methods and you'll now have to do the work yourself. Maybe this could be pulled into lsp4clj as optional entry points. But I know that @ericdallo and I have differing opinions on how much lsp4clj should provide, so I'm also happy to just do that on our end. At some point, I want to publish a library with all the extra utility stuff around lsp4clj anyway (file-management, URL handling, and so on).

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we could open a new discussion on lsp4clj to see if we could provide something that help you like a different project using lsp4clj under the hood, I think discussing the problem a little bit more would make us understand better the problem

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

#14


```clojure
;; a notification; return value is ignored
(defmethod lsp4clj.server/receive-notification "textDocument/didOpen"
[_ context {:keys [text-document]}]
(handler/did-open context (:uri text-document) (:text text-document))

;; a request; return value is converted to a response
(defmethod lsp4clj.server/receive-request "textDocument/definition"
[_ context params]
(->> params
(handler/definition context)
(conform-or-log ::coercer/location)))
```

The return value of requests will be converted to camelCase json and returned to the client. If the return value looks like `{:error ...}`, it is assumed to indicate an error response, and the `...` part will be set as the `error` of a [JSON-RPC error object](https://www.jsonrpc.org/specification#error_object). It is up to you to conform the `...` object (by giving it a `code`, `message`, and `data`.) Otherwise, the entire return value will be set as the `result` of a [JSON-RPC response object](https://www.jsonrpc.org/specification#response_object). (Message ids are handled internally by lsp4clj.)

### Send messages

Servers also initiate their own requests and notifications to a client. To send a notification, call `lsp4clj.server/send-notification`.

```clojure
(->> {:message message
:type type
:extra extra}
(conform-or-log ::coercer/show-message)
(lsp4clj.server/send-notification server "window/showMessage"))
```

Sending a request is similar, with `lsp4clj.server/send-request`. This method returns a request object which may be dereffed to get the client's response. Most of the time you will want to call `lsp4clj.server/deref-or-cancel`, which will send a `$/cancelRequest` to the client if a timeout is reached before the client responds.

```clojure
(let [request (->> {:edit edit}
(conform-or-log ::coercer/workspace-edit-params)
(lsp4clj.server/send-request server "workspace/applyEdit"))
response (lsp4clj.server/deref-or-cancel request 10e3 ::timeout)]
(if (= ::timeout response)
(logger/error "No reponse from client after 10 seconds.")
response))
```

Otherwise, the request object presents the same interface as `future`. Responds to `future-cancel` (which sends `$/cancelRequest`), `realized?`, `future?`, `future-done?` and `future-cancelled?`.

If the request is cancelled, future invocations of `deref` will return `:lsp4clj.server/cancelled`.

Sends `$/cancelRequest` only once, though `lsp4clj.server/deref-or-cancel` or `future-cancel` can be called multiple times.

### Start and stop a server

The last step is to start the server you created earlier. Use `lsp4clj.server/start`. This method accepts two arguments, the server and a "context".

The context should be `associative?`. Whatever you provide in the context will be passed as the second argument to the notification and request `defmethod`s you defined earlier. This is a convenient way to make components of your system available to those methods without definining global constants. Often the context will include the server itself so that you can initiate outbound requests and notifications in reaction to inbound messages. lsp4clj reserves the right to add its own data to the context, using keys namespaced with `:lsp4clj.server/...`.

```clojure
(lsp4clj.server/start server {:custom-settings custom-settings, :logger logger})
```

The return of `start` is a promise that will resolve to `:done` when the server shuts down, which can happen in a few ways.

First, if the server's input is closed, it will shut down too. Second, if you call `lsp4clj.server/shutdown` on it, it will shut down.

When a server shuts down it stops reading input, finishes processing the messages it has in flight, and then closes is output. (If it is shut down with `lsp4cl.server/shutdown` it also closes its `:log-ch` and `:trace-ch`.) As such, it should probably not be shut down until the LSP `exit` notification (as opposed to the `shutdown` request) to ensure all messages are received. `lsp4clj.server/shutdown` will not return until all messages have been processed, or until 10 seconds have passed, whichever happens sooner. It will return `:done` in the first case and `:timeout` in the second.

## Development details

### Tracing

As you are implementing, you may want to trace incoming and outgoing messages. Initialize the server with `:trace? true` and then read traces (two element vectors, beginning with the log level `:debug` and ending with a string, the trace itself) off its `:trace-ch`.

```clojure
(let [server (lsp4clj.server/stdio-server {:trace? true
:in System/in
:out System/out})]
(async/go-loop []
(when-let [[level trace] (async/<! (:trace-ch server))]
(logger/log level trace)
(recur)))
(lsp4clj.server/start server context))
```

### Testing

A client is in many ways like a server—it also sends requests and notifications and receives responses. That is, LSP's flavor of JSON-RPC is bi-directional. As such, you may be able to use some of lsp4clj's tools to build a mock client for testing. See `integration.client` in `clojure-lsp` for one such example.

You may also find `lsp4clj.server/chan-server` a useful alternative to `stdio-server`. This server reads and writes off channels, instead of stdio streams. See `lsp4clj.server-test` for many examples of interacting with such a server.

## Caveats

You must not print to stdout while a `stdio-server` is running. This will corrupt its output stream and clients will receive malformed messages. To protect a block of code from writing to stdout, wrap it with `lsp4clj.server/discarding-stdout`. The `receive-notification` and `receive-request` multimethods are already protected this way, but tasks started outside of these multimethods need this protection added. See https://github.com/clojure-lsp/lsp4clj/issues/1 for future work on avoiding this problem.

## Known lsp4clj users

- [clojure-lsp](https://clojure-lsp.io/): A Clojure LSP server implementation.
17 changes: 6 additions & 11 deletions bb.edn
Original file line number Diff line number Diff line change
@@ -1,17 +1,13 @@
{:paths ["scripts"]
:min-bb-version "0.4.0"
:tasks {:requires ([babashka.fs :as fs])
clean (do (fs/delete-tree "server/target")
(fs/delete-tree "server/lsp4clj-server.jar")
(fs/delete-tree "protocols/target")
(fs/delete-tree "protocols/lsp4clj-protocols.jar"))
test (shell {:dir "server"} "clojure -M:test")
clean (do (fs/delete-tree "target")
(fs/delete-tree "lsp4clj.jar"))
test (shell "clojure -M:test")

server-pom (shell {:dir "server"} "clojure -T:build pom")
protocols-pom (shell {:dir "protocols"} "clojure -T:build pom")
pom (shell "clojure -T:build pom")

server-jar (shell {:dir "server"} "clojure -T:build jar")
protocols-jar (shell {:dir "protocols"} "clojure -T:build jar")
jar (shell "clojure -T:build jar")

lint (do (shell "clojure-lsp format --dry")
(shell "clojure-lsp clean-ns --dry")
Expand All @@ -22,5 +18,4 @@
;; Receive arg without v
tag lsp4clj.ci/tag

deploy-clojars-server (shell {:dir "server"} "clojure -T:build deploy-clojars")
deploy-clojars-protocols (shell {:dir "protocols"} "clojure -T:build deploy-clojars")}}
deploy-clojars (shell "clojure -T:build deploy-clojars")}}
2 changes: 1 addition & 1 deletion protocols/build.clj → build.clj
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
[clojure.string :as string]
[clojure.tools.build.api :as b]))

(def lib 'com.github.clojure-lsp/lsp4clj-protocols)
(def lib 'com.github.clojure-lsp/lsp4clj)
(def jar-file (format "target/%s.jar" (name lib)))

(def current-version (string/trim (slurp "resources/LSP4CLJ_VERSION")))
Expand Down
24 changes: 13 additions & 11 deletions deps.edn
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
{:paths []
:aliases {:dev {:extra-paths ["protocols/src"
"server/src"]
:extra-deps {lsp4clj/server {:local/root "server"}
lsp4clj/protocols {:local/root "protocols"}
io.github.clojure/tools.build {:git/url "https://github.com/clojure/tools.build.git"
:tag "v0.8.1"
:sha "7d40500"}}}
:test {:extra-deps {lambdaisland/kaocha {:mvn/version "1.64.1010"}}
:extra-paths ["server/test"]
:main-opts ["-m" "kaocha.runner"]}}}
{:deps {org.clojure/clojure {:mvn/version "1.11.1"}
org.clojure/core.async {:mvn/version "1.5.648"}
camel-snake-kebab/camel-snake-kebab {:mvn/version "0.4.3"}
cheshire/cheshire {:mvn/version "5.11.0"} }
:paths ["src" "resources"]
:aliases {:test {:extra-deps {lambdaisland/kaocha {:mvn/version "1.64.1010"}}
:extra-paths ["test"]
:main-opts ["-m" "kaocha.runner"]}
:build {:extra-paths ["resources"]
:deps {io.github.clojure/tools.build {:git/tag "v0.8.1"
:git/sha "7d40500"}
slipset/deps-deploy {:mvn/version "0.2.0"}}
:ns-default build}}}
5 changes: 5 additions & 0 deletions pom.properties
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# Generated by org.clojure/tools.build
# Thu Jul 14 13:48:53 PDT 2022
version=1.0.0
groupId=com.github.clojure-lsp
artifactId=lsp4clj
35 changes: 25 additions & 10 deletions protocols/pom.xml → pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,37 @@
<modelVersion>4.0.0</modelVersion>
<packaging>jar</packaging>
<groupId>com.github.clojure-lsp</groupId>
<artifactId>lsp4clj-protocols</artifactId>
<version>0.4.3</version>
<name>lsp4clj-protocols</name>
<artifactId>lsp4clj</artifactId>
<version>1.0.0</version>
<name>lsp4clj</name>
<dependencies>
<dependency>
<groupId>org.clojure</groupId>
<artifactId>clojure</artifactId>
<version>1.11.1</version>
</dependency>
<dependency>
<groupId>cheshire</groupId>
<artifactId>cheshire</artifactId>
<version>5.11.0</version>
</dependency>
<dependency>
<groupId>camel-snake-kebab</groupId>
<artifactId>camel-snake-kebab</artifactId>
<version>0.4.3</version>
</dependency>
<dependency>
<groupId>org.clojure</groupId>
<artifactId>core.async</artifactId>
<version>1.5.648</version>
</dependency>
</dependencies>
<repositories>
<repository>
<id>clojars</id>
<url>https://repo.clojars.org/</url>
</repository>
</repositories>
<build>
<sourceDirectory>src</sourceDirectory>
<resources>
Expand All @@ -21,16 +42,10 @@
</resource>
</resources>
</build>
<repositories>
<repository>
<id>clojars</id>
<url>https://repo.clojars.org/</url>
</repository>
</repositories>
<scm>
<url>https://github.com/clojure-lsp/lsp4clj</url>
<connection>scm:git:git://github.com/clojure-lsp/lsp4clj.git</connection>
<developerConnection>scm:git:ssh://git@github.com/clojure-lsp/lsp4clj.git</developerConnection>
<tag>0.4.3</tag>
<tag>v1.0.0</tag>
</scm>
</project>
7 changes: 0 additions & 7 deletions protocols/deps.edn

This file was deleted.

1 change: 0 additions & 1 deletion protocols/resources

This file was deleted.

13 changes: 0 additions & 13 deletions protocols/src/lsp4clj/components.clj

This file was deleted.

41 changes: 0 additions & 41 deletions protocols/src/lsp4clj/protocols/feature_handler.clj

This file was deleted.

Loading