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.
- {easycoder-260320.2 → easycoder-260321.16}/PKG-INFO +1 -1
- {easycoder-260320.2 → easycoder-260321.16}/easycoder/__init__.py +1 -1
- {easycoder-260320.2 → easycoder-260321.16}/easycoder/ec_core.py +27 -10
- {easycoder-260320.2 → easycoder-260321.16}/easycoder/ec_mqtt.py +2 -2
- {easycoder-260320.2 → easycoder-260321.16}/easycoder/ec_program.py +6 -2
- easycoder-260320.2/lsp/.vscode/launch.json +0 -39
- easycoder-260320.2/lsp/.vscode/tasks.json +0 -22
- easycoder-260320.2/lsp/LSP_ARCHITECTURE.md +0 -430
- easycoder-260320.2/lsp/QUICK_START.md +0 -132
- easycoder-260320.2/lsp/client/out/extension.d.ts +0 -3
- easycoder-260320.2/lsp/client/out/extension.js +0 -106
- easycoder-260320.2/lsp/client/package-lock.json +0 -140
- easycoder-260320.2/lsp/client/package.json +0 -27
- easycoder-260320.2/lsp/client/src/extension.ts +0 -93
- easycoder-260320.2/lsp/client/tsconfig.json +0 -17
- easycoder-260320.2/lsp/package-lock.json +0 -51
- easycoder-260320.2/lsp/package.json +0 -85
- easycoder-260320.2/lsp/requirements.txt +0 -2
- easycoder-260320.2/lsp/server.py +0 -557
- easycoder-260320.2/lsp/syntaxes/easycoder.configuration.json +0 -22
- easycoder-260320.2/lsp/test_server.py +0 -332
- {easycoder-260320.2 → easycoder-260321.16}/.github/copilot-instructions.md +0 -0
- {easycoder-260320.2 → easycoder-260321.16}/.github/workflows/conformance-report.yml +0 -0
- {easycoder-260320.2 → easycoder-260321.16}/.gitignore +0 -0
- {easycoder-260320.2 → easycoder-260321.16}/.vscode/EXTENSION_GUIDE.md +0 -0
- {easycoder-260320.2 → easycoder-260321.16}/.vscode/PYTHON_SETUP.md +0 -0
- {easycoder-260320.2 → easycoder-260321.16}/.vscode/easycoder/README.md +0 -0
- {easycoder-260320.2 → easycoder-260321.16}/.vscode/easycoder/language-configuration.json +0 -0
- {easycoder-260320.2 → easycoder-260321.16}/.vscode/easycoder/package.json +0 -0
- {easycoder-260320.2 → easycoder-260321.16}/.vscode/easycoder/snippets/easycoder.json +0 -0
- {easycoder-260320.2 → easycoder-260321.16}/.vscode/easycoder/syntaxes/easycoder.tmLanguage.json +0 -0
- {easycoder-260320.2 → easycoder-260321.16}/.vscode/launch.json +0 -0
- {easycoder-260320.2 → easycoder-260321.16}/.vscode/settings.json +0 -0
- {easycoder-260320.2 → easycoder-260321.16}/AI/ARCHITECTURE.md +0 -0
- {easycoder-260320.2 → easycoder-260321.16}/AI/EASYCODER_AND_WEBSON.md +0 -0
- {easycoder-260320.2 → easycoder-260321.16}/AI/EXAMPLES.md +0 -0
- {easycoder-260320.2 → easycoder-260321.16}/AI/PROJECT_OVERVIEW.md +0 -0
- {easycoder-260320.2 → easycoder-260321.16}/AI/README.md +0 -0
- {easycoder-260320.2 → easycoder-260321.16}/AI/WORKING_RULES.md +0 -0
- {easycoder-260320.2 → easycoder-260321.16}/AI/articles/Arrays and Modules.md +0 -0
- {easycoder-260320.2 → easycoder-260321.16}/AI/examples/primes/primes.ecs +0 -0
- {easycoder-260320.2 → easycoder-260321.16}/AI/examples/primes/primes.md +0 -0
- {easycoder-260320.2 → easycoder-260321.16}/AI/examples/wordlist/wordlist.ecs +0 -0
- {easycoder-260320.2 → easycoder-260321.16}/AI/examples/wordlist/wordlist.md +0 -0
- {easycoder-260320.2 → easycoder-260321.16}/AI/log/CONTRIBUTING.md +0 -0
- {easycoder-260320.2 → easycoder-260321.16}/AI/log/DEVELOPER_RESOURCES.md +0 -0
- {easycoder-260320.2 → easycoder-260321.16}/AI/log/GRAPHICS_PHASE1.md +0 -0
- {easycoder-260320.2 → easycoder-260321.16}/AI/log/PHASE1_COMPLETION_SUMMARY.md +0 -0
- {easycoder-260320.2 → easycoder-260321.16}/AI/log/PHASE_1_3_COMPLETION_REPORT.md +0 -0
- {easycoder-260320.2 → easycoder-260321.16}/AI/log/PHASE_4_COMPLETION_REPORT.md +0 -0
- {easycoder-260320.2 → easycoder-260321.16}/AI/log/PLUGIN_PATTERNS.md +0 -0
- {easycoder-260320.2 → easycoder-260321.16}/AI/log/PROJECT_COMPLETION_SUMMARY.md +0 -0
- {easycoder-260320.2 → easycoder-260321.16}/AI/log/START_HERE.md +0 -0
- {easycoder-260320.2 → easycoder-260321.16}/AI/log/SYNTAX_REFACTORING.md +0 -0
- {easycoder-260320.2 → easycoder-260321.16}/LICENSE +0 -0
- {easycoder-260320.2 → easycoder-260321.16}/README.md +0 -0
- {easycoder-260320.2 → easycoder-260321.16}/RELEASE_NOTES.md +0 -0
- {easycoder-260320.2 → easycoder-260321.16}/backdrop.jpg +0 -0
- {easycoder-260320.2 → easycoder-260321.16}/basic.py +0 -0
- {easycoder-260320.2 → easycoder-260321.16}/conformance/README.md +0 -0
- {easycoder-260320.2 → easycoder-260321.16}/conformance/actuals-python-cli.json +0 -0
- {easycoder-260320.2 → easycoder-260321.16}/conformance/ec_py_runner.py +0 -0
- {easycoder-260320.2 → easycoder-260321.16}/conformance/parity-report-template.json +0 -0
- {easycoder-260320.2 → easycoder-260321.16}/conformance/parity-report.generated.json +0 -0
- {easycoder-260320.2 → easycoder-260321.16}/conformance/parity-report.initial.json +0 -0
- {easycoder-260320.2 → easycoder-260321.16}/conformance/plugin-interface-matrix.json +0 -0
- {easycoder-260320.2 → easycoder-260321.16}/conformance/run_conformance.py +0 -0
- {easycoder-260320.2 → easycoder-260321.16}/conformance/runner-contract.md +0 -0
- {easycoder-260320.2 → easycoder-260321.16}/conformance/tests/EC-0001-basic-assignment.ecs +0 -0
- {easycoder-260320.2 → easycoder-260321.16}/conformance/tests/EC-0001-basic-assignment.json +0 -0
- {easycoder-260320.2 → easycoder-260321.16}/conformance/tests/EC-0002-arithmetic-chain.ecs +0 -0
- {easycoder-260320.2 → easycoder-260321.16}/conformance/tests/EC-0002-arithmetic-chain.json +0 -0
- {easycoder-260320.2 → easycoder-260321.16}/conformance/tests/EC-0003-condition-branch.ecs +0 -0
- {easycoder-260320.2 → easycoder-260321.16}/conformance/tests/EC-0003-condition-branch.json +0 -0
- {easycoder-260320.2 → easycoder-260321.16}/conformance/tests/EC-0004-while-sum.ecs +0 -0
- {easycoder-260320.2 → easycoder-260321.16}/conformance/tests/EC-0004-while-sum.json +0 -0
- {easycoder-260320.2 → easycoder-260321.16}/conformance/tests/EC-0005-array-index-access.ecs +0 -0
- {easycoder-260320.2 → easycoder-260321.16}/conformance/tests/EC-0005-array-index-access.json +0 -0
- {easycoder-260320.2 → easycoder-260321.16}/conformance/tests/EC-0006-and-or-conditions.ecs +0 -0
- {easycoder-260320.2 → easycoder-260321.16}/conformance/tests/EC-0006-and-or-conditions.json +0 -0
- {easycoder-260320.2 → easycoder-260321.16}/conformance/tests/EC-0007-includes-membership.ecs +0 -0
- {easycoder-260320.2 → easycoder-260321.16}/conformance/tests/EC-0007-includes-membership.json +0 -0
- {easycoder-260320.2 → easycoder-260321.16}/conformance/tests/index.json +0 -0
- {easycoder-260320.2 → easycoder-260321.16}/doc/README.md +0 -0
- {easycoder-260320.2 → easycoder-260321.16}/doc/RESERVED_STEMS.md +0 -0
- {easycoder-260320.2 → easycoder-260321.16}/doc/core/README.md +0 -0
- {easycoder-260320.2 → easycoder-260321.16}/doc/core/conditions/boolean.md +0 -0
- {easycoder-260320.2 → easycoder-260321.16}/doc/core/conditions/empty.md +0 -0
- {easycoder-260320.2 → easycoder-260321.16}/doc/core/conditions/ends.md +0 -0
- {easycoder-260320.2 → easycoder-260321.16}/doc/core/conditions/even.md +0 -0
- {easycoder-260320.2 → easycoder-260321.16}/doc/core/conditions/exists.md +0 -0
- {easycoder-260320.2 → easycoder-260321.16}/doc/core/conditions/greater.md +0 -0
- {easycoder-260320.2 → easycoder-260321.16}/doc/core/conditions/hasProperty.md +0 -0
- {easycoder-260320.2 → easycoder-260321.16}/doc/core/conditions/includes.md +0 -0
- {easycoder-260320.2 → easycoder-260321.16}/doc/core/conditions/is.md +0 -0
- {easycoder-260320.2 → easycoder-260321.16}/doc/core/conditions/less.md +0 -0
- {easycoder-260320.2 → easycoder-260321.16}/doc/core/conditions/list.md +0 -0
- {easycoder-260320.2 → easycoder-260321.16}/doc/core/conditions/none.md +0 -0
- {easycoder-260320.2 → easycoder-260321.16}/doc/core/conditions/not.md +0 -0
- {easycoder-260320.2 → easycoder-260321.16}/doc/core/conditions/numeric.md +0 -0
- {easycoder-260320.2 → easycoder-260321.16}/doc/core/conditions/object.md +0 -0
- {easycoder-260320.2 → easycoder-260321.16}/doc/core/conditions/odd.md +0 -0
- {easycoder-260320.2 → easycoder-260321.16}/doc/core/conditions/starts.md +0 -0
- {easycoder-260320.2 → easycoder-260321.16}/doc/core/conditions/string.md +0 -0
- {easycoder-260320.2 → easycoder-260321.16}/doc/core/keywords/add.md +0 -0
- {easycoder-260320.2 → easycoder-260321.16}/doc/core/keywords/append.md +0 -0
- {easycoder-260320.2 → easycoder-260321.16}/doc/core/keywords/assert.md +0 -0
- {easycoder-260320.2 → easycoder-260321.16}/doc/core/keywords/begin.md +0 -0
- {easycoder-260320.2 → easycoder-260321.16}/doc/core/keywords/clear.md +0 -0
- {easycoder-260320.2 → easycoder-260321.16}/doc/core/keywords/close.md +0 -0
- {easycoder-260320.2 → easycoder-260321.16}/doc/core/keywords/create.md +0 -0
- {easycoder-260320.2 → easycoder-260321.16}/doc/core/keywords/debug.md +0 -0
- {easycoder-260320.2 → easycoder-260321.16}/doc/core/keywords/decrement.md +0 -0
- {easycoder-260320.2 → easycoder-260321.16}/doc/core/keywords/delete.md +0 -0
- {easycoder-260320.2 → easycoder-260321.16}/doc/core/keywords/divide.md +0 -0
- {easycoder-260320.2 → easycoder-260321.16}/doc/core/keywords/download.md +0 -0
- {easycoder-260320.2 → easycoder-260321.16}/doc/core/keywords/exit.md +0 -0
- {easycoder-260320.2 → easycoder-260321.16}/doc/core/keywords/file.md +0 -0
- {easycoder-260320.2 → easycoder-260321.16}/doc/core/keywords/fork.md +0 -0
- {easycoder-260320.2 → easycoder-260321.16}/doc/core/keywords/get.md +0 -0
- {easycoder-260320.2 → easycoder-260321.16}/doc/core/keywords/go.md +0 -0
- {easycoder-260320.2 → easycoder-260321.16}/doc/core/keywords/gosub.md +0 -0
- {easycoder-260320.2 → easycoder-260321.16}/doc/core/keywords/if.md +0 -0
- {easycoder-260320.2 → easycoder-260321.16}/doc/core/keywords/import.md +0 -0
- {easycoder-260320.2 → easycoder-260321.16}/doc/core/keywords/increment.md +0 -0
- {easycoder-260320.2 → easycoder-260321.16}/doc/core/keywords/index.md +0 -0
- {easycoder-260320.2 → easycoder-260321.16}/doc/core/keywords/init.md +0 -0
- {easycoder-260320.2 → easycoder-260321.16}/doc/core/keywords/input.md +0 -0
- {easycoder-260320.2 → easycoder-260321.16}/doc/core/keywords/load.md +0 -0
- {easycoder-260320.2 → easycoder-260321.16}/doc/core/keywords/lock.md +0 -0
- {easycoder-260320.2 → easycoder-260321.16}/doc/core/keywords/log.md +0 -0
- {easycoder-260320.2 → easycoder-260321.16}/doc/core/keywords/module.md +0 -0
- {easycoder-260320.2 → easycoder-260321.16}/doc/core/keywords/multiply.md +0 -0
- {easycoder-260320.2 → easycoder-260321.16}/doc/core/keywords/negate.md +0 -0
- {easycoder-260320.2 → easycoder-260321.16}/doc/core/keywords/on.md +0 -0
- {easycoder-260320.2 → easycoder-260321.16}/doc/core/keywords/open.md +0 -0
- {easycoder-260320.2 → easycoder-260321.16}/doc/core/keywords/pass.md +0 -0
- {easycoder-260320.2 → easycoder-260321.16}/doc/core/keywords/pop.md +0 -0
- {easycoder-260320.2 → easycoder-260321.16}/doc/core/keywords/post.md +0 -0
- {easycoder-260320.2 → easycoder-260321.16}/doc/core/keywords/print.md +0 -0
- {easycoder-260320.2 → easycoder-260321.16}/doc/core/keywords/push.md +0 -0
- {easycoder-260320.2 → easycoder-260321.16}/doc/core/keywords/put.md +0 -0
- {easycoder-260320.2 → easycoder-260321.16}/doc/core/keywords/read.md +0 -0
- {easycoder-260320.2 → easycoder-260321.16}/doc/core/keywords/release.md +0 -0
- {easycoder-260320.2 → easycoder-260321.16}/doc/core/keywords/replace.md +0 -0
- {easycoder-260320.2 → easycoder-260321.16}/doc/core/keywords/return.md +0 -0
- {easycoder-260320.2 → easycoder-260321.16}/doc/core/keywords/run.md +0 -0
- {easycoder-260320.2 → easycoder-260321.16}/doc/core/keywords/save.md +0 -0
- {easycoder-260320.2 → easycoder-260321.16}/doc/core/keywords/script.md +0 -0
- {easycoder-260320.2 → easycoder-260321.16}/doc/core/keywords/send.md +0 -0
- {easycoder-260320.2 → easycoder-260321.16}/doc/core/keywords/set.md +0 -0
- {easycoder-260320.2 → easycoder-260321.16}/doc/core/keywords/shuffle.md +0 -0
- {easycoder-260320.2 → easycoder-260321.16}/doc/core/keywords/split.md +0 -0
- {easycoder-260320.2 → easycoder-260321.16}/doc/core/keywords/stack.md +0 -0
- {easycoder-260320.2 → easycoder-260321.16}/doc/core/keywords/stop.md +0 -0
- {easycoder-260320.2 → easycoder-260321.16}/doc/core/keywords/system.md +0 -0
- {easycoder-260320.2 → easycoder-260321.16}/doc/core/keywords/take.md +0 -0
- {easycoder-260320.2 → easycoder-260321.16}/doc/core/keywords/toggle.md +0 -0
- {easycoder-260320.2 → easycoder-260321.16}/doc/core/keywords/trim.md +0 -0
- {easycoder-260320.2 → easycoder-260321.16}/doc/core/keywords/truncate.md +0 -0
- {easycoder-260320.2 → easycoder-260321.16}/doc/core/keywords/unlock.md +0 -0
- {easycoder-260320.2 → easycoder-260321.16}/doc/core/keywords/use.md +0 -0
- {easycoder-260320.2 → easycoder-260321.16}/doc/core/keywords/variable.md +0 -0
- {easycoder-260320.2 → easycoder-260321.16}/doc/core/keywords/wait.md +0 -0
- {easycoder-260320.2 → easycoder-260321.16}/doc/core/keywords/while.md +0 -0
- {easycoder-260320.2 → easycoder-260321.16}/doc/core/keywords/write.md +0 -0
- {easycoder-260320.2 → easycoder-260321.16}/doc/core/values/arg.md +0 -0
- {easycoder-260320.2 → easycoder-260321.16}/doc/core/values/args.md +0 -0
- {easycoder-260320.2 → easycoder-260321.16}/doc/core/values/cat.md +0 -0
- {easycoder-260320.2 → easycoder-260321.16}/doc/core/values/cos.md +0 -0
- {easycoder-260320.2 → easycoder-260321.16}/doc/core/values/datime.md +0 -0
- {easycoder-260320.2 → easycoder-260321.16}/doc/core/values/decode.md +0 -0
- {easycoder-260320.2 → easycoder-260321.16}/doc/core/values/element.md +0 -0
- {easycoder-260320.2 → easycoder-260321.16}/doc/core/values/elements.md +0 -0
- {easycoder-260320.2 → easycoder-260321.16}/doc/core/values/empty.md +0 -0
- {easycoder-260320.2 → easycoder-260321.16}/doc/core/values/encode.md +0 -0
- {easycoder-260320.2 → easycoder-260321.16}/doc/core/values/error.md +0 -0
- {easycoder-260320.2 → easycoder-260321.16}/doc/core/values/files.md +0 -0
- {easycoder-260320.2 → easycoder-260321.16}/doc/core/values/float.md +0 -0
- {easycoder-260320.2 → easycoder-260321.16}/doc/core/values/from.md +0 -0
- {easycoder-260320.2 → easycoder-260321.16}/doc/core/values/hash.md +0 -0
- {easycoder-260320.2 → easycoder-260321.16}/doc/core/values/index.md +0 -0
- {easycoder-260320.2 → easycoder-260321.16}/doc/core/values/integer.md +0 -0
- {easycoder-260320.2 → easycoder-260321.16}/doc/core/values/json.md +0 -0
- {easycoder-260320.2 → easycoder-260321.16}/doc/core/values/keys.md +0 -0
- {easycoder-260320.2 → easycoder-260321.16}/doc/core/values/left.md +0 -0
- {easycoder-260320.2 → easycoder-260321.16}/doc/core/values/length.md +0 -0
- {easycoder-260320.2 → easycoder-260321.16}/doc/core/values/lowercase.md +0 -0
- {easycoder-260320.2 → easycoder-260321.16}/doc/core/values/memory.md +0 -0
- {easycoder-260320.2 → easycoder-260321.16}/doc/core/values/modification.md +0 -0
- {easycoder-260320.2 → easycoder-260321.16}/doc/core/values/modulo.md +0 -0
- {easycoder-260320.2 → easycoder-260321.16}/doc/core/values/newline.md +0 -0
- {easycoder-260320.2 → easycoder-260321.16}/doc/core/values/now.md +0 -0
- {easycoder-260320.2 → easycoder-260321.16}/doc/core/values/operations.md +0 -0
- {easycoder-260320.2 → easycoder-260321.16}/doc/core/values/position.md +0 -0
- {easycoder-260320.2 → easycoder-260321.16}/doc/core/values/property.md +0 -0
- {easycoder-260320.2 → easycoder-260321.16}/doc/core/values/random.md +0 -0
- {easycoder-260320.2 → easycoder-260321.16}/doc/core/values/right.md +0 -0
- {easycoder-260320.2 → easycoder-260321.16}/doc/core/values/sin.md +0 -0
- {easycoder-260320.2 → easycoder-260321.16}/doc/core/values/stringify.md +0 -0
- {easycoder-260320.2 → easycoder-260321.16}/doc/core/values/tab.md +0 -0
- {easycoder-260320.2 → easycoder-260321.16}/doc/core/values/tan.md +0 -0
- {easycoder-260320.2 → easycoder-260321.16}/doc/core/values/timestamp.md +0 -0
- {easycoder-260320.2 → easycoder-260321.16}/doc/core/values/today.md +0 -0
- {easycoder-260320.2 → easycoder-260321.16}/doc/core/values/trim.md +0 -0
- {easycoder-260320.2 → easycoder-260321.16}/doc/core/values/type.md +0 -0
- {easycoder-260320.2 → easycoder-260321.16}/doc/core/values/uppercase.md +0 -0
- {easycoder-260320.2 → easycoder-260321.16}/doc/core/values/value.md +0 -0
- {easycoder-260320.2 → easycoder-260321.16}/doc/core/values/weekday.md +0 -0
- {easycoder-260320.2 → easycoder-260321.16}/doc/graphics/PATTERNS.md +0 -0
- {easycoder-260320.2 → easycoder-260321.16}/doc/graphics/README.md +0 -0
- {easycoder-260320.2 → easycoder-260321.16}/doc/graphics/keywords/add.md +0 -0
- {easycoder-260320.2 → easycoder-260321.16}/doc/graphics/keywords/attach.md +0 -0
- {easycoder-260320.2 → easycoder-260321.16}/doc/graphics/keywords/center.md +0 -0
- {easycoder-260320.2 → easycoder-260321.16}/doc/graphics/keywords/checkbox.md +0 -0
- {easycoder-260320.2 → easycoder-260321.16}/doc/graphics/keywords/clear.md +0 -0
- {easycoder-260320.2 → easycoder-260321.16}/doc/graphics/keywords/close.md +0 -0
- {easycoder-260320.2 → easycoder-260321.16}/doc/graphics/keywords/combobox.md +0 -0
- {easycoder-260320.2 → easycoder-260321.16}/doc/graphics/keywords/create.md +0 -0
- {easycoder-260320.2 → easycoder-260321.16}/doc/graphics/keywords/dialog.md +0 -0
- {easycoder-260320.2 → easycoder-260321.16}/doc/graphics/keywords/disable.md +0 -0
- {easycoder-260320.2 → easycoder-260321.16}/doc/graphics/keywords/enable.md +0 -0
- {easycoder-260320.2 → easycoder-260321.16}/doc/graphics/keywords/group.md +0 -0
- {easycoder-260320.2 → easycoder-260321.16}/doc/graphics/keywords/hide.md +0 -0
- {easycoder-260320.2 → easycoder-260321.16}/doc/graphics/keywords/label.md +0 -0
- {easycoder-260320.2 → easycoder-260321.16}/doc/graphics/keywords/layout.md +0 -0
- {easycoder-260320.2 → easycoder-260321.16}/doc/graphics/keywords/lineinput.md +0 -0
- {easycoder-260320.2 → easycoder-260321.16}/doc/graphics/keywords/listbox.md +0 -0
- {easycoder-260320.2 → easycoder-260321.16}/doc/graphics/keywords/messagebox.md +0 -0
- {easycoder-260320.2 → easycoder-260321.16}/doc/graphics/keywords/move.md +0 -0
- {easycoder-260320.2 → easycoder-260321.16}/doc/graphics/keywords/multiline.md +0 -0
- {easycoder-260320.2 → easycoder-260321.16}/doc/graphics/keywords/on.md +0 -0
- {easycoder-260320.2 → easycoder-260321.16}/doc/graphics/keywords/pushbutton.md +0 -0
- {easycoder-260320.2 → easycoder-260321.16}/doc/graphics/keywords/remove.md +0 -0
- {easycoder-260320.2 → easycoder-260321.16}/doc/graphics/keywords/select.md +0 -0
- {easycoder-260320.2 → easycoder-260321.16}/doc/graphics/keywords/set.md +0 -0
- {easycoder-260320.2 → easycoder-260321.16}/doc/graphics/keywords/window.md +0 -0
- {easycoder-260320.2 → easycoder-260321.16}/doc/graphics/values/attribute.md +0 -0
- {easycoder-260320.2 → easycoder-260321.16}/doc/graphics/values/window.md +0 -0
- {easycoder-260320.2 → easycoder-260321.16}/easycoder/debugger/__init__.py +0 -0
- {easycoder-260320.2 → easycoder-260321.16}/easycoder/debugger/ec_dbg_value_display copy.py +0 -0
- {easycoder-260320.2 → easycoder-260321.16}/easycoder/debugger/ec_dbg_value_display.py +0 -0
- {easycoder-260320.2 → easycoder-260321.16}/easycoder/debugger/ec_dbg_watch_list copy.py +0 -0
- {easycoder-260320.2 → easycoder-260321.16}/easycoder/debugger/ec_dbg_watchlist.py +0 -0
- {easycoder-260320.2 → easycoder-260321.16}/easycoder/debugger/ec_debug.py +0 -0
- {easycoder-260320.2 → easycoder-260321.16}/easycoder/ec_border.py +0 -0
- {easycoder-260320.2 → easycoder-260321.16}/easycoder/ec_classes.py +0 -0
- {easycoder-260320.2 → easycoder-260321.16}/easycoder/ec_compiler.py +0 -0
- {easycoder-260320.2 → easycoder-260321.16}/easycoder/ec_condition.py +0 -0
- {easycoder-260320.2 → easycoder-260321.16}/easycoder/ec_gclasses.py +0 -0
- {easycoder-260320.2 → easycoder-260321.16}/easycoder/ec_graphics.py +0 -0
- {easycoder-260320.2 → easycoder-260321.16}/easycoder/ec_handler.py +0 -0
- {easycoder-260320.2 → easycoder-260321.16}/easycoder/ec_keyboard.py +0 -0
- {easycoder-260320.2 → easycoder-260321.16}/easycoder/ec_psutil.py +0 -0
- {easycoder-260320.2 → easycoder-260321.16}/easycoder/ec_server.py +0 -0
- {easycoder-260320.2 → easycoder-260321.16}/easycoder/ec_timestamp.py +0 -0
- {easycoder-260320.2 → easycoder-260321.16}/easycoder/ec_value.py +0 -0
- {easycoder-260320.2 → easycoder-260321.16}/easycoder/icons/close.png +0 -0
- {easycoder-260320.2 → easycoder-260321.16}/easycoder/icons/exit.png +0 -0
- {easycoder-260320.2 → easycoder-260321.16}/easycoder/icons/run.png +0 -0
- {easycoder-260320.2 → easycoder-260321.16}/easycoder/icons/step.png +0 -0
- {easycoder-260320.2 → easycoder-260321.16}/easycoder/icons/stop.png +0 -0
- {easycoder-260320.2 → easycoder-260321.16}/easycoder/icons/tick.png +0 -0
- {easycoder-260320.2 → easycoder-260321.16}/easycoder/mqtt_listener.py +0 -0
- {easycoder-260320.2 → easycoder-260321.16}/easycoder/mqtt_publisher.py +0 -0
- {easycoder-260320.2/lsp/syntaxes → easycoder-260321.16}/easycoder.tmLanguage.json +0 -0
- {easycoder-260320.2 → easycoder-260321.16}/flash.py +0 -0
- {easycoder-260320.2 → easycoder-260321.16}/images/Semoigo Dawn.jpg +0 -0
- {easycoder-260320.2 → easycoder-260321.16}/json/graphics-demo.json +0 -0
- {easycoder-260320.2 → easycoder-260321.16}/mqtt_listen.py +0 -0
- {easycoder-260320.2 → easycoder-260321.16}/mqtt_publish.py +0 -0
- {easycoder-260320.2 → easycoder-260321.16}/mqtt_test.html +0 -0
- {easycoder-260320.2 → easycoder-260321.16}/plugins/ec_p100.py +0 -0
- {easycoder-260320.2 → easycoder-260321.16}/plugins/ec_points.py +0 -0
- {easycoder-260320.2 → easycoder-260321.16}/plugins/ec_sql.py +0 -0
- {easycoder-260320.2 → easycoder-260321.16}/pyproject.toml +0 -0
- {easycoder-260320.2 → easycoder-260321.16}/spec/README.md +0 -0
- {easycoder-260320.2 → easycoder-260321.16}/spec/easycoder-language-contract.md +0 -0
- {easycoder-260320.2 → easycoder-260321.16}/spec/easycoder-plugin-contract.md +0 -0
- {easycoder-260320.2 → easycoder-260321.16}/spec/easycoder-versioning-policy.md +0 -0
- {easycoder-260320.2 → easycoder-260321.16}/test.py +0 -0
- {easycoder-260320.2 → easycoder-260321.16}/testController.py +0 -0
- {easycoder-260320.2 → easycoder-260321.16}/testDoclets.py +0 -0
- {easycoder-260320.2 → easycoder-260321.16}/testServer.py +0 -0
- {easycoder-260320.2 → easycoder-260321.16}/test_debug_graphics.py +0 -0
- {easycoder-260320.2 → easycoder-260321.16}/test_debug_launch.py +0 -0
- {easycoder-260320.2 → easycoder-260321.16}/test_init_debug.py +0 -0
- {easycoder-260320.2 → easycoder-260321.16}/test_initializers.py +0 -0
- {easycoder-260320.2 → easycoder-260321.16}/test_mqtt_listener.py +0 -0
- {easycoder-260320.2 → easycoder-260321.16}/test_mqtt_publisher.py +0 -0
- {easycoder-260320.2 → easycoder-260321.16}/testdbg.py +0 -0
- {easycoder-260320.2 → easycoder-260321.16}/testg.py +0 -0
- {easycoder-260320.2 → easycoder-260321.16}/testgetconfig.py +0 -0
- {easycoder-260320.2 → easycoder-260321.16}/testmodules.py +0 -0
- {easycoder-260320.2 → easycoder-260321.16}/testmqtt.py +0 -0
- {easycoder-260320.2 → easycoder-260321.16}/testnewui.py +0 -0
- {easycoder-260320.2 → easycoder-260321.16}/testrbr.py +0 -0
- {easycoder-260320.2 → easycoder-260321.16}/testrc.py +0 -0
- {easycoder-260320.2 → easycoder-260321.16}/testrmain.py +0 -0
- {easycoder-260320.2 → easycoder-260321.16}/tests/benchmark.ecs +0 -0
- {easycoder-260320.2 → easycoder-260321.16}/tests/child.ecs +0 -0
- {easycoder-260320.2 → easycoder-260321.16}/tests/ec_mqtt.py +0 -0
- {easycoder-260320.2 → easycoder-260321.16}/tests/editor_server.ecs +0 -0
- {easycoder-260320.2 → easycoder-260321.16}/tests/fizzbuzz.ecs +0 -0
- {easycoder-260320.2 → easycoder-260321.16}/tests/hello.ecs +0 -0
- {easycoder-260320.2 → easycoder-260321.16}/tests/mqtt.ecs +0 -0
- {easycoder-260320.2 → easycoder-260321.16}/tests/mqtt_listener.ecs +0 -0
- {easycoder-260320.2 → easycoder-260321.16}/tests/mqtt_publisher.ecs +0 -0
- {easycoder-260320.2 → easycoder-260321.16}/tests/parent.ecs +0 -0
- {easycoder-260320.2 → easycoder-260321.16}/tests/points.ecs +0 -0
- {easycoder-260320.2 → easycoder-260321.16}/tests/rbr_ui.py +0 -0
- {easycoder-260320.2 → easycoder-260321.16}/tests/rbrconf.ecs +0 -0
- {easycoder-260320.2 → easycoder-260321.16}/tests/rbrwidgets.py +0 -0
- {easycoder-260320.2 → easycoder-260321.16}/tests/server.ecs +0 -0
- {easycoder-260320.2 → easycoder-260321.16}/tests/server_test.html +0 -0
- {easycoder-260320.2 → easycoder-260321.16}/tests/server_test.sh +0 -0
- {easycoder-260320.2 → easycoder-260321.16}/tests/test.ecs +0 -0
- {easycoder-260320.2 → easycoder-260321.16}/tests/testg.ecs +0 -0
- {easycoder-260320.2 → easycoder-260321.16}/tests/tests.ecs +0 -0
- {easycoder-260320.2 → easycoder-260321.16}/tests.py +0 -0
- {easycoder-260320.2 → easycoder-260321.16}/testsql.py +0 -0
- {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:
|
|
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>
|
|
@@ -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
|
|
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, '
|
|
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
|
|
2377
|
-
radius = self.textify(v
|
|
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
|
-
|
|
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
|
|
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
|
|
2646
|
-
radius = self.textify(v
|
|
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
|
|
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
|
|
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
|
|
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
|
-
|
|
57
|
+
parts = arg[6:].split()
|
|
58
|
+
self.scriptName = parts[0]
|
|
59
|
+
self.argv = parts[1:]
|
|
58
60
|
self.debugging = True
|
|
59
61
|
else:
|
|
60
|
-
|
|
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
|
-
|