❌vscode-scbで優先度問題を回避しつつインデントと引用とコードブロックを実現する1
試行錯誤には限界があったので、ちゃんと勉強し直すことにした
-.icon
しこうさくごのあと
どうやる?
苦戦してもしゃーないので既存事例探す
だけどさ、行頭スペースをハイライトしてる言語なんてあるか?wsta.icon
文字は何でもいいので「行頭の "特定の文字がn個続くパターン" をハイライトしている」とも言える
code:記号一覧
!"#$%&'()-^\@;:,./\=~|`{+*}<>?_ code:つまり
!!!!!!aaa
""""""aaaa
あ、あるわsta.icon*2
code:py
"""
これ
"""
code:json
"docstring-statement": {
"begin": "^(?=\\s*rR?(\\'\\'\\'|\\\"\\\"\\\"|\\'|\\\"))", "comment": "the string either terminates correctly or by the beginning of a new line (this is for single line docstrings that aren't terminated) AND it's not followed by another docstring",
"end": "((?<=\\1)|^)(?!\\s*rR?(\\'\\'\\'|\\\"\\\"\\\"|\\'|\\\"))", "patterns": [
{
"include": "#docstring"
}
]
},
??sta.icon
正規表現読めないw
(?=って何
あー、なんか最小マッチだとかgreedyとかなんとかその辺の挙動変えるのあったよな、あの辺だっけ?
\sはwhitespace
[rR]?はr"……"とか検出するやつだよな
貪欲と怠惰
code:これはデフォルト貪欲なので意図通りにならない.js
let reg = /".+"/g;
let str = 'a "witch" and her "broom" is one';
alert( str.match(reg) ); // "witch" and her "broom"
貪欲なので "witch" and her "broom" の部分が取れちゃう
貪欲(Greedy)モード(デフォルト)では、量指定子は可能な限り繰り返されます。
📝量指定子とは* + ? {1,3}などのこと。何個マッチするかが変化する。 怠惰モード
これを有効にするには量指定子の後に疑問符 '?' を置き
code:怠惰だと期待どおり.js
let reg = /".+?"/g;
let str = 'a "witch" and her "broom" is one';
alert( str.match(reg) ); // witch, broom
戻ってきた
(?=……) こうか?
先読みだsta.icon
あー、何回も調べたことあるわ(全然覚えてねえけど)
先読み
先読みはアンカー
アンカーは位置にマッチするもので、^や$が好例
https://gyazo.com/bfc9c1a25a5922e8f46786f164c750c4
https://gyazo.com/0479f60cb5adda38c461075c4e384ffa
位置にマッチさせた後、その前後を拾うための拾う部分の正規表現をひっつけるsta.icon*2
とりあえず肯定的先読み後読みは理解
は?100行以上あるけど……w
いや、場合分けしてるだけや
code:py
"これと"
'これと'
'''
これと
'''
"""
これな
"""
先読み後読みは特にしてない
ってことは、やはりdocstring-statementだなぁsta.icon
beginとend
code:py
"begin": "^(?=\\s*rR?(\\'\\'\\'|\\\"\\\"\\\"|\\'|\\\"))", "end": "((?<=\\1)|^)(?!\\s*rR?(\\'\\'\\'|\\\"\\\"\\\"|\\'|\\\"))", beginは肯定的先読み
endは肯定的後読み
先後読みの範囲どこだ?
全部囲ってるね?sta.icon
つまり位置のマッチだけしている
マッチしたら"#docstringに飛ばしている
理解した
✅
あー、だめ、わけわかんねーsta.icon
at 2022/06/30 20:44:28
https://gyazo.com/3c1fd1d19f5aebb54d9a821fb84b7a2d
先読み後読みを入れた
indent1
codeblock
quote
引用もblockと同じ感じで実装したんだが、そしたら今度はindent0の引用がハイライトされなくなった
code:これでインデントなしの引用がハイライトされんのなんで?.json
"quote-statement": {
"begin": "^(?<= *)>",
"end": "$",
"patterns": [
{
"include": "#quote"
}
]
},
"quote": {
"begin": ">",
"end": "$",
"beginCaptures": {
"0": { "name": "quote.line.start.scb" }
},
"endCaptures": {
"0": { "name": "quote.line.end.scb" }
},
"name": "quote.line.scb"
},
謎。わからんsta.icon*2
*は0個も含むから入るやろ?
ひょっとして先読み後読みって量指定子の結果が0のときに効果なくなる、とかってある?
できた
後読みに全部入れた
code:json
"quote-statement": {
"begin": "^(?<= *>)",
"end": "$",
"patterns": [
{
"include": "#quote"
}
]
},
まだ理屈正直わかってないねんけど、python拡張機能でもxxx-statementではまず全体を捉えてるので真似したsta.icon
pythonの#コメント参考
code:py
"begin": "(?x)\n (?:\n \\# \\s* (type:)\n \\s*+ (?# we want \\s*+ which is possessive quantifier since\n we do not actually want to backtrack when matching\n whitespace here)\n (?! $ | \\#)\n )\n",
"end": "(?:$|(?=\\#))",
??sta.icon
黒魔術?w
バックトラック(一番強欲なケースでマッチしなかったら他のパターンを試す)しないってやつらしい
$1みたいな対応をすっとばせる
行頭じゃないのに引用される問題
https://gyazo.com/a90cd9b47c71fb0d665ce8a926c32a69
どうもここが全行に及んでしまうようで
https://gyazo.com/5ab79f70f50b6feb1a41e8b8efac461f
なんでや。quote-statementでちゃんと絞っとるやろ
endがあかんのかなぁ?
次行以降の行末を指してる?
貪欲になってる?
大差ないけど
code:json
"quote": {
"begin": ">.+?",
"end": "$",
pythonのcommentsのぱくったけど、効果なし
https://gyazo.com/b4f4f0b85ef12bd6465e923659898786
そもそもこれで何がどうなるかもよーわからん
ダメやなぁ。完璧に把握せんとダメなん?sta.icon
コードもダメだった。それで、あーそうか、pythonのdocstringは途中でも発動するわと思い出す
https://gyazo.com/50e6d0b57668f24e843d5ff31b78009a
なるほどなー、途中では発動しない正規表現、自力で考えるしかなさそうだなぁsta.icon*3
後読み先読みも厳密に理解する必要がある
VSCodeのsyntaxの定義の癖(どう解釈されてくのか)も知る必要がある
問題
行頭じゃないのに引用される
https://gyazo.com/a90cd9b47c71fb0d665ce8a926c32a69
コードも
https://gyazo.com/50e6d0b57668f24e843d5ff31b78009a
引用の中でリンクとか効かない
https://gyazo.com/6269c0052a87de8eb11ab6c211795c6e
---
https://gyazo.com/358837d06553bd9078076cd9a6fc6a56
✅コードブロック
https://gyazo.com/2bfe6f8cf1cbd46081379773d65bb971 インデントがあるとヒットしなくなるのを何とかしたい
❌肯定的先読み
code:json
"codeblock": {
"begin": "^(?=( )*)code\\:.+",
"end": "^( )*\\:c",
"beginCaptures": {
"0": { "name": "codeblock.start.scb" }
},
"endCaptures": {
"0": { "name": "codeblock.end.scb" }
},
"name": "codeblock.scb"
}
❌肯定的後よみ
code:json
"codeblock": {
"begin": "^(?<=( )*)code\\:.+",
"end": "^( )*\\:c",
"beginCaptures": {
"0": { "name": "codeblock.start.scb" }
},
"endCaptures": {
"0": { "name": "codeblock.end.scb" }
},
"name": "codeblock.scb"
}
❌docstringの正規表現真似た
code:json
"codeblock-statement": {
"begin": "^(?= *)code\\:",
"end": "^(?= *)\\:c",
"patterns": [
{
"include": "#codeblock"
}
]
},
"codeblock": {
"begin": "code\\:.+",
"end": "\\:c",
"beginCaptures": {
"0": { "name": "codeblock.start.scb" }
},
"endCaptures": {
"0": { "name": "codeblock.end.scb" }
},
"name": "codeblock.scb"
}
結果かわらんのやが(インデントがあるとハイライトされねぇ……)
やっぱりindent1~9もこの先読み後読みで捕捉する必要があるか?
お?
https://gyazo.com/a4a108178fdff354b5356c14eb7411a8
code:indent1をこうした.json
"indent1": {
"patterns": [{
"captures" : {
"1" : {
"name" : "indent.1.scb"
}
}
}]
},