sublimehq / sublime_text

Issue tracker for Sublime Text
https://www.sublimetext.com
809 stars 39 forks source link

The Sublime Text's Syntax Regex is jumping/not catching/ignoring the current line end #1377

Closed evandrocoan closed 8 years ago

evandrocoan commented 8 years ago

Summary

The Sublime Text's Syntax Regex is jumping/not catching/ignoring the current line end

The following regex is jumping the current line end when the -match expression ^\s*\#(define\s*([A-Z]*)) captures the whole line, except the line feed character \\n.

    # For lines which does not continue using \
    - match: '^\s*\#(define\s*([A-Za-z_]*))'
      captures:
        2: function.definition.AmxxPawn
      push:
        - meta_scope: meta.preprocessor.AmxxPawn
        - include: preprocessor_numbers
        - match: '[^\\]\n'
          pop: true

Example: image The line 34 does not end with spaces or nothing so the regex expression -match: ^\s*\#(define\s*([A-Z]*)) captures the whole line, except the line feed character \n. It causes the regex end expression - match: '[^\\]\n' to jump/ignore the current line end, and only finally capture the correct line end at the next line, causing, wrong match.

Expected behavior

Is expected to the end regex expression - match: '[^\\]\n' to match the current line ending, not the next line ending.

Steps to reproduce

1 . Create a file named test.sublime-syntax within the following contents:

%YAML 1.2

---

name: test
file_extensions:
  - test
scope: source.test
contexts:
  main:
    - include: pawn_directives
  pawn_directives:
    - match: '^\s*\#(define\s*([A-Za-z_0-9]+))'
      captures:
        2: function.definition.AmxxPawn
      push:
        - meta_scope: meta.preprocessor.test
        - include: preprocessor_numbers
        - match: '[^\\]\n'
          pop: true

2 . Install the syntax file and apply it to your file within the image's example:

    #define DEBUG a
not match
not match

    #define DEBUG 
not match
not match

    #define DEBUG
not match
not match

3 . Be sure there is the scope meta.preprocessor defined with your syntax theme file.

4 . You will the the above problem:

image

Environment

keith-hall commented 8 years ago

Your match: '[^\\]\n' is looking for any character that is not a \, followed by a newline. As you have already consumed every character except the newline on line 34, it doesn't match until the next newline character at the end of line 35.

evandrocoan commented 8 years ago

I fixed it adding this line before that:

    - match: '^\s*\#(define\s*({{words_pawn}}))\n'
      captures:
        0: meta.preprocessor.AmxxPawn
        2: function.definition.AmxxPawn

The full new block is now:

  pawn_directives:
    # For lines which does not continue using \
    - match: '^\s*\#(define\s*({{words_pawn}}))\n'
      captures:
        0: meta.preprocessor.AmxxPawn
        2: function.definition.AmxxPawn

    - match: '^\s*\#(define\s*({{words_pawn}}))'
      captures:
        2: function.definition.AmxxPawn
      push:
        - meta_scope: meta.preprocessor.AmxxPawn
        - include: preprocessor_numbers
        - match: '[^\\]\n'
          pop: true

    - match: '^\s*\#'
      push:
        - meta_scope: meta.preprocessor.AmxxPawn
        - include: preprocessor_numbers
        - match: '[^\\]\n'
          pop: true

    # For lines which does continue using \
    - match: '^\s*\#.*(%\d|(\\\n))'
      push:
        - meta_scope: meta.preprocessor.AmxxPawn
        - include: preprocessor_numbers
        - match: '((.*\\\n)*.*[^\\]\n)'
          pop: true

  preprocessor_numbers:
    - match: '%\d'
      scope: constant.numeric.AmxxPawn