You're Invited:Meet the Socket Team at BlackHat and DEF CON in Las Vegas, Aug 4-6.RSVP
Socket
Book a DemoInstallSign in
Socket

vscode-markdown-languageservice

Package Overview
Dependencies
Maintainers
6
Versions
60
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

vscode-markdown-languageservice - npm Package Compare versions

Comparing version

to
0.5.0-alpha.2

out/types/inMemoryDocument.js

2

out/index.js

@@ -53,3 +53,3 @@ "use strict";

const definitionsProvider = new definitions_1.MdDefinitionProvider(config, init.workspace, tocProvider, linkCache);
const renameProvider = new rename_1.MdRenameProvider(config, init.workspace, referencesProvider, init.parser.slugifier, logger);
const renameProvider = new rename_1.MdRenameProvider(config, init.workspace, init.parser, referencesProvider, tocProvider, init.parser.slugifier, logger);
const fileRenameProvider = new fileRename_1.MdFileRenameProvider(config, init.workspace, linkCache, referencesProvider);

@@ -56,0 +56,0 @@ const diagnosticsComputer = new diagnostics_1.DiagnosticComputer(config, init.workspace, linkProvider, tocProvider, logger);

@@ -53,3 +53,3 @@ "use strict";

const toc = await this.#tocProvider.get(resolvedResource);
return toc.lookup(sourceLink.href.fragment)?.headerLocation;
return toc?.lookup(sourceLink.href.fragment)?.headerLocation;
}

@@ -56,0 +56,0 @@ #getDefinitionOfRef(ref, allLinksInFile) {

@@ -11,2 +11,3 @@ "use strict";

const lsp = require("vscode-languageserver-protocol");
const logging_1 = require("../logging");
const position_1 = require("../types/position");

@@ -21,3 +22,2 @@ const range_1 = require("../types/range");

