Add Python Shell Type and .python_history (#204680)

* Add Python Shell type and history

* remove one comment

* remove unncessary

* Why can't I manually override setShellType

* Detect python shell type on Windows

* fire shellType in _sendProcessTitle

* Detect python shell type on Windows

* delete comment

* remove more comments

* remove comment

* remove dup

* clean up

* more comprehensive regex for windows python

* follow previous style for map key name

* remove unused variable

* remove comment

* last cleanup

* More cleanup

* more clean up

* re-arrange

* remove unused

---------

Co-authored-by: Daniel Imms <2193314+Tyriar@users.noreply.github.com>
This commit is contained in:
Anthony Kim 2024-02-15 11:39:05 -08:00 committed by GitHub
parent e4e853fecf
commit d30f7018d2
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 41 additions and 2 deletions

View File

@ -140,12 +140,14 @@ export const enum PosixShellType {
Csh = 'csh',
Ksh = 'ksh',
Zsh = 'zsh',
Python = 'python'
}
export const enum WindowsShellType {
CommandPrompt = 'cmd',
PowerShell = 'pwsh',
Wsl = 'wsl',
GitBash = 'gitbash'
GitBash = 'gitbash',
Python = 'python'
}
export type TerminalShellType = PosixShellType | WindowsShellType;

View File

@ -73,6 +73,7 @@ const posixShellTypeMap = new Map<string, PosixShellType>([
['ksh', PosixShellType.Ksh],
['sh', PosixShellType.Sh],
['pwsh', PosixShellType.PowerShell],
['python', PosixShellType.Python],
['zsh', PosixShellType.Zsh]
]);
@ -404,7 +405,12 @@ export class TerminalProcess extends Disposable implements ITerminalChildProcess
this._onDidChangeProperty.fire({ type: ProcessPropertyType.Title, value: this._currentTitle });
// If fig is installed it may change the title of the process
const sanitizedTitle = this.currentTitle.replace(/ \(figterm\)$/g, '');
this._onDidChangeProperty.fire({ type: ProcessPropertyType.ShellType, value: posixShellTypeMap.get(sanitizedTitle) });
if (sanitizedTitle.toLowerCase().startsWith('python')) {
this._onDidChangeProperty.fire({ type: ProcessPropertyType.ShellType, value: PosixShellType.Python });
} else {
this._onDidChangeProperty.fire({ type: ProcessPropertyType.ShellType, value: posixShellTypeMap.get(sanitizedTitle) });
}
}
shutdown(immediate: boolean): void {

View File

@ -152,6 +152,9 @@ export class WindowsShellHelper extends Disposable implements IWindowsShellHelpe
case 'sles-12.exe':
return WindowsShellType.Wsl;
default:
if (executable.match(/python(\d(\.\d{0,2})?)?\.exe/)) {
return WindowsShellType.Python;
}
return undefined;
}
}

View File

@ -118,6 +118,7 @@ const shellIntegrationSupportedShellTypes = [
PosixShellType.Bash,
PosixShellType.Zsh,
PosixShellType.PowerShell,
PosixShellType.Python,
WindowsShellType.PowerShell
];

View File

@ -92,6 +92,9 @@ export async function getShellFileHistory(accessor: ServicesAccessor, shellType:
case PosixShellType.Fish:
result = await fetchFishHistory(accessor);
break;
case PosixShellType.Python:
result = await fetchPythonHistory(accessor);
break;
default: return [];
}
if (result === undefined) {
@ -295,6 +298,30 @@ export async function fetchZshHistory(accessor: ServicesAccessor) {
return result.values();
}
export async function fetchPythonHistory(accessor: ServicesAccessor): Promise<IterableIterator<string> | undefined> {
const fileService = accessor.get(IFileService);
const remoteAgentService = accessor.get(IRemoteAgentService);
const content = await fetchFileContents(env['HOME'], '.python_history', false, fileService, remoteAgentService);
if (content === undefined) {
return undefined;
}
// Python history file is a simple text file with one command per line
const fileLines = content.split('\n');
const result: Set<string> = new Set();
fileLines.forEach(line => {
if (line.trim().length > 0) {
result.add(line.trim());
}
});
return result.values();
}
export async function fetchPwshHistory(accessor: ServicesAccessor) {
const fileService: Pick<IFileService, 'readFile'> = accessor.get(IFileService);
const remoteAgentService: Pick<IRemoteAgentService, 'getConnection' | 'getEnvironment'> = accessor.get(IRemoteAgentService);