IncludeCPP 4.6.0__py3-none-any.whl → 4.9.3__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.
Files changed (35) hide show
  1. includecpp/CHANGELOG.md +241 -0
  2. includecpp/__init__.py +89 -3
  3. includecpp/__init__.pyi +2 -1
  4. includecpp/cli/commands.py +1747 -266
  5. includecpp/cli/config_parser.py +1 -1
  6. includecpp/core/build_manager.py +64 -13
  7. includecpp/core/cpp_api_extensions.pyi +43 -270
  8. includecpp/core/cssl/CSSL_DOCUMENTATION.md +1799 -1445
  9. includecpp/core/cssl/cpp/build/api.pyd +0 -0
  10. includecpp/core/cssl/cpp/build/api.pyi +274 -0
  11. includecpp/core/cssl/cpp/build/cssl_core.pyi +0 -99
  12. includecpp/core/cssl/cpp/cssl_core.cp +2 -23
  13. includecpp/core/cssl/cssl_builtins.py +2116 -171
  14. includecpp/core/cssl/cssl_builtins.pyi +1324 -104
  15. includecpp/core/cssl/cssl_compiler.py +4 -1
  16. includecpp/core/cssl/cssl_modules.py +605 -6
  17. includecpp/core/cssl/cssl_optimizer.py +12 -1
  18. includecpp/core/cssl/cssl_parser.py +1048 -52
  19. includecpp/core/cssl/cssl_runtime.py +2041 -131
  20. includecpp/core/cssl/cssl_syntax.py +405 -277
  21. includecpp/core/cssl/cssl_types.py +5891 -1655
  22. includecpp/core/cssl_bridge.py +427 -4
  23. includecpp/core/error_catalog.py +54 -10
  24. includecpp/core/homeserver.py +1037 -0
  25. includecpp/generator/parser.cpp +203 -39
  26. includecpp/generator/parser.h +15 -1
  27. includecpp/templates/cpp.proj.template +1 -1
  28. includecpp/vscode/cssl/snippets/cssl.snippets.json +163 -0
  29. includecpp/vscode/cssl/syntaxes/cssl.tmLanguage.json +87 -12
  30. {includecpp-4.6.0.dist-info → includecpp-4.9.3.dist-info}/METADATA +81 -10
  31. {includecpp-4.6.0.dist-info → includecpp-4.9.3.dist-info}/RECORD +35 -33
  32. {includecpp-4.6.0.dist-info → includecpp-4.9.3.dist-info}/WHEEL +1 -1
  33. {includecpp-4.6.0.dist-info → includecpp-4.9.3.dist-info}/entry_points.txt +0 -0
  34. {includecpp-4.6.0.dist-info → includecpp-4.9.3.dist-info}/licenses/LICENSE +0 -0
  35. {includecpp-4.6.0.dist-info → includecpp-4.9.3.dist-info}/top_level.txt +0 -0
