00:00.000 Introduction
00:52.516 Motivation
03:29.120 My requirements
04:37.600 Basic setup: corfu + eglot
05:02.960 Looking at completion-at-point functions
06:44.880 Making my own (basic) c-a-p-f for yasnippet: the completion properties
08:10.900 Getting yas-kw-list right: What do I want?
09:18.880 Diving in yasnippet
11:33.840 Fine-tuning: adding cape
13:03.804 Automatic snippet expansion
14:05.360 Themes
14:58.320 My check-list
15:48.584 Takeaways
16:58.040 Requests (to whom it may concern)
18:55.000 Q: Did you try yasnippet-capf? If so, what did you miss from it that this approach has? Thanks! https://github.com/elken/yasnippet-capf
19:40.160 A small demo
24:51.880 Q: Do special characters in yasnippets work well too? example <FD ?
32:32.120 Emacs Lisp
I describe my experience in "getting rid" of company-mode and
transitioning to corfu. I now have yasnippets integrated with
a couple lines Emacs Lisp. The main advantage is that with I
need less packages and configuration, specially on master.
The talk will include some code snippets that show it was
easier than expectedand a life demo.
20 minutes (with demo)
About the speaker:
After 30 years using Emacs, professionally and for my PhD, I'm currenly
quite involved in org-mode, where I'm revamping the LaTeX backend.
To do this, I needed a new approach to auto-completion because
company-mode started requiring too much code and integration.
Nice to have you here on this talk.This is my second talk this year.First one was on things that I've done to Org Mode.Just as a side note, this presentationthat I'm going to share with youabout my work on Corfu and Yasnippet.I've prepared that on Org Modeand exported that with a work I've been doingto the latest exporter.Anyhow, what is my talk going to be about?It's going to be about Corfu and Yasnippet,which I thought would be difficult to integrate,and it was much easier than I thought.So just a short outline, my motivation,step-by-step of the things that I've been investigating,and some takeaways.
So my motivation, yasnippet is old.So I've tried another. I've tried Tempeland other template management packages,but it was really not my cup of tea. So mainly why?Mainly because I have a nice base of yasnippetsI have generated for my needs.So it's not that I've been importing snippetsfrom packages which are out there.No, they are my snippets. I'm used to them.And of course, migration counts as a cost.I've been using Company as my completion point function GUI for years,but with the time coming in features and so on,it was not as easy to set up as I wanted for my needs.So I had been working,I've been playing with Eglot already some timefor a language server protocol.I had read about how easy it was to integrate with Corfu,which was really nice, and I had given it a try,but I'm using both graphical user interface mode in Emacsand text mode,and for text mode you need corfu-terminal,which was yet another package that I didn't download.Well, and I didn't really find a quick wayto get rid of company to get yasnippet.So at the end, when, at the beginning,when I was using Corfu and Eglot,I also needed to load companyto have yasnippet support,which was really like sort of weirdbecause I wanted to get rid of yasnippet.Anyhow, while I try now, I'm following the mailing list,the development mailing list,and I got interested when I heard something aboutTTY child frames being announced for master.That would mean less packages to downloadbecause I thought I could get rid of Corfu,and I wanted to try if I could get rid of corfu-terminaland run Corfu without that.So, there were some hints there in that mailing listthat made it interesting for me.And at the end, I'm also like a "why not try"ing man,so I said, let's give it a try.
My requirements, I'm working always on a new Emacs,a decently new Emacs, normally from master, vanilla,completely vanilla, and I don't have any extraslike Doom or things like that.So I'm only vanilla. And one of the thingsthat I don't want is that on this vanilla recent Emacs,I don't want a corfu-terminal. I need yasnippet.I'm basically an old man.Old dog doesn't do new tricks and snippets must,in my way of working, must be easy and quick to configure,and tempel or others that I've seen are not.I don't want any reminiscence of company in my setup.And of course, don't forget that I've embracedthe language protocol implementations and basically Eglot.My main focus now is Python and LaTeX,and I have pylsp and texlab.I don't want to have to stop using them.
So basic setup for Corfu and Eglot.You can find it everywhere you look for it.It's really easy.And actually, I also do something somehow naughty,which is to set this variable,the corfu-auto variable to true,although I know it's not recommended, blah, blah, blah.But I use that because I'm a bit lazy in that.
So next step was looking at completion at point functions.So the information there, if you go through, is scatteredand sometimes a bit cryptic.At the end I came up with something like the thingthat you see there on the screen.It's a function for yas-completion-at-point.I need my list of keywords,so that I'm going to be talking later,and I have my bounds, which is normally a word,and from that, I get the start and the endof the thing that I want tobe my seed for looking and bringing up Corfu,and of course, I need some completion properties here.This looked like this is what you need to do,but I had to dig quite deepto create a yasnippet keyword testand to understand the completion props.And as an update of what I've been doing in the last weeks,I've created a bound of things at point for mewith a different thingthat doesn't skip over non-blank characters,that only skips over non-blank characters.Why? Because 'word was confusing LaTeX,because the backslash,like in the example for the teletype text,was not taken into account by 'word.So I had to create my own one,which was a bounds-of-thing-at-point,and then my thing is non-blanks.
[00:06:44.880]Making my own (basic) c-a-p-f for yasnippet: the completion properties
Completion at point properties, what are they?They allow Emacs to know how to handle the informationfor a specific completion time.So you normally will have an annotation,which then can disappear if you use nerd-icons-corfu,which is what I'm doing currently,but I keep it commented just in case I get tired of Corfuand I want to have my completion function.Then the :company-kind is actually not somethingthat comes from the company package, but does not require.And that's going to allow nerd-icons-corfu to identifyand put the right icon there in the completion list,as you will see in a couple of minutes.So it's a snippet key.So basically what this is telling youis that this is a snippet keyword.These two lines, either line,tell you that this is a snippet keyword,and that it should be added to the other completionsthat you already have in your list.
[00:08:10.900]Getting yas-kw-list right: What do I want?
Problems. Looking... Now, next step,once I had the completion propswhich was relatively easy was to goand get the keyword list right.I've been looking at pre-existing solutionslike, for example, how the menuis built in by yasnippetand it looked a bit like Mission Impossible,because the approach by all the thingsthat I have seen and I have examinedis to get the keys and the namesand then further process them.My take was, do I really need both?At the end, if I use my own snippets,I'm going to be using somethingI would call meaningful keys for them,or at least meaningful for... These keys are meaningful for me,and I try not to repeat them,because it makes little sense to repeat a keyword.So why not center everything around the keys only,and can that help simplify my code?
So I started to dive into yasnippetand I found a lot of useful semi-hidden functions there.I discovered that getting the list,the list of keys for a given mode was not that difficult.And at the end, what I started doingis get all the snippet tables used by a major modeand get the lists of the keys that you have in each table.Sometimes the list is emptyso it's going to return a nil and that you have to discard.When you're using structured snippetslike snippets and submenus and so onto get a structured menu.You also get some non-strings that you need to filter outin order to get a workable keyword list.At the end of the day, what I had was something like this.I have, for a mode, I went through all modes.through all modes associated to that, and then I went,I got my results from all the tables that I hadfor a given time, for a given table.So what you do is you get the tablesthat are associated to a mode, because, surprise, surprise,some modes have more than one table.And then what you do is you filter out all non stringsfrom each of the keys list that you have for each table.So as you see, it's a 1, 2, 3, 4, 5, 6, 7 liner,which was not too much.By the way, if someone from Yasnippet is around,I sent a pull request to include thisas a public function in Yasnipitbecause it might be nice to have it in the packagein order to do this kind of things.
So fine-tuning. Just adding a yas completionto the completion point functions was not enough.I don't really know,but :exclusive no didn't seem to work how I wantedso I needed to escape... Sorry. Yeah.I was saying I was getting rid of packages,and I had to add one packagein order to get a function, which is very, very, nice,and which is part of the cape function of the cape package,and that's cape-capf-super.So at the end, using that, you define an alias,which, for that, where you use cape-capf-superto have a list of what you want...So in this case, for example, for the demoI'm going to make, I'm using yas completionand then the elisp-completion-at-point functionprovided by Emacs.I combine them using cape-capf-super,and with that, I create a completion point,a new completion point function which I call cape-lisp-mode,and then I add this alias to the completion functions list,and with that, it is enough.
Snippet expansion.If you want to have your snippets expanded automatically,you have to add an exit function to the, I'm sorry,to the completion properties.Yet another functionality you have to add.And to avoid this automatic selection to be too eager,you need to add this setq corfu-on-exact-match to nilbecause otherwise, you will always get the snippet expanded,even if you don't want it. Basically, why?Basically, because this would be suboptimalbecause the key can appear as part of a variable name.
Another nice thing, I'm also creating my own themes.I'm trying to have very sleek themesthat only cover the modes that I useand for that I have my own theme creator forkfrom the original theme creator.In my personal fork that I'm running at home,I only have the faces for the modes I use.I don't want to overload the thingwith too much different things.Looking at this, I really didn't need, as you will see now,I don't need to add anything to my themes,because the default faces for Corfuadapt quite well to most of the themes.
So if I go back to my checklist,decently new Emacs, yes,compiled. The one you'll seein the demo I'm doing is a mastercompiled the day before yesterdayand I don't need corfu-terminal there.I need yasnippet,and you're going to see that in a secondwith a couple of snippets that I can expand here.I don't want any reminiscence of a company in my setup,and there's none. Well, actually, :company-kind is thereyou see the company there,but it isn't defined by company strictly speaking,and for... I don't want... I need Eglot integrationwhich I will also be showing you.
Takeaways from all this,if you accept the extra burdenof corfu-terminal for Emacs 30 or earlier Emacs 30s,it's not too difficult to get this set up running.Corfu was easier to integrate and configure than Company,and it's much lighter in termsof number of lines, et cetera. I learned a lot.Well, actually, yes, with the help of Cape,but it is much lighter and much easierto integrate and configure.I've learned a lot about computational functions in the process,which is, something that is always nice to learn new thingsand the nerd-icons-corfu makes the...at least, at this point in time... I might get tired of it,but at this point in time, it makesa very nice overall look and feel for Emacs.
Requests (to whom it may concern): cape has nice featuresthat maybe could make their way into emacs.I'm thinking basically aboutthis super cape functionalitywhich is very nice, and overcomes the problem of linking,and this :exclusive and all this kind of thingsthat we have currently in Corfuwith the completion-at-point functions.Corfu is also really nice to have, and it's not too big.So is there any possibilitythat it makes its way into Emacs?Please keep yasnippet alive.I'm not saying here that my pull request should be there,but it would be nice if someone took a lookand made it part of Yasnippet.And P.S., currently on master,there's a lot of semantic highlighting going on,which is very, very nice. No criticism on that.But you may need to add to your snippet hookthis simple local value for elisp-fontify-semantically,because at least in my case, I felt thatthe faces were a bit too pushy,so I had to make the snippet modeuse the old Emacs Lisp fontification.This would be my talk.Any initial reactions to this? There's a question here.
[00:18:55.000]Q: Did you try yasnippet-capf? If so, what did you miss from it that this approach has? Thanks! https://github.com/elken/yasnippet-capf
Someone asked, did you try yasnippet-capf?If so, what did you miss from this approach? I tried that.And it's not that I missed anything.It was more or less that I wanted to do it myself.So I wanted to see what was behind it. That's my answer.There are lots of packages there,but I try to keep learning. So, this was a nice objectiveto learn a bit more about Emacs. And now, just a second.
Now, a small demo. This is the interaction.And as you see, I have the snippet there.and I have a couple of snippets.So, for example, if I would like to sayI want to define a function, I can go like this.And what you see here is thatI have two snippets appearing and then some variables.So, I could go for defun or if I want a key map, for def-keymap,which would be something like this.And then when I press enter, I get directly into the mapand I could say like, show off map.Then it sets out directly a :prefix t,which is something that I asked for in Emacs master.So with :prefix t, for those who prefix it true,for those who don't know it,it makes integrating this into keymapsin use-package much easier.So the next thing would be,I would like to write a description,like, for example, a cool show-off keymap,and then my keys are my functions, and that would be it.Of course, you also have like this define function.And of course you can say, that's nice,but you're not showing the integrationwith Eglot, and you're right.So I'm going just to open up a small programthat I'm currently developing in Python.This is a tool to do things in MP3.And here I would have, like, all these things.As you see here in the bottom,server is running, file is local, eglot is active.So I have my eglot stop and then I go down.And I want to add a new argument here.I would go like for it. I would go like add flag.For example, I would add a flagand I would get a new flag to add here.Oops. Of course, this is integrated into Eglot,so I'm getting your information about what I have.I could... I don't have os, so I would need to import here,but I can go up just to see...If I would like to, for example,create a new regular expression,I'm getting this information that you see right now on call.I'm getting that from Eglot.So you see there's the integrationwith Eglot too in Python.I have Eglot, and as you've seenI also have the... and all these are snippets. Fine.More reactions and questions?Because that would be my show off here.Any questions? Any more questions on the pad?but anyhow I'm going to try,I'm going to try yasnippet tooand I'm going to be answering this question moreyeah time is good okay fineso I would be done if there's no more reactions...Thank you so much. You're welcome.If you have any other questions, folks,you can always follow up on the pad.That was a great demonstration, and I'm sure lots of peopleare looking forward to trying it out.Oh, I see some questions coming in now.You may go ahead if you like.Okay, fine. There's someone asking:
[00:24:51.880]Q: Do special characters in yasnippets work well too? example <FD ?
Do special characters in your snippets work well too?what kind of... I don't use special characters in the key name,so in this case everything works quite nicely,and then I'm passing, I'm passing the control to yasnippet,so if there's any problem in yasnippetwith special characters,that, I don't know. I don't use that as a key.I'm just using for key names.I normally use a... I only use letters, but that should work.I mean, let's, uh, let's give it a trial.Let's kill here. Yes. I don't want, I don't want to touch this.Ugh. Let's go into this one.Let's say I'm going to define this, for example, like this,and I'm going to create a new snippet.I'm going to create a new snippetand use this. For example, when you look at this,if you have the new way of the new Emacssemantical highlighting working,this would be quite cramped. This is why I'm using,this is why I said the snippet, the...So is this more or less what you're talking about?This is what you're talking about. Snippet. Save the snippet.Snippet, load and put window.Enable interaction mode. Yes, I'm going to save.And I'm going to save that as fd test in the file.No, I'm going to save this. Load. Load input window.I'm going to put this in Emacs Lisp mode. I want to save it. No.I'm going to write that directly into Emacs Lisp mode.Going to go back into scratch buffer,and here I have it. We have it here. But anyhow...And I'm just going to try to see, if I feel like...Empty? Of course, there's only one.It will not show in Corfu.but I mean, I don't have any problemswith that, as you see. Was that what you were meaning?Yeah, I guess that works. Fine.All right, shall we wrap up hereso that you can have supperand have lunch and other things? Okay, fine for me.I was hoping to see the drop down. Just a second.I think we can do that too. Two seconds.How can we do that with a drop down?Yeah, if I say something like this.And then I go and save it.And I'm going to go and write thisinto, with a second, fine.And now I need to quit here, sorry.And I'm going to come back in a second with another remark.Well, I'm bringing back and now let's see.Let's see what we have in yasnippet.It's not there. Why not? Just a second. Let's see if I go.I don't know if it matters that the name wasthat didn't have the characters in the beginning.Just a second. I think I know what is happening here.Do I have them? I'm going to clean.cd - to get back in.Yeah. That's right.So you see how the name also has...it doesn't have the same as the keys.I don't know if that affects what shows up.That's a quick one. This is my...Fine, now that I have this,which is going to be quicker, we check again.They both seem to be the same nowand I don't know if that affects, but anyhow, let's try it.I go and then I look at the yasnippet, if it's there.Yes, it is.It doesn't seem to be affecting.
getting more templates set up with yasnippet.I really love the fact thatyou can evaluate Emacs Lisp in it too.try that because if I go into my, for example,into my org mode stuffand in my org mode, I go to the article,which is one of the big ones.I have things like, for example,I defined a couple of functions here to do if it's empty,if that is empty, just add a white space.If one is empty, add a white space.add a white space here so it becomes a comment.I have functions to do more things on that,and I also have menus to seewhat language I want to choose formy spell checking and so on.And that's all... As you see,this is Lisp being evaluated.So yes, do. I really encourage youlike, especially if they're workingin different programming languages,so they can just have the syntaxfor the different languagesbe condensed into a consistent abbreviation.This is when I'm writing articles. I have another one.I have another one for writing lettersin org mode and so on. So, it's like letter, block,and you have the complete infrastructureand you don't have to type it by hand.So, it's really, really nice.a future Emacs carnival, you know,shared blogging theme thing be aroundhaving people share their snippets.this is something stupid.I'm switching my themes. All right.And of course, there you see,I have also, this is also with,this is my way of switching buffers,which is with the shift control and tab,I can switch different familiesand then when I'm in a family,I can go and switch with control tab between the different,I'm using tab line by the way. I'm not using the other one.I'm using the old plain tab line with my themes.So that's more or less everything.I will work on getting the recordings for the live talkssorted out at some point very soon.I might even be able to get them out next week.So thanks again. All right. Have a nice supper.