const documentLinks_1 = require("./documentLinks");
const logging_1 = require("../logging");
/**

@@ -297,3 +297,3 @@ * The severity at which diagnostics are reported

}
if (!toc.lookup(link.fragment) && !this.#isIgnoredLink(options, link.source.pathText) && !this.#isIgnoredLink(options, link.source.hrefText)) {
if (!toc?.lookup(link.fragment) && !this.#isIgnoredLink(options, link.source.pathText) && !this.#isIgnoredLink(options, link.source.hrefText)) {
const range = (link.source.fragmentRange && (0, range_1.modifyRange)(link.source.fragmentRange, (0, position_1.translatePosition)(link.source.fragmentRange.start, { characterDelta: -1 }), undefined)) ?? link.source.hrefRange;

@@ -300,0 +300,0 @@ diagnostics.push({

@@ -18,2 +18,3 @@ "use strict";

const file_1 = require("../util/file");
const mdLinks_1 = require("../util/mdLinks");
const path_2 = require("../util/path");

@@ -25,3 +26,2 @@ const schemes_1 = require("../util/schemes");

const documentLinks_1 = require("./documentLinks");
const mdLinks_1 = require("../util/mdLinks");
var CompletionContextKind;

@@ -28,0 +28,0 @@ (function (CompletionContextKind) {

@@ -81,3 +81,3 @@ "use strict";

&& (0, documentLinks_1.looksLikeLinkToResource)(this.#configuration, link.href, (0, textDocument_1.getDocUri)(document))
&& this.#parser.slugifier.fromHeading(link.href.fragment).value === header.slug.value) {
&& this.#parser.slugifier.fromFragment(link.href.fragment).equals(header.slug)) {
references.push({

@@ -149,3 +149,3 @@ kind: MdReferenceKind.Link,

const toc = await this.#tocProvider.get(resolvedResource);
const entry = toc.lookup(sourceLink.href.fragment);
const entry = toc?.lookup(sourceLink.href.fragment);
if (entry) {

@@ -152,0 +152,0 @@ references.push({

@@ -10,5 +10,8 @@ "use strict";

const path = require("path");
const lsp = require("vscode-languageserver-protocol");
const vscode_uri_1 = require("vscode-uri");
const config_1 = require("../config");
const logging_1 = require("../logging");
const tableOfContents_1 = require("../tableOfContents");
const inMemoryDocument_1 = require("../types/inMemoryDocument");
const position_1 = require("../types/position");

@@ -38,10 +41,14 @@ const range_1 = require("../types/range");

#workspace;
#parser;
#referencesProvider;
#tableOfContentProvider;
#slugifier;
#logger;
constructor(configuration, workspace, referencesProvider, slugifier, logger) {
constructor(configuration, workspace, parser, referencesProvider, tableOfContentProvider, slugifier, logger) {
super();
this.#configuration = configuration;
this.#workspace = workspace;
this.#parser = parser;
this.#referencesProvider = referencesProvider;
this.#tableOfContentProvider = tableOfContentProvider;
this.#slugifier = slugifier;

@@ -108,3 +115,3 @@ this.#logger = logger;

else if (triggerRef.kind === references_1.MdReferenceKind.Header || (triggerRef.kind === references_1.MdReferenceKind.Link && triggerRef.link.source.fragmentRange && (0, range_1.rangeContains)(triggerRef.link.source.fragmentRange, position) && (triggerRef.link.kind === documentLinks_1.MdLinkKind.Definition || triggerRef.link.kind === documentLinks_1.MdLinkKind.Link && triggerRef.link.href.kind === documentLinks_1.HrefKind.Internal))) {
return this.#renameFragment(allRefsInfo, newName);
return this.#renameFragment(allRefsInfo, newName, token);
}

@@ -154,12 +161,73 @@ else if (triggerRef.kind === references_1.MdReferenceKind.Link && !(triggerRef.link.source.fragmentRange && (0, range_1.rangeContains)(triggerRef.link.source.fragmentRange, position)) && (triggerRef.link.kind === documentLinks_1.MdLinkKind.Link || triggerRef.link.kind === documentLinks_1.MdLinkKind.Definition) && triggerRef.link.href.kind === documentLinks_1.HrefKind.Internal) {

}
#renameFragment(allRefsInfo, newName) {
const slug = this.#slugifier.fromHeading(newName).value;
async #renameFragment(allRefsInfo, newHeaderText, token) {
const builder = new editBuilder_1.WorkspaceEditBuilder();
let newSlug = this.#slugifier.fromHeading(newHeaderText);
const existingHeader = allRefsInfo.references.find(x => x.kind === references_1.MdReferenceKind.Header);
if (existingHeader) {
// If there's a real header we're renaming, we need to handle cases where there are duplicate header ids.
// There are two cases of this to consider:
//
// - The new name duplicates an existing header. In this case, we need to use the unique slug of the new header
// but also potentially update links to the other duplicated headers.
//
// - The old header was duplicated. This may result in links to other instances of the duplicated headers changing
//
// In both cases, there could be a cascading effect where multiple headers/links are updated.
// For instance:
//
// ``
// # Header
// # Header <- rename here
// # Header
// ```
//
// In this case we need to rename the third header as well plus all reference to it.
const doc = await this.#workspace.openMarkdownDocument(vscode_uri_1.URI.parse(existingHeader.location.uri));
if (token.isCancellationRequested) {
return;
}
if (doc) {
const editedDoc = new inMemoryDocument_1.InMemoryDocument(vscode_uri_1.URI.parse(existingHeader.location.uri), doc.getText());
editedDoc.updateContent(editedDoc.applyEdits([lsp.TextEdit.replace(existingHeader.location.range, '# ' + newHeaderText)]));
const [oldToc, newToc] = await Promise.all([
this.#tableOfContentProvider.getForDocument(doc),
tableOfContents_1.TableOfContents.create(this.#parser, editedDoc, token) // Don't use cache for new temp doc
]);
if (token.isCancellationRequested) {
return;
}
const changedHeaders = [];
oldToc.entries.forEach((oldEntry, index) => {
const newEntry = newToc.entries[index];
if (!newEntry) {
return;
}
if (oldEntry.headerLocation.range.start.line === existingHeader.location.range.start.line) {
newSlug = newEntry.slug; // Take the new slug from the edited document
return;
}
if (newEntry && !oldEntry.slug.equals(newEntry.slug)) {
changedHeaders.push(newEntry);
}
});
for (const changedHeader of changedHeaders) {
const refs = await this.#getAllReferences(doc, changedHeader.headerLocation.range.start, token);
if (token.isCancellationRequested) {
return;
}
for (const ref of refs?.references ?? []) {
if (ref.kind === references_1.MdReferenceKind.Link) {
builder.replace(ref.link.source.resource, ref.link.source.fragmentRange ?? ref.location.range, changedHeader.slug.value);
}
}
}
}
}
for (const ref of allRefsInfo.references) {
switch (ref.kind) {
case references_1.MdReferenceKind.Header:
builder.replace(vscode_uri_1.URI.parse(ref.location.uri), ref.headerTextLocation.range, newName);
builder.replace(vscode_uri_1.URI.parse(ref.location.uri), ref.headerTextLocation.range, newHeaderText);
break;
case references_1.MdReferenceKind.Link:
builder.replace(ref.link.source.resource, ref.link.source.fragmentRange ?? ref.location.range, !ref.link.source.fragmentRange || ref.link.href.kind === documentLinks_1.HrefKind.External ? newName : slug);
builder.replace(ref.link.source.resource, ref.link.source.fragmentRange ?? ref.location.range, !ref.link.source.fragmentRange || ref.link.href.kind === documentLinks_1.HrefKind.External ? newHeaderText : newSlug.value);
break;

@@ -166,0 +234,0 @@ }

@@ -10,4 +10,4 @@ "use strict";

const dispose_1 = require("../util/dispose");
const string_1 = require("../util/string");
const workspaceCache_1 = require("../workspaceCache");
const string_1 = require("../util/string");
class MdWorkspaceSymbolProvider extends dispose_1.Disposable {

@@ -14,0 +14,0 @@ #cache;

@@ -7,4 +7,4 @@ "use strict";

Object.defineProperty(exports, "__esModule", { value: true });
exports.githubSlugifier = exports.Slug = void 0;
class Slug {
exports.githubSlugifier = exports.GithubSlug = void 0;
class GithubSlug {
value;

@@ -15,6 +15,6 @@ constructor(value) {

equals(other) {
return this.value === other.value;
return other instanceof GithubSlug && this.value.toLowerCase() === other.value.toLowerCase();
}
}
exports.Slug = Slug;
exports.GithubSlug = GithubSlug;
/**

@@ -33,5 +33,23 @@ * A {@link ISlugifier slugifier} that approximates how GitHub's slugifier works.

);
return new Slug(slugifiedHeading);
return new GithubSlug(slugifiedHeading);
}
fromFragment(fragmentText) {
return new GithubSlug(fragmentText.toLowerCase());
}
createBuilder() {
const entries = new Map();
return {
add: (heading) => {
const slug = this.fromHeading(heading);
const existingSlugEntry = entries.get(slug.value);
if (existingSlugEntry) {
++existingSlugEntry.count;
return this.fromHeading(slug.value + '-' + existingSlugEntry.count);
}
entries.set(slug.value, { count: 0 });
return slug;
}
};
}
};
//# sourceMappingURL=slugify.js.map

@@ -9,3 +9,2 @@ "use strict";

const logging_1 = require("./logging");
const slugify_1 = require("./slugify");
const range_1 = require("./types/range");

@@ -42,3 +41,3 @@ const textDocument_1 = require("./types/textDocument");

}
const existingSlugEntries = new Map();
const slugBuilder = parser.slugifier.createBuilder();
const headers = [];

@@ -70,11 +69,3 @@ let currentHeader;

const bodyText = TableOfContents.#getHeaderTitleAsPlainText(body);
let slug = parser.slugifier.fromHeading(bodyText);
const existingSlugEntry = existingSlugEntries.get(slug.value);
if (existingSlugEntry) {
++existingSlugEntry.count;
slug = parser.slugifier.fromHeading(slug.value + '-' + existingSlugEntry.count);
}
else {
existingSlugEntries.set(slug.value, { count: 0 });
}
const slug = slugBuilder.add(bodyText);
const headerLocation = {

@@ -147,3 +138,2 @@ uri: docUri.toString(),

}
static empty = new TableOfContents([], slugify_1.githubSlugifier);
#slugifier;

@@ -175,4 +165,4 @@ constructor(entries, slugifier) {

}
async get(resource) {
return await this.#cache.get(resource) ?? TableOfContents.empty;
get(resource) {
return this.#cache.get(resource);
}

@@ -179,0 +169,0 @@ getForDocument(doc) {

@@ -9,13 +9,13 @@ "use strict";

const lsp = require("vscode-languageserver-protocol");
const config_1 = require("../../config");
const extractLinkDef_1 = require("../../languageFeatures/codeActions/extractLinkDef");
const documentLinks_1 = require("../../languageFeatures/documentLinks");
const extractLinkDef_1 = require("../../languageFeatures/codeActions/extractLinkDef");
const tableOfContents_1 = require("../../tableOfContents");
const inMemoryDocument_1 = require("../../types/inMemoryDocument");
const range_1 = require("../../types/range");
const cancellation_1 = require("../../util/cancellation");
const engine_1 = require("../engine");
const inMemoryDocument_1 = require("../inMemoryDocument");
const inMemoryWorkspace_1 = require("../inMemoryWorkspace");
const nulLogging_1 = require("../nulLogging");
const util_1 = require("../util");
const range_1 = require("../../types/range");
const config_1 = require("../../config");
async function getActions(store, doc, pos) {

@@ -22,0 +22,0 @@ const workspace = store.add(new inMemoryWorkspace_1.InMemoryWorkspace([doc]));

@@ -14,6 +14,6 @@ "use strict";

const tableOfContents_1 = require("../../tableOfContents");
const inMemoryDocument_1 = require("../../types/inMemoryDocument");
const range_1 = require("../../types/range");
const cancellation_1 = require("../../util/cancellation");
const engine_1 = require("../engine");
const inMemoryDocument_1 = require("../inMemoryDocument");
const inMemoryWorkspace_1 = require("../inMemoryWorkspace");

@@ -20,0 +20,0 @@ const nulLogging_1 = require("../nulLogging");

@@ -46,3 +46,3 @@ "use strict";

}
async getForDocument(document) {
getForDocument(document) {
const existing = this.#cache.get((0, textDocument_1.getDocUri)(document));

@@ -49,0 +49,0 @@ if (existing) {

{
"name": "vscode-markdown-languageservice",
"description": "Markdown language service",
"version": "0.5.0-alpha.1",
"version": "0.5.0-alpha.2",
"author": "Microsoft Corporation",

@@ -22,2 +22,3 @@ "license": "MIT",

"vscode-languageserver-protocol": "^3.17.1",
"vscode-languageserver-textdocument": "^1.0.11",
"vscode-uri": "^3.0.7"

@@ -37,4 +38,4 @@ },

"mocha": "^10.0.0",
"typescript": "^5.4.2",
"vscode-languageserver-textdocument": "^1.0.8"
"source-map-support": "^0.5.21",
"typescript": "^5.4.2"
},

@@ -47,3 +48,3 @@ "scripts": {

"prepublishOnly": "npm run compile && npm run api-extractor",
"test": "mocha 'out/test/**/*.test.js' --ui=tdd --timeout=2000 --exit"
"test": "mocha -r source-map-support/register 'out/test/**/*.test.js' --ui=tdd --timeout=2000 --exit"
},

@@ -50,0 +51,0 @@ "repository": {

@@ -374,2 +374,7 @@ import { Event as Event_2 } from 'vscode-languageserver-protocol';

export declare interface ISlug {
readonly value: string;
equals(other: ISlug): boolean;
}
/**

@@ -379,3 +384,22 @@ * Generates unique ids for headers in the Markdown.

export declare interface ISlugifier {
fromHeading(heading: string): Slug;
/**
* Create a new slug from the text of a markdown heading.
*
* For a heading such as `# Header`, this will be called with `Header`
*/
fromHeading(headingText: string): ISlug;
/**
* Create a slug from a link fragment.
*
* For a link such as `[text](#header)`, this will be called with `header`
*/
fromFragment(fragmentText: string): ISlug;
/**
* Creates a stateful object that can be used to build slugs incrementally.
*
* This should be used when getting all slugs in a document as it handles duplicate headings
*/
createBuilder(): {
add(headingText: string): ISlug;
};
}

@@ -605,8 +629,2 @@

declare class Slug {
readonly value: string;
constructor(value: string);
equals(other: Slug): boolean;
}
export declare interface Token {

@@ -613,0 +631,0 @@ readonly type: string;