Emacs From Scratch #3 - Key Bindings and Evil

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments

9:15am PDT happens when this comment is 2 hours and 17 minutes old.

You can find the live countdown here: https://countle.com/ZA3B5iPq3


I'm a bot, if you want to send feedback, please comment below or send a PM.

👍︎︎ 2 👤︎︎ u/the_timezone_bot 📅︎︎ Sep 18 2020 🗫︎ replies

I wasn't able to watch the whole stream, but I caught part of it. Here's the gist I linked that implements Spacemacs-like nested menus using general.el:

https://gist.github.com/progfolio/1c96a67fcec7584b31507ef664de36cc/

👍︎︎ 2 👤︎︎ u/nv-elisp 📅︎︎ Sep 18 2020 🗫︎ replies

Hey folks! Back again today with another live stream where we build an Emacs configuration from scratch. This time we'll be learning about how key bindings work in Emacs and then we'll use general.el, Evil, and Hydra to take things to the next level.

Hope to see you there!

👍︎︎ 1 👤︎︎ u/daviwil 📅︎︎ Sep 18 2020 🗫︎ replies
Captions
[Music] so [Music] what's up everybody david wilson here within back with another uh emacs from scratch stream uh the stream series is something i started out recently where we basically go through writing an e-max configuration from scratch no doomy max no space max nothing like that uh basically we're just trying to figure out how to build our own emacs configuration to our own taste and see how far we can get with it um so in the last episode we added some useful packages that uh added some new information to our ui so that we can get things like function descriptions in the interactive command list and a more helpful describe function describe variable panel those kinds of things so that was pretty useful for making the ui better but now let's talk more about key bindings so one of the main reasons that why you would use emacs is because you want to control everything with the keyboard maybe you are the type of person who you know uses keyboard sorry the computer all day long maybe you're a software developer maybe you're a writer maybe you just like computers and you've kind of gotten tired of this whole mentality of just you know everything is dominated by the mouse so emacs is a program that will allow you to do most things that you want to do with the keyboard and today i'm going to show you how you can set up keybinds in your configuration and then take it a few steps further with vim keybinding emulation and some other packages that make this stuff a lot easier to set up so let's see who's in the chat uh my buddy alex is here uh he's saying that uh mouse's increased coveted risk well i'm not sure that that's actually true but let's go with that for now uh at least what i can say is using the mouse can make your hand sore and it generally just slows you down so avoiding that can be a good thing so um let's jump over to the code and we turn this music down a little bit [Music] so uh before we get into everything let me just remind once again that the uh the code for um this configuration that we've been building so far can be found at my uh my github account uh let me hit that one more time it's github.com davey will slash rune max and if you go here i've got some helpful information about how to rebind your caps lock key to control i highly recommend doing this especially whenever you start dealing with key bindings because in emacs control is pretty much in many of the key bindings that you're going to use at least from a vanilla emac standpoint so putting the position of control in a more convenient place for your pinky finger is a very good thing to do so if you haven't done that yet please check out the instructions here but you can also check out the init.el file that we've been working on so far so uh after the last couple streams i got some feedback um from a couple different people one was on an issue here at the repo which i highly recommend if you have any questions or comments please file issues at the repo because uh we can deal with them there um so kyle sexton uh let me know that uh in the first stream we were talking about setting up doom mode line and um it by default has all this nice configuration for icons in the mode line well apparently um my system setup kind of helped me cheat a little bit there when i didn't realize it at the time but um the icons were already installed for me however if you've tried this on your own you might realize that the um the icons didn't show up so the thing you have to do to um to make that work is you have to install the all the icons package and i'll show you in the configuration where we've done that or i've committed this change already so you should be able to see it so if we look here we're using use package all the icons and i've also added some instructions where um the first time you install this package you need to run the all the icons install fonts function so that it will actually install the fonts since these fonts need to be set up in your systems um your os specific font location directory where emacs can pull them up so this is an important thing to do to make sure that you get the icons showing correctly inside of your mode line um also want to give credit to uh let's see if we can pull that up to give credit to nathan chen who left a comment on the video also saying the same thing so i appreciate kyle and nathan for leaving those comments and let me know about that so um one other thing that i want to mention is you'll see if i if i run right emacs right now the way that i set the uh theme the last time by calling load theme if you start up emacs with that configuration you'll see that you'll get a prompt whenever you're loading emacs which is a little bit annoying at the bottom you'll see loading a theme can run lip lips code really really load yes or no so you can press yes to make it load the theme but you don't want that to happen every time so the fix for this is to go find the load theme call and then add t as the second parameter and what that does is it tells load theme don't prompt me about it i know i want to load this theme just go ahead and do it so if i were to close emacs now and save the init.el then start it again and you'll see that it doesn't prompt us this time just goes straight into emacs with the font with the theme loaded okay i think that's everything that uh we needed to cover uh before we start moving on to key bindings so um so emacs has a couple of main functions that you can use for setting up key bindings and it's very easy to use not really a hard thing to do so let's start with global set key so if i was to pull up the documentation for global set key it will tell me that uh it says give a key a global binding as command so basically we're saying that if we call global set key with a certain key definition or like basically the key binding syntax uh bind it to this emax list command um so let me think what we could do for that i'll actually go look at my own configuration and see if there's something useful we could bind so globals i think we're actually doing something already let me check that real quick okay so um i may have copied this to init oh let me pull our emacs back up all right global set key all right so we do have one global set key call already here so global set key and then we're calling this keyboard function which converts a string form of the key binding into the actual sort of key code string that emacs uses internally and we're saying we want to call this keyboard escape quit one other thing that i like to do for my own buffer switching is to bind control alt j because j is right under the thumb and if you remap the uh control key to caps lock then it's really easy to hit ctrl alt j on your keyboard at least it is for the keyboard that i use uh maybe it's different for you but uh well let's just set that up real quick i'm gonna put it near our iv configuration because we're doing this for buffer switching let me just paste that in alright so we're calling global set key and we're using the control-m j so this is generally what the syntax is for emacs key bindings c stands for control m as we mentioned before stands for meta which actually means alt in most cases and then j is just the letter j and then we're going to bind this to cancel switch buffer and in typical emacs fashion we can uh evaluate this and let me actually pull up my um clm slash command command log buffer so you can see that and global oh is this the right no i'm in my outer emacs at this point let's full screen this do that one more time clm open command log buffer and then global command log mode all right so um we're gonna go and evaluate this text by control x control e and somehow that's not showing up there we are so you can see control x control e vowel last x s expression and now if i hit control alt j then we get cancel switch buffer and you can see here that the control control mj control meta j uh launched console switch buffer so that gave us the ability to pull up our buffer switcher which then we can you know use the arrow keys to select which buffer we want to go to and then we can just go back to the the init buffer so um that's good for setting global key bindings there's also a function called define key and this is for setting a key in a specific key map so i think we mentioned maybe in the previous stream that uh for each major mode and minor mode and e-max there usually are key maps that you can use that are specific to that mode you can use define key to set key binding specific specifically to a key map so that for instance whenever let's say emacs list mode is active you can bind a key only to be active in e-max list mode this is pretty nice because it allows you to be very specific about when a certain key binding appears so you could technically use the same key binding to do two different functions in two different modes but to you they mean the same thing like if there's like an evaluation function like the eval last s expression if you want to do like if you're editing a python buffer and you want to evaluate some python code in the ipython repo or something you could do a similar key binding only in python mode so that that same key binding works for python in the way that python needs it to work so it gives you a lot of flexibility for being able to set keys in a particular mode let's see if we can come up with one for that so let's say we're in emacs list mode now let's just do a different type of binding so i'm going to hit control h f and say emax lisp i'm sorry no ctrl h v we're going to look for the mode map for emacs list mode emacs lisp mode map so generally whenever a mode map is defined for a major minor mode it's going to have this naming convention where it's whatever the mode name is emax list mode and then map as the last part of the variable name so if you go to that you can see that the helpful ui actually gives us the values of all the bindings in this map already so we can see what's what's bound here and then we can add our own bindings to this map by using define key so um let's see what's an interesting function we can find um just for fun i think what we'll do is just use a theme switcher so cancel uh the switch theme was it theme yeah cancel load theme so we will say define key and i believe we just give the mode name directly but i could be wrong about that we'll find out real fast so emax lisp mode and then let's grab the the help for that okay so key is the next thing i think we're going to say a keyboard so c x uh m t just something to do here like we're not gonna keep this key binding this is just by way of example so we'll say cancel load theme i think it was called cancel load theme okay so i think that's everything we need here let's run this and see what it does okay so we have an emax list error and it's not really giving us much details but what i think is happening is maybe i need to use a symbol for this uh oh no i'm sorry i did not use the mode map let's do this we're gonna run that okay now uh we are in um emacs list mode already so this key binding that i just evaluated should work let me pull back up our command log buffer so i'm going to hit control x and then alt t and then now you see that we have our load custom theme pop up at the bottom you can also see in the command log that i did that keybinding so that's just a nice thing that you can do to um you know set your key bindings directly if you want to but in many cases we're not going to use these commands directly we're going to use either use package the bind section and use package for a particular mode or we can use another package called general.el to set key bindings for the global key bindings and for modes so let me just go ahead and take these out and i will show you general.el so we've gone through basic key bindings here so let's switch over to general.el and i will pull up the uh page for this so um you go to github it's well i'm not gonna i don't know how to pronounce this username not uid uh general.el and i've jumped directly to the examples because that's sort of what we want to look at so um we will just use use package to pull in general.el and i'm going to pull in a little bit of configuration with it which i will explain in a moment let me pull our emacs back up and um let's just drop it down here at the bottom at some point i'm going to go and re-organize all this config but for now we're just going to go with what we have here and please uh if at any point if you have any questions about what i'm doing just stop me and ask a question in the chat i'll be happy to answer it so uh we are going to use use pack as general and then um we're calling this general evil setup but let's just skip that for now until we get uh evil turned on and uh let's ignore this for now also so i'm just going to delete this part so in fact we can just drop this back to plain old use package general i'm going to use ctrl x e to install that and now general is set up so what general allows you to do is to define keys in a more sort of concise way so if you can see this example here general define key we can copy this and paste it and then we can do what we did before which is to do a global key binding um oh and one thing that i can also tell you let's see what was the key binding that we had done before i think it was ctrl x uh alt t is that right or is that that was only in the major mode can anybody remind me what that keybinding was um let's see maybe it's in my command buffer actually so i had done global key binding oh yeah so cmj so you can use global unset key i believe as a function if i say control hf and then global onset key you can use this to unbind a key that's already been bound so if you wanted to like remove something you've been experimenting with you can do that easily so i'll show you another little trick here if you do uh alt shift colon or technically it's alt colon because you have to hold shift to do that you can see that here uh m colon uh it brings up this little eval prompt at the uh the mini buffer and you can use that to email evaluate any emacs lisp code just sort of right there in the mini buffer so i'm going to say global onset key and say keyboard uh cmj i think i need to take that that parenthesis out so now i should have have unbound that and if i hit control alt j the set tells me down here in the mini buffer that cmj is undefined so cool so now we've made sure that we don't already have that binding set up and now we're going to use general to set that same binding so we'll say cmj and then console switch buffer we'll take this other part out so now if i execute this code and i hit control alt j then we see once again we have a council switch buffer running and you can see this in the command log buffer here so uh that is what you can say is simpler because you can do multiple bindings here like if i was if i wanted to do uh c m k and bind that to something then i could just basically have a list of the global bindings that i wanted to set up in this little block so that's kind of nice however i very rarely use general.el in this way one thing that i do use general el for is to maintain my own global key prefix and for me that's very useful because i can have my own custom set of key bindings for getting to common actions that i use that aren't in the normal emacs prefixes of cx and cc so um let me go and pull that up from the example config that i have so what you do for this is you call um general create definer and this uh basically creates a function that can be used for future key definitions and uh if you've ever used space max before it's kind of in the name space for space max the space max uses a space bar as what they call the leader key for getting to all its built-in uh key bindings so i kind of stole that idea because i found that control space is a very good global key binding that you can hit without moving your hand so if you have uh control bound to caps lock like i do uh you can very easily just hit control space without doing anything and since we're setting it as a global key map you can get that to that from any uh mode anywhere in emacs even if you have like an exwm window manager setup and you're uh you're looking at an exwm window so that could be very useful so uh we are defining a definer a key definer called rune slash leader keys and this rune slash is just a basically a name space that i made up to um to put some sort of config specific stuff in you'll see this often in people's personal keybinding or personal emac configurations they will have like something slash maybe their initials maybe some other word um just their own personal name space for definition since there's really no name spaces in emacs so um we are going to do this definer and actually we need to do this inside of the config block of use package general so i'll take this part out and then in general i will say config and then move this over a little bit and i could do the leader key bit there as well and yeah let's do this okay i think one of the parentheses un unbalanced uh so uh one other little tip that you might want to know about is if you are editing an emax list buffer and you're not sure if you have like a problem with parentheses you can hit alt x and type check parens and it will jump the keyboard or sorry the cursor to the point where there is an issue with with a parenthesis in your in your file which can be very helpful sometimes like one issue that you will commonly hit whenever you're editing an elis configuration file or even a config in org mode um if you set up your parentheses wrong and you try to load emacs it will it won't crash but it will stop during load load time and give you an error basically saying that it can't do something or maybe the parentheses are unbalanced so the best way to diagnose that issue is to run the check parens function so that it will jump your cursor to the point where there's a problem so that's saved me a bunch of times all right so i think that this is that still doesn't look right to me oh that's why because i have the closing parenthesis there all right now i'll put this there then we're good so um i will just run this block by itself let me pull back up the command log buffer so control x e so now um i have a definer for control space and if i hit control space um it's not doing anything yet but that's because we haven't actually set up any key bindings within that definer yet so since it's called runeslash leader keys we can use that as the function name to do definitions and what we're going to do is create a prefix within this leader key prefix with the letter t so it's like control space t and then under that you'll have a set of extra commands so if i go and evaluate this then i think if i hit control space it should give me that oh no it's still doing the um i wonder if it's because i'm using the e-max bit here or sorry the e-lisp or evil bit so let's try doing that again and then i will run it one more time so key sequence starts with non-prefix space all right let me do this too just as a precaution the way that i have mine set up is uh based on evil mode which we'll get into in a moment so maybe that's what's causing a problem here key sequence tt starts with non-prefix key t that's interesting so let me check my own personal configuration real fast and see what i'm doing wrong so create definer um so we've loaded general mode we've been using it already it's kind of interesting that it would have this problem let's check the documentation create definer [Music] if we could find it somewhere prefix prefix my leader proof effects without a variable um does the global prefix still work global dash prefix okay let's just try it with uh plain old prefix for now because i think something's going wrong here and then we'll change it up once we get this working correctly so let me try this one more time i still think it's not doing anything so we'll just give it a shot that's very weird okay well if anyone's used general before and knows why this is happening let me know uh so i'll just demonstrate this within my own configuration so if i hit control space i get this panel at the bottom and i've got things organized in a way where different letters have words attached to them and this is something that is a part of which key so in general.el you can bind when you bind a sort of like a prefix in general you can say what the which key string should be so that allows you to say that f is for files and d is for dear ed and a is for apps so if i hit a now it goes into my apps list and then if i hit p would go into my my password list basically so similarly if i hit g control space g it brings me into my git commands and then i have a bunch of keys defined for going to my git commands so it's kind of nice because i have my own isolated place where i can set key bindings and it'll be very cool if i could demonstrate it in our own configuration but for some reason right now um it's not cooperating with me so what we're gonna do is come back to this after we talk about evil mode because i think that somehow general is working with evil in a way that works fine in my config and maybe here it's got problems so let's uh let's move on to evil so if you have ever used vim before you've probably gotten used to the um the modal editing idea which is that instead of being able to type letters into the buffer at any given time instead you have modes that you're in and each mode has basically binds the keys differently so in vim the normal mode is like a command mode where pressing letters on the keyboard will actually run commands that do things to the buffer or do things in the editor in general so one example of this in normal mode is if you hit dd it deletes the current line where the cursor is now if you wanted to actually type some text into the buffer you would press i to go into insert mode and then you could type text at however you wish then you can press the escape key to jump back to normal mode you're probably thinking well this sounds pretty complicated well what i can tell you is that in emacs with vanilla emacs key bindings or maybe some customized key bindings that depend on normal emax bindings you will be hitting control a lot or alt a lot and it's not really good for your hand to be constantly trying to hit modified modifier keys all day in combination with other keys because you'll be stretching your hand a lot so you kind of want to save um your hand movements for the things that are not so frequent so um vim key bindings are very good for allowing you to do those kind of complex editing tasks and moving around a buffer very quickly without having to use modifier keys as much so this is why i prefer to use vim key bindings for editing inside of buffers and then use emacs keybindings for other things that are sort of in the broader editor at any given moment so uh what we're going to do is set up a mode called evil mode and uh it has a really cool name but it doesn't really say what it does but this is basically a vi or vim emulation layer for emacs and we'll jump over to the uh the uh git repo for that so that you can see what the the page looks like and then we'll get it set up very quickly so um let me pull this up so yeah if you go to github.com emacs evil evil you can see the home page for that and it has some documentation there's quite a lot of documentation here that you can use um and um i think it's worthwhile to look at some of that however once you get evil mode set up initially you probably won't go back to the docs very much because this configuration kind of just works after you get it going let me copy this initial config block over to our emacs and now we're finally going to get to the point where i'm going to hit keys that actually makes sense to me and i won't be hitting the wrong key all day long which is great so there's a lot more to this initial bit of configuration than what we've been doing so far there's more in the basic use package definition in fact let me go and grab another part of this because we're going to need to show that too but i will explain what all this stuff does because it does it is relevant to what we're doing so um evil mode has quite a lot of different configuration flags you can set to enable or disable certain behavior and it really kind of comes down to how familiar familiar you are with them key bindings if you're not very familiar with them key bindings and you probably don't really care too much about changing some of these settings internally in evil mode but if there are certain key bindings that you're used to that that aren't working for you in evil mode you may have to look at this set of evil dash want variables that configure evil mode for certain things so if we were to look up uh hit control hv in fact let me pull the command log up again ctrl h v evil dash whoa that's not right sorry for that um control h v evil dash okay we haven't installed evil yet so let's do that first um i will just say use package evil first and once that's installed then we'll be able to check the variables all right now it's installed hi juliet sulieth uh yes i've been using emacs for quite a while now uh and i do not use f-sharp very much anymore i haven't used it in a few years actually but it's a great language so um all right so here's another little emacs tip sometimes whenever you call use package you'll see this lisp error file error melpa packages evil whatever not found um often when this happens uh it's an indication that your package list is out of date so i think uh usually the way that i deal with this issue is to run list packages list dash packages and this pulls up emacs internal package list but whenever it does that it actually refreshes everything from the um melpa and elpa etc whenever you load it so that's one way to make this let's make it go away uh make this work so now i'm going to run use package again for evil and this time it should download and install it correctly because we have the most up-to-date uh package list so it's just one more thing to be aware of whenever doing your own emacs configuration so now we should be able to see all of these evil dash want variables so there are quite a few um there's like one of them that i find is pretty helpful to set is this uh evil want cu scroll um c-u i'm not sure what it's bound to by default but i guess we can find out now because it should be bound the correct way so ctrl h k for key binding cu this is for a universal argument so universal argument actually is a pretty common thing that you will see in emx key bindings and what this does is allows you to modify interactive commands you might run so if you run an interactive command the default behavior could be something and then if you hit cu before you run an interactive command then it may augment the behavior somehow and depending on how many times you hit cu it continues like shifting or incrementing this augmentation number that gets passed into the interactive command to change the behavior um i don't really use that very much i'm sure there's like good uses for it but for me i prefer to use vim's scrolling key bindings of cu and cd cu scrolls up and cd scrolls down because i'm used to that so this variable evil want cu scroll will actually cause cu to be rebound so that it does scrolling in a buffer instead of doing universal argument i've never gone back and rebounded universal argument to something else because i don't really ever run commands that need it or i just never known i needed it so uh hasn't been a problem for me but if it ever becomes a problem for you then this is the explanation for why um that happened if you use this cu scroll setting so we're just gonna leave that turned on for now because i do like that another thing is uh evil wants ci jump and there's some jumping functionality in vim that you could turn off in evil mode i never used that so i turned it off because i think there was some other binding that i wanted to set with ci i mean you could turn that off you could leave it alone whatever you wanted to do by default it's set to true but uh i turned it to nil so um these other two variables here are pretty important um evil want integration if i hit ctrl h v on that it tells me whether to load evil integration.el um i don't exactly know what that does um maybe it automatically does keybinding or something but uh pretty much everywhere you see people describing evil configuration this should be turned on um the thing you don't want to turn on is this evil want key binding which i think loads some um helpful bindings for them style bindings in other modes because the stuff here isn't so good or so consistent i turn that off and i use a different package for that which i'll describe in a minute so we do all these variable settings in the init block before the evil package loads up so that they're already set whenever evil lows because whenever evil mode loads it looks at these variables to decide how to configure key bindings as it's loading so you want to make sure these are set first using the init block then in the config block which gets run after evil gets installed basically and uh and check to see if it's there uh we are loading evil mode uh globally so we just turn it on by default and then we do some other key bindings with it so what i'm going to do right now is i'm going to evaluate this set of things just manually i'm not going to run the whole block yet because i want to demonstrate some stuff also i'm going to run evil mode and one thing you may or may not have just realized is that this little icon showed up here in the bottom left-hand corner of the screen this is our indicator for what mode we're in and green is indicating that we are in normal mode so now um i can use j and k and you can see in the command log view here that i'm using jnk to navigate across the lines just like in vim i can hit shift v to go into visual line mode to do line based selections i can press dd to delete a line i could press u to undo that deletion and um this you know is in my opinion a lot more convenient than using the normal setup for emax key bindings now i just hit ctrl u and it's still doing that uh universal key let me check this real quick so evil want cu scroll so i haven't set the t but it didn't work so i wonder if there's just something going on with that but we won't worry about that for now so um so that's great we have basic vim key bindings working that was very easy so now we want to uh do some extra things that sort of in my opinion blend emacs and the vim emulation a little bit more the one important thing is to bind um cg which is uh emac's own sort of exit function usually you can just smash cg at any point if something weird is going on to just get back control of emacs again um i also like to use cjcg to convert back to normal mode um actually i should show insert mode first so um you see that there's a green icon here if i press i that puts us into insert mode and now the icon turns i guess pink in this particular theme and i'm able to type things but then i can hit escape to go back to normal mode and hit u to undo the text that i just inserted into the buffer so i'm going to bind this cg so that we can get back to the normal mode from insert mode if i was to try that now i'm in insert mode hit c g it it will do the quick command but it won't actually put me back into normal mode so if i go and hit ctrl x e to bind that now whenever i'm insert mode i can hit control g and it drops back to normal mode so i found that to be kind of helpful and it helps to sort of reinforce this mental model that you're in emacs and you can use the cg command to do what you expect it to do at any given point another thing is ch so um this i'm not sure whether this is something that you should set up or not because it turns out to be an annoyance for me so i'm gonna explain it then i'm gonna take it out so ch obviously is the help command um now if i'm going into insert mode hit ch it still gives me the help command but if you are used to emacs key bindings um ch actually means delete backwards it's almost like using the backspace so if i was to go to evaluate this and then in um insert mode i can hit control h and then that does backspace so um i guess it is good to have that because it does keep us in this mindset of staying on the home road so instead of reaching your hand up to hit backspace in insert mode you can hit ctrl h instead which is all in the home row and you don't have to move your hand at all so um actually maybe i've changed my mind now i will do that end the the the thing that you have to remember though is whenever you are in insert mode and you hit control h thinking that's going to bring up the help menu or the help key prefix it's not going to do that so you're going to have to go like oh god this again and hit control g or escape to get back to normal mode and then hit control h to get to the help list so i don't know i find that to be a little bit of an annoyance sometimes but um ch is a pretty useful uh key binding even though i find that i don't use it very much um you know i should slap my own hand for that okay so um another thing is uh these visual line motion keys so uh there is this concept in emacs of visual line mode and this is a mode where whenever your text reaches the edge of the current window and needs to wrap there's two options either it can be truncated and then you have to scroll the buffer over to see what's there or you can turn on visual line mode and it will wrap the text down to the next line by default in evil mode the uh when you hit j and k it won't go to the wrapped line it will jump to the next line and that can be really confusing whenever you see it happen the first time you're like i need to get to the end of this line but whenever i hit j it jumps past that and goes to the next line so if you set these motion keys j and k to evil next visual line and evil previous visual line then that will solve that problem we haven't actually set up visual line mode at all in our configuration yet but that's just some something to keep in mind for uh in the future so um now evil mode is great for editing text buffers but there are some buffers that you don't want evil mode to be activated for on by default you want evil mode to be enabled globally but then there's some modes where you don't want it to be starting in normal mode in the buffer you want to start in insert mode for instance like a terminal so if i was to start uh let's say term mode um right now let's see it did drop into insert mode by default which is good maybe there's already some configuration there for that so i'm in insert mode i can hit escape for normal mode and use normal vim keys for that then i can add again to go back into insert so let's say like get get status i hit escape then i hit b or sorry was it maybe it's not working in this buffer actually let's kill this one so um anyway the point is that in some buffers you do want the initial mode in the buffer not to be the normal mode you want to be the insert mode it seems that in this case i've set a couple of these modes to have normal as their initial mode but we want to do the opposite what we want to do is say for a set of modes we want to have them be in emacs mode to begin with and not in not even in insert mode so in them there i think there's like three different modes typically there's like normal mode insert mode and visual mode then experts may know of more but those are the ones that i know of and evo mode will give you an extra one called emacs and what that does is by default just disables vim key bindings until you hit the control z key binding so if i was to hit ctrl z right now it puts me into emax mode and you can tell by the orange icon down here and now i don't i don't have uh emax key bindings anymore i'm hitting j and k and it doesn't navigate um this can be useful sometimes whenever evo mode is doing something really weird in a buffer you're in and you want to like say okay stop for a second let me get out of this because i'm going to like delete something that i need to keep so you can hit control z to jump into emac state so that you can use normal emax key bindings and get yourself out of trouble i'll hit ctrl z to jump back into that so uh i think what happened must be that um no i haven't set these up yet but basically this is another sort of example of setting a hook like i was doing before where um for the hook of uh emax mode or sorry evil mode we are going to run this um list of modes through this we're adding it to the list of emacs sorry evil emac state modes so if i check that variable out there's a lot of modes in here i think they must have a bunch of configuration by default which is good i suppose so um basically all of these modes whenever you go to them they will automatically start up in the emac state rather than normal mode or insert mode so um maybe this setting that i have here is not even necessary anymore i can search in this buffer to see if term mode is here no turn mode is not here term mode nope what about uh erc mode nope okay so this is some some custom configuration of my own i think let me see if i can close this one other nice thing a little digression here that evil mode will give you by default is you get the control w set of key bindings that you have in vim for window management i use these all the time and um i find them to be a lot more intuitive than the key bindings that emacs has in the control x prefix so if you hit control w you can see that um which key will tell us about all these different evil window management commands so if i hit v it will do a vertical split in the buffer if i hit ctrl w s it will do a horizontal split and then if i say ctrl w c it will close that window so that can be really fast for doing window management in emacs i find this to be like like i said one of the most common things i'm using all day whenever i'm having to do window management of buffers so um yeah not sure how i got there but i think that for now we can just like ignore this whole evil hook part since i've i've described that but it's good to know that for certain buffers you may want it to start in a different mode than normal mode so um on the topic of evil key bindings in other types of modes there is a really good package called evil collection and what that does is gives you a stable or let's say a good emax or evil mode configuration for different emacs modes so let me go to this i'm going to take you to their website so the evil collection basically is just like a whole bunch of e-lisp files for different modes you might use that set up evil mode key bindings for those modes and um there's a lot of stuff here any anything well let's not say anything but many of the modes that you would find that people commonly use in emacs are represented here and the goal is that you don't have to think too much about what the binding might be the vim style binding set in those modes should be predictable based on what you know from them key bindings and also some influence from emacs keybinding so we're going to install this so that we can get some some of that shared sort of key binding configuration so use package evil collection let's go ahead and install that first and let's see yeah there's a lot of files that come with this so it's going to take a little bit of time to download okay so now we have uh installed all these we get a little bit of a message that's actually kind of helpful uh evo1 keyboarding was set to nil but not before loading evil interesting i did that but maybe what happened was use package loaded evil first and that may explain why cu didn't work so um since we got this message the likelihood is that things will not be set up correctly so what i'm going to do is back out of i'm going to close this emacs instance and start it up again just so that we have a chance to get things at a fresh state and close that okay i can't close that climb close all right so starting emacs back up again [Music] um let's see all right so apparently i have a syntax error in the evil configuration and also my general config is still making it unhappy so let me see if i can yeah i can't comment that out right now or can i nope [Music] so um let's see what could be wrong here uh the hook is not defined so let's take that out i think that we should be okay there so uh another nice little evil or them key binding that you can use for uh editing um emaxless buffers or any buffers that have delimiters in it as you can hit uh shift 5 which is the percent sign key to jump to the matching delimiter so that could be helpful sometimes for navigating emacs list code let me check again yes okay so it failed to define function rune evil hook okay so basically i've just uh broken it by referencing the the hook that's not defined so let's just open that back up one more time okay so yeah we got this general issue i'm not going to worry about that just at the moment okay so um now we have evil collection loaded but we need to do one extra step to make sure that it is uh gonna configure buffers the right way or modes the right way so we are going to look for the evil collection and knit function and we're going to drop it in under this so one thing you'll notice here is we're using the after hook i suppose you could call it to say that we want evil collection to be loaded after evil loads so that's a nice thing you can do to sequence the loading of certain packages that are dependent on another uh and in the config block we're going to call evil collection and knit so let me just go ahead and run that now and now we should be set up to have them style key bindings in a lot more modes let's try one just to see for sure if that actually works so i'm going to go hit control hf and we'll say evil collection init and now we're bringing up the help buffer and uh one thing typically in vim is that if you're if you've got some kind of panel up usually you can hit q to close it so let's see if i hit q if it closes it yeah so that works um i use that quite a lot for getting out of pretty much any type of pop-up window in e-max i just press q it's quicker than doing like a control wc for close close window etc so that's that's kind of nice um so if you look at the let's see there's a variable that you can check for the modes that get configured by default on startup which is kind of useful if you um let's see mode list yeah if if you have a particular mode and evil bindings are being bound in that mode and they're wrong or they're giving you trouble somehow one thing you can do to easily get by this problem is to remove that mode from the evil evil mode evil collection mode list so if you remove that value which i think that the function for that is um remove let's see add to list so there's an add to list uh function is there a remove from list no remove well there's definitely a way to remove an item from a list i don't remember what it is at the moment but um if you remove the item from this list then it won't be configured whenever evil collection init gets called so that's something you might want to look out for in case you have issues with um with the evil collection configurations for a particular mode so um let's see that gets us through the evil configuration for now uh when we discuss future modes like megit and lsp mode etc we will talk about or in org mode specifically we'll talk about maybe different ways to configure evil key bindings for those modes because they um they have their own sort of needs so we'll come back to this in a later stream one last thing i wanted to show you is another package called hydra and hydra allows you to set up transient key bindings for certain things so that you don't have to continue hitting key bindings multiple times you can actually pull up a panel that gives you a temporary set of key bindings that you can use with individual letters to really quickly do some kind of action that's repetitive so let me go grab my example for that and i'll just run through this quickly because we're running out of time here um let's look at the git repo first this package is by who has written a lot of stuff i believe um i believe abu did the ivy and swiper and council as well so is a pretty prolific emacs package author i sponsor him on github uh you can see my face here and i recommend that you do too um so we are on the hydra page there's some documentation here that sort of describes why you would want to use this but we're just going to jump right into an example so i'll pull in all of this and explain what it does as we go all right so first i'll install hydra okay it's installed now and now uh hydra brings in this uh command called uh def hydra and uh this is a macro i believe which is able to say i wanna define a hydra called hydra text scale so we're gonna define a transient key binding for changing the scale of the text in the current buffer let's ignore the timeout thing for right now we're saying that the name or the text display for what this binding is is scale text and the keys are j k and f j increases the scale with a string of n which basically is like you know how do we describe this this letter this character key binding k scales out and f exits so i'll go ahead and um run that definition and now if i run a hydra text scale body this is the function that gets defined to actually run this hydra uh you can see i have this little pop-up in the mini buffer that says scale text jn k out and then somehow oh yes my timeout happened so uh let's run it one more time and then f is finished so if i hit j it scales in the text and i just keep hitting j j jj it gets huge i can hit k to scale back out and then whenever i decide that i'm done i can hit f to exit the hydra so that's pretty helpful for things like scaling or any kind of um cycling commands like if you want to cycle through buffers really fast you can make a hydra for cycling buffers or just anything you can think of that you want to make like a really fast key binding for this little timeout bit here says that if the hydra stays open for four seconds without any input then make it go away this is optional you can actually just take this out and then the timeout will go away but you could also set a global key binding here i think there's some syntax for that uh let's see global yeah so you can say basically what map you want the key to go into and what key should go in that map so we could say for this zoom hydra that f2 should pull up this hydra so we're going to use a slightly different approach for that and this requires that our general bindings work so let's see if i can actually make that work first now that we're loaded we have emac or evil load moded evil mode loaded we should be able to make this work i hope we're able to make this work anyway so let's run this definer one more time and then i'm going to try to run the roon leader keys now this seems to have worked i don't know why but now when i hit ctrl space you can see down at the very bottom that we have t for toggles like i set up here in this roon leader keys t goes to a which key description of toggles if i press t again then it shows me choose theme which is the tt binding basically so the prefix is t and i say tt which is uh the existing t plus another t basically then we get to choose theme so if i hit t again then we get the the theme chooser so um now if i go to this next instance of roon leader keys and bind ts to hydra text scale body and evaluate that i can hit control space t and that brings up my list and then scale text is one of the options in addition to choose theme if i hit s then i have my jk bindings that pop up that i can use so i can just hit jnk all day long so um since this is finally working let me just go back one more time and cover that just so that you know what happened so in general the general.el package they allow you to create a key definer um this could be any prefix that you want so you could even be cc one of the existing uh defined or one of the existing prefixes in emacs so we could set up a definer function that could be used to define um key bindings that go under that key prefix so in this case we're doing control space we're also doing space if i just hit the spacebar right now the same thing happens the the bindings come up i find that i use that much less because control space is just as easy to get to and it works from anywhere so now that you have this definer called roon leader keys you can call that as a function to bind bindings key bindings that go under that prefix and whenever you do the bindings um basically it's a sequence of letters that um are then set up so i could say t e for control space t e and then i bind that to something else um but that's basically how you can set up a bunch of bindings with a certain prefix very very simply and consistently i'll show you in my own personal configuration what that looks like for let's say the get bindings so if i look for my get status i think i'll find it pretty fast here so i have my own leader key definition function and you can see i have this uh gs gd gc glc glf i mean there's a lot of stuff that i have here for different git uh commands so if you have sort of like a subset of things that use a lot that you really want to get fax ass fact fast access to my mouth is not working today apparently then you can set up one of these leader keys definition functions to then be able to bind a whole bunch of these keys all at once without having to do a bunch of like global set key command calls or define key calls or that kind of thing so general that yell is is really helpful for having a cleaner keybinding configuration and have it be a lot more sort of standard and integrated into which key which i find to be pretty helpful so i think that's everything that i wanted to cover today um before i go if anybody has any questions about any of this please feel free to ask in the chat um i think next time i'm going to start getting into some of the uh oh okay no wayman says you should make use of general.el's in-fix keyword well i've never heard of that so let's actually see what that does let's go back to this infix infix keyword can be used to sandwich keys in between all of the specified prefix keys and the keys in each mapping that sounds interesting different define several keys that was prefixed with space g in normal state and m space g and insert state you could insert you can use a previous wrapper within fix instead of re-specifying both the prefix and non-normal uh i don't fully understand what's going on there it'd be good to see an example of that no wayman if you want to give an example ah you link a gist i didn't actually see that maybe it got eaten by the uh the live chat but uh yeah that's a great idea um if you want no wayman please like leave a comment in the video after the stream is over so that people can see that because um yeah i don't actually see a good example of that here but um but yeah that's that's a great suggestion thank you for that um yeah so as i was saying in the next stream what i want to do is start getting into more of the um project and repository management packages like projectile and myget because i use those often and i find they're very useful for you know for as being a software developer i mean they're very useful to my day-to-day activity and mygit is quite amazing so we'll i think we'll talk about that next um i think that we'll do that stream on monday so stay tuned for that um so for future streams please make sure to subscribe to the channel um in the button below and make sure to hit the bell so that you get notifications whenever i schedule and start streams because otherwise youtube may not let you know in advance and keep in mind that we do have the code for the configuration so far um in the roon max repo after the stream is over i'll commit the changes we've made so far and then you'll be able to see those there so um i think that's all for today uh thanks a lot everyone for joining uh it was a good time maybe a little bit rough today but uh we made it through hopefully this has been useful for you so far if so leave a like or a comment and just let me know what you think about it and until next time uh thanks a lot for watching and happy hacking [Music] you
Info
Channel: System Crafters
Views: 20,494
Rating: 4.9858155 out of 5
Keywords: emacs, configuration, vanilla emacs, ivy, exwm, magit, org-mode, org, doom emacs, spacemacs, vim, evil
Id: xaZMwNELaJY
Channel Id: undefined
Length: 59min 26sec (3566 seconds)
Published: Fri Sep 18 2020
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.