Skip to content
Open
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
10 changes: 8 additions & 2 deletions apps/lsp/src/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ export interface Settings {
};
readonly symbols: {
readonly exportToWorkspace: 'default' | 'all' | 'none';
readonly showCodeCellsInOutline: boolean;
};
};
readonly markdown: {
Expand Down Expand Up @@ -96,7 +97,8 @@ function defaultSettings(): Settings {
extensions: []
},
symbols: {
exportToWorkspace: 'all'
exportToWorkspace: 'all',
showCodeCellsInOutline: true
}
},
markdown: {
Expand Down Expand Up @@ -181,7 +183,8 @@ export class ConfigurationManager extends Disposable {
extensions: quarto?.mathjax?.extensions ?? this._settings.quarto.mathjax.extensions
},
symbols: {
exportToWorkspace: quarto?.symbols?.exportToWorkspace ?? this._settings.quarto.symbols.exportToWorkspace
exportToWorkspace: quarto?.symbols?.exportToWorkspace ?? this._settings.quarto.symbols.exportToWorkspace,
showCodeCellsInOutline: quarto?.symbols?.showCodeCellsInOutline ?? this._settings.quarto.symbols.showCodeCellsInOutline
}
}
};
Expand Down Expand Up @@ -258,6 +261,9 @@ export function lsConfiguration(configManager: ConfigurationManager): LsConfigur
},
get exportSymbolsToWorkspace(): 'default' | 'all' | 'none' {
return configManager.getSettings().quarto.symbols.exportToWorkspace;
},
get showCodeCellsInOutline(): boolean {
return configManager.getSettings().quarto.symbols.showCodeCellsInOutline;
}
};
}
Expand Down
4 changes: 3 additions & 1 deletion apps/lsp/src/service/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@ export interface LsConfiguration {
readonly mathjaxScale: number;
readonly mathjaxExtensions: readonly MathjaxSupportedExtension[];
readonly exportSymbolsToWorkspace: 'default' | 'all' | 'none';
readonly showCodeCellsInOutline: boolean;
}

export const defaultMarkdownFileExtension = 'qmd';
Expand Down Expand Up @@ -111,7 +112,8 @@ const defaultConfig: LsConfiguration = {
colorTheme: 'light',
mathjaxScale: 1,
mathjaxExtensions: [],
exportSymbolsToWorkspace: 'all'
exportSymbolsToWorkspace: 'all',
showCodeCellsInOutline: true
};

