| @@ -94,7 +94,9 @@ struct FileView: View { |
| 94 | 94 | } |
| 95 | 95 | // Defined once: that line, at the ref on screen, as the |
| 96 | 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 | 100 | pushRoute(RepoRoute.file(repo: model.repoPath, path: def.path, ref: model.ref, line: def.line)) |
| 99 | 101 | } else { |
| 100 | 102 | pushRoute(RepoRoute.symbols(repo: model.repoPath, query: name)) |
| @@ -117,7 +119,6 @@ private struct CodeScrollView: View { |
| 117 | 119 | var line: Int? |
| 118 | 120 | var definitions: [String: Definition] = [:] |
| 119 | 121 | |
| 120 | | @State private var highlighted: [AttributedString] = [] |
| 121 | 122 | @State private var lines: [AttributedString] = [] |
| 122 | 123 | |
| 123 | 124 | var body: some View { |
| @@ -128,7 +129,10 @@ private struct CodeScrollView: View { |
| 128 | 129 | // scrollTo names: a lazy row not yet drawn has no other. |
| 129 | 130 | ForEach(lines.indices, id: \.self) { index in |
| 130 | 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 | 136 | .fixedSize() |
| 133 | 137 | .frame(maxWidth: .infinity, alignment: .leading) |
| 134 | 138 | .background(target ? Color.gbMark.opacity(0.18) : .clear) |
| @@ -140,8 +144,7 @@ private struct CodeScrollView: View { |
| 140 | 144 | .defaultScrollAnchor(.topLeading) |
| 141 | 145 | .font(.gbMono(.caption)) |
| 142 | 146 | .task(id: colorScheme) { |
| 143 | | highlighted = highlightedLines() |
| 144 | | lines = linked(highlighted) |
| 147 | lines = highlightedLines() |
| 145 | 148 | if let line, line <= lines.count { |
| 146 | 149 | // A frame for the highlighted lines to exist before the |
| 147 | 150 | // jump, or the lazy stack has nothing to scroll to. |
| @@ -149,15 +152,9 @@ private struct CodeScrollView: View { |
| 149 | 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 | 158 | private func highlightedLines() -> [AttributedString] { |
| 162 | 159 | let size = UIFont.preferredFont(forTextStyle: .caption1).pointSize |
| 163 | 160 | let font = UIFont(name: "Atkinson Hyperlegible Mono", size: size) |