easycoder 260320.2__tar.gz → 260321.16__tar.gz

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 (322) hide show
  1. {easycoder-260320.2 → easycoder-260321.16}/PKG-INFO +1 -1
  2. {easycoder-260320.2 → easycoder-260321.16}/easycoder/__init__.py +1 -1
  3. {easycoder-260320.2 → easycoder-260321.16}/easycoder/ec_core.py +27 -10
  4. {easycoder-260320.2 → easycoder-260321.16}/easycoder/ec_mqtt.py +2 -2
  5. {easycoder-260320.2 → easycoder-260321.16}/easycoder/ec_program.py +6 -2
  6. easycoder-260320.2/lsp/.vscode/launch.json +0 -39
  7. easycoder-260320.2/lsp/.vscode/tasks.json +0 -22
  8. easycoder-260320.2/lsp/LSP_ARCHITECTURE.md +0 -430
  9. easycoder-260320.2/lsp/QUICK_START.md +0 -132
  10. easycoder-260320.2/lsp/client/out/extension.d.ts +0 -3
  11. easycoder-260320.2/lsp/client/out/extension.js +0 -106
  12. easycoder-260320.2/lsp/client/package-lock.json +0 -140
  13. easycoder-260320.2/lsp/client/package.json +0 -27
  14. easycoder-260320.2/lsp/client/src/extension.ts +0 -93
  15. easycoder-260320.2/lsp/client/tsconfig.json +0 -17
  16. easycoder-260320.2/lsp/package-lock.json +0 -51
  17. easycoder-260320.2/lsp/package.json +0 -85
  18. easycoder-260320.2/lsp/requirements.txt +0 -2
  19. easycoder-260320.2/lsp/server.py +0 -557
  20. easycoder-260320.2/lsp/syntaxes/easycoder.configuration.json +0 -22
  21. easycoder-260320.2/lsp/test_server.py +0 -332
  22. {easycoder-260320.2 → easycoder-260321.16}/.github/copilot-instructions.md +0 -0
  23. {easycoder-260320.2 → easycoder-260321.16}/.github/workflows/conformance-report.yml +0 -0
  24. {easycoder-260320.2 → easycoder-260321.16}/.gitignore +0 -0
  25. {easycoder-260320.2 → easycoder-260321.16}/.vscode/EXTENSION_GUIDE.md +0 -0
  26. {easycoder-260320.2 → easycoder-260321.16}/.vscode/PYTHON_SETUP.md +0 -0
  27. {easycoder-260320.2 → easycoder-260321.16}/.vscode/easycoder/README.md +0 -0
  28. {easycoder-260320.2 → easycoder-260321.16}/.vscode/easycoder/language-configuration.json +0 -0
  29. {easycoder-260320.2 → easycoder-260321.16}/.vscode/easycoder/package.json +0 -0
  30. {easycoder-260320.2 → easycoder-260321.16}/.vscode/easycoder/snippets/easycoder.json +0 -0
  31. {easycoder-260320.2 → easycoder-260321.16}/.vscode/easycoder/syntaxes/easycoder.tmLanguage.json +0 -0
  32. {easycoder-260320.2 → easycoder-260321.16}/.vscode/launch.json +0 -0
  33. {easycoder-260320.2 → easycoder-260321.16}/.vscode/settings.json +0 -0
  34. {easycoder-260320.2 → easycoder-260321.16}/AI/ARCHITECTURE.md +0 -0
  35. {easycoder-260320.2 → easycoder-260321.16}/AI/EASYCODER_AND_WEBSON.md +0 -0
  36. {easycoder-260320.2 → easycoder-260321.16}/AI/EXAMPLES.md +0 -0
  37. {easycoder-260320.2 → easycoder-260321.16}/AI/PROJECT_OVERVIEW.md +0 -0
  38. {easycoder-260320.2 → easycoder-260321.16}/AI/README.md +0 -0
  39. {easycoder-260320.2 → easycoder-260321.16}/AI/WORKING_RULES.md +0 -0
  40. {easycoder-260320.2 → easycoder-260321.16}/AI/articles/Arrays and Modules.md +0 -0
  41. {easycoder-260320.2 → easycoder-260321.16}/AI/examples/primes/primes.ecs +0 -0
  42. {easycoder-260320.2 → easycoder-260321.16}/AI/examples/primes/primes.md +0 -0
  43. {easycoder-260320.2 → easycoder-260321.16}/AI/examples/wordlist/wordlist.ecs +0 -0
  44. {easycoder-260320.2 → easycoder-260321.16}/AI/examples/wordlist/wordlist.md +0 -0
  45. {easycoder-260320.2 → easycoder-260321.16}/AI/log/CONTRIBUTING.md +0 -0
  46. {easycoder-260320.2 → easycoder-260321.16}/AI/log/DEVELOPER_RESOURCES.md +0 -0
  47. {easycoder-260320.2 → easycoder-260321.16}/AI/log/GRAPHICS_PHASE1.md +0 -0
  48. {easycoder-260320.2 → easycoder-260321.16}/AI/log/PHASE1_COMPLETION_SUMMARY.md +0 -0
  49. {easycoder-260320.2 → easycoder-260321.16}/AI/log/PHASE_1_3_COMPLETION_REPORT.md +0 -0
  50. {easycoder-260320.2 → easycoder-260321.16}/AI/log/PHASE_4_COMPLETION_REPORT.md +0 -0
  51. {easycoder-260320.2 → easycoder-260321.16}/AI/log/PLUGIN_PATTERNS.md +0 -0
  52. {easycoder-260320.2 → easycoder-260321.16}/AI/log/PROJECT_COMPLETION_SUMMARY.md +0 -0
  53. {easycoder-260320.2 → easycoder-260321.16}/AI/log/START_HERE.md +0 -0
  54. {easycoder-260320.2 → easycoder-260321.16}/AI/log/SYNTAX_REFACTORING.md +0 -0
  55. {easycoder-260320.2 → easycoder-260321.16}/LICENSE +0 -0
  56. {easycoder-260320.2 → easycoder-260321.16}/README.md +0 -0
  57. {easycoder-260320.2 → easycoder-260321.16}/RELEASE_NOTES.md +0 -0
  58. {easycoder-260320.2 → easycoder-260321.16}/backdrop.jpg +0 -0
  59. {easycoder-260320.2 → easycoder-260321.16}/basic.py +0 -0
  60. {easycoder-260320.2 → easycoder-260321.16}/conformance/README.md +0 -0
  61. {easycoder-260320.2 → easycoder-260321.16}/conformance/actuals-python-cli.json +0 -0
  62. {easycoder-260320.2 → easycoder-260321.16}/conformance/ec_py_runner.py +0 -0
  63. {easycoder-260320.2 → easycoder-260321.16}/conformance/parity-report-template.json +0 -0
  64. {easycoder-260320.2 → easycoder-260321.16}/conformance/parity-report.generated.json +0 -0
  65. {easycoder-260320.2 → easycoder-260321.16}/conformance/parity-report.initial.json +0 -0
  66. {easycoder-260320.2 → easycoder-260321.16}/conformance/plugin-interface-matrix.json +0 -0
  67. {easycoder-260320.2 → easycoder-260321.16}/conformance/run_conformance.py +0 -0
  68. {easycoder-260320.2 → easycoder-260321.16}/conformance/runner-contract.md +0 -0
  69. {easycoder-260320.2 → easycoder-260321.16}/conformance/tests/EC-0001-basic-assignment.ecs +0 -0
  70. {easycoder-260320.2 → easycoder-260321.16}/conformance/tests/EC-0001-basic-assignment.json +0 -0
  71. {easycoder-260320.2 → easycoder-260321.16}/conformance/tests/EC-0002-arithmetic-chain.ecs +0 -0
  72. {easycoder-260320.2 → easycoder-260321.16}/conformance/tests/EC-0002-arithmetic-chain.json +0 -0
  73. {easycoder-260320.2 → easycoder-260321.16}/conformance/tests/EC-0003-condition-branch.ecs +0 -0
  74. {easycoder-260320.2 → easycoder-260321.16}/conformance/tests/EC-0003-condition-branch.json +0 -0
  75. {easycoder-260320.2 → easycoder-260321.16}/conformance/tests/EC-0004-while-sum.ecs +0 -0
  76. {easycoder-260320.2 → easycoder-260321.16}/conformance/tests/EC-0004-while-sum.json +0 -0
  77. {easycoder-260320.2 → easycoder-260321.16}/conformance/tests/EC-0005-array-index-access.ecs +0 -0
  78. {easycoder-260320.2 → easycoder-260321.16}/conformance/tests/EC-0005-array-index-access.json +0 -0
  79. {easycoder-260320.2 → easycoder-260321.16}/conformance/tests/EC-0006-and-or-conditions.ecs +0 -0
  80. {easycoder-260320.2 → easycoder-260321.16}/conformance/tests/EC-0006-and-or-conditions.json +0 -0
  81. {easycoder-260320.2 → easycoder-260321.16}/conformance/tests/EC-0007-includes-membership.ecs +0 -0
  82. {easycoder-260320.2 → easycoder-260321.16}/conformance/tests/EC-0007-includes-membership.json +0 -0
  83. {easycoder-260320.2 → easycoder-260321.16}/conformance/tests/index.json +0 -0
  84. {easycoder-260320.2 → easycoder-260321.16}/doc/README.md +0 -0
  85. {easycoder-260320.2 → easycoder-260321.16}/doc/RESERVED_STEMS.md +0 -0
  86. {easycoder-260320.2 → easycoder-260321.16}/doc/core/README.md +0 -0
  87. {easycoder-260320.2 → easycoder-260321.16}/doc/core/conditions/boolean.md +0 -0
  88. {easycoder-260320.2 → easycoder-260321.16}/doc/core/conditions/empty.md +0 -0
  89. {easycoder-260320.2 → easycoder-260321.16}/doc/core/conditions/ends.md +0 -0
  90. {easycoder-260320.2 → easycoder-260321.16}/doc/core/conditions/even.md +0 -0
  91. {easycoder-260320.2 → easycoder-260321.16}/doc/core/conditions/exists.md +0 -0
  92. {easycoder-260320.2 → easycoder-260321.16}/doc/core/conditions/greater.md +0 -0
  93. {easycoder-260320.2 → easycoder-260321.16}/doc/core/conditions/hasProperty.md +0 -0
  94. {easycoder-260320.2 → easycoder-260321.16}/doc/core/conditions/includes.md +0 -0
  95. {easycoder-260320.2 → easycoder-260321.16}/doc/core/conditions/is.md +0 -0
  96. {easycoder-260320.2 → easycoder-260321.16}/doc/core/conditions/less.md +0 -0
  97. {easycoder-260320.2 → easycoder-260321.16}/doc/core/conditions/list.md +0 -0
  98. {easycoder-260320.2 → easycoder-260321.16}/doc/core/conditions/none.md +0 -0
  99. {easycoder-260320.2 → easycoder-260321.16}/doc/core/conditions/not.md +0 -0
  100. {easycoder-260320.2 → easycoder-260321.16}/doc/core/conditions/numeric.md +0 -0
  101. {easycoder-260320.2 → easycoder-260321.16}/doc/core/conditions/object.md +0 -0
  102. {easycoder-260320.2 → easycoder-260321.16}/doc/core/conditions/odd.md +0 -0
  103. {easycoder-260320.2 → easycoder-260321.16}/doc/core/conditions/starts.md +0 -0
  104. {easycoder-260320.2 → easycoder-260321.16}/doc/core/conditions/string.md +0 -0
  105. {easycoder-260320.2 → easycoder-260321.16}/doc/core/keywords/add.md +0 -0
  106. {easycoder-260320.2 → easycoder-260321.16}/doc/core/keywords/append.md +0 -0
  107. {easycoder-260320.2 → easycoder-260321.16}/doc/core/keywords/assert.md +0 -0
  108. {easycoder-260320.2 → easycoder-260321.16}/doc/core/keywords/begin.md +0 -0
  109. {easycoder-260320.2 → easycoder-260321.16}/doc/core/keywords/clear.md +0 -0
  110. {easycoder-260320.2 → easycoder-260321.16}/doc/core/keywords/close.md +0 -0
  111. {easycoder-260320.2 → easycoder-260321.16}/doc/core/keywords/create.md +0 -0
  112. {easycoder-260320.2 → easycoder-260321.16}/doc/core/keywords/debug.md +0 -0
  113. {easycoder-260320.2 → easycoder-260321.16}/doc/core/keywords/decrement.md +0 -0
  114. {easycoder-260320.2 → easycoder-260321.16}/doc/core/keywords/delete.md +0 -0
  115. {easycoder-260320.2 → easycoder-260321.16}/doc/core/keywords/divide.md +0 -0
  116. {easycoder-260320.2 → easycoder-260321.16}/doc/core/keywords/download.md +0 -0
  117. {easycoder-260320.2 → easycoder-260321.16}/doc/core/keywords/exit.md +0 -0
  118. {easycoder-260320.2 → easycoder-260321.16}/doc/core/keywords/file.md +0 -0
  119. {easycoder-260320.2 → easycoder-260321.16}/doc/core/keywords/fork.md +0 -0
  120. {easycoder-260320.2 → easycoder-260321.16}/doc/core/keywords/get.md +0 -0
  121. {easycoder-260320.2 → easycoder-260321.16}/doc/core/keywords/go.md +0 -0
  122. {easycoder-260320.2 → easycoder-260321.16}/doc/core/keywords/gosub.md +0 -0
  123. {easycoder-260320.2 → easycoder-260321.16}/doc/core/keywords/if.md +0 -0
  124. {easycoder-260320.2 → easycoder-260321.16}/doc/core/keywords/import.md +0 -0
  125. {easycoder-260320.2 → easycoder-260321.16}/doc/core/keywords/increment.md +0 -0
  126. {easycoder-260320.2 → easycoder-260321.16}/doc/core/keywords/index.md +0 -0
  127. {easycoder-260320.2 → easycoder-260321.16}/doc/core/keywords/init.md +0 -0
  128. {easycoder-260320.2 → easycoder-260321.16}/doc/core/keywords/input.md +0 -0
  129. {easycoder-260320.2 → easycoder-260321.16}/doc/core/keywords/load.md +0 -0
  130. {easycoder-260320.2 → easycoder-260321.16}/doc/core/keywords/lock.md +0 -0
  131. {easycoder-260320.2 → easycoder-260321.16}/doc/core/keywords/log.md +0 -0
  132. {easycoder-260320.2 → easycoder-260321.16}/doc/core/keywords/module.md +0 -0
  133. {easycoder-260320.2 → easycoder-260321.16}/doc/core/keywords/multiply.md +0 -0
  134. {easycoder-260320.2 → easycoder-260321.16}/doc/core/keywords/negate.md +0 -0
  135. {easycoder-260320.2 → easycoder-260321.16}/doc/core/keywords/on.md +0 -0
  136. {easycoder-260320.2 → easycoder-260321.16}/doc/core/keywords/open.md +0 -0
  137. {easycoder-260320.2 → easycoder-260321.16}/doc/core/keywords/pass.md +0 -0
  138. {easycoder-260320.2 → easycoder-260321.16}/doc/core/keywords/pop.md +0 -0
  139. {easycoder-260320.2 → easycoder-260321.16}/doc/core/keywords/post.md +0 -0
  140. {easycoder-260320.2 → easycoder-260321.16}/doc/core/keywords/print.md +0 -0
  141. {easycoder-260320.2 → easycoder-260321.16}/doc/core/keywords/push.md +0 -0
  142. {easycoder-260320.2 → easycoder-260321.16}/doc/core/keywords/put.md +0 -0
  143. {easycoder-260320.2 → easycoder-260321.16}/doc/core/keywords/read.md +0 -0
  144. {easycoder-260320.2 → easycoder-260321.16}/doc/core/keywords/release.md +0 -0
  145. {easycoder-260320.2 → easycoder-260321.16}/doc/core/keywords/replace.md +0 -0
  146. {easycoder-260320.2 → easycoder-260321.16}/doc/core/keywords/return.md +0 -0
  147. {easycoder-260320.2 → easycoder-260321.16}/doc/core/keywords/run.md +0 -0
  148. {easycoder-260320.2 → easycoder-260321.16}/doc/core/keywords/save.md +0 -0
  149. {easycoder-260320.2 → easycoder-260321.16}/doc/core/keywords/script.md +0 -0
  150. {easycoder-260320.2 → easycoder-260321.16}/doc/core/keywords/send.md +0 -0
  151. {easycoder-260320.2 → easycoder-260321.16}/doc/core/keywords/set.md +0 -0
  152. {easycoder-260320.2 → easycoder-260321.16}/doc/core/keywords/shuffle.md +0 -0
  153. {easycoder-260320.2 → easycoder-260321.16}/doc/core/keywords/split.md +0 -0
  154. {easycoder-260320.2 → easycoder-260321.16}/doc/core/keywords/stack.md +0 -0
  155. {easycoder-260320.2 → easycoder-260321.16}/doc/core/keywords/stop.md +0 -0
  156. {easycoder-260320.2 → easycoder-260321.16}/doc/core/keywords/system.md +0 -0
  157. {easycoder-260320.2 → easycoder-260321.16}/doc/core/keywords/take.md +0 -0
  158. {easycoder-260320.2 → easycoder-260321.16}/doc/core/keywords/toggle.md +0 -0
  159. {easycoder-260320.2 → easycoder-260321.16}/doc/core/keywords/trim.md +0 -0
  160. {easycoder-260320.2 → easycoder-260321.16}/doc/core/keywords/truncate.md +0 -0
  161. {easycoder-260320.2 → easycoder-260321.16}/doc/core/keywords/unlock.md +0 -0
  162. {easycoder-260320.2 → easycoder-260321.16}/doc/core/keywords/use.md +0 -0
  163. {easycoder-260320.2 → easycoder-260321.16}/doc/core/keywords/variable.md +0 -0
  164. {easycoder-260320.2 → easycoder-260321.16}/doc/core/keywords/wait.md +0 -0
  165. {easycoder-260320.2 → easycoder-260321.16}/doc/core/keywords/while.md +0 -0
  166. {easycoder-260320.2 → easycoder-260321.16}/doc/core/keywords/write.md +0 -0
  167. {easycoder-260320.2 → easycoder-260321.16}/doc/core/values/arg.md +0 -0
  168. {easycoder-260320.2 → easycoder-260321.16}/doc/core/values/args.md +0 -0
  169. {easycoder-260320.2 → easycoder-260321.16}/doc/core/values/cat.md +0 -0
  170. {easycoder-260320.2 → easycoder-260321.16}/doc/core/values/cos.md +0 -0
  171. {easycoder-260320.2 → easycoder-260321.16}/doc/core/values/datime.md +0 -0
  172. {easycoder-260320.2 → easycoder-260321.16}/doc/core/values/decode.md +0 -0
  173. {easycoder-260320.2 → easycoder-260321.16}/doc/core/values/element.md +0 -0
  174. {easycoder-260320.2 → easycoder-260321.16}/doc/core/values/elements.md +0 -0
  175. {easycoder-260320.2 → easycoder-260321.16}/doc/core/values/empty.md +0 -0
  176. {easycoder-260320.2 → easycoder-260321.16}/doc/core/values/encode.md +0 -0
  177. {easycoder-260320.2 → easycoder-260321.16}/doc/core/values/error.md +0 -0
  178. {easycoder-260320.2 → easycoder-260321.16}/doc/core/values/files.md +0 -0
  179. {easycoder-260320.2 → easycoder-260321.16}/doc/core/values/float.md +0 -0
  180. {easycoder-260320.2 → easycoder-260321.16}/doc/core/values/from.md +0 -0
  181. {easycoder-260320.2 → easycoder-260321.16}/doc/core/values/hash.md +0 -0
  182. {easycoder-260320.2 → easycoder-260321.16}/doc/core/values/index.md +0 -0
  183. {easycoder-260320.2 → easycoder-260321.16}/doc/core/values/integer.md +0 -0
  184. {easycoder-260320.2 → easycoder-260321.16}/doc/core/values/json.md +0 -0
  185. {easycoder-260320.2 → easycoder-260321.16}/doc/core/values/keys.md +0 -0
  186. {easycoder-260320.2 → easycoder-260321.16}/doc/core/values/left.md +0 -0
  187. {easycoder-260320.2 → easycoder-260321.16}/doc/core/values/length.md +0 -0
  188. {easycoder-260320.2 → easycoder-260321.16}/doc/core/values/lowercase.md +0 -0
  189. {easycoder-260320.2 → easycoder-260321.16}/doc/core/values/memory.md +0 -0
  190. {easycoder-260320.2 → easycoder-260321.16}/doc/core/values/modification.md +0 -0
  191. {easycoder-260320.2 → easycoder-260321.16}/doc/core/values/modulo.md +0 -0
  192. {easycoder-260320.2 → easycoder-260321.16}/doc/core/values/newline.md +0 -0
  193. {easycoder-260320.2 → easycoder-260321.16}/doc/core/values/now.md +0 -0
  194. {easycoder-260320.2 → easycoder-260321.16}/doc/core/values/operations.md +0 -0
  195. {easycoder-260320.2 → easycoder-260321.16}/doc/core/values/position.md +0 -0
  196. {easycoder-260320.2 → easycoder-260321.16}/doc/core/values/property.md +0 -0
  197. {easycoder-260320.2 → easycoder-260321.16}/doc/core/values/random.md +0 -0
  198. {easycoder-260320.2 → easycoder-260321.16}/doc/core/values/right.md +0 -0
  199. {easycoder-260320.2 → easycoder-260321.16}/doc/core/values/sin.md +0 -0
  200. {easycoder-260320.2 → easycoder-260321.16}/doc/core/values/stringify.md +0 -0
  201. {easycoder-260320.2 → easycoder-260321.16}/doc/core/values/tab.md +0 -0
  202. {easycoder-260320.2 → easycoder-260321.16}/doc/core/values/tan.md +0 -0
  203. {easycoder-260320.2 → easycoder-260321.16}/doc/core/values/timestamp.md +0 -0
  204. {easycoder-260320.2 → easycoder-260321.16}/doc/core/values/today.md +0 -0
  205. {easycoder-260320.2 → easycoder-260321.16}/doc/core/values/trim.md +0 -0
  206. {easycoder-260320.2 → easycoder-260321.16}/doc/core/values/type.md +0 -0
  207. {easycoder-260320.2 → easycoder-260321.16}/doc/core/values/uppercase.md +0 -0
  208. {easycoder-260320.2 → easycoder-260321.16}/doc/core/values/value.md +0 -0
  209. {easycoder-260320.2 → easycoder-260321.16}/doc/core/values/weekday.md +0 -0
  210. {easycoder-260320.2 → easycoder-260321.16}/doc/graphics/PATTERNS.md +0 -0
  211. {easycoder-260320.2 → easycoder-260321.16}/doc/graphics/README.md +0 -0
  212. {easycoder-260320.2 → easycoder-260321.16}/doc/graphics/keywords/add.md +0 -0
  213. {easycoder-260320.2 → easycoder-260321.16}/doc/graphics/keywords/attach.md +0 -0
  214. {easycoder-260320.2 → easycoder-260321.16}/doc/graphics/keywords/center.md +0 -0
  215. {easycoder-260320.2 → easycoder-260321.16}/doc/graphics/keywords/checkbox.md +0 -0
  216. {easycoder-260320.2 → easycoder-260321.16}/doc/graphics/keywords/clear.md +0 -0
  217. {easycoder-260320.2 → easycoder-260321.16}/doc/graphics/keywords/close.md +0 -0
  218. {easycoder-260320.2 → easycoder-260321.16}/doc/graphics/keywords/combobox.md +0 -0
  219. {easycoder-260320.2 → easycoder-260321.16}/doc/graphics/keywords/create.md +0 -0
  220. {easycoder-260320.2 → easycoder-260321.16}/doc/graphics/keywords/dialog.md +0 -0
  221. {easycoder-260320.2 → easycoder-260321.16}/doc/graphics/keywords/disable.md +0 -0
  222. {easycoder-260320.2 → easycoder-260321.16}/doc/graphics/keywords/enable.md +0 -0
  223. {easycoder-260320.2 → easycoder-260321.16}/doc/graphics/keywords/group.md +0 -0
  224. {easycoder-260320.2 → easycoder-260321.16}/doc/graphics/keywords/hide.md +0 -0
  225. {easycoder-260320.2 → easycoder-260321.16}/doc/graphics/keywords/label.md +0 -0
  226. {easycoder-260320.2 → easycoder-260321.16}/doc/graphics/keywords/layout.md +0 -0
  227. {easycoder-260320.2 → easycoder-260321.16}/doc/graphics/keywords/lineinput.md +0 -0
  228. {easycoder-260320.2 → easycoder-260321.16}/doc/graphics/keywords/listbox.md +0 -0
  229. {easycoder-260320.2 → easycoder-260321.16}/doc/graphics/keywords/messagebox.md +0 -0
  230. {easycoder-260320.2 → easycoder-260321.16}/doc/graphics/keywords/move.md +0 -0
  231. {easycoder-260320.2 → easycoder-260321.16}/doc/graphics/keywords/multiline.md +0 -0
  232. {easycoder-260320.2 → easycoder-260321.16}/doc/graphics/keywords/on.md +0 -0
  233. {easycoder-260320.2 → easycoder-260321.16}/doc/graphics/keywords/pushbutton.md +0 -0
  234. {easycoder-260320.2 → easycoder-260321.16}/doc/graphics/keywords/remove.md +0 -0
  235. {easycoder-260320.2 → easycoder-260321.16}/doc/graphics/keywords/select.md +0 -0
  236. {easycoder-260320.2 → easycoder-260321.16}/doc/graphics/keywords/set.md +0 -0
  237. {easycoder-260320.2 → easycoder-260321.16}/doc/graphics/keywords/window.md +0 -0
  238. {easycoder-260320.2 → easycoder-260321.16}/doc/graphics/values/attribute.md +0 -0
  239. {easycoder-260320.2 → easycoder-260321.16}/doc/graphics/values/window.md +0 -0
  240. {easycoder-260320.2 → easycoder-260321.16}/easycoder/debugger/__init__.py +0 -0
  241. {easycoder-260320.2 → easycoder-260321.16}/easycoder/debugger/ec_dbg_value_display copy.py +0 -0
  242. {easycoder-260320.2 → easycoder-260321.16}/easycoder/debugger/ec_dbg_value_display.py +0 -0
  243. {easycoder-260320.2 → easycoder-260321.16}/easycoder/debugger/ec_dbg_watch_list copy.py +0 -0
  244. {easycoder-260320.2 → easycoder-260321.16}/easycoder/debugger/ec_dbg_watchlist.py +0 -0
  245. {easycoder-260320.2 → easycoder-260321.16}/easycoder/debugger/ec_debug.py +0 -0
  246. {easycoder-260320.2 → easycoder-260321.16}/easycoder/ec_border.py +0 -0
  247. {easycoder-260320.2 → easycoder-260321.16}/easycoder/ec_classes.py +0 -0
  248. {easycoder-260320.2 → easycoder-260321.16}/easycoder/ec_compiler.py +0 -0
  249. {easycoder-260320.2 → easycoder-260321.16}/easycoder/ec_condition.py +0 -0
  250. {easycoder-260320.2 → easycoder-260321.16}/easycoder/ec_gclasses.py +0 -0
  251. {easycoder-260320.2 → easycoder-260321.16}/easycoder/ec_graphics.py +0 -0
  252. {easycoder-260320.2 → easycoder-260321.16}/easycoder/ec_handler.py +0 -0
  253. {easycoder-260320.2 → easycoder-260321.16}/easycoder/ec_keyboard.py +0 -0
  254. {easycoder-260320.2 → easycoder-260321.16}/easycoder/ec_psutil.py +0 -0
  255. {easycoder-260320.2 → easycoder-260321.16}/easycoder/ec_server.py +0 -0
  256. {easycoder-260320.2 → easycoder-260321.16}/easycoder/ec_timestamp.py +0 -0
  257. {easycoder-260320.2 → easycoder-260321.16}/easycoder/ec_value.py +0 -0
  258. {easycoder-260320.2 → easycoder-260321.16}/easycoder/icons/close.png +0 -0
  259. {easycoder-260320.2 → easycoder-260321.16}/easycoder/icons/exit.png +0 -0
  260. {easycoder-260320.2 → easycoder-260321.16}/easycoder/icons/run.png +0 -0
  261. {easycoder-260320.2 → easycoder-260321.16}/easycoder/icons/step.png +0 -0
  262. {easycoder-260320.2 → easycoder-260321.16}/easycoder/icons/stop.png +0 -0
  263. {easycoder-260320.2 → easycoder-260321.16}/easycoder/icons/tick.png +0 -0
  264. {easycoder-260320.2 → easycoder-260321.16}/easycoder/mqtt_listener.py +0 -0
  265. {easycoder-260320.2 → easycoder-260321.16}/easycoder/mqtt_publisher.py +0 -0
  266. {easycoder-260320.2/lsp/syntaxes → easycoder-260321.16}/easycoder.tmLanguage.json +0 -0
  267. {easycoder-260320.2 → easycoder-260321.16}/flash.py +0 -0
  268. {easycoder-260320.2 → easycoder-260321.16}/images/Semoigo Dawn.jpg +0 -0
  269. {easycoder-260320.2 → easycoder-260321.16}/json/graphics-demo.json +0 -0
  270. {easycoder-260320.2 → easycoder-260321.16}/mqtt_listen.py +0 -0
  271. {easycoder-260320.2 → easycoder-260321.16}/mqtt_publish.py +0 -0
  272. {easycoder-260320.2 → easycoder-260321.16}/mqtt_test.html +0 -0
  273. {easycoder-260320.2 → easycoder-260321.16}/plugins/ec_p100.py +0 -0
  274. {easycoder-260320.2 → easycoder-260321.16}/plugins/ec_points.py +0 -0
  275. {easycoder-260320.2 → easycoder-260321.16}/plugins/ec_sql.py +0 -0
  276. {easycoder-260320.2 → easycoder-260321.16}/pyproject.toml +0 -0
  277. {easycoder-260320.2 → easycoder-260321.16}/spec/README.md +0 -0
  278. {easycoder-260320.2 → easycoder-260321.16}/spec/easycoder-language-contract.md +0 -0
  279. {easycoder-260320.2 → easycoder-260321.16}/spec/easycoder-plugin-contract.md +0 -0
  280. {easycoder-260320.2 → easycoder-260321.16}/spec/easycoder-versioning-policy.md +0 -0
  281. {easycoder-260320.2 → easycoder-260321.16}/test.py +0 -0
  282. {easycoder-260320.2 → easycoder-260321.16}/testController.py +0 -0
  283. {easycoder-260320.2 → easycoder-260321.16}/testDoclets.py +0 -0
  284. {easycoder-260320.2 → easycoder-260321.16}/testServer.py +0 -0
  285. {easycoder-260320.2 → easycoder-260321.16}/test_debug_graphics.py +0 -0
  286. {easycoder-260320.2 → easycoder-260321.16}/test_debug_launch.py +0 -0
  287. {easycoder-260320.2 → easycoder-260321.16}/test_init_debug.py +0 -0
  288. {easycoder-260320.2 → easycoder-260321.16}/test_initializers.py +0 -0
  289. {easycoder-260320.2 → easycoder-260321.16}/test_mqtt_listener.py +0 -0
  290. {easycoder-260320.2 → easycoder-260321.16}/test_mqtt_publisher.py +0 -0
  291. {easycoder-260320.2 → easycoder-260321.16}/testdbg.py +0 -0
  292. {easycoder-260320.2 → easycoder-260321.16}/testg.py +0 -0
  293. {easycoder-260320.2 → easycoder-260321.16}/testgetconfig.py +0 -0
  294. {easycoder-260320.2 → easycoder-260321.16}/testmodules.py +0 -0
  295. {easycoder-260320.2 → easycoder-260321.16}/testmqtt.py +0 -0
  296. {easycoder-260320.2 → easycoder-260321.16}/testnewui.py +0 -0
  297. {easycoder-260320.2 → easycoder-260321.16}/testrbr.py +0 -0
  298. {easycoder-260320.2 → easycoder-260321.16}/testrc.py +0 -0
  299. {easycoder-260320.2 → easycoder-260321.16}/testrmain.py +0 -0
  300. {easycoder-260320.2 → easycoder-260321.16}/tests/benchmark.ecs +0 -0
  301. {easycoder-260320.2 → easycoder-260321.16}/tests/child.ecs +0 -0
  302. {easycoder-260320.2 → easycoder-260321.16}/tests/ec_mqtt.py +0 -0
  303. {easycoder-260320.2 → easycoder-260321.16}/tests/editor_server.ecs +0 -0
  304. {easycoder-260320.2 → easycoder-260321.16}/tests/fizzbuzz.ecs +0 -0
  305. {easycoder-260320.2 → easycoder-260321.16}/tests/hello.ecs +0 -0
  306. {easycoder-260320.2 → easycoder-260321.16}/tests/mqtt.ecs +0 -0
  307. {easycoder-260320.2 → easycoder-260321.16}/tests/mqtt_listener.ecs +0 -0
  308. {easycoder-260320.2 → easycoder-260321.16}/tests/mqtt_publisher.ecs +0 -0
  309. {easycoder-260320.2 → easycoder-260321.16}/tests/parent.ecs +0 -0
  310. {easycoder-260320.2 → easycoder-260321.16}/tests/points.ecs +0 -0
  311. {easycoder-260320.2 → easycoder-260321.16}/tests/rbr_ui.py +0 -0
  312. {easycoder-260320.2 → easycoder-260321.16}/tests/rbrconf.ecs +0 -0
  313. {easycoder-260320.2 → easycoder-260321.16}/tests/rbrwidgets.py +0 -0
  314. {easycoder-260320.2 → easycoder-260321.16}/tests/server.ecs +0 -0
  315. {easycoder-260320.2 → easycoder-260321.16}/tests/server_test.html +0 -0
  316. {easycoder-260320.2 → easycoder-260321.16}/tests/server_test.sh +0 -0
  317. {easycoder-260320.2 → easycoder-260321.16}/tests/test.ecs +0 -0
  318. {easycoder-260320.2 → easycoder-260321.16}/tests/testg.ecs +0 -0
  319. {easycoder-260320.2 → easycoder-260321.16}/tests/tests.ecs +0 -0
  320. {easycoder-260320.2 → easycoder-260321.16}/tests.py +0 -0
  321. {easycoder-260320.2 → easycoder-260321.16}/testsql.py +0 -0
  322. {easycoder-260320.2 → easycoder-260321.16}/testui.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: easycoder
