mirror of https://github.com/requarks/wiki
parent
97bcc56c65
commit
9e875794cd
@ -0,0 +1,23 @@
|
||||
import EditorWorker from 'monaco-editor/esm/vs/editor/editor.worker?worker'
|
||||
import JsonWorker from 'monaco-editor/esm/vs/language/json/json.worker?worker'
|
||||
import CssWorker from 'monaco-editor/esm/vs/language/css/css.worker?worker'
|
||||
import HtmlWorker from 'monaco-editor/esm/vs/language/html/html.worker?worker'
|
||||
import TsWorker from 'monaco-editor/esm/vs/language/typescript/ts.worker?worker'
|
||||
|
||||
self.MonacoEnvironment = {
|
||||
getWorker (_, label) {
|
||||
if (label === 'json') {
|
||||
return new JsonWorker()
|
||||
}
|
||||
if (label === 'css' || label === 'scss' || label === 'less') {
|
||||
return new CssWorker()
|
||||
}
|
||||
if (label === 'html' || label === 'handlebars' || label === 'razor') {
|
||||
return new HtmlWorker()
|
||||
}
|
||||
if (label === 'typescript' || label === 'javascript') {
|
||||
return new TsWorker()
|
||||
}
|
||||
return new EditorWorker()
|
||||
}
|
||||
}
|
@ -0,0 +1,621 @@
|
||||
// Adapted from https://github.com/trofimander/monaco-markdown/blob/master/src/ts/extHostTypes.ts
|
||||
// by https://github.com/trofimander
|
||||
// MIT Licensed
|
||||
|
||||
// export function values<V = any>(set: Set<V>): V[];
|
||||
// export function values<K = any, V = any>(map: Map<K, V>): V[];
|
||||
export function values (forEachable) {
|
||||
const result = []
|
||||
forEachable.forEach(value => result.push(value))
|
||||
return result
|
||||
}
|
||||
|
||||
export class Position {
|
||||
static Min (...positions) {
|
||||
if (positions.length === 0) {
|
||||
throw new TypeError()
|
||||
}
|
||||
let result = positions[0]
|
||||
for (let i = 1; i < positions.length; i++) {
|
||||
const p = positions[i]
|
||||
if (p.isBefore(result)) {
|
||||
result = p
|
||||
}
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
static Max (...positions) {
|
||||
if (positions.length === 0) {
|
||||
throw new TypeError()
|
||||
}
|
||||
let result = positions[0]
|
||||
for (let i = 1; i < positions.length; i++) {
|
||||
const p = positions[i]
|
||||
if (p.isAfter(result)) {
|
||||
result = p
|
||||
}
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
static isPosition (other) {
|
||||
if (!other) {
|
||||
return false
|
||||
}
|
||||
if (other instanceof Position) {
|
||||
return true
|
||||
}
|
||||
const { line, character } = other
|
||||
if (typeof line === 'number' && typeof character === 'number') {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
get line () {
|
||||
return this._line
|
||||
}
|
||||
|
||||
get character () {
|
||||
return this._character
|
||||
}
|
||||
|
||||
constructor (line, character) {
|
||||
if (line < 0) {
|
||||
throw new Error('line must be non-negative')
|
||||
}
|
||||
if (character < 0) {
|
||||
throw new Error('character must be non-negative')
|
||||
}
|
||||
this._line = line
|
||||
this._character = character
|
||||
}
|
||||
|
||||
isBefore (other) {
|
||||
if (this._line < other._line) {
|
||||
return true
|
||||
}
|
||||
if (other._line < this._line) {
|
||||
return false
|
||||
}
|
||||
return this._character < other._character
|
||||
}
|
||||
|
||||
isBeforeOrEqual (other) {
|
||||
if (this._line < other._line) {
|
||||
return true
|
||||
}
|
||||
if (other._line < this._line) {
|
||||
return false
|
||||
}
|
||||
return this._character <= other._character
|
||||
}
|
||||
|
||||
isAfter (other) {
|
||||
return !this.isBeforeOrEqual(other)
|
||||
}
|
||||
|
||||
isAfterOrEqual (other) {
|
||||
return !this.isBefore(other)
|
||||
}
|
||||
|
||||
isEqual (other) {
|
||||
return this._line === other._line && this._character === other._character
|
||||
}
|
||||
|
||||
compareTo (other) {
|
||||
if (this._line < other._line) {
|
||||
return -1
|
||||
} else if (this._line > other.line) {
|
||||
return 1
|
||||
} else {
|
||||
// equal line
|
||||
if (this._character < other._character) {
|
||||
return -1
|
||||
} else if (this._character > other._character) {
|
||||
return 1
|
||||
} else {
|
||||
// equal line and character
|
||||
return 0
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
translate (lineDeltaOrChange, characterDelta = 0) {
|
||||
if (lineDeltaOrChange === null || characterDelta === null) {
|
||||
throw new Error()
|
||||
}
|
||||
|
||||
let lineDelta
|
||||
if (typeof lineDeltaOrChange === 'undefined') {
|
||||
lineDelta = 0
|
||||
} else if (typeof lineDeltaOrChange === 'number') {
|
||||
lineDelta = lineDeltaOrChange
|
||||
} else {
|
||||
lineDelta = typeof lineDeltaOrChange.lineDelta === 'number' ? lineDeltaOrChange.lineDelta : 0
|
||||
characterDelta = typeof lineDeltaOrChange.characterDelta === 'number' ? lineDeltaOrChange.characterDelta : 0
|
||||
}
|
||||
|
||||
if (lineDelta === 0 && characterDelta === 0) {
|
||||
return this
|
||||
}
|
||||
return new Position(this.line + lineDelta, this.character + characterDelta)
|
||||
}
|
||||
|
||||
with (lineOrChange, character = this.character) {
|
||||
if (lineOrChange === null || character === null) {
|
||||
throw new Error()
|
||||
}
|
||||
|
||||
let line
|
||||
if (typeof lineOrChange === 'undefined') {
|
||||
line = this.line
|
||||
} else if (typeof lineOrChange === 'number') {
|
||||
line = lineOrChange
|
||||
} else {
|
||||
line = typeof lineOrChange.line === 'number' ? lineOrChange.line : this.line
|
||||
character = typeof lineOrChange.character === 'number' ? lineOrChange.character : this.character
|
||||
}
|
||||
|
||||
if (line === this.line && character === this.character) {
|
||||
return this
|
||||
}
|
||||
return new Position(line, character)
|
||||
}
|
||||
|
||||
toJSON () {
|
||||
return { line: this.line, character: this.character }
|
||||
}
|
||||
}
|
||||
|
||||
export class Range {
|
||||
static isRange (thing) {
|
||||
if (thing instanceof Range) {
|
||||
return true
|
||||
}
|
||||
if (!thing) {
|
||||
return false
|
||||
}
|
||||
return Position.isPosition(thing.start) && Position.isPosition(thing.end)
|
||||
}
|
||||
|
||||
get start () {
|
||||
return this._start
|
||||
}
|
||||
|
||||
get end () {
|
||||
return this._end
|
||||
}
|
||||
|
||||
constructor (startLineOrStart, startColumnOrEnd, endLine, endColumn) {
|
||||
let start
|
||||
let end
|
||||
|
||||
if (typeof startLineOrStart === 'number' && typeof startColumnOrEnd === 'number' && typeof endLine === 'number' && typeof endColumn === 'number') {
|
||||
start = new Position(startLineOrStart, startColumnOrEnd)
|
||||
end = new Position(endLine, endColumn)
|
||||
} else if (startLineOrStart instanceof Position && startColumnOrEnd instanceof Position) {
|
||||
start = startLineOrStart
|
||||
end = startColumnOrEnd
|
||||
}
|
||||
|
||||
if (!start || !end) {
|
||||
throw new Error('Invalid arguments')
|
||||
}
|
||||
|
||||
if (start.isBefore(end)) {
|
||||
this._start = start
|
||||
this._end = end
|
||||
} else {
|
||||
this._start = end
|
||||
this._end = start
|
||||
}
|
||||
}
|
||||
|
||||
contains (positionOrRange) {
|
||||
if (positionOrRange instanceof Range) {
|
||||
return this.contains(positionOrRange._start) &&
|
||||
this.contains(positionOrRange._end)
|
||||
} else if (positionOrRange instanceof Position) {
|
||||
if (positionOrRange.isBefore(this._start)) {
|
||||
return false
|
||||
}
|
||||
if (this._end.isBefore(positionOrRange)) {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
isEqual (other) {
|
||||
return this._start.isEqual(other._start) && this._end.isEqual(other._end)
|
||||
}
|
||||
|
||||
intersection (other) {
|
||||
const start = Position.Max(other.start, this._start)
|
||||
const end = Position.Min(other.end, this._end)
|
||||
if (start.isAfter(end)) {
|
||||
// this happens when there is no overlap:
|
||||
// |-----|
|
||||
// |----|
|
||||
return undefined
|
||||
}
|
||||
return new Range(start, end)
|
||||
}
|
||||
|
||||
union (other) {
|
||||
if (this.contains(other)) {
|
||||
return this
|
||||
} else if (other.contains(this)) {
|
||||
return other
|
||||
}
|
||||
const start = Position.Min(other.start, this._start)
|
||||
const end = Position.Max(other.end, this.end)
|
||||
return new Range(start, end)
|
||||
}
|
||||
|
||||
get isEmpty () {
|
||||
return this._start.isEqual(this._end)
|
||||
}
|
||||
|
||||
get isSingleLine () {
|
||||
return this._start.line === this._end.line
|
||||
}
|
||||
|
||||
with (startOrChange, end = this.end) {
|
||||
if (startOrChange === null || end === null) {
|
||||
throw new Error()
|
||||
}
|
||||
|
||||
let start
|
||||
if (!startOrChange) {
|
||||
start = this.start
|
||||
} else if (Position.isPosition(startOrChange)) {
|
||||
start = startOrChange
|
||||
} else {
|
||||
start = startOrChange.start || this.start
|
||||
end = startOrChange.end || this.end
|
||||
}
|
||||
|
||||
if (start.isEqual(this._start) && end.isEqual(this.end)) {
|
||||
return this
|
||||
}
|
||||
return new Range(start, end)
|
||||
}
|
||||
|
||||
toJSON () {
|
||||
return [this.start, this.end]
|
||||
}
|
||||
}
|
||||
|
||||
export class Selection extends Range {
|
||||
static isSelection (thing) {
|
||||
if (thing instanceof Selection) {
|
||||
return true
|
||||
}
|
||||
if (!thing) {
|
||||
return false
|
||||
}
|
||||
return Range.isRange(thing) &&
|
||||
Position.isPosition(thing.anchor) &&
|
||||
Position.isPosition(thing.active) &&
|
||||
typeof thing.isReversed === 'boolean'
|
||||
}
|
||||
|
||||
get anchor () {
|
||||
return this._anchor
|
||||
}
|
||||
|
||||
get active () {
|
||||
return this._active
|
||||
}
|
||||
|
||||
constructor (anchorLineOrAnchor, anchorColumnOrActive, activeLine, activeColumn) {
|
||||
let anchor
|
||||
let active
|
||||
|
||||
if (typeof anchorLineOrAnchor === 'number' && typeof anchorColumnOrActive === 'number' && typeof activeLine === 'number' && typeof activeColumn === 'number') {
|
||||
anchor = new Position(anchorLineOrAnchor, anchorColumnOrActive)
|
||||
active = new Position(activeLine, activeColumn)
|
||||
} else if (anchorLineOrAnchor instanceof Position && anchorColumnOrActive instanceof Position) {
|
||||
anchor = anchorLineOrAnchor
|
||||
active = anchorColumnOrActive
|
||||
}
|
||||
|
||||
if (!anchor || !active) {
|
||||
throw new Error('Invalid arguments')
|
||||
}
|
||||
|
||||
super(anchor, active)
|
||||
|
||||
this._anchor = anchor
|
||||
this._active = active
|
||||
}
|
||||
|
||||
get isReversed () {
|
||||
return this._anchor === this._end
|
||||
}
|
||||
|
||||
toJSON () {
|
||||
return {
|
||||
start: this.start,
|
||||
end: this.end,
|
||||
active: this.active,
|
||||
anchor: this.anchor
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export const EndOfLine = {
|
||||
LF: 1,
|
||||
CRLF: 2
|
||||
}
|
||||
|
||||
export class TextEdit {
|
||||
static isTextEdit (thing) {
|
||||
if (thing instanceof TextEdit) {
|
||||
return true
|
||||
}
|
||||
if (!thing) {
|
||||
return false
|
||||
}
|
||||
return Range.isRange(thing) && typeof thing.newText === 'string'
|
||||
}
|
||||
|
||||
static replace (range, newText) {
|
||||
return new TextEdit(range, newText)
|
||||
}
|
||||
|
||||
static insert (position, newText) {
|
||||
return TextEdit.replace(new Range(position, position), newText)
|
||||
}
|
||||
|
||||
static delete (range) {
|
||||
return TextEdit.replace(range, '')
|
||||
}
|
||||
|
||||
static setEndOfLine (eol) {
|
||||
const ret = new TextEdit(new Range(new Position(0, 0), new Position(0, 0)), '')
|
||||
ret.newEol = eol
|
||||
return ret
|
||||
}
|
||||
|
||||
get range () {
|
||||
return this._range
|
||||
}
|
||||
|
||||
set range (value) {
|
||||
if (value && !Range.isRange(value)) {
|
||||
throw new Error('range')
|
||||
}
|
||||
this._range = value
|
||||
}
|
||||
|
||||
get newText () {
|
||||
return this._newText || ''
|
||||
}
|
||||
|
||||
set newText (value) {
|
||||
if (value && typeof value !== 'string') {
|
||||
throw new Error('newText')
|
||||
}
|
||||
this._newText = value
|
||||
}
|
||||
|
||||
get newEol () {
|
||||
return this._newEol
|
||||
}
|
||||
|
||||
set newEol (value) {
|
||||
if (value && typeof value !== 'number') {
|
||||
throw new Error('newEol')
|
||||
}
|
||||
this._newEol = value
|
||||
}
|
||||
|
||||
constructor (range, newText) {
|
||||
this.range = range
|
||||
this._newText = newText
|
||||
}
|
||||
|
||||
toJSON () {
|
||||
return {
|
||||
range: this.range,
|
||||
newText: this.newText,
|
||||
newEol: this._newEol
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export class WorkspaceEdit {
|
||||
constructor () {
|
||||
this._edits = []
|
||||
}
|
||||
|
||||
renameFile (from, to, options) {
|
||||
this._edits.push({ _type: 1, from, to, options })
|
||||
}
|
||||
|
||||
createFile (uri, options) {
|
||||
this._edits.push({ _type: 1, from: undefined, to: uri, options })
|
||||
}
|
||||
|
||||
deleteFile (uri, options) {
|
||||
this._edits.push({ _type: 1, from: uri, to: undefined, options })
|
||||
}
|
||||
|
||||
replace (uri, range, newText) {
|
||||
this._edits.push({ _type: 2, uri, edit: new TextEdit(range, newText) })
|
||||
}
|
||||
|
||||
insert (resource, position, newText) {
|
||||
this.replace(resource, new Range(position, position), newText)
|
||||
}
|
||||
|
||||
delete (resource, range) {
|
||||
this.replace(resource, range, '')
|
||||
}
|
||||
|
||||
has (uri) {
|
||||
for (const edit of this._edits) {
|
||||
if (edit._type === 2 && edit.uri.toString() === uri.toString()) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
set (uri, edits) {
|
||||
if (!edits) {
|
||||
// remove all text edits for `uri`
|
||||
for (let i = 0; i < this._edits.length; i++) {
|
||||
const element = this._edits[i]
|
||||
if (element._type === 2 && element.uri.toString() === uri.toString()) {
|
||||
this._edits[i] = undefined // will be coalesced down below
|
||||
}
|
||||
}
|
||||
// this._edits = coalesce(this._edits); TODO
|
||||
} else {
|
||||
// append edit to the end
|
||||
for (const edit of edits) {
|
||||
if (edit) {
|
||||
this._edits.push({ _type: 2, uri, edit })
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
get (uri) {
|
||||
const res = []
|
||||
for (const candidate of this._edits) {
|
||||
if (candidate._type === 2 && candidate.uri.toString() === uri.toString()) {
|
||||
res.push(candidate.edit)
|
||||
}
|
||||
}
|
||||
return res
|
||||
}
|
||||
|
||||
entries () {
|
||||
const textEdits = new Map()
|
||||
for (const candidate of this._edits) {
|
||||
if (candidate._type === 2) {
|
||||
let textEdit = textEdits.get(candidate.uri.toString())
|
||||
if (!textEdit) {
|
||||
textEdit = [candidate.uri, []]
|
||||
textEdits.set(candidate.uri.toString(), textEdit)
|
||||
}
|
||||
textEdit[1].push(candidate.edit)
|
||||
}
|
||||
}
|
||||
return values(textEdits)
|
||||
}
|
||||
|
||||
_allEntries () {
|
||||
const res = []
|
||||
for (const edit of this._edits) {
|
||||
if (edit._type === 1) {
|
||||
res.push([edit.from, edit.to, edit.options])
|
||||
} else {
|
||||
res.push([edit.uri, [edit.edit]])
|
||||
}
|
||||
}
|
||||
return res
|
||||
}
|
||||
|
||||
get size () {
|
||||
return this.entries().length
|
||||
}
|
||||
|
||||
toJSON () {
|
||||
return this.entries()
|
||||
}
|
||||
}
|
||||
|
||||
export const TextEditorRevealType = {
|
||||
Default: 0,
|
||||
InCenter: 1,
|
||||
InCenterIfOutsideViewport: 2,
|
||||
AtTop: 3
|
||||
}
|
||||
|
||||
export const TextEditorSelectionChangeKind = {
|
||||
Keyboard: 1,
|
||||
Mouse: 2,
|
||||
Command: 3
|
||||
}
|
||||
|
||||
export class SnippetString {
|
||||
static isSnippetString (thing) {
|
||||
if (thing instanceof SnippetString) {
|
||||
return true
|
||||
}
|
||||
if (!thing) {
|
||||
return false
|
||||
}
|
||||
return typeof thing.value === 'string'
|
||||
}
|
||||
|
||||
static _escape (value) {
|
||||
return value.replace(/\$|}|\\/g, '\\$&')
|
||||
}
|
||||
|
||||
constructor (value) {
|
||||
this._tabstop = 1
|
||||
this.value = value || ''
|
||||
}
|
||||
|
||||
appendText (string) {
|
||||
this.value += SnippetString._escape(string)
|
||||
return this
|
||||
}
|
||||
|
||||
appendTabstop (number = this._tabstop++) {
|
||||
this.value += '$'
|
||||
this.value += number
|
||||
return this
|
||||
}
|
||||
|
||||
appendPlaceholder (value, number = this._tabstop++) {
|
||||
if (typeof value === 'function') {
|
||||
const nested = new SnippetString()
|
||||
nested._tabstop = this._tabstop
|
||||
value(nested)
|
||||
this._tabstop = nested._tabstop
|
||||
value = nested.value
|
||||
} else {
|
||||
value = SnippetString._escape(value)
|
||||
}
|
||||
|
||||
this.value += '${'
|
||||
this.value += number
|
||||
this.value += ':'
|
||||
this.value += value
|
||||
this.value += '}'
|
||||
|
||||
return this
|
||||
}
|
||||
|
||||
appendVariable (name, defaultValue) {
|
||||
if (typeof defaultValue === 'function') {
|
||||
const nested = new SnippetString()
|
||||
nested._tabstop = this._tabstop
|
||||
defaultValue(nested)
|
||||
this._tabstop = nested._tabstop
|
||||
defaultValue = nested.value
|
||||
} else if (typeof defaultValue === 'string') {
|
||||
defaultValue = defaultValue.replace(/\$|}/g, '\\$&')
|
||||
}
|
||||
|
||||
this.value += '${'
|
||||
this.value += name
|
||||
if (defaultValue) {
|
||||
this.value += ':'
|
||||
this.value += defaultValue
|
||||
}
|
||||
this.value += '}'
|
||||
|
||||
return this
|
||||
}
|
||||
}
|
Loading…
Reference in new issue