Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
f1bad06
Initial plan
Copilot Oct 23, 2025
ac9c6c2
Fix notes move operation to handle cross-filesystem moves properly
Copilot Oct 23, 2025
4be84b5
Improve code comments and documentation for file move operations
Copilot Oct 23, 2025
6d259bb
Address code review feedback - improve comment clarity
Copilot Oct 23, 2025
d8bbd3f
Fix remaining notes bugs: breadcrumb root navigation and line break p…
Copilot Oct 23, 2025
795fb71
Simplify file operations and improve note navigation
DeJeune Oct 23, 2025
99de3ee
Improve paste behavior to preserve inline text formatting
DeJeune Oct 23, 2025
d5dd8bc
Improve paste behavior in styled blocks and multi-line content
DeJeune Oct 23, 2025
ec16657
Upgrade TipTap to v3.7.2 and add text highlight feature
DeJeune Oct 24, 2025
71f0059
优化 Markdown 配置以支持 HTML,确保保留 <u> 标签用于下划线
DeJeune Oct 25, 2025
ecc7f63
Merge remote-tracking branch 'origin/main' into copilot/fix-notes-bug
DeJeune Oct 28, 2025
b7d8dff
fix(i18n): Auto update translations for PR #10929
actions-user Oct 28, 2025
c2fe216
fix(RichEditor): remove comment about underline default in useRichEditor
DeJeune Oct 28, 2025
ed6bfec
feat(RichEditor): add underline extension to enhance text formatting …
DeJeune Oct 28, 2025
27ccc25
fix(package): add patch for @tiptap/extension-code to improve regex h…
DeJeune Oct 28, 2025
c9b1e61
Upgrade TipTap dependencies and patch table of contents extension
DeJeune Oct 28, 2025
24563b5
Upgrade TipTap dependencies to v3.9.0 and fix task list styling
DeJeune Oct 28, 2025
1067e6f
Improve task list alignment and nesting behavior
DeJeune Oct 28, 2025
252e30a
fix(richtext): adjust task list item margin for better spacing
DeJeune Oct 28, 2025
cd188e1
Add patched TipTap extensions and clean up dependency overrides
DeJeune Oct 28, 2025
a418b61
fix(richtext): update regex patterns for code formatting and add disa…
DeJeune Oct 28, 2025
a66c086
Add markdown parsing and serialization for YAML front matter
DeJeune Oct 28, 2025
54503c0
Add custom markdown tokenizer with logging for YAML front matter
DeJeune Oct 28, 2025
ef7e8a7
Add YAML front matter as atom node without child content
DeJeune Oct 28, 2025
cfb9ee7
Remove verbose logging and simplify YAML front matter handling
DeJeune Oct 28, 2025
9b8e4d1
Add enhanced horizontal rule extension with markdown indentation support
DeJeune Oct 29, 2025
3bd71e4
fix(yaml-front-matter): update start method regex to match exact YAML…
DeJeune Oct 29, 2025
438b167
Merge remote-tracking branch 'origin/v2' into copilot/fix-notes-bug
DeJeune Nov 16, 2025
c97f7b8
chore: version
DeJeune Nov 16, 2025
0de1b02
fix: update regex patterns for code extension and add scroll handling…
DeJeune Dec 20, 2025
a8ded04
merge origin/v2
DeJeune Dec 20, 2025
daf5b7c
feat: add tests for YAML front matter tokenizer and enhance parsing l…
DeJeune Dec 22, 2025
f31a3e9
Merge remote-tracking branch 'origin/v2' into copilot/fix-notes-bug
DeJeune Dec 22, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 29 additions & 0 deletions .yarn/patches/@tiptap-extension-code-npm-3.14.0-b697759ce9.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
diff --git a/dist/index.cjs b/dist/index.cjs
index 650402009637c04dce23b2de9baa48b69601f6e7..e4106894f67ff68b78e4e7485b7beb24570f91c0 100644
--- a/dist/index.cjs
+++ b/dist/index.cjs
@@ -29,8 +29,8 @@ module.exports = __toCommonJS(index_exports);

