<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Shane Kennedy</title>
    <description>The latest articles on DEV Community by Shane Kennedy (@shaneikennedy).</description>
    <link>https://dev.to/shaneikennedy</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F811668%2F6b7cc751-990f-4fed-accf-50ef065202d2.jpeg</url>
      <title>DEV Community: Shane Kennedy</title>
      <link>https://dev.to/shaneikennedy</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/shaneikennedy"/>
    <language>en</language>
    <item>
      <title>First 10 things to do at your new job as a junior dev</title>
      <dc:creator>Shane Kennedy</dc:creator>
      <pubDate>Thu, 28 Apr 2022 11:42:02 +0000</pubDate>
      <link>https://dev.to/shaneikennedy/first-10-things-to-do-at-your-new-job-as-a-junior-dev-mmm</link>
      <guid>https://dev.to/shaneikennedy/first-10-things-to-do-at-your-new-job-as-a-junior-dev-mmm</guid>
      <description>&lt;p&gt;This is a repost from &lt;a href="https://shaneikennedy.xyz/blog" rel="noopener noreferrer"&gt;my personal website&lt;/a&gt;, head over there to see more tutorials, tips and tricks I wish I had when starting out.&lt;/p&gt;

&lt;p&gt;When starting a new job (from junior to senior) here are the first 10 things I like to do related to the code/project you're going to be working on.&lt;/p&gt;

&lt;p&gt;There are a bunch of things you can do outside of the context of code, like starting to build your network at the company, setting yourself up for productive 1:1s with your manager and getting to know your team better that I won't cover in this post, but are all equally important, so don't forget these!&lt;/p&gt;

&lt;p&gt;I'm also going to skip the "get your dev machine setup" suggestion (at least the most basic configuration of it). I assume this is a given if you're a developer: download your editor/IDE of choice, a terminal app if you want one, and any CLI tools that make you more productive in your normal workflows. If you need any suggestions, checkout &lt;a href="https://juniordeveloperdiaries.com/command-line-upgrade" rel="noopener noreferrer"&gt;Upgrade your command line&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;I'm also going to assume you have an "onboarding buddy", someone who's responsible for making sure you're getting up to speed and someone you can ask a shameful amout of questions to (there's no shame in this, actually, but 3 jobs later and I still feel like I'm being annoying when I ask too many questions, even if I tell people that I onboard not to feel this way towards me). If you don't have an onboarding buddy assigned to you when you start, talk to your manager and &lt;em&gt;get one&lt;/em&gt;; I promise you nothing will make your first 6 weeks at a company better than a good onboarding buddy.&lt;/p&gt;

&lt;p&gt;In any of the following points you find yourself asking "how do I find this out?", ask your onboarding buddy. This is what they are there for.&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Get a list of repositories you're going to need
&lt;/h3&gt;

&lt;p&gt;Typically when you join a team you're responsible for a certain service, or area of the code/platform/product, so find out where your code lives and any dependecies it has to other repositories in your organization, and clone them to your local machine. When you finally start working in the code you're going to want to jump around alot trying to figure out how this code all works, and having everything in place will save you a bunch of time.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Each of these projects probably also have a very basic README.md to get each of them running, be sure to go through these as well.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  2. Run the product/platform/service locally
&lt;/h3&gt;

&lt;p&gt;This may sound obvious, but you would be surprised how many times I hear that people don't run their service locally, and that they rely on tests to verify their changes. While this might work in some cases, there's nothing that gives your more confidence that your changes work than to use the product/platform/service the way your users will. Maybe you won't always need to run your service locally, but someday you will and you don't want to be 6 months in to a job not knowing how to do this, because now you can't ask your onboarding buddy (of course you can, just not as shamelessly as you could 6 months ago).&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Run the test suite
&lt;/h3&gt;

&lt;p&gt;When you first jump into the code it's going to seem like a lot (because it normally is), and you're not going to be able to grasp it all at once. One thing that helps me onboard quickly is to find a module/package/class/function that I'm interested in, and find its test suite. Tests should be dumb and easy to understand: what's being tested, what the test conditions are and what the expectations of the test are. Tests are great for learning the codebase&lt;/p&gt;

&lt;p&gt;Additionally, when you finally start coding, you're still not going to have in-depth knowledge of the codebase, product or platform, so tests are really all you have to make sure you're not breaking anything, so make sure you can run your tests locally!&lt;/p&gt;

&lt;h3&gt;
  
  
  4. Ask your team what tools they like to use
&lt;/h3&gt;

&lt;p&gt;This is an easy but often overlooked tip: this will show you who likes similar tools to you and show you some new ones. Ask for any command line aliases or functions, too!&lt;/p&gt;

&lt;h3&gt;
  
  
  5. Find the "Getting started" guide for your team
&lt;/h3&gt;

&lt;p&gt;This might exist as the project's README.md file, in a Confluence page, or any number of places really. If there isn't one already, consider taking notes on your onboarding experience: where to start, what wasn't completely clear, and what made no sense at all. Once you've onboarded, summarize this in a document and start your team's "Getting started" guide.&lt;/p&gt;

&lt;h3&gt;
  
  
  6. Check out your project's CI/CD
&lt;/h3&gt;

&lt;p&gt;When it's finally time to open your first PR it will hopefully have to go through a bunch of automatic checks: tests, linting, etc. Figure out what these steps are and make sure you can setup some local tooling to avoid having to re-push little fixes like styling and commit message format.&lt;/p&gt;

&lt;h3&gt;
  
  
  7. Ask if there are any git conventions within the team or organization
&lt;/h3&gt;

&lt;p&gt;Some of these conventions might be enforce in CI checks while others might just be agreed upon within the team as "best practices". Either way, find out what they are and learn to incorporate them into your workflow.&lt;/p&gt;

&lt;h3&gt;
  
  
  8. Note down some quick wins that you can get for yourself
&lt;/h3&gt;

&lt;p&gt;One of the best parts of being new is that you're a pair of fresh eyes: you see problems that others don't want to, don't care to, or just don't see at all. Take note of where you can immdeiately start to add value, no matter how small. This not only adds value to the team, but demonstrates good initiative and some excitement from your side, both excellent qualities for your manager and peers to see.&lt;/p&gt;

&lt;h3&gt;
  
  
  9. Understand the deploy process
&lt;/h3&gt;

&lt;p&gt;You just merged your first change into master/main.... what now???? Figure out if you have any staging environments, how often changes are pushed to production, and how/when you can verify them.&lt;/p&gt;

&lt;h3&gt;
  
  
  10. Observe your system
&lt;/h3&gt;

&lt;p&gt;Find out what your team uses for your product/platform/services observability. Understand the load this system is under, how it's performing and what sort of indicators you can look for &lt;em&gt;when&lt;/em&gt; your system starts to break.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;This has ties to #8 and #9, in my experience the observability is always one of the least maintained parts of the product because its development is often reactive rather than proactive (aka it only gets updated &lt;em&gt;after&lt;/em&gt; something goes wrong, and is &lt;strong&gt;ripe&lt;/strong&gt; with quick wins). It's also where you're going to want to keep an eye on after you merge PRs (certainly after your first) to know if your change is performing under load in production.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Have any other tips? Leave them in the comments below! All feedback welcome :)&lt;/p&gt;

</description>
      <category>beginners</category>
      <category>programming</category>
      <category>productivity</category>
      <category>discuss</category>
    </item>
    <item>
      <title>Upgrade your command line</title>
      <dc:creator>Shane Kennedy</dc:creator>
      <pubDate>Wed, 16 Feb 2022 16:28:59 +0000</pubDate>
      <link>https://dev.to/shaneikennedy/upgrade-your-command-line-57bo</link>
      <guid>https://dev.to/shaneikennedy/upgrade-your-command-line-57bo</guid>
      <description>&lt;p&gt;This is a repost from &lt;a href="https://shaneikennedy.xyz/blog" rel="noopener noreferrer"&gt;my personal website&lt;/a&gt;, head over there to see more tutorials, tips and tricks I wish I had when starting out.&lt;/p&gt;

&lt;h4&gt;
  
  
  Context switching in your workflow (the enemy)
&lt;/h4&gt;

