v0.26.1 75cd777

KeybindingGroup.svelte RawHistoryFolder

1<script lang="ts">
2  import { Button } from "$lib/components/ui/button";
3  import * as Table from "$lib/components/ui/table";
4  import { RotateCcw, Edit3 } from "@lucide/svelte";
5  import { formatKey } from "$lib/utils/keys";
6
7  type KeybindingEntry = {
8    action: string;
9    description: string;
10    keys: string[];
11    default_keys: string[];
12    is_custom: boolean;
13  };
14
15  type KeybindingGroupData = {
16    mode: string;
17    display_name: string;
18    bindings: KeybindingEntry[];
19    activation?: string;
20  };
21
22  interface Props {
23    group: KeybindingGroupData;
24    onEdit: (action: string, entry: KeybindingEntry) => void;
25    onReset: (action: string) => void;
26  }
27
28  let { group, onEdit, onReset }: Props = $props();
29</script>
30
31<div class="space-y-3">
32  <div class="flex items-center gap-2">
33    <h3 class="text-sm font-semibold uppercase tracking-[0.15em] text-muted-foreground">
34      {group.display_name}
35    </h3>
36    {#if group.activation}
37      <span class="rounded-md bg-muted px-2 py-0.5 text-xs font-mono text-muted-foreground">
38        {formatKey(group.activation)}
39      </span>
40    {/if}
41  </div>
42
43  <Table.Root class="rounded-md border border-border">
44    <Table.Header>
45      <Table.Row>
46        <Table.Head class="w-[180px]">Action</Table.Head>
47        <Table.Head>Description</Table.Head>
48        <Table.Head class="w-[200px]">Keybinding</Table.Head>
49        <Table.Head class="w-[100px] text-right">Actions</Table.Head>
50      </Table.Row>
51    </Table.Header>
52    <Table.Body>
53      {#each group.bindings as binding (binding.action)}
54        <Table.Row class={binding.is_custom ? "bg-accent/5" : ""}>
55          <Table.Cell class="font-mono text-sm">{binding.action}</Table.Cell>
56          <Table.Cell class="text-muted-foreground">{binding.description}</Table.Cell>
57          <Table.Cell>
58            <div class="flex flex-wrap gap-1">
59              {#each binding.keys as key (key)}
60                <kbd class="rounded bg-muted px-1.5 py-0.5 text-xs font-mono">
61                  {formatKey(key)}
62                </kbd>
63              {/each}
64              {#if binding.keys.length === 0}
65                <span class="text-xs text-muted-foreground">(unbound)</span>
66              {/if}
67            </div>
68          </Table.Cell>
69          <Table.Cell class="text-right">
70            <div class="flex justify-end gap-1">
71              <Button
72                variant="ghost"
73                size="icon"
74                onclick={() => onEdit(binding.action, binding)}
75                aria-label="Edit binding"
76              >
77                <Edit3 class="size-4" />
78              </Button>
79              {#if binding.is_custom}
80                <Button
81                  variant="ghost"
82                  size="icon"
83                  onclick={() => onReset(binding.action)}
84                  aria-label="Reset to default"
85                >
86                  <RotateCcw class="size-4" />
87                </Button>
88              {/if}
89            </div>
90          </Table.Cell>
91        </Table.Row>
92      {/each}
93    </Table.Body>
94  </Table.Root>
95</div>

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