<turbo-stream action="append" target="posts_list"><template>    <div class="postbit" id="359811" data-post-id="359811">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="garrison" src="/assets/icons/user-9f439610.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  garrison
                  </h3>
		          </div>
						
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>Assuming you have already figured out how to install plugins, the instructions for configuring elixirls can be <a href="https://github.com/neovim/nvim-lspconfig/blob/master/doc/configs.md#elixirls" rel="noopener nofollow ugc">found here</a>. The only required config flag is <code>cmd</code>, which is the path where you installed elixirls. If you have elixirls in $PATH, you can just use <code>"elixir-ls"</code> as the command - the brew package installs it this way.</p>
<p>It’s hard to give specific help because the nature of such an open ecosystem is that there are like 30 different valid ways to do something - for example, which of the several popular plugin managers are you using? Are you using lua or vimscript? What is your completions plugin? And so on.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="359811" data-batch-url="/posts/batch_likers">
                        0
                      </span>
                      <!-- <span class="thread-count js-solved-indicator" title="Marked as solution"></span> -->
	                </div>
	                <div class="go-to-post">
	                  <a title="Go to post" alt="Go to post" href="https://forum.elixirforum.com/t/neovim-elixir-setup-configuration-from-scratch-guide/46310/102">Post #101</a>
	                </div>
	            </div>
              <div id="likers-container-359811" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="359811"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-standard-post cat-standard-post" title="Post #101"></div>
  </section>
</div>
    <div class="postbit" id="359815" data-post-id="359815">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="AstonJ" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/AstonJ/120/15_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  AstonJ
                  </h3>
		          </div>
						
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<aside class="quote no-group" data-username="dimitarvp" data-post="97" data-topic="46310">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/dimitarvp/48/38664_2.png" class="avatar"> dimitarvp:</div>
<blockquote>
<p>You are better off using a “distro” like AstroNvim or LazyVim to be honest.</p>
</blockquote>
</aside>
<p>I agree with Dimi - using a distro might make life a lot easier for you. Have a look at what people are using here:</p>
<aside class="quote quote-modified" data-post="1" data-topic="68627">
  <div class="title">
    <div class="quote-controls"></div>
    <img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/astonj/48/15_2.png" class="avatar">
    <div class="quote-title__text-content">
      <a href="https://forum.elixirforum.com/t/which-neovim-configuration-distro-do-you-use-recommend-poll/68627" rel="nofollow">Which Neovim configuration distro do you use/recommend? (Poll)</a> <a class="badge-category__wrapper " href="/c/chat-discussions/polls/112" rel="nofollow"><span data-category-id="112" style="--category-badge-color: #cca771; --category-badge-text-color: #FFFFFF; --parent-category-badge-color: #cca771;" data-parent-category-id="165" data-drop-close="true" class="badge-category --style-square --has-parent"><span class="badge-category__name">Polls</span></span></a>
    </div>
  </div>
  <blockquote>
    Posting this to see if we can make things easier for people to get into Neovim. If you use Neovim and have a favourite distro please let us know! 

You can only pick one - if you like more than one, please pick your favourite and tell us about the other/s in the thread!
If you use a custom configuration, please skip the poll (unless one of them is your favourite, in which case please vote for it) and if possible please let us know about your configuration in the thread and why you prefer it over…
  </blockquote>
</aside>

<p>I started writing instructions by updating my blog post on setting up an Elixir (and Ruby) dev environment, but I haven’t got around to finishing it yet. If you want to have a look <a href="https://astonj.com/how-to-set-up-a-ruby-and-elixir-dev-environment-on-macos-2021/" rel="nofollow">it’s here</a> (if anyone can spot any mistakes please let me know!)</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="359815" data-batch-url="/posts/batch_likers">
                        1
                      </span>
                      <!-- <span class="thread-count js-solved-indicator" title="Marked as solution"></span> -->
	                </div>
	                <div class="go-to-post">
	                  <a title="Go to post" alt="Go to post" href="https://forum.elixirforum.com/t/neovim-elixir-setup-configuration-from-scratch-guide/46310/103">Post #102</a>
	                </div>
	            </div>
              <div id="likers-container-359815" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="359815"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-standard-post cat-standard-post" title="Post #102"></div>
  </section>