&lt;p&gt;Imagine you're writing a function that depends on a module in another one of your company's repositories; you probably don't have jump-to-definition capabilities here in your editor, which means you need to go find this module manually on your machine (if this sounds awful, it is. Consider this before going all in on multi-repo microservices). If every time you need to do this you need to re-remember/go look up commands, or just need to type a lot of tedious ones, it can take you right out of the context that you're currently focused on: writing code. Being slow at this isn't just annoying for you, it can be mentally draining.&lt;/p&gt;

&lt;h4&gt;
  
  
  The argument against speed - and why it makes no sense
&lt;/h4&gt;

&lt;p&gt;People love to talk about how "speed doesn't matter" because "my editor/workflow isn't and shouldn't be the bottleneck when coding", and they're right. But no one is arguing that speed matters more than thinking about and designing your solution? Speed won't make your code better, but it does help with reducing lengthy context switching, and the general satisfaction of how you work, and this has been very important in my experience. There's nothing wrong with being new at something, but no one likes feeling like they're new.&lt;/p&gt;

&lt;p&gt;Think about anything you've ever been good at: when you started you were probably slow, maybe it felt awkward, and maybe more importantly you might have been around other people who were doing the same thing as you but much, &lt;em&gt;much&lt;/em&gt; faster. Not a great feeling. But as time went by and you got better, you got comfortable, you learned some tricks, and soon enough you were much faster than before. This is just a good feeling to have, regardless of what you're doing.&lt;/p&gt;

&lt;h4&gt;
  
  
  So let's upgrade that workflow
&lt;/h4&gt;

&lt;p&gt;So now you've just started as a junior dev, working 8-10 hours a day and you're feeling slow, awkward and uncomfortable at all the things &lt;em&gt;around&lt;/em&gt; coding; here are some tips, tricks and tools to help you get up to speed so you can focus on your code.&lt;/p&gt;

&lt;h2&gt;
  
  
  Your shell
&lt;/h2&gt;

&lt;p&gt;Not everyone likes to work in the terminal, but if you do it's nice to have a shell that helps you out.&lt;/p&gt;

&lt;h3&gt;
  
  
  Zsh
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://en.wikipedia.org/wiki/Z_shell" rel="noopener noreferrer"&gt;zsh&lt;/a&gt; is an extension of bash with some nice improvements, and is now the default shell on new apple computers. Taking it one step further is &lt;a href="https://ohmyz.sh/" rel="noopener noreferrer"&gt;oh-my-zsh&lt;/a&gt;, a framework for extending zsh with plugins and is what I personally use. This gives me a clean and helpful foundation for my terminal. Some of my favorite plugins are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/ohmyzsh/ohmyzsh/blob/master/themes/refined.zsh-theme" rel="noopener noreferrer"&gt;refined theme&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/zsh-users/zsh-syntax-highlighting" rel="noopener noreferrer"&gt;zsh-syntax-highlighting&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/zsh-users/zsh-autosuggestions" rel="noopener noreferrer"&gt;zsh-autosuggestions&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Fish
&lt;/h3&gt;

&lt;p&gt;The friendly interactive shell or &lt;a href="https://fishshell.com/" rel="noopener noreferrer"&gt;fish&lt;/a&gt; is a really interesting shell that takes a modern approach to shell configuration. Similar to oh-my-zsh there is &lt;a href="https://github.com/oh-my-fish/oh-my-fish" rel="noopener noreferrer"&gt;oh-my-fish&lt;/a&gt; for extending this shell with plugins. The only reason I haven't switched from zsh to fish is crippling laziness.&lt;/p&gt;

&lt;h2&gt;
  
  
  Command line tools
&lt;/h2&gt;

&lt;h3&gt;
  
  
  z
&lt;/h3&gt;

&lt;p&gt;If you work in lots of repositories you want &lt;a href="https://github.com/rupa/z" rel="noopener noreferrer"&gt;z&lt;/a&gt; in your toolbelt. This cli tool keeps a history of directories you visit and makes jumping between folders much easier.&lt;/p&gt;

&lt;h3&gt;
  
  
  rg/ag
&lt;/h3&gt;

