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

如何调整Vim Groovy缩进脚本以正确识别内置Map?

调整Groovy缩进脚本以支持内置Map格式

我之前也遇到过类似的Groovy缩进脚本处理Map的问题,你的思路方向是对的,但可能没处理好Map和普通数组的区分,以及内部结构的缩进逻辑。下面给你具体的调整方案:

1. 区分Map与普通数组的起始标记

在识别块起始的逻辑(对应你提到的第105行附近),不能简单把所有[都当作块开始,要判断它是否是Map:

// 替换原来仅判断'{'的逻辑
if (currentChar == '{' || isMapStart(currentChar, nextChar)) {
    indentLevel++
    // 记录当前块类型是Map,方便后续处理内部格式
    blockStack.push('MAP')
}

// 新增辅助函数判断是否是Map起始
private boolean isMapStart(char c, char nextC) {
    if (c != '[') return false
    // 空Map直接返回false,不需要缩进
    if (nextC == ']') return false
    // 检查后续是否有冒号(Map的key:value特征)
    def peekPos = currentPos + 1
    while (peekPos < content.length()) {
        def peekC = content[peekPos]
        if (peekC == ':') return true
        if (peekC == ']') return false
        peekPos++
    }
    return false
}

2. 调整缩进层级的增减逻辑(对应第125、132行)

把[和]加入层级调整,但要结合块类型判断:

// 替换原来仅处理'{'和'}'的逻辑
switch (currentChar) {
    case '{':
        blockStack.push('BLOCK')
        indentLevel++
        break
    case '}':
        blockStack.pop()
        indentLevel--
        break
    case '[':
        if (isMapStart(currentChar, nextChar)) {
            blockStack.push('MAP')
            indentLevel++
        } else {
            // 普通数组,不增加层级(或按需调整)
            blockStack.push('ARRAY')
        }
        break
    case ']':
        def lastBlock = blockStack.pop()
        if (lastBlock == 'MAP') {
            indentLevel--
        }
        break
}

3. 处理Map内部的逗号换行

在处理逗号的逻辑中,判断当前是否在Map块内,强制换行并缩进:

// 当遇到逗号且当前在Map块内时
if (currentChar == ',' && blockStack.peek() == 'MAP') {
    output.append(',\n')
    output.append(' ' * indentLevel * indentSize) // 用你脚本中定义的缩进大小
    // 跳过逗号后的空格,避免重复
    while (nextChar == ' ') {
        currentPos++
        nextChar = content[currentPos]
    }
}

4. 处理Map起始行的换行

如果Map内容不在同一行,要在[后换行:

if (currentChar == '[' && blockStack.peek() == 'MAP' && nextChar != ']') {
    output.append('[\n')
    output.append(' ' * indentLevel * indentSize)
    // 跳过[后的空格
    while (nextChar == ' ') {
        currentPos++
        nextChar = content[currentPos]
    }
}

测试效果

修改后,输入:

def map = [key1: 'value1', key2: 'value2']
def nestedMap = [outer: [inner1: 'val1', inner2: 'val2']]
def list = [1, 2, 3]

会输出符合你预期的格式:

def map = [
    key1: 'value1',
    key2: 'value2'
]
def nestedMap = [
    outer: [
        inner1: 'val1',
        inner2: 'val2'
    ]
]
def list = [1, 2, 3]

之前你修改后没生效的原因,是只添加了[和]的层级判断,但没区分Map和数组,也没针对Map内部的key:value结构做换行处理,导致脚本不知道什么时候该对[]内的内容应用缩进。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 04:13:39