CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/pypi-jupyterlab-code-formatter

A JupyterLab extension to facilitate invocation of code formatters for multiple programming languages.

Pending
Overview
Eval results
Files

configuration-system.mddocs/

Configuration System

JupyterLab settings integration with support for formatter-specific options, format-on-save settings, error handling preferences, and language-specific default formatters.

Capabilities

Settings Schema

The extension provides a comprehensive JSON schema for configuration.

Schema Location: schema/settings.json

Core Configuration Options

Format-on-Save Settings

{
  "formatOnSave": {
    "type": "boolean",
    "default": false,
    "description": "Automatically format code when saving files"
  }
}

Caching Settings

{
  "cacheFormatters": {
    "type": "boolean", 
    "default": true,
    "description": "Cache formatter availability checks for better performance"
  }
}

Error Handling Settings

{
  "suppressFormatterErrors": {
    "type": "boolean",
    "default": false,
    "description": "Suppress formatter error dialogs globally"
  },
  "suppressFormatterErrorsIFFAutoFormatOnSave": {
    "type": "boolean",
    "default": true,
    "description": "Suppress errors only during automatic format-on-save"
  }
}

Default Formatter Configuration

Language-specific default formatter settings.

{
  "preferences": {
    "type": "object",
    "properties": {
      "default_formatter": {
        "type": "object",
        "properties": {
          "python": {
            "anyOf": [
              { "type": "string" },
              { "type": "array", "items": { "type": "string" } }
            ],
            "default": ["isort", "black"]
          },
          "R": {
            "anyOf": [
              { "type": "string" },
              { "type": "array", "items": { "type": "string" } }
            ]
          }
        },
        "additionalProperties": true
      }
    }
  }
}

Formatter-Specific Options

Black Formatter Options

{
  "black": {
    "type": "object",
    "properties": {
      "line_length": {
        "type": "number",
        "default": 88,
        "description": "Maximum line length"
      },
      "string_normalization": {
        "type": "boolean",
        "default": true,
        "description": "Normalize string quotes"
      },
      "magic_trailing_comma": {
        "type": "boolean",
        "default": true,
        "description": "Use trailing commas"
      },
      "experimental_string_processing": {
        "type": "boolean",
        "default": false,
        "description": "Enable experimental string processing"
      },
      "preview": {
        "type": "boolean",
        "default": false,
        "description": "Enable preview features"
      }
    }
  }
}

Blue Formatter Options

{
  "blue": {
    "type": "object",
    "properties": {
      "line_length": {
        "type": "number",
        "default": 88
      },
      "string_normalization": {
        "type": "boolean",
        "default": true
      }
    }
  }
}

Autopep8 Formatter Options

{
  "autopep8": {
    "type": "object",
    "properties": {
      "max_line_length": {
        "type": "number",
        "default": 79
      },
      "aggressive": {
        "type": "number",
        "default": 0,
        "description": "Aggressiveness level (0-2)"
      }
    }
  }
}

YAPF Formatter Options

{
  "yapf": {
    "type": "object",
    "properties": {
      "based_on_style": {
        "type": "string",
        "default": "pep8",
        "enum": ["pep8", "google", "chromium", "facebook"]
      },
      "column_limit": {
        "type": "number",
        "default": 79
      },
      "indent_width": {
        "type": "number",
        "default": 4
      }
    }
  }
}

Isort Formatter Options

{
  "isort": {
    "type": "object",
    "properties": {
      "multi_line_output": {
        "type": "number",
        "default": 3,
        "description": "Multi-line output mode"
      },
      "include_trailing_comma": {
        "type": "boolean",
        "default": true
      },
      "force_grid_wrap": {
        "type": "number",
        "default": 0
      },
      "use_parentheses": {
        "type": "boolean",
        "default": true
      },
      "line_length": {
        "type": "number",
        "default": 88
      }
    }
  }
}

Ruff Formatter Options

{
  "ruff": {
    "type": "object",
    "properties": {
      "line_length": {
        "type": "number",
        "default": 88
      },
      "select": {
        "type": "array",
        "items": { "type": "string" },
        "description": "Rule codes to enable"
      },
      "ignore": {
        "type": "array", 
        "items": { "type": "string" },
        "description": "Rule codes to ignore"
      }
    }
  }
}

Usage Examples

Complete Configuration Example

{
  "formatOnSave": true,
  "cacheFormatters": true,
  "suppressFormatterErrors": false,
  "suppressFormatterErrorsIFFAutoFormatOnSave": true,
  
  "preferences": {
    "default_formatter": {
      "python": ["isort", "black"],
      "r": "formatR",
      "scala": "scalafmt",
      "rust": "rustfmt",
      "cpp": "astyle"
    }
  },
  
  "black": {
    "line_length": 88,
    "string_normalization": true,
    "magic_trailing_comma": true,
    "experimental_string_processing": false,
    "preview": false
  },
  
  "isort": {
    "multi_line_output": 3,
    "include_trailing_comma": true,
    "force_grid_wrap": 0,
    "use_parentheses": true,
    "line_length": 88,
    "profile": "black"
  },
  
  "yapf": {
    "based_on_style": "google",
    "column_limit": 100,
    "indent_width": 2
  },
  
  "ruff": {
    "line_length": 88,
    "select": ["E", "F", "W"],
    "ignore": ["E501"]
  }
}

