| @@ -94,7 +94,9 @@ struct FileView: View { |
| 94 | } |
94 | } |
| 95 | // Defined once: that line, at the ref on screen, as the |
95 | // Defined once: that line, at the ref on screen, as the |
| 96 | // web links it. More often: the search, to choose. |
96 | // web links it. More often: the search, to choose. |
| 97 | if def.count == 1 { |
97 | // repo symbols takes two characters at least, so a |
| |
98 | // one-letter name defined more often opens its first. |
| |
99 | if def.count == 1 || name.count < 2 { |
| 98 | pushRoute(RepoRoute.file(repo: model.repoPath, path: def.path, ref: model.ref, line: def.line)) |
100 | pushRoute(RepoRoute.file(repo: model.repoPath, path: def.path, ref: model.ref, line: def.line)) |
| 99 | } else { |
101 | } else { |
| 100 | pushRoute(RepoRoute.symbols(repo: model.repoPath, query: name)) |
102 | pushRoute(RepoRoute.symbols(repo: model.repoPath, query: name)) |
| @@ -117,7 +119,6 @@ private struct CodeScrollView: View { |
| 117 | var line: Int? |
119 | var line: Int? |
| 118 | var definitions: [String: Definition] = [:] |
120 | var definitions: [String: Definition] = [:] |
| 119 | |
121 | |
| 120 | @State private var highlighted: [AttributedString] = [] |
| |
| 121 | @State private var lines: [AttributedString] = [] |
122 | @State private var lines: [AttributedString] = [] |
| 122 | |
123 | |
| 123 | var body: some View { |
124 | var body: some View { |
| @@ -128,7 +129,10 @@ private struct CodeScrollView: View { |
| 128 | // scrollTo names: a lazy row not yet drawn has no other. |
129 | // scrollTo names: a lazy row not yet drawn has no other. |
| 129 | ForEach(lines.indices, id: \.self) { index in |
130 | ForEach(lines.indices, id: \.self) { index in |
| 130 | let target = index + 1 == line |
131 | let target = index + 1 == line |
| 131 | Text(lines[index].characters.isEmpty ? " " : lines[index]) |
132 | // Linked as the row is drawn, so a long file costs |
| |
133 | // only the rows on screen. |
| |
134 | let shown = definitions.isEmpty ? lines[index] : Definition.link(lines[index], definitions: definitions) |
| |
135 | Text(shown.characters.isEmpty ? " " : shown) |
| 132 | .fixedSize() |
136 | .fixedSize() |
| 133 | .frame(maxWidth: .infinity, alignment: .leading) |
137 | .frame(maxWidth: .infinity, alignment: .leading) |
| 134 | .background(target ? Color.gbMark.opacity(0.18) : .clear) |
138 | .background(target ? Color.gbMark.opacity(0.18) : .clear) |
| @@ -140,8 +144,7 @@ private struct CodeScrollView: View { |
| 140 | .defaultScrollAnchor(.topLeading) |
144 | .defaultScrollAnchor(.topLeading) |
| 141 | .font(.gbMono(.caption)) |
145 | .font(.gbMono(.caption)) |
| 142 | .task(id: colorScheme) { |
146 | .task(id: colorScheme) { |
| 143 | highlighted = highlightedLines() |
147 | lines = highlightedLines() |
| 144 | lines = linked(highlighted) |
| |
| 145 | if let line, line <= lines.count { |
148 | if let line, line <= lines.count { |
| 146 | // A frame for the highlighted lines to exist before the |
149 | // A frame for the highlighted lines to exist before the |
| 147 | // jump, or the lazy stack has nothing to scroll to. |
150 | // jump, or the lazy stack has nothing to scroll to. |
| @@ -149,15 +152,9 @@ private struct CodeScrollView: View { |
| 149 | proxy.scrollTo(line - 1, anchor: UnitPoint(x: 0, y: 0.3)) |
152 | proxy.scrollTo(line - 1, anchor: UnitPoint(x: 0, y: 0.3)) |
| 150 | } |
153 | } |
| 151 | } |
154 | } |
| 152 | // The definitions arrive after the file; link what is drawn. |
| |
| 153 | .onChange(of: definitions) { lines = linked(highlighted) } |
| |
| 154 | } |
155 | } |
| 155 | } |
156 | } |
| 156 | |
157 | |
| 157 | private func linked(_ lines: [AttributedString]) -> [AttributedString] { |
| |
| 158 | definitions.isEmpty ? lines : lines.map { Definition.link($0, definitions: definitions) } |
| |
| 159 | } |
| |
| 160 | |
| |
| 161 | private func highlightedLines() -> [AttributedString] { |
158 | private func highlightedLines() -> [AttributedString] { |
| 162 | let size = UIFont.preferredFont(forTextStyle: .caption1).pointSize |
159 | let size = UIFont.preferredFont(forTextStyle: .caption1).pointSize |
| 163 | let font = UIFont(name: "Atkinson Hyperlegible Mono", size: size) |
160 | let font = UIFont(name: "Atkinson Hyperlegible Mono", size: size) |