</div>
    <div class="postbit" id="359816" data-post-id="359816">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="garrison" src="/assets/icons/user-9f439610.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  garrison
                  </h3>
		          </div>
						
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<aside class="quote no-group" data-username="AstonJ" data-post="103" data-topic="46310">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/astonj/48/15_2.png" class="avatar"> AstonJ:</div>
<blockquote>
<p>I agree with Dimi - using a distro might make life a lot easier for you.</p>
</blockquote>
</aside>
<p>Just to provide another perspective, I am personally not a fan of the number of deps that would be pulled in by a distro and prefer to manage my (very short) plugin list myself. Really this is the whole reason I use nvim - otherwise I would just be using Zed or whatever <img src="https://forum.elixirforum.com/images/emoji/apple/slight_smile.png?v=15" title=":slight_smile:" class="emoji" alt=":slight_smile:" loading="lazy" width="20" height="20"></p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="359816" data-batch-url="/posts/batch_likers">
                        3
                      </span>
                      <!-- <span class="thread-count js-solved-indicator" title="Marked as solution"></span> -->
	                </div>
	                <div class="go-to-post">
	                  <a title="Go to post" alt="Go to post" href="https://forum.elixirforum.com/t/neovim-elixir-setup-configuration-from-scratch-guide/46310/104">Post #103</a>
	                </div>
	            </div>
              <div id="likers-container-359816" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="359816"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-standard-post cat-standard-post" title="Post #103"></div>
  </section>
</div>
    <div class="postbit" id="359916" data-post-id="359916">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="itzmidinesh" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/itzmidinesh/120/34350_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  itzmidinesh
                  </h3>
		          </div>
						
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>I am looking for config help to avoid unnecessary dependencies from distros. My focus is solely on working with Elixir and Phoenix code.</p>
<p>Personalization and other settings can come later. Right now, I just want to set up ElixirLS with auto-completion and Dialyzer working. That’s my main priority.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="359916" data-batch-url="/posts/batch_likers">
                        0
                      </span>
                      <!-- <span class="thread-count js-solved-indicator" title="Marked as solution"></span> -->
	                </div>
	                <div class="go-to-post">
	                  <a title="Go to post" alt="Go to post" href="https://forum.elixirforum.com/t/neovim-elixir-setup-configuration-from-scratch-guide/46310/106">Post #105</a>
	                </div>
	            </div>
              <div id="likers-container-359916" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="359916"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-standard-post cat-standard-post" title="Post #105"></div>
  </section>
</div>
    <div class="postbit" id="359989" data-post-id="359989">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="garrison" src="/assets/icons/user-9f439610.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  garrison
                  </h3>
		          </div>
						
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>For a minimal setup you need a plugin manager, something to configure the lsp, and a completions plugin for autocomplete. If you’re not sure what to go with, a simple setup would be <code>Plug</code> for plugins, <code>nvim-lspconfig</code> to run the LSP, and <code>nvim-cmp</code> for completions. You need <code>cmp-nvim-lsp</code> from the same guy as <code>nvim-cmp</code> to get completions <em>from</em> the LSP, and you probably also want <code>cmp-buffer</code> to get completions from the current file (“buffer” in vim terms).</p>
<p>If you follow the setup guides from each of these you should be able to piece together a basic <code>init.vim</code>. Again there are many different ways to do things. If you get stuck on something just ask on here.</p>
<p><a href="https://github.com/junegunn/vim-plug" rel="noopener nofollow ugc">vim-plug</a>, <a href="https://github.com/neovim/nvim-lspconfig" rel="noopener nofollow ugc">nvim-lspconfig</a>, <a href="https://github.com/hrsh7th/nvim-cmp" rel="noopener nofollow ugc">nvim-cmp</a></p>
<p>In addition to vim stuff you also need to have a working <code>elixir-ls</code> installation. If you’re on a Mac the easiest way is brew, otherwise follow the elixir-ls installation instructions.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="359989" data-batch-url="/posts/batch_likers">
                        2
                      </span>
                      <!-- <span class="thread-count js-solved-indicator" title="Marked as solution"></span> -->
	                </div>
	                <div class="go-to-post">
	                  <a title="Go to post" alt="Go to post" href="https://forum.elixirforum.com/t/neovim-elixir-setup-configuration-from-scratch-guide/46310/107">Post #106</a>
	                </div>
	            </div>
              <div id="likers-container-359989" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="359989"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-standard-post cat-standard-post" title="Post #106"></div>
  </section>
