Skip to content
Merged
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
4 changes: 4 additions & 0 deletions src/Client/.vscodeignore
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,10 @@ node_modules/**
server/**/*.pdb

# Development files
tests/**
.vscode-test.mjs
tsconfig.integration.json
**/*.kqr
.gitignore
.git/**
**/*.bat
Expand Down
4 changes: 2 additions & 2 deletions src/Client/features/connectionManager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@ import type { IServer, DatabaseInfo } from './server';
// Storage Keys
// =============================================================================

export const SERVERS_STORAGE_KEY = 'kusto.serversAndGroups';
export const DOCUMENT_CONNECTIONS_KEY = 'kusto.documentConnections';
const SERVERS_STORAGE_KEY = 'kusto.serversAndGroups';
const DOCUMENT_CONNECTIONS_KEY = 'kusto.documentConnections';

// =============================================================================
// Data Types
Expand Down
6 changes: 3 additions & 3 deletions src/Client/features/connectionsPanel.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1583,7 +1583,7 @@ class KustoDragAndDropController implements vscode.TreeDragAndDropController<Kus

constructor(private readonly connections: ConnectionManager, private readonly onDragStart: () => void) {}

async handleDrag(source: readonly KustoTreeItem[], dataTransfer: vscode.DataTransfer, token: vscode.CancellationToken): Promise<void> {
async handleDrag(source: readonly KustoTreeItem[], dataTransfer: vscode.DataTransfer, _token: vscode.CancellationToken): Promise<void> {
// Suppress selection changes during drag
this.onDragStart();

Expand Down Expand Up @@ -1619,7 +1619,7 @@ class KustoDragAndDropController implements vscode.TreeDragAndDropController<Kus
}
}