TypeScript Configuration Access

import { ISettingRegistry } from '@jupyterlab/settingregistry';

// In the extension class
private async setupSettings() {
  const settings = await this.settingRegistry.load('jupyterlab_code_formatter:settings');
  
  const onSettingsUpdated = (jsettings: ISettingRegistry.ISettings) => {
    this.config = jsettings.composite;
  };
  
  settings.changed.connect(onSettingsUpdated);
  onSettingsUpdated(settings);
}

// Access configuration values
if (this.config.formatOnSave) {
  // Perform format on save
}

const blackOptions = this.config.black || {};
const defaultFormatters = this.config.preferences?.default_formatter?.python || [];

Python Backend Configuration Usage

# Configuration is passed from frontend to backend via HTTP API
def format_code(self, code: str, notebook: bool, **options) -> str:
    # Options contain formatter-specific configuration
    line_length = options.get('line_length', 88)
    string_normalization = options.get('string_normalization', True)
    
    # Use options to configure formatter
    black_mode = black.FileMode(
        line_length=line_length,
        string_normalization=string_normalization,
        **options
    )
    
    return black.format_str(code, mode=black_mode)

Settings Integration

JupyterLab Settings System

The extension integrates with JupyterLab's settings system:

  • Settings Registry: Uses ISettingRegistry service
  • Schema Validation: Automatic validation against JSON schema
  • Live Updates: Settings changes trigger immediate updates
  • Persistence: Settings saved automatically across sessions
  • UI Integration: Settings accessible through JupyterLab settings editor

Settings UI

Users can modify settings through:

  1. Settings Menu: JupyterLab → Settings → Advanced Settings Editor
  2. Settings Panel: Dedicated "Jupyterlab Code Formatter" section
  3. JSON Editor: Direct JSON editing with schema validation
  4. Form Interface: Auto-generated form fields from schema

Default Values

The extension provides sensible defaults:

  • formatOnSave: false (user must opt-in)
  • cacheFormatters: true (performance optimization)
  • suppressFormatterErrors: false (show errors by default)
  • Default Formatters: Python uses ["isort", "black"]
  • Formatter Options: Use tool defaults (e.g., Black line length 88)

Language-Specific Configuration

Python Configuration

{
  "preferences": {
    "default_formatter": {
      "python": ["isort", "black"]  // Multiple formatters in order
    }
  },
  "black": { "line_length": 88 },
  "isort": { "profile": "black" }
}

R Configuration

{
  "preferences": {
    "default_formatter": {
      "R": "styler"  // Single formatter
    }
  },
  "styler": {
    "scope": "tokens",
    "indent_by": 2
  }
}

Multi-Language Configuration

{
  "preferences": {
    "default_formatter": {
      "python": ["isort", "black"],
      "r": "formatR", 
      "scala": "scalafmt",
      "rust": "rustfmt",
      "cpp": "astyle"
    }
  }
}

Error Handling Configuration

Error Suppression Strategies

  1. Show All Errors: Default behavior for manual formatting
  2. Suppress Auto-Format Errors: Hide errors during format-on-save
  3. Suppress All Errors: Hide all formatter errors (not recommended)

Configuration Examples

{
  // Show all errors (default)
  "suppressFormatterErrors": false,
  "suppressFormatterErrorsIFFAutoFormatOnSave": false,
  
  // Suppress errors only during auto-format (recommended)
  "suppressFormatterErrors": false,
  "suppressFormatterErrorsIFFAutoFormatOnSave": true,
  
  // Suppress all errors (not recommended)
  "suppressFormatterErrors": true,
  "suppressFormatterErrorsIFFAutoFormatOnSave": true
}

Performance Configuration

Caching Options

{
  "cacheFormatters": true  // Cache formatter availability checks
}

Benefits of caching:

  • Faster Startup: Reduced initialization time
  • Better Performance: Avoid repeated dependency checks
  • Improved UX: Faster menu updates and command execution

Format-on-Save Performance

{
  "formatOnSave": true,
  "suppressFormatterErrorsIFFAutoFormatOnSave": true  // Avoid error dialogs during save
}

This configuration enables automatic formatting while preventing disruptive error dialogs during the save process.

Install with Tessl CLI

npx tessl i tessl/pypi-jupyterlab-code-formatter

docs

code-formatters.md

configuration-system.md

file-editor-formatting.md

frontend-integration.md

http-api-client.md

http-api-handlers.md

index.md

notebook-formatting.md

tile.json