Skip to content

Commit 7fbaf8b

Browse files
CopilotPKief
andauthored
feat: fix bold formatting removal when unchecking checkboxes (#65)
* Initial plan * Fix bold formatting preservation when unchecking checkboxes Co-authored-by: PKief <[email protected]> --------- Co-authored-by: copilot-swe-agent[bot] <[email protected]> Co-authored-by: PKief <[email protected]>
1 parent 1f3dec2 commit 7fbaf8b

File tree

2 files changed

+105
-1
lines changed

2 files changed

+105
-1
lines changed

src/test/spec/checkbox/toggleCheckbox.spec.ts

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,4 +101,60 @@ describe('toggle checkboxes', () => {
101101

102102
assert.strictEqual(content, expectedResult);
103103
});
104+
105+
it('should preserve bold formatting when unchecking', async () => {
106+
// create new document with bold formatting
107+
const newDocument = await vscode.workspace.openTextDocument({
108+
content: '[x] ~~*this is a **bold** action*~~ [2023-12-01]',
109+
language: 'markdown',
110+
});
111+
await vscode.window.showTextDocument(newDocument);
112+
113+
// position cursor on the checkbox line
114+
const editor = getEditor();
115+
const startPosition = new vscode.Position(0, 0);
116+
const endPosition = new vscode.Position(0, 0);
117+
const newSelection = new vscode.Selection(startPosition, endPosition);
118+
editor.selection = newSelection;
119+
120+
await toggleCheckbox();
121+
122+
const content = editor.document.getText();
123+
const expectedResult = '[ ] this is a **bold** action';
124+
125+
assert.strictEqual(content, expectedResult);
126+
});
127+
128+
it('should preserve bold formatting when toggling checkbox', async () => {
129+
// create new document with bold formatting
130+
const newDocument = await vscode.workspace.openTextDocument({
131+
content: '[ ] this is a **bold** action',
132+
language: 'markdown',
133+
});
134+
await vscode.window.showTextDocument(newDocument);
135+
136+
// position cursor on the checkbox line
137+
const editor = getEditor();
138+
const startPosition = new vscode.Position(0, 0);
139+
const endPosition = new vscode.Position(0, 0);
140+
const newSelection = new vscode.Selection(startPosition, endPosition);
141+
editor.selection = newSelection;
142+
143+
// check the checkbox
144+
await toggleCheckbox();
145+
146+
let content = editor.document.getText();
147+
const dateNow = getDateString(new Date());
148+
let expectedResult = `[X] ~~*this is a **bold** action*~~ [${dateNow}]`;
149+
150+
assert.strictEqual(content, expectedResult);
151+
152+
// now uncheck it - this should preserve the bold formatting
153+
await toggleCheckbox();
154+
155+
content = editor.document.getText();
156+
expectedResult = '[ ] this is a **bold** action';
157+
158+
assert.strictEqual(content, expectedResult);
159+
});
104160
});

src/toggleCheckbox.ts

Lines changed: 49 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -123,7 +123,55 @@ const markField = (
123123
newText
124124
);
125125
} else if (lhc && lhc.checked) {
126-
let newText = textWithoutCheckbox.replace(/~~/g, '').replace(/\*/g, '');
126+
let newText = textWithoutCheckbox;
127+
128+
// Remove strikethrough formatting (outermost ~~ pairs) if present
129+
if (strikeThroughWhenChecked && newText.startsWith('~~')) {
130+
// Remove the date first to avoid interfering with strikethrough detection
131+
let tempText = newText;
132+
let datePart = '';
133+
if (dateWhenChecked) {
134+
const dateMatch = tempText.match(/(\s+\[[^[]+?\])$/);
135+
if (dateMatch) {
136+
datePart = dateMatch[1];
137+
tempText = tempText.substring(0, tempText.length - datePart.length);
138+
}
139+
}
140+
141+
// Now remove strikethrough from the main text
142+
if (tempText.startsWith('~~') && tempText.endsWith('~~')) {
143+
tempText = tempText.substring(2, tempText.length - 2);
144+
}
145+
146+
newText = tempText + datePart;
147+
}
148+
149+
// Remove italic formatting (outermost * pairs) if present
150+
if (italicWhenChecked) {
151+
// Remove the date first to avoid interfering with italic detection
152+
let tempText = newText;
153+
let datePart = '';
154+
if (dateWhenChecked) {
155+
const dateMatch = tempText.match(/(\s+\[[^[]+?\])$/);
156+
if (dateMatch) {
157+
datePart = dateMatch[1];
158+
tempText = tempText.substring(0, tempText.length - datePart.length);
159+
}
160+
}
161+
162+
// Now remove italic from the main text only if it wraps the entire content
163+
if (tempText.startsWith('*') && tempText.endsWith('*') && tempText.length > 2) {
164+
// Check if these are the outermost asterisks (not part of **bold**)
165+
const inner = tempText.substring(1, tempText.length - 1);
166+
// Only remove if the inner content doesn't start/end with * (avoiding **bold** cases)
167+
if (!inner.startsWith('*') && !inner.endsWith('*')) {
168+
tempText = inner;
169+
}
170+
}
171+
172+
newText = tempText + datePart;
173+
}
174+
127175
// remove the date string
128176
if (dateWhenChecked) {
129177
newText = newText.replace(/\s+\[[^[]+?\]$/, '') + whitespace;

0 commit comments

Comments
 (0)