@lvce-editor/editor-worker 9.1.0 → 10.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/editorWorkerMain.js +1768 -1671
- package/package.json +2 -2
package/dist/editorWorkerMain.js
CHANGED
|
@@ -1066,6 +1066,39 @@ const createMockRpc = ({
|
|
|
1066
1066
|
return mockRpc;
|
|
1067
1067
|
};
|
|
1068
1068
|
|
|
1069
|
+
const Backspace = 1;
|
|
1070
|
+
const Tab$1 = 2;
|
|
1071
|
+
const Enter = 3;
|
|
1072
|
+
const Escape = 8;
|
|
1073
|
+
const Space$1 = 9;
|
|
1074
|
+
const End = 255;
|
|
1075
|
+
const Home = 12;
|
|
1076
|
+
const LeftArrow = 13;
|
|
1077
|
+
const UpArrow = 14;
|
|
1078
|
+
const RightArrow = 15;
|
|
1079
|
+
const DownArrow = 16;
|
|
1080
|
+
const Delete = 18;
|
|
1081
|
+
const KeyA = 29;
|
|
1082
|
+
const KeyC = 31;
|
|
1083
|
+
const KeyD = 32;
|
|
1084
|
+
const KeyF = 34;
|
|
1085
|
+
const KeyH = 36;
|
|
1086
|
+
const KeyJ = 38;
|
|
1087
|
+
const KeyK = 39;
|
|
1088
|
+
const KeyL = 40;
|
|
1089
|
+
const KeyO = 43;
|
|
1090
|
+
const KeyV = 50;
|
|
1091
|
+
const KeyX = 52;
|
|
1092
|
+
const KeyZ = 54;
|
|
1093
|
+
const F2 = 58;
|
|
1094
|
+
const F3 = 59;
|
|
1095
|
+
const F4 = 60;
|
|
1096
|
+
const F12 = 68;
|
|
1097
|
+
const Period = 87;
|
|
1098
|
+
const Slash$1 = 88;
|
|
1099
|
+
const BracketLeft = 90;
|
|
1100
|
+
const BracketRight = 92;
|
|
1101
|
+
|
|
1069
1102
|
const CodeGenerator = 1;
|
|
1070
1103
|
const ColorPicker$1 = 2;
|
|
1071
1104
|
const Completion = 3;
|
|
@@ -1075,6 +1108,10 @@ const Hover = 6;
|
|
|
1075
1108
|
const Rename$1 = 7;
|
|
1076
1109
|
const SourceAction$1 = 8;
|
|
1077
1110
|
|
|
1111
|
+
const CtrlCmd = 1 << 11 >>> 0;
|
|
1112
|
+
const Shift = 1 << 10 >>> 0;
|
|
1113
|
+
const Alt$1 = 1 << 9 >>> 0;
|
|
1114
|
+
|
|
1078
1115
|
const DebugWorker = 55;
|
|
1079
1116
|
const EditorWorker = 99;
|
|
1080
1117
|
const ExtensionHostWorker = 44;
|
|
@@ -1774,574 +1811,1272 @@ const setDeltaY$2 = (state, value) => {
|
|
|
1774
1811
|
};
|
|
1775
1812
|
};
|
|
1776
1813
|
|
|
1777
|
-
const
|
|
1778
|
-
|
|
1779
|
-
|
|
1814
|
+
const Link$1 = 'Link';
|
|
1815
|
+
const Function = 'Function';
|
|
1816
|
+
const Parameter = 'Parameter';
|
|
1817
|
+
const Type = 'Type';
|
|
1818
|
+
const VariableName = 'VariableName';
|
|
1819
|
+
const Class = 'Class';
|
|
1820
|
+
|
|
1821
|
+
const Link = 1;
|
|
1822
|
+
const Ts2816 = 2816;
|
|
1823
|
+
const Ts2817 = 2817;
|
|
1824
|
+
const Ts2824 = 2824;
|
|
1825
|
+
const Ts2825 = 2825;
|
|
1826
|
+
const Ts2856 = 2956;
|
|
1827
|
+
const Ts2857 = 2857;
|
|
1828
|
+
const Ts3072 = 3072;
|
|
1829
|
+
const Ts3073 = 3073;
|
|
1830
|
+
const Ts3077 = 3077;
|
|
1831
|
+
const Ts3088 = 3088;
|
|
1832
|
+
const Ts1792 = 1792;
|
|
1833
|
+
const Ts1793 = 1793;
|
|
1834
|
+
const Ts512 = 512;
|
|
1835
|
+
const Ts513 = 513;
|
|
1836
|
+
const Ts769 = 769;
|
|
1837
|
+
const Ts1024 = 1024;
|
|
1838
|
+
const Ts1536 = 1536;
|
|
1839
|
+
const Ts1537 = 1537;
|
|
1840
|
+
const Ts1544 = 1544;
|
|
1841
|
+
const Ts1545 = 1545;
|
|
1842
|
+
const Ts2048 = 2048;
|
|
1843
|
+
const Ts2049 = 2049;
|
|
1844
|
+
const Ts2056 = 2056;
|
|
1845
|
+
const Ts2057 = 2057;
|
|
1846
|
+
const Ts2064 = 2064;
|
|
1847
|
+
const Ts2080 = 2080;
|
|
1848
|
+
const Ts2081 = 2081;
|
|
1849
|
+
const Ts2088 = 2088;
|
|
1850
|
+
const Ts2089 = 2089;
|
|
1851
|
+
const Ts2313 = 2313;
|
|
1852
|
+
const Ts2560 = 2560;
|
|
1853
|
+
const Ts2561 = 2561;
|
|
1854
|
+
const Ts2569 = 2569;
|
|
1855
|
+
const Ts2584 = 2584;
|
|
1856
|
+
const Ts256 = 256;
|
|
1857
|
+
const Ts257 = 257;
|
|
1858
|
+
const Ts272 = 272;
|
|
1859
|
+
|
|
1860
|
+
const getDecorationClassName = type => {
|
|
1861
|
+
switch (type) {
|
|
1862
|
+
case Link:
|
|
1863
|
+
return Link$1;
|
|
1864
|
+
case Ts2816:
|
|
1865
|
+
case Ts2817:
|
|
1866
|
+
case Ts2824:
|
|
1867
|
+
case Ts2825:
|
|
1868
|
+
case Ts2856:
|
|
1869
|
+
case Ts2857:
|
|
1870
|
+
case Ts3072:
|
|
1871
|
+
case Ts3073:
|
|
1872
|
+
case Ts3077:
|
|
1873
|
+
case Ts3088:
|
|
1874
|
+
return Function;
|
|
1875
|
+
case Ts1792:
|
|
1876
|
+
case Ts1793:
|
|
1877
|
+
return Parameter;
|
|
1878
|
+
case Ts512:
|
|
1879
|
+
case Ts513:
|
|
1880
|
+
case Ts769:
|
|
1881
|
+
case Ts1024:
|
|
1882
|
+
case Ts1536:
|
|
1883
|
+
case Ts1537:
|
|
1884
|
+
case Ts1544:
|
|
1885
|
+
case Ts1545:
|
|
1886
|
+
return Type;
|
|
1887
|
+
case Ts2048:
|
|
1888
|
+
case Ts2049:
|
|
1889
|
+
case Ts2056:
|
|
1890
|
+
case Ts2057:
|
|
1891
|
+
case Ts2064:
|
|
1892
|
+
case Ts2080:
|
|
1893
|
+
case Ts2081:
|
|
1894
|
+
case Ts2088:
|
|
1895
|
+
case Ts2089:
|
|
1896
|
+
case Ts2313:
|
|
1897
|
+
case Ts2560:
|
|
1898
|
+
case Ts2561:
|
|
1899
|
+
case Ts2569:
|
|
1900
|
+
case Ts2584:
|
|
1901
|
+
return VariableName;
|
|
1902
|
+
case Ts256:
|
|
1903
|
+
case Ts257:
|
|
1904
|
+
case Ts272:
|
|
1905
|
+
return Class;
|
|
1906
|
+
default:
|
|
1907
|
+
return `Unknown-${type}`;
|
|
1780
1908
|
}
|
|
1781
|
-
return lines.split('\n');
|
|
1782
1909
|
};
|
|
1783
1910
|
|
|
1784
|
-
|
|
1911
|
+
const deepCopy = value => {
|
|
1912
|
+
return structuredClone(value);
|
|
1913
|
+
};
|
|
1785
1914
|
|
|
1786
|
-
|
|
1787
|
-
|
|
1788
|
-
|
|
1789
|
-
|
|
1790
|
-
|
|
1791
|
-
|
|
1792
|
-
|
|
1793
|
-
|
|
1915
|
+
const getInitialLineState = initialLineState => {
|
|
1916
|
+
return deepCopy(initialLineState);
|
|
1917
|
+
};
|
|
1918
|
+
|
|
1919
|
+
const state$8 = {
|
|
1920
|
+
warned: []
|
|
1921
|
+
};
|
|
1922
|
+
const flattenTokensArray = tokens => {
|
|
1923
|
+
const flattened = [];
|
|
1924
|
+
for (const token of tokens) {
|
|
1925
|
+
object(token);
|
|
1926
|
+
flattened.push(token.type, token.length);
|
|
1794
1927
|
}
|
|
1795
|
-
|
|
1796
|
-
|
|
1928
|
+
return flattened;
|
|
1929
|
+
};
|
|
1930
|
+
const warnDeprecatedArrayReturn = (languageId, fn) => {
|
|
1931
|
+
if (state$8.warned.includes(fn)) {
|
|
1932
|
+
return;
|
|
1933
|
+
}
|
|
1934
|
+
state$8.warned.push(fn);
|
|
1935
|
+
console.warn(`tokenizers without hasArrayReturn=false are deprecated (language ${languageId})`);
|
|
1936
|
+
};
|
|
1937
|
+
const safeTokenizeLine = (languageId, tokenizeLine, line, lineStateAtStart, hasArrayReturn) => {
|
|
1938
|
+
try {
|
|
1939
|
+
const lineState = tokenizeLine(line, lineStateAtStart);
|
|
1940
|
+
if (!lineState?.tokens || !lineState.state) {
|
|
1941
|
+
throw new Error('invalid tokenization result');
|
|
1942
|
+
}
|
|
1943
|
+
if (!hasArrayReturn) {
|
|
1944
|
+
warnDeprecatedArrayReturn(languageId, tokenizeLine);
|
|
1945
|
+
// workaround for old tokenizers
|
|
1946
|
+
lineState.tokens = flattenTokensArray(lineState.tokens);
|
|
1947
|
+
}
|
|
1948
|
+
return lineState;
|
|
1949
|
+
} catch (error) {
|
|
1950
|
+
console.error(error);
|
|
1951
|
+
return {
|
|
1952
|
+
tokens: [/* type */0, /* length */line.length],
|
|
1953
|
+
lineState: lineStateAtStart
|
|
1954
|
+
};
|
|
1797
1955
|
}
|
|
1798
1956
|
};
|
|
1799
1957
|
|
|
1800
1958
|
/**
|
|
1801
|
-
*
|
|
1802
|
-
* can only support limited number of items due to the maximum call stack size limit.
|
|
1959
|
+
* @enum number
|
|
1803
1960
|
*/
|
|
1804
|
-
|
|
1805
|
-
|
|
1806
|
-
const result = array.splice(start, deleteCount);
|
|
1807
|
-
insertInto(array, start, newItems);
|
|
1808
|
-
return result;
|
|
1961
|
+
const State = {
|
|
1962
|
+
TopLevelContent: 1
|
|
1809
1963
|
};
|
|
1810
1964
|
|
|
1811
|
-
|
|
1812
|
-
|
|
1965
|
+
/**
|
|
1966
|
+
* @enum number
|
|
1967
|
+
*/
|
|
1968
|
+
const TokenType = {
|
|
1969
|
+
Text: 1
|
|
1970
|
+
};
|
|
1971
|
+
const TokenMap = {
|
|
1972
|
+
[TokenType.Text]: 'Text'
|
|
1973
|
+
};
|
|
1974
|
+
const initialLineState = {
|
|
1975
|
+
state: State.TopLevelContent
|
|
1976
|
+
};
|
|
1977
|
+
const hasArrayReturn = true;
|
|
1978
|
+
const tokenizeLine = (line, lineState) => {
|
|
1979
|
+
return {
|
|
1980
|
+
tokens: [TokenType.Text, line.length],
|
|
1981
|
+
state: lineState.state
|
|
1982
|
+
};
|
|
1813
1983
|
};
|
|
1814
1984
|
|
|
1815
|
-
const
|
|
1985
|
+
const TokenizePlainText = {
|
|
1986
|
+
__proto__: null,
|
|
1987
|
+
State,
|
|
1988
|
+
TokenMap,
|
|
1989
|
+
TokenType,
|
|
1990
|
+
hasArrayReturn,
|
|
1991
|
+
initialLineState,
|
|
1992
|
+
tokenizeLine
|
|
1993
|
+
};
|
|
1816
1994
|
|
|
1817
|
-
|
|
1818
|
-
const
|
|
1819
|
-
|
|
1820
|
-
|
|
1821
|
-
|
|
1822
|
-
|
|
1823
|
-
return whitespaceMatch[0];
|
|
1995
|
+
let enabled$1 = false;
|
|
1996
|
+
const setEnabled$1 = value => {
|
|
1997
|
+
enabled$1 = value;
|
|
1998
|
+
};
|
|
1999
|
+
const getEnabled$1 = () => {
|
|
2000
|
+
return enabled$1;
|
|
1824
2001
|
};
|
|
1825
2002
|
|
|
1826
|
-
|
|
1827
|
-
|
|
1828
|
-
|
|
1829
|
-
|
|
1830
|
-
|
|
1831
|
-
|
|
1832
|
-
|
|
1833
|
-
|
|
1834
|
-
|
|
1835
|
-
const endRowIndex = change.end.rowIndex + linesDelta;
|
|
1836
|
-
const startColumnIndex = change.start.columnIndex;
|
|
1837
|
-
const endColumnIndex = change.end.columnIndex;
|
|
1838
|
-
const {
|
|
1839
|
-
inserted
|
|
1840
|
-
} = change;
|
|
1841
|
-
const {
|
|
1842
|
-
deleted
|
|
1843
|
-
} = change;
|
|
1844
|
-
number(startRowIndex);
|
|
1845
|
-
number(endRowIndex);
|
|
1846
|
-
number(startColumnIndex);
|
|
1847
|
-
number(endColumnIndex);
|
|
1848
|
-
array(inserted);
|
|
1849
|
-
array(deleted);
|
|
1850
|
-
if (startRowIndex === endRowIndex) {
|
|
1851
|
-
if (inserted.length === 0) {
|
|
1852
|
-
const line = newLines[startRowIndex];
|
|
1853
|
-
const before = line.slice(0, startColumnIndex);
|
|
1854
|
-
const after = line.slice(endColumnIndex);
|
|
1855
|
-
newLines[startRowIndex] = before + after;
|
|
1856
|
-
} else if (inserted.length === 1) {
|
|
1857
|
-
const line = newLines[startRowIndex];
|
|
1858
|
-
let before = line.slice(0, startColumnIndex);
|
|
1859
|
-
if (startColumnIndex > line.length) {
|
|
1860
|
-
before += ' '.repeat(startColumnIndex - line.length);
|
|
1861
|
-
}
|
|
1862
|
-
const after = line.slice(endColumnIndex);
|
|
1863
|
-
const text = inserted[0];
|
|
1864
|
-
newLines[startRowIndex] = before + text + after;
|
|
1865
|
-
} else {
|
|
1866
|
-
const line = newLines[startRowIndex];
|
|
1867
|
-
const before = line.slice(0, startColumnIndex) + inserted[0];
|
|
1868
|
-
const after = inserted.at(-1) + line.slice(endColumnIndex);
|
|
1869
|
-
spliceLargeArray(newLines, startRowIndex, deleted.length, [before, ...inserted.slice(1, -1), after]);
|
|
1870
|
-
// TODO only do this once after all edits, not inside loop
|
|
1871
|
-
textDocument.maxLineY = Math.min(textDocument.numberOfVisibleLines, newLines.length);
|
|
1872
|
-
}
|
|
1873
|
-
} else {
|
|
1874
|
-
if (inserted.length === 1) {
|
|
1875
|
-
const before = newLines[startRowIndex].slice(0, startColumnIndex) + inserted[0];
|
|
1876
|
-
const after = endRowIndex >= newLines.length ? '' : newLines[endRowIndex].slice(endColumnIndex);
|
|
1877
|
-
spliceLargeArray(newLines, startRowIndex, deleted.length, [before + after]);
|
|
1878
|
-
} else {
|
|
1879
|
-
const before = newLines[startRowIndex].slice(0, startColumnIndex) + inserted[0];
|
|
1880
|
-
const middle = inserted.slice(1, -1);
|
|
1881
|
-
const after = inserted.at(-1) + (endRowIndex >= newLines.length ? '' : newLines[endRowIndex].slice(endColumnIndex));
|
|
1882
|
-
spliceLargeArray(newLines, startRowIndex, deleted.length, [before, ...middle, after]);
|
|
1883
|
-
}
|
|
1884
|
-
// TODO only do this once after all edits, not inside loop
|
|
1885
|
-
textDocument.maxLineY = Math.min(textDocument.numberOfVisibleLines, textDocument.lines.length);
|
|
1886
|
-
}
|
|
1887
|
-
linesDelta += inserted.length - deleted.length;
|
|
1888
|
-
}
|
|
1889
|
-
return newLines;
|
|
2003
|
+
const {
|
|
2004
|
+
set: set$5,
|
|
2005
|
+
invoke: invoke$7} = SyntaxHighlightingWorker;
|
|
2006
|
+
|
|
2007
|
+
const state$7 = {
|
|
2008
|
+
tokenizers: Object.create(null),
|
|
2009
|
+
pending: Object.create(null)};
|
|
2010
|
+
const has = languageId => {
|
|
2011
|
+
return languageId in state$7.tokenizers;
|
|
1890
2012
|
};
|
|
1891
|
-
const
|
|
1892
|
-
|
|
2013
|
+
const set$4 = (languageId, tokenizer) => {
|
|
2014
|
+
state$7.tokenizers[languageId] = tokenizer;
|
|
1893
2015
|
};
|
|
1894
|
-
const
|
|
1895
|
-
return
|
|
2016
|
+
const get$3 = languageId => {
|
|
2017
|
+
return state$7.tokenizers[languageId];
|
|
2018
|
+
};
|
|
2019
|
+
const isPending = languageId => {
|
|
2020
|
+
return languageId in state$7.pending;
|
|
1896
2021
|
};
|
|
1897
2022
|
|
|
1898
|
-
|
|
1899
|
-
const
|
|
1900
|
-
|
|
1901
|
-
const startRowIndex = range.start.rowIndex;
|
|
1902
|
-
const startColumnIndex = range.start.columnIndex;
|
|
1903
|
-
const endRowIndex = Math.min(range.end.rowIndex, textDocument.lines.length - 1);
|
|
1904
|
-
const endColumnIndex = range.end.columnIndex;
|
|
1905
|
-
if (startRowIndex === endRowIndex) {
|
|
1906
|
-
return [textDocument.lines[startRowIndex].slice(startColumnIndex, endColumnIndex)];
|
|
1907
|
-
}
|
|
1908
|
-
const selectedLines = [textDocument.lines[startRowIndex].slice(startColumnIndex), ...textDocument.lines.slice(startRowIndex + 1, endRowIndex), textDocument.lines[endRowIndex].slice(0, endColumnIndex)];
|
|
1909
|
-
return selectedLines;
|
|
2023
|
+
const tokenMaps = Object.create(null);
|
|
2024
|
+
const set$3 = (languageId, tokenMap) => {
|
|
2025
|
+
tokenMaps[languageId] = tokenMap;
|
|
1910
2026
|
};
|
|
1911
|
-
const
|
|
1912
|
-
|
|
1913
|
-
number(positionRowIndex);
|
|
1914
|
-
number(positionColumnIndex);
|
|
1915
|
-
let offset = 0;
|
|
1916
|
-
let rowIndex = 0;
|
|
1917
|
-
const {
|
|
1918
|
-
lines
|
|
1919
|
-
} = textDocument;
|
|
1920
|
-
const max = Math.min(positionRowIndex, textDocument.lines.length);
|
|
1921
|
-
while (rowIndex < max) {
|
|
1922
|
-
offset += lines[rowIndex].length + 1;
|
|
1923
|
-
rowIndex++;
|
|
1924
|
-
}
|
|
1925
|
-
offset += positionColumnIndex;
|
|
1926
|
-
return offset;
|
|
2027
|
+
const get$2 = languageId => {
|
|
2028
|
+
return tokenMaps[languageId] || {};
|
|
1927
2029
|
};
|
|
1928
|
-
|
|
1929
|
-
|
|
1930
|
-
|
|
1931
|
-
|
|
1932
|
-
|
|
1933
|
-
let rowIndex = 0;
|
|
1934
|
-
const {
|
|
1935
|
-
lines
|
|
1936
|
-
} = textDocument;
|
|
1937
|
-
const max = Math.min(positionRowIndex, textDocument.lines.length);
|
|
1938
|
-
while (rowIndex < max) {
|
|
1939
|
-
offset += lines[rowIndex].length + 1;
|
|
1940
|
-
rowIndex++;
|
|
2030
|
+
|
|
2031
|
+
// TODO loadTokenizer should be invoked from renderer worker
|
|
2032
|
+
const loadTokenizer = async (languageId, tokenizePath) => {
|
|
2033
|
+
if (!tokenizePath) {
|
|
2034
|
+
return;
|
|
1941
2035
|
}
|
|
1942
|
-
|
|
1943
|
-
|
|
1944
|
-
|
|
1945
|
-
|
|
1946
|
-
|
|
1947
|
-
lines
|
|
1948
|
-
} = textDocument;
|
|
1949
|
-
let rowIndex = 0;
|
|
1950
|
-
let columnIndex = 0;
|
|
1951
|
-
let currentOffset = 0;
|
|
1952
|
-
while (rowIndex < lines.length && currentOffset < offset) {
|
|
1953
|
-
currentOffset += lines[rowIndex].length + 1;
|
|
1954
|
-
rowIndex++;
|
|
2036
|
+
if (getEnabled$1()) {
|
|
2037
|
+
// @ts-ignore
|
|
2038
|
+
const tokenMap = await invoke$7('Tokenizer.load', languageId, tokenizePath);
|
|
2039
|
+
set$3(languageId, tokenMap);
|
|
2040
|
+
return;
|
|
1955
2041
|
}
|
|
1956
|
-
|
|
1957
|
-
|
|
1958
|
-
|
|
1959
|
-
|
|
1960
|
-
|
|
1961
|
-
|
|
2042
|
+
try {
|
|
2043
|
+
// TODO check that tokenizer is valid
|
|
2044
|
+
// 1. tokenizeLine should be of type function
|
|
2045
|
+
// 2. getTokenClass should be of type function
|
|
2046
|
+
const tokenizer = await import(tokenizePath);
|
|
2047
|
+
if (typeof tokenizer.tokenizeLine !== 'function') {
|
|
2048
|
+
console.warn(`tokenizer.tokenizeLine should be a function in "${tokenizePath}"`);
|
|
2049
|
+
return;
|
|
2050
|
+
}
|
|
2051
|
+
if (!tokenizer.TokenMap || typeof tokenizer.TokenMap !== 'object' || Array.isArray(tokenizer.TokenMap)) {
|
|
2052
|
+
console.warn(`tokenizer.TokenMap should be an object in "${tokenizePath}"`);
|
|
2053
|
+
return;
|
|
2054
|
+
}
|
|
2055
|
+
set$3(languageId, tokenizer.TokenMap);
|
|
2056
|
+
set$4(languageId, tokenizer);
|
|
2057
|
+
} catch (error) {
|
|
2058
|
+
// TODO better error handling
|
|
2059
|
+
console.error(error);
|
|
1962
2060
|
}
|
|
1963
|
-
return {
|
|
1964
|
-
rowIndex,
|
|
1965
|
-
columnIndex
|
|
1966
|
-
};
|
|
1967
2061
|
};
|
|
1968
|
-
|
|
1969
|
-
|
|
1970
|
-
|
|
1971
|
-
const second = selections[i + 1];
|
|
1972
|
-
const third = selections[i + 2];
|
|
1973
|
-
const fourth = selections[i + 3];
|
|
1974
|
-
if (first > third || first === third && second >= fourth) {
|
|
1975
|
-
return [third, fourth, first, second, 1];
|
|
2062
|
+
const getTokenizer = languageId => {
|
|
2063
|
+
if (has(languageId)) {
|
|
2064
|
+
return get$3(languageId);
|
|
1976
2065
|
}
|
|
1977
|
-
|
|
1978
|
-
|
|
1979
|
-
|
|
1980
|
-
const EmptyString = '';
|
|
1981
|
-
const NewLine = '\n';
|
|
1982
|
-
const Space$1 = ' ';
|
|
1983
|
-
const Tab$1 = '\t';
|
|
1984
|
-
const DoubleQuote$1 = '"';
|
|
1985
|
-
|
|
1986
|
-
const getTabCount = string => {
|
|
1987
|
-
let count = 0;
|
|
1988
|
-
for (const element of string) {
|
|
1989
|
-
if (element === Tab$1) {
|
|
1990
|
-
count++;
|
|
1991
|
-
}
|
|
2066
|
+
if (isPending(languageId)) {
|
|
2067
|
+
return TokenizePlainText;
|
|
1992
2068
|
}
|
|
1993
|
-
return
|
|
1994
|
-
};
|
|
1995
|
-
|
|
1996
|
-
const measureTextWidthFast = (text, charWidth) => {
|
|
1997
|
-
return text.length * charWidth;
|
|
1998
|
-
};
|
|
1999
|
-
|
|
2000
|
-
const getFontString = (fontWeight, fontSize, fontFamily) => {
|
|
2001
|
-
return `${fontWeight} ${fontSize}px ${fontFamily}`;
|
|
2069
|
+
return TokenizePlainText;
|
|
2002
2070
|
};
|
|
2003
2071
|
|
|
2004
|
-
const
|
|
2005
|
-
|
|
2072
|
+
const tokenizers = Object.create(null);
|
|
2073
|
+
const set$2 = (id, value) => {
|
|
2074
|
+
tokenizers[id] = value;
|
|
2006
2075
|
};
|
|
2007
|
-
|
|
2008
|
-
|
|
2009
|
-
const canvas = new OffscreenCanvas(0, 0);
|
|
2010
|
-
const ctx = /** @type {OffscreenCanvasRenderingContext2D} */canvas.getContext('2d');
|
|
2011
|
-
if (!ctx) {
|
|
2012
|
-
throw new Error('Failed to get canvas context 2d');
|
|
2013
|
-
}
|
|
2014
|
-
return ctx;
|
|
2076
|
+
const get$1 = id => {
|
|
2077
|
+
return tokenizers[id] || TokenizePlainText;
|
|
2015
2078
|
};
|
|
2016
2079
|
|
|
2017
|
-
const
|
|
2018
|
-
|
|
2019
|
-
|
|
2020
|
-
|
|
2021
|
-
|
|
2022
|
-
|
|
2080
|
+
const getTokensViewportEmbedded = (langageId, lines, lineCache, linesWithEmbed) => {
|
|
2081
|
+
const tokenizersToLoad = [];
|
|
2082
|
+
const embeddedResults = [];
|
|
2083
|
+
let topContext;
|
|
2084
|
+
for (const index of linesWithEmbed) {
|
|
2085
|
+
const result = lineCache[index + 1];
|
|
2086
|
+
const line = lines[index];
|
|
2087
|
+
if (result.embeddedLanguage) {
|
|
2088
|
+
const {
|
|
2089
|
+
embeddedLanguage,
|
|
2090
|
+
embeddedLanguageStart,
|
|
2091
|
+
embeddedLanguageEnd
|
|
2092
|
+
} = result;
|
|
2093
|
+
const embeddedTokenizer = getTokenizer(embeddedLanguage);
|
|
2094
|
+
if (embeddedLanguageStart !== line.length && embeddedTokenizer && embeddedTokenizer !== TokenizePlainText) {
|
|
2095
|
+
const isFull = embeddedLanguageStart === 0 && embeddedLanguageEnd === line.length;
|
|
2096
|
+
const partialLine = line.slice(embeddedLanguageStart, embeddedLanguageEnd);
|
|
2097
|
+
const embedResult = safeTokenizeLine(langageId, embeddedTokenizer.tokenizeLine, partialLine, topContext || getInitialLineState(embeddedTokenizer.initialLineState), embeddedTokenizer.hasArrayReturn);
|
|
2098
|
+
topContext = embedResult;
|
|
2099
|
+
result.embeddedResultIndex = embeddedResults.length;
|
|
2100
|
+
embeddedResults.push({
|
|
2101
|
+
result: embedResult,
|
|
2102
|
+
TokenMap: embeddedTokenizer.TokenMap,
|
|
2103
|
+
isFull
|
|
2104
|
+
});
|
|
2105
|
+
} else if (line.length === 0) {
|
|
2106
|
+
const embedResult = {
|
|
2107
|
+
tokens: []
|
|
2108
|
+
};
|
|
2109
|
+
result.embeddedResultIndex = embeddedResults.length;
|
|
2110
|
+
embeddedResults.push({
|
|
2111
|
+
result: embedResult,
|
|
2112
|
+
isFull: true,
|
|
2113
|
+
TokenMap: []
|
|
2114
|
+
});
|
|
2115
|
+
} else {
|
|
2116
|
+
tokenizersToLoad.push(embeddedLanguage);
|
|
2117
|
+
embeddedResults.push({
|
|
2118
|
+
result: {},
|
|
2119
|
+
isFull: false,
|
|
2120
|
+
TokenMap: []
|
|
2121
|
+
});
|
|
2122
|
+
topContext = undefined;
|
|
2123
|
+
}
|
|
2124
|
+
} else {
|
|
2125
|
+
topContext = undefined;
|
|
2126
|
+
}
|
|
2023
2127
|
}
|
|
2024
|
-
|
|
2025
|
-
|
|
2128
|
+
return {
|
|
2129
|
+
tokenizersToLoad,
|
|
2130
|
+
embeddedResults
|
|
2131
|
+
};
|
|
2026
2132
|
};
|
|
2027
|
-
|
|
2028
|
-
|
|
2029
|
-
const ctx = getOrCreate$4(createMeasureContext);
|
|
2030
|
-
return ctx;
|
|
2133
|
+
const getTokenizeEndIndex = (invalidStartIndex, endLineIndex, tokenizeStartIndex) => {
|
|
2134
|
+
return invalidStartIndex < endLineIndex ? endLineIndex : tokenizeStartIndex;
|
|
2031
2135
|
};
|
|
2032
2136
|
|
|
2033
|
-
// TODO
|
|
2137
|
+
// TODO only send changed lines to renderer process instead of all lines in viewport
|
|
2138
|
+
const getTokensViewport = (editor, startLineIndex, endLineIndex) => {
|
|
2139
|
+
const {
|
|
2140
|
+
invalidStartIndex,
|
|
2141
|
+
lineCache,
|
|
2142
|
+
tokenizerId,
|
|
2143
|
+
lines,
|
|
2144
|
+
languageId
|
|
2145
|
+
} = editor;
|
|
2146
|
+
const tokenizer = get$1(tokenizerId);
|
|
2147
|
+
const {
|
|
2148
|
+
hasArrayReturn,
|
|
2149
|
+
tokenizeLine,
|
|
2150
|
+
initialLineState
|
|
2151
|
+
} = tokenizer;
|
|
2152
|
+
const tokenizeStartIndex = invalidStartIndex;
|
|
2153
|
+
const tokenizeEndIndex = getTokenizeEndIndex(invalidStartIndex, endLineIndex, tokenizeStartIndex);
|
|
2154
|
+
const tokenizersToLoad = [];
|
|
2155
|
+
const embeddedResults = [];
|
|
2156
|
+
const linesWithEmbed = [];
|
|
2157
|
+
for (let i = tokenizeStartIndex; i < tokenizeEndIndex; i++) {
|
|
2158
|
+
const lineState = i === 0 ? getInitialLineState(initialLineState) : lineCache[i];
|
|
2159
|
+
const line = lines[i];
|
|
2160
|
+
const result = safeTokenizeLine(languageId, tokenizeLine, line, lineState, hasArrayReturn);
|
|
2161
|
+
// TODO if lineCacheEnd matches the one before, skip tokenizing lines after
|
|
2162
|
+
lineCache[i + 1] = result;
|
|
2163
|
+
if (result.embeddedLanguage) {
|
|
2164
|
+
result.embeddedResultIndex = linesWithEmbed.length;
|
|
2165
|
+
linesWithEmbed.push(i);
|
|
2166
|
+
}
|
|
2167
|
+
}
|
|
2168
|
+
const visibleLines = lineCache.slice(startLineIndex + 1, endLineIndex + 1);
|
|
2169
|
+
if (linesWithEmbed.length > 0) {
|
|
2170
|
+
const {
|
|
2171
|
+
tokenizersToLoad,
|
|
2172
|
+
embeddedResults
|
|
2173
|
+
} = getTokensViewportEmbedded(languageId, lines, lineCache, linesWithEmbed);
|
|
2174
|
+
// TODO support lineCache with embedded content
|
|
2175
|
+
editor.invalidStartIndex = 0;
|
|
2176
|
+
return {
|
|
2177
|
+
tokens: visibleLines,
|
|
2178
|
+
tokenizersToLoad,
|
|
2179
|
+
embeddedResults
|
|
2180
|
+
};
|
|
2181
|
+
}
|
|
2182
|
+
editor.invalidStartIndex = Math.max(invalidStartIndex, tokenizeEndIndex);
|
|
2183
|
+
return {
|
|
2184
|
+
tokens: visibleLines,
|
|
2185
|
+
tokenizersToLoad,
|
|
2186
|
+
embeddedResults
|
|
2187
|
+
};
|
|
2188
|
+
};
|
|
2034
2189
|
|
|
2035
|
-
const
|
|
2036
|
-
|
|
2037
|
-
|
|
2038
|
-
|
|
2039
|
-
|
|
2040
|
-
|
|
2041
|
-
|
|
2042
|
-
|
|
2043
|
-
|
|
2190
|
+
const sentLines = Object.create(null);
|
|
2191
|
+
|
|
2192
|
+
// TODO only send changed lines to renderer process instead of all lines in viewport
|
|
2193
|
+
const getTokensViewport2 = async (editor, startLineIndex, endLineIndex, syncIncremental) => {
|
|
2194
|
+
if (getEnabled$1()) {
|
|
2195
|
+
if (syncIncremental) {
|
|
2196
|
+
const {
|
|
2197
|
+
invalidStartIndex,
|
|
2198
|
+
lines,
|
|
2199
|
+
languageId,
|
|
2200
|
+
id
|
|
2201
|
+
} = editor;
|
|
2202
|
+
let hasLinesToSend = true;
|
|
2203
|
+
let linesToSend = lines;
|
|
2204
|
+
if (sentLines[id] === lines) {
|
|
2205
|
+
hasLinesToSend = false;
|
|
2206
|
+
linesToSend = [];
|
|
2207
|
+
} else {
|
|
2208
|
+
sentLines[id] = lines;
|
|
2209
|
+
}
|
|
2210
|
+
const slimEditor = {
|
|
2211
|
+
languageId,
|
|
2212
|
+
invalidStartIndex
|
|
2213
|
+
};
|
|
2214
|
+
return invoke$7('GetTokensViewport.getTokensViewport', slimEditor,
|
|
2215
|
+
// @ts-ignore
|
|
2216
|
+
startLineIndex, endLineIndex, hasLinesToSend, id, linesToSend);
|
|
2217
|
+
}
|
|
2218
|
+
// TODO only send needed lines of text
|
|
2219
|
+
// @ts-ignore
|
|
2220
|
+
return invoke$7('GetTokensViewport.getTokensViewport', editor, startLineIndex, endLineIndex, true, editor.id, editor.lines);
|
|
2044
2221
|
}
|
|
2045
|
-
|
|
2046
|
-
const fontString = getFontString(fontWeight, fontSize, fontFamily);
|
|
2047
|
-
const ctx = getContext();
|
|
2048
|
-
ctx.letterSpacing = letterSpacingString;
|
|
2049
|
-
ctx.font = fontString;
|
|
2050
|
-
const metrics = ctx.measureText(text);
|
|
2051
|
-
const {
|
|
2052
|
-
width
|
|
2053
|
-
} = metrics;
|
|
2054
|
-
return width;
|
|
2222
|
+
return getTokensViewport(editor, startLineIndex, endLineIndex);
|
|
2055
2223
|
};
|
|
2056
2224
|
|
|
2057
|
-
const
|
|
2058
|
-
|
|
2059
|
-
|
|
2225
|
+
const loadTokenizers = async languageIds => {
|
|
2226
|
+
for (const languageId of languageIds) {
|
|
2227
|
+
// @ts-ignore
|
|
2228
|
+
await loadTokenizer(languageId);
|
|
2060
2229
|
}
|
|
2061
|
-
return measureTextWidthSlow(text, fontWeight, fontSize, fontFamily, letterSpacing, isMonoSpaceFont, charWidth);
|
|
2062
2230
|
};
|
|
2063
2231
|
|
|
2232
|
+
const EmptyString = '';
|
|
2233
|
+
const NewLine = '\n';
|
|
2234
|
+
const Space = ' ';
|
|
2235
|
+
const Tab = '\t';
|
|
2236
|
+
const DoubleQuote$1 = '"';
|
|
2237
|
+
|
|
2064
2238
|
const normalizeText = (text, normalize, tabSize) => {
|
|
2065
2239
|
if (normalize) {
|
|
2066
|
-
return text.replaceAll(Tab
|
|
2240
|
+
return text.replaceAll(Tab, Space.repeat(tabSize));
|
|
2067
2241
|
}
|
|
2068
2242
|
return text;
|
|
2069
2243
|
};
|
|
2070
2244
|
const shouldNormalizeText = text => {
|
|
2071
|
-
return text.includes(Tab
|
|
2245
|
+
return text.includes(Tab);
|
|
2072
2246
|
};
|
|
2073
2247
|
|
|
2074
|
-
|
|
2075
|
-
|
|
2076
|
-
|
|
2077
|
-
|
|
2078
|
-
|
|
2079
|
-
|
|
2080
|
-
|
|
2081
|
-
|
|
2082
|
-
|
|
2083
|
-
|
|
2084
|
-
number(difference);
|
|
2085
|
-
if (column === 0) {
|
|
2086
|
-
return 0;
|
|
2248
|
+
// based on https://github.com/microsoft/vscode/blob/c0769274fa136b45799edeccc0d0a2f645b75caf/src/vs/base/common/arrays.ts#L625 (License MIT)
|
|
2249
|
+
|
|
2250
|
+
// @ts-ignore
|
|
2251
|
+
const insertInto = (array, start, newItems) => {
|
|
2252
|
+
const originalLength = array.length;
|
|
2253
|
+
const newItemsLength = newItems.length;
|
|
2254
|
+
array.length = originalLength + newItemsLength;
|
|
2255
|
+
// Move the items after the start index, start from the end so that we don't overwrite any value.
|
|
2256
|
+
for (let i = originalLength - 1; i >= start; i--) {
|
|
2257
|
+
array[i + newItemsLength] = array[i];
|
|
2087
2258
|
}
|
|
2088
|
-
|
|
2089
|
-
|
|
2090
|
-
return width;
|
|
2259
|
+
for (let i = 0; i < newItemsLength; i++) {
|
|
2260
|
+
array[i + start] = newItems[i];
|
|
2091
2261
|
}
|
|
2092
|
-
const normalize = shouldNormalizeText(line);
|
|
2093
|
-
const normalizedLine = normalizeText(line, normalize, tabSize);
|
|
2094
|
-
const tabCount = getTabCount(line.slice(0, column));
|
|
2095
|
-
const partialText = normalizedLine.slice(0, column + tabCount);
|
|
2096
|
-
return measureTextWidth(partialText, fontWeight, fontSize, fontFamily, letterSpacing, isMonospaceFont, averageCharWidth) - halfCursorWidth + difference;
|
|
2097
2262
|
};
|
|
2098
2263
|
|
|
2099
|
-
|
|
2100
|
-
|
|
2264
|
+
/**
|
|
2265
|
+
* Alternative to the native Array.splice method, it
|
|
2266
|
+
* can only support limited number of items due to the maximum call stack size limit.
|
|
2267
|
+
*/
|
|
2268
|
+
// @ts-ignore
|
|
2269
|
+
const spliceLargeArray = (array, start, deleteCount, newItems) => {
|
|
2270
|
+
const result = array.splice(start, deleteCount);
|
|
2271
|
+
insertInto(array, start, newItems);
|
|
2272
|
+
return result;
|
|
2101
2273
|
};
|
|
2102
2274
|
|
|
2103
|
-
const
|
|
2104
|
-
return
|
|
2275
|
+
const joinLines = lines => {
|
|
2276
|
+
return lines.join('\n');
|
|
2105
2277
|
};
|
|
2106
2278
|
|
|
2107
|
-
const
|
|
2108
|
-
|
|
2109
|
-
|
|
2110
|
-
const
|
|
2111
|
-
|
|
2112
|
-
|
|
2113
|
-
|
|
2114
|
-
return alloc(selections.length);
|
|
2115
|
-
};
|
|
2116
|
-
const map = (selections, fn) => {
|
|
2117
|
-
const newSelections = clone(selections);
|
|
2118
|
-
for (let i = 0; i < newSelections.length; i += 4) {
|
|
2119
|
-
const [selectionStartRow, selectionStartColumn, selectionEndRow, selectionEndColumn] = getSelectionPairs(selections, i);
|
|
2120
|
-
fn(newSelections, i, selectionStartRow, selectionStartColumn, selectionEndRow, selectionEndColumn);
|
|
2279
|
+
const RE_WHITESPACE = /^\s+/;
|
|
2280
|
+
|
|
2281
|
+
// TODO this doesn't belong here
|
|
2282
|
+
const getIndent = line => {
|
|
2283
|
+
const whitespaceMatch = line.match(RE_WHITESPACE);
|
|
2284
|
+
if (!whitespaceMatch) {
|
|
2285
|
+
return '';
|
|
2121
2286
|
}
|
|
2122
|
-
return
|
|
2287
|
+
return whitespaceMatch[0];
|
|
2123
2288
|
};
|
|
2124
|
-
|
|
2125
|
-
|
|
2126
|
-
|
|
2127
|
-
|
|
2128
|
-
|
|
2129
|
-
|
|
2130
|
-
|
|
2289
|
+
|
|
2290
|
+
// TODO have function for single edit (most common, avoid one array)
|
|
2291
|
+
const applyEdits = (textDocument, changes) => {
|
|
2292
|
+
object(textDocument);
|
|
2293
|
+
array(changes);
|
|
2294
|
+
// TODO don't copy all lines (can be expensive, e.g. 10000 lines = 10000 * 64bit = 64kB on every keystroke)
|
|
2295
|
+
const newLines = [...textDocument.lines];
|
|
2296
|
+
let linesDelta = 0;
|
|
2297
|
+
for (const change of changes) {
|
|
2298
|
+
const startRowIndex = change.start.rowIndex + linesDelta;
|
|
2299
|
+
const endRowIndex = change.end.rowIndex + linesDelta;
|
|
2300
|
+
const startColumnIndex = change.start.columnIndex;
|
|
2301
|
+
const endColumnIndex = change.end.columnIndex;
|
|
2302
|
+
const {
|
|
2303
|
+
inserted
|
|
2304
|
+
} = change;
|
|
2305
|
+
const {
|
|
2306
|
+
deleted
|
|
2307
|
+
} = change;
|
|
2308
|
+
number(startRowIndex);
|
|
2309
|
+
number(endRowIndex);
|
|
2310
|
+
number(startColumnIndex);
|
|
2311
|
+
number(endColumnIndex);
|
|
2312
|
+
array(inserted);
|
|
2313
|
+
array(deleted);
|
|
2314
|
+
if (startRowIndex === endRowIndex) {
|
|
2315
|
+
if (inserted.length === 0) {
|
|
2316
|
+
const line = newLines[startRowIndex];
|
|
2317
|
+
const before = line.slice(0, startColumnIndex);
|
|
2318
|
+
const after = line.slice(endColumnIndex);
|
|
2319
|
+
newLines[startRowIndex] = before + after;
|
|
2320
|
+
} else if (inserted.length === 1) {
|
|
2321
|
+
const line = newLines[startRowIndex];
|
|
2322
|
+
let before = line.slice(0, startColumnIndex);
|
|
2323
|
+
if (startColumnIndex > line.length) {
|
|
2324
|
+
before += ' '.repeat(startColumnIndex - line.length);
|
|
2325
|
+
}
|
|
2326
|
+
const after = line.slice(endColumnIndex);
|
|
2327
|
+
const text = inserted[0];
|
|
2328
|
+
newLines[startRowIndex] = before + text + after;
|
|
2329
|
+
} else {
|
|
2330
|
+
const line = newLines[startRowIndex];
|
|
2331
|
+
const before = line.slice(0, startColumnIndex) + inserted[0];
|
|
2332
|
+
const after = inserted.at(-1) + line.slice(endColumnIndex);
|
|
2333
|
+
spliceLargeArray(newLines, startRowIndex, deleted.length, [before, ...inserted.slice(1, -1), after]);
|
|
2334
|
+
// TODO only do this once after all edits, not inside loop
|
|
2335
|
+
textDocument.maxLineY = Math.min(textDocument.numberOfVisibleLines, newLines.length);
|
|
2336
|
+
}
|
|
2337
|
+
} else {
|
|
2338
|
+
if (inserted.length === 1) {
|
|
2339
|
+
const before = newLines[startRowIndex].slice(0, startColumnIndex) + inserted[0];
|
|
2340
|
+
const after = endRowIndex >= newLines.length ? '' : newLines[endRowIndex].slice(endColumnIndex);
|
|
2341
|
+
spliceLargeArray(newLines, startRowIndex, deleted.length, [before + after]);
|
|
2342
|
+
} else {
|
|
2343
|
+
const before = newLines[startRowIndex].slice(0, startColumnIndex) + inserted[0];
|
|
2344
|
+
const middle = inserted.slice(1, -1);
|
|
2345
|
+
const after = inserted.at(-1) + (endRowIndex >= newLines.length ? '' : newLines[endRowIndex].slice(endColumnIndex));
|
|
2346
|
+
spliceLargeArray(newLines, startRowIndex, deleted.length, [before, ...middle, after]);
|
|
2347
|
+
}
|
|
2348
|
+
// TODO only do this once after all edits, not inside loop
|
|
2349
|
+
textDocument.maxLineY = Math.min(textDocument.numberOfVisibleLines, textDocument.lines.length);
|
|
2350
|
+
}
|
|
2351
|
+
linesDelta += inserted.length - deleted.length;
|
|
2131
2352
|
}
|
|
2353
|
+
return newLines;
|
|
2132
2354
|
};
|
|
2133
|
-
const
|
|
2134
|
-
|
|
2135
|
-
selections[i + 1] = selections[i + 3] = columnIndex;
|
|
2136
|
-
};
|
|
2137
|
-
const isEmpty = (selectionStartRow, selectionStartColumn, selectionEndRow, selectionEndColumn) => {
|
|
2138
|
-
return selectionStartRow === selectionEndRow && selectionStartColumn === selectionEndColumn;
|
|
2139
|
-
};
|
|
2140
|
-
const isSelectionSingleLine = (selectionStartRow, selectionStartColumn, selectionEndRow, selectionEndColumn) => {
|
|
2141
|
-
return selectionStartRow === selectionEndRow;
|
|
2142
|
-
};
|
|
2143
|
-
const isEverySelection = (selections, fn) => {
|
|
2144
|
-
for (let i = 0; i < selections.length; i += 4) {
|
|
2145
|
-
const selectionStartRow = selections[i];
|
|
2146
|
-
const selectionStartColumn = selections[i + 1];
|
|
2147
|
-
const selectionEndRow = selections[i + 2];
|
|
2148
|
-
const selectionEndColumn = selections[i + 3];
|
|
2149
|
-
if (!fn(selectionStartRow, selectionStartColumn, selectionEndRow, selectionEndColumn)) {
|
|
2150
|
-
return false;
|
|
2151
|
-
}
|
|
2152
|
-
}
|
|
2153
|
-
return true;
|
|
2154
|
-
};
|
|
2155
|
-
const isEverySelectionEmpty = selections => {
|
|
2156
|
-
return isEverySelection(selections, isEmpty);
|
|
2157
|
-
};
|
|
2158
|
-
const isEverySelectionSingleLine = selections => {
|
|
2159
|
-
return isEverySelection(selections, isSelectionSingleLine);
|
|
2160
|
-
};
|
|
2161
|
-
const from = (array, getSelection) => {
|
|
2162
|
-
const newSelections = alloc(array.length * 4);
|
|
2163
|
-
let i = 0;
|
|
2164
|
-
for (const item of array) {
|
|
2165
|
-
const {
|
|
2166
|
-
start,
|
|
2167
|
-
end
|
|
2168
|
-
} = getSelection(item);
|
|
2169
|
-
newSelections[i++] = start.rowIndex;
|
|
2170
|
-
newSelections[i++] = start.columnIndex;
|
|
2171
|
-
newSelections[i++] = end.rowIndex;
|
|
2172
|
-
newSelections[i++] = end.columnIndex;
|
|
2173
|
-
}
|
|
2174
|
-
return newSelections;
|
|
2355
|
+
const getLine = (textDocument, index) => {
|
|
2356
|
+
return textDocument.lines[index];
|
|
2175
2357
|
};
|
|
2176
|
-
const
|
|
2177
|
-
|
|
2178
|
-
const newSelections = alloc(oldLength + 4);
|
|
2179
|
-
newSelections.set(selections);
|
|
2180
|
-
newSelections[oldLength + 1] = startRowIndex;
|
|
2181
|
-
newSelections[oldLength + 2] = startColumnIndex;
|
|
2182
|
-
newSelections[oldLength + 3] = endRowIndex;
|
|
2183
|
-
newSelections[oldLength + 4] = endColumnIndex;
|
|
2184
|
-
return newSelections;
|
|
2358
|
+
const getText$1 = state => {
|
|
2359
|
+
return joinLines(state.lines);
|
|
2185
2360
|
};
|
|
2186
2361
|
|
|
2187
|
-
//
|
|
2188
|
-
|
|
2189
|
-
|
|
2190
|
-
const
|
|
2191
|
-
|
|
2192
|
-
|
|
2193
|
-
|
|
2194
|
-
|
|
2195
|
-
|
|
2196
|
-
const x = visibleCursors[i];
|
|
2197
|
-
const y = visibleCursors[i + 1];
|
|
2198
|
-
cursorArray.push(`${px(x)} ${px(y)}`);
|
|
2362
|
+
// TDOO this doesn;t belong here
|
|
2363
|
+
const getSelectionText = (textDocument, range) => {
|
|
2364
|
+
object(textDocument);
|
|
2365
|
+
const startRowIndex = range.start.rowIndex;
|
|
2366
|
+
const startColumnIndex = range.start.columnIndex;
|
|
2367
|
+
const endRowIndex = Math.min(range.end.rowIndex, textDocument.lines.length - 1);
|
|
2368
|
+
const endColumnIndex = range.end.columnIndex;
|
|
2369
|
+
if (startRowIndex === endRowIndex) {
|
|
2370
|
+
return [textDocument.lines[startRowIndex].slice(startColumnIndex, endColumnIndex)];
|
|
2199
2371
|
}
|
|
2200
|
-
|
|
2372
|
+
const selectedLines = [textDocument.lines[startRowIndex].slice(startColumnIndex), ...textDocument.lines.slice(startRowIndex + 1, endRowIndex), textDocument.lines[endRowIndex].slice(0, endColumnIndex)];
|
|
2373
|
+
return selectedLines;
|
|
2201
2374
|
};
|
|
2202
|
-
const
|
|
2203
|
-
|
|
2204
|
-
|
|
2205
|
-
|
|
2206
|
-
|
|
2207
|
-
|
|
2208
|
-
|
|
2209
|
-
|
|
2375
|
+
const offsetAtSync = async (textDocument, positionRowIndex, positionColumnIndex) => {
|
|
2376
|
+
object(textDocument);
|
|
2377
|
+
number(positionRowIndex);
|
|
2378
|
+
number(positionColumnIndex);
|
|
2379
|
+
let offset = 0;
|
|
2380
|
+
let rowIndex = 0;
|
|
2381
|
+
const {
|
|
2382
|
+
lines
|
|
2383
|
+
} = textDocument;
|
|
2384
|
+
const max = Math.min(positionRowIndex, textDocument.lines.length);
|
|
2385
|
+
while (rowIndex < max) {
|
|
2386
|
+
offset += lines[rowIndex].length + 1;
|
|
2387
|
+
rowIndex++;
|
|
2210
2388
|
}
|
|
2211
|
-
|
|
2389
|
+
offset += positionColumnIndex;
|
|
2390
|
+
return offset;
|
|
2212
2391
|
};
|
|
2213
|
-
const
|
|
2214
|
-
|
|
2215
|
-
|
|
2216
|
-
|
|
2217
|
-
|
|
2392
|
+
const offsetAt = (textDocument, positionRowIndex, positionColumnIndex) => {
|
|
2393
|
+
object(textDocument);
|
|
2394
|
+
number(positionRowIndex);
|
|
2395
|
+
number(positionColumnIndex);
|
|
2396
|
+
let offset = 0;
|
|
2397
|
+
let rowIndex = 0;
|
|
2218
2398
|
const {
|
|
2219
|
-
|
|
2220
|
-
|
|
2221
|
-
|
|
2222
|
-
|
|
2223
|
-
lines
|
|
2224
|
-
|
|
2225
|
-
fontFamily,
|
|
2226
|
-
fontWeight,
|
|
2227
|
-
letterSpacing,
|
|
2228
|
-
cursorWidth,
|
|
2229
|
-
tabSize,
|
|
2230
|
-
width,
|
|
2231
|
-
differences,
|
|
2232
|
-
focused,
|
|
2233
|
-
charWidth,
|
|
2234
|
-
isMonospaceFont
|
|
2235
|
-
} = editor;
|
|
2236
|
-
const averageCharWidth = charWidth;
|
|
2237
|
-
const halfCursorWidth = cursorWidth / 2;
|
|
2238
|
-
for (let i = 0; i < selections.length; i += 4) {
|
|
2239
|
-
const [selectionStartRow, selectionStartColumn, selectionEndRow, selectionEndColumn, reversed] = getSelectionPairs(selections, i);
|
|
2240
|
-
if (selectionEndRow < minLineY || selectionStartRow > maxLineY) {
|
|
2241
|
-
continue;
|
|
2242
|
-
}
|
|
2243
|
-
const relativeEndLineRow = selectionEndRow - minLineY;
|
|
2244
|
-
const endLineDifference = differences[relativeEndLineRow];
|
|
2245
|
-
const endLine = lines[selectionEndRow];
|
|
2246
|
-
const endLineEndX = getX(endLine, selectionEndColumn, fontWeight, fontSize, fontFamily, isMonospaceFont, letterSpacing, tabSize, halfCursorWidth, width, averageCharWidth, endLineDifference);
|
|
2247
|
-
const endLineY = getY(selectionEndRow, minLineY, rowHeight);
|
|
2248
|
-
if (isEmpty(selectionStartRow, selectionStartColumn, selectionEndRow, selectionEndColumn) && endLineEndX > 0) {
|
|
2249
|
-
visibleCursors.push(endLineEndX, endLineY);
|
|
2250
|
-
continue;
|
|
2251
|
-
}
|
|
2252
|
-
const startLineY = getY(selectionStartRow, minLineY, rowHeight);
|
|
2253
|
-
const startLineYRelative = selectionStartRow - minLineY;
|
|
2254
|
-
const startLineDifference = differences[startLineYRelative];
|
|
2255
|
-
if (selectionStartRow === selectionEndRow) {
|
|
2256
|
-
const startX = getX(endLine, selectionStartColumn, fontWeight, fontSize, fontFamily, isMonospaceFont, letterSpacing, tabSize, halfCursorWidth, width, averageCharWidth, startLineDifference);
|
|
2257
|
-
if (reversed) {
|
|
2258
|
-
visibleCursors.push(startX, endLineY);
|
|
2259
|
-
} else if (endLineEndX >= 0) {
|
|
2260
|
-
visibleCursors.push(endLineEndX, endLineY);
|
|
2261
|
-
}
|
|
2262
|
-
const selectionWidth = endLineEndX - startX;
|
|
2263
|
-
visibleSelections.push(startX, startLineY, selectionWidth, rowHeight);
|
|
2264
|
-
} else {
|
|
2265
|
-
if (selectionStartRow >= minLineY) {
|
|
2266
|
-
const startLine = lines[selectionStartRow];
|
|
2267
|
-
const startLineStartX = getX(startLine, selectionStartColumn, fontWeight, fontSize, fontFamily, isMonospaceFont, letterSpacing, tabSize, halfCursorWidth, width, averageCharWidth, startLineDifference);
|
|
2268
|
-
const startLineEndX = getX(startLine, startLine.length, fontWeight, fontSize, fontFamily, isMonospaceFont, letterSpacing, tabSize, halfCursorWidth, width, averageCharWidth, startLineDifference);
|
|
2269
|
-
const startLineStartY = getY(selectionStartRow, minLineY, rowHeight);
|
|
2270
|
-
const selectionWidth = startLineEndX - startLineStartX;
|
|
2271
|
-
if (reversed) {
|
|
2272
|
-
visibleCursors.push(startLineStartX, startLineStartY);
|
|
2273
|
-
}
|
|
2274
|
-
visibleSelections.push(startLineStartX, startLineStartY, selectionWidth, rowHeight);
|
|
2275
|
-
}
|
|
2276
|
-
const iMin = Math.max(selectionStartRow + 1, minLineY);
|
|
2277
|
-
const iMax = Math.min(selectionEndRow, maxLineY);
|
|
2278
|
-
for (let i = iMin; i < iMax; i++) {
|
|
2279
|
-
const currentLine = lines[i];
|
|
2280
|
-
const currentLineY = getY(i, minLineY, rowHeight);
|
|
2281
|
-
const relativeLine = i - minLineY;
|
|
2282
|
-
const difference = differences[relativeLine];
|
|
2283
|
-
const selectionWidth = getX(currentLine, currentLine.length, fontWeight, fontSize, fontFamily, isMonospaceFont, letterSpacing, tabSize, halfCursorWidth, width, averageCharWidth, difference);
|
|
2284
|
-
visibleSelections.push(0, currentLineY, selectionWidth, rowHeight);
|
|
2285
|
-
}
|
|
2286
|
-
if (selectionEndRow <= maxLineY) {
|
|
2287
|
-
const selectionWidth = endLineEndX;
|
|
2288
|
-
visibleSelections.push(0, endLineY, selectionWidth, rowHeight);
|
|
2289
|
-
if (!reversed) {
|
|
2290
|
-
visibleCursors.push(selectionWidth, endLineY);
|
|
2291
|
-
}
|
|
2292
|
-
}
|
|
2293
|
-
}
|
|
2399
|
+
lines
|
|
2400
|
+
} = textDocument;
|
|
2401
|
+
const max = Math.min(positionRowIndex, textDocument.lines.length);
|
|
2402
|
+
while (rowIndex < max) {
|
|
2403
|
+
offset += lines[rowIndex].length + 1;
|
|
2404
|
+
rowIndex++;
|
|
2294
2405
|
}
|
|
2295
|
-
|
|
2296
|
-
return
|
|
2297
|
-
cursorInfos: getCursorArray(visibleCursors, focused),
|
|
2298
|
-
selectionInfos: getSelectionArray(visibleSelections)
|
|
2299
|
-
};
|
|
2406
|
+
offset += positionColumnIndex;
|
|
2407
|
+
return offset;
|
|
2300
2408
|
};
|
|
2301
|
-
|
|
2302
|
-
const getSelectionFromChange = change => {
|
|
2409
|
+
const positionAt = (textDocument, offset) => {
|
|
2303
2410
|
const {
|
|
2304
|
-
|
|
2305
|
-
|
|
2306
|
-
|
|
2307
|
-
|
|
2308
|
-
|
|
2309
|
-
|
|
2310
|
-
|
|
2311
|
-
|
|
2312
|
-
|
|
2313
|
-
|
|
2314
|
-
|
|
2315
|
-
|
|
2316
|
-
|
|
2317
|
-
|
|
2318
|
-
|
|
2411
|
+
lines
|
|
2412
|
+
} = textDocument;
|
|
2413
|
+
let rowIndex = 0;
|
|
2414
|
+
let columnIndex = 0;
|
|
2415
|
+
let currentOffset = 0;
|
|
2416
|
+
while (rowIndex < lines.length && currentOffset < offset) {
|
|
2417
|
+
currentOffset += lines[rowIndex].length + 1;
|
|
2418
|
+
rowIndex++;
|
|
2419
|
+
}
|
|
2420
|
+
if (currentOffset > offset) {
|
|
2421
|
+
rowIndex--;
|
|
2422
|
+
currentOffset -= lines[rowIndex].length + 1;
|
|
2423
|
+
columnIndex = offset - currentOffset;
|
|
2424
|
+
} else {
|
|
2425
|
+
columnIndex = currentOffset - offset;
|
|
2319
2426
|
}
|
|
2320
|
-
const newPosition = {
|
|
2321
|
-
rowIndex: startRowIndex + insertedLength - 1,
|
|
2322
|
-
columnIndex: startColumnIndex
|
|
2323
|
-
};
|
|
2324
|
-
return {
|
|
2325
|
-
start: newPosition,
|
|
2326
|
-
end: newPosition
|
|
2327
|
-
};
|
|
2328
|
-
};
|
|
2329
|
-
const setSelections$1 = (editor, selections) => {
|
|
2330
|
-
object(editor);
|
|
2331
|
-
// Assert.uint32array(selections)
|
|
2332
2427
|
return {
|
|
2333
|
-
|
|
2334
|
-
|
|
2428
|
+
rowIndex,
|
|
2429
|
+
columnIndex
|
|
2335
2430
|
};
|
|
2336
|
-
// editor.selections = selections
|
|
2337
|
-
// GlobalEventBus.emitEvent('editor.selectionChange', editor, selections)
|
|
2338
2431
|
};
|
|
2339
2432
|
|
|
2340
|
-
//
|
|
2341
|
-
|
|
2342
|
-
//
|
|
2343
|
-
//
|
|
2344
|
-
|
|
2433
|
+
// const getTokensIncremental = (editor, min, max) => {
|
|
2434
|
+
// const currentLength = editor.lineStateCache.length
|
|
2435
|
+
// const tokens = []
|
|
2436
|
+
// const lines = editor.lines
|
|
2437
|
+
// let lineState = editor.tokenizer.initialLineState
|
|
2438
|
+
// for (let i = currentLength; i < max; i++) {
|
|
2439
|
+
// const line = lines[i]
|
|
2440
|
+
// try {
|
|
2441
|
+
// lineState = editor.tokenizer.tokenizeLine(line, lineState)
|
|
2442
|
+
// if (!lineState || !lineState.tokens || !lineState.state) {
|
|
2443
|
+
// throw new Error('invalid tokenization result')
|
|
2444
|
+
// }
|
|
2445
|
+
// } catch (error) {
|
|
2446
|
+
// tokens.push([{ length: line.length, type: 0 }])
|
|
2447
|
+
// console.error(error)
|
|
2448
|
+
// // renderWithoutSyntaxHighlighting(state, firstRow, lastRow)
|
|
2449
|
+
// continue
|
|
2450
|
+
// }
|
|
2451
|
+
// const newTokens = lineState.tokens
|
|
2452
|
+
// tokens.push(newTokens)
|
|
2453
|
+
// }
|
|
2454
|
+
// return tokens
|
|
2455
|
+
// }
|
|
2456
|
+
|
|
2457
|
+
// const getLineInfosIncremental = (editor, tokens, minLineY, maxLineY) => {
|
|
2458
|
+
// const result = []
|
|
2459
|
+
// const lines = editor.lines
|
|
2460
|
+
// const TokenMap = editor.tokenizer.TokenMap
|
|
2461
|
+
// for (let i = minLineY; i < maxLineY; i++) {
|
|
2462
|
+
// result.push(getLineInfo(lines[i], tokens[i], TokenMap))
|
|
2463
|
+
// }
|
|
2464
|
+
// return result
|
|
2465
|
+
// }
|
|
2466
|
+
|
|
2467
|
+
const getStartDefaults = (tokens, minOffset) => {
|
|
2468
|
+
let start = 0;
|
|
2469
|
+
let end = 0;
|
|
2470
|
+
let startIndex = 0;
|
|
2471
|
+
const tokensLength = tokens.length;
|
|
2472
|
+
for (let i = 0; i < tokensLength; i += 2) {
|
|
2473
|
+
const tokenLength = tokens[i + 1];
|
|
2474
|
+
end += tokenLength;
|
|
2475
|
+
start = end;
|
|
2476
|
+
if (start >= minOffset) {
|
|
2477
|
+
start -= tokenLength;
|
|
2478
|
+
end -= tokenLength;
|
|
2479
|
+
startIndex = i;
|
|
2480
|
+
break;
|
|
2481
|
+
}
|
|
2482
|
+
}
|
|
2483
|
+
return {
|
|
2484
|
+
start,
|
|
2485
|
+
end,
|
|
2486
|
+
startIndex
|
|
2487
|
+
};
|
|
2488
|
+
};
|
|
2489
|
+
const getLineInfoEmbeddedFull = (embeddedResults, tokenResults, line, normalize, tabSize, width, deltaX, averageCharWidth, minOffset, maxOffset) => {
|
|
2490
|
+
const lineInfo = [];
|
|
2491
|
+
const embeddedResult = embeddedResults[tokenResults.embeddedResultIndex];
|
|
2492
|
+
const embeddedTokens = embeddedResult.result.tokens;
|
|
2493
|
+
const embeddedTokenMap = embeddedResult.TokenMap;
|
|
2494
|
+
const tokensLength = embeddedTokens.length;
|
|
2495
|
+
let {
|
|
2496
|
+
startIndex,
|
|
2497
|
+
start,
|
|
2498
|
+
end
|
|
2499
|
+
} = getStartDefaults(embeddedTokens, minOffset);
|
|
2500
|
+
const difference = getDifference(start, averageCharWidth, deltaX);
|
|
2501
|
+
for (let i = startIndex; i < tokensLength; i += 2) {
|
|
2502
|
+
const tokenType = embeddedTokens[i];
|
|
2503
|
+
const tokenLength = embeddedTokens[i + 1];
|
|
2504
|
+
end += tokenLength;
|
|
2505
|
+
const className = `Token ${embeddedTokenMap[tokenType] || 'Unknown'}`;
|
|
2506
|
+
const text = line.slice(start, end);
|
|
2507
|
+
const normalizedText = normalizeText(text, normalize, tabSize);
|
|
2508
|
+
lineInfo.push(normalizedText, className);
|
|
2509
|
+
start = end;
|
|
2510
|
+
if (end >= maxOffset) {
|
|
2511
|
+
break;
|
|
2512
|
+
}
|
|
2513
|
+
}
|
|
2514
|
+
return {
|
|
2515
|
+
lineInfo,
|
|
2516
|
+
difference
|
|
2517
|
+
};
|
|
2518
|
+
};
|
|
2519
|
+
const getOffsets = (deltaX, width, averageCharWidth) => {
|
|
2520
|
+
// TODO accurately measure char widths using offscreen canvas
|
|
2521
|
+
// and use fast measurements for monospace ascii text
|
|
2522
|
+
if (deltaX === 0) {
|
|
2523
|
+
return {
|
|
2524
|
+
minOffset: 0,
|
|
2525
|
+
maxOffset: Math.ceil(width / averageCharWidth)
|
|
2526
|
+
};
|
|
2527
|
+
}
|
|
2528
|
+
const minOffset = Math.ceil(deltaX / averageCharWidth);
|
|
2529
|
+
const maxOffset = minOffset + Math.ceil(width / averageCharWidth);
|
|
2530
|
+
return {
|
|
2531
|
+
minOffset,
|
|
2532
|
+
maxOffset
|
|
2533
|
+
};
|
|
2534
|
+
};
|
|
2535
|
+
const getDifference = (start, averageCharWidth, deltaX) => {
|
|
2536
|
+
const beforeWidth = start * averageCharWidth;
|
|
2537
|
+
const difference = beforeWidth - deltaX;
|
|
2538
|
+
return difference;
|
|
2539
|
+
};
|
|
2540
|
+
const getLineInfoDefault = (line, tokenResults, embeddedResults, decorations, TokenMap, lineOffset, normalize, tabSize, width, deltaX, averageCharWidth, minOffset, maxOffset) => {
|
|
2541
|
+
const lineInfo = [];
|
|
2542
|
+
let decorationIndex = 0;
|
|
2543
|
+
for (; decorationIndex < decorations.length; decorationIndex += 3) {
|
|
2544
|
+
const decorationOffset = decorations[decorationIndex];
|
|
2545
|
+
if (decorationOffset >= lineOffset) {
|
|
2546
|
+
break;
|
|
2547
|
+
}
|
|
2548
|
+
}
|
|
2549
|
+
const {
|
|
2550
|
+
tokens
|
|
2551
|
+
} = tokenResults;
|
|
2552
|
+
let {
|
|
2553
|
+
startIndex,
|
|
2554
|
+
start,
|
|
2555
|
+
end
|
|
2556
|
+
} = getStartDefaults(tokens, minOffset);
|
|
2557
|
+
const difference = getDifference(start, averageCharWidth, deltaX);
|
|
2558
|
+
const tokensLength = tokens.length;
|
|
2559
|
+
for (let i = startIndex; i < tokensLength; i += 2) {
|
|
2560
|
+
const tokenType = tokens[i];
|
|
2561
|
+
const tokenLength = tokens[i + 1];
|
|
2562
|
+
const decorationOffset = decorations[decorationIndex];
|
|
2563
|
+
let extraClassName = '';
|
|
2564
|
+
if (decorationOffset !== undefined && decorationOffset - lineOffset === start) {
|
|
2565
|
+
// @ts-ignore
|
|
2566
|
+
decorations[++decorationIndex];
|
|
2567
|
+
const decorationType = decorations[++decorationIndex];
|
|
2568
|
+
// @ts-ignore
|
|
2569
|
+
decorations[++decorationIndex];
|
|
2570
|
+
// decorationIndex,
|
|
2571
|
+
// decorationLength,
|
|
2572
|
+
// decorationType,
|
|
2573
|
+
// decorationModifiers,
|
|
2574
|
+
// })
|
|
2575
|
+
extraClassName = getDecorationClassName(decorationType);
|
|
2576
|
+
}
|
|
2577
|
+
end += tokenLength;
|
|
2578
|
+
const text = line.slice(start, end);
|
|
2579
|
+
const className = `Token ${extraClassName || TokenMap[tokenType] || 'Unknown'}`;
|
|
2580
|
+
const normalizedText = normalizeText(text, normalize, tabSize);
|
|
2581
|
+
lineInfo.push(normalizedText, className);
|
|
2582
|
+
start = end;
|
|
2583
|
+
if (end >= maxOffset) {
|
|
2584
|
+
break;
|
|
2585
|
+
}
|
|
2586
|
+
}
|
|
2587
|
+
return {
|
|
2588
|
+
lineInfo,
|
|
2589
|
+
difference
|
|
2590
|
+
};
|
|
2591
|
+
};
|
|
2592
|
+
const getLineInfo$1 = (line, tokenResults, embeddedResults, decorations, TokenMap, lineOffset, normalize, tabSize, width, deltaX, averageCharWidth) => {
|
|
2593
|
+
const {
|
|
2594
|
+
minOffset,
|
|
2595
|
+
maxOffset
|
|
2596
|
+
} = getOffsets(deltaX, width, averageCharWidth);
|
|
2597
|
+
if (embeddedResults.length > 0 && tokenResults.embeddedResultIndex !== undefined) {
|
|
2598
|
+
const embeddedResult = embeddedResults[tokenResults.embeddedResultIndex];
|
|
2599
|
+
if (embeddedResult?.isFull) {
|
|
2600
|
+
return getLineInfoEmbeddedFull(embeddedResults, tokenResults, line, normalize, tabSize, width, deltaX, averageCharWidth, minOffset, maxOffset);
|
|
2601
|
+
}
|
|
2602
|
+
}
|
|
2603
|
+
return getLineInfoDefault(line, tokenResults, embeddedResults, decorations, TokenMap, lineOffset, normalize, tabSize, width, deltaX, averageCharWidth, minOffset, maxOffset);
|
|
2604
|
+
};
|
|
2605
|
+
|
|
2606
|
+
// TODO need lots of tests for this
|
|
2607
|
+
const getLineInfosViewport = (editor, tokens, embeddedResults, minLineY, maxLineY, minLineOffset, width, deltaX, averageCharWidth) => {
|
|
2608
|
+
const result = [];
|
|
2609
|
+
const differences = [];
|
|
2610
|
+
const {
|
|
2611
|
+
lines,
|
|
2612
|
+
decorations,
|
|
2613
|
+
languageId
|
|
2614
|
+
} = editor;
|
|
2615
|
+
const tokenMap = get$2(languageId);
|
|
2616
|
+
let offset = minLineOffset;
|
|
2617
|
+
const tabSize = 2;
|
|
2618
|
+
for (let i = minLineY; i < maxLineY; i++) {
|
|
2619
|
+
const line = lines[i];
|
|
2620
|
+
const normalize = shouldNormalizeText(line);
|
|
2621
|
+
const {
|
|
2622
|
+
lineInfo,
|
|
2623
|
+
difference
|
|
2624
|
+
} = getLineInfo$1(line, tokens[i - minLineY], embeddedResults, decorations, tokenMap, offset, normalize, tabSize, width, deltaX, averageCharWidth);
|
|
2625
|
+
result.push(lineInfo);
|
|
2626
|
+
differences.push(difference);
|
|
2627
|
+
offset += line.length + 1;
|
|
2628
|
+
}
|
|
2629
|
+
return {
|
|
2630
|
+
result,
|
|
2631
|
+
differences
|
|
2632
|
+
};
|
|
2633
|
+
};
|
|
2634
|
+
const getVisible$1 = async (editor, syncIncremental) => {
|
|
2635
|
+
// TODO should separate rendering from business logic somehow
|
|
2636
|
+
// currently hard to test because need to mock editor height, top, left,
|
|
2637
|
+
// invalidStartIndex, lineCache, etc. just for testing editorType
|
|
2638
|
+
// editor.invalidStartIndex = changes[0].start.rowIndex
|
|
2639
|
+
// @ts-ignore
|
|
2640
|
+
const {
|
|
2641
|
+
minLineY,
|
|
2642
|
+
numberOfVisibleLines,
|
|
2643
|
+
lines,
|
|
2644
|
+
width,
|
|
2645
|
+
deltaX,
|
|
2646
|
+
charWidth
|
|
2647
|
+
} = editor;
|
|
2648
|
+
const maxLineY = Math.min(minLineY + numberOfVisibleLines, lines.length);
|
|
2649
|
+
// @ts-ignore
|
|
2650
|
+
const {
|
|
2651
|
+
tokens,
|
|
2652
|
+
tokenizersToLoad,
|
|
2653
|
+
embeddedResults
|
|
2654
|
+
} = await getTokensViewport2(editor, minLineY, maxLineY, syncIncremental);
|
|
2655
|
+
const minLineOffset = offsetAtSync(editor, minLineY, 0);
|
|
2656
|
+
const averageCharWidth = charWidth;
|
|
2657
|
+
const {
|
|
2658
|
+
result,
|
|
2659
|
+
differences
|
|
2660
|
+
} = getLineInfosViewport(editor, tokens, embeddedResults, minLineY, maxLineY, minLineOffset, width, deltaX, averageCharWidth);
|
|
2661
|
+
if (tokenizersToLoad.length > 0) {
|
|
2662
|
+
loadTokenizers(tokenizersToLoad);
|
|
2663
|
+
}
|
|
2664
|
+
return {
|
|
2665
|
+
textInfos: result,
|
|
2666
|
+
differences
|
|
2667
|
+
};
|
|
2668
|
+
};
|
|
2669
|
+
|
|
2670
|
+
const emptyIncrementalEdits = [];
|
|
2671
|
+
|
|
2672
|
+
const getIncrementalEdits = async (oldState, newState) => {
|
|
2673
|
+
if (!newState.undoStack) {
|
|
2674
|
+
return emptyIncrementalEdits;
|
|
2675
|
+
}
|
|
2676
|
+
if (oldState.undoStack === newState.undoStack) {
|
|
2677
|
+
return emptyIncrementalEdits;
|
|
2678
|
+
}
|
|
2679
|
+
const lastChanges = newState.undoStack.at(-1);
|
|
2680
|
+
if (lastChanges && lastChanges.length === 1) {
|
|
2681
|
+
const lastChange = lastChanges[0];
|
|
2682
|
+
if (lastChange.origin === EditorType) {
|
|
2683
|
+
const {
|
|
2684
|
+
rowIndex
|
|
2685
|
+
} = lastChange.start;
|
|
2686
|
+
const {
|
|
2687
|
+
lines
|
|
2688
|
+
} = newState;
|
|
2689
|
+
const oldLine = oldState.lines[rowIndex];
|
|
2690
|
+
const newLine = lines[rowIndex];
|
|
2691
|
+
// @ts-ignore
|
|
2692
|
+
const incrementalEdits = await invoke$7(
|
|
2693
|
+
// @ts-ignore
|
|
2694
|
+
'TokenizeIncremental.tokenizeIncremental', newState.uid,
|
|
2695
|
+
// @ts-ignore
|
|
2696
|
+
newState.languageId, oldLine, newLine, rowIndex, newState.minLineY);
|
|
2697
|
+
if (incrementalEdits && incrementalEdits.length === 1) {
|
|
2698
|
+
return incrementalEdits;
|
|
2699
|
+
}
|
|
2700
|
+
}
|
|
2701
|
+
}
|
|
2702
|
+
return emptyIncrementalEdits;
|
|
2703
|
+
};
|
|
2704
|
+
|
|
2705
|
+
const splitLines = lines => {
|
|
2706
|
+
if (!lines) {
|
|
2707
|
+
return [''];
|
|
2708
|
+
}
|
|
2709
|
+
return lines.split('\n');
|
|
2710
|
+
};
|
|
2711
|
+
|
|
2712
|
+
let enabled = false;
|
|
2713
|
+
const setEnabled = value => {
|
|
2714
|
+
enabled = value;
|
|
2715
|
+
};
|
|
2716
|
+
const getEnabled = () => {
|
|
2717
|
+
return enabled;
|
|
2718
|
+
};
|
|
2719
|
+
|
|
2720
|
+
const getSelectionPairs = (selections, i) => {
|
|
2721
|
+
const first = selections[i];
|
|
2722
|
+
const second = selections[i + 1];
|
|
2723
|
+
const third = selections[i + 2];
|
|
2724
|
+
const fourth = selections[i + 3];
|
|
2725
|
+
if (first > third || first === third && second >= fourth) {
|
|
2726
|
+
return [third, fourth, first, second, 1];
|
|
2727
|
+
}
|
|
2728
|
+
return [first, second, third, fourth, 0];
|
|
2729
|
+
};
|
|
2730
|
+
|
|
2731
|
+
const getTabCount = string => {
|
|
2732
|
+
let count = 0;
|
|
2733
|
+
for (const element of string) {
|
|
2734
|
+
if (element === Tab) {
|
|
2735
|
+
count++;
|
|
2736
|
+
}
|
|
2737
|
+
}
|
|
2738
|
+
return count;
|
|
2739
|
+
};
|
|
2740
|
+
|
|
2741
|
+
const measureTextWidthFast = (text, charWidth) => {
|
|
2742
|
+
return text.length * charWidth;
|
|
2743
|
+
};
|
|
2744
|
+
|
|
2745
|
+
const getFontString = (fontWeight, fontSize, fontFamily) => {
|
|
2746
|
+
return `${fontWeight} ${fontSize}px ${fontFamily}`;
|
|
2747
|
+
};
|
|
2748
|
+
|
|
2749
|
+
const getLetterSpacingString = letterSpacing => {
|
|
2750
|
+
return `${letterSpacing}px`;
|
|
2751
|
+
};
|
|
2752
|
+
|
|
2753
|
+
const createMeasureContext = () => {
|
|
2754
|
+
const canvas = new OffscreenCanvas(0, 0);
|
|
2755
|
+
const ctx = /** @type {OffscreenCanvasRenderingContext2D} */canvas.getContext('2d');
|
|
2756
|
+
if (!ctx) {
|
|
2757
|
+
throw new Error('Failed to get canvas context 2d');
|
|
2758
|
+
}
|
|
2759
|
+
return ctx;
|
|
2760
|
+
};
|
|
2761
|
+
|
|
2762
|
+
const state$6 = {
|
|
2763
|
+
ctx: undefined
|
|
2764
|
+
};
|
|
2765
|
+
const getOrCreate$4 = createCtx => {
|
|
2766
|
+
if (state$6.ctx) {
|
|
2767
|
+
return state$6.ctx;
|
|
2768
|
+
}
|
|
2769
|
+
state$6.ctx = createCtx();
|
|
2770
|
+
return state$6.ctx;
|
|
2771
|
+
};
|
|
2772
|
+
|
|
2773
|
+
const getContext = () => {
|
|
2774
|
+
const ctx = getOrCreate$4(createMeasureContext);
|
|
2775
|
+
return ctx;
|
|
2776
|
+
};
|
|
2777
|
+
|
|
2778
|
+
// TODO for text editor, could dispose measuring canvas after editor has been initialized to free up offscreencanvas space
|
|
2779
|
+
|
|
2780
|
+
const measureTextWidthSlow = (text, fontWeight, fontSize, fontFamily, letterSpacing, isMonoSpaceFont, charWidth) => {
|
|
2781
|
+
string(text);
|
|
2782
|
+
number(fontWeight);
|
|
2783
|
+
number(fontSize);
|
|
2784
|
+
string(fontFamily);
|
|
2785
|
+
boolean(isMonoSpaceFont);
|
|
2786
|
+
number(charWidth);
|
|
2787
|
+
if (typeof letterSpacing !== 'number') {
|
|
2788
|
+
throw new TypeError('letterSpacing must be of type number');
|
|
2789
|
+
}
|
|
2790
|
+
const letterSpacingString = getLetterSpacingString(letterSpacing);
|
|
2791
|
+
const fontString = getFontString(fontWeight, fontSize, fontFamily);
|
|
2792
|
+
const ctx = getContext();
|
|
2793
|
+
ctx.letterSpacing = letterSpacingString;
|
|
2794
|
+
ctx.font = fontString;
|
|
2795
|
+
const metrics = ctx.measureText(text);
|
|
2796
|
+
const {
|
|
2797
|
+
width
|
|
2798
|
+
} = metrics;
|
|
2799
|
+
return width;
|
|
2800
|
+
};
|
|
2801
|
+
|
|
2802
|
+
const measureTextWidth = (text, fontWeight, fontSize, fontFamily, letterSpacing, isMonoSpaceFont, charWidth) => {
|
|
2803
|
+
if (isMonoSpaceFont) {
|
|
2804
|
+
return measureTextWidthFast(text, charWidth);
|
|
2805
|
+
}
|
|
2806
|
+
return measureTextWidthSlow(text, fontWeight, fontSize, fontFamily, letterSpacing, isMonoSpaceFont, charWidth);
|
|
2807
|
+
};
|
|
2808
|
+
|
|
2809
|
+
const getX = (line, column, fontWeight, fontSize, fontFamily, isMonospaceFont, letterSpacing, tabSize, halfCursorWidth, width, averageCharWidth, difference = 0) => {
|
|
2810
|
+
if (!line) {
|
|
2811
|
+
return 0;
|
|
2812
|
+
}
|
|
2813
|
+
string(line);
|
|
2814
|
+
number(tabSize);
|
|
2815
|
+
number(halfCursorWidth);
|
|
2816
|
+
number(width);
|
|
2817
|
+
boolean(isMonospaceFont);
|
|
2818
|
+
number(averageCharWidth);
|
|
2819
|
+
number(difference);
|
|
2820
|
+
if (column === 0) {
|
|
2821
|
+
return 0;
|
|
2822
|
+
}
|
|
2823
|
+
// TODO support non-monospace font, emoji, tab character, zero width characters
|
|
2824
|
+
if (column * averageCharWidth > width) {
|
|
2825
|
+
return width;
|
|
2826
|
+
}
|
|
2827
|
+
const normalize = shouldNormalizeText(line);
|
|
2828
|
+
const normalizedLine = normalizeText(line, normalize, tabSize);
|
|
2829
|
+
const tabCount = getTabCount(line.slice(0, column));
|
|
2830
|
+
const partialText = normalizedLine.slice(0, column + tabCount);
|
|
2831
|
+
return measureTextWidth(partialText, fontWeight, fontSize, fontFamily, letterSpacing, isMonospaceFont, averageCharWidth) - halfCursorWidth + difference;
|
|
2832
|
+
};
|
|
2833
|
+
|
|
2834
|
+
const getY = (row, minLineY, rowHeight) => {
|
|
2835
|
+
return (row - minLineY) * rowHeight;
|
|
2836
|
+
};
|
|
2837
|
+
|
|
2838
|
+
const px = value => {
|
|
2839
|
+
return `${value}px`;
|
|
2840
|
+
};
|
|
2841
|
+
|
|
2842
|
+
const fromRange = (startRowIndex, startColumnIndex, endRowIndex, endColumnIndex) => {
|
|
2843
|
+
return new Uint32Array([startRowIndex, startColumnIndex, endRowIndex, endColumnIndex]);
|
|
2844
|
+
};
|
|
2845
|
+
const alloc = length => {
|
|
2846
|
+
return new Uint32Array(length);
|
|
2847
|
+
};
|
|
2848
|
+
const clone = selections => {
|
|
2849
|
+
return alloc(selections.length);
|
|
2850
|
+
};
|
|
2851
|
+
const map = (selections, fn) => {
|
|
2852
|
+
const newSelections = clone(selections);
|
|
2853
|
+
for (let i = 0; i < newSelections.length; i += 4) {
|
|
2854
|
+
const [selectionStartRow, selectionStartColumn, selectionEndRow, selectionEndColumn] = getSelectionPairs(selections, i);
|
|
2855
|
+
fn(newSelections, i, selectionStartRow, selectionStartColumn, selectionEndRow, selectionEndColumn);
|
|
2856
|
+
}
|
|
2857
|
+
return newSelections;
|
|
2858
|
+
};
|
|
2859
|
+
const forEach = (selections, fn) => {
|
|
2860
|
+
for (let i = 0; i < selections.length; i += 4) {
|
|
2861
|
+
const selectionStartRow = selections[i];
|
|
2862
|
+
const selectionStartColumn = selections[i + 1];
|
|
2863
|
+
const selectionEndRow = selections[i + 2];
|
|
2864
|
+
const selectionEndColumn = selections[i + 3];
|
|
2865
|
+
fn(selectionStartRow, selectionStartColumn, selectionEndRow, selectionEndColumn);
|
|
2866
|
+
}
|
|
2867
|
+
};
|
|
2868
|
+
const moveRangeToPosition$1 = (selections, i, rowIndex, columnIndex) => {
|
|
2869
|
+
selections[i] = selections[i + 2] = rowIndex;
|
|
2870
|
+
selections[i + 1] = selections[i + 3] = columnIndex;
|
|
2871
|
+
};
|
|
2872
|
+
const isEmpty = (selectionStartRow, selectionStartColumn, selectionEndRow, selectionEndColumn) => {
|
|
2873
|
+
return selectionStartRow === selectionEndRow && selectionStartColumn === selectionEndColumn;
|
|
2874
|
+
};
|
|
2875
|
+
const isSelectionSingleLine = (selectionStartRow, selectionStartColumn, selectionEndRow, selectionEndColumn) => {
|
|
2876
|
+
return selectionStartRow === selectionEndRow;
|
|
2877
|
+
};
|
|
2878
|
+
const isEverySelection = (selections, fn) => {
|
|
2879
|
+
for (let i = 0; i < selections.length; i += 4) {
|
|
2880
|
+
const selectionStartRow = selections[i];
|
|
2881
|
+
const selectionStartColumn = selections[i + 1];
|
|
2882
|
+
const selectionEndRow = selections[i + 2];
|
|
2883
|
+
const selectionEndColumn = selections[i + 3];
|
|
2884
|
+
if (!fn(selectionStartRow, selectionStartColumn, selectionEndRow, selectionEndColumn)) {
|
|
2885
|
+
return false;
|
|
2886
|
+
}
|
|
2887
|
+
}
|
|
2888
|
+
return true;
|
|
2889
|
+
};
|
|
2890
|
+
const isEverySelectionEmpty = selections => {
|
|
2891
|
+
return isEverySelection(selections, isEmpty);
|
|
2892
|
+
};
|
|
2893
|
+
const isEverySelectionSingleLine = selections => {
|
|
2894
|
+
return isEverySelection(selections, isSelectionSingleLine);
|
|
2895
|
+
};
|
|
2896
|
+
const from = (array, getSelection) => {
|
|
2897
|
+
const newSelections = alloc(array.length * 4);
|
|
2898
|
+
let i = 0;
|
|
2899
|
+
for (const item of array) {
|
|
2900
|
+
const {
|
|
2901
|
+
start,
|
|
2902
|
+
end
|
|
2903
|
+
} = getSelection(item);
|
|
2904
|
+
newSelections[i++] = start.rowIndex;
|
|
2905
|
+
newSelections[i++] = start.columnIndex;
|
|
2906
|
+
newSelections[i++] = end.rowIndex;
|
|
2907
|
+
newSelections[i++] = end.columnIndex;
|
|
2908
|
+
}
|
|
2909
|
+
return newSelections;
|
|
2910
|
+
};
|
|
2911
|
+
const push = (selections, startRowIndex, startColumnIndex, endRowIndex, endColumnIndex) => {
|
|
2912
|
+
const oldLength = selections.length;
|
|
2913
|
+
const newSelections = alloc(oldLength + 4);
|
|
2914
|
+
newSelections.set(selections);
|
|
2915
|
+
newSelections[oldLength + 1] = startRowIndex;
|
|
2916
|
+
newSelections[oldLength + 2] = startColumnIndex;
|
|
2917
|
+
newSelections[oldLength + 3] = endRowIndex;
|
|
2918
|
+
newSelections[oldLength + 4] = endColumnIndex;
|
|
2919
|
+
return newSelections;
|
|
2920
|
+
};
|
|
2921
|
+
|
|
2922
|
+
// TODO maybe only accept sorted selection edits in the first place
|
|
2923
|
+
|
|
2924
|
+
const emptyCursors = [];
|
|
2925
|
+
const getCursorArray = (visibleCursors, isFocused) => {
|
|
2926
|
+
if (!isFocused) {
|
|
2927
|
+
return emptyCursors;
|
|
2928
|
+
}
|
|
2929
|
+
const cursorArray = [];
|
|
2930
|
+
for (let i = 0; i < visibleCursors.length; i += 2) {
|
|
2931
|
+
const x = visibleCursors[i];
|
|
2932
|
+
const y = visibleCursors[i + 1];
|
|
2933
|
+
cursorArray.push(`${px(x)} ${px(y)}`);
|
|
2934
|
+
}
|
|
2935
|
+
return cursorArray;
|
|
2936
|
+
};
|
|
2937
|
+
const getSelectionArray = visibleSelections => {
|
|
2938
|
+
const selectionsArray = [];
|
|
2939
|
+
for (let i = 0; i < visibleSelections.length; i += 4) {
|
|
2940
|
+
const x = visibleSelections[i];
|
|
2941
|
+
const y = visibleSelections[i + 1];
|
|
2942
|
+
const width = visibleSelections[i + 2];
|
|
2943
|
+
const height = visibleSelections[i + 3];
|
|
2944
|
+
selectionsArray.push(px(x), px(y), px(width), px(height));
|
|
2945
|
+
}
|
|
2946
|
+
return selectionsArray;
|
|
2947
|
+
};
|
|
2948
|
+
const getVisible = editor => {
|
|
2949
|
+
const visibleCursors = [];
|
|
2950
|
+
const visibleSelections = [];
|
|
2951
|
+
// // TODO binary search
|
|
2952
|
+
|
|
2953
|
+
const {
|
|
2954
|
+
selections,
|
|
2955
|
+
minLineY,
|
|
2956
|
+
maxLineY,
|
|
2957
|
+
rowHeight,
|
|
2958
|
+
lines,
|
|
2959
|
+
fontSize,
|
|
2960
|
+
fontFamily,
|
|
2961
|
+
fontWeight,
|
|
2962
|
+
letterSpacing,
|
|
2963
|
+
cursorWidth,
|
|
2964
|
+
tabSize,
|
|
2965
|
+
width,
|
|
2966
|
+
differences,
|
|
2967
|
+
focused,
|
|
2968
|
+
charWidth,
|
|
2969
|
+
isMonospaceFont
|
|
2970
|
+
} = editor;
|
|
2971
|
+
const averageCharWidth = charWidth;
|
|
2972
|
+
const halfCursorWidth = cursorWidth / 2;
|
|
2973
|
+
for (let i = 0; i < selections.length; i += 4) {
|
|
2974
|
+
const [selectionStartRow, selectionStartColumn, selectionEndRow, selectionEndColumn, reversed] = getSelectionPairs(selections, i);
|
|
2975
|
+
if (selectionEndRow < minLineY || selectionStartRow > maxLineY) {
|
|
2976
|
+
continue;
|
|
2977
|
+
}
|
|
2978
|
+
const relativeEndLineRow = selectionEndRow - minLineY;
|
|
2979
|
+
const endLineDifference = differences[relativeEndLineRow];
|
|
2980
|
+
const endLine = lines[selectionEndRow];
|
|
2981
|
+
const endLineEndX = getX(endLine, selectionEndColumn, fontWeight, fontSize, fontFamily, isMonospaceFont, letterSpacing, tabSize, halfCursorWidth, width, averageCharWidth, endLineDifference);
|
|
2982
|
+
const endLineY = getY(selectionEndRow, minLineY, rowHeight);
|
|
2983
|
+
if (isEmpty(selectionStartRow, selectionStartColumn, selectionEndRow, selectionEndColumn) && endLineEndX > 0) {
|
|
2984
|
+
visibleCursors.push(endLineEndX, endLineY);
|
|
2985
|
+
continue;
|
|
2986
|
+
}
|
|
2987
|
+
const startLineY = getY(selectionStartRow, minLineY, rowHeight);
|
|
2988
|
+
const startLineYRelative = selectionStartRow - minLineY;
|
|
2989
|
+
const startLineDifference = differences[startLineYRelative];
|
|
2990
|
+
if (selectionStartRow === selectionEndRow) {
|
|
2991
|
+
const startX = getX(endLine, selectionStartColumn, fontWeight, fontSize, fontFamily, isMonospaceFont, letterSpacing, tabSize, halfCursorWidth, width, averageCharWidth, startLineDifference);
|
|
2992
|
+
if (reversed) {
|
|
2993
|
+
visibleCursors.push(startX, endLineY);
|
|
2994
|
+
} else if (endLineEndX >= 0) {
|
|
2995
|
+
visibleCursors.push(endLineEndX, endLineY);
|
|
2996
|
+
}
|
|
2997
|
+
const selectionWidth = endLineEndX - startX;
|
|
2998
|
+
visibleSelections.push(startX, startLineY, selectionWidth, rowHeight);
|
|
2999
|
+
} else {
|
|
3000
|
+
if (selectionStartRow >= minLineY) {
|
|
3001
|
+
const startLine = lines[selectionStartRow];
|
|
3002
|
+
const startLineStartX = getX(startLine, selectionStartColumn, fontWeight, fontSize, fontFamily, isMonospaceFont, letterSpacing, tabSize, halfCursorWidth, width, averageCharWidth, startLineDifference);
|
|
3003
|
+
const startLineEndX = getX(startLine, startLine.length, fontWeight, fontSize, fontFamily, isMonospaceFont, letterSpacing, tabSize, halfCursorWidth, width, averageCharWidth, startLineDifference);
|
|
3004
|
+
const startLineStartY = getY(selectionStartRow, minLineY, rowHeight);
|
|
3005
|
+
const selectionWidth = startLineEndX - startLineStartX;
|
|
3006
|
+
if (reversed) {
|
|
3007
|
+
visibleCursors.push(startLineStartX, startLineStartY);
|
|
3008
|
+
}
|
|
3009
|
+
visibleSelections.push(startLineStartX, startLineStartY, selectionWidth, rowHeight);
|
|
3010
|
+
}
|
|
3011
|
+
const iMin = Math.max(selectionStartRow + 1, minLineY);
|
|
3012
|
+
const iMax = Math.min(selectionEndRow, maxLineY);
|
|
3013
|
+
for (let i = iMin; i < iMax; i++) {
|
|
3014
|
+
const currentLine = lines[i];
|
|
3015
|
+
const currentLineY = getY(i, minLineY, rowHeight);
|
|
3016
|
+
const relativeLine = i - minLineY;
|
|
3017
|
+
const difference = differences[relativeLine];
|
|
3018
|
+
const selectionWidth = getX(currentLine, currentLine.length, fontWeight, fontSize, fontFamily, isMonospaceFont, letterSpacing, tabSize, halfCursorWidth, width, averageCharWidth, difference);
|
|
3019
|
+
visibleSelections.push(0, currentLineY, selectionWidth, rowHeight);
|
|
3020
|
+
}
|
|
3021
|
+
if (selectionEndRow <= maxLineY) {
|
|
3022
|
+
const selectionWidth = endLineEndX;
|
|
3023
|
+
visibleSelections.push(0, endLineY, selectionWidth, rowHeight);
|
|
3024
|
+
if (!reversed) {
|
|
3025
|
+
visibleCursors.push(selectionWidth, endLineY);
|
|
3026
|
+
}
|
|
3027
|
+
}
|
|
3028
|
+
}
|
|
3029
|
+
}
|
|
3030
|
+
// TODO maybe use Uint32array or Float64Array?
|
|
3031
|
+
return {
|
|
3032
|
+
cursorInfos: getCursorArray(visibleCursors, focused),
|
|
3033
|
+
selectionInfos: getSelectionArray(visibleSelections)
|
|
3034
|
+
};
|
|
3035
|
+
};
|
|
3036
|
+
|
|
3037
|
+
const getSelectionFromChange = change => {
|
|
3038
|
+
const {
|
|
3039
|
+
start,
|
|
3040
|
+
inserted
|
|
3041
|
+
} = change;
|
|
3042
|
+
const startRowIndex = start.rowIndex;
|
|
3043
|
+
const startColumnIndex = start.columnIndex;
|
|
3044
|
+
const insertedLength = inserted.length;
|
|
3045
|
+
if (insertedLength === 1) {
|
|
3046
|
+
const newPosition = {
|
|
3047
|
+
rowIndex: startRowIndex + insertedLength - 1,
|
|
3048
|
+
columnIndex: inserted.at(-1).length + startColumnIndex
|
|
3049
|
+
};
|
|
3050
|
+
return {
|
|
3051
|
+
start: newPosition,
|
|
3052
|
+
end: newPosition
|
|
3053
|
+
};
|
|
3054
|
+
}
|
|
3055
|
+
const newPosition = {
|
|
3056
|
+
rowIndex: startRowIndex + insertedLength - 1,
|
|
3057
|
+
columnIndex: startColumnIndex
|
|
3058
|
+
};
|
|
3059
|
+
return {
|
|
3060
|
+
start: newPosition,
|
|
3061
|
+
end: newPosition
|
|
3062
|
+
};
|
|
3063
|
+
};
|
|
3064
|
+
const setSelections$1 = (editor, selections) => {
|
|
3065
|
+
object(editor);
|
|
3066
|
+
// Assert.uint32array(selections)
|
|
3067
|
+
return {
|
|
3068
|
+
...editor,
|
|
3069
|
+
selections
|
|
3070
|
+
};
|
|
3071
|
+
// editor.selections = selections
|
|
3072
|
+
// GlobalEventBus.emitEvent('editor.selectionChange', editor, selections)
|
|
3073
|
+
};
|
|
3074
|
+
|
|
3075
|
+
// TODO maybe only accept sorted selection edits in the first place
|
|
3076
|
+
|
|
3077
|
+
// TODO avoid allocating too many objects when creating new selection from changes
|
|
3078
|
+
// @ts-ignore
|
|
3079
|
+
const applyEdit$1 = (editor, changes) => {
|
|
2345
3080
|
object(editor);
|
|
2346
3081
|
array(changes);
|
|
2347
3082
|
const newSelections = from(changes, getSelectionFromChange);
|
|
@@ -2428,15 +3163,29 @@ const scheduleDocumentAndCursorsSelections = async (editor, changes, selectionCh
|
|
|
2428
3163
|
autoClosingRanges
|
|
2429
3164
|
};
|
|
2430
3165
|
set$6(editor.uid, editor, newEditor);
|
|
3166
|
+
const incrementalEdits = await getIncrementalEdits(editor, newEditor);
|
|
2431
3167
|
const newWidgets = await applyWidgetChanges(newEditor, changes);
|
|
2432
3168
|
const newEditor2 = {
|
|
2433
3169
|
...newEditor,
|
|
2434
|
-
widgets: newWidgets
|
|
3170
|
+
widgets: newWidgets,
|
|
3171
|
+
incrementalEdits
|
|
3172
|
+
};
|
|
3173
|
+
if (incrementalEdits !== emptyIncrementalEdits) {
|
|
3174
|
+
return newEditor2;
|
|
3175
|
+
}
|
|
3176
|
+
const syncIncremental = getEnabled();
|
|
3177
|
+
const {
|
|
3178
|
+
textInfos,
|
|
3179
|
+
differences
|
|
3180
|
+
} = await getVisible$1(newEditor2, syncIncremental);
|
|
3181
|
+
return {
|
|
3182
|
+
...newEditor2,
|
|
3183
|
+
textInfos,
|
|
3184
|
+
differences
|
|
2435
3185
|
};
|
|
2436
|
-
return newEditor2;
|
|
2437
3186
|
};
|
|
2438
3187
|
// @ts-ignore
|
|
2439
|
-
const scheduleDocumentAndCursorsSelectionIsUndo = (editor, changes) => {
|
|
3188
|
+
const scheduleDocumentAndCursorsSelectionIsUndo = async (editor, changes) => {
|
|
2440
3189
|
object(editor);
|
|
2441
3190
|
array(changes);
|
|
2442
3191
|
if (changes.length === 0) {
|
|
@@ -2456,7 +3205,26 @@ const scheduleDocumentAndCursorsSelectionIsUndo = (editor, changes) => {
|
|
|
2456
3205
|
// undoStack: [...editor.undoStack.slice(0, -2)],
|
|
2457
3206
|
invalidStartIndex
|
|
2458
3207
|
};
|
|
2459
|
-
|
|
3208
|
+
const incrementalEdits = await getIncrementalEdits(editor, newEditor);
|
|
3209
|
+
|
|
3210
|
+
// TODO change event should be emitted after rendering
|
|
3211
|
+
const finalEditor = {
|
|
3212
|
+
...newEditor,
|
|
3213
|
+
incrementalEdits
|
|
3214
|
+
};
|
|
3215
|
+
if (incrementalEdits !== emptyIncrementalEdits) {
|
|
3216
|
+
return finalEditor;
|
|
3217
|
+
}
|
|
3218
|
+
const syncIncremental = getEnabled();
|
|
3219
|
+
const {
|
|
3220
|
+
textInfos,
|
|
3221
|
+
differences
|
|
3222
|
+
} = await getVisible$1(finalEditor, syncIncremental);
|
|
3223
|
+
return {
|
|
3224
|
+
...finalEditor,
|
|
3225
|
+
textInfos,
|
|
3226
|
+
differences
|
|
3227
|
+
};
|
|
2460
3228
|
};
|
|
2461
3229
|
|
|
2462
3230
|
// @ts-ignore
|
|
@@ -2481,8 +3249,26 @@ const scheduleDocument = async (editor, changes) => {
|
|
|
2481
3249
|
lines: newLines,
|
|
2482
3250
|
invalidStartIndex
|
|
2483
3251
|
};
|
|
3252
|
+
const incrementalEdits = await getIncrementalEdits(editor, newEditor);
|
|
3253
|
+
|
|
2484
3254
|
// TODO change event should be emitted after rendering
|
|
2485
|
-
|
|
3255
|
+
const finalEditor = {
|
|
3256
|
+
...newEditor,
|
|
3257
|
+
incrementalEdits
|
|
3258
|
+
};
|
|
3259
|
+
if (incrementalEdits !== emptyIncrementalEdits) {
|
|
3260
|
+
return finalEditor;
|
|
3261
|
+
}
|
|
3262
|
+
const syncIncremental = getEnabled();
|
|
3263
|
+
const {
|
|
3264
|
+
textInfos,
|
|
3265
|
+
differences
|
|
3266
|
+
} = await getVisible$1(finalEditor, syncIncremental);
|
|
3267
|
+
return {
|
|
3268
|
+
...finalEditor,
|
|
3269
|
+
textInfos,
|
|
3270
|
+
differences
|
|
3271
|
+
};
|
|
2486
3272
|
// RendererProcess.send([
|
|
2487
3273
|
// /* Viewlet.invoke */ 'Viewlet.send',
|
|
2488
3274
|
// /* id */ 'EditorText',
|
|
@@ -2548,8 +3334,8 @@ const TabCompletionExecuteTabCompletionProvider = 'ExtensionHost.executeTabCompl
|
|
|
2548
3334
|
const TextDocumentSyncFull = 'ExtensionHostTextDocument.syncFull';
|
|
2549
3335
|
|
|
2550
3336
|
const {
|
|
2551
|
-
set: set$
|
|
2552
|
-
invoke: invoke$
|
|
3337
|
+
set: set$1,
|
|
3338
|
+
invoke: invoke$6} = ExtensionHost;
|
|
2553
3339
|
|
|
2554
3340
|
const ColorPicker = 41;
|
|
2555
3341
|
const EditorCompletion = 9;
|
|
@@ -2578,7 +3364,7 @@ const execute = async ({
|
|
|
2578
3364
|
}) => {
|
|
2579
3365
|
const fullEvent = `${event}:${editor.languageId}`;
|
|
2580
3366
|
await activateByEvent(fullEvent);
|
|
2581
|
-
const result = await invoke$
|
|
3367
|
+
const result = await invoke$6(method, editor.uid, ...args);
|
|
2582
3368
|
return result;
|
|
2583
3369
|
};
|
|
2584
3370
|
|
|
@@ -2646,7 +3432,7 @@ const updateDiagnostics = async newState => {
|
|
|
2646
3432
|
// TODO don't really need text document sync response
|
|
2647
3433
|
// could perhaps save a lot of messages by using send instead of invoke
|
|
2648
3434
|
// @ts-ignore
|
|
2649
|
-
await invoke$
|
|
3435
|
+
await invoke$6(TextDocumentSyncFull, newState.uri, newState.id, newState.languageId, content);
|
|
2650
3436
|
const diagnostics = await executeDiagnosticProvider(newState);
|
|
2651
3437
|
const latest = get$4(newState.id);
|
|
2652
3438
|
if (!latest) {
|
|
@@ -2672,6 +3458,8 @@ const updateDiagnostics = async newState => {
|
|
|
2672
3458
|
};
|
|
2673
3459
|
|
|
2674
3460
|
const emptyEditor = {
|
|
3461
|
+
textInfos: [],
|
|
3462
|
+
differences: [],
|
|
2675
3463
|
uri: '',
|
|
2676
3464
|
languageId: '',
|
|
2677
3465
|
// TODO use numeric language id?
|
|
@@ -2695,7 +3483,8 @@ const emptyEditor = {
|
|
|
2695
3483
|
selections: new Uint32Array(),
|
|
2696
3484
|
diagnostics: [],
|
|
2697
3485
|
highlightedLine: -1,
|
|
2698
|
-
debugEnabled: false
|
|
3486
|
+
debugEnabled: false,
|
|
3487
|
+
incrementalEdits: emptyIncrementalEdits
|
|
2699
3488
|
};
|
|
2700
3489
|
const createEditor = async ({
|
|
2701
3490
|
id,
|
|
@@ -2732,6 +3521,7 @@ const createEditor = async ({
|
|
|
2732
3521
|
string(content);
|
|
2733
3522
|
const charWidth = measureCharacterWidth(fontWeight, fontSize, fontFamily, letterSpacing);
|
|
2734
3523
|
const editor = {
|
|
3524
|
+
textInfos: [],
|
|
2735
3525
|
uri,
|
|
2736
3526
|
isAutoClosingBracketsEnabled,
|
|
2737
3527
|
isAutoClosingTagsEnabled,
|
|
@@ -2787,7 +3577,8 @@ const createEditor = async ({
|
|
|
2787
3577
|
id,
|
|
2788
3578
|
widgets: [],
|
|
2789
3579
|
focusKey: Empty,
|
|
2790
|
-
diagnosticsEnabled
|
|
3580
|
+
diagnosticsEnabled,
|
|
3581
|
+
incrementalEdits: emptyIncrementalEdits
|
|
2791
3582
|
};
|
|
2792
3583
|
// TODO avoid creating intermediate editors here
|
|
2793
3584
|
const newEditor1 = setBounds(editor, x, y, width, height, 9);
|
|
@@ -2800,13 +3591,23 @@ const createEditor = async ({
|
|
|
2800
3591
|
} else {
|
|
2801
3592
|
newEditor3 = setDeltaY$2(newEditor2, 0);
|
|
2802
3593
|
}
|
|
3594
|
+
const syncIncremental = getEnabled();
|
|
3595
|
+
const {
|
|
3596
|
+
textInfos,
|
|
3597
|
+
differences
|
|
3598
|
+
} = await getVisible$1(newEditor3, syncIncremental);
|
|
2803
3599
|
const newEditor4 = {
|
|
2804
3600
|
...newEditor3,
|
|
2805
|
-
focused: true
|
|
3601
|
+
focused: true,
|
|
3602
|
+
textInfos,
|
|
3603
|
+
differences
|
|
2806
3604
|
};
|
|
2807
3605
|
set$6(id, emptyEditor, newEditor4);
|
|
3606
|
+
|
|
3607
|
+
// TODO only sync when needed
|
|
3608
|
+
// e.g. it might not always be necessary to send text to extension host worker
|
|
2808
3609
|
// @ts-ignore
|
|
2809
|
-
await invoke$
|
|
3610
|
+
await invoke$6(TextDocumentSyncFull, uri, id, languageId, content);
|
|
2810
3611
|
if (diagnosticsEnabled) {
|
|
2811
3612
|
updateDiagnostics(newEditor4);
|
|
2812
3613
|
}
|
|
@@ -3086,7 +3887,7 @@ const guessOffset = (eventX, averageCharWidth) => {
|
|
|
3086
3887
|
const normalizeGuess = (line, guess, tabSize) => {
|
|
3087
3888
|
let normalizedGuess = guess;
|
|
3088
3889
|
for (let i = 0; i < guess; i++) {
|
|
3089
|
-
if (line[i] === Tab
|
|
3890
|
+
if (line[i] === Tab) {
|
|
3090
3891
|
normalizedGuess -= tabSize - 1;
|
|
3091
3892
|
}
|
|
3092
3893
|
}
|
|
@@ -3180,7 +3981,7 @@ const y = (editor, rowIndex) => {
|
|
|
3180
3981
|
return offsetY;
|
|
3181
3982
|
};
|
|
3182
3983
|
|
|
3183
|
-
const state$
|
|
3984
|
+
const state$5 = {
|
|
3184
3985
|
timeout: -1
|
|
3185
3986
|
};
|
|
3186
3987
|
|
|
@@ -3211,7 +4012,7 @@ const editorShowMessage = async (editor, rowIndex, columnIndex, message, isError
|
|
|
3211
4012
|
|
|
3212
4013
|
// TODO use wrapper timing module instead of this
|
|
3213
4014
|
// @ts-ignore
|
|
3214
|
-
state$
|
|
4015
|
+
state$5.timeout = setTimeout(handleTimeout, 3000);
|
|
3215
4016
|
}
|
|
3216
4017
|
return editor;
|
|
3217
4018
|
};
|
|
@@ -3231,8 +4032,8 @@ const showErrorMessage = async (editor, rowIndex, columnIndex, message) => {
|
|
|
3231
4032
|
|
|
3232
4033
|
// @ts-ignore
|
|
3233
4034
|
const editorHideMessage = async editor => {
|
|
3234
|
-
clearTimeout(state$
|
|
3235
|
-
state$
|
|
4035
|
+
clearTimeout(state$5.timeout);
|
|
4036
|
+
state$5.timeout = -1;
|
|
3236
4037
|
// await RendererProcess.invoke(/* Viewlet.send */ 'Viewlet.send', /* id */ editor.uid, /* method */ 'hideOverlayMessage')
|
|
3237
4038
|
return editor;
|
|
3238
4039
|
};
|
|
@@ -3357,7 +4158,7 @@ const getOrCreate$3 = () => {
|
|
|
3357
4158
|
}
|
|
3358
4159
|
return workerPromise$3;
|
|
3359
4160
|
};
|
|
3360
|
-
const invoke$
|
|
4161
|
+
const invoke$5 = async (method, ...params) => {
|
|
3361
4162
|
const worker = await getOrCreate$3();
|
|
3362
4163
|
return await worker.invoke(method, ...params);
|
|
3363
4164
|
};
|
|
@@ -3376,7 +4177,7 @@ const closeRename = async editor => {
|
|
|
3376
4177
|
return editor;
|
|
3377
4178
|
}
|
|
3378
4179
|
const renameWidget = widgets[renameWidgetIndex];
|
|
3379
|
-
await invoke$
|
|
4180
|
+
await invoke$5('Rename.close', renameWidget.newState.uid);
|
|
3380
4181
|
const latest = get$4(uid);
|
|
3381
4182
|
const {
|
|
3382
4183
|
newState
|
|
@@ -3495,12 +4296,12 @@ const openColorPicker = async editor => {
|
|
|
3495
4296
|
return addWidgetToEditor(ColorPicker$1, ColorPicker, editor, create$6, newStateGenerator$6);
|
|
3496
4297
|
};
|
|
3497
4298
|
|
|
3498
|
-
const state$
|
|
4299
|
+
const state$4 = {
|
|
3499
4300
|
isComposing: false,
|
|
3500
4301
|
compositionText: ''
|
|
3501
4302
|
};
|
|
3502
4303
|
const compositionStart = (editor, event) => {
|
|
3503
|
-
state$
|
|
4304
|
+
state$4.isComposing = true;
|
|
3504
4305
|
return editor;
|
|
3505
4306
|
};
|
|
3506
4307
|
const getCompositionChanges = (selections, data) => {
|
|
@@ -3510,7 +4311,7 @@ const getCompositionChanges = (selections, data) => {
|
|
|
3510
4311
|
const selectionStartColumn = selections[i + 1];
|
|
3511
4312
|
const selectionEndRow = selections[i + 2];
|
|
3512
4313
|
const selectionEndColumn = selections[i + 3];
|
|
3513
|
-
const startColumnIndex = selectionStartColumn - state$
|
|
4314
|
+
const startColumnIndex = selectionStartColumn - state$4.compositionText.length;
|
|
3514
4315
|
changes.push({
|
|
3515
4316
|
start: {
|
|
3516
4317
|
rowIndex: selectionStartRow,
|
|
@@ -3521,7 +4322,7 @@ const getCompositionChanges = (selections, data) => {
|
|
|
3521
4322
|
columnIndex: selectionEndColumn
|
|
3522
4323
|
},
|
|
3523
4324
|
inserted: [data],
|
|
3524
|
-
deleted: [state$
|
|
4325
|
+
deleted: [state$4.compositionText],
|
|
3525
4326
|
origin: CompositionUpdate
|
|
3526
4327
|
});
|
|
3527
4328
|
}
|
|
@@ -3532,7 +4333,7 @@ const compositionUpdate = (editor, data) => {
|
|
|
3532
4333
|
selections
|
|
3533
4334
|
} = editor;
|
|
3534
4335
|
const changes = getCompositionChanges(selections, data);
|
|
3535
|
-
state$
|
|
4336
|
+
state$4.compositionText = data;
|
|
3536
4337
|
return scheduleDocumentAndCursorsSelections(editor, changes);
|
|
3537
4338
|
};
|
|
3538
4339
|
const compositionEnd = (editor, data) => {
|
|
@@ -3540,8 +4341,8 @@ const compositionEnd = (editor, data) => {
|
|
|
3540
4341
|
selections
|
|
3541
4342
|
} = editor;
|
|
3542
4343
|
const changes = getCompositionChanges(selections, data);
|
|
3543
|
-
state$
|
|
3544
|
-
state$
|
|
4344
|
+
state$4.isComposing = false;
|
|
4345
|
+
state$4.compositionText = '';
|
|
3545
4346
|
return scheduleDocumentAndCursorsSelections(editor, changes);
|
|
3546
4347
|
};
|
|
3547
4348
|
|
|
@@ -3755,7 +4556,7 @@ const characterRight = (line, columnIndex) => {
|
|
|
3755
4556
|
return next.segment.length;
|
|
3756
4557
|
};
|
|
3757
4558
|
const isWhitespace = char => {
|
|
3758
|
-
return char === Space
|
|
4559
|
+
return char === Space || char === Tab;
|
|
3759
4560
|
};
|
|
3760
4561
|
const lineCharacterStart = (line, columnIndex) => {
|
|
3761
4562
|
if (line.length === 0) {
|
|
@@ -4567,68 +5368,19 @@ const goToTypeDefinition = async (editor, explicit = true) => {
|
|
|
4567
5368
|
});
|
|
4568
5369
|
};
|
|
4569
5370
|
|
|
4570
|
-
const
|
|
4571
|
-
|
|
4572
|
-
const handleContextMenu = async (editor, button, x, y) => {
|
|
4573
|
-
await invoke$9(/* ContextMenu.show */'ContextMenu.show', /* x */x, /* y */y, /* id */Editor);
|
|
4574
|
-
return editor;
|
|
4575
|
-
};
|
|
4576
|
-
|
|
4577
|
-
// @ts-ignore
|
|
4578
|
-
|
|
4579
|
-
// match all words, including umlauts, see https://stackoverflow.com/questions/5436824/matching-accented-characters-with-javascript-regexes/#answer-11550799
|
|
4580
|
-
const RE_WORD_START = /^[a-z\u00C0-\u017F\d]+/i;
|
|
4581
|
-
const RE_WORD_END = /[a-z\u00C0-\u017F\d]+$/i;
|
|
4582
|
-
|
|
4583
|
-
// @ts-ignore
|
|
4584
|
-
const getNewSelections$7 = (line, rowIndex, columnIndex) => {
|
|
4585
|
-
const before = line.slice(0, columnIndex);
|
|
4586
|
-
const after = line.slice(columnIndex);
|
|
4587
|
-
const beforeMatch = before.match(RE_WORD_END);
|
|
4588
|
-
const afterMatch = after.match(RE_WORD_START);
|
|
4589
|
-
const columnStart = columnIndex - (beforeMatch ? beforeMatch[0].length : 0);
|
|
4590
|
-
const columnEnd = columnIndex + (afterMatch ? afterMatch[0].length : 0);
|
|
4591
|
-
const newSelections = new Uint32Array([rowIndex, columnStart, rowIndex, columnEnd]);
|
|
4592
|
-
return newSelections;
|
|
4593
|
-
};
|
|
4594
|
-
|
|
4595
|
-
// @ts-ignore
|
|
4596
|
-
const selectWord = (editor, rowIndex, columnIndex) => {
|
|
4597
|
-
const line = getLine(editor, rowIndex);
|
|
4598
|
-
const newSelections = getNewSelections$7(line, rowIndex, columnIndex);
|
|
4599
|
-
return scheduleSelections(editor, newSelections);
|
|
4600
|
-
};
|
|
4601
|
-
|
|
4602
|
-
const handleDoubleClick = (editor, modifier, x, y) => {
|
|
4603
|
-
const position = at(editor, x, y);
|
|
4604
|
-
return selectWord(editor, position.rowIndex, position.columnIndex);
|
|
4605
|
-
};
|
|
4606
|
-
|
|
4607
|
-
const WhenExpressionEditorText = 12;
|
|
4608
|
-
const handleFocus$1 = editor => {
|
|
4609
|
-
// TODO make change events functional,
|
|
4610
|
-
// when rendering, send focus changes to renderer worker
|
|
4611
|
-
invoke$9('Focus.setFocus', WhenExpressionEditorText);
|
|
4612
|
-
return editor;
|
|
4613
|
-
};
|
|
4614
|
-
|
|
4615
|
-
const Single = 1;
|
|
4616
|
-
const Double = 2;
|
|
4617
|
-
const Triple = 3;
|
|
4618
|
-
|
|
4619
|
-
const state$5 = {
|
|
5371
|
+
const state$3 = {
|
|
4620
5372
|
position: {
|
|
4621
5373
|
rowIndex: 0,
|
|
4622
5374
|
columnIndex: 0
|
|
4623
5375
|
}
|
|
4624
5376
|
};
|
|
4625
5377
|
const getPosition$1 = () => {
|
|
4626
|
-
return state$
|
|
5378
|
+
return state$3.position;
|
|
4627
5379
|
};
|
|
4628
5380
|
|
|
4629
5381
|
// @ts-ignore
|
|
4630
5382
|
const setPosition$1 = position => {
|
|
4631
|
-
state$
|
|
5383
|
+
state$3.position = position;
|
|
4632
5384
|
};
|
|
4633
5385
|
|
|
4634
5386
|
// TODO first change cursor position, then run go to definition
|
|
@@ -4675,7 +5427,7 @@ const handleSingleClickWithCtrl = async (editor, position) => {
|
|
|
4675
5427
|
};
|
|
4676
5428
|
|
|
4677
5429
|
const Ctrl = 1;
|
|
4678
|
-
const Alt
|
|
5430
|
+
const Alt = 2;
|
|
4679
5431
|
|
|
4680
5432
|
const handleSingleClickDefault = (editor, position) => {
|
|
4681
5433
|
setPosition$1(position);
|
|
@@ -4685,37 +5437,86 @@ const handleSingleClickDefault = (editor, position) => {
|
|
|
4685
5437
|
focused: true
|
|
4686
5438
|
};
|
|
4687
5439
|
};
|
|
4688
|
-
const getClickHandler = modifier => {
|
|
4689
|
-
switch (modifier) {
|
|
4690
|
-
case Alt
|
|
4691
|
-
return handleSingleClickWithAlt;
|
|
4692
|
-
case Ctrl:
|
|
4693
|
-
return handleSingleClickWithCtrl;
|
|
4694
|
-
default:
|
|
4695
|
-
return handleSingleClickDefault;
|
|
4696
|
-
}
|
|
5440
|
+
const getClickHandler = modifier => {
|
|
5441
|
+
switch (modifier) {
|
|
5442
|
+
case Alt:
|
|
5443
|
+
return handleSingleClickWithAlt;
|
|
5444
|
+
case Ctrl:
|
|
5445
|
+
return handleSingleClickWithCtrl;
|
|
5446
|
+
default:
|
|
5447
|
+
return handleSingleClickDefault;
|
|
5448
|
+
}
|
|
5449
|
+
};
|
|
5450
|
+
|
|
5451
|
+
const handleClickAtPosition = async (editor, modifier, rowIndex, columnIndex) => {
|
|
5452
|
+
object(editor);
|
|
5453
|
+
number(modifier);
|
|
5454
|
+
number(rowIndex);
|
|
5455
|
+
number(columnIndex);
|
|
5456
|
+
const fn = getClickHandler(modifier);
|
|
5457
|
+
const newEditor = await fn(editor, {
|
|
5458
|
+
rowIndex,
|
|
5459
|
+
columnIndex
|
|
5460
|
+
});
|
|
5461
|
+
return newEditor;
|
|
5462
|
+
};
|
|
5463
|
+
|
|
5464
|
+
const Editor = 3;
|
|
5465
|
+
|
|
5466
|
+
const handleContextMenu = async (editor, button, x, y) => {
|
|
5467
|
+
await invoke$9(/* ContextMenu.show */'ContextMenu.show', /* x */x, /* y */y, /* id */Editor);
|
|
5468
|
+
return editor;
|
|
5469
|
+
};
|
|
5470
|
+
|
|
5471
|
+
// @ts-ignore
|
|
5472
|
+
|
|
5473
|
+
// match all words, including umlauts, see https://stackoverflow.com/questions/5436824/matching-accented-characters-with-javascript-regexes/#answer-11550799
|
|
5474
|
+
const RE_WORD_START = /^[a-z\u00C0-\u017F\d]+/i;
|
|
5475
|
+
const RE_WORD_END = /[a-z\u00C0-\u017F\d]+$/i;
|
|
5476
|
+
|
|
5477
|
+
// @ts-ignore
|
|
5478
|
+
const getNewSelections$7 = (line, rowIndex, columnIndex) => {
|
|
5479
|
+
const before = line.slice(0, columnIndex);
|
|
5480
|
+
const after = line.slice(columnIndex);
|
|
5481
|
+
const beforeMatch = before.match(RE_WORD_END);
|
|
5482
|
+
const afterMatch = after.match(RE_WORD_START);
|
|
5483
|
+
const columnStart = columnIndex - (beforeMatch ? beforeMatch[0].length : 0);
|
|
5484
|
+
const columnEnd = columnIndex + (afterMatch ? afterMatch[0].length : 0);
|
|
5485
|
+
const newSelections = new Uint32Array([rowIndex, columnStart, rowIndex, columnEnd]);
|
|
5486
|
+
return newSelections;
|
|
5487
|
+
};
|
|
5488
|
+
|
|
5489
|
+
// @ts-ignore
|
|
5490
|
+
const selectWord = (editor, rowIndex, columnIndex) => {
|
|
5491
|
+
const line = getLine(editor, rowIndex);
|
|
5492
|
+
const newSelections = getNewSelections$7(line, rowIndex, columnIndex);
|
|
5493
|
+
return scheduleSelections(editor, newSelections);
|
|
5494
|
+
};
|
|
5495
|
+
|
|
5496
|
+
const handleDoubleClick = (editor, modifier, x, y) => {
|
|
5497
|
+
const position = at(editor, x, y);
|
|
5498
|
+
return selectWord(editor, position.rowIndex, position.columnIndex);
|
|
5499
|
+
};
|
|
5500
|
+
|
|
5501
|
+
const WhenExpressionEditorText = 12;
|
|
5502
|
+
const handleFocus$1 = editor => {
|
|
5503
|
+
// TODO make change events functional,
|
|
5504
|
+
// when rendering, send focus changes to renderer worker
|
|
5505
|
+
invoke$9('Focus.setFocus', WhenExpressionEditorText);
|
|
5506
|
+
return editor;
|
|
4697
5507
|
};
|
|
4698
5508
|
|
|
5509
|
+
const Single = 1;
|
|
5510
|
+
const Double = 2;
|
|
5511
|
+
const Triple = 3;
|
|
5512
|
+
|
|
4699
5513
|
const handleSingleClick = async (editor, modifier, x, y) => {
|
|
4700
5514
|
object(editor);
|
|
4701
5515
|
number(modifier);
|
|
4702
5516
|
number(x);
|
|
4703
5517
|
number(y);
|
|
4704
5518
|
const position = at(editor, x, y);
|
|
4705
|
-
|
|
4706
|
-
const newEditor = await fn(editor, position);
|
|
4707
|
-
// switch (newEditor.completionState) {
|
|
4708
|
-
// case EditorCompletionState.None:
|
|
4709
|
-
// case EditorCompletionState.Visible:
|
|
4710
|
-
// case EditorCompletionState.Loading:
|
|
4711
|
-
// return {
|
|
4712
|
-
// newState: newEditor,
|
|
4713
|
-
// commands: [],
|
|
4714
|
-
// }
|
|
4715
|
-
// default:
|
|
4716
|
-
// break
|
|
4717
|
-
// }
|
|
4718
|
-
return newEditor;
|
|
5519
|
+
return handleClickAtPosition(editor, modifier, position.rowIndex, position.columnIndex);
|
|
4719
5520
|
};
|
|
4720
5521
|
|
|
4721
5522
|
// @ts-ignore
|
|
@@ -4762,20 +5563,20 @@ const handleMouseDown = (state, modifier, x, y, detail) => {
|
|
|
4762
5563
|
}
|
|
4763
5564
|
};
|
|
4764
5565
|
|
|
4765
|
-
const state$
|
|
5566
|
+
const state$2 = {
|
|
4766
5567
|
timeout: -1,
|
|
4767
5568
|
x: 0,
|
|
4768
5569
|
y: 0,
|
|
4769
5570
|
editor: undefined
|
|
4770
5571
|
};
|
|
4771
|
-
const get
|
|
4772
|
-
return state$
|
|
5572
|
+
const get = () => {
|
|
5573
|
+
return state$2;
|
|
4773
5574
|
};
|
|
4774
|
-
const set
|
|
4775
|
-
state$
|
|
4776
|
-
state$
|
|
4777
|
-
state$
|
|
4778
|
-
state$
|
|
5575
|
+
const set = (editor, timeout, x, y) => {
|
|
5576
|
+
state$2.editor = editor;
|
|
5577
|
+
state$2.timeout = timeout;
|
|
5578
|
+
state$2.x = x;
|
|
5579
|
+
state$2.y = y;
|
|
4779
5580
|
};
|
|
4780
5581
|
|
|
4781
5582
|
const showHover$1 = async (editor, position) => {
|
|
@@ -4797,7 +5598,7 @@ const onHoverIdle = async () => {
|
|
|
4797
5598
|
x,
|
|
4798
5599
|
y,
|
|
4799
5600
|
editor
|
|
4800
|
-
} = get
|
|
5601
|
+
} = get();
|
|
4801
5602
|
at(editor, x, y);
|
|
4802
5603
|
await showHover$1();
|
|
4803
5604
|
};
|
|
@@ -4808,12 +5609,12 @@ const handleMouseMove = (editor, x, y) => {
|
|
|
4808
5609
|
if (!editor.hoverEnabled) {
|
|
4809
5610
|
return editor;
|
|
4810
5611
|
}
|
|
4811
|
-
const oldState = get
|
|
5612
|
+
const oldState = get();
|
|
4812
5613
|
if (oldState.timeout !== -1) {
|
|
4813
5614
|
clearTimeout(oldState.timeout);
|
|
4814
5615
|
}
|
|
4815
5616
|
const timeout = setTimeout(onHoverIdle, hoverDelay);
|
|
4816
|
-
set
|
|
5617
|
+
set(editor, timeout, x, y);
|
|
4817
5618
|
return editor;
|
|
4818
5619
|
};
|
|
4819
5620
|
|
|
@@ -4920,7 +5721,7 @@ const editorHandleNativeSelectionChange = (editor, range) => {
|
|
|
4920
5721
|
return scheduleSelections(editor, selections);
|
|
4921
5722
|
};
|
|
4922
5723
|
|
|
4923
|
-
const state$
|
|
5724
|
+
const state$1 = {
|
|
4924
5725
|
/**
|
|
4925
5726
|
* @type {any}
|
|
4926
5727
|
*/
|
|
@@ -4934,26 +5735,26 @@ const state$3 = {
|
|
|
4934
5735
|
|
|
4935
5736
|
// @ts-ignore
|
|
4936
5737
|
const setEditor = editor => {
|
|
4937
|
-
state$
|
|
4938
|
-
state$
|
|
5738
|
+
state$1.currentEditor = editor;
|
|
5739
|
+
state$1.hasListener = true;
|
|
4939
5740
|
};
|
|
4940
5741
|
const clearEditor = () => {
|
|
4941
|
-
state$
|
|
4942
|
-
state$
|
|
5742
|
+
state$1.currentEditor = undefined;
|
|
5743
|
+
state$1.hasListener = false;
|
|
4943
5744
|
};
|
|
4944
5745
|
|
|
4945
5746
|
// @ts-ignore
|
|
4946
5747
|
const setPosition = position => {
|
|
4947
|
-
state$
|
|
5748
|
+
state$1.position = position;
|
|
4948
5749
|
};
|
|
4949
5750
|
const getEditor$1 = () => {
|
|
4950
|
-
return state$
|
|
5751
|
+
return state$1.currentEditor;
|
|
4951
5752
|
};
|
|
4952
5753
|
const getPosition = () => {
|
|
4953
|
-
return state$
|
|
5754
|
+
return state$1.position;
|
|
4954
5755
|
};
|
|
4955
5756
|
const hasListener = () => {
|
|
4956
|
-
return state$
|
|
5757
|
+
return state$1.hasListener;
|
|
4957
5758
|
};
|
|
4958
5759
|
|
|
4959
5760
|
// @ts-ignore
|
|
@@ -5136,7 +5937,7 @@ const handleTouchEnd = (editor, touchEvent) => {
|
|
|
5136
5937
|
// }
|
|
5137
5938
|
};
|
|
5138
5939
|
|
|
5139
|
-
const state
|
|
5940
|
+
const state = {
|
|
5140
5941
|
touchOffsetY: 0,
|
|
5141
5942
|
deltaY: 0
|
|
5142
5943
|
};
|
|
@@ -5147,8 +5948,8 @@ const handleTouchStart = (editor, touchEvent) => {
|
|
|
5147
5948
|
return;
|
|
5148
5949
|
}
|
|
5149
5950
|
const firstTouch = touchEvent.touches[0];
|
|
5150
|
-
state
|
|
5151
|
-
state
|
|
5951
|
+
state.touchOffsetY = firstTouch.y;
|
|
5952
|
+
state.deltaY = editor.deltaY;
|
|
5152
5953
|
// const position = EditorPosition.at(editor, firstTouch.x, firstTouch.y)
|
|
5153
5954
|
// EditorMoveSelection.state.position = position
|
|
5154
5955
|
// state.date = Date.now()
|
|
@@ -5188,7 +5989,7 @@ const handleTouchMove = (editor, touchEvent) => {
|
|
|
5188
5989
|
return;
|
|
5189
5990
|
}
|
|
5190
5991
|
const firstTouch = touchEvent.touches[0];
|
|
5191
|
-
const offsetY = state
|
|
5992
|
+
const offsetY = state.deltaY + (state.touchOffsetY - firstTouch.y);
|
|
5192
5993
|
setDeltaYFixedValue(editor, offsetY);
|
|
5193
5994
|
};
|
|
5194
5995
|
|
|
@@ -5624,7 +6425,7 @@ const getOrCreate$2 = () => {
|
|
|
5624
6425
|
}
|
|
5625
6426
|
return workerPromise$2;
|
|
5626
6427
|
};
|
|
5627
|
-
const invoke$
|
|
6428
|
+
const invoke$4 = async (method, ...params) => {
|
|
5628
6429
|
const worker = await getOrCreate$2();
|
|
5629
6430
|
return await worker.invoke(method, ...params);
|
|
5630
6431
|
};
|
|
@@ -5643,10 +6444,10 @@ const newStateGenerator$4 = async (state, parentUid) => {
|
|
|
5643
6444
|
const {
|
|
5644
6445
|
languageId
|
|
5645
6446
|
} = newState;
|
|
5646
|
-
await invoke$
|
|
5647
|
-
await invoke$
|
|
5648
|
-
const diff = await invoke$
|
|
5649
|
-
const commands = await invoke$
|
|
6447
|
+
await invoke$4('Completions.create', uid, x, y, width, height, parentUid, languageId);
|
|
6448
|
+
await invoke$4('Completions.loadContent', uid);
|
|
6449
|
+
const diff = await invoke$4('Completions.diff2', uid);
|
|
6450
|
+
const commands = await invoke$4('Completions.render2', uid, diff);
|
|
5650
6451
|
return {
|
|
5651
6452
|
...state,
|
|
5652
6453
|
commands
|
|
@@ -5698,7 +6499,7 @@ const launch = async () => {
|
|
|
5698
6499
|
const rpc = await launchFindWidgetWorker();
|
|
5699
6500
|
set$c(rpcId, rpc);
|
|
5700
6501
|
};
|
|
5701
|
-
const invoke$
|
|
6502
|
+
const invoke$3 = async (method, ...params) => {
|
|
5702
6503
|
const rpc = get$6(rpcId);
|
|
5703
6504
|
return await rpc.invoke(method, ...params);
|
|
5704
6505
|
};
|
|
@@ -5737,10 +6538,10 @@ const loadContent$1 = async (state, parentUid) => {
|
|
|
5737
6538
|
height
|
|
5738
6539
|
} = editor;
|
|
5739
6540
|
await launch();
|
|
5740
|
-
await invoke$
|
|
5741
|
-
await invoke$
|
|
5742
|
-
const diff = await invoke$
|
|
5743
|
-
const commands = await invoke$
|
|
6541
|
+
await invoke$3('FindWidget.create', uid, x, y, width, height, parentUid);
|
|
6542
|
+
await invoke$3('FindWidget.loadContent', uid);
|
|
6543
|
+
const diff = await invoke$3('FindWidget.diff2', uid);
|
|
6544
|
+
const commands = await invoke$3('FindWidget.render2', uid, diff);
|
|
5744
6545
|
return {
|
|
5745
6546
|
...state,
|
|
5746
6547
|
commands
|
|
@@ -5813,10 +6614,10 @@ const newStateGenerator$2 = async (state, parentUid) => {
|
|
|
5813
6614
|
const {
|
|
5814
6615
|
languageId
|
|
5815
6616
|
} = newState;
|
|
5816
|
-
await invoke$
|
|
5817
|
-
await invoke$
|
|
5818
|
-
const diff = await invoke$
|
|
5819
|
-
const commands = await invoke$
|
|
6617
|
+
await invoke$5('Rename.create', uid, x, y, width, height, parentUid, languageId);
|
|
6618
|
+
await invoke$5('Rename.loadContent', uid);
|
|
6619
|
+
const diff = await invoke$5('Rename.diff2', uid);
|
|
6620
|
+
const commands = await invoke$5('Rename.render2', uid, diff);
|
|
5820
6621
|
return {
|
|
5821
6622
|
...state,
|
|
5822
6623
|
commands
|
|
@@ -6556,128 +7357,6 @@ const setDecorations = (editor, decorations, diagnostics) => {
|
|
|
6556
7357
|
};
|
|
6557
7358
|
};
|
|
6558
7359
|
|
|
6559
|
-
let enabled$1 = false;
|
|
6560
|
-
const setEnabled$1 = value => {
|
|
6561
|
-
enabled$1 = value;
|
|
6562
|
-
};
|
|
6563
|
-
const getEnabled$1 = () => {
|
|
6564
|
-
return enabled$1;
|
|
6565
|
-
};
|
|
6566
|
-
|
|
6567
|
-
const {
|
|
6568
|
-
set: set$3,
|
|
6569
|
-
invoke: invoke$3} = SyntaxHighlightingWorker;
|
|
6570
|
-
|
|
6571
|
-
/**
|
|
6572
|
-
* @enum number
|
|
6573
|
-
*/
|
|
6574
|
-
const State = {
|
|
6575
|
-
TopLevelContent: 1
|
|
6576
|
-
};
|
|
6577
|
-
|
|
6578
|
-
/**
|
|
6579
|
-
* @enum number
|
|
6580
|
-
*/
|
|
6581
|
-
const TokenType = {
|
|
6582
|
-
Text: 1
|
|
6583
|
-
};
|
|
6584
|
-
const TokenMap = {
|
|
6585
|
-
[TokenType.Text]: 'Text'
|
|
6586
|
-
};
|
|
6587
|
-
const initialLineState = {
|
|
6588
|
-
state: State.TopLevelContent
|
|
6589
|
-
};
|
|
6590
|
-
const hasArrayReturn = true;
|
|
6591
|
-
const tokenizeLine = (line, lineState) => {
|
|
6592
|
-
return {
|
|
6593
|
-
tokens: [TokenType.Text, line.length],
|
|
6594
|
-
state: lineState.state
|
|
6595
|
-
};
|
|
6596
|
-
};
|
|
6597
|
-
|
|
6598
|
-
const TokenizePlainText = {
|
|
6599
|
-
__proto__: null,
|
|
6600
|
-
State,
|
|
6601
|
-
TokenMap,
|
|
6602
|
-
TokenType,
|
|
6603
|
-
hasArrayReturn,
|
|
6604
|
-
initialLineState,
|
|
6605
|
-
tokenizeLine
|
|
6606
|
-
};
|
|
6607
|
-
|
|
6608
|
-
const state$1 = {
|
|
6609
|
-
tokenizers: Object.create(null),
|
|
6610
|
-
pending: Object.create(null)};
|
|
6611
|
-
const has = languageId => {
|
|
6612
|
-
return languageId in state$1.tokenizers;
|
|
6613
|
-
};
|
|
6614
|
-
const set$2 = (languageId, tokenizer) => {
|
|
6615
|
-
state$1.tokenizers[languageId] = tokenizer;
|
|
6616
|
-
};
|
|
6617
|
-
const get$2 = languageId => {
|
|
6618
|
-
return state$1.tokenizers[languageId];
|
|
6619
|
-
};
|
|
6620
|
-
const isPending = languageId => {
|
|
6621
|
-
return languageId in state$1.pending;
|
|
6622
|
-
};
|
|
6623
|
-
|
|
6624
|
-
const tokenMaps = Object.create(null);
|
|
6625
|
-
const set$1 = (languageId, tokenMap) => {
|
|
6626
|
-
tokenMaps[languageId] = tokenMap;
|
|
6627
|
-
};
|
|
6628
|
-
const get$1 = languageId => {
|
|
6629
|
-
return tokenMaps[languageId] || {};
|
|
6630
|
-
};
|
|
6631
|
-
|
|
6632
|
-
// TODO loadTokenizer should be invoked from renderer worker
|
|
6633
|
-
const loadTokenizer = async (languageId, tokenizePath) => {
|
|
6634
|
-
if (!tokenizePath) {
|
|
6635
|
-
return;
|
|
6636
|
-
}
|
|
6637
|
-
if (getEnabled$1()) {
|
|
6638
|
-
// @ts-ignore
|
|
6639
|
-
const tokenMap = await invoke$3('Tokenizer.load', languageId, tokenizePath);
|
|
6640
|
-
set$1(languageId, tokenMap);
|
|
6641
|
-
return;
|
|
6642
|
-
}
|
|
6643
|
-
try {
|
|
6644
|
-
// TODO check that tokenizer is valid
|
|
6645
|
-
// 1. tokenizeLine should be of type function
|
|
6646
|
-
// 2. getTokenClass should be of type function
|
|
6647
|
-
const tokenizer = await import(tokenizePath);
|
|
6648
|
-
if (typeof tokenizer.tokenizeLine !== 'function') {
|
|
6649
|
-
console.warn(`tokenizer.tokenizeLine should be a function in "${tokenizePath}"`);
|
|
6650
|
-
return;
|
|
6651
|
-
}
|
|
6652
|
-
if (!tokenizer.TokenMap || typeof tokenizer.TokenMap !== 'object' || Array.isArray(tokenizer.TokenMap)) {
|
|
6653
|
-
console.warn(`tokenizer.TokenMap should be an object in "${tokenizePath}"`);
|
|
6654
|
-
return;
|
|
6655
|
-
}
|
|
6656
|
-
set$1(languageId, tokenizer.TokenMap);
|
|
6657
|
-
set$2(languageId, tokenizer);
|
|
6658
|
-
} catch (error) {
|
|
6659
|
-
// TODO better error handling
|
|
6660
|
-
console.error(error);
|
|
6661
|
-
}
|
|
6662
|
-
};
|
|
6663
|
-
const getTokenizer = languageId => {
|
|
6664
|
-
if (has(languageId)) {
|
|
6665
|
-
return get$2(languageId);
|
|
6666
|
-
}
|
|
6667
|
-
if (isPending(languageId)) {
|
|
6668
|
-
return TokenizePlainText;
|
|
6669
|
-
}
|
|
6670
|
-
return TokenizePlainText;
|
|
6671
|
-
};
|
|
6672
|
-
|
|
6673
|
-
const tokenizers = Object.create(null);
|
|
6674
|
-
const set = (id, value) => {
|
|
6675
|
-
tokenizers[id] = value;
|
|
6676
|
-
};
|
|
6677
|
-
const get = id => {
|
|
6678
|
-
return tokenizers[id] || TokenizePlainText;
|
|
6679
|
-
};
|
|
6680
|
-
|
|
6681
7360
|
// TODO add command to set language id
|
|
6682
7361
|
// without needing to specify tokenizePath
|
|
6683
7362
|
const setLanguageId = async (editor, languageId, tokenizePath) => {
|
|
@@ -6691,17 +7370,33 @@ const setLanguageId = async (editor, languageId, tokenizePath) => {
|
|
|
6691
7370
|
await loadTokenizer(languageId, tokenizePath);
|
|
6692
7371
|
const tokenizer = getTokenizer(languageId);
|
|
6693
7372
|
const newTokenizerId = tokenizerId + 1;
|
|
6694
|
-
set(newTokenizerId, tokenizer);
|
|
7373
|
+
set$2(newTokenizerId, tokenizer);
|
|
6695
7374
|
const latest = getEditor(editor.uid);
|
|
6696
7375
|
if (!latest) {
|
|
6697
7376
|
return editor;
|
|
6698
7377
|
}
|
|
7378
|
+
const syncIncremental = getEnabled();
|
|
7379
|
+
const {
|
|
7380
|
+
textInfos,
|
|
7381
|
+
differences
|
|
7382
|
+
} = await getVisible$1(editor, syncIncremental);
|
|
7383
|
+
const latest2 = getEditor(editor.uid);
|
|
7384
|
+
if (!latest2) {
|
|
7385
|
+
return editor;
|
|
7386
|
+
}
|
|
7387
|
+
const newEditor4 = {
|
|
7388
|
+
...latest2,
|
|
7389
|
+
focused: true,
|
|
7390
|
+
textInfos,
|
|
7391
|
+
differences
|
|
7392
|
+
};
|
|
7393
|
+
|
|
6699
7394
|
// TODO don't update editor if tokenizer was already loaded
|
|
6700
7395
|
// TODO update syntax highlighting
|
|
6701
7396
|
// TODO get edits
|
|
6702
7397
|
|
|
6703
7398
|
return {
|
|
6704
|
-
...
|
|
7399
|
+
...newEditor4,
|
|
6705
7400
|
languageId,
|
|
6706
7401
|
invalidStartIndex: 0,
|
|
6707
7402
|
tokenizerId: newTokenizerId
|
|
@@ -7404,7 +8099,7 @@ const type = (editor, text) => {
|
|
|
7404
8099
|
return scheduleDocumentAndCursorsSelections(editor, changes);
|
|
7405
8100
|
};
|
|
7406
8101
|
|
|
7407
|
-
const Slash
|
|
8102
|
+
const Slash = '/';
|
|
7408
8103
|
|
|
7409
8104
|
const CurlyOpen = '{';
|
|
7410
8105
|
const CurlyClose = '}';
|
|
@@ -7519,7 +8214,7 @@ const typeWithAutoClosing = async (editor, text) => {
|
|
|
7519
8214
|
}
|
|
7520
8215
|
break;
|
|
7521
8216
|
// case AutoClosing.ClosingAngleBracket: // TODO support auto closing when typing closing angle bracket of start tag
|
|
7522
|
-
case Slash
|
|
8217
|
+
case Slash:
|
|
7523
8218
|
if (isAutoClosingTagsEnabled) {
|
|
7524
8219
|
return typeWithAutoClosingTag(editor, text);
|
|
7525
8220
|
}
|
|
@@ -7746,11 +8441,11 @@ const getWidgetInvoke = widgetId => {
|
|
|
7746
8441
|
case ColorPicker$1:
|
|
7747
8442
|
return invoke$8;
|
|
7748
8443
|
case Completion:
|
|
7749
|
-
return invoke$5;
|
|
7750
|
-
case Find:
|
|
7751
8444
|
return invoke$4;
|
|
8445
|
+
case Find:
|
|
8446
|
+
return invoke$3;
|
|
7752
8447
|
case Rename$1:
|
|
7753
|
-
return invoke$
|
|
8448
|
+
return invoke$5;
|
|
7754
8449
|
case SourceAction$1:
|
|
7755
8450
|
return invoke$1;
|
|
7756
8451
|
case Hover:
|
|
@@ -8017,15 +8712,7 @@ const measureTextBlockHeight = async (text, fontFamily, fontSize, lineHeight, wi
|
|
|
8017
8712
|
return 100;
|
|
8018
8713
|
};
|
|
8019
8714
|
|
|
8020
|
-
const
|
|
8021
|
-
return structuredClone(value);
|
|
8022
|
-
};
|
|
8023
|
-
|
|
8024
|
-
const getInitialLineState = initialLineState => {
|
|
8025
|
-
return deepCopy(initialLineState);
|
|
8026
|
-
};
|
|
8027
|
-
|
|
8028
|
-
const getLineInfo$1 = (line, tokens, TokenMap) => {
|
|
8715
|
+
const getLineInfo = (line, tokens, TokenMap) => {
|
|
8029
8716
|
const tokensLength = tokens.length;
|
|
8030
8717
|
let end = 0;
|
|
8031
8718
|
let start = 0;
|
|
@@ -8043,45 +8730,6 @@ const getLineInfo$1 = (line, tokens, TokenMap) => {
|
|
|
8043
8730
|
return lineInfo;
|
|
8044
8731
|
};
|
|
8045
8732
|
|
|
8046
|
-
const state = {
|
|
8047
|
-
warned: []
|
|
8048
|
-
};
|
|
8049
|
-
const flattenTokensArray = tokens => {
|
|
8050
|
-
const flattened = [];
|
|
8051
|
-
for (const token of tokens) {
|
|
8052
|
-
object(token);
|
|
8053
|
-
flattened.push(token.type, token.length);
|
|
8054
|
-
}
|
|
8055
|
-
return flattened;
|
|
8056
|
-
};
|
|
8057
|
-
const warnDeprecatedArrayReturn = (languageId, fn) => {
|
|
8058
|
-
if (state.warned.includes(fn)) {
|
|
8059
|
-
return;
|
|
8060
|
-
}
|
|
8061
|
-
state.warned.push(fn);
|
|
8062
|
-
console.warn(`tokenizers without hasArrayReturn=false are deprecated (language ${languageId})`);
|
|
8063
|
-
};
|
|
8064
|
-
const safeTokenizeLine = (languageId, tokenizeLine, line, lineStateAtStart, hasArrayReturn) => {
|
|
8065
|
-
try {
|
|
8066
|
-
const lineState = tokenizeLine(line, lineStateAtStart);
|
|
8067
|
-
if (!lineState?.tokens || !lineState.state) {
|
|
8068
|
-
throw new Error('invalid tokenization result');
|
|
8069
|
-
}
|
|
8070
|
-
if (!hasArrayReturn) {
|
|
8071
|
-
warnDeprecatedArrayReturn(languageId, tokenizeLine);
|
|
8072
|
-
// workaround for old tokenizers
|
|
8073
|
-
lineState.tokens = flattenTokensArray(lineState.tokens);
|
|
8074
|
-
}
|
|
8075
|
-
return lineState;
|
|
8076
|
-
} catch (error) {
|
|
8077
|
-
console.error(error);
|
|
8078
|
-
return {
|
|
8079
|
-
tokens: [/* type */0, /* length */line.length],
|
|
8080
|
-
lineState: lineStateAtStart
|
|
8081
|
-
};
|
|
8082
|
-
}
|
|
8083
|
-
};
|
|
8084
|
-
|
|
8085
8733
|
const getLineInfos = (lines, tokenizer, languageId) => {
|
|
8086
8734
|
const lineInfos = [];
|
|
8087
8735
|
const {
|
|
@@ -8096,7 +8744,7 @@ const getLineInfos = (lines, tokenizer, languageId) => {
|
|
|
8096
8744
|
const {
|
|
8097
8745
|
tokens
|
|
8098
8746
|
} = result;
|
|
8099
|
-
const lineInfo = getLineInfo
|
|
8747
|
+
const lineInfo = getLineInfo(line, tokens, TokenMap);
|
|
8100
8748
|
lineInfos.push(lineInfo);
|
|
8101
8749
|
currentLineState = result;
|
|
8102
8750
|
}
|
|
@@ -8698,71 +9346,34 @@ const getFonts = () => {
|
|
|
8698
9346
|
|
|
8699
9347
|
const loadFont = async (fontName, fontUrl) => {
|
|
8700
9348
|
try {
|
|
8701
|
-
string(fontName);
|
|
8702
|
-
string(fontUrl);
|
|
8703
|
-
if (fontName.startsWith("'")) {
|
|
8704
|
-
throw new Error('font name is not allowed start with quotes');
|
|
8705
|
-
}
|
|
8706
|
-
const fontFace = new FontFace(fontName, fontUrl, {});
|
|
8707
|
-
await fontFace.load();
|
|
8708
|
-
const fonts = getFonts();
|
|
8709
|
-
// @ts-ignore
|
|
8710
|
-
fonts.add(fontFace);
|
|
8711
|
-
} catch (error) {
|
|
8712
|
-
throw new VError(error, `Failed to load font ${fontName}`);
|
|
8713
|
-
}
|
|
8714
|
-
};
|
|
8715
|
-
|
|
8716
|
-
const ensure = async (fontName, fontUrl) => {
|
|
8717
|
-
if (isLoaded(fontName)) {
|
|
8718
|
-
return;
|
|
8719
|
-
}
|
|
8720
|
-
if (hasPending(fontName)) {
|
|
8721
|
-
return getPending(fontName);
|
|
8722
|
-
}
|
|
8723
|
-
const promise = loadFont(fontName, fontUrl);
|
|
8724
|
-
setPending(fontName, promise);
|
|
8725
|
-
await promise;
|
|
8726
|
-
removePending(fontName);
|
|
8727
|
-
setLoaded(fontName);
|
|
8728
|
-
};
|
|
8729
|
-
|
|
8730
|
-
const Backspace = 1;
|
|
8731
|
-
const Tab = 2;
|
|
8732
|
-
const Enter = 3;
|
|
8733
|
-
const Escape = 8;
|
|
8734
|
-
const Space = 9;
|
|
8735
|
-
const End = 255;
|
|
8736
|
-
const Home = 12;
|
|
8737
|
-
const LeftArrow = 13;
|
|
8738
|
-
const UpArrow = 14;
|
|
8739
|
-
const RightArrow = 15;
|
|
8740
|
-
const DownArrow = 16;
|
|
8741
|
-
const Delete = 18;
|
|
8742
|
-
const KeyA = 29;
|
|
8743
|
-
const KeyC = 31;
|
|
8744
|
-
const KeyD = 32;
|
|
8745
|
-
const KeyF = 34;
|
|
8746
|
-
const KeyH = 36;
|
|
8747
|
-
const KeyJ = 38;
|
|
8748
|
-
const KeyK = 39;
|
|
8749
|
-
const KeyL = 40;
|
|
8750
|
-
const KeyO = 43;
|
|
8751
|
-
const KeyV = 50;
|
|
8752
|
-
const KeyX = 52;
|
|
8753
|
-
const KeyZ = 54;
|
|
8754
|
-
const F2 = 58;
|
|
8755
|
-
const F3 = 59;
|
|
8756
|
-
const F4 = 60;
|
|
8757
|
-
const F12 = 68;
|
|
8758
|
-
const Period = 87;
|
|
8759
|
-
const Slash = 88;
|
|
8760
|
-
const BracketLeft = 90;
|
|
8761
|
-
const BracketRight = 92;
|
|
9349
|
+
string(fontName);
|
|
9350
|
+
string(fontUrl);
|
|
9351
|
+
if (fontName.startsWith("'")) {
|
|
9352
|
+
throw new Error('font name is not allowed start with quotes');
|
|
9353
|
+
}
|
|
9354
|
+
const fontFace = new FontFace(fontName, fontUrl, {});
|
|
9355
|
+
await fontFace.load();
|
|
9356
|
+
const fonts = getFonts();
|
|
9357
|
+
// @ts-ignore
|
|
9358
|
+
fonts.add(fontFace);
|
|
9359
|
+
} catch (error) {
|
|
9360
|
+
throw new VError(error, `Failed to load font ${fontName}`);
|
|
9361
|
+
}
|
|
9362
|
+
};
|
|
8762
9363
|
|
|
8763
|
-
const
|
|
8764
|
-
|
|
8765
|
-
|
|
9364
|
+
const ensure = async (fontName, fontUrl) => {
|
|
9365
|
+
if (isLoaded(fontName)) {
|
|
9366
|
+
return;
|
|
9367
|
+
}
|
|
9368
|
+
if (hasPending(fontName)) {
|
|
9369
|
+
return getPending(fontName);
|
|
9370
|
+
}
|
|
9371
|
+
const promise = loadFont(fontName, fontUrl);
|
|
9372
|
+
setPending(fontName, promise);
|
|
9373
|
+
await promise;
|
|
9374
|
+
removePending(fontName);
|
|
9375
|
+
setLoaded(fontName);
|
|
9376
|
+
};
|
|
8766
9377
|
|
|
8767
9378
|
const getKeyBindings = () => {
|
|
8768
9379
|
return [{
|
|
@@ -8806,59 +9417,59 @@ const getKeyBindings = () => {
|
|
|
8806
9417
|
command: 'FindWidget.focusNext',
|
|
8807
9418
|
when: FocusFindWidget
|
|
8808
9419
|
}, {
|
|
8809
|
-
key: Shift | Tab,
|
|
9420
|
+
key: Shift | Tab$1,
|
|
8810
9421
|
command: 'FindWidget.focusToggleReplace',
|
|
8811
9422
|
when: FocusFindWidget
|
|
8812
9423
|
}, {
|
|
8813
|
-
key: Tab,
|
|
9424
|
+
key: Tab$1,
|
|
8814
9425
|
command: 'FindWidget.focusReplace',
|
|
8815
9426
|
when: FocusFindWidget
|
|
8816
9427
|
}, {
|
|
8817
|
-
key: Tab,
|
|
9428
|
+
key: Tab$1,
|
|
8818
9429
|
command: 'FindWidget.focusPreviousMatchButton',
|
|
8819
9430
|
when: FocusFindWidgetReplace
|
|
8820
9431
|
}, {
|
|
8821
|
-
key: Alt | CtrlCmd | Enter,
|
|
9432
|
+
key: Alt$1 | CtrlCmd | Enter,
|
|
8822
9433
|
command: 'FindWidget.replaceAll',
|
|
8823
9434
|
when: FocusFindWidgetReplace
|
|
8824
9435
|
}, {
|
|
8825
|
-
key: Tab,
|
|
9436
|
+
key: Tab$1,
|
|
8826
9437
|
command: 'FindWidget.focusNextMatchButton',
|
|
8827
9438
|
when: FocusFindWidgetPreviousMatchButton
|
|
8828
9439
|
}, {
|
|
8829
|
-
key: Shift | Tab,
|
|
9440
|
+
key: Shift | Tab$1,
|
|
8830
9441
|
command: 'FindWidget.focusReplace',
|
|
8831
9442
|
when: FocusFindWidgetPreviousMatchButton
|
|
8832
9443
|
}, {
|
|
8833
|
-
key: Shift | Tab,
|
|
9444
|
+
key: Shift | Tab$1,
|
|
8834
9445
|
command: 'FindWidget.focusPreviousMatchButton',
|
|
8835
9446
|
when: FocusFindWidgetNextMatchButton
|
|
8836
9447
|
}, {
|
|
8837
|
-
key: Tab,
|
|
9448
|
+
key: Tab$1,
|
|
8838
9449
|
command: 'FindWidget.focusCloseButton',
|
|
8839
9450
|
when: FocusFindWidgetNextMatchButton
|
|
8840
9451
|
}, {
|
|
8841
|
-
key: Shift | Tab,
|
|
9452
|
+
key: Shift | Tab$1,
|
|
8842
9453
|
command: 'FindWidget.focusNextMatchButton',
|
|
8843
9454
|
when: FocusFindWidgetCloseButton
|
|
8844
9455
|
}, {
|
|
8845
|
-
key: Tab,
|
|
9456
|
+
key: Tab$1,
|
|
8846
9457
|
command: 'FindWidget.focusReplaceButton',
|
|
8847
9458
|
when: FocusFindWidgetCloseButton
|
|
8848
9459
|
}, {
|
|
8849
|
-
key: Shift | Tab,
|
|
9460
|
+
key: Shift | Tab$1,
|
|
8850
9461
|
command: 'FindWidget.focusFind',
|
|
8851
9462
|
when: FocusFindWidgetReplace
|
|
8852
9463
|
}, {
|
|
8853
|
-
key: Tab,
|
|
9464
|
+
key: Tab$1,
|
|
8854
9465
|
command: 'FindWidget.focusReplaceAllButton',
|
|
8855
9466
|
when: FocusFindWidgetReplaceButton
|
|
8856
9467
|
}, {
|
|
8857
|
-
key: Shift | Tab,
|
|
9468
|
+
key: Shift | Tab$1,
|
|
8858
9469
|
command: 'FindWidget.focusCloseButton',
|
|
8859
9470
|
when: FocusFindWidgetReplaceButton
|
|
8860
9471
|
}, {
|
|
8861
|
-
key: Shift | Tab,
|
|
9472
|
+
key: Shift | Tab$1,
|
|
8862
9473
|
command: 'FindWidget.focusReplaceButton',
|
|
8863
9474
|
when: FocusFindWidgetReplaceAllButton
|
|
8864
9475
|
}, {
|
|
@@ -8886,7 +9497,7 @@ const getKeyBindings = () => {
|
|
|
8886
9497
|
command: 'EditorCompletion.focusFirst',
|
|
8887
9498
|
when: FocusEditorCompletions
|
|
8888
9499
|
}, {
|
|
8889
|
-
key: CtrlCmd | Space,
|
|
9500
|
+
key: CtrlCmd | Space$1,
|
|
8890
9501
|
command: 'EditorCompletion.toggleDetails',
|
|
8891
9502
|
when: FocusEditorCompletions
|
|
8892
9503
|
}, {
|
|
@@ -8898,11 +9509,11 @@ const getKeyBindings = () => {
|
|
|
8898
9509
|
command: 'Editor.cursorWordLeft',
|
|
8899
9510
|
when: FocusEditorText
|
|
8900
9511
|
}, {
|
|
8901
|
-
key: Alt | Backspace,
|
|
9512
|
+
key: Alt$1 | Backspace,
|
|
8902
9513
|
command: 'Editor.deleteWordPartLeft',
|
|
8903
9514
|
when: FocusEditorText
|
|
8904
9515
|
}, {
|
|
8905
|
-
key: Alt | Delete,
|
|
9516
|
+
key: Alt$1 | Delete,
|
|
8906
9517
|
command: 'Editor.deleteWordPartRight',
|
|
8907
9518
|
when: FocusEditorText
|
|
8908
9519
|
}, {
|
|
@@ -8926,11 +9537,11 @@ const getKeyBindings = () => {
|
|
|
8926
9537
|
command: 'Editor.showSourceActions3',
|
|
8927
9538
|
when: FocusEditorText
|
|
8928
9539
|
}, {
|
|
8929
|
-
key: Tab,
|
|
9540
|
+
key: Tab$1,
|
|
8930
9541
|
command: 'Editor.handleTab',
|
|
8931
9542
|
when: FocusEditorText
|
|
8932
9543
|
}, {
|
|
8933
|
-
key: Shift | Tab,
|
|
9544
|
+
key: Shift | Tab$1,
|
|
8934
9545
|
command: 'Editor.unindent',
|
|
8935
9546
|
when: FocusEditorText
|
|
8936
9547
|
}, {
|
|
@@ -9038,7 +9649,7 @@ const getKeyBindings = () => {
|
|
|
9038
9649
|
command: 'Editor.moveLineUp',
|
|
9039
9650
|
when: FocusEditorText
|
|
9040
9651
|
}, {
|
|
9041
|
-
key: CtrlCmd | Space,
|
|
9652
|
+
key: CtrlCmd | Space$1,
|
|
9042
9653
|
command: 'Editor.openCompletion',
|
|
9043
9654
|
when: FocusEditorText
|
|
9044
9655
|
}, {
|
|
@@ -9062,7 +9673,7 @@ const getKeyBindings = () => {
|
|
|
9062
9673
|
command: 'Editor.cursorEnd',
|
|
9063
9674
|
when: FocusEditorText
|
|
9064
9675
|
}, {
|
|
9065
|
-
key: CtrlCmd | Slash,
|
|
9676
|
+
key: CtrlCmd | Slash$1,
|
|
9066
9677
|
command: 'Editor.toggleComment',
|
|
9067
9678
|
when: FocusEditorText
|
|
9068
9679
|
}, {
|
|
@@ -9086,35 +9697,35 @@ const getKeyBindings = () => {
|
|
|
9086
9697
|
command: 'Editor.paste',
|
|
9087
9698
|
when: FocusEditorText
|
|
9088
9699
|
}, {
|
|
9089
|
-
key: Alt | LeftArrow,
|
|
9700
|
+
key: Alt$1 | LeftArrow,
|
|
9090
9701
|
command: 'Editor.cursorWordPartLeft',
|
|
9091
9702
|
when: FocusEditorText
|
|
9092
9703
|
}, {
|
|
9093
|
-
key: Alt | RightArrow,
|
|
9704
|
+
key: Alt$1 | RightArrow,
|
|
9094
9705
|
command: 'Editor.cursorWordPartRight',
|
|
9095
9706
|
when: FocusEditorText
|
|
9096
9707
|
}, {
|
|
9097
|
-
key: Alt | F3,
|
|
9708
|
+
key: Alt$1 | F3,
|
|
9098
9709
|
command: 'Editor.selectAllOccurrences',
|
|
9099
9710
|
when: FocusEditorText
|
|
9100
9711
|
}, {
|
|
9101
|
-
key: Alt | Shift | UpArrow,
|
|
9712
|
+
key: Alt$1 | Shift | UpArrow,
|
|
9102
9713
|
command: 'Editor.addCursorAbove',
|
|
9103
9714
|
when: FocusEditorText
|
|
9104
9715
|
}, {
|
|
9105
|
-
key: Alt | Shift | DownArrow,
|
|
9716
|
+
key: Alt$1 | Shift | DownArrow,
|
|
9106
9717
|
command: 'Editor.addCursorBelow',
|
|
9107
9718
|
when: FocusEditorText
|
|
9108
9719
|
}, {
|
|
9109
|
-
key: Alt | Shift | F12,
|
|
9720
|
+
key: Alt$1 | Shift | F12,
|
|
9110
9721
|
command: 'Editor.findAllReferences',
|
|
9111
9722
|
when: FocusEditorText
|
|
9112
9723
|
}, {
|
|
9113
|
-
key: Alt | Shift | KeyO,
|
|
9724
|
+
key: Alt$1 | Shift | KeyO,
|
|
9114
9725
|
command: 'Editor.organizeImports',
|
|
9115
9726
|
when: FocusEditorText
|
|
9116
9727
|
}, {
|
|
9117
|
-
key: CtrlCmd | Shift | Space,
|
|
9728
|
+
key: CtrlCmd | Shift | Space$1,
|
|
9118
9729
|
command: 'Editor.selectionGrow',
|
|
9119
9730
|
when: FocusEditor
|
|
9120
9731
|
}];
|
|
@@ -9211,776 +9822,282 @@ const getQuickPickMenuEntries = () => {
|
|
|
9211
9822
|
}, {
|
|
9212
9823
|
id: 'Editor.showSourceActions2',
|
|
9213
9824
|
label: sourceAction()
|
|
9214
|
-
}];
|
|
9215
|
-
};
|
|
9216
|
-
|
|
9217
|
-
const getSelections = editorUid => {
|
|
9218
|
-
const editor = getEditor(editorUid);
|
|
9219
|
-
const {
|
|
9220
|
-
selections
|
|
9221
|
-
} = editor;
|
|
9222
|
-
return selections;
|
|
9223
|
-
};
|
|
9224
|
-
|
|
9225
|
-
const getText = editorUid => {
|
|
9226
|
-
number(editorUid);
|
|
9227
|
-
const editor = getEditor(editorUid);
|
|
9228
|
-
const {
|
|
9229
|
-
lines
|
|
9230
|
-
} = editor;
|
|
9231
|
-
return lines.join(NewLine);
|
|
9232
|
-
};
|
|
9233
|
-
|
|
9234
|
-
const InsertText = 'insertText';
|
|
9235
|
-
|
|
9236
|
-
const handleBeforeInput = (editor, inputType, data) => {
|
|
9237
|
-
switch (inputType) {
|
|
9238
|
-
case InsertText:
|
|
9239
|
-
return typeWithAutoClosing(editor, data);
|
|
9240
|
-
default:
|
|
9241
|
-
return editor;
|
|
9242
|
-
}
|
|
9243
|
-
};
|
|
9244
|
-
|
|
9245
|
-
const handleMessagePort = async (port, rpcId) => {
|
|
9246
|
-
const rpc = await PlainMessagePortRpcParent.create({
|
|
9247
|
-
messagePort: port,
|
|
9248
|
-
commandMap: {}
|
|
9249
|
-
});
|
|
9250
|
-
if (rpcId) {
|
|
9251
|
-
set$c(rpcId, rpc);
|
|
9252
|
-
}
|
|
9253
|
-
};
|
|
9254
|
-
|
|
9255
|
-
const applyTabCompletion = (editor, result) => {
|
|
9256
|
-
return editorSnippet(editor, result);
|
|
9257
|
-
};
|
|
9258
|
-
|
|
9259
|
-
const handleTab = async editor => {
|
|
9260
|
-
const result = await getTabCompletion(editor);
|
|
9261
|
-
if (!result) {
|
|
9262
|
-
// TODO enter tab or two spaces
|
|
9263
|
-
return editor;
|
|
9264
|
-
}
|
|
9265
|
-
return applyTabCompletion(editor, result);
|
|
9266
|
-
};
|
|
9267
|
-
|
|
9268
|
-
const relaunchWorkers = async () => {
|
|
9269
|
-
await dispose();
|
|
9270
|
-
await launch();
|
|
9271
|
-
};
|
|
9272
|
-
|
|
9273
|
-
const getWidgetName = widgetId => {
|
|
9274
|
-
switch (widgetId) {
|
|
9275
|
-
case Find:
|
|
9276
|
-
return `FindWidget`;
|
|
9277
|
-
default:
|
|
9278
|
-
return '';
|
|
9279
|
-
}
|
|
9280
|
-
};
|
|
9281
|
-
const saveWidgetState = async keys => {
|
|
9282
|
-
const savedStates = Object.create(null);
|
|
9283
|
-
for (const key of keys) {
|
|
9284
|
-
const editor = get$4(parseInt(key));
|
|
9285
|
-
const {
|
|
9286
|
-
widgets
|
|
9287
|
-
} = editor.newState;
|
|
9288
|
-
for (const widget of widgets) {
|
|
9289
|
-
const invoke = getWidgetInvoke(widget.id);
|
|
9290
|
-
const fullKey = `${key}:${widget.newState.uid}`;
|
|
9291
|
-
const name = getWidgetName(widget.id);
|
|
9292
|
-
const savedState = await invoke(`${name}.saveState`, widget.newState.uid);
|
|
9293
|
-
savedStates[fullKey] = savedState;
|
|
9294
|
-
}
|
|
9295
|
-
}
|
|
9296
|
-
return savedStates;
|
|
9297
|
-
};
|
|
9298
|
-
|
|
9299
|
-
const restoreWidgetState = async (keys, savedStates) => {
|
|
9300
|
-
const newEditors = [];
|
|
9301
|
-
for (const key of keys) {
|
|
9302
|
-
const editorUid = parseInt(key);
|
|
9303
|
-
const editor = get$4(editorUid);
|
|
9304
|
-
const {
|
|
9305
|
-
widgets
|
|
9306
|
-
} = editor.newState;
|
|
9307
|
-
const newWidgets = [];
|
|
9308
|
-
for (const widget of widgets) {
|
|
9309
|
-
const invoke = getWidgetInvoke(widget.id);
|
|
9310
|
-
const fullKey = `${key}:${widget.newState.uid}`;
|
|
9311
|
-
const savedState = savedStates[fullKey] || {};
|
|
9312
|
-
const name = getWidgetName(widget.id);
|
|
9313
|
-
await invoke(`${name}.create`, widget.newState.uid, widget.newState.x, widget.newState.y, widget.newState.width, widget.newState.height, editorUid);
|
|
9314
|
-
await invoke(`${name}.loadContent`, widget.newState.uid, savedState);
|
|
9315
|
-
const diffResult = await invoke(`${name}.diff2`, widget.newState.uid);
|
|
9316
|
-
const commands = await invoke(`${name}.render2`, widget.newState.uid, diffResult);
|
|
9317
|
-
const newWidget = {
|
|
9318
|
-
...widget,
|
|
9319
|
-
newState: {
|
|
9320
|
-
...widget.newState,
|
|
9321
|
-
commands
|
|
9322
|
-
}
|
|
9323
|
-
};
|
|
9324
|
-
newWidgets.push(newWidget);
|
|
9325
|
-
}
|
|
9326
|
-
newEditors.push({
|
|
9327
|
-
...editor,
|
|
9328
|
-
newState: {
|
|
9329
|
-
...editor.newState,
|
|
9330
|
-
widgets: newWidgets
|
|
9331
|
-
}
|
|
9332
|
-
});
|
|
9333
|
-
}
|
|
9334
|
-
return newEditors;
|
|
9335
|
-
};
|
|
9336
|
-
|
|
9337
|
-
let isReloading = false;
|
|
9338
|
-
const hotReload = async () => {
|
|
9339
|
-
if (isReloading) {
|
|
9340
|
-
return;
|
|
9341
|
-
}
|
|
9342
|
-
isReloading = true;
|
|
9343
|
-
|
|
9344
|
-
// TODO use getEditors
|
|
9345
|
-
const keys = getKeys$1();
|
|
9346
|
-
const savedStates = await saveWidgetState(keys);
|
|
9347
|
-
await relaunchWorkers();
|
|
9348
|
-
const newEditors = await restoreWidgetState(keys, savedStates);
|
|
9349
|
-
for (const editor of newEditors) {
|
|
9350
|
-
set$6(editor.newState.uid, editor.oldState, editor.newState);
|
|
9351
|
-
}
|
|
9352
|
-
|
|
9353
|
-
// TODO ask renderer worker to rerender all editors
|
|
9354
|
-
// @ts-ignore
|
|
9355
|
-
await invoke$9(`Editor.rerender`);
|
|
9356
|
-
isReloading = false;
|
|
9357
|
-
};
|
|
9358
|
-
|
|
9359
|
-
const sendMessagePortToExtensionHostWorker2 = async (port, initialCommand, rpcId) => {
|
|
9360
|
-
await invokeAndTransfer('SendMessagePortToExtensionHostWorker.sendMessagePortToExtensionHostWorker', port, initialCommand, rpcId);
|
|
9361
|
-
};
|
|
9362
|
-
|
|
9363
|
-
const createExtensionHostRpc = async () => {
|
|
9364
|
-
try {
|
|
9365
|
-
const {
|
|
9366
|
-
port1,
|
|
9367
|
-
port2
|
|
9368
|
-
} = getPortTuple();
|
|
9369
|
-
const initialCommand = 'HandleMessagePort.handleMessagePort2';
|
|
9370
|
-
// TODO use transfer rpc
|
|
9371
|
-
await sendMessagePortToExtensionHostWorker2(port2, initialCommand, EditorWorker);
|
|
9372
|
-
const rpc = await PlainMessagePortRpcParent.create({
|
|
9373
|
-
commandMap: {},
|
|
9374
|
-
messagePort: port1
|
|
9375
|
-
});
|
|
9376
|
-
return rpc;
|
|
9377
|
-
} catch (error) {
|
|
9378
|
-
throw new VError(error, `Failed to create extension host rpc`);
|
|
9379
|
-
}
|
|
9380
|
-
};
|
|
9381
|
-
|
|
9382
|
-
const initializeExtensionHost = async () => {
|
|
9383
|
-
const extensionHostRpc = await createExtensionHostRpc();
|
|
9384
|
-
set$5(extensionHostRpc);
|
|
9385
|
-
};
|
|
9386
|
-
|
|
9387
|
-
const sendMessagePortToSyntaxHighlightingWorker = async () => {
|
|
9388
|
-
try {
|
|
9389
|
-
const {
|
|
9390
|
-
port1,
|
|
9391
|
-
port2
|
|
9392
|
-
} = getPortTuple();
|
|
9393
|
-
await invokeAndTransfer(
|
|
9394
|
-
// @ts-ignore
|
|
9395
|
-
'SendMessagePortToSyntaxHighlightingWorker.sendMessagePortToSyntaxHighlightingWorker', port1, 'HandleMessagePort.handleMessagePort2');
|
|
9396
|
-
return port2;
|
|
9397
|
-
} catch {
|
|
9398
|
-
const {
|
|
9399
|
-
port1,
|
|
9400
|
-
port2
|
|
9401
|
-
} = getPortTuple();
|
|
9402
|
-
await invokeAndTransfer(
|
|
9403
|
-
// @ts-ignore
|
|
9404
|
-
'SendMessagePortToSyntaxHighlightingWorker.sendMessagePortToSyntaxHighlightingWorker', port1, 'HandleMessagePort.handleMessagePort');
|
|
9405
|
-
return port2;
|
|
9406
|
-
}
|
|
9407
|
-
};
|
|
9408
|
-
|
|
9409
|
-
const createSyntaxHighlightingWorkerRpc = async () => {
|
|
9410
|
-
try {
|
|
9411
|
-
const port = await sendMessagePortToSyntaxHighlightingWorker();
|
|
9412
|
-
const rpc = await PlainMessagePortRpcParent.create({
|
|
9413
|
-
commandMap: {},
|
|
9414
|
-
messagePort: port
|
|
9415
|
-
});
|
|
9416
|
-
return rpc;
|
|
9417
|
-
} catch (error) {
|
|
9418
|
-
throw new VError(error, `Failed to create syntax highlighting worker rpc`);
|
|
9419
|
-
}
|
|
9420
|
-
};
|
|
9421
|
-
|
|
9422
|
-
let enabled = false;
|
|
9423
|
-
const setEnabled = value => {
|
|
9424
|
-
enabled = value;
|
|
9425
|
-
};
|
|
9426
|
-
const getEnabled = () => {
|
|
9427
|
-
return enabled;
|
|
9428
|
-
};
|
|
9429
|
-
|
|
9430
|
-
const initializeSyntaxHighlighting = async (syntaxHighlightingEnabled, syncIncremental) => {
|
|
9431
|
-
if (syntaxHighlightingEnabled) {
|
|
9432
|
-
setEnabled$1(true);
|
|
9433
|
-
const syntaxRpc = await createSyntaxHighlightingWorkerRpc();
|
|
9434
|
-
set$3(syntaxRpc);
|
|
9435
|
-
}
|
|
9436
|
-
if (syncIncremental) {
|
|
9437
|
-
setEnabled(true);
|
|
9438
|
-
}
|
|
9439
|
-
};
|
|
9440
|
-
|
|
9441
|
-
const intialize = async (syntaxHighlightingEnabled, syncIncremental) => {
|
|
9442
|
-
await Promise.all([initializeSyntaxHighlighting(syntaxHighlightingEnabled, syncIncremental), initializeExtensionHost()]);
|
|
9825
|
+
}];
|
|
9443
9826
|
};
|
|
9444
9827
|
|
|
9445
|
-
|
|
9446
|
-
|
|
9447
|
-
|
|
9448
|
-
|
|
9449
|
-
|
|
9450
|
-
|
|
9451
|
-
// return
|
|
9452
|
-
// }
|
|
9453
|
-
// const documentEdits = [
|
|
9454
|
-
// {
|
|
9455
|
-
// type: /* splice */ 2,
|
|
9456
|
-
// rowIndex: rowIndex,
|
|
9457
|
-
// count: 2,
|
|
9458
|
-
// newLines: [TextDocument.getLine(editor.textDocument, rowIndex + 1), TextDocument.getLine(editor.textDocument, rowIndex)],
|
|
9459
|
-
// },
|
|
9460
|
-
// ]
|
|
9461
|
-
// // @ts-ignore
|
|
9462
|
-
// const cursorEdits = Editor.moveCursors(editor, (editor, cursor) => {
|
|
9463
|
-
// return {
|
|
9464
|
-
// rowIndex: cursor.rowIndex + 1,
|
|
9465
|
-
// columnIndex: cursor.columnIndex,
|
|
9466
|
-
// }
|
|
9467
|
-
// })
|
|
9468
|
-
// @ts-ignore
|
|
9469
|
-
// Editor.scheduleDocumentAndCursors(editor, documentEdits, cursorEdits)
|
|
9470
|
-
return editor;
|
|
9828
|
+
const getSelections = editorUid => {
|
|
9829
|
+
const editor = getEditor(editorUid);
|
|
9830
|
+
const {
|
|
9831
|
+
selections
|
|
9832
|
+
} = editor;
|
|
9833
|
+
return selections;
|
|
9471
9834
|
};
|
|
9472
9835
|
|
|
9473
|
-
|
|
9474
|
-
|
|
9475
|
-
|
|
9476
|
-
|
|
9477
|
-
|
|
9478
|
-
|
|
9479
|
-
|
|
9480
|
-
// {
|
|
9481
|
-
// type: /* splice */ 2,
|
|
9482
|
-
// rowIndex: rowIndex - 1,
|
|
9483
|
-
// count: 2,
|
|
9484
|
-
// newLines: [TextDocument.getLine(editor.textDocument, rowIndex), TextDocument.getLine(editor.textDocument, rowIndex - 1)],
|
|
9485
|
-
// },
|
|
9486
|
-
// ]
|
|
9487
|
-
// // @ts-ignore
|
|
9488
|
-
// const cursorEdits = Editor.moveCursors(editor, (editor, cursor) => {
|
|
9489
|
-
// return {
|
|
9490
|
-
// // TODO handle bottom 0
|
|
9491
|
-
// rowIndex: cursor.rowIndex - 1,
|
|
9492
|
-
// columnIndex: cursor.columnIndex,
|
|
9493
|
-
// }
|
|
9494
|
-
// })
|
|
9495
|
-
// // @ts-ignore
|
|
9496
|
-
// Editor.scheduleDocumentAndCursors(editor, documentEdits, cursorEdits)
|
|
9497
|
-
return editor;
|
|
9836
|
+
const getText = editorUid => {
|
|
9837
|
+
number(editorUid);
|
|
9838
|
+
const editor = getEditor(editorUid);
|
|
9839
|
+
const {
|
|
9840
|
+
lines
|
|
9841
|
+
} = editor;
|
|
9842
|
+
return lines.join(NewLine);
|
|
9498
9843
|
};
|
|
9499
9844
|
|
|
9500
|
-
const
|
|
9501
|
-
const Function = 'Function';
|
|
9502
|
-
const Parameter = 'Parameter';
|
|
9503
|
-
const Type = 'Type';
|
|
9504
|
-
const VariableName = 'VariableName';
|
|
9505
|
-
const Class = 'Class';
|
|
9506
|
-
|
|
9507
|
-
const Link = 1;
|
|
9508
|
-
const Ts2816 = 2816;
|
|
9509
|
-
const Ts2817 = 2817;
|
|
9510
|
-
const Ts2824 = 2824;
|
|
9511
|
-
const Ts2825 = 2825;
|
|
9512
|
-
const Ts2856 = 2956;
|
|
9513
|
-
const Ts2857 = 2857;
|
|
9514
|
-
const Ts3072 = 3072;
|
|
9515
|
-
const Ts3073 = 3073;
|
|
9516
|
-
const Ts3077 = 3077;
|
|
9517
|
-
const Ts3088 = 3088;
|
|
9518
|
-
const Ts1792 = 1792;
|
|
9519
|
-
const Ts1793 = 1793;
|
|
9520
|
-
const Ts512 = 512;
|
|
9521
|
-
const Ts513 = 513;
|
|
9522
|
-
const Ts769 = 769;
|
|
9523
|
-
const Ts1024 = 1024;
|
|
9524
|
-
const Ts1536 = 1536;
|
|
9525
|
-
const Ts1537 = 1537;
|
|
9526
|
-
const Ts1544 = 1544;
|
|
9527
|
-
const Ts1545 = 1545;
|
|
9528
|
-
const Ts2048 = 2048;
|
|
9529
|
-
const Ts2049 = 2049;
|
|
9530
|
-
const Ts2056 = 2056;
|
|
9531
|
-
const Ts2057 = 2057;
|
|
9532
|
-
const Ts2064 = 2064;
|
|
9533
|
-
const Ts2080 = 2080;
|
|
9534
|
-
const Ts2081 = 2081;
|
|
9535
|
-
const Ts2088 = 2088;
|
|
9536
|
-
const Ts2089 = 2089;
|
|
9537
|
-
const Ts2313 = 2313;
|
|
9538
|
-
const Ts2560 = 2560;
|
|
9539
|
-
const Ts2561 = 2561;
|
|
9540
|
-
const Ts2569 = 2569;
|
|
9541
|
-
const Ts2584 = 2584;
|
|
9542
|
-
const Ts256 = 256;
|
|
9543
|
-
const Ts257 = 257;
|
|
9544
|
-
const Ts272 = 272;
|
|
9845
|
+
const InsertText = 'insertText';
|
|
9545
9846
|
|
|
9546
|
-
const
|
|
9547
|
-
switch (
|
|
9548
|
-
case
|
|
9549
|
-
return
|
|
9550
|
-
case Ts2816:
|
|
9551
|
-
case Ts2817:
|
|
9552
|
-
case Ts2824:
|
|
9553
|
-
case Ts2825:
|
|
9554
|
-
case Ts2856:
|
|
9555
|
-
case Ts2857:
|
|
9556
|
-
case Ts3072:
|
|
9557
|
-
case Ts3073:
|
|
9558
|
-
case Ts3077:
|
|
9559
|
-
case Ts3088:
|
|
9560
|
-
return Function;
|
|
9561
|
-
case Ts1792:
|
|
9562
|
-
case Ts1793:
|
|
9563
|
-
return Parameter;
|
|
9564
|
-
case Ts512:
|
|
9565
|
-
case Ts513:
|
|
9566
|
-
case Ts769:
|
|
9567
|
-
case Ts1024:
|
|
9568
|
-
case Ts1536:
|
|
9569
|
-
case Ts1537:
|
|
9570
|
-
case Ts1544:
|
|
9571
|
-
case Ts1545:
|
|
9572
|
-
return Type;
|
|
9573
|
-
case Ts2048:
|
|
9574
|
-
case Ts2049:
|
|
9575
|
-
case Ts2056:
|
|
9576
|
-
case Ts2057:
|
|
9577
|
-
case Ts2064:
|
|
9578
|
-
case Ts2080:
|
|
9579
|
-
case Ts2081:
|
|
9580
|
-
case Ts2088:
|
|
9581
|
-
case Ts2089:
|
|
9582
|
-
case Ts2313:
|
|
9583
|
-
case Ts2560:
|
|
9584
|
-
case Ts2561:
|
|
9585
|
-
case Ts2569:
|
|
9586
|
-
case Ts2584:
|
|
9587
|
-
return VariableName;
|
|
9588
|
-
case Ts256:
|
|
9589
|
-
case Ts257:
|
|
9590
|
-
case Ts272:
|
|
9591
|
-
return Class;
|
|
9847
|
+
const handleBeforeInput = (editor, inputType, data) => {
|
|
9848
|
+
switch (inputType) {
|
|
9849
|
+
case InsertText:
|
|
9850
|
+
return typeWithAutoClosing(editor, data);
|
|
9592
9851
|
default:
|
|
9593
|
-
return
|
|
9852
|
+
return editor;
|
|
9594
9853
|
}
|
|
9595
9854
|
};
|
|
9596
9855
|
|
|
9597
|
-
const
|
|
9598
|
-
const
|
|
9599
|
-
|
|
9600
|
-
|
|
9601
|
-
|
|
9602
|
-
|
|
9603
|
-
|
|
9604
|
-
if (result.embeddedLanguage) {
|
|
9605
|
-
const {
|
|
9606
|
-
embeddedLanguage,
|
|
9607
|
-
embeddedLanguageStart,
|
|
9608
|
-
embeddedLanguageEnd
|
|
9609
|
-
} = result;
|
|
9610
|
-
const embeddedTokenizer = getTokenizer(embeddedLanguage);
|
|
9611
|
-
if (embeddedLanguageStart !== line.length && embeddedTokenizer && embeddedTokenizer !== TokenizePlainText) {
|
|
9612
|
-
const isFull = embeddedLanguageStart === 0 && embeddedLanguageEnd === line.length;
|
|
9613
|
-
const partialLine = line.slice(embeddedLanguageStart, embeddedLanguageEnd);
|
|
9614
|
-
const embedResult = safeTokenizeLine(langageId, embeddedTokenizer.tokenizeLine, partialLine, topContext || getInitialLineState(embeddedTokenizer.initialLineState), embeddedTokenizer.hasArrayReturn);
|
|
9615
|
-
topContext = embedResult;
|
|
9616
|
-
result.embeddedResultIndex = embeddedResults.length;
|
|
9617
|
-
embeddedResults.push({
|
|
9618
|
-
result: embedResult,
|
|
9619
|
-
TokenMap: embeddedTokenizer.TokenMap,
|
|
9620
|
-
isFull
|
|
9621
|
-
});
|
|
9622
|
-
} else if (line.length === 0) {
|
|
9623
|
-
const embedResult = {
|
|
9624
|
-
tokens: []
|
|
9625
|
-
};
|
|
9626
|
-
result.embeddedResultIndex = embeddedResults.length;
|
|
9627
|
-
embeddedResults.push({
|
|
9628
|
-
result: embedResult,
|
|
9629
|
-
isFull: true,
|
|
9630
|
-
TokenMap: []
|
|
9631
|
-
});
|
|
9632
|
-
} else {
|
|
9633
|
-
tokenizersToLoad.push(embeddedLanguage);
|
|
9634
|
-
embeddedResults.push({
|
|
9635
|
-
result: {},
|
|
9636
|
-
isFull: false,
|
|
9637
|
-
TokenMap: []
|
|
9638
|
-
});
|
|
9639
|
-
topContext = undefined;
|
|
9640
|
-
}
|
|
9641
|
-
} else {
|
|
9642
|
-
topContext = undefined;
|
|
9643
|
-
}
|
|
9856
|
+
const handleMessagePort = async (port, rpcId) => {
|
|
9857
|
+
const rpc = await PlainMessagePortRpcParent.create({
|
|
9858
|
+
messagePort: port,
|
|
9859
|
+
commandMap: {}
|
|
9860
|
+
});
|
|
9861
|
+
if (rpcId) {
|
|
9862
|
+
set$c(rpcId, rpc);
|
|
9644
9863
|
}
|
|
9645
|
-
return {
|
|
9646
|
-
tokenizersToLoad,
|
|
9647
|
-
embeddedResults
|
|
9648
|
-
};
|
|
9649
9864
|
};
|
|
9650
|
-
|
|
9651
|
-
|
|
9865
|
+
|
|
9866
|
+
const applyTabCompletion = (editor, result) => {
|
|
9867
|
+
return editorSnippet(editor, result);
|
|
9652
9868
|
};
|
|
9653
9869
|
|
|
9654
|
-
|
|
9655
|
-
const
|
|
9656
|
-
|
|
9657
|
-
|
|
9658
|
-
|
|
9659
|
-
tokenizerId,
|
|
9660
|
-
lines,
|
|
9661
|
-
languageId
|
|
9662
|
-
} = editor;
|
|
9663
|
-
const tokenizer = get(tokenizerId);
|
|
9664
|
-
const {
|
|
9665
|
-
hasArrayReturn,
|
|
9666
|
-
tokenizeLine,
|
|
9667
|
-
initialLineState
|
|
9668
|
-
} = tokenizer;
|
|
9669
|
-
const tokenizeStartIndex = invalidStartIndex;
|
|
9670
|
-
const tokenizeEndIndex = getTokenizeEndIndex(invalidStartIndex, endLineIndex, tokenizeStartIndex);
|
|
9671
|
-
const tokenizersToLoad = [];
|
|
9672
|
-
const embeddedResults = [];
|
|
9673
|
-
const linesWithEmbed = [];
|
|
9674
|
-
for (let i = tokenizeStartIndex; i < tokenizeEndIndex; i++) {
|
|
9675
|
-
const lineState = i === 0 ? getInitialLineState(initialLineState) : lineCache[i];
|
|
9676
|
-
const line = lines[i];
|
|
9677
|
-
const result = safeTokenizeLine(languageId, tokenizeLine, line, lineState, hasArrayReturn);
|
|
9678
|
-
// TODO if lineCacheEnd matches the one before, skip tokenizing lines after
|
|
9679
|
-
lineCache[i + 1] = result;
|
|
9680
|
-
if (result.embeddedLanguage) {
|
|
9681
|
-
result.embeddedResultIndex = linesWithEmbed.length;
|
|
9682
|
-
linesWithEmbed.push(i);
|
|
9683
|
-
}
|
|
9870
|
+
const handleTab = async editor => {
|
|
9871
|
+
const result = await getTabCompletion(editor);
|
|
9872
|
+
if (!result) {
|
|
9873
|
+
// TODO enter tab or two spaces
|
|
9874
|
+
return editor;
|
|
9684
9875
|
}
|
|
9685
|
-
|
|
9686
|
-
|
|
9876
|
+
return applyTabCompletion(editor, result);
|
|
9877
|
+
};
|
|
9878
|
+
|
|
9879
|
+
const relaunchWorkers = async () => {
|
|
9880
|
+
await dispose();
|
|
9881
|
+
await launch();
|
|
9882
|
+
};
|
|
9883
|
+
|
|
9884
|
+
const getWidgetName = widgetId => {
|
|
9885
|
+
switch (widgetId) {
|
|
9886
|
+
case Find:
|
|
9887
|
+
return `FindWidget`;
|
|
9888
|
+
default:
|
|
9889
|
+
return '';
|
|
9890
|
+
}
|
|
9891
|
+
};
|
|
9892
|
+
const saveWidgetState = async keys => {
|
|
9893
|
+
const savedStates = Object.create(null);
|
|
9894
|
+
for (const key of keys) {
|
|
9895
|
+
const editor = get$4(parseInt(key));
|
|
9687
9896
|
const {
|
|
9688
|
-
|
|
9689
|
-
|
|
9690
|
-
|
|
9691
|
-
|
|
9692
|
-
|
|
9693
|
-
|
|
9694
|
-
|
|
9695
|
-
|
|
9696
|
-
|
|
9697
|
-
};
|
|
9897
|
+
widgets
|
|
9898
|
+
} = editor.newState;
|
|
9899
|
+
for (const widget of widgets) {
|
|
9900
|
+
const invoke = getWidgetInvoke(widget.id);
|
|
9901
|
+
const fullKey = `${key}:${widget.newState.uid}`;
|
|
9902
|
+
const name = getWidgetName(widget.id);
|
|
9903
|
+
const savedState = await invoke(`${name}.saveState`, widget.newState.uid);
|
|
9904
|
+
savedStates[fullKey] = savedState;
|
|
9905
|
+
}
|
|
9698
9906
|
}
|
|
9699
|
-
|
|
9700
|
-
return {
|
|
9701
|
-
tokens: visibleLines,
|
|
9702
|
-
tokenizersToLoad,
|
|
9703
|
-
embeddedResults
|
|
9704
|
-
};
|
|
9907
|
+
return savedStates;
|
|
9705
9908
|
};
|
|
9706
9909
|
|
|
9707
|
-
const
|
|
9708
|
-
|
|
9709
|
-
|
|
9710
|
-
const
|
|
9711
|
-
|
|
9712
|
-
|
|
9713
|
-
|
|
9714
|
-
|
|
9715
|
-
|
|
9716
|
-
|
|
9717
|
-
|
|
9718
|
-
|
|
9719
|
-
|
|
9720
|
-
|
|
9721
|
-
|
|
9722
|
-
|
|
9723
|
-
|
|
9724
|
-
}
|
|
9725
|
-
|
|
9726
|
-
|
|
9727
|
-
|
|
9728
|
-
|
|
9729
|
-
|
|
9910
|
+
const restoreWidgetState = async (keys, savedStates) => {
|
|
9911
|
+
const newEditors = [];
|
|
9912
|
+
for (const key of keys) {
|
|
9913
|
+
const editorUid = parseInt(key);
|
|
9914
|
+
const editor = get$4(editorUid);
|
|
9915
|
+
const {
|
|
9916
|
+
widgets
|
|
9917
|
+
} = editor.newState;
|
|
9918
|
+
const newWidgets = [];
|
|
9919
|
+
for (const widget of widgets) {
|
|
9920
|
+
const invoke = getWidgetInvoke(widget.id);
|
|
9921
|
+
const fullKey = `${key}:${widget.newState.uid}`;
|
|
9922
|
+
const savedState = savedStates[fullKey] || {};
|
|
9923
|
+
const name = getWidgetName(widget.id);
|
|
9924
|
+
await invoke(`${name}.create`, widget.newState.uid, widget.newState.x, widget.newState.y, widget.newState.width, widget.newState.height, editorUid);
|
|
9925
|
+
await invoke(`${name}.loadContent`, widget.newState.uid, savedState);
|
|
9926
|
+
const diffResult = await invoke(`${name}.diff2`, widget.newState.uid);
|
|
9927
|
+
const commands = await invoke(`${name}.render2`, widget.newState.uid, diffResult);
|
|
9928
|
+
const newWidget = {
|
|
9929
|
+
...widget,
|
|
9930
|
+
newState: {
|
|
9931
|
+
...widget.newState,
|
|
9932
|
+
commands
|
|
9933
|
+
}
|
|
9730
9934
|
};
|
|
9731
|
-
|
|
9732
|
-
// @ts-ignore
|
|
9733
|
-
startLineIndex, endLineIndex, hasLinesToSend, id, linesToSend);
|
|
9935
|
+
newWidgets.push(newWidget);
|
|
9734
9936
|
}
|
|
9735
|
-
|
|
9736
|
-
|
|
9737
|
-
|
|
9937
|
+
newEditors.push({
|
|
9938
|
+
...editor,
|
|
9939
|
+
newState: {
|
|
9940
|
+
...editor.newState,
|
|
9941
|
+
widgets: newWidgets
|
|
9942
|
+
}
|
|
9943
|
+
});
|
|
9738
9944
|
}
|
|
9739
|
-
return
|
|
9945
|
+
return newEditors;
|
|
9740
9946
|
};
|
|
9741
9947
|
|
|
9742
|
-
|
|
9743
|
-
|
|
9744
|
-
|
|
9745
|
-
|
|
9948
|
+
let isReloading = false;
|
|
9949
|
+
const hotReload = async () => {
|
|
9950
|
+
if (isReloading) {
|
|
9951
|
+
return;
|
|
9746
9952
|
}
|
|
9747
|
-
|
|
9953
|
+
isReloading = true;
|
|
9748
9954
|
|
|
9749
|
-
//
|
|
9750
|
-
|
|
9751
|
-
|
|
9752
|
-
|
|
9753
|
-
|
|
9754
|
-
|
|
9755
|
-
|
|
9756
|
-
|
|
9757
|
-
// lineState = editor.tokenizer.tokenizeLine(line, lineState)
|
|
9758
|
-
// if (!lineState || !lineState.tokens || !lineState.state) {
|
|
9759
|
-
// throw new Error('invalid tokenization result')
|
|
9760
|
-
// }
|
|
9761
|
-
// } catch (error) {
|
|
9762
|
-
// tokens.push([{ length: line.length, type: 0 }])
|
|
9763
|
-
// console.error(error)
|
|
9764
|
-
// // renderWithoutSyntaxHighlighting(state, firstRow, lastRow)
|
|
9765
|
-
// continue
|
|
9766
|
-
// }
|
|
9767
|
-
// const newTokens = lineState.tokens
|
|
9768
|
-
// tokens.push(newTokens)
|
|
9769
|
-
// }
|
|
9770
|
-
// return tokens
|
|
9771
|
-
// }
|
|
9955
|
+
// TODO use getEditors
|
|
9956
|
+
const keys = getKeys$1();
|
|
9957
|
+
const savedStates = await saveWidgetState(keys);
|
|
9958
|
+
await relaunchWorkers();
|
|
9959
|
+
const newEditors = await restoreWidgetState(keys, savedStates);
|
|
9960
|
+
for (const editor of newEditors) {
|
|
9961
|
+
set$6(editor.newState.uid, editor.oldState, editor.newState);
|
|
9962
|
+
}
|
|
9772
9963
|
|
|
9773
|
-
//
|
|
9774
|
-
//
|
|
9775
|
-
|
|
9776
|
-
|
|
9777
|
-
|
|
9778
|
-
// result.push(getLineInfo(lines[i], tokens[i], TokenMap))
|
|
9779
|
-
// }
|
|
9780
|
-
// return result
|
|
9781
|
-
// }
|
|
9964
|
+
// TODO ask renderer worker to rerender all editors
|
|
9965
|
+
// @ts-ignore
|
|
9966
|
+
await invoke$9(`Editor.rerender`);
|
|
9967
|
+
isReloading = false;
|
|
9968
|
+
};
|
|
9782
9969
|
|
|
9783
|
-
const
|
|
9784
|
-
|
|
9785
|
-
|
|
9786
|
-
|
|
9787
|
-
|
|
9788
|
-
|
|
9789
|
-
const
|
|
9790
|
-
|
|
9791
|
-
|
|
9792
|
-
|
|
9793
|
-
|
|
9794
|
-
|
|
9795
|
-
|
|
9796
|
-
|
|
9797
|
-
|
|
9970
|
+
const sendMessagePortToExtensionHostWorker2 = async (port, initialCommand, rpcId) => {
|
|
9971
|
+
await invokeAndTransfer('SendMessagePortToExtensionHostWorker.sendMessagePortToExtensionHostWorker', port, initialCommand, rpcId);
|
|
9972
|
+
};
|
|
9973
|
+
|
|
9974
|
+
const createExtensionHostRpc = async () => {
|
|
9975
|
+
try {
|
|
9976
|
+
const {
|
|
9977
|
+
port1,
|
|
9978
|
+
port2
|
|
9979
|
+
} = getPortTuple();
|
|
9980
|
+
const initialCommand = 'HandleMessagePort.handleMessagePort2';
|
|
9981
|
+
// TODO use transfer rpc
|
|
9982
|
+
await sendMessagePortToExtensionHostWorker2(port2, initialCommand, EditorWorker);
|
|
9983
|
+
const rpc = await PlainMessagePortRpcParent.create({
|
|
9984
|
+
commandMap: {},
|
|
9985
|
+
messagePort: port1
|
|
9986
|
+
});
|
|
9987
|
+
return rpc;
|
|
9988
|
+
} catch (error) {
|
|
9989
|
+
throw new VError(error, `Failed to create extension host rpc`);
|
|
9798
9990
|
}
|
|
9799
|
-
return {
|
|
9800
|
-
start,
|
|
9801
|
-
end,
|
|
9802
|
-
startIndex
|
|
9803
|
-
};
|
|
9804
9991
|
};
|
|
9805
|
-
|
|
9806
|
-
|
|
9807
|
-
const
|
|
9808
|
-
|
|
9809
|
-
|
|
9810
|
-
|
|
9811
|
-
|
|
9812
|
-
|
|
9813
|
-
|
|
9814
|
-
|
|
9815
|
-
|
|
9816
|
-
|
|
9817
|
-
|
|
9818
|
-
|
|
9819
|
-
|
|
9820
|
-
|
|
9821
|
-
|
|
9822
|
-
const
|
|
9823
|
-
|
|
9824
|
-
|
|
9825
|
-
|
|
9826
|
-
|
|
9827
|
-
|
|
9828
|
-
|
|
9992
|
+
|
|
9993
|
+
const initializeExtensionHost = async () => {
|
|
9994
|
+
const extensionHostRpc = await createExtensionHostRpc();
|
|
9995
|
+
set$1(extensionHostRpc);
|
|
9996
|
+
};
|
|
9997
|
+
|
|
9998
|
+
const sendMessagePortToSyntaxHighlightingWorker = async () => {
|
|
9999
|
+
try {
|
|
10000
|
+
const {
|
|
10001
|
+
port1,
|
|
10002
|
+
port2
|
|
10003
|
+
} = getPortTuple();
|
|
10004
|
+
await invokeAndTransfer(
|
|
10005
|
+
// @ts-ignore
|
|
10006
|
+
'SendMessagePortToSyntaxHighlightingWorker.sendMessagePortToSyntaxHighlightingWorker', port1, 'HandleMessagePort.handleMessagePort2');
|
|
10007
|
+
return port2;
|
|
10008
|
+
} catch {
|
|
10009
|
+
const {
|
|
10010
|
+
port1,
|
|
10011
|
+
port2
|
|
10012
|
+
} = getPortTuple();
|
|
10013
|
+
await invokeAndTransfer(
|
|
10014
|
+
// @ts-ignore
|
|
10015
|
+
'SendMessagePortToSyntaxHighlightingWorker.sendMessagePortToSyntaxHighlightingWorker', port1, 'HandleMessagePort.handleMessagePort');
|
|
10016
|
+
return port2;
|
|
9829
10017
|
}
|
|
9830
|
-
return {
|
|
9831
|
-
lineInfo,
|
|
9832
|
-
difference
|
|
9833
|
-
};
|
|
9834
10018
|
};
|
|
9835
|
-
|
|
9836
|
-
|
|
9837
|
-
|
|
9838
|
-
|
|
9839
|
-
|
|
9840
|
-
|
|
9841
|
-
|
|
9842
|
-
};
|
|
10019
|
+
|
|
10020
|
+
const createSyntaxHighlightingWorkerRpc = async () => {
|
|
10021
|
+
try {
|
|
10022
|
+
const port = await sendMessagePortToSyntaxHighlightingWorker();
|
|
10023
|
+
const rpc = await PlainMessagePortRpcParent.create({
|
|
10024
|
+
commandMap: {},
|
|
10025
|
+
messagePort: port
|
|
10026
|
+
});
|
|
10027
|
+
return rpc;
|
|
10028
|
+
} catch (error) {
|
|
10029
|
+
throw new VError(error, `Failed to create syntax highlighting worker rpc`);
|
|
9843
10030
|
}
|
|
9844
|
-
const minOffset = Math.ceil(deltaX / averageCharWidth);
|
|
9845
|
-
const maxOffset = minOffset + Math.ceil(width / averageCharWidth);
|
|
9846
|
-
return {
|
|
9847
|
-
minOffset,
|
|
9848
|
-
maxOffset
|
|
9849
|
-
};
|
|
9850
|
-
};
|
|
9851
|
-
const getDifference = (start, averageCharWidth, deltaX) => {
|
|
9852
|
-
const beforeWidth = start * averageCharWidth;
|
|
9853
|
-
const difference = beforeWidth - deltaX;
|
|
9854
|
-
return difference;
|
|
9855
10031
|
};
|
|
9856
|
-
|
|
9857
|
-
|
|
9858
|
-
|
|
9859
|
-
|
|
9860
|
-
const
|
|
9861
|
-
|
|
9862
|
-
break;
|
|
9863
|
-
}
|
|
9864
|
-
}
|
|
9865
|
-
const {
|
|
9866
|
-
tokens
|
|
9867
|
-
} = tokenResults;
|
|
9868
|
-
let {
|
|
9869
|
-
startIndex,
|
|
9870
|
-
start,
|
|
9871
|
-
end
|
|
9872
|
-
} = getStartDefaults(tokens, minOffset);
|
|
9873
|
-
const difference = getDifference(start, averageCharWidth, deltaX);
|
|
9874
|
-
const tokensLength = tokens.length;
|
|
9875
|
-
for (let i = startIndex; i < tokensLength; i += 2) {
|
|
9876
|
-
const tokenType = tokens[i];
|
|
9877
|
-
const tokenLength = tokens[i + 1];
|
|
9878
|
-
const decorationOffset = decorations[decorationIndex];
|
|
9879
|
-
let extraClassName = '';
|
|
9880
|
-
if (decorationOffset !== undefined && decorationOffset - lineOffset === start) {
|
|
9881
|
-
// @ts-ignore
|
|
9882
|
-
decorations[++decorationIndex];
|
|
9883
|
-
const decorationType = decorations[++decorationIndex];
|
|
9884
|
-
// @ts-ignore
|
|
9885
|
-
decorations[++decorationIndex];
|
|
9886
|
-
// decorationIndex,
|
|
9887
|
-
// decorationLength,
|
|
9888
|
-
// decorationType,
|
|
9889
|
-
// decorationModifiers,
|
|
9890
|
-
// })
|
|
9891
|
-
extraClassName = getDecorationClassName(decorationType);
|
|
9892
|
-
}
|
|
9893
|
-
end += tokenLength;
|
|
9894
|
-
const text = line.slice(start, end);
|
|
9895
|
-
const className = `Token ${extraClassName || TokenMap[tokenType] || 'Unknown'}`;
|
|
9896
|
-
const normalizedText = normalizeText(text, normalize, tabSize);
|
|
9897
|
-
lineInfo.push(normalizedText, className);
|
|
9898
|
-
start = end;
|
|
9899
|
-
if (end >= maxOffset) {
|
|
9900
|
-
break;
|
|
9901
|
-
}
|
|
10032
|
+
|
|
10033
|
+
const initializeSyntaxHighlighting = async (syntaxHighlightingEnabled, syncIncremental) => {
|
|
10034
|
+
if (syntaxHighlightingEnabled) {
|
|
10035
|
+
setEnabled$1(true);
|
|
10036
|
+
const syntaxRpc = await createSyntaxHighlightingWorkerRpc();
|
|
10037
|
+
set$5(syntaxRpc);
|
|
9902
10038
|
}
|
|
9903
|
-
|
|
9904
|
-
|
|
9905
|
-
difference
|
|
9906
|
-
};
|
|
9907
|
-
};
|
|
9908
|
-
const getLineInfo = (line, tokenResults, embeddedResults, decorations, TokenMap, lineOffset, normalize, tabSize, width, deltaX, averageCharWidth) => {
|
|
9909
|
-
const {
|
|
9910
|
-
minOffset,
|
|
9911
|
-
maxOffset
|
|
9912
|
-
} = getOffsets(deltaX, width, averageCharWidth);
|
|
9913
|
-
if (embeddedResults.length > 0 && tokenResults.embeddedResultIndex !== undefined) {
|
|
9914
|
-
const embeddedResult = embeddedResults[tokenResults.embeddedResultIndex];
|
|
9915
|
-
if (embeddedResult?.isFull) {
|
|
9916
|
-
return getLineInfoEmbeddedFull(embeddedResults, tokenResults, line, normalize, tabSize, width, deltaX, averageCharWidth, minOffset, maxOffset);
|
|
9917
|
-
}
|
|
10039
|
+
if (syncIncremental) {
|
|
10040
|
+
setEnabled(true);
|
|
9918
10041
|
}
|
|
9919
|
-
return getLineInfoDefault(line, tokenResults, embeddedResults, decorations, TokenMap, lineOffset, normalize, tabSize, width, deltaX, averageCharWidth, minOffset, maxOffset);
|
|
9920
10042
|
};
|
|
9921
10043
|
|
|
9922
|
-
|
|
9923
|
-
|
|
9924
|
-
const result = [];
|
|
9925
|
-
const differences = [];
|
|
9926
|
-
const {
|
|
9927
|
-
lines,
|
|
9928
|
-
decorations,
|
|
9929
|
-
languageId
|
|
9930
|
-
} = editor;
|
|
9931
|
-
const tokenMap = get$1(languageId);
|
|
9932
|
-
let offset = minLineOffset;
|
|
9933
|
-
const tabSize = 2;
|
|
9934
|
-
for (let i = minLineY; i < maxLineY; i++) {
|
|
9935
|
-
const line = lines[i];
|
|
9936
|
-
const normalize = shouldNormalizeText(line);
|
|
9937
|
-
const {
|
|
9938
|
-
lineInfo,
|
|
9939
|
-
difference
|
|
9940
|
-
} = getLineInfo(line, tokens[i - minLineY], embeddedResults, decorations, tokenMap, offset, normalize, tabSize, width, deltaX, averageCharWidth);
|
|
9941
|
-
result.push(lineInfo);
|
|
9942
|
-
differences.push(difference);
|
|
9943
|
-
offset += line.length + 1;
|
|
9944
|
-
}
|
|
9945
|
-
return {
|
|
9946
|
-
result,
|
|
9947
|
-
differences
|
|
9948
|
-
};
|
|
10044
|
+
const intialize = async (syntaxHighlightingEnabled, syncIncremental) => {
|
|
10045
|
+
await Promise.all([initializeSyntaxHighlighting(syntaxHighlightingEnabled, syncIncremental), initializeExtensionHost()]);
|
|
9949
10046
|
};
|
|
9950
|
-
|
|
9951
|
-
|
|
9952
|
-
|
|
9953
|
-
|
|
9954
|
-
|
|
9955
|
-
//
|
|
9956
|
-
|
|
9957
|
-
|
|
9958
|
-
|
|
9959
|
-
|
|
9960
|
-
|
|
9961
|
-
|
|
9962
|
-
|
|
9963
|
-
|
|
9964
|
-
|
|
10047
|
+
|
|
10048
|
+
// TODO move cursor
|
|
10049
|
+
// TODO multiple cursors -> vscode removes multiple cursors
|
|
10050
|
+
// TODO with selection -> vscode moves whole selection
|
|
10051
|
+
const moveLineDown = editor => {
|
|
10052
|
+
// const rowIndex = editor.cursor.rowIndex
|
|
10053
|
+
// if (rowIndex === editor.lines.length - 1) {
|
|
10054
|
+
// return
|
|
10055
|
+
// }
|
|
10056
|
+
// const documentEdits = [
|
|
10057
|
+
// {
|
|
10058
|
+
// type: /* splice */ 2,
|
|
10059
|
+
// rowIndex: rowIndex,
|
|
10060
|
+
// count: 2,
|
|
10061
|
+
// newLines: [TextDocument.getLine(editor.textDocument, rowIndex + 1), TextDocument.getLine(editor.textDocument, rowIndex)],
|
|
10062
|
+
// },
|
|
10063
|
+
// ]
|
|
10064
|
+
// // @ts-ignore
|
|
10065
|
+
// const cursorEdits = Editor.moveCursors(editor, (editor, cursor) => {
|
|
10066
|
+
// return {
|
|
10067
|
+
// rowIndex: cursor.rowIndex + 1,
|
|
10068
|
+
// columnIndex: cursor.columnIndex,
|
|
10069
|
+
// }
|
|
10070
|
+
// })
|
|
9965
10071
|
// @ts-ignore
|
|
9966
|
-
|
|
9967
|
-
|
|
9968
|
-
|
|
9969
|
-
|
|
9970
|
-
|
|
9971
|
-
|
|
9972
|
-
const
|
|
9973
|
-
|
|
9974
|
-
|
|
9975
|
-
|
|
9976
|
-
|
|
9977
|
-
|
|
9978
|
-
|
|
9979
|
-
|
|
9980
|
-
|
|
9981
|
-
|
|
9982
|
-
|
|
9983
|
-
|
|
10072
|
+
// Editor.scheduleDocumentAndCursors(editor, documentEdits, cursorEdits)
|
|
10073
|
+
return editor;
|
|
10074
|
+
};
|
|
10075
|
+
|
|
10076
|
+
// TODO handle multiple cursors
|
|
10077
|
+
const moveLineUp = editor => {
|
|
10078
|
+
// const rowIndex = editor.cursor.rowIndex
|
|
10079
|
+
// if (rowIndex === 0) {
|
|
10080
|
+
// return
|
|
10081
|
+
// }
|
|
10082
|
+
// const documentEdits = [
|
|
10083
|
+
// {
|
|
10084
|
+
// type: /* splice */ 2,
|
|
10085
|
+
// rowIndex: rowIndex - 1,
|
|
10086
|
+
// count: 2,
|
|
10087
|
+
// newLines: [TextDocument.getLine(editor.textDocument, rowIndex), TextDocument.getLine(editor.textDocument, rowIndex - 1)],
|
|
10088
|
+
// },
|
|
10089
|
+
// ]
|
|
10090
|
+
// // @ts-ignore
|
|
10091
|
+
// const cursorEdits = Editor.moveCursors(editor, (editor, cursor) => {
|
|
10092
|
+
// return {
|
|
10093
|
+
// // TODO handle bottom 0
|
|
10094
|
+
// rowIndex: cursor.rowIndex - 1,
|
|
10095
|
+
// columnIndex: cursor.columnIndex,
|
|
10096
|
+
// }
|
|
10097
|
+
// })
|
|
10098
|
+
// // @ts-ignore
|
|
10099
|
+
// Editor.scheduleDocumentAndCursors(editor, documentEdits, cursorEdits)
|
|
10100
|
+
return editor;
|
|
9984
10101
|
};
|
|
9985
10102
|
|
|
9986
10103
|
const getCursorsVirtualDom = cursors => {
|
|
@@ -10079,36 +10196,6 @@ const getEditorRowsVirtualDom = (textInfos, differences, lineNumbers = true, hig
|
|
|
10079
10196
|
return dom;
|
|
10080
10197
|
};
|
|
10081
10198
|
|
|
10082
|
-
const getIncrementalEdits = async (oldState, newState) => {
|
|
10083
|
-
if (!newState.undoStack) {
|
|
10084
|
-
return undefined;
|
|
10085
|
-
}
|
|
10086
|
-
const lastChanges = newState.undoStack.at(-1);
|
|
10087
|
-
if (lastChanges && lastChanges.length === 1) {
|
|
10088
|
-
const lastChange = lastChanges[0];
|
|
10089
|
-
if (lastChange.origin === EditorType) {
|
|
10090
|
-
const {
|
|
10091
|
-
rowIndex
|
|
10092
|
-
} = lastChange.start;
|
|
10093
|
-
const {
|
|
10094
|
-
lines
|
|
10095
|
-
} = newState;
|
|
10096
|
-
const oldLine = oldState.lines[rowIndex];
|
|
10097
|
-
const newLine = lines[rowIndex];
|
|
10098
|
-
// @ts-ignore
|
|
10099
|
-
const incrementalEdits = await invoke$3(
|
|
10100
|
-
// @ts-ignore
|
|
10101
|
-
'TokenizeIncremental.tokenizeIncremental', newState.uid,
|
|
10102
|
-
// @ts-ignore
|
|
10103
|
-
newState.languageId, oldLine, newLine, rowIndex, newState.minLineY);
|
|
10104
|
-
if (incrementalEdits && incrementalEdits.length === 1) {
|
|
10105
|
-
return incrementalEdits;
|
|
10106
|
-
}
|
|
10107
|
-
}
|
|
10108
|
-
}
|
|
10109
|
-
return undefined;
|
|
10110
|
-
};
|
|
10111
|
-
|
|
10112
10199
|
const getSelectionsVirtualDom = selections => {
|
|
10113
10200
|
const dom = [];
|
|
10114
10201
|
for (let i = 0; i < selections.length; i += 4) {
|
|
@@ -10154,16 +10241,17 @@ const renderLines = {
|
|
|
10154
10241
|
isEqual(oldState, newState) {
|
|
10155
10242
|
return oldState.lines === newState.lines && oldState.tokenizerId === newState.tokenizerId && oldState.minLineY === newState.minLineY && oldState.decorations === newState.decorations && oldState.embeds === newState.embeds && oldState.deltaX === newState.deltaX && oldState.width === newState.width && oldState.highlightedLine === newState.highlightedLine && oldState.debugEnabled === newState.debugEnabled;
|
|
10156
10243
|
},
|
|
10157
|
-
|
|
10158
|
-
const
|
|
10159
|
-
|
|
10244
|
+
apply(oldState, newState) {
|
|
10245
|
+
const {
|
|
10246
|
+
incrementalEdits
|
|
10247
|
+
} = newState;
|
|
10248
|
+
if (incrementalEdits !== emptyIncrementalEdits) {
|
|
10160
10249
|
return [/* method */'setIncrementalEdits', /* incrementalEdits */incrementalEdits];
|
|
10161
10250
|
}
|
|
10162
|
-
const syncIncremental = getEnabled();
|
|
10163
10251
|
const {
|
|
10164
10252
|
textInfos,
|
|
10165
10253
|
differences
|
|
10166
|
-
} =
|
|
10254
|
+
} = newState;
|
|
10167
10255
|
newState.differences = differences;
|
|
10168
10256
|
const {
|
|
10169
10257
|
highlightedLine,
|
|
@@ -10182,7 +10270,7 @@ const renderSelections = {
|
|
|
10182
10270
|
const {
|
|
10183
10271
|
cursorInfos,
|
|
10184
10272
|
selectionInfos
|
|
10185
|
-
} = getVisible
|
|
10273
|
+
} = getVisible(newState);
|
|
10186
10274
|
const cursorsDom = getCursorsVirtualDom(cursorInfos);
|
|
10187
10275
|
const selectionsDom = getSelectionsVirtualDom(selectionInfos);
|
|
10188
10276
|
return [/* method */'setSelections', cursorsDom, selectionsDom];
|
|
@@ -10308,7 +10396,7 @@ const renderWidgets = {
|
|
|
10308
10396
|
multiple: true
|
|
10309
10397
|
};
|
|
10310
10398
|
const render$6 = [renderLines, renderSelections, renderScrollBarX, renderScrollBarY, renderFocus$1, renderDecorations, renderGutterInfo, renderWidgets];
|
|
10311
|
-
const renderEditor =
|
|
10399
|
+
const renderEditor = id => {
|
|
10312
10400
|
const instance = get$4(id);
|
|
10313
10401
|
if (!instance) {
|
|
10314
10402
|
return [];
|
|
@@ -10321,7 +10409,7 @@ const renderEditor = async id => {
|
|
|
10321
10409
|
set$6(id, newState, newState);
|
|
10322
10410
|
for (const item of render$6) {
|
|
10323
10411
|
if (!item.isEqual(oldState, newState)) {
|
|
10324
|
-
const result =
|
|
10412
|
+
const result = item.apply(oldState, newState);
|
|
10325
10413
|
// @ts-ignore
|
|
10326
10414
|
if (item.multiple) {
|
|
10327
10415
|
commands.push(...result);
|
|
@@ -10453,16 +10541,24 @@ const effects = [editorDiagnosticEffect];
|
|
|
10453
10541
|
const wrapCommand = fn => async (editorUid, ...args) => {
|
|
10454
10542
|
const oldInstance = get$4(editorUid);
|
|
10455
10543
|
const newEditor = await fn(oldInstance.newState, ...args);
|
|
10544
|
+
if (oldInstance.newState === newEditor) {
|
|
10545
|
+
return newEditor;
|
|
10546
|
+
}
|
|
10456
10547
|
for (const effect of effects) {
|
|
10457
10548
|
if (effect.isActive(oldInstance.newState, newEditor)) {
|
|
10458
10549
|
effect.apply(newEditor);
|
|
10459
10550
|
}
|
|
10460
10551
|
}
|
|
10552
|
+
// TODO if editor did not change, no need to update furthur
|
|
10553
|
+
|
|
10554
|
+
// TODO combine neweditor with latest editor?
|
|
10555
|
+
|
|
10461
10556
|
set$6(editorUid, oldInstance.newState, newEditor);
|
|
10462
|
-
|
|
10463
|
-
|
|
10464
|
-
|
|
10465
|
-
|
|
10557
|
+
const commands = renderEditor(editorUid);
|
|
10558
|
+
return {
|
|
10559
|
+
...newEditor,
|
|
10560
|
+
commands
|
|
10561
|
+
};
|
|
10466
10562
|
};
|
|
10467
10563
|
const wrapCommands = commands => {
|
|
10468
10564
|
for (const [key, value] of Object.entries(commands)) {
|
|
@@ -10497,6 +10593,7 @@ const commandMap = {
|
|
|
10497
10593
|
'Editor.compositionEnd': compositionEnd,
|
|
10498
10594
|
'Editor.compositionStart': compositionStart,
|
|
10499
10595
|
'Editor.compositionUpdate': compositionUpdate,
|
|
10596
|
+
'Editor.handleClickAtPosition': handleClickAtPosition,
|
|
10500
10597
|
'Editor.applyDocumentEdits': applyDocumentEdits,
|
|
10501
10598
|
'Editor.contextMenu': handleContextMenu,
|
|
10502
10599
|
'Editor.copy': copy,
|