chemql-python 1.6.1__tar.gz → 1.6.3__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.
- chemql_python-1.6.3/PKG-INFO +1341 -0
- chemql_python-1.6.3/README.md +1327 -0
- {chemql_python-1.6.1 → chemql_python-1.6.3}/pyproject.toml +1 -1
- {chemql_python-1.6.1 → chemql_python-1.6.3}/src/chemql/__init__.py +283 -32
- {chemql_python-1.6.1 → chemql_python-1.6.3}/src/chemql/codecql.py +141 -9
- chemql_python-1.6.3/src/chemql/foo.py +8 -0
- chemql_python-1.6.3/src/chemql/highlighting.py +255 -0
- chemql_python-1.6.3/src/chemql_python.egg-info/PKG-INFO +1341 -0
- {chemql_python-1.6.1 → chemql_python-1.6.3}/src/chemql_python.egg-info/SOURCES.txt +2 -0
- chemql_python-1.6.1/PKG-INFO +0 -1240
- chemql_python-1.6.1/README.md +0 -1226
- chemql_python-1.6.1/src/chemql_python.egg-info/PKG-INFO +0 -1240
- {chemql_python-1.6.1 → chemql_python-1.6.3}/LICENSE +0 -0
- {chemql_python-1.6.1 → chemql_python-1.6.3}/setup.cfg +0 -0
- {chemql_python-1.6.1 → chemql_python-1.6.3}/src/chemql/__main__.py +0 -0
- {chemql_python-1.6.1 → chemql_python-1.6.3}/src/chemql/build.py +0 -0
- {chemql_python-1.6.1 → chemql_python-1.6.3}/src/chemql/colors.json +0 -0
- {chemql_python-1.6.1 → chemql_python-1.6.3}/src/chemql/data/BondEnergies.json +0 -0
- {chemql_python-1.6.1 → chemql_python-1.6.3}/src/chemql/data/MoleculeBonds.json +0 -0
- {chemql_python-1.6.1 → chemql_python-1.6.3}/src/chemql/data/Molecules.json +0 -0
- {chemql_python-1.6.1 → chemql_python-1.6.3}/src/chemql/data/PeriodicTableJSON.json +0 -0
- {chemql_python-1.6.1 → chemql_python-1.6.3}/src/chemql/data/Reactions.json +0 -0
- {chemql_python-1.6.1 → chemql_python-1.6.3}/src/chemql/data/THIRD_PARTY_LICENSES/PeriodicTableJSON.txt +0 -0
- {chemql_python-1.6.1 → chemql_python-1.6.3}/src/chemql/data/THIRD_PARTY_LICENSES/RHEA.txt +0 -0
- {chemql_python-1.6.1 → chemql_python-1.6.3}/src/chemql/html/periodic_table.html +0 -0
- {chemql_python-1.6.1 → chemql_python-1.6.3}/src/chemql/stdlib/README.md +0 -0
- {chemql_python-1.6.1 → chemql_python-1.6.3}/src/chemql/stdlib/collections.cql +0 -0
- {chemql_python-1.6.1 → chemql_python-1.6.3}/src/chemql/stdlib/datetime.cql +0 -0
- {chemql_python-1.6.1 → chemql_python-1.6.3}/src/chemql/stdlib/decimal.cql +0 -0
- {chemql_python-1.6.1 → chemql_python-1.6.3}/src/chemql/stdlib/fractions.cql +0 -0
- {chemql_python-1.6.1 → chemql_python-1.6.3}/src/chemql/stdlib/json.cql +0 -0
- {chemql_python-1.6.1 → chemql_python-1.6.3}/src/chemql/stdlib/math/statistics.cql +0 -0
- {chemql_python-1.6.1 → chemql_python-1.6.3}/src/chemql/stdlib/math.cql +0 -0
- {chemql_python-1.6.1 → chemql_python-1.6.3}/src/chemql/stdlib/pathlib.cql +0 -0
- {chemql_python-1.6.1 → chemql_python-1.6.3}/src/chemql/stdlib/random.cql +0 -0
- {chemql_python-1.6.1 → chemql_python-1.6.3}/src/chemql/stdlib/text.cql +0 -0
- {chemql_python-1.6.1 → chemql_python-1.6.3}/src/chemql_python.egg-info/dependency_links.txt +0 -0
- {chemql_python-1.6.1 → chemql_python-1.6.3}/src/chemql_python.egg-info/entry_points.txt +0 -0
- {chemql_python-1.6.1 → chemql_python-1.6.3}/src/chemql_python.egg-info/requires.txt +0 -0
- {chemql_python-1.6.1 → chemql_python-1.6.3}/src/chemql_python.egg-info/top_level.txt +0 -0
- {chemql_python-1.6.1 → chemql_python-1.6.3}/tests/test_codecql.py +0 -0
- {chemql_python-1.6.1 → chemql_python-1.6.3}/tests/test_external_molecule_lookup.py +0 -0
- {chemql_python-1.6.1 → chemql_python-1.6.3}/tests/test_public_api.py +0 -0
- {chemql_python-1.6.1 → chemql_python-1.6.3}/tests/test_reactions.py +0 -0
- {chemql_python-1.6.1 → chemql_python-1.6.3}/tests/test_stdlib.py +0 -0
- {chemql_python-1.6.1 → chemql_python-1.6.3}/tests/test_structured_types.py +0 -0
|
@@ -0,0 +1,1341 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: chemql-python
|
|
3
|
+
Version: 1.6.3
|
|
4
|
+
Summary: A chemistry-focused query language and REPL
|
|
5
|
+
Author-email: Mohammad Rakibul Islam <rakibulofficial1017@gmail.com>
|
|
6
|
+
Requires-Python: >=3.10
|
|
7
|
+
Description-Content-Type: text/markdown
|
|
8
|
+
License-File: LICENSE
|
|
9
|
+
Requires-Dist: prompt_toolkit>=3.0
|
|
10
|
+
Requires-Dist: rich>=13.7
|
|
11
|
+
Provides-Extra: test
|
|
12
|
+
Requires-Dist: pytest>=8.0; extra == "test"
|
|
13
|
+
Dynamic: license-file
|
|
14
|
+
|
|
15
|
+
# ChemQL & CodecQL
|
|
16
|
+
|
|
17
|
+
ChemQL is a chemistry-oriented query and programming language with an
|
|
18
|
+
interactive terminal, a Python-backed execution environment, chemistry
|
|
19
|
+
data types and operations, user-defined functions, and a package system.
|
|
20
|
+
|
|
21
|
+
CodecQL is the terminal text editor distributed with ChemQL. It edits
|
|
22
|
+
source files, provides syntax highlighting, and supports configurable
|
|
23
|
+
highlighting profiles for multiple file extensions.
|
|
24
|
+
|
|
25
|
+
> **Version represented by this documentation:** ChemQL `1.6.3`; CodecQL
|
|
26
|
+
> `0.0.11`.
|
|
27
|
+
>
|
|
28
|
+
> This README documents the implementation represented by the
|
|
29
|
+
> accompanying source files. Some advanced syntax is intentionally
|
|
30
|
+
> described at a high level; use the built-in `help` system for the
|
|
31
|
+
> authoritative in-app reference.
|
|
32
|
+
|
|
33
|
+
------------------------------------------------------------------------
|
|
34
|
+
|
|
35
|
+
## Contents
|
|
36
|
+
|
|
37
|
+
- [Installation and requirements](#installation-and-requirements)
|
|
38
|
+
- [ChemQL](#chemql)
|
|
39
|
+
- [Starting ChemQL](#starting-chemql)
|
|
40
|
+
- [Running scripts and commands](#running-scripts-and-commands)
|
|
41
|
+
- [Language syntax at a glance](#language-syntax-at-a-glance)
|
|
42
|
+
- [Built-in functions](#built-in-functions)
|
|
43
|
+
- [Standard-library packages](#standard-library-packages)
|
|
44
|
+
- [Chemistry features](#chemistry-features)
|
|
45
|
+
- [Package management](#package-management)
|
|
46
|
+
- [Python interoperability](#python-interoperability)
|
|
47
|
+
- [Help and errors](#help-and-errors)
|
|
48
|
+
- [CodecQL](#codecql)
|
|
49
|
+
- [Opening and creating files](#opening-and-creating-files)
|
|
50
|
+
- [Keyboard shortcuts](#keyboard-shortcuts)
|
|
51
|
+
- [Search syntax](#search-syntax)
|
|
52
|
+
- [Terminal integration](#terminal-integration)
|
|
53
|
+
- [CodecQL configuration](#codecql-configuration)
|
|
54
|
+
- [`colors.json`: editor colors](#colorsjson-editor-colors)
|
|
55
|
+
- [`highlighting.json`: language
|
|
56
|
+
profiles](#highlightingjson-language-profiles)
|
|
57
|
+
- [Rule types](#rule-types)
|
|
58
|
+
- [Style syntax](#style-syntax)
|
|
59
|
+
- [Configuration lookup and
|
|
60
|
+
precedence](#configuration-lookup-and-precedence)
|
|
61
|
+
- [Editing configuration from
|
|
62
|
+
CodecQL](#editing-configuration-from-codecql)
|
|
63
|
+
- [Troubleshooting](#troubleshooting)
|
|
64
|
+
|
|
65
|
+
------------------------------------------------------------------------
|
|
66
|
+
|
|
67
|
+
# Installation and requirements
|
|
68
|
+
|
|
69
|
+
ChemQL is a Python package. CodecQL is a Python terminal application
|
|
70
|
+
that is imported by ChemQL and can also be launched through its editor
|
|
71
|
+
command.
|
|
72
|
+
|
|
73
|
+
The ChemQL runtime imports `prompt_toolkit` for the interactive prompt.
|
|
74
|
+
The editor uses Python's standard library and ANSI terminal escape
|
|
75
|
+
sequences. On Windows it attempts to initialize ANSI support with
|
|
76
|
+
`colorama`, and falls back to enabling virtual-terminal processing when
|
|
77
|
+
`colorama` is unavailable.
|
|
78
|
+
|
|
79
|
+
Install ChemQL using the distribution method provided by the project. If
|
|
80
|
+
installing from a local source checkout, install the project from its
|
|
81
|
+
package root so that its package metadata and dependencies are installed
|
|
82
|
+
together.
|
|
83
|
+
|
|
84
|
+
Check the installed version:
|
|
85
|
+
|
|
86
|
+
``` bash
|
|
87
|
+
chemql --version
|
|
88
|
+
codecql --version
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
If the `codecql` command is not exposed as a separate executable in your
|
|
92
|
+
installation, launch the editor through ChemQL:
|
|
93
|
+
|
|
94
|
+
``` bash
|
|
95
|
+
chemql edit path/to/file.cql
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
------------------------------------------------------------------------
|
|
99
|
+
|
|
100
|
+
# ChemQL
|
|
101
|
+
|
|
102
|
+
## Starting ChemQL
|
|
103
|
+
|
|
104
|
+
Start the interactive prompt:
|
|
105
|
+
|
|
106
|
+
``` bash
|
|
107
|
+
chemql
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
The prompt accepts ChemQL commands and expressions. The welcome message
|
|
111
|
+
points to the built-in help system:
|
|
112
|
+
|
|
113
|
+
``` text
|
|
114
|
+
help
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
or:
|
|
118
|
+
|
|
119
|
+
``` text
|
|
120
|
+
?
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
Exit the interactive prompt with:
|
|
124
|
+
|
|
125
|
+
``` text
|
|
126
|
+
exit
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
You can also press `Ctrl+C` to leave the prompt.
|
|
130
|
+
|
|
131
|
+
The prompt supports multiline input for constructs such as functions,
|
|
132
|
+
macros, Python blocks, and other block forms. The continuation prompt is
|
|
133
|
+
shown as `...`.
|
|
134
|
+
|
|
135
|
+
## Running scripts and commands
|
|
136
|
+
|
|
137
|
+
Execute a one-line or multi-line ChemQL command supplied on the command
|
|
138
|
+
line:
|
|
139
|
+
|
|
140
|
+
``` bash
|
|
141
|
+
chemql -c 'molar_mass{"H2O"}'
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
Execute a source file:
|
|
145
|
+
|
|
146
|
+
``` bash
|
|
147
|
+
chemql -f path/to/script.cql
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
Write command or script output to a file without ANSI escape sequences:
|
|
151
|
+
|
|
152
|
+
``` bash
|
|
153
|
+
chemql -f path/to/script.cql -o output.txt
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
Useful runtime options:
|
|
157
|
+
|
|
158
|
+
-----------------------------------------------------------------------
|
|
159
|
+
Option Purpose
|
|
160
|
+
----------------------------------- -----------------------------------
|
|
161
|
+
`-c`, `--command` Execute ChemQL code supplied as an
|
|
162
|
+
argument
|
|
163
|
+
|
|
164
|
+
`-f`, `--file` Execute ChemQL code from a file
|
|
165
|
+
|
|
166
|
+
`--no-ansi` Disable ANSI styling in output
|
|
167
|
+
|
|
168
|
+
`--suppress-warnings` Suppress warning messages
|
|
169
|
+
|
|
170
|
+
`-o`, `--output FILE` Write captured output to a file
|
|
171
|
+
without ANSI sequences
|
|
172
|
+
|
|
173
|
+
`-v`, `--version` Print the ChemQL version
|
|
174
|
+
|
|
175
|
+
`--upgrade [VERSION]` Upgrade ChemQL, optionally to a
|
|
176
|
+
specified version
|
|
177
|
+
|
|
178
|
+
`--force` / `--dangerously` Force an upgrade, including
|
|
179
|
+
bypassing system-package
|
|
180
|
+
protections
|
|
181
|
+
-----------------------------------------------------------------------
|
|
182
|
+
|
|
183
|
+
`-o` is only valid with `-c` or `-f`.
|
|
184
|
+
|
|
185
|
+
## Language syntax at a glance
|
|
186
|
+
|
|
187
|
+
ChemQL combines its own command/query syntax with Python expressions and
|
|
188
|
+
statements in explicitly delimited blocks.
|
|
189
|
+
|
|
190
|
+
### Function calls
|
|
191
|
+
|
|
192
|
+
ChemQL function calls use braces rather than parentheses:
|
|
193
|
+
|
|
194
|
+
``` text
|
|
195
|
+
function_name{argument1, argument2}
|
|
196
|
+
```
|
|
197
|
+
|
|
198
|
+
Examples:
|
|
199
|
+
|
|
200
|
+
``` text
|
|
201
|
+
molar_mass{"H2O"}
|
|
202
|
+
upper{"hello world"}
|
|
203
|
+
math::sqrt{81}
|
|
204
|
+
```
|
|
205
|
+
|
|
206
|
+
Separate arguments with commas. Quote text containing spaces.
|
|
207
|
+
|
|
208
|
+
### Variables
|
|
209
|
+
|
|
210
|
+
Use `let` to assign a value:
|
|
211
|
+
|
|
212
|
+
``` text
|
|
213
|
+
let answer = 42
|
|
214
|
+
let message = "Hello from ChemQL"
|
|
215
|
+
```
|
|
216
|
+
|
|
217
|
+
Variables can be used in later expressions:
|
|
218
|
+
|
|
219
|
+
``` text
|
|
220
|
+
let radius = 5
|
|
221
|
+
let area = math::PI * radius ** 2
|
|
222
|
+
```
|
|
223
|
+
|
|
224
|
+
The runtime also supports listing and removing variables:
|
|
225
|
+
|
|
226
|
+
``` text
|
|
227
|
+
variables
|
|
228
|
+
unset answer
|
|
229
|
+
```
|
|
230
|
+
|
|
231
|
+
### Definitions and macros
|
|
232
|
+
|
|
233
|
+
Definitions are expanded using an `@NAME` reference:
|
|
234
|
+
|
|
235
|
+
``` text
|
|
236
|
+
define MAX {
|
|
237
|
+
100
|
|
238
|
+
}
|
|
239
|
+
```
|
|
240
|
+
|
|
241
|
+
Use the definition as:
|
|
242
|
+
|
|
243
|
+
``` text
|
|
244
|
+
@MAX
|
|
245
|
+
```
|
|
246
|
+
|
|
247
|
+
Definitions are maintained in the current ChemQL session. The
|
|
248
|
+
preprocessor performs one literal substitution pass; replacement text is
|
|
249
|
+
not recursively expanded.
|
|
250
|
+
|
|
251
|
+
Macros use a block form and are invoked by name according to the macro
|
|
252
|
+
syntax supported by the interpreter. Use `help{syntax}` and the in-app
|
|
253
|
+
completion/help facilities for the exact forms supported by your
|
|
254
|
+
installed version.
|
|
255
|
+
|
|
256
|
+
### Embedded Python
|
|
257
|
+
|
|
258
|
+
A single-line Python statement or expression can be placed inside square
|
|
259
|
+
brackets:
|
|
260
|
+
|
|
261
|
+
``` text
|
|
262
|
+
[print("Hello from Python")]
|
|
263
|
+
```
|
|
264
|
+
|
|
265
|
+
A multiline Python block uses triple square brackets:
|
|
266
|
+
|
|
267
|
+
``` text
|
|
268
|
+
[[[
|
|
269
|
+
numbers = [1, 2, 3, 4]
|
|
270
|
+
total = sum(numbers)
|
|
271
|
+
print(total)
|
|
272
|
+
]]]
|
|
273
|
+
```
|
|
274
|
+
|
|
275
|
+
Python code executes in ChemQL's Python-backed environment. This makes
|
|
276
|
+
Python expressions and available Python objects usable alongside ChemQL
|
|
277
|
+
features.
|
|
278
|
+
|
|
279
|
+
### Embedded ChemQL expressions
|
|
280
|
+
|
|
281
|
+
Double curly braces are used for embedded/lazy ChemQL query expressions
|
|
282
|
+
in supported contexts:
|
|
283
|
+
|
|
284
|
+
``` text
|
|
285
|
+
{{ search molecules ... }}
|
|
286
|
+
```
|
|
287
|
+
|
|
288
|
+
The precise query expression depends on the operation being performed.
|
|
289
|
+
See `help{syntax}` and the query examples shipped with the project.
|
|
290
|
+
|
|
291
|
+
### Control flow
|
|
292
|
+
|
|
293
|
+
ChemQL supports block-oriented control-flow constructs including `if`,
|
|
294
|
+
`elif`, `else`, `for`, and `while`. Closing markers are explicit:
|
|
295
|
+
|
|
296
|
+
``` text
|
|
297
|
+
if condition
|
|
298
|
+
...
|
|
299
|
+
else
|
|
300
|
+
...
|
|
301
|
+
endif
|
|
302
|
+
```
|
|
303
|
+
|
|
304
|
+
``` text
|
|
305
|
+
for item in items
|
|
306
|
+
...
|
|
307
|
+
endfor
|
|
308
|
+
```
|
|
309
|
+
|
|
310
|
+
``` text
|
|
311
|
+
while condition
|
|
312
|
+
...
|
|
313
|
+
endwhile
|
|
314
|
+
```
|
|
315
|
+
|
|
316
|
+
`break` and `continue` are also recognized control keywords.
|
|
317
|
+
|
|
318
|
+
### Functions
|
|
319
|
+
|
|
320
|
+
User-defined functions are declared with `func` and closed with
|
|
321
|
+
`endfunc`. Functions can accept arguments and return values. Inside a
|
|
322
|
+
function, positional arguments are available through the function's
|
|
323
|
+
argument mechanism; the implementation also supports `\1`, `\2`, and so
|
|
324
|
+
on as positional argument references in function bodies.
|
|
325
|
+
|
|
326
|
+
A minimal illustrative shape:
|
|
327
|
+
|
|
328
|
+
``` text
|
|
329
|
+
func greet
|
|
330
|
+
return "Hello"
|
|
331
|
+
endfunc
|
|
332
|
+
```
|
|
333
|
+
|
|
334
|
+
Call a function using ChemQL's brace-call syntax:
|
|
335
|
+
|
|
336
|
+
``` text
|
|
337
|
+
greet{}
|
|
338
|
+
```
|
|
339
|
+
|
|
340
|
+
### Structs, records, and enums
|
|
341
|
+
|
|
342
|
+
ChemQL supports user-defined `struct`, `record`, and `enum`
|
|
343
|
+
declarations. Structs and records can declare fields, and the
|
|
344
|
+
implementation supports inheritance using `from Base`. Structs can
|
|
345
|
+
inherit from structs, records, or Python classes; records can inherit
|
|
346
|
+
from records.
|
|
347
|
+
|
|
348
|
+
Declarations are closed with their corresponding terminators, such as
|
|
349
|
+
`endstruct`, `endrecord`, and `endenum`.
|
|
350
|
+
|
|
351
|
+
Example declaration shape:
|
|
352
|
+
|
|
353
|
+
``` text
|
|
354
|
+
struct Point
|
|
355
|
+
x
|
|
356
|
+
y
|
|
357
|
+
endstruct
|
|
358
|
+
```
|
|
359
|
+
|
|
360
|
+
Enum members can receive automatically generated values when values are
|
|
361
|
+
omitted.
|
|
362
|
+
|
|
363
|
+
### Namespaces
|
|
364
|
+
|
|
365
|
+
Namespaces group related declarations and support public/private
|
|
366
|
+
members:
|
|
367
|
+
|
|
368
|
+
``` text
|
|
369
|
+
namespace Geometry
|
|
370
|
+
public func ...
|
|
371
|
+
private func ...
|
|
372
|
+
endnamespace
|
|
373
|
+
```
|
|
374
|
+
|
|
375
|
+
A namespace member is referenced with a qualified name using `::`, for
|
|
376
|
+
example `Geometry::member`. Private namespace members are intended for
|
|
377
|
+
internal use by functions in the same namespace.
|
|
378
|
+
|
|
379
|
+
### Error handling and signals
|
|
380
|
+
|
|
381
|
+
The interpreter supports structured `risk`, `fix`, and `cleanup`
|
|
382
|
+
sections, closed by `endrisk`. It also supports `signal` and `warn`
|
|
383
|
+
statements in the relevant execution contexts.
|
|
384
|
+
|
|
385
|
+
The `fix` section is used when the risk section raises a handled error;
|
|
386
|
+
`cleanup` is for cleanup side effects. The current error information is
|
|
387
|
+
exposed to the execution environment.
|
|
388
|
+
|
|
389
|
+
## Built-in functions
|
|
390
|
+
|
|
391
|
+
The built-in function set includes general-purpose operations, string
|
|
392
|
+
and collection helpers, file I/O, and chemistry helpers. Calls use
|
|
393
|
+
braces.
|
|
394
|
+
|
|
395
|
+
-----------------------------------------------------------------------
|
|
396
|
+
Category Functions
|
|
397
|
+
----------------------------------- -----------------------------------
|
|
398
|
+
Numbers `abs`, `round`, `min`, `max`, `sum`
|
|
399
|
+
|
|
400
|
+
Core and conversion `len`, `type`, `str`, `int`,
|
|
401
|
+
`float`, `bool`
|
|
402
|
+
|
|
403
|
+
Strings `upper`, `lower`, `contains`,
|
|
404
|
+
`replace`, `split`, `join`
|
|
405
|
+
|
|
406
|
+
Collections `first`, `last`, `unique`, `sort`,
|
|
407
|
+
`reversed`
|
|
408
|
+
|
|
409
|
+
Files and data `read_text`, `read_lines`,
|
|
410
|
+
`read_json`, `read_csv`,
|
|
411
|
+
`write_text`, `write_json`,
|
|
412
|
+
`write_csv`, `file_exists`,
|
|
413
|
+
`list_files`
|
|
414
|
+
|
|
415
|
+
Chemistry `element`, `count_atoms`,
|
|
416
|
+
`molar_mass`, `empirical_formula`
|
|
417
|
+
|
|
418
|
+
Help `help`
|
|
419
|
+
-----------------------------------------------------------------------
|
|
420
|
+
|
|
421
|
+
Examples:
|
|
422
|
+
|
|
423
|
+
``` text
|
|
424
|
+
abs{-15}
|
|
425
|
+
round{3.14159, 2}
|
|
426
|
+
sum{1, 2, 3, 4}
|
|
427
|
+
upper{"chemql"}
|
|
428
|
+
unique{1, 2, 2, 3}
|
|
429
|
+
molar_mass{"H2O"}
|
|
430
|
+
count_atoms{"H2SO4", "O"}
|
|
431
|
+
empirical_formula{"C6H12O6"}
|
|
432
|
+
```
|
|
433
|
+
|
|
434
|
+
File examples:
|
|
435
|
+
|
|
436
|
+
``` text
|
|
437
|
+
let text = read_text{"notes.txt"}
|
|
438
|
+
let rows = read_csv{"data.csv"}
|
|
439
|
+
let data = read_json{"data.json"}
|
|
440
|
+
|
|
441
|
+
write_text{"output.txt", "Hello"}
|
|
442
|
+
write_json{"output.json", data}
|
|
443
|
+
write_csv{"output.csv", rows}
|
|
444
|
+
```
|
|
445
|
+
|
|
446
|
+
`read_csv` treats the first row as headers by default and returns rows
|
|
447
|
+
as dictionaries. Pass `false` as the `headers` argument to read rows as
|
|
448
|
+
lists.
|
|
449
|
+
|
|
450
|
+
For exact signatures, optional arguments, and examples, use:
|
|
451
|
+
|
|
452
|
+
``` text
|
|
453
|
+
help{function_name}
|
|
454
|
+
```
|
|
455
|
+
|
|
456
|
+
For example:
|
|
457
|
+
|
|
458
|
+
``` text
|
|
459
|
+
help{read_csv}
|
|
460
|
+
help{molar_mass}
|
|
461
|
+
```
|
|
462
|
+
|
|
463
|
+
## Standard-library packages
|
|
464
|
+
|
|
465
|
+
ChemQL includes loadable standard-library namespaces. Load a package
|
|
466
|
+
before using its members:
|
|
467
|
+
|
|
468
|
+
``` text
|
|
469
|
+
load math
|
|
470
|
+
math::sqrt{81}
|
|
471
|
+
```
|
|
472
|
+
|
|
473
|
+
The source's built-in help index lists these standard-library
|
|
474
|
+
namespaces:
|
|
475
|
+
|
|
476
|
+
Package Purpose
|
|
477
|
+
-------------------- --------------------------------------------------
|
|
478
|
+
`math` Mathematical constants and numeric functions
|
|
479
|
+
`math::statistics` Descriptive statistics
|
|
480
|
+
`text` String operations and regular expressions
|
|
481
|
+
`collections` Collection and iterable helpers
|
|
482
|
+
`datetime` Dates, times, timestamps, and date arithmetic
|
|
483
|
+
`json` JSON serialization, parsing, and type inspection
|
|
484
|
+
`random` Pseudorandom values and sequence sampling
|
|
485
|
+
|
|
486
|
+
Ask ChemQL for a package's documented members:
|
|
487
|
+
|
|
488
|
+
``` text
|
|
489
|
+
help{stdlib}
|
|
490
|
+
help{math}
|
|
491
|
+
help{math::statistics}
|
|
492
|
+
help{text}
|
|
493
|
+
```
|
|
494
|
+
|
|
495
|
+
A function can be documented individually when its help entry is
|
|
496
|
+
registered:
|
|
497
|
+
|
|
498
|
+
``` text
|
|
499
|
+
help{math::sqrt}
|
|
500
|
+
```
|
|
501
|
+
|
|
502
|
+
## Chemistry features
|
|
503
|
+
|
|
504
|
+
ChemQL exposes chemistry-oriented data types and operations, including:
|
|
505
|
+
|
|
506
|
+
- `Element`, `Molecule`, and `Reaction` objects.
|
|
507
|
+
- Element and molecule lookup helpers.
|
|
508
|
+
- Reaction lookup and reaction searching.
|
|
509
|
+
- Stoichiometric balancing through `balance_stoichiometry`.
|
|
510
|
+
- Reaction matching against the current temperature, pressure, and
|
|
511
|
+
catalyst conditions.
|
|
512
|
+
- Chemistry built-ins such as `element`, `count_atoms`, `molar_mass`,
|
|
513
|
+
and `empirical_formula`.
|
|
514
|
+
|
|
515
|
+
The interactive command set includes chemistry/query commands such as
|
|
516
|
+
`search`, `source`, `findel`, `findmol`, `findre`, `react`, `balance`,
|
|
517
|
+
`conditions`, and `view`.
|
|
518
|
+
|
|
519
|
+
Examples of built-in chemistry functions:
|
|
520
|
+
|
|
521
|
+
``` text
|
|
522
|
+
element{"Na"}
|
|
523
|
+
count_atoms{"H2SO4", "O"}
|
|
524
|
+
molar_mass{"H2O"}
|
|
525
|
+
empirical_formula{"C6H12O6"}
|
|
526
|
+
```
|
|
527
|
+
|
|
528
|
+
Reaction operations can depend on the current reaction conditions.
|
|
529
|
+
Inspect or set conditions with the relevant interactive commands and use
|
|
530
|
+
`conditions` to display the current state.
|
|
531
|
+
|
|
532
|
+
The available data sources and query fields are defined by the ChemQL
|
|
533
|
+
package/data files. Use the interactive prompt's completion and
|
|
534
|
+
`help{chemistry}` for the current details.
|
|
535
|
+
|
|
536
|
+
## Package management
|
|
537
|
+
|
|
538
|
+
ChemQL provides package-management subcommands:
|
|
539
|
+
|
|
540
|
+
-------------------------------------------------------------------------------
|
|
541
|
+
Command Purpose
|
|
542
|
+
------------------------------------------- -----------------------------------
|
|
543
|
+
`chemql init [NAME] [-d DIRECTORY]` Create a ChemQL package project
|
|
544
|
+
|
|
545
|
+
`chemql build` Build the current package
|
|
546
|
+
|
|
547
|
+
`chemql search QUERY` Search the package registry
|
|
548
|
+
|
|
549
|
+
`chemql info NAME` Show registry information for a
|
|
550
|
+
package
|
|
551
|
+
|
|
552
|
+
`chemql install NAME [--version VERSION]` Install a package
|
|
553
|
+
|
|
554
|
+
`chemql upgrade NAME [--version VERSION]` Upgrade an installed package
|
|
555
|
+
|
|
556
|
+
`chemql list` List installed packages
|
|
557
|
+
|
|
558
|
+
`chemql uninstall NAME` Uninstall a package
|
|
559
|
+
|
|
560
|
+
`chemql upload` Upload the current package to the
|
|
561
|
+
registry
|
|
562
|
+
-------------------------------------------------------------------------------
|
|
563
|
+
|
|
564
|
+
Example workflow:
|
|
565
|
+
|
|
566
|
+
``` bash
|
|
567
|
+
chemql search statistics
|
|
568
|
+
chemql info package_name
|
|
569
|
+
chemql install package_name
|
|
570
|
+
chemql list
|
|
571
|
+
```
|
|
572
|
+
|
|
573
|
+
Load an installed package from the ChemQL prompt:
|
|
574
|
+
|
|
575
|
+
``` text
|
|
576
|
+
load package_name
|
|
577
|
+
```
|
|
578
|
+
|
|
579
|
+
Then call its namespaced functions:
|
|
580
|
+
|
|
581
|
+
``` text
|
|
582
|
+
package_name::function_name{...}
|
|
583
|
+
```
|
|
584
|
+
|
|
585
|
+
The package manager also supports upgrading ChemQL itself:
|
|
586
|
+
|
|
587
|
+
``` bash
|
|
588
|
+
chemql --upgrade
|
|
589
|
+
chemql --upgrade 1.6.3
|
|
590
|
+
```
|
|
591
|
+
|
|
592
|
+
Use `--force` only when you understand that it bypasses normal
|
|
593
|
+
protections around system-managed installations.
|
|
594
|
+
|
|
595
|
+
## Python interoperability
|
|
596
|
+
|
|
597
|
+
ChemQL is implemented in Python and evaluates embedded Python blocks in
|
|
598
|
+
its Python execution environment. The runtime imports and uses Python
|
|
599
|
+
modules internally, and the language exposes Python-backed objects and
|
|
600
|
+
functions.
|
|
601
|
+
|
|
602
|
+
Use square-bracket blocks for Python statements and expressions. Use
|
|
603
|
+
`[[[ ... ]]]` for multiline Python. This is the intended boundary
|
|
604
|
+
between ChemQL's command/query syntax and general Python code.
|
|
605
|
+
|
|
606
|
+
## Help and errors
|
|
607
|
+
|
|
608
|
+
The interactive help system is the quickest way to discover the exact
|
|
609
|
+
syntax supported by the installed version:
|
|
610
|
+
|
|
611
|
+
``` text
|
|
612
|
+
help
|
|
613
|
+
help{syntax}
|
|
614
|
+
help{errors}
|
|
615
|
+
help{files}
|
|
616
|
+
help{chemistry}
|
|
617
|
+
help{stdlib}
|
|
618
|
+
help{function_name}
|
|
619
|
+
```
|
|
620
|
+
|
|
621
|
+
The runtime defines specific built-in error classes:
|
|
622
|
+
|
|
623
|
+
- `TooFewArguments`
|
|
624
|
+
- `TooManyArguments`
|
|
625
|
+
- `InvalidArgumentType`
|
|
626
|
+
- `InvalidArgumentValue`
|
|
627
|
+
- `FileReadError`
|
|
628
|
+
- `FileWriteError`
|
|
629
|
+
|
|
630
|
+
Other errors can include `SyntaxError`, `NameError`, and
|
|
631
|
+
`PermissionError`.
|
|
632
|
+
|
|
633
|
+
------------------------------------------------------------------------
|
|
634
|
+
|
|
635
|
+
# CodecQL
|
|
636
|
+
|
|
637
|
+
CodecQL is a terminal-based text editor intended for ChemQL source
|
|
638
|
+
files. It also supports configurable syntax-highlighting profiles for
|
|
639
|
+
other extensions.
|
|
640
|
+
|
|
641
|
+
## Opening and creating files
|
|
642
|
+
|
|
643
|
+
Open an existing file:
|
|
644
|
+
|
|
645
|
+
``` bash
|
|
646
|
+
codecql script.cql
|
|
647
|
+
```
|
|
648
|
+
|
|
649
|
+
Create a new file by opening a path that does not exist yet:
|
|
650
|
+
|
|
651
|
+
``` bash
|
|
652
|
+
codecql new_script.cql
|
|
653
|
+
```
|
|
654
|
+
|
|
655
|
+
The editor starts with an empty buffer when the file does not exist.
|
|
656
|
+
Save with `Ctrl+S` to create it.
|
|
657
|
+
|
|
658
|
+
Launch it through ChemQL:
|
|
659
|
+
|
|
660
|
+
``` bash
|
|
661
|
+
chemql edit script.cql
|
|
662
|
+
```
|
|
663
|
+
|
|
664
|
+
Open the editor's main highlighting configuration:
|
|
665
|
+
|
|
666
|
+
``` bash
|
|
667
|
+
codecql --main-highlighting
|
|
668
|
+
```
|
|
669
|
+
|
|
670
|
+
Open the current working directory's local highlighting configuration:
|
|
671
|
+
|
|
672
|
+
``` bash
|
|
673
|
+
codecql --local-highlighting
|
|
674
|
+
```
|
|
675
|
+
|
|
676
|
+
The two highlighting flags cannot be used together. If the selected
|
|
677
|
+
configuration file does not exist, CodecQL creates an empty JSON object
|
|
678
|
+
in that location.
|
|
679
|
+
|
|
680
|
+
## Keyboard shortcuts
|
|
681
|
+
|
|
682
|
+
-----------------------------------------------------------------------
|
|
683
|
+
Shortcut Action
|
|
684
|
+
----------------------------------- -----------------------------------
|
|
685
|
+
`Ctrl+S` Save the current file
|
|
686
|
+
|
|
687
|
+
`Ctrl+Q` Quit; if there are unsaved changes,
|
|
688
|
+
press it again to discard and quit
|
|
689
|
+
|
|
690
|
+
`Ctrl+Z` Undo
|
|
691
|
+
|
|
692
|
+
`Ctrl+Y` Redo
|
|
693
|
+
|
|
694
|
+
`Ctrl+F` Open search
|
|
695
|
+
|
|
696
|
+
`Ctrl+C` Copy the current selection
|
|
697
|
+
|
|
698
|
+
`Ctrl+X` Cut the current selection
|
|
699
|
+
|
|
700
|
+
`Ctrl+V` Paste the editor clipboard
|
|
701
|
+
|
|
702
|
+
`Shift+Insert` Paste the editor clipboard
|
|
703
|
+
|
|
704
|
+
`Ctrl+T` Open a split terminal
|
|
705
|
+
|
|
706
|
+
`Ctrl+R` Save if needed and run the current
|
|
707
|
+
file with ChemQL
|
|
708
|
+
|
|
709
|
+
`Shift+Arrow` Extend the selection while moving
|
|
710
|
+
the cursor
|
|
711
|
+
|
|
712
|
+
`Ctrl+Arrow Up/Down` Scroll the viewport
|
|
713
|
+
|
|
714
|
+
`Ctrl+Arrow Left/Right` Move by word
|
|
715
|
+
|
|
716
|
+
`Home` / `End` Move to the start/end of the line
|
|
717
|
+
|
|
718
|
+
`Backspace` / `Delete` Delete text
|
|
719
|
+
-----------------------------------------------------------------------
|
|
720
|
+
|
|
721
|
+
Clipboard integration uses the available system clipboard command when
|
|
722
|
+
possible: - Windows: `clip` - WSL: `clip.exe` - macOS: `pbcopy` - Linux:
|
|
723
|
+
`wl-copy`, `xclip`, or `xsel`
|
|
724
|
+
|
|
725
|
+
If no system clipboard utility is available, CodecQL keeps the copied
|
|
726
|
+
text in its own editor clipboard.
|
|
727
|
+
|
|
728
|
+
## Search syntax
|
|
729
|
+
|
|
730
|
+
Press `Ctrl+F` to open search. Enter a query and use the arrow keys to
|
|
731
|
+
move between matches. Press `Enter` to select the next match; `Up` or
|
|
732
|
+
`Left` selects the previous match. `Esc` closes search.
|
|
733
|
+
|
|
734
|
+
Search supports optional prefix flags:
|
|
735
|
+
|
|
736
|
+
Flag Meaning
|
|
737
|
+
------ -----------------------------------------
|
|
738
|
+
`r` Treat the query as a regular expression
|
|
739
|
+
`l` Literal search (the default)
|
|
740
|
+
`w` Match whole words
|
|
741
|
+
`i` Ignore case
|
|
742
|
+
|
|
743
|
+
Place flags before a colon. Examples:
|
|
744
|
+
|
|
745
|
+
``` text
|
|
746
|
+
hello
|
|
747
|
+
i:hello
|
|
748
|
+
w:hello
|
|
749
|
+
ri:\b[A-Z]{2,}\b
|
|
750
|
+
lw:token
|
|
751
|
+
```
|
|
752
|
+
|
|
753
|
+
Search is case-insensitive by default. `r` and `l` cannot be combined.
|
|
754
|
+
|
|
755
|
+
## Terminal integration
|
|
756
|
+
|
|
757
|
+
- `Ctrl+T` opens a shell in a terminal pane/window.
|
|
758
|
+
- `Ctrl+R` saves the current buffer if it has unsaved changes, then
|
|
759
|
+
runs the file with `chemql -f`.
|
|
760
|
+
- On Windows, CodecQL uses a new console, or a Windows Terminal split
|
|
761
|
+
pane when running inside Windows Terminal.
|
|
762
|
+
- On Unix-like systems, CodecQL uses a pseudo-terminal for the
|
|
763
|
+
integrated terminal.
|
|
764
|
+
|
|
765
|
+
------------------------------------------------------------------------
|
|
766
|
+
|
|
767
|
+
# CodecQL configuration
|
|
768
|
+
|
|
769
|
+
CodecQL has two separate JSON configuration files:
|
|
770
|
+
|
|
771
|
+
- `colors.json` controls the editor's ANSI color palette.
|
|
772
|
+
- `highlighting.json` controls which tokens are highlighted for each
|
|
773
|
+
file extension and which style is assigned to each rule.
|
|
774
|
+
|
|
775
|
+
They serve different purposes. Changing a color in `colors.json` changes
|
|
776
|
+
the appearance of a named style throughout the editor. Changing
|
|
777
|
+
`highlighting.json` changes which words are assigned to styles for a
|
|
778
|
+
language.
|
|
779
|
+
|
|
780
|
+
## `colors.json`: editor colors
|
|
781
|
+
|
|
782
|
+
`colors.json` is read from the directory containing the CodecQL source
|
|
783
|
+
module. It has two top-level objects: `syntax` and `ui`.
|
|
784
|
+
|
|
785
|
+
Every color entry must be an object containing an integer `ansi256`
|
|
786
|
+
value from `0` through `255`. The optional `channel` is either
|
|
787
|
+
`foreground` (the default) or `background`.
|
|
788
|
+
|
|
789
|
+
Example:
|
|
790
|
+
|
|
791
|
+
``` json
|
|
792
|
+
{
|
|
793
|
+
"syntax": {
|
|
794
|
+
"comment": { "ansi256": 244 },
|
|
795
|
+
"string": { "ansi256": 114 },
|
|
796
|
+
"number": { "ansi256": 179 },
|
|
797
|
+
"formula": { "ansi256": 117 },
|
|
798
|
+
"operator": { "ansi256": 213 },
|
|
799
|
+
"delimiter": { "ansi256": 250 },
|
|
800
|
+
"command": { "ansi256": 81 },
|
|
801
|
+
"keyword": { "ansi256": 141 },
|
|
802
|
+
"constant": { "ansi256": 215 },
|
|
803
|
+
"type": { "ansi256": 150 },
|
|
804
|
+
"source": { "ansi256": 110 },
|
|
805
|
+
"condition": { "ansi256": 180 },
|
|
806
|
+
"property": { "ansi256": 116 },
|
|
807
|
+
"builtin": { "ansi256": 222 }
|
|
808
|
+
},
|
|
809
|
+
"ui": {
|
|
810
|
+
"line_numbers": {
|
|
811
|
+
"ansi256": 244
|
|
812
|
+
},
|
|
813
|
+
"status_background": {
|
|
814
|
+
"ansi256": 24,
|
|
815
|
+
"channel": "background"
|
|
816
|
+
},
|
|
817
|
+
"status_foreground": {
|
|
818
|
+
"ansi256": 255
|
|
819
|
+
}
|
|
820
|
+
}
|
|
821
|
+
}
|
|
822
|
+
```
|
|
823
|
+
|
|
824
|
+
The values above mirror the fallback palette in the editor source. If
|
|
825
|
+
`colors.json` is missing, CodecQL uses that fallback palette. If the
|
|
826
|
+
file exists but is malformed or missing a required top-level group,
|
|
827
|
+
loading the theme raises a configuration error.
|
|
828
|
+
|
|
829
|
+
### Syntax color categories
|
|
830
|
+
|
|
831
|
+
The editor's syntax theme uses these categories:
|
|
832
|
+
|
|
833
|
+
Category Used for
|
|
834
|
+
------------- ---------------------------------------------------
|
|
835
|
+
`comment` Comments
|
|
836
|
+
`string` Quoted strings
|
|
837
|
+
`number` Numeric literals
|
|
838
|
+
`formula` Chemical formula-like tokens
|
|
839
|
+
`operator` Operators
|
|
840
|
+
`delimiter` Brackets and punctuation delimiters
|
|
841
|
+
`command` ChemQL commands
|
|
842
|
+
`keyword` Language/control keywords
|
|
843
|
+
`constant` Values such as `true`, `false`, and `none`
|
|
844
|
+
`type` Type/declaration names and manifest table headers
|
|
845
|
+
`source` ChemQL data sources
|
|
846
|
+
`condition` Chemistry conditions and units
|
|
847
|
+
`property` Chemistry fields and manifest keys
|
|
848
|
+
`builtin` Python built-in names recognized by the editor
|
|
849
|
+
|
|
850
|
+
The UI categories are:
|
|
851
|
+
|
|
852
|
+
Category Used for
|
|
853
|
+
--------------------- -----------------------
|
|
854
|
+
`line_numbers` Line-number gutter
|
|
855
|
+
`status_background` Status bar background
|
|
856
|
+
`status_foreground` Status bar text
|
|
857
|
+
|
|
858
|
+
### ANSI 256-color values
|
|
859
|
+
|
|
860
|
+
`ansi256` is a terminal color index, not an RGB hex value. It accepts
|
|
861
|
+
integers from `0` to `255`.
|
|
862
|
+
|
|
863
|
+
Common ranges in the standard 256-color palette:
|
|
864
|
+
|
|
865
|
+
- `0–15`: standard and bright terminal colors.
|
|
866
|
+
- `16–231`: 6×6×6 RGB color cube.
|
|
867
|
+
- `232–255`: grayscale ramp.
|
|
868
|
+
|
|
869
|
+
The actual appearance depends on the terminal's color palette and
|
|
870
|
+
settings.
|
|
871
|
+
|
|
872
|
+
To set a background color, add `"channel": "background"`:
|
|
873
|
+
|
|
874
|
+
``` json
|
|
875
|
+
"status_background": {
|
|
876
|
+
"ansi256": 24,
|
|
877
|
+
"channel": "background"
|
|
878
|
+
}
|
|
879
|
+
```
|
|
880
|
+
|
|
881
|
+
Foreground is assumed when `channel` is omitted.
|
|
882
|
+
|
|
883
|
+
## `highlighting.json`: language profiles
|
|
884
|
+
|
|
885
|
+
`highlighting.json` maps file extensions to ordered lists of
|
|
886
|
+
highlighting rules.
|
|
887
|
+
|
|
888
|
+
CodecQL starts with a built-in `.cql` profile. It then loads the main
|
|
889
|
+
configuration and the current directory's local configuration, if
|
|
890
|
+
present. A custom profile for an existing extension replaces that
|
|
891
|
+
extension's previous profile; a new extension adds a profile.
|
|
892
|
+
|
|
893
|
+
A minimal configuration:
|
|
894
|
+
|
|
895
|
+
``` json
|
|
896
|
+
{
|
|
897
|
+
".py": [
|
|
898
|
+
{
|
|
899
|
+
"name": "python-keywords",
|
|
900
|
+
"type": "keywords",
|
|
901
|
+
"values": ["def", "class", "return", "if", "elif", "else", "for", "while", "import", "from", "as", "try", "except", "finally", "with", "pass", "break", "continue"],
|
|
902
|
+
"style": "keyword"
|
|
903
|
+
},
|
|
904
|
+
{
|
|
905
|
+
"name": "python-builtins",
|
|
906
|
+
"type": "keywords",
|
|
907
|
+
"values": ["print", "len", "range", "enumerate", "zip", "map", "filter", "sum", "min", "max", "str", "int", "float", "list", "dict", "set", "tuple"],
|
|
908
|
+
"style": "builtin"
|
|
909
|
+
}
|
|
910
|
+
],
|
|
911
|
+
".js": [
|
|
912
|
+
{
|
|
913
|
+
"name": "javascript-keywords",
|
|
914
|
+
"type": "keywords",
|
|
915
|
+
"values": ["const", "let", "var", "function", "return", "if", "else", "for", "while", "class", "new", "import", "export", "from", "async", "await"],
|
|
916
|
+
"style": "keyword"
|
|
917
|
+
}
|
|
918
|
+
]
|
|
919
|
+
}
|
|
920
|
+
```
|
|
921
|
+
|
|
922
|
+
### Profile structure
|
|
923
|
+
|
|
924
|
+
The top-level value must be a JSON object. Each key is a file extension
|
|
925
|
+
and each value is an array of rules.
|
|
926
|
+
|
|
927
|
+
``` json
|
|
928
|
+
{
|
|
929
|
+
".extension": [
|
|
930
|
+
{
|
|
931
|
+
"name": "rule-name",
|
|
932
|
+
"type": "keywords",
|
|
933
|
+
"values": ["word1", "word2"],
|
|
934
|
+
"style": "keyword"
|
|
935
|
+
}
|
|
936
|
+
]
|
|
937
|
+
}
|
|
938
|
+
```
|
|
939
|
+
|
|
940
|
+
Extension normalization: - A leading dot is added if omitted. -
|
|
941
|
+
Extensions are converted to lowercase. - Empty extensions and values
|
|
942
|
+
containing path separators are rejected. - The profile is selected from
|
|
943
|
+
the file's final extension. For example, `script.py` uses `.py`.
|
|
944
|
+
|
|
945
|
+
Each rule must be an object with: - `name`: non-empty string identifying
|
|
946
|
+
the rule. - `type`: supported rule type (`keywords` or `regex`). -
|
|
947
|
+
`style`: non-empty style expression.
|
|
948
|
+
|
|
949
|
+
A keyword rule additionally requires: - `values`: a non-empty array of
|
|
950
|
+
non-empty strings.
|
|
951
|
+
|
|
952
|
+
Keyword matching is case-insensitive. Rule order matters: the first
|
|
953
|
+
matching keyword rule supplies the style for that word.
|
|
954
|
+
|
|
955
|
+
### Rule types
|
|
956
|
+
|
|
957
|
+
#### `keywords`
|
|
958
|
+
|
|
959
|
+
Use this rule to assign a style to a list of exact words:
|
|
960
|
+
|
|
961
|
+
``` json
|
|
962
|
+
{
|
|
963
|
+
"name": "control-flow",
|
|
964
|
+
"type": "keywords",
|
|
965
|
+
"values": ["if", "else", "while", "for", "return"],
|
|
966
|
+
"style": "keyword"
|
|
967
|
+
}
|
|
968
|
+
```
|
|
969
|
+
|
|
970
|
+
The current implementation applies keyword rules during identifier
|
|
971
|
+
highlighting. Matching is case-insensitive.
|
|
972
|
+
|
|
973
|
+
#### `regex`
|
|
974
|
+
|
|
975
|
+
Regex rules are accepted and validated by the profile loader. A regex
|
|
976
|
+
rule must include a non-empty `pattern`; `case_sensitive` is optional
|
|
977
|
+
and defaults to `true`.
|
|
978
|
+
|
|
979
|
+
``` json
|
|
980
|
+
{
|
|
981
|
+
"name": "special-identifiers",
|
|
982
|
+
"type": "regex",
|
|
983
|
+
"pattern": "\\b(?:TODO|FIXME|NOTE)\\b",
|
|
984
|
+
"case_sensitive": true,
|
|
985
|
+
"style": "#FFB000 bold"
|
|
986
|
+
}
|
|
987
|
+
```
|
|
988
|
+
|
|
989
|
+
**Implementation note:** the current editor integration applies
|
|
990
|
+
`keywords` rules through `get_keyword_style`. Although `regex` rules are
|
|
991
|
+
parsed and validated by `highlighting.py`, they are not yet applied by
|
|
992
|
+
the current token-highlighting path. Treat regex highlighting as a
|
|
993
|
+
reserved/configuration-ready feature until regex application is wired
|
|
994
|
+
into the renderer.
|
|
995
|
+
|
|
996
|
+
### Style syntax
|
|
997
|
+
|
|
998
|
+
A rule's `style` is a space-separated list of style components.
|
|
999
|
+
Components can be combined.
|
|
1000
|
+
|
|
1001
|
+
#### Named theme styles
|
|
1002
|
+
|
|
1003
|
+
These names refer to entries in `colors.json` under `syntax`:
|
|
1004
|
+
|
|
1005
|
+
``` text
|
|
1006
|
+
keyword
|
|
1007
|
+
command
|
|
1008
|
+
operator
|
|
1009
|
+
string
|
|
1010
|
+
comment
|
|
1011
|
+
number
|
|
1012
|
+
constant
|
|
1013
|
+
type
|
|
1014
|
+
source
|
|
1015
|
+
condition
|
|
1016
|
+
property
|
|
1017
|
+
builtin
|
|
1018
|
+
```
|
|
1019
|
+
|
|
1020
|
+
Example:
|
|
1021
|
+
|
|
1022
|
+
``` json
|
|
1023
|
+
"style": "keyword"
|
|
1024
|
+
```
|
|
1025
|
+
|
|
1026
|
+
#### Formatting modifiers
|
|
1027
|
+
|
|
1028
|
+
The editor recognizes these modifiers:
|
|
1029
|
+
|
|
1030
|
+
Modifier Effect
|
|
1031
|
+
------------- -------------------------------
|
|
1032
|
+
`bold` Bold text
|
|
1033
|
+
`dim` Dim text
|
|
1034
|
+
`italic` Italic text
|
|
1035
|
+
`underline` Underlined text
|
|
1036
|
+
`reverse` Reverse foreground/background
|
|
1037
|
+
`strike` Strikethrough text
|
|
1038
|
+
|
|
1039
|
+
Example:
|
|
1040
|
+
|
|
1041
|
+
``` json
|
|
1042
|
+
"style": "keyword bold underline"
|
|
1043
|
+
```
|
|
1044
|
+
|
|
1045
|
+
#### Custom foreground colors
|
|
1046
|
+
|
|
1047
|
+
Use a six-digit hexadecimal RGB color prefixed with `#`:
|
|
1048
|
+
|
|
1049
|
+
``` json
|
|
1050
|
+
"style": "#FF00FF"
|
|
1051
|
+
```
|
|
1052
|
+
|
|
1053
|
+
#### Custom background colors
|
|
1054
|
+
|
|
1055
|
+
Use `bg:` followed by a six-digit hexadecimal RGB color:
|
|
1056
|
+
|
|
1057
|
+
``` json
|
|
1058
|
+
"style": "bg:#202020"
|
|
1059
|
+
```
|
|
1060
|
+
|
|
1061
|
+
#### Combining components
|
|
1062
|
+
|
|
1063
|
+
You can combine a named style, formatting modifiers, and custom
|
|
1064
|
+
foreground/background colors:
|
|
1065
|
+
|
|
1066
|
+
``` json
|
|
1067
|
+
"style": "#FF00FF underline bold italic"
|
|
1068
|
+
```
|
|
1069
|
+
|
|
1070
|
+
``` json
|
|
1071
|
+
"style": "keyword bold"
|
|
1072
|
+
```
|
|
1073
|
+
|
|
1074
|
+
``` json
|
|
1075
|
+
"style": "#E0B0FF bg:#202020 bold"
|
|
1076
|
+
```
|
|
1077
|
+
|
|
1078
|
+
Hexadecimal colors use true-color ANSI escape sequences. Your terminal
|
|
1079
|
+
must support ANSI styling and preferably 24-bit true color for the full
|
|
1080
|
+
effect.
|
|
1081
|
+
|
|
1082
|
+
### Example: create a profile for Python
|
|
1083
|
+
|
|
1084
|
+
Create or edit `highlighting.json` in your project directory:
|
|
1085
|
+
|
|
1086
|
+
``` json
|
|
1087
|
+
{
|
|
1088
|
+
".py": [
|
|
1089
|
+
{
|
|
1090
|
+
"name": "python-keywords",
|
|
1091
|
+
"type": "keywords",
|
|
1092
|
+
"values": [
|
|
1093
|
+
"def", "class", "return", "if", "elif", "else",
|
|
1094
|
+
"for", "while", "in", "break", "continue",
|
|
1095
|
+
"import", "from", "as", "try", "except",
|
|
1096
|
+
"finally", "with", "raise", "yield", "lambda"
|
|
1097
|
+
],
|
|
1098
|
+
"style": "keyword bold"
|
|
1099
|
+
},
|
|
1100
|
+
{
|
|
1101
|
+
"name": "python-constants",
|
|
1102
|
+
"type": "keywords",
|
|
1103
|
+
"values": ["True", "False", "None"],
|
|
1104
|
+
"style": "#FFB86C bold"
|
|
1105
|
+
},
|
|
1106
|
+
{
|
|
1107
|
+
"name": "python-builtins",
|
|
1108
|
+
"type": "keywords",
|
|
1109
|
+
"values": ["print", "len", "range", "enumerate", "zip", "sum", "min", "max"],
|
|
1110
|
+
"style": "builtin"
|
|
1111
|
+
}
|
|
1112
|
+
]
|
|
1113
|
+
}
|
|
1114
|
+
```
|
|
1115
|
+
|
|
1116
|
+
Then open a Python file from that directory:
|
|
1117
|
+
|
|
1118
|
+
``` bash
|
|
1119
|
+
codecql example.py
|
|
1120
|
+
```
|
|
1121
|
+
|
|
1122
|
+
The local `.py` profile is loaded and used for matching identifier
|
|
1123
|
+
tokens.
|
|
1124
|
+
|
|
1125
|
+
### Example: add a language without changing ChemQL's built-in profile
|
|
1126
|
+
|
|
1127
|
+
You can define several extensions in the same JSON file:
|
|
1128
|
+
|
|
1129
|
+
``` json
|
|
1130
|
+
{
|
|
1131
|
+
".py": [
|
|
1132
|
+
{
|
|
1133
|
+
"name": "python-keywords",
|
|
1134
|
+
"type": "keywords",
|
|
1135
|
+
"values": ["def", "class", "return", "if", "else", "for", "while"],
|
|
1136
|
+
"style": "keyword"
|
|
1137
|
+
}
|
|
1138
|
+
],
|
|
1139
|
+
".rs": [
|
|
1140
|
+
{
|
|
1141
|
+
"name": "rust-keywords",
|
|
1142
|
+
"type": "keywords",
|
|
1143
|
+
"values": ["fn", "let", "mut", "pub", "struct", "enum", "impl", "trait", "use", "mod", "match", "if", "else", "loop", "while", "for", "return"],
|
|
1144
|
+
"style": "#D19A66 bold"
|
|
1145
|
+
}
|
|
1146
|
+
],
|
|
1147
|
+
".js": [
|
|
1148
|
+
{
|
|
1149
|
+
"name": "javascript-keywords",
|
|
1150
|
+
"type": "keywords",
|
|
1151
|
+
"values": ["const", "let", "var", "function", "return", "class", "new", "async", "await"],
|
|
1152
|
+
"style": "keyword"
|
|
1153
|
+
}
|
|
1154
|
+
]
|
|
1155
|
+
}
|
|
1156
|
+
```
|
|
1157
|
+
|
|
1158
|
+
This adds profiles for `.py`, `.rs`, and `.js`. It does not remove the
|
|
1159
|
+
built-in `.cql` profile unless you explicitly provide a `.cql` profile
|
|
1160
|
+
in a loaded configuration.
|
|
1161
|
+
|
|
1162
|
+
### Configuration lookup and precedence
|
|
1163
|
+
|
|
1164
|
+
The editor loads highlighting profiles in this order:
|
|
1165
|
+
|
|
1166
|
+
1. The built-in profiles in `highlighting.py` (currently includes
|
|
1167
|
+
`.cql`).
|
|
1168
|
+
2. `highlighting.json` beside the CodecQL source module (the main
|
|
1169
|
+
configuration).
|
|
1170
|
+
3. `highlighting.json` in the current working directory (the local
|
|
1171
|
+
configuration).
|
|
1172
|
+
|
|
1173
|
+
Later profiles replace earlier profiles for the same extension.
|
|
1174
|
+
Therefore:
|
|
1175
|
+
|
|
1176
|
+
- The main configuration can provide defaults shared by projects.
|
|
1177
|
+
- A local configuration can override those defaults for the current
|
|
1178
|
+
project.
|
|
1179
|
+
- Profiles for unrelated extensions are retained.
|
|
1180
|
+
- If the main and local paths point to the same file, it is loaded
|
|
1181
|
+
only once.
|
|
1182
|
+
- If neither file exists, the built-in profiles remain available.
|
|
1183
|
+
|
|
1184
|
+
**Important:** the local configuration is merged by extension; it does
|
|
1185
|
+
not merge individual rules into an existing extension profile. If a
|
|
1186
|
+
local `.py` profile is present, it replaces the main `.py` profile as a
|
|
1187
|
+
whole.
|
|
1188
|
+
|
|
1189
|
+
The main configuration path is relative to the installed CodecQL module.
|
|
1190
|
+
The local configuration path is relative to the directory from which
|
|
1191
|
+
CodecQL is launched.
|
|
1192
|
+
|
|
1193
|
+
### Editing configuration from CodecQL
|
|
1194
|
+
|
|
1195
|
+
Open the main configuration:
|
|
1196
|
+
|
|
1197
|
+
``` bash
|
|
1198
|
+
codecql --main-highlighting
|
|
1199
|
+
```
|
|
1200
|
+
|
|
1201
|
+
Open the local configuration:
|
|
1202
|
+
|
|
1203
|
+
``` bash
|
|
1204
|
+
codecql --local-highlighting
|
|
1205
|
+
```
|
|
1206
|
+
|
|
1207
|
+
If the selected file does not exist, CodecQL creates it as:
|
|
1208
|
+
|
|
1209
|
+
``` json
|
|
1210
|
+
{}
|
|
1211
|
+
```
|
|
1212
|
+
|
|
1213
|
+
Edit the JSON, save with `Ctrl+S`, then restart CodecQL or reopen the
|
|
1214
|
+
file being edited so the editor reloads the profile configuration.
|
|
1215
|
+
|
|
1216
|
+
Do not combine `--main-highlighting` and `--local-highlighting`.
|
|
1217
|
+
|
|
1218
|
+
## Built-in ChemQL highlighting
|
|
1219
|
+
|
|
1220
|
+
The built-in `.cql` profile groups words into these rules:
|
|
1221
|
+
|
|
1222
|
+
-----------------------------------------------------------------------
|
|
1223
|
+
Rule name Style Examples
|
|
1224
|
+
----------------------- ----------------------- -----------------------
|
|
1225
|
+
`commands` `command` `search`, `source`,
|
|
1226
|
+
`findmol`, `react`,
|
|
1227
|
+
`balance`, `help`,
|
|
1228
|
+
`load`
|
|
1229
|
+
|
|
1230
|
+
`control-keywords` `keyword` `if`, `else`, `for`,
|
|
1231
|
+
`while`, `struct`,
|
|
1232
|
+
`record`, `enum`,
|
|
1233
|
+
`namespace`
|
|
1234
|
+
|
|
1235
|
+
`word-operators` `operator` `and`, `or`, `has`,
|
|
1236
|
+
`like`, `sort`,
|
|
1237
|
+
`limit`, `union`
|
|
1238
|
+
|
|
1239
|
+
`sources` `source` `elements`,
|
|
1240
|
+
`molecules`,
|
|
1241
|
+
`reactions`
|
|
1242
|
+
|
|
1243
|
+
`conditions` `condition` `temperature`,
|
|
1244
|
+
`pressure`, `catalyst`,
|
|
1245
|
+
`atm`, `bar`, `kpa`
|
|
1246
|
+
|
|
1247
|
+
`properties` `property` `name`, `symbol`,
|
|
1248
|
+
`atomic_mass`,
|
|
1249
|
+
`formula`, `reactants`,
|
|
1250
|
+
`products`
|
|
1251
|
+
-----------------------------------------------------------------------
|
|
1252
|
+
|
|
1253
|
+
The editor also recognizes lexical token categories such as comments,
|
|
1254
|
+
strings, numbers, chemical formula-like tokens, operators, and
|
|
1255
|
+
delimiters. JSON and TOML package manifests named `cqlpackage.json` and
|
|
1256
|
+
`cqlpackage.toml` receive dedicated manifest highlighting.
|
|
1257
|
+
|
|
1258
|
+
------------------------------------------------------------------------
|
|
1259
|
+
|
|
1260
|
+
# Troubleshooting
|
|
1261
|
+
|
|
1262
|
+
### A file opens without custom highlighting
|
|
1263
|
+
|
|
1264
|
+
Check that: 1. The file has the extension used as the profile key, such
|
|
1265
|
+
as `.py`. 2. The JSON file is named exactly `highlighting.json`. 3. The
|
|
1266
|
+
local file is in the current working directory from which CodecQL was
|
|
1267
|
+
launched. 4. The extension key includes the intended extension. 5. The
|
|
1268
|
+
rule uses `"type": "keywords"` and has a non-empty `values` array. 6.
|
|
1269
|
+
The token is recognized as an identifier by the editor's tokenizer.
|
|
1270
|
+
|
|
1271
|
+
Unknown extensions remain unhighlighted by language-specific keyword
|
|
1272
|
+
profiles, though the editor's general lexical token styling still
|
|
1273
|
+
applies.
|
|
1274
|
+
|
|
1275
|
+
### My local profile is not overriding the main profile
|
|
1276
|
+
|
|
1277
|
+
Profiles are replaced per extension, not merged rule by rule. Make sure
|
|
1278
|
+
the local profile includes the complete rule list you want for that
|
|
1279
|
+
extension.
|
|
1280
|
+
|
|
1281
|
+
### The editor rejects my highlighting JSON
|
|
1282
|
+
|
|
1283
|
+
Check standard JSON syntax: - Use double quotes around keys and string
|
|
1284
|
+
values. - Do not leave trailing commas. - Use `true` and `false` for
|
|
1285
|
+
booleans, not quoted strings. - Make sure each extension maps to an
|
|
1286
|
+
array of rules. - Make sure each rule has a non-empty `name`, supported
|
|
1287
|
+
`type`, and non-empty `style`.
|
|
1288
|
+
|
|
1289
|
+
For regex rules, `pattern` must be a valid Python regular expression.
|
|
1290
|
+
`case_sensitive` must be a JSON boolean.
|
|
1291
|
+
|
|
1292
|
+
### My custom style is rejected
|
|
1293
|
+
|
|
1294
|
+
Use only recognized style components: - A named theme style listed in
|
|
1295
|
+
[Style syntax](#style-syntax). - One of `bold`, `dim`, `italic`,
|
|
1296
|
+
`underline`, `reverse`, or `strike`. - A foreground color such as
|
|
1297
|
+
`#FF00FF`. - A background color such as `bg:#202020`.
|
|
1298
|
+
|
|
1299
|
+
Separate components with spaces.
|
|
1300
|
+
|
|
1301
|
+
### Colors look different in my terminal
|
|
1302
|
+
|
|
1303
|
+
ANSI 256-color and true-color output are interpreted by the terminal.
|
|
1304
|
+
Different terminal palettes, themes, and color capabilities can make the
|
|
1305
|
+
same color index or RGB value look different.
|
|
1306
|
+
|
|
1307
|
+
### `Ctrl+R` does not run my file
|
|
1308
|
+
|
|
1309
|
+
`Ctrl+R` invokes `chemql -f` with the current file's absolute path.
|
|
1310
|
+
Ensure ChemQL is installed and its `chemql` command is available in the
|
|
1311
|
+
environment inherited by CodecQL. The editor saves a modified buffer
|
|
1312
|
+
before running it.
|
|
1313
|
+
|
|
1314
|
+
------------------------------------------------------------------------
|
|
1315
|
+
|
|
1316
|
+
## Project components
|
|
1317
|
+
|
|
1318
|
+
-----------------------------------------------------------------------
|
|
1319
|
+
File/component Responsibility
|
|
1320
|
+
----------------------------------- -----------------------------------
|
|
1321
|
+
ChemQL package (`__init__.py`) Language runtime, interactive
|
|
1322
|
+
prompt, chemistry functionality,
|
|
1323
|
+
built-ins, package management
|
|
1324
|
+
|
|
1325
|
+
`codecql.py` Terminal editor, file operations,
|
|
1326
|
+
key handling, terminal integration,
|
|
1327
|
+
token rendering
|
|
1328
|
+
|
|
1329
|
+
`highlighting.py` Highlighting profile definitions,
|
|
1330
|
+
JSON loading, extension
|
|
1331
|
+
normalization, and rule validation
|
|
1332
|
+
|
|
1333
|
+
`colors.json` ANSI 256-color theme for syntax and
|
|
1334
|
+
editor UI
|
|
1335
|
+
|
|
1336
|
+
`highlighting.json` Optional user-defined language
|
|
1337
|
+
profiles
|
|
1338
|
+
-----------------------------------------------------------------------
|
|
1339
|
+
|
|
1340
|
+
ChemQL and CodecQL are related but separate components: ChemQL provides
|
|
1341
|
+
the language/runtime, while CodecQL provides the editing environment.
|