3
- Version: 260320.2
3
+ Version: 260321.16
4
4
  Summary: Rapid scripting in English
5
5
  Keywords: compiler,scripting,prototyping,programming,coding,python,low code,hypertalk,computer language,learn to code
6
6
  Author-email: Graham Trott <gtanyware@gmail.com>
@@ -3,7 +3,7 @@
3
3
  import importlib
4
4
  import math
5
5
 
6
- __version__ = "260320.2"
6
+ __version__ = "260321.16"
7
7
 
8
8
  from .ec_classes import *
9
9
  from .ec_compiler import *
@@ -2120,7 +2120,7 @@ class Core(Handler):
2120
2120
  return value
2121
2121
  return None
2122
2122
 
2123
- if token in ['now', 'today', 'newline', 'tab', 'empty']:
2123
+ if token in ['now', 'today', 'newline', 'tab', 'empty', 'cwd']:
2124
2124
  return value
2125
2125
 
2126
2126
  if token in ['stringify', 'prettify', 'json', 'lowercase', 'uppercase', 'hash', 'random', float, 'integer', 'encode', 'decode']:
@@ -2291,6 +2291,9 @@ class Core(Handler):
2291
2291
  token = self.nextToken()
2292
2292
  if token in ['in', 'of']:
2293
2293
  value.target = self.nextValue() # type: ignore