@@ -230,22 +230,62 @@ ModuleDescriptor API::parse_cp_file(const std::string& filepath) {
230
230
 
231
231
  if (!in_public_block) {
232
232
  if (starts_with(line, "SOURCE")) {
233
- size_t source_start = line.find('(');
234
- size_t source_end = line.find(')');
235
- if (source_start != std::string::npos && source_end != std::string::npos) {
236
- desc.source_path = trim(line.substr(source_start + 1, source_end - source_start - 1));
233
+ // v4.6.5: Support multiple SOURCE() and HEADER() declarations
234
+ // Format: SOURCE(file1) && SOURCE(file2) && HEADER(h) module_name
235
+
236
+ // Find ALL SOURCE(...) declarations
237
+ std::regex source_regex(R"(SOURCE\s*\(\s*([^)]+)\s*\))");
238
+ std::sregex_iterator source_it(line.begin(), line.end(), source_regex);
239
+ std::sregex_iterator end_it;
240
+ bool first_source = true;
241
+ while (source_it != end_it) {
242
+ std::string src_content = trim((*source_it)[1].str());
243
+ // Handle space/comma-separated files within one SOURCE()
244
+ std::istringstream iss(src_content);
245
+ std::string single_src;
246
+ while (iss >> single_src) {
247
+ // Remove trailing comma if present
248
+ if (!single_src.empty() && single_src.back() == ',') {
249
+ single_src.pop_back();
250
+ }
251
+ if (!single_src.empty()) {
252
+ if (first_source && desc.source_path.empty()) {
253
+ desc.source_path = single_src;
254
+ first_source = false;
255
+ } else {
256
+ desc.additional_sources.push_back(single_src);
257
+ }
258
+ }
259
+ }
260
+ ++source_it;
237
261
  }
238
262
 
239
- size_t header_pos = line.find("HEADER");
240
- if (header_pos != std::string::npos) {
241
- desc.has_header = true;
242
- size_t header_start = line.find('(', header_pos);
243
- size_t header_end = line.find(')', header_pos);
244
- if (header_start != std::string::npos && header_end != std::string::npos) {
245
- desc.header_path = trim(line.substr(header_start + 1, header_end - header_start - 1));
263
+ // Find ALL HEADER(...) declarations
264
+ std::regex header_regex(R"(HEADER\s*\(\s*([^)]+)\s*\))");
265
+ std::sregex_iterator header_it(line.begin(), line.end(), header_regex);
266
+ bool first_header = true;
267
+ while (header_it != end_it) {
268
+ std::string hdr_content = trim((*header_it)[1].str());
269
+ // Handle space/comma-separated headers within one HEADER()
270
+ std::istringstream hss(hdr_content);
271
+ std::string single_hdr;
272
+ while (hss >> single_hdr) {
273
+ if (!single_hdr.empty() && single_hdr.back() == ',') {
274
+ single_hdr.pop_back();
275
+ }
276
+ if (!single_hdr.empty()) {
277
+ if (first_header) {
278
+ desc.header_path = single_hdr;
279
+ desc.has_header = true;
280
+ first_header = false;
281
+ }
282
+ // Additional headers can be stored if needed in future
283
+ }
246
284
  }
285
+ ++header_it;
247
286
  }
248
287
 
288
+ // Module name is at the end after all declarations
249
289
  size_t last_space = line.rfind(' ');
250
290
  if (last_space != std::string::npos) {
251
291
  desc.module_name = trim(line.substr(last_space + 1));
@@ -380,6 +420,66 @@ ModuleDescriptor API::parse_cp_file(const std::string& filepath) {
380
420
  desc.functions.push_back(fb);
381
421
  }
382
422
  }
423
+ // v4.6.5: Check ENUM before CLASS (ENUM lines may contain "CLASS" keyword)
424
+ else if (cleaned.find("ENUM(") != std::string::npos) {
425
+ EnumBinding eb;
426
+ auto parts = split(cleaned, ' ');
427
+ if (parts.size() >= 2) {
428
+ eb.module_name = parts[0];
429
+
430
+ size_t enum_start = cleaned.find("ENUM(");
431
+ size_t enum_end = cleaned.find(')', enum_start);
432
+ size_t enum_paren = enum_start + 4; // Position of '(' in "ENUM("
433
+ eb.enum_name = safe_extract_between(cleaned, enum_paren, enum_end, "ENUM");
434
+
435
+ // Check for CLASS keyword (enum class vs plain enum)
436
+ if (cleaned.find(" CLASS") != std::string::npos) {
437
+ eb.is_class_enum = true;
438
+ }
439
+
440
+ // Check for NOEXPORT keyword
441
+ if (cleaned.find("NOEXPORT") != std::string::npos) {
442
+ eb.export_values = false;
443
+ }
444
+
445
+ // Check for VALUES block: ENUM(Name) { VALUE1 VALUE2 ... }
446
+ size_t brace_open = cleaned.find('{');
447
+ if (brace_open != std::string::npos) {
448
+ std::string values_block;
449
+ size_t brace_close = cleaned.find('}', brace_open);
450
+ if (brace_close != std::string::npos) {
451
+ values_block = cleaned.substr(brace_open + 1, brace_close - brace_open - 1);
452
+ } else {
453
+ // Multi-line - collect from next lines
454
+ for (size_t j = i + 1; j < public_lines.size(); ++j) {
455
+ std::string next_line = trim(public_lines[j]);
456
+ size_t close_pos = next_line.find('}');
457
+ if (close_pos != std::string::npos) {
458
+ values_block += next_line.substr(0, close_pos);
459
+ i = j;
460
+ break;
461
+ } else {
462
+ values_block += next_line + " ";
463
+ }
464
+ }
465
+ }
466
+
467
+ // Parse enum values
468
+ std::istringstream vss(values_block);
469
+ std::string value;
470
+ while (vss >> value) {
471
+ if (!value.empty() && value.back() == ',') {
472
+ value.pop_back();
473
+ }
474
+ if (!value.empty()) {
475
+ eb.values.push_back(value);
476
+ }
477
+ }
478
+ }
479
+
480
+ desc.enums.push_back(eb);
481
+ }
482
+ }
383
483
  else if (cleaned.find("CLASS") != std::string::npos) {
384
484
  ClassBinding cb;
385
485
  cb.auto_bind_all = false;
@@ -672,6 +772,23 @@ ModuleDescriptor API::parse_cp_file(const std::string& filepath) {
672
772
  }
673
773
  }
674
774
  }
775
+ // v4.6.6: Parse FIELD_ARRAY(name, type, size) for C-style arrays
776
+ else if (ftrim.find("FIELD_ARRAY(") != std::string::npos) {
777
+ size_t f_start = ftrim.find('(');
778
+ size_t f_end = ftrim.find(')');
779
+ if (f_start != std::string::npos && f_end != std::string::npos) {
780
+ std::string field_content = ftrim.substr(f_start + 1, f_end - f_start - 1);
781
+ auto field_parts = split(field_content, ',');
782
+ if (field_parts.size() >= 3) {
783
+ FieldInfo fi;
784
+ fi.name = trim(field_parts[0]);
785
+ fi.type = trim(field_parts[1]);
786
+ fi.is_array = true;
787
+ fi.array_size = std::stoi(trim(field_parts[2]));
788
+ sb.fields.push_back(fi);
789
+ }
790
+ }
791
+ }
675
792
  // Parse FIELD(name) or FIELD(type, name)
676
793
  else if (ftrim.find("FIELD(") != std::string::npos) {
677
794
  size_t f_start = ftrim.find('(');
@@ -680,15 +797,18 @@ ModuleDescriptor API::parse_cp_file(const std::string& filepath) {
680
797
  std::string field_content = ftrim.substr(f_start + 1, f_end - f_start - 1);
681
798
  auto field_parts = split(field_content, ',');
682
799
 
800
+ FieldInfo fi;
683
801
  if (field_parts.size() >= 2) {
684
- std::string field_type = trim(field_parts[0]);
685
- std::string field_name = trim(field_parts[1]);
686
- sb.fields.push_back({field_type, field_name});
802
+ fi.type = trim(field_parts[0]);
803
+ fi.name = trim(field_parts[1]);
687
804
  } else if (field_parts.size() == 1) {
688
805
  // Simple FIELD(name) - type will be inferred
689
- std::string field_name = trim(field_parts[0]);
690
- sb.fields.push_back({"auto", field_name});
806
+ fi.type = "auto";
807
+ fi.name = trim(field_parts[0]);
691
808
  }
809
+ fi.is_array = false;
810
+ fi.array_size = 0;
811
+ sb.fields.push_back(fi);
692
812
  }
693
813
  }
694
814
  }
@@ -962,15 +1082,23 @@ std::string generate_struct_bindings(const StructBinding& sb, const ModuleDescri
962
1082
  }
963
1083
 
964
1084
  // Fields - readwrite access
965
- for (const auto& [field_type, field_name] : sb.fields) {
966
- std::string actual_type = field_type;
1085
+ // v4.6.6: Handle array fields with def_property
1086
+ for (const auto& fi : sb.fields) {
1087
+ std::string actual_type = fi.type;
967
1088
  // Replace template parameter T with actual type
968
1089
  if (actual_type == "T") {
969
1090
  actual_type = ttype;
970
1091
  }
971
1092
 
972
- code << " .def_readwrite(\"" << field_name << "\", &"
973
- << cpp_type << "::" << field_name << ")\n";
1093
+ if (fi.is_array) {
1094
+ // Array field: use def_property with lambda getter returning py::bytes
1095
+ code << " .def_property_readonly(\"" << fi.name << "\", [](" << cpp_type << "& self) {\n";
1096
+ code << " return py::bytes(reinterpret_cast<const char*>(self." << fi.name << "), " << fi.array_size << ");\n";
1097
+ code << " })\n";
1098
+ } else {
1099
+ code << " .def_readwrite(\"" << fi.name << "\", &"
1100
+ << cpp_type << "::" << fi.name << ")\n";
1101
+ }
974
1102
  }
975
1103
 
976
1104
  // v4.1.1: Generate method bindings
@@ -985,8 +1113,10 @@ std::string generate_struct_bindings(const StructBinding& sb, const ModuleDescri
985
1113
  // Auto-generate to_dict() method
986
1114
  code << " .def(\"to_dict\", [](" << cpp_type << "& self) {\n";
987
1115
  code << " py::dict d;\n";
988
- for (const auto& [field_type, field_name] : sb.fields) {
989
- code << " d[\"" << field_name << "\"] = self." << field_name << ";\n";
1116
+ for (const auto& fi : sb.fields) {
1117
+ if (!fi.is_array) {
1118
+ code << " d[\"" << fi.name << "\"] = self." << fi.name << ";\n";
1119
+ }
990
1120
  }
991
1121
  code << " return d;\n";
992
1122
  code << " })\n";
@@ -994,8 +1124,9 @@ std::string generate_struct_bindings(const StructBinding& sb, const ModuleDescri
994
1124
  // Auto-generate from_dict() static method
995
1125
  // v4.3.2: Check if all fields have known types (not "auto")
996
1126
  bool template_all_types_known = true;
997
- for (const auto& [field_type, field_name] : sb.fields) {
998
- std::string actual_type = field_type;
1127
+ for (const auto& fi : sb.fields) {
1128
+ if (fi.is_array) continue;
1129
+ std::string actual_type = fi.type;
999
1130
  if (actual_type == "T") actual_type = ttype;
1000
1131
  if (actual_type == "auto" || actual_type.empty()) {
1001
1132
  template_all_types_known = false;
@@ -1006,13 +1137,14 @@ std::string generate_struct_bindings(const StructBinding& sb, const ModuleDescri
1006
1137
  if (template_all_types_known && !sb.fields.empty()) {
1007
1138
  code << " .def_static(\"from_dict\", [](py::dict d) {\n";
1008
1139
  code << " " << cpp_type << " obj;\n";
1009
- for (const auto& [field_type, field_name] : sb.fields) {
1010
- std::string actual_type = field_type;
1140
+ for (const auto& fi : sb.fields) {
1141
+ if (fi.is_array) continue;
1142
+ std::string actual_type = fi.type;
1011
1143
  if (actual_type == "T") {
1012
1144
  actual_type = ttype;
1013
1145
  }
1014
1146
 
1015
- code << " obj." << field_name << " = d[\"" << field_name
1147
+ code << " obj." << fi.name << " = d[\"" << fi.name
1016
1148
  << "\"].cast<" << actual_type << ">();\n";
1017
1149
  }
1018
1150
  code << " return obj;\n";
@@ -1045,9 +1177,17 @@ std::string generate_struct_bindings(const StructBinding& sb, const ModuleDescri
1045
1177
  }
1046
1178
 
1047
1179
  // Fields
1048
- for (const auto& [field_type, field_name] : sb.fields) {
1049
- code << " .def_readwrite(\"" << field_name << "\", &"
1050
- << sb.struct_name << "::" << field_name << ")\n";
1180
+ // v4.6.6: Handle array fields with def_property
1181
+ for (const auto& fi : sb.fields) {
1182
+ if (fi.is_array) {
1183
+ // Array field: use def_property_readonly with lambda getter returning py::bytes
1184
+ code << " .def_property_readonly(\"" << fi.name << "\", [](" << sb.struct_name << "& self) {\n";
1185
+ code << " return py::bytes(reinterpret_cast<const char*>(self." << fi.name << "), " << fi.array_size << ");\n";
1186
+ code << " })\n";
1187
+ } else {
1188
+ code << " .def_readwrite(\"" << fi.name << "\", &"
1189
+ << sb.struct_name << "::" << fi.name << ")\n";
1190
+ }
1051
1191
  }
1052
1192
 
1053
1193
  // v4.1.1: Generate method bindings
@@ -1058,8 +1198,10 @@ std::string generate_struct_bindings(const StructBinding& sb, const ModuleDescri
1058
1198
  // Auto-generate to_dict() method
1059
1199
  code << " .def(\"to_dict\", [](" << sb.struct_name << "& self) {\n";
1060
1200
  code << " py::dict d;\n";
1061
- for (const auto& [field_type, field_name] : sb.fields) {
1062
- code << " d[\"" << field_name << "\"] = self." << field_name << ";\n";
1201
+ for (const auto& fi : sb.fields) {
1202
+ if (!fi.is_array) {
1203
+ code << " d[\"" << fi.name << "\"] = self." << fi.name << ";\n";
1204
+ }
1063
1205
  }
1064
1206
  code << " return d;\n";
1065
1207
  code << " })\n";
@@ -1067,8 +1209,9 @@ std::string generate_struct_bindings(const StructBinding& sb, const ModuleDescri
1067
1209
  // Auto-generate from_dict() static method
1068
1210
  // v4.3.2: Check if all fields have known types (not "auto")
1069
1211
  bool all_types_known = true;
1070
- for (const auto& [field_type, field_name] : sb.fields) {
1071
- if (field_type == "auto" || field_type.empty()) {
1212
+ for (const auto& fi : sb.fields) {
1213
+ if (fi.is_array) continue;
1214
+ if (fi.type == "auto" || fi.type.empty()) {
1072
1215
  all_types_known = false;
1073
1216
  break;
1074
1217
  }
@@ -1077,9 +1220,10 @@ std::string generate_struct_bindings(const StructBinding& sb, const ModuleDescri
1077
1220
  if (all_types_known && !sb.fields.empty()) {
1078
1221
  code << " .def_static(\"from_dict\", [](py::dict d) {\n";
1079
1222
  code << " " << sb.struct_name << " obj;\n";
1080
- for (const auto& [field_type, field_name] : sb.fields) {
1081
- code << " obj." << field_name << " = d[\"" << field_name
1082
- << "\"].cast<" << field_type << ">();\n";
1223
+ for (const auto& fi : sb.fields) {
1224
+ if (fi.is_array) continue;
1225
+ code << " obj." << fi.name << " = d[\"" << fi.name
1226
+ << "\"].cast<" << fi.type << ">();\n";
1083
1227
  }
1084
1228
  code << " return obj;\n";
1085
1229
  code << " })\n";
@@ -1156,6 +1300,22 @@ std::string API::generate_pybind11_code(const std::vector<ModuleDescriptor>& mod
1156
1300
  code << generate_struct_bindings(st, mod);
1157
1301
  }
1158
1302
 
1303
+ // v4.6.5: Generate enum bindings
1304
+ for (const auto& en : mod.enums) {
1305
+ code << " py::enum_<" << en.enum_name << ">(";
1306
+ code << mod.module_name << "_module, \"" << en.enum_name << "\")\n";
1307
+
1308
+ for (const auto& val : en.values) {
1309
+ code << " .value(\"" << val << "\", " << en.enum_name << "::" << val << ")\n";
1310
+ }
1311
+
1312
+ if (en.export_values) {
1313
+ code << " .export_values();\n\n";
1314
+ } else {
1315
+ code << " ;\n\n";
1316
+ }
1317
+ }
1318
+
1159
1319
  for (const auto& func : mod.functions) {
1160
1320
  if (func.is_template && !func.template_types.empty()) {
1161
1321
  for (const auto& ttype : func.template_types) {
@@ -1505,8 +1665,12 @@ std::string API::generate_registry_json(const std::vector<ModuleDescriptor>& mod
1505
1665
  }
1506
1666
  json << ",\n \"fields\": [\n";
1507
1667
  for (size_t k = 0; k < st.fields.size(); ++k) {
1508
- const auto& [type, name] = st.fields[k];
1509
- json << " {\"type\": \"" << type << "\", \"name\": \"" << name << "\"}";
1668
+ const auto& fi = st.fields[k];
1669
+ json << " {\"type\": \"" << fi.type << "\", \"name\": \"" << fi.name << "\"";
1670
+ if (fi.is_array) {
1671
+ json << ", \"is_array\": true, \"array_size\": " << fi.array_size;
1672
+ }
1673
+ json << "}";
1510
1674
  if (k < st.fields.size() - 1) json << ",";
1511
1675
  json << "\n";
1512
1676
  }
@@ -91,11 +91,14 @@ struct MethodSignature {
91
91
  };
92
92
 
93
93
  // v2.3.5: Field metadata
94
+ // v4.6.6: Added array support
94
95
  struct FieldInfo {
95
96
  std::string name;
96
97
  std::string type;
97
98
  bool is_static = false;
98
99
  bool is_const = false;
100
+ bool is_array = false; // v4.6.6: Is this a C-style array?
101
+ int array_size = 0; // v4.6.6: Size of array (0 if not array)
99
102
  std::string documentation;
100
103
  };
101
104
 
@@ -126,12 +129,22 @@ struct VariableBinding {
126
129
  std::string documentation; // Variable documentation from DOC()
127
130
  };
128
131
 
132
+ // v4.6.5: ENUM() Bindings for C++ enums
133
+ struct EnumBinding {
134
+ std::string module_name;
135
+ std::string enum_name;
136
+ std::vector<std::string> values; // Enum values to expose
137
+ bool export_values = true; // Call .export_values() to export to module scope
138
+ bool is_class_enum = false; // enum class vs plain enum
139
+ std::string documentation;
140
+ };
141
+
129
142
  // v2.0: STRUCT() Bindings for Plain-Old-Data types
130
143
  // v4.1.1: Added CONSTRUCTOR and METHOD support (same as CLASS)
131
144
  struct StructBinding {
132
145
  std::string module_name;
133
146
  std::string struct_name;
134
- std::vector<std::pair<std::string, std::string>> fields; // <type, name>
147
+ std::vector<FieldInfo> fields; // v4.6.6: Changed from pair to FieldInfo for array support
135
148
  std::vector<std::string> template_types; // For STRUCT(Point) TYPES(int, float)
136
149
  bool is_template = false;
137
150
  std::string documentation;
@@ -202,6 +215,7 @@ struct ModuleDescriptor {
202
215
  std::vector<ClassBinding> classes;
203
216
  std::vector<StructBinding> structs; // v2.0: NEW
204
217
  std::vector<VariableBinding> variables;
218
+ std::vector<EnumBinding> enums; // v4.6.5: NEW
205
219
 
206
220
  // Dependencies & Multi-Source (v2.0)
207
221
  std::vector<ModuleDependency> dependencies; // v2.0: NEW
@@ -15,4 +15,4 @@
15
15
  "enabled": true,
16
16
  "max_workers": 8
17
17
  }
18
- }
18
+ }
@@ -1202,5 +1202,168 @@
1202
1202
  "parameter.return(python::pythonize(${7}));$0"
1203
1203
  ],
1204
1204
  "description": "Create a class and export as Python object"
1205
+ },
1206
+
1207
+ "fmt::red": {
1208
+ "prefix": ["fmt::red", "fmtred"],
1209
+ "body": "fmt::red(${1:text})$0",
1210
+ "description": "Red colored text"
1211
+ },
1212
+ "fmt::green": {
1213
+ "prefix": ["fmt::green", "fmtgreen"],
1214
+ "body": "fmt::green(${1:text})$0",
1215
+ "description": "Green colored text"
1216
+ },
1217
+ "fmt::blue": {
1218
+ "prefix": ["fmt::blue", "fmtblue"],
1219
+ "body": "fmt::blue(${1:text})$0",
1220
+ "description": "Blue colored text"
1221
+ },
1222
+ "fmt::yellow": {
1223
+ "prefix": ["fmt::yellow", "fmtyellow"],
1224
+ "body": "fmt::yellow(${1:text})$0",
1225
+ "description": "Yellow colored text"
1226
+ },
1227
+ "fmt::cyan": {
1228
+ "prefix": ["fmt::cyan", "fmtcyan"],
1229
+ "body": "fmt::cyan(${1:text})$0",
1230
+ "description": "Cyan colored text"
1231
+ },
1232
+ "fmt::magenta": {
1233
+ "prefix": ["fmt::magenta", "fmtmagenta"],
1234
+ "body": "fmt::magenta(${1:text})$0",
1235
+ "description": "Magenta colored text"
1236
+ },
1237
+ "fmt::white": {
1238
+ "prefix": ["fmt::white", "fmtwhite"],
1239
+ "body": "fmt::white(${1:text})$0",
1240
+ "description": "White colored text"
1241
+ },
1242
+ "fmt::black": {
1243
+ "prefix": ["fmt::black", "fmtblack"],
1244
+ "body": "fmt::black(${1:text})$0",
1245
+ "description": "Black colored text"
1246
+ },
1247
+ "fmt::bold": {
1248
+ "prefix": ["fmt::bold", "fmtbold"],
1249
+ "body": "fmt::bold(${1:text})$0",
1250
+ "description": "Bold text"
1251
+ },
1252
+ "fmt::dim": {
1253
+ "prefix": ["fmt::dim", "fmtdim"],
1254
+ "body": "fmt::dim(${1:text})$0",
1255
+ "description": "Dim text"
1256
+ },
1257
+ "fmt::italic": {
1258
+ "prefix": ["fmt::italic", "fmtitalic"],
1259
+ "body": "fmt::italic(${1:text})$0",
1260
+ "description": "Italic text"
1261
+ },
1262
+ "fmt::underline": {
1263
+ "prefix": ["fmt::underline", "fmtunderline"],
1264
+ "body": "fmt::underline(${1:text})$0",
1265
+ "description": "Underlined text"
1266
+ },
1267
+ "fmt::blink": {
1268
+ "prefix": ["fmt::blink", "fmtblink"],
1269
+ "body": "fmt::blink(${1:text})$0",
1270
+ "description": "Blinking text"
1271
+ },
1272
+ "fmt::reverse": {
1273
+ "prefix": ["fmt::reverse", "fmtreverse"],
1274
+ "body": "fmt::reverse(${1:text})$0",
1275
+ "description": "Reversed color text"
1276
+ },
1277
+ "fmt::bright_red": {
1278
+ "prefix": "fmt::bright_red",
1279
+ "body": "fmt::bright_red(${1:text})$0",
1280
+ "description": "Bright red colored text"
1281
+ },
1282
+ "fmt::bright_green": {
1283
+ "prefix": "fmt::bright_green",
1284
+ "body": "fmt::bright_green(${1:text})$0",
1285
+ "description": "Bright green colored text"
1286
+ },
1287
+ "fmt::bright_blue": {
1288
+ "prefix": "fmt::bright_blue",
1289
+ "body": "fmt::bright_blue(${1:text})$0",
1290
+ "description": "Bright blue colored text"
1291
+ },
1292
+ "fmt::bright_yellow": {
1293
+ "prefix": "fmt::bright_yellow",
1294
+ "body": "fmt::bright_yellow(${1:text})$0",
1295
+ "description": "Bright yellow colored text"
1296
+ },
1297
+ "fmt::bright_cyan": {
1298
+ "prefix": "fmt::bright_cyan",
1299
+ "body": "fmt::bright_cyan(${1:text})$0",
1300
+ "description": "Bright cyan colored text"
1301
+ },
1302
+ "fmt::bright_magenta": {
1303
+ "prefix": "fmt::bright_magenta",
1304
+ "body": "fmt::bright_magenta(${1:text})$0",
1305
+ "description": "Bright magenta colored text"
1306
+ },
1307
+ "fmt::color": {
1308
+ "prefix": ["fmt::color", "fmtcolor"],
1309
+ "body": "fmt::color(${1:text}, ${2:\"green\"}, ${3:\"black\"})$0",
1310
+ "description": "Custom foreground and background color"
1311
+ },
1312
+ "fmt::rgb": {
1313
+ "prefix": ["fmt::rgb", "fmtrgb"],
1314
+ "body": "fmt::rgb(${1:text}, ${2:255}, ${3:128}, ${4:0})$0",
1315
+ "description": "24-bit RGB color"
1316
+ },
1317
+ "fmt::hex": {
1318
+ "prefix": ["fmt::hex", "fmthex"],
1319
+ "body": "fmt::hex(${1:text}, ${2:\"#ff8800\"})$0",
1320
+ "description": "Hex color code"
1321
+ },
1322
+ "fmt::reset": {
1323
+ "prefix": "fmt::reset",
1324
+ "body": "fmt::reset()$0",
1325
+ "description": "ANSI reset code"
1326
+ },
1327
+ "fmt::strip": {
1328
+ "prefix": "fmt::strip",
1329
+ "body": "fmt::strip(${1:text})$0",
1330
+ "description": "Strip all ANSI codes from text"
1331
+ },
1332
+
1333
+ "Namespace Definition": {
1334
+ "prefix": ["namespace", "ns"],
1335
+ "body": [
1336
+ "namespace ${1:mylib} {",
1337
+ "\t// Functions",
1338
+ "\t${2:void} ${3:myFunc}(${4:params}) {",
1339
+ "\t\t$0",
1340
+ "\t}",
1341
+ "}"
1342
+ ],
1343
+ "description": "Create a namespace with functions accessible via mylib::myFunc()"
1344
+ },
1345
+ "Namespace with Class": {
1346
+ "prefix": ["namespace-class", "nsclass"],
1347
+ "body": [
1348
+ "namespace ${1:mylib} {",
1349
+ "\tclass ${2:MyClass} {",
1350
+ "\t\t${3:string} ${4:value};",
1351
+ "\t\t",
1352
+ "\t\t${2}(${5:params}) {",
1353
+ "\t\t\tthis->${4} = ${6:initialValue};",
1354
+ "\t\t}",
1355
+ "\t\t",
1356
+ "\t\t${7:void} ${8:method}() {",
1357
+ "\t\t\t$0",
1358
+ "\t\t}",
1359
+ "\t}",
1360
+ "}"
1361
+ ],
1362
+ "description": "Create a namespace with a class accessible via mylib::MyClass"
1363
+ },
1364
+ "Namespace Function Call": {
1365
+ "prefix": ["ns::", "namespace::"],
1366
+ "body": "${1:namespace}::${2:function}(${3:args})$0",
1367
+ "description": "Call a namespaced function"
1205
1368
  }
1206
1369
  }