</div>
    <div class="postbit" id="360013" data-post-id="360013">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="nico_amsterdam" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/nico_amsterdam/120/3706_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  nico_amsterdam
                  </h3>
		          </div>
						
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>I use the lazy-vim package manager.<br>
You can get inspiration from my <a href="https://github.com/nico-amsterdam/neovim_config" rel="noopener nofollow ugc">Neovim config</a>.<br>
ElixirLS autocompletions runs via the <a href="https://github.com/elixir-tools/elixir-tools.nvim" rel="noopener nofollow ugc">elixir-tools.nvim</a> plugin.<br>
I have not tried the Dialyzer config in ElixirLS.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="360013" data-batch-url="/posts/batch_likers">
                        1
                      </span>
                      <!-- <span class="thread-count js-solved-indicator" title="Marked as solution"></span> -->
	                </div>
	                <div class="go-to-post">
	                  <a title="Go to post" alt="Go to post" href="https://forum.elixirforum.com/t/neovim-elixir-setup-configuration-from-scratch-guide/46310/108">Post #107</a>
	                </div>
	            </div>
              <div id="likers-container-360013" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="360013"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-standard-post cat-standard-post" title="Post #107"></div>
  </section>
</div>
    <div class="postbit" id="360043" data-post-id="360043">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="adamcstephens" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/adamcstephens/120/24542_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  adamcstephens
                  </h3>
		          </div>
						
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>I recently switched from nvim-cmp to blink. <a href="https://github.com/Saghen/blink.cmp" class="inline-onebox" rel="noopener nofollow ugc">GitHub - saghen/blink.cmp: Performant, batteries-included completion plugin for Neovim · GitHub</a></p>
<p>I find the performance to be better and things like the included snippet support let me drop a handful of packages in the migration.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="360043" data-batch-url="/posts/batch_likers">
                        4
                      </span>
                      <!-- <span class="thread-count js-solved-indicator" title="Marked as solution"></span> -->
	                </div>
	                <div class="go-to-post">
	                  <a title="Go to post" alt="Go to post" href="https://forum.elixirforum.com/t/neovim-elixir-setup-configuration-from-scratch-guide/46310/109">Post #108</a>
	                </div>
	            </div>
              <div id="likers-container-360043" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="360043"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-standard-post cat-standard-post" title="Post #108"></div>
  </section>
</div>
    <div class="postbit" id="360508" data-post-id="360508">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="Nezteb" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/Nezteb/120/30092_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  Nezteb
                  </h3>
		          </div>
						
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>Neovim version 0.11 just released.</p>
<p><a href="https://gpanders.com/blog/whats-new-in-neovim-0-11/#simpler-lsp-setup-and-configuration" rel="noopener nofollow ugc">One of the highlights is “Simpler LSP setup and configuration”</a>.</p>
<p><a href="https://gpanders.com/blog/whats-new-in-neovim-0-11/#virtual-lines" rel="noopener nofollow ugc">Another involves upstreaming LSP virtual lines</a>.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="360508" data-batch-url="/posts/batch_likers">
                        11
                      </span>
                      <!-- <span class="thread-count js-solved-indicator" title="Marked as solution"></span> -->
	                </div>
	                <div class="go-to-post">
	                  <a title="Go to post" alt="Go to post" href="https://forum.elixirforum.com/t/neovim-elixir-setup-configuration-from-scratch-guide/46310/110">Post #109</a>
	                </div>
	            </div>
              <div id="likers-container-360508" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="360508"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-standard-post cat-standard-post" title="Post #109"></div>
  </section>
</div>
    <div class="postbit" id="369251" data-post-id="369251">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="gmile" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/gmile/120/33982_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  gmile
                  </h3>
		          </div>
						
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>FWIW, native <a href="https://github.com/neovim/neovim/pull/34009" rel="noopener nofollow ugc">support for packages</a> is in neovim master branch since last week, in case anyone is brave enough to try that out <img src="https://forum.elixirforum.com/images/emoji/apple/slight_smile.png?v=15" title=":slight_smile:" class="emoji" alt=":slight_smile:" loading="lazy" width="20" height="20"></p>
<p>A tracking issue is available here: <a href="https://github.com/neovim/neovim/issues/34763" class="inline-onebox" rel="noopener nofollow ugc">`vim.pack` improvements · Issue #34763 · neovim/neovim · GitHub</a></p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="369251" data-batch-url="/posts/batch_likers">
                        2
                      </span>
                      <!-- <span class="thread-count js-solved-indicator" title="Marked as solution"></span> -->
	                </div>
	                <div class="go-to-post">
	                  <a title="Go to post" alt="Go to post" href="https://forum.elixirforum.com/t/neovim-elixir-setup-configuration-from-scratch-guide/46310/111">Post #110</a>
	                </div>
	            </div>
              <div id="likers-container-369251" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="369251"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-standard-post cat-standard-post" title="Post #110"></div>
  </section>
