CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-monaco-editor

A browser based code editor that powers Visual Studio Code

Pending
Quality

Pending

Does it follow best practices?

Impact

Pending

No eval scenarios have been run

SecuritybySnyk

Pending

The risk profile of this skill

Overview
Eval results
Files

models-and-uris.mddocs/

Models and URIs

Model management, URI handling, and content operations in Monaco Editor.

Core Concepts

Models

Models represent the text content and metadata of files. Each model contains:

  • Text content
  • Language identifier
  • URI for identification
  • Edit history and version tracking
  • Diagnostic markers and decorations

URIs

URIs uniquely identify models and enable features like import resolution and schema validation. Monaco uses a virtual file system approach where each model has a unique URI.

Core Classes

Monaco Editor provides fundamental classes for working with text positions, ranges, and selections.

Position

monaco.Position(lineNumber: number, column: number): Position

Creates a text position (line and column coordinates).

interface Position {
    readonly lineNumber: number;
    readonly column: number;
}

Static Methods:

monaco.Position.isIPosition(obj: any): boolean

Type guard to check if object is a position.

monaco.Position.lift(position: IPosition): Position

Converts IPosition to Position instance.

monaco.Position.compare(a: IPosition, b: IPosition): number

Compares two positions (-1, 0, or 1).

monaco.Position.isBefore(a: IPosition, b: IPosition): boolean

Checks if position a is before position b.

monaco.Position.isBeforeOrEqual(a: IPosition, b: IPosition): boolean

Checks if position a is before or equal to position b.

// Create positions
const pos1 = new monaco.Position(1, 1); // Line 1, column 1
const pos2 = new monaco.Position(2, 5); // Line 2, column 5

// Compare positions
const comparison = monaco.Position.compare(pos1, pos2); // -1 (pos1 is before pos2)
const isBefore = monaco.Position.isBefore(pos1, pos2); // true

Range

monaco.Range(startLineNumber: number, startColumn: number, endLineNumber: number, endColumn: number): Range

Creates a text range from start position to end position.

interface Range {
    readonly startLineNumber: number;
    readonly startColumn: number;  
    readonly endLineNumber: number;
    readonly endColumn: number;
}

Static Methods:

monaco.Range.isEmpty(range: IRange): boolean

Checks if range is empty (start equals end).

monaco.Range.isIRange(obj: any): boolean

Type guard to check if object is a range.

monaco.Range.lift(range: IRange): Range

Converts IRange to Range instance.

monaco.Range.containsPosition(range: IRange, position: IPosition): boolean

Checks if range contains the given position.

monaco.Range.containsRange(range: IRange, otherRange: IRange): boolean

Checks if range fully contains another range.

monaco.Range.intersectRanges(a: IRange, b: IRange): Range | null

Finds intersection of two ranges, returns null if no overlap.

// Create ranges
const range1 = new monaco.Range(1, 1, 1, 10); // Line 1, columns 1-10
const range2 = new monaco.Range(1, 5, 2, 1);  // Line 1 col 5 to line 2 col 1

// Range operations
const isEmpty = monaco.Range.isEmpty(range1); // false
const contains = monaco.Range.containsPosition(range1, new monaco.Position(1, 5)); // true
const intersection = monaco.Range.intersectRanges(range1, range2); // Overlapping portion

Selection

monaco.Selection(startLineNumber: number, startColumn: number, endLineNumber: number, endColumn: number): Selection

Creates a text selection (extends Range with direction).

interface Selection extends Range {
    readonly selectionStartLineNumber: number;
    readonly selectionStartColumn: number;
    readonly positionLineNumber: number;
    readonly positionColumn: number;
}

Static Methods:

monaco.Selection.isISelection(obj: any): boolean

Type guard to check if object is a selection.

monaco.Selection.createWithDirection(
    startLineNumber: number, 
    startColumn: number, 
    endLineNumber: number, 
    endColumn: number, 
    direction: SelectionDirection
): Selection

Creates selection with explicit direction.

Instance Methods:

selection.getDirection(): SelectionDirection

Gets the selection direction.

selection.setEndPosition(endLineNumber: number, endColumn: number): Selection

Creates new selection with different end position.

selection.getPosition(): Position

Gets cursor position (where selection ends).

// Create selections
const selection = new monaco.Selection(1, 1, 1, 10); // Select line 1, columns 1-10

// Selection operations
const direction = selection.getDirection();
const cursorPos = selection.getPosition(); // Position(1, 10)
const newSelection = selection.setEndPosition(2, 5); // Extend to line 2

Model Creation

Creating Text Models

monaco.editor.createModel(
    value: string,
    language?: string,
    uri?: Uri
): ITextModel

Creates a new text model.

