Skip to content

Commit

Permalink
fix: description positioning (#119)
Browse files Browse the repository at this point in the history
Signed-off-by: Chapman Pendery <[email protected]>
  • Loading branch information
cpendery authored Dec 14, 2023
1 parent 481f18e commit 5c35624
Show file tree
Hide file tree
Showing 2 changed files with 44 additions and 23 deletions.
47 changes: 34 additions & 13 deletions src/ui/suggestionManager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ const activeSuggestionBackgroundColor = "#7D56F4";
export const MAX_LINES = borderWidth + Math.max(maxSuggestions, descriptionHeight);
type SuggestionsSequence = {
data: string;
columns: number;
rows: number;
};

export class SuggestionManager {
Expand Down Expand Up @@ -58,6 +58,11 @@ export class SuggestionManager {
return renderBox(truncateMultilineText(description, descriptionWidth - borderWidth, descriptionHeight), descriptionWidth, x);
}

private _descriptionRows(description: string | undefined) {
if (!description) return 0;
return truncateMultilineText(description, descriptionWidth - borderWidth, descriptionHeight).length;
}

private _renderSuggestions(suggestions: Suggestion[], activeSuggestionIdx: number, x: number) {
return renderBox(
suggestions.map((suggestion, idx) => {
Expand All @@ -70,9 +75,9 @@ export class SuggestionManager {
);
}

async render(): Promise<SuggestionsSequence> {
async render(remainingLines: number): Promise<SuggestionsSequence> {
await this._loadSuggestions();
if (!this.#suggestBlob) return { data: "", columns: 0 };
if (!this.#suggestBlob) return { data: "", rows: 0 };
const { suggestions, argumentDescription } = this.#suggestBlob;

const page = Math.min(Math.floor(this.#activeSuggestionIdx / maxSuggestions) + 1, Math.floor(suggestions.length / maxSuggestions) + 1);
Expand All @@ -98,21 +103,37 @@ export class SuggestionManager {
ansi.cursorUp(2) +
ansi.cursorForward(clampedLeftPadding) +
this._renderArgumentDescription(argumentDescription, clampedLeftPadding),
columns: 3,
rows: 3,
};
}
return { data: "", columns: 0 };
return { data: "", rows: 0 };
}

const columnsUsed = pagedSuggestions.length + borderWidth;
const ui = swapDescription
? this._renderDescription(activeDescription, clampedLeftPadding) +
this._renderSuggestions(pagedSuggestions, activePagedSuggestionIndex, clampedLeftPadding + descriptionWidth)
: this._renderSuggestions(pagedSuggestions, activePagedSuggestionIndex, clampedLeftPadding) +
this._renderDescription(activeDescription, clampedLeftPadding + suggestionWidth);
const suggestionRowsUsed = pagedSuggestions.length + borderWidth;
let descriptionRowsUsed = this._descriptionRows(activeDescription) + borderWidth;
let rows = Math.max(descriptionRowsUsed, suggestionRowsUsed);
if (rows <= remainingLines) {
descriptionRowsUsed = suggestionRowsUsed;
rows = suggestionRowsUsed;
}

const descriptionUI =
ansi.cursorUp(descriptionRowsUsed - 1) +
(swapDescription
? this._renderDescription(activeDescription, clampedLeftPadding)
: this._renderDescription(activeDescription, clampedLeftPadding + suggestionWidth)) +
ansi.cursorDown(descriptionRowsUsed - 1);
const suggestionUI =
ansi.cursorUp(suggestionRowsUsed - 1) +
(swapDescription
? this._renderSuggestions(pagedSuggestions, activePagedSuggestionIndex, clampedLeftPadding + descriptionWidth)
: this._renderSuggestions(pagedSuggestions, activePagedSuggestionIndex, clampedLeftPadding)) +
ansi.cursorDown(suggestionRowsUsed - 1);

const ui = swapDescription ? descriptionUI + suggestionUI : suggestionUI + descriptionUI;
return {
data: ansi.cursorHide + ansi.cursorUp(columnsUsed - 1) + ansi.cursorForward(clampedLeftPadding) + ui + ansi.cursorShow,
columns: columnsUsed,
data: ansi.cursorHide + ansi.cursorForward(clampedLeftPadding) + ui + ansi.cursorShow,
rows,
};
}

Expand Down
20 changes: 10 additions & 10 deletions src/ui/ui-root.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ export const render = async (shell: Shell) => {
const term = await isterm.spawn({ shell, rows: process.stdout.rows, cols: process.stdout.columns });
const suggestionManager = new SuggestionManager(term);
let hasActiveSuggestions = false;
let previousSuggestionsColumns = 0;
let previousSuggestionsRows = 0;
process.stdin.setRawMode(true);

const writeOutput = (data: string) => {
Expand All @@ -26,7 +26,7 @@ export const render = async (shell: Shell) => {
term.onData((data) => {
const commandState = term.getCommandState();
if ((commandState.hasOutput || hasActiveSuggestions) && !commandState.persistentOutput) {
if (term.getCursorState().remainingLines < previousSuggestionsColumns) {
if (term.getCursorState().remainingLines < previousSuggestionsRows) {
writeOutput(
ansi.cursorHide +
ansi.cursorSavePosition +
Expand All @@ -44,12 +44,12 @@ export const render = async (shell: Shell) => {
}

setImmediate(async () => {
const suggestion = await suggestionManager.render();
const suggestion = await suggestionManager.render(term.getCursorState().remainingLines);
const commandState = term.getCommandState();

if (suggestion.data != "" && commandState.cursorTerminated && !commandState.hasOutput) {
if (hasActiveSuggestions) {
if (term.getCursorState().remainingLines < suggestion.columns) {
if (term.getCursorState().remainingLines < suggestion.rows) {
writeOutput(
ansi.cursorHide +
ansi.cursorSavePosition +
Expand All @@ -63,7 +63,7 @@ export const render = async (shell: Shell) => {
ansi.cursorShow,
);
} else {
const offset = MAX_LINES - suggestion.columns;
const offset = MAX_LINES - suggestion.rows;
writeOutput(
ansi.cursorHide +
ansi.cursorSavePosition +
Expand All @@ -75,13 +75,13 @@ export const render = async (shell: Shell) => {
);
}
} else {
if (term.getCursorState().remainingLines < suggestion.columns) {
if (term.getCursorState().remainingLines < suggestion.rows) {
writeOutput(ansi.cursorHide + ansi.cursorSavePosition + ansi.cursorUp() + suggestion.data + ansi.cursorRestorePosition + ansi.cursorShow);
} else {
writeOutput(
ansi.cursorHide +
ansi.cursorSavePosition +
ansi.cursorNextLine.repeat(suggestion.columns) +
ansi.cursorNextLine.repeat(suggestion.rows) +
suggestion.data +
ansi.cursorRestorePosition +
ansi.cursorShow,
Expand All @@ -91,7 +91,7 @@ export const render = async (shell: Shell) => {
hasActiveSuggestions = true;
} else {
if (hasActiveSuggestions) {
if (term.getCursorState().remainingLines < previousSuggestionsColumns) {
if (term.getCursorState().remainingLines < previousSuggestionsRows) {
writeOutput(
ansi.cursorHide +
ansi.cursorSavePosition +
Expand All @@ -106,12 +106,12 @@ export const render = async (shell: Shell) => {
}
hasActiveSuggestions = false;
}
previousSuggestionsColumns = suggestion.columns;
previousSuggestionsRows = suggestion.rows;
});
});
process.stdin.on("data", (d: Buffer) => {
const suggestionResult = suggestionManager.update(d);
if (previousSuggestionsColumns > 0 && suggestionResult == "handled") {
if (previousSuggestionsRows > 0 && suggestionResult == "handled") {
term.noop();
} else if (suggestionResult != "fully-handled") {
term.write(inputModifier(d));
Expand Down

0 comments on commit 5c35624

Please sign in to comment.