Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

VSCode API Check if the current line is a comment

Is it possible to query if the current line is a comment using the VSCode API ?

like image 364
sreenivas Avatar asked May 01 '20 04:05

sreenivas


People also ask

How do I find comments in VS Code?

Type CTRL + F and type //. * and select the regex sign like the below picture. Now you can see all the commented lines are selected.

How do you select the current line in VS Code?

“shortcut to select a line vscode” Code Answer's On Windows: Shift + Alt + Up/Down. On Mac: Shift + Option + Up/Down.

How do you do single line comments in VS Code?

Windows: Ctrl + K + U. Mac: Command + K + U.

How do I comment out multiple lines of code in VSCode?

If you want to comment out multiple lines of code within the same comment, this is what you're looking for. To toggle a VSCode comment block, you can use editor.action.blockComment: There's one other way to comment and un-comment, but it's not as handy.

What is VSCode API?

VS Code API is a set of JavaScript APIs that you can invoke in your Visual Studio Code extension. This page lists all VS Code APIs available to extension authors. This listing is compiled from the vscode.d.ts file from the VS Code repository. Namespace for authentication.

What is a VSCode comment block?

These are comments which span multiple lines of code (a block). If you want to comment out multiple lines of code within the same comment, this is what you're looking for. To toggle a VSCode comment block, you can use editor.action.blockComment: There's one other way to comment and un-comment, but it's not as handy.

How do I block multiple lines of code in VSCode?

Some programming languages support block comments. These are comments which span multiple lines of code (a block). If you want to comment out multiple lines of code within the same comment, this is what you’re looking for. To toggle a VSCode comment block, you can use editor.action.blockComment: Windows: Shift + Alt + A.


1 Answers

This solution is not optimal, but it works.

Taken from: https://github.com/aaron-bond/better-comments/pull/302/commits/47717e7ddcf110cb7cd2a7902ccc98ab146f97a5

You can generate a configuration file that lists all the language specific keywords/symbols from the currently installed extensions.

Then use this file to get the comment configuration and thus the comment delimiters (for line comment and comment blocks).

I implemented a class for doing this, borrowing from the above commit:

import * as vscode from 'vscode';
import * as path from 'path';
import * as fs from 'fs';

interface CommentConfig {
    lineComment?: string;
    blockComment?: [string, string];
}

export class CommentConfigHandler {
    private readonly languageToConfigPath = new Map<string, string>();
    private readonly commentConfig = new Map<string, CommentConfig | undefined>();

    public constructor() {
        this.updateLanguagesDefinitions();
    }

    /**
        * Generate a map of language configuration file by language defined by extensions
        * External extensions can override default configurations os VSCode
        */
    public updateLanguagesDefinitions() {
        this.commentConfig.clear();

        for (const extension of vscode.extensions.all) {
            const packageJSON = extension.packageJSON as any;
            if (packageJSON.contributes && packageJSON.contributes.languages) {
                for (const language of packageJSON.contributes.languages) {
                    if (language.configuration) {
                        const configPath = path.join(extension.extensionPath, language.configuration);
                        this.languageToConfigPath.set(language.id, configPath);
                    }
                }
            }
        }
    }

    /**
        * Return the comment config for `languageCode`
        * @param languageCode The short code of the current language
        */
    public getCommentConfig(languageCode: string): CommentConfig | undefined {
        if (this.commentConfig.has(languageCode)) {
            return this.commentConfig.get(languageCode);
        }

        if (!this.languageToConfigPath.has(languageCode)) {
            return undefined;
        }

        const file = this.languageToConfigPath.get(languageCode) as string;

        const content = fs.readFileSync(file, { encoding: 'utf8' });

        try {
            // Using normal JSON because json5 behaved buggy.
            // Might need JSON5 in the future to parse language jsons with comments.
            const config = JSON.parse(content);

            this.commentConfig.set(languageCode, config.comments);
            return config.comments;
        } catch (error) {
            this.commentConfig.set(languageCode, undefined);
            return undefined;
        }
    }
}

To detect if a line is a comment you could get the comment configuration using the class above, escape the delimiters, and use them in a regex.

Something like this:

activeEditor = vscode.window.activeTextEditor;

const commentConfigHandler = new CommentConfig();

const commentCfg = commentConfigHandler.getCommentConfig(activeEditor.document.languageId);

function escapeRegex(string: string) {
    return string.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&');
}

const commentLineDelimiter = commentCfg.lineComment;

const regex = new RegExp(`\s*${escapeRegex(commentLineDelimiter )}.*`, "ig");

const isComment = regex.test(lineText)

Note that the above example only tests for single line comments and will need to be extended for block comments with a more extensive regex that includes commentCfg.blockComment[0] and commentCfg.blockComment[1].

like image 122
Zoom Avatar answered Sep 22 '22 23:09

Zoom