@lvce-editor/shared-process 0.16.3 → 0.16.5

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.
@@ -385,6 +385,10 @@
385
385
  "id": "Developer.openProcessExplorer",
386
386
  "label": "Developer: Open Process Explorer"
387
387
  },
388
+ {
389
+ "id": "Developer.openBrowserViewOverview",
390
+ "label": "Developer: Open Browser View Overview"
391
+ },
388
392
  {
389
393
  "id": "Explorer.collapseAll",
390
394
  "label": "Explorer: Collapse All"
@@ -114,6 +114,7 @@ const RE_INCLUDE_WITH_QUOTES = /^"([^"]*)"/
114
114
  const RE_INCLUDE_WITH_ANGLE_BRACKETS = /^<[^>]*>/
115
115
  const RE_TYPE = /^(?:size_t)\b/
116
116
  const RE_MACRO = /^#[a-z]+/
117
+ const RE_FUNCTION_CALL_NAME = /^[\w]+(?=\s*(\())/
117
118
 
118
119
  export const initialLineState = {
119
120
  state: State.TopLevelContent,
@@ -183,6 +184,9 @@ export const tokenizeLine = (line, lineState) => {
183
184
  } else if ((next = part.match(RE_TYPE))) {
184
185
  token = TokenType.Type
185
186
  state = State.TopLevelContent
187
+ } else if ((next = part.match(RE_FUNCTION_CALL_NAME))) {
188
+ token = TokenType.FunctionName
189
+ state = State.TopLevelContent
186
190
  } else if ((next = part.match(RE_VARIABLE_NAME))) {
187
191
  token = TokenType.VariableName
188
192
  state = State.TopLevelContent
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2022-present, Lvce Editor
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
@@ -0,0 +1,17 @@
1
+ {
2
+ "comments": {
3
+ "blockComment": ["/*", "*/"]
4
+ },
5
+ "brackets": [
6
+ ["{", "}"],
7
+ ["[", "]"],
8
+ ["(", ")"]
9
+ ],
10
+ "autoClosingPairs": [
11
+ { "open": "{", "close": "}", "notIn": ["string", "comment"] },
12
+ { "open": "[", "close": "]", "notIn": ["string", "comment"] },
13
+ { "open": "(", "close": ")", "notIn": ["string", "comment"] },
14
+ { "open": "\"", "close": "\"", "notIn": ["string", "comment"] },
15
+ { "open": "'", "close": "'", "notIn": ["string", "comment"] }
16
+ ]
17
+ }
@@ -20,6 +20,7 @@
20
20
  "FocusOutline": "#3d5252",
21
21
 
22
22
  "InputBackground": "rgb(36, 41, 42)",
23
+ "InputBoxBackground": "rgb(36, 41, 42)",
23
24
  "InputForeground": "rgb(225, 225, 225)",
24
25
 
25
26
  "LinkForeground": "#3794ff",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lvce-editor/shared-process",
3
- "version": "0.16.3",
3
+ "version": "0.16.5",
4
4
  "description": "Utility package for @lvce-editor/server",
5
5
  "main": "index.js",
6
6
  "type": "module",
@@ -17,9 +17,9 @@
17
17
  },
18
18
  "dependencies": {
19
19
  "@babel/code-frame": "^7.22.5",
20
- "@lvce-editor/extension-host": "0.16.3",
21
- "@lvce-editor/extension-host-helper-process": "0.16.3",
22
- "@lvce-editor/pty-host": "0.16.3",
20
+ "@lvce-editor/extension-host": "0.16.5",
21
+ "@lvce-editor/extension-host-helper-process": "0.16.5",
22
+ "@lvce-editor/pty-host": "0.16.5",
23
23
  "debug": "^4.3.4",
24
24
  "execa": "^7.1.1",
25
25
  "exit-hook": "^3.2.0",
@@ -0,0 +1,103 @@
1
+ import { Writable } from 'node:stream'
2
+ import { pipeline } from 'node:stream/promises'
3
+ import * as EncodingType from '../EncodingType/EncodingType.js'
4
+ import * as GetNewLineIndex from '../GetNewLineIndex/GetNewLineIndex.js'
5
+ import * as RipGrepParsedLineType from '../RipGrepParsedLineType/RipGrepParsedLineType.js'
6
+ import * as TextSearchResultType from '../TextSearchResultType/TextSearchResultType.js'
7
+ import * as ToTextSearchResult from '../ToTextSearchResult/ToTextSearchResult.js'
8
+ // TODO update vscode-ripgrep when https://github.com/mhinz/vim-grepper/issues/244, https://github.com/BurntSushi/ripgrep/issues/1892 is fixed
9
+
10
+ // need to use '.' as last argument for ripgrep
11
+ // issue 1 https://github.com/nvim-telescope/telescope.nvim/pull/908/files
12
+ // issue 2 https://github.com/BurntSushi/ripgrep/issues/1892
13
+ // remove workaround when ripgrep is fixed
14
+
15
+ // TODO stats flag might not be necessary
16
+ // TODO update client
17
+ // TODO not always run nice, maybe configure nice via flag/options
18
+
19
+ export const collectStdout = async (childProcess, maxSearchResults, charsBefore, charsAfter) => {
20
+ const allSearchResults = Object.create(null)
21
+ let buffer = ''
22
+ let stats = {}
23
+ let limitHit = false
24
+ let numberOfResults = 0
25
+
26
+ childProcess.stdout.setEncoding(EncodingType.Utf8)
27
+
28
+ const handleLine = (line) => {
29
+ const parsedLine = JSON.parse(line)
30
+ const { type, data } = parsedLine
31
+ switch (type) {
32
+ case RipGrepParsedLineType.Begin:
33
+ allSearchResults[data.path.text] = [
34
+ {
35
+ type: TextSearchResultType.File,
36
+ start: 0,
37
+ end: 0,
38
+ lineNumber: 0,
39
+ text: data.path.text,
40
+ },
41
+ ]
42
+ break
43
+ case RipGrepParsedLineType.Match:
44
+ const remaining = maxSearchResults - numberOfResults
45
+ const matches = ToTextSearchResult.toTextSearchResult(parsedLine, remaining, charsBefore, charsAfter)
46
+ numberOfResults += matches.length
47
+ allSearchResults[data.path.text].push(...matches)
48
+ break
49
+ case RipGrepParsedLineType.Summary:
50
+ stats = data
51
+ break
52
+ default:
53
+ break
54
+ }
55
+ }
56
+
57
+ const handleData = (chunk) => {
58
+ let newLineIndex = GetNewLineIndex.getNewLineIndex(chunk)
59
+ const dataString = buffer + chunk
60
+ if (newLineIndex === -1) {
61
+ buffer = dataString
62
+ return
63
+ }
64
+ newLineIndex += buffer.length
65
+ let previousIndex = 0
66
+ while (newLineIndex >= 0) {
67
+ const line = dataString.slice(previousIndex, newLineIndex)
68
+ handleLine(line)
69
+ previousIndex = newLineIndex + 1
70
+ newLineIndex = GetNewLineIndex.getNewLineIndex(dataString, previousIndex)
71
+ }
72
+ buffer = dataString.slice(previousIndex)
73
+
74
+ if (numberOfResults > maxSearchResults) {
75
+ limitHit = true
76
+ childProcess.kill()
77
+ }
78
+ }
79
+
80
+ await pipeline(
81
+ childProcess.stdout,
82
+ new Writable({
83
+ decodeStrings: false,
84
+ construct(callback) {
85
+ callback()
86
+ },
87
+ write(chunk, encoding, callback) {
88
+ try {
89
+ handleData(chunk)
90
+ callback()
91
+ } catch (error) {
92
+ callback(error)
93
+ }
94
+ },
95
+ })
96
+ )
97
+ const results = Object.values(allSearchResults).flat(1)
98
+ return {
99
+ results,
100
+ stats,
101
+ limitHit,
102
+ }
103
+ }
@@ -0,0 +1,49 @@
1
+ import * as RipGrep from '../RipGrep/RipGrep.js'
2
+
3
+ const connectProcess = (ipc, id, childProcess) => {
4
+ let count = 0
5
+ const cleanup = () => {
6
+ childProcess.kill()
7
+ }
8
+ childProcess.stdout.on('data', (data) => {
9
+ count++
10
+ if (count > 20) {
11
+ cleanup()
12
+ return
13
+ }
14
+ // console.log({ data: data.toString() })
15
+ ipc.send({
16
+ jsonrpc: '2.0',
17
+ method: 'IncrementalTextSearch.handleData',
18
+ params: [id, data.toString()],
19
+ })
20
+ // emitter.dispatchEvent(new Event('data', x))
21
+ })
22
+
23
+ childProcess.on('exit', () => {
24
+ ipc.send({
25
+ jsonrpc: '2.0',
26
+ method: 'IncrementalTextSearch.handleExit',
27
+ params: [id],
28
+ })
29
+ // emitter.dispatchEvent(new Event('exit'))
30
+ })
31
+ childProcess.on('error', () => {
32
+ ipc.send({
33
+ jsonrpc: '2.0',
34
+ method: 'IncrementalTextSearch.handleError',
35
+ params: [id],
36
+ })
37
+ // emitter.dispatchEvent(new Event('error'))
38
+ })
39
+ }
40
+
41
+ export const start = async (ipc, id, { searchDir = '', maxSearchResults = 20_000, ripGrepArgs = [] } = {}) => {
42
+ console.log({ ipc })
43
+ const emitter = new EventTarget()
44
+ const childProcess = RipGrep.spawn(ripGrepArgs, {
45
+ cwd: searchDir,
46
+ })
47
+ console.log('start', { searchDir, ripGrepArgs, id })
48
+ connectProcess(ipc, id, childProcess)
49
+ }
@@ -0,0 +1,7 @@
1
+ import * as IncrementalTextSearch from './IncrementalTextSearch.js'
2
+
3
+ export const name = 'IncrementalTextSearch'
4
+
5
+ export const Commands = {
6
+ start: IncrementalTextSearch.start,
7
+ }
@@ -0,0 +1,20 @@
1
+ const RE_WORD = /\b/g
2
+
3
+ export const leftCut = (text, final, charsBefore) => {
4
+ if (text.length < charsBefore) {
5
+ return text.length
6
+ }
7
+ let i = 0
8
+ while (RE_WORD.test(text)) {
9
+ if (final - RE_WORD.lastIndex < charsBefore) {
10
+ break
11
+ }
12
+ i = RE_WORD.lastIndex
13
+ RE_WORD.lastIndex++
14
+ }
15
+ RE_WORD.lastIndex = 0
16
+ if (final - i > charsBefore + 10) {
17
+ return final - charsBefore
18
+ }
19
+ return i
20
+ }
@@ -72,6 +72,8 @@ export const load = (moduleId) => {
72
72
  return import('../HandleCliArgs/HandleCliArgs.ipc.js')
73
73
  case ModuleId.ListProcessesWithMemoryUsage:
74
74
  return import('../ListProcessesWithMemoryUsage/ListProcessesWithMemoryUsage.ipc.js')
75
+ case ModuleId.IncrementalTextSearch:
76
+ return import('../IncrementalTextSearch/IncremetalTextSearch.ipc.js')
75
77
  default:
76
78
  throw new Error(`module ${moduleId} not found`)
77
79
  }
@@ -33,3 +33,4 @@ export const HandleNodeMessagePort = 32
33
33
  export const GetTerminalSpawnOptions = 33
34
34
  export const HandleCliArgs = 34
35
35
  export const ListProcessesWithMemoryUsage = 35
36
+ export const IncrementalTextSearch = 36
@@ -185,6 +185,8 @@ export const getModuleId = (commandId) => {
185
185
  return ModuleId.HandleCliArgs
186
186
  case 'ListProcessesWithMemoryUsage.listProcessesWithMemoryUsage':
187
187
  return ModuleId.ListProcessesWithMemoryUsage
188
+ case 'IncrementalTextSearch.start':
189
+ return ModuleId.IncrementalTextSearch
188
190
  default:
189
191
  throw new CommandNotFoundError(commandId)
190
192
  }
@@ -0,0 +1,11 @@
1
+ import * as EncodingType from '../EncodingType/EncodingType.js'
2
+
3
+ export const parseRipGrepLines = (parsedLineData) => {
4
+ if (parsedLineData.lines.text) {
5
+ return parsedLineData.lines.text
6
+ }
7
+ if (parsedLineData.lines.bytes) {
8
+ return Buffer.from(parsedLineData.lines.bytes, EncodingType.Base64).toString()
9
+ }
10
+ throw new Error(`unable to parse line data`)
11
+ }
@@ -165,11 +165,11 @@ export const getSetupName = () => {
165
165
  return 'Lvce-Setup'
166
166
  }
167
167
 
168
- export const version = '0.16.3'
168
+ export const version = '0.16.5'
169
169
 
170
- export const commit = '6fbd9fc'
170
+ export const commit = 'b8dddc3'
171
171
 
172
- export const date = '2023-07-04T07:58:24.000Z'
172
+ export const date = '2023-07-05T18:20:16.000Z'
173
173
 
174
174
  export const getVersion = () => {
175
175
  return version
@@ -7,6 +7,7 @@ const METHODS_THAT_REQUIRE_SOCKET = new Set([
7
7
  'ExtensionHost.send',
8
8
  'ExtensionHost.watchColorTheme',
9
9
  'Terminal.create',
10
+ 'IncrementalTextSearch.start',
10
11
  ])
11
12
 
12
13
  export const requiresSocket = (method) => {
@@ -1,14 +1,9 @@
1
- import { Writable } from 'node:stream'
2
- import { pipeline } from 'node:stream/promises'
3
- import * as EncodingType from '../EncodingType/EncodingType.js'
4
- import * as GetNewLineIndex from '../GetNewLineIndex/GetNewLineIndex.js'
1
+ import * as CollectTextSearchStdout from '../CollectTextSearchStdout/CollectTextSearchStdout.js'
5
2
  import * as ProcessExitEventType from '../ProcessExitEventType/ProcessExitEventType.js'
6
3
  import * as RipGrep from '../RipGrep/RipGrep.js'
7
- import * as RipGrepParsedLineType from '../RipGrepParsedLineType/RipGrepParsedLineType.js'
8
4
  import { TextSearchError } from '../TextSearchError/TextSearchError.js'
9
- import * as TextSearchResultType from '../TextSearchResultType/TextSearchResultType.js'
10
- import * as ToTextSearchResult from '../ToTextSearchResult/ToTextSearchResult.js'
11
5
  import * as WaitForProcessToExit from '../WaitForProcessToExit/WaitForProcessToExit.js'
6
+
12
7
  // TODO update vscode-ripgrep when https://github.com/mhinz/vim-grepper/issues/244, https://github.com/BurntSushi/ripgrep/issues/1892 is fixed
13
8
 
14
9
  // need to use '.' as last argument for ripgrep
@@ -20,98 +15,13 @@ import * as WaitForProcessToExit from '../WaitForProcessToExit/WaitForProcessToE
20
15
  // TODO update client
21
16
  // TODO not always run nice, maybe configure nice via flag/options
22
17
 
23
- const collectStdout = async (childProcess, maxSearchResults, charsBefore, charsAfter) => {
24
- const allSearchResults = Object.create(null)
25
- let buffer = ''
26
- let stats = {}
27
- let limitHit = false
28
- let numberOfResults = 0
29
-
30
- childProcess.stdout.setEncoding(EncodingType.Utf8)
31
-
32
- const handleLine = (line) => {
33
- const parsedLine = JSON.parse(line)
34
- switch (parsedLine.type) {
35
- case RipGrepParsedLineType.Begin:
36
- allSearchResults[parsedLine.data.path.text] = [
37
- {
38
- type: TextSearchResultType.File,
39
- start: 0,
40
- end: 0,
41
- lineNumber: 0,
42
- text: parsedLine.data.path.text,
43
- },
44
- ]
45
- break
46
- case RipGrepParsedLineType.Match:
47
- const remaining = maxSearchResults - numberOfResults
48
- const matches = ToTextSearchResult.toTextSearchResult(parsedLine, remaining, charsBefore, charsAfter)
49
- numberOfResults += matches.length
50
- allSearchResults[parsedLine.data.path.text].push(...matches)
51
- break
52
- case RipGrepParsedLineType.Summary:
53
- stats = parsedLine.data
54
- break
55
- default:
56
- break
57
- }
58
- }
59
-
60
- const handleData = (chunk) => {
61
- let newLineIndex = GetNewLineIndex.getNewLineIndex(chunk)
62
- const dataString = buffer + chunk
63
- if (newLineIndex === -1) {
64
- buffer = dataString
65
- return
66
- }
67
- newLineIndex += buffer.length
68
- let previousIndex = 0
69
- while (newLineIndex >= 0) {
70
- const line = dataString.slice(previousIndex, newLineIndex)
71
- handleLine(line)
72
- previousIndex = newLineIndex + 1
73
- newLineIndex = GetNewLineIndex.getNewLineIndex(dataString, previousIndex)
74
- }
75
- buffer = dataString.slice(previousIndex)
76
-
77
- if (numberOfResults > maxSearchResults) {
78
- limitHit = true
79
- childProcess.kill()
80
- }
81
- }
82
-
83
- await pipeline(
84
- childProcess.stdout,
85
- new Writable({
86
- decodeStrings: false,
87
- construct(callback) {
88
- callback()
89
- },
90
- write(chunk, encoding, callback) {
91
- try {
92
- handleData(chunk)
93
- callback()
94
- } catch (error) {
95
- callback(error)
96
- }
97
- },
98
- })
99
- )
100
- const results = Object.values(allSearchResults).flat(1)
101
- return {
102
- results,
103
- stats,
104
- limitHit,
105
- }
106
- }
107
-
108
18
  export const search = async ({ searchDir = '', maxSearchResults = 20_000, ripGrepArgs = [] } = {}) => {
109
19
  const charsBefore = 26
110
20
  const charsAfter = 50
111
21
  const childProcess = RipGrep.spawn(ripGrepArgs, {
112
22
  cwd: searchDir,
113
23
  })
114
- const pipeLinePromise = collectStdout(childProcess, maxSearchResults, charsBefore, charsAfter)
24
+ const pipeLinePromise = CollectTextSearchStdout.collectStdout(childProcess, maxSearchResults, charsBefore, charsAfter)
115
25
  const closePromise = WaitForProcessToExit.waitForProcessToExit(childProcess)
116
26
  const [pipeLineResult, exitResult] = await Promise.all([pipeLinePromise, closePromise])
117
27
  if (exitResult.type === ProcessExitEventType.Error) {
@@ -1,57 +1,16 @@
1
- import * as EncodingType from '../EncodingType/EncodingType.js'
1
+ import * as ParseRipGrepLines from '../ParseRipGrepLines/ParseRipGrepLines.js'
2
2
  import * as TextSearchResultType from '../TextSearchResultType/TextSearchResultType.js'
3
3
 
4
- const getLines = (parsedLineData) => {
5
- if (parsedLineData.lines.text) {
6
- return parsedLineData.lines.text
7
- }
8
- if (parsedLineData.lines.bytes) {
9
- return Buffer.from(parsedLineData.lines.bytes, EncodingType.Base64).toString()
10
- }
11
- throw new Error(`unable to parse line data`)
12
- }
13
-
14
- const getRemainingSubMatches = (submatches, remaining) => {
15
- if (submatches.length < remaining) {
16
- return submatches
17
- }
18
- return submatches.slice(0, remaining)
19
- }
20
-
21
- const RE_WORD = /\b/g
22
-
23
- const leftCut = (text, final, charsBefore) => {
24
- if (text.length < charsBefore) {
25
- return text.length
26
- }
27
- let i = 0
28
- while (RE_WORD.test(text)) {
29
- if (final - RE_WORD.lastIndex < charsBefore) {
30
- break
31
- }
32
- i = RE_WORD.lastIndex
33
- RE_WORD.lastIndex++
34
- }
35
- RE_WORD.lastIndex = 0
36
- if (final - i > charsBefore + 10) {
37
- return final - charsBefore
38
- }
39
- return i
40
- }
41
-
42
4
  export const toTextSearchResult = (parsedLine, remaining, charsBefore, charsAfter) => {
43
5
  const results = []
44
6
  const parsedLineData = parsedLine.data
45
- const lines = getLines(parsedLineData)
7
+ const lines = ParseRipGrepLines.parseRipGrepLines(parsedLineData)
46
8
  const lineNumber = parsedLineData.line_number
47
9
  const submatches = parsedLineData.submatches
48
10
  const linesLength = lines.length
49
11
  for (const submatch of submatches) {
50
12
  const previewStart = Math.max(submatch.start - charsBefore, 0)
51
13
  let actualStart = previewStart
52
- if (actualStart > 0) {
53
- actualStart = leftCut(lines, submatch.start, charsBefore)
54
- }
55
14
  const previewEnd = Math.min(submatch.end + charsAfter, linesLength)
56
15
  const previewText = lines.slice(actualStart, previewEnd)
57
16
  results.push({