The Digital Cat - toolshttps://www.thedigitalcatonline.com/2021-08-22T09:00:00+00:00Adventures of a curious cat in the land of programmingStop using tools as if they were solutions2021-05-25T09:00:00+01:002021-08-22T09:00:00+00:00Leonardo Giordanitag:www.thedigitalcatonline.com,2021-05-25:/blog/2021/05/25/stop-using-tools-as-if-they-were-solutions/<p><em>"I will write a class"</em>.</p><p>I can't tell you how many times I have heard this sentence from candidates during coding interviews.</p><p>What's wrong with this sentence? Nothing, out of context, but let me add this little detail: this is usually the first sentence I hear when the candidate tries to tackle a problem.</p><p>I know that coding interviews can be very stressful and I also think that leading such interviews requires a lot of effort to avoid transforming them into nitpicking sessions in which the candidate feels every single keystroke is scrutinised and analysed. As if the destiny of the whole company depended on how fast you can code a function that reverses a string!</p><p>But even taking into account interview anxiety, I think such an approach reveals something wrong deeper in the way we approach problems as programmers. This is the result of a culture that mistakes tools for solutions, and if I can detect it in senior programmers it means it already propagated into our teams and our companies.</p><h2 id="the-problem-solving-challenge-f589">The problem-solving challenge<a class="headerlink" href="#the-problem-solving-challenge-f589" title="Permanent link">¶</a></h2><p>When you face a problem (<em>any</em> problem) you need to devise a strategy to solve it. You need to have an idea of what to do before doing it, otherwise you are reacting and not acting.</p><p>When you practice any type of combat sport you train your body to react to specific inputs (attacks) with automatic reactions (defences, counterattacks), but you usually do it because in a real fight you don't have the time to make a conscious decision. Such "perfect" reactions, though, are the result of a constant and very focused effort to transform consciously selected actions into involuntary ones. Without training, a pure reaction is usually an average response at best.</p><p>In problem-solving we face the same challenge. Either we devise a strategy, or our approach will be clumsy and ultimately not efficient.</p><p>Imagine you were tasked to build a bridge between two sides of a river. Would your first concern be the specific type of hammers that the workers should use? After all, you can have ball-peen hammers, sledgehammers, brick hammers, and many other types. Choosing the wrong one might severely affect the performances of your workers.</p><p>That's hardly the first thing you should ask yourself. I'm pretty sure you agree that knowing the distance that the bridge should cover is much more urgent. Also, the type and the amount of traffic that it has to carry (walkers, cars, trucks, trains) is an important factor, and you should be concerned about the budget that you are allowed.</p><p>Why are these questions more important than the one about hammers? Because the answers to these questions can heavily influence the whole project. They are pillars of your architecture and not details<sup>[<a id="fr-d8d83501-1" href="#">1</a>]</sup>. My colleague Ken Pemberton always reminds me that most of the time we don't ask ourselves an even more important question: "What problem are you trying to solve?". In the example above, a bridge might not be the best solution in the first place.</p><p>I think the process, at least when it comes to software projects, can be divided into three connected phases: decomposition, communication, implementation.</p><h3 id="decomposition-a9dc">Decomposition</h3><p>Macroscopically, a <em>processing system</em> is made of an initial state, some transformations or intermediate states, and a final state.</p><p>Usually, it's simple to identify the initial and final state, while it's harder to describe what happens between the two. So, we need to proceed iteratively, describing the system using black boxes, and then opening each one of them, zooming in to describe what happens inside.</p><p>At any zoom level, from the 10,000 feet overview down to the description of a single function, you need to identify 4 things: the <strong>input</strong>, the <strong>output</strong>, the <strong>actors</strong> and the <strong>data flow</strong>.</p><p>The input is what enters the black box. It has usually been decided at a higher level of zoom or while discussing a component that provides it as output. So, it is given, and if it turns out to be inadequate we should take a step back in the design and question how we can provide proper input. The same is valid for the output.</p><p>The actors must be black boxes that accept data and transform it, and the data flow is how information is exchanged between the actors. This is clearly where it can take a long time to find a good solution, and we might need to go back and forth several times.</p><p>Let's look at an example. A search engine is a complicated piece of software, and implementing it is not a matter of 1 hour of work. But we can decompose it pretty easily, starting from the fact that the input of the system is a query, and that the output is an ordered set of results. So, my overview of this component is the following: the user inputs a query, the query is processed and the system returns a list of results, ordered by quality.</p><p>I didn't describe what "quality" is, nor discussed the specific implementation of the system that stores all possible results. Those details are buried down somewhere at a certain level of zoom and are utterly useless at this level.</p><h3 id="communication-1fc1">Communication</h3><p>Any level of zoom in the decomposition can be described, and the amount of specific technical knowledge needed to understand the explanation should be directly proportional to the zoom level. You might have heard the quote "You do not really understand something unless you can explain it to your grandmother." I believe this might be very offensive to grandmothers, but paraphrasing it, I would say that "There should be a zoom level at which the project is understandable by anyone who doesn't have a specific knowledge of the field".</p><p>Indeed, the problem of technical communication is that tech-savvy gurus are usually not able to decompose what they are working on into black boxes that are sufficiently abstract to be understandable by any human being. Please note this can happen to anyone, not only to programmers. I had to listen enough times to people working in banking, insurances, or project management (just to name a few different fields) to know that they can be unable to describe their job or specific aspects of it without using 4 obscure words every 5 words, the fifth one probably being a conjunction.</p><p>Being a blogger and an author I want to add a consideration about communication. Explaining things is the best way to see if everything is clear in your mind, which is another way to read the previous quote (without involving grandmothers). The very same post that you are reading started as an intuition, a small list of ideas, and so far has been rewritten 6 times. In the process, I understood the topics I am discussing much better than I did when I first felt the need to write them down.</p><h3 id="implementation-ef77">Implementation</h3><p>Professor Sidney Morris, in a <a href="https://www.youtube.com/watch?v=T1snRQEQuEk">very interesting video</a> about how to write proofs in mathematics, describes the process with these words:</p><div class="excerpt"><div class="content"><ul><li>Step 1: write down what we are given</li><li>Step 2: write down the definition of each technical term in what we are given</li><li>Step 3: write down what we are required to prove</li><li>Step 4: write down the definition of each technical term in what we are required to prove</li></ul>
<p>So these 4 steps are quite easy, quite straightforward.</p>
<p>The next step is not as easy</p>
<ul><li>Step 5: THINK!</li></ul></div></div><p>While we don't need to aim to the same level of formality required to mathematicians who prove theorems, we can surely keep the spirit of the process: write down and define what you have, write down and define what you want to achieve. Then, think.</p><p>We tend to take for granted that we can think, after all we do it all day long. But focusing our attention on a specific topic, giving it time, exploring it, considering questions about it, evaluating possible answers, all these things are increasingly unpopular. This is not the place for a critique of our society full of noise, where ideas, products, and works of art are watched for mere seconds before getting a like and passing into oblivion. But it is worth noting that thinking is <em>not</em> easy.</p><p>The implementation of a black box might require a lot of thinking, and we have to accept this. It might require a lot of rewrites, prove unsuccessful only after a certain amount of time, or even require a separate project to be properly managed. There are no shortcuts here.</p><h2 id="the-coding-interview-problem-9b56">The coding interview problem<a class="headerlink" href="#the-coding-interview-problem-9b56" title="Permanent link">¶</a></h2><p>What do we do during a coding interview? What are we trying to understand with this excruciating exercise that puts people in a pillory for one hour? </p><p>What we should do, in my opinion, is to <em>help the candidate to show how they solve problems</em>. We should facilitate a discussion along the lines of the three points that I mentioned: decomposition, communication, implementation. As you can see implementation is not avoided, it's a coding interview because there should be a part of it in which we write code, but it should be done only after we established a decomposition of the system.</p><p>I also believe that the assignment should be purposefully too complex to implement in a single one-hour session, and this should be explicitly communicated. This forces the candidate to design instead of rushing headlong into implementing the first requirement of the exercise without reading the rest. At any point, if the candidate is unable to implement a specific step, we can also move on to other steps and fake the input. This way we get many benefits:</p><ol><li>The candidate won't feel stressed by the need of showing how good they are at coding. The design part is a friendly chat, where suggestions can be made and specific technologies/solutions might be discarded if not known to the candidate.</li><li>They won't perceive the interview as a failure because they couldn't implement a single step or because they didn't complete the assignment in time.</li><li>We can explore the way the candidate communicates, the way they decompose complex processes, how well they understand problems and, eventually, how they write code.</li><li>We can adjust the level of difficulty of the interview or explore specific topics in detail just asking the candidate to focus on a specific detail.</li></ol><p>As an interviewer, I value the decomposition phase much more than the part in which you show me how well you remember all the functions of the Python standard library in a stressful situation. The truth is that I look them up very often and I don't look down on people because they don't remember the name of a method. I have one hour to decide if you are a good addition to the company, if you can be a good teammate for my next project, and if (possibly with some training) you can be given the responsibility for part of the system. In that hour I need to capture the main traits of your approach.</p><p>Don't get me wrong, I am a terrible nitpicker and probably on the brink of being OCD about some things, such as naming or tidiness of the code. But I try to take my own advice. What is the most important thing about you that I can understand? I think it would be extremely disappointing to discover that I hired someone who knows the standard library by heart but can't pick the right technology to complete a project before the deadline.</p><p>I understand that when you are interviewed you feel like you are in a position of weakness and that you are sitting there at the mercy of an evil interviewer whose purpose is only to uncover what you don't know. I'm sorry if you had to face such interviewers. I had to, and I understand the frustration. My advice is: always remember that working for a company is a matter of giving your time and your energy in exchange for personal growth. You might be interviewing for your dream job, but if the interviewer is not interested in you and your growth it's probably not that useful for you to work with them.</p><p>So, as a candidate, you have a responsibility to show the interviewer how you can solve problems. If you show how good you are at coding, you will impress only interviewers that are interested in your coding skills, and this is, in my opinion, a very limited part of what you can do as a programmer. You need to show that you can design, and this is independent of the level you are at.</p><p>You need to show that you understand problems, that you can compare solutions, that you can take your risks picking one specific strategy and that if needed you can stop at a certain point and say "This is the wrong approach".</p><h2 id="patterns-e366">Patterns<a class="headerlink" href="#patterns-e366" title="Permanent link">¶</a></h2><p>Design patterns are defined by Erich Gamma and his co-authors in their seminal book<sup>[<a id="fr-f70c86c9-2" href="#">2</a>]</sup> with these words: "[...] patterns solve specific design problems and make object-oriented designs more flexible, elegant, and ultimately reusable. [...] A designer who is familiar with such patterns can apply them immediately to design problems without having to rediscover them."</p><p>I want to focus on the words "solve specific design problems" because what I notice is that many people apply patterns without having understood the problem they are trying to solve. Even worse, they look at the world through the lens of the patterns they know, twisting the nature of problems to fit the solution they know.</p><p>Back to the original sentence. "I will write a class" is considered the go-to solution in OOP languages. What we believe is that, in an OOP language, whatever the problem, the solution is to write a class. So, our first move on the chessboard of the interview is to write a class. This is a dangerous misuse of a pattern such as data encapsulation, and an expert interviewer will checkmate us in one move. I saw candidates facing problems that could be solved in 10 minutes with two functions and a dictionary spending more than 50 minutes swamped in a multitude of classes, trying to figure out which object contained the data they needed at a certain point of the process.</p><p>Clearly, classes might be the best solution for some problems, but this should come at the end of your analysis. You write a class because you have data and functions that can be put together, and this is valid for any other technology. Always ask yourself: what is the reason why I use this? What is the problem that I'm trying to solve?</p><h2 id="a-dangerous-culture-3fdd">A dangerous culture<a class="headerlink" href="#a-dangerous-culture-3fdd" title="Permanent link">¶</a></h2><p>We all make the same mistake here: we push (or at least accept) a culture in which we teach and learn tools as go-to solutions without teaching to identify and face problems.</p><p>Programming languages, architectural patterns, algorithms. Those are all tools to implement solutions, they are not the solutions. You should learn them, down to the most minute details if you can, but never put them on the table before you understood the problem.</p><p>Alexis Carrel said, "A few observation and much reasoning lead to error; many observations and a little reasoning to truth."<sup>[<a id="fr-241c28c1-3" href="#">3</a>]</sup> The advice that I take from the French Nobel Prize winner is: what is in front of you has to be observed deeply to find out its real nature. What things are is much more important than what we think they are and how we think we should treat them ("reasoning"). And what things are, if observed properly, will also reveal ways to interact with them, to manipulate them, to solve them.</p><p>If you want a clear example of the opposite, observe a programmer (maybe you yourself) looking for help on an error the web framework or the compiler threw at them. Copy and paste the error message into Google, pick the first result (Stack Overflow), scroll down until you find some code, apply. I dare you to call this "engineering". Many times we don't even read the Stack Overflow question, we directly read the answer, not to mention the fact that many times we don't even read the error message!</p><p>I recommend reading a very interesting article by Joseph Gefroh, <a href="https://medium.com/swlh/why-your-technical-interview-is-broken-and-how-to-fix-it-7004da002aa8">Why Your Technical Interview Is Broken, and How to Fix It</a>, where he discusses the various types of skills that you can explore during an interview, and which ones you should be interested in. In particular, I couldn't agree more with his point about algorithmic interviews, as I believe they are deeply flawed.</p><p>I also recommend having a look at the <a href="https://github.com/guardian/coding-exercises">Guardian Coding Exercises</a> and to read the description of the repository. I think they are a good example of tests that allow the candidate and the interviewer to work together, to actually meet and to discuss a solution. There is no "right" way to solve them, and many of them cannot be solved in 45 minutes, which is usually the time given to a candidate after an initial introductory chat.</p><h2 id="conclusion-506c">Conclusion<a class="headerlink" href="#conclusion-506c" title="Permanent link">¶</a></h2><p>I hope these short considerations helped you to see my point. We should all shift our gaze from the tools we have to the nature of problems and to their solutions. We are missing an important step here, which is ultimately what defines a good engineer and which is the most important thing that you can learn in your career. Observe problems, stop and think, devise a strategy, zoom out and zoom in. Learn to use tools, don't be used by them.</p><p>We need to push for this approach in our interviews, but also try to promote this culture in our teams and companies.</p><hr><div id="_footnotes"><div id=""><a href="#fr-d8d83501-1">1</a> <p>See "What is a software architecture?" in <a href="https://www.thedigitalcatbooks.com">Clean Architectures in Python</a>.</p></div><div id=""><a href="#fr-f70c86c9-2">2</a> <p><em>Design Patterns: Elements of Reusable Object-Oriented Software</em> by Gamma, Vlissides, Johnson, and Helm</p></div><div id=""><a href="#fr-241c28c1-3">3</a> <p><em>Réflexions sur la vie</em>, Paris, 1952</p></div></div><h2 id="feedback-d845">Feedback<a class="headerlink" href="#feedback-d845" title="Permanent link">¶</a></h2><p>Feel free to reach me on <a href="https://twitter.com/thedigicat">Twitter</a> if you have questions. The <a href="https://github.com/TheDigitalCatOnline/blog_source/issues">GitHub issues</a> page is the best place to submit corrections.</p>Emacs Configuration for Python/JavaScript, Terraform and blogging2020-07-18T15:30:00+01:002020-07-18T15:30:00+01:00Leonardo Giordanitag:www.thedigitalcatonline.com,2020-07-18:/blog/2020/07/18/emacs-configuration-for-python-javascript-terraform-and-blogging/<p>A step-by-step analysis of the Emacs configuration that I use to write Python/JavaScript/Terraform code and posts for the blog</p><p>(image from https://commons.wikimedia.org/wiki/File:Gnu-listen-half.jpg)</p>
<p>I have been an Emacs user for a long time. There is no specific reason why I started using Emacs: it was available in the RedHat 6.0 distribution that I found in a magazine in 1999, and with which I started my journey in the open source world. It was mentioned in some Linux guide I read at the time, so it became my editor.</p>
<p>I'm not into flame wars, in particular about editors. If I don't like a software/operating system/language/whatever, I just don't use it, and at the same time I'm not scared to test alternatives, even though I'm not actively looking to replace tools that work. Admittedly, at the time I didn't properly configure my Emacs for years, in particular because the C language support was very good out of the box, and that was what I needed, so when I started programming in Python not everything was optimal.</p>
<p>One day a new colleague showed me <a href="https://www.sublimetext.com/">Sublime Text</a> and PyCharm. I don't like IDEs that much, they are too integrated, so the PyCharm wasn't very attractive, but Sublime Text is a very good editor, it's fast and has a lot of features (multiple cursors blew my mind when I first discovered them) and so it became my editor of choice for some years. In time, however I started growing increasingly dissatisfied with it, and with some alternatives that I tested like Atom. The main reason is that modern editor rely too much on the mouse: many people are happy with this, in particular because they use trackpads, but I honestly can't get use to them, and I simply don't want to take my hands off the keyboards while I code because I want to change tab, reorganise the screen, open a file, and so on.</p>
<p>So I went back to Emacs, and started from scratch to configure it in order to match my needs. In this post I want to describe what I did, so that newcomers might be helped to setup their own editor. Emacs is incredibly customisable, and this is one of its main strengths, but a proper setup takes time. Please don't consider configuring your editor a waste of time. If you are a programmer, the editor is your main tool, and you have to take care of it: like any other editor, Emacs has pros and cons, and a proper setup minimises the impact of the shortcomings on your daily work.</p>
<h2 id="requirements">Requirements<a class="headerlink" href="#requirements" title="Permanent link">¶</a></h2>
<p>As always, the choice of tools and their configuration depends on the requirements, so these are the ones I have at the moment.</p>
<ul>
<li>I need to create <strong>keyboard shortcuts</strong> for everything I do often in the editor, I should be able to work without the mouse</li>
<li><strong>Multiple cursors</strong> are a very useful feature and I am used to have them, so there should be an implementation similar to the one I found in Sublime Text</li>
<li><strong>Python</strong>/<strong>JavaScript</strong>/<strong>Terraform</strong> syntax highlighting and formatting/linting</li>
<li>As I have some projects written with React, <strong>JSX</strong> syntax highlighting is also needed</li>
<li><strong>Markdown</strong> syntax highlighting with spell-checking for my blogger activity</li>
</ul>
<h2 id="preamble">Preamble<a class="headerlink" href="#preamble" title="Permanent link">¶</a></h2>
<p>The Emacs configuration file is <code>~/.emacs</code>, and when you install the editor you might get a default minimal version of it. Whenever part of the configuration is changed from the menus, Emacs writes the changes in the .emacs, using the <code>custom-set-variables</code> function. That file also contains the list of packages that I have installed, so I moved the <code>custom-set-variables</code> invocation to a separate file, <code>.emacs-custom</code>. This way Emacs doesn't have to change the main file whenever I install or remove a package and when I customise the face (colours and fonts).</p>
<p>For packages, I'm using the standard <a href="https://melpa.org/#/getting-started">MELPA configuration</a></p>
<div class="highlight"><pre><span></span><code><span class="c1">;; Added by Package.el. This must come before configurations of</span>
<span class="c1">;; installed packages. Don't delete this line. If you don't want it,</span>
<span class="c1">;; just comment it out by adding a semicolon to the start of the line.</span>
<span class="c1">;; You may delete these explanatory comments.</span>
<span class="p">(</span><span class="nv">package-initialize</span><span class="p">)</span>
<span class="p">(</span><span class="k">setq</span><span class="w"> </span><span class="nv">custom-file</span><span class="w"> </span><span class="s">"~/.emacs-custom"</span><span class="p">)</span>
<span class="p">(</span><span class="nb">load</span><span class="w"> </span><span class="nv">custom-file</span><span class="p">)</span>
<span class="c1">;; Load package system and add MELPA repository.</span>
<span class="p">(</span><span class="nb">require</span><span class="w"> </span><span class="ss">'package</span><span class="p">)</span>
<span class="p">(</span><span class="nv">add-to-list</span>
<span class="w"> </span><span class="ss">'package-archives</span>
<span class="w"> </span><span class="c1">;; '("melpa" . "https://stable.melpa.org/packages/") ; many packages won't show if using stable</span>
<span class="w"> </span><span class="o">'</span><span class="p">(</span><span class="s">"melpa"</span><span class="w"> </span><span class="o">.</span><span class="w"> </span><span class="s">"https://melpa.milkbox.net/packages/"</span><span class="p">)</span>
<span class="w"> </span><span class="no">t</span><span class="p">)</span>
</code></pre></div>
<h2 id="global-settings">Global settings<a class="headerlink" href="#global-settings" title="Permanent link">¶</a></h2>
<p>In Emacs you can define new functions and assign them to key combinations, and this is usually a major part of the setup. As I often need to work on the configuration file, at least initially, the first function I defined is one that allows me to quickly open the <code>.emacs</code> file. In the comments I'm following <a href="https://www.emacswiki.org/emacs/EmacsKeyNotation">Emacs key notation</a></p>
<div class="highlight"><pre><span></span><code><span class="c1">;; Open .emacs with C-x c</span>
<span class="p">(</span><span class="nb">defun</span><span class="w"> </span><span class="nv">dotemacs</span><span class="w"> </span><span class="p">()</span><span class="w"> </span><span class="p">(</span><span class="nv">interactive</span><span class="p">)</span><span class="w"> </span><span class="p">(</span><span class="nv">switch-to-buffer</span><span class="w"> </span><span class="p">(</span><span class="nv">find-file-noselect</span><span class="w"> </span><span class="s">"~/.emacs"</span><span class="p">)))</span>
<span class="p">(</span><span class="nv">global-set-key</span><span class="w"> </span><span class="p">(</span><span class="nv">kbd</span><span class="w"> </span><span class="s">"C-x c"</span><span class="p">)</span><span class="w"> </span><span class="ss">'dotemacs</span><span class="p">)</span>
</code></pre></div>
<p>I like the <a href="https://www.emacswiki.org/emacs/VisualLineMode">visual line mode</a> to wraps long lines</p>
<div class="highlight"><pre><span></span><code><span class="c1">;; Visual line mode everywhere, please</span>
<span class="p">(</span><span class="nv">global-visual-line-mode</span><span class="w"> </span><span class="no">t</span><span class="p">)</span>
</code></pre></div>
<p>I also want to always see <a href="http://ergoemacs.org/emacs/emacs_line_number_mode.html">line numbers</a></p>
<div class="highlight"><pre><span></span><code><span class="c1">;; Display line numbers</span>
<span class="p">(</span><span class="nv">global-display-line-numbers-mode</span><span class="p">)</span>
</code></pre></div>
<p>I use <code>C-End</code> a lot to reach the end of the file, but often I press <code>C-<next></code> (<code>Ctrl-PgDown</code>) by mistake. That is by default associated with <code>scroll-left</code> which is disabled, but Emacs opens a buffer to warn me. I don't want that, so I just unset the key combination</p>
<div class="highlight"><pre><span></span><code><span class="c1">;; I keep pressing C-next by mistake...</span>
<span class="p">(</span><span class="nv">global-unset-key</span><span class="w"> </span><span class="p">(</span><span class="nv">kbd</span><span class="w"> </span><span class="s">"C-<next>"</span><span class="p">))</span>
</code></pre></div>
<p>I might not be a purist here. I used <code>M-w</code> and <code>C-y</code> for many years, but I also use other software during my day, and now the <code>Ctrl-c/x/v</code> combinations are universally implemented. It's really hard to remap my brain every time I go back to Emacs, so I prefer to remap Emacs. Welcome <a href="https://www.emacswiki.org/emacs/CuaMode">Cua Mode</a>, which also maps <code>undo</code> to <code>C-z</code></p>
<div class="highlight"><pre><span></span><code><span class="c1">;; Set C-c, C-x, C-v just to be in sync with the rest of the world</span>
<span class="p">(</span><span class="nv">cua-mode</span><span class="w"> </span><span class="no">t</span><span class="p">)</span>
</code></pre></div>
<p>I like Emacs to highlight the <a href="https://www.emacswiki.org/emacs/ShowParenMode">matching parenthesis</a> whenever I'm on an opening or closing one. Please note that the word "parenthesis" here refers to what are more generally called <a href="https://en.wikipedia.org/wiki/Bracket">brackets</a> in English, which includes parentheses or round brackets <code>()</code>, curly brackets or curly braces <code>{}</code>, and square brackets <code>[]</code></p>
<div class="highlight"><pre><span></span><code><span class="c1">;; Show the matching parenthesis</span>
<span class="p">(</span><span class="nv">show-paren-mode</span><span class="w"> </span><span class="mi">1</span><span class="p">)</span>
</code></pre></div>
<p>Speaking of brackets, I like to have a way to automatically match the opened ones. This is good in Lisp because there are more parentheses than words, but also in other languages like Python when dealing with complex data structures. Long story short, I mapped <code>C-]</code> to the auto-closing feature called <code>syntactic-close</code> (installed as a package)</p>
<div class="highlight"><pre><span></span><code><span class="c1">;; Syntactic close</span>
<span class="c1">;; https://github.com/emacs-berlin/syntactic-close</span>
<span class="p">(</span><span class="nv">global-set-key</span><span class="w"> </span><span class="p">(</span><span class="nv">kbd</span><span class="w"> </span><span class="s">"C-]"</span><span class="p">)</span><span class="w"> </span><span class="ss">'syntactic-close</span><span class="p">)</span>
</code></pre></div>
<p>Minibuffer is a very important part of Emacs, not only when you open files but also when running commands. I like the Ivy completion, so I installed it with MELPA and activate it. I want to have a quick access to the commands that I run previously (history), but since <code><down></code> and <code><up></code> are already used to navigate the suggestions I mapped the history functions to their Shift version. </p>
<div class="highlight"><pre><span></span><code><span class="c1">;; Ivy completion</span>
<span class="c1">;; https://github.com/abo-abo/swiper</span>
<span class="p">(</span><span class="nv">ivy-mode</span><span class="w"> </span><span class="mi">1</span><span class="p">)</span>
<span class="p">(</span><span class="nv">define-key</span><span class="w"> </span><span class="nv">ivy-minibuffer-map</span><span class="w"> </span><span class="p">(</span><span class="nv">kbd</span><span class="w"> </span><span class="s">"S-<up>"</span><span class="p">)</span><span class="w"> </span><span class="nf">#'</span><span class="nv">ivy-previous-history-element</span><span class="p">)</span>
<span class="p">(</span><span class="nv">define-key</span><span class="w"> </span><span class="nv">ivy-minibuffer-map</span><span class="w"> </span><span class="p">(</span><span class="nv">kbd</span><span class="w"> </span><span class="s">"S-<down>"</span><span class="p">)</span><span class="w"> </span><span class="nf">#'</span><span class="nv">ivy-next-history-element</span><span class="p">)</span>
</code></pre></div>
<p>The standard behaviour of <code>C-Del</code> in Emacs is far too greedy for me. I'm used to have a combination that deletes all spaces if I'm on a space, and the word if I'm on a word, so I found this</p>
<div class="highlight"><pre><span></span><code><span class="c1">;; https://stackoverflow.com/questions/17958397/emacs-delete-whitespaces-or-a-word</span>
<span class="p">(</span><span class="nb">defun</span><span class="w"> </span><span class="nv">kill-whitespace-or-word</span><span class="w"> </span><span class="p">()</span>
<span class="w"> </span><span class="p">(</span><span class="nv">interactive</span><span class="p">)</span>
<span class="w"> </span><span class="p">(</span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="nv">looking-at</span><span class="w"> </span><span class="s">"[ \t\n]"</span><span class="p">)</span>
<span class="w"> </span><span class="p">(</span><span class="k">let</span><span class="w"> </span><span class="p">((</span><span class="nv">p</span><span class="w"> </span><span class="p">(</span><span class="nv">point</span><span class="p">)))</span>
<span class="w"> </span><span class="p">(</span><span class="nv">re-search-forward</span><span class="w"> </span><span class="s">"[^ \t\n]"</span><span class="w"> </span><span class="no">nil</span><span class="w"> </span><span class="ss">:no-error</span><span class="p">)</span>
<span class="w"> </span><span class="p">(</span><span class="nv">backward-char</span><span class="p">)</span>
<span class="w"> </span><span class="p">(</span><span class="nv">kill-region</span><span class="w"> </span><span class="nv">p</span><span class="w"> </span><span class="p">(</span><span class="nv">point</span><span class="p">)))</span>
<span class="w"> </span><span class="p">(</span><span class="nv">kill-word</span><span class="w"> </span><span class="mi">1</span><span class="p">)))</span>
<span class="p">(</span><span class="nv">global-set-key</span><span class="w"> </span><span class="p">(</span><span class="nv">kbd</span><span class="w"> </span><span class="s">"C-<delete>"</span><span class="p">)</span><span class="w"> </span><span class="ss">'kill-whitespace-or-word</span><span class="p">)</span>
</code></pre></div>
<p>Last, as I have a rotating wallpaper with screenshots from my favourite films I like to see them behind the editor and the terminal, so I enable a little bit of transparency. I like this to be callable as an interactive function as I might want to remove the transparency, for example when sharing the screen, as that way the text might be easier to read.</p>
<div class="highlight"><pre><span></span><code><span class="c1">;; Set transparency of emacs</span>
<span class="c1">;; https://www.emacswiki.org/emacs/TransparentEmacs</span>
<span class="p">(</span><span class="nb">defun</span><span class="w"> </span><span class="nv">transparency</span><span class="w"> </span><span class="p">(</span><span class="nv">value</span><span class="p">)</span>
<span class="w"> </span><span class="s">"Sets the transparency of the frame window. 0=transparent/100=opaque"</span>
<span class="w"> </span><span class="p">(</span><span class="nv">interactive</span><span class="w"> </span><span class="s">"nTransparency Value 0 - 100 opaque:"</span><span class="p">)</span>
<span class="w"> </span><span class="p">(</span><span class="nv">set-frame-parameter</span><span class="w"> </span><span class="p">(</span><span class="nv">selected-frame</span><span class="p">)</span><span class="w"> </span><span class="ss">'alpha</span><span class="w"> </span><span class="nv">value</span><span class="p">))</span>
<span class="p">(</span><span class="nv">set-frame-parameter</span><span class="w"> </span><span class="p">(</span><span class="nv">selected-frame</span><span class="p">)</span><span class="w"> </span><span class="ss">'alpha</span><span class="w"> </span><span class="ss">'90</span><span class="p">)</span>
</code></pre></div>
<h2 id="keyboard-mapping">Keyboard mapping<a class="headerlink" href="#keyboard-mapping" title="Permanent link">¶</a></h2>
<p>I'm an Italian native speaker, so I often write texts in that language for my personal blog or for other reasons. In Italian, we use the accented letters à, è, é, ì, ò, ù a lot ("is" is just "è", "why" and "because" are "perché", almost all future tenses end with an accented letter, and so on), so I like to have a proper mapping. Emacs has a very powerful mode for Latin alphabet <a href="https://en.wikipedia.org/wiki/Diacritic">diacritics</a>, which is <code>latin-postfix</code>, where you can write "è" typing <code>e</code> followed by backticks, so that was my first choice. While this is very powerful, and allows me to input almost everything I need also for other languages like German, on the long run I found it very difficult to use efficiently.</p>
<p>First of all, I'm used to the Italian keymap, I know it by heart as I know the English keyboard mapping, so I tend to press keys that are supposed to insert the accented letters directly. Moreover, other software like the browser work with a system keyboard mapping (that Emacs ignores), so again, I need to rewire my brain every time I go back to the editor. Last, <code>latin-postfix</code> is far too generic and has mappings for letters like ą or ę which are created typing "a," which is a combination that we have every time we type a comma in Italian given that almost all words end in a vowel. This forces me to type "a,," whenever I need "a,", which is far too different from the normal system I'm used to.</p>
<p>The input method <code>italian-keyboard</code> unfortunately doesn't map very well on a standard modern English keyboard, so I decided to just write my own mapping using the <a href="http://web.mit.edu/Emacs/source/emacs/lisp/international/quail.el">quail</a> system, which is unsurprisingly not very well documented. I'm sorry to say it, but multilingual input has been and still is one of the great forgotten and messy topics in computer science, in particular in the open source world. Let's not even mention Chinese and other languages not based on an alphabet.</p>
<div class="highlight"><pre><span></span><code><span class="c1">; Define a proper mapping for the Italian keyboard over the English one</span>
<span class="p">(</span><span class="nv">quail-define-package</span>
<span class="w"> </span><span class="s">"italian-english-keyboard"</span><span class="w"> </span><span class="s">"Latin-1"</span><span class="w"> </span><span class="s">"IT@"</span><span class="w"> </span><span class="no">t</span>
<span class="w"> </span><span class="s">"Italian (Italiano) input method for modern English keyboards"</span>
<span class="w"> </span><span class="no">nil</span><span class="w"> </span><span class="no">t</span><span class="w"> </span><span class="no">t</span><span class="w"> </span><span class="no">t</span><span class="w"> </span><span class="no">t</span><span class="w"> </span><span class="no">nil</span><span class="w"> </span><span class="no">nil</span><span class="w"> </span><span class="no">nil</span><span class="w"> </span><span class="no">nil</span><span class="w"> </span><span class="no">nil</span><span class="w"> </span><span class="no">t</span><span class="p">)</span>
<span class="c1">;; \| 1! 2" 3£ 4$ 5% 6& 7/ 8( 9) 0= '? ì^</span>
<span class="c1">;; qQ wW eE rR tT yY uU iI oO pP èé +*</span>
<span class="c1">;; aA sS dD fF gG hH jJ kK lL òç à° ù§</span>
<span class="c1">;; <> zZ xX cC vV bB nN mM ,; .: -_</span>
<span class="c1">;; èè -> È Originally CapsLock+è</span>
<span class="c1">;; àà -> # Originally AltGr+à</span>
<span class="c1">;; òò -> @ Originally AltGr+ò</span>
<span class="c1">;; ìì -> ~ Originally AltGr+ì</span>
<span class="p">(</span><span class="nv">quail-define-rules</span>
<span class="w"> </span><span class="p">(</span><span class="s">"`"</span><span class="w"> </span><span class="nv">?\\</span><span class="p">)</span><span class="w"> </span><span class="p">(</span><span class="s">"¬"</span><span class="w"> </span><span class="nv">?|)</span>
<span class="nv"> ("^" ?&)</span>
<span class="nv"> ("&" ?/)</span>
<span class="nv"> ("*" ?\()</span>
<span class="nv"> ("(" ?\))</span>
<span class="nv"> (")" ?=)</span>
<span class="nv"> ("-" ?') ("_" ??)</span>
<span class="nv"> ("=" ?ì) ("+" ?^) ("==" ?~)</span>
<span class="nv"> ("[" ?è) ("{" ?é) ("[[" ?È)</span>
<span class="nv"> ("]" ?+) ("}" ?*)</span>
<span class="nv"> (";" ?ò) (":" ?ç) (";;" ?@)</span>
<span class="nv"> ("'" ?à) ("@" ?\°) ("''" ?#)</span>
<span class="nv"> ("#" ?ù) ("~" ?§)</span>
<span class="nv"> ("\\" ?<) ("|</span><span class="s">" ?>)</span>
<span class="s"> ("</span><span class="nb"><</span><span class="s">" ?\;)</span>
<span class="s"> ("</span><span class="nb">></span><span class="s">" ?:)</span>
<span class="s"> ("</span><span class="nb">/</span><span class="s">" ?-) ("</span><span class="nv">?</span><span class="err">"</span><span class="w"> </span><span class="nv">?_</span><span class="p">)</span>
<span class="p">)</span>
</code></pre></div>
<p>The standard Italian keyboard allows to input <code>È</code> activating CapsLock, pressing the key for <code>è</code> and deactivating CapsLock. This because <code>Shift-è</code> inputs <code>é</code>. I always found that system incredibly awkward, not to mention that it is impossible (as far as I understand) to create such a combination using quail, so I mapped it to <code>èè</code>, since that combination doesn't exist in Italian.</p>
<p>Another issue is that the Italian keyboard makes use of the right Alt key (AltGr) to input third level characters like <code>#</code>, <code>@</code>, and <code>~</code>. Again, I don't know if and how I can express these in quail so I went for a slight variation of that. Instead of typing AltGr+à for <code>#</code> I will type <code>àà</code> and so on. This is not a perfect mapping, but considering that I don't use those character that much when writing notes or blog posts I can accept it.</p>
<h2 id="lines-and-regions">Lines and regions<a class="headerlink" href="#lines-and-regions" title="Permanent link">¶</a></h2>
<p>This section is about shortcuts to interact with lines and regions. First of all something that comments the regions I highlighted or just the line I'm on. This is a good example of something that Emacs doesn't provide out of the box, maybe surprisingly, but that is easily implemented. OK, "easily" might be an overstatement, but this function is a good starting point if you want to learn how <a href="https://www.gnu.org/software/emacs/manual/html_node/elisp/">Emacs Lisp</a> works. If you are not interested you can just copy and paste it and call it a day</p>
<div class="highlight"><pre><span></span><code><span class="c1">;; Define C-/ to comment and uncomment regions and lines</span>
<span class="p">(</span><span class="nb">defun</span><span class="w"> </span><span class="nv">comment-or-uncomment-line-or-region</span><span class="w"> </span><span class="p">()</span>
<span class="w"> </span><span class="s">"Comments or uncomments the region or the current line if there's no active region."</span>
<span class="w"> </span><span class="p">(</span><span class="nv">interactive</span><span class="p">)</span>
<span class="w"> </span><span class="p">(</span><span class="k">let</span><span class="w"> </span><span class="p">(</span><span class="nv">beg</span><span class="w"> </span><span class="nv">end</span><span class="p">)</span>
<span class="w"> </span><span class="p">(</span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="nv">region-active-p</span><span class="p">)</span>
<span class="w"> </span><span class="p">(</span><span class="k">setq</span><span class="w"> </span><span class="nv">beg</span><span class="w"> </span><span class="p">(</span><span class="nv">region-beginning</span><span class="p">)</span><span class="w"> </span><span class="nv">end</span><span class="w"> </span><span class="p">(</span><span class="nv">region-end</span><span class="p">))</span>
<span class="w"> </span><span class="p">(</span><span class="k">setq</span><span class="w"> </span><span class="nv">beg</span><span class="w"> </span><span class="p">(</span><span class="nv">line-beginning-position</span><span class="p">)</span><span class="w"> </span><span class="nv">end</span><span class="w"> </span><span class="p">(</span><span class="nv">line-end-position</span><span class="p">)))</span>
<span class="w"> </span><span class="p">(</span><span class="nv">comment-or-uncomment-region</span><span class="w"> </span><span class="nv">beg</span><span class="w"> </span><span class="nv">end</span><span class="p">)</span>
<span class="w"> </span><span class="p">(</span><span class="nv">next-line</span><span class="p">)))</span>
<span class="p">(</span><span class="nv">global-set-key</span><span class="w"> </span><span class="p">(</span><span class="nv">kbd</span><span class="w"> </span><span class="s">"C-/"</span><span class="p">)</span><span class="w"> </span><span class="ss">'comment-or-uncomment-line-or-region</span><span class="p">)</span>
</code></pre></div>
<p>I want to be able to move up and down lines or regions using <code>Ctrl-Shift-up/down</code>, that is to <a href="https://github.com/rejeep/drag-stuff.el">drag stuff</a></p>
<div class="highlight"><pre><span></span><code><span class="c1">;; Drag-stuff - Drag lines and regions</span>
<span class="p">(</span><span class="nv">drag-stuff-global-mode</span><span class="w"> </span><span class="mi">1</span><span class="p">)</span>
<span class="c1">;; Use C-S-up/down</span>
<span class="p">(</span><span class="k">setq</span><span class="w"> </span><span class="nv">drag-stuff-modifier</span><span class="w"> </span><span class="o">'</span><span class="p">(</span><span class="nv">control</span><span class="w"> </span><span class="nv">shift</span><span class="p">))</span>
<span class="p">(</span><span class="nv">define-key</span><span class="w"> </span><span class="nv">drag-stuff-mode-map</span><span class="w"> </span><span class="p">(</span><span class="nv">drag-stuff--kbd</span><span class="w"> </span><span class="ss">'up</span><span class="p">)</span><span class="w"> </span><span class="ss">'drag-stuff-up</span><span class="p">)</span>
<span class="p">(</span><span class="nv">define-key</span><span class="w"> </span><span class="nv">drag-stuff-mode-map</span><span class="w"> </span><span class="p">(</span><span class="nv">drag-stuff--kbd</span><span class="w"> </span><span class="ss">'down</span><span class="p">)</span><span class="w"> </span><span class="ss">'drag-stuff-down</span><span class="p">)</span>
</code></pre></div>
<p>I also want to be able to duplicate the current line or region with <code>Ctrl-Shift-d</code>. This function is a mixture of several solutions I found on Internet, and I'm not 100% satisfied with it, as when I duplicate a region it also duplicates the last line of the region itself, even though the line is not highlighted. Again, it might be surprising that Emacs doesn't provide a solution out-of-the-box, but this way I can implement the behaviour I prefer. The fact that I'm not able to implement the exact behaviour (yet!) is part of the game, I think.</p>
<div class="highlight"><pre><span></span><code><span class="c1">;; Duplicate line with C-S-d</span>
<span class="p">(</span><span class="nb">defun</span><span class="w"> </span><span class="nv">duplicate-current-line-or-region</span><span class="w"> </span><span class="p">(</span><span class="nv">arg</span><span class="p">)</span>
<span class="w"> </span><span class="s">"Duplicates the current line or region ARG times.</span>
<span class="s">If there's no region, the current line will be duplicated. However, if</span>
<span class="s">there's a region, all lines that region covers will be duplicated."</span>
<span class="w"> </span><span class="p">(</span><span class="nv">interactive</span><span class="w"> </span><span class="s">"p"</span><span class="p">)</span>
<span class="w"> </span><span class="p">(</span><span class="k">let</span><span class="w"> </span><span class="p">(</span><span class="nv">beg</span><span class="w"> </span><span class="nv">end</span><span class="w"> </span><span class="p">(</span><span class="nv">origin</span><span class="w"> </span><span class="p">(</span><span class="nv">point</span><span class="p">)))</span>
<span class="w"> </span><span class="p">(</span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="nb">and</span><span class="w"> </span><span class="nv">mark-active</span><span class="w"> </span><span class="p">(</span><span class="nb">></span><span class="w"> </span><span class="p">(</span><span class="nv">point</span><span class="p">)</span><span class="w"> </span><span class="p">(</span><span class="nv">mark</span><span class="p">)))</span>
<span class="w"> </span><span class="p">(</span><span class="nv">exchange-point-and-mark</span><span class="p">))</span>
<span class="w"> </span><span class="p">(</span><span class="k">setq</span><span class="w"> </span><span class="nv">beg</span><span class="w"> </span><span class="p">(</span><span class="nv">line-beginning-position</span><span class="p">))</span>
<span class="w"> </span><span class="p">(</span><span class="k">if</span><span class="w"> </span><span class="nv">mark-active</span>
<span class="w"> </span><span class="p">(</span><span class="nv">exchange-point-and-mark</span><span class="p">))</span>
<span class="w"> </span><span class="p">(</span><span class="k">setq</span><span class="w"> </span><span class="nv">end</span><span class="w"> </span><span class="p">(</span><span class="nv">line-end-position</span><span class="p">))</span>
<span class="w"> </span><span class="p">(</span><span class="k">let</span><span class="w"> </span><span class="p">((</span><span class="nv">region</span><span class="w"> </span><span class="p">(</span><span class="nv">buffer-substring-no-properties</span><span class="w"> </span><span class="nv">beg</span><span class="w"> </span><span class="nv">end</span><span class="p">)))</span>
<span class="w"> </span><span class="p">(</span><span class="nb">dotimes</span><span class="w"> </span><span class="p">(</span><span class="nv">i</span><span class="w"> </span><span class="nv">arg</span><span class="p">)</span>
<span class="w"> </span><span class="p">(</span><span class="nv">goto-char</span><span class="w"> </span><span class="nv">end</span><span class="p">)</span>
<span class="w"> </span><span class="p">(</span><span class="nv">newline</span><span class="p">)</span>
<span class="w"> </span><span class="p">(</span><span class="nv">insert</span><span class="w"> </span><span class="nv">region</span><span class="p">)</span>
<span class="w"> </span><span class="p">(</span><span class="k">setq</span><span class="w"> </span><span class="nv">end</span><span class="w"> </span><span class="p">(</span><span class="nv">point</span><span class="p">)))</span>
<span class="w"> </span><span class="p">(</span><span class="nv">goto-char</span><span class="w"> </span><span class="p">(</span><span class="nb">+</span><span class="w"> </span><span class="nv">origin</span><span class="w"> </span><span class="p">(</span><span class="nb">*</span><span class="w"> </span><span class="p">(</span><span class="nb">length</span><span class="w"> </span><span class="nv">region</span><span class="p">)</span><span class="w"> </span><span class="nv">arg</span><span class="p">)</span><span class="w"> </span><span class="nv">arg</span><span class="p">)))))</span>
<span class="p">(</span><span class="nv">global-set-key</span><span class="w"> </span><span class="p">(</span><span class="nv">kbd</span><span class="w"> </span><span class="s">"C-S-d"</span><span class="p">)</span><span class="w"> </span><span class="ss">'duplicate-current-line-or-region</span><span class="p">)</span>
</code></pre></div>
<p>Multiple cursors! Emacs has an implementation of <a href="https://github.com/magnars/multiple-cursors.el">multiple cursors</a>, that is slightly different from the Sublime Text one, but that can be customised to my needs. Most notably, multiple cursors don't work perfectly with some parts of the editor like <code>TAB</code> for indentation, which is not automatically applied to all of them. So, this part of the setup is not perfect, but it's definitely usable and effective.</p>
<p><code>Ctrl-d</code> creates a second cursor on the next repetition of the current word, <code>Ctrl-c Ctrl-d</code> marks all the repetitions in the text, <code>Ctrl-Alt-up/down</code> add a new cursor on the previous/following line, and last <code>Ctrl-Alt-d</code> marks all the lines in a region</p>
<div class="highlight"><pre><span></span><code><span class="c1">;; Multiple cursors</span>
<span class="p">(</span><span class="nv">global-set-key</span><span class="w"> </span><span class="p">(</span><span class="nv">kbd</span><span class="w"> </span><span class="s">"C-d"</span><span class="p">)</span><span class="w"> </span><span class="ss">'mc/mark-next-like-this-word</span><span class="p">)</span>
<span class="p">(</span><span class="nv">global-set-key</span><span class="w"> </span><span class="p">(</span><span class="nv">kbd</span><span class="w"> </span><span class="s">"C-c C-d"</span><span class="p">)</span><span class="w"> </span><span class="ss">'mc/mark-all-words-like-this</span><span class="p">)</span>
<span class="p">(</span><span class="nv">global-set-key</span><span class="w"> </span><span class="p">(</span><span class="nv">kbd</span><span class="w"> </span><span class="s">"C-M-<up>"</span><span class="p">)</span><span class="w"> </span><span class="ss">'mc/mark-previous-lines</span><span class="p">)</span>
<span class="p">(</span><span class="nv">global-set-key</span><span class="w"> </span><span class="p">(</span><span class="nv">kbd</span><span class="w"> </span><span class="s">"C-M-<down>"</span><span class="p">)</span><span class="w"> </span><span class="ss">'mc/mark-next-lines</span><span class="p">)</span>
<span class="p">(</span><span class="nv">global-set-key</span><span class="w"> </span><span class="p">(</span><span class="nv">kbd</span><span class="w"> </span><span class="s">"C-M-d"</span><span class="p">)</span><span class="w"> </span><span class="ss">'mc/edit-lines</span><span class="p">)</span>
</code></pre></div>
<p>How many times do I need to highlight the whole buffer? More than I imagined, so I defined the classic <code>Ctrl-a</code> shortcut</p>
<div class="highlight"><pre><span></span><code><span class="c1">;; C-a marks the whole buffer</span>
<span class="p">(</span><span class="nv">global-set-key</span><span class="w"> </span><span class="p">(</span><span class="nv">kbd</span><span class="w"> </span><span class="s">"C-a"</span><span class="p">)</span><span class="w"> </span><span class="ss">'mark-whole-buffer</span><span class="p">)</span>
</code></pre></div>
<h2 id="windows-and-buffers">Windows and buffers<a class="headerlink" href="#windows-and-buffers" title="Permanent link">¶</a></h2>
<p>As everyone else, when I code I need to keep multiple files open, and often to have them side-by-side. Emacs provides out of the box the window split shortcuts <code>Ctrl-2</code> (horizontal split) and <code>Ctrl-3</code> (vertical split), but I need a shortcut to quickly move between them. Enter <a href="https://www.emacswiki.org/emacs/WindMove">Windmove</a>, which by default uses <code>Shift-<arrow></code> combinations, which I instead want to keep for highlighting regions, so I remapped it to <code>Alt-<arrow></code></p>
<div class="highlight"><pre><span></span><code><span class="c1">;; Windmove - move between windows use ALT</span>
<span class="p">(</span><span class="nv">windmove-default-keybindings</span><span class="w"> </span><span class="ss">'meta</span><span class="p">)</span>
<span class="c1">;; Unset Shift-arrow keybindings</span>
<span class="p">(</span><span class="nv">global-unset-key</span><span class="w"> </span><span class="p">(</span><span class="nb">vector</span><span class="w"> </span><span class="p">(</span><span class="nb">list</span><span class="w"> </span><span class="ss">'shift</span><span class="w"> </span><span class="ss">'left</span><span class="p">)))</span>
<span class="p">(</span><span class="nv">global-unset-key</span><span class="w"> </span><span class="p">(</span><span class="nb">vector</span><span class="w"> </span><span class="p">(</span><span class="nb">list</span><span class="w"> </span><span class="ss">'shift</span><span class="w"> </span><span class="ss">'right</span><span class="p">)))</span>
<span class="p">(</span><span class="nv">global-unset-key</span><span class="w"> </span><span class="p">(</span><span class="nb">vector</span><span class="w"> </span><span class="p">(</span><span class="nb">list</span><span class="w"> </span><span class="ss">'shift</span><span class="w"> </span><span class="ss">'up</span><span class="p">)))</span>
<span class="p">(</span><span class="nv">global-unset-key</span><span class="w"> </span><span class="p">(</span><span class="nb">vector</span><span class="w"> </span><span class="p">(</span><span class="nb">list</span><span class="w"> </span><span class="ss">'shift</span><span class="w"> </span><span class="ss">'down</span><span class="p">)))</span>
</code></pre></div>
<p>Next I need to move between buffers (open files not currently visible) Emacs used buffers also for its own internal logs, and all those buffers have a name surrounded by <code>*</code>, so I filter them out when I move through open files</p>
<div class="highlight"><pre><span></span><code><span class="c1">;; Skip system buffers when cycling</span>
<span class="p">(</span><span class="nv">set-frame-parameter</span><span class="w"> </span><span class="p">(</span><span class="nv">selected-frame</span><span class="p">)</span><span class="w"> </span><span class="ss">'buffer-predicate</span>
<span class="w"> </span><span class="p">(</span><span class="k">lambda</span><span class="w"> </span><span class="p">(</span><span class="nv">buf</span><span class="p">)</span><span class="w"> </span><span class="p">(</span><span class="nb">not</span><span class="w"> </span><span class="p">(</span><span class="nv">string-match-p</span><span class="w"> </span><span class="s">"^*"</span><span class="w"> </span><span class="p">(</span><span class="nv">buffer-name</span><span class="w"> </span><span class="nv">buf</span><span class="p">)))))</span>
</code></pre></div>
<p>To move between buffers I map <code>previous-buffer</code> and <code>next-buffer</code> to <code>Ctrl-Super-left/right</code> (Super here is my left Win key, which is between Ctrl and Alt)</p>
<div class="highlight"><pre><span></span><code><span class="c1">;; Map previous and next buffer to C-s-</span>
<span class="p">(</span><span class="nv">global-set-key</span><span class="w"> </span><span class="p">(</span><span class="nv">kbd</span><span class="w"> </span><span class="s">"C-s-<left>"</span><span class="p">)</span><span class="w"> </span><span class="ss">'previous-buffer</span><span class="p">)</span>
<span class="p">(</span><span class="nv">global-set-key</span><span class="w"> </span><span class="p">(</span><span class="nv">kbd</span><span class="w"> </span><span class="s">"C-s-<right>"</span><span class="p">)</span><span class="w"> </span><span class="ss">'next-buffer</span><span class="p">)</span>
</code></pre></div>
<p>Oh, I love the <a href="https://github.com/roman/golden-ratio.el">golden ratio mode</a> that splits window giving more space to the current one </p>
<div class="highlight"><pre><span></span><code><span class="c1">;; Golden ratio mode</span>
<span class="p">(</span><span class="nb">require</span><span class="w"> </span><span class="ss">'golden-ratio</span><span class="p">)</span>
<span class="p">(</span><span class="nv">golden-ratio-mode</span><span class="w"> </span><span class="mi">1</span><span class="p">)</span>
</code></pre></div>
<h2 id="spell-checking">Spell checking<a class="headerlink" href="#spell-checking" title="Permanent link">¶</a></h2>
<p>When I will learn how to properly spell <code>inconceivably</code> and <code>counter-intuitive</code> I might get rid of this. In the meanwhile a good spell check is a blessing from heaven. I haven't used function keys that much so far, and since I'm used to the standard Sublime Text mapping <code>F6</code> I reused that.</p>
<div class="highlight"><pre><span></span><code><span class="c1">;; Spell check</span>
<span class="p">(</span><span class="nv">global-set-key</span><span class="w"> </span><span class="p">(</span><span class="nv">kbd</span><span class="w"> </span><span class="s">"<f6>"</span><span class="p">)</span><span class="w"> </span><span class="ss">'flyspell-mode</span><span class="p">)</span>
<span class="c1">;; Spell check with hunspell</span>
<span class="p">(</span><span class="nb">when</span><span class="w"> </span><span class="p">(</span><span class="nv">executable-find</span><span class="w"> </span><span class="s">"hunspell"</span><span class="p">)</span>
<span class="w"> </span><span class="p">(</span><span class="nv">setq-default</span><span class="w"> </span><span class="nv">ispell-program-name</span><span class="w"> </span><span class="s">"hunspell"</span><span class="p">)</span>
<span class="w"> </span><span class="p">(</span><span class="k">setq</span><span class="w"> </span><span class="nv">ispell-really-hunspell</span><span class="w"> </span><span class="no">t</span><span class="p">))</span>
</code></pre></div>
<p>By the way, I misspell simpler words all the time, no need to get into inconceivably counter-intuitive words. And I'm sure there will be typos in this text, no matter how many times I check and read it =)</p>
<h2 id="python-development">Python development<a class="headerlink" href="#python-development" title="Permanent link">¶</a></h2>
<p>At last, let's get into development! Emacs has a very good package for Python, called <a href="https://elpy.readthedocs.io/en/latest/">Elpy</a>.</p>
<div class="highlight"><pre><span></span><code><span class="c1">;; Enable Elpy for Python development</span>
<span class="c1">;; https://elpy.readthedocs.io/en/latest/</span>
<span class="p">(</span><span class="k">setq</span><span class="w"> </span><span class="nv">elpy-rpc-python-command</span><span class="w"> </span><span class="s">"python3"</span><span class="p">)</span>
<span class="p">(</span><span class="nv">elpy-enable</span><span class="p">)</span>
</code></pre></div>
<p>There are some adjustment needed to prevent the mode to override the Windmove and other binding</p>
<div class="highlight"><pre><span></span><code><span class="c1">;; Prevent Elpy from overriding Windmove shortcuts</span>
<span class="p">(</span><span class="nv">eval-after-load</span><span class="w"> </span><span class="s">"elpy"</span>
<span class="w"> </span><span class="o">'</span><span class="p">(</span><span class="nv">cl-dolist</span><span class="w"> </span><span class="p">(</span><span class="nv">key</span><span class="w"> </span><span class="o">'</span><span class="p">(</span><span class="s">"M-<up>"</span><span class="w"> </span><span class="s">"M-<down>"</span><span class="w"> </span><span class="s">"M-<left>"</span><span class="w"> </span><span class="s">"M-<right>"</span><span class="p">))</span>
<span class="w"> </span><span class="p">(</span><span class="nv">define-key</span><span class="w"> </span><span class="nv">elpy-mode-map</span><span class="w"> </span><span class="p">(</span><span class="nv">kbd</span><span class="w"> </span><span class="nv">key</span><span class="p">)</span><span class="w"> </span><span class="no">nil</span><span class="p">)))</span>
<span class="c1">;; Prevent Elpy from overriding standard cursor movements</span>
<span class="p">(</span><span class="nv">eval-after-load</span><span class="w"> </span><span class="s">"elpy"</span>
<span class="w"> </span><span class="o">'</span><span class="p">(</span><span class="nv">cl-dolist</span><span class="w"> </span><span class="p">(</span><span class="nv">key</span><span class="w"> </span><span class="o">'</span><span class="p">(</span><span class="s">"C-<left>"</span><span class="w"> </span><span class="s">"C-<right>"</span><span class="p">))</span>
<span class="w"> </span><span class="p">(</span><span class="nv">define-key</span><span class="w"> </span><span class="nv">elpy-mode-map</span><span class="w"> </span><span class="p">(</span><span class="nv">kbd</span><span class="w"> </span><span class="nv">key</span><span class="p">)</span><span class="w"> </span><span class="no">nil</span><span class="p">)))</span>
</code></pre></div>
<p>Since I use <a href="https://github.com/psf/black">black</a> to format Python code I run it on save. Plus I have a shortcut to fix the syntax in the buffer at any time. Since the syntax document is PEP8 <code>C-8</code> is a nice combination.</p>
<div class="highlight"><pre><span></span><code><span class="c1">;; Run black on save</span>
<span class="p">(</span><span class="nv">add-hook</span><span class="w"> </span><span class="ss">'elpy-mode-hook</span><span class="w"> </span><span class="p">(</span><span class="k">lambda</span><span class="w"> </span><span class="p">()</span>
<span class="w"> </span><span class="p">(</span><span class="nv">add-hook</span><span class="w"> </span><span class="ss">'before-save-hook</span><span class="w"> </span><span class="ss">'elpy-black-fix-code</span><span class="w"> </span><span class="no">nil</span><span class="w"> </span><span class="no">t</span><span class="p">)))</span>
<span class="c1">;; Set C-8 to format Python code</span>
<span class="p">(</span><span class="nv">global-set-key</span><span class="w"> </span><span class="p">(</span><span class="nv">kbd</span><span class="w"> </span><span class="s">"C-8"</span><span class="p">)</span><span class="w"> </span><span class="ss">'elpy-black-fix-code</span><span class="p">)</span>
</code></pre></div>
<h2 id="javascript-development">JavaScript development<a class="headerlink" href="#javascript-development" title="Permanent link">¶</a></h2>
<p>Let's go full-stack and add some JavaScript and JSX to the recipe. The <a href="https://github.com/felipeochoa/rjsx-mode">rjsx-mode</a> is perfect for React development and similar things</p>
<div class="highlight"><pre><span></span><code><span class="c1">;; JSX</span>
<span class="c1">;;https://github.com/felipeochoa/rjsx-mode</span>
<span class="p">(</span><span class="nv">add-to-list</span><span class="w"> </span><span class="ss">'auto-mode-alist</span><span class="w"> </span><span class="o">'</span><span class="p">(</span><span class="s">"\\.js\\'"</span><span class="w"> </span><span class="o">.</span><span class="w"> </span><span class="nv">rjsx-mode</span><span class="p">))</span>
<span class="c1">;; Don't override my beloved multiple cursors</span>
<span class="p">(</span><span class="nv">with-eval-after-load</span><span class="w"> </span><span class="ss">'rjsx-mode</span>
<span class="w"> </span><span class="p">(</span><span class="nv">define-key</span><span class="w"> </span><span class="nv">rjsx-mode-map</span><span class="w"> </span><span class="p">(</span><span class="nv">kbd</span><span class="w"> </span><span class="s">"C-d"</span><span class="p">)</span><span class="w"> </span><span class="no">nil</span><span class="p">))</span>
</code></pre></div>
<p>As I will install Node.js modules locally in <code>node_modules</code> I want code formatters and other tools to run the binaries stored there</p>
<div class="highlight"><pre><span></span><code><span class="c1">;; Use binaries in node_modules</span>
<span class="c1">;; https://github.com/codesuki/add-node-modules-path</span>
<span class="p">(</span><span class="nv">add-hook</span><span class="w"> </span><span class="ss">'js2-mode-hook</span><span class="w"> </span><span class="ss">'add-node-modules-path</span><span class="p">)</span>
</code></pre></div>
<p>And also JS need to be beautified, at least when I have to read and understand it. I use <a href="https://prettier.io/">prettier</a> and <a href="https://github.com/prettier/prettier-emacs">prettier-emacs</a></p>
<div class="highlight"><pre><span></span><code><span class="c1">;; Pretty JS code</span>
<span class="c1">;; https://github.com/prettier/prettier-emacs</span>
<span class="p">(</span><span class="nb">require</span><span class="w"> </span><span class="ss">'prettier-js</span><span class="p">)</span>
<span class="p">(</span><span class="nv">add-hook</span><span class="w"> </span><span class="ss">'js2-mode-hook</span><span class="w"> </span><span class="ss">'prettier-js-mode</span><span class="p">)</span>
</code></pre></div>
<h2 id="other-languages">Other languages<a class="headerlink" href="#other-languages" title="Permanent link">¶</a></h2>
<p>Other languages I use are less demanding in term of customisation (generally because they are simpler or less general-purpose). The <a href="https://github.com/emacsorphanage/terraform-mode">Terraform mode</a> automatically fixes the syntax of the file on save</p>
<div class="highlight"><pre><span></span><code><span class="c1">;; Terraform</span>
<span class="c1">;; https://github.com/emacsorphanage/terraform-mode</span>
<span class="p">(</span><span class="nb">require</span><span class="w"> </span><span class="ss">'terraform-mode</span><span class="p">)</span>
<span class="p">(</span><span class="nv">add-to-list</span><span class="w"> </span><span class="ss">'auto-mode-alist</span><span class="w"> </span><span class="o">'</span><span class="p">(</span><span class="s">"\\.tf\\'"</span><span class="w"> </span><span class="o">.</span><span class="w"> </span><span class="nv">terraform-mode</span><span class="p">))</span>
<span class="p">(</span><span class="nv">add-hook</span><span class="w"> </span><span class="ss">'terraform-mode-hook</span><span class="w"> </span><span class="nf">#'</span><span class="nv">terraform-format-on-save-mode</span><span class="p">)</span>
<span class="c1">;; YAML</span>
<span class="p">(</span><span class="nb">require</span><span class="w"> </span><span class="ss">'yaml-mode</span><span class="p">)</span>
<span class="p">(</span><span class="nv">add-to-list</span><span class="w"> </span><span class="ss">'auto-mode-alist</span><span class="w"> </span><span class="o">'</span><span class="p">(</span><span class="s">"\\.ya?ml\\'"</span><span class="w"> </span><span class="o">.</span><span class="w"> </span><span class="nv">yaml-mode</span><span class="p">))</span>
</code></pre></div>
<h2 id="files-and-projects">Files and projects<a class="headerlink" href="#files-and-projects" title="Permanent link">¶</a></h2>
<p>My setup is still a work in progress here, I'm testing <a href="https://docs.projectile.mx/projectile/usage.html">Projectile</a>, <a href="https://github.com/raxod502/prescient.el">Prescient</a>, and <a href="https://github.com/Alexander-Miller/treemacs">Treemacs</a>. So far, only Projectile made it to the configuration file, but I'm not using it that much yet. I think I might use a good sidebar with Git integration through colours and icons, but I still have to find something I feel comfortable with.</p>
<div class="highlight"><pre><span></span><code><span class="c1">;; Projectile</span>
<span class="c1">;; https://docs.projectile.mx/projectile/usage.html</span>
<span class="p">(</span><span class="nb">require</span><span class="w"> </span><span class="ss">'projectile</span><span class="p">)</span>
<span class="p">(</span><span class="nv">define-key</span><span class="w"> </span><span class="nv">projectile-mode-map</span><span class="w"> </span><span class="p">(</span><span class="nv">kbd</span><span class="w"> </span><span class="s">"s-p"</span><span class="p">)</span><span class="w"> </span><span class="ss">'projectile-command-map</span><span class="p">)</span>
<span class="p">(</span><span class="nv">projectile-mode</span><span class="w"> </span><span class="mi">+1</span><span class="p">)</span>
<span class="p">(</span><span class="k">setq</span><span class="w"> </span><span class="nv">projectile-completion-system</span><span class="w"> </span><span class="ss">'ivy</span><span class="p">)</span>
</code></pre></div>
<h2 id="the-custom-file">The custom file<a class="headerlink" href="#the-custom-file" title="Permanent link">¶</a></h2>
<p>As I mentioned when I discussed the preamble the file <code>.emacs-custom</code> contains the customisation of variables and faces, and this is what I have</p>
<div class="highlight"><pre><span></span><code><span class="p">(</span><span class="nv">custom-set-variables</span>
<span class="w"> </span><span class="c1">;; custom-set-variables was added by Custom.</span>
<span class="w"> </span><span class="c1">;; If you edit it by hand, you could mess it up, so be careful.</span>
<span class="w"> </span><span class="c1">;; Your init file should contain only one such instance.</span>
<span class="w"> </span><span class="c1">;; If there is more than one, they won't work right.</span>
<span class="w"> </span><span class="o">'</span><span class="p">(</span><span class="nv">ansi-color-faces-vector</span>
<span class="w"> </span><span class="nv">[default</span><span class="w"> </span><span class="nv">default</span><span class="w"> </span><span class="nv">default</span><span class="w"> </span><span class="nv">italic</span><span class="w"> </span><span class="nv">underline</span><span class="w"> </span><span class="nv">success</span><span class="w"> </span><span class="kt">warning</span><span class="w"> </span><span class="nv">error]</span><span class="p">)</span>
<span class="w"> </span><span class="o">'</span><span class="p">(</span><span class="nv">custom-enabled-themes</span><span class="w"> </span><span class="p">(</span><span class="k">quote</span><span class="w"> </span><span class="p">(</span><span class="nv">tango-dark</span><span class="p">)))</span>
<span class="w"> </span><span class="o">'</span><span class="p">(</span><span class="nv">default-input-method</span><span class="w"> </span><span class="p">(</span><span class="k">quote</span><span class="w"> </span><span class="nv">italian-english-keyboard</span><span class="p">))</span>
<span class="w"> </span><span class="o">'</span><span class="p">(</span><span class="nv">inhibit-startup-screen</span><span class="w"> </span><span class="no">t</span><span class="p">)</span>
<span class="w"> </span><span class="o">'</span><span class="p">(</span><span class="nv">js-indent-level</span><span class="w"> </span><span class="mi">2</span><span class="p">)</span>
<span class="w"> </span><span class="o">'</span><span class="p">(</span><span class="nv">package-selected-packages</span>
<span class="w"> </span><span class="p">(</span><span class="k">quote</span>
<span class="w"> </span><span class="p">(</span><span class="nv">syntactic-close</span><span class="w"> </span><span class="nv">ivy</span><span class="w"> </span><span class="nv">projectile</span><span class="w"> </span><span class="nv">rjsx-mode</span><span class="w"> </span><span class="nv">js2-mode</span><span class="w"> </span><span class="nv">golden-ratio</span>
<span class="w"> </span><span class="nv">add-node-modules-path</span><span class="w"> </span><span class="nv">prettier-js</span><span class="w"> </span><span class="nv">tide</span><span class="w"> </span><span class="nv">elpy</span><span class="w"> </span><span class="nv">jinja2-mode</span><span class="w"> </span><span class="nv">drag-stuff</span>
<span class="w"> </span><span class="nv">markdown-mode</span><span class="w"> </span><span class="nv">fcitx</span><span class="w"> </span><span class="nv">command-log-mode</span><span class="w"> </span><span class="nv">yaml-mode</span><span class="w"> </span><span class="nv">terraform-mode</span><span class="w"> </span><span class="nv">multiple-cursors</span><span class="p">))))</span>
<span class="p">(</span><span class="nv">custom-set-faces</span>
<span class="w"> </span><span class="c1">;; custom-set-faces was added by Custom.</span>
<span class="w"> </span><span class="c1">;; If you edit it by hand, you could mess it up, so be careful.</span>
<span class="w"> </span><span class="c1">;; Your init file should contain only one such instance.</span>
<span class="w"> </span><span class="c1">;; If there is more than one, they won't work right.</span>
<span class="w"> </span><span class="o">'</span><span class="p">(</span><span class="nv">flymake-error</span><span class="w"> </span><span class="p">((</span><span class="no">t</span><span class="w"> </span><span class="p">(</span><span class="ss">:foreground</span><span class="w"> </span><span class="s">"orange red"</span><span class="w"> </span><span class="ss">:background</span><span class="w"> </span><span class="s">"yellow"</span><span class="p">))))</span>
<span class="w"> </span><span class="o">'</span><span class="p">(</span><span class="nv">js2-external-variable</span><span class="w"> </span><span class="p">((</span><span class="no">t</span><span class="w"> </span><span class="p">(</span><span class="ss">:foreground</span><span class="w"> </span><span class="s">"orange red"</span><span class="w"> </span><span class="ss">:background</span><span class="w"> </span><span class="s">"yellow"</span><span class="p">)))))</span>
</code></pre></div>
<p>As you can see I have a default theme <code>tango-dark</code>. The default alternate input method activated by <code>C-\</code> is the one I defined previously, <code>italian-english-keyboard</code>. JavaScript uses 2 spaces for indentation, and last I changed some colours to make errors in Python and JavaScript stand out very clearly.</p>
<h2 id="final-words">Final words<a class="headerlink" href="#final-words" title="Permanent link">¶</a></h2>
<p>Any configuration is a work in progress, as it changes with the personal preferences and the requirements, but this has been my configuration for a while now, so it seems pretty stable. I hope this might help whoever wants to try emacs or who is already using it but struggles to properly configure it. Happy coding!</p>
<h2 id="feedback">Feedback<a class="headerlink" href="#feedback" title="Permanent link">¶</a></h2>
<p>Feel free to reach me on <a href="https://twitter.com/thedigicat">Twitter</a> if you have questions. The <a href="https://github.com/TheDigitalCatOnline/blog_source/issues">GitHub issues</a> page is the best place to submit corrections.</p>