Parameters:

  • value: Initial text content
  • language: Language identifier (optional)
  • uri: Unique identifier for the model (optional)

Returns: ITextModel instance

// Basic model creation
const model = monaco.editor.createModel(
    'console.log("Hello world!");',
    'javascript'
);

// Model with specific URI
const model = monaco.editor.createModel(
    'function add(a: number, b: number): number { return a + b; }',
    'typescript',
    monaco.Uri.parse('file:///math.ts')
);

Getting Existing Models

monaco.editor.getModel(uri: Uri): ITextModel | null

Gets an existing model by URI.

monaco.editor.getModels(): ITextModel[]

Gets all existing models.

const uri = monaco.Uri.parse('file:///example.ts');
const model = monaco.editor.getModel(uri);

if (model) {
    console.log('Model found:', model.getValue());
}

URI Management

URI Creation

monaco.Uri.parse(value: string): Uri

Parses a string into a URI.

monaco.Uri.file(path: string): Uri

Creates a file URI from a path.

monaco.Uri.from(components: UriComponents): Uri

Creates a URI from components.

interface UriComponents {
    scheme: string;
    authority?: string;
    path?: string;
    query?: string;
    fragment?: string;
}
// Parse URI from string
const uri1 = monaco.Uri.parse('file:///path/to/file.ts');

// Create file URI
const uri2 = monaco.Uri.file('/path/to/file.ts');

// Create from components
const uri3 = monaco.Uri.from({
    scheme: 'https',
    authority: 'example.com',
    path: '/api/data',
    query: 'format=json'
});

URI Properties and Methods

interface Uri {
    readonly scheme: string;
    readonly authority: string;
    readonly path: string;
    readonly query: string;
    readonly fragment: string;
    readonly fsPath: string;
    
    with(change: UriComponents): Uri;
    toString(skipEncoding?: boolean): string;
    toJSON(): UriComponents;
}
const uri = monaco.Uri.parse('file:///src/main.ts');

console.log(uri.scheme);    // 'file'
console.log(uri.path);      // '/src/main.ts'
console.log(uri.fsPath);    // '/src/main.ts' (filesystem path)

// Create modified URI
const newUri = uri.with({ path: '/src/utils.ts' });

Model Operations

Content Management

model.getValue(eol?: EndOfLinePreference, preserveBOM?: boolean): string

Gets the model content.

model.setValue(newValue: string): void

Sets the model content.

model.getValueLength(): number

Gets the content length.

model.getValueInRange(range: IRange, eol?: EndOfLinePreference): string

Gets content within a specific range.

const model = monaco.editor.createModel('Hello\nWorld', 'text');

// Get full content
const content = model.getValue();

// Get content in range
const range = new monaco.Range(1, 1, 1, 5); // First line, chars 1-5
const partial = model.getValueInRange(range); // 'Hello'

// Set new content
model.setValue('New content');

Language Management

model.getLanguageId(): string

Gets the model's language identifier.

monaco.editor.setModelLanguage(model: ITextModel, languageId: string): void

Sets the model's language.

const model = monaco.editor.createModel('console.log("test")', 'javascript');

console.log(model.getLanguageId()); // 'javascript'

// Change language
monaco.editor.setModelLanguage(model, 'typescript');
console.log(model.getLanguageId()); // 'typescript'

Position and Range Operations

model.getPositionAt(offset: number): Position

Converts character offset to position.

model.getOffsetAt(position: IPosition): number

Converts position to character offset.

model.getLineContent(lineNumber: number): string

Gets the content of a specific line.

model.getLineCount(): number

Gets the number of lines.

model.getLineMaxColumn(lineNumber: number): number

Gets the maximum column for a line.

const model = monaco.editor.createModel('Hello\nWorld\nTest', 'text');

// Position and offset conversions
const position = model.getPositionAt(7); // Position after 'Hello\nW'
console.log(position); // { lineNumber: 2, column: 2 }

const offset = model.getOffsetAt(new monaco.Position(2, 2));
console.log(offset); // 7

// Line operations
console.log(model.getLineCount()); // 3
console.log(model.getLineContent(2)); // 'World'
console.log(model.getLineMaxColumn(1)); // 6 (length of 'Hello' + 1)

Text Editing

Edit Operations

model.pushEditOperations(
    beforeCursorState: Selection[] | null,
    editOperations: IIdentifiedSingleEditOperation[],
    cursorStateComputer?: ICursorStateComputer | null
): Selection[] | null

Applies edit operations to the model.

interface IIdentifiedSingleEditOperation {
    range: IRange;
    text: string | null;
    forceMoveMarkers?: boolean;
}
const model = monaco.editor.createModel('Hello World', 'text');