2294
+ if self.peek() == 'type':
2295
+ self.nextToken()
2296
+ value.filter = self.nextValue() # type: ignore
2294
2297
  return value
2295
2298
  return None
2296
2299
 
@@ -2361,9 +2364,13 @@ class Core(Handler):
2361
2364
  return ECValue(type=str, content=json.dumps(self.program.argv))
2362
2365
 
2363
2366
  def v_arg(self, v):
2364
- index = self.textify(v['index'])
2367
+ index = self.textify(v.index)
2368
+ if not hasattr(self.program, 'argv') or self.program.argv is None:
2369
+ RuntimeError(self.program, 'No command-line arguments were provided')
2370
+ return ECValue(type=str, content='')
2365
2371
  if index >= len(self.program.argv):
2366
- RuntimeError(self.program, 'Index exceeds # of args')
2372
+ RuntimeError(self.program, f'Argument index {index} out of range (only {len(self.program.argv)} args provided)')
2373
+ return ECValue(type=str, content='')
2367
2374
  return ECValue(type=str, content=self.program.argv[index])
2368
2375
 
2369
2376
  def v_bool(self, v):
@@ -2373,8 +2380,8 @@ class Core(Handler):
2373
2380
  return self.v_bool(v)
2374
2381
 
2375
2382
  def v_cos(self, v):
