2020-04-15-emacs-bankruptcy-is-fun.html (8679B)
1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <!-- Sep 03, 2024 --> 5 <meta charset="utf-8" /> 6 <meta name="viewport" content="width=device-width, initial-scale=1" /> 7 <title>Emacs bankruptcy is fun</title> 8 <meta name="author" content="Vincent Demeester" /> 9 <meta name="generator" content="Org Mode" /> 10 <link rel='icon' type='image/x-icon' href='/images/favicon.ico'/> 11 <meta name='viewport' content='width=device-width, initial-scale=1'> 12 <link rel='stylesheet' href='/css/new.css' type='text/css'/> 13 <link rel='stylesheet' href='/css/syntax.css' type='text/css'/> 14 <link href='/index.xml' rel='alternate' type='application/rss+xml' title='Vincent Demeester' /> 15 </head> 16 <body> 17 <main id="content" class="content"> 18 <header> 19 <h1 class="title">Emacs bankruptcy is fun</h1> 20 </header><section id="outline-container-Introduction" class="outline-2"> 21 <h2 id="Introduction">Introduction</h2> 22 <div class="outline-text-2" id="text-Introduction"> 23 <p> 24 Since go 1.14 go released, I’ve had a broken <code>go-mode</code> setup on my Emacs. I was using 25 <code>lsp-mode</code> and <code>gopls</code> and well, the update broke everything. I initally try to fix it but 26 I made it worse. At the same time, I started to get fed up with some performance issue of 27 my configuration and how slow my Emacs starts, about 6s. 28 </p> 29 30 <p> 31 I, thus, declared my third Emacs bankruptcy, <code>:disabled</code> everything and slowly started 32 from scratch, with the following goal: 33 </p> 34 35 <ul class="org-ul"> 36 <li>Have it start quick, as less than a second, not too much more than <code>emacs -Q</code> would</li> 37 <li>Disable anything that I don’t use often initially</li> 38 <li>Try to use as much built-in as possible (example: using <code>icomplete</code> instead of 39 <code>ivy=/=counsel</code>)</li> 40 </ul> 41 </div> 42 </section> 43 <section id="outline-container-Do%20I%20really%20need%20this%20feature" class="outline-2"> 44 <h2 id="Do%20I%20really%20need%20this%20feature">Do I really need this feature</h2> 45 <div class="outline-text-2" id="text-Do%20I%20really%20need%20this%20feature"> 46 <p> 47 Following <a href="https://protesilaos.com/">Protesilaos Stavrou</a>’s emacs videos (and <a href="https://protesilaos.com/dotemacs/"><code>dotemacs</code></a>) for a while now, I have a 48 tendency to try to use built-in feature as much as possible. The most obvious example is 49 using <code>icomplete</code> instead of <code>ivy=/=counsel</code>. 50 </p> 51 52 <p> 53 When I started my <i>bankruptcy</i>, I disabled every single customization I had, either using 54 <code>:disabled</code> when using <code>use-package</code> <b>or</b> the <code>(when nil)</code> <i>hack</i>. I then started Emacs 55 and acted on what was missing : 56 </p> 57 58 <ol class="org-ol"> 59 <li>Do I really miss it ? An example would be, at least initially, the completion in a <code>go</code> 60 file. I do miss it, but I miss it <b>way less</b> than having Emacs lagging because of 61 <code>lsp-mode</code> and showing me wrong completion.</li> 62 <li>Is there a built-in option to what I previously used ? Here, the <code>icomplete</code> example 63 fits well, or <code>isearch</code> instead of <code>swiper</code>.</li> 64 <li>Do I need it at startup or <i>on-demand</i> ?</li> 65 </ol> 66 </div> 67 </section> 68 <section id="outline-container-Looking%20into%20what%20takes%20time" class="outline-2"> 69 <h2 id="Looking%20into%20what%20takes%20time">Looking into what takes time</h2> 70 <div class="outline-text-2" id="text-Looking%20into%20what%20takes%20time"> 71 <p> 72 In “Advanced Techniques for Reducing Emacs Startup Time”<sup><a id="fnr.1" class="footref" href="#fn.1" role="doc-backlink">1</a></sup>, I discovered the <a href="https://github.com/jschaf/esup"><code>esup</code></a> 73 emacs library. In a gist, this is a profiler for Emacs. It starts a new Emacs instance and 74 look at the loading time. 75 </p> 76 77 78 <figure id="orgb8e5f7b"> 79 <img src="../images/2020-04-15-16-12-54.png" alt="2020-04-15-16-12-54.png"> 80 81 <figcaption><span class="figure-number">Figure 1: </span>esup “result” view</figcaption> 82 </figure> 83 84 <p> 85 Then, you can do a simple loop: 86 </p> 87 88 <ul class="org-ul"> 89 <li>Run <code>esup</code></li> 90 <li>Look at the top result</li> 91 <li>Fix it (lazy load, removing the feature, …)</li> 92 <li>Re-iterate</li> 93 </ul> 94 </div> 95 </section> 96 <section id="outline-container-Loading%20on-demand" class="outline-2"> 97 <h2 id="Loading%20on-demand">Loading on-demand</h2> 98 <div class="outline-text-2" id="text-Loading%20on-demand"> 99 <p> 100 Once you have the setup to know what takes time and what not, it’s time to look into how 101 to load the most thing on demand. 102 </p> 103 104 <p> 105 For this, <a href="https://github.com/jwiegley/use-package"><code>use-package</code></a> is amazing, it tremendously help autoloading modules on-demand. If 106 you are not using <code>use-package</code>, usually you are using <code>require</code>, which loads the 107 underlying source file (all of it). 108 </p> 109 110 <p> 111 With <code>use-package</code>, there is multiple ways to load on demand: 112 </p> 113 114 <ul class="org-ul"> 115 <li><code>:commands</code> to add callable that will trigger loading the package</li> 116 <li><code>:bind</code>, <code>:bind*</code>, <code>:bind-keymap</code> and <code>:bind-keymap*</code> to bind key sequences to the 117 global keymap or a specific keymap.</li> 118 <li><code>:mode</code> and <code>:interpreter</code> establish a deferred binding with the <code>auto-mode-alist</code> and 119 <code>interpreter-mode-alist</code>.</li> 120 <li><code>:hook</code> allows adding functions onto the package hook</li> 121 <li><code>:defer</code> is the most generic one, all the previous keyword imply <code>:defer</code>. You can 122 specify a number of second of idle to load the package.</li> 123 </ul> 124 125 <aside id="orgbb35d32"> 126 <p> 127 In a gist for <code>org-babel</code>, use <code>use-package ob-python</code> and never call <code>org-babel-do-languages</code>. 128 </p> 129 </aside> 130 <p> 131 Once this is done, you are left with edge cases, like <code>org-babel-do-languages</code>. Those are 132 to be handle case by case. The good thing about those cases is that you’ll learn what 133 those function do and this will give you an even better understanding of what is 134 happening. 135 </p> 136 137 <p> 138 Doing this exercise also forces you to make you see if you really use that feature or 139 not. I ended up removing entire feature from my configuration because they were taking 140 quite some time to load, and was used almost never. Instead I am forcing myself to learn 141 more what I can do with the built-in features first. 142 </p> 143 </div> 144 </section> 145 <section id="outline-container-Conclusion" class="outline-2"> 146 <h2 id="Conclusion">Conclusion</h2> 147 <div class="outline-text-2" id="text-Conclusion"> 148 <p> 149 All in all, this <i>bankruptcy</i> was the most fun I had to do. I consider myself still in the 150 process but the base is there. 151 </p> 152 153 <ol class="org-ol"> 154 <li>I learned a lot !</li> 155 <li>My Emacs starts in 0.6s against previously in 5s — <code>emacs -q</code> starts in about 0.3s so 156 there is still a little bit of room for improvement.</li> 157 <li>I discovered / re-discovered a lot of built-in feature</li> 158 <li>I started documenting my configuration, see <a href="../configurations/emacs.html">here</a>.</li> 159 </ol> 160 161 <p> 162 🎉 163 </p> 164 165 <div class='drawer update'> 166 <h6>Update</h6> 167 <p> 168 Well, I’ve look into the <i>portable dump</i> feature of Emacs, thanks to <a href="https://archive.casouri.cat/note/2020/painless-transition-to-portable-dumper/index.html">Painless Transition 169 to Portable Dumper</a>. And I am now down to <code>0.091s</code> for the startup. There is a few gotchas 170 with <i>portable dump</i>, I’ll try to write about it later. 171 </p> 172 </div> 173 </div> 174 </section> 175 <div id="footnotes"> 176 <h2 class="footnotes">Footnotes: </h2> 177 <div id="text-footnotes"> 178 179 <div class="footdef"><sup><a id="fn.1" class="footnum" href="#fnr.1" role="doc-backlink">1</a></sup> <div class="footpara" role="doc-footnote"><p class="footpara"> 180 : <a href="https://blog.d46.us/advanced-emacs-startup/">Advanced Techniques for Reducing Emacs Startup Time</a> 181 </p></div></div> 182 183 184 </div> 185 </div></main> 186 <footer id="postamble" class="status"> 187 <footer> 188 <small><a href="/" rel="history">Index</a> • <a href="/sitemap.html">Sitemap</a> • <a href="https://dl.sbr.pm/">Files</a></small><br/> 189 <small class='questions'>Questions, comments ? Please use my <a href="https://lists.sr.ht/~vdemeester/public-inbox">public inbox</a> by sending a plain-text email to <a href="mailto:~vdemeester/public-inbox@lists.sr.ht">~vdemeester/public-inbox@lists.sr.ht</a>.</small><br/> 190 <small class='copyright'> 191 Content and design by Vincent Demeester 192 (<a rel='licence' href='http://creativecommons.org/licenses/by-nc-sa/3.0/'>Some rights reserved</a>) 193 </small><br /> 194 </footer> 195 </footer> 196 </body> 197 </html>