Skip to content

Commit

Permalink
Merge pull request #9 from mattmundell/rest-of-line
Browse files Browse the repository at this point in the history
Also continue when there's text after the cursor
  • Loading branch information
tmcw authored Jan 9, 2025
2 parents 2932c5a + 0e16e70 commit ea37a90
Show file tree
Hide file tree
Showing 2 changed files with 114 additions and 46 deletions.
108 changes: 92 additions & 16 deletions src/index.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,36 +31,68 @@ function insert(text: string, pos: number, char = " ") {
else if (char === "/") maybeCloseBlockComment({ state, dispatch: dispatch });
else throw new Error("char must be ' ' or '/'");

let doc: Text;
if (tr) doc = (tr as Transaction).state.doc;
else doc = state.doc;
if (tr)
state = (tr as Transaction).state

return doc?.toString();
return [ state.doc?.toString(), state.selection.main.head ];
}

test("/*", () => {
const doc = "/* abc";
const end = "/* abc\n * ";
expect(insert(doc, doc.length)).toEqual(end);
expect(insert(doc, doc.length)).toEqual([ end, end.length ]);
});

test("/**", () => {
const doc = "/** abc";
const end = "/** abc\n * ";
expect(insert(doc, doc.length)).toEqual(end);
expect(insert(doc, doc.length)).toEqual([ end, end.length ]);
});

test("midway", () => {
const doc = "/** abc";
expect(insert(doc, doc.length - 2)).toEqual(doc);
const doc = `
/** abc`;
const end = `
/** a
* bc`;
expect(insert(doc, doc.length - 2)).toEqual([ end, end.length - 2 ]);
});

test("midway with trim", () => {
const doc = `
/** abc `;
const end = `
/** a
* bc`;
expect(insert(doc, doc.length - 5)).toEqual([ end, end.length - 2 ]);
});

test("midway on second line", () => {
const doc = `
/* @brief Add one.
* This is a longish sentence that will be split in two.`;
const end = `
/* @brief Add one.
* This is a longish sentence that will be split
* in two.`;
expect(insert(doc, doc.length - ' in two.'.length)).toEqual([ end, end.length - 'in two.'.length ]);
});

test("midway with text before", () => {
const doc = `
let a = 1; /** abc`;
const end = `
let a = 1; /** a
* bc`;
expect(insert(doc, doc.length - 2)).toEqual([ end, end.length - 2 ]);
});

test("after code", () => {
const doc = `
let a = 1; /** abc`;
const end = `${doc}
* `;
expect(insert(doc, doc.length)).toEqual(end);
expect(insert(doc, doc.length)).toEqual([ end, end.length ]);
});