2376
- angle = self.textify(v['angle'])
2377
- radius = self.textify(v['radius'])
2383
+ angle = self.textify(v.angle)
2384
+ radius = self.textify(v.radius)
2378
2385
  return ECValue(type=int, content=round(math.cos(angle * 0.01745329) * radius))
2379
2386
 
2380
2387
  def v_count(self, v):
@@ -2453,7 +2460,13 @@ class Core(Handler):
2453
2460
 
2454
2461
  def v_files(self, v):
2455
2462
  path = self.textify(v.target)
2456
- return ECValue(type=str, content=json.dumps(os.listdir(path)))
2463
+ filter_ext = self.textify(v.filter) if v.filter else None
2464
+ entries = [f for f in os.listdir(path) if os.path.isfile(os.path.join(path, f))]
2465
+ if filter_ext:
2466
+ exts = {e.strip().lstrip('.') for e in filter_ext.split(',')}
2467
+ entries = [f for f in entries if os.path.splitext(f)[1].lstrip('.').lower() in exts]
2468
+ entries.sort()
2469
+ return ECValue(type=str, content=json.dumps(entries))
2457
2470
 
2458
2471
  def v_float(self, v):
2459
2472
  val = self.textify(v.getContent())
@@ -2563,7 +2576,7 @@ class Core(Handler):
2563
2576
  return ECValue(type=str, content=self.program.message)
