You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

349 lines
40 KiB

<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom" ><generator uri="https://jekyllrb.com/" version="3.4.3">Jekyll</generator><link href="https://emacs.cafe/feed.xml" rel="self" type="application/atom+xml" /><link href="https://emacs.cafe/" rel="alternate" type="text/html" /><updated>2017-06-14T10:02:44+02:00</updated><id>https://emacs.cafe/</id><title type="html">Emacs café</title><subtitle>A blog about Emacs, mostly focused on JavaScript development, by Nicolas Petton.
</subtitle><entry><title type="html">Indium 0.6 is out!</title><link href="https://emacs.cafe/indium/emacs/javascript/2017/05/31/indium-0.6-released.html" rel="alternate" type="text/html" title="Indium 0.6 is out!" /><published>2017-05-31T15:10:00+02:00</published><updated>2017-05-31T15:10:00+02:00</updated><id>https://emacs.cafe/indium/emacs/javascript/2017/05/31/indium-0.6-released</id><content type="html" xml:base="https://emacs.cafe/indium/emacs/javascript/2017/05/31/indium-0.6-released.html">&lt;p&gt;&lt;a href=&quot;https://github.com/NicolasPetton/Indium&quot;&gt;Indium&lt;/a&gt; – the JavaScript development
environment for Emacs – version 0.6 has just been released!&lt;/p&gt;
&lt;p&gt;This release brings a lot of improvements and polish:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The stepping debugger now shows exceptions inline in the source;&lt;/li&gt;
&lt;li&gt;Breakpoints can now be &lt;a href=&quot;https://indium.readthedocs.io/en/latest/&quot;&gt;activated and deactivated&lt;/a&gt;;&lt;/li&gt;
&lt;li&gt;Indium supports &lt;a href=&quot;https://indium.readthedocs.io/en/latest/code-evaluation.html#adding-and-removing-breakpoints&quot;&gt;live code updates&lt;/a&gt; (hot-swapping JavaScript);&lt;/li&gt;
&lt;li&gt;NodeJS integration has been &lt;a href=&quot;https://indium.readthedocs.io/en/latest/setup.html#nodejs&quot;&gt;greatly improved&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Installation and update instructions can be found in
the &lt;a href=&quot;https://indium.readthedocs.io/en/latest/&quot;&gt;documentation&lt;/a&gt;. You can also check out the project on &lt;a href=&quot;https://github.com/NicolasPetton/Indium&quot;&gt;GitHub&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Many thanks to &lt;a href=&quot;https://github.com/TatriX&quot;&gt;Tatrix&lt;/a&gt; for his contributions to this release!&lt;/p&gt;</content><author><name>Nicolas Petton</name></author><summary type="html">Indium – the JavaScript development environment for Emacs – version 0.6 has just been released!</summary></entry><entry><title type="html">How to find all unused functions in JS buffers</title><link href="https://emacs.cafe/emacs/javascript/2017/05/12/finding-unused-functions.html" rel="alternate" type="text/html" title="How to find all unused functions in JS buffers" /><published>2017-05-12T14:43:00+02:00</published><updated>2017-05-12T14:43:00+02:00</updated><id>https://emacs.cafe/emacs/javascript/2017/05/12/finding-unused-functions</id><content type="html" xml:base="https://emacs.cafe/emacs/javascript/2017/05/12/finding-unused-functions.html">&lt;p&gt;The real power of Emacs lies in its extensibility. To be able to quickly hack
some Elisp together to fix a specific problem right in your development
environment is something quite unique to Emacs, and it makes it stand apart from
other text editors.&lt;/p&gt;
&lt;p&gt;I’m working on a fairly large JavaScript code base for which maintenance can
sometimes be an issue.&lt;/p&gt;
&lt;p&gt;Yesterday I wanted to quickly find all function definitions in a JavaScript file
that were not referenced anymore in the project, so I decided to hack some
Elisp to do that.&lt;/p&gt;
&lt;h2 id=&quot;what-do-we-already-have&quot;&gt;What do we already have?&lt;/h2&gt;
&lt;p&gt;Let’s see what building blocks are already available.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://github.com/nicolaspetton/xref-js2&quot;&gt;xref-js2&lt;/a&gt; makes it easy to find all
references to a specific function within a project,
and &lt;a href=&quot;https://github.com/mooz/js2-mode&quot;&gt;js2-mode&lt;/a&gt; exposes an AST that can be
visited.&lt;/p&gt;
&lt;p&gt;All in all, what I want to achieve shouldn’t be too hard to implement!&lt;/p&gt;
&lt;h2 id=&quot;first-steps&quot;&gt;First steps&lt;/h2&gt;
&lt;p&gt;I’m calling my small package &lt;code class=&quot;highlighter-rouge&quot;&gt;js2-unused&lt;/code&gt;, so all functions and variables will
have that prefix.&lt;/p&gt;
&lt;p&gt;We’ll need some packages along the way, so let’s require them:&lt;/p&gt;
&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-elisp&quot; data-lang=&quot;elisp&quot;&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;require&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;'seq&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;require&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;'xref-js2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;require&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;'subr-x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;
&lt;p&gt;The first step is to find all function definitions within the current buffer.
&lt;code class=&quot;highlighter-rouge&quot;&gt;JS2-mode&lt;/code&gt; has a function &lt;code class=&quot;highlighter-rouge&quot;&gt;js2-visit-ast&lt;/code&gt; that makes it really easy to traverse
the entire AST tree.&lt;/p&gt;
&lt;p&gt;We can first define a variable that will hold all function definition names that
we find:&lt;/p&gt;
&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-elisp&quot; data-lang=&quot;elisp&quot;&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;defvar&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;js2-unused-definitions&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;nil&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;
&lt;p&gt;Now let’s traverse the AST and find all function definitions. We want to find:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;all assignments that assign to a function;&lt;/li&gt;
&lt;li&gt;all function declarations that are named (skipping anonymous functions).&lt;/li&gt;
&lt;/ul&gt;
&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-elisp&quot; data-lang=&quot;elisp&quot;&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;defun&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;js2-unused--find-definitions&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;;; Reset the value before visiting the AST&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;setq&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;js2-unused-definitions&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;nil&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;js2-visit-ast&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;js2-mode-ast&lt;/span&gt;
&lt;span class=&quot;nf&quot;&gt;#'&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;js2-unused-visitor&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;defun&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;js2-unused-visitor&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;node&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;end-p&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;s&quot;&gt;&quot;Add NODE's name to `js2-unused-definitions` if it is a function.&quot;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;unless&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;end-p&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;cond&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;;; assignment to a function&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;((&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;and&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;js2-assign-node-p&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;node&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;js2-function-node-p&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;js2-assign-node-right&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;node&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)))&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;push&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;js2-node-string&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;js2-assign-node-left&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;node&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;js2-unused-definitions&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;;; function declaration (skipping anonymous ones)&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;((&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;js2-function-node-p&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;node&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;if-let&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;((&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;name&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;js2-function-name&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;node&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)))&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;push&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;name&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;js2-unused-definitions&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))))&lt;/span&gt;
&lt;span class=&quot;no&quot;&gt;t&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;
&lt;h2 id=&quot;finding-references-using-xref-js2&quot;&gt;Finding references using xref-js2&lt;/h2&gt;
&lt;p&gt;Now that we can find and store all function names in a list, let’s use
&lt;code class=&quot;highlighter-rouge&quot;&gt;xref-js2&lt;/code&gt; to filter the ones that are never referenced. If we find
unreferenced functions, we simply display a message listing them.&lt;/p&gt;
&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-elisp&quot; data-lang=&quot;elisp&quot;&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;defun&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;js2-unused-functions&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;interactive&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;;; Make sure that JS2 has finished parsing the buffer&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;js2-mode-wait-for-parse&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;lambda&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;;; Walk the AST tree to find all function definitions&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;js2-unused--find-definitions&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;;; Use xref-js2 to filter the ones that are not referenced anywhere&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;((&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;unused&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;seq-filter&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;lambda&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;null&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;xref-js2--find-references&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;js2-unused--unqualified-name&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))))&lt;/span&gt;
&lt;span class=&quot;nv&quot;&gt;js2-unused-definitions&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)))&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;;; If there are unreferenced function, display a message&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;apply&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;#'&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;message&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;unused&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;`&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Unused functions in %s: %s &quot;&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;file-name-nondirectory&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;buffer-file-name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;mapconcat&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;#'&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;identity&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;unused&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot; &quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;No unused function found&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)))))))&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;defun&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;js2-unused--unqualified-name&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;s&quot;&gt;&quot;Return the local name of NAME.
foo.bar.baz =&amp;gt; baz&quot;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;save-match-data&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;string-match&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;\\.\\([^.]+\\)$&quot;&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;match-string&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;nv&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)))&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;
&lt;h2 id=&quot;conclusion&quot;&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;That’s it! In ~30 lines we can now find unreferenced functions in any JS file.
Sure, the code is not perfect, far from it, but it was hacked together in 10
minutes and gets the job done.&lt;/p&gt;
&lt;p&gt;Quickly writing some lisp code to fix a specific problem is something I do very
often. Most of the time, it’s code I throw away as soon as the task is
completed, but from time to time it’s something generic enough to be reused
later, in which case I save it in my &lt;code class=&quot;highlighter-rouge&quot;&gt;emacs.d&lt;/code&gt;, or make a proper package out of
it.&lt;/p&gt;
&lt;p&gt;If you find this feature useful, you can grab it from
my
&lt;a href=&quot;https://gitlab.petton.fr/nico/emacs.d/blob/master/local-packages/js2-unused.el&quot;&gt;emacs.d&lt;/a&gt;.&lt;/p&gt;</content><author><name>Nicolas Petton</name></author><summary type="html">The real power of Emacs lies in its extensibility. To be able to quickly hack some Elisp together to fix a specific problem right in your development environment is something quite unique to Emacs, and it makes it stand apart from other text editors.</summary></entry><entry><title type="html">Setting up Emacs for JavaScript (part #2)</title><link href="https://emacs.cafe/emacs/javascript/setup/2017/05/09/emacs-setup-javascript-2.html" rel="alternate" type="text/html" title="Setting up Emacs for JavaScript (part #2)" /><published>2017-05-09T17:00:00+02:00</published><updated>2017-05-09T17:00:00+02:00</updated><id>https://emacs.cafe/emacs/javascript/setup/2017/05/09/emacs-setup-javascript-2</id><content type="html" xml:base="https://emacs.cafe/emacs/javascript/setup/2017/05/09/emacs-setup-javascript-2.html">&lt;p&gt;This is the second part of my series of articles describing how to make Emacs a
great JavaScript development environment. This time we’ll focus on getting good
auto-completion with type inference.&lt;/p&gt;
&lt;p&gt;If you haven’t read it yet, you should jump to
the &lt;a href=&quot;/emacs/javascript/setup/2017/04/23/emacs-setup-javascript.html&quot;&gt;first post&lt;/a&gt;
first to get things started.&lt;/p&gt;
&lt;h2 id=&quot;setting-up-tern--company-mode-for-auto-completion&quot;&gt;Setting up Tern &amp;amp; company-mode for auto-completion&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;https://ternjs.net&quot;&gt;Tern&lt;/a&gt; is a great tool once setup correctly. It parses
JavaScript files in a project and does type inference to provide meaningful
completion (with type hints) and support for cross-references.&lt;/p&gt;
&lt;p&gt;Unfortunately, cross-references with tern never reliably worked for me, that’s
why I have always been
using &lt;a href=&quot;https://github.com/nicolaspetton/xref-js2&quot;&gt;xref-js2&lt;/a&gt; instead for that
(see &lt;a href=&quot;/emacs/javascript/setup/2017/04/23/emacs-setup-javascript.html&quot;&gt;part #1&lt;/a&gt;).&lt;/p&gt;
&lt;p&gt;For auto-completion, we’ll be using company-mode with tern. Let’s go ahead and
install tern:&lt;/p&gt;
&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;$ sudo npm install -g tern
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;Now let’s install the Emacs packages:&lt;/p&gt;
&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;M-x package-install RET company-tern RET
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;The Emacs configuration is straight-forward, we simply enable company-mode with
the tern backend for JavaScript buffers:&lt;/p&gt;
&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-elisp&quot; data-lang=&quot;elisp&quot;&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;require&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;'company-mode&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;require&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;'company-tern&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;add-to-list&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;'company-backends&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;'company-tern&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;add-hook&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;'js2-mode-hook&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;lambda&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;tern-mode&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;company-mode&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)))&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;;; Disable completion keybindings, as we use xref-js2 instead&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;define-key&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;tern-mode-keymap&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;kbd&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;M-.&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;nil&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;define-key&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;tern-mode-keymap&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;kbd&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;M-,&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;nil&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;
&lt;p&gt;Now, depending on your JavaScript project, you might want to setup tern to work
with your project structure. If completion doesn’t work out of the box using
tern defaults you will have to set it up using a &lt;code class=&quot;highlighter-rouge&quot;&gt;.tern-project&lt;/code&gt; placed in the
root folder containing your JavaScript files.&lt;/p&gt;
&lt;p&gt;Here’s an example setup for a project that uses &lt;code class=&quot;highlighter-rouge&quot;&gt;requirejs&lt;/code&gt; and &lt;code class=&quot;highlighter-rouge&quot;&gt;jQuery&lt;/code&gt;,
ignoring files from the &lt;code class=&quot;highlighter-rouge&quot;&gt;bower_components&lt;/code&gt; directory:&lt;/p&gt;
&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-json&quot; data-lang=&quot;json&quot;&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&quot;libs&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;jquery&quot;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&quot;loadEagerly&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;./**/*.js&quot;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&quot;dontLoad&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;./bower_components/&quot;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&quot;plugins&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&quot;requirejs&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&quot;baseURL&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;./&quot;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;
&lt;p&gt;Once setup, tern offers superb completion. Together with company-mode, you get
great context-based completion with type inference.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/img/tern-company-mode.png&quot; alt=&quot;Ternjs&quot; /&gt;&lt;/p&gt;
&lt;p&gt;When completing a function, you can hit &lt;code class=&quot;highlighter-rouge&quot;&gt;&amp;lt;F1&amp;gt;&lt;/code&gt; to get its documentation:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/img/tern-documentation.png&quot; alt=&quot;Ternjs documentation&quot; /&gt;&lt;/p&gt;
&lt;h2 id=&quot;until-next-time&quot;&gt;Until next time&lt;/h2&gt;
&lt;p&gt;In the next articles I’ll cover linting with Flycheck, &lt;code class=&quot;highlighter-rouge&quot;&gt;gulp&lt;/code&gt; and &lt;code class=&quot;highlighter-rouge&quot;&gt;grunt&lt;/code&gt;
integration into Emacs, and of course how to setup and
use &lt;a href=&quot;https://indium.readthedocs.io&quot;&gt;Indium&lt;/a&gt;.&lt;/p&gt;</content><author><name>Nicolas Petton</name></author><summary type="html">This is the second part of my series of articles describing how to make Emacs a great JavaScript development environment. This time we’ll focus on getting good auto-completion with type inference.</summary></entry><entry><title type="html">Setting up Emacs for JavaScript (part #1)</title><link href="https://emacs.cafe/emacs/javascript/setup/2017/04/23/emacs-setup-javascript.html" rel="alternate" type="text/html" title="Setting up Emacs for JavaScript (part #1)" /><published>2017-04-23T14:50:00+02:00</published><updated>2017-04-23T14:50:00+02:00</updated><id>https://emacs.cafe/emacs/javascript/setup/2017/04/23/emacs-setup-javascript</id><content type="html" xml:base="https://emacs.cafe/emacs/javascript/setup/2017/04/23/emacs-setup-javascript.html">&lt;p&gt;There’s a lot that can be done to make Emacs a great tool for JavaScript
development. So much that I had to split it up into several posts.&lt;/p&gt;
&lt;p&gt;In this first article we’ll see how to
setup &lt;a href=&quot;https://github.com/mooz/js2-mode&quot;&gt;js2-mode&lt;/a&gt; and two other packages that
rely upon it: &lt;a href=&quot;https://github.com/magnars/js2-refactor.el&quot;&gt;js2-refactor&lt;/a&gt;
and &lt;a href=&quot;https://github.com/nicolaspetton/xref-js2&quot;&gt;xref-js2&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Emacs comes with a major mode for JavaScript named &lt;code class=&quot;highlighter-rouge&quot;&gt;js-mode&lt;/code&gt;. While it is a
good major mode, we’ll be using &lt;code class=&quot;highlighter-rouge&quot;&gt;js2-mode&lt;/code&gt; instead, an external package that
extends &lt;code class=&quot;highlighter-rouge&quot;&gt;js-mode&lt;/code&gt; and provides a very interesting feature: instead of using
regular expressions, it parses buffers and builds an AST for things like syntax
highlighting. While diverging a bit from the traditional “Emacs way of doing
things”, this is really interesting, and used as the foundation for other
features like refactorings.&lt;/p&gt;
&lt;h2 id=&quot;setting-up-js2-mode&quot;&gt;Setting up js2-mode&lt;/h2&gt;
&lt;p&gt;If you haven’t done it already, you should first setup &lt;code class=&quot;highlighter-rouge&quot;&gt;package.el&lt;/code&gt; to
use &lt;a href=&quot;https://melpa.org&quot;&gt;MELPA&lt;/a&gt;, then install and setup &lt;code class=&quot;highlighter-rouge&quot;&gt;js2-mode&lt;/code&gt; like the
following:&lt;/p&gt;
&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;M-x package-install RET js2-mode RET
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-elisp&quot; data-lang=&quot;elisp&quot;&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;require&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;'js2-mode&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;add-to-list&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;'auto-mode-alist&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;\\.js\\'&quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;js2-mode&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;;; Better imenu&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;add-hook&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;'js2-mode-hook&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;#'&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;js2-imenu-extras-mode&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;
&lt;h2 id=&quot;js2-refactor-and-xref-js2&quot;&gt;js2-refactor and xref-js2&lt;/h2&gt;
&lt;p&gt;Now that we’re using &lt;code class=&quot;highlighter-rouge&quot;&gt;js2-mode&lt;/code&gt; for JavaScript buffers, let’s take advantage its
capabilities of and install two other
packages: &lt;a href=&quot;https://github.com/magnars/js2-refactor.el&quot;&gt;js2-refactor&lt;/a&gt;
and &lt;a href=&quot;https://github.com/nicolaspetton/xref-js2&quot;&gt;xref-js2&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;js2-refactor&lt;/code&gt; adds powerful refactorings based on the AST generated by
&lt;code class=&quot;highlighter-rouge&quot;&gt;js2-mode&lt;/code&gt;, and &lt;code class=&quot;highlighter-rouge&quot;&gt;xref-js2&lt;/code&gt; makes it easy to jump to function references or
definitions.&lt;/p&gt;
&lt;p&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;xref-js2&lt;/code&gt; uses &lt;code class=&quot;highlighter-rouge&quot;&gt;ag&lt;/code&gt; to perform searches, so you’ll need to install it as well.&lt;/p&gt;
&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;M-x package-install RET js2-refactor RET
M-x package-install RET xref-js2 RET
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-elisp&quot; data-lang=&quot;elisp&quot;&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;require&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;'js2-refactor&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;require&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;'xref-js2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;add-hook&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;'js2-mode-hook&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;#'&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;js2-refactor-mode&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;js2r-add-keybindings-with-prefix&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;C-c C-r&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;define-key&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;js2-mode-map&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;kbd&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;C-k&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;#'&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;js2r-kill&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;;; js-mode (which js2 is based on) binds &quot;M-.&quot; which conflicts with xref, so&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;;; unbind it.&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;define-key&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;js-mode-map&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;kbd&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;M-.&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;nil&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;add-hook&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;'js2-mode-hook&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;lambda&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;add-hook&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;'xref-backend-functions&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;#'&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;xref-js2-xref-backend&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;nil&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;t&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)))&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;
&lt;p&gt;Now that everything’s setup, let’s see how to use &lt;code class=&quot;highlighter-rouge&quot;&gt;js2-refactor&lt;/code&gt; and &lt;code class=&quot;highlighter-rouge&quot;&gt;xref-js2&lt;/code&gt;.&lt;/p&gt;
&lt;h2 id=&quot;using-js2-refactor&quot;&gt;Using js2-refactor&lt;/h2&gt;
&lt;p&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;js2-refactor&lt;/code&gt; is a JavaScript refactoring library for emacs.&lt;/p&gt;
&lt;p&gt;It provides a collection of refactoring functions leveraging the AST provided by
&lt;code class=&quot;highlighter-rouge&quot;&gt;js2-mode&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Refactorings go from inlining/extracting variables to converting ternary
operators to if statements.
The &lt;a href=&quot;https://github.com/magnars/js2-refactor.el&quot;&gt;README&lt;/a&gt; provides the full list of
keybindings.&lt;/p&gt;
&lt;p&gt;One minor tweak that I really couldn’t live without is binding &lt;code class=&quot;highlighter-rouge&quot;&gt;js2r-kill&lt;/code&gt; to
&lt;code class=&quot;highlighter-rouge&quot;&gt;C-k&lt;/code&gt; in JS buffers:&lt;/p&gt;
&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-elisp&quot; data-lang=&quot;elisp&quot;&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;define-key&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;js2-mode-map&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;kbd&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;C-k&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;#'&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;js2r-kill&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;
&lt;p&gt;This command is very similar to killing in &lt;code class=&quot;highlighter-rouge&quot;&gt;paredit&lt;/code&gt;: It kills up to the end of
the line, but always keeping the AST valid.&lt;/p&gt;
&lt;p&gt;Here’s a usage example of &lt;code class=&quot;highlighter-rouge&quot;&gt;js2-refactor&lt;/code&gt;: renaming a function parameter and
inlining a variable.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/img/js2-refactorings.gif&quot; alt=&quot;Refactorings&quot; /&gt;&lt;/p&gt;
&lt;h2 id=&quot;using-xref-js2&quot;&gt;Using xref-js2&lt;/h2&gt;
&lt;p&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;xref-js2&lt;/code&gt; adds support for quickly jumping to function definitions or
references to JavaScript projects in Emacs (&amp;gt;= 25.1).&lt;/p&gt;
&lt;p&gt;Instead of using a tag system, it relies on &lt;code class=&quot;highlighter-rouge&quot;&gt;ag&lt;/code&gt; to query the codebase of a
project.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;M-.&lt;/code&gt; Jump to definition&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;M-?&lt;/code&gt; Jump to references&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;M-,&lt;/code&gt; Pop back to where &lt;code class=&quot;highlighter-rouge&quot;&gt;M-.&lt;/code&gt; was last invoked.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Here’s a usage example of &lt;code class=&quot;highlighter-rouge&quot;&gt;xref-js2&lt;/code&gt;:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/img/xref-jump-to-references.gif&quot; alt=&quot;Jumping to references&quot; /&gt;&lt;/p&gt;
&lt;h2 id=&quot;until-next-time&quot;&gt;Until next time&lt;/h2&gt;
&lt;p&gt;You should now have a decent setup for &lt;code class=&quot;highlighter-rouge&quot;&gt;js2-mode&lt;/code&gt; and associated tools.&lt;/p&gt;
&lt;p&gt;We still have a lot to explore like linting, getting good auto-completion, using
snippets, setting up a REPL and debugger, etc. but I promised I would keep posts
short, so stay tuned for part #2!&lt;/p&gt;</content><author><name>Nicolas Petton</name></author><summary type="html">There’s a lot that can be done to make Emacs a great tool for JavaScript development. So much that I had to split it up into several posts.</summary></entry><entry><title type="html">M-x hello-world</title><link href="https://emacs.cafe/jekyll/update/2017/04/21/hello-world.html" rel="alternate" type="text/html" title="M-x hello-world" /><published>2017-04-21T23:14:09+02:00</published><updated>2017-04-21T23:14:09+02:00</updated><id>https://emacs.cafe/jekyll/update/2017/04/21/hello-world</id><content type="html" xml:base="https://emacs.cafe/jekyll/update/2017/04/21/hello-world.html">&lt;p&gt;All blogs should begin with an introductory post, so here we go.&lt;/p&gt;
&lt;p&gt;I’ve been willing to make a blog dedicated
to &lt;a href=&quot;http://gnu.org/software/emacs&quot;&gt;Emacs&lt;/a&gt; for a long time, but until now I
couldn’t find the right topic.&lt;/p&gt;
&lt;p&gt;This blog will have a focus on using Emacs as an environment for writing
JavaScript. I will talk about Emacs configurations specific to JavaScript and
packages that make Emacs the great and powerful IDE that it is for web
development.&lt;/p&gt;
&lt;p&gt;I’ll try to keep all posts short and to the point, and I’ll most probably post
tutorial videos from time to time.&lt;/p&gt;
&lt;p&gt;Topics might sometimes slip a bit from the original focus, but as long as it’s
about Emacs, I think it’ll be ok.&lt;/p&gt;</content><author><name>Nicolas Petton</name></author><summary type="html">All blogs should begin with an introductory post, so here we go.</summary></entry></feed>