Skip to content

Commit

Permalink
enhance(refs): more intelligent ref copying
Browse files Browse the repository at this point in the history
copy note ref copies header if selected
  • Loading branch information
kevinslin committed Sep 10, 2020
1 parent a2183ec commit 6f1906f
Show file tree
Hide file tree
Showing 5 changed files with 131 additions and 3 deletions.
2 changes: 1 addition & 1 deletion packages/common-server/src/testUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ export class NodeTestUtils {
notes.map((n) => {
const body = cleanOpts.withBody ? n.fname + " body" : "";
// @ts-ignore
node2MdFile(new Note({ ...n, body }), {
node2MdFile(new Note({ body, ...n }), {
root: vaultPath,
});
});
Expand Down
46 changes: 46 additions & 0 deletions packages/engine-server/src/__tests__/utils.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import {
replaceRefWithMPEImport,
stripLocalOnlyTags,
extractBlock,
refLink2String,
} from "../utils";
import _ from "lodash";
import { EngineTestUtils } from "@dendronhq/common-server/src";
Expand Down Expand Up @@ -53,8 +54,53 @@ describe("parseFileLink", () => {
type: "file",
});
});

it("next anchor", () => {
expect(parseFileLink("[[foo]]#head1:#*")).toEqual({
anchorEnd: "*",
anchorStart: "head1",
name: "foo",
type: "file",
});
});
});

describe("link2String", () => {
test("file", () => {
expect(refLink2String({
name: "foo",
type: "file",
})).toEqual("[[foo]]")
});

it("one anchor", () => {
expect(refLink2String({
name: "foo",
anchorStart: "head1",
type: "file",
})).toEqual("[[foo]]#head1");
});

it("all parts", () => {
expect(refLink2String({
anchorEnd: "head2",
anchorStart: "head1",
name: "foo",
type: "file",
})).toEqual("[[foo]]#head1:#head2");
});

it("next anchor", () => {
expect(refLink2String({
anchorEnd: "*",
anchorStart: "head1",
name: "foo",
type: "file",
})).toEqual("[[foo]]#head1:#*");
});

})

describe("parseRef", () => {
it("describe file ref without extension", () => {
expect(parseDendronRef("ref: [[foo]]")).toEqual({
Expand Down
27 changes: 27 additions & 0 deletions packages/engine-server/src/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,30 @@ import path from "path";

const markdownIt = _markdownIt();

function normalize(text: string) {
return _.toLower(_.trim(text, ' #'));
}

export function refLink2String(link: DendronRefLink, opts?: {includeParen: boolean}): string {
const cleanOpts = _.defaults(opts, {includeParen: false});
// [[foo]]#head1:#*"
const linkParts = [`[[${link.name}]]`]
if (link.anchorStart) {
linkParts.push(`#${normalize(link.anchorStart)}`)
}
if (link.anchorStartOffset) {
linkParts.push(`,${link.anchorStartOffset}`)
}
if (link.anchorEnd) {
linkParts.push(`:#${normalize(link.anchorEnd)}`)
}
if (cleanOpts.includeParen) {
linkParts.splice(0, 0, "((");
linkParts.push("))");
}
return linkParts.join("");
}

// const testString = "<!--(([[class.mba.chapters.2]]))-->";
function genAST(txt: string): ASTEnt[] {
const tokens: Token[] = markdownIt.parse(txt, {});
Expand All @@ -17,6 +41,9 @@ function genAST(txt: string): ASTEnt[] {
export type DendronRefLink = {
label?: string;
id?: string;
/**
* Name of file
*/
name?: string;
anchorStart?: string;
anchorEnd?: string;
Expand Down
29 changes: 27 additions & 2 deletions packages/plugin-core/src/commands/CopyNoteRef.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
import { DNodeUtils } from "@dendronhq/common-all";
import clipboardy from "@dendronhq/clipboardy";
import _ from "lodash";
import { TextEditor, window } from "vscode";
import { TextEditor, window, Selection } from "vscode";
import { VSCodeUtils } from "../utils";
import { DendronWorkspace } from "../workspace";
import { BasicCommand } from "./base";
import { DendronRefLink, refLink2String } from "@dendronhq/engine-server";

type CommandOpts = {};
type CommandOutput = string;
Expand All @@ -24,14 +25,38 @@ export class CopyNoteRefCommand extends BasicCommand<
window.showInformationMessage(`${link} copied`);
}

isHeader(text: string, selection: Selection) {
return text.startsWith("#") && (selection.start.line === selection.end.line)
}

async buildLink(opts: {fname: string}) {
const {fname} = opts;
const link: DendronRefLink = {
type: "file",
name: fname,
};
const { text, selection } = VSCodeUtils.getSelection();
let refLinkString: string = refLink2String(link);
if (!_.isEmpty(text)) {
if (this.isHeader(text, selection)) {
const headerText = _.trim(text)
link.anchorStart = headerText;
link.anchorEnd = "*";
link.anchorStartOffset = 1;
refLinkString = refLink2String(link);
}
}
return ["((", "ref: ", refLinkString, "))"].join("");
}

async execute(_opts: CommandOpts) {
const editor = VSCodeUtils.getActiveTextEditor() as TextEditor;
const fname = DNodeUtils.uri2Fname(editor.document.uri);
const note = _.find(DendronWorkspace.instance().engine.notes, { fname });
if (!note) {
throw Error(`${fname} not found in engine`);
}
const link = `((ref:[[${fname}]]))`;
const link = await this.buildLink({fname});
try {
clipboardy.writeSync(link);
} catch (err) {
Expand Down
30 changes: 30 additions & 0 deletions packages/plugin-core/src/test/suite-integ/extension.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@ import {
} from "@dendronhq/pods-core";
import { ConfigurePodCommand } from "../../commands/ConfigurePodCommand";
import { ImportPodCommand } from "../../commands/ImportPod";
import { CopyNoteRefCommand } from "../../commands/CopyNoteRef";

type ExportConfig = any;
const expectedSettings = (opts?: { folders?: any; settings?: any }): any => {
Expand Down Expand Up @@ -1020,6 +1021,35 @@ suite("commands", function () {
});
});

describe.only("CopyNoteRefCommand", function () {
test("basic", function (done) {
onWSInit(async () => {
const uri = vscode.Uri.file(path.join(root.name, "vault", "foo.md"));
await vscode.window.showTextDocument(uri);
const link = await new CopyNoteRefCommand().run();
assert.equal(link, "((ref: [[foo]]))");
done();
});
setupDendronWorkspace(root.name, ctx, { useFixtures: true });
});

test("with selection", function (done) {
onWSInit(async () => {
const uri = vscode.Uri.file(path.join(root.name, "vault", "bar.md"));
const editor = await vscode.window.showTextDocument(uri);
editor.selection = new vscode.Selection(8, 0, 8, 12);
const link = await new CopyNoteRefCommand().run();
assert.equal(link, "((ref: [[bar]]#foo,1:#*))");
done();
});
setupDendronWorkspace(root.name, ctx, { useFixtures: false, useCb: async (vault) => {
NodeTestUtils.createNotes(vault, [
{ fname: "bar", body: "## Foo\nfoo text\n## Header\n Header text" },
]);
}});
});
});

describe("GoUp", function () {
test("basic", function (done) {
onWSInit(async () => {
Expand Down

0 comments on commit 6f1906f

Please sign in to comment.