2564
2577
 
2565
2578
  def v_modification(self, v):
2566
- fileName = self.textify(v['fileName'])
2579
+ fileName = self.textify(v.fileName)
2567
2580
  ts = int(os.stat(self.resolveLocalPath(fileName)).st_mtime)
2568
2581
  return ECValue(type=int, content=ts)
2569
2582
 
@@ -2575,6 +2588,9 @@ class Core(Handler):
2575
2588
  def v_newline(self, v):
2576
2589
  return ECValue(type=str, content='\n')
2577
2590
 
2591
+ def v_cwd(self, v):
2592
+ return ECValue(type=str, content=os.getcwd())
2593
+
2578
2594
  def v_now(self, v):
2579
2595
  return ECValue(type=int, content=int(time.time() * 1000))
2580
2596
 
@@ -2642,8 +2658,8 @@ class Core(Handler):
2642
2658
  return ECValue(type=str, content='\t')
2643
2659
 
2644
2660
  def v_tan(self, v):
2645
- angle = self.textify(v['angle'])
2646
- radius = self.textify(v['radius'])
2661
+ angle = self.textify(v.angle)
2662
+ radius = self.textify(v.radius)
2647
2663
  return ECValue(type=int, content=round(math.tan(angle * 0.01745329) * radius))
2648
2664
 
