|
1 | 1 | import logging
|
2 | 2 | import os
|
3 | 3 | from pathlib import Path
|
4 |
| -from typing import Any, Dict, Generator, TypedDict |
| 4 | +from typing import Any, Dict, Generator, Optional, TypedDict, Union |
5 | 5 |
|
6 | 6 | import isort
|
7 | 7 | from pylsp import hookimpl
|
@@ -39,38 +39,72 @@ def pylsp_format_document(config: Config, document: Document) -> Generator:
|
39 | 39 | end={"line": len(document.lines), "character": 0},
|
40 | 40 | )
|
41 | 41 | outcome = yield
|
42 |
| - _process(outcome, config, document, range) |
| 42 | + _format(outcome, config, document, range) |
43 | 43 |
|
44 | 44 |
|
45 | 45 | @hookimpl(hookwrapper=True)
|
46 | 46 | def pylsp_format_range(config: Config, document: Document, range: Range) -> Generator:
|
47 | 47 | outcome = yield
|
48 |
| - _process(outcome, config, document, range) |
| 48 | + _format(outcome, config, document, range) |
49 | 49 |
|
50 | 50 |
|
51 |
| -def _process(outcome, config: Config, document: Document, range: Range): |
| 51 | +def _format(outcome, config: Config, document: Document, range: Range) -> None: |
52 | 52 | result = outcome.get_result()
|
53 | 53 | if result:
|
54 | 54 | text = result[0]["newText"]
|
55 | 55 | range = result[0]["range"]
|
56 | 56 | else:
|
57 |
| - start = range["start"]["line"] |
58 |
| - end = range["end"]["line"] |
59 |
| - text = "".join(document.lines[start:end]) |
| 57 | + text = "".join(document.lines[range["start"]["line"] : range["end"]["line"]]) |
60 | 58 |
|
| 59 | + settings = config.plugin_settings("isort", document_path=document.path) |
| 60 | + new_text = run_isort(text, settings, file_path=document.path) |
| 61 | + |
| 62 | + if new_text != text: |
| 63 | + result = [{"range": range, "newText": new_text}] |
| 64 | + outcome.force_result(result) |
| 65 | + |
| 66 | + |
| 67 | +def run_isort( |
| 68 | + text: str, |
| 69 | + settings: Optional[Dict[str, Any]] = None, |
| 70 | + file_path: Optional[Union[str, bytes, os.PathLike]] = None, |
| 71 | +) -> str: |
| 72 | + config = isort_config(settings or {}, file_path) |
| 73 | + file_path = Path(os.fsdecode(file_path)) if file_path else None |
| 74 | + return isort.code(text, config=config, file_path=file_path) |
| 75 | + |
| 76 | + |
| 77 | +def isort_config( |
| 78 | + settings: Dict[str, Any], |
| 79 | + target_path: Optional[Union[str, bytes, os.PathLike]] = None, |
| 80 | +) -> isort.Config: |
61 | 81 | config_kwargs = {}
|
| 82 | + unsupported_kwargs = {} |
| 83 | + |
62 | 84 | defined_args = set(getattr(isort.Config, "__dataclass_fields__", {}).keys())
|
63 |
| - settings = config.plugin_settings("isort", document_path=document.path) |
64 | 85 | for key, value in settings.items():
|
65 | 86 | if key in defined_args:
|
66 | 87 | config_kwargs[key] = value
|
67 |
| - config_kwargs["settings_path"] = os.path.dirname(os.path.abspath(document.path)) |
68 |
| - logger.debug("config_kwargs=%r", config_kwargs) |
| 88 | + else: |
| 89 | + unsupported_kwargs[key] = value |
| 90 | + |
| 91 | + if "settings_path" in settings: |
| 92 | + if os.path.isfile(settings["settings_path"]): |
| 93 | + config_kwargs["settings_file"] = os.path.abspath(settings["settings_path"]) |
| 94 | + config_kwargs["settings_path"] = os.path.dirname( |
| 95 | + config_kwargs["settings_file"] |
| 96 | + ) |
| 97 | + else: |
| 98 | + config_kwargs["settings_path"] = os.path.abspath(settings["settings_path"]) |
| 99 | + elif target_path: |
| 100 | + config_kwargs["settings_path"] = os.path.abspath(target_path) |
| 101 | + if not os.path.isdir(config_kwargs["settings_path"]): |
| 102 | + config_kwargs["settings_path"] = os.path.dirname( |
| 103 | + config_kwargs["settings_path"] |
| 104 | + ) |
69 | 105 |
|
70 |
| - new_text = isort.code( |
71 |
| - text, config=isort.Config(**config_kwargs), file_path=Path(document.path) |
72 |
| - ) |
| 106 | + logger.debug("config_kwargs=%r", config_kwargs) |
| 107 | + if unsupported_kwargs: |
| 108 | + logger.info("unsupported_kwargs=%r", unsupported_kwargs) |
73 | 109 |
|
74 |
| - if new_text != text: |
75 |
| - result = [{"range": range, "newText": new_text}] |
76 |
| - outcome.force_result(result) |
| 110 | + return isort.Config(**config_kwargs) |
0 commit comments