export function defaultLsConfiguration(): LsConfiguration {
Expand Down
2 changes: 1 addition & 1 deletion apps/lsp/src/service/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -208,7 +208,7 @@ export function createLanguageService(init: LanguageServiceInitialization): IMdL
const definitionsProvider = new MdDefinitionProvider(config, init.workspace, tocProvider, linkCache);
const diagnosticOnSaveComputer = new DiagnosticOnSaveComputer(init.quarto);
const diagnosticsComputer = new DiagnosticComputer(config, init.workspace, linkProvider, tocProvider, logger);
const docSymbolProvider = new MdDocumentSymbolProvider(tocProvider, linkProvider, logger);
const docSymbolProvider = new MdDocumentSymbolProvider(config, tocProvider, linkProvider, logger);
const workspaceSymbolProvider = new MdWorkspaceSymbolProvider(init.workspace, init.config, docSymbolProvider);
const documentHighlightProvider = new MdDocumentHighlightProvider(config, tocProvider, linkProvider);

Expand Down
22 changes: 20 additions & 2 deletions apps/lsp/src/service/providers/document-symbols.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,10 @@
import { CancellationToken } from 'vscode-languageserver';
import * as lsp from 'vscode-languageserver-types';
import { isBefore, makeRange, Document } from 'quarto-core';
import { ILogger, LogLevel } from '../logging';
import { ILogger } from '../logging';
import { MdTableOfContentsProvider, TableOfContents, TocEntry, TocEntryType } from '../toc';
import { MdLinkDefinition, MdLinkKind, MdLinkProvider } from './document-links';
import { LsConfiguration } from '../config';

interface MarkdownSymbol {
readonly level: number;
Expand All @@ -36,12 +37,15 @@ export class MdDocumentSymbolProvider {
readonly #tocProvider: MdTableOfContentsProvider;
readonly #linkProvider: MdLinkProvider;
readonly #logger: ILogger;
readonly #config: LsConfiguration;

constructor(
config: LsConfiguration,
tocProvider: MdTableOfContentsProvider,
linkProvider: MdLinkProvider,
logger: ILogger,
) {
this.#config = config;
this.#tocProvider = tocProvider;
this.#linkProvider = linkProvider;
this.#logger = logger;
Expand Down Expand Up @@ -75,7 +79,21 @@ export class MdDocumentSymbolProvider {
range: makeRange(0, 0, document.lineCount + 1, 0),
};
const additionalSymbols = [...linkSymbols];
this.#buildTocSymbolTree(root, toc.entries.filter(entry => entry.type !== TocEntryType.Title), additionalSymbols);

// Filter out TOC entries based on configuration
const filteredEntries = toc.entries.filter(entry => {
// Always exclude title entries
if (entry.type === TocEntryType.Title) {
return false;
}
// Exclude all code cells if the setting is disabled
if (entry.type === TocEntryType.CodeCell && !this.#config.showCodeCellsInOutline) {
return false;
}
return true;
});

this.#buildTocSymbolTree(root, filteredEntries, additionalSymbols);
// Put remaining link definitions into top level document instead of last header
root.children.push(...additionalSymbols);
return root.children;
Expand Down
10 changes: 10 additions & 0 deletions apps/vscode/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -292,6 +292,11 @@
"title": "Clear Cache...",
"category": "Quarto"
},
{
"command": "quarto.toggleCodeCellsInOutline",
"title": "Toggle Code Cells in Outline",
"category": "Quarto"
},
{
"command": "quarto.convertToIpynb",
"title": "Convert to .ipynb",
Expand Down Expand Up @@ -1364,6 +1369,11 @@
],
"default": "default",
"description": "Whether Markdown elements like section headers are included in workspace symbol search."
},
"quarto.symbols.showCodeCellsInOutline": {
"type": "boolean",
"default": true,
"description": "Show code cells in the document outline."
}
}
},
Expand Down
3 changes: 3 additions & 0 deletions apps/vscode/src/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ import { activateDenoConfig } from "./providers/deno-config";
import { textFormattingCommands } from "./providers/text-format";
import { newDocumentCommands } from "./providers/newdoc";
import { insertCommands } from "./providers/insert";
import { symbolsCommands } from "./providers/symbols";
import { activateDiagram } from "./providers/diagram/diagram";
import { activateCodeFormatting } from "./providers/format";
import { activateOptionEnterProvider } from "./providers/option";
Expand Down Expand Up @@ -157,6 +158,8 @@ export async function activate(context: vscode.ExtensionContext): Promise<Quarto

commands.push(...insertCommands(engine));

commands.push(...symbolsCommands());

commands.push(...activateDiagram(context, host, engine));

commands.push(...activateCodeFormatting(engine));
Expand Down
44 changes: 44 additions & 0 deletions apps/vscode/src/providers/symbols.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
/*
* symbols.ts
*
* Copyright (C) 2025 by Posit Software, PBC
*
* Unless you have received this program directly from Posit Software pursuant
* to the terms of a commercial license agreement with Posit Software, then
* this program is licensed to you under the terms of version 3 of the
* GNU Affero General Public License. This program is distributed WITHOUT
* ANY EXPRESS OR IMPLIED WARRANTY, INCLUDING THOSE OF NON-INFRINGEMENT,
* MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Please refer to the
* AGPL (http://www.gnu.org/licenses/agpl-3.0.txt) for more details.
*
*/

import * as vscode from "vscode";
import { Command } from "../core/command";

class ToggleCodeCellsInOutlineCommand implements Command {
public readonly id = "quarto.toggleCodeCellsInOutline";

public async execute() {
const config = vscode.workspace.getConfiguration("quarto");
const currentValue = config.get<boolean>("symbols.showCodeCellsInOutline", true);
const newValue = !currentValue;

await config.update("symbols.showCodeCellsInOutline", newValue, vscode.ConfigurationTarget.Global);

// Hack: trigger outline refresh by making a no-op edit
const editor = vscode.window.activeTextEditor;
if (editor && editor.document.languageId === "quarto") {
await editor.edit(edit => edit.insert(new vscode.Position(0, 0), " "));
await editor.edit(edit => edit.delete(new vscode.Range(0, 0, 0, 1)));
}

vscode.window.showInformationMessage(
`Code cells in outline will now be ${newValue ? "shown" : "hidden"}.`
);
}
}

export function symbolsCommands(): Command[] {
return [new ToggleCodeCellsInOutlineCommand()];
}
Loading