You can get the language configuration for the current language and check that for lineComment
or blockComment
. I do this in my extension Find and Transform so you could look in that repository to see how it is done.
But here is my code simplified (I have to parse some keybinding args, etc. along the way you don't have to):
With const jsonc = require('jsonc-parser');
at the top of the file and that package installed in your extension. Why? Because some of the language configuration files have comments in them, so JSON.parse()
will not work for them.
// call the language configuration getter (in an async function)
const documentLanguageId = vscode.window.activeTextEditor.document.languageId;
const config = await languageConfigs.getLanguageConfigFile(documentLanguageId);
config
will be an object like config.comments.lineComment
and/or config.comments.blockComment
. A language like javascript will have values for both but css will have only a config.comments.blockComment
and config.comments.lineComment
will be undefined
.
Here is more code
/**
* Get an array of "languages", like plaintext, that don't have comment syntax
* @returns {string[]}
*/
function _getLanguagesToSkip () {
return ['log', 'Log', 'search-result', 'plaintext', 'scminput', 'properties', 'csv', 'tsv', 'excel'];
}
This function above is called because some "languages" like .txt
files don't have any comments so skip those in the next function:
/**
* @param {string} langID -
*/
exports.getLanguageConfigFile = async function (langID) {
let thisConfig = {};
let langConfigFilePath = null;
// loop through all installed extensions, including built-in extensions
for (let i = 0; i < vscode.extensions.all.length; i++) {
let _ext = vscode.extensions.all[i];
// if an extension contributes languages we want them
// they have links to their language configuration file
if (_ext.packageJSON.contributes && _ext.packageJSON.contributes.languages) {
const contributedLanguages = _ext.packageJSON.contributes.languages; // may be an array!
for (let j = 0; j < contributedLanguages.length; j++) {
let packageLang = contributedLanguages[j];
// match the current editor language ID that we passed in
if (packageLang.id === langID) {
// "languages" to skip, like plaintext, etc. = no configuration properties that we are interested in
let skipLangs = _getLanguagesToSkip();
if (!skipLangs?.includes(packageLang.id) && _ext.packageJSON.contributes.languages[j].configuration) {
langConfigFilePath = path.join(
_ext.extensionPath,
_ext.packageJSON.contributes.languages[j].configuration
);
if (!!langConfigFilePath && fs.existsSync(langConfigFilePath)) {
thisConfig = jsonc.parse(fs.readFileSync(langConfigFilePath).toString());
return thisConfig;
}
}
}
}
}
}
return thisConfig; // would be an empty object if we end up here
// which would mean there is no extension with a language configuration file thay matches the active editor language
};
It works fast enough to not be noticeable, although I do have a version somewhere which gets all the currently installed language configs and saves to storage which can be run once and then again if no match for the current langID is found. That version is much cleaner and shorter because it goes through all extensions, instead of stopping at the current editor language like the above - but does unnecessary work unless you are going to save them all.