v0.6.0 7d47882

uierrors.go RawHistoryFolder

1// Package uierrors holds the error helper shared by the layer-surface UI
2// adapters.
3package uierrors
4
5import (
6	"context"
7	"errors"
8)
9
10// Drop removes from err, and recursively from errors.Join trees, every leaf
11// that is exactly one of targets. Only bare leaves match: a real failure that
12// merely wraps a target (fmt.Errorf("x: %w", context.Canceled)) is kept, and so
13// is every sibling of a dropped leaf. It returns nil when nothing else remains.
14//
15// Use it to discard the context.Canceled a layerui.Run reports after the
16// adapter itself ended it, without hiding a real error joined to it.
17func Drop(err error, targets ...error) error {
18	if err == nil {
19		return nil
20	}
21	if j, ok := err.(interface{ Unwrap() []error }); ok {
22		var keep []error
23		for _, e := range j.Unwrap() {
24			if e = Drop(e, targets...); e != nil {
25				keep = append(keep, e)
26			}
27		}
28		switch len(keep) {
29		case 0:
30			return nil
31		case 1:
32			return keep[0]
33		}
34		return errors.Join(keep...)
35	}
36	for _, t := range targets {
37		if err == t {
38			return nil
39		}
40	}
41	return err
42}
43
44// Ended classifies how a layerui.Run ended. It is pure: the caller snapshots
45// its state once and passes it, so a context that ends between two reads cannot
46// flip the answer.
47//
48// explained says that this adapter or its caller ended the run on purpose (a
49// decision was made, or the parent context is done). parent is the parent
50// context's error at that snapshot, nil when it is still live. closed is
51// returned when the run ended without an explanation.
52//
53//   - explained: a bare context.Canceled (and bare parent) is the expected echo
54//     of our own cancellation and is dropped. Anything else, including a real
55//     error joined with it or an error that merely wraps Canceled, is kept.
56//   - not explained: the run ended on its own. When something real remains
57//     (an initial authorization, capability or font failure, say), exactly that
58//     is returned: calling it a compositor close would mislead. Only when
59//     nothing real remains, including a bare Canceled, is closed returned.
60func Ended(runErr error, explained bool, parent, closed error) error {
61	if explained {
62		return Drop(runErr, context.Canceled, parent)
63	}
64	if rest := Drop(runErr, context.Canceled, parent); rest != nil {
65		return rest
66	}
67	return closed
68}
69
70// IsCancellation reports whether err is non-nil and made only of
71// context.Canceled leaves, possibly wrapped with %w or joined. A failure
72// joined with, or merely mentioning, a cancellation is not one. Unlike Drop,
73// wrapped Canceled counts: it is how a caller's own cancellation surfaces
74// through layers that add context. DeadlineExceeded is deliberately not
75// included, so a bounded-operation timeout stays a real failure.
76func IsCancellation(err error) bool {
77	switch e := err.(type) {
78	case nil:
79		return false
80	case interface{ Unwrap() []error }:
81		children := e.Unwrap()
82		for _, child := range children {
83			if !IsCancellation(child) {
84				return false
85			}
86		}
87		return len(children) > 0
88	case interface{ Unwrap() error }:
89		return err == context.Canceled || IsCancellation(e.Unwrap())
90	default:
91		return err == context.Canceled
92	}
93}

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 2

Tags 9

↑↓ moveenter openesc close