Skip to content

Commit

Permalink
feat: ✨ add codeblock for ext
Browse files Browse the repository at this point in the history
  • Loading branch information
isboyjc committed Dec 7, 2024
1 parent b8da4d9 commit 00ecccc
Show file tree
Hide file tree
Showing 13 changed files with 197 additions and 4 deletions.
2 changes: 2 additions & 0 deletions packages/core/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
"@tiptap/extension-bullet-list": "^2.9.1",
"@tiptap/extension-character-count": "^2.9.1",
"@tiptap/extension-code": "^2.9.1",
"@tiptap/extension-code-block": "^2.10.3",
"@tiptap/extension-document": "^2.9.1",
"@tiptap/extension-dropcursor": "^2.9.1",
"@tiptap/extension-gapcursor": "^2.9.1",
Expand All @@ -38,6 +39,7 @@
"@tiptap/suggestion": "^2.9.1",
"i18next": "^23.16.5",
"lodash": "^4.17.21",
"shiki": "^1.24.0",
"uuid": "^11.0.2"
},
"files": [
Expand Down
142 changes: 142 additions & 0 deletions packages/core/src/extensions/code-block.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,142 @@
import CodeBlock from "@tiptap/extension-code-block";

export default CodeBlock.extend({
name: "codeBlock",

addOptions() {
return {
...this.parent?.(),
languageClassPrefix: "language-",
exitOnTripleEnter: true,
exitOnArrowDown: true,
defaultLanguage: null,
tabSize: 2, // 默认缩进2个空格
useTab: false, // 默认使用空格而不是制表符
nodeView: undefined,
HTMLAttributes: {},
slash: true,
name: "codeBlock",
desc: "```javascript",
command: ({ editor, range }) => {
range
? editor.chain().focus().deleteRange(range).toggleCodeBlock().run()
: editor.commands.toggleCodeBlock();
},
isActive: ({ editor }) => editor.isActive("codeBlock"),
isDisabled: ({ editor }) => !editor.can().toggleCodeBlock(),
shortcutkeys: "Mod-Shift-C",
};
},

addNodeView() {
// 如果提供了自定义的 nodeView 函数,使用它
if (typeof this.options.nodeView === "function") {
return this.options.nodeView;
}

return () => undefined;
},

addKeyboardShortcuts() {
return {
Tab: ({ editor }) => {
// 只在代码块内处理
if (!editor.isActive(this.name)) {
return false;
}

const { selection } = editor.state;
const { $from, $to } = selection;

// 获取缩进字符
const indentChar = this.options.useTab ? "\t" : " ";
const indentSize = this.options.useTab ? 1 : this.options.tabSize;
const indent = indentChar.repeat(indentSize);

// 如果有选中文本,对选中的每一行进行缩进
if (!selection.empty) {
const lines = editor.state.doc
.textBetween($from.pos, $to.pos)
.split("\n");
const indentedText = lines.map((line) => indent + line).join("\n");

editor
.chain()
.focus()
.deleteSelection()
.insertContent(indentedText)
.run();

return true;
}

// 如果没有选中文本,直接插入缩进
editor.chain().focus().insertContent(indent).run();

return true;
},
// 支持 Shift-Tab 反向缩进
"Shift-Tab": ({ editor }) => {
if (!editor.isActive(this.name)) {
return false;
}

const { selection } = editor.state;
const { $from, $to } = selection;

// 获取缩进字符
const indentChar = this.options.useTab ? "\t" : " ";
const indentSize = this.options.useTab ? 1 : this.options.tabSize;

// 如果有选中文本,对选中的每一行进行反向缩进
if (!selection.empty) {
const lines = editor.state.doc
.textBetween($from.pos, $to.pos)
.split("\n");
const unindentedText = lines
.map((line) => {
// 移除行首的缩进字符
if (this.options.useTab) {
return line.replace(/^\t/, "");
}
return line.replace(new RegExp(`^ {1,${indentSize}}`), "");
})
.join("\n");

editor
.chain()
.focus()
.deleteSelection()
.insertContent(unindentedText)
.run();

return true;
}

// 如果没有选中文本,尝试移除当前行的缩进
const line = editor.state.doc.textBetween(
$from.before(),
$from.after(),
);

const pos = $from.pos - $from.parentOffset;
const currentIndent = line.match(/^[\t ]*/)?.[0];

if (currentIndent) {
const newIndent = this.options.useTab
? currentIndent.replace(/^\t/, "")
: currentIndent.replace(new RegExp(` {1,${indentSize}}$`), "");

editor
.chain()
.focus()
.deleteRange({ from: pos, to: pos + currentIndent.length })
.insertContent(newIndent)
.run();
}

return true;
},
};
},
});
1 change: 1 addition & 0 deletions packages/core/src/extensions/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -41,3 +41,4 @@ export { default as TaskList } from "./task-list.js";
export { default as Blockquote } from "./blockquote.js";
export { default as Divider } from "./divider.js";
export { default as HardBreak } from "./hard-break.js";
export { default as CodeBlock } from "./code-block.js";
5 changes: 5 additions & 0 deletions packages/core/src/kit/notion-kit.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import {
Link,
Background,
TextStyle,
CodeBlock,
} from "@/extensions";

export default BasicKit.extend({
Expand Down Expand Up @@ -139,6 +140,10 @@ export default BasicKit.extend({
extensions.push(Background.configure(this.options?.background));
}

if (this.options.codeBlock !== false) {
extensions.push(CodeBlock.configure(this.options?.codeBlock));
}

return extensions;
},
});
1 change: 1 addition & 0 deletions packages/core/src/locales/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
"bulletList": "Bullet List",
"orderedList": "Ordered List",
"taskList": "Task List",
"codeBlock": "Code Block",
"divider": "Divider",
"indent": "Increase Indent",
"outdent": "Decrease Indent",
Expand Down
1 change: 1 addition & 0 deletions packages/core/src/locales/zh.json
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
"bulletList": "无序列表",
"orderedList": "有序列表",
"taskList": "任务列表",
"codeBlock": "代码块",
"divider": "分割线",
"indent": "增加缩进",
"outdent": "减少缩进",
Expand Down
2 changes: 1 addition & 1 deletion packages/vue3/src/components/bubble-menu/bubble-menu.js
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,7 @@ export default defineComponent({
// console.log(selection.node)
// return !!node.attrs?.src
// }
if (editor.isActive("codeblock") || isNodeSelection(selection)) {
if (editor.isActive("codeBlock") || isNodeSelection(selection)) {
return false;
}

Expand Down
1 change: 1 addition & 0 deletions packages/vue3/src/components/toolbar-menu/toolbar-menu.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ const TOOLBAR_MENU_SORT = [
"background",
"textAlign",
"link",
"codeBlock",
"|",
"bulletList",
"orderedList",
Expand Down
21 changes: 21 additions & 0 deletions packages/vue3/src/styles/code-block.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
@use "config" as *;

.#{$prefix}.ProseMirror {
pre {
white-space: pre-wrap;
color: var(--isle-editor-text-color-secondary);
background-color: rgba(var(--isle-editor-border-color-val), 0.2);
border-radius: 0.4rem;
border: 1px solid rgba(var(--isle-editor-border-color-val), 0.5);
font-weight: 500;
font-family: "JetBrainsMono", monospace;
padding: 1.25rem;

code {
background: none;
color: inherit;
font-size: 0.8rem;
padding: 0;
}
}
}
5 changes: 2 additions & 3 deletions packages/vue3/src/styles/code.scss
Original file line number Diff line number Diff line change
@@ -1,14 +1,13 @@
@use "config" as *;

.#{$prefix}.ProseMirror {
code,
.#{$prefix}__code {
code.#{$prefix}__code {
padding: 0.2em 0.4em;
line-height: normal;
font-size: 90%;
border-radius: 0.25rem;
background-color: rgba(var(--#{$prefix}-border-color-val), 0.55);
color: var(--#{$prefix}-text-color);
color: var(--#{$prefix}-color-red);
box-decoration-break: clone;
}
}
1 change: 1 addition & 0 deletions packages/vue3/src/styles/index.scss
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
@use "code";
@use "link";
@use "selection";
@use "code-block";

@use "menu";
@use "ui";
2 changes: 2 additions & 0 deletions packages/vue3/src/utils/icon.js
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ import {
Outdent,
WrapText as HardBreak,
ChevronDown as Down,
CodeXml as CodeBlock,
} from "lucide-vue-next";
const ICONS = {
Bold,
Expand Down Expand Up @@ -81,6 +82,7 @@ const ICONS = {
Outdent,
HardBreak,
Down,
CodeBlock,
};

export const getIcon = (name) => {
Expand Down
17 changes: 17 additions & 0 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit 00ecccc

Please sign in to comment.