mirror of
https://github.com/wavetermdev/inshellisense.git
synced 2026-08-05 13:43:30 -07:00
fix: description positioning (#119)
Signed-off-by: Chapman Pendery <cpendery@vt.edu>
This commit is contained in:
+34
-13
@@ -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 {
|
||||
@@ -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) => {
|
||||
@@ -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);
|
||||
@@ -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,
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
+10
-10
@@ -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) => {
|
||||
@@ -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 +
|
||||
@@ -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 +
|
||||
@@ -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 +
|
||||
@@ -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,
|
||||
@@ -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 +
|
||||
@@ -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));
|
||||
|
||||
Reference in New Issue
Block a user