&lt;p&gt;These are both improvements on &lt;code&gt;grep&lt;/code&gt;. If you need to search for something in a project like where a certain class is defined, usages of a certain word (when your designer tells you we're no longer calling it by "x", it should now be "y"), these two are life savers. &lt;a href="https://github.com/BurntSushi/ripgrep" rel="noopener noreferrer"&gt;rg&lt;/a&gt; and &lt;a href="https://github.com/ggreer/the_silver_searcher" rel="noopener noreferrer"&gt;ag&lt;/a&gt; can also act as backends for some editor plugins and some other tools in this post.&lt;/p&gt;

&lt;h3&gt;
  
  
  bat
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://github.com/sharkdp/bat" rel="noopener noreferrer"&gt;bat&lt;/a&gt; is a pretty version of cat. Just nice to have some syntax highlighting when you're viewing a files contents in the terminal.&lt;/p&gt;

&lt;h3&gt;
  
  
  lsd
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://github.com/Peltoche/lsd" rel="noopener noreferrer"&gt;lsd&lt;/a&gt; more colors, this is just a nicer &lt;code&gt;ls&lt;/code&gt; command. I have lsd aliased to ls because I have no reason to use ls with lsd installed and I can't be bothered to change my ls muscle memory.&lt;/p&gt;

&lt;h3&gt;
  
  
  fzf
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://github.com/junegunn/fzf" rel="noopener noreferrer"&gt;fzf&lt;/a&gt; is a command line file fuzzy-finder. Super useful if you need to find the location of a file on the command line. You can also fuzzy-find-then-open-in-editor, which is :chefs-kiss:&lt;/p&gt;

&lt;h3&gt;
  
  
  pgcli/mycli
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://www.pgcli.com/" rel="noopener noreferrer"&gt;pgcli&lt;/a&gt; basically taught me sql, along with a very nice co-worker (aside, no book, cli, editor or blog post will help you improve faster than a good mentor). This provides IDE-like syntax completion for sql and is database-aware, i.e based on what database you're connected to it can provide completions for tables when joining. &lt;a href="https://www.pgcli.com/" rel="noopener noreferrer"&gt;pgcli&lt;/a&gt; and &lt;a href="https://www.mycli.net/" rel="noopener noreferrer"&gt;mycli&lt;/a&gt; are the same programs for postgres and mysql, respectively.&lt;/p&gt;

&lt;h2&gt;
  
  
  Your editor
&lt;/h2&gt;

&lt;p&gt;I'm not going to list any editors or tell you which &lt;a href="https://www.gnu.org/software/emacs/" rel="noopener noreferrer"&gt;one&lt;/a&gt; is my favourite. All I'm going to say is that this is where the majority of your work is going to be done, so no matter what you pick, &lt;em&gt;really learn&lt;/em&gt; it. Know how to find files/symbols quickly, get used to the git client (if you like those), learn the refactoring tools where applicable, multiple cursors for quick renaming in a single file, learn how to use &lt;em&gt;macros&lt;/em&gt;. I promise you, time invested in learning your editor pays dividends in time saved in the long run.&lt;/p&gt;

&lt;h2&gt;
  
  
  General advice
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Automate when it makes sense
&lt;/h3&gt;

&lt;p&gt;If you find yourself writing the same command(s) over, and over again, then it's probably worth your time to automate/streamline this.&lt;/p&gt;

&lt;h4&gt;
  
  
  Aliases
&lt;/h4&gt;

&lt;p&gt;There is a general concept in shells that you can alias commands ex: &lt;code&gt;alias ls="lsd"&lt;/code&gt; this means whenever I type ls in my terminal, lsd will actually be executed. But lots of CLIs let you provide aliases specific to that cli. Git is one of those programs and I have the following aliases in my &lt;em&gt;.gitconfig&lt;/em&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;alias&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;
        co &lt;span class="o"&gt;=&lt;/span&gt; checkout
        st &lt;span class="o"&gt;=&lt;/span&gt; status
        lg &lt;span class="o"&gt;=&lt;/span&gt; log &lt;span class="nt"&gt;--graph&lt;/span&gt; &lt;span class="nt"&gt;--pretty&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;format:&lt;span class="s1"&gt;'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)&amp;lt;%an&amp;gt;%Creset'&lt;/span&gt; &lt;span class="nt"&gt;--abbrev-commit&lt;/span&gt; &lt;span class="nt"&gt;--date&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;relative
        lg2 &lt;span class="o"&gt;=&lt;/span&gt; log &lt;span class="nt"&gt;--graph&lt;/span&gt; &lt;span class="nt"&gt;--pretty&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;format:&lt;span class="s1"&gt;'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cd) %C(bold blue)&amp;lt;%an&amp;gt;%Creset'&lt;/span&gt; &lt;span class="nt"&gt;--abbrev-commit&lt;/span&gt; &lt;span class="nt"&gt;--date&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;short
        search &lt;span class="o"&gt;=&lt;/span&gt; log &lt;span class="nt"&gt;-p&lt;/span&gt; &lt;span class="nt"&gt;--all&lt;/span&gt; &lt;span class="nt"&gt;-S&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This allows me to write &lt;code&gt;git st&lt;/code&gt; instead of &lt;code&gt;git status&lt;/code&gt;, which I previously mentioned I write all the time. The two log aliases are because the default log is not intuitive to read and the basic "git log --graph" is too verbose. Lastly, git search is more of a "I can never remember this so I will keep it here". Basically if you know you committed something in the past and it's since been deleted, for example a class that got refactored, you can do &lt;code&gt;git search myclass&lt;/code&gt; and it will find commits where this class was added, modified or deleted.&lt;/p&gt;

&lt;h4&gt;
  
  
  Functions
&lt;/h4&gt;

&lt;p&gt;If you find yourself writing the same multiple commands in succession all the time, you might want to write a bazh, zsh, fish function. I personally don't have any in use at the moment, but it's nice to know about these when you start noticing the pattern of repeating commands in succession.&lt;/p&gt;

&lt;h4&gt;
  
  
  "Dotfile" repositories
&lt;/h4&gt;

&lt;blockquote&gt;
&lt;p&gt;Dotfiles refer to files you keep in your home folder that command line tools typically look for for configuration such as ".gitconfig" ".zshrc" and are aptly-named "dotfiles".&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;In your career and life you're going to have multiple computers through different jobs, ones you buy yourself, and ec2 instances you rent; you don't want to rewrite your config every time. Consider version controlling your configuration files (or dotfiles) and pushing to your favourite git remote so you can access them whenever and wherever.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Interactive rebasing, git god-mode</title>
      <dc:creator>Shane Kennedy</dc:creator>
      <pubDate>Tue, 08 Feb 2022 18:40:37 +0000</pubDate>
      <link>https://dev.to/shaneikennedy/interactive-rebasing-git-god-mode-9hj</link>
      <guid>https://dev.to/shaneikennedy/interactive-rebasing-git-god-mode-9hj</guid>
      <description>&lt;p&gt;This is a repost from &lt;a href="https://shaneikennedy.xyz/blog" rel="noopener noreferrer"&gt;my personal website&lt;/a&gt;, head over there to see more tutorials, tips and tricks I wish I had when starting out.&lt;/p&gt;

&lt;p&gt;Imagine you have this feature branch with 5 commits:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;* 02a7e84ccee - (HEAD -&amp;gt; billing, origin/billing) Fail gracefully if unknown error (8 hours ago) &amp;lt;Commit author&amp;gt;
* 8647daf1a2f -  Add R0801 to pylint ignore list (8 hours ago) &amp;lt;Commit author&amp;gt;
* 1c5d459147a -  Don't use BaseException anywhere (8 hours ago) &amp;lt;Commit author&amp;gt;
* 62de8bb854d -  Send billing events (8 hours ago) &amp;lt;Commit author&amp;gt;
* d783109d594 -  Raise insuffient data exceptions (8 hours ago) &amp;lt;Commit author&amp;gt;
* d8d58d1f055 -  Update event service client with billing logic (8 hours ago) &amp;lt;Commit author&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You've put the work in to reflect incremental units of change, each with their own value, as well authored commits and you open a PR. Overall the PR looks good, but your reviewer found a few issues:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Typo here&lt;/li&gt;
&lt;li&gt;Missing edge case there&lt;/li&gt;
&lt;li&gt;Missing test somewhere else&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;What we could do is create a commit that fixes the typo, handles the edge case and adds a test called "Update with PR feedback", but I'm here to tell you that we can do better than that. A commit that fixes mistakes that were introduced in this PR does not make any sense. In the git history we would just prefer that these mistakes never existed at all. So let me propose a different way:&lt;/p&gt;

&lt;p&gt;Let's add a new commit for each fix we make&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Fix typo&lt;/li&gt;
&lt;li&gt;Handle edge case&lt;/li&gt;
&lt;li&gt;Add test&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These are bad commit messages but you'll see why in a second. Further, let's say we know that the typo happened in  "d8d58d1f055 -  Update event service client with billing logic", the edge case was missed in "d783109d594 -  Raise insuffient data exceptions", and that you missed a test in "62de8bb854d -  Send billing events".&lt;/p&gt;

&lt;p&gt;So now our commit history looks like this :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;* da7f3059367 - (HEAD -&amp;gt; billing) Add test (1 second ago) &amp;lt;Commit author&amp;gt;
* e62d6fd4bab - Handle edge case (38 seconds ago) &amp;lt;Commit author&amp;gt;
* 01507911dfd - Fix typo (2 minutes ago) &amp;lt;Commit author&amp;gt;
* 02a7e84ccee - (origin/billing) Fail gracefully if unknown error (8 hours ago) &amp;lt;Commit author&amp;gt;
* 8647daf1a2f - Add R0801 to pylint ignore list (8 hours ago) &amp;lt;Commit author&amp;gt;
* 1c5d459147a - Don't use BaseException anywhere (8 hours ago) &amp;lt;Commit author&amp;gt;
* 62de8bb854d - Send billing events (8 hours ago) &amp;lt;Commit author&amp;gt;
* d783109d594 - Raise insuffient data exceptions (8 hours ago) &amp;lt;Commit author&amp;gt;
* d8d58d1f055 - Update event service client with billing logic (8 hours ago) &amp;lt;Commit author&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;What we're going to do here is combine, or fixup, these small fixes with the commit where the problem was introduced; this means I'm going to combine  "01507911dfd - Fix typo (2 minutes ago)" with "d8d58d1f055 -  Update event service client with billing logic" and so on.&lt;/p&gt;

&lt;h4&gt;
  
  
  Rebase recap
&lt;/h4&gt;

&lt;p&gt;If you haven't already read my &lt;a href="https://juniordeveloperdiaries.com/git-rebase" rel="noopener noreferrer"&gt;intro to git rebase&lt;/a&gt;, that's a good place to start in order to understand rebasing in general. TL;DR rebasing is to &lt;em&gt;re&lt;/em&gt; apply commits on top of some &lt;em&gt;base&lt;/em&gt;. In my other article we talked about rebasing feature branches on top of the master/main branch, but here we just want to modify the commit history that's unique to our branch (the commit listed above), so in this case, we want our &lt;em&gt;base&lt;/em&gt; to be whatever comes before our earliest commit. Let's learn by doing and rebase this branch -- interactively:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Command: &lt;code&gt;git rebase &amp;lt;options&amp;gt; _base_&lt;/code&gt; where base is what you want to re apply commits on to. In my previous post, we wanted to rebase on top of master/main so we would write &lt;code&gt;git rebase origin/main&lt;/code&gt;. But here we just want to rebase on top of what came before our earliest commit: &lt;code&gt;git rebase &amp;lt;commit-sha&amp;gt;&lt;/code&gt; but this can be a bit tideous to do, so I prefer to use &lt;code&gt;git rebase HEAD~n&lt;/code&gt; where n is the number of commits back to the base commit.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h4&gt;
  
  
  --interactive or -i
&lt;/h4&gt;

&lt;p&gt;I have 9 commits in this branch, which means the base that I want is 10 commits back:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;git rebase -i HEAD~9&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;pick d8d58d1f055 Update event service client with billing logic
pick d783109d594 Raise insuffient data exceptions
pick 62de8bb854d Send billing events
pick 1c5d459147a Don't use BaseException anywhere
pick 8647daf1a2f Add R0801 to pylint ignore list
pick 02a7e84ccee Fail gracefully if unknown error
pick 01507911dfd Fix typo
pick e62d6fd4bab Handle edge case
pick da7f3059367 Add test

#
# Commands:
# p, pick &amp;lt;commit&amp;gt; = use commit
# r, reword &amp;lt;commit&amp;gt; = use commit, but edit the commit message
# e, edit &amp;lt;commit&amp;gt; = use commit, but stop for amending
# s, squash &amp;lt;commit&amp;gt; = use commit, but meld into previous commit
# f, fixup [-C | -c] &amp;lt;commit&amp;gt; = like "squash" but keep only the previous
#                    commit's log message, unless -C is used, in which case
#                    keep only this commit's message; -c is same as -C but
#                    opens the editor
# x, exec &amp;lt;command&amp;gt; = run command (the rest of the line) using shell
# b, break = stop here (continue rebase later with 'git rebase --continue')
# d, drop &amp;lt;commit&amp;gt; = remove commit
# l, label &amp;lt;label&amp;gt; = label current HEAD with a name
# t, reset &amp;lt;label&amp;gt; = reset HEAD to a label
# m, merge [-C &amp;lt;commit&amp;gt; | -c &amp;lt;commit&amp;gt;] &amp;lt;label&amp;gt; [# &amp;lt;oneline&amp;gt;]
# .       create a merge commit using the original merge commit's
# .       message (or the oneline, if no original merge commit was
# .       specified); use -c &amp;lt;commit&amp;gt; to reword the commit message
#
# These lines can be re-ordered; they are executed from top to bottom.
#
# If you remove a line here THAT COMMIT WILL BE LOST.
#
# However, if you remove everything, the rebase will be aborted.
#

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is what you should see in your git commit editor. Let me point out some interesting information:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Next to all of the commits we have the word "pick"&lt;/li&gt;
&lt;li&gt;The command list that includes the various options we have and their explanations&lt;/li&gt;
&lt;li&gt;This is an editable file: we can change whether we "pick" certain commits, we can move commits up or down etc.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Looking at the descriptions for each command:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Pick - "use commit" this means leave it as is&lt;/li&gt;
&lt;li&gt;Reword - don't like the commit message you used?&lt;/li&gt;
&lt;li&gt;Edit - forgot something on this commit?&lt;/li&gt;
&lt;li&gt;Squash - "meld" into previous commit (this is what we want to do)&lt;/li&gt;
&lt;li&gt;Fixup - same as squash, but use the first commit's message (this is also what we want, and what we'll use because I like the commit messages I made initially)&lt;/li&gt;
&lt;li&gt;...&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You get the point, I find these first four to be the most used in my workflow but the other options are worth knowing about.&lt;/p&gt;

