or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

configuration-system.mdindex.mdplugin-development.mdserver-management.mdutilities-helpers.mdworkspace-management.md

configuration-system.mddocs/

0

# Configuration System

1

2

Hierarchical configuration system supporting workspace-level, plugin-specific, and document-specific settings with integration to external configuration files. Provides comprehensive configuration management for server behavior and plugin customization.

3

4

## Capabilities

5

6

### Config Class

7

8

Main configuration management class with hierarchical settings resolution.

9

10

```python { .api }

11

class Config:

12

def __init__(self, root_uri, init_opts, process_id, capabilities):

13

"""

14

Initialize configuration.

15

16

Parameters:

17

- root_uri: str, workspace root URI

18

- init_opts: dict, initialization options from client

19

- process_id: int, client process ID

20

- capabilities: dict, client capabilities

21

"""

22

23

@property

24

def disabled_plugins(self):

25

"""

26

Get list of disabled plugin names.

27

28

Returns:

29

list: Disabled plugin names

30

"""

31

32

@property

33

def plugin_manager(self):

34

"""

35

Get Pluggy plugin manager.

36

37

Returns:

38

PluginManager: Plugin manager instance

39

"""

40

41

@property

42

def init_opts(self):

43

"""

44

Get initialization options.

45

46

Returns:

47

dict: Client initialization options

48

"""

49

50

@property

51

def root_uri(self):

52

"""

53

Get workspace root URI.

54

55

Returns:

56

str: Root URI

57

"""

58

59

@property

60

def process_id(self):

61

"""

62

Get client process ID.

63

64

Returns:

65

int: Process ID

66

"""

67

68

@property

69

def capabilities(self):

70

"""

71

Get client capabilities.

72

73

Returns:

74

dict: Client capabilities

75

"""

76

77

def settings(self, document_path=None):

78

"""

79

Get merged settings for document or workspace.

80

81

Parameters:

82

- document_path: str, optional document path for document-specific settings

83

84

Returns:

85

dict: Merged configuration settings

86

"""

87

88

def find_parents(self, path, names):

89

"""

90

Find parent configuration files.

91

92

Parameters:

93

- path: str, starting path

94

- names: list, configuration file names to find

95

96

Returns:

97

list: Found configuration file paths

98

"""

99

100

def plugin_settings(self, plugin, document_path=None):

101

"""

102

Get plugin-specific settings.

103

104

Parameters:

105

- plugin: str, plugin name

106

- document_path: str, optional document path

107

108

Returns:

109

dict: Plugin configuration

110

"""

111

112

def update(self, settings):

113

"""

114

Update LSP settings.

115

116

Parameters:

117

- settings: dict, new settings to merge

118

"""

119

```

120

121

### Configuration Sources

122

123

Configuration resolution follows this hierarchy (later sources override earlier):

124

125

```python { .api }

126

DEFAULT_CONFIG_SOURCES = ["pycodestyle"] # Default configuration sources

127

128

# Configuration file names searched

129

CONFIG_FILE_NAMES = [

130

"pycodestyle.cfg",

131

"setup.cfg",

132

"tox.ini",

133

".flake8"

134

]

135

```

136

137

### PluginManager Class

138

139

Enhanced Pluggy plugin manager with error handling.

140

141

```python { .api }

142

class PluginManager(pluggy.PluginManager):

143

"""

144

Extended PluginManager with enhanced error handling.

145

Wraps hook execution to provide better error reporting.

146

"""

147

```

148

149

## Configuration Schema

150

151

### Server Configuration

152

153

Top-level server settings structure.

154

155

```python { .api }

156

# Server settings schema

157

SERVER_SETTINGS = {

158

"pylsp": {

159

"type": "object",

160

"properties": {

161

"configurationSources": {

162

"type": "array",

163

"items": {"type": "string"},

164

"default": ["pycodestyle"],

165

"description": "Configuration sources to use"

166

},

167

"plugins": {

168

"type": "object",

169

"description": "Plugin-specific settings"

170

},

171

"rope": {

172

"type": "object",

173

"properties": {

174

"extensionModules": {

175

"type": "array",

176

"items": {"type": "string"},

177

"description": "Rope extension modules"

178

},

179

"ropeFolder": {

180

"type": "string",

181

"description": "Rope project folder"

182

}

183

}

184

}

185

}

186

}

187

}

188

```

