Skip to content

Commit 7552464

Browse files
committed
resolve comments
1 parent d36ebf6 commit 7552464

8 files changed

Lines changed: 67 additions & 21 deletions

File tree

com.microsoft.copilot.eclipse.terminal.api/scripts/copilot-bash-integration.sh

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ __copilot_bash_integration_main() {
1616
__copilot_prompt_initialized=1
1717
fi
1818
printf '\033]7775;A\007'
19+
return "$__copilot_status"
1920
}
2021

2122
__copilot_prompt_end() {
@@ -26,7 +27,18 @@ __copilot_bash_integration_main() {
2627
__copilot_original_ps1=${PS1:-'\$ '}
2728
fi
2829

29-
PROMPT_COMMAND=__copilot_precmd
30+
case "$(declare -p PROMPT_COMMAND 2>/dev/null)" in
31+
declare\ -a*|declare\ -A*)
32+
PROMPT_COMMAND=(__copilot_precmd "${PROMPT_COMMAND[@]}")
33+
;;
34+
*)
35+
if [ -n "${PROMPT_COMMAND:-}" ]; then
36+
PROMPT_COMMAND="__copilot_precmd; ${PROMPT_COMMAND}"
37+
else
38+
PROMPT_COMMAND=__copilot_precmd
39+
fi
40+
;;
41+
esac
3042
PS1="${__copilot_original_ps1}"'\[$(__copilot_prompt_end)\]'
3143
}
3244