&lt;p&gt;Back to our rebase!&lt;/p&gt;

&lt;p&gt;I want to take my small fixup commits, and "meld" them onto the commit where they were introduced:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;pick cc449795730 Update event service client with billing logic
fixup bd8222bd083 Fix typo
pick a96ad17080a  Raise insuffient data exceptions
fixup 9c8776fbe9f Handle edge case
pick 745554d6aa5 Send billing events
fixup 3eef03eb869 Add test
pick a5487033dbb Don't use BaseException anywhere
pick aaebfa866a2 Add R0801 to pylint ignore list
pick ab307ed1550 Fail gracefully if unknown error
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Your rebase file should now look like this after you moved the fixup commits one spot after where the thing they're fixing was introduced, and then changed "pick" to "fixup" because we don't want those little fixup commits in our git history.&lt;/p&gt;

&lt;p&gt;Now save and close the file and run &lt;code&gt;git log --graph&lt;/code&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;--graph is a preference, use normal git log if you want&lt;br&gt;
&lt;/p&gt;
&lt;/blockquote&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;* 9857802cbb1 - (HEAD -&amp;gt; billing) Fail gracefully if unknown error (5 seconds ago) &amp;lt;Commit author&amp;gt;
* 747321db1e0 -  Add R0801 to pylint ignore list (6 seconds ago) &amp;lt;Commit author&amp;gt;
* cbd6a8442b7 -  Don't use BaseException anywhere (6 seconds ago) &amp;lt;Commit author&amp;gt;
* 6f1f0da8a9d -  Send billing events (6 seconds ago) &amp;lt;Commit author&amp;gt;
* 158da739da5 -  Raise insuffient data exceptions (6 seconds ago) &amp;lt;Commit author&amp;gt;
* 4f702d469e3 -  Update event service client with billing logic (6 seconds ago) &amp;lt;Commit author&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And there you go! Those fixup commits are gone, but their changes are in the commits that they were squashed onto (use &lt;code&gt;git show &amp;lt;sha&amp;gt;&lt;/code&gt; to see for yourself).&lt;/p&gt;

&lt;p&gt;Some important things to notice: similar to rebasing on top of master like in my last post, you'll see that all of the commit hashes have changed, even for the commits that weren't changed. Go read that previous post for the explanation why.&lt;/p&gt;

&lt;p&gt;The time stamps were modifed as well: before most of my commits were from 8 hours ago, and now it's saying 6 seconds ago. This is because they're new commits.&lt;/p&gt;

</description>
      <category>git</category>
      <category>tutorial</category>
      <category>beginners</category>
    </item>
    <item>
      <title>Your first taste of emacs</title>
      <dc:creator>Shane Kennedy</dc:creator>
      <pubDate>Tue, 08 Feb 2022 18:22:03 +0000</pubDate>
      <link>https://dev.to/shaneikennedy/your-first-taste-of-emacs-46fo</link>
      <guid>https://dev.to/shaneikennedy/your-first-taste-of-emacs-46fo</guid>
      <description>&lt;p&gt;This is a repost from &lt;a href="https://shaneikennedy.xyz/blog" rel="noopener noreferrer"&gt;my personal website&lt;/a&gt;, head over there to see more tutorials, tips and tricks I wish I had when starting out.&lt;/p&gt;

&lt;h2&gt;
  
  
  Foreword
&lt;/h2&gt;

&lt;p&gt;There are a few reasons why you might be here reading this article&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;You heard emacs is an editor for "Hardcore Devs" on some thread about what editor is best&lt;/li&gt;
&lt;li&gt;You know or work with an emacs user who's pretty good and think it's worth trying out&lt;/li&gt;
&lt;li&gt;You pair programmed with an emacs user who was lightning quick and their answer to "how did you ..." when you inevitably asked was: "emacs"&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;If you're here because of 1. then let me be the first to say that this article probably isn't for you. A developers choice of editor and their skill have no correlation. I know great devs who use emacs, vim, vscode and IntelliJ/jetbrains. The ability to be a good software engineer has nothing to do with your editor.&lt;/p&gt;

&lt;p&gt;In my opinion Emacs is for people who are obsessed with, or atleast firmly interested in, efficiency in their coding. Emacs is a good choice for these types of people because emacs is nearly unuseable out of the box and this forces it's users to customize it &lt;em&gt;completely&lt;/em&gt;. This forceful way of making users create the experience they want is why, in my opinion, you see developers like the one mentioned above in 3.; you are forced to &lt;em&gt;really learn&lt;/em&gt; your editor, so when you find some sort of inefficiency while programming, you know how to set a keybinding, write a custom function, create a new tool, of look for an existing tool. And this tutorial is for people who identify like this.&lt;/p&gt;

&lt;p&gt;So with that out of the way, let's get started.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is emacs?
&lt;/h2&gt;