189

190

### Plugin Configuration

191

192

Standard plugin configuration patterns.

193

194

```python { .api }

195

# Standard plugin settings pattern

196

PLUGIN_SETTINGS_SCHEMA = {

197

"enabled": {

198

"type": "boolean",

199

"default": True,

200

"description": "Enable/disable plugin"

201

},

202

"exclude": {

203

"type": "array",

204

"items": {"type": "string"},

205

"description": "Files/patterns to exclude"

206

},

207

"filename": {

208

"type": "array",

209

"items": {"type": "string"},

210

"description": "Files/patterns to include"

211

}

212

}

213

214

# Linter-specific settings

215

LINTER_SETTINGS_SCHEMA = {

216

"ignore": {

217

"type": "array",

218

"items": {"type": "string"},

219

"description": "Error codes to ignore"

220

},

221

"select": {

222

"type": "array",

223

"items": {"type": "string"},

224

"description": "Error codes to select"

225

},

226

"maxLineLength": {

227

"type": "integer",

228

"description": "Maximum line length"

229

}

230

}

231

232

# Formatter-specific settings

233

FORMATTER_SETTINGS_SCHEMA = {

234

"args": {

235

"type": "array",

236

"items": {"type": "string"},

237

"description": "Additional formatter arguments"

238

}

239

}

240

```

241

242

## Built-in Plugin Settings

243

244

### Jedi Plugins

245

246

Settings for Jedi-based language features.

247

248

```python { .api }

249

JEDI_SETTINGS = {

250

"jedi_completion": {

251

"enabled": True,

252

"include_params": True,

253

"include_class_objects": True,

254

"fuzzy": False,

255

"eager": False,

256

"resolve_at_most": 25,

257

"cache_for": ["pandas", "numpy", "tensorflow", "matplotlib"]

258

},

259

"jedi_definition": {

260

"enabled": True,

261

"follow_imports": True,

262

"follow_builtin_imports": True

263

},

264

"jedi_hover": {

265

"enabled": True

266

},

267

"jedi_references": {

268

"enabled": True

269

},

270

"jedi_signature_help": {

271

"enabled": True

272

},

273

"jedi_symbols": {

274

"enabled": True,

275

"all_scopes": True,

276

"include_import_symbols": True

277

}

278

}

279

```

280

281

### Linter Settings

282

283

Configuration for built-in linters.

284

285

```python { .api }

286

LINTER_SETTINGS = {

287

"pyflakes": {

288

"enabled": True

289

},

290

"pycodestyle": {

291

"enabled": True,

292

"ignore": [],

293

"select": [],

294

"filename": [],

295

"exclude": [],

296

"hangClosing": False,

297

"maxLineLength": 79

298

},

299

"mccabe": {

300

"enabled": True,

301

"threshold": 15

302

},

303

"pydocstyle": {

304

"enabled": False,

305

"ignore": [],

306

"select": [],

307

"convention": None,

308

"addIgnore": [],

309

"addSelect": [],

310

"match": "(?!test_).*\\.py",

311

"matchDir": "[^\\.].*"

312

},

313

"flake8": {

314

"enabled": False,

315

"ignore": [],

316

"select": [],

317

"filename": [],

318

"exclude": [],

319

"maxLineLength": 79,

320

"hangClosing": False,

321

"args": []

322

},

323

"pylint": {

324

"enabled": False,

325

"args": [],

326

"executable": "pylint"

327

}

328

}

329

```

330

331

### Formatter Settings

332

333

Configuration for code formatters.

334

335

```python { .api }

336

FORMATTER_SETTINGS = {

337

"autopep8": {

338

"enabled": True,

339

"args": []

340

},

341

"yapf": {

342

"enabled": True,

343

"args": []

344

},

345

"black": {

346

"enabled": True,

347

"line_length": 88,

348

"cache_config": True

349

}

350

}

351

```

352

353

### Rope Settings

354

355

Configuration for Rope integration.

356

357

```python { .api }

358

ROPE_SETTINGS = {

359

"rope_completion": {

360

"enabled": True,

361

"eager": False

362

},

363

"rope_autoimport": {

364

"enabled": True,

365

"completions": {

366

"enabled": True

367

},

368

"code_actions": {

369

"enabled": True

370

},

371

"memory": False

372

}

373

}

374

```

