@blankdotpage/cake 0.1.61 → 0.1.63

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- {"version":3,"file":"heading.d.ts","sourceRoot":"","sources":["../../../../src/cake/extensions/heading/heading.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,aAAa,EAKnB,MAAM,oBAAoB,CAAC;AA2W5B,eAAO,MAAM,gBAAgB,EAAE,aAwM9B,CAAC"}
1
+ {"version":3,"file":"heading.d.ts","sourceRoot":"","sources":["../../../../src/cake/extensions/heading/heading.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,aAAa,EAKnB,MAAM,oBAAoB,CAAC;AAwa5B,eAAO,MAAM,gBAAgB,EAAE,aAwM9B,CAAC"}
@@ -202,11 +202,13 @@ function handleLineBreakInHeading(state) {
202
202
  }
203
203
  function handleToggleHeading(state, targetLevel) {
204
204
  const { source, selection, map, runtime } = state;
205
- // Get the cursor's source position
206
- const cursorPos = Math.min(selection.start, selection.end);
207
- const sourcePos = map.cursorToSource(cursorPos, selection.affinity ?? "forward");
205
+ const selectionStart = Math.min(selection.start, selection.end);
206
+ const selectionEnd = Math.max(selection.start, selection.end);
207
+ const isCollapsed = selectionStart === selectionEnd;
208
+ // Keep collapsed cursor behavior affinity-aware.
209
+ const primarySourcePos = map.cursorToSource(selectionStart, selection.affinity ?? "forward");
208
210
  // Find line boundaries in source
209
- const lineStart = findLineStartInSource(source, sourcePos);
211
+ const lineStart = findLineStartInSource(source, primarySourcePos);
210
212
  let lineEnd = source.indexOf("\n", lineStart);
211
213
  if (lineEnd === -1) {
212
214
  lineEnd = source.length;
@@ -214,7 +216,7 @@ function handleToggleHeading(state, targetLevel) {
214
216
  const lineContent = source.slice(lineStart, lineEnd);
215
217
  const headingMatch = lineContent.match(HEADING_PATTERN);
216
218
  let newSource;
217
- let newCursorOffset;
219
+ let remapSourceOffset;
218
220
  if (headingMatch) {
219
221
  // Line is already a heading
220
222
  const currentLevel = headingMatch[1].length;
@@ -225,14 +227,15 @@ function handleToggleHeading(state, targetLevel) {
225
227
  source.slice(0, lineStart) +
226
228
  lineContent.slice(existingMarker.length) +
227
229
  source.slice(lineEnd);
228
- // Adjust cursor position - move back by marker length
229
- const cursorLineOffset = sourcePos - lineStart;
230
- if (cursorLineOffset >= existingMarker.length) {
231
- newCursorOffset = sourcePos - existingMarker.length;
232
- }
233
- else {
234
- newCursorOffset = lineStart;
235
- }
230
+ remapSourceOffset = (offset) => {
231
+ if (offset <= lineStart) {
232
+ return offset;
233
+ }
234
+ if (offset >= lineEnd) {
235
+ return offset - existingMarker.length;
236
+ }
237
+ return Math.max(lineStart, offset - existingMarker.length);
238
+ };
236
239
  }
237
240
  else {
238
241
  // Different level - change the heading level
@@ -242,15 +245,20 @@ function handleToggleHeading(state, targetLevel) {
242
245
  newMarker +
243
246
  lineContent.slice(existingMarker.length) +
244
247
  source.slice(lineEnd);
245
- // Adjust cursor position for marker length difference
246
248
  const markerDiff = newMarker.length - existingMarker.length;
247
- const cursorLineOffset = sourcePos - lineStart;
248
- if (cursorLineOffset >= existingMarker.length) {
249
- newCursorOffset = sourcePos + markerDiff;
250
- }
251
- else {
252
- newCursorOffset = lineStart + newMarker.length;
253
- }
249
+ remapSourceOffset = (offset) => {
250
+ if (offset <= lineStart) {
251
+ return offset;
252
+ }
253
+ if (offset >= lineEnd) {
254
+ return offset + markerDiff;
255
+ }
256
+ const offsetInLine = offset - lineStart;
257
+ if (offsetInLine >= existingMarker.length) {
258
+ return offset + markerDiff;
259
+ }
260
+ return lineStart + newMarker.length;
261
+ };
254
262
  }
255
263
  }
256
264
  else {
@@ -265,19 +273,47 @@ function handleToggleHeading(state, targetLevel) {
265
273
  const removedPrefixLength = lineContent.endsWith(lineContentWithoutBlockMarkers)
266
274
  ? lineContent.length - lineContentWithoutBlockMarkers.length
267
275
  : 0;
268
- const cursorLineOffset = sourcePos - lineStart;
269
- const adjustedLineOffset = Math.max(0, cursorLineOffset - Math.min(cursorLineOffset, removedPrefixLength));
270
- newCursorOffset = lineStart + newMarker.length + adjustedLineOffset;
276
+ const markerDiff = newMarker.length - removedPrefixLength;
277
+ remapSourceOffset = (offset) => {
278
+ if (offset <= lineStart) {
279
+ return offset;
280
+ }
281
+ if (offset >= lineEnd) {
282
+ return offset + markerDiff;
283
+ }
284
+ const offsetInLine = offset - lineStart;
285
+ const adjustedLineOffset = Math.max(0, offsetInLine - Math.min(offsetInLine, removedPrefixLength));
286
+ return lineStart + newMarker.length + adjustedLineOffset;
287
+ };
271
288
  }
272
- // Create new state and map cursor through it
289
+ const nextSelectionSource = isCollapsed
290
+ ? {
291
+ start: primarySourcePos,
292
+ end: primarySourcePos,
293
+ }
294
+ : {
295
+ start: map.cursorToSource(selectionStart, "forward"),
296
+ end: map.cursorToSource(selectionEnd, "backward"),
297
+ };
298
+ const mappedSelectionSource = {
299
+ start: remapSourceOffset(nextSelectionSource.start),
300
+ end: remapSourceOffset(nextSelectionSource.end),
301
+ };
302
+ // Create new state and map selection through it.
273
303
  const next = runtime.createState(newSource);
274
- const caretCursor = next.map.sourceToCursor(newCursorOffset, "forward");
304
+ const nextStartCursor = next.map.sourceToCursor(mappedSelectionSource.start, "forward");
305
+ const nextEndCursor = next.map.sourceToCursor(mappedSelectionSource.end, "backward");
306
+ const nextSelectionStart = Math.min(nextStartCursor.cursorOffset, nextEndCursor.cursorOffset);
307
+ const nextSelectionEnd = Math.max(nextStartCursor.cursorOffset, nextEndCursor.cursorOffset);
308
+ const nextAffinity = isCollapsed
309
+ ? nextStartCursor.affinity
310
+ : (selection.affinity ?? "forward");
275
311
  return {
276
312
  source: newSource,
277
313
  selection: {
278
- start: caretCursor.cursorOffset,
279
- end: caretCursor.cursorOffset,
280
- affinity: "forward",
314
+ start: nextSelectionStart,
315
+ end: nextSelectionEnd,
316
+ affinity: nextAffinity,
281
317
  },
282
318
  };
283
319
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@blankdotpage/cake",
3
- "version": "0.1.61",
3
+ "version": "0.1.63",
4
4
  "type": "module",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",