2649
2665
  def v_ticker(self, v):
@@ -2673,7 +2689,7 @@ class Core(Handler):
2673
2689
 
2674
2690
  def v_type(self, v):
2675
2691
  value = ECValue(type=str)
2676
- val = self.textify(v['value'])
2692
+ val = self.textify(v.value)
2677
2693
  if val is None:
2678
2694
  value.setContent('none')
2679
2695
  elif type(val) is str:
@@ -2812,6 +2828,7 @@ class Core(Handler):
2812
2828
  return condition
2813
2829
 
2814
2830
  if token == 'includes':
2831
+ self.nextToken()
2815
2832
  condition.value2 = self.nextValue() # type: ignore
2816
2833
  return condition
2817
2834
 
@@ -210,7 +210,7 @@ class ECTopic(ECObject):
210
210
  return ""
211
211
  if v is None:
212
212
  return ""
213
- return v['name']
213
+ return v.name
214
214
 
215
215
  def getQoS(self):
216
216
  v = self.getValue()
@@ -218,7 +218,7 @@ class ECTopic(ECObject):
218
218
  return 0
219
219
  if v is None:
220
220
  return 0
221
- return int(v['qos'])
221
+ return int(v.qos)
222
222
 
223
223
  def textify(self):
224
224
  v = self.getValue()
@@ -54,10 +54,14 @@ class Program:
54
54
  if arg in ['-v', '--version']: return
55
55
  if arg[0:6] == 'debug ':
56
56
  print('Debug mode requested')
57
- self.scriptName = arg[6:]
57
+ parts = arg[6:].split()
58
+ self.scriptName = parts[0]
59
+ self.argv = parts[1:]
58
60
  self.debugging = True
59
61
  else:
60
- self.scriptName = arg
62
+ parts = arg.split()
63
+ self.scriptName = parts[0]
64
+ self.argv = parts[1:]
61
65
  self.debugging = False
62
66
 
63
67
  f = open(self.scriptName, 'r')