// src/code.ts
var import_core = require("@tiptap/core");
-var inputRegex = /(^|[^`])`([^`]+)`(?!`)$/;
-var pasteRegex = /(^|[^`])`([^`]+)`(?!`)/g;
+var inputRegex = /(?:^|\s)(`(?!\s+`)((?:[^`]+))`(?!\s+`))$/;
+var pasteRegex = /(?:^|\s)(`(?!\s+`)((?:[^`]+))`(?!\s+`))/g;
var Code = import_core.Mark.create({
name: "code",
addOptions() {
diff --git a/dist/index.js b/dist/index.js
index 7f9e650a5713377d8d6a824f884bbfe6d27fe519..3736cac514b979438a808705931636ae04b06d16 100644
--- a/dist/index.js
+++ b/dist/index.js
@@ -1,7 +1,7 @@
// src/code.ts
import { Mark, markInputRule, markPasteRule, mergeAttributes } from "@tiptap/core";
-var inputRegex = /(^|[^`])`([^`]+)`(?!`)$/;
-var pasteRegex = /(^|[^`])`([^`]+)`(?!`)/g;
+var inputRegex = /(?:^|\s)(`(?!\s+`)((?:[^`]+))`(?!\s+`))$/;
+var pasteRegex = /(?:^|\s)(`(?!\s+`)((?:[^`]+))`(?!\s+`))/g;
var Code = Mark.create({
name: "code",
addOptions() {
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
diff --git a/dist/index.cjs b/dist/index.cjs
index 8e560a4406c5cc616c11bb9fd5455ac0dcf47fa3..c7cd0d65ddc971bff71e89f610de82cfdaa5a8c7 100644
index e96c7203f83b753dd950fd23d4ac5051a337ecc6..bc8b4723a16f72715bd1f83b63dfb177edf73318 100644
--- a/dist/index.cjs
+++ b/dist/index.cjs
@@ -413,6 +413,19 @@ var DragHandlePlugin = ({
@@ -468,6 +468,19 @@ var DragHandlePlugin = ({
}
return false;
},
Expand All @@ -23,10 +23,10 @@ index 8e560a4406c5cc616c11bb9fd5455ac0dcf47fa3..c7cd0d65ddc971bff71e89f610de82cf
if (locked) {
return false;
diff --git a/dist/index.js b/dist/index.js
index 39e4c3ef9986cd25544d9d3994cf6a9ada74b145..378d9130abbfdd0e1e4f743b5b537743c9ab07d0 100644
index 309bbba9f2dcdfe1f9cb9e98c1ad9cae6258d253..f66be7dfbf4d5185992445246e43e710d9797260 100644
--- a/dist/index.js
+++ b/dist/index.js
@@ -387,6 +387,19 @@ var DragHandlePlugin = ({
@@ -442,6 +442,19 @@ var DragHandlePlugin = ({
}
return false;
},
Expand Down
40 changes: 23 additions & 17 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -188,22 +188,26 @@
"@testing-library/jest-dom": "^6.6.3",
"@testing-library/react": "^16.3.0",
"@testing-library/user-event": "^14.6.1",
"@tiptap/extension-collaboration": "^3.2.0",
"@tiptap/extension-drag-handle": "patch:@tiptap/extension-drag-handle@npm%3A3.2.0#~/.yarn/patches/@tiptap-extension-drag-handle-npm-3.2.0-5a9ebff7c9.patch",
"@tiptap/extension-drag-handle-react": "^3.2.0",
"@tiptap/extension-image": "^3.2.0",
"@tiptap/extension-list": "^3.2.0",
"@tiptap/extension-mathematics": "^3.2.0",
"@tiptap/extension-mention": "^3.2.0",
"@tiptap/extension-node-range": "^3.2.0",
"@tiptap/extension-table-of-contents": "^3.2.0",
"@tiptap/extension-typography": "^3.2.0",
"@tiptap/extension-underline": "^3.2.0",
"@tiptap/pm": "^3.2.0",
"@tiptap/react": "^3.2.0",
"@tiptap/starter-kit": "^3.2.0",
"@tiptap/suggestion": "^3.2.0",
"@tiptap/y-tiptap": "^3.0.0",
"@tiptap/extension-code": "patch:@tiptap/extension-code@npm%3A3.14.0#~/.yarn/patches/@tiptap-extension-code-npm-3.14.0-b697759ce9.patch",
"@tiptap/extension-code-block": "^3.14.0",
"@tiptap/extension-collaboration": "^3.14.0",
"@tiptap/extension-drag-handle": "patch:@tiptap/extension-drag-handle@npm%3A3.14.0#~/.yarn/patches/@tiptap-extension-drag-handle-npm-3.14.0-e3af57813c.patch",
"@tiptap/extension-drag-handle-react": "^3.14.0",
"@tiptap/extension-image": "^3.14.0",
"@tiptap/extension-link": "^3.14.0",
"@tiptap/extension-list": "^3.14.0",
"@tiptap/extension-mathematics": "^3.14.0",
"@tiptap/extension-mention": "^3.14.0",
"@tiptap/extension-node-range": "^3.14.0",
"@tiptap/extension-table-of-contents": "^3.14.0",
"@tiptap/extension-typography": "^3.14.0",
"@tiptap/extension-underline": "^3.14.0",
"@tiptap/markdown": "^3.14.0",
"@tiptap/pm": "^3.14.0",
"@tiptap/react": "^3.14.0",
"@tiptap/starter-kit": "^3.14.0",
"@tiptap/suggestion": "^3.14.0",
"@tiptap/y-tiptap": "^3.0.1",
"@truto/turndown-plugin-gfm": "^1.0.2",
"@tryfabric/martian": "^1.2.4",
"@types/cli-progress": "^3",
Expand Down Expand Up @@ -326,6 +330,7 @@
"oxlint": "^1.22.0",
"oxlint-tsgolint": "^0.2.0",
"p-queue": "^8.1.0",
"patch-package": "^8.0.1",
"pdf-lib": "^1.17.1",
"pdf-parse": "^1.1.1",
"proxy-agent": "^6.5.0",
Expand Down Expand Up @@ -421,7 +426,8 @@
"@ai-sdk/openai@npm:^2.0.42": "patch:@ai-sdk/openai@npm%3A2.0.85#~/.yarn/patches/@ai-sdk-openai-npm-2.0.85-27483d1d6a.patch",
"@ai-sdk/google@npm:^2.0.40": "patch:@ai-sdk/google@npm%3A2.0.40#~/.yarn/patches/@ai-sdk-google-npm-2.0.40-47e0eeee83.patch",
"@ai-sdk/openai-compatible@npm:^1.0.27": "patch:@ai-sdk/openai-compatible@npm%3A1.0.27#~/.yarn/patches/@ai-sdk-openai-compatible-npm-1.0.27-06f74278cf.patch",
"@ai-sdk/google@npm:2.0.49": "patch:@ai-sdk/google@npm%3A2.0.49#~/.yarn/patches/@ai-sdk-google-npm-2.0.49-84720f41bd.patch"
"@ai-sdk/google@npm:2.0.49": "patch:@ai-sdk/google@npm%3A2.0.49#~/.yarn/patches/@ai-sdk-google-npm-2.0.49-84720f41bd.patch",
"@tiptap/extension-code@npm:^3.14.0": "patch:@tiptap/extension-code@npm%3A3.14.0#~/.yarn/patches/@tiptap-extension-code-npm-3.14.0-b697759ce9.patch"
},
"packageManager": "yarn@4.9.1",
"lint-staged": {
Expand Down
4 changes: 2 additions & 2 deletions packages/extension-table-plus/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -68,8 +68,8 @@
],
"devDependencies": {
"@biomejs/biome": "2.2.4",
"@tiptap/core": "^3.2.0",
"@tiptap/pm": "^3.2.0",
"@tiptap/core": "^3.14.0",
"@tiptap/pm": "^3.14.0",
"eslint": "^9.22.0",
"eslint-plugin-react-hooks": "^5.2.0",
"eslint-plugin-simple-import-sort": "^12.1.1",
Expand Down
6 changes: 2 additions & 4 deletions src/main/services/FileStorage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -397,13 +397,12 @@ class FileStorage {
throw new Error(`Source file does not exist: ${filePath}`)
}

// 确保目标目录存在
// Ensure the destination directory exists
const destDir = path.dirname(newPath)
if (!fs.existsSync(destDir)) {
await fs.promises.mkdir(destDir, { recursive: true })
}

// 移动文件
await fs.promises.rename(filePath, newPath)
logger.debug(`File moved successfully: ${filePath} to ${newPath}`)
} catch (error) {
Expand All @@ -418,13 +417,12 @@ class FileStorage {
throw new Error(`Source directory does not exist: ${dirPath}`)
}

// 确保目标父目录存在
// Ensure the parent directory of the destination exists
const parentDir = path.dirname(newDirPath)
if (!fs.existsSync(parentDir)) {
await fs.promises.mkdir(parentDir, { recursive: true })
}

// 移动目录
await fs.promises.rename(dirPath, newDirPath)
logger.debug(`Directory moved successfully: ${dirPath} to ${newDirPath}`)
} catch (error) {
Expand Down
30 changes: 29 additions & 1 deletion src/renderer/src/assets/styles/richtext.css
Original file line number Diff line number Diff line change
Expand Up @@ -452,6 +452,7 @@
.tiptap ul[data-type='taskList'] li > label {
flex: 0 0 auto;
margin-right: 0.5rem;
margin-top: 0.1rem;
user-select: none;
display: flex;
align-items: center;
Expand All @@ -461,12 +462,39 @@
flex: 1 1 auto;
}

/* For nested task lists, align label with first line of text */
.tiptap ul[data-type='taskList'] li:has(ul[data-type='taskList']) {
align-items: flex-start;
}

.tiptap ul[data-type='taskList'] li:has(ul[data-type='taskList']) > label {
margin-top: 0.4rem;
}

.tiptap ul[data-type='taskList'] li > div p {
margin: 0;
}

/* Checked task item appearance */
.tiptap ul[data-type='taskList'] li[data-checked='true'] > div {
.tiptap ul[data-type='taskList'] li[data-checked='true'] > div > p {
color: var(--color-text-2);
text-decoration: line-through;
}

/* Prevent nested task lists from inheriting checked styles */
.tiptap ul[data-type='taskList'] li[data-checked='true'] > div ul[data-type='taskList'] li > div > p {
color: inherit;
text-decoration: none;
}

.tiptap
ul[data-type='taskList']
li[data-checked='true']
> div
ul[data-type='taskList']
li[data-checked='true']
> div
> p {
color: var(--color-text-2);
text-decoration: line-through;
}
Expand Down
19 changes: 17 additions & 2 deletions src/renderer/src/components/RichEditor/command.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import {
Heading1,
Heading2,
Heading3,
Highlighter,
Image,
Italic,
Link,
Expand Down Expand Up @@ -193,6 +194,20 @@ const DEFAULT_COMMANDS: Command[] = [
toolbarGroup: 'formatting',
formattingCommand: 'strike'
},
{
id: 'highlight',
title: 'Highlight',
description: 'Highlight text',
category: CommandCategory.TEXT,
icon: Highlighter,
keywords: ['highlight', 'marker', 'background'],
handler: (editor: Editor) => {
editor.chain().focus().toggleHighlight().run()
},
showInToolbar: true,
toolbarGroup: 'formatting',
formattingCommand: 'highlight'
},
{
id: 'inlineCode',
title: 'Inline Code',
Expand Down Expand Up @@ -348,11 +363,11 @@ const DEFAULT_COMMANDS: Command[] = [
id: 'link',
title: 'Link',
description: 'Add a link',
category: CommandCategory.SPECIAL,
category: CommandCategory.TEXT,
icon: Link,
keywords: ['link', 'url', 'href'],
handler: (editor: Editor) => {
editor.chain().focus().setEnhancedLink({ href: '' }).run()
editor.chain().focus().setLink({ href: '' }).run()
},
showInToolbar: true,
toolbarGroup: 'media',
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
import type { JSONContent } from '@tiptap/core'
import { MarkdownManager } from '@tiptap/markdown'
import { describe, expect, it } from 'vitest'

import { YamlFrontMatter } from '../yaml-front-matter'

const parseFrontMatters = (markdown: string) => {
const manager = new MarkdownManager({
extensions: [YamlFrontMatter]
})
const doc = manager.parse(markdown) as JSONContent
const frontMatterNodes = (doc.content || []).filter((node) => node.type === 'yamlFrontMatter')
return frontMatterNodes.map((node) => (node.attrs as { content?: string } | undefined)?.content?.trim())
}

describe('YamlFrontMatter markdown tokenizer', () => {
it('only parses the first front matter block at the very start of the document', () => {
const markdown = `---
title: First
---

Body text

---
title: Second
---
More content`

const contents = parseFrontMatters(markdown)
expect(contents).toHaveLength(1)
expect(contents[0]).toBe('title: First')
})

it('ignores a front matter block when it is not at the beginning of the document', () => {
const markdown = `Intro paragraph

---
title: Should not parse
---`

const contents = parseFrontMatters(markdown)
expect(contents).toHaveLength(0)
})

it('ignores consecutive front matter blocks after the first one', () => {
const markdown = `---
first: yes
---
---
second: no
---`

const contents = parseFrontMatters(markdown)
expect(contents).toHaveLength(1)
expect(contents[0]).toBe('first: yes')
})

it('does not treat body content containing --- as additional front matter', () => {
const markdown = `---
title: Only header
---

Paragraph text.

---

More text.`

const contents = parseFrontMatters(markdown)
expect(contents).toHaveLength(1)
expect(contents[0]).toBe('title: Only header')
})

it('treats later front matter markers as regular markdown when content already exists', () => {
const markdown = `Intro paragraph

---
title: Should not parse
---`

const contents = parseFrontMatters(markdown)
expect(contents).toHaveLength(0)
})
})
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ export const CodeBlockShiki = CodeBlock.extend<CodeBlockShikiOptions>({
addOptions() {
return {
...this.parent?.(),
tabSize: 4,
enableTabIndentation: true,
languageClassPrefix: 'language-',
exitOnTripleEnter: true,
exitOnArrowDown: true,
Expand Down Expand Up @@ -58,12 +60,6 @@ export const CodeBlockShiki = CodeBlock.extend<CodeBlockShikiOptions>({

addKeyboardShortcuts() {
return {
Tab: () => {
if (this.editor.isActive(this.name)) {
return this.editor.commands.insertContent(' ')
}
return false
},
'Shift-Tab': () => {
if (this.editor.isActive(this.name)) {
const { selection } = this.editor.state
Expand Down
Loading
Loading