diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..16f1825 --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,51 @@ +name: ci +on: + - pull_request + - push + +jobs: + Test: + if: "!contains(github.event.head_commit.message, '[skip ci]')" + runs-on: ${{ matrix.os }} + strategy: + fail-fast: false + matrix: + os: + - ubuntu-latest + - macos-latest + - windows-latest + atom_channel: + - stable + - nightly + steps: + - uses: actions/checkout@v2 + - name: Cache + uses: actions/cache@v2 + with: + path: | + 'node_modules' + 'C:/Program Files (x86)/MSBuild/Microsoft.Cpp/v4.0/v140' + key: ${{ runner.os }}-${{ matrix.atom_channel }}-${{ hashFiles('package.json') }} + + - uses: UziTech/action-setup-atom@v1 + with: + channel: ${{ matrix.atom_channel }} + + - name: Install Visual Studio 2015 on Windows + if: ${{ contains(matrix.os, 'windows') }} + run: | + choco install visualcpp-build-tools --version=14.0.25420.1 --ignore-dependencies -y --params "'/IncludeRequired'" + echo ::set-env name=VCTargetsPath::'C:\Program Files (x86)\MSBuild\Microsoft.Cpp\v4.0\v140' + + - name: Install dependencies + run: apm install + + - name: Run tests + run: apm test + + Skip: + if: contains(github.event.head_commit.message, '[skip ci]') + runs-on: ubuntu-latest + steps: + - name: Skip CI 🚫 + run: echo skip ci diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index 47ee9a1..0000000 --- a/.travis.yml +++ /dev/null @@ -1,41 +0,0 @@ -### Project specific config ### -language: generic - -env: - global: - - APM_TEST_PACKAGES="" - - ATOM_LINT_WITH_BUNDLED_NODE="true" - - matrix: - - ATOM_CHANNEL=stable - - ATOM_CHANNEL=beta - -### Generic setup follows ### -script: - - curl -s -O https://raw.githubusercontent.com/atom/ci/master/build-package.sh - - chmod u+x build-package.sh - - ./build-package.sh - -notifications: - email: - on_success: never - on_failure: change - -branches: - only: - - master - -git: - depth: 10 - -sudo: false - -dist: trusty - -addons: - apt: - packages: - - build-essential - - fakeroot - - git - - libsecret-1-dev diff --git a/README.md b/README.md index e646780..4def7c0 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ -# Python language support in Atom -[![macOS Build Status](https://travis-ci.org/atom/language-python.svg?branch=master)](https://travis-ci.org/atom/language-python) -[![Windows Build Status](https://ci.appveyor.com/api/projects/status/hmxrb9jttjh41es9/branch/master?svg=true)](https://ci.appveyor.com/project/Atom/language-python/branch/master) +##### Atom and all repositories under Atom will be archived on December 15, 2022. Learn more in our [official announcement](https://github.blog/2022-06-08-sunsetting-atom/) + # Python language support in Atom +![ci](https://github.com/atom/language-python/workflows/ci/badge.svg) [![Dependency Status](https://david-dm.org/atom/language-python.svg)](https://david-dm.org/atom/language-python) Adds syntax highlighting and snippets to Python files in Atom. diff --git a/appveyor.yml b/appveyor.yml index 7d07d05..795da41 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -1,29 +1,6 @@ -version: "{build}" - -image: Visual Studio 2015 - -platform: x64 +# empty appveyor +build: off branches: - only: - - master - -clone_depth: 10 - -skip_tags: true - -environment: - APM_TEST_PACKAGES: - - matrix: - - ATOM_CHANNEL: stable - - ATOM_CHANNEL: beta - -install: - - ps: Install-Product node 4 - -build_script: - - ps: iex ((new-object net.webclient).DownloadString('https://raw.githubusercontent.com/atom/ci/master/build-package.ps1')) - -test: off -deploy: off + only: + - non-existing diff --git a/grammars/python.cson b/grammars/python.cson index dc84094..71cb6d4 100644 --- a/grammars/python.cson +++ b/grammars/python.cson @@ -848,7 +848,7 @@ 'generic_names': 'match': '[A-Za-z_][A-Za-z0-9_]*' 'illegal_names': - 'match': '\\b(and|as|assert|break|class|continue|def|del|elif|else|except|exec|finally|for|from|global|if|import|in|is|lambda|nonlocal|not|or|pass|print|raise|return|try|while|with|yield|await)\\b' + 'match': '\\b(and|as|assert|break|class|continue|def|del|elif|else|except|exec|finally|for|from|global|if|import|in|is|lambda|nonlocal|not|or|pass|print|raise|return|try|while|with|yield|await|async)\\b' 'name': 'invalid.illegal.name.python' 'keyword_arguments': 'begin': '\\b([a-zA-Z_][a-zA-Z_0-9]*)\\s*(=)(?!=)' @@ -1643,7 +1643,7 @@ 'name': 'string.quoted.double.block.python' 'patterns': [ { - 'begin': '(?=\\s*(SELECT|INSERT|UPDATE|DELETE|CREATE|REPLACE|ALTER|WITH))' + 'begin': '(?=\\s*(SELECT|INSERT|UPDATE|DELETE(?! \/)|CREATE|REPLACE|ALTER|WITH))' 'name': 'meta.embedded.sql' 'end': '(?=\\s*""")' 'patterns': [ @@ -1655,7 +1655,7 @@ ] } { - 'begin': '(")(?=\\s*(SELECT|INSERT|UPDATE|DELETE|CREATE|REPLACE|ALTER|WITH))' + 'begin': '(")(?=\\s*(SELECT|INSERT|UPDATE|DELETE(?! \/)|CREATE|REPLACE|ALTER|WITH))' 'beginCaptures': '1': 'name': 'punctuation.definition.string.begin.python' @@ -2214,7 +2214,7 @@ 'name': 'string.quoted.single.block.python' 'patterns': [ { - 'begin': '(?=\\s*(SELECT|INSERT|UPDATE|DELETE|CREATE|REPLACE|ALTER|WITH))' + 'begin': '(?=\\s*(SELECT|INSERT|UPDATE|DELETE(?! \/)|CREATE|REPLACE|ALTER|WITH))' 'end': '(?=\\s*\'\'\')' 'name': 'meta.embedded.sql' 'patterns': [ @@ -2226,7 +2226,7 @@ ] } { - 'begin': '(\')(?=\\s*(SELECT|INSERT|UPDATE|DELETE|CREATE|REPLACE|ALTER|WITH))' + 'begin': '(\')(?=\\s*(SELECT|INSERT|UPDATE|DELETE(?! \/)|CREATE|REPLACE|ALTER|WITH))' 'beginCaptures': '1': 'name': 'punctuation.definition.string.begin.python' diff --git a/grammars/tree-sitter-python.cson b/grammars/tree-sitter-python.cson index ff31929..4490d74 100644 --- a/grammars/tree-sitter-python.cson +++ b/grammars/tree-sitter-python.cson @@ -5,7 +5,7 @@ parser: 'tree-sitter-python' firstLineRegex: [ # shebang line - '^#!.*\\b(python)\\r?\\n' + '^#![ \\t]*/.*\\bpython[\\d\\.]*\\b' # vim modeline 'vim\\b.*\\bset\\b.*\\b(filetype|ft|syntax)=python' @@ -25,8 +25,14 @@ fileTypes: [ ] folds: [ + { + type: ['if_statement'] + start: {type: ':'} + end: {type: ['elif_clause', 'else_clause']} + }, { type: [ + 'if_statement' 'elif_clause' 'else_clause' 'for_statement' @@ -39,11 +45,6 @@ folds: [ ] start: {type: ':'} }, - { - type: ['if_statement'] - start: {type: ':'} - end: {type: ['elif_clause', 'else_clause']} - } { start: {type: '(', index: 0} end: {type: ')', index: -1} @@ -72,14 +73,22 @@ scopes: 'interpolation > "}"': 'punctuation.section.embedded' 'class_definition > identifier': 'entity.name.type.class' - 'function_definition > identifier': 'entity.name.function' + 'function_definition > identifier': 'entity.name.function.definition' 'call > identifier:nth-child(0)': [ {match: '^(abs|all|any|ascii|bin|bool|breakpoint|bytearray|bytes|callable|chr|classmethod|compile|complex|delattr|dict|dir|divmod|enumerate|eval|exec|filter|float|format|frozenset|getattr|globals|hasattr|hash|help|hex|id|input|int|isinstance|issubclass|iter|len|list|locals|map|max|memoryview|min|next|object|oct|open|ord|pow|print|property|range|repr|reversed|round|set|setattr|slice|sorted|staticmethod|str|sum|super|tuple|type|vars|zip|__import__)$', - scopes: 'support.function'}, - 'entity.name.function' + scopes: 'support.function.call'}, + {match: '^[A-Z]', scopes: 'support.type.contructor'} + 'entity.name.function.call' ] 'call > attribute > identifier:nth-child(2)': 'entity.name.function' + 'identifier': [ + {match: + '^(BaseException|Exception|TypeError|StopAsyncIteration|StopIteration|ImportError|ModuleNotFoundError|OSError|ConnectionError|BrokenPipeError|ConnectionAbortedError|ConnectionRefusedError|ConnectionResetError|BlockingIOError|ChildProcessError|FileExistsError|FileNotFoundError|IsADirectoryError|NotADirectoryError|InterruptedError|PermissionError|ProcessLookupError|TimeoutError|EOFError|RuntimeError|RecursionError|NotImplementedError|NameError|UnboundLocalError|AttributeError|SyntaxError|IndentationError|TabError|LookupError|IndexError|KeyError|ValueError|UnicodeError|UnicodeEncodeError|UnicodeDecodeError|UnicodeTranslateError|AssertionError|ArithmeticError|FloatingPointError|OverflowError|ZeroDivisionError|SystemError|ReferenceError|BufferError|MemoryError|Warning|UserWarning|DeprecationWarning|PendingDeprecationWarning|SyntaxWarning|RuntimeWarning|FutureWarning|ImportWarning|UnicodeWarning|BytesWarning|ResourceWarning|GeneratorExit|SystemExit|KeyboardInterrupt)$' + scopes: 'support.type.exception'}, + {match: '^(self)', scopes: 'entity.name.variable.self'} + ] + 'attribute > identifier:nth-child(2)': 'variable.other.object.property' 'decorator': 'entity.name.function.decorator' @@ -87,11 +96,16 @@ scopes: 'none': 'constant.language' 'true': 'constant.language' 'false': 'constant.language' - 'integer': 'constant.language' - 'float': 'constant.language' + 'integer': 'constant.numeric' + 'float': 'constant.numeric' 'type > identifier': 'support.storage.type' + 'class_definition > argument_list > attribute': 'entity.other.inherited-class' + 'class_definition > argument_list > identifier': 'entity.other.inherited-class' + 'class_definition > argument_list > keyword_argument > attribute': 'entity.other.inherited-class' + 'class_definition > argument_list > keyword_argument > identifier:nth-child(2)': 'entity.other.inherited-class' + '"class"': 'storage.type.class' '"def"': 'storage.type.function' '"lambda"': 'storage.type.function' @@ -99,7 +113,15 @@ scopes: '"global"': 'storage.modifier.global' '"nonlocal"': 'storage.modifier.nonlocal' + 'parameters > identifier': 'variable.parameter.function' + 'parameters > list_splat > identifier': 'variable.parameter.function' + 'parameters > dictionary_splat > identifier': 'variable.parameter.function' + 'default_parameter > identifier:nth-child(0)': 'variable.parameter.function' 'keyword_argument > identifier:nth-child(0)': 'variable.parameter.function' + 'lambda_parameters > identifier': 'variable.parameter.function' + 'typed_parameter > identifier': 'variable.parameter.function' + + 'argument_list': 'meta.method-call.python' '"if"': 'keyword.control' '"else"': 'keyword.control' @@ -155,8 +177,19 @@ scopes: '"~"': 'keyword.operator' '"<<"': 'keyword.operator' '">>"': 'keyword.operator' + 'binary_operator > "@"': 'keyword.operator' + 'binary_operator > "@="': 'keyword.operator' '"in"': 'keyword.operator.logical.python' '"and"': 'keyword.operator.logical.python' '"or"': 'keyword.operator.logical.python' '"not"': 'keyword.operator.logical.python' '"is"': 'keyword.operator.logical.python' + '"->"': 'keyword.control.return' + + '"["': 'punctuation.definition.begin.bracket.square' + '"]"': 'punctuation.definition.end.bracket.square' + '","': 'punctuation.separator.delimiter' + '"{"': 'punctuation.section.block.begin.bracket.curly' + '"}"': 'punctuation.section.block.end.bracket.curly' + '"("': 'punctuation.section.parens.begin.bracket.round' + '")"': 'punctuation.section.parens.end.bracket.round' diff --git a/package-lock.json b/package-lock.json index 743c8e3..d77eb13 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "language-python", - "version": "0.51.9", + "version": "0.53.6", "lockfileVersion": 1, "requires": true, "dependencies": { @@ -123,9 +123,9 @@ "dev": true }, "nan": { - "version": "2.12.1", - "resolved": "https://registry.npmjs.org/nan/-/nan-2.12.1.tgz", - "integrity": "sha512-JY7V6lRkStKcKTvHO5NVSQRv+RV+FIL5pvDoLiAtSL9pKlC5x9PKQcZDsq7m4FO4d57mkhC6Z+QhAh3Jdk5JFw==" + "version": "2.14.2", + "resolved": "https://registry.npmjs.org/nan/-/nan-2.14.2.tgz", + "integrity": "sha512-M2ufzIiINKCuDfBSAUr1vWQ+vuVcA9kqx8JJUsbQi6yf1uGRyb7HfpdfUr5qLXf3B/t8dPvcjhKMmlfnP47EzQ==" }, "once": { "version": "1.4.0", @@ -165,9 +165,9 @@ "dev": true }, "tree-sitter-python": { - "version": "0.13.6", - "resolved": "https://registry.npmjs.org/tree-sitter-python/-/tree-sitter-python-0.13.6.tgz", - "integrity": "sha512-QGc7dNObFv5+kCIvknO+Jv9eHusgamlcxZpLkDioAK6/dZ/f+3vbn3KQ2y4PpS1qiAHaaxh2V4XgMyv6k/rS9g==", + "version": "0.17.0", + "resolved": "https://registry.npmjs.org/tree-sitter-python/-/tree-sitter-python-0.17.0.tgz", + "integrity": "sha512-6HaqF/1GHB0/qrkcIxYqEELsQq6bXdQxx2KnGLZhoGn5ipbAibncSuQT9f8HYbmqLZ4dIGleQzsXreY1mx2lig==", "requires": { "nan": "^2.4.0" } diff --git a/package.json b/package.json index b1bab16..6a079e3 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "language-python", - "version": "0.51.9", + "version": "0.53.6", "engines": { "atom": "*", "node": "*" @@ -20,7 +20,7 @@ }, "dependencies": { "atom-grammar-test": "^0.6.4", - "tree-sitter-python": "^0.13.6" + "tree-sitter-python": "^0.17.0" }, "devDependencies": { "coffeelint": "^1.10.1" diff --git a/spec/python-spec.coffee b/spec/python-spec.coffee index c1851d0..423f8c1 100644 --- a/spec/python-spec.coffee +++ b/spec/python-spec.coffee @@ -750,3 +750,10 @@ describe "Python grammar", -> expect(tokens[13]).toEqual value: ')', scopes: ['source.python', 'string.quoted.double.single-line.sql.python', 'meta.embedded.sql', 'punctuation.definition.section.bracket.round.end.sql'] expect(tokens[15]).toEqual value: '"', scopes: ['source.python', 'string.quoted.double.single-line.sql.python', 'punctuation.definition.string.end.python'] expect(tokens[17]).toEqual value: '%', scopes: ['source.python', 'keyword.operator.arithmetic.python'] + + it "recognizes DELETE as an HTTP method", -> + {tokens} = grammar.tokenizeLine('"DELETE /api/v1/endpoint"') + + expect(tokens[0]).toEqual value: '"', scopes: ['source.python', 'string.quoted.double.single-line.python', 'punctuation.definition.string.begin.python'] + expect(tokens[1]).toEqual value: 'DELETE /api/v1/endpoint', scopes: ['source.python', 'string.quoted.double.single-line.python'] + expect(tokens[2]).toEqual value: '"', scopes: ['source.python', 'string.quoted.double.single-line.python', 'punctuation.definition.string.end.python']