setta 0.0.8.dev0__py3-none-any.whl → 0.0.9__py3-none-any.whl
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.
- setta/__init__.py +1 -1
- setta/code_gen/export_selected.py +6 -4
- setta/code_gen/python/generate_code.py +2 -0
- setta/database/db/codeInfo/copy.py +1 -4
- setta/database/db/projects/saveAs.py +0 -3
- setta/database/db/projects/utils.py +2 -2
- setta/database/db/sectionVariants/copy.py +12 -3
- setta/database/db/sections/copy.py +4 -1
- setta/database/db/sections/jsonSource.py +109 -42
- setta/database/db/sections/load.py +145 -73
- setta/database/settings_file.py +1 -1
- setta/lsp/file_watcher.py +0 -16
- setta/lsp/specific_file_watcher.py +278 -0
- setta/lsp/utils.py +20 -0
- setta/routers/dependencies.py +4 -0
- setta/routers/projects.py +1 -1
- setta/routers/sections.py +28 -5
- setta/server.py +6 -0
- setta/static/constants/constants.json +3 -1
- setta/static/constants/defaultValues.json +3 -2
- setta/static/constants/settingsProject.json +200 -29
- setta/static/frontend/assets/{index-c90491bb.js → index-0693b9a1.js} +165 -165
- setta/static/frontend/assets/index-cf887608.css +32 -0
- setta/static/frontend/index.html +2 -2
- setta/utils/constants.py +1 -4
- setta/utils/websocket_manager.py +5 -0
- {setta-0.0.8.dev0.dist-info → setta-0.0.9.dist-info}/METADATA +11 -6
- {setta-0.0.8.dev0.dist-info → setta-0.0.9.dist-info}/RECORD +32 -31
- {setta-0.0.8.dev0.dist-info → setta-0.0.9.dist-info}/WHEEL +1 -1
- setta/static/frontend/assets/index-3a6274db.css +0 -32
- {setta-0.0.8.dev0.dist-info → setta-0.0.9.dist-info}/LICENSE +0 -0
- {setta-0.0.8.dev0.dist-info → setta-0.0.9.dist-info}/entry_points.txt +0 -0
- {setta-0.0.8.dev0.dist-info → setta-0.0.9.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,278 @@
|
|
1
|
+
import asyncio
|
2
|
+
import glob
|
3
|
+
import logging
|
4
|
+
import os
|
5
|
+
from typing import Dict, List, Set
|
6
|
+
|
7
|
+
from watchdog.events import FileSystemEvent, FileSystemEventHandler
|
8
|
+
from watchdog.observers import Observer
|
9
|
+
|
10
|
+
logger = logging.getLogger(__name__)
|
11
|
+
|
12
|
+
|
13
|
+
class SpecificFileWatcher:
|
14
|
+
"""File watcher that monitors specific files and notifies via a single callback."""
|
15
|
+
|
16
|
+
def __init__(self, callback):
|
17
|
+
"""
|
18
|
+
Initialize the file watcher for specific files.
|
19
|
+
|
20
|
+
Args:
|
21
|
+
callback: Function to call when any watched file changes
|
22
|
+
Callback receives (file_path, event_type) where event_type is
|
23
|
+
one of 'created', 'modified', 'deleted', or 'moved'
|
24
|
+
"""
|
25
|
+
self.observer = Observer()
|
26
|
+
self.watched_files: Set[str] = set()
|
27
|
+
self.file_to_patterns = {}
|
28
|
+
self.handler = SpecificFileEventHandler(
|
29
|
+
callback,
|
30
|
+
asyncio.get_event_loop(),
|
31
|
+
self.watched_files,
|
32
|
+
self.file_to_patterns,
|
33
|
+
)
|
34
|
+
|
35
|
+
def add_file(self, file_path: str) -> bool:
|
36
|
+
"""
|
37
|
+
Add a specific file to watch.
|
38
|
+
|
39
|
+
Args:
|
40
|
+
file_path: Absolute path to the file to watch
|
41
|
+
|
42
|
+
Returns:
|
43
|
+
bool: True if the file was added, False if it doesn't exist
|
44
|
+
"""
|
45
|
+
if not os.path.exists(file_path):
|
46
|
+
return False
|
47
|
+
|
48
|
+
absolute_path = os.path.abspath(file_path)
|
49
|
+
dir_path = os.path.dirname(absolute_path)
|
50
|
+
|
51
|
+
# Add file to watched files if not already there
|
52
|
+
if absolute_path not in self.watched_files:
|
53
|
+
self.watched_files.add(absolute_path)
|
54
|
+
else:
|
55
|
+
# Already watching this file
|
56
|
+
return True
|
57
|
+
|
58
|
+
# Schedule the directory for watching if needed
|
59
|
+
if not self.observer.emitters:
|
60
|
+
# No directories are being watched yet
|
61
|
+
self.observer.schedule(self.handler, dir_path, recursive=False)
|
62
|
+
else:
|
63
|
+
# Check if the directory is already being watched
|
64
|
+
is_dir_watched = False
|
65
|
+
for emitter in self.observer.emitters:
|
66
|
+
if emitter.watch.path == dir_path:
|
67
|
+
is_dir_watched = True
|
68
|
+
break
|
69
|
+
|
70
|
+
if not is_dir_watched:
|
71
|
+
self.observer.schedule(self.handler, dir_path, recursive=False)
|
72
|
+
|
73
|
+
return True
|
74
|
+
|
75
|
+
def remove_file(self, file_path: str) -> None:
|
76
|
+
"""
|
77
|
+
Remove a file from being watched.
|
78
|
+
|
79
|
+
Args:
|
80
|
+
file_path: Path to the file
|
81
|
+
"""
|
82
|
+
absolute_path = os.path.abspath(file_path)
|
83
|
+
|
84
|
+
if absolute_path in self.watched_files:
|
85
|
+
self.watched_files.remove(absolute_path)
|
86
|
+
|
87
|
+
def update_watch_list(
|
88
|
+
self, filepaths_and_glob_patterns: List[str]
|
89
|
+
) -> Dict[str, List[str]]:
|
90
|
+
"""
|
91
|
+
Update the entire list of files being watched with a single function call.
|
92
|
+
This efficiently handles adding new files and removing files that are no longer needed.
|
93
|
+
|
94
|
+
Args:
|
95
|
+
filepaths_and_glob_patterns: List of file paths that should be watched
|
96
|
+
|
97
|
+
Returns:
|
98
|
+
Dict containing 'added' and 'removed' lists of file paths
|
99
|
+
"""
|
100
|
+
file_paths = self.get_actual_file_paths_to_watch(filepaths_and_glob_patterns)
|
101
|
+
|
102
|
+
# Convert all input paths to absolute paths (only if they exist)
|
103
|
+
absolute_paths = [
|
104
|
+
os.path.abspath(path) for path in file_paths if os.path.exists(path)
|
105
|
+
]
|
106
|
+
absolute_paths_set = set(absolute_paths)
|
107
|
+
|
108
|
+
# Calculate differences
|
109
|
+
files_to_add = absolute_paths_set - self.watched_files
|
110
|
+
files_to_remove = self.watched_files - absolute_paths_set
|
111
|
+
|
112
|
+
# Track which files were successfully added
|
113
|
+
added_files = []
|
114
|
+
|
115
|
+
# Add new files
|
116
|
+
for file_path in files_to_add:
|
117
|
+
success = self.add_file(file_path)
|
118
|
+
if success:
|
119
|
+
added_files.append(file_path)
|
120
|
+
|
121
|
+
# Remove files no longer in the list
|
122
|
+
for file_path in files_to_remove:
|
123
|
+
self.remove_file(file_path)
|
124
|
+
|
125
|
+
# Return information about what changed
|
126
|
+
return {"added": added_files, "removed": list(files_to_remove)}
|
127
|
+
|
128
|
+
def get_actual_file_paths_to_watch(self, filepaths_and_glob_patterns):
|
129
|
+
actual_filepaths = set()
|
130
|
+
# Expand glob patterns and build the mapping
|
131
|
+
for pattern in filepaths_and_glob_patterns:
|
132
|
+
matching_files = glob.glob(pattern)
|
133
|
+
for file_path in matching_files:
|
134
|
+
# Only add actual files, not directories
|
135
|
+
if os.path.isfile(file_path):
|
136
|
+
abs_path = os.path.abspath(file_path)
|
137
|
+
actual_filepaths.add(abs_path)
|
138
|
+
|
139
|
+
# Add to the mapping
|
140
|
+
if abs_path not in self.file_to_patterns:
|
141
|
+
self.file_to_patterns[abs_path] = set()
|
142
|
+
self.file_to_patterns[abs_path].add(pattern)
|
143
|
+
|
144
|
+
return actual_filepaths
|
145
|
+
|
146
|
+
def start(self) -> None:
|
147
|
+
"""Start the file watcher."""
|
148
|
+
self.observer.start()
|
149
|
+
self.started = True
|
150
|
+
|
151
|
+
def stop(self) -> None:
|
152
|
+
"""Stop the file watcher."""
|
153
|
+
self.observer.stop()
|
154
|
+
self.observer.join()
|
155
|
+
self.started = False
|
156
|
+
|
157
|
+
|
158
|
+
class SpecificFileEventHandler(FileSystemEventHandler):
|
159
|
+
"""Event handler for specific file events."""
|
160
|
+
|
161
|
+
def __init__(self, callback, loop, watched_files_ref, file_to_patterns):
|
162
|
+
"""
|
163
|
+
Initialize the event handler.
|
164
|
+
|
165
|
+
Args:
|
166
|
+
callback: Function to call when a watched file changes
|
167
|
+
loop: Asyncio event loop for async callbacks
|
168
|
+
watched_files_ref: Reference to the set of files being watched
|
169
|
+
"""
|
170
|
+
self.callback = callback
|
171
|
+
self.loop = loop
|
172
|
+
self.watched_files_ref = watched_files_ref
|
173
|
+
self.file_to_patterns = file_to_patterns
|
174
|
+
|
175
|
+
def on_created(self, event: FileSystemEvent):
|
176
|
+
"""Handle file creation event."""
|
177
|
+
if not event.is_directory:
|
178
|
+
file_path = os.path.abspath(event.src_path)
|
179
|
+
if file_path in self.watched_files_ref:
|
180
|
+
self._send_event(event, "created")
|
181
|
+
|
182
|
+
def on_modified(self, event: FileSystemEvent):
|
183
|
+
"""Handle file modification event."""
|
184
|
+
if not event.is_directory:
|
185
|
+
file_path = os.path.abspath(event.src_path)
|
186
|
+
if file_path in self.watched_files_ref:
|
187
|
+
self._send_event(event, "modified")
|
188
|
+
|
189
|
+
def on_deleted(self, event: FileSystemEvent):
|
190
|
+
"""Handle file deletion event."""
|
191
|
+
if not event.is_directory:
|
192
|
+
file_path = os.path.abspath(event.src_path)
|
193
|
+
if file_path in self.watched_files_ref:
|
194
|
+
self._send_event(event, "deleted")
|
195
|
+
|
196
|
+
def on_moved(self, event: FileSystemEvent):
|
197
|
+
"""Handle file move event."""
|
198
|
+
if not event.is_directory:
|
199
|
+
# For moved events, we need to check both source and destination
|
200
|
+
src_path = os.path.abspath(event.src_path)
|
201
|
+
dest_path = (
|
202
|
+
os.path.abspath(event.dest_path)
|
203
|
+
if hasattr(event, "dest_path")
|
204
|
+
else None
|
205
|
+
)
|
206
|
+
|
207
|
+
# If the source was being watched, notify about the move
|
208
|
+
if src_path in self.watched_files_ref:
|
209
|
+
self._send_event(event, "moved")
|
210
|
+
|
211
|
+
# If the destination is also being watched, notify about modification
|
212
|
+
if (
|
213
|
+
dest_path
|
214
|
+
and dest_path in self.watched_files_ref
|
215
|
+
and dest_path != src_path
|
216
|
+
):
|
217
|
+
# Create a modified event for the destination
|
218
|
+
self._send_event(event, "modified")
|
219
|
+
|
220
|
+
def _send_event(self, event: FileSystemEvent, event_type: str):
|
221
|
+
"""
|
222
|
+
Process and send the event to the callback.
|
223
|
+
|
224
|
+
Args:
|
225
|
+
event: The file system event
|
226
|
+
event_type: The type of event ('created', 'modified', 'deleted', 'moved')
|
227
|
+
"""
|
228
|
+
logger.debug("_send_event")
|
229
|
+
# Get absolute path
|
230
|
+
abs_path = os.path.abspath(event.src_path)
|
231
|
+
|
232
|
+
# Get relative path to current working directory
|
233
|
+
rel_path = os.path.relpath(abs_path)
|
234
|
+
|
235
|
+
# Get file contents for created and modified events
|
236
|
+
file_content = None
|
237
|
+
if event_type in ("created", "modified"):
|
238
|
+
try:
|
239
|
+
with open(abs_path, "r", encoding="utf-8") as f:
|
240
|
+
file_content = f.read()
|
241
|
+
except Exception as e:
|
242
|
+
logger.debug(f"Error reading file {abs_path}: {e}")
|
243
|
+
file_content = None
|
244
|
+
|
245
|
+
# For moved events, get the content of the destination file
|
246
|
+
dest_abs_path = None
|
247
|
+
dest_rel_path = None
|
248
|
+
if event_type == "moved" and hasattr(event, "dest_path"):
|
249
|
+
dest_abs_path = os.path.abspath(event.dest_path)
|
250
|
+
dest_rel_path = os.path.relpath(dest_abs_path)
|
251
|
+
try:
|
252
|
+
with open(dest_abs_path, "r", encoding="utf-8") as f:
|
253
|
+
file_content = f.read()
|
254
|
+
except Exception as e:
|
255
|
+
logger.debug(f"Error reading destination file {dest_abs_path}: {e}")
|
256
|
+
file_content = None
|
257
|
+
|
258
|
+
# Prepare event info object
|
259
|
+
event_info = {
|
260
|
+
"absPath": abs_path,
|
261
|
+
"relPath": rel_path,
|
262
|
+
"eventType": event_type,
|
263
|
+
"fileContent": file_content,
|
264
|
+
"matchingGlobPatterns": list(self.file_to_patterns[abs_path]),
|
265
|
+
}
|
266
|
+
|
267
|
+
# Add destination paths for moved events
|
268
|
+
if event_type == "moved" and dest_abs_path:
|
269
|
+
event_info["destAbsPath"] = dest_abs_path
|
270
|
+
event_info["destRelPath"] = dest_rel_path
|
271
|
+
|
272
|
+
logger.debug(f"will send {event_info}")
|
273
|
+
if asyncio.iscoroutinefunction(self.callback):
|
274
|
+
self.loop.call_soon_threadsafe(
|
275
|
+
lambda: self.loop.create_task(self.callback(event_info))
|
276
|
+
)
|
277
|
+
else:
|
278
|
+
self.callback(event_info)
|
setta/lsp/utils.py
CHANGED
@@ -1,8 +1,15 @@
|
|
1
|
+
import logging
|
2
|
+
|
3
|
+
from setta.utils.constants import C
|
4
|
+
|
1
5
|
from .file_watcher import LSPFileWatcher
|
2
6
|
from .reader import LanguageServerReader
|
3
7
|
from .server import LanguageServer
|
8
|
+
from .specific_file_watcher import SpecificFileWatcher
|
4
9
|
from .writer import LanguageServerWriter
|
5
10
|
|
11
|
+
logger = logging.getLogger(__name__)
|
12
|
+
|
6
13
|
|
7
14
|
def create_lsps(
|
8
15
|
workspace_folder,
|
@@ -42,6 +49,19 @@ def create_file_watcher(lsps, lsp_writers):
|
|
42
49
|
return file_watcher
|
43
50
|
|
44
51
|
|
52
|
+
def create_specific_file_watcher(websocket_manager):
|
53
|
+
async def callback(event_info):
|
54
|
+
logger.debug(f"callback {event_info}")
|
55
|
+
await websocket_manager.broadcast(
|
56
|
+
{
|
57
|
+
"content": event_info,
|
58
|
+
"messageType": C.WS_SPECIFIC_FILE_WATCHER_UPDATE,
|
59
|
+
}
|
60
|
+
)
|
61
|
+
|
62
|
+
return SpecificFileWatcher(callback)
|
63
|
+
|
64
|
+
|
45
65
|
async def start_lsps(lsps, lsp_readers, lsp_writers):
|
46
66
|
for k, v in lsps.items():
|
47
67
|
await v.start_server()
|
setta/routers/dependencies.py
CHANGED
setta/routers/projects.py
CHANGED
@@ -178,7 +178,7 @@ def router_set_as_default_project(x: SetAsDefaultProjectRequest, dbq=Depends(get
|
|
178
178
|
|
179
179
|
@router.post(C.ROUTE_FILTER_DATA_FOR_JSON_EXPORT)
|
180
180
|
def router_filter_data_for_json_export(x: FilterDataForJSONExportRequest):
|
181
|
-
filter_data_for_json_export(x.project
|
181
|
+
filter_data_for_json_export(x.project)
|
182
182
|
return x.project
|
183
183
|
|
184
184
|
|
setta/routers/sections.py
CHANGED
@@ -2,7 +2,7 @@ import os
|
|
2
2
|
from pathlib import Path
|
3
3
|
from typing import Dict, List, Optional
|
4
4
|
|
5
|
-
from fastapi import APIRouter, HTTPException, status
|
5
|
+
from fastapi import APIRouter, Depends, HTTPException, status
|
6
6
|
from pydantic import BaseModel
|
7
7
|
|
8
8
|
from setta.code_gen.export_selected import (
|
@@ -21,6 +21,7 @@ from setta.database.db.sections.copy import (
|
|
21
21
|
)
|
22
22
|
from setta.database.db.sections.jsonSource import save_json_source_data
|
23
23
|
from setta.database.db.sections.load import load_json_sources_into_data_structures
|
24
|
+
from setta.routers.dependencies import get_specific_file_watcher
|
24
25
|
from setta.utils.constants import C
|
25
26
|
from setta.utils.generate_new_filename import generate_new_filename
|
26
27
|
|
@@ -53,8 +54,7 @@ class GlobalParamSweepSectionToYamlRequest(BaseModel):
|
|
53
54
|
|
54
55
|
class LoadSectionJSONSourceRequest(BaseModel):
|
55
56
|
project: dict
|
56
|
-
|
57
|
-
jsonSource: str
|
57
|
+
sectionIdToJSONSource: Dict[str, str]
|
58
58
|
|
59
59
|
|
60
60
|
class SaveSectionJSONSourceRequest(BaseModel):
|
@@ -67,6 +67,10 @@ class NewJSONVersionNameRequest(BaseModel):
|
|
67
67
|
filenameGlob: str
|
68
68
|
|
69
69
|
|
70
|
+
class CreateFileRequest(BaseModel):
|
71
|
+
filepath: str
|
72
|
+
|
73
|
+
|
70
74
|
class GetJSONSourcePathToBeDeleted(BaseModel):
|
71
75
|
variantName: str
|
72
76
|
|
@@ -75,6 +79,10 @@ class DeleteFileRequest(BaseModel):
|
|
75
79
|
filepath: str
|
76
80
|
|
77
81
|
|
82
|
+
class FileWatchListRequest(BaseModel):
|
83
|
+
filepaths: List[str]
|
84
|
+
|
85
|
+
|
78
86
|
@router.post(C.ROUTE_COPY_SECTIONS)
|
79
87
|
def route_sections_make_copy(x: SectionsMakeCopyRequest):
|
80
88
|
output = copy_sections_and_other_info(x.sectionsAndOtherInfo)
|
@@ -126,13 +134,14 @@ def route_global_param_sweep_section_to_yaml(x: GlobalParamSweepSectionToYamlReq
|
|
126
134
|
@router.post(C.ROUTE_LOAD_SECTION_JSON_SOURCE)
|
127
135
|
def route_load_section_json_source(x: LoadSectionJSONSourceRequest):
|
128
136
|
p = x.project
|
129
|
-
|
137
|
+
for k, v in x.sectionIdToJSONSource.items():
|
138
|
+
p["sections"][k]["jsonSource"] = v
|
130
139
|
load_json_sources_into_data_structures(
|
131
140
|
p["sections"],
|
132
141
|
p["codeInfo"],
|
133
142
|
p["codeInfoCols"],
|
134
143
|
p["sectionVariants"],
|
135
|
-
section_ids=
|
144
|
+
section_ids=list(x.sectionIdToJSONSource.keys()),
|
136
145
|
)
|
137
146
|
return {"project": p}
|
138
147
|
|
@@ -145,6 +154,12 @@ def route_new_json_version_name(x: NewJSONVersionNameRequest):
|
|
145
154
|
return new_filename
|
146
155
|
|
147
156
|
|
157
|
+
@router.post(C.ROUTE_CREATE_FILE)
|
158
|
+
def route_create_file(x: CreateFileRequest):
|
159
|
+
Path(x.filepath).parent.mkdir(parents=True, exist_ok=True)
|
160
|
+
Path(x.filepath).touch()
|
161
|
+
|
162
|
+
|
148
163
|
@router.post(C.ROUTE_SAVE_SECTION_JSON_SOURCE)
|
149
164
|
def route_save_section_json_source(x: SaveSectionJSONSourceRequest):
|
150
165
|
save_json_source_data(x.project, [x.sectionId], x.forking_from)
|
@@ -172,3 +187,11 @@ def route_delete_file(x: DeleteFileRequest):
|
|
172
187
|
status_code=status.HTTP_404_NOT_FOUND,
|
173
188
|
detail=f"Failed to delete file: {str(e)}",
|
174
189
|
)
|
190
|
+
|
191
|
+
|
192
|
+
@router.post(C.ROUTE_FILE_WATCH_LIST)
|
193
|
+
def route_file_watch_list(
|
194
|
+
x: FileWatchListRequest, specific_file_watcher=Depends(get_specific_file_watcher)
|
195
|
+
):
|
196
|
+
# x.filepaths is the current list of file paths or glob patterns that should be watched
|
197
|
+
specific_file_watcher.update_watch_list(x.filepaths)
|
setta/server.py
CHANGED
@@ -16,6 +16,7 @@ from setta.lsp.utils import (
|
|
16
16
|
create_lsp_readers,
|
17
17
|
create_lsp_writers,
|
18
18
|
create_lsps,
|
19
|
+
create_specific_file_watcher,
|
19
20
|
kill_lsps,
|
20
21
|
start_lsps,
|
21
22
|
)
|
@@ -52,6 +53,9 @@ async def lifespan(app: FastAPI):
|
|
52
53
|
app.state.file_watcher = create_file_watcher(app.state.lsps, app.state.lsp_writers)
|
53
54
|
app.state.terminal_websockets = TerminalWebsockets()
|
54
55
|
app.state.websocket_manager = WebsocketManager()
|
56
|
+
app.state.specific_file_watcher = create_specific_file_watcher(
|
57
|
+
app.state.websocket_manager
|
58
|
+
)
|
55
59
|
app.state.tasks = Tasks(app.state.lsp_writers)
|
56
60
|
app.state.lsp_readers = create_lsp_readers(
|
57
61
|
app.state.lsps, app.state.websocket_manager
|
@@ -73,6 +77,7 @@ async def lifespan(app: FastAPI):
|
|
73
77
|
app.state.lsp_writers,
|
74
78
|
)
|
75
79
|
app.state.file_watcher.start()
|
80
|
+
app.state.specific_file_watcher.start()
|
76
81
|
|
77
82
|
if not is_dev_mode():
|
78
83
|
# Mount the 'frontend/dist' directory at '/static'
|
@@ -98,6 +103,7 @@ async def lifespan(app: FastAPI):
|
|
98
103
|
finally:
|
99
104
|
app.state.tasks.close()
|
100
105
|
app.state.file_watcher.stop()
|
106
|
+
app.state.specific_file_watcher.stop()
|
101
107
|
await kill_lsps(app.state.lsps, app.state.lsp_readers)
|
102
108
|
|
103
109
|
|
@@ -89,11 +89,12 @@
|
|
89
89
|
"ROUTE_ADD_DEFAULT_DATA_FOR_JSON_IMPORT": "/addDefaultDataForJSONImport",
|
90
90
|
"ROUTE_GET_JSON_SOURCE_PATH_TO_BE_DELETED": "/getJsonSourcePathToBeDeleted",
|
91
91
|
"ROUTE_MAKE_EV_REF_TEMPLATE_VAR_REPLACEMENTS": "/makeEVRefReplacements",
|
92
|
+
"ROUTE_CREATE_FILE": "/createFile",
|
92
93
|
"ROUTE_DELETE_FILE": "/deleteFile",
|
93
94
|
"ROUTE_CHECK_IF_FILE_EXISTS": "/checkIfFileExists",
|
94
95
|
"ROUTE_LOAD_ARTIFACT_FROM_DISK": "/loadArtifactFromDisk",
|
95
96
|
"ROUTE_RESTART_LANGUAGE_SERVER": "/restartLanguageServer",
|
96
|
-
"
|
97
|
+
"ROUTE_FILE_WATCH_LIST": "/fileWatchList",
|
97
98
|
"NESTED_PARAM": "NESTED_PARAM",
|
98
99
|
"ARGS_PREFIX": "__",
|
99
100
|
"TEMPLATE_PREFIX": "$",
|
@@ -105,6 +106,7 @@
|
|
105
106
|
"WS_TERMINAL_RESIZE": "terminalResize",
|
106
107
|
"WS_LSP_STATUS": "lspStatus",
|
107
108
|
"WS_IN_MEMORY_FN_AVG_RUN_TIME": "inMemoryFnAvgRunTime",
|
109
|
+
"WS_SPECIFIC_FILE_WATCHER_UPDATE": "specificFileWatcherUpdate",
|
108
110
|
"SETTA_GENERATED_PYTHON": "SETTA_GENERATED_PYTHON",
|
109
111
|
"SETTA_GENERATED_PYTHON_IMPORTS": "SETTA_GENERATED_PYTHON_IMPORTS",
|
110
112
|
"TEMPLATE_VAR_IMPORT_PATH_SUFFIX": "import_path",
|
@@ -65,7 +65,7 @@
|
|
65
65
|
"aspectRatioExtraWidth": 0,
|
66
66
|
"columnWidth": null,
|
67
67
|
"renderedValue": null,
|
68
|
-
"subprocessStartMethod": "
|
68
|
+
"subprocessStartMethod": "spawn",
|
69
69
|
"headingAsSectionName": false
|
70
70
|
},
|
71
71
|
"sectionVariant": {
|
@@ -94,7 +94,8 @@
|
|
94
94
|
"isFrozen": false,
|
95
95
|
"isSelected": false,
|
96
96
|
"evRefs": [],
|
97
|
-
"ignoreTypeErrors": false
|
97
|
+
"ignoreTypeErrors": false,
|
98
|
+
"jsonSource": null
|
98
99
|
},
|
99
100
|
"codeInfoCol": {
|
100
101
|
"children": { "null": [] }
|