Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions Changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,14 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).


## [1.0.76] - 2026-02-14
### Added
- Added on-demand scan command `DevSkim: Scan All Open Files` for VS Code extension to manually trigger rescanning of all open documents
- Automatically rescan all open documents when DevSkim settings are changed
- Added custom LSP request handler `devskim/rescanDocument` to Language Server to support on-demand rescanning


## [1.0.75] - 2026-02-06
### Changed
- Removed unnecessary uninstall/reinstall of @vscode/vsce from postinstall script in VSCode plugin
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,5 +9,6 @@ public static class DevSkimMessages
public const string FileVersion = "devskim/fileversion";
public const string CodeFixMapping = "devskim/codefixmapping";
public const string SetServerSettings = "devskim/setSettings";
public const string RescanDocument = "devskim/rescanDocument";
}
}
1 change: 1 addition & 0 deletions DevSkim-DotNet/Microsoft.DevSkim.LanguageServer/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ static async Task Main(string[] args)
.WithHandler<TextDocumentSyncHandler>()
.WithHandler<DidChangeConfigurationHandler>()
.WithHandler<VisualStudioConfigurationHandler>()
.WithHandler<RescanHandler>()
.WithServices(x => x.AddLogging(b => b.SetMinimumLevel(LogLevel.Debug)))
.WithConfigurationSection(ConfigHelpers.Section)
.OnInitialize(
Expand Down
51 changes: 51 additions & 0 deletions DevSkim-DotNet/Microsoft.DevSkim.LanguageServer/RescanHandler.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.

using MediatR;
using Microsoft.DevSkim.LanguageProtoInterop;
using Microsoft.Extensions.Logging;
using OmniSharp.Extensions.JsonRpc;
using OmniSharp.Extensions.LanguageServer.Protocol;
using OmniSharp.Extensions.LanguageServer.Protocol.Models;

namespace DevSkim.LanguageServer
{
[Method(DevSkimMessages.RescanDocument, Direction.ClientToServer)]
public record RescanDocumentParams : IRequest
{
public DocumentUri? Uri { get; init; }
public string? Text { get; init; }
public int? Version { get; init; }
}

/// <summary>
/// Handles requests from the client to rescan a document on demand
/// </summary>
public class RescanHandler : IJsonRpcRequestHandler<RescanDocumentParams>
{
private readonly ILogger<RescanHandler> _logger;
private readonly TextDocumentSyncHandler _syncHandler;

public RescanHandler(ILogger<RescanHandler> logger, TextDocumentSyncHandler syncHandler)
{
_logger = logger;
_syncHandler = syncHandler;
}

async Task<Unit> IRequestHandler<RescanDocumentParams, Unit>.Handle(RescanDocumentParams request, CancellationToken cancellationToken)
{
_logger.LogDebug($"RescanHandler: Received rescan request for {request.Uri}");

if (request.Uri is null || request.Text is null)
{
_logger.LogWarning("RescanHandler: Uri or Text is null");
return Unit.Value;
}

_logger.LogDebug($"RescanHandler: Rescanning document {request.Uri}");
await _syncHandler.ScanDocumentAsync(request.Text, request.Version, request.Uri);

return Unit.Value;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@

namespace DevSkim.LanguageServer
{
internal class TextDocumentSyncHandler : TextDocumentSyncHandlerBase
public class TextDocumentSyncHandler : TextDocumentSyncHandlerBase
{
private readonly ILogger<TextDocumentSyncHandler> _logger;
private readonly ILanguageServerFacade _facade;
Expand All @@ -31,6 +31,14 @@ public TextDocumentSyncHandler(ILogger<TextDocumentSyncHandler> logger, ILanguag

public TextDocumentSyncKind Change { get; } = TextDocumentSyncKind.Full;

/// <summary>
/// Public method to trigger document scanning on demand
/// </summary>
public async Task ScanDocumentAsync(string text, int? version, DocumentUri uri)
{
await GenerateDiagnosticsForTextDocumentAsync(text, version, uri);
}

private async Task<Unit> GenerateDiagnosticsForTextDocumentAsync(string text, int? version, DocumentUri uri)
{
if (string.IsNullOrEmpty(text))
Expand Down
24 changes: 24 additions & 0 deletions DevSkim-VSCode-Plugin/client/extension.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,21 @@ import { FileVersion } from './common/fileVersion';

let client: LanguageClient;

// Helper to rescan documents via custom server request
function rescanOpenDocuments() {
vscode.workspace.textDocuments
.filter(doc => selectors.some(s => vscode.languages.match(s, doc) > 0))
.forEach(doc => {
client?.sendRequest('devskim/rescanDocument', {
uri: doc.uri.toString(),
text: doc.getText(),
version: doc.version
}).catch(err => {
console.error(`DevSkim: Failed to rescan ${doc.uri.toString()}`, err);
});
});
}

async function resolveDotNetPath(): Promise<string> {
const result = await vscode.commands.executeCommand<any>(
"dotnet.acquire",
Expand Down Expand Up @@ -72,6 +87,14 @@ export function activate(context: ExtensionContext) {
})
);

// Register manual scan command
context.subscriptions.push(
vscode.commands.registerCommand('devskim.scanWorkspace', () => {
rescanOpenDocuments();
vscode.window.showInformationMessage('DevSkim: Rescanned all open files');
})
);

// The server bridge is implemented in .NET
const serverModule = vscode.Uri.joinPath(context.extensionUri, 'devskimBinaries', 'Microsoft.DevSkim.LanguageServer.dll');

Expand Down Expand Up @@ -136,6 +159,7 @@ export function activate(context: ExtensionContext) {
// Triggers server to query for client config.
// Hacky, but vscode insists a pull model should be used over a push model for transmitting settings.
client.sendNotification(DidChangeConfigurationNotification.type, { settings: "" });
rescanOpenDocuments();
}
});

Expand Down
7 changes: 6 additions & 1 deletion DevSkim-VSCode-Plugin/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,12 @@
],
"main": "./client/out/extension.js",
"contributes": {
"commands": [],
"commands": [
{
"command": "devskim.scanWorkspace",
"title": "DevSkim: Scan All Open Files"
}
],
"configuration": [
{
"order": 10,
Expand Down