2

这个 SO question涵盖了我遇到的同样的一般问题......除了它的答案不够详细,我无法理解我必须做错什么。

我想让 sql 文件突出显示任何“CREATE PROCEDURE”命令。

sql-extension.tmLanguage我有以下文件调用Packages\User\

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>fileTypes</key>
    <array>
        <string>sql</string>
    </array>
    <key>name</key>
    <string>XYZ</string>
    <key>patterns</key>
    <array>
        <dict>
            <key>captures</key>
            <dict>
                <key>1</key>
                <dict>
                    <key>name</key>
                    <string>keyword.other.create.sql</string>
                </dict>
                <key>2</key>
                <dict>
                    <key>name</key>
                    <string>keyword.other.sql</string>
                </dict>
                <key>5</key>
                <dict>
                    <key>name</key>
                    <string>entity.name.function.sql</string>
                </dict>
            </dict>
            <key>match</key>
            <string>(?i:^\s*(create)\s+(procedure)\s+)(['"`]?)(\w+)\4</string>
            <key>name</key>
            <string>meta.create.sql</string>
        </dict>
        <dict>
            <key>include</key>
            <string>#SQL</string>
        </dict>
    </dict>
    <key>scopeName</key>
    <string>source.sql</string>
    <key>uuid</key>
    <string>158e3bda-c76d-439e-b8ea-cb640f0a911c</string>
</dict>
</plist>

我从ST3 包中的SQL.tmLanguage文件中复制了这些信息。SQL它的内容是这样的:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>fileTypes</key>
    <array>
        <string>sql</string>
        <string>ddl</string>
        <string>dml</string>
    </array>
    <key>foldingStartMarker</key>
    <string>\s*\(\s*$</string>
    <key>foldingStopMarker</key>
    <string>^\s*\)</string>
    <key>keyEquivalent</key>
    <string>^~S</string>
    <key>name</key>
    <string>SQL</string>
    <key>patterns</key>
    <array>
        <dict>
            <key>include</key>
            <string>#comments</string>
        </dict>
        <dict>
            <key>captures</key>
            <dict>
                <key>1</key>
                <dict>
                    <key>name</key>
                    <string>keyword.other.create.sql</string>
                </dict>
                <key>2</key>
                <dict>
                    <key>name</key>
                    <string>keyword.other.sql</string>
                </dict>
                <key>5</key>
                <dict>
                    <key>name</key>
                    <string>entity.name.function.sql</string>
                </dict>
            </dict>
            <key>match</key>
            <string>(?i:^\s*(create)\s+(aggregate|conversion|database|domain|function|group|(unique\s+)?index|language|operator class|operator|rule|schema|sequence|table|tablespace|trigger|type|user|view)\s+)(['"`]?)(\w+)\4</string>
            <key>name</key>
            <string>meta.create.sql</string>
        </dict>
        <dict>
            <key>captures</key>
            <dict>
                <key>1</key>
                <dict>
                    <key>name</key>
                    <string>keyword.other.create.sql</string>
                </dict>
                <key>2</key>
                <dict>
                    <key>name</key>
                    <string>keyword.other.sql</string>
                </dict>
            </dict>
            <key>match</key>
            <string>(?i:^\s*(drop)\s+(aggregate|conversion|database|domain|function|group|index|language|operator class|operator|rule|schema|sequence|table|tablespace|trigger|type|user|view))</string>
            <key>name</key>
            <string>meta.drop.sql</string>
        </dict>
        <dict>
            <key>captures</key>
            <dict>
                <key>1</key>
                <dict>
                    <key>name</key>
                    <string>keyword.other.create.sql</string>
                </dict>
                <key>2</key>
                <dict>
                    <key>name</key>
                    <string>keyword.other.table.sql</string>
                </dict>
                <key>3</key>
                <dict>
                    <key>name</key>
                    <string>entity.name.function.sql</string>
                </dict>
                <key>4</key>
                <dict>
                    <key>name</key>
                    <string>keyword.other.cascade.sql</string>
                </dict>
            </dict>
            <key>match</key>
            <string>(?i:\s*(drop)\s+(table)\s+(\w+)(\s+cascade)?\b)</string>
            <key>name</key>
            <string>meta.drop.sql</string>
        </dict>
        <dict>
            <key>captures</key>
            <dict>
                <key>1</key>
                <dict>
                    <key>name</key>
                    <string>keyword.other.create.sql</string>
                </dict>
                <key>2</key>
                <dict>
                    <key>name</key>
                    <string>keyword.other.table.sql</string>
                </dict>
            </dict>
            <key>match</key>
            <string>(?i:^\s*(alter)\s+(aggregate|conversion|database|domain|function|group|index|language|operator class|operator|rule|schema|sequence|table|tablespace|trigger|type|user|view)\s+)</string>
            <key>name</key>
            <string>meta.alter.sql</string>
        </dict>
        <dict>
            <key>captures</key>
            <dict>
                <key>1</key>
                <dict>
                    <key>name</key>
                    <string>storage.type.sql</string>
                </dict>
                <key>10</key>
                <dict>
                    <key>name</key>
                    <string>constant.numeric.sql</string>
                </dict>
                <key>11</key>
                <dict>
                    <key>name</key>
                    <string>storage.type.sql</string>
                </dict>
                <key>12</key>
                <dict>
                    <key>name</key>
                    <string>storage.type.sql</string>
                </dict>
                <key>13</key>
                <dict>
                    <key>name</key>
                    <string>storage.type.sql</string>
                </dict>
                <key>14</key>
                <dict>
                    <key>name</key>
                    <string>constant.numeric.sql</string>
                </dict>
                <key>15</key>
                <dict>
                    <key>name</key>
                    <string>storage.type.sql</string>
                </dict>
                <key>2</key>
                <dict>
                    <key>name</key>
                    <string>storage.type.sql</string>
                </dict>
                <key>3</key>
                <dict>
                    <key>name</key>
                    <string>constant.numeric.sql</string>
                </dict>
                <key>4</key>
                <dict>
                    <key>name</key>
                    <string>storage.type.sql</string>
                </dict>
                <key>5</key>
                <dict>
                    <key>name</key>
                    <string>constant.numeric.sql</string>
                </dict>
                <key>6</key>
                <dict>
                    <key>name</key>
                    <string>storage.type.sql</string>
                </dict>
                <key>7</key>
                <dict>
                    <key>name</key>
                    <string>constant.numeric.sql</string>
                </dict>
                <key>8</key>
                <dict>
                    <key>name</key>
                    <string>constant.numeric.sql</string>
                </dict>
                <key>9</key>
                <dict>
                    <key>name</key>
                    <string>storage.type.sql</string>
                </dict>
            </dict>
            <key>match</key>
            <string>(?xi)

                # normal stuff, capture 1
                 \b(bigint|bigserial|bit|boolean|box|bytea|cidr|circle|date|double\sprecision|inet|int|integer|line|lseg|macaddr|money|oid|path|point|polygon|real|serial|smallint|sysdate|text)\b

                # numeric suffix, capture 2 + 3i
                |\b(bit\svarying|character\s(?:varying)?|tinyint|var\schar|float|interval)\((\d+)\)

                # optional numeric suffix, capture 4 + 5i
                |\b(char|number|varchar\d?)\b(?:\((\d+)\))?

                # special case, capture 6 + 7i + 8i
                |\b(numeric)\b(?:\((\d+),(\d+)\))?

                # special case, captures 9, 10i, 11
                |\b(times)(?:\((\d+)\))(\swithoutstimeszone\b)?

                # special case, captures 12, 13, 14i, 15
                |\b(timestamp)(?:(s)\((\d+)\)(\swithoutstimeszone\b)?)?

            </string>
        </dict>
        <dict>
            <key>match</key>
            <string>(?i:\b((?:primary|foreign)\s+key|references|on\sdelete(\s+cascade)?|check|constraint)\b)</string>
            <key>name</key>
            <string>storage.modifier.sql</string>
        </dict>
        <dict>
            <key>match</key>
            <string>\b\d+\b</string>
            <key>name</key>
            <string>constant.numeric.sql</string>
        </dict>
        <dict>
            <key>match</key>
            <string>(?i:\b(select(\s+distinct)?|insert\s+(ignore\s+)?into|update|delete|from|set|where|group\sby|or|like|and|union(\s+all)?|having|order\sby|limit|(inner|cross)\s+join|straight_join|(left|right)(\s+outer)?\s+join|natural(\s+(left|right)(\s+outer)?)?\s+join)\b)</string>
            <key>name</key>
            <string>keyword.other.DML.sql</string>
        </dict>
        <dict>
            <key>match</key>
            <string>(?i:\b(on|((is\s+)?not\s+)?null)\b)</string>
            <key>name</key>
            <string>keyword.other.DDL.create.II.sql</string>
        </dict>
        <dict>
            <key>match</key>
            <string>(?i:\bvalues\b)</string>
            <key>name</key>
            <string>keyword.other.DML.II.sql</string>
        </dict>
        <dict>
            <key>match</key>
            <string>(?i:\b(begin(\s+work)?|start\s+transaction|commit(\s+work)?|rollback(\s+work)?)\b)</string>
            <key>name</key>
            <string>keyword.other.LUW.sql</string>
        </dict>
        <dict>
            <key>match</key>
            <string>(?i:\b(grant(\swith\sgrant\soption)?|revoke)\b)</string>
            <key>name</key>
            <string>keyword.other.authorization.sql</string>
        </dict>
        <dict>
            <key>match</key>
            <string>(?i:\bin\b)</string>
            <key>name</key>
            <string>keyword.other.data-integrity.sql</string>
        </dict>
        <dict>
            <key>match</key>
            <string>(?i:^\s*(comment\s+on\s+(table|column|aggregate|constraint|database|domain|function|index|operator|rule|schema|sequence|trigger|type|view))\s+.*?\s+(is)\s+)</string>
            <key>name</key>
            <string>keyword.other.object-comments.sql</string>
        </dict>
        <dict>
            <key>match</key>
            <string>(?i)\bAS\b</string>
            <key>name</key>
            <string>keyword.other.alias.sql</string>
        </dict>
        <dict>
            <key>match</key>
            <string>(?i)\b(DESC|ASC)\b</string>
            <key>name</key>
            <string>keyword.other.order.sql</string>
        </dict>
        <dict>
            <key>match</key>
            <string>\*</string>
            <key>name</key>
            <string>keyword.operator.star.sql</string>
        </dict>
        <dict>
            <key>match</key>
            <string>[!&lt;&gt;]?=|&lt;&gt;|&lt;|&gt;</string>
            <key>name</key>
            <string>keyword.operator.comparison.sql</string>
        </dict>
        <dict>
            <key>match</key>
            <string>-|\+|/</string>
            <key>name</key>
            <string>keyword.operator.math.sql</string>
        </dict>
        <dict>
            <key>match</key>
            <string>\|\|</string>
            <key>name</key>
            <string>keyword.operator.concatenator.sql</string>
        </dict>
        <dict>
            <key>comment</key>
            <string>List of SQL99 built-in functions from http://www.oreilly.com/catalog/sqlnut/chapter/ch04.html</string>
            <key>match</key>
            <string>(?i)\b(CURRENT_(DATE|TIME(STAMP)?|USER)|(SESSION|SYSTEM)_USER)\b</string>
            <key>name</key>
            <string>support.function.scalar.sql</string>
        </dict>
        <dict>
            <key>comment</key>
            <string>List of SQL99 built-in functions from http://www.oreilly.com/catalog/sqlnut/chapter/ch04.html</string>
            <key>match</key>
            <string>(?i)\b(AVG|COUNT|MIN|MAX|SUM)(?=\s*\()</string>
            <key>name</key>
            <string>support.function.aggregate.sql</string>
        </dict>
        <dict>
            <key>match</key>
            <string>(?i)\b(CONCATENATE|CONVERT|LOWER|SUBSTRING|TRANSLATE|TRIM|UPPER)\b</string>
            <key>name</key>
            <string>support.function.string.sql</string>
        </dict>
        <dict>
            <key>captures</key>
            <dict>
                <key>1</key>
                <dict>
                    <key>name</key>
                    <string>constant.other.database-name.sql</string>
                </dict>
                <key>2</key>
                <dict>
                    <key>name</key>
                    <string>constant.other.table-name.sql</string>
                </dict>
            </dict>
            <key>match</key>
            <string>\b(\w+?)\.(\w+)\b</string>
            <!-- <string>(\w+?)\.(\w+)</string> -->
        </dict>
        <dict>
            <key>include</key>
            <string>#strings</string>
        </dict>
        <dict>
            <key>include</key>
            <string>#regexps</string>
        </dict>
    </array>
    <key>repository</key>
    <dict>
        <key>comments</key>
        <dict>
            <key>patterns</key>
            <array>
                <dict>
                    <key>captures</key>
                    <dict>
                        <key>1</key>
                        <dict>
                            <key>name</key>
                            <string>punctuation.definition.comment.sql</string>
                        </dict>
                    </dict>
                    <key>match</key>
                    <string>(--).*$\n?</string>
                    <key>name</key>
                    <string>comment.line.double-dash.sql</string>
                </dict>
                <dict>
                    <key>captures</key>
                    <dict>
                        <key>1</key>
                        <dict>
                            <key>name</key>
                            <string>punctuation.definition.comment.sql</string>
                        </dict>
                    </dict>
                    <key>match</key>
                    <string>(#).*$\n?</string>
                    <key>name</key>
                    <string>comment.line.number-sign.sql</string>
                </dict>
                <dict>
                    <key>begin</key>
                    <string>/\*</string>
                    <key>captures</key>
                    <dict>
                        <key>0</key>
                        <dict>
                            <key>name</key>
                            <string>punctuation.definition.comment.sql</string>
                        </dict>
                    </dict>
                    <key>end</key>
                    <string>\*/</string>
                    <key>name</key>
                    <string>comment.block.c</string>
                </dict>
            </array>
        </dict>
        <key>regexps</key>
        <dict>
            <key>patterns</key>
            <array>
                <dict>
                    <key>begin</key>
                    <string>/(?=\S.*/)</string>
                    <key>beginCaptures</key>
                    <dict>
                        <key>0</key>
                        <dict>
                            <key>name</key>
                            <string>punctuation.definition.string.begin.sql</string>
                        </dict>
                    </dict>
                    <key>end</key>
                    <string>/</string>
                    <key>endCaptures</key>
                    <dict>
                        <key>0</key>
                        <dict>
                            <key>name</key>
                            <string>punctuation.definition.string.end.sql</string>
                        </dict>
                    </dict>
                    <key>name</key>
                    <string>string.regexp.sql</string>
                    <key>patterns</key>
                    <array>
                        <dict>
                            <key>include</key>
                            <string>#string_interpolation</string>
                        </dict>
                        <dict>
                            <key>match</key>
                            <string>\\/</string>
                            <key>name</key>
                            <string>constant.character.escape.slash.sql</string>
                        </dict>
                    </array>
                </dict>
                <dict>
                    <key>begin</key>
                    <string>%r\{</string>
                    <key>beginCaptures</key>
                    <dict>
                        <key>0</key>
                        <dict>
                            <key>name</key>
                            <string>punctuation.definition.string.begin.sql</string>
                        </dict>
                    </dict>
                    <key>comment</key>
                    <string>We should probably handle nested bracket pairs!?! -- Allan</string>
                    <key>end</key>
                    <string>\}</string>
                    <key>endCaptures</key>
                    <dict>
                        <key>0</key>
                        <dict>
                            <key>name</key>
                            <string>punctuation.definition.string.end.sql</string>
                        </dict>
                    </dict>
                    <key>name</key>
                    <string>string.regexp.modr.sql</string>
                    <key>patterns</key>
                    <array>
                        <dict>
                            <key>include</key>
                            <string>#string_interpolation</string>
                        </dict>
                    </array>
                </dict>
            </array>
        </dict>
        <key>string_escape</key>
        <dict>
            <key>match</key>
            <string>\\.</string>
            <key>name</key>
            <string>constant.character.escape.sql</string>
        </dict>
        <key>string_interpolation</key>
        <dict>
            <key>captures</key>
            <dict>
                <key>1</key>
                <dict>
                    <key>name</key>
                    <string>punctuation.definition.string.end.sql</string>
                </dict>
            </dict>
            <key>match</key>
            <string>(#\{)([^\}]*)(\})</string>
            <key>name</key>
            <string>string.interpolated.sql</string>
        </dict>
        <key>strings</key>
        <dict>
            <key>patterns</key>
            <array>
                <dict>
                    <key>captures</key>
                    <dict>
                        <key>1</key>
                        <dict>
                            <key>name</key>
                            <string>punctuation.definition.string.begin.sql</string>
                        </dict>
                        <key>3</key>
                        <dict>
                            <key>name</key>
                            <string>punctuation.definition.string.end.sql</string>
                        </dict>
                    </dict>
                    <key>comment</key>
                    <string>this is faster than the next begin/end rule since sub-pattern will match till end-of-line and SQL files tend to have very long lines.</string>
                    <key>match</key>
                    <string>(')[^'\\]*(')</string>
                    <key>name</key>
                    <string>string.quoted.single.sql</string>
                </dict>
                <dict>
                    <key>begin</key>
                    <string>'</string>
                    <key>beginCaptures</key>
                    <dict>
                        <key>0</key>
                        <dict>
                            <key>name</key>
                            <string>punctuation.definition.string.begin.sql</string>
                        </dict>
                    </dict>
                    <key>end</key>
                    <string>'</string>
                    <key>endCaptures</key>
                    <dict>
                        <key>0</key>
                        <dict>
                            <key>name</key>
                            <string>punctuation.definition.string.end.sql</string>
                        </dict>
                    </dict>
                    <key>name</key>
                    <string>string.quoted.single.sql</string>
                    <key>patterns</key>
                    <array>
                        <dict>
                            <key>include</key>
                            <string>#string_escape</string>
                        </dict>
                    </array>
                </dict>
                <dict>
                    <key>captures</key>
                    <dict>
                        <key>1</key>
                        <dict>
                            <key>name</key>
                            <string>punctuation.definition.string.begin.sql</string>
                        </dict>
                        <key>3</key>
                        <dict>
                            <key>name</key>
                            <string>punctuation.definition.string.end.sql</string>
                        </dict>
                    </dict>
                    <key>comment</key>
                    <string>this is faster than the next begin/end rule since sub-pattern will match till end-of-line and SQL files tend to have very long lines.</string>
                    <key>match</key>
                    <string>(`)[^`\\]*(`)</string>
                    <key>name</key>
                    <string>string.quoted.other.backtick.sql</string>
                </dict>
                <dict>
                    <key>begin</key>
                    <string>`</string>
                    <key>beginCaptures</key>
                    <dict>
                        <key>0</key>
                        <dict>
                            <key>name</key>
                            <string>punctuation.definition.string.begin.sql</string>
                        </dict>
                    </dict>
                    <key>end</key>
                    <string>`</string>
                    <key>endCaptures</key>
                    <dict>
                        <key>0</key>
                        <dict>
                            <key>name</key>
                            <string>punctuation.definition.string.end.sql</string>
                        </dict>
                    </dict>
                    <key>name</key>
                    <string>string.quoted.other.backtick.sql</string>
                    <key>patterns</key>
                    <array>
                        <dict>
                            <key>include</key>
                            <string>#string_escape</string>
                        </dict>
                    </array>
                </dict>
                <dict>
                    <key>captures</key>
                    <dict>
                        <key>1</key>
                        <dict>
                            <key>name</key>
                            <string>punctuation.definition.string.begin.sql</string>
                        </dict>
                        <key>3</key>
                        <dict>
                            <key>name</key>
                            <string>punctuation.definition.string.end.sql</string>
                        </dict>
                    </dict>
                    <key>comment</key>
                    <string>this is faster than the next begin/end rule since sub-pattern will match till end-of-line and SQL files tend to have very long lines.</string>
                    <key>match</key>
                    <string>(")[^"#]*(")</string>
                    <key>name</key>
                    <string>string.quoted.double.sql</string>
                </dict>
                <dict>
                    <key>begin</key>
                    <string>"</string>
                    <key>beginCaptures</key>
                    <dict>
                        <key>0</key>
                        <dict>
                            <key>name</key>
                            <string>punctuation.definition.string.begin.sql</string>
                        </dict>
                    </dict>
                    <key>end</key>
                    <string>"</string>
                    <key>endCaptures</key>
                    <dict>
                        <key>0</key>
                        <dict>
                            <key>name</key>
                            <string>punctuation.definition.string.end.sql</string>
                        </dict>
                    </dict>
                    <key>name</key>
                    <string>string.quoted.double.sql</string>
                    <key>patterns</key>
                    <array>
                        <dict>
                            <key>include</key>
                            <string>#string_interpolation</string>
                        </dict>
                    </array>
                </dict>
                <dict>
                    <key>begin</key>
                    <string>%\{</string>
                    <key>beginCaptures</key>
                    <dict>
                        <key>0</key>
                        <dict>
                            <key>name</key>
                            <string>punctuation.definition.string.begin.sql</string>
                        </dict>
                    </dict>
                    <key>end</key>
                    <string>\}</string>
                    <key>endCaptures</key>
                    <dict>
                        <key>0</key>
                        <dict>
                            <key>name</key>
                            <string>punctuation.definition.string.end.sql</string>
                        </dict>
                    </dict>
                    <key>name</key>
                    <string>string.other.quoted.brackets.sql</string>
                    <key>patterns</key>
                    <array>
                        <dict>
                            <key>include</key>
                            <string>#string_interpolation</string>
                        </dict>
                    </array>
                </dict>
            </array>
        </dict>
    </dict>
    <key>scopeName</key>
    <string>source.sql</string>
    <key>uuid</key>
    <string>C49120AC-6ECC-11D9-ACC8-000D93589AF6</string>
</dict>
</plist>

我通过在控制台中输入以下内容获得了 uuid:

import uuid
u = uuid.uuid4()

然后将创建的 UUID 复制/粘贴到文件中。

保存文件并查看 sql 文件后,我得到了这个(注意“CREATE PROCEDURE”这个词没有突出显示):

在此处输入图像描述

那么我做错了什么?


额外说明:

AAAPackageDev 包似乎在 ST3 中不起作用。所有的菜单选项都是灰色的。

4

1 回答 1

3

对于以下内容,我猜您使用的是 Windows,但如果您不让我知道(或自己查找命令)。首先,为了演示,将光标放在TABLE. 然后按ctrl+alt+shift+p。在状态栏中,您会注意到出现了一些文本(类似于source.sql meta.create.sql keyword.other.sql)。这是应用于该词的范围。范围与您的 tmTheme 文件一起定义它的颜色。现在将光标放在上面PROCEDURE并重复。您应该会看到与之前看到的范围类似的内容。如果不是,则您的正则表达式可能有问题。

ignored_packages哦,如果您还没有,我也会将 SQL 添加到您的设置中。这将确保正在使用您的语法文件,而不是内置的。您可能还想复制该包的内容,因为它们可能提供一些额外的功能。


AAAPackageDev 与 ST3 不兼容。ST3 使用 Python3,而 ST2 使用 Python2。所以我不会盲目地期望插件与两者兼容。无论如何,我会尝试提供一些关于语法高亮的指导(虽然我不是专家)。值得检查的第一件事是您的正则表达式是否正确。也就是说,您需要确保将正确的范围应用于CREATE PROCEDURE.

如果您喜欢使用 JSON 而不是 XML,请查看PlistJsonConverter。它与 ST3 兼容,但您需要使用它的 ST3 分支。


编辑 让我相信你的正则表达式有问题。你有什么理由不改变

<string>(?i:^\s*(create)\s+(aggregate|conversion|database|domain|function|group|(unique\s+)?index|language|operator class|operator|rule|schema|sequence|table|tablespace|trigger|type|user|view)\s+)(['"`]?)(\w+)\4</string>

<string>(?i:^\s*(create)\s+(aggregate|conversion|database|domain|function|group|(unique\s+)?index|language|operator class|operator|rule|schema|sequence|table|tablespace|trigger|type|user|view)\s+)(['"`]?)(\w+)\4</string>

我只是添加procedure到现有的正则表达式模式。

于 2013-08-09T02:06:11.040 回答