Simplify - Articles tagged with ElispPersonal website of Saša Jovanićhttps://www.simplify.ba/articles/tags/elisp/2021-12-17T19:12:00+01:00Saša Jovanićflycheck-popup-tip available on Melpahttps://www.simplify.ba/articles/2017/08/09/flycheck-popup-tip-available-on-melpa/2017-08-09T13:25:34+02:002017-08-22T01:54:02+02:00Saša Jovanić<p><code>flycheck-popup-tip</code> is now available on Melpa. It took too long to get there doe to lack of free time recently…
<a href="https://github.com/flycheck/flycheck-popup-tip">flycheck-popup-tip</a> is extension for <a href="http://www.flycheck.org/">Flycheck</a>. It implements minor-mode for displaying errors from Flycheck using <a href="https://github.com/auto-complete/popup-el">popup.el</a>. Repo placement is under Flycheck org.</p>
<p><img src="/articles/2017/08/09/flycheck-popup-tip-available-on-melpa/01.png" alt="flycheck-popup-tip screenshot" title="flycheck-popup-tip Screenshot" class="center" /></p>
<p>There is <a href="https://github.com/flycheck/flycheck-pos-tip">another official flycheck-pos-tip</a> extension for displaying errors under point. However, it does not display popup if you run Emacs under TTY (where I use GNU Emacs). Also, It displays message on echo area and that is often used for help texts from ELDoc.</p>
flycheck-typescript-tslint is now part of flycheck packagehttps://www.simplify.ba/articles/2016/05/09/flycheck-typescript-tslint-now-part-of-flycheck/2016-05-09T13:42:00+02:002016-05-09T14:50:51+02:00Saša Jovanić<p>Two days ago my pull request for merging <a href="https://github.com/Simplify/flycheck-typescript-tslint">flycheck-typescript-tslint</a> into <code>flycheck</code> is accepted. Package is now removed from Melpa. I also joined <a href="http://www.flycheck.org/en/latest/">Flycheck</a> organization on GitHub and I'll continue to support TSLint checker from there.</p>
Linting JavaScript in GNU Emacshttps://www.simplify.ba/articles/2016/02/14/linting-javascript-in-gnu-emacs/2016-02-14T18:22:00+01:002016-02-22T12:25:29+01:00Saša Jovanić<p>With any programming language, when you do some client or day job work, you need to deliver quality software. When you contribute to <abbr title="Free Libre Open Source Software">FLOSS</abbr> projects, you have to follow some style guides specified for that project. Great help with all of that are linters and style checkers.</p>
<p>JavaScript world if full of those… Just try to search <abbr title="Node package manager">npm</abbr> package with word 'lint'…</p>
<h2 id="my-choice">My choice</h2>
<p>However, <code>flycheck</code> package for <abbr title="GNU is Not Unix">GNU</abbr> Emacs supports some of the biggest names: <code>gjslint</code>, <code>jshint</code>, <code>eslint</code> as linters and <code>jscs</code> and <code>standard</code>/<code>semistandard</code> as style checkers. I use only <a href="http://eslint.org/">eslint</a> (best ES6 support) and <a href="http://jscs.info/">jscs</a> (great support for <a href="http://usejsdoc.org/">JSDoc</a>).</p>
<p>Both can be installed using <code>npm</code>. I also install <code>babel-eslint</code> because almost all my projects use <code>babel</code>.</p>
<p>Both tools require configuration files in project directory in order to work correctly.</p>
<h2 id="eslint">ESLint</h2>
<p>Install with <abbr title="Node package manager">npm</abbr>:</p>
<pre class="highlight plaintext"><code>$ npm install -g eslint babel-eslint
</code></pre>
<p>You can install modules without <code>-g</code> flag, but then you need to <a href="/articles/2016/02/14/node-modules-bin-in-path/">set $PATH in Emacs</a>.</p>
<p>Create <code>.eslintrc</code> file in your project directory (or your $HOME directory) with following:</p>
<pre class="highlight json"><code><span class="p">{</span><span class="w">
</span><span class="nt">"extends"</span><span class="p">:</span><span class="w"> </span><span class="s2">"eslint:recommended"</span><span class="p">,</span><span class="w">
</span><span class="nt">"parser"</span><span class="p">:</span><span class="w"> </span><span class="s2">"babel-eslint"</span><span class="p">,</span><span class="w">
</span><span class="nt">"rules"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w">
</span><span class="nt">"strict"</span><span class="p">:</span><span class="w"> </span><span class="mi">0</span><span class="w">
</span><span class="p">}</span><span class="w">
</span><span class="p">}</span><span class="w">
</span></code></pre>
<h2 id="jscs">JSCS</h2>
<p>Again, install with <abbr title="Node package manager">npm</abbr>:</p>
<pre class="highlight plaintext"><code>$ npm install -g jscs
</code></pre>
<p>In order to create <code>.jscsrc</code> file, best way is to point to your existing JavaScript file and then <code>jscs</code> will offer you some presets based on your coding style.</p>
<pre class="highlight plaintext"><code>$ jscs --auto-configure <directory with your files or single js file>
</code></pre>
<p>In my example case I got config under this paragraph using js file with 20 lines… Not really correct style for mine taste, so please use a good example JavaScript file when you do this.</p>
<pre class="highlight json"><code><span class="p">{</span><span class="w">
</span><span class="nt">"preset"</span><span class="p">:</span><span class="w"> </span><span class="s2">"airbnb"</span><span class="p">,</span><span class="w">
</span><span class="nt">"requireSpacesInAnonymousFunctionExpression"</span><span class="p">:</span><span class="w"> </span><span class="kc">null</span><span class="w">
</span><span class="p">}</span><span class="w">
</span></code></pre>
<p>You can take it from there and tweak it if needed.</p>
<p>I also like to check JSDoc documentation in JavaScript files. In order to do that add following to your <code>.jscsrc</code> file:</p>
<pre class="highlight json"><code><span class="p">{</span><span class="w">
</span><span class="nt">"preset"</span><span class="p">:</span><span class="w"> </span><span class="s2">"airbnb"</span><span class="p">,</span><span class="w">
</span><span class="nt">"requireSpacesInAnonymousFunctionExpression"</span><span class="p">:</span><span class="w"> </span><span class="kc">null</span><span class="p">,</span><span class="w">
</span><span class="nt">"maxErrors"</span><span class="p">:</span><span class="w"> </span><span class="mi">-1</span><span class="p">,</span><span class="w">
</span><span class="nt">"esnext"</span><span class="p">:</span><span class="w"> </span><span class="kc">true</span><span class="p">,</span><span class="w">
</span><span class="nt">"plugins"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="w">
</span><span class="s2">"jscs-jsdoc"</span><span class="w">
</span><span class="p">],</span><span class="w">
</span><span class="nt">"jsDoc"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w">
</span><span class="nt">"checkAnnotations"</span><span class="p">:</span><span class="w"> </span><span class="s2">"jsdoc3"</span><span class="p">,</span><span class="w">
</span><span class="nt">"checkParamExistence"</span><span class="p">:</span><span class="w"> </span><span class="kc">true</span><span class="p">,</span><span class="w">
</span><span class="nt">"checkParamNames"</span><span class="p">:</span><span class="w"> </span><span class="kc">true</span><span class="p">,</span><span class="w">
</span><span class="nt">"checkRedundantParams"</span><span class="p">:</span><span class="w"> </span><span class="kc">true</span><span class="p">,</span><span class="w">
</span><span class="nt">"checkReturnTypes"</span><span class="p">:</span><span class="w"> </span><span class="kc">true</span><span class="p">,</span><span class="w">
</span><span class="nt">"checkRedundantReturns"</span><span class="p">:</span><span class="w"> </span><span class="kc">true</span><span class="p">,</span><span class="w">
</span><span class="nt">"requireReturnTypes"</span><span class="p">:</span><span class="w"> </span><span class="kc">true</span><span class="p">,</span><span class="w">
</span><span class="nt">"checkTypes"</span><span class="p">:</span><span class="w"> </span><span class="s2">"strictNativeCase"</span><span class="p">,</span><span class="w">
</span><span class="nt">"enforceExistence"</span><span class="p">:</span><span class="w"> </span><span class="kc">true</span><span class="p">,</span><span class="w">
</span><span class="nt">"requireHyphenBeforeDescription"</span><span class="p">:</span><span class="w"> </span><span class="kc">true</span><span class="p">,</span><span class="w">
</span><span class="nt">"requireParamDescription"</span><span class="p">:</span><span class="w"> </span><span class="kc">true</span><span class="p">,</span><span class="w">
</span><span class="nt">"requireReturnDescription"</span><span class="p">:</span><span class="w"> </span><span class="kc">true</span><span class="w">
</span><span class="p">}</span><span class="w">
</span><span class="p">}</span><span class="w">
</span></code></pre>
<p>That 'maxErrors' is in order to ask for all errors, without limit.</p>
<h2 id="gnu-emacs-settings"><abbr title="GNU is Not Unix">GNU</abbr> Emacs settings</h2>
<p>Well, <code>flycheck</code> will use <code>eslint</code> and then stop with collecting errors and warnings. <code>jscs</code> is never called if <code>eslint</code> is present. In most modes <code>flycheck</code> will chain checkers, one after another, but not for JavaScript. In order to chain checkers, add following somewhere in <code>init.el</code>:</p>
<pre class="highlight common_lisp"><code><span class="p">(</span><span class="nv">with-eval-after-load</span> <span class="ss">'flycheck</span>
<span class="c1">;; Run javascript-jscs to run after javascript-eslint.</span>
<span class="p">(</span><span class="nv">flycheck-add-next-checker</span> <span class="ss">'javascript-eslint</span> <span class="o">'</span><span class="p">(</span><span class="no">t</span> <span class="o">.</span> <span class="nv">javascript-jscs</span><span class="p">)))</span>
</code></pre>
node_modules/.bin in your project $PATHhttps://www.simplify.ba/articles/2016/02/14/node-modules-bin-in-path/2016-02-14T14:14:00+01:002016-02-18T14:59:19+01:00Saša Jovanić<p>Just to remind myself in the future. Add this to <code>.bash_profile</code> or <code>.profile</code> in order to have per project installed node modules executable in $PATH:</p>
<pre class="highlight shell"><code><span class="nb">export </span><span class="nv">PATH</span><span class="o">=</span><span class="s2">"</span><span class="nv">$PATH</span><span class="s2">:node_modules/.bin"</span>
</code></pre>
<p>Unfortunately, this works only in root project directory, not when I use <abbr title="GNU is Not Unix">GNU</abbr> Emacs. Solution is to use <code>.dir-locals.el</code> file in project directory with following code inside:</p>
<pre class="highlight common_lisp"><code><span class="p">((</span><span class="no">nil</span> <span class="o">.</span> <span class="p">((</span><span class="nb">eval</span> <span class="o">.</span> <span class="p">(</span><span class="k">progn</span>
<span class="p">(</span><span class="nv">add-to-list</span> <span class="ss">'exec-path</span> <span class="p">(</span><span class="nv">concat</span> <span class="p">(</span><span class="nv">locate-dominating-file</span> <span class="nv">default-directory</span> <span class="s">".dir-locals.el"</span><span class="p">)</span> <span class="s">"node_modules/.bin/"</span><span class="p">)))))))</span>
</code></pre>
<p>When you start <abbr title="GNU is Not Unix">GNU</abbr> Emacs somewhere in your project directory, he will ask do you want to apply local settings. You can answer with 'y' or '!' (to apply those permanently). That will add <code>$(your project)/node_modules/.bin</code> to your $PATH inside <abbr title="GNU is Not Unix">GNU</abbr> Emacs. No need to install any <abbr title="Node package manager">npm</abbr> modules globally any more.</p>
flycheck-typescript-tslint releasedhttps://www.simplify.ba/articles/2016/02/13/flycheck-typescript-tslint-released/2016-02-13T21:45:00+01:002016-02-17T15:42:51+01:00Saša Jovanić<p>Today I released <a href="https://github.com/Simplify/flycheck-typescript-tslint">flycheck-typescript-tslint</a> <abbr title="GNU is Not Unix">GNU</abbr> Emacs package version 0.21 on <a href="http://melpa.org/#/flycheck-typescript-tslint">Melpa</a>.</p>
<p>No real code changes, just documentation. There was no reference in any file that you need <code>tslint.json</code> config in order to use this package.</p>
Loading and unloading GNU Emacs themeshttps://www.simplify.ba/articles/2016/02/13/loading-and-unloading-emacs-themes/2016-02-13T15:02:00+01:002016-02-25T14:06:09+01:00Saša Jovanić<p>Every time you call <code>load-theme</code> in <abbr title="GNU is Not Unix">GNU</abbr> Emacs, there is a chance that previous theme changed something that new theme does not. Also, sometimes themes change <code>linum</code> (line numbers) settings and if you use <code>linum</code> you don't want that. Here is part of my <abbr title="GNU is Not Unix">GNU</abbr> Emacs configuration and how I deal with those problems.</p>
<h2 id="enter-advice-add">Enter <code>advice-add</code></h2>
<p>In Emacs lisp you can create are advising functions that can run before or after some other functions. Actually, there are other possibilities except before or after, but those are out of scope of this article.</p>
<p>Here is complete code, including line number formatting. Comments are present to explain code.</p>
<pre class="highlight common_lisp"><code><span class="c1">;; enable linum-mode (line number mode)</span>
<span class="p">(</span><span class="nv">global-linum-mode</span> <span class="mi">1</span><span class="p">)</span>
<span class="c1">;; Create function for line number format</span>
<span class="c1">;; Basic idea is to align line number to the right and to make</span>
<span class="c1">;; height of linum dependent of total line numbers.</span>
<span class="p">(</span><span class="nb">defun</span> <span class="nv">linum-format-func</span> <span class="p">(</span><span class="nv">line</span><span class="p">)</span>
<span class="s">"Format LINE for 'linum-mode'."</span>
<span class="p">(</span><span class="k">let</span> <span class="p">((</span><span class="nv">w</span> <span class="p">(</span><span class="nb">length</span> <span class="p">(</span><span class="nv">number-to-string</span> <span class="p">(</span><span class="nv">count-lines</span> <span class="p">(</span><span class="nv">point-min</span><span class="p">)</span> <span class="p">(</span><span class="nv">point-max</span><span class="p">))))))</span>
<span class="p">(</span><span class="nv">propertize</span> <span class="p">(</span><span class="nb">format</span> <span class="p">(</span><span class="nb">format</span> <span class="s">"%%%dd%c"</span> <span class="nv">w</span> <span class="nv">?\x2007</span><span class="p">)</span> <span class="nv">line</span><span class="p">)</span> <span class="ss">'face</span> <span class="ss">'linum</span><span class="p">)))</span>
<span class="c1">;; Set last function as linum formatter</span>
<span class="p">(</span><span class="k">setq</span> <span class="nv">linum-format</span> <span class="ss">'linum-format-func</span><span class="p">)</span>
<span class="c1">;; before loading new theme</span>
<span class="p">(</span><span class="nb">defun</span> <span class="nv">load-theme--disable-old-theme</span><span class="p">(</span><span class="nv">theme</span> <span class="k">&rest</span> <span class="nv">args</span><span class="p">)</span>
<span class="s">"Disable current theme before loading new one."</span>
<span class="p">(</span><span class="nb">mapcar</span> <span class="nf">#'</span><span class="nv">disable-theme</span> <span class="nv">custom-enabled-themes</span><span class="p">))</span>
<span class="p">(</span><span class="nv">advice-add</span> <span class="ss">'load-theme</span> <span class="ss">:before</span> <span class="nf">#'</span><span class="nv">load-theme--disable-old-theme</span><span class="p">)</span>
<span class="c1">;; After loading new theme</span>
<span class="p">(</span><span class="nb">defun</span> <span class="nv">load-theme--restore-line-numbering</span><span class="p">(</span><span class="nv">theme</span> <span class="k">&rest</span> <span class="nv">args</span><span class="p">)</span>
<span class="s">"Set linum-format again after loading any theme."</span>
<span class="p">(</span><span class="k">setq</span> <span class="nv">linum-format</span> <span class="ss">'linum-format-func</span><span class="p">))</span>
<span class="p">(</span><span class="nv">advice-add</span> <span class="ss">'load-theme</span> <span class="ss">:after</span> <span class="nf">#'</span><span class="nv">load-theme--restore-line-numbering</span><span class="p">)</span>
</code></pre>
<h2 id="old-defadvice">Old <code>defadvice</code></h2>
<p>There are few examples on the Internet of doing this in Emacs with <code>defadvice</code>. That is old version of <code>advice-add</code> and it's deprecated. There is <a href="https://www.gnu.org/software/emacs/manual/html_node/elisp/Porting-old-advices.html">one chapter</a> in Emacs manual that explains how to port old <code>defadvice</code> code to <code>add-advice</code>. At the moment of writing of this article, <code>defadvice</code> is still working in <abbr title="GNU is Not Unix">GNU</abbr> Emacs.</p>
Using display-buffer-alisthttps://www.simplify.ba/articles/2016/01/25/display-buffer-alist/2016-01-25T22:10:00+01:002016-02-28T10:35:30+01:00Saša Jovanić<p><abbr title="GNU is Not Unix">GNU</abbr> Emacs is editor of my choice for decade and a half. My usual work flow is to have 3 windows in one singe frame. Most of the time I use <abbr title="GNU is Not Unix">GNU</abbr> Emacs in terminal, so multiple frames are not an option. Also, with limited space in terminal, 3 windows are just enough.</p>
<p>This is how I split frame into 3 windows:</p>
<pre class="highlight plaintext"><code>-----------------------------
| Main editing area | shell |
| |-------|
| | rest |
-----------------------------
</code></pre>
<p>'Main editing area' is window where I actually edit files. 'Shell' is where I run <code>eshell</code> with <code>guard</code>, <code>gulp watch</code> or other automated build/test process. Last window, labeled 'rest', is what this article is about. That window I use for displaying help, flycheck errors, <abbr title="GNU is Not Unix">GNU</abbr> Emacs completions, ELDoc, etc…</p>
<h2 id="splitting-windows">Splitting windows</h2>
<p>This is part of my <code>.emacs</code> configuration (comments added for clarification):</p>
<pre class="highlight common_lisp"><code><span class="p">(</span><span class="nb">defun</span> <span class="nv">sasa/split-windows</span><span class="p">()</span>
<span class="s">"Split windows my way."</span>
<span class="p">(</span><span class="nv">interactive</span><span class="p">)</span>
<span class="c1">;; Create new window right of the current one</span>
<span class="c1">;; Current window is 80 characters (columns) wide</span>
<span class="p">(</span><span class="nv">split-window-right</span> <span class="mi">80</span><span class="p">)</span>
<span class="c1">;; Go to next window</span>
<span class="p">(</span><span class="nv">other-window</span> <span class="mi">1</span><span class="p">)</span>
<span class="c1">;; Create new window below current one</span>
<span class="p">(</span><span class="nv">split-window-below</span><span class="p">)</span>
<span class="c1">;; Start eshell in current window</span>
<span class="p">(</span><span class="nv">eshell</span><span class="p">)</span>
<span class="c1">;; Go to previous window</span>
<span class="p">(</span><span class="nv">other-window</span> <span class="mi">-1</span><span class="p">)</span>
<span class="c1">;; never open any buffer in window with shell</span>
<span class="p">(</span><span class="nv">set-window-dedicated-p</span> <span class="p">(</span><span class="nb">nth</span> <span class="mi">1</span> <span class="p">(</span><span class="nv">window-list</span><span class="p">))</span> <span class="no">t</span><span class="p">))</span>
</code></pre>
<h2 id="special-buffers-for-display-buffer-alist">Special buffers for display-buffer-alist</h2>
<p>Before <abbr title="GNU is Not Unix">GNU</abbr> Emacs 24.X i have used <code>special-display-regexp</code> and <code>special-display-function</code>, but those are deprecated now. New way to choose where to display specific buffer is to use <code>display-buffer-alist</code>. Unfortunately, documentation is not clear and good examples are almost impossible to find. Here is what I manage to create after some research and testing.</p>
<pre class="highlight common_lisp"><code><span class="p">(</span><span class="nb">defun</span> <span class="nv">sasa/display-buffer</span> <span class="p">(</span><span class="nv">buffer</span> <span class="k">&optional</span> <span class="nv">alist</span><span class="p">)</span>
<span class="s">"Select window for BUFFER (need to use word ALIST on the first line).
Returns thirth visible window if there are three visible windows, nil otherwise.
Minibuffer is ignored."</span>
<span class="p">(</span><span class="k">let</span> <span class="p">((</span><span class="nv">wnr</span> <span class="p">(</span><span class="k">if</span> <span class="p">(</span><span class="nv">active-minibuffer-window</span><span class="p">)</span> <span class="mi">3</span> <span class="mi">2</span><span class="p">)))</span>
<span class="p">(</span><span class="nb">when</span> <span class="p">(</span><span class="nb">=</span> <span class="p">(</span><span class="nb">+</span> <span class="nv">wnr</span> <span class="mi">1</span><span class="p">)</span> <span class="p">(</span><span class="nb">length</span> <span class="p">(</span><span class="nv">window-list</span><span class="p">)))</span>
<span class="p">(</span><span class="k">let</span> <span class="p">((</span><span class="nv">window</span> <span class="p">(</span><span class="nb">nth</span> <span class="nv">wnr</span> <span class="p">(</span><span class="nv">window-list</span><span class="p">))))</span>
<span class="p">(</span><span class="nv">set-window-buffer</span> <span class="nv">window</span> <span class="nv">buffer</span><span class="p">)</span>
<span class="nv">window</span><span class="p">)))</span>
<span class="p">)</span>
<span class="p">(</span><span class="nb">defvar</span> <span class="nv">sasa/help-temp-buffers</span> <span class="o">'</span><span class="p">(</span><span class="s">"^\\*Flycheck errors\\*$"</span>
<span class="s">"^\\*Completions\\*$"</span>
<span class="s">"^\\*Help\\*$"</span>
<span class="c1">;; Other buffers names...</span>
<span class="s">"^\\*Colors\\*$"</span>
<span class="s">"^\\*Async Shell Command\\*$"</span><span class="p">))</span>
<span class="p">(</span><span class="nv">while</span> <span class="nv">sasa/help-temp-buffers</span>
<span class="p">(</span><span class="nv">add-to-list</span> <span class="ss">'display-buffer-alist</span>
<span class="o">`</span><span class="p">(</span><span class="o">,</span><span class="p">(</span><span class="nb">car</span> <span class="nv">sasa/help-temp-buffers</span><span class="p">)</span>
<span class="p">(</span><span class="nv">display-buffer-reuse-window</span>
<span class="nv">sasa/display-buffer</span>
<span class="nv">display-buffer-in-side-window</span><span class="p">)</span>
<span class="p">(</span><span class="nv">reusable-frames</span> <span class="o">.</span> <span class="nv">visible</span><span class="p">)</span>
<span class="p">(</span><span class="nv">side</span> <span class="o">.</span> <span class="nv">bottom</span><span class="p">)</span>
<span class="p">(</span><span class="nv">window-height</span> <span class="o">.</span> <span class="mf">0.33</span><span class="p">)</span>
<span class="p">))</span>
<span class="p">(</span><span class="k">setq</span> <span class="nv">sasa/help-temp-buffers</span> <span class="p">(</span><span class="nb">cdr</span> <span class="nv">sasa/help-temp-buffers</span><span class="p">)))</span>
</code></pre>
<p>Lets ignore <code>sasa/display-buffer</code> function for a moment and concentrate on the rest of the code. <code>sasa/help-temp-buffers</code> is a list of regular expressions for buffer names. In while loop I'm adding those regular expressions into <code>display-buffer-alist</code> list. That list takes, except regular expression, list of display functions and display options.</p>
<p><code>display-buffer-reuse-window</code> will try to display buffer in the window that already displays buffer with a same name. if not, next display function will be called.</p>
<p><code>sasa/display-buffer</code> will display buffer in window that I previously called <code>rest</code>, but only if there are 3 windows. Sometimes, there are actually 4 windows. In <code>*Completion*</code>, for example, mini-buffer is also in <code>window-list</code>, always in first place. In that case we need to open buffer on the fourth window, not third. If there are no three windows, function will return <code>nil</code> and next display function is called.</p>
<p><code>display-buffer-in-side-window</code> will pop up new window, based on provided options: on the bottom of the frame and take about 33% of available height.</p>
Evaluating Emacs Lisphttps://www.simplify.ba/articles/2016/01/20/evaluating-emacs-lisp/2016-01-20T12:09:23+01:002016-02-17T15:27:03+01:00Saša Jovanić<p>Evaluating your Emacs Lisp code when editing your <abbr title="GNU is Not Unix">GNU</abbr> Emacs configuration or working on some package is best way to see what are you doing.</p>
<h2 id="scratch">*scratch*</h2>
<p>When you start <abbr title="GNU is Not Unix">GNU</abbr> Emacs, one of the open buffers is *scratch* buffer. When you open it you'll see following message, that explain it:</p>
<pre class="highlight common_lisp"><code><span class="c1">;; This buffer is for notes you don't want to save, and for Lisp evaluation.</span>
<span class="c1">;; If you want to create a file, visit that file with C-x C-f,</span>
<span class="c1">;; then enter the text in that file's own buffer.</span>
</code></pre>
<p>You can disable this message by setting:</p>
<pre class="highlight common_lisp"><code><span class="p">(</span><span class="k">setq</span> <span class="nv">initial-scratch-message</span> <span class="no">nil</span><span class="p">)</span>
</code></pre>
<p>You can type some Emacs lisp code in *scratch*, for example <code>(+ 1 2)</code> and place cursor after ')'. Then press <kbd>C-j</kbd> and '4' will appear in *scratch* buffer. If you want to display result in minibuffer you can press <kbd>C-x C-e</kbd> <code>(eval-last-sexp)</code>.</p>
<h2 id="minibuffer">Minibuffer</h2>
<p>You can evaluate Emacs lisp code in minibuffer. Just press <kbd>M-:</kbd> and you'll get prompt to enter elisp code in minibuffer. Result is displayed in echo area and in *Messages* buffer.</p>
<h2 id="inferior-emacs-lisp-mode">Inferior Emacs Lisp mode</h2>
<p>Both *scratch* and minibuffer have their limitations and they are useful only for small code chunks. They can not replace real <abbr title="Read Execute Print Loop">REPL</abbr> like a <strong>Inferior Emacs Lisp mode</strong>.</p>
<p>You can start Inferior Emacs Lisp mode it with <kbd>M-x ielm</kbd>. It behaves like a any <abbr title="Read Execute Print Loop">REPL</abbr> you are familiar with. Just type some Emacs lisp code and press enter. Great for exploring Emacs lisp!</p>
<h2 id="evaluating-emacs-lisp-files">Evaluating Emacs lisp files</h2>
<p>When you work on Emacs lisp files (.el), you can use <kbd>C-x C-e</kbd> same as in *scratch* buffer. Limitations are the same, you can not for example change variables made with defvar, etc…</p>
<p>One of the most handy evaluation command is <kbd>M-x eval-defun</kbd> or <kbd>C-M-x</kbd>. It evaluates any Emacs lisp form where point (cursor) is located or form before point. Despite <code>defun</code> in name, you can evaluate any Emacs lisp form: <code>defvar</code>, <code>defface</code>, etc… This evaluation displays the result value in echo area. Just be aware that running this on <code>defvar</code> will reset that variable to value of that form.</p>
<p>You can evaluate only part of the buffer by marking specific part (same way you do copying in <abbr title="GNU is Not Unix">GNU</abbr> Emacs) and by typing <kbd>M-x eval-region</kbd>. I can't remember when I used this one.</p>
<p>Other handy evaluation command is <code>eval-buffer</code>. You can run it with <kbd>M-x eval-buffer</kbd>. As the name says, it evaluate whole buffer. I bind this to <kbd>C-c C-b</kbd> in my configuration files:</p>
<pre class="highlight common_lisp"><code><span class="p">(</span><span class="nv">global-set-key</span> <span class="p">(</span><span class="nv">kbd</span> <span class="s">"C-c C-b"</span><span class="p">)</span> <span class="ss">'eval-buffer</span><span class="p">)</span>
</code></pre>
<p>You can find value of an variable by typing <kbd>C-h v</kbd>. You will then get prompt to type variable name. If your point (cursor) is placed on an variable in Emacs lisp buffer, that variable will be default, so you can just press <kbd>Enter</kbd>. You then get *Help* popup window with variable value and description.</p>
<p>Sometimes you'll need to set variable value in <abbr title="GNU is Not Unix">GNU</abbr> Emacs. You can do it in minibuffer, as described above, with <kbd>M-:</kbd> <code>(setq your-variable t)</code>. However, if you see that variable in buffer, place point on it and change it using <kbd>M-x set-variable</kbd>. It's just a bit faster.</p>
<p>That's is. Whole Emacs lisp evaluation is basically a few commands. Easy to remember and use.</p>