mirror of
https://github.com/voideditor/void
synced 2026-05-23 01:18:25 +00:00
misc ui
This commit is contained in:
parent
77e562e278
commit
98e07e1c7f
3 changed files with 85 additions and 28 deletions
|
|
@ -8,3 +8,5 @@ Look for services and built-in functions that you might need to use to solve the
|
|||
In typescript, do NOT cast to types if not neccessary. NEVER lazily cast to 'any'. Find the correct type to apply and use it.
|
||||
|
||||
Do not add or remove semicolons to any of my files. Just go with convention and make the least number of changes.
|
||||
|
||||
Never modify files outside src/vs/workbench/contrib/void without consulting with the user first.
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@ import { getBasename, getFolderName } from '../sidebar-tsx/SidebarChat.js';
|
|||
import { ChevronRight, File, Folder, FolderClosed, LucideProps } from 'lucide-react';
|
||||
import { StagingSelectionItem } from '../../../../common/chatThreadServiceTypes.js';
|
||||
import { DiffEditorWidget } from '../../../../../../../editor/browser/widget/diffEditor/diffEditorWidget.js';
|
||||
import { extractSearchReplaceBlocks } from '../../../../common/helpers/extractCodeFromResult.js';
|
||||
import { extractSearchReplaceBlocks, ExtractedSearchReplaceBlock } from '../../../../common/helpers/extractCodeFromResult.js';
|
||||
import { IAccessibilitySignalService } from '../../../../../../../platform/accessibilitySignal/browser/accessibilitySignalService.js';
|
||||
import { IEditorProgressService } from '../../../../../../../platform/progress/common/progress.js';
|
||||
import { detectLanguage } from '../../../../common/helpers/languageHelpers.js';
|
||||
|
|
@ -1844,33 +1844,16 @@ export const VoidButtonBgDarken = ({ children, disabled, onClick, className }: {
|
|||
// return <div ref={containerRef} className="w-full" />;
|
||||
// };
|
||||
|
||||
/**
|
||||
* ToolDiffEditor mounts a native VSCode DiffEditorWidget to show a diff between original and modified code blocks.
|
||||
* Props:
|
||||
* - uri: URI of the file (for language detection, etc)
|
||||
* - searchReplaceBlocks: string in search/replace format (from LLM)
|
||||
* - language?: string (optional, fallback to 'plaintext')
|
||||
*/
|
||||
export const VoidDiffEditor = ({ uri, searchReplaceBlocks, language }: { uri?: any, searchReplaceBlocks: string, language?: string }) => {
|
||||
|
||||
|
||||
|
||||
const SingleDiffEditor = ({ block, lang }: { block: ExtractedSearchReplaceBlock, lang: string | undefined }) => {
|
||||
const accessor = useAccessor();
|
||||
const modelService = accessor.get('IModelService');
|
||||
const instantiationService = accessor.get('IInstantiationService');
|
||||
const languageService = accessor.get('ILanguageService');
|
||||
const contextKeyService = accessor.get('IContextKeyService');
|
||||
const codeEditorService = accessor.get('ICodeEditorService');
|
||||
|
||||
// Extract the first block (if present)
|
||||
const blocks = extractSearchReplaceBlocks(searchReplaceBlocks);
|
||||
const block = blocks[0] || { orig: '', final: '' };
|
||||
|
||||
// Use detectLanguage for language detection if not provided
|
||||
let lang = language;
|
||||
if (!lang) {
|
||||
lang = detectLanguage(languageService, { uri: uri ?? null, fileContents: block.orig });
|
||||
}
|
||||
|
||||
// Use ILanguageSelection for model creation
|
||||
const languageSelection = useMemo(() => languageService.createById(lang!), [lang, languageService]);
|
||||
const languageSelection = useMemo(() => languageService.createById(lang), [lang, languageService]);
|
||||
|
||||
// Create models for original and modified
|
||||
const originalModel = useMemo(() =>
|
||||
|
|
@ -1906,7 +1889,7 @@ export const VoidDiffEditor = ({ uri, searchReplaceBlocks, language }: { uri?: a
|
|||
renderSideBySide: true,
|
||||
minimap: { enabled: false },
|
||||
lineNumbers: 'off',
|
||||
scrollbar: { vertical: 'auto', horizontal: 'auto', verticalScrollbarSize: 8, horizontalScrollbarSize: 8 },
|
||||
scrollbar: { vertical: 'hidden', horizontal: 'auto', verticalScrollbarSize: 0, horizontalScrollbarSize: 8 },
|
||||
hover: { enabled: false },
|
||||
folding: false,
|
||||
selectionHighlight: false,
|
||||
|
|
@ -1916,20 +1899,92 @@ export const VoidDiffEditor = ({ uri, searchReplaceBlocks, language }: { uri?: a
|
|||
overviewRulerBorder: false,
|
||||
glyphMargin: false,
|
||||
stickyScroll: { enabled: false },
|
||||
scrollBeyondLastLine: false,
|
||||
renderGutterMenu: false,
|
||||
renderIndicators: false,
|
||||
},
|
||||
{ originalEditor: { isSimpleWidget: true }, modifiedEditor: { isSimpleWidget: true } }
|
||||
);
|
||||
editor.setModel({ original: originalModel, modified: modifiedModel });
|
||||
editor.layout();
|
||||
|
||||
// Calculate the height based on content
|
||||
const updateHeight = () => {
|
||||
const contentHeight = Math.max(
|
||||
originalModel.getLineCount() * 19, // approximate line height
|
||||
modifiedModel.getLineCount() * 19
|
||||
) + 19 * 2 + 1; // add padding
|
||||
|
||||
// Set reasonable min/max heights
|
||||
const height = Math.min(Math.max(contentHeight, 100), 300);
|
||||
if (divRef.current) {
|
||||
divRef.current.style.height = `${height}px`;
|
||||
editor.layout();
|
||||
}
|
||||
};
|
||||
|
||||
updateHeight();
|
||||
editorRef.current = editor;
|
||||
|
||||
// Update height when content changes
|
||||
const disposable1 = originalModel.onDidChangeContent(() => updateHeight());
|
||||
const disposable2 = modifiedModel.onDidChangeContent(() => updateHeight());
|
||||
|
||||
return () => {
|
||||
disposable1.dispose();
|
||||
disposable2.dispose();
|
||||
editor.dispose();
|
||||
editorRef.current = null;
|
||||
};
|
||||
}, [originalModel, modifiedModel, instantiationService]);
|
||||
|
||||
return (
|
||||
<div className="w-full h-[300px] bg-void-bg-3 rounded" ref={divRef} />
|
||||
<div className="w-full bg-void-bg-3 @@bg-editor-style-override" ref={divRef} />
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* ToolDiffEditor mounts a native VSCode DiffEditorWidget to show a diff between original and modified code blocks.
|
||||
* Props:
|
||||
* - uri: URI of the file (for language detection, etc)
|
||||
* - searchReplaceBlocks: string in search/replace format (from LLM)
|
||||
* - language?: string (optional, fallback to 'plaintext')
|
||||
*/
|
||||
export const VoidDiffEditor = ({ uri, searchReplaceBlocks, language }: { uri?: any, searchReplaceBlocks: string, language?: string }) => {
|
||||
const accessor = useAccessor();
|
||||
const languageService = accessor.get('ILanguageService');
|
||||
|
||||
// Extract all blocks
|
||||
const blocks = extractSearchReplaceBlocks(searchReplaceBlocks);
|
||||
|
||||
// Use detectLanguage for language detection if not provided
|
||||
let lang = language;
|
||||
if (!lang && blocks.length > 0) {
|
||||
lang = detectLanguage(languageService, { uri: uri ?? null, fileContents: blocks[0].orig });
|
||||
}
|
||||
|
||||
// If no blocks, show empty state
|
||||
if (blocks.length === 0) {
|
||||
return <div className="w-full p-4 text-void-fg-4 text-sm">No changes found</div>;
|
||||
}
|
||||
|
||||
// Display all blocks
|
||||
return (
|
||||
<div className="w-full flex flex-col gap-2">
|
||||
{blocks.map((block, index) => (
|
||||
<div key={index} className="w-full">
|
||||
{blocks.length > 1 && (
|
||||
<div className="text-void-fg-4 text-xs mb-1 px-1">
|
||||
Change {index + 1} of {blocks.length}
|
||||
</div>
|
||||
)}
|
||||
<SingleDiffEditor block={block} lang={lang} />
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -456,7 +456,7 @@ export const ModelDump = ({ filteredProviders }: { filteredProviders?: ProviderN
|
|||
{/* left part is width:full */}
|
||||
<div className={`flex flex-grow items-center gap-4`}>
|
||||
<span className='w-full max-w-32'>{isNewProviderName ? providerTitle : ''}</span>
|
||||
<span className='w-fit truncate'>{modelName}</span>
|
||||
<span className='w-fit max-w-[400px] truncate'>{modelName}</span>
|
||||
</div>
|
||||
|
||||
{/* right part is anything that fits */}
|
||||
|
|
@ -495,7 +495,7 @@ export const ModelDump = ({ filteredProviders }: { filteredProviders?: ProviderN
|
|||
|
||||
{/* X button */}
|
||||
<div className={`w-5 flex items-center justify-center`}>
|
||||
{type === 'default' || type === 'autodetected' ? null : <button
|
||||
{type === 'default' || type === 'autodetected' ? null : <button
|
||||
onClick={() => { settingsStateService.deleteModel(providerName, modelName); }}
|
||||
data-tooltip-id='void-tooltip'
|
||||
data-tooltip-place='right'
|
||||
|
|
|
|||
Loading…
Reference in a new issue