diff --git a/.flake8rc b/.flake8rc new file mode 100644 index 0000000..bfead2c --- /dev/null +++ b/.flake8rc @@ -0,0 +1,2 @@ +[flake8] +max-line-length = 79 diff --git a/.github/workflows/python-package.yml b/.github/workflows/python-package.yml index da9c0e2..61c0c0b 100644 --- a/.github/workflows/python-package.yml +++ b/.github/workflows/python-package.yml @@ -18,20 +18,19 @@ jobs: python-version: ['3.7', '3.8', '3.9', '3.10', '3.11'] steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - name: Set up Python ${{ matrix.python-version }} - uses: actions/setup-python@v2 + uses: actions/setup-python@v4 with: python-version: ${{ matrix.python-version }} - name: Install dependencies run: | python -m pip install --upgrade pip python -m pip install pytest - pip install -r requirements.txt + make install - name: Lint with pycodestyle and pyflakes run: | - pycodestyle . - pyflakes . + make flake - name: Test with pytest run: | - pytest + make test diff --git a/.pycodestylerc b/.pycodestylerc new file mode 100644 index 0000000..fa95328 --- /dev/null +++ b/.pycodestylerc @@ -0,0 +1,2 @@ +[pycodestyle] +max-line-length = 79 diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..bec2ed4 --- /dev/null +++ b/Makefile @@ -0,0 +1,23 @@ +SHELL = /bin/bash +PYTHON = python + + +.PHONY: clean +clean: + find . -path "*/__pycache__/*" -delete + find . -type d -empty -delete + + +.PHONY: install +install: clean + $(PYTHON) -m pip install -r requirements.txt + + +.PHONY: flake flake8 +flake flake8: + pycodestyle --config .pycodestylerc . + pyflakes . + +.PHONY: test +test: + $(PYTHON) -m pytest diff --git a/NEWS.md b/NEWS.md index 431ff49..b24d4c1 100644 --- a/NEWS.md +++ b/NEWS.md @@ -1,5 +1,9 @@ # NEWS +## 1.17 + +- Migrating to pygls v1.1 + ## 1.16 - Use version 0 for not opened files on rename diff --git a/README.md b/README.md index db93774..af056ef 100644 --- a/README.md +++ b/README.md @@ -6,8 +6,8 @@ Yet another Jedi Python language server ## Requirements - Python >= 3.6 -- pygls >= 0.10.2,<0.11 -- Jedi >= 0.18 +- pygls >= 1.1, <1.2 +- Jedi >= 0.19 - pyflakes ~= 2.2 - pycodestyle ~= 2.5 - yapf ~=0.30 diff --git a/VERSION b/VERSION new file mode 100644 index 0000000..b48f322 --- /dev/null +++ b/VERSION @@ -0,0 +1 @@ +1.17 diff --git a/anakinls/__main__.py b/anakinls/__main__.py index 90dd3e6..e1ea589 100644 --- a/anakinls/__main__.py +++ b/anakinls/__main__.py @@ -18,7 +18,7 @@ import logging from .server import server -from .version import get_version +from .version import __version__ logging.basicConfig(level=logging.INFO) logging.getLogger('pygls.protocol').setLevel(logging.WARN) @@ -56,7 +56,7 @@ def main(): args = parser.parse_args() if args.version: - print(inspect.cleandoc(f'''anakinls v{get_version()} + print(inspect.cleandoc(f'''anakinls v{__version__} Copyright (C) 2020 Andrii Kolomoiets This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A diff --git a/anakinls/server.py b/anakinls/server.py index 4972693..e2414ab 100644 --- a/anakinls/server.py +++ b/anakinls/server.py @@ -35,19 +35,12 @@ from yapf.yapflib.yapf_api import FormatCode # type: ignore -from pygls.lsp.methods import (COMPLETION, TEXT_DOCUMENT_DID_CHANGE, - TEXT_DOCUMENT_DID_CLOSE, TEXT_DOCUMENT_DID_OPEN, - HOVER, SIGNATURE_HELP, DEFINITION, - REFERENCES, WORKSPACE_DID_CHANGE_CONFIGURATION, - TEXT_DOCUMENT_WILL_SAVE, TEXT_DOCUMENT_DID_SAVE, - DOCUMENT_SYMBOL, CODE_ACTION, FORMATTING, - RANGE_FORMATTING, RENAME, DOCUMENT_HIGHLIGHT) -from pygls.lsp import types +from lsprotocol import types from pygls.server import LanguageServer -from pygls.protocol import LanguageServerProtocol +from pygls.protocol import LanguageServerProtocol, lsp_method from pygls.uris import to_fs_path -from .version import get_version # type: ignore +from .version import __version__ # type: ignore RE_WORD = re.compile(r'\w*') @@ -76,9 +69,10 @@ class AnakinLanguageServerProtocol(LanguageServerProtocol): - def bf_initialize( + @lsp_method(types.INITIALIZE) + def lsp_initialize( self, params: types.InitializeParams) -> types.InitializeResult: - result = super().bf_initialize(params) + result = super().lsp_initialize(params) global jediEnvironment global jediProject global completionFunction @@ -129,15 +123,14 @@ def get_attr(o, *attrs): else: hoverFunction = _docstring - # pygls does not currently support serverInfo of LSP v3.15 - result.server_info = types.ServerInfo( - name='anakinls', - version=get_version(), - ) return result -server = LanguageServer(protocol_cls=AnakinLanguageServerProtocol) +server = LanguageServer( + name='anakinls', + version=__version__, + protocol_cls=AnakinLanguageServerProtocol +) scripts: Dict[str, Script] = {} pycodestyleOptions: Dict[str, Any] = {} @@ -172,7 +165,7 @@ def get_attr(o, *attrs): def get_script(ls: LanguageServer, uri: str, update: bool = False) -> Script: result = None if update else scripts.get(uri) if not result: - document = ls.workspace.get_document(uri) + document = ls.workspace.get_text_document(uri) result = Script( code=document.source, path=document.path, @@ -395,13 +388,13 @@ def _validate(ls: LanguageServer, uri: str, script: Script = None): ls.publish_diagnostics(uri, result) -@server.feature(TEXT_DOCUMENT_DID_OPEN) +@server.feature(types.TEXT_DOCUMENT_DID_OPEN) def did_open(ls: LanguageServer, params: types.DidOpenTextDocumentParams): if config['diagnostic_on_open']: _validate(ls, params.text_document.uri) -@server.feature(TEXT_DOCUMENT_DID_CLOSE) +@server.feature(types.TEXT_DOCUMENT_DID_CLOSE) def did_close(ls: LanguageServer, params: types.DidCloseTextDocumentParams): try: del scripts[params.text_document.uri] @@ -409,7 +402,7 @@ def did_close(ls: LanguageServer, params: types.DidCloseTextDocumentParams): pass -@server.feature(TEXT_DOCUMENT_DID_CHANGE) +@server.feature(types.TEXT_DOCUMENT_DID_CHANGE) def did_change(ls: LanguageServer, params: types.DidChangeTextDocumentParams): script = get_script(ls, params.text_document.uri, True) if config['diagnostic_on_change']: @@ -497,7 +490,10 @@ def _completions_snippets(completions: List[Completion], )) -@server.feature(COMPLETION, types.CompletionOptions(trigger_characters=['.'])) +@server.feature( + types.TEXT_DOCUMENT_COMPLETION, + types.CompletionOptions(trigger_characters=['.']), +) def completions(ls: LanguageServer, params: types.CompletionParams): global completionFunction script = get_script(ls, params.text_document.uri) @@ -543,7 +539,7 @@ def _docstring_markdown(name: Name) -> str: return f'```\n{doc}\n```' -@server.feature(HOVER) +@server.feature(types.TEXT_DOCUMENT_HOVER) def hover(ls: LanguageServer, params: types.TextDocumentPositionParams) -> Optional[types.Hover]: global hoverFunction @@ -560,8 +556,10 @@ def hover(ls: LanguageServer, return None -@server.feature(SIGNATURE_HELP, - types.SignatureHelpOptions(trigger_characters=['(', ','])) +@server.feature( + types.TEXT_DOCUMENT_SIGNATURE_HELP, + types.SignatureHelpOptions(trigger_characters=['(', ',']) +) def signature_help( ls: LanguageServer, params: types.TextDocumentPositionParams @@ -614,7 +612,7 @@ def _get_locations(defs: List[Name]) -> List[types.Location]: ] -@server.feature(DEFINITION) +@server.feature(types.TEXT_DOCUMENT_DEFINITION) def definition( ls: LanguageServer, params: types.TextDocumentPositionParams) -> List[types.Location]: @@ -623,7 +621,7 @@ def definition( return _get_locations(defs) -@server.feature(REFERENCES) +@server.feature(types.TEXT_DOCUMENT_REFERENCES) def references(ls: LanguageServer, params: types.ReferenceParams) -> List[types.Location]: script = get_script(ls, params.text_document.uri) @@ -632,7 +630,7 @@ def references(ls: LanguageServer, return _get_locations(refs) -@server.feature(WORKSPACE_DID_CHANGE_CONFIGURATION) +@server.feature(types.WORKSPACE_DID_CHANGE_CONFIGURATION) def did_change_configuration(ls: LanguageServer, settings: types.DidChangeConfigurationParams): if not settings.settings or 'anakinls' not in settings.settings: @@ -673,13 +671,14 @@ def did_change_configuration(ls: LanguageServer, _validate(ls, uri) -@server.feature(TEXT_DOCUMENT_WILL_SAVE) +@server.feature(types.TEXT_DOCUMENT_WILL_SAVE) def will_save(ls: LanguageServer, params: types.WillSaveTextDocumentParams): pass -@server.feature(TEXT_DOCUMENT_DID_SAVE, - types.TextDocumentSaveRegistrationOptions(include_text=False)) +@server.feature( + types.TEXT_DOCUMENT_DID_SAVE, types.SaveOptions(include_text=False) +) def did_save(ls: LanguageServer, params: types.DidSaveTextDocumentParams): if config['diagnostic_on_save']: _validate(ls, params.text_document.uri) @@ -765,7 +764,7 @@ def _symbols(): return list(_symbols()) -@server.feature(DOCUMENT_SYMBOL) +@server.feature(types.TEXT_DOCUMENT_DOCUMENT_SYMBOL) def document_symbol( ls: LanguageServer, params: types.DocumentSymbolParams ) -> Union[List[types.DocumentSymbol], List[types.SymbolInformation], None]: @@ -837,14 +836,14 @@ def _get_document_changes( result.append(types.TextDocumentEdit( text_document=types.VersionedTextDocumentIdentifier( uri=uri, - version=ls.workspace.get_document(uri).version or 0 + version=ls.workspace.get_text_document(uri).version or 0 ), edits=text_edits )) return result -@server.feature(CODE_ACTION, types.CodeActionOptions( +@server.feature(types.TEXT_DOCUMENT_CODE_ACTION, types.CodeActionOptions( code_action_kinds=[ types.CodeActionKind.RefactorInline, types.CodeActionKind.RefactorExtract])) @@ -881,21 +880,21 @@ def _formatting( return _get_text_edits(diff) -@server.feature(FORMATTING) +@server.feature(types.TEXT_DOCUMENT_FORMATTING) def formatting( ls: LanguageServer, params: types.DocumentFormattingParams ) -> Optional[List[types.TextEdit]]: return _formatting(ls, params.text_document.uri) -@server.feature(RANGE_FORMATTING) +@server.feature(types.TEXT_DOCUMENT_RANGE_FORMATTING) def range_formatting( ls: LanguageServer, params: types.DocumentRangeFormattingParams ) -> Optional[List[types.TextEdit]]: return _formatting(ls, params.text_document.uri, params.range) -@server.feature(RENAME) +@server.feature(types.TEXT_DOCUMENT_RENAME) def rename(ls: LanguageServer, params: types.RenameParams) -> Optional[types.WorkspaceEdit]: script = get_script(ls, params.text_document.uri) @@ -911,7 +910,7 @@ def rename(ls: LanguageServer, return None -@server.feature(DOCUMENT_HIGHLIGHT) +@server.feature(types.TEXT_DOCUMENT_DOCUMENT_HIGHLIGHT) def highlight( ls: LanguageServer, params: types.TextDocumentPositionParams ) -> Optional[List[types.DocumentHighlight]]: diff --git a/anakinls/version.py b/anakinls/version.py index 1c815eb..bf63db1 100644 --- a/anakinls/version.py +++ b/anakinls/version.py @@ -13,10 +13,10 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see . -import pkg_resources +from pathlib import Path -def get_version() -> str: - "Return the version of anakinls." - r = pkg_resources.require('anakin-language-server') - return r[0].version +__all__ = ['__version__'] + + +__version__ = (Path(__file__).parents[1] / 'VERSION').read_text().strip() diff --git a/requirements.txt b/requirements.txt index f828819..74ebdc5 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,5 +1,5 @@ -jedi>=0.18.0 -pygls>=0.10.2,<0.11 +jedi>=0.19.0 +pygls>=1.1,<1.2 pyflakes~=2.2 pycodestyle~=2.5 yapf~=0.30 diff --git a/setup.py b/setup.py index f8bf78c..be53be4 100644 --- a/setup.py +++ b/setup.py @@ -1,24 +1,23 @@ +from pathlib import Path from setuptools import setup # type: ignore - -with open('README.md', 'r') as f: - long_description = f.read() +from anakinls import version setup( name='anakin-language-server', - version='1.16', + version=version.__version__, author='Andrii Kolomoiets', author_email='andreyk.mad@gmail.com', description='Yet another Jedi Python language server', - long_description=long_description, + long_description=Path('README.md').read_text(), long_description_content_type='text/markdown', url='https://github.com/muffinmad/anakin-language-server', packages=['anakinls'], python_requires='>=3.6', install_requires=[ - 'jedi>=0.18.0', - 'pygls>=0.10.2,<0.11', + 'jedi>=0.19.0', + 'pygls>=1.1,<1.2', 'pyflakes~=2.2', 'pycodestyle~=2.5', 'yapf~=0.30' diff --git a/tests/test_server.py b/tests/test_server.py index 98526ef..f2bdc7e 100644 --- a/tests/test_server.py +++ b/tests/test_server.py @@ -17,7 +17,7 @@ from anakinls import server as aserver -from pygls.lsp import types +from lsprotocol import types from pygls.workspace import Document, Workspace @@ -41,7 +41,7 @@ def foo(a, *, b, c=None): foo''' doc = Document(uri, content) - server.workspace.get_document = Mock(return_value=doc) + server.workspace.get_text_document = Mock(return_value=doc) aserver.completionFunction = aserver._completions_snippets completion = aserver.completions( server, @@ -73,7 +73,7 @@ def foo(a, *, b, c=None): foo''' doc = Document(uri, content) - server.workspace.get_document = Mock(return_value=doc) + server.workspace.get_text_document = Mock(return_value=doc) aserver.hoverFunction = aserver._docstring h = aserver.hover(server, types.TextDocumentPositionParams( text_document=types.TextDocumentIdentifier(uri=uri), @@ -123,9 +123,9 @@ def test_diff_to_edits(): ''' edits = aserver._get_text_edits(diff) assert len(edits) == 4 - assert str(edits[0].range) == 'start=0:0 end=0:0' - assert str(edits[1].range) == 'start=10:0 end=15:0' + assert str(edits[0].range) == '0:0-0:0' + assert str(edits[1].range) == '10:0-15:0' assert edits[1].new_text == '' - assert str(edits[2].range) == 'start=16:0 end=17:0' + assert str(edits[2].range) == '16:0-17:0' assert edits[2].new_text == 'check this document. On\n' - assert str(edits[3].range) == 'start=24:0 end=24:0' + assert str(edits[3].range) == '24:0-24:0'