test("indented", () => {
Expand All @@ -81,7 +113,28 @@ function increment(num: number) {
}
/** Continue`;

expect(insert(doc, 64)).toEqual(end);
expect(insert(doc, 64)).toEqual([ end, 70 ]);
});

test("indented midway", () => {
const doc = `
/** Comment */
function increment(num: number) {
/** indented with four words
return num + 1;
}
/** Continue`;

const end = `
/** Comment */
function increment(num: number) {
/** indented
* with four words
return num + 1;
}
/** Continue`;

expect(insert(doc, 64)).toEqual([ end, 70 ]);
});

test("earlier close missing", () => {
Expand All @@ -93,31 +146,54 @@ let a /* forgot to close this...
const end = `${doc}
* `;

expect(insert(doc, doc.length)).toEqual(end);
expect(insert(doc, doc.length)).toEqual([ end, end.length ]);
});

test("ends on line", () => {
const doc = "/** abc */";
expect(insert(doc, doc.length - 3)).toEqual(doc);
const doc = `
/** abc */`;
const end = `
/** abc
* */`;
expect(insert(doc, doc.length - 3)).toEqual([ end, end.length - 2 ]);
});

test("ends on line with strip", () => {
const doc = `
/** before after */ `;
const end = `
/** before
* after */`; // note only end spaces gone
expect(insert(doc, 11)).toEqual([ end, 15 ]);
});

test("at end of comment", () => {
const doc = '/** abc */';
expect(insert(doc, doc.length)).toEqual([ doc, doc.length ]);
});

test("at end slash", () => {
const doc = '/** abc */';
expect(insert(doc, doc.length - 1)).toEqual([ doc, doc.length - 1 ]);
});

test("previous comment ends on line", () => {
const doc = `
/*export*/ function f() { /* description `;
const end = `${doc}
* `;
expect(insert(doc, doc.length)).toEqual(end);
expect(insert(doc, doc.length)).toEqual([ end, end.length ]);
});

test("ends on line (/)", () => {
const doc = "/** abc */";
expect(insert(doc, doc.length - 3, "/")).toEqual(doc);
expect(insert(doc, doc.length - 3, "/")).toEqual([ doc, doc.length - 3 ]);
});

test("previous comment ends on line (/)", () => {
const doc = "/*export*/ function f() { /* * ";
// Could do this.
//const end = "/*export*/ function f() { /* */";
const end = "/*export*/ function f() { /* * ";
expect(insert(doc, doc.length, "/")).toEqual(end);
expect(insert(doc, doc.length, "/")).toEqual([ end, end.length ]);
});
52 changes: 22 additions & 30 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,17 @@ interface CommentTokens {
block: Block | null
}

const atCommentToken = (doc: Text, pos: number, node: SyntaxNode) => {
return (
// Either */<HERE> or *<HERE>/.
((pos === node.to) || (pos === (node.to - 1)))
// And there's enough space in the comment for it to be ending.
&& ((node.to - node.from) >= "/**/".length)
// And the comment actually ends.
&& (doc.sliceString(node.to - 2, node.to) === "*/")
);
}

const able = (state: EditorState, range: SelectionRange) => {
if (range.empty) {
const data = state.languageDataAt<CommentTokens>("commentTokens", range.from);
Expand All @@ -32,18 +43,7 @@ const able = (state: EditorState, range: SelectionRange) => {
return true;
}
}
return false
}

const endsOnLine = (doc: Text, node: SyntaxNode, line: Line) => {
return (
// The comment node ends on the line
(node.to <= line.to)
// There's enough space in the comment for it to be ending.
&& ((node.to - node.from) >= "/**/".length)
// The comment actually ends.
&& (doc.sliceString(node.to - 2, node.to) === "*/")
)
return false;
}

/**
Expand All @@ -67,37 +67,29 @@ export const insertNewlineContinueComment: StateCommand = ({
const pos = range.from;
const line = doc.lineAt(pos);

const restOfLine = line.text.slice(pos - line.from).trim();

// TODO: we could do something more sophisticated here.
// If we're not at the end of the line,
// do nothing.
if (restOfLine) {
return (dont = { range });
}

const node = tree.resolveInner(pos, -1);

if (node.name === "BlockComment") {
// If the comment ends on this line, do not continue.
if (endsOnLine(doc, node, line)) {
// If the cursor is at the */ token, do not continue.
if (atCommentToken(doc, pos, node)) {
return (dont = { range });
}

const startLine = doc.lineAt(node.from)
let offset = node.from - startLine.from
const startLine = doc.lineAt(node.from);
let offset = node.from - startLine.from;
if (offset < 0) {
// Something went wrong.
return (dont = { range });
}
offset++ // Line up with the *.
offset++; // Line up with the *.

let indentStr = " ".repeat(offset)
const insert = `${state.lineBreak}${indentStr}* `;
const restOfLine = line.text.slice(pos - line.from).trim();
let indentStr = " ".repeat(offset);
const insert = `${state.lineBreak}${indentStr}* ${restOfLine}`;

return {
range: EditorSelection.cursor(pos + insert.length),
changes: { from: line.to, insert: insert },
range: EditorSelection.cursor(pos + insert.length - restOfLine.length),
changes: { from: pos, to: line.to, insert: insert },
};
}

Expand Down

0 comments on commit ea37a90

Please sign in to comment.