@lvce-editor/editor-worker 9.0.0 → 10.0.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 +1093 -1001
- package/package.json +2 -2
package/dist/editorWorkerMain.js
CHANGED
|
@@ -1774,53 +1774,480 @@ const setDeltaY$2 = (state, value) => {
|
|
|
1774
1774
|
};
|
|
1775
1775
|
};
|
|
1776
1776
|
|
|
1777
|
-
const
|
|
1778
|
-
|
|
1779
|
-
|
|
1777
|
+
const Link$1 = 'Link';
|
|
1778
|
+
const Function = 'Function';
|
|
1779
|
+
const Parameter = 'Parameter';
|
|
1780
|
+
const Type = 'Type';
|
|
1781
|
+
const VariableName = 'VariableName';
|
|
1782
|
+
const Class = 'Class';
|
|
1783
|
+
|
|
1784
|
+
const Link = 1;
|
|
1785
|
+
const Ts2816 = 2816;
|
|
1786
|
+
const Ts2817 = 2817;
|
|
1787
|
+
const Ts2824 = 2824;
|
|
1788
|
+
const Ts2825 = 2825;
|
|
1789
|
+
const Ts2856 = 2956;
|
|
1790
|
+
const Ts2857 = 2857;
|
|
1791
|
+
const Ts3072 = 3072;
|
|
1792
|
+
const Ts3073 = 3073;
|
|
1793
|
+
const Ts3077 = 3077;
|
|
1794
|
+
const Ts3088 = 3088;
|
|
1795
|
+
const Ts1792 = 1792;
|
|
1796
|
+
const Ts1793 = 1793;
|
|
1797
|
+
const Ts512 = 512;
|
|
1798
|
+
const Ts513 = 513;
|
|
1799
|
+
const Ts769 = 769;
|
|
1800
|
+
const Ts1024 = 1024;
|
|
1801
|
+
const Ts1536 = 1536;
|
|
1802
|
+
const Ts1537 = 1537;
|
|
1803
|
+
const Ts1544 = 1544;
|
|
1804
|
+
const Ts1545 = 1545;
|
|
1805
|
+
const Ts2048 = 2048;
|
|
1806
|
+
const Ts2049 = 2049;
|
|
1807
|
+
const Ts2056 = 2056;
|
|
1808
|
+
const Ts2057 = 2057;
|
|
1809
|
+
const Ts2064 = 2064;
|
|
1810
|
+
const Ts2080 = 2080;
|
|
1811
|
+
const Ts2081 = 2081;
|
|
1812
|
+
const Ts2088 = 2088;
|
|
1813
|
+
const Ts2089 = 2089;
|
|
1814
|
+
const Ts2313 = 2313;
|
|
1815
|
+
const Ts2560 = 2560;
|
|
1816
|
+
const Ts2561 = 2561;
|
|
1817
|
+
const Ts2569 = 2569;
|
|
1818
|
+
const Ts2584 = 2584;
|
|
1819
|
+
const Ts256 = 256;
|
|
1820
|
+
const Ts257 = 257;
|
|
1821
|
+
const Ts272 = 272;
|
|
1822
|
+
|
|
1823
|
+
const getDecorationClassName = type => {
|
|
1824
|
+
switch (type) {
|
|
1825
|
+
case Link:
|
|
1826
|
+
return Link$1;
|
|
1827
|
+
case Ts2816:
|
|
1828
|
+
case Ts2817:
|
|
1829
|
+
case Ts2824:
|
|
1830
|
+
case Ts2825:
|
|
1831
|
+
case Ts2856:
|
|
1832
|
+
case Ts2857:
|
|
1833
|
+
case Ts3072:
|
|
1834
|
+
case Ts3073:
|
|
1835
|
+
case Ts3077:
|
|
1836
|
+
case Ts3088:
|
|
1837
|
+
return Function;
|
|
1838
|
+
case Ts1792:
|
|
1839
|
+
case Ts1793:
|
|
1840
|
+
return Parameter;
|
|
1841
|
+
case Ts512:
|
|
1842
|
+
case Ts513:
|
|
1843
|
+
case Ts769:
|
|
1844
|
+
case Ts1024:
|
|
1845
|
+
case Ts1536:
|
|
1846
|
+
case Ts1537:
|
|
1847
|
+
case Ts1544:
|
|
1848
|
+
case Ts1545:
|
|
1849
|
+
return Type;
|
|
1850
|
+
case Ts2048:
|
|
1851
|
+
case Ts2049:
|
|
1852
|
+
case Ts2056:
|
|
1853
|
+
case Ts2057:
|
|
1854
|
+
case Ts2064:
|
|
1855
|
+
case Ts2080:
|
|
1856
|
+
case Ts2081:
|
|
1857
|
+
case Ts2088:
|
|
1858
|
+
case Ts2089:
|
|
1859
|
+
case Ts2313:
|
|
1860
|
+
case Ts2560:
|
|
1861
|
+
case Ts2561:
|
|
1862
|
+
case Ts2569:
|
|
1863
|
+
case Ts2584:
|
|
1864
|
+
return VariableName;
|
|
1865
|
+
case Ts256:
|
|
1866
|
+
case Ts257:
|
|
1867
|
+
case Ts272:
|
|
1868
|
+
return Class;
|
|
1869
|
+
default:
|
|
1870
|
+
return `Unknown-${type}`;
|
|
1780
1871
|
}
|
|
1781
|
-
return lines.split('\n');
|
|
1782
1872
|
};
|
|
1783
1873
|
|
|
1784
|
-
|
|
1874
|
+
const deepCopy = value => {
|
|
1875
|
+
return structuredClone(value);
|
|
1876
|
+
};
|
|
1785
1877
|
|
|
1786
|
-
|
|
1787
|
-
|
|
1788
|
-
|
|
1789
|
-
|
|
1790
|
-
|
|
1791
|
-
|
|
1792
|
-
|
|
1793
|
-
|
|
1878
|
+
const getInitialLineState = initialLineState => {
|
|
1879
|
+
return deepCopy(initialLineState);
|
|
1880
|
+
};
|
|
1881
|
+
|
|
1882
|
+
const state$8 = {
|
|
1883
|
+
warned: []
|
|
1884
|
+
};
|
|
1885
|
+
const flattenTokensArray = tokens => {
|
|
1886
|
+
const flattened = [];
|
|
1887
|
+
for (const token of tokens) {
|
|
1888
|
+
object(token);
|
|
1889
|
+
flattened.push(token.type, token.length);
|
|
1794
1890
|
}
|
|
1795
|
-
|
|
1796
|
-
|
|
1891
|
+
return flattened;
|
|
1892
|
+
};
|
|
1893
|
+
const warnDeprecatedArrayReturn = (languageId, fn) => {
|
|
1894
|
+
if (state$8.warned.includes(fn)) {
|
|
1895
|
+
return;
|
|
1896
|
+
}
|
|
1897
|
+
state$8.warned.push(fn);
|
|
1898
|
+
console.warn(`tokenizers without hasArrayReturn=false are deprecated (language ${languageId})`);
|
|
1899
|
+
};
|
|
1900
|
+
const safeTokenizeLine = (languageId, tokenizeLine, line, lineStateAtStart, hasArrayReturn) => {
|
|
1901
|
+
try {
|
|
1902
|
+
const lineState = tokenizeLine(line, lineStateAtStart);
|
|
1903
|
+
if (!lineState?.tokens || !lineState.state) {
|
|
1904
|
+
throw new Error('invalid tokenization result');
|
|
1905
|
+
}
|
|
1906
|
+
if (!hasArrayReturn) {
|
|
1907
|
+
warnDeprecatedArrayReturn(languageId, tokenizeLine);
|
|
1908
|
+
// workaround for old tokenizers
|
|
1909
|
+
lineState.tokens = flattenTokensArray(lineState.tokens);
|
|
1910
|
+
}
|
|
1911
|
+
return lineState;
|
|
1912
|
+
} catch (error) {
|
|
1913
|
+
console.error(error);
|
|
1914
|
+
return {
|
|
1915
|
+
tokens: [/* type */0, /* length */line.length],
|
|
1916
|
+
lineState: lineStateAtStart
|
|
1917
|
+
};
|
|
1797
1918
|
}
|
|
1798
1919
|
};
|
|
1799
1920
|
|
|
1800
1921
|
/**
|
|
1801
|
-
*
|
|
1802
|
-
* can only support limited number of items due to the maximum call stack size limit.
|
|
1922
|
+
* @enum number
|
|
1803
1923
|
*/
|
|
1804
|
-
|
|
1805
|
-
|
|
1806
|
-
const result = array.splice(start, deleteCount);
|
|
1807
|
-
insertInto(array, start, newItems);
|
|
1808
|
-
return result;
|
|
1924
|
+
const State = {
|
|
1925
|
+
TopLevelContent: 1
|
|
1809
1926
|
};
|
|
1810
1927
|
|
|
1811
|
-
|
|
1812
|
-
|
|
1928
|
+
/**
|
|
1929
|
+
* @enum number
|
|
1930
|
+
*/
|
|
1931
|
+
const TokenType = {
|
|
1932
|
+
Text: 1
|
|
1933
|
+
};
|
|
1934
|
+
const TokenMap = {
|
|
1935
|
+
[TokenType.Text]: 'Text'
|
|
1936
|
+
};
|
|
1937
|
+
const initialLineState = {
|
|
1938
|
+
state: State.TopLevelContent
|
|
1939
|
+
};
|
|
1940
|
+
const hasArrayReturn = true;
|
|
1941
|
+
const tokenizeLine = (line, lineState) => {
|
|
1942
|
+
return {
|
|
1943
|
+
tokens: [TokenType.Text, line.length],
|
|
1944
|
+
state: lineState.state
|
|
1945
|
+
};
|
|
1813
1946
|
};
|
|
1814
1947
|
|
|
1815
|
-
const
|
|
1948
|
+
const TokenizePlainText = {
|
|
1949
|
+
__proto__: null,
|
|
1950
|
+
State,
|
|
1951
|
+
TokenMap,
|
|
1952
|
+
TokenType,
|
|
1953
|
+
hasArrayReturn,
|
|
1954
|
+
initialLineState,
|
|
1955
|
+
tokenizeLine
|
|
1956
|
+
};
|
|
1816
1957
|
|
|
1817
|
-
|
|
1818
|
-
const
|
|
1819
|
-
|
|
1820
|
-
|
|
1821
|
-
|
|
1958
|
+
let enabled$1 = false;
|
|
1959
|
+
const setEnabled$1 = value => {
|
|
1960
|
+
enabled$1 = value;
|
|
1961
|
+
};
|
|
1962
|
+
const getEnabled$1 = () => {
|
|
1963
|
+
return enabled$1;
|
|
1964
|
+
};
|
|
1965
|
+
|
|
1966
|
+
const {
|
|
1967
|
+
set: set$5,
|
|
1968
|
+
invoke: invoke$7} = SyntaxHighlightingWorker;
|
|
1969
|
+
|
|
1970
|
+
const state$7 = {
|
|
1971
|
+
tokenizers: Object.create(null),
|
|
1972
|
+
pending: Object.create(null)};
|
|
1973
|
+
const has = languageId => {
|
|
1974
|
+
return languageId in state$7.tokenizers;
|
|
1975
|
+
};
|
|
1976
|
+
const set$4 = (languageId, tokenizer) => {
|
|
1977
|
+
state$7.tokenizers[languageId] = tokenizer;
|
|
1978
|
+
};
|
|
1979
|
+
const get$3 = languageId => {
|
|
1980
|
+
return state$7.tokenizers[languageId];
|
|
1981
|
+
};
|
|
1982
|
+
const isPending = languageId => {
|
|
1983
|
+
return languageId in state$7.pending;
|
|
1984
|
+
};
|
|
1985
|
+
|
|
1986
|
+
const tokenMaps = Object.create(null);
|
|
1987
|
+
const set$3 = (languageId, tokenMap) => {
|
|
1988
|
+
tokenMaps[languageId] = tokenMap;
|
|
1989
|
+
};
|
|
1990
|
+
const get$2 = languageId => {
|
|
1991
|
+
return tokenMaps[languageId] || {};
|
|
1992
|
+
};
|
|
1993
|
+
|
|
1994
|
+
// TODO loadTokenizer should be invoked from renderer worker
|
|
1995
|
+
const loadTokenizer = async (languageId, tokenizePath) => {
|
|
1996
|
+
if (!tokenizePath) {
|
|
1997
|
+
return;
|
|
1822
1998
|
}
|
|
1823
|
-
|
|
1999
|
+
if (getEnabled$1()) {
|
|
2000
|
+
// @ts-ignore
|
|
2001
|
+
const tokenMap = await invoke$7('Tokenizer.load', languageId, tokenizePath);
|
|
2002
|
+
set$3(languageId, tokenMap);
|
|
2003
|
+
return;
|
|
2004
|
+
}
|
|
2005
|
+
try {
|
|
2006
|
+
// TODO check that tokenizer is valid
|
|
2007
|
+
// 1. tokenizeLine should be of type function
|
|
2008
|
+
// 2. getTokenClass should be of type function
|
|
2009
|
+
const tokenizer = await import(tokenizePath);
|
|
2010
|
+
if (typeof tokenizer.tokenizeLine !== 'function') {
|
|
2011
|
+
console.warn(`tokenizer.tokenizeLine should be a function in "${tokenizePath}"`);
|
|
2012
|
+
return;
|
|
2013
|
+
}
|
|
2014
|
+
if (!tokenizer.TokenMap || typeof tokenizer.TokenMap !== 'object' || Array.isArray(tokenizer.TokenMap)) {
|
|
2015
|
+
console.warn(`tokenizer.TokenMap should be an object in "${tokenizePath}"`);
|
|
2016
|
+
return;
|
|
2017
|
+
}
|
|
2018
|
+
set$3(languageId, tokenizer.TokenMap);
|
|
2019
|
+
set$4(languageId, tokenizer);
|
|
2020
|
+
} catch (error) {
|
|
2021
|
+
// TODO better error handling
|
|
2022
|
+
console.error(error);
|
|
2023
|
+
}
|
|
2024
|
+
};
|
|
2025
|
+
const getTokenizer = languageId => {
|
|
2026
|
+
if (has(languageId)) {
|
|
2027
|
+
return get$3(languageId);
|
|
2028
|
+
}
|
|
2029
|
+
if (isPending(languageId)) {
|
|
2030
|
+
return TokenizePlainText;
|
|
2031
|
+
}
|
|
2032
|
+
return TokenizePlainText;
|
|
2033
|
+
};
|
|
2034
|
+
|
|
2035
|
+
const tokenizers = Object.create(null);
|
|
2036
|
+
const set$2 = (id, value) => {
|
|
2037
|
+
tokenizers[id] = value;
|
|
2038
|
+
};
|
|
2039
|
+
const get$1 = id => {
|
|
2040
|
+
return tokenizers[id] || TokenizePlainText;
|
|
2041
|
+
};
|
|
2042
|
+
|
|
2043
|
+
const getTokensViewportEmbedded = (langageId, lines, lineCache, linesWithEmbed) => {
|
|
2044
|
+
const tokenizersToLoad = [];
|
|
2045
|
+
const embeddedResults = [];
|
|
2046
|
+
let topContext;
|
|
2047
|
+
for (const index of linesWithEmbed) {
|
|
2048
|
+
const result = lineCache[index + 1];
|
|
2049
|
+
const line = lines[index];
|
|
2050
|
+
if (result.embeddedLanguage) {
|
|
2051
|
+
const {
|
|
2052
|
+
embeddedLanguage,
|
|
2053
|
+
embeddedLanguageStart,
|
|
2054
|
+
embeddedLanguageEnd
|
|
2055
|
+
} = result;
|
|
2056
|
+
const embeddedTokenizer = getTokenizer(embeddedLanguage);
|
|
2057
|
+
if (embeddedLanguageStart !== line.length && embeddedTokenizer && embeddedTokenizer !== TokenizePlainText) {
|
|
2058
|
+
const isFull = embeddedLanguageStart === 0 && embeddedLanguageEnd === line.length;
|
|
2059
|
+
const partialLine = line.slice(embeddedLanguageStart, embeddedLanguageEnd);
|
|
2060
|
+
const embedResult = safeTokenizeLine(langageId, embeddedTokenizer.tokenizeLine, partialLine, topContext || getInitialLineState(embeddedTokenizer.initialLineState), embeddedTokenizer.hasArrayReturn);
|
|
2061
|
+
topContext = embedResult;
|
|
2062
|
+
result.embeddedResultIndex = embeddedResults.length;
|
|
2063
|
+
embeddedResults.push({
|
|
2064
|
+
result: embedResult,
|
|
2065
|
+
TokenMap: embeddedTokenizer.TokenMap,
|
|
2066
|
+
isFull
|
|
2067
|
+
});
|
|
2068
|
+
} else if (line.length === 0) {
|
|
2069
|
+
const embedResult = {
|
|
2070
|
+
tokens: []
|
|
2071
|
+
};
|
|
2072
|
+
result.embeddedResultIndex = embeddedResults.length;
|
|
2073
|
+
embeddedResults.push({
|
|
2074
|
+
result: embedResult,
|
|
2075
|
+
isFull: true,
|
|
2076
|
+
TokenMap: []
|
|
2077
|
+
});
|
|
2078
|
+
} else {
|
|
2079
|
+
tokenizersToLoad.push(embeddedLanguage);
|
|
2080
|
+
embeddedResults.push({
|
|
2081
|
+
result: {},
|
|
2082
|
+
isFull: false,
|
|
2083
|
+
TokenMap: []
|
|
2084
|
+
});
|
|
2085
|
+
topContext = undefined;
|
|
2086
|
+
}
|
|
2087
|
+
} else {
|
|
2088
|
+
topContext = undefined;
|
|
2089
|
+
}
|
|
2090
|
+
}
|
|
2091
|
+
return {
|
|
2092
|
+
tokenizersToLoad,
|
|
2093
|
+
embeddedResults
|
|
2094
|
+
};
|
|
2095
|
+
};
|
|
2096
|
+
const getTokenizeEndIndex = (invalidStartIndex, endLineIndex, tokenizeStartIndex) => {
|
|
2097
|
+
return invalidStartIndex < endLineIndex ? endLineIndex : tokenizeStartIndex;
|
|
2098
|
+
};
|
|
2099
|
+
|
|
2100
|
+
// TODO only send changed lines to renderer process instead of all lines in viewport
|
|
2101
|
+
const getTokensViewport = (editor, startLineIndex, endLineIndex) => {
|
|
2102
|
+
const {
|
|
2103
|
+
invalidStartIndex,
|
|
2104
|
+
lineCache,
|
|
2105
|
+
tokenizerId,
|
|
2106
|
+
lines,
|
|
2107
|
+
languageId
|
|
2108
|
+
} = editor;
|
|
2109
|
+
const tokenizer = get$1(tokenizerId);
|
|
2110
|
+
const {
|
|
2111
|
+
hasArrayReturn,
|
|
2112
|
+
tokenizeLine,
|
|
2113
|
+
initialLineState
|
|
2114
|
+
} = tokenizer;
|
|
2115
|
+
const tokenizeStartIndex = invalidStartIndex;
|
|
2116
|
+
const tokenizeEndIndex = getTokenizeEndIndex(invalidStartIndex, endLineIndex, tokenizeStartIndex);
|
|
2117
|
+
const tokenizersToLoad = [];
|
|
2118
|
+
const embeddedResults = [];
|
|
2119
|
+
const linesWithEmbed = [];
|
|
2120
|
+
for (let i = tokenizeStartIndex; i < tokenizeEndIndex; i++) {
|
|
2121
|
+
const lineState = i === 0 ? getInitialLineState(initialLineState) : lineCache[i];
|
|
2122
|
+
const line = lines[i];
|
|
2123
|
+
const result = safeTokenizeLine(languageId, tokenizeLine, line, lineState, hasArrayReturn);
|
|
2124
|
+
// TODO if lineCacheEnd matches the one before, skip tokenizing lines after
|
|
2125
|
+
lineCache[i + 1] = result;
|
|
2126
|
+
if (result.embeddedLanguage) {
|
|
2127
|
+
result.embeddedResultIndex = linesWithEmbed.length;
|
|
2128
|
+
linesWithEmbed.push(i);
|
|
2129
|
+
}
|
|
2130
|
+
}
|
|
2131
|
+
const visibleLines = lineCache.slice(startLineIndex + 1, endLineIndex + 1);
|
|
2132
|
+
if (linesWithEmbed.length > 0) {
|
|
2133
|
+
const {
|
|
2134
|
+
tokenizersToLoad,
|
|
2135
|
+
embeddedResults
|
|
2136
|
+
} = getTokensViewportEmbedded(languageId, lines, lineCache, linesWithEmbed);
|
|
2137
|
+
// TODO support lineCache with embedded content
|
|
2138
|
+
editor.invalidStartIndex = 0;
|
|
2139
|
+
return {
|
|
2140
|
+
tokens: visibleLines,
|
|
2141
|
+
tokenizersToLoad,
|
|
2142
|
+
embeddedResults
|
|
2143
|
+
};
|
|
2144
|
+
}
|
|
2145
|
+
editor.invalidStartIndex = Math.max(invalidStartIndex, tokenizeEndIndex);
|
|
2146
|
+
return {
|
|
2147
|
+
tokens: visibleLines,
|
|
2148
|
+
tokenizersToLoad,
|
|
2149
|
+
embeddedResults
|
|
2150
|
+
};
|
|
2151
|
+
};
|
|
2152
|
+
|
|
2153
|
+
const sentLines = Object.create(null);
|
|
2154
|
+
|
|
2155
|
+
// TODO only send changed lines to renderer process instead of all lines in viewport
|
|
2156
|
+
const getTokensViewport2 = async (editor, startLineIndex, endLineIndex, syncIncremental) => {
|
|
2157
|
+
if (getEnabled$1()) {
|
|
2158
|
+
if (syncIncremental) {
|
|
2159
|
+
const {
|
|
2160
|
+
invalidStartIndex,
|
|
2161
|
+
lines,
|
|
2162
|
+
languageId,
|
|
2163
|
+
id
|
|
2164
|
+
} = editor;
|
|
2165
|
+
let hasLinesToSend = true;
|
|
2166
|
+
let linesToSend = lines;
|
|
2167
|
+
if (sentLines[id] === lines) {
|
|
2168
|
+
hasLinesToSend = false;
|
|
2169
|
+
linesToSend = [];
|
|
2170
|
+
} else {
|
|
2171
|
+
sentLines[id] = lines;
|
|
2172
|
+
}
|
|
2173
|
+
const slimEditor = {
|
|
2174
|
+
languageId,
|
|
2175
|
+
invalidStartIndex
|
|
2176
|
+
};
|
|
2177
|
+
return invoke$7('GetTokensViewport.getTokensViewport', slimEditor,
|
|
2178
|
+
// @ts-ignore
|
|
2179
|
+
startLineIndex, endLineIndex, hasLinesToSend, id, linesToSend);
|
|
2180
|
+
}
|
|
2181
|
+
// TODO only send needed lines of text
|
|
2182
|
+
// @ts-ignore
|
|
2183
|
+
return invoke$7('GetTokensViewport.getTokensViewport', editor, startLineIndex, endLineIndex, true, editor.id, editor.lines);
|
|
2184
|
+
}
|
|
2185
|
+
return getTokensViewport(editor, startLineIndex, endLineIndex);
|
|
2186
|
+
};
|
|
2187
|
+
|
|
2188
|
+
const loadTokenizers = async languageIds => {
|
|
2189
|
+
for (const languageId of languageIds) {
|
|
2190
|
+
// @ts-ignore
|
|
2191
|
+
await loadTokenizer(languageId);
|
|
2192
|
+
}
|
|
2193
|
+
};
|
|
2194
|
+
|
|
2195
|
+
const EmptyString = '';
|
|
2196
|
+
const NewLine = '\n';
|
|
2197
|
+
const Space$1 = ' ';
|
|
2198
|
+
const Tab$1 = '\t';
|
|
2199
|
+
const DoubleQuote$1 = '"';
|
|
2200
|
+
|
|
2201
|
+
const normalizeText = (text, normalize, tabSize) => {
|
|
2202
|
+
if (normalize) {
|
|
2203
|
+
return text.replaceAll(Tab$1, Space$1.repeat(tabSize));
|
|
2204
|
+
}
|
|
2205
|
+
return text;
|
|
2206
|
+
};
|
|
2207
|
+
const shouldNormalizeText = text => {
|
|
2208
|
+
return text.includes(Tab$1);
|
|
2209
|
+
};
|
|
2210
|
+
|
|
2211
|
+
// based on https://github.com/microsoft/vscode/blob/c0769274fa136b45799edeccc0d0a2f645b75caf/src/vs/base/common/arrays.ts#L625 (License MIT)
|
|
2212
|
+
|
|
2213
|
+
// @ts-ignore
|
|
2214
|
+
const insertInto = (array, start, newItems) => {
|
|
2215
|
+
const originalLength = array.length;
|
|
2216
|
+
const newItemsLength = newItems.length;
|
|
2217
|
+
array.length = originalLength + newItemsLength;
|
|
2218
|
+
// Move the items after the start index, start from the end so that we don't overwrite any value.
|
|
2219
|
+
for (let i = originalLength - 1; i >= start; i--) {
|
|
2220
|
+
array[i + newItemsLength] = array[i];
|
|
2221
|
+
}
|
|
2222
|
+
for (let i = 0; i < newItemsLength; i++) {
|
|
2223
|
+
array[i + start] = newItems[i];
|
|
2224
|
+
}
|
|
2225
|
+
};
|
|
2226
|
+
|
|
2227
|
+
/**
|
|
2228
|
+
* Alternative to the native Array.splice method, it
|
|
2229
|
+
* can only support limited number of items due to the maximum call stack size limit.
|
|
2230
|
+
*/
|
|
2231
|
+
// @ts-ignore
|
|
2232
|
+
const spliceLargeArray = (array, start, deleteCount, newItems) => {
|
|
2233
|
+
const result = array.splice(start, deleteCount);
|
|
2234
|
+
insertInto(array, start, newItems);
|
|
2235
|
+
return result;
|
|
2236
|
+
};
|
|
2237
|
+
|
|
2238
|
+
const joinLines = lines => {
|
|
2239
|
+
return lines.join('\n');
|
|
2240
|
+
};
|
|
2241
|
+
|
|
2242
|
+
const RE_WHITESPACE = /^\s+/;
|
|
2243
|
+
|
|
2244
|
+
// TODO this doesn't belong here
|
|
2245
|
+
const getIndent = line => {
|
|
2246
|
+
const whitespaceMatch = line.match(RE_WHITESPACE);
|
|
2247
|
+
if (!whitespaceMatch) {
|
|
2248
|
+
return '';
|
|
2249
|
+
}
|
|
2250
|
+
return whitespaceMatch[0];
|
|
1824
2251
|
};
|
|
1825
2252
|
|
|
1826
2253
|
// TODO have function for single edit (most common, avoid one array)
|
|
@@ -1966,114 +2393,385 @@ const positionAt = (textDocument, offset) => {
|
|
|
1966
2393
|
};
|
|
1967
2394
|
};
|
|
1968
2395
|
|
|
1969
|
-
const
|
|
1970
|
-
|
|
1971
|
-
|
|
1972
|
-
|
|
1973
|
-
|
|
1974
|
-
|
|
1975
|
-
|
|
1976
|
-
|
|
1977
|
-
|
|
1978
|
-
|
|
1979
|
-
|
|
1980
|
-
|
|
1981
|
-
|
|
1982
|
-
|
|
1983
|
-
|
|
1984
|
-
|
|
2396
|
+
// const getTokensIncremental = (editor, min, max) => {
|
|
2397
|
+
// const currentLength = editor.lineStateCache.length
|
|
2398
|
+
// const tokens = []
|
|
2399
|
+
// const lines = editor.lines
|
|
2400
|
+
// let lineState = editor.tokenizer.initialLineState
|
|
2401
|
+
// for (let i = currentLength; i < max; i++) {
|
|
2402
|
+
// const line = lines[i]
|
|
2403
|
+
// try {
|
|
2404
|
+
// lineState = editor.tokenizer.tokenizeLine(line, lineState)
|
|
2405
|
+
// if (!lineState || !lineState.tokens || !lineState.state) {
|
|
2406
|
+
// throw new Error('invalid tokenization result')
|
|
2407
|
+
// }
|
|
2408
|
+
// } catch (error) {
|
|
2409
|
+
// tokens.push([{ length: line.length, type: 0 }])
|
|
2410
|
+
// console.error(error)
|
|
2411
|
+
// // renderWithoutSyntaxHighlighting(state, firstRow, lastRow)
|
|
2412
|
+
// continue
|
|
2413
|
+
// }
|
|
2414
|
+
// const newTokens = lineState.tokens
|
|
2415
|
+
// tokens.push(newTokens)
|
|
2416
|
+
// }
|
|
2417
|
+
// return tokens
|
|
2418
|
+
// }
|
|
1985
2419
|
|
|
1986
|
-
const
|
|
1987
|
-
|
|
1988
|
-
|
|
1989
|
-
|
|
1990
|
-
|
|
2420
|
+
// const getLineInfosIncremental = (editor, tokens, minLineY, maxLineY) => {
|
|
2421
|
+
// const result = []
|
|
2422
|
+
// const lines = editor.lines
|
|
2423
|
+
// const TokenMap = editor.tokenizer.TokenMap
|
|
2424
|
+
// for (let i = minLineY; i < maxLineY; i++) {
|
|
2425
|
+
// result.push(getLineInfo(lines[i], tokens[i], TokenMap))
|
|
2426
|
+
// }
|
|
2427
|
+
// return result
|
|
2428
|
+
// }
|
|
2429
|
+
|
|
2430
|
+
const getStartDefaults = (tokens, minOffset) => {
|
|
2431
|
+
let start = 0;
|
|
2432
|
+
let end = 0;
|
|
2433
|
+
let startIndex = 0;
|
|
2434
|
+
const tokensLength = tokens.length;
|
|
2435
|
+
for (let i = 0; i < tokensLength; i += 2) {
|
|
2436
|
+
const tokenLength = tokens[i + 1];
|
|
2437
|
+
end += tokenLength;
|
|
2438
|
+
start = end;
|
|
2439
|
+
if (start >= minOffset) {
|
|
2440
|
+
start -= tokenLength;
|
|
2441
|
+
end -= tokenLength;
|
|
2442
|
+
startIndex = i;
|
|
2443
|
+
break;
|
|
1991
2444
|
}
|
|
1992
2445
|
}
|
|
1993
|
-
return
|
|
1994
|
-
|
|
1995
|
-
|
|
1996
|
-
|
|
1997
|
-
|
|
1998
|
-
};
|
|
1999
|
-
|
|
2000
|
-
const getFontString = (fontWeight, fontSize, fontFamily) => {
|
|
2001
|
-
return `${fontWeight} ${fontSize}px ${fontFamily}`;
|
|
2002
|
-
};
|
|
2003
|
-
|
|
2004
|
-
const getLetterSpacingString = letterSpacing => {
|
|
2005
|
-
return `${letterSpacing}px`;
|
|
2446
|
+
return {
|
|
2447
|
+
start,
|
|
2448
|
+
end,
|
|
2449
|
+
startIndex
|
|
2450
|
+
};
|
|
2006
2451
|
};
|
|
2007
|
-
|
|
2008
|
-
const
|
|
2009
|
-
const
|
|
2010
|
-
const
|
|
2011
|
-
|
|
2012
|
-
|
|
2452
|
+
const getLineInfoEmbeddedFull = (embeddedResults, tokenResults, line, normalize, tabSize, width, deltaX, averageCharWidth, minOffset, maxOffset) => {
|
|
2453
|
+
const lineInfo = [];
|
|
2454
|
+
const embeddedResult = embeddedResults[tokenResults.embeddedResultIndex];
|
|
2455
|
+
const embeddedTokens = embeddedResult.result.tokens;
|
|
2456
|
+
const embeddedTokenMap = embeddedResult.TokenMap;
|
|
2457
|
+
const tokensLength = embeddedTokens.length;
|
|
2458
|
+
let {
|
|
2459
|
+
startIndex,
|
|
2460
|
+
start,
|
|
2461
|
+
end
|
|
2462
|
+
} = getStartDefaults(embeddedTokens, minOffset);
|
|
2463
|
+
const difference = getDifference(start, averageCharWidth, deltaX);
|
|
2464
|
+
for (let i = startIndex; i < tokensLength; i += 2) {
|
|
2465
|
+
const tokenType = embeddedTokens[i];
|
|
2466
|
+
const tokenLength = embeddedTokens[i + 1];
|
|
2467
|
+
end += tokenLength;
|
|
2468
|
+
const className = `Token ${embeddedTokenMap[tokenType] || 'Unknown'}`;
|
|
2469
|
+
const text = line.slice(start, end);
|
|
2470
|
+
const normalizedText = normalizeText(text, normalize, tabSize);
|
|
2471
|
+
lineInfo.push(normalizedText, className);
|
|
2472
|
+
start = end;
|
|
2473
|
+
if (end >= maxOffset) {
|
|
2474
|
+
break;
|
|
2475
|
+
}
|
|
2013
2476
|
}
|
|
2014
|
-
return
|
|
2015
|
-
|
|
2016
|
-
|
|
2017
|
-
|
|
2018
|
-
ctx: undefined
|
|
2477
|
+
return {
|
|
2478
|
+
lineInfo,
|
|
2479
|
+
difference
|
|
2480
|
+
};
|
|
2019
2481
|
};
|
|
2020
|
-
const
|
|
2021
|
-
|
|
2022
|
-
|
|
2482
|
+
const getOffsets = (deltaX, width, averageCharWidth) => {
|
|
2483
|
+
// TODO accurately measure char widths using offscreen canvas
|
|
2484
|
+
// and use fast measurements for monospace ascii text
|
|
2485
|
+
if (deltaX === 0) {
|
|
2486
|
+
return {
|
|
2487
|
+
minOffset: 0,
|
|
2488
|
+
maxOffset: Math.ceil(width / averageCharWidth)
|
|
2489
|
+
};
|
|
2023
2490
|
}
|
|
2024
|
-
|
|
2025
|
-
|
|
2491
|
+
const minOffset = Math.ceil(deltaX / averageCharWidth);
|
|
2492
|
+
const maxOffset = minOffset + Math.ceil(width / averageCharWidth);
|
|
2493
|
+
return {
|
|
2494
|
+
minOffset,
|
|
2495
|
+
maxOffset
|
|
2496
|
+
};
|
|
2026
2497
|
};
|
|
2027
|
-
|
|
2028
|
-
const
|
|
2029
|
-
const
|
|
2030
|
-
return
|
|
2498
|
+
const getDifference = (start, averageCharWidth, deltaX) => {
|
|
2499
|
+
const beforeWidth = start * averageCharWidth;
|
|
2500
|
+
const difference = beforeWidth - deltaX;
|
|
2501
|
+
return difference;
|
|
2031
2502
|
};
|
|
2032
|
-
|
|
2033
|
-
|
|
2034
|
-
|
|
2035
|
-
|
|
2036
|
-
|
|
2037
|
-
|
|
2038
|
-
|
|
2039
|
-
|
|
2040
|
-
boolean(isMonoSpaceFont);
|
|
2041
|
-
number(charWidth);
|
|
2042
|
-
if (typeof letterSpacing !== 'number') {
|
|
2043
|
-
throw new TypeError('letterSpacing must be of type number');
|
|
2503
|
+
const getLineInfoDefault = (line, tokenResults, embeddedResults, decorations, TokenMap, lineOffset, normalize, tabSize, width, deltaX, averageCharWidth, minOffset, maxOffset) => {
|
|
2504
|
+
const lineInfo = [];
|
|
2505
|
+
let decorationIndex = 0;
|
|
2506
|
+
for (; decorationIndex < decorations.length; decorationIndex += 3) {
|
|
2507
|
+
const decorationOffset = decorations[decorationIndex];
|
|
2508
|
+
if (decorationOffset >= lineOffset) {
|
|
2509
|
+
break;
|
|
2510
|
+
}
|
|
2044
2511
|
}
|
|
2045
|
-
const letterSpacingString = getLetterSpacingString(letterSpacing);
|
|
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
2512
|
const {
|
|
2052
|
-
|
|
2053
|
-
} =
|
|
2054
|
-
|
|
2513
|
+
tokens
|
|
2514
|
+
} = tokenResults;
|
|
2515
|
+
let {
|
|
2516
|
+
startIndex,
|
|
2517
|
+
start,
|
|
2518
|
+
end
|
|
2519
|
+
} = getStartDefaults(tokens, minOffset);
|
|
2520
|
+
const difference = getDifference(start, averageCharWidth, deltaX);
|
|
2521
|
+
const tokensLength = tokens.length;
|
|
2522
|
+
for (let i = startIndex; i < tokensLength; i += 2) {
|
|
2523
|
+
const tokenType = tokens[i];
|
|
2524
|
+
const tokenLength = tokens[i + 1];
|
|
2525
|
+
const decorationOffset = decorations[decorationIndex];
|
|
2526
|
+
let extraClassName = '';
|
|
2527
|
+
if (decorationOffset !== undefined && decorationOffset - lineOffset === start) {
|
|
2528
|
+
// @ts-ignore
|
|
2529
|
+
decorations[++decorationIndex];
|
|
2530
|
+
const decorationType = decorations[++decorationIndex];
|
|
2531
|
+
// @ts-ignore
|
|
2532
|
+
decorations[++decorationIndex];
|
|
2533
|
+
// decorationIndex,
|
|
2534
|
+
// decorationLength,
|
|
2535
|
+
// decorationType,
|
|
2536
|
+
// decorationModifiers,
|
|
2537
|
+
// })
|
|
2538
|
+
extraClassName = getDecorationClassName(decorationType);
|
|
2539
|
+
}
|
|
2540
|
+
end += tokenLength;
|
|
2541
|
+
const text = line.slice(start, end);
|
|
2542
|
+
const className = `Token ${extraClassName || TokenMap[tokenType] || 'Unknown'}`;
|
|
2543
|
+
const normalizedText = normalizeText(text, normalize, tabSize);
|
|
2544
|
+
lineInfo.push(normalizedText, className);
|
|
2545
|
+
start = end;
|
|
2546
|
+
if (end >= maxOffset) {
|
|
2547
|
+
break;
|
|
2548
|
+
}
|
|
2549
|
+
}
|
|
2550
|
+
return {
|
|
2551
|
+
lineInfo,
|
|
2552
|
+
difference
|
|
2553
|
+
};
|
|
2055
2554
|
};
|
|
2056
|
-
|
|
2057
|
-
const
|
|
2058
|
-
|
|
2059
|
-
|
|
2555
|
+
const getLineInfo$1 = (line, tokenResults, embeddedResults, decorations, TokenMap, lineOffset, normalize, tabSize, width, deltaX, averageCharWidth) => {
|
|
2556
|
+
const {
|
|
2557
|
+
minOffset,
|
|
2558
|
+
maxOffset
|
|
2559
|
+
} = getOffsets(deltaX, width, averageCharWidth);
|
|
2560
|
+
if (embeddedResults.length > 0 && tokenResults.embeddedResultIndex !== undefined) {
|
|
2561
|
+
const embeddedResult = embeddedResults[tokenResults.embeddedResultIndex];
|
|
2562
|
+
if (embeddedResult?.isFull) {
|
|
2563
|
+
return getLineInfoEmbeddedFull(embeddedResults, tokenResults, line, normalize, tabSize, width, deltaX, averageCharWidth, minOffset, maxOffset);
|
|
2564
|
+
}
|
|
2060
2565
|
}
|
|
2061
|
-
return
|
|
2566
|
+
return getLineInfoDefault(line, tokenResults, embeddedResults, decorations, TokenMap, lineOffset, normalize, tabSize, width, deltaX, averageCharWidth, minOffset, maxOffset);
|
|
2062
2567
|
};
|
|
2063
2568
|
|
|
2064
|
-
|
|
2065
|
-
|
|
2066
|
-
|
|
2569
|
+
// TODO need lots of tests for this
|
|
2570
|
+
const getLineInfosViewport = (editor, tokens, embeddedResults, minLineY, maxLineY, minLineOffset, width, deltaX, averageCharWidth) => {
|
|
2571
|
+
const result = [];
|
|
2572
|
+
const differences = [];
|
|
2573
|
+
const {
|
|
2574
|
+
lines,
|
|
2575
|
+
decorations,
|
|
2576
|
+
languageId
|
|
2577
|
+
} = editor;
|
|
2578
|
+
const tokenMap = get$2(languageId);
|
|
2579
|
+
let offset = minLineOffset;
|
|
2580
|
+
const tabSize = 2;
|
|
2581
|
+
for (let i = minLineY; i < maxLineY; i++) {
|
|
2582
|
+
const line = lines[i];
|
|
2583
|
+
const normalize = shouldNormalizeText(line);
|
|
2584
|
+
const {
|
|
2585
|
+
lineInfo,
|
|
2586
|
+
difference
|
|
2587
|
+
} = getLineInfo$1(line, tokens[i - minLineY], embeddedResults, decorations, tokenMap, offset, normalize, tabSize, width, deltaX, averageCharWidth);
|
|
2588
|
+
result.push(lineInfo);
|
|
2589
|
+
differences.push(difference);
|
|
2590
|
+
offset += line.length + 1;
|
|
2067
2591
|
}
|
|
2068
|
-
return
|
|
2592
|
+
return {
|
|
2593
|
+
result,
|
|
2594
|
+
differences
|
|
2595
|
+
};
|
|
2069
2596
|
};
|
|
2070
|
-
const
|
|
2071
|
-
|
|
2597
|
+
const getVisible$1 = async (editor, syncIncremental) => {
|
|
2598
|
+
// TODO should separate rendering from business logic somehow
|
|
2599
|
+
// currently hard to test because need to mock editor height, top, left,
|
|
2600
|
+
// invalidStartIndex, lineCache, etc. just for testing editorType
|
|
2601
|
+
// editor.invalidStartIndex = changes[0].start.rowIndex
|
|
2602
|
+
// @ts-ignore
|
|
2603
|
+
const {
|
|
2604
|
+
minLineY,
|
|
2605
|
+
numberOfVisibleLines,
|
|
2606
|
+
lines,
|
|
2607
|
+
width,
|
|
2608
|
+
deltaX,
|
|
2609
|
+
charWidth
|
|
2610
|
+
} = editor;
|
|
2611
|
+
const maxLineY = Math.min(minLineY + numberOfVisibleLines, lines.length);
|
|
2612
|
+
// @ts-ignore
|
|
2613
|
+
const {
|
|
2614
|
+
tokens,
|
|
2615
|
+
tokenizersToLoad,
|
|
2616
|
+
embeddedResults
|
|
2617
|
+
} = await getTokensViewport2(editor, minLineY, maxLineY, syncIncremental);
|
|
2618
|
+
const minLineOffset = offsetAtSync(editor, minLineY, 0);
|
|
2619
|
+
const averageCharWidth = charWidth;
|
|
2620
|
+
const {
|
|
2621
|
+
result,
|
|
2622
|
+
differences
|
|
2623
|
+
} = getLineInfosViewport(editor, tokens, embeddedResults, minLineY, maxLineY, minLineOffset, width, deltaX, averageCharWidth);
|
|
2624
|
+
if (tokenizersToLoad.length > 0) {
|
|
2625
|
+
loadTokenizers(tokenizersToLoad);
|
|
2626
|
+
}
|
|
2627
|
+
return {
|
|
2628
|
+
textInfos: result,
|
|
2629
|
+
differences
|
|
2630
|
+
};
|
|
2072
2631
|
};
|
|
2073
2632
|
|
|
2074
|
-
const
|
|
2075
|
-
|
|
2076
|
-
|
|
2633
|
+
const emptyIncrementalEdits = [];
|
|
2634
|
+
|
|
2635
|
+
const getIncrementalEdits = async (oldState, newState) => {
|
|
2636
|
+
if (!newState.undoStack) {
|
|
2637
|
+
return emptyIncrementalEdits;
|
|
2638
|
+
}
|
|
2639
|
+
if (oldState.undoStack === newState.undoStack) {
|
|
2640
|
+
return emptyIncrementalEdits;
|
|
2641
|
+
}
|
|
2642
|
+
const lastChanges = newState.undoStack.at(-1);
|
|
2643
|
+
if (lastChanges && lastChanges.length === 1) {
|
|
2644
|
+
const lastChange = lastChanges[0];
|
|
2645
|
+
if (lastChange.origin === EditorType) {
|
|
2646
|
+
const {
|
|
2647
|
+
rowIndex
|
|
2648
|
+
} = lastChange.start;
|
|
2649
|
+
const {
|
|
2650
|
+
lines
|
|
2651
|
+
} = newState;
|
|
2652
|
+
const oldLine = oldState.lines[rowIndex];
|
|
2653
|
+
const newLine = lines[rowIndex];
|
|
2654
|
+
// @ts-ignore
|
|
2655
|
+
const incrementalEdits = await invoke$7(
|
|
2656
|
+
// @ts-ignore
|
|
2657
|
+
'TokenizeIncremental.tokenizeIncremental', newState.uid,
|
|
2658
|
+
// @ts-ignore
|
|
2659
|
+
newState.languageId, oldLine, newLine, rowIndex, newState.minLineY);
|
|
2660
|
+
if (incrementalEdits && incrementalEdits.length === 1) {
|
|
2661
|
+
return incrementalEdits;
|
|
2662
|
+
}
|
|
2663
|
+
}
|
|
2664
|
+
}
|
|
2665
|
+
return emptyIncrementalEdits;
|
|
2666
|
+
};
|
|
2667
|
+
|
|
2668
|
+
const splitLines = lines => {
|
|
2669
|
+
if (!lines) {
|
|
2670
|
+
return [''];
|
|
2671
|
+
}
|
|
2672
|
+
return lines.split('\n');
|
|
2673
|
+
};
|
|
2674
|
+
|
|
2675
|
+
let enabled = false;
|
|
2676
|
+
const setEnabled = value => {
|
|
2677
|
+
enabled = value;
|
|
2678
|
+
};
|
|
2679
|
+
const getEnabled = () => {
|
|
2680
|
+
return enabled;
|
|
2681
|
+
};
|
|
2682
|
+
|
|
2683
|
+
const getSelectionPairs = (selections, i) => {
|
|
2684
|
+
const first = selections[i];
|
|
2685
|
+
const second = selections[i + 1];
|
|
2686
|
+
const third = selections[i + 2];
|
|
2687
|
+
const fourth = selections[i + 3];
|
|
2688
|
+
if (first > third || first === third && second >= fourth) {
|
|
2689
|
+
return [third, fourth, first, second, 1];
|
|
2690
|
+
}
|
|
2691
|
+
return [first, second, third, fourth, 0];
|
|
2692
|
+
};
|
|
2693
|
+
|
|
2694
|
+
const getTabCount = string => {
|
|
2695
|
+
let count = 0;
|
|
2696
|
+
for (const element of string) {
|
|
2697
|
+
if (element === Tab$1) {
|
|
2698
|
+
count++;
|
|
2699
|
+
}
|
|
2700
|
+
}
|
|
2701
|
+
return count;
|
|
2702
|
+
};
|
|
2703
|
+
|
|
2704
|
+
const measureTextWidthFast = (text, charWidth) => {
|
|
2705
|
+
return text.length * charWidth;
|
|
2706
|
+
};
|
|
2707
|
+
|
|
2708
|
+
const getFontString = (fontWeight, fontSize, fontFamily) => {
|
|
2709
|
+
return `${fontWeight} ${fontSize}px ${fontFamily}`;
|
|
2710
|
+
};
|
|
2711
|
+
|
|
2712
|
+
const getLetterSpacingString = letterSpacing => {
|
|
2713
|
+
return `${letterSpacing}px`;
|
|
2714
|
+
};
|
|
2715
|
+
|
|
2716
|
+
const createMeasureContext = () => {
|
|
2717
|
+
const canvas = new OffscreenCanvas(0, 0);
|
|
2718
|
+
const ctx = /** @type {OffscreenCanvasRenderingContext2D} */canvas.getContext('2d');
|
|
2719
|
+
if (!ctx) {
|
|
2720
|
+
throw new Error('Failed to get canvas context 2d');
|
|
2721
|
+
}
|
|
2722
|
+
return ctx;
|
|
2723
|
+
};
|
|
2724
|
+
|
|
2725
|
+
const state$6 = {
|
|
2726
|
+
ctx: undefined
|
|
2727
|
+
};
|
|
2728
|
+
const getOrCreate$4 = createCtx => {
|
|
2729
|
+
if (state$6.ctx) {
|
|
2730
|
+
return state$6.ctx;
|
|
2731
|
+
}
|
|
2732
|
+
state$6.ctx = createCtx();
|
|
2733
|
+
return state$6.ctx;
|
|
2734
|
+
};
|
|
2735
|
+
|
|
2736
|
+
const getContext = () => {
|
|
2737
|
+
const ctx = getOrCreate$4(createMeasureContext);
|
|
2738
|
+
return ctx;
|
|
2739
|
+
};
|
|
2740
|
+
|
|
2741
|
+
// TODO for text editor, could dispose measuring canvas after editor has been initialized to free up offscreencanvas space
|
|
2742
|
+
|
|
2743
|
+
const measureTextWidthSlow = (text, fontWeight, fontSize, fontFamily, letterSpacing, isMonoSpaceFont, charWidth) => {
|
|
2744
|
+
string(text);
|
|
2745
|
+
number(fontWeight);
|
|
2746
|
+
number(fontSize);
|
|
2747
|
+
string(fontFamily);
|
|
2748
|
+
boolean(isMonoSpaceFont);
|
|
2749
|
+
number(charWidth);
|
|
2750
|
+
if (typeof letterSpacing !== 'number') {
|
|
2751
|
+
throw new TypeError('letterSpacing must be of type number');
|
|
2752
|
+
}
|
|
2753
|
+
const letterSpacingString = getLetterSpacingString(letterSpacing);
|
|
2754
|
+
const fontString = getFontString(fontWeight, fontSize, fontFamily);
|
|
2755
|
+
const ctx = getContext();
|
|
2756
|
+
ctx.letterSpacing = letterSpacingString;
|
|
2757
|
+
ctx.font = fontString;
|
|
2758
|
+
const metrics = ctx.measureText(text);
|
|
2759
|
+
const {
|
|
2760
|
+
width
|
|
2761
|
+
} = metrics;
|
|
2762
|
+
return width;
|
|
2763
|
+
};
|
|
2764
|
+
|
|
2765
|
+
const measureTextWidth = (text, fontWeight, fontSize, fontFamily, letterSpacing, isMonoSpaceFont, charWidth) => {
|
|
2766
|
+
if (isMonoSpaceFont) {
|
|
2767
|
+
return measureTextWidthFast(text, charWidth);
|
|
2768
|
+
}
|
|
2769
|
+
return measureTextWidthSlow(text, fontWeight, fontSize, fontFamily, letterSpacing, isMonoSpaceFont, charWidth);
|
|
2770
|
+
};
|
|
2771
|
+
|
|
2772
|
+
const getX = (line, column, fontWeight, fontSize, fontFamily, isMonospaceFont, letterSpacing, tabSize, halfCursorWidth, width, averageCharWidth, difference = 0) => {
|
|
2773
|
+
if (!line) {
|
|
2774
|
+
return 0;
|
|
2077
2775
|
}
|
|
2078
2776
|
string(line);
|
|
2079
2777
|
number(tabSize);
|
|
@@ -2210,7 +2908,7 @@ const getSelectionArray = visibleSelections => {
|
|
|
2210
2908
|
}
|
|
2211
2909
|
return selectionsArray;
|
|
2212
2910
|
};
|
|
2213
|
-
const getVisible
|
|
2911
|
+
const getVisible = editor => {
|
|
2214
2912
|
const visibleCursors = [];
|
|
2215
2913
|
const visibleSelections = [];
|
|
2216
2914
|
// // TODO binary search
|
|
@@ -2428,15 +3126,29 @@ const scheduleDocumentAndCursorsSelections = async (editor, changes, selectionCh
|
|
|
2428
3126
|
autoClosingRanges
|
|
2429
3127
|
};
|
|
2430
3128
|
set$6(editor.uid, editor, newEditor);
|
|
3129
|
+
const incrementalEdits = await getIncrementalEdits(editor, newEditor);
|
|
2431
3130
|
const newWidgets = await applyWidgetChanges(newEditor, changes);
|
|
2432
3131
|
const newEditor2 = {
|
|
2433
3132
|
...newEditor,
|
|
2434
|
-
widgets: newWidgets
|
|
3133
|
+
widgets: newWidgets,
|
|
3134
|
+
incrementalEdits
|
|
3135
|
+
};
|
|
3136
|
+
if (incrementalEdits !== emptyIncrementalEdits) {
|
|
3137
|
+
return newEditor2;
|
|
3138
|
+
}
|
|
3139
|
+
const syncIncremental = getEnabled();
|
|
3140
|
+
const {
|
|
3141
|
+
textInfos,
|
|
3142
|
+
differences
|
|
3143
|
+
} = await getVisible$1(newEditor2, syncIncremental);
|
|
3144
|
+
return {
|
|
3145
|
+
...newEditor2,
|
|
3146
|
+
textInfos,
|
|
3147
|
+
differences
|
|
2435
3148
|
};
|
|
2436
|
-
return newEditor2;
|
|
2437
3149
|
};
|
|
2438
3150
|
// @ts-ignore
|
|
2439
|
-
const scheduleDocumentAndCursorsSelectionIsUndo = (editor, changes) => {
|
|
3151
|
+
const scheduleDocumentAndCursorsSelectionIsUndo = async (editor, changes) => {
|
|
2440
3152
|
object(editor);
|
|
2441
3153
|
array(changes);
|
|
2442
3154
|
if (changes.length === 0) {
|
|
@@ -2456,7 +3168,26 @@ const scheduleDocumentAndCursorsSelectionIsUndo = (editor, changes) => {
|
|
|
2456
3168
|
// undoStack: [...editor.undoStack.slice(0, -2)],
|
|
2457
3169
|
invalidStartIndex
|
|
2458
3170
|
};
|
|
2459
|
-
|
|
3171
|
+
const incrementalEdits = await getIncrementalEdits(editor, newEditor);
|
|
3172
|
+
|
|
3173
|
+
// TODO change event should be emitted after rendering
|
|
3174
|
+
const finalEditor = {
|
|
3175
|
+
...newEditor,
|
|
3176
|
+
incrementalEdits
|
|
3177
|
+
};
|
|
3178
|
+
if (incrementalEdits !== emptyIncrementalEdits) {
|
|
3179
|
+
return finalEditor;
|
|
3180
|
+
}
|
|
3181
|
+
const syncIncremental = getEnabled();
|
|
3182
|
+
const {
|
|
3183
|
+
textInfos,
|
|
3184
|
+
differences
|
|
3185
|
+
} = await getVisible$1(finalEditor, syncIncremental);
|
|
3186
|
+
return {
|
|
3187
|
+
...finalEditor,
|
|
3188
|
+
textInfos,
|
|
3189
|
+
differences
|
|
3190
|
+
};
|
|
2460
3191
|
};
|
|
2461
3192
|
|
|
2462
3193
|
// @ts-ignore
|
|
@@ -2481,8 +3212,26 @@ const scheduleDocument = async (editor, changes) => {
|
|
|
2481
3212
|
lines: newLines,
|
|
2482
3213
|
invalidStartIndex
|
|
2483
3214
|
};
|
|
3215
|
+
const incrementalEdits = await getIncrementalEdits(editor, newEditor);
|
|
3216
|
+
|
|
2484
3217
|
// TODO change event should be emitted after rendering
|
|
2485
|
-
|
|
3218
|
+
const finalEditor = {
|
|
3219
|
+
...newEditor,
|
|
3220
|
+
incrementalEdits
|
|
3221
|
+
};
|
|
3222
|
+
if (incrementalEdits !== emptyIncrementalEdits) {
|
|
3223
|
+
return finalEditor;
|
|
3224
|
+
}
|
|
3225
|
+
const syncIncremental = getEnabled();
|
|
3226
|
+
const {
|
|
3227
|
+
textInfos,
|
|
3228
|
+
differences
|
|
3229
|
+
} = await getVisible$1(finalEditor, syncIncremental);
|
|
3230
|
+
return {
|
|
3231
|
+
...finalEditor,
|
|
3232
|
+
textInfos,
|
|
3233
|
+
differences
|
|
3234
|
+
};
|
|
2486
3235
|
// RendererProcess.send([
|
|
2487
3236
|
// /* Viewlet.invoke */ 'Viewlet.send',
|
|
2488
3237
|
// /* id */ 'EditorText',
|
|
@@ -2548,8 +3297,8 @@ const TabCompletionExecuteTabCompletionProvider = 'ExtensionHost.executeTabCompl
|
|
|
2548
3297
|
const TextDocumentSyncFull = 'ExtensionHostTextDocument.syncFull';
|
|
2549
3298
|
|
|
2550
3299
|
const {
|
|
2551
|
-
set: set$
|
|
2552
|
-
invoke: invoke$
|
|
3300
|
+
set: set$1,
|
|
3301
|
+
invoke: invoke$6} = ExtensionHost;
|
|
2553
3302
|
|
|
2554
3303
|
const ColorPicker = 41;
|
|
2555
3304
|
const EditorCompletion = 9;
|
|
@@ -2578,7 +3327,7 @@ const execute = async ({
|
|
|
2578
3327
|
}) => {
|
|
2579
3328
|
const fullEvent = `${event}:${editor.languageId}`;
|
|
2580
3329
|
await activateByEvent(fullEvent);
|
|
2581
|
-
const result = await invoke$
|
|
3330
|
+
const result = await invoke$6(method, editor.uid, ...args);
|
|
2582
3331
|
return result;
|
|
2583
3332
|
};
|
|
2584
3333
|
|
|
@@ -2646,7 +3395,7 @@ const updateDiagnostics = async newState => {
|
|
|
2646
3395
|
// TODO don't really need text document sync response
|
|
2647
3396
|
// could perhaps save a lot of messages by using send instead of invoke
|
|
2648
3397
|
// @ts-ignore
|
|
2649
|
-
await invoke$
|
|
3398
|
+
await invoke$6(TextDocumentSyncFull, newState.uri, newState.id, newState.languageId, content);
|
|
2650
3399
|
const diagnostics = await executeDiagnosticProvider(newState);
|
|
2651
3400
|
const latest = get$4(newState.id);
|
|
2652
3401
|
if (!latest) {
|
|
@@ -2672,6 +3421,8 @@ const updateDiagnostics = async newState => {
|
|
|
2672
3421
|
};
|
|
2673
3422
|
|
|
2674
3423
|
const emptyEditor = {
|
|
3424
|
+
textInfos: [],
|
|
3425
|
+
differences: [],
|
|
2675
3426
|
uri: '',
|
|
2676
3427
|
languageId: '',
|
|
2677
3428
|
// TODO use numeric language id?
|
|
@@ -2695,7 +3446,8 @@ const emptyEditor = {
|
|
|
2695
3446
|
selections: new Uint32Array(),
|
|
2696
3447
|
diagnostics: [],
|
|
2697
3448
|
highlightedLine: -1,
|
|
2698
|
-
debugEnabled: false
|
|
3449
|
+
debugEnabled: false,
|
|
3450
|
+
incrementalEdits: emptyIncrementalEdits
|
|
2699
3451
|
};
|
|
2700
3452
|
const createEditor = async ({
|
|
2701
3453
|
id,
|
|
@@ -2732,6 +3484,7 @@ const createEditor = async ({
|
|
|
2732
3484
|
string(content);
|
|
2733
3485
|
const charWidth = measureCharacterWidth(fontWeight, fontSize, fontFamily, letterSpacing);
|
|
2734
3486
|
const editor = {
|
|
3487
|
+
textInfos: [],
|
|
2735
3488
|
uri,
|
|
2736
3489
|
isAutoClosingBracketsEnabled,
|
|
2737
3490
|
isAutoClosingTagsEnabled,
|
|
@@ -2787,7 +3540,8 @@ const createEditor = async ({
|
|
|
2787
3540
|
id,
|
|
2788
3541
|
widgets: [],
|
|
2789
3542
|
focusKey: Empty,
|
|
2790
|
-
diagnosticsEnabled
|
|
3543
|
+
diagnosticsEnabled,
|
|
3544
|
+
incrementalEdits: emptyIncrementalEdits
|
|
2791
3545
|
};
|
|
2792
3546
|
// TODO avoid creating intermediate editors here
|
|
2793
3547
|
const newEditor1 = setBounds(editor, x, y, width, height, 9);
|
|
@@ -2800,13 +3554,23 @@ const createEditor = async ({
|
|
|
2800
3554
|
} else {
|
|
2801
3555
|
newEditor3 = setDeltaY$2(newEditor2, 0);
|
|
2802
3556
|
}
|
|
3557
|
+
const syncIncremental = getEnabled();
|
|
3558
|
+
const {
|
|
3559
|
+
textInfos,
|
|
3560
|
+
differences
|
|
3561
|
+
} = await getVisible$1(newEditor3, syncIncremental);
|
|
2803
3562
|
const newEditor4 = {
|
|
2804
3563
|
...newEditor3,
|
|
2805
|
-
focused: true
|
|
3564
|
+
focused: true,
|
|
3565
|
+
textInfos,
|
|
3566
|
+
differences
|
|
2806
3567
|
};
|
|
2807
3568
|
set$6(id, emptyEditor, newEditor4);
|
|
3569
|
+
|
|
3570
|
+
// TODO only sync when needed
|
|
3571
|
+
// e.g. it might not always be necessary to send text to extension host worker
|
|
2808
3572
|
// @ts-ignore
|
|
2809
|
-
await invoke$
|
|
3573
|
+
await invoke$6(TextDocumentSyncFull, uri, id, languageId, content);
|
|
2810
3574
|
if (diagnosticsEnabled) {
|
|
2811
3575
|
updateDiagnostics(newEditor4);
|
|
2812
3576
|
}
|
|
@@ -3180,7 +3944,7 @@ const y = (editor, rowIndex) => {
|
|
|
3180
3944
|
return offsetY;
|
|
3181
3945
|
};
|
|
3182
3946
|
|
|
3183
|
-
const state$
|
|
3947
|
+
const state$5 = {
|
|
3184
3948
|
timeout: -1
|
|
3185
3949
|
};
|
|
3186
3950
|
|
|
@@ -3211,7 +3975,7 @@ const editorShowMessage = async (editor, rowIndex, columnIndex, message, isError
|
|
|
3211
3975
|
|
|
3212
3976
|
// TODO use wrapper timing module instead of this
|
|
3213
3977
|
// @ts-ignore
|
|
3214
|
-
state$
|
|
3978
|
+
state$5.timeout = setTimeout(handleTimeout, 3000);
|
|
3215
3979
|
}
|
|
3216
3980
|
return editor;
|
|
3217
3981
|
};
|
|
@@ -3231,8 +3995,8 @@ const showErrorMessage = async (editor, rowIndex, columnIndex, message) => {
|
|
|
3231
3995
|
|
|
3232
3996
|
// @ts-ignore
|
|
3233
3997
|
const editorHideMessage = async editor => {
|
|
3234
|
-
clearTimeout(state$
|
|
3235
|
-
state$
|
|
3998
|
+
clearTimeout(state$5.timeout);
|
|
3999
|
+
state$5.timeout = -1;
|
|
3236
4000
|
// await RendererProcess.invoke(/* Viewlet.send */ 'Viewlet.send', /* id */ editor.uid, /* method */ 'hideOverlayMessage')
|
|
3237
4001
|
return editor;
|
|
3238
4002
|
};
|
|
@@ -3357,7 +4121,7 @@ const getOrCreate$3 = () => {
|
|
|
3357
4121
|
}
|
|
3358
4122
|
return workerPromise$3;
|
|
3359
4123
|
};
|
|
3360
|
-
const invoke$
|
|
4124
|
+
const invoke$5 = async (method, ...params) => {
|
|
3361
4125
|
const worker = await getOrCreate$3();
|
|
3362
4126
|
return await worker.invoke(method, ...params);
|
|
3363
4127
|
};
|
|
@@ -3376,7 +4140,7 @@ const closeRename = async editor => {
|
|
|
3376
4140
|
return editor;
|
|
3377
4141
|
}
|
|
3378
4142
|
const renameWidget = widgets[renameWidgetIndex];
|
|
3379
|
-
await invoke$
|
|
4143
|
+
await invoke$5('Rename.close', renameWidget.newState.uid);
|
|
3380
4144
|
const latest = get$4(uid);
|
|
3381
4145
|
const {
|
|
3382
4146
|
newState
|
|
@@ -3495,12 +4259,12 @@ const openColorPicker = async editor => {
|
|
|
3495
4259
|
return addWidgetToEditor(ColorPicker$1, ColorPicker, editor, create$6, newStateGenerator$6);
|
|
3496
4260
|
};
|
|
3497
4261
|
|
|
3498
|
-
const state$
|
|
4262
|
+
const state$4 = {
|
|
3499
4263
|
isComposing: false,
|
|
3500
4264
|
compositionText: ''
|
|
3501
4265
|
};
|
|
3502
4266
|
const compositionStart = (editor, event) => {
|
|
3503
|
-
state$
|
|
4267
|
+
state$4.isComposing = true;
|
|
3504
4268
|
return editor;
|
|
3505
4269
|
};
|
|
3506
4270
|
const getCompositionChanges = (selections, data) => {
|
|
@@ -3510,7 +4274,7 @@ const getCompositionChanges = (selections, data) => {
|
|
|
3510
4274
|
const selectionStartColumn = selections[i + 1];
|
|
3511
4275
|
const selectionEndRow = selections[i + 2];
|
|
3512
4276
|
const selectionEndColumn = selections[i + 3];
|
|
3513
|
-
const startColumnIndex = selectionStartColumn - state$
|
|
4277
|
+
const startColumnIndex = selectionStartColumn - state$4.compositionText.length;
|
|
3514
4278
|
changes.push({
|
|
3515
4279
|
start: {
|
|
3516
4280
|
rowIndex: selectionStartRow,
|
|
@@ -3521,7 +4285,7 @@ const getCompositionChanges = (selections, data) => {
|
|
|
3521
4285
|
columnIndex: selectionEndColumn
|
|
3522
4286
|
},
|
|
3523
4287
|
inserted: [data],
|
|
3524
|
-
deleted: [state$
|
|
4288
|
+
deleted: [state$4.compositionText],
|
|
3525
4289
|
origin: CompositionUpdate
|
|
3526
4290
|
});
|
|
3527
4291
|
}
|
|
@@ -3532,7 +4296,7 @@ const compositionUpdate = (editor, data) => {
|
|
|
3532
4296
|
selections
|
|
3533
4297
|
} = editor;
|
|
3534
4298
|
const changes = getCompositionChanges(selections, data);
|
|
3535
|
-
state$
|
|
4299
|
+
state$4.compositionText = data;
|
|
3536
4300
|
return scheduleDocumentAndCursorsSelections(editor, changes);
|
|
3537
4301
|
};
|
|
3538
4302
|
const compositionEnd = (editor, data) => {
|
|
@@ -3540,8 +4304,8 @@ const compositionEnd = (editor, data) => {
|
|
|
3540
4304
|
selections
|
|
3541
4305
|
} = editor;
|
|
3542
4306
|
const changes = getCompositionChanges(selections, data);
|
|
3543
|
-
state$
|
|
3544
|
-
state$
|
|
4307
|
+
state$4.isComposing = false;
|
|
4308
|
+
state$4.compositionText = '';
|
|
3545
4309
|
return scheduleDocumentAndCursorsSelections(editor, changes);
|
|
3546
4310
|
};
|
|
3547
4311
|
|
|
@@ -4616,19 +5380,19 @@ const Single = 1;
|
|
|
4616
5380
|
const Double = 2;
|
|
4617
5381
|
const Triple = 3;
|
|
4618
5382
|
|
|
4619
|
-
const state$
|
|
5383
|
+
const state$3 = {
|
|
4620
5384
|
position: {
|
|
4621
5385
|
rowIndex: 0,
|
|
4622
5386
|
columnIndex: 0
|
|
4623
5387
|
}
|
|
4624
5388
|
};
|
|
4625
5389
|
const getPosition$1 = () => {
|
|
4626
|
-
return state$
|
|
5390
|
+
return state$3.position;
|
|
4627
5391
|
};
|
|
4628
5392
|
|
|
4629
5393
|
// @ts-ignore
|
|
4630
5394
|
const setPosition$1 = position => {
|
|
4631
|
-
state$
|
|
5395
|
+
state$3.position = position;
|
|
4632
5396
|
};
|
|
4633
5397
|
|
|
4634
5398
|
// TODO first change cursor position, then run go to definition
|
|
@@ -4762,20 +5526,20 @@ const handleMouseDown = (state, modifier, x, y, detail) => {
|
|
|
4762
5526
|
}
|
|
4763
5527
|
};
|
|
4764
5528
|
|
|
4765
|
-
const state$
|
|
5529
|
+
const state$2 = {
|
|
4766
5530
|
timeout: -1,
|
|
4767
5531
|
x: 0,
|
|
4768
5532
|
y: 0,
|
|
4769
5533
|
editor: undefined
|
|
4770
5534
|
};
|
|
4771
|
-
const get
|
|
4772
|
-
return state$
|
|
5535
|
+
const get = () => {
|
|
5536
|
+
return state$2;
|
|
4773
5537
|
};
|
|
4774
|
-
const set
|
|
4775
|
-
state$
|
|
4776
|
-
state$
|
|
4777
|
-
state$
|
|
4778
|
-
state$
|
|
5538
|
+
const set = (editor, timeout, x, y) => {
|
|
5539
|
+
state$2.editor = editor;
|
|
5540
|
+
state$2.timeout = timeout;
|
|
5541
|
+
state$2.x = x;
|
|
5542
|
+
state$2.y = y;
|
|
4779
5543
|
};
|
|
4780
5544
|
|
|
4781
5545
|
const showHover$1 = async (editor, position) => {
|
|
@@ -4797,7 +5561,7 @@ const onHoverIdle = async () => {
|
|
|
4797
5561
|
x,
|
|
4798
5562
|
y,
|
|
4799
5563
|
editor
|
|
4800
|
-
} = get
|
|
5564
|
+
} = get();
|
|
4801
5565
|
at(editor, x, y);
|
|
4802
5566
|
await showHover$1();
|
|
4803
5567
|
};
|
|
@@ -4808,12 +5572,12 @@ const handleMouseMove = (editor, x, y) => {
|
|
|
4808
5572
|
if (!editor.hoverEnabled) {
|
|
4809
5573
|
return editor;
|
|
4810
5574
|
}
|
|
4811
|
-
const oldState = get
|
|
5575
|
+
const oldState = get();
|
|
4812
5576
|
if (oldState.timeout !== -1) {
|
|
4813
5577
|
clearTimeout(oldState.timeout);
|
|
4814
5578
|
}
|
|
4815
5579
|
const timeout = setTimeout(onHoverIdle, hoverDelay);
|
|
4816
|
-
set
|
|
5580
|
+
set(editor, timeout, x, y);
|
|
4817
5581
|
return editor;
|
|
4818
5582
|
};
|
|
4819
5583
|
|
|
@@ -4920,7 +5684,7 @@ const editorHandleNativeSelectionChange = (editor, range) => {
|
|
|
4920
5684
|
return scheduleSelections(editor, selections);
|
|
4921
5685
|
};
|
|
4922
5686
|
|
|
4923
|
-
const state$
|
|
5687
|
+
const state$1 = {
|
|
4924
5688
|
/**
|
|
4925
5689
|
* @type {any}
|
|
4926
5690
|
*/
|
|
@@ -4934,26 +5698,26 @@ const state$3 = {
|
|
|
4934
5698
|
|
|
4935
5699
|
// @ts-ignore
|
|
4936
5700
|
const setEditor = editor => {
|
|
4937
|
-
state$
|
|
4938
|
-
state$
|
|
5701
|
+
state$1.currentEditor = editor;
|
|
5702
|
+
state$1.hasListener = true;
|
|
4939
5703
|
};
|
|
4940
5704
|
const clearEditor = () => {
|
|
4941
|
-
state$
|
|
4942
|
-
state$
|
|
5705
|
+
state$1.currentEditor = undefined;
|
|
5706
|
+
state$1.hasListener = false;
|
|
4943
5707
|
};
|
|
4944
5708
|
|
|
4945
5709
|
// @ts-ignore
|
|
4946
5710
|
const setPosition = position => {
|
|
4947
|
-
state$
|
|
5711
|
+
state$1.position = position;
|
|
4948
5712
|
};
|
|
4949
5713
|
const getEditor$1 = () => {
|
|
4950
|
-
return state$
|
|
5714
|
+
return state$1.currentEditor;
|
|
4951
5715
|
};
|
|
4952
5716
|
const getPosition = () => {
|
|
4953
|
-
return state$
|
|
5717
|
+
return state$1.position;
|
|
4954
5718
|
};
|
|
4955
5719
|
const hasListener = () => {
|
|
4956
|
-
return state$
|
|
5720
|
+
return state$1.hasListener;
|
|
4957
5721
|
};
|
|
4958
5722
|
|
|
4959
5723
|
// @ts-ignore
|
|
@@ -5136,7 +5900,7 @@ const handleTouchEnd = (editor, touchEvent) => {
|
|
|
5136
5900
|
// }
|
|
5137
5901
|
};
|
|
5138
5902
|
|
|
5139
|
-
const state
|
|
5903
|
+
const state = {
|
|
5140
5904
|
touchOffsetY: 0,
|
|
5141
5905
|
deltaY: 0
|
|
5142
5906
|
};
|
|
@@ -5147,8 +5911,8 @@ const handleTouchStart = (editor, touchEvent) => {
|
|
|
5147
5911
|
return;
|
|
5148
5912
|
}
|
|
5149
5913
|
const firstTouch = touchEvent.touches[0];
|
|
5150
|
-
state
|
|
5151
|
-
state
|
|
5914
|
+
state.touchOffsetY = firstTouch.y;
|
|
5915
|
+
state.deltaY = editor.deltaY;
|
|
5152
5916
|
// const position = EditorPosition.at(editor, firstTouch.x, firstTouch.y)
|
|
5153
5917
|
// EditorMoveSelection.state.position = position
|
|
5154
5918
|
// state.date = Date.now()
|
|
@@ -5188,7 +5952,7 @@ const handleTouchMove = (editor, touchEvent) => {
|
|
|
5188
5952
|
return;
|
|
5189
5953
|
}
|
|
5190
5954
|
const firstTouch = touchEvent.touches[0];
|
|
5191
|
-
const offsetY = state
|
|
5955
|
+
const offsetY = state.deltaY + (state.touchOffsetY - firstTouch.y);
|
|
5192
5956
|
setDeltaYFixedValue(editor, offsetY);
|
|
5193
5957
|
};
|
|
5194
5958
|
|
|
@@ -5624,7 +6388,7 @@ const getOrCreate$2 = () => {
|
|
|
5624
6388
|
}
|
|
5625
6389
|
return workerPromise$2;
|
|
5626
6390
|
};
|
|
5627
|
-
const invoke$
|
|
6391
|
+
const invoke$4 = async (method, ...params) => {
|
|
5628
6392
|
const worker = await getOrCreate$2();
|
|
5629
6393
|
return await worker.invoke(method, ...params);
|
|
5630
6394
|
};
|
|
@@ -5643,10 +6407,10 @@ const newStateGenerator$4 = async (state, parentUid) => {
|
|
|
5643
6407
|
const {
|
|
5644
6408
|
languageId
|
|
5645
6409
|
} = newState;
|
|
5646
|
-
await invoke$
|
|
5647
|
-
await invoke$
|
|
5648
|
-
const diff = await invoke$
|
|
5649
|
-
const commands = await invoke$
|
|
6410
|
+
await invoke$4('Completions.create', uid, x, y, width, height, parentUid, languageId);
|
|
6411
|
+
await invoke$4('Completions.loadContent', uid);
|
|
6412
|
+
const diff = await invoke$4('Completions.diff2', uid);
|
|
6413
|
+
const commands = await invoke$4('Completions.render2', uid, diff);
|
|
5650
6414
|
return {
|
|
5651
6415
|
...state,
|
|
5652
6416
|
commands
|
|
@@ -5698,7 +6462,7 @@ const launch = async () => {
|
|
|
5698
6462
|
const rpc = await launchFindWidgetWorker();
|
|
5699
6463
|
set$c(rpcId, rpc);
|
|
5700
6464
|
};
|
|
5701
|
-
const invoke$
|
|
6465
|
+
const invoke$3 = async (method, ...params) => {
|
|
5702
6466
|
const rpc = get$6(rpcId);
|
|
5703
6467
|
return await rpc.invoke(method, ...params);
|
|
5704
6468
|
};
|
|
@@ -5737,10 +6501,10 @@ const loadContent$1 = async (state, parentUid) => {
|
|
|
5737
6501
|
height
|
|
5738
6502
|
} = editor;
|
|
5739
6503
|
await launch();
|
|
5740
|
-
await invoke$
|
|
5741
|
-
await invoke$
|
|
5742
|
-
const diff = await invoke$
|
|
5743
|
-
const commands = await invoke$
|
|
6504
|
+
await invoke$3('FindWidget.create', uid, x, y, width, height, parentUid);
|
|
6505
|
+
await invoke$3('FindWidget.loadContent', uid);
|
|
6506
|
+
const diff = await invoke$3('FindWidget.diff2', uid);
|
|
6507
|
+
const commands = await invoke$3('FindWidget.render2', uid, diff);
|
|
5744
6508
|
return {
|
|
5745
6509
|
...state,
|
|
5746
6510
|
commands
|
|
@@ -5813,10 +6577,10 @@ const newStateGenerator$2 = async (state, parentUid) => {
|
|
|
5813
6577
|
const {
|
|
5814
6578
|
languageId
|
|
5815
6579
|
} = newState;
|
|
5816
|
-
await invoke$
|
|
5817
|
-
await invoke$
|
|
5818
|
-
const diff = await invoke$
|
|
5819
|
-
const commands = await invoke$
|
|
6580
|
+
await invoke$5('Rename.create', uid, x, y, width, height, parentUid, languageId);
|
|
6581
|
+
await invoke$5('Rename.loadContent', uid);
|
|
6582
|
+
const diff = await invoke$5('Rename.diff2', uid);
|
|
6583
|
+
const commands = await invoke$5('Rename.render2', uid, diff);
|
|
5820
6584
|
return {
|
|
5821
6585
|
...state,
|
|
5822
6586
|
commands
|
|
@@ -6556,155 +7320,45 @@ const setDecorations = (editor, decorations, diagnostics) => {
|
|
|
6556
7320
|
};
|
|
6557
7321
|
};
|
|
6558
7322
|
|
|
6559
|
-
|
|
6560
|
-
|
|
6561
|
-
|
|
6562
|
-
|
|
6563
|
-
|
|
6564
|
-
|
|
6565
|
-
|
|
6566
|
-
|
|
6567
|
-
|
|
6568
|
-
|
|
6569
|
-
|
|
7323
|
+
// TODO add command to set language id
|
|
7324
|
+
// without needing to specify tokenizePath
|
|
7325
|
+
const setLanguageId = async (editor, languageId, tokenizePath) => {
|
|
7326
|
+
const {
|
|
7327
|
+
tokenizerId
|
|
7328
|
+
} = editor;
|
|
7329
|
+
// TODO move tokenizer to syntax highlighting worker
|
|
7330
|
+
// TODO only load tokenizer if not already loaded
|
|
7331
|
+
// if already loaded just set tokenizer and rerender text
|
|
7332
|
+
// TODO race condition
|
|
7333
|
+
await loadTokenizer(languageId, tokenizePath);
|
|
7334
|
+
const tokenizer = getTokenizer(languageId);
|
|
7335
|
+
const newTokenizerId = tokenizerId + 1;
|
|
7336
|
+
set$2(newTokenizerId, tokenizer);
|
|
7337
|
+
const latest = getEditor(editor.uid);
|
|
7338
|
+
if (!latest) {
|
|
7339
|
+
return editor;
|
|
7340
|
+
}
|
|
7341
|
+
const syncIncremental = getEnabled();
|
|
7342
|
+
const {
|
|
7343
|
+
textInfos,
|
|
7344
|
+
differences
|
|
7345
|
+
} = await getVisible$1(editor, syncIncremental);
|
|
7346
|
+
const newEditor4 = {
|
|
7347
|
+
...latest,
|
|
7348
|
+
focused: true,
|
|
7349
|
+
textInfos,
|
|
7350
|
+
differences
|
|
7351
|
+
};
|
|
6570
7352
|
|
|
6571
|
-
|
|
6572
|
-
|
|
6573
|
-
|
|
6574
|
-
const State = {
|
|
6575
|
-
TopLevelContent: 1
|
|
6576
|
-
};
|
|
7353
|
+
// TODO don't update editor if tokenizer was already loaded
|
|
7354
|
+
// TODO update syntax highlighting
|
|
7355
|
+
// TODO get edits
|
|
6577
7356
|
|
|
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
7357
|
return {
|
|
6593
|
-
|
|
6594
|
-
|
|
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
|
-
// TODO add command to set language id
|
|
6682
|
-
// without needing to specify tokenizePath
|
|
6683
|
-
const setLanguageId = async (editor, languageId, tokenizePath) => {
|
|
6684
|
-
const {
|
|
6685
|
-
tokenizerId
|
|
6686
|
-
} = editor;
|
|
6687
|
-
// TODO move tokenizer to syntax highlighting worker
|
|
6688
|
-
// TODO only load tokenizer if not already loaded
|
|
6689
|
-
// if already loaded just set tokenizer and rerender text
|
|
6690
|
-
// TODO race condition
|
|
6691
|
-
await loadTokenizer(languageId, tokenizePath);
|
|
6692
|
-
const tokenizer = getTokenizer(languageId);
|
|
6693
|
-
const newTokenizerId = tokenizerId + 1;
|
|
6694
|
-
set(newTokenizerId, tokenizer);
|
|
6695
|
-
const latest = getEditor(editor.uid);
|
|
6696
|
-
if (!latest) {
|
|
6697
|
-
return editor;
|
|
6698
|
-
}
|
|
6699
|
-
// TODO don't update editor if tokenizer was already loaded
|
|
6700
|
-
// TODO update syntax highlighting
|
|
6701
|
-
// TODO get edits
|
|
6702
|
-
|
|
6703
|
-
return {
|
|
6704
|
-
...latest,
|
|
6705
|
-
languageId,
|
|
6706
|
-
invalidStartIndex: 0,
|
|
6707
|
-
tokenizerId: newTokenizerId
|
|
7358
|
+
...newEditor4,
|
|
7359
|
+
languageId,
|
|
7360
|
+
invalidStartIndex: 0,
|
|
7361
|
+
tokenizerId: newTokenizerId
|
|
6708
7362
|
};
|
|
6709
7363
|
};
|
|
6710
7364
|
|
|
@@ -7746,11 +8400,11 @@ const getWidgetInvoke = widgetId => {
|
|
|
7746
8400
|
case ColorPicker$1:
|
|
7747
8401
|
return invoke$8;
|
|
7748
8402
|
case Completion:
|
|
7749
|
-
return invoke$5;
|
|
7750
|
-
case Find:
|
|
7751
8403
|
return invoke$4;
|
|
8404
|
+
case Find:
|
|
8405
|
+
return invoke$3;
|
|
7752
8406
|
case Rename$1:
|
|
7753
|
-
return invoke$
|
|
8407
|
+
return invoke$5;
|
|
7754
8408
|
case SourceAction$1:
|
|
7755
8409
|
return invoke$1;
|
|
7756
8410
|
case Hover:
|
|
@@ -7953,8 +8607,9 @@ const {
|
|
|
7953
8607
|
toggleReplace,
|
|
7954
8608
|
toggleUseRegularExpression,
|
|
7955
8609
|
focusNextElement,
|
|
7956
|
-
focusPreviousElement
|
|
7957
|
-
|
|
8610
|
+
focusPreviousElement,
|
|
8611
|
+
togglePreserveCase
|
|
8612
|
+
} = createFns(['close', 'focusCloseButton', 'focusFind', 'focusNext', 'focusNextMatchButton', 'focusPrevious', 'focusPreviousMatchButton', 'focusReplace', 'focusReplaceAllButton', 'focusReplaceButton', 'focusToggleReplace', 'handleBlur', 'handleClickButton', 'handleFocus', 'handleInput', 'handleReplaceFocus', 'handleReplaceInput', 'handleToggleReplaceFocus', 'replace', 'replaceAll', 'toggleMatchCase', 'toggleMatchWholeWord', 'toggleReplace', 'toggleUseRegularExpression', 'focusNextElement', 'focusPreviousElement', 'togglePreserveCase'], 'FindWidget', Find);
|
|
7958
8613
|
|
|
7959
8614
|
const EditorFindWidget = {
|
|
7960
8615
|
__proto__: null,
|
|
@@ -7985,6 +8640,7 @@ const EditorFindWidget = {
|
|
|
7985
8640
|
replaceAll,
|
|
7986
8641
|
toggleMatchCase,
|
|
7987
8642
|
toggleMatchWholeWord,
|
|
8643
|
+
togglePreserveCase,
|
|
7988
8644
|
toggleReplace,
|
|
7989
8645
|
toggleUseRegularExpression
|
|
7990
8646
|
};
|
|
@@ -8015,15 +8671,7 @@ const measureTextBlockHeight = async (text, fontFamily, fontSize, lineHeight, wi
|
|
|
8015
8671
|
return 100;
|
|
8016
8672
|
};
|
|
8017
8673
|
|
|
8018
|
-
const
|
|
8019
|
-
return structuredClone(value);
|
|
8020
|
-
};
|
|
8021
|
-
|
|
8022
|
-
const getInitialLineState = initialLineState => {
|
|
8023
|
-
return deepCopy(initialLineState);
|
|
8024
|
-
};
|
|
8025
|
-
|
|
8026
|
-
const getLineInfo$1 = (line, tokens, TokenMap) => {
|
|
8674
|
+
const getLineInfo = (line, tokens, TokenMap) => {
|
|
8027
8675
|
const tokensLength = tokens.length;
|
|
8028
8676
|
let end = 0;
|
|
8029
8677
|
let start = 0;
|
|
@@ -8041,45 +8689,6 @@ const getLineInfo$1 = (line, tokens, TokenMap) => {
|
|
|
8041
8689
|
return lineInfo;
|
|
8042
8690
|
};
|
|
8043
8691
|
|
|
8044
|
-
const state = {
|
|
8045
|
-
warned: []
|
|
8046
|
-
};
|
|
8047
|
-
const flattenTokensArray = tokens => {
|
|
8048
|
-
const flattened = [];
|
|
8049
|
-
for (const token of tokens) {
|
|
8050
|
-
object(token);
|
|
8051
|
-
flattened.push(token.type, token.length);
|
|
8052
|
-
}
|
|
8053
|
-
return flattened;
|
|
8054
|
-
};
|
|
8055
|
-
const warnDeprecatedArrayReturn = (languageId, fn) => {
|
|
8056
|
-
if (state.warned.includes(fn)) {
|
|
8057
|
-
return;
|
|
8058
|
-
}
|
|
8059
|
-
state.warned.push(fn);
|
|
8060
|
-
console.warn(`tokenizers without hasArrayReturn=false are deprecated (language ${languageId})`);
|
|
8061
|
-
};
|
|
8062
|
-
const safeTokenizeLine = (languageId, tokenizeLine, line, lineStateAtStart, hasArrayReturn) => {
|
|
8063
|
-
try {
|
|
8064
|
-
const lineState = tokenizeLine(line, lineStateAtStart);
|
|
8065
|
-
if (!lineState?.tokens || !lineState.state) {
|
|
8066
|
-
throw new Error('invalid tokenization result');
|
|
8067
|
-
}
|
|
8068
|
-
if (!hasArrayReturn) {
|
|
8069
|
-
warnDeprecatedArrayReturn(languageId, tokenizeLine);
|
|
8070
|
-
// workaround for old tokenizers
|
|
8071
|
-
lineState.tokens = flattenTokensArray(lineState.tokens);
|
|
8072
|
-
}
|
|
8073
|
-
return lineState;
|
|
8074
|
-
} catch (error) {
|
|
8075
|
-
console.error(error);
|
|
8076
|
-
return {
|
|
8077
|
-
tokens: [/* type */0, /* length */line.length],
|
|
8078
|
-
lineState: lineStateAtStart
|
|
8079
|
-
};
|
|
8080
|
-
}
|
|
8081
|
-
};
|
|
8082
|
-
|
|
8083
8692
|
const getLineInfos = (lines, tokenizer, languageId) => {
|
|
8084
8693
|
const lineInfos = [];
|
|
8085
8694
|
const {
|
|
@@ -8094,7 +8703,7 @@ const getLineInfos = (lines, tokenizer, languageId) => {
|
|
|
8094
8703
|
const {
|
|
8095
8704
|
tokens
|
|
8096
8705
|
} = result;
|
|
8097
|
-
const lineInfo = getLineInfo
|
|
8706
|
+
const lineInfo = getLineInfo(line, tokens, TokenMap);
|
|
8098
8707
|
lineInfos.push(lineInfo);
|
|
8099
8708
|
currentLineState = result;
|
|
8100
8709
|
}
|
|
@@ -9379,7 +9988,7 @@ const createExtensionHostRpc = async () => {
|
|
|
9379
9988
|
|
|
9380
9989
|
const initializeExtensionHost = async () => {
|
|
9381
9990
|
const extensionHostRpc = await createExtensionHostRpc();
|
|
9382
|
-
set$
|
|
9991
|
+
set$1(extensionHostRpc);
|
|
9383
9992
|
};
|
|
9384
9993
|
|
|
9385
9994
|
const sendMessagePortToSyntaxHighlightingWorker = async () => {
|
|
@@ -9399,586 +10008,92 @@ const sendMessagePortToSyntaxHighlightingWorker = async () => {
|
|
|
9399
10008
|
} = getPortTuple();
|
|
9400
10009
|
await invokeAndTransfer(
|
|
9401
10010
|
// @ts-ignore
|
|
9402
|
-
'SendMessagePortToSyntaxHighlightingWorker.sendMessagePortToSyntaxHighlightingWorker', port1, 'HandleMessagePort.handleMessagePort');
|
|
9403
|
-
return port2;
|
|
9404
|
-
}
|
|
9405
|
-
};
|
|
9406
|
-
|
|
9407
|
-
const createSyntaxHighlightingWorkerRpc = async () => {
|
|
9408
|
-
try {
|
|
9409
|
-
const port = await sendMessagePortToSyntaxHighlightingWorker();
|
|
9410
|
-
const rpc = await PlainMessagePortRpcParent.create({
|
|
9411
|
-
commandMap: {},
|
|
9412
|
-
messagePort: port
|
|
9413
|
-
});
|
|
9414
|
-
return rpc;
|
|
9415
|
-
} catch (error) {
|
|
9416
|
-
throw new VError(error, `Failed to create syntax highlighting worker rpc`);
|
|
9417
|
-
}
|
|
9418
|
-
};
|
|
9419
|
-
|
|
9420
|
-
let enabled = false;
|
|
9421
|
-
const setEnabled = value => {
|
|
9422
|
-
enabled = value;
|
|
9423
|
-
};
|
|
9424
|
-
const getEnabled = () => {
|
|
9425
|
-
return enabled;
|
|
9426
|
-
};
|
|
9427
|
-
|
|
9428
|
-
const initializeSyntaxHighlighting = async (syntaxHighlightingEnabled, syncIncremental) => {
|
|
9429
|
-
if (syntaxHighlightingEnabled) {
|
|
9430
|
-
setEnabled$1(true);
|
|
9431
|
-
const syntaxRpc = await createSyntaxHighlightingWorkerRpc();
|
|
9432
|
-
set$3(syntaxRpc);
|
|
9433
|
-
}
|
|
9434
|
-
if (syncIncremental) {
|
|
9435
|
-
setEnabled(true);
|
|
9436
|
-
}
|
|
9437
|
-
};
|
|
9438
|
-
|
|
9439
|
-
const intialize = async (syntaxHighlightingEnabled, syncIncremental) => {
|
|
9440
|
-
await Promise.all([initializeSyntaxHighlighting(syntaxHighlightingEnabled, syncIncremental), initializeExtensionHost()]);
|
|
9441
|
-
};
|
|
9442
|
-
|
|
9443
|
-
// TODO move cursor
|
|
9444
|
-
// TODO multiple cursors -> vscode removes multiple cursors
|
|
9445
|
-
// TODO with selection -> vscode moves whole selection
|
|
9446
|
-
const moveLineDown = editor => {
|
|
9447
|
-
// const rowIndex = editor.cursor.rowIndex
|
|
9448
|
-
// if (rowIndex === editor.lines.length - 1) {
|
|
9449
|
-
// return
|
|
9450
|
-
// }
|
|
9451
|
-
// const documentEdits = [
|
|
9452
|
-
// {
|
|
9453
|
-
// type: /* splice */ 2,
|
|
9454
|
-
// rowIndex: rowIndex,
|
|
9455
|
-
// count: 2,
|
|
9456
|
-
// newLines: [TextDocument.getLine(editor.textDocument, rowIndex + 1), TextDocument.getLine(editor.textDocument, rowIndex)],
|
|
9457
|
-
// },
|
|
9458
|
-
// ]
|
|
9459
|
-
// // @ts-ignore
|
|
9460
|
-
// const cursorEdits = Editor.moveCursors(editor, (editor, cursor) => {
|
|
9461
|
-
// return {
|
|
9462
|
-
// rowIndex: cursor.rowIndex + 1,
|
|
9463
|
-
// columnIndex: cursor.columnIndex,
|
|
9464
|
-
// }
|
|
9465
|
-
// })
|
|
9466
|
-
// @ts-ignore
|
|
9467
|
-
// Editor.scheduleDocumentAndCursors(editor, documentEdits, cursorEdits)
|
|
9468
|
-
return editor;
|
|
9469
|
-
};
|
|
9470
|
-
|
|
9471
|
-
// TODO handle multiple cursors
|
|
9472
|
-
const moveLineUp = editor => {
|
|
9473
|
-
// const rowIndex = editor.cursor.rowIndex
|
|
9474
|
-
// if (rowIndex === 0) {
|
|
9475
|
-
// return
|
|
9476
|
-
// }
|
|
9477
|
-
// const documentEdits = [
|
|
9478
|
-
// {
|
|
9479
|
-
// type: /* splice */ 2,
|
|
9480
|
-
// rowIndex: rowIndex - 1,
|
|
9481
|
-
// count: 2,
|
|
9482
|
-
// newLines: [TextDocument.getLine(editor.textDocument, rowIndex), TextDocument.getLine(editor.textDocument, rowIndex - 1)],
|
|
9483
|
-
// },
|
|
9484
|
-
// ]
|
|
9485
|
-
// // @ts-ignore
|
|
9486
|
-
// const cursorEdits = Editor.moveCursors(editor, (editor, cursor) => {
|
|
9487
|
-
// return {
|
|
9488
|
-
// // TODO handle bottom 0
|
|
9489
|
-
// rowIndex: cursor.rowIndex - 1,
|
|
9490
|
-
// columnIndex: cursor.columnIndex,
|
|
9491
|
-
// }
|
|
9492
|
-
// })
|
|
9493
|
-
// // @ts-ignore
|
|
9494
|
-
// Editor.scheduleDocumentAndCursors(editor, documentEdits, cursorEdits)
|
|
9495
|
-
return editor;
|
|
9496
|
-
};
|
|
9497
|
-
|
|
9498
|
-
const Link$1 = 'Link';
|
|
9499
|
-
const Function = 'Function';
|
|
9500
|
-
const Parameter = 'Parameter';
|
|
9501
|
-
const Type = 'Type';
|
|
9502
|
-
const VariableName = 'VariableName';
|
|
9503
|
-
const Class = 'Class';
|
|
9504
|
-
|
|
9505
|
-
const Link = 1;
|
|
9506
|
-
const Ts2816 = 2816;
|
|
9507
|
-
const Ts2817 = 2817;
|
|
9508
|
-
const Ts2824 = 2824;
|
|
9509
|
-
const Ts2825 = 2825;
|
|
9510
|
-
const Ts2856 = 2956;
|
|
9511
|
-
const Ts2857 = 2857;
|
|
9512
|
-
const Ts3072 = 3072;
|
|
9513
|
-
const Ts3073 = 3073;
|
|
9514
|
-
const Ts3077 = 3077;
|
|
9515
|
-
const Ts3088 = 3088;
|
|
9516
|
-
const Ts1792 = 1792;
|
|
9517
|
-
const Ts1793 = 1793;
|
|
9518
|
-
const Ts512 = 512;
|
|
9519
|
-
const Ts513 = 513;
|
|
9520
|
-
const Ts769 = 769;
|
|
9521
|
-
const Ts1024 = 1024;
|
|
9522
|
-
const Ts1536 = 1536;
|
|
9523
|
-
const Ts1537 = 1537;
|
|
9524
|
-
const Ts1544 = 1544;
|
|
9525
|
-
const Ts1545 = 1545;
|
|
9526
|
-
const Ts2048 = 2048;
|
|
9527
|
-
const Ts2049 = 2049;
|
|
9528
|
-
const Ts2056 = 2056;
|
|
9529
|
-
const Ts2057 = 2057;
|
|
9530
|
-
const Ts2064 = 2064;
|
|
9531
|
-
const Ts2080 = 2080;
|
|
9532
|
-
const Ts2081 = 2081;
|
|
9533
|
-
const Ts2088 = 2088;
|
|
9534
|
-
const Ts2089 = 2089;
|
|
9535
|
-
const Ts2313 = 2313;
|
|
9536
|
-
const Ts2560 = 2560;
|
|
9537
|
-
const Ts2561 = 2561;
|
|
9538
|
-
const Ts2569 = 2569;
|
|
9539
|
-
const Ts2584 = 2584;
|
|
9540
|
-
const Ts256 = 256;
|
|
9541
|
-
const Ts257 = 257;
|
|
9542
|
-
const Ts272 = 272;
|
|
9543
|
-
|
|
9544
|
-
const getDecorationClassName = type => {
|
|
9545
|
-
switch (type) {
|
|
9546
|
-
case Link:
|
|
9547
|
-
return Link$1;
|
|
9548
|
-
case Ts2816:
|
|
9549
|
-
case Ts2817:
|
|
9550
|
-
case Ts2824:
|
|
9551
|
-
case Ts2825:
|
|
9552
|
-
case Ts2856:
|
|
9553
|
-
case Ts2857:
|
|
9554
|
-
case Ts3072:
|
|
9555
|
-
case Ts3073:
|
|
9556
|
-
case Ts3077:
|
|
9557
|
-
case Ts3088:
|
|
9558
|
-
return Function;
|
|
9559
|
-
case Ts1792:
|
|
9560
|
-
case Ts1793:
|
|
9561
|
-
return Parameter;
|
|
9562
|
-
case Ts512:
|
|
9563
|
-
case Ts513:
|
|
9564
|
-
case Ts769:
|
|
9565
|
-
case Ts1024:
|
|
9566
|
-
case Ts1536:
|
|
9567
|
-
case Ts1537:
|
|
9568
|
-
case Ts1544:
|
|
9569
|
-
case Ts1545:
|
|
9570
|
-
return Type;
|
|
9571
|
-
case Ts2048:
|
|
9572
|
-
case Ts2049:
|
|
9573
|
-
case Ts2056:
|
|
9574
|
-
case Ts2057:
|
|
9575
|
-
case Ts2064:
|
|
9576
|
-
case Ts2080:
|
|
9577
|
-
case Ts2081:
|
|
9578
|
-
case Ts2088:
|
|
9579
|
-
case Ts2089:
|
|
9580
|
-
case Ts2313:
|
|
9581
|
-
case Ts2560:
|
|
9582
|
-
case Ts2561:
|
|
9583
|
-
case Ts2569:
|
|
9584
|
-
case Ts2584:
|
|
9585
|
-
return VariableName;
|
|
9586
|
-
case Ts256:
|
|
9587
|
-
case Ts257:
|
|
9588
|
-
case Ts272:
|
|
9589
|
-
return Class;
|
|
9590
|
-
default:
|
|
9591
|
-
return `Unknown-${type}`;
|
|
9592
|
-
}
|
|
9593
|
-
};
|
|
9594
|
-
|
|
9595
|
-
const getTokensViewportEmbedded = (langageId, lines, lineCache, linesWithEmbed) => {
|
|
9596
|
-
const tokenizersToLoad = [];
|
|
9597
|
-
const embeddedResults = [];
|
|
9598
|
-
let topContext;
|
|
9599
|
-
for (const index of linesWithEmbed) {
|
|
9600
|
-
const result = lineCache[index + 1];
|
|
9601
|
-
const line = lines[index];
|
|
9602
|
-
if (result.embeddedLanguage) {
|
|
9603
|
-
const {
|
|
9604
|
-
embeddedLanguage,
|
|
9605
|
-
embeddedLanguageStart,
|
|
9606
|
-
embeddedLanguageEnd
|
|
9607
|
-
} = result;
|
|
9608
|
-
const embeddedTokenizer = getTokenizer(embeddedLanguage);
|
|
9609
|
-
if (embeddedLanguageStart !== line.length && embeddedTokenizer && embeddedTokenizer !== TokenizePlainText) {
|
|
9610
|
-
const isFull = embeddedLanguageStart === 0 && embeddedLanguageEnd === line.length;
|
|
9611
|
-
const partialLine = line.slice(embeddedLanguageStart, embeddedLanguageEnd);
|
|
9612
|
-
const embedResult = safeTokenizeLine(langageId, embeddedTokenizer.tokenizeLine, partialLine, topContext || getInitialLineState(embeddedTokenizer.initialLineState), embeddedTokenizer.hasArrayReturn);
|
|
9613
|
-
topContext = embedResult;
|
|
9614
|
-
result.embeddedResultIndex = embeddedResults.length;
|
|
9615
|
-
embeddedResults.push({
|
|
9616
|
-
result: embedResult,
|
|
9617
|
-
TokenMap: embeddedTokenizer.TokenMap,
|
|
9618
|
-
isFull
|
|
9619
|
-
});
|
|
9620
|
-
} else if (line.length === 0) {
|
|
9621
|
-
const embedResult = {
|
|
9622
|
-
tokens: []
|
|
9623
|
-
};
|
|
9624
|
-
result.embeddedResultIndex = embeddedResults.length;
|
|
9625
|
-
embeddedResults.push({
|
|
9626
|
-
result: embedResult,
|
|
9627
|
-
isFull: true,
|
|
9628
|
-
TokenMap: []
|
|
9629
|
-
});
|
|
9630
|
-
} else {
|
|
9631
|
-
tokenizersToLoad.push(embeddedLanguage);
|
|
9632
|
-
embeddedResults.push({
|
|
9633
|
-
result: {},
|
|
9634
|
-
isFull: false,
|
|
9635
|
-
TokenMap: []
|
|
9636
|
-
});
|
|
9637
|
-
topContext = undefined;
|
|
9638
|
-
}
|
|
9639
|
-
} else {
|
|
9640
|
-
topContext = undefined;
|
|
9641
|
-
}
|
|
9642
|
-
}
|
|
9643
|
-
return {
|
|
9644
|
-
tokenizersToLoad,
|
|
9645
|
-
embeddedResults
|
|
9646
|
-
};
|
|
9647
|
-
};
|
|
9648
|
-
const getTokenizeEndIndex = (invalidStartIndex, endLineIndex, tokenizeStartIndex) => {
|
|
9649
|
-
return invalidStartIndex < endLineIndex ? endLineIndex : tokenizeStartIndex;
|
|
9650
|
-
};
|
|
9651
|
-
|
|
9652
|
-
// TODO only send changed lines to renderer process instead of all lines in viewport
|
|
9653
|
-
const getTokensViewport = (editor, startLineIndex, endLineIndex) => {
|
|
9654
|
-
const {
|
|
9655
|
-
invalidStartIndex,
|
|
9656
|
-
lineCache,
|
|
9657
|
-
tokenizerId,
|
|
9658
|
-
lines,
|
|
9659
|
-
languageId
|
|
9660
|
-
} = editor;
|
|
9661
|
-
const tokenizer = get(tokenizerId);
|
|
9662
|
-
const {
|
|
9663
|
-
hasArrayReturn,
|
|
9664
|
-
tokenizeLine,
|
|
9665
|
-
initialLineState
|
|
9666
|
-
} = tokenizer;
|
|
9667
|
-
const tokenizeStartIndex = invalidStartIndex;
|
|
9668
|
-
const tokenizeEndIndex = getTokenizeEndIndex(invalidStartIndex, endLineIndex, tokenizeStartIndex);
|
|
9669
|
-
const tokenizersToLoad = [];
|
|
9670
|
-
const embeddedResults = [];
|
|
9671
|
-
const linesWithEmbed = [];
|
|
9672
|
-
for (let i = tokenizeStartIndex; i < tokenizeEndIndex; i++) {
|
|
9673
|
-
const lineState = i === 0 ? getInitialLineState(initialLineState) : lineCache[i];
|
|
9674
|
-
const line = lines[i];
|
|
9675
|
-
const result = safeTokenizeLine(languageId, tokenizeLine, line, lineState, hasArrayReturn);
|
|
9676
|
-
// TODO if lineCacheEnd matches the one before, skip tokenizing lines after
|
|
9677
|
-
lineCache[i + 1] = result;
|
|
9678
|
-
if (result.embeddedLanguage) {
|
|
9679
|
-
result.embeddedResultIndex = linesWithEmbed.length;
|
|
9680
|
-
linesWithEmbed.push(i);
|
|
9681
|
-
}
|
|
9682
|
-
}
|
|
9683
|
-
const visibleLines = lineCache.slice(startLineIndex + 1, endLineIndex + 1);
|
|
9684
|
-
if (linesWithEmbed.length > 0) {
|
|
9685
|
-
const {
|
|
9686
|
-
tokenizersToLoad,
|
|
9687
|
-
embeddedResults
|
|
9688
|
-
} = getTokensViewportEmbedded(languageId, lines, lineCache, linesWithEmbed);
|
|
9689
|
-
// TODO support lineCache with embedded content
|
|
9690
|
-
editor.invalidStartIndex = 0;
|
|
9691
|
-
return {
|
|
9692
|
-
tokens: visibleLines,
|
|
9693
|
-
tokenizersToLoad,
|
|
9694
|
-
embeddedResults
|
|
9695
|
-
};
|
|
9696
|
-
}
|
|
9697
|
-
editor.invalidStartIndex = Math.max(invalidStartIndex, tokenizeEndIndex);
|
|
9698
|
-
return {
|
|
9699
|
-
tokens: visibleLines,
|
|
9700
|
-
tokenizersToLoad,
|
|
9701
|
-
embeddedResults
|
|
9702
|
-
};
|
|
9703
|
-
};
|
|
9704
|
-
|
|
9705
|
-
const sentLines = Object.create(null);
|
|
9706
|
-
|
|
9707
|
-
// TODO only send changed lines to renderer process instead of all lines in viewport
|
|
9708
|
-
const getTokensViewport2 = async (editor, startLineIndex, endLineIndex, syncIncremental) => {
|
|
9709
|
-
if (getEnabled$1()) {
|
|
9710
|
-
if (syncIncremental) {
|
|
9711
|
-
const {
|
|
9712
|
-
invalidStartIndex,
|
|
9713
|
-
lines,
|
|
9714
|
-
languageId,
|
|
9715
|
-
id
|
|
9716
|
-
} = editor;
|
|
9717
|
-
let hasLinesToSend = true;
|
|
9718
|
-
let linesToSend = lines;
|
|
9719
|
-
if (sentLines[id] === lines) {
|
|
9720
|
-
hasLinesToSend = false;
|
|
9721
|
-
linesToSend = [];
|
|
9722
|
-
} else {
|
|
9723
|
-
sentLines[id] = lines;
|
|
9724
|
-
}
|
|
9725
|
-
const slimEditor = {
|
|
9726
|
-
languageId,
|
|
9727
|
-
invalidStartIndex
|
|
9728
|
-
};
|
|
9729
|
-
return invoke$3('GetTokensViewport.getTokensViewport', slimEditor,
|
|
9730
|
-
// @ts-ignore
|
|
9731
|
-
startLineIndex, endLineIndex, hasLinesToSend, id, linesToSend);
|
|
9732
|
-
}
|
|
9733
|
-
// TODO only send needed lines of text
|
|
9734
|
-
// @ts-ignore
|
|
9735
|
-
return invoke$3('GetTokensViewport.getTokensViewport', editor, startLineIndex, endLineIndex, true, editor.id, editor.lines);
|
|
9736
|
-
}
|
|
9737
|
-
return getTokensViewport(editor, startLineIndex, endLineIndex);
|
|
9738
|
-
};
|
|
9739
|
-
|
|
9740
|
-
const loadTokenizers = async languageIds => {
|
|
9741
|
-
for (const languageId of languageIds) {
|
|
9742
|
-
// @ts-ignore
|
|
9743
|
-
await loadTokenizer(languageId);
|
|
9744
|
-
}
|
|
9745
|
-
};
|
|
9746
|
-
|
|
9747
|
-
// const getTokensIncremental = (editor, min, max) => {
|
|
9748
|
-
// const currentLength = editor.lineStateCache.length
|
|
9749
|
-
// const tokens = []
|
|
9750
|
-
// const lines = editor.lines
|
|
9751
|
-
// let lineState = editor.tokenizer.initialLineState
|
|
9752
|
-
// for (let i = currentLength; i < max; i++) {
|
|
9753
|
-
// const line = lines[i]
|
|
9754
|
-
// try {
|
|
9755
|
-
// lineState = editor.tokenizer.tokenizeLine(line, lineState)
|
|
9756
|
-
// if (!lineState || !lineState.tokens || !lineState.state) {
|
|
9757
|
-
// throw new Error('invalid tokenization result')
|
|
9758
|
-
// }
|
|
9759
|
-
// } catch (error) {
|
|
9760
|
-
// tokens.push([{ length: line.length, type: 0 }])
|
|
9761
|
-
// console.error(error)
|
|
9762
|
-
// // renderWithoutSyntaxHighlighting(state, firstRow, lastRow)
|
|
9763
|
-
// continue
|
|
9764
|
-
// }
|
|
9765
|
-
// const newTokens = lineState.tokens
|
|
9766
|
-
// tokens.push(newTokens)
|
|
9767
|
-
// }
|
|
9768
|
-
// return tokens
|
|
9769
|
-
// }
|
|
9770
|
-
|
|
9771
|
-
// const getLineInfosIncremental = (editor, tokens, minLineY, maxLineY) => {
|
|
9772
|
-
// const result = []
|
|
9773
|
-
// const lines = editor.lines
|
|
9774
|
-
// const TokenMap = editor.tokenizer.TokenMap
|
|
9775
|
-
// for (let i = minLineY; i < maxLineY; i++) {
|
|
9776
|
-
// result.push(getLineInfo(lines[i], tokens[i], TokenMap))
|
|
9777
|
-
// }
|
|
9778
|
-
// return result
|
|
9779
|
-
// }
|
|
9780
|
-
|
|
9781
|
-
const getStartDefaults = (tokens, minOffset) => {
|
|
9782
|
-
let start = 0;
|
|
9783
|
-
let end = 0;
|
|
9784
|
-
let startIndex = 0;
|
|
9785
|
-
const tokensLength = tokens.length;
|
|
9786
|
-
for (let i = 0; i < tokensLength; i += 2) {
|
|
9787
|
-
const tokenLength = tokens[i + 1];
|
|
9788
|
-
end += tokenLength;
|
|
9789
|
-
start = end;
|
|
9790
|
-
if (start >= minOffset) {
|
|
9791
|
-
start -= tokenLength;
|
|
9792
|
-
end -= tokenLength;
|
|
9793
|
-
startIndex = i;
|
|
9794
|
-
break;
|
|
9795
|
-
}
|
|
9796
|
-
}
|
|
9797
|
-
return {
|
|
9798
|
-
start,
|
|
9799
|
-
end,
|
|
9800
|
-
startIndex
|
|
9801
|
-
};
|
|
9802
|
-
};
|
|
9803
|
-
const getLineInfoEmbeddedFull = (embeddedResults, tokenResults, line, normalize, tabSize, width, deltaX, averageCharWidth, minOffset, maxOffset) => {
|
|
9804
|
-
const lineInfo = [];
|
|
9805
|
-
const embeddedResult = embeddedResults[tokenResults.embeddedResultIndex];
|
|
9806
|
-
const embeddedTokens = embeddedResult.result.tokens;
|
|
9807
|
-
const embeddedTokenMap = embeddedResult.TokenMap;
|
|
9808
|
-
const tokensLength = embeddedTokens.length;
|
|
9809
|
-
let {
|
|
9810
|
-
startIndex,
|
|
9811
|
-
start,
|
|
9812
|
-
end
|
|
9813
|
-
} = getStartDefaults(embeddedTokens, minOffset);
|
|
9814
|
-
const difference = getDifference(start, averageCharWidth, deltaX);
|
|
9815
|
-
for (let i = startIndex; i < tokensLength; i += 2) {
|
|
9816
|
-
const tokenType = embeddedTokens[i];
|
|
9817
|
-
const tokenLength = embeddedTokens[i + 1];
|
|
9818
|
-
end += tokenLength;
|
|
9819
|
-
const className = `Token ${embeddedTokenMap[tokenType] || 'Unknown'}`;
|
|
9820
|
-
const text = line.slice(start, end);
|
|
9821
|
-
const normalizedText = normalizeText(text, normalize, tabSize);
|
|
9822
|
-
lineInfo.push(normalizedText, className);
|
|
9823
|
-
start = end;
|
|
9824
|
-
if (end >= maxOffset) {
|
|
9825
|
-
break;
|
|
9826
|
-
}
|
|
10011
|
+
'SendMessagePortToSyntaxHighlightingWorker.sendMessagePortToSyntaxHighlightingWorker', port1, 'HandleMessagePort.handleMessagePort');
|
|
10012
|
+
return port2;
|
|
9827
10013
|
}
|
|
9828
|
-
return {
|
|
9829
|
-
lineInfo,
|
|
9830
|
-
difference
|
|
9831
|
-
};
|
|
9832
10014
|
};
|
|
9833
|
-
|
|
9834
|
-
|
|
9835
|
-
|
|
9836
|
-
|
|
9837
|
-
|
|
9838
|
-
|
|
9839
|
-
|
|
9840
|
-
};
|
|
10015
|
+
|
|
10016
|
+
const createSyntaxHighlightingWorkerRpc = async () => {
|
|
10017
|
+
try {
|
|
10018
|
+
const port = await sendMessagePortToSyntaxHighlightingWorker();
|
|
10019
|
+
const rpc = await PlainMessagePortRpcParent.create({
|
|
10020
|
+
commandMap: {},
|
|
10021
|
+
messagePort: port
|
|
10022
|
+
});
|
|
10023
|
+
return rpc;
|
|
10024
|
+
} catch (error) {
|
|
10025
|
+
throw new VError(error, `Failed to create syntax highlighting worker rpc`);
|
|
9841
10026
|
}
|
|
9842
|
-
const minOffset = Math.ceil(deltaX / averageCharWidth);
|
|
9843
|
-
const maxOffset = minOffset + Math.ceil(width / averageCharWidth);
|
|
9844
|
-
return {
|
|
9845
|
-
minOffset,
|
|
9846
|
-
maxOffset
|
|
9847
|
-
};
|
|
9848
|
-
};
|
|
9849
|
-
const getDifference = (start, averageCharWidth, deltaX) => {
|
|
9850
|
-
const beforeWidth = start * averageCharWidth;
|
|
9851
|
-
const difference = beforeWidth - deltaX;
|
|
9852
|
-
return difference;
|
|
9853
10027
|
};
|
|
9854
|
-
|
|
9855
|
-
|
|
9856
|
-
|
|
9857
|
-
|
|
9858
|
-
const
|
|
9859
|
-
|
|
9860
|
-
break;
|
|
9861
|
-
}
|
|
9862
|
-
}
|
|
9863
|
-
const {
|
|
9864
|
-
tokens
|
|
9865
|
-
} = tokenResults;
|
|
9866
|
-
let {
|
|
9867
|
-
startIndex,
|
|
9868
|
-
start,
|
|
9869
|
-
end
|
|
9870
|
-
} = getStartDefaults(tokens, minOffset);
|
|
9871
|
-
const difference = getDifference(start, averageCharWidth, deltaX);
|
|
9872
|
-
const tokensLength = tokens.length;
|
|
9873
|
-
for (let i = startIndex; i < tokensLength; i += 2) {
|
|
9874
|
-
const tokenType = tokens[i];
|
|
9875
|
-
const tokenLength = tokens[i + 1];
|
|
9876
|
-
const decorationOffset = decorations[decorationIndex];
|
|
9877
|
-
let extraClassName = '';
|
|
9878
|
-
if (decorationOffset !== undefined && decorationOffset - lineOffset === start) {
|
|
9879
|
-
// @ts-ignore
|
|
9880
|
-
decorations[++decorationIndex];
|
|
9881
|
-
const decorationType = decorations[++decorationIndex];
|
|
9882
|
-
// @ts-ignore
|
|
9883
|
-
decorations[++decorationIndex];
|
|
9884
|
-
// decorationIndex,
|
|
9885
|
-
// decorationLength,
|
|
9886
|
-
// decorationType,
|
|
9887
|
-
// decorationModifiers,
|
|
9888
|
-
// })
|
|
9889
|
-
extraClassName = getDecorationClassName(decorationType);
|
|
9890
|
-
}
|
|
9891
|
-
end += tokenLength;
|
|
9892
|
-
const text = line.slice(start, end);
|
|
9893
|
-
const className = `Token ${extraClassName || TokenMap[tokenType] || 'Unknown'}`;
|
|
9894
|
-
const normalizedText = normalizeText(text, normalize, tabSize);
|
|
9895
|
-
lineInfo.push(normalizedText, className);
|
|
9896
|
-
start = end;
|
|
9897
|
-
if (end >= maxOffset) {
|
|
9898
|
-
break;
|
|
9899
|
-
}
|
|
10028
|
+
|
|
10029
|
+
const initializeSyntaxHighlighting = async (syntaxHighlightingEnabled, syncIncremental) => {
|
|
10030
|
+
if (syntaxHighlightingEnabled) {
|
|
10031
|
+
setEnabled$1(true);
|
|
10032
|
+
const syntaxRpc = await createSyntaxHighlightingWorkerRpc();
|
|
10033
|
+
set$5(syntaxRpc);
|
|
9900
10034
|
}
|
|
9901
|
-
|
|
9902
|
-
|
|
9903
|
-
difference
|
|
9904
|
-
};
|
|
9905
|
-
};
|
|
9906
|
-
const getLineInfo = (line, tokenResults, embeddedResults, decorations, TokenMap, lineOffset, normalize, tabSize, width, deltaX, averageCharWidth) => {
|
|
9907
|
-
const {
|
|
9908
|
-
minOffset,
|
|
9909
|
-
maxOffset
|
|
9910
|
-
} = getOffsets(deltaX, width, averageCharWidth);
|
|
9911
|
-
if (embeddedResults.length > 0 && tokenResults.embeddedResultIndex !== undefined) {
|
|
9912
|
-
const embeddedResult = embeddedResults[tokenResults.embeddedResultIndex];
|
|
9913
|
-
if (embeddedResult?.isFull) {
|
|
9914
|
-
return getLineInfoEmbeddedFull(embeddedResults, tokenResults, line, normalize, tabSize, width, deltaX, averageCharWidth, minOffset, maxOffset);
|
|
9915
|
-
}
|
|
10035
|
+
if (syncIncremental) {
|
|
10036
|
+
setEnabled(true);
|
|
9916
10037
|
}
|
|
9917
|
-
return getLineInfoDefault(line, tokenResults, embeddedResults, decorations, TokenMap, lineOffset, normalize, tabSize, width, deltaX, averageCharWidth, minOffset, maxOffset);
|
|
9918
10038
|
};
|
|
9919
10039
|
|
|
9920
|
-
|
|
9921
|
-
|
|
9922
|
-
const result = [];
|
|
9923
|
-
const differences = [];
|
|
9924
|
-
const {
|
|
9925
|
-
lines,
|
|
9926
|
-
decorations,
|
|
9927
|
-
languageId
|
|
9928
|
-
} = editor;
|
|
9929
|
-
const tokenMap = get$1(languageId);
|
|
9930
|
-
let offset = minLineOffset;
|
|
9931
|
-
const tabSize = 2;
|
|
9932
|
-
for (let i = minLineY; i < maxLineY; i++) {
|
|
9933
|
-
const line = lines[i];
|
|
9934
|
-
const normalize = shouldNormalizeText(line);
|
|
9935
|
-
const {
|
|
9936
|
-
lineInfo,
|
|
9937
|
-
difference
|
|
9938
|
-
} = getLineInfo(line, tokens[i - minLineY], embeddedResults, decorations, tokenMap, offset, normalize, tabSize, width, deltaX, averageCharWidth);
|
|
9939
|
-
result.push(lineInfo);
|
|
9940
|
-
differences.push(difference);
|
|
9941
|
-
offset += line.length + 1;
|
|
9942
|
-
}
|
|
9943
|
-
return {
|
|
9944
|
-
result,
|
|
9945
|
-
differences
|
|
9946
|
-
};
|
|
10040
|
+
const intialize = async (syntaxHighlightingEnabled, syncIncremental) => {
|
|
10041
|
+
await Promise.all([initializeSyntaxHighlighting(syntaxHighlightingEnabled, syncIncremental), initializeExtensionHost()]);
|
|
9947
10042
|
};
|
|
9948
|
-
|
|
9949
|
-
|
|
9950
|
-
|
|
9951
|
-
|
|
9952
|
-
|
|
9953
|
-
//
|
|
9954
|
-
|
|
9955
|
-
|
|
9956
|
-
|
|
9957
|
-
|
|
9958
|
-
|
|
9959
|
-
|
|
9960
|
-
|
|
9961
|
-
|
|
9962
|
-
|
|
10043
|
+
|
|
10044
|
+
// TODO move cursor
|
|
10045
|
+
// TODO multiple cursors -> vscode removes multiple cursors
|
|
10046
|
+
// TODO with selection -> vscode moves whole selection
|
|
10047
|
+
const moveLineDown = editor => {
|
|
10048
|
+
// const rowIndex = editor.cursor.rowIndex
|
|
10049
|
+
// if (rowIndex === editor.lines.length - 1) {
|
|
10050
|
+
// return
|
|
10051
|
+
// }
|
|
10052
|
+
// const documentEdits = [
|
|
10053
|
+
// {
|
|
10054
|
+
// type: /* splice */ 2,
|
|
10055
|
+
// rowIndex: rowIndex,
|
|
10056
|
+
// count: 2,
|
|
10057
|
+
// newLines: [TextDocument.getLine(editor.textDocument, rowIndex + 1), TextDocument.getLine(editor.textDocument, rowIndex)],
|
|
10058
|
+
// },
|
|
10059
|
+
// ]
|
|
10060
|
+
// // @ts-ignore
|
|
10061
|
+
// const cursorEdits = Editor.moveCursors(editor, (editor, cursor) => {
|
|
10062
|
+
// return {
|
|
10063
|
+
// rowIndex: cursor.rowIndex + 1,
|
|
10064
|
+
// columnIndex: cursor.columnIndex,
|
|
10065
|
+
// }
|
|
10066
|
+
// })
|
|
9963
10067
|
// @ts-ignore
|
|
9964
|
-
|
|
9965
|
-
|
|
9966
|
-
|
|
9967
|
-
|
|
9968
|
-
|
|
9969
|
-
|
|
9970
|
-
const
|
|
9971
|
-
|
|
9972
|
-
|
|
9973
|
-
|
|
9974
|
-
|
|
9975
|
-
|
|
9976
|
-
|
|
9977
|
-
|
|
9978
|
-
|
|
9979
|
-
|
|
9980
|
-
|
|
9981
|
-
|
|
10068
|
+
// Editor.scheduleDocumentAndCursors(editor, documentEdits, cursorEdits)
|
|
10069
|
+
return editor;
|
|
10070
|
+
};
|
|
10071
|
+
|
|
10072
|
+
// TODO handle multiple cursors
|
|
10073
|
+
const moveLineUp = editor => {
|
|
10074
|
+
// const rowIndex = editor.cursor.rowIndex
|
|
10075
|
+
// if (rowIndex === 0) {
|
|
10076
|
+
// return
|
|
10077
|
+
// }
|
|
10078
|
+
// const documentEdits = [
|
|
10079
|
+
// {
|
|
10080
|
+
// type: /* splice */ 2,
|
|
10081
|
+
// rowIndex: rowIndex - 1,
|
|
10082
|
+
// count: 2,
|
|
10083
|
+
// newLines: [TextDocument.getLine(editor.textDocument, rowIndex), TextDocument.getLine(editor.textDocument, rowIndex - 1)],
|
|
10084
|
+
// },
|
|
10085
|
+
// ]
|
|
10086
|
+
// // @ts-ignore
|
|
10087
|
+
// const cursorEdits = Editor.moveCursors(editor, (editor, cursor) => {
|
|
10088
|
+
// return {
|
|
10089
|
+
// // TODO handle bottom 0
|
|
10090
|
+
// rowIndex: cursor.rowIndex - 1,
|
|
10091
|
+
// columnIndex: cursor.columnIndex,
|
|
10092
|
+
// }
|
|
10093
|
+
// })
|
|
10094
|
+
// // @ts-ignore
|
|
10095
|
+
// Editor.scheduleDocumentAndCursors(editor, documentEdits, cursorEdits)
|
|
10096
|
+
return editor;
|
|
9982
10097
|
};
|
|
9983
10098
|
|
|
9984
10099
|
const getCursorsVirtualDom = cursors => {
|
|
@@ -10077,36 +10192,6 @@ const getEditorRowsVirtualDom = (textInfos, differences, lineNumbers = true, hig
|
|
|
10077
10192
|
return dom;
|
|
10078
10193
|
};
|
|
10079
10194
|
|
|
10080
|
-
const getIncrementalEdits = async (oldState, newState) => {
|
|
10081
|
-
if (!newState.undoStack) {
|
|
10082
|
-
return undefined;
|
|
10083
|
-
}
|
|
10084
|
-
const lastChanges = newState.undoStack.at(-1);
|
|
10085
|
-
if (lastChanges && lastChanges.length === 1) {
|
|
10086
|
-
const lastChange = lastChanges[0];
|
|
10087
|
-
if (lastChange.origin === EditorType) {
|
|
10088
|
-
const {
|
|
10089
|
-
rowIndex
|
|
10090
|
-
} = lastChange.start;
|
|
10091
|
-
const {
|
|
10092
|
-
lines
|
|
10093
|
-
} = newState;
|
|
10094
|
-
const oldLine = oldState.lines[rowIndex];
|
|
10095
|
-
const newLine = lines[rowIndex];
|
|
10096
|
-
// @ts-ignore
|
|
10097
|
-
const incrementalEdits = await invoke$3(
|
|
10098
|
-
// @ts-ignore
|
|
10099
|
-
'TokenizeIncremental.tokenizeIncremental', newState.uid,
|
|
10100
|
-
// @ts-ignore
|
|
10101
|
-
newState.languageId, oldLine, newLine, rowIndex, newState.minLineY);
|
|
10102
|
-
if (incrementalEdits && incrementalEdits.length === 1) {
|
|
10103
|
-
return incrementalEdits;
|
|
10104
|
-
}
|
|
10105
|
-
}
|
|
10106
|
-
}
|
|
10107
|
-
return undefined;
|
|
10108
|
-
};
|
|
10109
|
-
|
|
10110
10195
|
const getSelectionsVirtualDom = selections => {
|
|
10111
10196
|
const dom = [];
|
|
10112
10197
|
for (let i = 0; i < selections.length; i += 4) {
|
|
@@ -10152,16 +10237,17 @@ const renderLines = {
|
|
|
10152
10237
|
isEqual(oldState, newState) {
|
|
10153
10238
|
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;
|
|
10154
10239
|
},
|
|
10155
|
-
|
|
10156
|
-
const
|
|
10157
|
-
|
|
10240
|
+
apply(oldState, newState) {
|
|
10241
|
+
const {
|
|
10242
|
+
incrementalEdits
|
|
10243
|
+
} = newState;
|
|
10244
|
+
if (incrementalEdits !== emptyIncrementalEdits) {
|
|
10158
10245
|
return [/* method */'setIncrementalEdits', /* incrementalEdits */incrementalEdits];
|
|
10159
10246
|
}
|
|
10160
|
-
const syncIncremental = getEnabled();
|
|
10161
10247
|
const {
|
|
10162
10248
|
textInfos,
|
|
10163
10249
|
differences
|
|
10164
|
-
} =
|
|
10250
|
+
} = newState;
|
|
10165
10251
|
newState.differences = differences;
|
|
10166
10252
|
const {
|
|
10167
10253
|
highlightedLine,
|
|
@@ -10180,7 +10266,7 @@ const renderSelections = {
|
|
|
10180
10266
|
const {
|
|
10181
10267
|
cursorInfos,
|
|
10182
10268
|
selectionInfos
|
|
10183
|
-
} = getVisible
|
|
10269
|
+
} = getVisible(newState);
|
|
10184
10270
|
const cursorsDom = getCursorsVirtualDom(cursorInfos);
|
|
10185
10271
|
const selectionsDom = getSelectionsVirtualDom(selectionInfos);
|
|
10186
10272
|
return [/* method */'setSelections', cursorsDom, selectionsDom];
|
|
@@ -10306,7 +10392,7 @@ const renderWidgets = {
|
|
|
10306
10392
|
multiple: true
|
|
10307
10393
|
};
|
|
10308
10394
|
const render$6 = [renderLines, renderSelections, renderScrollBarX, renderScrollBarY, renderFocus$1, renderDecorations, renderGutterInfo, renderWidgets];
|
|
10309
|
-
const renderEditor =
|
|
10395
|
+
const renderEditor = id => {
|
|
10310
10396
|
const instance = get$4(id);
|
|
10311
10397
|
if (!instance) {
|
|
10312
10398
|
return [];
|
|
@@ -10319,7 +10405,7 @@ const renderEditor = async id => {
|
|
|
10319
10405
|
set$6(id, newState, newState);
|
|
10320
10406
|
for (const item of render$6) {
|
|
10321
10407
|
if (!item.isEqual(oldState, newState)) {
|
|
10322
|
-
const result =
|
|
10408
|
+
const result = item.apply(oldState, newState);
|
|
10323
10409
|
// @ts-ignore
|
|
10324
10410
|
if (item.multiple) {
|
|
10325
10411
|
commands.push(...result);
|
|
@@ -10456,11 +10542,16 @@ const wrapCommand = fn => async (editorUid, ...args) => {
|
|
|
10456
10542
|
effect.apply(newEditor);
|
|
10457
10543
|
}
|
|
10458
10544
|
}
|
|
10545
|
+
// TODO if editor did not change, no need to update furthur
|
|
10546
|
+
|
|
10547
|
+
// TODO combine neweditor with latest editor?
|
|
10548
|
+
|
|
10459
10549
|
set$6(editorUid, oldInstance.newState, newEditor);
|
|
10460
|
-
|
|
10461
|
-
|
|
10462
|
-
|
|
10463
|
-
|
|
10550
|
+
const commands = renderEditor(editorUid);
|
|
10551
|
+
return {
|
|
10552
|
+
...newEditor,
|
|
10553
|
+
commands
|
|
10554
|
+
};
|
|
10464
10555
|
};
|
|
10465
10556
|
const wrapCommands = commands => {
|
|
10466
10557
|
for (const [key, value] of Object.entries(commands)) {
|
|
@@ -10695,6 +10786,7 @@ const commandMap = {
|
|
|
10695
10786
|
'FindWidget.toggleUseRegularExpression': toggleUseRegularExpression,
|
|
10696
10787
|
'FindWidget.focusNextElement': focusNextElement,
|
|
10697
10788
|
'FindWidget.focusPreviousElement': focusPreviousElement,
|
|
10789
|
+
'FindWidget.togglePreserveCase': togglePreserveCase,
|
|
10698
10790
|
'Font.ensure': ensure,
|
|
10699
10791
|
'HandleMessagePort.handleMessagePort': handleMessagePort,
|
|
10700
10792
|
'Hover.getHoverInfo': getEditorHoverInfo,
|