</div>
    <div class="postbit" id="371377" data-post-id="371377">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="adamu" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/adamu/120/31482_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  adamu
                  </h3>
		          </div>
						
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>I think I finally have a working setup using the built-in LSP integration.</p>
<p>Things seem to have changed quite a lot since this guide was written, most notably that <code>nvim-lspconfig</code> and <code>nvim-cmp</code> no longer seem to be required. I still had to install <code>nvim-treesitter</code>, though. Here are a few notes from my setup, in case it helps anyone else.</p>
<ol>
<li>Install <code>nvim-treesitter</code>. Also <strong>don’t forget to install the prerequisite CLI via for example <code>brew install tree-sitter-cli</code></strong>. At the time of writing, they are in the process of a complete rewrite on the <code>main</code> branch, and the <code>master</code> one will become unsupported. Also, the docs state that we should run <code>:TSUpdate</code> when updating the plugin, so I set that up too. Using vimplug:<pre data-code-wrap="vim"><code class="lang-vim">Plug 'nvim-treesitter/nvim-treesitter', { 'branch': 'main', 'build': ':TSUpdate' }
require'nvim-treesitter'.install { 'elixir', 'eex', 'heex' }
</code></pre>
</li>
<li>Set up ElixirLS. We need to supply the <code>cmd</code> to tell it where it’s installed, and <code>root_markers</code> so neovim can find the project root.<pre data-code-wrap="lua"><code class="lang-lua"> vim.lsp.config('elixirls', {
     cmd = { "/path/to/language_server.sh" },
     -- required to make language server aware of other files
     root_markers = { 'mix.exs', '.git' },
 })
 vim.lsp.enable('elixirls')
</code></pre>
</li>
<li>Set up an autocmd to start tree-sitter when an elixir file is opened. I also set up a sub-autocmd to configure some LSP-related buffer settings when the LSP attaches to the buffer: enabling completion and auto-format on save. I was stuck here for a while, because while in most places the <code>pattern</code> for an autocmd is something like <code>*.ex</code>, for the <code>FileType</code> autocmd it’s the detected filetype name, e.g. <code>elixir</code> <img src="https://forum.elixirforum.com/images/emoji/apple/exploding_head.png?v=15" title=":exploding_head:" class="emoji" alt=":exploding_head:" loading="lazy" width="20" height="20"><pre data-code-wrap="lua"><code class="lang-lua">vim.api.nvim_create_autocmd('FileType', {
  pattern = { 'elixir', 'eex', 'heex' },
  callback = function(ft_args)
    vim.treesitter.start()
    -- https://github.com/nvim-treesitter/nvim-treesitter/tree/main?tab=readme-ov-file#indentation
    vim.bo.indentexpr = "v:lua.require'nvim-treesitter'.indentexpr()"

    vim.api.nvim_create_autocmd('LspAttach', {
        buffer = ft_args.buf,
        callback = function(args)
          local client = assert(vim.lsp.get_client_by_id(args.data.client_id))
          -- Enable auto-completion
          vim.lsp.completion.enable(true, client.id, args.buf, {autotrigger = true})
          -- autoformat on save
          -- Apparently not needed if server supports "textDocument/willSaveWaitUntil".
          vim.api.nvim_create_autocmd('BufWritePre', {
            buffer = args.buf,
            callback = function()
              vim.lsp.buf.format({ bufnr = args.buf, id = client.id, timeout_ms = 1000 })
            end,
          })
      end,
    })
  end,
})
</code></pre>
</li>
<li>Turn on “virtual lines” for diagnostics, so warnings and error messages show up below the line (otherwise it’s necessary to press <a href="https://neovim.io/doc/user/tagsrch.html#CTRL-W_d-default" rel="noopener nofollow ugc">CTRL+W d</a> to view the warning - which you can still do if the warning scrolls off the edge of the screen and you want to view it in a popup).<pre data-code-wrap="lua"><code class="lang-lua">vim.diagnostic.config({ virtual_lines = true })
</code></pre>
</li>
<li>Set up any custom keymappings <a href="https://neovim.io/doc/user/lsp.html#lsp-defaults" rel="noopener nofollow ugc">in addition to the defaults</a>. For me I set <code>gd</code> to go to definition, <code>grr</code> to find references, and <code>Ctrl+m</code> to show the diagnostic in a popup.<pre data-code-wrap="lua"><code class="lang-lua">vim.keymap.set('n', 'gd', function() vim.lsp.buf.definition() end)
vim.keymap.set('n', 'grr', function() vim.lsp.buf.references() end)
vim.keymap.set('n', '&lt;C-m&gt;', function() vim.diagnostic.open_float() end)
</code></pre>
</li>
<li>Finally I added some vimscript to customise the autocompletion popup. The key bindings shouldn’t be necessary because neovim apparently already has these tab/shift+tab bindings, but for some reason it wasn’t working for me (also they are in vimscript, not lua, because I edited some existing code rather than figuring out how to do a conditional binding in lua…)<pre data-code-wrap="vim"><code class="lang-vim">set completeopt+=menuone,noselect,popup
imap &lt;expr&gt; &lt;enter&gt; pumvisible() ? "&lt;C-y&gt;" : "&lt;enter&gt;"
imap &lt;expr&gt; &lt;tab&gt; pumvisible() ? "&lt;C-n&gt;" : "&lt;tab&gt;"
imap &lt;expr&gt; &lt;S-tab&gt; pumvisible() ? "&lt;C-p&gt;" : "&lt;S-tab&gt;"
</code></pre>
</li>
</ol>
<p>Assembled config:</p>
<pre data-code-wrap="vim"><code class="lang-vim">" Install tree-sitter with plugin manager
Plug 'nvim-treesitter/nvim-treesitter', { 'branch': 'main', 'build': ':TSUpdate' }

