Skip to content
Merged
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,7 @@
"@types/vscode": "^1.130",
"prettier": "^3.9.6",
"prettier-plugin-multiline-arrays": "^4.1.11",
"typescript": "^5.7"
"typescript": "^7.0.0"
},
"dependencies": {
"is-wsl": "^3.1.0",
Expand Down
56 changes: 31 additions & 25 deletions src/configuration.ts
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ export class Configuration {
// Read the default multi-line config from the JSON file and cache it for later use.
this.defaultMultiLineConfig = utils.readJsonFile(`${configPath}/default-multi-line-config.json`) as vscode.LanguageConfiguration;
// Read the languages to skip from the JSON file and cache it for later use.
this.languagesToSkip = utils.readJsonFile(`${configPath}/skip-languages.jsonc`);
this.languagesToSkip = utils.readJsonFile<JsonObject>(`${configPath}/skip-languages.jsonc`) ?? {};

this.findAllLanguageConfigFilePaths();
this.setLanguageConfigDefinitions();
Expand Down Expand Up @@ -255,7 +255,7 @@ export class Configuration {
* ```
*/
public getConfigurationValue<K extends keyof Settings>(key: K): Settings[K] {
return this.getConfiguration().get<Settings[K]>(key);
return this.getConfiguration().get<Settings[K]>(key) as Settings[K];
}

/**
Expand Down Expand Up @@ -343,8 +343,8 @@ export class Configuration {
const builtInExtensionsPath = this.extensionData.getExtensionDiscoveryPath("builtInExtensionsPath");

// Read the paths and create arrays of the extensions.
const userExtensions = this.readExtensionsFromDirectory(userExtensionsPath);
const builtInExtensions = this.readExtensionsFromDirectory(builtInExtensionsPath);
const userExtensions = userExtensionsPath ? this.readExtensionsFromDirectory(userExtensionsPath) : [];
const builtInExtensions = builtInExtensionsPath ? this.readExtensionsFromDirectory(builtInExtensionsPath) : [];

// Add all installed extensions (including built-in ones) into the extensions array.
// If running WSL, these will be the WSL-installed extensions.
Expand Down Expand Up @@ -372,7 +372,7 @@ export class Configuration {
// If the langId already exists...
if (this.languageConfigFilePaths.has(langId)) {
// Push the new config path into the array of the existing langId.
this.languageConfigFilePaths.get(langId).push(configPath);
this.languageConfigFilePaths.get(langId)?.push(configPath);
}
// Otherwise, if the langId doesn't exist...
else {
Expand Down Expand Up @@ -412,7 +412,7 @@ export class Configuration {
// Define a new array as the new AutoClosingPair.
const autoClosingPairsArray: vscode.AutoClosingPair[] = [];
// Loop through the config's autoClosingPairs...
config.autoClosingPairs.forEach((item) => {
(config.autoClosingPairs ?? []).forEach((item) => {
// If the item is an array...
if (Array.isArray(item)) {
// Create a new object with the 1st array element [0] as the
Expand All @@ -439,7 +439,7 @@ export class Configuration {
const existingConfig = this.languageConfigs.get(langId);

// Only merge if both configs have comments
if (existingConfig.comments && config.comments) {
if (existingConfig?.comments && config.comments) {
// Start with existing comments as base
const mergedComments = {...existingConfig.comments};

Expand All @@ -449,7 +449,9 @@ export class Configuration {
if (Array.isArray(value) && value.length === 0) {
return;
}
mergedComments[key] = value;
if (key === "lineComment" || key === "blockComment") {
mergedComments[key] = value;
}
});

// Update the config with merged comments
Expand Down Expand Up @@ -555,7 +557,7 @@ export class Configuration {
this.languageConfigs.forEach((config: vscode.LanguageConfiguration, langId: LanguageId) => {
// If the config object has own property of comments AND the comments key has
// own property of blockComment...
if (Object.hasOwn(config, "comments") && Object.hasOwn(config.comments, "blockComment")) {
if (config.comments && Object.hasOwn(config.comments, "blockComment") && config.comments.blockComment) {
// If the blockComment array includes the multi-line start of "/*"...
if (config.comments.blockComment.includes("/*")) {
// console.log(langId, config.comments);
Expand Down Expand Up @@ -627,7 +629,7 @@ export class Configuration {

// If the config object has own property of comments AND the comments key has
// own property of lineComment...
if (Object.hasOwn(config, "comments") && Object.hasOwn(config.comments, "lineComment")) {
if (config.comments && Object.hasOwn(config.comments, "lineComment")) {
let lineComment = config.comments.lineComment;

// Line comments can be a string or an object with a "comment" key.
Expand Down Expand Up @@ -752,21 +754,19 @@ export class Configuration {

// Deep-clone the internalLangConfig so modifications never write back
// into the cached `languageConfigs` Map by accident.
let langConfig: vscode.LanguageConfiguration = internalLangConfig
? structuredClone(internalLangConfig)
: {};
let langConfig: vscode.LanguageConfiguration = internalLangConfig ? structuredClone(internalLangConfig) : {};

if (multiLine) {
langConfig.autoClosingPairs = utils.mergeArraysBy<vscode.AutoClosingPair>(
this.defaultMultiLineConfig.autoClosingPairs,
internalLangConfig?.autoClosingPairs,
this.defaultMultiLineConfig.autoClosingPairs ?? [],
internalLangConfig?.autoClosingPairs ?? [],
"open"
);

// Add the multi-line onEnter rules to the langConfig.
langConfig.onEnterRules = utils.mergeArraysBy<vscode.OnEnterRule>(
Rules.multilineEnterRules,
internalLangConfig?.onEnterRules,
internalLangConfig?.onEnterRules ?? [],
"beforeText"
);

Expand All @@ -780,7 +780,7 @@ export class Configuration {
if (this.isLangIdMultiLineCommentOverridden(langId) && langConfig.comments?.blockComment) {
langConfig.comments.blockComment = [
this.getOverriddenMultiLineComment(langId),
langConfig.comments.blockComment[1]
langConfig.comments.blockComment[1],
];
}

Expand All @@ -792,6 +792,7 @@ export class Configuration {

// If bladeComments has a value...
if (bladeComments) {
langConfig.comments ??= {};
langConfig.comments.blockComment = bladeComments;
}
}
Expand All @@ -805,22 +806,26 @@ export class Configuration {
if (isOnEnter && singleLineStyle) {
// //-style comments
if (singleLineStyle === "//") {
langConfig.onEnterRules = utils.mergeArraysBy<vscode.OnEnterRule>(Rules.slashEnterRules, langConfig?.onEnterRules, "beforeText");
langConfig.onEnterRules = utils.mergeArraysBy<vscode.OnEnterRule>(Rules.slashEnterRules, langConfig.onEnterRules ?? [], "beforeText");
}
// #-style comments
else if (singleLineStyle === "#") {
langConfig.onEnterRules = utils.mergeArraysBy<vscode.OnEnterRule>(Rules.hashEnterRules, langConfig?.onEnterRules, "beforeText");
langConfig.onEnterRules = utils.mergeArraysBy<vscode.OnEnterRule>(Rules.hashEnterRules, langConfig.onEnterRules ?? [], "beforeText");
}
// ;-style comments
else if (singleLineStyle === ";") {
langConfig.onEnterRules = utils.mergeArraysBy<vscode.OnEnterRule>(Rules.semicolonEnterRules, langConfig?.onEnterRules, "beforeText");
langConfig.onEnterRules = utils.mergeArraysBy<vscode.OnEnterRule>(
Rules.semicolonEnterRules,
langConfig.onEnterRules ?? [],
"beforeText"
);
}
}
// If isOnEnter is false AND singleLineStyle isn't false, i.e. a string.
else if (!isOnEnter && singleLineStyle) {
// If langConfig does NOT have a comments key OR
// the comments key exists but does NOT have the lineComment key...
if (!Object.hasOwn(langConfig, "comments") || !Object.hasOwn(langConfig.comments, "lineComment")) {
if (!langConfig.comments || !Object.hasOwn(langConfig.comments, "lineComment")) {
// Add the singleLineStyle to the lineComments key and make sure any
// blockComments aren't overwritten.
langConfig.comments = {...langConfig.comments, lineComment: singleLineStyle};
Expand All @@ -838,7 +843,7 @@ export class Configuration {

// Check if isOnEnter OR multiline is true.
if (isOnEnter || multiLine) {
langConfig.onEnterRules.forEach((item) => {
(langConfig.onEnterRules ?? []).forEach((item) => {
// Check if the item has a "beforeText" property and reconstruct its regex pattern.
if (Object.hasOwn(item, "beforeText")) {
item.beforeText = utils.reconstructRegex(item, "beforeText");
Expand Down Expand Up @@ -941,12 +946,13 @@ export class Configuration {

// Get the langId from the auto-supported langs. If it doesn't exist, try getting it from
// the custom-supported langs instead.
let style: SingleLineCommentStyle | ExtraSingleLineCommentStyles = singleLineLangs.get(langId) ?? customSingleLineLangs.get(langId);
let style: SingleLineCommentStyle | ExtraSingleLineCommentStyles | undefined =
singleLineLangs.get(langId) ?? customSingleLineLangs.get(langId);

if (style && textEditor.selection.isEmpty) {
let line = textEditor.document.lineAt(textEditor.selection.active);
let isCommentLine = true;
let indentRegex: RegExp;
let indentRegex: RegExp | undefined;

if (style === "//" && line.text.search(/^\s*\/\/\s*/) !== -1) {
indentRegex = /\//;
Expand All @@ -972,7 +978,7 @@ export class Configuration {
isCommentLine = false;
}

if (!isCommentLine) {
if (!isCommentLine || !indentRegex) {
return;
}

Expand Down
3 changes: 0 additions & 3 deletions src/extension.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,6 @@ import {addDevEnvVariables} from "./utils";
import {LogLevel} from "./interfaces/utils";

export function activate(context: vscode.ExtensionContext) {
// Setup logger first
logger.setupOutputChannel();

const initialLogLevel = vscode.workspace.getConfiguration("auto-comment-blocks").get<LogLevel>("logLevel", "debug");
logger.setLogLevel(initialLogLevel);

Expand Down
31 changes: 17 additions & 14 deletions src/extensionData.ts
Original file line number Diff line number Diff line change
Expand Up @@ -61,9 +61,9 @@ export class ExtensionData {
/**
* The package.json data for this extension.
*
* @type {IPackageJson}
* @type {IPackageJson | null}
*/
private packageJsonData: IPackageJson;
private packageJsonData: IPackageJson | null;

/**
* Create an instance of the ExtensionData class, which retrieves and stores metadata
Expand All @@ -90,18 +90,15 @@ export class ExtensionData {

this.packageJsonData = this.getExtensionPackageJsonData();

// Only proceed with extension data setup if packageJsonData is NOT null.
if (this.packageJsonData !== null) {
this.setExtensionData();
}
this.setExtensionData();

this.setExtensionDiscoveryPaths();
}

/**
* Get the names, id, and version of this extension from package.json.
*
* @returns {IPackageJson | null} The package.json data for this extension, with extra custom keys.
* @returns {IPackageJson | null} The package.json data for this extension.
*/
private getExtensionPackageJsonData(): IPackageJson | null {
// Get the package.json file path.
Expand All @@ -113,26 +110,32 @@ export class ExtensionData {
* Set the extension data into the extensionData Map.
*/
private setExtensionData() {
// Only proceed if packageJsonData is NOT falsy, otherwise return early.
const packageJsonData = this.packageJsonData;
if (!packageJsonData) {
return;
}

// Create the extension ID (publisher.name).
const id = `${this.packageJsonData.publisher}.${this.packageJsonData.name}`;
const id = `${packageJsonData.publisher}.${packageJsonData.name}`;

// Set each key-value pair directly into the Map
this.extensionData.set("id", id);
this.extensionData.set("name", this.packageJsonData.name);
this.extensionData.set("name", packageJsonData.name);

// Only set the namespace if it dealing with this extension.
if (this.packageJsonData.name === "automatic-comment-blocks") {
if (packageJsonData.name === "automatic-comment-blocks") {
// The configuration settings namespace is a shortened version of the extension name.
// We just need to replace "automatic" with "auto" in the name.
const settingsNamespace: string = this.packageJsonData.name.replace("automatic", "auto");
const settingsNamespace: string = packageJsonData.name.replace("automatic", "auto");

this.extensionData.set("namespace", settingsNamespace);
}

this.extensionData.set("displayName", this.packageJsonData.displayName);
this.extensionData.set("version", this.packageJsonData.version);
this.extensionData.set("displayName", packageJsonData.displayName);
this.extensionData.set("version", packageJsonData.version);
this.extensionData.set("extensionPath", this.extensionPath);
this.extensionData.set("packageJSON", this.packageJsonData);
this.extensionData.set("packageJSON", packageJsonData);
}

/**
Expand Down
4 changes: 2 additions & 2 deletions src/interfaces/commands.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,10 @@ export interface CommandRegistration {
* command is executed.
*
* @param textEditor The text editor
* @param edit The text editor edits. Optional because some commands may not need it.
* @param edit The text editor edits.
* @returns void
*/
handler: (textEditor: vscode.TextEditor, edit?: vscode.TextEditorEdit) => void;
handler: (textEditor: vscode.TextEditor, edit: vscode.TextEditorEdit) => void;
}

/**
Expand Down
21 changes: 6 additions & 15 deletions src/logger.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import {LogLevel, logLevels} from "./interfaces/utils";
/**
* Logger class for the Auto Comment Blocks extension.
* This class handles logging messages of differing log levels to the output channel.
* Logger is a singleton class, and should only be instantiated once (in this file).
*
* @class Logger
*/
Expand Down Expand Up @@ -41,15 +42,10 @@ class Logger {
***********/

/**
* Override the output channel
*
* @param {OutputChannel} channelOverride A vscode output channel.
* Constructor for the Logger class, which
* initialises the output channel for logging.
*/
public setupOutputChannel(channelOverride?: OutputChannel): void {
if (channelOverride) {
this.outputChannel = channelOverride;
return;
}
constructor() {
this.outputChannel = window.createOutputChannel("Auto Comment Blocks", "log");
}

Expand Down Expand Up @@ -90,9 +86,7 @@ class Logger {
* Show the output channel to the user.
*/
public showChannel(): void {
if (this.outputChannel) {
this.outputChannel.show();
}
this.outputChannel.show();
}

/**
Expand Down Expand Up @@ -190,10 +184,6 @@ class Logger {
* @param {unknown} meta Extra data as needed.
*/
private logMessage(level: string, message: string, meta?: unknown): void {
if (!this.outputChannel) {
this.setupOutputChannel();
}

message = this.redactUsername(message);

const time = new Date().toLocaleTimeString();
Expand Down Expand Up @@ -310,4 +300,5 @@ class Logger {
}
}

// Create and export the singleton instance of the Logger class.
export const logger = new Logger();
Loading
Loading