mirror of
https://github.com/wavetermdev/inshellisense.git
synced 2026-08-05 13:43:30 -07:00
feat: add arrow navigation support to input field
Signed-off-by: Chapman Pendery <cpendery@vt.edu>
This commit is contained in:
Generated
+1
@@ -10,6 +10,7 @@
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@withfig/autocomplete": "^2.633.0",
|
||||
"chalk": "^5.3.0",
|
||||
"commander": "^11.0.0",
|
||||
"ink": "^4.4.1",
|
||||
"react": "^18.2.0",
|
||||
|
||||
+2
-1
@@ -23,6 +23,7 @@
|
||||
"homepage": "https://github.com/microsoft/clac#readme",
|
||||
"dependencies": {
|
||||
"@withfig/autocomplete": "^2.633.0",
|
||||
"chalk": "^5.3.0",
|
||||
"commander": "^11.0.0",
|
||||
"ink": "^4.4.1",
|
||||
"react": "^18.2.0",
|
||||
@@ -38,4 +39,4 @@
|
||||
"ts-jest": "^29.1.1",
|
||||
"typescript": "^5.2.2"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,47 @@
|
||||
import React, { useState, useEffect } from "react";
|
||||
import { useInput, Text } from "ink";
|
||||
import chalk from "chalk";
|
||||
|
||||
const BlinkSpeed = 530;
|
||||
const CursorColor = "#FFFFFF";
|
||||
|
||||
export default function Input({ value, setValue, prompt }: { value: string; setValue: (_: string) => void; prompt: string }) {
|
||||
const [cursorLocation, setCursorLocation] = useState(value.length);
|
||||
const [cursorBlink, setCursorBlink] = useState(true);
|
||||
|
||||
useEffect(() => {
|
||||
setTimeout(() => {
|
||||
setCursorBlink(!cursorBlink);
|
||||
}, BlinkSpeed);
|
||||
}, [cursorBlink]);
|
||||
|
||||
// TODO: arrow key navigation shortcuts (emacs & vim modes)
|
||||
useInput((input, key) => {
|
||||
if (key.backspace) {
|
||||
setValue([...value].slice(0, Math.max(cursorLocation - 1, 0)).join("") + [...value].slice(cursorLocation).join(""));
|
||||
setCursorLocation(Math.max(cursorLocation - 1, 0));
|
||||
} else if (key.delete) {
|
||||
setValue([...value].slice(0, cursorLocation).join("") + [...value].slice(Math.min(value.length, cursorLocation + 1)).join(""));
|
||||
} else if (key.leftArrow) {
|
||||
setCursorLocation(Math.max(cursorLocation - 1, 0));
|
||||
} else if (key.rightArrow) {
|
||||
setCursorLocation(Math.min(cursorLocation + 1, value.length));
|
||||
} else if (input) {
|
||||
setValue([...value].slice(0, cursorLocation).join("") + input + [...value].slice(cursorLocation).join(""));
|
||||
setCursorLocation(cursorLocation + input.length);
|
||||
}
|
||||
});
|
||||
|
||||
const cursoredCommand = value + " ";
|
||||
const cursoredText =
|
||||
[...cursoredCommand].slice(0, cursorLocation).join("") +
|
||||
(cursorBlink ? chalk.bgHex(CursorColor).inverse([...cursoredCommand].at(cursorLocation)) : [...cursoredCommand].at(cursorLocation)) +
|
||||
[...cursoredCommand].slice(cursorLocation + 1).join("");
|
||||
|
||||
return (
|
||||
<Text>
|
||||
{prompt}
|
||||
{cursoredText}
|
||||
</Text>
|
||||
);
|
||||
}
|
||||
+5
-16
@@ -1,13 +1,14 @@
|
||||
import React, { useCallback, useEffect, useState } from "react";
|
||||
import { Text, Box, useInput, render as inkRender, measureElement, DOMElement } from "ink";
|
||||
import { Text, Box, render as inkRender, measureElement, DOMElement, useApp } from "ink";
|
||||
import wrapAnsi from "wrap-ansi";
|
||||
|
||||
import { getSuggestions } from "../runtime/runtime.js";
|
||||
import { Suggestion } from "../runtime/model.js";
|
||||
import Cursor from "./cursor.js";
|
||||
import Suggestions from "./suggestions.js";
|
||||
|
||||
import Input from "./input.js";
|
||||
const Prompt = "> ";
|
||||
|
||||
// TODO: support tab completion
|
||||
function UI() {
|
||||
const [command, setCommand] = useState("");
|
||||
const [activeSuggestion, setActiveSuggestion] = useState<Suggestion>();
|
||||
@@ -28,23 +29,11 @@ function UI() {
|
||||
});
|
||||
}, [command]);
|
||||
|
||||
useInput((input, key) => {
|
||||
if (key.backspace) {
|
||||
setCommand([...command].slice(0, -1).join(""));
|
||||
} else {
|
||||
setCommand(command + input);
|
||||
}
|
||||
});
|
||||
|
||||
return (
|
||||
<Box flexDirection="column" ref={measureRef}>
|
||||
<Box>
|
||||
<Text>
|
||||
<Text>
|
||||
{Prompt}
|
||||
{command}
|
||||
</Text>
|
||||
<Cursor />
|
||||
<Input value={command} setValue={setCommand} prompt={Prompt} />
|
||||
</Text>
|
||||
</Box>
|
||||
<Suggestions leftPadding={leftPadding} setActiveSuggestion={setActiveSuggestion} suggestions={suggestions} />
|
||||
|
||||
Reference in New Issue
Block a user