lua &lt;&lt; LUA
vim.lsp.config('elixirls', {
  cmd = { "/path/to/language_server.sh" },
  -- required to make language server aware of other files
  root_markers = { 'mix.exs', '.git' },
})
vim.lsp.enable('elixirls')

require'nvim-treesitter'.install { 'elixir', 'eex', 'heex' }

-- start tree-sitter and lsp for elixir files
vim.api.nvim_create_autocmd('FileType', {
  pattern = { 'elixir', 'eex', 'heex' },
  callback = function(ft_args)
    vim.treesitter.start()
    -- https://github.com/nvim-treesitter/nvim-treesitter/tree/main?tab=readme-ov-file#indentation
    vim.bo.indentexpr = "v:lua.require'nvim-treesitter'.indentexpr()"

    vim.api.nvim_create_autocmd('LspAttach', {
        buffer = ft_args.buf,
        callback = function(args)
          local client = assert(vim.lsp.get_client_by_id(args.data.client_id))
          -- Enable auto-completion
          vim.lsp.completion.enable(true, client.id, args.buf, {autotrigger = true})
          -- autoformat on save
          -- Apparently not needed if server supports "textDocument/willSaveWaitUntil".
          vim.api.nvim_create_autocmd('BufWritePre', {
            buffer = args.buf,
            callback = function()
              vim.lsp.buf.format({ bufnr = args.buf, id = client.id, timeout_ms = 1000 })
            end,
          })
      end,
    })
  end,
})

-- Enable warning/error messsages in virtual lines
vim.diagnostic.config({ virtual_lines = true })

vim.keymap.set('n', 'gd', function() vim.lsp.buf.definition() end)
vim.keymap.set('n', 'grr', function() vim.lsp.buf.references() end)
vim.keymap.set('n', '&lt;C-m&gt;', function() vim.diagnostic.open_float() end)
LUA

set completeopt+=menuone,noselect,popup

" Set up tab/enter navigation for autocomplete popup
" apparently this is already the default for snippets, no idea why it's not working without this
" https://github.com/neovim/neovim/pull/27339/files#diff-e682fc63c5b105e3eab956c380e8abf951a1b0d14fea03ae0f079bd490686e77
" have no idea what &lt;expr&gt; does but think it allows the ? operator
imap &lt;expr&gt; &lt;enter&gt; pumvisible() ? "&lt;C-y&gt;" : "&lt;enter&gt;"
imap &lt;expr&gt; &lt;tab&gt; pumvisible() ? "&lt;C-n&gt;" : "&lt;tab&gt;"
imap &lt;expr&gt; &lt;S-tab&gt; pumvisible() ? "&lt;C-p&gt;" : "&lt;S-tab&gt;"
</code></pre> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="371377" data-batch-url="/posts/batch_likers">
                        5
                      </span>
                      <!-- <span class="thread-count js-solved-indicator" title="Marked as solution"></span> -->
	                </div>
	                <div class="go-to-post">
	                  <a title="Go to post" alt="Go to post" href="https://forum.elixirforum.com/t/neovim-elixir-setup-configuration-from-scratch-guide/46310/112">Post #111</a>
	                </div>
	            </div>
              <div id="likers-container-371377" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="371377"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-standard-post cat-standard-post" title="Post #111"></div>
  </section>
</div>
</template></turbo-stream><turbo-stream action="replace" target="load-more-container"><template><div id="load-more-container" class="load-more-container">
    <a class="load-more-button" data-turbo-stream="true" href="/topics/46310/load_more?page=12">Load more posts (4 remaining)</a>
</div></template></turbo-stream>