mirror of
https://github.com/pulsar-edit/pulsar.git
synced 2024-09-21 07:58:04 +03:00
Add OnigRegExp.captureIndices(string, index, regexes)
Allows us to know if a zero-length regex matched.
This commit is contained in:
parent
48fdf8a708
commit
4f2cc1f856
@ -57,8 +57,8 @@ public:
|
||||
int resultCount = [result count];
|
||||
for (int index = 0; index < resultCount; index++) {
|
||||
int captureLength = [result lengthAt:index];
|
||||
if (captureLength == 0) continue;
|
||||
int captureStart = [result locationAt:index];
|
||||
if (captureLength == 0) continue;
|
||||
array->SetValue(i++, CefV8Value::CreateInt(index));
|
||||
array->SetValue(i++, CefV8Value::CreateInt(captureStart));
|
||||
array->SetValue(i++, CefV8Value::CreateInt(captureStart + captureLength));
|
||||
@ -93,18 +93,28 @@ bool OnigRegExp::Execute(const CefString& name,
|
||||
CefRefPtr<CefV8Value> index = arguments[1];
|
||||
CefRefPtr<CefV8Value> regexes = arguments[2];
|
||||
|
||||
int bestIndex = -1;
|
||||
CefRefPtr<CefV8Value> captureIndicesForBestIndex;
|
||||
CefRefPtr<CefV8Value> captureIndices;
|
||||
|
||||
retval = CefV8Value::CreateObject(NULL);
|
||||
for (int i = 0; i < regexes->GetArrayLength(); i++) {
|
||||
OnigRegExpUserData *userData = (OnigRegExpUserData *)regexes->GetValue(i)->GetUserData().get();
|
||||
captureIndices = userData->GetCaptureIndices(string, index);
|
||||
if (captureIndices->IsObject()) {
|
||||
retval->SetValue("index", CefV8Value::CreateInt(i), V8_PROPERTY_ATTRIBUTE_NONE);
|
||||
retval->SetValue("captureIndices", captureIndices, V8_PROPERTY_ATTRIBUTE_NONE);
|
||||
return true;
|
||||
if (captureIndices->IsNull()) continue;
|
||||
|
||||
if (bestIndex == -1 || captureIndices->GetValue(1)->GetIntValue() < captureIndicesForBestIndex->GetValue(1)->GetIntValue()) {
|
||||
bestIndex = i;
|
||||
captureIndicesForBestIndex = captureIndices;
|
||||
if (captureIndices->GetValue(1)->GetIntValue() == 0) break; // If the match starts at 0, just use it!
|
||||
}
|
||||
}
|
||||
|
||||
if (bestIndex != -1) {
|
||||
retval->SetValue("index", CefV8Value::CreateInt(bestIndex), V8_PROPERTY_ATTRIBUTE_NONE);
|
||||
retval->SetValue("captureIndices", captureIndicesForBestIndex, V8_PROPERTY_ATTRIBUTE_NONE);
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
}
|
||||
|
@ -141,3 +141,10 @@ describe "TextMateGrammar", ->
|
||||
it "returns a single token which has the global scope", ->
|
||||
{tokens} = grammar.getLineTokens('')
|
||||
expect(tokens[0]).toEqual value: '', scopes: ["source.coffee"]
|
||||
|
||||
describe "when the line matches a pattern with a 'contentName' key", ->
|
||||
it "creates tokens using the content of contentName as the token name", ->
|
||||
grammar = TextMateBundle.grammarForFileName("sample.txt")
|
||||
{tokens} = grammar.getLineTokens('ok, cool')
|
||||
expect(tokens[0]).toEqual value: 'ok, cool', scopes: ["text.plain", "meta.paragraph.text"]
|
||||
|
||||
|
@ -93,23 +93,21 @@ class Rule
|
||||
getAllPatterns: (included=[]) ->
|
||||
return [] if _.include(included, this)
|
||||
included.push(this)
|
||||
regexPatternPairs = []
|
||||
allPatterns = []
|
||||
|
||||
regexPatternPairs.push(@endPattern.getIncludedPatterns()...) if @endPattern
|
||||
allPatterns.push(@endPattern.getIncludedPatterns()...) if @endPattern
|
||||
for pattern in @patterns
|
||||
regexPatternPairs.push(pattern.getIncludedPatterns(included)...)
|
||||
regexPatternPairs
|
||||
allPatterns.push(pattern.getIncludedPatterns(included)...)
|
||||
allPatterns
|
||||
|
||||
getNextTokens: (stack, line, position) ->
|
||||
captureIndices = @regex.getCaptureIndices(line, position)
|
||||
patterns = @getAllPatterns()
|
||||
{index, captureIndices} = OnigRegExp.captureIndices(line, position, patterns.map (p) -> p.regex )
|
||||
|
||||
return {} unless captureIndices?[2] > 0 # ignore zero-length matches
|
||||
|
||||
shiftCapture(captureIndices)
|
||||
return {} unless index?
|
||||
|
||||
[firstCaptureIndex, firstCaptureStart, firstCaptureEnd] = captureIndices
|
||||
pattern = @patternsByCaptureIndex[firstCaptureIndex]
|
||||
nextTokens = pattern.handleMatch(stack, line, captureIndices)
|
||||
nextTokens = patterns[index].handleMatch(stack, line, captureIndices)
|
||||
{ nextTokens, tokensStartPosition: firstCaptureStart, tokensEndPosition: firstCaptureEnd }
|
||||
|
||||
getNextMatch: (line, position) ->
|
||||
@ -167,10 +165,16 @@ class Pattern
|
||||
scopes.push(@scopeName) unless @popRule
|
||||
|
||||
if @captures
|
||||
parentCapture = captureIndices[0..2]
|
||||
childCaptures = captureIndices[3..]
|
||||
tokens = @getTokensForCaptureIndices(line, captureIndices, scopes)
|
||||
else
|
||||
[start, end] = captureIndices[1..2]
|
||||
tokens = [{ value: line[start...end], scopes: scopes }]
|
||||
zeroLengthMatch = end == start
|
||||
if zeroLengthMatch
|
||||
tokens = []
|
||||
else
|
||||
tokens = [{ value: line[start...end], scopes: scopes }]
|
||||
|
||||
if @pushRule
|
||||
stack.push(@pushRule)
|
||||
@ -179,12 +183,11 @@ class Pattern
|
||||
|
||||
tokens
|
||||
|
||||
getTokensForCaptureIndices: (line, captureIndices, scopes, indexOffset=captureIndices[0]) ->
|
||||
getTokensForCaptureIndices: (line, captureIndices, scopes) ->
|
||||
[parentCaptureIndex, parentCaptureStart, parentCaptureEnd] = shiftCapture(captureIndices)
|
||||
relativeParentCaptureIndex = parentCaptureIndex - indexOffset
|
||||
|
||||
tokens = []
|
||||
if scope = @captures[relativeParentCaptureIndex]?.name
|
||||
if scope = @captures[parentCaptureIndex]?.name
|
||||
scopes = scopes.concat(scope)
|
||||
|
||||
previousChildCaptureEnd = parentCaptureStart
|
||||
@ -196,7 +199,7 @@ class Pattern
|
||||
value: line[previousChildCaptureEnd...childCaptureStart]
|
||||
scopes: scopes
|
||||
|
||||
captureTokens = @getTokensForCaptureIndices(line, captureIndices, scopes, indexOffset)
|
||||
captureTokens = @getTokensForCaptureIndices(line, captureIndices, scopes)
|
||||
tokens.push(captureTokens...)
|
||||
previousChildCaptureEnd = childCaptureEnd
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user