diff --git a/src/vs/platform/void/common/voidSettingsTypes.ts b/src/vs/platform/void/common/voidSettingsTypes.ts index 22cbdcc2..cd9ae0dc 100644 --- a/src/vs/platform/void/common/voidSettingsTypes.ts +++ b/src/vs/platform/void/common/voidSettingsTypes.ts @@ -385,7 +385,7 @@ type FeatureFlagDisplayInfo = { export const displayInfoOfFeatureFlag = (featureFlag: FeatureFlagName): FeatureFlagDisplayInfo => { if (featureFlag === 'autoRefreshModels') { return { - description: `Automatically scan for and enable local models.`, // ${`refreshableProviderNames.map(providerName => titleOfProviderName(providerName)).join(', ')`} + description: `Automatically scan for and enable local providers like Ollama.`, // ${`refreshableProviderNames.map(providerName => titleOfProviderName(providerName)).join(', ')`} } } throw new Error(`featureFlagInfo: Unknown feature flag: "${featureFlag}"`) diff --git a/src/vs/workbench/contrib/void/browser/react/src/markdown/BlockCode.tsx b/src/vs/workbench/contrib/void/browser/react/src/markdown/BlockCode.tsx index 14328b5c..6d4817c0 100644 --- a/src/vs/workbench/contrib/void/browser/react/src/markdown/BlockCode.tsx +++ b/src/vs/workbench/contrib/void/browser/react/src/markdown/BlockCode.tsx @@ -5,68 +5,65 @@ import React, { ReactNode } from "react" import { VoidCodeEditor } from '../util/inputs.js'; +import { ILanguageService } from '../../../../../../../editor/common/languages/language.js'; +const extensionMap: { [key: string]: string } = { + // Web + 'html': 'html', + 'htm': 'html', + 'css': 'css', + 'scss': 'scss', + 'less': 'less', + 'js': 'javascript', + 'jsx': 'javascript', + 'ts': 'typescript', + 'tsx': 'typescript', + 'json': 'json', + 'jsonc': 'json', + + // Programming Languages + 'py': 'python', + 'java': 'java', + 'cpp': 'cpp', + 'cc': 'cpp', + 'h': 'cpp', + 'hpp': 'cpp', + 'cs': 'csharp', + 'go': 'go', + 'rs': 'rust', + 'rb': 'ruby', + 'php': 'php', + 'sh': 'shell', + 'bash': 'shell', + 'zsh': 'shell', + + // Markup/Config + 'md': 'markdown', + 'markdown': 'markdown', + 'xml': 'xml', + 'svg': 'xml', + 'yaml': 'yaml', + 'yml': 'yaml', + 'ini': 'ini', + 'toml': 'ini', + + // Other + 'sql': 'sql', + 'graphql': 'graphql', + 'gql': 'graphql', + 'dockerfile': 'dockerfile', + 'docker': 'dockerfile' +}; export function getLanguageFromFileName(fileName: string): string { - if (!fileName) return 'plaintext'; const ext = fileName.toLowerCase().split('.').pop(); if (!ext) return 'plaintext'; - const extensionMap: { [key: string]: string } = { - // Web - 'html': 'html', - 'htm': 'html', - 'css': 'css', - 'scss': 'scss', - 'less': 'less', - 'js': 'javascript', - 'jsx': 'javascript', - 'ts': 'typescript', - 'tsx': 'typescript', - 'json': 'json', - 'jsonc': 'json', - - // Programming Languages - 'py': 'python', - 'java': 'java', - 'cpp': 'cpp', - 'cc': 'cpp', - 'h': 'cpp', - 'hpp': 'cpp', - 'cs': 'csharp', - 'go': 'go', - 'rs': 'rust', - 'rb': 'ruby', - 'php': 'php', - 'sh': 'shell', - 'bash': 'shell', - 'zsh': 'shell', - - // Markup/Config - 'md': 'markdown', - 'markdown': 'markdown', - 'xml': 'xml', - 'svg': 'xml', - 'yaml': 'yaml', - 'yml': 'yaml', - 'ini': 'ini', - 'toml': 'ini', - - // Other - 'sql': 'sql', - 'graphql': 'graphql', - 'gql': 'graphql', - 'dockerfile': 'dockerfile', - 'docker': 'dockerfile' - }; - return extensionMap[ext] || 'plaintext'; } - - export const BlockCode = ({ text, buttonsOnHover, language }: { text: string, buttonsOnHover?: ReactNode, language?: string }) => { return (<> diff --git a/src/vs/workbench/contrib/void/browser/react/src/markdown/ChatMarkdownRender.tsx b/src/vs/workbench/contrib/void/browser/react/src/markdown/ChatMarkdownRender.tsx index 3fa5140c..6cda2ed6 100644 --- a/src/vs/workbench/contrib/void/browser/react/src/markdown/ChatMarkdownRender.tsx +++ b/src/vs/workbench/contrib/void/browser/react/src/markdown/ChatMarkdownRender.tsx @@ -70,7 +70,7 @@ const RenderToken = ({ token, nested = false }: { token: Token | string, nested? if (t.type === "code") { return } /> } diff --git a/src/vs/workbench/contrib/void/browser/react/src/sidebar-tsx/SidebarChat.tsx b/src/vs/workbench/contrib/void/browser/react/src/sidebar-tsx/SidebarChat.tsx index 363c3630..82df0d53 100644 --- a/src/vs/workbench/contrib/void/browser/react/src/sidebar-tsx/SidebarChat.tsx +++ b/src/vs/workbench/contrib/void/browser/react/src/sidebar-tsx/SidebarChat.tsx @@ -18,7 +18,7 @@ import { ErrorDisplay } from './ErrorDisplay.js'; import { OnError, ServiceSendLLMMessageParams } from '../../../../../../../platform/void/common/llmMessageTypes.js'; import { getCmdKey } from '../../../helpers/getCmdKey.js' import { HistoryInputBox, InputBox } from '../../../../../../../base/browser/ui/inputbox/inputBox.js'; -import { VoidCodeEditor, VoidInputBox } from '../util/inputs.js'; +import { VoidInputBox } from '../util/inputs.js'; import { ModelDropdown } from '../void-settings-tsx/ModelDropdown.js'; import { chat_systemMessage, chat_prompt } from '../../../prompt/prompts.js'; import { ISidebarStateService } from '../../../sidebarStateService.js'; diff --git a/src/vs/workbench/contrib/void/browser/react/src/util/inputs.tsx b/src/vs/workbench/contrib/void/browser/react/src/util/inputs.tsx index 31710236..b247c279 100644 --- a/src/vs/workbench/contrib/void/browser/react/src/util/inputs.tsx +++ b/src/vs/workbench/contrib/void/browser/react/src/util/inputs.tsx @@ -294,6 +294,7 @@ export const VoidCodeEditor = ({ initValue, language }: { initValue: string, lan const accessor = useAccessor() const instantiationService = accessor.get('IInstantiationService') const modelService = accessor.get('IModelService') + const languageDetectionService = accessor.get('ILanguageDetectionService') initValue = normalizeIndentation(initValue) @@ -312,7 +313,7 @@ export const VoidCodeEditor = ({ initValue, language }: { initValue: string, lan alwaysConsumeMouseWheel: false, vertical: 'auto', horizontal: 'auto', - verticalScrollbarSize: 0, + // verticalScrollbarSize: 0, horizontalScrollbarSize: 0, }, scrollBeyondLastLine: false, @@ -350,7 +351,19 @@ export const VoidCodeEditor = ({ initValue, language }: { initValue: string, lan onCreateInstance={useCallback((editor: CodeEditorWidget) => { const model = modelService.createModel(initValue, null) editor.setModel(model); - model.setLanguage(language ?? 'plaintext') + + if (language) { + model.setLanguage(language) + } else { + languageDetectionService.detectLanguage(model.uri).then(detectedLanguage => { + + // TODOS: + // once the model has been detected, stop detecting it; currently we detect on every new token which is very slow + // dispose the model; i dont think editor.dispose() does this + model.setLanguage(detectedLanguage ?? 'plaintext') + }) + } + const container = editor.getDomNode() const parentNode = container?.parentElement @@ -374,7 +387,7 @@ export const VoidCodeEditor = ({ initValue, language }: { initValue: string, lan dispose={useCallback((editor: CodeEditorWidget) => { editor.dispose(); - }, [])} + }, [modelService, languageDetectionService])} propsFn={useCallback(() => { return [] }, [])} /> diff --git a/src/vs/workbench/contrib/void/browser/react/src/util/services.tsx b/src/vs/workbench/contrib/void/browser/react/src/util/services.tsx index 6404e108..88eb4cef 100644 --- a/src/vs/workbench/contrib/void/browser/react/src/util/services.tsx +++ b/src/vs/workbench/contrib/void/browser/react/src/util/services.tsx @@ -39,6 +39,7 @@ import { INotificationService } from '../../../../../../../platform/notification import { IAccessibilityService } from '../../../../../../../platform/accessibility/common/accessibility.js' import { ILanguageConfigurationService } from '../../../../../../../editor/common/languages/languageConfigurationRegistry.js' import { ILanguageFeaturesService } from '../../../../../../../editor/common/services/languageFeatures.js' +import { ILanguageDetectionService } from '../../../../../../services/languageDetection/common/languageDetectionWorkerService.js' @@ -145,6 +146,7 @@ export const _registerServices = (accessor: ServicesAccessor) => { } + const getReactAccessor = (accessor: ServicesAccessor) => { const reactAccessor = { IModelService: accessor.get(IModelService), @@ -169,6 +171,7 @@ const getReactAccessor = (accessor: ServicesAccessor) => { INotificationService: accessor.get(INotificationService), IAccessibilityService: accessor.get(IAccessibilityService), ILanguageConfigurationService: accessor.get(ILanguageConfigurationService), + ILanguageDetectionService: accessor.get(ILanguageDetectionService), ILanguageFeaturesService: accessor.get(ILanguageFeaturesService), } as const diff --git a/src/vs/workbench/contrib/void/browser/react/src/void-settings-tsx/Settings.tsx b/src/vs/workbench/contrib/void/browser/react/src/void-settings-tsx/Settings.tsx index 11411198..971e974a 100644 --- a/src/vs/workbench/contrib/void/browser/react/src/void-settings-tsx/Settings.tsx +++ b/src/vs/workbench/contrib/void/browser/react/src/void-settings-tsx/Settings.tsx @@ -9,7 +9,7 @@ import { ChatMarkdownRender } from '../markdown/ChatMarkdownRender.js' const SubtleButton = ({ onClick, text, icon, disabled }: { onClick: () => void, text: string, icon: React.ReactNode, disabled: boolean }) => { - return
+ return
@@ -19,7 +19,6 @@ const SubtleButton = ({ onClick, text, icon, disabled }: { onClick: () => void,
} - // models const RefreshModelButton = ({ providerName }: { providerName: RefreshableProviderName }) => { const refreshModelState = useRefreshModelState() @@ -59,7 +58,9 @@ const RefreshableModels = () => { const buttons = refreshableProviderNames.map(providerName => { if (!settingsState.settingsOfProvider[providerName]._enabled) return null - return + return
+ +
}) return <> @@ -346,7 +347,6 @@ export const VoidProviderSettings = () => { // } export const VoidFeatureFlagSettings = () => { - const accessor = useAccessor() const voidSettingsService = accessor.get('IVoidSettingsService') @@ -406,8 +406,8 @@ export const Settings = () => {

Providers

- +

Models