summaryrefslogtreecommitdiffstats
path: root/2023/captions/emacsconf-2023-lspocaml--writing-a-language-server-in-ocaml-for-emacs-fun-and-profit--austin-theriault--main.vtt
diff options
context:
space:
mode:
Diffstat (limited to '2023/captions/emacsconf-2023-lspocaml--writing-a-language-server-in-ocaml-for-emacs-fun-and-profit--austin-theriault--main.vtt')
-rw-r--r--2023/captions/emacsconf-2023-lspocaml--writing-a-language-server-in-ocaml-for-emacs-fun-and-profit--austin-theriault--main.vtt1180
1 files changed, 1180 insertions, 0 deletions
diff --git a/2023/captions/emacsconf-2023-lspocaml--writing-a-language-server-in-ocaml-for-emacs-fun-and-profit--austin-theriault--main.vtt b/2023/captions/emacsconf-2023-lspocaml--writing-a-language-server-in-ocaml-for-emacs-fun-and-profit--austin-theriault--main.vtt
new file mode 100644
index 00000000..cce4f460
--- /dev/null
+++ b/2023/captions/emacsconf-2023-lspocaml--writing-a-language-server-in-ocaml-for-emacs-fun-and-profit--austin-theriault--main.vtt
@@ -0,0 +1,1180 @@
+WEBVTT captioned by sachac, checked by sachac
+
+NOTE Introduction
+
+00:00:00.000 --> 00:00:01.839
+Hi, I'm Austin Theriault,
+
+00:00:01.840 --> 00:00:04.159
+and this is writing a language server in OCaml
+
+00:00:04.160 --> 00:00:07.639
+for Emacs, fun, and profit.
+
+00:00:07.640 --> 00:00:08.919
+Real quick, who am I?
+
+00:00:08.920 --> 00:00:10.919
+Well, I'm a software engineer at Semgrep.
+
+00:00:10.920 --> 00:00:13.239
+I work on our editor integrations,
+
+00:00:13.240 --> 00:00:15.359
+and I love working on programming languages, editors,
+
+00:00:15.360 --> 00:00:16.539
+and cryptography.
+
+NOTE What is Semgrep?
+
+00:00:16.540 --> 00:00:17.799
+What is Semgrep?
+
+00:00:17.800 --> 00:00:20.039
+We're a small cybersecurity startup
+
+00:00:20.040 --> 00:00:21.919
+whose core product is a SaaS tool,
+
+00:00:21.920 --> 00:00:24.759
+which is static application security testing.
+
+00:00:24.760 --> 00:00:27.799
+You can think of it as like a security linter.
+
+00:00:27.800 --> 00:00:30.119
+Normal linters will say, hey,
+
+00:00:30.120 --> 00:00:31.919
+you wrote ugly code, fix it.
+
+00:00:31.920 --> 00:00:35.079
+We'll say, hey, you wrote a SQL injection, fix that.
+
+00:00:35.080 --> 00:00:36.959
+We support 30+ languages,
+
+00:00:36.960 --> 00:00:39.319
+and we have lots of customers all using different IDEs.
+
+00:00:39.320 --> 00:00:40.719
+Why does that matter?
+
+NOTE How do we show security bugs early?
+
+00:00:40.720 --> 00:00:42.779
+Well, our goal is to show security bugs
+
+00:00:42.780 --> 00:00:45.239
+as early as possible in the development cycle.
+
+00:00:45.240 --> 00:00:48.479
+In the industry, we call this shifting left.
+
+00:00:48.480 --> 00:00:52.959
+And so how far left can we shift? The editor.
+
+00:00:52.960 --> 00:00:53.619
+So that's why it matters
+
+00:00:53.620 --> 00:00:56.079
+that our customers have different editors.
+
+00:00:56.080 --> 00:00:58.919
+Our goal is to have Semgrep and the editor
+
+00:00:58.920 --> 00:01:01.319
+show up like other language tooling.
+
+00:01:01.320 --> 00:01:05.199
+And what I mean by that is I wrote some bad OCaml up here,
+
+00:01:05.200 --> 00:01:07.599
+and the editor gave me that red squiggly and said,
+
+00:01:07.600 --> 00:01:12.199
+fix your OCaml, and we want Semgrep to do something similar.
+
+00:01:12.200 --> 00:01:15.519
+And so our goal then is to provide a similar experience
+
+00:01:15.520 --> 00:01:16.919
+to normal language checking.
+
+00:01:16.920 --> 00:01:18.999
+And then since we're a small startup,
+
+00:01:19.000 --> 00:01:22.079
+and there's a ton of different IDEs that our customers use,
+
+00:01:22.080 --> 00:01:24.919
+ideally, we don't want to have to rewrite a plugin
+
+00:01:24.920 --> 00:01:27.559
+for every single type of editor out there.
+
+00:01:27.560 --> 00:01:29.159
+Our other goal is abstract away
+
+00:01:29.160 --> 00:01:32.119
+editing and language features for editors to one code base.
+
+00:01:32.120 --> 00:01:33.879
+Ideally, we write it once
+
+00:01:33.880 --> 00:01:35.799
+and then plug it into all of them.
+
+00:01:35.800 --> 00:01:37.879
+So how can we do that, though?
+
+NOTE What is the Language Server Protocol?
+
+00:01:37.880 --> 00:01:40.679
+Well, in the process of working on this stuff,
+
+00:01:40.680 --> 00:01:42.999
+I found out about
+
+00:01:43.000 --> 00:01:44.879
+the Language Server Protocol.
+
+00:01:44.880 --> 00:01:47.279
+And what's great about the Language Server Protocol is
+
+00:01:47.280 --> 00:01:50.319
+it's a specification that defines all the ways
+
+00:01:50.320 --> 00:01:52.679
+that these language tools might interact
+
+00:01:52.680 --> 00:01:56.879
+with a development tool. And by development tool,
+
+00:01:56.880 --> 00:02:01.599
+I mean like VS Code, Sublime, Emacs, any of those.
+
+00:02:01.600 --> 00:02:07.279
+And by language tool, I mean something like PyRight, MyPy.
+
+00:02:07.280 --> 00:02:09.319
+So what's cool about LSP is that
+
+00:02:09.320 --> 00:02:12.999
+you can separate out those tools into language servers
+
+00:02:13.000 --> 00:02:15.519
+and the development tools into language clients.
+
+00:02:15.520 --> 00:02:18.079
+And because they share this common specification,
+
+00:02:18.080 --> 00:02:20.359
+they can now interact without knowing each other.
+
+00:02:20.360 --> 00:02:22.799
+So it's this great abstraction that means
+
+00:02:22.800 --> 00:02:25.439
+all you have to do is go write one language server
+
+00:02:25.440 --> 00:02:27.439
+and you can hook it up to a bunch of language clients
+
+00:02:27.440 --> 00:02:29.039
+and it'll just work.
+
+NOTE Case study: Rust Analyzer
+
+00:02:29.040 --> 00:02:34.039
+So let's do a quick case study on language servers in LSP,
+
+00:02:34.040 --> 00:02:37.239
+just so you get an idea of why this is super cool.
+
+00:02:37.240 --> 00:02:40.439
+So there's this language server called Rust Analyzer.
+
+00:02:40.440 --> 00:02:42.879
+It's a language server for the Rust language.
+
+00:02:42.880 --> 00:02:44.119
+If you've ever developed in Rust,
+
+00:02:44.120 --> 00:02:46.959
+you'll know that takes a really long time to compile,
+
+00:02:46.960 --> 00:02:50.359
+but the compiler gives you fantastic feedback.
+
+00:02:50.360 --> 00:02:52.359
+Rust has a lot of advanced language features,
+
+00:02:52.360 --> 00:02:55.439
+so that feedback is super important for developing.
+
+00:02:55.440 --> 00:02:58.919
+And so Rust Analyzer will give you that feedback instantly.
+
+00:02:58.920 --> 00:03:01.119
+Here's a ton of things that it gives you.
+
+00:03:01.120 --> 00:03:05.079
+Code completion, fixes, compiler errors, warnings,
+
+00:03:05.080 --> 00:03:08.679
+type signatures. Rust has a pretty strong type system.
+
+00:03:08.680 --> 00:03:12.199
+It also has this thing called lifetimes.
+
+00:03:12.200 --> 00:03:15.079
+A bunch of advanced language features in Rust Analyzer
+
+00:03:15.080 --> 00:03:16.199
+helps you manage all that
+
+00:03:16.200 --> 00:03:17.439
+and gives you all that info
+
+00:03:17.440 --> 00:03:19.219
+without having to wait for it to compile.
+
+00:03:19.220 --> 00:03:21.519
+Developing with the Rust Analyzer
+
+00:03:21.520 --> 00:03:24.319
+is just orders of magnitude easier
+
+00:03:24.320 --> 00:03:26.519
+than just trying to write Rust straight.
+
+00:03:26.520 --> 00:03:30.919
+Rust Analyzer, fantastic. They went and they developed it,
+
+00:03:30.920 --> 00:03:33.639
+and now you can go use that in Emacs, NeoVim,
+
+00:03:33.640 --> 00:03:35.239
+VS Code, wherever.
+
+00:03:35.240 --> 00:03:39.079
+So you can develop Rust in a way that's relatively efficient
+
+00:03:39.080 --> 00:03:42.759
+without having to give up your favorite editor.
+
+NOTE Rust Analyzer in action
+
+00:03:42.760 --> 00:03:44.399
+So here's a quick little demo
+
+00:03:44.400 --> 00:03:46.319
+of all the cool things it can do.
+
+00:03:46.320 --> 00:03:48.119
+So you can see I typed an error.
+
+00:03:48.120 --> 00:03:50.719
+It tells me that I wrote an error.
+
+00:03:50.720 --> 00:03:52.519
+I used the incorrect lifetime,
+
+00:03:52.520 --> 00:03:54.159
+which is some advanced language feature,
+
+00:03:54.160 --> 00:03:55.159
+and it'll let me know that.
+
+00:03:55.160 --> 00:03:57.519
+I expanded a Rust macro just there,
+
+00:03:57.520 --> 00:03:59.239
+which is similar to Lisp macros,
+
+00:03:59.240 --> 00:04:01.359
+and then I ran a single unit test,
+
+00:04:01.360 --> 00:04:04.639
+and that's really cool because I ran a single unit test
+
+00:04:04.640 --> 00:04:05.439
+from my editor.
+
+00:04:05.440 --> 00:04:07.839
+I didn't have to go and type any commands or anything.
+
+00:04:07.840 --> 00:04:09.959
+It just worked.
+
+NOTE Why is this useful?
+
+00:04:09.960 --> 00:04:13.399
+So why is this just useful in general for a user?
+
+00:04:13.400 --> 00:04:15.799
+Well, you get the same experience across editors.
+
+00:04:15.800 --> 00:04:17.119
+Like I was saying, you don't have to give up
+
+00:04:17.120 --> 00:04:18.359
+one editor for another
+
+00:04:18.360 --> 00:04:21.719
+so you get some sort of cool language feature.
+
+00:04:21.720 --> 00:04:23.559
+You can easily set up and use language servers
+
+00:04:23.560 --> 00:04:24.599
+made for other editors
+
+00:04:24.600 --> 00:04:27.859
+if developers don't support your editor of choice.
+
+00:04:27.860 --> 00:04:31.239
+Performance is not dependent on the editor.
+
+00:04:31.240 --> 00:04:35.439
+That's fantastic because to do all that Rust stuff,
+
+00:04:35.440 --> 00:04:37.439
+it takes a lot of CPU power,
+
+00:04:37.440 --> 00:04:40.499
+and so that's going to be slow
+
+00:04:40.500 --> 00:04:43.679
+if your editor language is not great, not fast.
+
+00:04:43.680 --> 00:04:47.799
+And then bug fixes, updates, all that,
+
+00:04:47.800 --> 00:04:50.119
+it all comes out at the same time.
+
+00:04:50.120 --> 00:04:53.399
+And then from the developer perspective, well,
+
+00:04:53.400 --> 00:04:55.359
+adding new editors is quick and easy.
+
+00:04:55.360 --> 00:04:58.699
+For reference, when I wrote the Semgrep language server,
+
+00:04:58.700 --> 00:05:00.519
+it took me maybe two or three weeks,
+
+00:05:00.520 --> 00:05:03.999
+but then actually going and setting it up for VS Code,
+
+00:05:04.000 --> 00:05:06.439
+that took an hour. For Emacs, 30 minutes.
+
+00:05:06.440 --> 00:05:08.359
+IntelliJ, maybe another hour.
+
+00:05:08.360 --> 00:05:10.399
+So it took me a day to add support
+
+00:05:10.400 --> 00:05:11.879
+for three different editors,
+
+00:05:11.880 --> 00:05:14.799
+which was I think something like 75% of the market share
+
+00:05:14.800 --> 00:05:16.319
+or something crazy like that.
+
+00:05:16.320 --> 00:05:20.179
+So very quick. You only need one mental model.
+
+00:05:20.180 --> 00:05:21.079
+You don't have to figure out
+
+00:05:21.080 --> 00:05:23.959
+all these different extension mental models,
+
+00:05:23.960 --> 00:05:26.519
+how those editors work, anything like that.
+
+00:05:26.520 --> 00:05:28.639
+And another thing that's cool is
+
+00:05:28.640 --> 00:05:30.399
+you only have to write tests for the language server,
+
+00:05:30.400 --> 00:05:31.959
+not necessarily for the editor.
+
+00:05:31.960 --> 00:05:33.839
+It's great to have just one set of tests
+
+00:05:33.840 --> 00:05:36.219
+that you have to pass.
+
+NOTE So what about Emacs?
+
+00:05:36.220 --> 00:05:40.159
+So why does a language server protocol matter with Emacs?
+
+00:05:40.160 --> 00:05:42.379
+Well, like I was saying before,
+
+00:05:42.380 --> 00:05:45.479
+Emacs gets the benefit from work put into other editors.
+
+00:05:45.480 --> 00:05:47.759
+So we get all this language support,
+
+00:05:47.760 --> 00:05:51.119
+and no one actually has to go and write the list for it
+
+00:05:51.120 --> 00:05:53.199
+or write those tools specific to Emacs.
+
+00:05:53.200 --> 00:05:54.919
+You get the language tooling,
+
+00:05:54.920 --> 00:05:56.759
+the CPU-intensive part of the editors.
+
+00:05:56.760 --> 00:05:58.559
+It can be written in something else.
+
+00:05:58.560 --> 00:06:01.319
+Lisp is fast. It's not that fast.
+
+00:06:01.320 --> 00:06:04.719
+Having that speed is fantastic. It's all asynchronous.
+
+00:06:04.720 --> 00:06:06.439
+It won't slow down Emacs.
+
+00:06:06.440 --> 00:06:08.919
+And then there's this package called `lsp-mode`,
+
+00:06:08.920 --> 00:06:11.359
+which is an LSP client commonly included
+
+00:06:11.360 --> 00:06:13.319
+in popular Emacs distributions.
+
+00:06:13.320 --> 00:06:15.159
+So a lot of people already have that.
+
+00:06:15.160 --> 00:06:18.679
+If you're using Emacs 29 or greater, you have `eglot-mode`,
+
+00:06:18.680 --> 00:06:21.679
+which is a lighter weight version of `lsp-mode`.
+
+00:06:21.680 --> 00:06:24.239
+It's just another LSP client.
+
+00:06:24.240 --> 00:06:26.359
+When I wrote the Semgrep language server,
+
+00:06:26.360 --> 00:06:28.319
+Emacs 29 hadn't come out yet.
+
+00:06:28.320 --> 00:06:31.479
+I'm not going to talk too much about `eglot-mode`
+
+00:06:31.480 --> 00:06:33.299
+because I did everything in `lsp-mode`,
+
+00:06:33.300 --> 00:06:37.779
+but I would imagine a lot of this stuff is very similar.
+
+00:06:37.780 --> 00:06:40.699
+Here's a list of some supported languages.
+
+NOTE Technical part - Brief communication overview
+
+00:06:40.700 --> 00:06:42.639
+Now let's get into the technical part.
+
+00:06:42.640 --> 00:06:45.039
+How does LSP actually work?
+
+00:06:45.040 --> 00:06:47.159
+So let's go over how it communicates first.
+
+00:06:47.160 --> 00:06:49.759
+It uses JSONRPC,
+
+00:06:49.760 --> 00:06:51.959
+which is just kind of like HTTP,
+
+00:06:51.960 --> 00:06:54.619
+but instead of sending plain text, you're sending JSON.
+
+00:06:54.620 --> 00:06:56.439
+So it's just sending JSON back and forth.
+
+00:06:56.440 --> 00:06:58.539
+It's great because it's a way
+
+00:06:58.540 --> 00:06:59.959
+for two programs to communicate
+
+00:06:59.960 --> 00:07:02.839
+without sharing a common programming language.
+
+00:07:02.840 --> 00:07:04.959
+Transport platform agnostic,
+
+00:07:04.960 --> 00:07:07.079
+so it could be stdin, stdout,
+
+00:07:07.080 --> 00:07:09.399
+sockets, whatever. It's just JSON.
+
+00:07:09.400 --> 00:07:11.139
+You can send it over whatever.
+
+00:07:11.140 --> 00:07:12.719
+There's two different types of messages,
+
+00:07:12.720 --> 00:07:15.839
+a request, which requires a response from the other party,
+
+00:07:15.840 --> 00:07:19.259
+and a notification, which does not expect a response.
+
+00:07:19.260 --> 00:07:21.759
+So just a quick little example,
+
+00:07:21.760 --> 00:07:23.759
+a user might open a document,
+
+00:07:23.760 --> 00:07:28.079
+and then it'll send like a text document did open
+
+00:07:28.080 --> 00:07:30.199
+and what document it was to the language server,
+
+00:07:30.200 --> 00:07:31.079
+and then they'll change it.
+
+00:07:31.080 --> 00:07:35.079
+Maybe they edit some code and introduce a syntax error.
+
+00:07:35.080 --> 00:07:37.159
+The changes will be sent to the language server,
+
+00:07:37.160 --> 00:07:39.219
+and then the language server will publish diagnostics,
+
+00:07:39.220 --> 00:07:41.199
+which is those red squigglies
+
+00:07:41.200 --> 00:07:42.559
+I was talking about earlier,
+
+00:07:42.560 --> 00:07:45.459
+and say, hey, syntax error or whatever here,
+
+00:07:45.460 --> 00:07:46.919
+or maybe the user says,
+
+00:07:46.920 --> 00:07:49.159
+I want to go to the definition of this function,
+
+00:07:49.160 --> 00:07:51.239
+and then the language server will spit back,
+
+00:07:51.240 --> 00:07:53.799
+hey, this is where that function lives.
+
+00:07:53.800 --> 00:07:55.399
+All very useful,
+
+00:07:55.400 --> 00:07:57.719
+and the communication is relatively simple,
+
+00:07:57.720 --> 00:07:58.759
+which is great.
+
+NOTE Example request
+
+00:07:58.760 --> 00:08:01.239
+This is what it looks like, what a request looks like.
+
+00:08:01.240 --> 00:08:03.379
+Notifications look somewhat similar.
+
+NOTE LSP capabilities
+
+00:08:03.380 --> 00:08:05.879
+So now we know how LSP communication works,
+
+00:08:05.880 --> 00:08:09.859
+but how does the actual protocol work?
+
+00:08:09.860 --> 00:08:12.399
+Well, almost all of the protocol is opt-in,
+
+00:08:12.400 --> 00:08:15.839
+meaning you don't have to support the entire specification,
+
+00:08:15.840 --> 00:08:17.399
+you can just pick and choose.
+
+00:08:17.400 --> 00:08:19.839
+Servers and clients will then communicate
+
+00:08:19.840 --> 00:08:21.679
+what part of the protocol they both support,
+
+00:08:21.680 --> 00:08:22.679
+so they'll both say, hey,
+
+00:08:22.680 --> 00:08:26.359
+we support being notified when a user opens a document,
+
+00:08:26.360 --> 00:08:28.879
+or if they're looking for documentation.
+
+00:08:28.880 --> 00:08:33.799
+And so then once they agree upon what they'll both support,
+
+00:08:33.800 --> 00:08:35.199
+then they'll send that stuff,
+
+00:08:35.200 --> 00:08:38.579
+those notifications and requests back and forth.
+
+00:08:38.580 --> 00:08:41.319
+Things like opening and closing files, diagnostics,
+
+00:08:41.320 --> 00:08:46.039
+code completion, hovering over stuff, type signatures,
+
+00:08:46.040 --> 00:08:48.559
+all of that. And what's cool is
+
+00:08:48.560 --> 00:08:50.239
+even though the specification is huge
+
+00:08:50.240 --> 00:08:52.039
+and probably has everything you need,
+
+00:08:52.040 --> 00:08:54.479
+you can go ahead and add custom capabilities
+
+00:08:54.480 --> 00:08:55.519
+if you really want to.
+
+00:08:55.520 --> 00:08:57.979
+So you can just define a custom method,
+
+00:08:57.980 --> 00:09:01.359
+and then now that works for you,
+
+00:09:01.360 --> 00:09:03.519
+and now you can have that in all your editors.
+
+00:09:03.520 --> 00:09:04.559
+For example, Rust Analyzer
+
+00:09:04.560 --> 00:09:06.199
+has structural search and replace,
+
+00:09:06.200 --> 00:09:08.159
+which is like find and replace,
+
+00:09:08.160 --> 00:09:11.599
+but with respect to the structure of the code.
+
+00:09:11.600 --> 00:09:13.639
+And if you choose to go down this route
+
+00:09:13.640 --> 00:09:15.159
+with the custom capabilities,
+
+00:09:15.160 --> 00:09:16.659
+you do have to remember you're going to have to
+
+00:09:16.660 --> 00:09:18.699
+implement it in every client.
+
+00:09:18.700 --> 00:09:20.399
+And that's a little bit more work,
+
+00:09:20.400 --> 00:09:23.379
+but it's better than where we were without LSP.
+
+NOTE Tips on writing a LS
+
+00:09:23.380 --> 00:09:25.439
+So some quick tips on writing a language server.
+
+00:09:25.440 --> 00:09:27.479
+I'm not going to get too into this
+
+00:09:27.480 --> 00:09:30.799
+because it's very application-specific.
+
+00:09:30.800 --> 00:09:32.759
+I wrote Semgrep's in OCaml
+
+00:09:32.760 --> 00:09:35.119
+since our code base was almost all OCaml already,
+
+00:09:35.120 --> 00:09:36.599
+and I wanted to leverage that.
+
+00:09:36.600 --> 00:09:38.039
+Would not recommend
+
+00:09:38.040 --> 00:09:41.559
+unless you also have a code base all in OCaml.
+
+00:09:41.560 --> 00:09:43.639
+Structure is similar to a Rust server,
+
+00:09:43.640 --> 00:09:45.739
+so a bunch of independent endpoints.
+
+00:09:45.740 --> 00:09:48.639
+I would do everything functionally if I were you.
+
+00:09:48.640 --> 00:09:49.919
+This is EmacsConf.
+
+00:09:49.920 --> 00:09:53.399
+We're all hopefully used to writing functional Lisp.
+
+00:09:53.400 --> 00:09:56.239
+I would recommend TypeScript or Rust, though,
+
+00:09:56.240 --> 00:09:58.319
+depending on your level of performance
+
+00:09:58.320 --> 00:10:00.839
+that you really need or whatever language
+
+00:10:00.840 --> 00:10:02.254
+you're trying to support ideally.
+
+00:10:02.255 --> 00:10:03.399
+Most languages have
+
+00:10:03.400 --> 00:10:06.499
+some sort of language server protocol already.
+
+00:10:06.500 --> 00:10:09.199
+But if they don't, then it might be easier
+
+00:10:09.200 --> 00:10:10.159
+to do it in that language.
+
+00:10:10.160 --> 00:10:12.799
+TypeScript has a lot of support, a lot of documentation,
+
+00:10:12.800 --> 00:10:14.159
+a lot of examples out there
+
+00:10:14.160 --> 00:10:17.679
+because it was what Microsoft originally intended
+
+00:10:17.680 --> 00:10:20.919
+the language server protocol to be for, for VS Code,
+
+00:10:20.920 --> 00:10:22.079
+which is written in TypeScript.
+
+00:10:22.080 --> 00:10:24.439
+Rust is fast, it's going to take more effort,
+
+00:10:24.440 --> 00:10:28.519
+but it's very fast, and Rust Analyzer has a great library
+
+00:10:28.520 --> 00:10:30.279
+that they use and that they support.
+
+00:10:30.280 --> 00:10:32.799
+So support there, examples there are great.
+
+00:10:32.800 --> 00:10:35.839
+The hard part is not really the language server protocol,
+
+00:10:35.840 --> 00:10:38.999
+but the actual logic. So, like, if you're doing, like,
+
+00:10:39.000 --> 00:10:40.199
+language tooling, you're going to have to do
+
+00:10:40.200 --> 00:10:42.679
+analysis on the code, so you need to do parsing,
+
+00:10:42.680 --> 00:10:46.999
+possibly compiling, all these different advanced features,
+
+00:10:47.000 --> 00:10:48.959
+all these advanced different things.
+
+00:10:48.960 --> 00:10:52.519
+For example, Rust Analyzer will do incremental compilation,
+
+00:10:52.520 --> 00:10:54.319
+which is really, really cool,
+
+00:10:54.320 --> 00:10:58.119
+but that's, like, a whole separate talk.
+
+00:10:58.120 --> 00:11:00.319
+If you're adapting an existing language tool,
+
+00:11:00.320 --> 00:11:01.679
+this stuff is really easy.
+
+00:11:01.680 --> 00:11:03.479
+You're basically just wiring stuff up.
+
+NOTE Supporting a LS through LSP mode in Emacs
+
+00:11:03.480 --> 00:11:08.359
+But, yeah. So, now we know all about
+
+00:11:08.360 --> 00:11:10.799
+LSP and language servers.
+
+00:11:10.800 --> 00:11:11.879
+Say you want to actually
+
+00:11:11.880 --> 00:11:14.079
+add support for a language server in Emacs.
+
+00:11:14.080 --> 00:11:19.159
+How do you do that? Well, let's look at LSP mode,
+
+00:11:19.160 --> 00:11:21.519
+because, like I said, this is what I'm most familiar with.
+
+00:11:21.520 --> 00:11:24.259
+I'm sure `eglot-mode` is pretty similar.
+
+00:11:24.260 --> 00:11:27.479
+So, `lsp-mode`'s repository is on GitHub,
+
+00:11:27.480 --> 00:11:31.499
+like everything, and it has a ton of different clients
+
+00:11:31.500 --> 00:11:34.439
+for a ton of different languages and frameworks and tools,
+
+00:11:34.440 --> 00:11:37.039
+like Semgrep, and these are available
+
+00:11:37.040 --> 00:11:39.739
+to anyone who installs LSP mode.
+
+00:11:39.740 --> 00:11:42.239
+Alternatively, you can make a separate package
+
+00:11:42.240 --> 00:11:43.679
+and just use LSP mode as a library,
+
+00:11:43.680 --> 00:11:45.479
+but I'm not going to focus on this,
+
+00:11:45.480 --> 00:11:47.879
+because there's already a ton of resources out there
+
+00:11:47.880 --> 00:11:50.799
+on packaging and Emacs.
+
+00:11:50.800 --> 00:11:54.559
+So, our steps, very quickly, are going to look like
+
+00:11:54.560 --> 00:11:58.299
+adding an Emacs Lisp file that contains some logic,
+
+00:11:58.300 --> 00:12:01.319
+add an entry somewhere, so we added a new client
+
+00:12:01.320 --> 00:12:03.719
+to the list of clients, and then do some documentation,
+
+00:12:03.720 --> 00:12:05.999
+because documentation's great.
+
+NOTE Create a client
+
+00:12:06.000 --> 00:12:07.639
+First, creating a client.
+
+00:12:07.640 --> 00:12:09.639
+In the `clients/` folder in `lsp-mode/`,
+
+00:12:09.640 --> 00:12:12.919
+literally just add, like, `lsp-` whatever it is,
+
+00:12:12.920 --> 00:12:15.759
+`require` the library, and register a client.
+
+00:12:15.760 --> 00:12:18.039
+Registering a client just means, like,
+
+00:12:18.040 --> 00:12:19.559
+saying what kind of connection it is.
+
+00:12:19.560 --> 00:12:21.479
+It's most likely going to be standard I/O,
+
+00:12:21.480 --> 00:12:24.359
+because that's pretty easy to implement,
+
+00:12:24.360 --> 00:12:26.839
+and then you just pass it the executable
+
+00:12:26.840 --> 00:12:29.559
+that you actually want to run.
+
+00:12:29.560 --> 00:12:31.719
+Say what the activation function is,
+
+00:12:31.720 --> 00:12:33.319
+so this is when the client should start,
+
+00:12:33.320 --> 00:12:36.239
+so you can specify the language
+
+00:12:36.240 --> 00:12:38.279
+or the major mode or whatever,
+
+00:12:38.760 --> 00:12:43.099
+and now your client will start whenever that's triggered,
+
+00:12:43.100 --> 00:12:45.639
+and then finally provide just a server ID,
+
+00:12:45.640 --> 00:12:48.579
+so that way it's easy to keep track of,
+
+00:12:48.580 --> 00:12:52.759
+and then run this LSP consistency check function.
+
+00:12:52.760 --> 00:12:56.579
+This just makes sure everything up there is good.
+
+00:12:56.580 --> 00:12:59.519
+You can do more advanced stuff with making an LSP client
+
+00:12:59.520 --> 00:13:01.199
+that I'm not going to get into,
+
+00:13:01.200 --> 00:13:03.799
+but just know that these aren't your only options,
+
+00:13:03.800 --> 00:13:07.299
+and then finally provide your client.
+
+NOTE Add to list of client packages
+
+00:13:07.300 --> 00:13:09.799
+Next, you just have to add your client
+
+00:13:09.800 --> 00:13:12.159
+to the list of clients that `lsp-mode` supports,
+
+00:13:12.160 --> 00:13:15.639
+and now you've added support for a whole new language,
+
+00:13:15.640 --> 00:13:17.719
+whole new framework, whole new tool to Emacs,
+
+00:13:17.720 --> 00:13:20.219
+and it's taking you, what, like, what is that,
+
+00:13:20.220 --> 00:13:23.639
+20 lines of Lisp? No, not even, like, 15.
+
+00:13:23.640 --> 00:13:26.639
+15 lines of Lisp, whole new language for Emacs.
+
+00:13:26.640 --> 00:13:31.599
+It's really exciting. Now that you have your client,
+
+00:13:31.600 --> 00:13:35.119
+let's do some documentation. Go fill out this, like, name,
+
+00:13:35.120 --> 00:13:37.919
+where the repository, the source code is,
+
+00:13:37.920 --> 00:13:39.599
+because free software is great,
+
+00:13:39.600 --> 00:13:42.179
+and you should open source your stuff.
+
+00:13:42.180 --> 00:13:44.199
+Specify the installation command.
+
+00:13:44.200 --> 00:13:45.399
+What's cool about this is
+
+00:13:45.400 --> 00:13:48.059
+this can be run automatically from Emacs,
+
+00:13:48.060 --> 00:13:50.319
+so if it's, like, `pip install pyright`, right,
+
+00:13:50.320 --> 00:13:53.399
+you can put that there, and Emacs will ask you,
+
+00:13:53.400 --> 00:13:55.279
+do you want to install the language server,
+
+00:13:55.280 --> 00:13:56.199
+and you can hit yes
+
+00:13:56.200 --> 00:13:59.539
+and users will just have it installed for them,
+
+00:13:59.540 --> 00:14:01.879
+and then you can say whether or not it's a debugger.
+
+00:14:01.880 --> 00:14:03.159
+This is completely separate,
+
+00:14:03.160 --> 00:14:05.119
+so there's this thing called DAP,
+
+00:14:05.120 --> 00:14:07.319
+which is the debugger adapter protocol,
+
+00:14:07.320 --> 00:14:09.679
+and it's similar to LSP but for debuggers,
+
+00:14:09.680 --> 00:14:11.679
+which is very cool,
+
+NOTE Add documentation!
+
+00:14:11.680 --> 00:14:14.599
+and then finally link to your documentation.
+
+00:14:14.600 --> 00:14:17.879
+Please, please document your stuff.
+
+NOTE Adding commands and custom capabilities
+
+00:14:17.880 --> 00:14:20.479
+If you want to add, like, a custom Emacs function
+
+00:14:20.480 --> 00:14:22.679
+or custom capabilities, it's super easy.
+
+00:14:22.680 --> 00:14:27.639
+It's literally just, like, calling a normal Emacs function.
+
+00:14:27.640 --> 00:14:30.559
+For example, Semgrep normally only scans files
+
+00:14:30.560 --> 00:14:34.199
+when you open them, but we added a Emacs function
+
+00:14:34.200 --> 00:14:36.719
+that will scan your entire project, right,
+
+00:14:36.720 --> 00:14:40.959
+and so that was just a client notification.
+
+00:14:40.960 --> 00:14:44.119
+It was just `lsp-notify` and then a custom method,
+
+00:14:44.120 --> 00:14:46.719
+and it's great because now you can just scan your project
+
+00:14:46.720 --> 00:14:48.719
+from a simple Emacs function.
+
+00:14:48.720 --> 00:14:52.119
+Requests, very similar to notifications.
+
+00:14:52.120 --> 00:14:56.079
+You send it and then pass it a lambda
+
+00:14:56.080 --> 00:14:58.459
+and do something with the result,
+
+00:14:58.460 --> 00:15:01.359
+and so that's adding custom capabilities.
+
+NOTE Thanks for listening
+
+00:15:01.360 --> 00:15:04.319
+That's pretty much it. Thank you for listening.
+
+00:15:04.320 --> 00:15:05.639
+Some resources here.
+
+00:15:05.640 --> 00:15:08.239
+These links are clickable if you get the PDF,
+
+00:15:08.240 --> 00:15:10.919
+if you get the slides. Semgrep: we're hiring!
+
+00:15:10.920 --> 00:15:12.119
+If you want to work on, like,
+
+00:15:12.120 --> 00:15:13.719
+programming language theory stuff,
+
+00:15:13.720 --> 00:15:18.119
+compilers, parsers, editors,
+
+00:15:18.120 --> 00:15:22.119
+email me or go look at our jobs.
+
+00:15:22.120 --> 00:15:25.119
+The LSP specification, this is, like, the holy Bible.
+
+00:15:25.120 --> 00:15:28.339
+It has all the specs, all the types, everything.
+
+00:15:28.340 --> 00:15:30.419
+`lsp-mode` and the docs.
+
+00:15:30.420 --> 00:15:33.279
+`lsp-mode`, right, that's where you want to add your client.
+
+00:15:33.280 --> 00:15:36.099
+The docs are great, super useful.
+
+00:15:36.100 --> 00:15:38.079
+Rust Analyzer is just a great reference
+
+00:15:38.080 --> 00:15:39.919
+for language servers in general
+
+00:15:39.920 --> 00:15:42.119
+if you want to write one or if you just want to, like,
+
+00:15:42.120 --> 00:15:45.399
+see how they work. It's all just really well done.
+
+00:15:45.400 --> 00:15:47.039
+It's great code, very readable.
+
+00:15:47.040 --> 00:15:50.479
+And then down here is just a long video tutorial,
+
+00:15:50.480 --> 00:15:54.699
+a longer video tutorial, not by me,
+
+00:15:54.700 --> 00:15:58.439
+by someone else, on how to add a language client to Emacs,
+
+00:15:58.440 --> 00:16:00.679
+but hopefully this is sufficient for y'all,
+
+00:16:01.480 --> 00:16:03.920
+and now it's time for some Q&A.