diff --git a/src/Client/README.md b/src/Client/README.md
index 12bfc33..4ab7e45 100644
--- a/src/Client/README.md
+++ b/src/Client/README.md
@@ -3,61 +3,38 @@
Edit, run and chart Kusto queries (KQL).
Explore databases and query results.
-## Features
-
-- KQL Documents
- - IntelliSense (auto completions)
- - Syntax and Semantic coloring
- - Semantic Copy/Paste
- - Copy query text as colorized html
- - Hover Tips
- - Describes item under the mouse cursor
- - Shows related diagnostics
- - Syntax highlighting
- - Highlights references to the same item
- - Highlights balanced parentheses, brackets and braces
- - Goto Definition
- - Goto the declaration location of items declared in your query or as part of the database
- - Find All References
- - Find all references to an item in your query
- - Diagnostics (errors/warnings)
- - All kusto diagnostics appear in VS Code Problems tab
- - Formatting
- - Pretty print a single query using Format button above first line of query
- - Pretty print the entire document using VS Code's Format Document (ALT-SHIFT-F).
- - Adjust format settings in VS Code `Settings/Extensions/Kusto`
- - Query execution
- - Place the caret inside the query and press F5
- - Code Actions
- - Quick fixes are indicated by ellipses beneath the related item, and are accissible within the hover tip.
- - Refactorings are indicated by a lightbulb menu that appears after clicking on related text item.
- - CoPilot also makes suggestions and offers fixes in the same UI.
-- Connection panel
- - Add and remove server connections
- - Add and remove server group folders
- - Drag and drop server into and out of groups folders
- - Assign a connection to a KQL document by selecting a database
- - Explore database contents and view entity definitions
-- Results Panel
- - View and explorer the tabular results of queries
- - Tab through multiple result tables
- - Copy a table as html and markdown
- - Copy a table as a Kusto datatable expression
-- Chart Panel
- - View chart as result of query with render operator
- - Copy charts as SVG, PNG and bitmap
-- Chat Panel
- - Ask CoPilot questions using @kusto in the chat interface
-
-## Usage
-
-1. Open a `.kql` or `.csl` file
-2. Select or add a connection in the connections view of the explorer panel
-3. Select a default database for the the document under the connection item
-4. Write your query
-5. Press F5 to execute
+## Get Started
+- Open or create a `.kql` file in VS Code
+- Adjust placement of connection panel (it will appear at bottom of list)
+- Add a server connection and select a default database for the document
+- Write a Kusto query or consult copilot for help writing one
+- Press F5 to execute the query and view results in the results panel
+- Use the chart button in the results panel to create a chart for your result data
+- Edit the chart options to customize the chart type, axes, legend and more
+- Add another query to the kql document, rinse and repeat
+- Save your results and charts as a .kqr file to share with others or re-open later
+
+## Query Editor (.kql documents)
+- Syntax and semantic coloring of query text
+- Autocompletion (Intellisense)
+- Hover tips
+- Pretty Printing (formatting)
+- Goto definition and find all references for functions, tables, columns, and more
+- Code actions and quick fixes for common issues and refactorings
+- Copy colorized query text to the clipboard for pasting into other documents
+- Have mutliple independent queries in the same document, separated by a blank line.
+
+## Results Panel (bottom panel)
+- Copy contents of cells or entire table to clipboard
+- Drag and drop a table into your document as a KQL datatable expression
+- Chart your data (it will open in a results viewer tab)
+
+## Results Viewer (.kqr documents)
+- Shows both result data and chart in the same view
+- Copy the chart as an image to clipboard for either light-mode or dark-mode pasting.
+- Copy the data to clipboard just like results panel.
+- Edit the chart options to customize the chart type, axes, legend and more
+- Save to a .kqr file to share with others or re-open later
## Requirements
-
-- VS Code 1.9.0 or higher
-
+- VS Code 1.9.0 or higher
\ No newline at end of file
diff --git a/src/Client/features/documentPanels.ts b/src/Client/features/documentPanels.ts
index d40eb1b..ceec831 100644
--- a/src/Client/features/documentPanels.ts
+++ b/src/Client/features/documentPanels.ts
@@ -304,24 +304,20 @@ async function copyQueryTransparent(client: LanguageClient, codeLensRange?: serv
return;
}
- const selection = {
- start: { line: queryRange.start.line, character: queryRange.start.character },
- end: { line: queryRange.end.line, character: queryRange.end.character }
- };
-
- // Request light-mode HTML from the server (darkMode = false)
- const result = await server.getQueryAsHtml(client, uri, selection, false);
- if (!result?.html) {
- return;
- }
-
- // Get plain text of the query for the text format
+ // Get plain text of the query
const range = new vscode.Range(
queryRange.start.line, queryRange.start.character,
queryRange.end.line, queryRange.end.character
);
const plainText = editor.document.getText(range);
+ // Request light-mode HTML from the server (darkMode = false)
+ const connection = await getDocumentConnection(uri);
+ const result = await server.getQueryAsHtml(client, plainText, connection?.cluster, connection?.database, false);
+ if (!result?.html) {
+ return;
+ }
+
// Place both HTML and plain text on the clipboard
const items: import('./clipboard').ClipboardItem[] = [
{ format: 'HTML Format', data: wrapHtmlForClipboard(result.html) },
diff --git a/src/Client/features/resultsViewer.ts b/src/Client/features/resultsViewer.ts
index a8a2eba..a13221b 100644
--- a/src/Client/features/resultsViewer.ts
+++ b/src/Client/features/resultsViewer.ts
@@ -398,6 +398,7 @@ export class ResultEditorProvider implements vscode.CustomTextEditorProvider {
const state = editorStates.get(webviewPanel);
const hasChart = !!state?.resultData?.chartOptions;
vscode.commands.executeCommand('setContext', 'kusto.resultEditorHasChart', hasChart);
+ vscode.commands.executeCommand('setContext', 'kusto.resultEditorChartActive', state?.activeView === 'chart');
}
};
webviewPanel.onDidChangeViewState(() => updateChartContext());
@@ -417,6 +418,7 @@ export class ResultEditorProvider implements vscode.CustomTextEditorProvider {
if (state) {
state.activeView = message.viewId;
}
+ vscode.commands.executeCommand('setContext', 'kusto.resultEditorChartActive', message.viewId === 'chart');
return;
}
if (message.command === 'copyText' && typeof message.text === 'string') {
@@ -429,19 +431,22 @@ export class ResultEditorProvider implements vscode.CustomTextEditorProvider {
state.chartOptionsOverride = message.chartOptions as server.ChartOptions;
if (chartOptionsTimer) { clearTimeout(chartOptionsTimer); }
chartOptionsTimer = setTimeout(async () => {
- await this.updateChartOnly(state, webviewPanel);
- // Persist updated chart options to the backing file
- const updatedData: server.ResultData = { ...state.resultData, chartOptions: state.chartOptionsOverride! };
- const content = JSON.stringify(updatedData, null, 2);
- const fullRange = new vscode.Range(
- document.positionAt(0),
- document.positionAt(document.getText().length)
- );
- const edit = new vscode.WorkspaceEdit();
- edit.replace(document.uri, fullRange, content);
- ignoringSelfEdit = true;
- await vscode.workspace.applyEdit(edit);
- ignoringSelfEdit = false;
+ try {
+ await this.updateChartOnly(state, webviewPanel);
+ // Persist updated chart options to the backing file
+ const updatedData: server.ResultData = { ...state.resultData, chartOptions: state.chartOptionsOverride! };
+ const content = JSON.stringify(updatedData, null, 2);
+ const fullRange = new vscode.Range(
+ document.positionAt(0),
+ document.positionAt(document.getText().length)
+ );
+ const edit = new vscode.WorkspaceEdit();
+ edit.replace(document.uri, fullRange, content);
+ ignoringSelfEdit = true;
+ await vscode.workspace.applyEdit(edit);
+ } finally {
+ ignoringSelfEdit = false;
+ }
}, 600);
return;
}
@@ -488,6 +493,7 @@ export class ResultEditorProvider implements vscode.CustomTextEditorProvider {
if (chartOptionsTimer) { clearTimeout(chartOptionsTimer); }
editorStates.delete(webviewPanel);
vscode.commands.executeCommand('setContext', 'kusto.resultEditorHasChart', false);
+ vscode.commands.executeCommand('setContext', 'kusto.resultEditorChartActive', false);
changeSubscription.dispose();
themeSubscription.dispose();
});
@@ -511,7 +517,7 @@ export class ResultEditorProvider implements vscode.CustomTextEditorProvider {
const darkMode = isDarkMode();
- // Fetch both table HTML and chart HTML in parallel
+ // Fetch table HTML and chart HTML in parallel
const [dataResult, chartResult] = await Promise.all([
Promise.resolve(resultDataToHtml(resultData)),
resultData.chartOptions
@@ -525,6 +531,8 @@ export class ResultEditorProvider implements vscode.CustomTextEditorProvider {
// Update context key for editor title actions
if (webviewPanel.active) {
vscode.commands.executeCommand('setContext', 'kusto.resultEditorHasChart', hasChart);
+ const activeView = editorStates.get(webviewPanel)?.activeView ?? (hasChart ? 'chart' : 'table-0');
+ vscode.commands.executeCommand('setContext', 'kusto.resultEditorChartActive', activeView === 'chart');
}
if (!hasTable && !hasChart) {
@@ -539,12 +547,14 @@ export class ResultEditorProvider implements vscode.CustomTextEditorProvider {
editorStates.set(webviewPanel, {
resultData,
tableNames,
- activeView: existingState?.activeView ?? firstActiveView
+ activeView: existingState?.activeView ?? firstActiveView,
+ chartOptionsOverride: existingState?.chartOptionsOverride
});
const chartOptions = existingState?.chartOptionsOverride ?? resultData.chartOptions;
const columnNames = resultData.tables[0]?.columns?.map(c => c.name) ?? [];
- const html = this.buildDualViewHtml(dataResult, chartResult?.html, hasChart, chartOptions, columnNames);
+ const html = this.buildDualViewHtml(dataResult, chartResult?.html, hasChart, chartOptions, columnNames,
+ resultData.query, resultData.cluster, resultData.database);
webviewPanel.webview.html = injectChartMessageHandler(html);
}
@@ -570,13 +580,16 @@ export class ResultEditorProvider implements vscode.CustomTextEditorProvider {
chartHtml: string | undefined,
hasChart: boolean,
chartOptions?: server.ChartOptions,
- columnNames?: string[]
+ columnNames?: string[],
+ queryText?: string,
+ cluster?: string,
+ database?: string
): string {
const tables = dataResult?.tables ?? [];
// Build individual table divs
const tableContents = tables.map((t, i) =>
- `