&lt;p&gt;If I had to simplify this as much as possible, I would describe emacs as a lisp interpreter with some added functionality for editing text. What do I mean by emacs being a lisp interpreter? I can open a file, write some (emacs-flavoured) lisp, and immediately evaluate it: &lt;code&gt;(message "Hello world")&lt;/code&gt; -&amp;gt;  &lt;code&gt;M-x eval-buffer&lt;/code&gt; and a "Hello world" message is logged to the *messages* buffer (a temporary file that's created when emacs is started for logging purposes). Emacs being a lisp interpreter is a very simple, yet powerful concept that enables extreme customizability and is why Emacs is one of the oldest editors in the programming world that has stood the test of time and is still used by many devoted fans today.&lt;/p&gt;

&lt;h2&gt;
  
  
  What are my basic requirements for an editor?
&lt;/h2&gt;

&lt;p&gt;When I start hacking on a project, whether I'm starting it from scratch or I'm jumping in to a large complex codebase, I have a few &lt;em&gt;must haves&lt;/em&gt; that are non-negotiable if I'm going to be doing non-trivial work (i.e more that just updating a single file to submit a patch):&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Searching/finding - I need to be able to quickly find files and/or keywords/usages in a project. (All self-respecting editors can do this, but emacs packages help do it on steroids).&lt;/li&gt;
&lt;li&gt;Syntax highlighting and smart completion for languages that I work with. This is the most trivial box that pretty much any editor can tick for me.&lt;/li&gt;
&lt;li&gt;Quickly build and test my project/source files (this is where most other editors fall short for me).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;With all that in mind let's get our first taste of emacs.&lt;/p&gt;

&lt;h2&gt;
  
  
  Emacs terminology and basics for this tutorial (don't skip this!)
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Emacs commands are executed with &lt;code&gt;C-*&lt;/code&gt;, &lt;code&gt;M-*&lt;/code&gt; or &lt;code&gt;C-M-*&lt;/code&gt;, "C" is the control key, and "M" is the &lt;em&gt;meta&lt;/em&gt; key which is not really a key on modern keyboards anymore, but maps to the "option" key on a Mac (later we'll switch this to the "Cmd or Command" key on Mac because I find that easier, but if you don't mind using the option key then skip that step!)&lt;/li&gt;
&lt;li&gt;Frame: what you normally call a "window" for GUI applications, basically it's one running instance of an emacs client. Each frame holds atleast one &lt;em&gt;window&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;Buffer: used to hold the contents of files that are being visited&lt;/li&gt;
&lt;li&gt;Window: the area of screen that displays a buffer&lt;/li&gt;
&lt;li&gt;Cutting and pasting: in emacs this is called killing and yanking, respectively (read more &lt;a href="https://www.gnu.org/software/emacs/manual/html_node/emacs/Yanking.html" rel="noopener noreferrer"&gt;here&lt;/a&gt;), for legacy reasons that aren't important here. To cut or &lt;em&gt;kill&lt;/em&gt; a highlighted area: &lt;code&gt;C-w&lt;/code&gt; and pasting or &lt;em&gt;yanking&lt;/em&gt;: &lt;code&gt;C-y&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;If/when you get stuck in some command and you don't know how to get out of it, spam &lt;code&gt;C-g&lt;/code&gt; (&lt;em&gt;This is probably the most important command in all of emacs&lt;/em&gt;).&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  TL;DR
&lt;/h2&gt;

&lt;p&gt;If you don’t feel like going through this tutorial step by step and just want the code, you can find it at my &lt;a href="https://github.com/shaneikennedy/emacs-light.git" rel="noopener noreferrer"&gt;emacs-light repo&lt;/a&gt;. Follow the README there to get started.&lt;/p&gt;

&lt;h2&gt;
  
  
  Let's start
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;Disclaimer, this is going to be a MacOS walkthrough because most devs work on macs afaik because their company requires it, but if you're on linux 95% of this should be applicable and the other 5% should be easy enough to figure out. If you're on windows you can use the Windows Subsystem for Linux.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;As you may have heard/seen, most people configure their emacs/vim with "dotfiles" that are loaded when you start emacs/vim. We'll get there, but first I'm going to show you why the idea that Emacs being a lisp interpreter is so powerful.&lt;/p&gt;

&lt;p&gt;I'm going to assume you have emacs installed already (if you don't, &lt;a href="https://wikemacs.org/wiki/Installing_Emacs_on_OS_X" rel="noopener noreferrer"&gt;go do that&lt;/a&gt;), so open a terminal in your home directory and run &lt;code&gt;emacs&lt;/code&gt; which should open up a blank, bland window for you with a bunch of intro information (if this has errors open emacs from your Applications folder).&lt;/p&gt;

&lt;p&gt;I'm going to hold your hand through the first few steps because raw emacs has a.... not so modern first-time-user-experience -- to put it lightly.&lt;/p&gt;

&lt;p&gt;Press C-x and then C-f. You should then see the "&lt;em&gt;mini buffer&lt;/em&gt;" at the bottom that's indicating that you are in the home "~/" directory. This key-combination is mapped to &lt;code&gt;find-file&lt;/code&gt;, an emacs function for finding files from your current directory (for us, this is the &lt;em&gt;home&lt;/em&gt; directory "~"). Type .emacs and hit enter. This has just created a new buffer for a file named ".emacs" in your home directory.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fnuxab90h4fyq8nu07x49.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fnuxab90h4fyq8nu07x49.png" title="M-x find-file" alt="find-file" width="613" height="292"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The next thing I want you to do is press M-x and type emacs-lisp-mode and then press enter RET (enter). We've learned two things here:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;M-x is where you find all emacs functions&lt;/li&gt;
&lt;li&gt;The idea of modes - this is a big topic in and of itself, but for now it's important that each language needs a mode so that emacs can understand how to treat it (syntax highlighting, language specific refactoring, code execution etc.)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;What we just did is make emacs think that this is an emacs-lisp (elisp) source file by enabling emacs-lisp-mode. You configure emacs by writing elisp, which it can then interpret and evaluate. What we're going to do is write elisp in this file ".emacs" and evaluate this file step by step so you can see how emacs changes at each step of the way.&lt;/p&gt;

&lt;p&gt;Like I said before, we're about to configure emacs with elisp and so this is a configuration file; but we're not going to write every last bit of functionality from scratch! Like most text-editors/IDEs today, emacs has a package system, and this configuration file will consist primarily of declarations for which packages we want emacs to use.&lt;/p&gt;

&lt;p&gt;Emacs packages are written in elisp and are hosted on various package repositories such as Milky Postmans E-Lisp Package Archive, or, &lt;a href="https://melpa.org/" rel="noopener noreferrer"&gt;MELPA&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Now let's get started!&lt;/p&gt;

&lt;p&gt;By now you should be in a file called ".emacs" and have enabled &lt;code&gt;emacs-lisp-mode&lt;/code&gt;. Lets start by configuring some package repository information:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight common_lisp"&gt;&lt;code&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;require&lt;/span&gt; &lt;span class="ss"&gt;'package&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;;; Nice macro for updating lists in place.&lt;/span&gt;
&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;defmacro&lt;/span&gt; &lt;span class="nv"&gt;append-to-list&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;target&lt;/span&gt; &lt;span class="nv"&gt;suffix&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="s"&gt;"Append SUFFIX to TARGET in place."&lt;/span&gt;
  &lt;span class="o"&gt;`&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;setq&lt;/span&gt; &lt;span class="o"&gt;,&lt;/span&gt;&lt;span class="nv"&gt;target&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;append&lt;/span&gt; &lt;span class="o"&gt;,&lt;/span&gt;&lt;span class="nv"&gt;target&lt;/span&gt; &lt;span class="o"&gt;,&lt;/span&gt;&lt;span class="nv"&gt;suffix&lt;/span&gt;&lt;span class="p"&gt;)))&lt;/span&gt;

&lt;span class="c1"&gt;;; Set up emacs package archives with 'package&lt;/span&gt;
&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;append-to-list&lt;/span&gt; &lt;span class="nv"&gt;package-archives&lt;/span&gt;
                &lt;span class="o"&gt;'&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="s"&gt;"melpa"&lt;/span&gt; &lt;span class="o"&gt;.&lt;/span&gt; &lt;span class="s"&gt;"http://melpa.org/packages/"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;;; Main package archive&lt;/span&gt;
                  &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"melpa-stable"&lt;/span&gt; &lt;span class="o"&gt;.&lt;/span&gt; &lt;span class="s"&gt;"http://stable.melpa.org/packages/"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;;; Some packages might only do stable releases?&lt;/span&gt;
                  &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"org-elpa"&lt;/span&gt; &lt;span class="o"&gt;.&lt;/span&gt; &lt;span class="s"&gt;"https://orgmode.org/elpa/"&lt;/span&gt;&lt;span class="p"&gt;)))&lt;/span&gt; &lt;span class="c1"&gt;;; Org packages, I don't use org but seems like a harmless default&lt;/span&gt;

&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;package-initialize&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;;; Ensure use-package is present. From here on out, all packages are loaded&lt;/span&gt;
&lt;span class="c1"&gt;;; with use-package, a macro for importing and installing packages. Also, refresh the package archive on load so we can pull the latest packages.&lt;/span&gt;
&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;unless&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;package-installed-p&lt;/span&gt; &lt;span class="ss"&gt;'use-package&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;package-refresh-contents&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;package-install&lt;/span&gt; &lt;span class="ss"&gt;'use-package&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;

&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;require&lt;/span&gt; &lt;span class="ss"&gt;'use-package&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;setq&lt;/span&gt;
 &lt;span class="nv"&gt;use-package-always-ensure&lt;/span&gt; &lt;span class="no"&gt;t&lt;/span&gt; &lt;span class="c1"&gt;;; Makes sure to download new packages if they aren't already downloaded&lt;/span&gt;
 &lt;span class="nv"&gt;use-package-verbose&lt;/span&gt; &lt;span class="no"&gt;t&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;;; Package install logging. Packages break, it's nice to know why.&lt;/span&gt;

&lt;span class="c1"&gt;;; Slurp environment variables from the shell.&lt;/span&gt;
&lt;span class="c1"&gt;;; a.k.a. The Most Asked Question On r/emacs&lt;/span&gt;
&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;use-package&lt;/span&gt; &lt;span class="nv"&gt;exec-path-from-shell&lt;/span&gt;
  &lt;span class="ss"&gt;:config&lt;/span&gt;
  &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;exec-path-from-shell-initialize&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Ok all this code so that we now have access to &lt;code&gt;use-package&lt;/code&gt;. From here on out, when we want to install and make a package available to emacs all we need to do is add &lt;code&gt;(use-package package-name)&lt;/code&gt; which will pull the package source files from the repositories we enabled above: melpa, melpa-stable, and org-elpa, install them and load them into emacs.&lt;/p&gt;

&lt;p&gt;Now lets evaluate this code: &lt;code&gt;M-x eval-buffer&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Nothing noticeable changes here because we just configured a package manager, but now lets install a theme from an emacs package, and enable it (because let's face it, the default in emacs is not very pretty).&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight common_lisp"&gt;&lt;code&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;use-package&lt;/span&gt; &lt;span class="nv"&gt;doom-themes&lt;/span&gt;
  &lt;span class="ss"&gt;:init&lt;/span&gt;
  &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;load-theme&lt;/span&gt; &lt;span class="ss"&gt;'doom-one&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Before when we configured the package manager there was a bunch of code and it was all new so it made sense to just go ahead and evaluate the whole buffer. But here we just added these few lines, why re-evaluate the whole thing? Put your cursor anywhere inside the (use-package...) parens, then hit &lt;code&gt;M-x eval-defun&lt;/code&gt; (this function also has a keybinding C-M-x, remmeber this, we're constantly going to be evaluating elisp chunks like this).&lt;/p&gt;

&lt;p&gt;You are probably going to get prompted with a yes/no for trusting this theme now and in the future (after all even themes in emacs are just elisp, so don't evaluate any elisp/themes you don't trust! But we trust the &lt;a href="https://github.com/hlissner/emacs-doom-themes" rel="noopener noreferrer"&gt;doom maintainer&lt;/a&gt;, so go ahead and type yes)&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frszmukpcb2j0q820xifm.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frszmukpcb2j0q820xifm.png" title="doom theme" alt="Doom theme" width="605" height="587"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Tada! You just downloaded an emacs package of themes, and told emacs to load one of them and it works!&lt;/p&gt;

&lt;p&gt;A few more UX importvements&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight common_lisp"&gt;&lt;code&gt;&lt;span class="c1"&gt;;; Any Customize-based settings should live in custom.el, not here.&lt;/span&gt;
&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;setq&lt;/span&gt; &lt;span class="nv"&gt;custom-file&lt;/span&gt; &lt;span class="s"&gt;"~/.emacs.d/custom.el"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;;; Without this emacs will dump generated custom settings in this file. No bueno.&lt;/span&gt;
&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;load&lt;/span&gt; &lt;span class="nv"&gt;custom-file&lt;/span&gt; &lt;span class="ss"&gt;'noerror&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;;;; OS specific config&lt;/span&gt;
&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;defconst&lt;/span&gt; &lt;span class="vg"&gt;*is-a-mac*&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;eq&lt;/span&gt; &lt;span class="nv"&gt;system-type&lt;/span&gt; &lt;span class="ss"&gt;'darwin&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;defconst&lt;/span&gt; &lt;span class="vg"&gt;*is-a-linux*&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;eq&lt;/span&gt; &lt;span class="nv"&gt;system-type&lt;/span&gt; &lt;span class="ss"&gt;'gnu/linux&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;

&lt;span class="c1"&gt;;; Emacs feels like it's developed with linux in mind, here are some mac UX improvments&lt;/span&gt;
&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;when&lt;/span&gt; &lt;span class="vg"&gt;*is-a-mac*&lt;/span&gt;
  &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;setq&lt;/span&gt; &lt;span class="nv"&gt;mac-command-modifier&lt;/span&gt; &lt;span class="ss"&gt;'meta&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;setq&lt;/span&gt; &lt;span class="nv"&gt;mac-option-modifier&lt;/span&gt; &lt;span class="ss"&gt;'none&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;setq&lt;/span&gt; &lt;span class="nv"&gt;default-input-method&lt;/span&gt; &lt;span class="s"&gt;"MacOSX"&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;

&lt;span class="c1"&gt;;; Some linux love, too&lt;/span&gt;
&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;when&lt;/span&gt; &lt;span class="vg"&gt;*is-a-linux*&lt;/span&gt;
  &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;setq&lt;/span&gt; &lt;span class="nv"&gt;x-super-keysym&lt;/span&gt; &lt;span class="ss"&gt;'meta&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;

&lt;span class="c1"&gt;;; Fullscreen by default, as early as possible. This tiny window is not enough&lt;/span&gt;
&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;add-to-list&lt;/span&gt; &lt;span class="ss"&gt;'default-frame-alist&lt;/span&gt; &lt;span class="o"&gt;'&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;fullscreen&lt;/span&gt; &lt;span class="o"&gt;.&lt;/span&gt; &lt;span class="nv"&gt;maximized&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;One more &lt;code&gt;eval&lt;/code&gt; trick: highlight the code you just pasted in and run &lt;code&gt;M-x eval-region&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;From here on out your Meta (M-*) key is now the command key (if you're on a Mac). I find this 100x better than the option key, but feel free to pick and choose from this block.&lt;/p&gt;

&lt;p&gt;One final block of UX improvements that will be much appreciated, I promise.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight common_lisp"&gt;&lt;code&gt;&lt;span class="c1"&gt;;; Make M-x and other mini-buffers sortable, filterable&lt;/span&gt;
&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;use-package&lt;/span&gt; &lt;span class="nv"&gt;ivy&lt;/span&gt;
  &lt;span class="ss"&gt;:init&lt;/span&gt;
  &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;ivy-mode&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;setq&lt;/span&gt; &lt;span class="nv"&gt;ivy-height&lt;/span&gt; &lt;span class="mi"&gt;15&lt;/span&gt;
        &lt;span class="nv"&gt;ivy-use-virtual-buffers&lt;/span&gt; &lt;span class="no"&gt;t&lt;/span&gt;
        &lt;span class="nv"&gt;ivy-use-selectable-prompt&lt;/span&gt; &lt;span class="no"&gt;t&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;

&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;use-package&lt;/span&gt; &lt;span class="nv"&gt;counsel&lt;/span&gt;
  &lt;span class="ss"&gt;:after&lt;/span&gt; &lt;span class="nv"&gt;ivy&lt;/span&gt;
  &lt;span class="ss"&gt;:init&lt;/span&gt;
  &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;counsel-mode&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="ss"&gt;:bind&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:map&lt;/span&gt; &lt;span class="nv"&gt;ivy-minibuffer-map&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Highlight this region and do &lt;code&gt;M-x eval-region&lt;/code&gt; again to let these changes take effect. Now hit M-x again and see that you now can see everything in emacs at your finger tips; from now on you'll be able to search and discover all of the emacs functions that you can interact with through M-x. Let's keep going.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhmmznv3l32oi8o8jc5ef.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhmmznv3l32oi8o8jc5ef.png" title="Meta X" alt="Meta X" width="594" height="225"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Let's start with my first necessity in an editor: "&lt;em&gt;Searching/finding - I need to be able to quickly find files and/or keywords/usages in a project.&lt;/em&gt;"
&lt;/h2&gt;

&lt;p&gt;For this we're going to use a mix of two packages: &lt;a href="https://github.com/bbatsov/projectile" rel="noopener noreferrer"&gt;projectile&lt;/a&gt; and &lt;a href="https://github.com/ericdanan/counsel-projectile" rel="noopener noreferrer"&gt;counsel-projectile&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight common_lisp"&gt;&lt;code&gt;&lt;span class="c1"&gt;;; We need something to manage the various projects we work on&lt;/span&gt;
&lt;span class="c1"&gt;;; and for common functionality like project-wide searching, fuzzy file finding etc.&lt;/span&gt;
&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;use-package&lt;/span&gt; &lt;span class="nv"&gt;projectile&lt;/span&gt;
  &lt;span class="ss"&gt;:init&lt;/span&gt;
  &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;projectile-mode&lt;/span&gt; &lt;span class="no"&gt;t&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;;; Enable this immediately&lt;/span&gt;
  &lt;span class="ss"&gt;:config&lt;/span&gt;
  &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;setq&lt;/span&gt; &lt;span class="nv"&gt;projectile-enable-caching&lt;/span&gt; &lt;span class="no"&gt;t&lt;/span&gt; &lt;span class="c1"&gt;;; Much better performance on large projects&lt;/span&gt;
        &lt;span class="nv"&gt;projectile-completion-system&lt;/span&gt; &lt;span class="ss"&gt;'ivy&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="c1"&gt;;; Ideally the minibuffer should aways look similar&lt;/span&gt;

&lt;span class="c1"&gt;;; Counsel and projectile should work together.&lt;/span&gt;
&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;use-package&lt;/span&gt; &lt;span class="nv"&gt;counsel-projectile&lt;/span&gt;
  &lt;span class="ss"&gt;:init&lt;/span&gt;
  &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;counsel-projectile-mode&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Highlight the region, M-x eval-region and now if you check M-x projectile- you should have a bunch of possible commands for registering projects, switching to them, finding files and searching files.&lt;/p&gt;

&lt;p&gt;Let's try an example &lt;code&gt;M-! git clone https://github.com/codemirror/CodeMirror.git ~/code-mirror&lt;/code&gt;(Notice when you type M-! the mini buffer pops up with a shell command prompt? This is great for running quick commands). CodeMirror isn't tiny, this might take a few seconds...&lt;/p&gt;

&lt;p&gt;Now lets register CodeMirror as a project &lt;code&gt;M-x projectile-add-known-project&lt;/code&gt; and then find the path where you just cloned the repo to (~/code-mirror if you followed the above directly).&lt;/p&gt;

&lt;p&gt;Now lets open the project &lt;code&gt;M-x projectile-switch-project&lt;/code&gt; (Maybe open a new buffer in emacs first so you don't lose your config file, we're going to work in this project for a little bit &lt;code&gt;C-x 3&lt;/code&gt; to open a window to the right). code-mirror should be the only project registered, so choose that and then you should be shown a list of files in the project that you can open; lets choose src/modes.js.&lt;/p&gt;

&lt;p&gt;Projectile rapid fire:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;em&gt;How can I register another project?&lt;/em&gt; &lt;code&gt;M-x projectile-add-known-project&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;How can I switch to another project?&lt;/em&gt; &lt;code&gt;M-x projectile-switch-project&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;How can I search for other files in this project?&lt;/em&gt; &lt;code&gt;M-x projectile-find-file&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;How can I do find-and-replace in this project?&lt;/em&gt; &lt;code&gt;M-x projectile-replace&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;How can I search for strings/words in this project?&lt;/em&gt; &lt;code&gt;M-x projectile-grep&lt;/code&gt; or &lt;code&gt;M-x projectile-ag&lt;/code&gt; or &lt;code&gt;M-x projectile-rg&lt;/code&gt; (I recommend &lt;a href="https://github.com/BurntSushi/ripgrep" rel="noopener noreferrer"&gt;rg&lt;/a&gt; but it's seperate from emacs so you'll need to install it. If you don't want to bother with that, use projectile-grep, but grep is noticeably slow on larger projects).&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;This will open a buffer with a list of occurences which is nice, but counsel-grep/ag/rg will show you results in the minibuffer so that you can quickly see your search results without opening another window. It's excellent, I don't know of any other editor that has this.&lt;/p&gt;

&lt;p&gt;Bonus: Another gem in emacs comes from the ivy package we installed earlier for searching within a file &lt;code&gt;M-x swiper&lt;/code&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  On to my second necessity in an editor "&lt;em&gt;Syntax highlighting and smart completion for languages that I work with.&lt;/em&gt;"
&lt;/h2&gt;

&lt;p&gt;Emacs comes with a bunch of built-in language modes for popular languages such as python, js etc. but let's configure completion capabilities.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight common_lisp"&gt;&lt;code&gt;&lt;span class="c1"&gt;;; Company is the best Emacs completion system.&lt;/span&gt;
&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;use-package&lt;/span&gt; &lt;span class="nv"&gt;company&lt;/span&gt;
  &lt;span class="ss"&gt;:bind&lt;/span&gt; &lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="s"&gt;"C-."&lt;/span&gt; &lt;span class="o"&gt;.&lt;/span&gt; &lt;span class="nv"&gt;company-complete&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
  &lt;span class="ss"&gt;:custom&lt;/span&gt;
  &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;company-idle-delay&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;;; I always want completion, give it to me asap&lt;/span&gt;
  &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;company-dabbrev-downcase&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt; &lt;span class="s"&gt;"Don't downcase returned candidates."&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;company-show-numbers&lt;/span&gt; &lt;span class="no"&gt;t&lt;/span&gt; &lt;span class="s"&gt;"Numbers are helpful."&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;company-tooltip-limit&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt; &lt;span class="s"&gt;"The more the merrier."&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="ss"&gt;:config&lt;/span&gt;
  &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;global-company-mode&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;;; We want completion everywhere&lt;/span&gt;

  &lt;span class="c1"&gt;;; use numbers 0-9 to select company completion candidates&lt;/span&gt;
  &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nb"&gt;map&lt;/span&gt; &lt;span class="nv"&gt;company-active-map&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
    &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;mapc&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;lambda&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;x&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;define-key&lt;/span&gt; &lt;span class="nb"&gt;map&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;format&lt;/span&gt; &lt;span class="s"&gt;"%d"&lt;/span&gt; &lt;span class="nv"&gt;x&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                        &lt;span class="o"&gt;`&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;lambda&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;interactive&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;company-complete-number&lt;/span&gt; &lt;span class="o"&gt;,&lt;/span&gt;&lt;span class="nv"&gt;x&lt;/span&gt;&lt;span class="p"&gt;))))&lt;/span&gt;
          &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;number-sequence&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="mi"&gt;9&lt;/span&gt;&lt;span class="p"&gt;))))&lt;/span&gt;

