2026-01-25 12:09:28 +00:00
<!DOCTYPE html>
<!-- retoor <retoor@molodetz.nl> -->
< html lang = "en" >
< head >
< meta charset = "UTF-8" >
< meta name = "viewport" content = "width=device-width, initial-scale=1.0" >
< title > fswatch - Wren-CLI Manual</ title >
< link rel = "stylesheet" href = "../css/style.css" >
</ head >
< body >
< button class = "mobile-menu-toggle" > Menu</ button >
< div class = "container" >
< aside class = "sidebar" >
< div class = "sidebar-header" >
< h1 >< a href = "../index.html" > Wren-CLI</ a ></ h1 >
< div class = "version" > v0.4.0</ div >
</ div >
< nav class = "sidebar-nav" >
< div class = "section" >
< span class = "section-title" > Getting Started</ span >
< ul >
< li >< a href = "../getting-started/index.html" > Overview</ a ></ li >
< li >< a href = "../getting-started/installation.html" > Installation</ a ></ li >
< li >< a href = "../getting-started/first-script.html" > First Script</ a ></ li >
< li >< a href = "../getting-started/repl.html" > Using the REPL</ a ></ li >
</ ul >
</ div >
< div class = "section" >
< span class = "section-title" > Language</ span >
< ul >
< li >< a href = "../language/index.html" > Syntax Overview</ a ></ li >
< li >< a href = "../language/classes.html" > Classes</ a ></ li >
< li >< a href = "../language/methods.html" > Methods</ a ></ li >
< li >< a href = "../language/control-flow.html" > Control Flow</ a ></ li >
< li >< a href = "../language/fibers.html" > Fibers</ a ></ li >
< li >< a href = "../language/modules.html" > Modules</ a ></ li >
</ ul >
</ div >
< div class = "section" >
< span class = "section-title" > API Reference</ span >
< ul >
< li >< a href = "index.html" > Overview</ a ></ li >
< li >< a href = "string.html" > String</ a ></ li >
< li >< a href = "number.html" > Num</ a ></ li >
< li >< a href = "argparse.html" > argparse</ a ></ li >
< li >< a href = "base64.html" > base64</ a ></ li >
< li >< a href = "crypto.html" > crypto</ a ></ li >
< li >< a href = "dataset.html" > dataset</ a ></ li >
< li >< a href = "datetime.html" > datetime</ a ></ li >
< li >< a href = "dns.html" > dns</ a ></ li >
< li >< a href = "env.html" > env</ a ></ li >
< li >< a href = "fswatch.html" class = "active" > fswatch</ a ></ li >
< li >< a href = "html.html" > html</ a ></ li >
< li >< a href = "http.html" > http</ a ></ li >
< li >< a href = "io.html" > io</ a ></ li >
< li >< a href = "jinja.html" > jinja</ a ></ li >
< li >< a href = "json.html" > json</ a ></ li >
< li >< a href = "markdown.html" > markdown</ a ></ li >
< li >< a href = "math.html" > math</ a ></ li >
< li >< a href = "net.html" > net</ a ></ li >
< li >< a href = "os.html" > os</ a ></ li >
< li >< a href = "pathlib.html" > pathlib</ a ></ li >
< li >< a href = "regex.html" > regex</ a ></ li >
< li >< a href = "scheduler.html" > scheduler</ a ></ li >
< li >< a href = "signal.html" > signal</ a ></ li >
< li >< a href = "sqlite.html" > sqlite</ a ></ li >
< li >< a href = "subprocess.html" > subprocess</ a ></ li >
< li >< a href = "sysinfo.html" > sysinfo</ a ></ li >
< li >< a href = "tempfile.html" > tempfile</ a ></ li >
< li >< a href = "timer.html" > timer</ a ></ li >
< li >< a href = "tls.html" > tls</ a ></ li >
< li >< a href = "udp.html" > udp</ a ></ li >
< li >< a href = "uuid.html" > uuid</ a ></ li >
< li >< a href = "wdantic.html" > wdantic</ a ></ li >
< li >< a href = "web.html" > web</ a ></ li >
< li >< a href = "websocket.html" > websocket</ a ></ li >
</ ul >
</ div >
< div class = "section" >
< span class = "section-title" > Tutorials</ span >
< ul >
< li >< a href = "../tutorials/index.html" > Tutorial List</ a ></ li >
< li >< a href = "../tutorials/http-client.html" > HTTP Client</ a ></ li >
< li >< a href = "../tutorials/websocket-chat.html" > WebSocket Chat</ a ></ li >
< li >< a href = "../tutorials/database-app.html" > Database App</ a ></ li >
< li >< a href = "../tutorials/template-rendering.html" > Templates</ a ></ li >
< li >< a href = "../tutorials/cli-tool.html" > CLI Tool</ a ></ li >
2026-01-25 18:02:02 +00:00
< li >< a href = "../tutorials/web-server.html" > Web Server</ a ></ li >
2026-01-25 12:09:28 +00:00
</ ul >
</ div >
< div class = "section" >
< span class = "section-title" > How-To Guides</ span >
< ul >
< li >< a href = "../howto/index.html" > How-To List</ a ></ li >
< li >< a href = "../howto/http-requests.html" > HTTP Requests</ a ></ li >
< li >< a href = "../howto/json-parsing.html" > JSON Parsing</ a ></ li >
< li >< a href = "../howto/regex-patterns.html" > Regex Patterns</ a ></ li >
< li >< a href = "../howto/file-operations.html" > File Operations</ a ></ li >
< li >< a href = "../howto/async-operations.html" > Async Operations</ a ></ li >
< li >< a href = "../howto/error-handling.html" > Error Handling</ a ></ li >
</ ul >
</ div >
2026-01-25 18:02:02 +00:00
< div class = "section" >
< span class = "section-title" > Contributing</ span >
< ul >
< li >< a href = "../contributing/index.html" > Overview</ a ></ li >
< li >< a href = "../contributing/module-overview.html" > Module Architecture</ a ></ li >
< li >< a href = "../contributing/pure-wren-module.html" > Pure-Wren Modules</ a ></ li >
< li >< a href = "../contributing/c-backed-module.html" > C-Backed Modules</ a ></ li >
< li >< a href = "../contributing/foreign-classes.html" > Foreign Classes</ a ></ li >
< li >< a href = "../contributing/async-patterns.html" > Async Patterns</ a ></ li >
< li >< a href = "../contributing/testing.html" > Writing Tests</ a ></ li >
< li >< a href = "../contributing/documentation.html" > Documentation</ a ></ li >
</ ul >
</ div >
2026-01-25 12:09:28 +00:00
</ nav >
</ aside >
< main class = "content" >
< nav class = "breadcrumb" >
< a href = "../index.html" > Home</ a >
< span class = "separator" > /</ span >
< a href = "index.html" > API Reference</ a >
< span class = "separator" > /</ span >
< span > fswatch</ span >
</ nav >
< article >
< h1 > fswatch</ h1 >
< p > The < code > fswatch</ code > module provides file system watching capabilities, allowing scripts to monitor files and directories for changes in real-time. Built on libuv's filesystem events.</ p >
< pre >< code > import "fswatch" for FileWatcher, FsEvent</ code ></ pre >
< div class = "toc" >
< h4 > On This Page</ h4 >
< ul >
< li >< a href = "#filewatcher-class" > FileWatcher Class</ a ></ li >
< li >< a href = "#fsevent-class" > FsEvent Class</ a ></ li >
< li >< a href = "#examples" > Examples</ a ></ li >
</ ul >
</ div >
< h2 id = "filewatcher-class" > FileWatcher Class</ h2 >
< div class = "class-header" >
< h3 > FileWatcher</ h3 >
< p > Monitors a file or directory for changes</ p >
</ div >
< h3 > Constructor</ h3 >
< div class = "method-signature" >
< span class = "method-name" > FileWatcher.new</ span > (< span class = "param" > path</ span > ) → < span class = "type" > FileWatcher</ span >
</ div >
< p > Creates a new FileWatcher for the specified path. The path can be a file or directory.</ p >
< ul class = "param-list" >
< li >< span class = "param-name" > path</ span > < span class = "param-type" > (String)</ span > - Path to the file or directory to watch</ li >
</ ul >
< pre >< code > var watcher = FileWatcher.new("./config.json")
var dirWatcher = FileWatcher.new("./src")</ code ></ pre >
< h3 > Methods</ h3 >
< div class = "method-signature" >
< span class = "method-name" > start</ span > (< span class = "param" > callback</ span > )
</ div >
< p > Starts watching for changes. The callback function is invoked with an FsEvent whenever a change is detected.</ p >
< ul class = "param-list" >
< li >< span class = "param-name" > callback</ span > < span class = "param-type" > (Fn)</ span > - Function that receives an FsEvent parameter</ li >
</ ul >
< pre >< code > watcher.start { |event|
System.print("Changed: %(event.filename)")
}</ code ></ pre >
< div class = "method-signature" >
< span class = "method-name" > stop</ span > ()
</ div >
< p > Stops watching for changes.</ p >
< pre >< code > watcher.stop()</ code ></ pre >
< h3 > Properties</ h3 >
< div class = "method-signature" >
< span class = "method-name" > isActive</ span > → < span class = "type" > Bool</ span >
</ div >
< p > Returns true if the watcher is currently active.</ p >
< pre >< code > if (watcher.isActive) {
System.print("Watcher is running")
}</ code ></ pre >
< h2 id = "fsevent-class" > FsEvent Class</ h2 >
< div class = "class-header" >
< h3 > FsEvent</ h3 >
< p > Represents a file system change event</ p >
</ div >
< h3 > Properties</ h3 >
< div class = "method-signature" >
< span class = "method-name" > filename</ span > → < span class = "type" > String</ span >
</ div >
< p > The name of the file that changed. For directory watchers, this is the relative filename within the directory.</ p >
< pre >< code > System.print("File changed: %(event.filename)")</ code ></ pre >
< div class = "method-signature" >
< span class = "method-name" > isRename</ span > → < span class = "type" > Bool</ span >
</ div >
< p > True if the event is a rename/move operation. This includes file creation and deletion.</ p >
< pre >< code > if (event.isRename) {
System.print("File renamed/created/deleted")
}</ code ></ pre >
< div class = "method-signature" >
< span class = "method-name" > isChange</ span > → < span class = "type" > Bool</ span >
</ div >
< p > True if the event is a content change.</ p >
< pre >< code > if (event.isChange) {
System.print("File content modified")
}</ code ></ pre >
< h2 id = "examples" > Examples</ h2 >
< h3 > Watch a Single File</ h3 >
< pre >< code > import "fswatch" for FileWatcher
var watcher = FileWatcher.new("./config.json")
watcher.start { |event|
System.print("Config changed!")
System.print(" Rename: %(event.isRename)")
System.print(" Change: %(event.isChange)")
}
System.print("Watching config.json for changes...")
System.print("Press Ctrl+C to stop")</ code ></ pre >
< h3 > Watch a Directory</ h3 >
< pre >< code > import "fswatch" for FileWatcher
var watcher = FileWatcher.new("./src")
watcher.start { |event|
System.print("[%(event.filename)]")
if (event.isRename) {
System.print(" Created/Deleted/Renamed")
}
if (event.isChange) {
System.print(" Modified")
}
}
System.print("Watching ./src directory...")
System.print("Press Ctrl+C to stop")</ code ></ pre >
< h3 > Auto-Reload Configuration</ h3 >
< pre >< code > import "fswatch" for FileWatcher
import "io" for File
import "json" for Json
var config = {}
var loadConfig = Fn.new {
var content = File.read("config.json")
config = Json.parse(content)
System.print("Config loaded: %(config)")
}
loadConfig.call()
var watcher = FileWatcher.new("./config.json")
watcher.start { |event|
System.print("Config file changed, reloading...")
loadConfig.call()
}
System.print("Running with auto-reload...")</ code ></ pre >
< h3 > Build on Change</ h3 >
< pre >< code > import "fswatch" for FileWatcher
import "subprocess" for Subprocess
var watcher = FileWatcher.new("./src")
var build = Fn.new {
System.print("Building...")
var result = Subprocess.run("make", ["build"])
if (result.exitCode == 0) {
System.print("Build successful!")
} else {
System.print("Build failed!")
System.print(result.stderr)
}
}
watcher.start { |event|
if (event.filename.endsWith(".c") || event.filename.endsWith(".h")) {
System.print("%(event.filename) changed")
build.call()
}
}
System.print("Watching for source changes...")</ code ></ pre >
< h3 > Multiple Watchers</ h3 >
< pre >< code > import "fswatch" for FileWatcher
var srcWatcher = FileWatcher.new("./src")
var testWatcher = FileWatcher.new("./test")
srcWatcher.start { |event|
System.print("[SRC] %(event.filename)")
}
testWatcher.start { |event|
System.print("[TEST] %(event.filename)")
}
System.print("Watching src/ and test/ directories...")</ code ></ pre >
< h3 > Debounced Watcher</ h3 >
< pre >< code > import "fswatch" for FileWatcher
import "timer" for Timer
import "datetime" for DateTime
var lastChange = null
var debounceMs = 500
var watcher = FileWatcher.new("./src")
watcher.start { |event|
var now = DateTime.now()
if (lastChange == null || (now - lastChange).milliseconds > debounceMs) {
lastChange = now
System.print("Change detected: %(event.filename)")
}
}
System.print("Watching with %(debounceMs)ms debounce...")</ code ></ pre >
< h3 > Graceful Shutdown</ h3 >
< pre >< code > import "fswatch" for FileWatcher
import "signal" for Signal
var watcher = FileWatcher.new("./data")
watcher.start { |event|
System.print("%(event.filename) changed")
}
Signal.trap(Signal.SIGINT) {
System.print("\nStopping watcher...")
watcher.stop()
System.print("Watcher stopped: %(watcher.isActive)")
}
System.print("Watching ./data (Ctrl+C to stop)")</ code ></ pre >
< div class = "admonition note" >
< div class = "admonition-title" > Note</ div >
< p > File system event behavior varies by operating system. On some platforms, multiple events may be delivered for a single change, or event types may overlap (both < code > isRename</ code > and < code > isChange</ code > true).</ p >
</ div >
< div class = "admonition tip" >
< div class = "admonition-title" > Tip</ div >
< p > When watching directories, the < code > filename</ code > property contains the relative path of the changed file within the watched directory, not the full path.</ p >
</ div >
< div class = "admonition warning" >
< div class = "admonition-title" > Warning</ div >
< p > Watching a large directory tree may consume significant system resources. Consider watching specific subdirectories when possible.</ p >
</ div >
</ article >
< footer class = "page-footer" >
< a href = "env.html" class = "prev" > env</ a >
< a href = "html.html" class = "next" > html</ a >
</ footer >
</ main >
</ div >
< script src = "../js/main.js" ></ script >
</ body >
</ html >