The term "containerName" in SymbolInformation is utilized to represent the hierarchy of

In my quest to make the code outline feature work for a custom language, I have made progress in generating symbols and displaying functions in the outline view. However, my next challenge is to display variables under the respective function in the outline view. While my symbols seem to have the correct containerName value, I am currently stuck with a flat outline view.

The following is the current code snippet from extension.ts:

'use strict';
import * as vscode from 'vscode';

export function activate(context: vscode.ExtensionContext) {
    context.subscriptions.push(vscode.languages.registerDocumentSymbolProvider(
        {language: "as"}, new FooDocumentSymbolProvider()
    ));
}

class FooDocumentSymbolProvider implements vscode.DocumentSymbolProvider {
    public provideDocumentSymbols(document: vscode.TextDocument, token: vscode.CancellationToken): Thenable<vscode.SymbolInformation[]> {
        return new Promise((resolve, reject) => {
            var symbols = [];
            var sym = "";
            for (var i = 0; i < document.lineCount; i++) {
                var line = document.lineAt(i);
                if (line.text.startsWith(".PROGRAM")) {
                    var sym = "";
                    symbols.push({
                        name: line.text.substr(9).trimRight(),
                        kind: vscode.SymbolKind.Function,
                        containerName: sym,
                        location: new vscode.Location(document.uri, line.range)
                    });
                    sym = line.text.substr(9).trimRight();
                }
                if (line.text.includes("CALL") && !(line.text.startsWith(".*"))) {
                    symbols.push({
                        name: line.text.substr(0).trimLeft(),
                        kind: vscode.SymbolKind.Module,
                        containerName: sym,
                        location: new vscode.Location(document.uri, line.range)
                    });
                }
            }
            resolve(symbols);
        });
    }
}

    

UPDATE #2:

public provideDocumentSymbols(document: vscode.TextDocument, token: vscode.CancellationToken): Thenable<vscode.DocumentSymbol[]> {
        return new Promise((resolve, reject) => {
            var symbols = [];
            var sym = "";
            for (var i = 0; i < document.lineCount; i++) {
                var line = document.lineAt(i);
                if (line.text.startsWith(".PROGRAM")) {
                    var sym = "";
                    var childrens = [];
                    symbols.push({
                        name: line.text.substr(9).trimRight(),
                        kind: vscode.SymbolKind.Function,
                        children: [],
                        range: line.range,
                        detail: "",
                        selectionRange: line.range
                    });
                    sym = line.text.substr(9).trimRight();
                }
                if (line.text.includes("CALL") && !(line.text.startsWith(".*"))) {
                    symbols.push({
                        name: line.text.substr(0).trimLeft(),
                        kind: vscode.SymbolKind.Module,
                        children: [],
                        range: line.range,
                        detail: "",
                        selectionRange: line.range
                    });
                }
            }
            resolve(symbols);
        });
    }

    

Answer №1

containerName isn't actually the key player in determining the hierarchy. It's more like an added "detail" that shows up in a faded font under the symbol.