// Replace 'World' with 'Monaco'
const editOperation = {
    range: new monaco.Range(1, 7, 1, 12), // 'World' range
    text: 'Monaco'
};

model.pushEditOperations([], [editOperation], null);
console.log(model.getValue()); // 'Hello Monaco'

Batch Operations

model.applyEdits(operations: IIdentifiedSingleEditOperation[]): void

Applies multiple edit operations.

const operations = [
    {
        range: new monaco.Range(1, 1, 1, 1),
        text: '// Comment\n'
    },
    {
        range: new monaco.Range(1, 7, 1, 12),
        text: 'Monaco'
    }
];

model.applyEdits(operations);

Version Tracking

Version Information

model.getVersionId(): number

Gets the current version ID.

model.getAlternativeVersionId(): number

Gets the alternative version ID.

const model = monaco.editor.createModel('Initial content', 'text');
console.log(model.getVersionId()); // 1

model.setValue('Modified content');
console.log(model.getVersionId()); // 2

Event Handling

Content Change Events

model.onDidChangeContent(listener: (e: IModelContentChangedEvent) => void): IDisposable

Fired when model content changes.

interface IModelContentChangedEvent {
    readonly changes: IModelContentChange[];
    readonly eol: string;
    readonly versionId: number;
    readonly isUndoing: boolean;
    readonly isRedoing: boolean;
    readonly isFlush: boolean;
}
const disposable = model.onDidChangeContent((e) => {
    console.log('Content changed, version:', e.versionId);
    console.log('Changes:', e.changes);
});

Language Change Events

model.onDidChangeLanguage(listener: (e: IModelLanguageChangedEvent) => void): IDisposable

Fired when model language changes.

Disposal Events

model.onWillDispose(listener: () => void): IDisposable

Fired before model disposal.

Markers and Diagnostics

Setting Markers

monaco.editor.setModelMarkers(
    model: ITextModel,
    owner: string,
    markers: IMarkerData[]
): void

Sets diagnostic markers for a model.

interface IMarkerData {
    severity: MarkerSeverity;
    message: string;
    startLineNumber: number;
    startColumn: number;
    endLineNumber: number;
    endColumn: number;
    code?: string | { value: string; target: Uri };
    source?: string;
    tags?: MarkerTag[];
    relatedInformation?: IRelatedInformation[];
}
enum MarkerSeverity {
    Hint = 1,
    Info = 2,
    Warning = 4,
    Error = 8
}
// Set error markers
monaco.editor.setModelMarkers(model, 'typescript', [
    {
        severity: monaco.MarkerSeverity.Error,
        message: 'Variable is not defined',
        startLineNumber: 1,
        startColumn: 1,
        endLineNumber: 1,
        endColumn: 5,
        code: 'TS2304'
    }
]);

Getting Markers

monaco.editor.getModelMarkers(filter: { owner?: string; resource?: Uri; take?: number }): IMarker[]

Gets markers for models.

// Get all markers for a model
const markers = monaco.editor.getModelMarkers({
    resource: model.getUri()
});

// Get TypeScript-specific markers
const tsMarkers = monaco.editor.getModelMarkers({
    owner: 'typescript'
});

Model Disposal

Disposing Models

model.dispose(): void

Disposes a model and frees resources.

// Always dispose models when done
model.dispose();

Automatic Cleanup

monaco.editor.onDidCreateModel(listener: (model: ITextModel) => void): IDisposable

Fired when a model is created.

monaco.editor.onWillDisposeModel(listener: (model: ITextModel) => void): IDisposable

Fired before a model is disposed.

// Track model lifecycle
monaco.editor.onDidCreateModel((model) => {
    console.log('Model created:', model.getUri().toString());
});

monaco.editor.onWillDisposeModel((model) => {
    console.log('Model disposing:', model.getUri().toString());
});

Core Interface Definitions

IPosition and IRange

interface IPosition {
    readonly lineNumber: number;
    readonly column: number;
}

interface IRange {
    readonly startLineNumber: number;
    readonly startColumn: number;
    readonly endLineNumber: number;
    readonly endColumn: number;
}

interface ISelection extends IRange {
    readonly selectionStartLineNumber: number;
    readonly selectionStartColumn: number;
    readonly positionLineNumber: number;
    readonly positionColumn: number;
}

Editor State Options

interface IEditorStateOptions {
    canUndoRedoOnly?: boolean;
    contributionsState?: boolean;
    cursorState?: boolean;
    viewState?: boolean;
}

Options for controlling what editor state to preserve.

docs

editor-core.md

index.md

languages-and-providers.md

models-and-uris.md

other-languages.md

typescript-language.md

workers-and-environment.md

tile.json