Compare commits
4 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| baa89cc17d | |||
| d3aa0bc3cc | |||
| b92420012c | |||
| 89d08071fc |
@@ -0,0 +1,119 @@
|
||||
/*--------------------------------------------------------------------------------------
|
||||
* Copyright 2025 Glass Devtools, Inc. All rights reserved.
|
||||
* Licensed under the Apache License, Version 2.0. See LICENSE.txt for more information.
|
||||
*--------------------------------------------------------------------------------------*/
|
||||
|
||||
import { Disposable } from '../../../../base/common/lifecycle.js';
|
||||
import { InstantiationType, registerSingleton } from '../../../../platform/instantiation/common/extensions.js';
|
||||
import { createDecorator } from '../../../../platform/instantiation/common/instantiation.js';
|
||||
import { IMarkerService, MarkerSeverity } from '../../../../platform/markers/common/markers.js';
|
||||
import { ILanguageFeaturesService } from '../../../../editor/common/services/languageFeatures.js';
|
||||
import { ITextModelService } from '../../../../editor/common/services/resolverService.js';
|
||||
import { Range } from '../../../../editor/common/core/range.js';
|
||||
import { CancellationToken } from '../../../../base/common/cancellation.js';
|
||||
import { CodeActionContext, CodeActionTriggerType } from '../../../../editor/common/languages.js';
|
||||
|
||||
export interface IMarkerCheckService {
|
||||
readonly _serviceBrand: undefined;
|
||||
}
|
||||
|
||||
export const IMarkerCheckService = createDecorator<IMarkerCheckService>('markerCheckService');
|
||||
|
||||
class MarkerCheckService extends Disposable implements IMarkerCheckService {
|
||||
_serviceBrand: undefined;
|
||||
|
||||
constructor(
|
||||
@IMarkerService private readonly _markerService: IMarkerService,
|
||||
@ILanguageFeaturesService private readonly _languageFeaturesService: ILanguageFeaturesService,
|
||||
@ITextModelService private readonly _textModelService: ITextModelService,
|
||||
) {
|
||||
super();
|
||||
|
||||
setInterval(async () => {
|
||||
const allMarkers = this._markerService.read();
|
||||
const errors = allMarkers.filter(marker => marker.severity === MarkerSeverity.Error);
|
||||
|
||||
if (errors.length > 0) {
|
||||
for (const error of errors) {
|
||||
|
||||
console.log(`----------------------------------------------`);
|
||||
|
||||
console.log(`${error.resource.toString()}: ${error.startLineNumber} ${error.message} ${error.severity}`); // ! all errors in the file
|
||||
|
||||
try {
|
||||
// Get the text model for the file
|
||||
const modelReference = await this._textModelService.createModelReference(error.resource);
|
||||
const model = modelReference.object.textEditorModel;
|
||||
|
||||
// Create a range from the marker
|
||||
const range = new Range(
|
||||
error.startLineNumber,
|
||||
error.startColumn,
|
||||
error.endLineNumber,
|
||||
error.endColumn
|
||||
);
|
||||
|
||||
// Get code action providers for this model
|
||||
const codeActionProvider = this._languageFeaturesService.codeActionProvider;
|
||||
const providers = codeActionProvider.ordered(model);
|
||||
|
||||
if (providers.length > 0) {
|
||||
// Request code actions from each provider
|
||||
for (const provider of providers) {
|
||||
const context: CodeActionContext = {
|
||||
trigger: CodeActionTriggerType.Invoke, // keeping 'trigger' since it works
|
||||
only: 'quickfix' // adding this to filter for quick fixes
|
||||
};
|
||||
|
||||
const actions = await provider.provideCodeActions(
|
||||
model,
|
||||
range,
|
||||
context,
|
||||
CancellationToken.None
|
||||
);
|
||||
|
||||
if (actions?.actions?.length) {
|
||||
|
||||
const quickFixes = actions.actions.filter(action => action.isPreferred); // ! all quickFixes for the error
|
||||
const quickFixesForImports = actions.actions.filter(action => action.isPreferred && action.title.includes('import')); // ! all possible imports
|
||||
quickFixesForImports
|
||||
|
||||
if (quickFixes.length > 0) {
|
||||
console.log('Available Quick Fixes:');
|
||||
quickFixes.forEach(action => {
|
||||
console.log(`- ${action.title}`);
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Dispose the model reference
|
||||
modelReference.dispose();
|
||||
} catch (e) {
|
||||
console.error('Error getting quick fixes:', e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}, 5000);
|
||||
}
|
||||
|
||||
|
||||
// private _onMarkersChanged = (changedResources: readonly URI[]): void => {
|
||||
// for (const resource of changedResources) {
|
||||
// const markers = this._markerService.read({ resource });
|
||||
|
||||
// if (markers.length === 0) {
|
||||
// console.log(`${resource.toString()}: No diagnostics`);
|
||||
// continue;
|
||||
// }
|
||||
|
||||
// console.log(`Diagnostics for ${resource.toString()}:`);
|
||||
// markers.forEach(marker => this._logMarker(marker));
|
||||
// }
|
||||
// };
|
||||
|
||||
|
||||
}
|
||||
|
||||
registerSingleton(IMarkerCheckService, MarkerCheckService, InstantiationType.Eager);
|
||||
@@ -20,7 +20,7 @@ export const VSReadFile = async (modelService: IModelService, fileService: IFile
|
||||
// read files from VSCode. preferred (but appears to only work if the model of this URI already exists. If it doesn't use the other function.)
|
||||
export const _VSReadModel = async (modelService: IModelService, uri: URI): Promise<string | null> => {
|
||||
|
||||
// attempt to read saved model (sometimes doesn't work if page is reloaded)
|
||||
// attempt to read saved model (doesn't work if application was reloaded...)
|
||||
const model = modelService.getModel(uri)
|
||||
if (model) {
|
||||
return model.getValue(EndOfLinePreference.LF)
|
||||
@@ -38,7 +38,12 @@ export const _VSReadModel = async (modelService: IModelService, uri: URI): Promi
|
||||
}
|
||||
|
||||
export const _VSReadFileRaw = async (fileService: IFileService, uri: URI) => {
|
||||
const res = await fileService.readFile(uri)
|
||||
const str = res.value.toString()
|
||||
return str
|
||||
try {
|
||||
const res = await fileService.readFile(uri)
|
||||
const str = res.value.toString()
|
||||
return str
|
||||
} catch (e) {
|
||||
return ''
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -703,7 +703,6 @@ const ChatBubble = ({ chatMessage, isLoading, messageIdx }: { chatMessage: ChatM
|
||||
: role === 'user' ? `px-2 self-end w-fit max-w-full whitespace-pre-wrap` // user words should be pre
|
||||
: role === 'assistant' ? `px-2 self-start w-full max-w-full` : ''
|
||||
}
|
||||
${role !== 'assistant' ? 'my-2' : ''}
|
||||
`}
|
||||
onMouseEnter={() => setIsHovered(true)}
|
||||
onMouseLeave={() => setIsHovered(false)}
|
||||
|
||||
@@ -19,90 +19,87 @@ export const useScrollbarStyles = (containerRef: React.MutableRefObject<HTMLDivE
|
||||
...Array.from(containerRef.current?.querySelectorAll(overflowSelector) || [])
|
||||
];
|
||||
|
||||
// Clean up existing elements first
|
||||
// Apply basic styling to all elements
|
||||
scrollElements.forEach(element => {
|
||||
if ((element as any).__scrollbarCleanup) {
|
||||
(element as any).__scrollbarCleanup();
|
||||
}
|
||||
element.classList.add('void-scrollable-element');
|
||||
});
|
||||
|
||||
// Apply styles and listeners to each scroll element
|
||||
// Only initialize fade effects for elements that haven't been initialized yet
|
||||
scrollElements.forEach(element => {
|
||||
// Add the scrollable class directly to the overflow element
|
||||
element.classList.add('void-scrollable-element');
|
||||
if (!(element as any).__scrollbarCleanup) {
|
||||
let fadeTimeout: NodeJS.Timeout | null = null;
|
||||
let fadeInterval: NodeJS.Timeout | null = null;
|
||||
|
||||
let fadeTimeout: NodeJS.Timeout | null = null;
|
||||
let fadeInterval: NodeJS.Timeout | null = null;
|
||||
const fadeIn = () => {
|
||||
if (fadeInterval) clearInterval(fadeInterval);
|
||||
|
||||
const fadeIn = () => {
|
||||
if (fadeInterval) clearInterval(fadeInterval);
|
||||
let step = 0;
|
||||
fadeInterval = setInterval(() => {
|
||||
if (step <= 10) {
|
||||
element.classList.remove(`show-scrollbar-${step - 1}`);
|
||||
element.classList.add(`show-scrollbar-${step}`);
|
||||
step++;
|
||||
} else {
|
||||
clearInterval(fadeInterval!);
|
||||
}
|
||||
}, 10);
|
||||
};
|
||||
|
||||
let step = 0;
|
||||
fadeInterval = setInterval(() => {
|
||||
if (step <= 10) {
|
||||
element.classList.remove(`show-scrollbar-${step - 1}`);
|
||||
element.classList.add(`show-scrollbar-${step}`);
|
||||
step++;
|
||||
} else {
|
||||
clearInterval(fadeInterval!);
|
||||
const fadeOut = () => {
|
||||
if (fadeInterval) clearInterval(fadeInterval);
|
||||
|
||||
let step = 10;
|
||||
fadeInterval = setInterval(() => {
|
||||
if (step >= 0) {
|
||||
element.classList.remove(`show-scrollbar-${step + 1}`);
|
||||
element.classList.add(`show-scrollbar-${step}`);
|
||||
step--;
|
||||
} else {
|
||||
clearInterval(fadeInterval!);
|
||||
}
|
||||
}, 60);
|
||||
};
|
||||
|
||||
const onMouseEnter = () => {
|
||||
if (fadeTimeout) clearTimeout(fadeTimeout);
|
||||
if (fadeInterval) clearInterval(fadeInterval);
|
||||
fadeIn();
|
||||
};
|
||||
|
||||
const onMouseLeave = () => {
|
||||
if (fadeTimeout) clearTimeout(fadeTimeout);
|
||||
fadeTimeout = setTimeout(() => {
|
||||
fadeOut();
|
||||
}, 10);
|
||||
};
|
||||
|
||||
element.addEventListener('mouseenter', onMouseEnter);
|
||||
element.addEventListener('mouseleave', onMouseLeave);
|
||||
|
||||
// Store cleanup function
|
||||
const cleanup = () => {
|
||||
element.removeEventListener('mouseenter', onMouseEnter);
|
||||
element.removeEventListener('mouseleave', onMouseLeave);
|
||||
if (fadeTimeout) clearTimeout(fadeTimeout);
|
||||
if (fadeInterval) clearInterval(fadeInterval);
|
||||
element.classList.remove('void-scrollable-element');
|
||||
// Remove any remaining show-scrollbar classes
|
||||
for (let i = 0; i <= 10; i++) {
|
||||
element.classList.remove(`show-scrollbar-${i}`);
|
||||
}
|
||||
}, 10);
|
||||
};
|
||||
};
|
||||
|
||||
const fadeOut = () => {
|
||||
if (fadeInterval) clearInterval(fadeInterval);
|
||||
|
||||
let step = 10;
|
||||
fadeInterval = setInterval(() => {
|
||||
if (step >= 0) {
|
||||
element.classList.remove(`show-scrollbar-${step + 1}`);
|
||||
element.classList.add(`show-scrollbar-${step}`);
|
||||
step--;
|
||||
} else {
|
||||
clearInterval(fadeInterval!);
|
||||
}
|
||||
}, 60);
|
||||
};
|
||||
|
||||
const onMouseEnter = () => {
|
||||
if (fadeTimeout) clearTimeout(fadeTimeout);
|
||||
if (fadeInterval) clearInterval(fadeInterval);
|
||||
fadeIn();
|
||||
};
|
||||
|
||||
const onMouseLeave = () => {
|
||||
if (fadeTimeout) clearTimeout(fadeTimeout);
|
||||
fadeTimeout = setTimeout(() => {
|
||||
fadeOut();
|
||||
}, 10);
|
||||
};
|
||||
|
||||
element.addEventListener('mouseenter', onMouseEnter);
|
||||
element.addEventListener('mouseleave', onMouseLeave);
|
||||
|
||||
// Store cleanup function
|
||||
const cleanup = () => {
|
||||
element.removeEventListener('mouseenter', onMouseEnter);
|
||||
element.removeEventListener('mouseleave', onMouseLeave);
|
||||
if (fadeTimeout) clearTimeout(fadeTimeout);
|
||||
if (fadeInterval) clearInterval(fadeInterval);
|
||||
element.classList.remove('void-scrollable-element');
|
||||
// Remove any remaining show-scrollbar classes
|
||||
for (let i = 0; i <= 10; i++) {
|
||||
element.classList.remove(`show-scrollbar-${i}`);
|
||||
}
|
||||
};
|
||||
|
||||
// Store the cleanup function on the element for later use
|
||||
(element as any).__scrollbarCleanup = cleanup;
|
||||
// Store the cleanup function on the element for later use
|
||||
(element as any).__scrollbarCleanup = cleanup;
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
// Initialize for the first time
|
||||
initializeScrollbarStyles();
|
||||
|
||||
// Set up mutation observer
|
||||
const observer = new MutationObserver((mutations) => {
|
||||
// Set up mutation observer to do the same
|
||||
const observer = new MutationObserver(() => {
|
||||
initializeScrollbarStyles();
|
||||
});
|
||||
|
||||
|
||||
Reference in New Issue
Block a user