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

file-editor-formatting.mddocs/

File Editor Formatting

File editor formatting capabilities for standalone code files with MIME type-based language detection and format-on-save support.

Capabilities

File Editor Code Formatter

Main class for handling file editor formatting operations.

class JupyterlabFileEditorCodeFormatter extends JupyterlabCodeFormatter {
  constructor(
    client: JupyterlabCodeFormatterClient,
    editorTracker: IEditorTracker
  );

  formatAction(config: any, formatter: string): Promise<void>;
  formatEditor(config: any, context: Context, formatter?: string): Promise<void>;
  applicable(formatter: string, currentWidget: Widget): boolean;
}

Constructor Parameters:

  • client - HTTP client for backend communication
  • editorTracker - JupyterLab file editor tracker

Methods:

  • formatAction() - Formats current editor (wrapper for formatEditor)
  • formatEditor() - Formats the currently active file editor
  • applicable() - Checks if formatter is applicable to current editor context

Usage Examples

Creating File Editor Formatter

import JupyterlabCodeFormatterClient from './client';
import { JupyterlabFileEditorCodeFormatter } from './formatter';
import { IEditorTracker } from '@jupyterlab/fileeditor';

// Create client and formatter
const client = new JupyterlabCodeFormatterClient();
const fileFormatter = new JupyterlabFileEditorCodeFormatter(client, editorTracker);

Format Current Editor

// Format with default formatter for file type
await fileFormatter.formatEditor(config, { saving: false });

// Format with specific formatter
await fileFormatter.formatEditor(config, { saving: false }, 'black');

// Format during save operation
await fileFormatter.formatEditor(config, { saving: true }, 'rustfmt');

Format Action (Wrapper)

// Convenient wrapper for manual formatting
await fileFormatter.formatAction(config, 'black');

Check Formatter Applicability

import { Widget } from '@lumino/widgets';

const currentWidget: Widget = app.shell.currentWidget;
const isApplicable = fileFormatter.applicable('rustfmt', currentWidget);

if (isApplicable) {
  await fileFormatter.formatAction(config, 'rustfmt');
}

Language Detection

MIME Type Mapping

The file editor formatter detects programming languages through MIME type analysis:

// MIME type to language mapping
const mimeTypes = new Map([
  ['text/x-python', 'python'],
  ['application/x-rsrc', 'r'],
  ['application/x-scala', 'scala'],
  ['application/x-rustsrc', 'rust'],
  ['application/x-c++src', 'cpp']
]);

Supported MIME Types:

  • text/x-python → Python files (.py)
  • application/x-rsrc → R files (.r, .R)
  • application/x-scala → Scala files (.scala)
  • application/x-rustsrc → Rust files (.rs)
  • application/x-c++src → C++ files (.cpp, .cxx, .cc)

Language-Specific Default Formatters

Default formatters are configured per programming language:

// Example configuration
const config = {
  preferences: {
    default_formatter: {
      python: ['isort', 'black'],
      r: ['formatR'],
      scala: ['scalafmt'],
      rust: ['rustfmt'],
      cpp: ['astyle']
    }
  }
};

Formatting Process

Editor State Management

The formatter manages editor state during formatting operations:

  1. Working State: Sets working = true to prevent concurrent operations
  2. Content Capture: Gets current editor content via editor.model.sharedModel.source
  3. Backend Communication: Sends code to backend formatters
  4. Content Update: Updates editor with formatted code
  5. State Cleanup: Resets working = false when complete

Error Handling

Comprehensive error handling for file editor operations:

  • Import Errors: Handles missing formatter dependencies gracefully
  • Format Errors: Displays error messages for formatting failures
  • Configuration Errors: Validates formatter configuration
  • Network Errors: Handles backend communication failures
  • Error Suppression: Configurable error display during auto-format on save

Asynchronous Operation

File editor formatting uses promises for non-blocking operations:

// Example of async formatter chain
for (const formatterToUse of formattersToUse) {
  if (formatterToUse === 'noop' || formatterToUse === 'skip') {
    continue;
  }
  
  const code = editor.model.sharedModel.source;
  
  try {
    const result = await this.formatCode(
      [code],
      formatterToUse,
      config[formatterToUse],
      false, // not notebook
      config.cacheFormatters
    );
    
    if (result.code[0].error) {
      // Handle error
    } else {
      // Update editor content
      editor.model.sharedModel.source = result.code[0].code;
    }
  } catch (error) {
    // Handle network/API errors
  }
}

Configuration Options

File Type Configuration

Configure formatters for different file types:

const config = {
  preferences: {
    default_formatter: {
      // Python files
      python: 'black',           // Single formatter
      // or
      python: ['isort', 'black'], // Multiple formatters in order
      
      // R files
      r: 'formatR',
      
      // Rust files
      rust: 'rustfmt',
      
      // C++ files
      cpp: 'astyle'
    }
  },
  
  // Formatter-specific options
  black: {
    line_length: 88,
    string_normalization: true
  },
  
  rustfmt: {
    edition: '2021',
    max_width: 100
  },
  
  astyle: {
    style: 'google',
    indent: 'spaces=2'
  }
};

Format-on-Save Settings

  • formatOnSave: Enable automatic formatting when saving files
  • suppressFormatterErrors: Suppress error dialogs globally
  • suppressFormatterErrorsIFFAutoFormatOnSave: Suppress errors only during auto-save formatting
  • cacheFormatters: Cache formatter availability for performance

Integration with JupyterLab

Document Registry Integration

The file editor formatter integrates with JupyterLab's document registry:

  • Widget Extension: Registers as a widget extension for 'editor' document type
  • Save Event Monitoring: Connects to document save state changes
  • Context Management: Manages document context and editor lifecycle

Menu and Command Integration

File editor formatting is accessible through:

  • Edit Menu: Formatter-specific menu items when editor is active
  • Command Palette: Format commands available for editor contexts
  • Context Menu: Right-click formatting options (if configured)
  • Keyboard Shortcuts: Configurable shortcuts for quick formatting

Settings Integration

File editor settings are managed through JupyterLab's settings system:

  • Live Configuration: Settings changes apply immediately
  • Per-Language Config: Different formatter settings for each language
  • User Preferences: Persistent user configuration across sessions

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