如何在Monaco Editor中实现粘贴时仅自动缩进(无额外格式化)
Monaco Editor 实现粘贴代码仅自动缩进并修复功能失效问题
要实现粘贴代码时自动匹配目标位置的缩进(比如把函数粘贴到另一个函数内时,粘贴内容的后续行自动对齐首行缩进),用formatOnPaste: true会带来两个问题:一是会触发额外的代码格式化(比如自动添加空格),二是功能时常失效,只有执行「格式化选中内容」命令后才恢复。
直接放弃formatOnPaste,通过监听粘贴事件手动处理缩进是更可靠的方案,既能只做缩进处理,又能避免失效问题。
修改后的完整代码
<!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content="text/html;charset=utf-8" /> <style> #container{ height: 200px; border:1px solid grey; } </style> </head> <body> <div id="container"></div> <script src="monaco-editor/min/vs/loader.js"></script> <script> require.config({ paths: { vs: 'monaco-editor/min/vs' } }); require(['vs/editor/editor.main'], function () { let monacoEditor = monaco.editor.create(container, { language: 'javascript', value: `function f(){ } function g(){ } `, insertSpaces: false, formatOnPaste: false, // 禁用自带格式化粘贴 }); // 监听粘贴事件处理缩进 monacoEditor.onDidPaste((event) => { // 获取粘贴的文本内容 const pasteText = event.text; if (!pasteText) return; // 获取粘贴起始位置的缩进 const pastePosition = monacoEditor.getPosition(); const indentation = monacoEditor.getIndentationForPosition(pastePosition); if (!indentation) return; // 拆分粘贴文本为行 const lines = pasteText.split('\n'); // 仅给第一行之外的行添加缩进 const indentedLines = [lines[0], ...lines.slice(1).map(line => indentation + line)]; const indentedText = indentedLines.join('\n'); // 取消默认粘贴,替换为处理后的文本 event.preventDefault(); monacoEditor.executeEdits('paste-indent', [ { range: event.range, text: indentedText } ]); }); }); </script> </body> </html>
代码说明
- 先关闭
formatOnPaste,避免和自定义逻辑冲突 - 监听
onDidPaste事件,拿到粘贴的原始文本和位置信息 - 通过
getIndentationForPosition获取粘贴目标位置的当前缩进(比如函数内部的4个空格/制表符) - 把粘贴的文本按行拆分,第一行保持原样,后续每一行前面加上目标位置的缩进
- 阻止默认粘贴行为,用
executeEdits插入处理后的文本
这样处理后,粘贴代码只会自动添加匹配的缩进,不会触发其他格式化操作,也不会出现功能失效的问题,完全符合期望效果:
function f(){ function g(){ } }
内容的提问来源于stack exchange,提问作者Grigory Hatsevich
相关产品推荐
相关产品推荐

