Lumesh Shell Syntax Manual
Here is the translation of your text into English:
I. Variables and Types
1. Variable Declaration and Assignment
Declaring Variables: Use the
let
keyword, supporting multiple variable declarations. Types are automatically assigned based on the assigned values.let x = 10 # Single variable
let a, b = 1, "hello" # Multiple variables assigned separately (the number of expressions on the right must match)
let a, b, c = 1 # Multiple variables assigned the same value
let a = b = 1 # Multiple variables assigned consecutivelyAssignment Operators:
=
: Normal assignment.:=
: Delayed assignment (stores the expression as a reference).
x := 2 + 3 # Delayed evaluation, storing the expression rather than the result
echo x # Outputs the expression: 2+3
eval x # Outputs the result: 5Deleting Variables: Use
del
.del x
Using Variables: Optional
$
, directly useecho a x
.
Strict mode requires $: echo $x
- Check Variable Type:
let a = 10
type a # Integer
type a == "Integer" # True
Edge Cases:
- In strict mode (
-s
), variables must be initialized; otherwise, an error will be thrown. - When declaring multiple variables, the number of expressions on the right must match the number of variables on the left or be a single value; otherwise, a
SyntaxError
will be thrown.
2. Data Types
Basic Types
Type | Example |
---|---|
Integer | 42 , -3 |
Float | 3.14 , -0.5 , 10% |
String | "Hello\n" , 'raw' |
Boolean | True , False |
List (Array) | [1, "a", True] |
Map (Dictionary) | {name: "Alice", age: 30} |
Range | 1..8 , 1..10 |
Time | time.parse('2025-5-20') |
File Size | 4K , 5T |
Null | None |
Complex Types
Type | Example |
---|---|
Variable | x |
Function | fn add(x,y){return x+y} |
Lambda | let add = (x,y) -> x + y |
Built-in Library | math.floor |
Scope Rules
- Lambda and function definitions create a child environment scope.
- Child environments inherit variables from the parent environment without modifying the parent scope.
Strings
Single quotes denote raw strings.
Double quotes support text escaping (e.g.,
\n
), Unicode escaping (e.g.,\u{2614}
), and ANSI escaping (e.g.,\033[34m
).Backticks denote string templates, supporting
$var
variable substitution and${var}
subprocess statement execution capture, as well as ANSI escape characters.print "Hello\nworld!\u{2614}"
Hello # Outputs two lines, \n is escaped to a newline
world!☔ # Unicode escape, \u{2614} is the umbrella character
let str2 = 'Hello\nworld!'
Hello\nworld! # Outputs one line, including the raw form of \n
let a = [1,2,5]
print `a is $a, and a[0] is ${a[0]}`
print "\033[31mRed msg\033[m" # Outputs red colored "Red msg"Variable substitution within backticks is more efficient than subprocess statement capture; it is recommended to use the former unless necessary.
Edge Cases:
The
\
in single-quoted strings is treated literally (e.g.,'Line\n'
outputsLine\n
).
Undefined escape sequences will throw an error, such as:echo "Hello\_"
[PARSE FAILED] syntax error: invalid string escape sequence `\_`
|
1 | echo "Hello\_"
|
File Size Type:
Composed of an integer followed by a unit, supporting the following units:
"B" "K" "M" "G" "T" "P"
Lumesh will automatically recognize the unit and output in a human-readable format, for example:
print 3050M 1038B 3000G
# Output
2.98G 1K 2.93T
File size types can participate in calculations.
For example:
1M > 30K # Returns True
fs.ls -l | where(size>20K) # Filters files larger than 20K
Date and Time Type
For example: time.parse('2025-5-20')
Date and time types can participate in calculations.
For example:
time.parse('2025-5-20') > time.parse('2025-1-20') # Returns True |
For specific operations, please refer to the built-in time
module functions.
Percentages
Written as a percentage, it will be automatically recognized as a float.
print 37% 2% + 3 |
A percentage sign immediately following a number indicates a percentage, while a space followed by a percentage sign indicates a modulo operation.
2. Operator Rules
1. Operator Categories and Precedence
From highest to lowest precedence (Smaller number means higher priority)
Precedence | Operator/Structure | Example/Description |
---|---|---|
1 | Parentheses () |
(a + b) * c |
2 | Function call, List [] |
func(arg) , [1, 2] |
3 | Unary operators ! , - , __.. |
!flag , -5 |
4 | Power operator ^ |
2 ^ 3 |
5 | Multiplication/division/modulus * , / , % , _*.. |
a * b % c |
6 | Addition/subtraction + , - , _+.. |
a + b - c |
7 | Comparison == , != , > etc |
a > b |
8 | Logical AND && |
cond1 && cond2 |
9 | Logical OR ` | |
10 | Ternary operator ? : |
cond ? t : f |
11 | Assignment = , := |
x = 5 , let y := 10 |
12 | Pipeline ` | ` |
Redirection << >> >>! |
date >> /tmp/day.txt |
Pipeline and redirection have same precedence, logical operators have higher precedence than pipeline/redirection.
special Operators
- quals:
==
means both type and value must be equal. ~=
means only value equal.~~
means regex match.~:
means string contains.&
shutdown all output and run in background-&
shutdown stdout
look at these examples:
5 == "5" # False |
2. Spacing Rules
Operator Type | Spacing Requirement | Example |
---|---|---|
Regular operators | Should have spaces on both sides | a + b x <= 10 |
Non-strict mode allows no space for some symbols | a+b x<=10 a=5 |
|
- and / should have spaces |
b-3 becomes string, 3-b subtraction |
|
Custom operators | Must start with _ and have spaces |
x _*+ y a _?= b |
Postfix operators must start with __ and have spaces |
x __*+ |
|
Prefix operators | Space before or start of line, no space after | !x -7 |
Infix operators | No space before/after | dict.key 1..9 |
Postfix operators | No space before/after | func(a) array[i] |
May be deprecated in future, not recommended | a++ a-- |
For increment, use a += 1
instead of a++
--
is typically used for shell arguments
Custom Operators:
- Custom operators start with
_
, can only contain symbols, not numbers or letters - Custom unary operators start with
__
, e.g.,__+
, same precedence as unary operators, only for postfix - Custom +-level operators start with
_+%
, e.g.,_+%
, same precedence as+
-
- Custom *-level operators start with
_*
, e.g.,_*-
, same precedence as*
/
let __++ = x -> x + 1; |
Edge Case:
x++y
invalid,x+++y
valid
3. Implicit Type Conversion
Numeric operations automatically convert to higher precision type.
When operating different types, always try to convert to first operand’s type.
# Non-strict mode |
4. Special Operation Behaviors
5 / 2 # → 2 (integer division) |
You can use * for string repetition, similar to Pythonecho "+" * 3
You can use * to multiply list elements with second operand[3,5,7] * 3
Edge Case:
- Division by zero throws error
5. Pipeline
|
Smart pipeline: automatically reads from expression result or stdout, passes to next command’s stdin or appends to function arguments|>
Pipeline to last argument of right-side function
cmd1 | cmd2 | ...
6. Redirection
<<
Read>>
Append output>>!
Overwrite output1 + 2 >> result.txt
Error redirection: Combine with error handling operators
See Error Handling section for details.
Redirection Type | Lume | Bash |
---|---|---|
Standard output append | cmd >> out.txt | cmd >> out.txt |
Standard output overwrite | cmd >>! out.txt | cmd > out.txt |
Error redirected to stdout | cmd ?! >> out.log | command 2>&1 >> out.log |
Separate error output | cmd ?? >> out.log | cmd 2>> out.log |
Combine stdout and stderr | cmd ?+ >> out.log | cmd >> out.log 2>&1 |
3. Intervals, Lists, and Maps
1. Intervals
Interval Expressions
Intervals use..<
(left-closed, right-open) or..
(closed interval), with no spaces on either side. Variable expansion is supported.0..<10 # does not include 10
0..10 # includes 10
a..brange support steps:
:step
0..6:2 # step is 2: [0,2,4,6]
Intervals can be used for loops, containment checks, array creation, etc.
let r = 0..8
for i in r {...} # More efficient than looping directly over an array
r ~: 5 # Check if the element is contained
list.from(r) # Convert to an array
2. Lists (Arrays)
Lists are represented with
[ ]
. The elements inside are ordered.You can also create lists directly from intervals using
...
or...<
.0...5 # Outputs [0, 1, 2, 3, 4]
# Equivalent to
list.from(0..5)
Two dots ..
..<
create intervals, while three dots ...
...<
create arrays.
Indexing is represented with
.
or[i]
.let arr = [10, "a", True]
Indexing and Slicing
# Basic Indexing
arr.1
arr[0] # → 10
# Slicing Operations
arr[1:3] # → ["a", True] (left-closed, right-open)
arr[::2] # → [10, True] (step of 2)
arr[-1:] # → True (slicing supports negative indexing)Complex Nesting
# Complex Nesting
[1, 24, 5, [5, 6, 8]][3][1] # Displays 6
# Modify Element
# arr[2] = 3.14 # → [10, "a", 3.14]Advanced Operations
Refer to the list module.
Edge Cases:
- Accessing an array index that is out of bounds will trigger an
out of bounds
error. - Array slicing supports negative numbers, indicating indices counted from the end.
- Indexing a non-indexable object will trigger the following error:
[ERROR] type error: expected indexable type (list/dict/string), found symbol
3. Maps (Dictionaries)
Maps are represented with
{}
.let mydict = {name: "Alice", age: 30}
Dictionary Indexing
# Basic Access
mydict["name"] # → "Alice"
mydict.name # → "Alice" (shorthand)
# Dynamic Key Support
let key = "ag" + "e"
dict[key] # → 30
# Nested Access
let data = {user: mydict}
data.user.age # → 30Advanced Operations
Refer to the map module.
Edge Cases:
Scenario | Behavior |
---|---|
Accessing a non-existent array index | Triggers [ERROR] key x not found in map error |
Indexing a non-dictionary object | Triggers [ERROR] not valid index option error |
Indexing an undefined symbol | Returns a string, as operating on filenames is a common operation in shell |
Indexing an undefined symbol | Returns a string, as operating on filenames is a common operation in shell |
4. Statements
Statement Blocks
Use{}
. Typically for flow control.Subcommand Groups
Parentheses execute as subcommand, doesn’t create new process or isolate variable scope.echo (len [5,6])
Statement Separation
Use;
orEnter
to separate:- Line Break:
;
or newline - Line Continuation: Use
\
+ newline for multi-line:
let long_expr = 3 \
+ 5 # Equivalent to "3 + 5"
let long_str = "Hello
World" # Equivalent to "Hello\n World"Note: No need for line continuation inside quotes.
- Line Break:
Comment
comment begin with#
5. Control Structures
Conditional Statements
- If Statement
Supports nesting:if cond1 { ... } else if cond2 { ... } else { ... }
No
then
keyword, code blocks use{}
:if True {1} else {if False {2} else {3}}
if x > 10 {
print("Large")
} else if x == 10 {
print("Equal")
} else {
print("Small")
}- Match Statement
Replaces bash switch:
let x = "a"
match x {
"b" => echo "is letter",
_ => echo "is others"
}- If Statement
Loops
- For Loop:
for i in 0..5 { # Outputs 0,1,2,3,4
print(i)
}
for i in [1,5,8] { print i } - While Loop:
let count = 0
while count < 3 {
print(count)
count = count + 1
}
- For Loop:
Statement Expressions
- Control statements can also act as expressions:
let a = if b>0 {5} else {-5}
- Ternary Expression
a = c>0 ? t : f
Supports nesting.
- Range Expression
Use..
with no space around, supports variable expansion:
0..10
# Equivalent to
[0,1,2,3,4,5,6,7,8,9]
# Equivalent to
let a=0
let b=10
a..b
6. Functions
Function Definition
- Use
fn
keyword, supports default parameters and rest parameter collection:
fn add(a,b,c=10,*d) {
return a + b + c + len(c)
}
# Equivalent to:
fn add(a,b,c=10,*d) {
a + b + c + len(c)
}
echo add(2, 3) # Output: 5
echo add(2,3,4, 5) # Output: 10- Use
Lambda Expressions
- Defined with
->
.
Differences from normal functions:- No default parameters or return statement
- Supports partial application, returns subsequent lambda
Both inherit current environment variables and run in isolated environment.
let add = (x,y) -> x + y
- Defined with
Function Calls
Differentiating function calls from command execution:# Test case 6: Function-command name conflict
fn ls() { echo "My ls" }
ls -l # Executes system command ls
ls() # Calls function
ls! -l # Using ! suffix, function call syntax sugarFunction Call
# Custom function call
add(3,5)
# Or
add! 3 5 # Note: ! suffix required to differentiate from commandCommand Call
ls -l
Built-in Commands
All three forms supported:
fmt.red(msg)
fmt.red! msg
fmt.red msg
Edge Cases:
- New function definitions override existing ones with same name
- Parameter count mismatch throws error:
[ERROR] arguments mismatch for function
add: expected 3, found 1
7. Running System Commands
The main task of a shell is to run system commands, and secondly, to improve efficiency through powerful programming capabilities.
Command Execution
In lumesh, you can conveniently run programs just like in other shells, such as:
ls |
If multiple commands are issued, subsequent commands will not execute if the preceding command fails; unless errors are ignored:
ls '/0' ; ls -l # The latter will not execute |
Wildcard Expansion
In lumesh, ~
directory expansion and *
expansion are also supported:
ls ~/**/*.md |
However, {}
expansion as in bash is not supported.
Background Execution and Output Control
- Similar to bash, use the
&
symbol to run programs in the background. - Output control symbol
&
: We adopt a more concise way to suppress output.
thunar & # run in background, and shut down stdout and stderr |
Here is a comparison of syntax with bash:
Task | bash | lumesh |
---|---|---|
Background Run | cmd & | cmd & |
Suppress Stdout | cmd 1> /dev/null | cmd &- |
Suppress Stderr | cmd 2> /dev/null | cmd &? |
Suppress All Output | cmd 2>&1 /dev/null | cmd &. |
Piping
lumesh uses the same pipe symbol as bash, but it is more powerful:
|
Smart pipe, the left side can automatically read from the computation result or standard output, and if the right side is a third-party command, it will receive data as standard input; if it is a function, it will be passed as the last argument.|>
Pipe to the last argument of the right-side function.
cmd1 | cmd2 | ...
Redirection
<<
Read>>
Append output>>!
Overwrite output1 + 2 >> result.txt
Error redirection: combined with error handling symbols.
For specific usage, please refer to the error handling section.
Redirection Type | Lume | Bash |
---|---|---|
Standard Output, Append | cmd >> out.txt | cmd >> out.txt |
Standard Output, Overwrite | cmd >>! out.txt | cmd > out.txt |
Error Redirecting Standard Output | cmd ?! >> out.log | command 2>&1 >> out.log |
Separate Error Output | cmd ?? >> out.log | cmd 2>> out.log |
Merge Standard and Error Output | cmd ?+ >> out.log | cmd >> out.log 2>&1 |
8. Error Handling
- Error Handling:
?:
Statement followed by?: expr
, where expr can be a lambda accepting an Error object (Map type withcode
,msg
, andexpr
properties):
6 / 0 ?. # Ignore error |
Tips
- Use error handling to provide default values:
let e = x -> 0 |
- Use error handling in function define:
let e = x -> {print x.code} |
9. Execution Modes
REPL Interactive Mode
- Interactive user interface with syntax highlighting
Auto Hint: - type anything will trigger auto hint, mathes executable cmds, builtin functions, syntax, alias,history.
- type
module_name+dot+space
:fs.
to see all functions in the module.
Auto Complete
Tab
: Auto-completion:- First word: matches executable commands,builtin functions,syntax,alias.
- Path-related: triggers path completion
- More than 2 words: triggers AI completion
AI requires configuration first default config is for ollama, just run it and AI should work.
Keys
Right
orCtrl+J
: Accept completion suggestionsAlt+J
: Accept one world suggestionCtrl+D
: EOFCtrl+C
: Cancel operation
see hotkeys to find out more.
History: Saved in config directory
UP/DOWN
orCtrl+N/P
: Navigate history
- Interactive user interface with syntax highlighting
Script Parsing Mode
Run script:lume ./my.lm
Login Shell Mode
Configure environment variables in config file similar to .bashrcStrict Mode
- Variables must be declared with
$
prefix - Variables must be declared before use
- No type conversion allowed
- Non-strict mode allows direct variable access without
$
- Variables must be declared with
10. Parameters and Environment Variables
Command-line Arguments:
- Accessed through
argv
list:
# Run lumesh script.lm Alice tom
echo argv # Output: "[Alice, tom]"
echo argv@0 # Output: "Alice"- Accessed through
Environment Variables
PATH # System environment variable
HOME # System environment variable
env # List all environment variables
IS_LOGIN # Is login shell?
IS_INTERACTIVE # Is interactive mode?
IS_STRICT # Is strict mode?
11. Configuration File
- supported settings
- Special settings for different mode.
- AI config。
- key-bindings。
- abbreviations。
- alias。
- history file path。
- …
see default config for details.
- config
if not specified in cmd, lume will read config file from default path with entrylumesh/config.lm
.
this is:
Platform | Value | Example |
---|---|---|
Linux | $XDG_CONFIG_HOME or $HOME /.config |
/home/alice/.config |
macOS | $HOME /Library/Application Support |
/Users/Alice/Library/Application Support |
Windows | {FOLDERID_RoamingAppData} |
C:\Users\Alice\AppData\Roaming |
to see yours, just type fs.dirs()
- history record
if not specified in config file, history record was located in default cache dir with namelume_history
.
this is :
Platform | Value | Example |
---|---|---|
Linux | $XDG_CACHE_HOME or $HOME /.cache |
/home/alice/.cache |
macOS | $HOME /Library/Caches |
/Users/Alice/Library/Caches |
Windows | {FOLDERID_LocalAppData} |
C:\Users\Alice\AppData\Local |
to see yours, just type fs.dirs()
12. Built-in Functions
Use help
command to list all.
See Built-in Lib Library for details.
By following this manual, users can master Lumesh’s core syntax and edge cases. Practice in REPL is recommended for better understanding.