375

376

## Usage Examples

377

378

### Basic Configuration

379

380

```python

381

from pylsp.config.config import Config

382

383

# Initialize configuration

384

config = Config(

385

root_uri="file:///project",

386

init_opts={"pylsp": {"plugins": {"pyflakes": {"enabled": True}}}},

387

process_id=1234,

388

capabilities={"textDocument": {"completion": {"completionItem": {"snippetSupport": True}}}}

389

)

390

391

# Get workspace settings

392

settings = config.settings()

393

print(settings["pylsp"]["plugins"]["pyflakes"]["enabled"]) # True

394

395

# Get document-specific settings

396

doc_settings = config.settings("/project/src/main.py")

397

398

# Get plugin settings

399

pyflakes_settings = config.plugin_settings("pyflakes", "/project/src/main.py")

400

```

401

402

### Plugin Configuration

403

404

```python

405

# Configure plugin settings

406

config.update({

407

"pylsp": {

408

"plugins": {

409

"pycodestyle": {

410

"enabled": True,

411

"ignore": ["E203", "W503"],

412

"maxLineLength": 88

413

},

414

"flake8": {

415

"enabled": False

416

},

417

"jedi_completion": {

418

"enabled": True,

419

"fuzzy": True,

420

"eager": True

421

}

422

}

423

}

424

})

425

426

# Access updated settings

427

jedi_settings = config.plugin_settings("jedi_completion")

428

print(jedi_settings["fuzzy"]) # True

429

```

430

431

### Configuration File Discovery

432

433

```python

434

# Find configuration files

435

config_files = config.find_parents("/project/src/main.py", [

436

"setup.cfg",

437

"pyproject.toml",

438

".flake8"

439

])

440

441

print(config_files) # ['/project/setup.cfg', '/project/.flake8']

442

```

443

444

### Dynamic Configuration Updates

445

446

```python

447

# Update configuration at runtime

448

config.update({

449

"pylsp": {

450

"configurationSources": ["flake8"],

451

"plugins": {

452

"pycodestyle": {"enabled": False},

453

"flake8": {"enabled": True}

454

}

455

}

456

})

457

458

# Configuration changes take effect immediately

459

settings = config.settings()

460

print(settings["pylsp"]["plugins"]["flake8"]["enabled"]) # True

461

```

462

463

### Custom Plugin Settings

464

465

```python

466

# Define custom plugin with settings

467

@hookimpl

468

def pylsp_settings(config):

469

return {

470

"plugins": {

471

"my_custom_plugin": {

472

"type": "object",

473

"properties": {

474

"enabled": {"type": "boolean", "default": True},

475

"severity": {

476

"type": "string",

477

"enum": ["error", "warning", "info"],

478

"default": "warning"

479

},

480

"patterns": {

481

"type": "array",

482

"items": {"type": "string"},

483

"default": ["*.py"]

484

}

485

}

486

}

487

}

488

}

489

490

# Use custom plugin settings

491

@hookimpl

492

def pylsp_lint(config, workspace, document, is_saved):

493

settings = config.plugin_settings("my_custom_plugin", document.path)

494

495

if not settings.get("enabled", True):

496

return []

497

498

severity_map = {"error": 1, "warning": 2, "info": 3}

499

severity = severity_map.get(settings.get("severity", "warning"), 2)

500

501

# Use settings in plugin logic

502

patterns = settings.get("patterns", ["*.py"])

503

# ... plugin implementation

504

```

505

506

### Multi-level Configuration

507

508

```python

509

# Configuration hierarchy example:

510

# 1. Default plugin settings

511

# 2. User home directory config

512

# 3. Workspace settings (init_opts)

513

# 4. Project config files (setup.cfg, etc.)

514

# 5. Document-specific overrides

515

516

# Each level can override previous levels

517

config.update({

518

"pylsp": {

519

"plugins": {

520

"pycodestyle": {

521

"enabled": True, # Workspace level

522

"maxLineLength": 100 # Override default 79

523

}

524

}

525

}

526

})

527

528

# setup.cfg in project root might further override:

529

# [pycodestyle]

530

# max-line-length = 120

531

# ignore = E203,W503

532

533

# Final resolved settings will have maxLineLength=120

534

final_settings = config.settings("/project/src/module.py")

535

```