@@ -1,39 +0,0 @@
1
- {
2
- "version": "0.2.0",
3
- "configurations": [
4
- {
5
- "name": "Run EasyCoder Extension",
6
- "type": "extensionHost",
7
- "request": "launch",
8
- "runtimeExecutable": "${execPath}",
9
- "args": [
10
- "--extensionDevelopmentPath=${workspaceFolder}"
11
- ],
12
- "outFiles": [
13
- "${workspaceFolder}/client/out/**/*.js"
14
- ],
15
- "preLaunchTask": "lsp: watch",
16
- "env": {
17
- "EASYCODER_LSP_DEBUGPY": "1"
18
- }
19
- },
20
- {
21
- "name": "Attach to EasyCoder LSP (Python)",
22
- "type": "python",
23
- "request": "attach",
24
- "connect": {
25
- "host": "127.0.0.1",
26
- "port": 5678
27
- }
28
- }
29
- ],
30
- "compounds": [
31
- {
32
- "name": "Run Extension + Attach LSP",
33
- "configurations": [
34
- "Run EasyCoder Extension",
35
- "Attach to EasyCoder LSP (Python)"
36
- ]
37
- }
38
- ]
39
- }
@@ -1,22 +0,0 @@
1
- {
2
- "version": "2.0.0",
3
- "tasks": [
4
- {
5
- "label": "lsp: compile",
6
- "type": "shell",
7
- "options": { "cwd": "${workspaceFolder}" },
8
- "command": "npm",
9
- "args": ["run", "compile"],
10
- "problemMatcher": ["$tsc"]
11
- },
12
- {
13
- "label": "lsp: watch",
14
- "type": "shell",
15
- "options": { "cwd": "${workspaceFolder}" },
16
- "command": "npm",
17
- "args": ["run", "watch"],
18
- "isBackground": true,
19
- "problemMatcher": ["$tsc-watch"]
20
- }
21
- ]
22
- }
@@ -1,430 +0,0 @@
1
- # EasyCoder Language Server Protocol (LSP) - Phase 4
2
-
3
- Intelligent language support for EasyCoder (.ecs) scripts with real-time collision detection, context-aware completions, and interactive documentation.
4
-
5
- ## Architecture Overview
6
-
7
- ```
8
- VS Code Extension (Client)
9
- ├── extension.ts - Entry point, launches server
10
- ├── package.json - Extension manifest, activation events
11
- └── syntaxes/ - TextMate grammar for .ecs files
12
-
13
- ↓ stdin/stdout (JSON-RPC 2.0)
14
-
15
- Python Language Server (Server)
16
- ├── server.py - Core LSP implementation
17
- │ ├── RegistryLoader - Parses RESERVED_STEMS.md, operations.md, PATTERNS.md
18
- │ ├── EasyCoderLanguageServer - Main server logic
19
- │ └── EasyCoderDispatcher - JSON-RPC method routing
20
- └── requirements.txt - Python dependencies
21
- ```
22
-
23
- ## Features
24
-
25
- ### 1. Code Completion (onCompletion)
26
-
27
- **Context-aware keyword suggestions** based on current script state:
28
-
29
- - **Core Mode** (default): Access to core keywords (variable, set, loop, etc.)
30
- - **Graphics Mode** (after `create window`): Access to graphics keywords (button, label, input, etc.)
31
-
32
- **Example**:
33
- ```easycoder
34
- script MyApp
35
- create window
36
- ! Typing 'but' shows: button (graphics)
37
- but
38
-
39
- exit
40
- ```
41
-
42
- **Completion Items Include**:
43
- - `label`: Keyword name
44
- - `kind`: CompletionItemKind.Keyword
45
- - `detail`: Brief description with context tag (CORE/GRAPHICS)
46
- - `sortText`: Ensures keywords appear first in list
47
- - `documentation`: Full docs with syntax (onCompletionResolve)
48
-
49
- ### 2. Hover Documentation (onHover)
50
-
51
- **Interactive keyword reference** showing:
52
- - Keyword type (CORE, GRAPHICS, VALUE)
53
- - Brief description
54
- - Context information
55
-
56
- **Example**: Hover over `set` keyword shows:
57
- ```
58
- set [CORE]
59
- Assign value to variable or property
60
- ```
61
-
62
- ### 3. Collision Detection (onDidChangeContent → publishDiagnostics)
63
-
64
- **Real-time warnings** for:
65
- - Reserved keyword usage as variable names
66
- - Plugin name conflicts
67
- - Value operation collisions
68
-
69
- **Severity Levels**:
70
- - `Error` (1): Critical collision, breaks code
71
- - `Warning` (2): Potential issue, may work but risky
72
- - `Information` (3): Advisory, semantic conflict detected
73
- - `Hint` (4): Suggestion for better alternatives
74
-
75
- **Example**: Using `set` as variable name:
76
- ```easycoder
77
- variable set ! ← Diagnostic: 'set' is reserved keyword [core]
78
- set set to 5 ! ← Two diagnostics
79
- ```
80
-
81
- ### 4. Smart Registry Loading
82
-
83
- **Startup Phase**:
84
- 1. Read `RESERVED_STEMS.md` → Extract core/graphics keywords (50+ items)
85
- 2. Read `doc/core/values/operations.md` → Extract value operations (18 stems)
86
- 3. Read `doc/graphics/PATTERNS.md` → Extract widget types/attributes
87
-
88
- **Loaded Data**:
89
- ```python
90
- registry.reserved_stems = {
91
- 'set': {'type': 'core', 'description': 'Assign value to variable'},
92
- 'button': {'type': 'graphics', 'description': 'Create button widget'},
93
- # 50+ keywords
94
- }
95
-
96
- registry.value_operations = {
97
- 'string concatenation': {'description': '...', 'alternatives': [...]},
98
- # 18 operations
99
- }
100
-
101
- registry.graphics_patterns = {
102
- 'window': {'description': '...'},
103
- 'button': {'description': '...'},
104
- # widgets, attributes, signals
105
- }
106
- ```
107
-
108
- ## Setup Instructions
109
-
110
- ### 1. Install Python Server Dependencies
111
-
112
- ```bash
113
- cd /home/graham/dev/easycoder/easycoder-py/lsp
114
- pip install -r requirements.txt
115
- ```
116
-
117
- ### 2. Build VS Code Extension
118
-
119
- ```bash
120
- cd /home/graham/dev/easycoder/easycoder-py/lsp
121
- npm install
122
- npm run compile
123
- ```
124
-
125
- ### 3. Install Extension in VS Code
126
-
127
- **Option A: Development Mode**
128
- ```bash
129
- code --install-extension ./
130
- # Or use VS Code command: Extensions → Install from VSIX
131
- ```
132
-
133
- **Option B: Manual Installation**
134
- 1. Copy entire `lsp/` directory to: `~/.vscode/extensions/easycoder-lsp-1.0.0/`
135
- 2. Reload VS Code (Cmd+R)
136
-
137
- ### 4. Verify Installation
138
-
139
- 1. Open any `.ecs` file
140
- 2. You should see syntax highlighting
141
- 3. Type a keyword and press Ctrl+Space (or Cmd+Space) for completions
142
- 4. Hover over a keyword to see documentation
143
-
144
- ## File Structure
145
-
146
- ```
147
- lsp/
148
- ├── server.py # Python LSP server
149
- ├── client/
150
- │ ├── package.json # Client dependencies
151
- │ ├── tsconfig.json # TypeScript config
152
- │ └── src/
153
- │ └── extension.ts # VS Code extension entry
154
- ├── syntaxes/
155
- │ ├── easycoder.tmLanguage.json # TextMate grammar for syntax highlighting
156
- │ └── easycoder.configuration.json # Editor behavior config
157
- ├── package.json # Extension manifest
158
- ├── requirements.txt # Python dependencies
159
- └── README.md # This file
160
- ```
161
-
162
- ## JSON-RPC Message Flow
163
-
164
- ### Initialization
165
-
166
- ```
167
- Client → Server: initialize(capabilities: {}, rootPath: string)
168
- Server → Client: InitializeResult {capabilities: {...}}
169
-
170
- Client → Server: initialized()
171
- Server: Load registries, start validation
172
- ```
173
-
174
- ### Document Lifecycle
175
-
176
- ```
177
- Client → Server: textDocument/didOpen({textDocument, text})
178
- Server: Store document, validate for diagnostics
179
-
180
- Client → Server: textDocument/didChange({textDocument, contentChanges})
181
- Server: Update document, re-validate
182
-
183
- Client → Server: textDocument/didClose({textDocument})
184
- Server: Remove from memory
185
- ```
186
-
187
- ### Code Completion
188
-
189
- ```
190
- Client → Server: textDocument/completion({textDocument, position})
191
- Server:
192
- 1. Extract word at cursor
193
- 2. Detect context (core/graphics)
194
- 3. Filter registry by prefix
195
- 4. Return CompletionItem[]
196
-
197
- Client → User: Show completion dropdown
198
-
199
- User: Select item → Client → Server: completionItem/resolve(item)
200
- Server: Enhance with documentation
201
- Client: Show full doc in completion panel
202
- ```
203
-
204
- ### Hover
205
-
206
- ```
207
- Client → Server: textDocument/hover({textDocument, position})
208
- Server:
209
- 1. Extract word at cursor
210
- 2. Look up in registries
211
- 3. Generate markdown docs
212
- 4. Return Hover{contents}
213
-
214
- Client → User: Show tooltip with docs
215
- ```
216
-
217
- ## Configuration Options
218
-
219
- Users can customize behavior in `.vscode/settings.json`:
220
-
221
- ```json
222
- {
223
- "easycoder.maxNumberOfProblems": 100,
224
- "easycoder.trace.server": "verbose"
225
- }
226
- ```
227
-
228
- ### Settings
229
-
230
- | Setting | Type | Default | Description |
231
- |---------|------|---------|-------------|
232
- | `easycoder.maxNumberOfProblems` | number | 100 | Max diagnostics per file |
233
- | `easycoder.trace.server` | enum | "off" | LSP trace level: "off" \| "messages" \| "verbose" |
234
-
235
- ## Logging
236
-
237
- Server logs to `/tmp/easycoder-lsp.log`:
238
-
239
- ```bash
240
- tail -f /tmp/easycoder-lsp.log
241
- ```
242
-
243
- **Log Levels**:
244
- - `INFO`: Normal operations (server start, registry load, document open/close)
245
- - `WARNING`: Registry files not found, missing dependencies
246
- - `ERROR`: Critical failures with stack traces
247
-
248
- ## Performance Characteristics
249
-
250
- | Operation | Time | Notes |
251
- |-----------|------|-------|
252
- | Registry load (startup) | ~50ms | Parses 3 markdown files, ~150 entries |
253
- | Completion request | <5ms | In-memory lookup + filtering |
254
- | Hover lookup | <1ms | Direct dictionary access |
255
- | Validation (full) | ~10ms per file | Regex scanning for collisions |
256
- | Context detection | <1ms | Backward scan for keywords |
257
-
258
- ## Testing
259
-
260
- ### Manual Test Cases
261
-
262
- **Test 1: Basic Completion**
263
- ```easycoder
264
- script Test
265
- ! Press Ctrl+Space to see 'variable', 'set', 'loop', etc.
266
- var
267
- exit
268
- ```
269
-
270
- **Test 2: Graphics Context**
271
- ```easycoder
272
- script Test
273
- create window
274
- ! Press Ctrl+Space to see 'button', 'label', 'input', etc.
275
- but
276
- exit
277
- ```
278
-
279
- **Test 3: Hover Documentation**
280
- ```easycoder
281
- script Test
282
- ! Hover over 'set' to see docs
283
- set
284
-
285
- exit
286
- ```
287
-
288
- **Test 4: Collision Detection**
289
- ```easycoder
290
- script Test
291
- variable set ! ← Should show diagnostic
292
- set set to 5 ! ← Should show 2 diagnostics
293
- exit
294
- ```
295
-
296
- ### Automated Test Suite
297
-
298
- Create `lsp/test/test_server.py`:
299
- ```python
300
- import pytest
301
- from server import RegistryLoader, EasyCoderLanguageServer
302
-
303
- def test_registry_loader():
304
- registry = RegistryLoader('/home/graham/dev/easycoder/easycoder-py')
305
- assert len(registry.reserved_stems) > 30
306
- assert 'set' in registry.reserved_stems
307
- assert len(registry.value_operations) > 15
308
-
309
- def test_completion():
310
- server = EasyCoderLanguageServer('/home/graham/dev/easycoder/easycoder-py')
311
- completions = server.registry.get_completions_for_context('core')
312
- assert len(completions) > 0
313
- assert any(c['label'] == 'set' for c in completions)
314
-
315
- def test_collision_detection():
316
- server = EasyCoderLanguageServer('/home/graham/dev/easycoder/easycoder-py')
317
- # Should detect 'set' as reserved
318
- assert server.registry.get_reserved_keyword('set') is not None
319
- # Should NOT detect random variable
320
- assert server.registry.get_reserved_keyword('MyVariable') is None
321
- ```
322
-
323
- Run tests:
324
- ```bash
325
- cd lsp
326
- pytest test/test_server.py -v
327
- ```
328
-
329
- ## Integration with RBR Controller
330
-
331
- ### Test with Production Scripts
332
-
333
- ```bash
334
- # Open RBR controller scripts in VS Code
335
- code /home/graham/dev/rbr/roombyroom/Controller/ui/*.ecs
336
-
337
- # Features available:
338
- # 1. Syntax highlighting for .ecs files
339
- # 2. Autocomplete for RBR UI keywords (create room, set temperature, etc.)
340
- # 3. Hover docs for keyword reference
341
- # 4. Real-time collision detection
342
- ```
343
-
344
- ### Expected Behavior
345
-
346
- **rbrconf.ecs**:
347
- ```
348
- - Graphics mode detected after 'create rbrwin'
349
- - Graphics completions (room, button) available
350
- - No collisions (using standard variable names)
351
- ```
352
-
353
- **schedule.ecs** / **systemName.ecs**:
354
- ```
355
- - Core mode (no windows)
356
- - Core completions (variable, set, loop)
357
- - Real-time diagnostics for keyword conflicts
358
- ```
359
-
360
- ## Future Enhancements
361
-
362
- ### Phase 4.1: Advanced Features
363
- - [ ] Jump to definition (onDefinition)
364
- - [ ] Find all references (onReferences)
365
- - [ ] Symbol outline (onDocumentSymbol)
366
- - [ ] Code formatting (onFormatting)
367
- - [ ] Code actions for quick fixes
368
-
369
- ### Phase 4.2: Plugin Awareness
370
- - [ ] Load plugin registries dynamically
371
- - [ ] Suggest plugin usage patterns
372
- - [ ] Warn on plugin conflicts with core
373
-
374
- ### Phase 4.3: Performance
375
- - [ ] Incremental document sync (TextDocumentSyncKind.Incremental)
376
- - [ ] Workspace symbol caching
377
- - [ ] Lazy registry loading for large workspaces
378
-
379
- ### Phase 4.4: Developer Tools
380
- - [ ] Debugger integration (DAP)
381
- - [ ] Test runner UI
382
- - [ ] Performance profiler
383
-
384
- ## Troubleshooting
385
-
386
- ### Server not starting
387
-
388
- **Error**: "Server crashed after 5 restarts"
389
-
390
- **Solution**:
391
- 1. Check Python installation: `python3 --version`
392
- 2. Install dependencies: `pip install -r requirements.txt`
393
- 3. Check logs: `tail -f /tmp/easycoder-lsp.log`
394
- 4. Verify registry files exist:
395
- ```bash
396
- ls -la /home/graham/dev/easycoder/easycoder-py/RESERVED_STEMS.md
397
- ls -la /home/graham/dev/easycoder/easycoder-py/doc/core/values/operations.md
398
- ```
399
-
400
- ### No completions showing
401
-
402
- **Solution**:
403
- 1. Verify language is set to `easycoder`: Check VS Code status bar (bottom-right)
404
- 2. Check file extension is `.ecs`
405
- 3. Try triggering manually: Ctrl+Space
406
- 4. Check output: View → Output → "EasyCoder Language Server"
407
-
408
- ### Collision detection too aggressive
409
-
410
- **Solution**:
411
- Adjust `maxNumberOfProblems` in settings:
412
- ```json
413
- {
414
- "easycoder.maxNumberOfProblems": 200
415
- }
416
- ```
417
-
418
- ## References
419
-
420
- - **LSP Specification**: https://microsoft.github.io/language-server-protocol/
421
- - **VS Code Extension API**: https://code.visualstudio.com/api
422
- - **Python JSON-RPC**: https://github.com/zigoni/python-jsonrpc
423
- - **TextMate Grammar**: https://macromates.com/manual/en/language_grammars
424
-
425
- ---
426
-
427
- **Phase 4 Status**: ✅ Initial Implementation Complete
428
- **Next Phase**: 4.1 (Advanced Language Features)
429
- **Estimated Timeline**: 2-4 weeks for Phase 4.1
430
-