v0.10.0 0f4e9eb

OmniboxFind.svelte RawHistoryFolder

1<!--
2  Omnibox Find Component
3
4  Displays find results and match navigation
5-->
6<script lang="ts">
7  import { omniboxStore } from './stores.svelte.ts';
8  import { revealMatch } from './find';
9
10  // Reactive state
11  let matches = $derived(omniboxStore.matches);
12  let selectedIndex = $derived(omniboxStore.selectedIndex);
13  let hasContent = $state(false);
14
15  // Update hasContent when matches change
16  $effect(() => {
17    hasContent = omniboxStore.mode === 'find' && matches.length > 0;
18  });
19
20  // Computed total count
21  let totalMatches = $derived(matches.length);
22
23  // Handle match item mouse enter
24  function handleItemMouseEnter(index: number) {
25    omniboxStore.setSelectedIndex(index);
26    omniboxStore.setFaded(true);
27    scrollToSelection();
28  }
29
30  // Handle match item click
31  function handleItemClick(index: number) {
32    omniboxStore.setSelectedIndex(index);
33    revealMatch(index);
34    omniboxStore.close();
35  }
36
37  // Scroll list to show selected item
38  function scrollToSelection() {
39    const selectedItem = document.getElementById(`find-item-${selectedIndex}`);
40    if (selectedItem && selectedItem.scrollIntoView) {
41      try {
42        selectedItem.scrollIntoView({ block: 'nearest' });
43      } catch {
44        selectedItem.scrollIntoView();
45      }
46    }
47  }
48
49  // Watch for selection changes to scroll
50  $effect(() => {
51    if (selectedIndex >= 0) {
52      scrollToSelection();
53    }
54  });
55</script>
56
57<div
58  id="find-list"
59  class="mt-2 max-h-[50vh] overflow-auto border-t border-[#333]"
60  role="listbox"
61  aria-label="Find results"
62>
63  <!-- Header with match count -->
64  <div
65    class="px-2.5 py-1.5 text-xs text-[#bbb]
66           border-b border-[#2a2a2a]"
67  >
68    {#if totalMatches > 0}
69      {totalMatches} match{totalMatches === 1 ? '' : 'es'}
70    {:else}
71      No matches
72    {/if}
73  </div>
74
75  <!-- Match results -->
76  {#if hasContent}
77    {#each matches as match, index (index)}
78      {@const isSelected = index === selectedIndex}
79
80      <div
81        id="find-item-{index}"
82        class="px-2.5 py-2 cursor-pointer
83               border-b border-[#2a2a2a] last:border-b-0
84               {isSelected ? 'bg-[#0a0a0a]' : ''}"
85        role="option"
86        tabindex="-1"
87        aria-selected={isSelected}
88        onmouseenter={() => handleItemMouseEnter(index)}
89        onclick={() => handleItemClick(index)}
90        onkeydown={(e) => e.key === 'Enter' && handleItemClick(index)}
91      >
92        <!-- Match context -->
93        <div
94          class="text-[#ddd] text-sm
95                 whitespace-nowrap overflow-hidden text-ellipsis"
96        >
97          {match.context || ''}
98        </div>
99      </div>
100    {/each}
101  {/if}
102</div>
103

Keyboard shortcuts

Single-key shortcuts are on. ctrl k and esc work whatever this says.

ctrl k :
go to a section, branch, tag, file or repository
?
this list
j k
move the row cursor down / up
enter
open the row under the cursor; on Files, a directory opens or closes in place
↑ ↓ ← → home end
in the file tree (focus on a row): previous / next row, close / open a directory or go to its parent / first entry, first / last row. They never open a file
l h
on Files: open a directory or a file / close a directory or go up to its parent, then to the parent page. Elsewhere: into the side panel (on a merge request, its files) / back to the content; there j k move between its controls
g g G
first / last row
/
filter the list; on Files, find a file anywhere in the repository (esc clears, enter opens the best match)
b
switch branch or tag
g s g f g c g b g m g i g r g a
tabs: summary, files, commits, branches & tags, merge requests, issues, releases, actions (when available)
g h
home
w
wide mode: use the whole width of the screen, or not (remembered)
y
copy a permalink pinned to the commit
d u x
diff: split / unified / collapse or expand all
e E
diff: the whole file in view / every file, with the lines the hunks hide
n
merge request: next note in the diff
esc
close a dialog, leave a field

Branches 8

Tags 42

↑↓ moveenter openesc close