|
| 1 | +/* eslint-disable no-console */ |
| 2 | +import process from 'node:process' |
1 | 3 | import c from 'picocolors'
|
2 | 4 | import { SemVer } from 'semver'
|
3 | 5 | import { getDiff } from './io/resolves'
|
@@ -110,3 +112,77 @@ export function colorizeVersionDiff(from: string, to: string, hightlightRange =
|
110 | 112 | + middot
|
111 | 113 | + c[color](partsToColor.slice(i).join('.')).trim()
|
112 | 114 | }
|
| 115 | + |
| 116 | +interface SliceRenderLine { |
| 117 | + content: string |
| 118 | + fixed?: boolean |
| 119 | +} |
| 120 | + |
| 121 | +export function createSliceRender() { |
| 122 | + const buffer: SliceRenderLine[] = [] |
| 123 | + |
| 124 | + return { |
| 125 | + push(...lines: SliceRenderLine[]) { |
| 126 | + buffer.push(...lines) |
| 127 | + }, |
| 128 | + render(selectedDepIndex: number) { |
| 129 | + let { |
| 130 | + rows: remainHeight, |
| 131 | + columns: availableWidth, |
| 132 | + } = process.stdout |
| 133 | + |
| 134 | + const lines: SliceRenderLine[] = buffer.length < remainHeight - 1 |
| 135 | + ? buffer |
| 136 | + : [...buffer, { content: c.yellow(' -- END --') }] |
| 137 | + |
| 138 | + // spare space for cursor |
| 139 | + remainHeight -= 1 |
| 140 | + let i = 0 |
| 141 | + while (i < lines.length) { |
| 142 | + const curr = lines[i] |
| 143 | + if (curr.fixed) { |
| 144 | + console.log(curr.content) |
| 145 | + remainHeight -= 1 |
| 146 | + i++ |
| 147 | + } |
| 148 | + else { |
| 149 | + break |
| 150 | + } |
| 151 | + } |
| 152 | + |
| 153 | + const remainLines = lines.slice(i) |
| 154 | + |
| 155 | + // calculate focused line index from selected dep index |
| 156 | + let focusedLineIndex = 0 |
| 157 | + let depIndex = 0 |
| 158 | + for (const line of remainLines) { |
| 159 | + if (line.content.includes(FIG_CHECK)) |
| 160 | + depIndex += 1 |
| 161 | + |
| 162 | + if (depIndex === selectedDepIndex) |
| 163 | + break |
| 164 | + else |
| 165 | + focusedLineIndex += 1 |
| 166 | + } |
| 167 | + |
| 168 | + let slice: SliceRenderLine[] |
| 169 | + if ( |
| 170 | + remainHeight < 1 |
| 171 | + || remainLines.length === 0 |
| 172 | + || remainLines.length <= remainHeight |
| 173 | + || lines.some(x => Math.ceil(visualLength(x.content) / availableWidth) > 1) |
| 174 | + ) { |
| 175 | + slice = remainLines |
| 176 | + } |
| 177 | + else { |
| 178 | + const half = Math.floor((remainHeight - 1) / 2) |
| 179 | + const f = focusedLineIndex - half |
| 180 | + const b = focusedLineIndex + remainHeight - half - remainLines.length |
| 181 | + const start = Math.max(0, b <= 0 ? f : f - b) |
| 182 | + slice = remainLines.slice(start, start + remainHeight) |
| 183 | + } |
| 184 | + |
| 185 | + console.log(slice.map(x => x.content).join('\n')) |
| 186 | + }, |
| 187 | + } |
| 188 | +} |
0 commit comments