Hide caret when the command is not executing

This commit is contained in:
Saoud Rizwan
2024-09-02 00:38:26 -04:00
parent 3a37421ffd
commit 492ffeb5b1
3 changed files with 25 additions and 8 deletions

View File

@@ -1277,7 +1277,7 @@ export class ClaudeDev {
// }
} catch (e) {
if ((e as ExecaError).signal === "SIGINT") {
await this.say("command_output", `\nUser exited command...`)
//await this.say("command_output", `\nUser exited command...`)
result += `\n====\nUser terminated command process via SIGINT. This is not an error. Please continue with your task, but keep in mind that the command is no longer running. For example, if this command was used to start a server for a react app, the server is no longer running and you cannot open a browser to view it anymore.`
} else {
throw e // if the command was not terminated by user, let outer catch handle it as a real error

View File

@@ -425,6 +425,7 @@ const ChatRow: React.FC<ChatRowProps> = ({
<Terminal
output={command + (output ? "\n" + output : "")}
handleSendStdin={handleSendStdin}
shouldAllowInput={!!isCommandExecuting && output.length > 0}
/>
</>
)

View File

@@ -3,6 +3,7 @@ import DynamicTextArea from "react-textarea-autosize"
interface TerminalProps {
output: string
shouldAllowInput: boolean
handleSendStdin: (text: string) => void
}
@@ -10,7 +11,7 @@ interface TerminalProps {
Inspired by https://phuoc.ng/collection/mirror-a-text-area/create-your-own-custom-cursor-in-a-text-area/
*/
const Terminal: React.FC<TerminalProps> = ({ output, handleSendStdin }) => {
const Terminal: React.FC<TerminalProps> = ({ output, shouldAllowInput, handleSendStdin }) => {
const [userInput, setUserInput] = useState("")
const [isFocused, setIsFocused] = useState(false) // Initially not focused
const textAreaRef = useRef<HTMLTextAreaElement>(null)
@@ -26,6 +27,7 @@ const Terminal: React.FC<TerminalProps> = ({ output, handleSendStdin }) => {
}, [output, lastProcessedOutput])
const handleKeyPress = (e: React.KeyboardEvent<HTMLTextAreaElement>) => {
if (!shouldAllowInput) return
if (e.key === "Enter") {
e.preventDefault()
handleSendStdin(userInput)
@@ -128,9 +130,12 @@ const Terminal: React.FC<TerminalProps> = ({ output, handleSendStdin }) => {
const caretEle = document.createElement("span")
caretEle.classList.add("terminal-cursor")
if (isFocused) {
if (isFocused && shouldAllowInput) {
caretEle.classList.add("terminal-cursor-focused")
}
if (!shouldAllowInput) {
caretEle.classList.add("terminal-cursor-hidden")
}
caretEle.innerHTML = "&nbsp;"
mirror.appendChild(caretEle)
@@ -142,7 +147,7 @@ const Terminal: React.FC<TerminalProps> = ({ output, handleSendStdin }) => {
document.addEventListener("selectionchange", updateMirror)
return () => document.removeEventListener("selectionchange", updateMirror)
}, [userInput, isFocused])
}, [userInput, isFocused, shouldAllowInput])
useEffect(() => {
// Position the dummy caret at the end of the text on initial render
@@ -154,15 +159,19 @@ const Terminal: React.FC<TerminalProps> = ({ output, handleSendStdin }) => {
const caretEle = document.createElement("span")
caretEle.classList.add("terminal-cursor")
if (isFocused) {
if (isFocused && shouldAllowInput) {
caretEle.classList.add("terminal-cursor-focused")
}
if (!shouldAllowInput) {
caretEle.classList.add("terminal-cursor-hidden")
}
caretEle.innerHTML = "&nbsp;"
mirror.appendChild(caretEle)
}
}, [output, userInput, isFocused])
}, [output, userInput, isFocused, shouldAllowInput])
const handleChange = (e: React.ChangeEvent<HTMLTextAreaElement>) => {
if (!shouldAllowInput) return
const newValue = e.target.value
if (newValue.startsWith(output)) {
setUserInput(newValue.slice(output.length))
@@ -181,6 +190,7 @@ const Terminal: React.FC<TerminalProps> = ({ output, handleSendStdin }) => {
}
const handleKeyDown = (e: React.KeyboardEvent<HTMLTextAreaElement>) => {
if (!shouldAllowInput) return
const textarea = e.target as HTMLTextAreaElement
const cursorPosition = textarea.selectionStart
@@ -260,11 +270,15 @@ const Terminal: React.FC<TerminalProps> = ({ output, handleSendStdin }) => {
.terminal-cursor-focused {
background-color: var(--vscode-terminalCursor-foreground);
}
.terminal-cursor-hidden {
display: none;
}
`}
</style>
<DynamicTextArea
ref={textAreaRef}
value={output + userInput}
value={output + (shouldAllowInput ? userInput : "")}
onChange={handleChange}
onKeyDown={handleKeyDown}
onKeyPress={handleKeyPress}
@@ -272,12 +286,14 @@ const Terminal: React.FC<TerminalProps> = ({ output, handleSendStdin }) => {
onBlur={() => setIsFocused(false)}
className="terminal-textarea"
style={{
backgroundColor: "var(--vscode-terminal-background)",
backgroundColor: "var(--vscode-editor-background)",
caretColor: "transparent", // Hide default caret
color: "var(--vscode-terminal-foreground)",
borderRadius: "3px",
...(textAreaStyle as any),
//pointerEvents: shouldAllowInput ? "auto" : "none",
}}
readOnly={!shouldAllowInput}
minRows={1}
/>
<div ref={mirrorRef} className="terminal-mirror"></div>