&lt;span class="c1"&gt;;; Flycheck is the newer version of flymake and is needed to make lsp-mode not freak out.&lt;/span&gt;
&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;use-package&lt;/span&gt; &lt;span class="nv"&gt;flycheck&lt;/span&gt;
  &lt;span class="ss"&gt;:config&lt;/span&gt;
  &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;add-hook&lt;/span&gt; &lt;span class="ss"&gt;'prog-mode-hook&lt;/span&gt; &lt;span class="ss"&gt;'flycheck-mode&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;;; always lint my code&lt;/span&gt;
  &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;add-hook&lt;/span&gt; &lt;span class="ss"&gt;'after-init-hook&lt;/span&gt; &lt;span class="nf"&gt;#'&lt;/span&gt;&lt;span class="nv"&gt;global-flycheck-mode&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;

&lt;span class="c1"&gt;;; Package for interacting with language servers&lt;/span&gt;
&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;use-package&lt;/span&gt; &lt;span class="nv"&gt;lsp-mode&lt;/span&gt;
  &lt;span class="ss"&gt;:commands&lt;/span&gt; &lt;span class="nv"&gt;lsp&lt;/span&gt;
  &lt;span class="ss"&gt;:config&lt;/span&gt;
  &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;setq&lt;/span&gt; &lt;span class="nv"&gt;lsp-prefer-flymake&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt; &lt;span class="c1"&gt;;; Flymake is outdated&lt;/span&gt;
        &lt;span class="nv"&gt;lsp-headerline-breadcrumb-mode&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="c1"&gt;;; I don't like the symbols on the header a-la-vscode, remove this if you like them.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Highlight, &lt;code&gt;M-x eval-region&lt;/code&gt;, and try typing "(use-" in your current file and see the completion dropdown (if you're not seeing it, try C-. you won't have to do this every time, but sometimes I notice it doesn't initialize properly). This completion is the company package at work.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjen4p0oadr2x0e47wpgz.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjen4p0oadr2x0e47wpgz.png" title="Completion" alt="Completion" width="242" height="180"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now for an example, lets make use of the CodeMirror repo that we cloned earlier. Open up src/modes.js in CodeMirror and Run &lt;code&gt;M-x lsp&lt;/code&gt;. This will prompt you to choose a language server, choose ts-ls and it will begin downloading it for you. Once it's done, it will ask you where the project root is (~/code-mirror).&lt;/p&gt;

