Skip to content

Commit e8cfc43

Browse files
authored
Merge pull request #26 from python-lsp/cache-config
Add client side configuration and cache configuration per file
2 parents 2bc7a91 + 8de8f96 commit e8cfc43

File tree

7 files changed

+172
-42
lines changed

7 files changed

+172
-42
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
.mypy_cache
33
*.egg-info
44
*.pyc
5+
*.orig
56
.pytest_cache
67
.ropeproject
78
build

README.md

Lines changed: 27 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,31 @@ To avoid unexpected results you should make sure `yapf` and `autopep8` are not i
2121
- The code will only be formatted if it is syntactically valid Python.
2222
- Text selections are treated as if they were a separate Python file.
2323
Unfortunately this means you can't format an indented block of code.
24-
- `python-lsp-black` will use your project's [pyproject.toml](https://github.com/psf/black#pyprojecttoml) if it has one.
25-
- `python-lsp-black` only officially supports the latest stable version of [black](https://github.com/psf/black). An effort is made to keep backwards-compatibility but older black versions will not be actively tested.
24+
- `python-lsp-black` will use your project's
25+
[pyproject.toml](https://github.com/psf/black#pyprojecttoml) if it has one.
26+
- `python-lsp-black` only officially supports the latest stable version of
27+
[black](https://github.com/psf/black). An effort is made to keep backwards-compatibility
28+
but older black versions will not be actively tested.
29+
- The plugin can cache the black configuration that applies to each Python file, this
30+
improves performance of the plugin. When configuration caching is enabled any changes to
31+
black's configuration will need the LSP server to be restarted. Configuration caching
32+
can be disabled with the `cache_config` option, see *Configuration* below.
33+
34+
# Configuration
35+
36+
The plugin follows [python-lsp-server's
37+
configuration](https://github.com/python-lsp/python-lsp-server/#configuration). These are
38+
the valid configuration keys:
39+
40+
- `pylsp.plugins.black.enabled`: boolean to enable/disable the plugin.
41+
- `pylsp.plugins.black.cache_config`: a boolean to enable black configuration caching (see
42+
*Usage*). `false` by default.
43+
- `pylsp.plugins.black.line_length`: an integer that maps to [black's
44+
`max-line-length`](https://black.readthedocs.io/en/stable/the_black_code_style/current_style.html#line-length)
45+
setting. Defaults to 88 (same as black's default). This can also be set through black's
46+
configuration files, which should be preferred for multi-user projects.
47+
- `pylsp.plugins.black.preview`: a boolean to enable or disable [black's `--preview`
48+
setting](https://black.readthedocs.io/en/stable/the_black_code_style/future_style.html#preview-style).
2649

2750
# Development
2851

@@ -35,8 +58,8 @@ pip install -e .[dev]
3558
```
3659

3760
This project uses [pre-commit](https://pre-commit.com/) hooks to control code quality,
38-
install them to run them when creating a git commit, thus avoiding seeing errors when you
39-
create a pull request:
61+
install them to run automatically when creating a git commit, thus avoiding seeing errors
62+
when you create a pull request:
4063

4164
```shell
4265
pre-commit install

pylsp_black/plugin.py

Lines changed: 39 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,14 @@
11
import logging
22
import os
3+
from functools import lru_cache
34
from pathlib import Path
45
from typing import Dict, Optional
56

67
import black
78
import toml
89
from pylsp import hookimpl
910
from pylsp._utils import get_eol_chars
11+
from pylsp.config.config import Config
1012

1113
logger = logging.getLogger(__name__)
1214

@@ -27,19 +29,34 @@
2729

2830

2931
@hookimpl(tryfirst=True)
30-
def pylsp_format_document(document):
31-
return format_document(document)
32+
def pylsp_format_document(config, document):
33+
return format_document(config, document)
3234

3335

3436
@hookimpl(tryfirst=True)
35-
def pylsp_format_range(document, range):
37+
def pylsp_format_range(config, document, range):
3638
range["start"]["character"] = 0
3739
range["end"]["line"] += 1
3840
range["end"]["character"] = 0
39-
return format_document(document, range)
41+
return format_document(config, document, range)
42+
43+
44+
@hookimpl
45+
def pylsp_settings():
46+
"""Configuration options that can be set on the client."""
47+
return {
48+
"plugins": {
49+
"black": {
50+
"enabled": True,
51+
"line_length": 88,
52+
"preview": False,
53+
"cache_config": False,
54+
}
55+
}
56+
}
4057

4158

42-
def format_document(document, range=None):
59+
def format_document(client_config, document, range=None):
4360
if range:
4461
start = range["start"]["line"]
4562
end = range["end"]["line"]
@@ -51,7 +68,7 @@ def format_document(document, range=None):
5168
"end": {"line": len(document.lines), "character": 0},
5269
}
5370

54-
config = load_config(document.path)
71+
config = load_config(document.path, client_config)
5572

5673
try:
5774
formatted_text = format_text(text=text, config=config)
@@ -103,13 +120,17 @@ def format_text(*, text, config):
103120
raise black.NothingChanged from e
104121

105122

106-
def load_config(filename: str) -> Dict:
123+
@lru_cache(100)
124+
def _load_config(filename: str, client_config: Config) -> Dict:
125+
settings = client_config.plugin_settings("black")
126+
107127
defaults = {
108-
"line_length": 88,
128+
"line_length": settings.get("line_length", 88),
109129
"fast": False,
110130
"pyi": filename.endswith(".pyi"),
111131
"skip_string_normalization": False,
112132
"target_version": set(),
133+
"preview": settings.get("preview", False),
113134
}
114135

115136
root = black.find_project_root((filename,))
@@ -168,3 +189,13 @@ def load_config(filename: str) -> Dict:
168189
logger.info("Using config from %s: %r", pyproject_filename, config)
169190

170191
return config
192+
193+
194+
def load_config(filename: str, client_config: Config) -> Dict:
195+
settings = client_config.plugin_settings("black")
196+
197+
# Use the original, not cached function to load settings if requested
198+
if not settings.get("cache_config", False):
199+
return _load_config.__wrapped__(filename, client_config)
200+
201+
return _load_config(filename, client_config)

setup.cfg

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ classifiers =
1818

1919
[options]
2020
packages = find:
21-
install_requires = python-lsp-server>=1.4.0; black>=19.3b0; toml
21+
install_requires = python-lsp-server>=1.4.0; black>=22.1.0; toml
2222
python_requires = >= 3.7
2323

2424
[options.entry_points]
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
def foo(
2+
aaaaa, bbbbb, ccccc, ddddd, eeeee, fffff, ggggg, hhhhh, iiiii, jjjjj, kkkkk
3+
):
4+
return aaaaa # noqa
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
2+
def foo(aaaaa, bbbbb, ccccc, ddddd, eeeee, fffff, ggggg, hhhhh, iiiii, jjjjj, kkkkk):
3+
return aaaaa # noqa

0 commit comments

Comments
 (0)