2222# 2018-05-30 Bernard The first version
2323# 2023-03-03 Supperthomas Add the vscode workspace config file
2424# 2024-12-13 Supperthomas covert compile_commands.json to vscode workspace file
25+ # 2025-07-05 Bernard Add support for generating .vscode/c_cpp_properties.json
26+ # and .vscode/settings.json files
2527"""
2628Utils for VSCode
2729"""
@@ -63,7 +65,7 @@ def build_tree(paths):
6365 tree = {}
6466 current_working_directory = os .getcwd ()
6567 current_folder_name = os .path .basename (current_working_directory )
66- #过滤异常和不存在的路径
68+ # Filter out invalid and non-existent paths
6769 relative_dirs = []
6870 for path in paths :
6971 normalized_path = os .path .normpath (path )
@@ -90,7 +92,7 @@ def extract_source_dirs(compile_commands):
9092 if file_path .endswith ('.c' ):
9193 dir_path = os .path .dirname (file_path )
9294 source_dirs .add (dir_path )
93- # command 或者arguments
95+ # command or arguments
9496 command = entry .get ('command' ) or entry .get ('arguments' )
9597
9698 if isinstance (command , str ):
@@ -105,7 +107,7 @@ def extract_source_dirs(compile_commands):
105107 elif part .startswith ('/I' ):
106108 include_dir = part [2 :] if len (part ) > 2 else parts [i + 1 ]
107109 source_dirs .add (os .path .abspath (include_dir ))
108- #print(f"Source Directories: {source_dirs}")
110+
109111 return sorted (source_dirs )
110112
111113
@@ -114,8 +116,7 @@ def is_path_in_tree(path, tree):
114116 current_level = tree
115117 found_first_node = False
116118 root_key = list (tree .keys ())[0 ]
117- #print(root_key)
118- #print(path)
119+
119120 index_start = parts .index (root_key )
120121 length = len (parts )
121122 try :
@@ -155,7 +156,6 @@ def generate_code_workspace_file(source_dirs,command_json_path,root_path):
155156 }
156157 }
157158 workspace_filename = f'{ current_folder_name } .code-workspace'
158- # print(workspace_data)
159159 with open (workspace_filename , 'w' ) as f :
160160 json .dump (workspace_data , f , indent = 4 )
161161
@@ -193,8 +193,6 @@ def command_json_to_workspace(root_path,command_json_path):
193193 if not is_path_in_tree (dir_path , filtered_tree ):
194194 exclude_fold .add (dir_path )
195195
196- #print("Excluded Folders:")
197- #print(exclude_fold)
198196 generate_code_workspace_file (exclude_fold ,command_json_path ,root_path )
199197
200198def delete_repeatelist (data ):
@@ -340,6 +338,51 @@ def GenerateVSCode(env):
340338
341339 return
342340
341+ import os
342+
343+ def find_rtconfig_dirs (bsp_dir , project_dir ):
344+ """
345+ Search for subdirectories containing 'rtconfig.h' under 'bsp_dir' (up to 4 levels deep), excluding 'project_dir'.
346+
347+ Args:
348+ bsp_dir (str): The root directory to search (absolute path).
349+ project_dir (str): The subdirectory to exclude from the search (absolute path).
350+
351+ Returns
352+ list: A list of absolute paths to subdirectories containing 'rtconfig.h'.
353+ """
354+
355+ result = []
356+ project_dir = os .path .normpath (project_dir )
357+
358+ # list the bsp_dir to add result
359+ list = os .listdir (bsp_dir )
360+ for item in list :
361+ item = os .path .join (bsp_dir , item )
362+
363+ # if item is a directory
364+ if not os .path .isdir (item ):
365+ continue
366+
367+ # print(item, project_dir)
368+ if not project_dir .startswith (item ):
369+ result .append (os .path .abspath (item ))
370+
371+ parent_dir = os .path .dirname (project_dir )
372+
373+ if parent_dir != bsp_dir :
374+ list = os .listdir (parent_dir )
375+ for item in list :
376+ item = os .path .join (parent_dir , item )
377+ rtconfig_path = os .path .join (item , 'rtconfig.h' )
378+ if os .path .isfile (rtconfig_path ):
379+ abs_path = os .path .abspath (item )
380+ if abs_path != project_dir :
381+ result .append (abs_path )
382+
383+ # print(result)
384+ return result
385+
343386def GenerateVSCodeWorkspace (env ):
344387 """
345388 Generate vscode.code files
@@ -349,6 +392,26 @@ def GenerateVSCodeWorkspace(env):
349392 # get the launch directory
350393 cwd = GetLaunchDir ()
351394
395+ # get .vscode/workspace.json file
396+ workspace_file = os .path .join (cwd , '.vscode' , 'workspace.json' )
397+ if not os .path .exists (workspace_file ):
398+ print ('Workspace file not found, skip generating.' )
399+ return
400+
401+ try :
402+ # read the workspace file
403+ with open (workspace_file , 'r' ) as f :
404+ workspace_data = json .load (f )
405+
406+ # get the bsp directories from the workspace data, bsps/folder
407+ bsp_dir = os .path .join (cwd , workspace_data .get ('bsps' , {}).get ('folder' , '' ))
408+ if not bsp_dir :
409+ print ('No BSP directories found in the workspace file, skip generating.' )
410+ return
411+ except Exception as e :
412+ print ('Error reading workspace file, skip generating.' )
413+ return
414+
352415 # check if .vscode folder exists, if not, create it
353416 if not os .path .exists (os .path .join (cwd , '.vscode' )):
354417 os .mkdir (os .path .join (cwd , '.vscode' ))
@@ -391,6 +454,36 @@ def GenerateVSCodeWorkspace(env):
391454 vsc_file .write (json .dumps (json_obj , ensure_ascii = False , indent = 4 ))
392455 vsc_file .close ()
393456
457+ # generate .vscode/settings.json
458+ vsc_settings = {}
459+ settings_path = os .path .join (cwd , '.vscode/settings.json' )
460+ if os .path .exists (settings_path ):
461+ with open (settings_path , 'r' ) as f :
462+ # read the existing settings file and load to vsc_settings
463+ vsc_settings = json .load (f )
464+
465+ vsc_file = open (settings_path , 'w' )
466+ if vsc_file :
467+ vsc_settings ['files.exclude' ] = {
468+ "**/__pycache__" : True ,
469+ "tools/kconfig-frontends" : True ,
470+ }
471+
472+ result = find_rtconfig_dirs (bsp_dir , os .getcwd ())
473+ if result :
474+ # sort the result
475+ result = sorted (result , key = lambda x : x .lower ())
476+ for item in result :
477+ # make the path relative to the current working directory
478+ rel_path = os .path .relpath (item , cwd )
479+ # add the path to files.exclude
480+ vsc_settings ['files.exclude' ][rel_path ] = True
481+
482+ vsc_settings ['search.exclude' ] = vsc_settings ['files.exclude' ]
483+ # write the settings to the file
484+ vsc_file .write (json .dumps (vsc_settings , ensure_ascii = False , indent = 4 ))
485+ vsc_file .close ()
486+
394487 print ('Done!' )
395488
396489 return
0 commit comments