async handleDrop(target: KustoTreeItem | undefined, dataTransfer: vscode.DataTransfer, token: vscode.CancellationToken): Promise<void> {
async handleDrop(target: KustoTreeItem | undefined, dataTransfer: vscode.DataTransfer, _token: vscode.CancellationToken): Promise<void> {
const transferItem = dataTransfer.get('application/vnd.code.tree.mskustoexplorer_connections');
if (!transferItem) {
return;
Expand Down Expand Up @@ -1661,7 +1661,7 @@ class KustoDocumentDropEditProvider implements vscode.DocumentDropEditProvider {

async provideDocumentDropEdits(
document: vscode.TextDocument,
position: vscode.Position,
_position: vscode.Position,
dataTransfer: vscode.DataTransfer,
token: vscode.CancellationToken
): Promise<vscode.DocumentDropEdit | undefined> {
Expand Down
2 changes: 1 addition & 1 deletion src/Client/features/copilot.ts
Original file line number Diff line number Diff line change
Expand Up @@ -441,7 +441,7 @@ async function runQuery(input: { query: string; cluster?: string; database?: str
*/
async function handleChatRequest(
request: vscode.ChatRequest,
context: vscode.ChatContext,
_context: vscode.ChatContext,
stream: vscode.ChatResponseStream,
token: vscode.CancellationToken
): Promise<vscode.ChatResult> {
Expand Down
2 changes: 1 addition & 1 deletion src/Client/features/plotlyChartProvider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2907,7 +2907,7 @@ export class PlotlyChartProvider implements IChartProvider {
}
builder = builder.addSecondaryYAxis('yaxis2', {
overlaying: 'y',
side: 'right',
side: PlotlyAxisSides.Right,
showgrid: false,
});
} else if (options.yLayout === ChartYLayout.SeparatePanels && yColumns.length > 1) {
Expand Down
42 changes: 4 additions & 38 deletions src/Client/features/queryEditor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,7 @@ import { ResultsViewer } from './resultsViewer';
import { HistoryManager } from './historyManager';
import type { HistoryEntry } from './historyManager';
import type { HistoryPanel } from './historyPanel';
import type { IClipboard } from './clipboard';
import type { ClipboardItem } from './clipboard';
import { formatCfHtml, type ClipboardItem, type IClipboard } from './clipboard';
import { ENTITY_DEFINITION_SCHEME } from './entityDefinitionProvider';

const PASTE_KIND = vscode.DocumentDropOrPasteEditKind.Text.append('kusto');
Expand Down Expand Up @@ -515,7 +514,7 @@ export class QueryEditor {

// Place both HTML and plain text on the clipboard
const items: ClipboardItem[] = [
{ format: 'HTML Format', data: wrapHtmlForClipboard(result.html) },
{ format: 'HTML Format', data: formatCfHtml(result.html) },
{ format: 'Text', data: plainText, encoding: 'text' }
];

Expand Down Expand Up @@ -752,8 +751,8 @@ class KustoPasteEditProvider implements vscode.DocumentPasteEditProvider {
document: vscode.TextDocument,
ranges: readonly vscode.Range[],
dataTransfer: vscode.DataTransfer,
context: vscode.DocumentPasteEditContext,
token: vscode.CancellationToken
_context: vscode.DocumentPasteEditContext,
_token: vscode.CancellationToken
): Promise<vscode.DocumentPasteEdit[] | undefined> {
const clipboardContext = this.clipboard.getContext();
if (!clipboardContext) {
Expand Down Expand Up @@ -975,39 +974,6 @@ function requestSemanticTokens(document: vscode.TextDocument): void {
).catch(() => undefined);
}

/**
* Wraps HTML content in the CF_HTML clipboard format header required by Windows.
*/
function wrapHtmlForClipboard(html: string): string {
// CF_HTML format requires specific headers with byte offsets
const header = 'Version:0.9\r\nStartHTML:SSSSSSSSSS\r\nEndHTML:EEEEEEEEEE\r\nStartFragment:FFFFFFFFFF\r\nEndFragment:GGGGGGGGGG\r\n';
const startFragment = '<!--StartFragment-->';
const endFragment = '<!--EndFragment-->';
const body = `<!DOCTYPE html><html><body>${startFragment}${html}${endFragment}</body></html>`;
const full = header + body;

// Calculate byte offsets (CF_HTML uses byte positions)
const encoder = new TextEncoder();
const headerBytes = encoder.encode(header).length;
const startFragOffset = headerBytes + encoder.encode(`<!DOCTYPE html><html><body>${startFragment}`).length - encoder.encode(startFragment).length + encoder.encode(startFragment).length;
const fullBytes = encoder.encode(full).length;

// Simpler: compute offsets by measuring
const beforeFragment = header + `<!DOCTYPE html><html><body>`;
const afterStartFragment = beforeFragment + startFragment;
const beforeEndFragment = afterStartFragment + html;

const startHtml = encoder.encode(header).length;
const endHtml = encoder.encode(full).length;
const startFrag = encoder.encode(afterStartFragment).length;
const endFrag = encoder.encode(beforeEndFragment).length;

return full
.replace('SSSSSSSSSS', startHtml.toString().padStart(10, '0'))
.replace('EEEEEEEEEE', endHtml.toString().padStart(10, '0'))
.replace('FFFFFFFFFF', startFrag.toString().padStart(10, '0'))
.replace('GGGGGGGGGG', endFrag.toString().padStart(10, '0'));
}

/**
* Forces VS Code to invalidate semantic token cache by making a real edit on all visible Kusto editors.
Expand Down
27 changes: 7 additions & 20 deletions src/Client/features/resultsViewer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ interface ResultViewerState {
/**
* Determines if VS Code is currently using a dark color theme.
*/
export function isDarkMode(): boolean {
function isDarkMode(): boolean {
const colorTheme = vscode.window.activeColorTheme;
return colorTheme.kind === vscode.ColorThemeKind.Dark ||
colorTheme.kind === vscode.ColorThemeKind.HighContrast;
Expand Down Expand Up @@ -432,7 +432,6 @@ export class ResultsViewer {
// ─── Bottom view state ──────────────────────────────────────────────
private resultsPanel: vscode.WebviewView | undefined;
private lastPanelResultData: server.ResultData | undefined;
private lastPanelTableNames: string[] = [];
private panelActiveTabIndex = 0;
private panelActiveView: string = 'table-0';
private panelHasChart = false;
Expand Down Expand Up @@ -489,7 +488,7 @@ export class ResultsViewer {
this.chartProvider = chartProvider;
this.chartEditorProvider = chartEditorProvider;
this.dataTableProvider = dataTableProvider;
this.htmlBuilder = new DocumentViewProvider(this.createPanelStateAccessor(), server, chartProvider, chartEditorProvider, dataTableProvider);
this.htmlBuilder = new DocumentViewProvider(this.createPanelStateAccessor(), chartProvider, chartEditorProvider, dataTableProvider);

context.subscriptions.push(
vscode.window.registerCustomEditorProvider(
Expand Down Expand Up @@ -671,7 +670,6 @@ export class ResultsViewer {
vscode.commands.executeCommand('setContext', 'msKustoExplorer.panelHasChart', hasChart);
vscode.commands.executeCommand('setContext', 'msKustoExplorer.panelChartActive', hasChart);
const hasTable = !!resultData.tables.length;
this.lastPanelTableNames = resultData.tables.map(t => t.name);

if (!hasTable && !hasChart) {
await this.showPanelHtml('<html><body>no results</body></html>');
Expand Down Expand Up @@ -726,7 +724,7 @@ export class ResultsViewer {
this.panelEditorView?.setOptions(rawChartOptions, columnNames, chartDefaults, resultData.tables.map(t => ({ name: t.name, columns: t.columns.map(c => c.name) })), chartTable?.name);
}

const html = this.htmlBuilder.BuildMultiTabbedHtml(hasChart, mode, this.panelWebView, this.panelEditorWebView, chartOptions, columnNames,
const html = this.htmlBuilder.BuildMultiTabbedHtml(hasChart, mode, this.panelWebView, this.panelEditorWebView, chartOptions,
resultData.query, resultData.cluster, resultData.database, resultData.tables, this.panelTableWebViews);

const totalRows = resultData.tables.reduce((sum, t) => sum + t.rows.length, 0);
Expand Down Expand Up @@ -880,7 +878,7 @@ export class ResultsViewer {
if (editorAdapter) { editorAdapter.suppressMessages = priorEditorSuppress; }
}

const html = this.htmlBuilder.BuildMultiTabbedHtml(hasChart, mode, this.singletonWebView, this.singletonEditorWebView, chartOptions, columnNames,
const html = this.htmlBuilder.BuildMultiTabbedHtml(hasChart, mode, this.singletonWebView, this.singletonEditorWebView, chartOptions,
resultData.query, resultData.cluster, resultData.database, resultData.tables, this.singletonTableWebViews);

this.showSingletonView(injectMessageHandlerScripts(html), resultData, resultData.tables.map(t => t.name), singletonLocation, mode);
Expand Down Expand Up @@ -1011,7 +1009,6 @@ export class ResultsViewer {
this.resultsPanel.badge = undefined;
}
this.lastPanelResultData = undefined;
this.lastPanelTableNames = [];
this.panelHasChart = false;
this.panelActiveView = 'table-0';
vscode.commands.executeCommand('setContext', 'msKustoExplorer.panelHasChart', false);
Expand Down Expand Up @@ -1231,8 +1228,7 @@ export class ResultsViewer {
} else {
// Re-render without the chart
const tableNames = updated.tables.map(t => t.name);
const columnNames = updated.tables[0]?.columns?.map(c => c.name) ?? [];
const html = this.htmlBuilder.BuildMultiTabbedHtml(false, this.singletonMode ?? 'all', this.singletonWebView, this.singletonEditorWebView, undefined, columnNames,
const html = this.htmlBuilder.BuildMultiTabbedHtml(false, this.singletonMode ?? 'all', this.singletonWebView, this.singletonEditorWebView, undefined,
updated.query, updated.cluster, updated.database, updated.tables, this.singletonTableWebViews);
this.singletonView!.webview.html = injectMessageHandlerScripts(html);

Expand Down Expand Up @@ -1312,14 +1308,6 @@ export class ResultsViewer {
return this.dataTableViews.get(panel);
}

private getActiveTableName(state: ResultViewerState): string | undefined {
const match = state.activeView.match(/^table-(\d+)$/);
if (match) {
const idx = parseInt(match[1]!, 10);
return state.tableNames[idx];
}
return state.tableNames[0];
}

/**
* Default \"Copy\" / Ctrl+C: TSV plain text + CF_HTML rich text.
Expand Down Expand Up @@ -1616,7 +1604,7 @@ class DocumentViewProvider implements vscode.CustomTextEditorProvider {
return next;
}

constructor(private readonly viewer: IViewerPanelState, private readonly server: IServer, private readonly chartProvider: IChartProvider, private readonly chartEditorProvider: IChartEditorProvider, private readonly dataTableProvider: IDataTableProvider) {
constructor(private readonly viewer: IViewerPanelState, private readonly chartProvider: IChartProvider, private readonly chartEditorProvider: IChartEditorProvider, private readonly dataTableProvider: IDataTableProvider) {
}

async resolveCustomTextEditor(
Expand Down Expand Up @@ -1871,7 +1859,7 @@ class DocumentViewProvider implements vscode.CustomTextEditorProvider {
editorView?.setOptions(rawChartOptions, columnNames, chartDefaults, resultData.tables.map(t => ({ name: t.name, columns: t.columns.map(c => c.name) })), chartTable?.name);
}

const html = this.BuildMultiTabbedHtml(hasChart, 'all', docWebView, docEditorWebView, chartOptions, columnNames,
const html = this.BuildMultiTabbedHtml(hasChart, 'all', docWebView, docEditorWebView, chartOptions,
resultData.query, resultData.cluster, resultData.database, resultData.tables, docTableWebViews);
webviewPanel.webview.html = injectMessageHandlerScripts(html);
}
Expand Down Expand Up @@ -1899,7 +1887,6 @@ class DocumentViewProvider implements vscode.CustomTextEditorProvider {
webview: WebViewAdapter | undefined,
editorWebView: WebViewAdapter | undefined,
chartOptions?: server.ChartOptions,
columnNames?: string[],
queryText?: string,
cluster?: string,
database?: string,
Expand Down
5 changes: 2 additions & 3 deletions src/Client/features/server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ import { CancellationToken, Disposable, ExtensionContext } from 'vscode';
import {
acquireMicrosoftAuthenticationToken,
GetAuthenticationTokenParams,
GetAuthenticationTokenResult,
} from './authentication';

/**
Expand Down Expand Up @@ -743,12 +742,12 @@ export interface DocumentReadyNotification {
}

/** Parameters for the server's getData request. */
export interface GetDataParams {
interface GetDataParams {
key: string;
}

/** Parameters for the server's setData request. */
export interface SetDataParams {
interface SetDataParams {
key: string;
data: object | undefined;
}
Expand Down
2 changes: 0 additions & 2 deletions src/Client/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading
Loading