The real solution is to steer clear of using SymbolInformation altogether, and instead opt for the newer DocumentSymbol API (remember when document symbol providers didn't support hierarchies until it was introduced in version 1.25). Each DocumentSymbol can have an array of children, making it easy to represent the hierarchy as a tree structure.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Yep, implementing conditional logic with the `when` keyword and radio buttons

I seem to be encountering an issue with my implementation (probably something trivial). I am utilizing React Hook Form along with Yup and attempting to establish a condition based on the selection of a radio group. The scenario is as follows: if the first ...

The 'eventKey' argument does not match the 'string' parameter. This is because 'null' cannot be assigned to type 'string'

Encountering an issue while invoking a TypeScript function within a React Project. const handleLanguageChange = React.useCallback((eventKey: eventKey) => { setLanguage(eventKey); if(eventKey == "DE") setCurre ...

NextJS introduces a unique functionality to Typescript's non-null assertion behavior

As per the typescript definition, the use of the non-null assertion operator is not supposed to impact execution. However, I have encountered a scenario where it does. I have been struggling to replicate this issue in a simpler project. In my current proj ...

Conceal object from inventory upon clicking

As someone who is new to React and Typescript, I am facing challenges in understanding how to hide a ticket from the list when the hide button is clicked. displayTickets = (tickets: Ticket[]) => { const filteredTickets = tickets.filter(t => ...

Automatic type inference for functions in TypeScript with arguments

I am looking to define an interface with the following structure: interface CheckNActSetup<D, C> { defs: (event: Event) => D, context: (defs: D) => C; exec: (context: C) => any[]; when: ((context: C) => boolean)[]; } and implement it usi ...

What are the solutions for handling undefined data within the scope of Typescript?

I am encountering an issue with my ngOnInit() method. The method fills a data list at the beginning and contains two different logic branches depending on whether there is a query param present (navigating back to the page) or it's the first opening o ...

Having conflicting useEffects?

I often encounter this problem. When I chain useEffects to trigger after state changes, some of the useEffects in the chain have overlapping dependencies that cause them both to be triggered simultaneously instead of sequentially following a state change. ...

Solving commitments through a series of actions

Can someone please explain why when resolving promises in a loop, accessing the loop variable is necessary for it to work correctly? Here's an example where logging occurs 5 times: for (let i = 0; i < 5; i++) { this.getData() .then(() ...

Tips for packaging a Node TypeScript/JavaScript library using Webpack

I am currently working on a Node project with the following setup: Written in Typescript Using Webpack and ts-loader for bundling Targeting Node.js +-proj/ +-src/ |-file1.ts |-file2.ts |-file3.ts |-... |-package.json |-webpack.confi ...

Retrieving a specific data point from the web address

What is the most efficient way to retrieve values from the window.location.href? For instance, consider this sample URL: http://localhost:3000/brand/1/brandCategory/3. The structure of the route remains consistent, with only the numbers varying based on u ...

The API endpoint code functions perfectly in Express, but encounters an error when integrated into Next.js

Express Code: app.get('/', async (req, res) => { const devices = await gsmarena.catalog.getBrand("apple-phones-48"); const name = devices.map((device) => device.name); res.json(name); }) Nextjs Code: import {gsmarena} ...

Having difficulty importing the WebRTCAdaptor from the antmedia package stored in the node modules directory into an Angular Typescript file

An error is appearing indicating that: There seems to be a problem finding a declaration file for the module '@antmedia/webrtc_adaptor/js/webrtc_adaptor.js'. The file 'D:/web/node_modules/@antmedia/webrtc_adaptor/js/webrtc_adaptor.js' ...

Is there a way to showcase just the month in one spot when presenting data using Angular 13?

Just starting out with Angular and facing a challenge in the Milestone section. There is a loop for displaying years and months, but I need to ensure that the month name is displayed only once for each specific year. Can someone provide me with a possible ...

Encountering challenges with reusing modules in Angular2

I am currently working on an angular2 website with a root module and a sub level module. However, I have noticed that whatever modules I include in the root module must also be re-included in the sub level module, making them not truly reusable. This is w ...

What are some strategies for circumventing the need for two switches?

My LayerEditor class consists of two private methods: export class LayerEditor { public layerManager: LayerManager; constructor() { this.layerManager = new LayerManager(this); } private executeCommand() { ...

Is there a RxJS equivalent of tap that disregards notification type?

Typically, a tap pipe is used for side effects like logging. In this scenario, the goal is simply to set the isLoading property to false. However, it's important that this action occurs regardless of whether the notification type is next or error. Thi ...

Using local fonts with Styled Components and React TypeScript: A beginner's guide

Currently, I'm in the process of building a component library utilizing Reactjs, TypeScript, and Styled-components. I've come across the suggestion to use createGlobalStyle as mentioned in the documentation. However, since I am only working on a ...

Is there a way to verify a user's login status?

Currently, I am working on an angular 13 project and incorporating @angular/fire 7 into my development process. I have developed a service with various functions for injection. Below is the code snippet: import { Injectable } from '@angular/core&apos ...

Using TypeScript and the `this` keyword in SharePoint Framework with Vue

I'm currently developing a SharePoint Framework web part with Vue.js. Check out this code snippet: export default class MyWorkspaceTestWebPart extends BaseClientSideWebPart<IMyWorkspaceTestWebPartProps> { public uol_app; public render(): ...

Most effective method for initiating model class attributes

Is there a more efficient way to initialize model classes without explicitly defining each member as undefined? The original concept was to be able to simply use super(data); in extended classes. class Model { construct(data: any) { Object.ke ...