&lt;p&gt;To make sure the language server is working, move your cursor to line 1 in modes.js on to &lt;code&gt;copyObj&lt;/code&gt; and then &lt;code&gt;M-x lsp-go-to-implementation&lt;/code&gt; and you should jump to a file called "misc.js" where the function is defined. Great, so lsp is analyzing the codebase which means we have some &lt;em&gt;smart&lt;/em&gt; completion.&lt;/p&gt;

&lt;h2&gt;
  
  
  And now for my final essential in an editor: &lt;em&gt;Quickly build and test my project/source files&lt;/em&gt;
&lt;/h2&gt;

&lt;p&gt;As I mentioned above this is where most editors tend to fall short for me; the reason being that it can be hard to just test one function at a time, it runs in some special test window which makes it &lt;em&gt;different&lt;/em&gt; to go debug, or it's just not fast enough to go from writing/modifying a test to executing it.&lt;/p&gt;

&lt;p&gt;Since we're working on a javascript project, we're going to install a package called &lt;a href="https://github.com/shaneikennedy/npm.el" rel="noopener noreferrer"&gt;npm.el&lt;/a&gt; which will provide some handy functions for quickly running npm commands.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight common_lisp"&gt;&lt;code&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;use-package&lt;/span&gt; &lt;span class="nv"&gt;npm&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Put the cursor inside the parens and &lt;code&gt;C-M-x&lt;/code&gt; to evaluate that function.&lt;/p&gt;

