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