<?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 🍃 - dynamic-completions</title>
    <link>https://emresahin.net/tags/dynamic-completions/</link>
    <description>Posts in the dynamic-completions 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/dynamic-completions/rss.xml" rel="self" type="application/rss+xml"/>
    <item>
      <title>devlog 21</title>
      <published>2025-02-03T09:59:28+00:00</published>
      <updated>2025-02-03T09:59:28+00:00</updated>
      <author>Emre Şahin</author>
      <pubDate>Mon, 03 Feb 2025 09:59:28 +0000</pubDate>
      <link>https://emresahin.net/devlog-21/</link>
      <guid isPermaLink="true">https://emresahin.net/devlog-21/</guid>
      <description>🐢 Now, the next version will have a --json output for xvc file list . We can start working on it or update the Readme file? 🐇 What about adding at least command completions for Nushell? 🐢 Let’s read a bit about clap_complete_nushell . 🦊 There seems to be a nu-complete command. Let’s check its doc...</description>
      <category>xvc</category>
      <category>Development</category>
      <category>Nushell</category>
      <category>clap_complete_nushell</category>
      <category>carapace</category>
      <category>dynamic completions</category>
      <category>JSON</category>
      <category>Lazygit</category>
      <category>Rust</category>
      <category>XVC</category>
      <category>completions</category>
      <content:encoded><![CDATA[<p>🐢 Now, the next version will have a <code>--json</code> output for <code>xvc file list</code>. We
can start working on it or update the Readme file?</p>
<p>🐇 What about adding at least command completions for Nushell?</p>
<p>🐢 Let’s read a bit about <code>clap_complete_nushell</code>.</p>
<p>🦊 There seems to be a <code>nu-complete</code> command. Let’s check its documentation.</p>
<p>🐇 Nothing was found, and Kagi doesn’t help much either.</p>
<p>🐢 There is a completions document for Nushell: https://www.nushell.sh/book/custom_completions.html</p>
<p>🐇 There is a tool called carapace to provide completions across shells.</p>
<p>🐢 Its <a href="https://carapace-sh.github.io/carapace/carapace.html">documentation</a> is
thin, and I’m not sure if it supports dynamic completions out of the box. I
believe instead of adding a carapace setup, we can just write a Nushell
completion script that will use JSON output from the commands and add some
(maybe hidden) utility commands to support it.</p>
<p>🐇 There are a set of example scripts in the Nushell repo:
https://github.com/nushell/nu_scripts/tree/main/custom-completions</p>
<p>🐢 The reason I want to write custom completions for Nushell is that it will be
an exercise for the scripting language. <a href="https://github.com/nushell/nu_scripts/blob/main/custom-completions/gh/gh-completions.nu"><code>gh</code>
completions</a>
are not as scary as a Bash script.</p>
<p>🐇 <a href="https://github.com/nushell/nu_scripts/blob/main/custom-completions/git/git-completions.nu"><code>git</code>
completions</a>
are a better example for XVC. They simply run <code>git</code> whenever necessary. We can
start from a static completions command and update this with dynamic
completions manually. It will teach a lot.</p>
<p>🐢 I <a href="https://github.com/iesahin/nu_scripts">forked</a> the <code>nu_scripts</code> repo and
will add XVC completions script there.</p>
<p>🐇 Then let’s begin by adding Nushell static completions. Shall we add a
command for this?</p>
<p>🦊 Reviving the <code>completion</code> command we removed in 0.6.13?</p>
<p>🐢 We shouldn’t list it. We can make a <code>_comp</code> subcommand for the time being
and generate and distribute completions in the repository. When
<code>clap_complete_nushell</code> has the feature parity to provide dynamic completions,
we can remove these commands.</p>
<p>🐇 What will we use this for other than generating completions?</p>
<p>🐢 Maybe dynamic completions can call this as well.</p>
<p>🐇 Added Nushell static completions to be output using <code>xvc _comp generate-nushell</code>. Let’s bump up the version to 0.6.15.</p>
<pre><code>cargo set-version 0.6.15-alpha.1
   Upgrading xvc from 0.6.14 to 0.6.15-alpha.1
...
</code></pre>
<p>🐢 I noticed we forgot a line in the CLI command handler that asserts <code>xvc_root_opt.is_some()</code>, and this fails when we run <code>xvc</code> outside of repositories. We need to release this version quickly.</p>
<p>🐇 Oops, now, ok, let’s write a static Nushell generator and just release quickly.</p>
<p>🦊 Generating completions with</p>
<pre><code>xvc comp generate-nushell
</code></pre>
<p>🐢 Completion command is run with <code>comp</code> instead of <code>_comp</code>. Should we rename it?</p>
<p>🐇 Renamed it to <code>_comp</code>. It’s not hidden, but at least we can be sure that it won’t be misunderstood as a common command.</p>
<p>🐢 Bumping the version again. Now let’s source the generated script and test it.</p>
<pre><code>cargo set-version 0.6.15-alpha.2
   Upgrading xvc from 0.6.15-alpha.1 to 0.6.15-alpha.2
...
</code></pre>
<p>🦊 Yep, it works. We now have completions for Nushell.</p>
<p>🐢 Let’s update the completions documentation.</p>
<p>🐇 Done. Now, let’s take a look at CI and see what fails.</p>
<pre><code class="language-nu">ghrl | first
╭──────────────┬─────────────────────────────────────────────────────────╮
│ conclusion   │ success                                                 │
│ displayTitle │ Add Nushell completions                                 │
│ headBranch   │ nushell-completions                                     │
│ url          │ https://github.com/iesahin/xvc/actions/runs/13070200765 │
╰──────────────┴─────────────────────────────────────────────────────────╯
</code></pre>
<p>🐢 It fails because of coverage, not the tests. <a href="https://github.com/iesahin/xvc/pull/266#issuecomment-2626794240">Codecov says</a> the new code isn’t tested.</p>
<p>🐇 The added <code>xvc _comp</code> command isn’t tested. We can add a test running those lines and testing if the command outputs a completion script.</p>
<p>🐢 We have a <a href="https://github.com/iesahin/xvc/blob/main/lib/tests/test_completions.rs#L18">test for completions</a>. We can add a test that runs the lines.</p>
<p>🐇 Added a test and bumping up the version.</p>
<pre><code class="language-nu">cargo set-version 0.6.15-alpha.3
   Upgrading xvc from 0.6.15-alpha.2 to 0.6.15-alpha.3
...
</code></pre>
<p>🦊 We can add some more coverage while waiting for the tests.</p>
<p>🐇 <a href="https://app.codecov.io/gh/iesahin/xvc/blob/main/logging%2Fsrc%2Flib.rs#L285"><code>XvcOutputLine</code> implementation</a> seems to have no tests. It’s weird because we use these everywhere.</p>
<p>🐢 I’m not sure we use this particular implementation; we just use <code>XvcOutputLine::Info(s)</code>, not <code>XvcOutputLine::info(s)</code> anywhere. We can delete these methods actually.</p>
<p>🐇 We’ll add JSON output via this particular struct. Can we refactor these to use formatting for JSON, for example? Or use these to output JSON?</p>
<p>🦊 We can add a formatter to <code>XvcOutputLine</code> to output structures.</p>
<p>🐢 The enum is now defined as:</p>
<pre><code class="language-rust">#[derive(Clone, Debug)]
pub enum XvcOutputLine {
    /// The output that we should be reporting to user
    Output(String),
    /// For informational messages
    Info(String),
    /// For debug output to show the internals of Xvc
    Debug(String),
    /// Warnings that are against some usual workflows
    Warn(String),
    /// Errors that interrupts a workflow but may be recoverable
    Error(String),
    /// Panics that interrupts the workflow and ends the program
    /// Note that this doesn't call panic! automatically
    Panic(String),
    /// Progress bar ticks.
    /// Self::Info is also used for Tick(1)
    Tick(usize),
}</code></pre>
<p>Here, these fields can also have a <code>formatter</code> that will render the string in a particular format. For example, the output can be</p>
<pre><code class="language-rust">XvcOutputLine::Output(XvcJsonFormatter, String)</code></pre>
<p>🐇 I’m not sure this is a good idea. <code>Output</code> already specifies this string as output. We can have a wrapper instead, like,</p>
<pre><code class="language-rust">struct XvcJsonOutput(Format&lt;XvcStructuredOutput&gt;, XvcStructuredOutput)</code></pre>
<p>and we can use the supplied format to render <code>XvcStructuredOutput</code> to an output line with <code>XvcOutputLine::Output</code>. If we don’t provide output as structured, it will be too much error-prone work to convert the current outputs to structured.</p>
<p>🦊 The transition will also be gradual. We may not need structured output for most of the commands. We can start with <code>xvc file list</code> and convert others as we go.</p>
<p>🐢 This is sensible. By the way, coverage still didn’t increase. There may be something going on with Codecov or running the test.</p>
<pre><code class="language-nu">ghrl | first
╭──────────────┬─────────────────────────────────────────────────────────╮
│ conclusion   │ success                                                 │
│ displayTitle │ Add Nushell completions                                 │
│ headBranch   │ nushell-completions                                     │
│ url          │ https://github.com/iesahin/xvc/actions/runs/13087431038 │
╰──────────────┴─────────────────────────────────────────────────────────╯
</code></pre>
<p>🐇 Let’s run the test:</p>
<pre><code class="language-sh">cargo test -p xvc --test test_completions
...
test test_completions ... ok

test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.80s
</code></pre>
<p>🐢 Can we make sure the output is a Nushell script and not an error message?</p>
<p>🐇 Let’s print it out.</p>
<p>🐢 It looks like when the <code>COMPLETE</code> environment variable is set, it never calls <code>_comp</code> subcommand and never calls those lines.</p>
<pre><code>cargo set-version 0.6.15-alpha.4
   Upgrading xvc from 0.6.15-alpha.3 to 0.6.15-alpha.4
...
</code></pre>
<p>🐢 Let’s make a release for 0.6.15. Coverage is OK now.</p>
<pre><code class="language-nu">cargo set-version 0.6.15
   Upgrading xvc from 0.6.15-alpha.4 to 0.6.15
...
</code></pre>
<pre><code class="language-nu">gh pr merge --squash --body $"(open CHANGELOG.md | lines | skip 2 | take 5)" --subject "Add static nushell completions"
</code></pre>
<p>🐇 Merged the PR.</p>
<p>🐢 Releases should appear in a few minutes.</p>
<p>🐇 We need to tag the merge commit for this.</p>
<p>🐢 Oh, yep. AFAIK Lazygit doesn’t have something for <code>git push --tags</code>. Let’s push from the CLI.</p>
<pre><code class="language-nu">git push --tags
You are on the main branch. Skipping CHANGELOG.md check.
To github.com:iesahin/xvc
 * [new tag]         v0.6.15 -&gt; v0.6.15
</code></pre>
<p>🦊 These commands, especially tables, are not rendered correctly on the web. We need to change the theme, I think.</p>]]></content:encoded>
    </item>
    <item>
      <title>devlog 17</title>
      <published>2025-01-27T16:07:11+00:00</published>
      <updated>2025-01-27T16:07:11+00:00</updated>
      <author>Emre Şahin</author>
      <pubDate>Mon, 27 Jan 2025 16:07:11 +0000</pubDate>
      <link>https://emresahin.net/devlog-17/</link>
      <guid isPermaLink="true">https://emresahin.net/devlog-17/</guid>
      <description>🐢 We are progressing towards adding all store completions. In the meantime, I switched to nushell from zsh. Completions for nushell require a different crate and it doesn’t have dynamic completions yet. 🐇 We can just complete the completions for this version and add JSON output for all commands t...</description>
      <category>devlog</category>
      <category>xvc</category>
      <category>clap_complete</category>
      <category>clap</category>
      <category>nushell</category>
      <category>dynamic-completions</category>
      <category>completions</category>
      <category>rust</category>
      <content:encoded><![CDATA[<p>🐢 We are progressing towards adding all store completions. In the meantime, I
switched to nushell from zsh. Completions for
<a href="https://github.com/nushell/nushell">nushell</a> require a different crate and it
doesn’t have dynamic completions yet.</p>
<p>🐇 We can just complete the completions for this version and add JSON output
for all commands to use in nushell. In the meantime, dynamic completions support
for nushell is likely to be added.</p>
<p>🐢 Umm, yep. Then we’ll continue to run tests with zsh for the current version.</p>
<p>🐇 <a href="~/github.com/iesahin/xvc/run-tests.zsh"><code>run-tests</code></a> is a zsh file, and
we will continue to use it. We can switch to nushell eventually as we add more
compatibility with it, but let’s not do this now.</p>
<p>🐢 Where were we the last time for completions?</p>
<p>🐇 We added xvc_path_completers. Let’s check the TODO list now.</p>
<p>🐢 We still need tracked_targets completions in a few places.</p>
<p>🐇 Added those.</p>
<p>🐢 Now we have some strum completers. Let’s finish these up as well.</p>
<p>🐇 Ok. They are done as well.</p>
<p>🐢 Now, let’s start adding a storage_identifier completer. It should read all
<code>XvcStorage</code> records and list their names.</p>
<p>🐇 Added a <code>storage_identifier</code> completer. Let’s add it to all places where we use
storage_identifiers.</p>
<p>🐢 Now, we need completers for pipeline and step names. These are
straightforward.</p>
<p>🐇 Added these. Let’s fill up where they are needed.</p>
<p>🐢 I want to skip some of the fine-grained completions in this version. We can
have a specific completer for <code>--params</code> options for files and params inside,
for example. Or a special completer for directories.</p>
<p>🐇 Let’s not forget these. Reading YAML files and extracting hyperparameter
keys for the prompt would be a really good feature for the user.</p>
<p>🐢 I agree. These are good features in general, but we need to ship the current
version as soon as possible.</p>
<p>🐇 Let’s check the TODO comments once more.</p>
<pre><code class="language-sh">$ rg 'TODO:' 
...
- ✅ pipeline/src/pipeline/api/update.rs:    /// TODO: Add a repository_dirs completer (11:08)
- ✅ file/src/remove/mod.rs:    /// TODO: Add a storage_identifier completer (11:08)
- ✅ file/src/bring/mod.rs:    /// TODO: Add a storage_identifier completer (11:08)
...
</code></pre>
<p>🦊 We can use <code>xvc_path_completer</code> for the tracked directory completer for the
time being. For <code>pipeline update</code>, we can use a <code>ValueHint</code> instead. It’s not
necessary to use a custom completion.</p>
<p>🐢 For the <code>xvc file copy</code> destination, we can have a file or a directory that we
track and is not available, or we don’t track and is available. It’s a similar situation
to xvc_path_completer, but we also need to check the local paths. It requires
some more care.</p>
<p>🐇 Now we can begin to run the tests.</p>
<p>🐢 Is this building?</p>
<p>🐇 It should.</p>
<p>🐢 We also have one bug. xvc shouldn’t print help text when the <code>COMPLETE</code>
environment variable is set.</p>
<p>🐇 Umm, yeah, that’s a blocker.</p>
<p>🐢 Fixed it. We can bump the version and push the changes.</p>]]></content:encoded>
    </item>
  </channel>
</rss>
