or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

code-formatters.mdconfiguration-system.mdfile-editor-formatting.mdfrontend-integration.mdhttp-api-client.mdhttp-api-handlers.mdindex.mdnotebook-formatting.md

file-editor-formatting.mddocs/

0

# File Editor Formatting

1

2

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

3

4

## Capabilities

5

6

### File Editor Code Formatter

7

8

Main class for handling file editor formatting operations.

9

10

```typescript { .api }

11

class JupyterlabFileEditorCodeFormatter extends JupyterlabCodeFormatter {

12

constructor(

13

client: JupyterlabCodeFormatterClient,

14

editorTracker: IEditorTracker

15

);

16

17

formatAction(config: any, formatter: string): Promise<void>;

18

formatEditor(config: any, context: Context, formatter?: string): Promise<void>;

19

applicable(formatter: string, currentWidget: Widget): boolean;

20

}

21

```

22

23

**Constructor Parameters**:

24

- `client` - HTTP client for backend communication

25

- `editorTracker` - JupyterLab file editor tracker

26

27

**Methods**:

28

- `formatAction()` - Formats current editor (wrapper for formatEditor)

29

- `formatEditor()` - Formats the currently active file editor

30

- `applicable()` - Checks if formatter is applicable to current editor context

31

32

## Usage Examples

33

34

### Creating File Editor Formatter

35

36

```typescript

37

import JupyterlabCodeFormatterClient from './client';

38

import { JupyterlabFileEditorCodeFormatter } from './formatter';

39

import { IEditorTracker } from '@jupyterlab/fileeditor';

40

41

// Create client and formatter

42

const client = new JupyterlabCodeFormatterClient();

43

const fileFormatter = new JupyterlabFileEditorCodeFormatter(client, editorTracker);

44

```

45

46

### Format Current Editor

47

48

```typescript

49

// Format with default formatter for file type

50

await fileFormatter.formatEditor(config, { saving: false });

51

52

// Format with specific formatter

53

await fileFormatter.formatEditor(config, { saving: false }, 'black');

54

55

// Format during save operation

56

await fileFormatter.formatEditor(config, { saving: true }, 'rustfmt');

57

```

58

59

### Format Action (Wrapper)

60

61

```typescript

62

// Convenient wrapper for manual formatting

63

await fileFormatter.formatAction(config, 'black');

64

```

65

66

### Check Formatter Applicability

67

68

```typescript

69

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

70

71

const currentWidget: Widget = app.shell.currentWidget;

72

const isApplicable = fileFormatter.applicable('rustfmt', currentWidget);

73

74

if (isApplicable) {

75

await fileFormatter.formatAction(config, 'rustfmt');

76

}

77

```

78

79

## Language Detection

80

81

### MIME Type Mapping

82

83

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

84

85

```typescript

86

// MIME type to language mapping

87

const mimeTypes = new Map([

88

['text/x-python', 'python'],

89

['application/x-rsrc', 'r'],

90

['application/x-scala', 'scala'],

91

['application/x-rustsrc', 'rust'],

92

['application/x-c++src', 'cpp']

93

]);

94

```

95

96

**Supported MIME Types**:

97

- `text/x-python` → Python files (.py)

98

- `application/x-rsrc` → R files (.r, .R)

99

- `application/x-scala` → Scala files (.scala)

100

- `application/x-rustsrc` → Rust files (.rs)

101

- `application/x-c++src` → C++ files (.cpp, .cxx, .cc)

102

103

### Language-Specific Default Formatters

104

105

Default formatters are configured per programming language:

106

107

```typescript

108

// Example configuration

109

const config = {

110

preferences: {

111

default_formatter: {

112

python: ['isort', 'black'],

113

r: ['formatR'],

114

scala: ['scalafmt'],

115

rust: ['rustfmt'],

116

cpp: ['astyle']

117

}

118

}

119

};

120

```

121

122

## Formatting Process

123

124

### Editor State Management

125

126

The formatter manages editor state during formatting operations:

127

128

1. **Working State**: Sets `working = true` to prevent concurrent operations

129

2. **Content Capture**: Gets current editor content via `editor.model.sharedModel.source`

130

3. **Backend Communication**: Sends code to backend formatters

131

4. **Content Update**: Updates editor with formatted code

132

5. **State Cleanup**: Resets `working = false` when complete

133

134

### Error Handling

135

136

Comprehensive error handling for file editor operations:

137

138

- **Import Errors**: Handles missing formatter dependencies gracefully

139

- **Format Errors**: Displays error messages for formatting failures

140

- **Configuration Errors**: Validates formatter configuration

141

- **Network Errors**: Handles backend communication failures

142

- **Error Suppression**: Configurable error display during auto-format on save

143

144

### Asynchronous Operation

145

146

File editor formatting uses promises for non-blocking operations:

147

148

```typescript

149

// Example of async formatter chain

150

for (const formatterToUse of formattersToUse) {

151

if (formatterToUse === 'noop' || formatterToUse === 'skip') {

152

continue;

153

}

154

155

const code = editor.model.sharedModel.source;

156

157

try {

158

const result = await this.formatCode(

159

[code],

160

formatterToUse,

161

config[formatterToUse],

162

false, // not notebook

163

config.cacheFormatters

164

);

165

166

if (result.code[0].error) {

167

// Handle error

168

} else {

169

// Update editor content

170

editor.model.sharedModel.source = result.code[0].code;

171

}

172

} catch (error) {

173

// Handle network/API errors

174

}

175

}

176

```

177

178

## Configuration Options

179

180

### File Type Configuration

181

182

Configure formatters for different file types:

183

184

```typescript

185

const config = {

186

preferences: {

187

default_formatter: {

188

// Python files

189

python: 'black', // Single formatter

190

// or

191

python: ['isort', 'black'], // Multiple formatters in order

192

193

// R files

194

r: 'formatR',

195

196

// Rust files

197

rust: 'rustfmt',

198

199

// C++ files

200

cpp: 'astyle'

201

}

202

},

203

204

// Formatter-specific options

205

black: {

206

line_length: 88,

207

string_normalization: true

208

},

209

210

rustfmt: {

211

edition: '2021',

212

max_width: 100

213

},

214

215

astyle: {

216

style: 'google',

217

indent: 'spaces=2'

218

}

219

};

220

```

221

222

### Format-on-Save Settings

223

224

- **formatOnSave**: Enable automatic formatting when saving files

225

- **suppressFormatterErrors**: Suppress error dialogs globally

226

- **suppressFormatterErrorsIFFAutoFormatOnSave**: Suppress errors only during auto-save formatting

227

- **cacheFormatters**: Cache formatter availability for performance

228

229

## Integration with JupyterLab

230

231

### Document Registry Integration

232

233

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

234

235

- **Widget Extension**: Registers as a widget extension for 'editor' document type

236

- **Save Event Monitoring**: Connects to document save state changes

237

- **Context Management**: Manages document context and editor lifecycle

238

239

### Menu and Command Integration

240

241

File editor formatting is accessible through:

242

243

- **Edit Menu**: Formatter-specific menu items when editor is active

244

- **Command Palette**: Format commands available for editor contexts

245

- **Context Menu**: Right-click formatting options (if configured)

246

- **Keyboard Shortcuts**: Configurable shortcuts for quick formatting

247

248

### Settings Integration

249

250

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

251

252

- **Live Configuration**: Settings changes apply immediately

253

- **Per-Language Config**: Different formatter settings for each language

254

- **User Preferences**: Persistent user configuration across sessions