<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/">
  <channel>
    <title>emre şahin's digital garden 🍃 - rust-analyzer</title>
    <link>https://emresahin.net/tags/rust-analyzer/</link>
    <description>Posts in the rust-analyzer tag</description>
    <language>en</language>
    <managingEditor>contact@emresahin.net (Emre Şahin)</managingEditor>
    <lastBuildDate>Tue, 15 Sep 2026 19:46:32 +0000</lastBuildDate>
    <atom:link href="https://emresahin.net/tags/rust-analyzer/rss.xml" rel="self" type="application/rss+xml"/>
    <item>
      <title>devlog 13</title>
      <published>2025-01-19T09:55:05+00:00</published>
      <updated>2025-01-19T09:55:05+00:00</updated>
      <author>Emre Şahin</author>
      <pubDate>Sun, 19 Jan 2025 09:55:05 +0000</pubDate>
      <link>https://emresahin.net/devlog-13/</link>
      <guid isPermaLink="true">https://emresahin.net/devlog-13/</guid>
      <description>🐇 So, what’s next? 🐲 We can work on completions or the GUI. 🐢 Completions are similar to the Homebrew work. It’s in another ecosystem and feels boring. 🐲 We can try to make it in Rust: “Writing shell completions in Rust.” 🐢 There are two solutions: One is clap_complete (https://docs.rs/clap_compl...</description>
      <category>xvc</category>
      <category>completions</category>
      <category>clap_complete</category>
      <category>subcommands</category>
      <category>xvc pipeline step dependency</category>
      <category>xvc aliases</category>
      <category>Rust</category>
      <category>rust-analyzer</category>
      <category>shell completion</category>
      <category>CLI</category>
      <category>auto-save.nvim</category>
      <content:encoded><![CDATA[<p>🐇 So, what’s next?</p>
<p>🐲 We can work on completions or the GUI.</p>
<p>🐢 Completions are similar to the Homebrew work. It’s in another ecosystem and feels boring.</p>
<p>🐲 We can try to make it in Rust: “Writing shell completions in Rust.”</p>
<p>🐢 There are two solutions: One is <code>clap_complete</code> (https://docs.rs/clap_complete/latest/clap_complete/) and the other is <code>shell_completion</code> (https://github.com/JoshMcguigan/shell_completion). The latter is very new but may be what we need: writing completions only with Rust.</p>
<p>🐲 The <code>shell_completion</code> crate is very bare-bones. It doesn’t have anything, actually. https://github.com/JoshMcguigan/shell_completion/issues/1</p>
<p>🐇 The feature that we need is dynamic completion. We’ll write something similar to <a href="https://docs.rs/clap_complete/latest/clap_complete/engine/struct.ArgValueCompleter.html"><code>ArgValueCompleter</code></a> for this.</p>
<p>🦊 I think we can just start a new branch.</p>
<p>🐲 We have a branch for Homebrew; should we merge it?</p>
<p>🐢 I think, yes, we can merge it. We’ll fix it if it breaks. It’s a separate workflow file anyway.</p>
<p>🦊 Created the PR.</p>
<pre><code class="language-sh">ghpl
264	add brew tap	add-brew-tap	OPEN	2025-01-03T05:14:45Z
</code></pre>
<p>🐢 Merged it.</p>
<p>🐇 Now let’s create a new branch and add <code>clap-complete</code> to <code>Cargo.toml</code>.</p>
<p>🐲 There are some packages that we need to take a look at. <code>thiserror</code> now has v2.</p>
<p>🐢 Upgraded packages and compiled. It works.</p>
<p>🐲 Let’s update the version.</p>
<p>🐢 Done. Now we can add <code>clap-complete</code>.</p>
<p>🦊 Added with the <code>unstable-dynamic</code> command. Can we build it again?</p>
<p>🐢 Built it. Now we can add a <code>completions</code> subcommand to Xvc.</p>
<p>🐲 Is this the right name for this?</p>
<p>🐢 It will output a shell script that we can source in the shell.</p>
<p>🐲 Okay, let’s add the subcommand now.</p>
<p>🐢 The example doesn’t work with the <code>clap</code> builder.</p>
<p>🐇 Let’s search for it.</p>
<hr>
<p>🐢 I think we’re extending ourselves a bit when trying to add all dynamic features of completion at once. We can just start by adding completion to <code>xvc-test-helper</code>.</p>
<p>🐇 Yep, that’s a better idea. We can have many more examples, and it’s certainly more straightforward.</p>
<p>🐢 One thing I noticed when working yesterday is that using auto-save was actually preventing many of these swap errors.</p>
<p>🐲 It was a bit slow. Can we take a look at a few others?</p>
<p>🐢 https://github.com/okuuva/auto-save.nvim seems a bit more polished.</p>
<p>🐇 Installed it, but haven’t seen an effect yet.</p>
<p>🐢 We may need to restart this.</p>
<p>🐲 Now, we can get into the <code>test-helper</code> completions.</p>
<p>🐢 Done. Added these quickly as you thought. Now adding this to <code>main</code> seems much easier.</p>
<p>🦊 That was a nice approach. Let’s dive into adding this to <code>main</code>.</p>
<p>🐇 Should we go with a separate command or just an option?</p>
<p>🐲 Our commands have distinct initial letters, allowing them to be used with just those letters. Adding another top-level command for this will make <code>c</code> useless.</p>
<p>🐢 I don’t think that’s a valid concern. We can create aliases for all commands and <code>completions</code> shouldn’t have to have an alias. But I agree that completions should not be a top-level command. It will be run once for installation at most.</p>
<p>🦊 I agree. Let’s call it <code>--completions</code>. It will be run as <code>xvc --completions zsh</code> and will print out the completions.</p>
<p>🐢 Okay. Let’s do this.</p>
<p>🦊 No errors left. Let’s install this version.</p>
<p>🐢 We get:</p>
<pre><code class="language-sh">error: 'xvc' requires a subcommand but one was not provided
  [subcommands: file, init, pipeline, storage, root, check-ignore, aliases, help]

Usage: xvc [OPTIONS] &lt;COMMAND&gt;

For more information, try '--help'.
</code></pre>
<p>🦊 Umm, okay. I think we don’t have an option to create a command like that. Then we’ll have to print completions with a subcommand.</p>
<p>🐲 The above discussion is now moot. ❌</p>
<p>🐢 We can try to push, but probably it’s not worth it.</p>
<p>🐲 Let’s not lose time on this. I think we can remove the <code>aliases</code> command and replace it with <code>completions</code>, and add single-letter aliases to subcommands.</p>
<p>🐢 We can have an option in the <code>completions</code> command to print aliases. That will work.</p>
<p>🦊 I don’t think people will use the <code>aliases</code> command if we have single-letter command aliases.</p>
<p>🐢 You may be right. No need to try to maintain that at this time.</p>
<hr>
<p>🐢 Good morning, and I’m fed up with these <code>blink.cmp</code> errors, you know.</p>
<p>🐇 Reinstalling <code>blink</code> works. It’s interesting to rely on such unreliable software.</p>
<p>🐢 Oh, yeah. It’s <em>interesting</em>. Where were we yesterday?</p>
<p>🐲 We decided to rename the <code>aliases</code> command to <code>completions</code>.</p>
<p>🐇 And waiting for <code>rust-analyzer</code> to complete its analysis.</p>
<p>🐢 Uh, yeah. I see.</p>
<p>🦊 The code itself is very short, actually.</p>
<pre><code class="language-rust">    if let Some(shell) = cli_opts.completions {
        let mut cmd = XvcCLI::command();
        generate(shell, &amp;mut cmd, "xvc", &amp;mut io::stdout());
        return Ok(None);
    }</code></pre>
<p>🐲 We’ll use the <code>output!</code> macro instead of writing to <code>io::stdout()</code>, right?</p>
<p>🐢 Yes, we can rely on the usual output system. It will be slower to create an output thread but shouldn’t matter for outputting a shell script.</p>
<p>🐇 It takes a while for <code>rust-analyzer</code> to scan all the directories, it looks like. When I close the project, it just cannot reload it immediately.</p>
<p>🐢 We can use <code>cargo clean</code> from time to time.</p>
<p>🦊 <code>rust-analyzer</code> finished scanning; let’s try to rename <code>AliasesCLI</code>.</p>
<p>🐲 Let’s keep these here; maybe we’ll need them in our scripts:</p>
<pre><code class="language-sh"># Standard Xvc command aliases for longer commands.
alias xls='xvc file list'
alias pvc='xvc pipeline'
alias fvc='xvc file'
alias xvcf='xvc file'
alias xvcft='xvc file track'
alias xvcfl='xvc file list'
alias xvcfs='xvc file send'
alias xvcfb='xvc file bring'
alias xvcfh='xvc file hash'
alias xvcfco='xvc file checkout'
alias xvcfr='xvc file recheck'
alias xvcp='xvc pipeline'
alias xvcpr='xvc pipeline run'
alias xvcps='xvc pipeline step'
alias xvcpsn='xvc pipeline step new'
alias xvcpsd='xvc pipeline step dependency'
alias xvcpso='xvc pipeline step output'
alias xvcpi='xvc pipeline import'
alias xvcpe='xvc pipeline export'
alias xvcpl='xvc pipeline list'
alias xvcpn='xvc pipeline new'
alias xvcpu='xvc pipeline update'
alias xvcpd='xvc pipeline dag'
alias xvcs='xvc storage'
alias xvcsn='xvc storage new'
alias xvcsl='xvc storage list'
alias xvcsr='xvc storage remove'
</code></pre>
<p>🦊 We can use them when adding single-letter aliases.</p>
<p>🐇 There is a <a href="https://docs.rs/clap_complete/latest/clap_complete/aot/enum.Shell.html#method.from_env"><code>from_env</code></a> method for <code>Shell</code>; will we support it?</p>
<p>🦊 I think we can support it. It’s much easier to use if we omit the shell.</p>
<p>🐲 We had <code>aliases</code> in <code>xvc-core</code>, but we need to access <code>XvcCLI</code> from completions. The completions module must be moved to <code>xvc</code>.</p>
<p>🦊 We added the <code>clap_complete</code> dependency to the <code>xvc-pipeline</code> and <code>xvc-file</code> crates, but I don’t think they are necessary. Let’s remove them now.</p>
<p>🐢 Now only the <code>test-helper</code> and <code>xvc</code> crates have the <code>clap_complete</code> dependency.</p>
<p>🐇 Are we ready to test?</p>
<p>🐢 Completions are working. 🎉</p>
<p>🐲 Now we need to update the docs and doc tests, I believe.</p>
<p>🐢 There are also tests to update.</p>
<p>🐇 Tests are running now. In the meantime, can we take a look at the <code>blink</code> configuration?</p>
<p>🐲 When we removed <code>xvc aliases</code>, we also removed <code>pvc</code>, <code>xls</code>, and other aliases. Maybe we can add these to the docs.</p>
<p>🐢 We can put them in the <code>xvc completions</code> reference for now.</p>
<hr>
<p>🐢 It takes a while for <code>rust-analyzer</code> to finish analyzing the codebase.</p>
<p>🦊 Added aliases for <code>xvc pipeline</code> commands. Do you think we need to repeat root-level flags in <code>xvc-pipeline</code>?</p>
<p>🐢 No need to divert attention, I believe. Also, I still think there is an easier way to do that.</p>
<p>🐇 Okay. Do you think we should add easier subcommands to <code>step</code>? Like, <code>step new</code> becoming <code>xvc p s n</code> instead of <code>xvc p s n</code>? (Wait, that’s the same). I mean, more concise.</p>
<p>🐢 I think we can extend these even to the top-level, but shouldn’t make them visible. It will pollute the help text. We can add <code>xvc fl</code> for <code>file list</code> to avoid the space, but hide these from the help text.</p>
<p>🐲 That’s a good idea, but it will require including sub-crate level modules at the top level. We must test it first.</p>
<p>🐢 Let’s finish up the current changes and release them first.</p>
<p>🐇 By the way, we didn’t add two-letter abbreviations to the <code>xvc storage new</code> subcommands. Do you think we need them?</p>
<p>🐢 When we think about the frequency of these commands, no, I don’t think we need them. Users won’t add a new storage every day.</p>
<p>🐇 By that logic, we shouldn’t need an <code>n</code> for <code>xvc storage new</code>.</p>
<p>🐢 Actually, yeah. Maybe we should remove even <code>s</code>.</p>
<p>🦊 <code>storage list</code> may be useful.</p>
<p>🐢 <code>s</code> is a very common letter, though. We can have other uses for that letter.</p>
<p>🐇  Updating <code>xvc p s dependency</code> options, but it looks like making dependency options subcommands is a better way.</p>
<p>🦊 We didn’t do it because currently we can supply multiple options with a single command. If we go the subcommand route, we’ll have to write all dependencies one by one. Adding multiple subcommands with <code>clap</code> is a bit tricky.</p>
<p>🐢 Umm. Yeah, I see.</p>
<p>🐇 Maybe we can provide a separate command to add multiple dependencies. Like, <code>xvc p s d add 'lines=myfile.csv::10-20; file=myimage.jpg; glob=dir/image-10*'</code></p>
<p>🐲 That looks like the start of a language. We need a parser for those strings. They will be freeform.</p>
<p>🦊 Another option is to keep the current options and add commands with the same names.</p>
<p>🐢 That will be confusing. The user will have both <code>--param</code> and <code>param</code>, and they will work differently.</p>
<p>🐇 We can have an <code>add</code> command that accepts the current options. Parsing will be done by <code>clap</code> just like now, but for a subcommand of <code>dependency</code>.</p>
<p>🐢 The full command will be something like <code>xvc pipeline step --step-name preprocessing dependency add --params 'params.json::batch_size'</code></p>
<p>🐇 With shorter commands, it’s like <code>xvc p s -s preprocessing d a --params 'params.json::batch_size'</code>, and this doesn’t look like <code>ffmpeg</code> monstrosities.</p>
<p>🐲 In any case, this is a backward-incompatible change. This should wait for v0.7 along with ECS changes.</p>
<p>🐢 ECS changes are not user-visible, but these are. Certainly needs a minor version update.</p>
<p>🐇 Then, okay, let’s keep the current ones for this version and think about updating them in a future version.</p>
<p>🐢 Okay. Let’s finish up and we’ll create a separate invisible subcommand to ask questions to the Xvc repo for completions.</p>
<p>🐇 We completed completions for the common command structure. Now, we need a way to show certain info after certain commands. A tab after <code>xvc p r -p</code> should show pipeline names, for example.</p>
<p>🐢 Umm, yeah. And these should be as quick as possible. They shouldn’t check Git or any other things.</p>
<p>🐇 I looked here and there, and the only working example I found is here: https://github.com/clap-rs/clap/blob/master/clap_complete/tests/testsuite/zsh.rs#L248 in <code>clap_complete</code> tests.</p>
<p>🐢 Let’s try to dive in. We can start by cloning the repo, I believe.</p>]]></content:encoded>
    </item>
    <item>
      <title>Xvc Devlog - 221107</title>
      <published>2022-11-08T09:57:00+00:00</published>
      <updated>2022-11-08T09:57:00+00:00</updated>
      <author>Emre Şahin</author>
      <pubDate>Tue, 08 Nov 2022 09:57:00 +0000</pubDate>
      <link>https://emresahin.net/xvc-devlog---221107/</link>
      <guid isPermaLink="true">https://emresahin.net/xvc-devlog---221107/</guid>
      <description>🐇 Welcome to the November 7th issue of Xvc Devlog. In the previous devlog , we began to implement Git integration. How is it going, Mr. Tortoise? 🐢 It looks like we don’t have many architectural problems. 🐇 You’re forgetting how Exec::cmd works, though. You have those kinds of problems. 🐢 Yeah, I...</description>
      <category>devlog</category>
      <category>Software Development</category>
      <category>xvc</category>
      <category>architecture</category>
      <category>shell</category>
      <category>git</category>
      <category>gitignore</category>
      <category>rust-analyzer</category>
      <category>LSP</category>
      <content:encoded><![CDATA[<p>🐇 Welcome to the November 7th issue of Xvc Devlog. In the <a href="https://emresahin.net/xvc-devlog-221105">previous devlog</a>, we began to implement Git integration. How is it going, Mr. Tortoise?</p>
<p>🐢 It looks like we don’t have many architectural problems.</p>
<p>🐇 You’re forgetting how <code>Exec::cmd</code> works, though. You have those kinds of problems.</p>
<p>🐢 Yeah, I’m figuring that out. <code>Exec::shell</code> requires a string to run on the shell, while <code>Exec::cmd</code> just needs a command name. You have to supply <code>args</code> with another function. I’m writing a closure now to handle this.</p>
<hr>
<p>🐢 It started working, but it revealed a much bigger problem: <code>.xvc/</code> is not added to <code>.gitignore</code> in <code>xvc init</code>.</p>
<p>🐇 Wow, that’s a showstopper.</p>
<p>🐢 Yup. I think I should fix it as well.</p>
<p>🐇 On closer glance, I think the problem is not <code>xvc init</code> <em>not modifying</em> <code>.gitignore</code>; it modifies it incorrectly. Maybe putting certain files on a whitelist is a better idea than trying to blacklist everything.</p>
<p>🐢 Yeah, we should define a set of <em>Git-tracked</em> files and directories, whitelist them, and let all other files be ignored.</p>
<p>🐇 Go ahead, then.</p>
<p>🐢 I think I’ve fixed it. There were two problems: the initial gitignore content was wrong, and it was placed in the root of the repository instead of <code>.xvc</code>.</p>
<p>🐇 Maybe putting it directly in the root is better than hiding it in <code>.xvc</code>. What do you think?</p>
<p>🐢 There seems to be an assumption in <code>file track</code> to have a <code>.gitignore</code> file somewhere. I think we should also handle changes in <code>.gitignore</code> files throughout the repository.</p>
<p>🐇 Umm, yes. We should handle <code>.gitignore</code> files as well. But not all <code>.gitignore</code> files are changed by Xvc. How can we make sure they were modified by Xvc?</p>
<p>🐢 I think there are ways to do that, like tracking them somewhere. But I believe we shouldn’t try. We should just get a list of <code>.gitignore</code> files, <code>git add</code> them, and include them in the commit.</p>
<p>🐇 Ok. Let’s write a test for this as well. No <code>.gitignore</code> should appear in <code>git status -s</code>.</p>
<p>🐢 I wrote the test. It fails now. Do you think we should check the output of Git status to determine which files to add?</p>
<p>🐇 That may be a good idea. Git status should already know which files need to be added. We can use that information.</p>
<p>🐢 <a href="https://css-tricks.com/git-pathspecs-and-how-to-use-them/">It looks like <code>pathspec</code></a> is enough to modify <code>git add</code> behavior. We should be able to write <code>*.gitignore</code> and let all gitignore files be added.</p>
<p>🐇 Let’s try this manually.</p>
<p>🐢 Yep, it works. <code>git add '*.gitignore'</code> adds all <code>.gitignore</code> files in the subdirectories, too.</p>
<p>🐇 Congrats. 👏🥳</p>
<hr>
<p>🐢 I’m writing the missing documentation for the crates. There are <code>proc_macro not expanded</code> errors all over the code.</p>
<p>🐇 I think you should update rust-analyzer and everything. There must be a command for this.</p>
<p>🐢 I reinstalled RA with <code>:LspInstall</code> and restarted the LSP. It seems to work correctly now.</p>]]></content:encoded>
    </item>
  </channel>
</rss>