com.microsoft.copilot.eclipse.terminal.api/scripts/copilot-powershell-integration.ps1

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,6 @@ try {
55
$global:OutputEncoding = New-Object System.Text.UTF8Encoding $false
66
[Console]::InputEncoding = $global:OutputEncoding
77
[Console]::OutputEncoding = $global:OutputEncoding
8-
$env:PYTHONIOENCODING = "utf-8"
9-
$env:PYTHONUTF8 = "1"
108
} catch {
119
# Some hosts do not expose console encodings during startup.
1210
}
@@ -17,6 +15,8 @@ if (-not $global:COPILOT_SHELL_INTEGRATION) {
1715
$global:__copilot_last_history_id = -1
1816

1917
function global:prompt {
18+
$lastSuccess = $?
19+
$lastExitCode = $LASTEXITCODE
2020
$esc = [char]27
2121
$bel = [char]7
2222
$lastHistoryEntry = Get-History -Count 1
@@ -26,7 +26,13 @@ if (-not $global:COPILOT_SHELL_INTEGRATION) {
2626
if ($lastHistoryEntry.Id -eq $global:__copilot_last_history_id) {
2727
$result += "$esc]7775;C$bel"
2828
} else {
29-
$exitCode = [int](!$global:?)
29+
if ($lastSuccess) {
30+
$exitCode = 0
31+
} elseif ($null -ne $lastExitCode -and $lastExitCode -ne 0) {
32+
$exitCode = $lastExitCode
33+
} else {
34+
$exitCode = 1
35+
}
3036
$result += "$esc]7775;C;$exitCode$bel"
3137
}
3238
}

com.microsoft.copilot.eclipse.terminal.api/src/com/microsoft/copilot/eclipse/terminal/api/ShellIntegrationScripts.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ private ShellIntegrationScripts() {
4646
}
4747

4848
private static String buildOscMarkerPattern() {
49-
return "(?:\u001B)?\\]?" + OSC_NAMESPACE + ";[ABC](?:;[-]?\\d+)?(?:\u0007|\u001B\\\\)?";
49+
return "(?:\u001B)?\\]" + OSC_NAMESPACE + ";[ABC](?:;[-]?\\d+)?(?:\u0007|\u001B\\\\)?";
5050
}
5151

5252
/**

com.microsoft.copilot.eclipse.terminal.api/src/com/microsoft/copilot/eclipse/terminal/api/TerminalCommandProcessor.java

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@ public final class TerminalCommandProcessor {
1313
private static final int MAX_OUTPUT_LINE_COUNT = 1000;
1414
private static final String BRACKETED_PASTE_START = "\u001b[200~";
1515
private static final String BRACKETED_PASTE_END = "\u001b[201~";
16-
private static final String BELL = "\u0007";
1716
private static final String ANSI_CSI_SEQUENCE_PATTERN = "\u001B\\[(\\?)?[\\d;]*[a-zA-Z]";
1817
private static final String OSC_SEQUENCE_PATTERN = "\u001B\\][^\u0007\u001B]*(?:\u0007|\u001B\\\\)";
1918
private static final Pattern PROMPT_START_MARKER_PATTERN = buildMarkerPattern("A", false);
@@ -31,8 +30,19 @@ private TerminalCommandProcessor() {
3130
* @return command text formatted for terminal input
3231
*/
3332
public static String formatForExecution(String command) {
33+
return formatForExecution(command, true);
34+
}
35+
36+
/**
37+
* Formats a command for immediate terminal execution.
38+
*
39+
* @param command the command to send
40+
* @param useBracketedPaste whether multiline commands should be sent using bracketed paste
41+
* @return command text formatted for terminal input
42+
*/
43+
public static String formatForExecution(String command, boolean useBracketedPaste) {
3444
String normalizedCommand = removeTrailingLineEndings(normalizeLineEndings(command));
35-
String terminalInput = isMultilineCommand(normalizedCommand)
45+
String terminalInput = useBracketedPaste && isMultilineCommand(normalizedCommand)
3646
? BRACKETED_PASTE_START + normalizedCommand + BRACKETED_PASTE_END
3747
: normalizedCommand;
3848
terminalInput = terminalInput.replace('\n', '\r');

com.microsoft.copilot.eclipse.ui.terminal.tm/src/com/microsoft/copilot/eclipse/ui/terminal/tm/RunInTerminalTool.java

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,7 @@ public CompletableFuture<String> executeCommand(String command, boolean isBackgr
110110
}
111111

112112
String executionId = UUID.randomUUID().toString();
113-
final String finalCommand = TerminalCommandProcessor.formatForExecution(command);
113+
final String finalCommand = TerminalCommandProcessor.formatForExecution(command, useBracketedPaste());
114114

115115
synchronized (lock) {
116116
if (!isBackground && this.persistentTerminalViewControl != null) {
@@ -161,6 +161,7 @@ public Map<String, Object> prepareTerminalProperties(boolean runInBackground, St
161161
String workingDirectory) {
162162
Map<String, Object> properties = new HashMap<>();
163163

164+
properties.put(ITerminalsConnectorConstants.PROP_ENCODING, "UTF-8");
164165
properties.put(ITerminalsConnectorConstants.PROP_TITLE_DISABLE_ANSI_TITLE, true);
165166
if (StringUtils.isNotBlank(workingDirectory)) {
166167
properties.put(ITerminalsConnectorConstants.PROP_PROCESS_WORKING_DIR, workingDirectory);
@@ -272,6 +273,11 @@ private boolean hasShellIntegrationMarker() {
272273
return false;
273274
}
274275

276+
private boolean useBracketedPaste() {
277+
// macOS terminal multiline handling differs from PowerShell/Bash integration, so keep its existing plain input.
278+
return Platform.getOS().equals(Platform.OS_WIN32) || Platform.getOS().equals(Platform.OS_LINUX);
279+
}
280+
275281
private ITerminalViewControl finalizeTerminalSetup(String executionId, boolean isBackground) {
276282
String title = isBackground ? buildBackgroundTerminalTitle(executionId) : "Copilot";
277283
synchronized (lock) {

com.microsoft.copilot.eclipse.ui.terminal/src/com/microsoft/copilot/eclipse/ui/terminal/RunInTerminalTool.java

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,7 @@ public CompletableFuture<String> executeCommand(String command, boolean isBackgr
111111
}
112112

113113
String executionId = UUID.randomUUID().toString();
114-
final String finalCommand = TerminalCommandProcessor.formatForExecution(command);
114+
final String finalCommand = TerminalCommandProcessor.formatForExecution(command, useBracketedPaste());
115115

116116
synchronized (lock) {
117117
if (!isBackground && this.persistentTerminalViewControl != null) {
@@ -163,6 +163,7 @@ public Map<String, Object> prepareTerminalProperties(boolean runInBackground, St
163163
String workingDirectory) {
164164
Map<String, Object> properties = new HashMap<>();
165165

166+
properties.put(ITerminalsConnectorConstants.PROP_ENCODING, "UTF-8");
166167
properties.put(ITerminalsConnectorConstants.PROP_TITLE_DISABLE_ANSI_TITLE, true);
167168
if (StringUtils.isNotBlank(workingDirectory)) {
168169
properties.put(ITerminalsConnectorConstants.PROP_PROCESS_WORKING_DIR, workingDirectory);
@@ -274,6 +275,11 @@ private boolean hasShellIntegrationMarker() {
274275
return false;
275276
}
276277

278+
private boolean useBracketedPaste() {
279+
// macOS terminal multiline handling differs from PowerShell/Bash integration, so keep its existing plain input.
280+
return Platform.getOS().equals(Platform.OS_WIN32) || Platform.getOS().equals(Platform.OS_LINUX);
281+
}
282+
277283
private ITerminalViewControl finalizeTerminalSetup(String executionId, boolean isBackground) {
278284
String title = isBackground ? buildBackgroundTerminalTitle(executionId) : "Copilot";
279285
synchronized (lock) {

com.microsoft.copilot.eclipse.ui.test/src/com/microsoft/copilot/eclipse/terminal/api/TerminalCommandProcessorTest.java

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,12 @@ void testFormatForExecution_multilineWithTrailingNewline_doesNotSubmitEmptyComma
3535
TerminalCommandProcessor.formatForExecution("echo first\necho second\n"));
3636
}
3737

38+
@Test
39+
void testFormatForExecution_multilineWithoutBracketedPaste_submitsPlainLines() {
40+
assertEquals("echo first\recho second\r",
41+
TerminalCommandProcessor.formatForExecution("echo first\necho second", false));
42+
}
43+
3844
@Test
3945
void testFormatForExecution_singleLineWithTrailingNewline_doesNotUseBracketedPaste() {
4046
assertEquals("echo hello\r", TerminalCommandProcessor.formatForExecution("echo hello\n"));
@@ -154,11 +160,11 @@ void testTruncateOutput_longOutput_keepsTailLines() {
154160
@Test
155161
void testPrepareOutputForModel_removesCopilotShellMarkers() {
156162
String output = "start\n" + ShellIntegrationScripts.PROMPT_START_MARKER
157-
+ "]7775;B\nbody\n]7775;C;0\n"
163+
+ "]7775;B\nbody\n]7775;C;0\nliteral 7775;A remains\n"
158164
+ ShellIntegrationScripts.COMMAND_FINISH_MARKER_PREFIX + "1\u0007end";
159165

160166
String result = TerminalCommandProcessor.prepareOutputForModel(output);
161167

162-
assertEquals("start\n\nbody\n\nend", result);
168+
assertEquals("start\n\nbody\n\nliteral 7775;A remains\nend", result);
163169
}
164170
}

com.microsoft.copilot.eclipse.ui/src/com/microsoft/copilot/eclipse/ui/chat/tools/RunInTerminalToolAdapter.java

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -55,9 +55,9 @@ private String buildToolDescription() {
5555
- Use ; to chain commands on one line
5656
- Never create a sub-shell (e.g., powershell -c "command") unless explicitly asked
5757
- Prefer pipelines | for object-based data flow
58-
- Multi-line commands must be complete and non-interactive. Do not run REPLs, continuation-prompt commands, \
59-
unmatched quotes or brackets, or commands that wait for stdin. For Python/Node scripts, create a file first,
60-
then run it
58+
- Multi-line commands must be complete and non-interactive. Do not run REPLs, continuation-prompt commands,
59+
unmatched quotes or brackets, or commands that wait for stdin. For Python/Node scripts, create a file first,
60+
then run it
6161
- Must use absolute paths to avoid navigation issues
6262
- If a command may use a pager, disable it with command flags (e.g., `git --no-pager`)
6363
- Output returned to the model is automatically truncated to the last 1000 lines to prevent context overflow
@@ -79,9 +79,9 @@ private String buildToolDescription() {
7979
- Use && to chain commands on one line
8080
- Never create a sub-shell (e.g., bash -c "command") unless explicitly asked
8181
- Prefer pipelines | for data flow
82-
- Multi-line commands must be complete and non-interactive. Do not run REPLs, continuation-prompt commands, \
83-
unmatched quotes or brackets, or commands that wait for stdin. For Python/Node scripts, create a file first,
84-
then run it
82+
- Multi-line commands must be complete and non-interactive. Do not run REPLs, continuation-prompt commands,
83+
unmatched quotes or brackets, or commands that wait for stdin. For Python/Node scripts, create a file first,
84+
then run it
8585
- Must use absolute paths to avoid navigation issues
8686
- If a command may use a pager, disable it (e.g., `git --no-pager` or add `| cat`)
8787
- Bash syntax is supported, including arrays and [[ ]]
@@ -102,9 +102,9 @@ private String buildToolDescription() {
102102
- Use && to chain commands on one line
103103
- Never create a sub-shell (e.g., bash -c "command") unless explicitly asked
104104
- Prefer pipelines | for data flow
105-
- Multi-line commands must be complete and non-interactive. Do not run REPLs, continuation-prompt commands, \
106-
unmatched quotes or brackets, or commands that wait for stdin. For Python/Node scripts, create a file first,
107-
then run it
105+
- Multi-line commands must be complete and non-interactive. Do not run REPLs, continuation-prompt commands,
106+
unmatched quotes or brackets, or commands that wait for stdin. For Python/Node scripts, create a file first,
107+
then run it
108108
- Must use absolute paths to avoid navigation issues
109109
- If a command may use a pager, disable it (e.g., `git --no-pager` or add `| cat`)
110110
- Output returned to the model is automatically truncated to the last 1000 lines to prevent context overflow
@@ -274,7 +274,7 @@ public LanguageModelToolInformation getToolInformation() {
274274
// Set the name and description of the tool
275275
toolInfo.setName(TOOL_NAME);
276276
toolInfo.setDescription("""
277-
Get the output of a terminal command previous started with run_in_terminal.
277+
Get the output of a terminal command previously started with run_in_terminal.
278278
Output returned to the model is automatically truncated to the last 1000 lines to prevent context overflow.
279279
""");
280280

0 commit comments

Comments
 (0)