summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--continuedev/src/continuedev/core/autopilot.py2
-rw-r--r--continuedev/src/continuedev/server/ide.py7
-rw-r--r--continuedev/src/continuedev/steps/core/core.py22
-rw-r--r--extension/package-lock.json4
-rw-r--r--extension/package.json2
-rw-r--r--extension/react-app/src/components/ComboBox.tsx62
-rw-r--r--extension/react-app/src/components/ContinueButton.tsx3
-rw-r--r--extension/react-app/src/components/StepContainer.tsx3
-rw-r--r--extension/react-app/src/tabs/gui.tsx26
-rw-r--r--extension/src/continueIdeClient.ts4
-rw-r--r--extension/src/diffs.ts3
11 files changed, 73 insertions, 65 deletions
diff --git a/continuedev/src/continuedev/core/autopilot.py b/continuedev/src/continuedev/core/autopilot.py
index 6e4326f0..02fd61de 100644
--- a/continuedev/src/continuedev/core/autopilot.py
+++ b/continuedev/src/continuedev/core/autopilot.py
@@ -153,7 +153,7 @@ class Autopilot(ContinueBaseModel):
async def handle_highlighted_code(self, range_in_files: List[RangeInFileWithContents]):
# If un-highlighting, then remove the range
- if len(self._highlighted_ranges) == 1 and len(range_in_files) <= 1 and (len(range_in_files) == 0 or range_in_files[0].range.start == range_in_files[0].range.end):
+ if len(self._highlighted_ranges) == 1 and len(range_in_files) <= 1 and (len(range_in_files) == 0 or range_in_files[0].range.start == range_in_files[0].range.end) and not self._adding_highlighted_code:
self._highlighted_ranges = []
await self.update_subscribers()
return
diff --git a/continuedev/src/continuedev/server/ide.py b/continuedev/src/continuedev/server/ide.py
index ea355d3c..d16bd449 100644
--- a/continuedev/src/continuedev/server/ide.py
+++ b/continuedev/src/continuedev/server/ide.py
@@ -148,6 +148,8 @@ class IdeProtocolServer(AbstractIdeProtocolServer):
self.onCommandOutput(output)
elif message_type == "acceptRejectSuggestion":
self.onAcceptRejectSuggestion(data["accepted"])
+ elif message_type == "acceptRejectDiff":
+ self.onAcceptRejectDiff(data["accepted"])
elif message_type in ["highlightedCode", "openFiles", "readFile", "editFile", "workspaceDirectory", "getUserSecret", "runCommand", "uniqueId"]:
self.sub_queue.post(message_type, data)
else:
@@ -219,6 +221,11 @@ class IdeProtocolServer(AbstractIdeProtocolServer):
"accepted": accepted
})
+ def onAcceptRejectDiff(self, accepted: bool):
+ capture_event(self.unique_id, "accept_reject_diff", {
+ "accepted": accepted
+ })
+
def onFileSystemUpdate(self, update: FileSystemEdit):
# Access to Autopilot (so SessionManager)
pass
diff --git a/continuedev/src/continuedev/steps/core/core.py b/continuedev/src/continuedev/steps/core/core.py
index 5577c49a..f22297ae 100644
--- a/continuedev/src/continuedev/steps/core/core.py
+++ b/continuedev/src/continuedev/steps/core/core.py
@@ -450,40 +450,40 @@ class DefaultModelEditCodeStep(Step):
chunk_lines.pop() # because this will be an empty string
else:
unfinished_line = chunk_lines.pop()
- lines.extend(map(lambda l: common_whitespace + l, chunk_lines))
-
- if True:
- await sendDiffUpdate(lines + [common_whitespace + unfinished_line], sdk)
# Deal with newly accumulated lines
- for line in chunk_lines:
+ for i in range(len(chunk_lines)):
# Trailing whitespace doesn't matter
- line = line.rstrip()
+ chunk_lines[i] = chunk_lines[i].rstrip()
+ chunk_lines[i] = common_whitespace + chunk_lines[i]
# Lines that should signify the end of generation
- if self.is_end_line(line):
+ if self.is_end_line(chunk_lines[i]):
break
# Lines that should be ignored, like the <> tags
- elif self.line_to_be_ignored(line, completion_lines_covered == 0):
+ elif self.line_to_be_ignored(chunk_lines[i], completion_lines_covered == 0):
continue
# Check if we are currently just copying the prefix
- elif (lines_of_prefix_copied > 0 or completion_lines_covered == 0) and lines_of_prefix_copied < len(file_prefix.splitlines()) and line == full_file_contents_lines[lines_of_prefix_copied]:
+ elif (lines_of_prefix_copied > 0 or completion_lines_covered == 0) and lines_of_prefix_copied < len(file_prefix.splitlines()) and chunk_lines[i] == full_file_contents_lines[lines_of_prefix_copied]:
# This is a sketchy way of stopping it from repeating the file_prefix. Is a bug if output happens to have a matching line
lines_of_prefix_copied += 1
continue
# Because really short lines might be expected to be repeated, this is only a !heuristic!
# Stop when it starts copying the file_suffix
- elif line.strip() == line_below_highlighted_range.strip() and len(line.strip()) > 4 and not (len(original_lines_below_previous_blocks) > 0 and line.strip() == original_lines_below_previous_blocks[0].strip()):
+ elif chunk_lines[i].strip() == line_below_highlighted_range.strip() and len(chunk_lines[i].strip()) > 4 and not (len(original_lines_below_previous_blocks) > 0 and chunk_lines[i].strip() == original_lines_below_previous_blocks[0].strip()):
repeating_file_suffix = True
break
# If none of the above, insert the line!
if False:
- await handle_generated_line(line)
+ await handle_generated_line(chunk_lines[i])
+ lines.append(chunk_lines[i])
completion_lines_covered += 1
current_line_in_file += 1
+ await sendDiffUpdate(lines + [common_whitespace + unfinished_line], sdk)
+
# Add the unfinished line
if unfinished_line != "" and not self.line_to_be_ignored(unfinished_line, completion_lines_covered == 0) and not self.is_end_line(unfinished_line):
unfinished_line = common_whitespace + unfinished_line
diff --git a/extension/package-lock.json b/extension/package-lock.json
index cb11c5a8..915c228e 100644
--- a/extension/package-lock.json
+++ b/extension/package-lock.json
@@ -1,12 +1,12 @@
{
"name": "continue",
- "version": "0.0.115",
+ "version": "0.0.116",
"lockfileVersion": 2,
"requires": true,
"packages": {
"": {
"name": "continue",
- "version": "0.0.115",
+ "version": "0.0.116",
"license": "Apache-2.0",
"dependencies": {
"@electron/rebuild": "^3.2.10",
diff --git a/extension/package.json b/extension/package.json
index bbc83e4a..30690397 100644
--- a/extension/package.json
+++ b/extension/package.json
@@ -14,7 +14,7 @@
"displayName": "Continue",
"pricing": "Free",
"description": "The open-source coding autopilot",
- "version": "0.0.115",
+ "version": "0.0.116",
"publisher": "Continue",
"engines": {
"vscode": "^1.67.0"
diff --git a/extension/react-app/src/components/ComboBox.tsx b/extension/react-app/src/components/ComboBox.tsx
index 55496fb9..4dab8bcd 100644
--- a/extension/react-app/src/components/ComboBox.tsx
+++ b/extension/react-app/src/components/ComboBox.tsx
@@ -1,4 +1,9 @@
-import React, { useCallback, useEffect, useState } from "react";
+import React, {
+ useCallback,
+ useEffect,
+ useImperativeHandle,
+ useState,
+} from "react";
import { useCombobox } from "downshift";
import styled from "styled-components";
import {
@@ -151,22 +156,13 @@ const ComboBox = React.forwardRef((props: ComboBoxProps, ref) => {
const [highlightedCodeSections, setHighlightedCodeSections] = React.useState(
props.highlightedCodeSections || []
);
+ const inputRef = React.useRef<HTMLInputElement>(null);
useEffect(() => {
setHighlightedCodeSections(props.highlightedCodeSections || []);
}, [props.highlightedCodeSections]);
- const {
- isOpen,
- getToggleButtonProps,
- getLabelProps,
- getMenuProps,
- getInputProps,
- highlightedIndex,
- getItemProps,
- selectedItem,
- setInputValue,
- } = useCombobox({
+ const { getInputProps, ...downshiftProps } = useCombobox({
onInputValueChange({ inputValue }) {
if (!inputValue) return;
props.onInputValueChange(inputValue);
@@ -182,6 +178,24 @@ const ComboBox = React.forwardRef((props: ComboBoxProps, ref) => {
},
});
+ useImperativeHandle(ref, () => downshiftProps, [downshiftProps]);
+
+ useEffect(() => {
+ if (!inputRef.current) {
+ return;
+ }
+ inputRef.current.focus();
+ const handler = (event: any) => {
+ if (event.data.type === "focusContinueInput") {
+ inputRef.current!.focus();
+ }
+ };
+ window.addEventListener("message", handler);
+ return () => {
+ window.removeEventListener("message", handler);
+ };
+ }, [inputRef.current]);
+
const divRef = React.useRef<HTMLDivElement>(null);
const ulRef = React.useRef<HTMLUListElement>(null);
const showAbove = () => {
@@ -255,7 +269,7 @@ const ComboBox = React.forwardRef((props: ComboBoxProps, ref) => {
</HeaderButtonWithText>
))}
</div>
- <div className="flex px-2" ref={divRef} hidden={!isOpen}>
+ <div className="flex px-2" ref={divRef} hidden={!downshiftProps.isOpen}>
<MainTextInput
disabled={props.disabled}
placeholder="Ask a question, give instructions, or type '/' to see slash commands"
@@ -277,9 +291,9 @@ const ComboBox = React.forwardRef((props: ComboBoxProps, ref) => {
(event.nativeEvent as any).preventDownshiftDefault = true;
} else if (
event.key === "Enter" &&
- (!isOpen || items.length === 0)
+ (!downshiftProps.isOpen || items.length === 0)
) {
- setInputValue("");
+ downshiftProps.setInputValue("");
const value = event.currentTarget.value;
if (value !== "") {
setPositionInHistory(history.length + 1);
@@ -294,7 +308,7 @@ const ComboBox = React.forwardRef((props: ComboBoxProps, ref) => {
}
if (props.onEnter) props.onEnter(event);
} else if (event.key === "Tab" && items.length > 0) {
- setInputValue(items[0].name);
+ downshiftProps.setInputValue(items[0].name);
event.preventDefault();
} else if (
(event.key === "ArrowUp" || event.key === "ArrowDown") &&
@@ -311,35 +325,35 @@ const ComboBox = React.forwardRef((props: ComboBoxProps, ref) => {
) {
setHistory([...history, event.currentTarget.value]);
}
- setInputValue(history[positionInHistory - 1]);
+ downshiftProps.setInputValue(history[positionInHistory - 1]);
setPositionInHistory((prev) => prev - 1);
} else if (event.key === "ArrowDown") {
if (positionInHistory < history.length) {
- setInputValue(history[positionInHistory + 1]);
+ downshiftProps.setInputValue(history[positionInHistory + 1]);
}
setPositionInHistory((prev) =>
Math.min(prev + 1, history.length)
);
}
},
- ref: ref as any,
+ ref: inputRef,
})}
/>
<Ul
- {...getMenuProps({
+ {...downshiftProps.getMenuProps({
ref: ulRef,
})}
showAbove={showAbove()}
ulHeightPixels={ulRef.current?.getBoundingClientRect().height || 0}
>
- {isOpen &&
+ {downshiftProps.isOpen &&
items.map((item, index) => (
<Li
style={{ borderTop: index === 0 ? "none" : undefined }}
key={`${item.name}${index}`}
- {...getItemProps({ item, index })}
- highlighted={highlightedIndex === index}
- selected={selectedItem === item}
+ {...downshiftProps.getItemProps({ item, index })}
+ highlighted={downshiftProps.highlightedIndex === index}
+ selected={downshiftProps.selectedItem === item}
>
<span>
{item.name}: {item.description}
diff --git a/extension/react-app/src/components/ContinueButton.tsx b/extension/react-app/src/components/ContinueButton.tsx
index 72f6dcd2..d7739b20 100644
--- a/extension/react-app/src/components/ContinueButton.tsx
+++ b/extension/react-app/src/components/ContinueButton.tsx
@@ -13,9 +13,8 @@ let StyledButton = styled(Button)`
background: #be1b55;
&:hover {
- transition-delay: 0.5s;
transition-property: "background";
- opacity: 0.8;
+ opacity: 0.7;
}
`;
diff --git a/extension/react-app/src/components/StepContainer.tsx b/extension/react-app/src/components/StepContainer.tsx
index 590b1166..d480c565 100644
--- a/extension/react-app/src/components/StepContainer.tsx
+++ b/extension/react-app/src/components/StepContainer.tsx
@@ -260,6 +260,9 @@ function StepContainer(props: StepContainerProps) {
code: ({ node, ...props }) => {
return <StyledCode children={props.children[0] as any} />;
},
+ ul: ({ node, ...props }) => {
+ return <ul className="ml-0" {...props} />;
+ },
}}
>
{props.historyNode.step.description as any}
diff --git a/extension/react-app/src/tabs/gui.tsx b/extension/react-app/src/tabs/gui.tsx
index c8a42d9a..1ea70dd2 100644
--- a/extension/react-app/src/tabs/gui.tsx
+++ b/extension/react-app/src/tabs/gui.tsx
@@ -217,25 +217,10 @@ function GUI(props: GUIProps) {
[client]
);
- useEffect(() => {
- if (mainTextInputRef.current) {
- mainTextInputRef.current.focus();
- let handler = (event: any) => {
- if (event.data.type === "focusContinueInput") {
- mainTextInputRef.current?.focus();
- }
- };
- window.addEventListener("message", handler);
- return () => {
- window.removeEventListener("message", handler);
- };
- }
- }, [mainTextInputRef]);
-
const onMainTextInput = () => {
if (mainTextInputRef.current) {
- let input = mainTextInputRef.current.value;
- mainTextInputRef.current.value = "";
+ const input = (mainTextInputRef.current as any).inputValue;
+ (mainTextInputRef.current as any).setInputValue("");
if (!client) return;
setWaitingForSteps(true);
@@ -266,13 +251,6 @@ function GUI(props: GUIProps) {
setUserInputQueue((queue) => {
return [...queue, input];
});
-
- // Delete all context items unless locked
- if (!pinned) {
- client?.deleteContextAtIndices(
- highlightedRanges.map((_, index) => index)
- );
- }
}
};
diff --git a/extension/src/continueIdeClient.ts b/extension/src/continueIdeClient.ts
index e6966f41..3615ab92 100644
--- a/extension/src/continueIdeClient.ts
+++ b/extension/src/continueIdeClient.ts
@@ -423,6 +423,10 @@ class IdeProtocolClient {
sendAcceptRejectSuggestion(accepted: boolean) {
this.messenger?.send("acceptRejectSuggestion", { accepted });
}
+
+ sendAcceptRejectDiff(accepted: boolean) {
+ this.messenger?.send("acceptRejectDiff", { accepted });
+ }
}
export default IdeProtocolClient;
diff --git a/extension/src/diffs.ts b/extension/src/diffs.ts
index 1b8888e8..4fce744c 100644
--- a/extension/src/diffs.ts
+++ b/extension/src/diffs.ts
@@ -2,6 +2,7 @@ import * as os from "os";
import * as path from "path";
import * as fs from "fs";
import * as vscode from "vscode";
+import { ideProtocolClient } from "./activation/activate";
interface DiffInfo {
originalFilepath: string;
@@ -133,8 +134,10 @@ export const diffManager = new DiffManager();
export async function acceptDiffCommand(newFilepath?: string) {
diffManager.acceptDiff(newFilepath);
+ ideProtocolClient.sendAcceptRejectDiff(true);
}
export async function rejectDiffCommand(newFilepath?: string) {
diffManager.rejectDiff(newFilepath);
+ ideProtocolClient.sendAcceptRejectDiff(false);
}