You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在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>

代码说明

  1. 先关闭formatOnPaste,避免和自定义逻辑冲突
  2. 监听onDidPaste事件,拿到粘贴的原始文本和位置信息
  3. 通过getIndentationForPosition获取粘贴目标位置的当前缩进(比如函数内部的4个空格/制表符)
  4. 把粘贴的文本按行拆分,第一行保持原样,后续每一行前面加上目标位置的缩进
  5. 阻止默认粘贴行为,用executeEdits插入处理后的文本

这样处理后,粘贴代码只会自动添加匹配的缩进,不会触发其他格式化操作,也不会出现功能失效的问题,完全符合期望效果:

function f(){
    function g(){

    }
}

内容的提问来源于stack exchange,提问作者Grigory Hatsevich

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.20 15:27:39