&lt;p&gt;Now back to the code mirror (reopen misc.js, or any file in the project if you don't still have that open) and run &lt;code&gt;M-x npm&lt;/code&gt; and you'll see a menu pop-up on the bottom with a few possible npm options. We're going to start with npm install, choose "i" and when it asks for a package name leave it blank to simply run npm install to install everything in package.json. When that finished lets try "run", &lt;code&gt;M-x npm&lt;/code&gt; and press "r" and you should get a list of options to choose from, choose one and hit Enter. You should see a new buffer open that's running the command you chose. This is called a compilation buffer and it's very useful when you are repeatedly running a certain command, like when using TDD or refactoring a module and frequently need to re-run tests. To re-run the command that you chose earlier, you don't need to go through the entire &lt;code&gt;M-x npm&lt;/code&gt; flow again, you just need to switch to that buffer and hit "g"; this is a special command in "compilation-mode" which means "recompile".&lt;/p&gt;

&lt;p&gt;And there you have it, lightning speed building and testing in javascript projects. But this type of flow isn't limited to javascript; there are packages for all sorts of languages, build tools and other technologies you're working on; just checkout &lt;a href="https://melpa.org" rel="noopener noreferrer"&gt;MELPA&lt;/a&gt;. And as a last resort, you can always &lt;code&gt;M-x compile&lt;/code&gt; and write out the command you want manually to get a compilation buffer that you can &lt;code&gt;M-x recompile&lt;/code&gt; as you need.&lt;/p&gt;

&lt;p&gt;To save this file so that emacs starts with this configuration the next time you open it hit &lt;code&gt;C-x s&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;This is the bare minimum emacs configuration for what my basic needs in an editor are, but the emacs world is vast and exciting to explore. Follow some emacs-ers on github, checkout youtube, and read blog posts to see all kinds of interesting things you can do with emacs.&lt;/p&gt;

&lt;h2&gt;
  
  
  Appendix
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Commands and keybindings
&lt;/h3&gt;

&lt;p&gt;These are some of my most used commands, some of them are built in to emacs and others come from the packages installed in this tutorial. If they have a default keybinding then I've listed it below but if not I've left it as N/A&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Command&lt;/th&gt;
&lt;th&gt;Keybinding&lt;/th&gt;
&lt;th&gt;Description&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;swiper&lt;/td&gt;
&lt;td&gt;N/A&lt;/td&gt;
&lt;td&gt;Search within the current buffer for a string/regex and results are dislplayed in the minibuffer&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;counsel-rg&lt;/td&gt;
&lt;td&gt;N/A&lt;/td&gt;
&lt;td&gt;Search the entire current project for a string/regex using ripgrep and results are displayed in the minibuffer&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;projectfile-find-file&lt;/td&gt;
&lt;td&gt;N/A&lt;/td&gt;
&lt;td&gt;Search your current project for a filename&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;ivy-switch-buffer&lt;/td&gt;
&lt;td&gt;&lt;code&gt;C-x b&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Switch to another previously opened buffer&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;delete-window&lt;/td&gt;
&lt;td&gt;&lt;code&gt;C-x 0&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Delete the current window&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;delete-other-windows&lt;/td&gt;
&lt;td&gt;&lt;code&gt;C-x 1&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;When you have a bunch of windows this bufferes open at once and need to just delete them all except the one you're working on&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;split-window-right&lt;/td&gt;
&lt;td&gt;&lt;code&gt;C-x 3&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Open a new window to the right&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;save-buffer&lt;/td&gt;
&lt;td&gt;&lt;code&gt;C-x s&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Save the contents of the buffer you're working on&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;comment-line&lt;/td&gt;
&lt;td&gt;&lt;code&gt;C-x C-;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Comment out the current line&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;kill-region&lt;/td&gt;
&lt;td&gt;&lt;code&gt;C-w&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Copy highlighted text&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;yank&lt;/td&gt;
&lt;td&gt;&lt;code&gt;C-y&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Paste from clipboard&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  Package recommendations
&lt;/h3&gt;

&lt;p&gt;A great package for learning emacs is &lt;a href="https://github.com/justbur/emacs-which-key" rel="noopener noreferrer"&gt;which-key&lt;/a&gt;. This package makes a minibuffer popup with a key map based on the last key you just pressed (i.e if there are any). Add &lt;code&gt;(use-package which-key :config (which-key-mode t))&lt;/code&gt; to your config and try pressing &lt;code&gt;C-x&lt;/code&gt; to see what options you have from there.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://magit.vc/" rel="noopener noreferrer"&gt;Magit&lt;/a&gt; is the best git client you can get. All other git clients should aspire to be how great Magit is. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/dgutov/diff-hl" rel="noopener noreferrer"&gt;diff-hl&lt;/a&gt; Git diff markers in modified buffers. Nice to see which lines you've added, changed and deleted, visually.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/Fuco1/smartparens" rel="noopener noreferrer"&gt;smart-parens&lt;/a&gt; bracket/parens matching is nice&lt;/p&gt;

&lt;h3&gt;
  
  
  Doom emacs and Spacemacs
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://github.com/hlissner/doom-emacs" rel="noopener noreferrer"&gt;Doom emacs&lt;/a&gt; and &lt;a href="https://www.spacemacs.org/" rel="noopener noreferrer"&gt;Spacemacs&lt;/a&gt; are "emacs distributions": when installed you get an entirely pre-configured emacs with all of the nice bells and whistles already there for you. I personally started with spacemacs and then moved to my own emacs config later. One massive caveat for spacemacs is that it is highly intergrated with the "evil" package, which means it uses vim keybindings. While you can disable "evil-mode", the configuration will be greatly hindered without it.&lt;/p&gt;

</description>
      <category>emacs</category>
      <category>beginners</category>
      <category>productivity</category>
      <category>tutorial</category>
    </item>
  </channel>
</rss>
