👁️Gaze runs a command, right after you save a file.
It greatly helps you to focus on writing code!
Setting up Gaze is easy.
gaze .
Then, invoke your favorite editor on another terminal and edit it!
vi a.py
brew install gaze
Or, download binary
- Modify a.py -> 👁️Runs
python a.py
- Modify a.rb -> 👁️Runs
rubocop
- Modify a.js -> 👁️Runs
npm run lint
- Modify a.go -> 👁️Runs
make build
- Modify Dockerfile -> 👁️Runs
docker build
- And so forth...
Software development often requires us to repeatedly execute the same command manually.
For example, when writing a simple Python script, you may create a.py file, write a few lines of code, and run python a.py
. If the result isn't what you expected, you edit a.py and run python a.py
again.
Again and again...
As a result, you may find yourself constantly switching between the editor and terminal, typing the same command repeatedly.
This can be frustrating and a waste of time and energy🙄
👁️Gaze runs a command for you, right after you save a file.
Gaze is designed as a CLI tool that accelerates your coding.
- 📦 Easy to use, out-of-the-box
- ⚡ Super quick reaction
- 🌎 Language-agnostic, editor-agnostic
- 🔧 Flexible configuration
- 💻 Multiplatform (macOS, Windows, Linux)
- 📝 Create-and-rename file actions handling
- 🔍 Advanced options for more control
-r
: restart (useful for server applications)-t 2000
: timeout (useful if you sometimes write infinite loops)
- 🚀 Optimal parallel handling
- See also: Parallel handling
Gaze was developed for supporting daily coding.
Even though there are already many "update-and-run" type of tools, I would say Gaze is the best for quick coding because all the technical design decisions have been made for that purpose.
The top priority of the Gaze's design is "easy to invoke".
gaze .
Then, switch to another terminal and run vi a.py
. Gaze executes a.py in response to your file modifications.
Gaze at one file.
gaze a.py
Specify files with pattern matching (*, **, ?, {, })
gaze "*.py"
gaze "src/**/*.rb"
gaze "{aaa,bbb}/*.{rb,py}"
Specify an arbitrary command by -c
option.
gaze "src/**/*.js" -c "eslint {{file}}"
Kill the previous one before launching a new process. This is useful if you are writing a server.
gaze -r server.py
Kill an ongoing process after 1000(ms). This is useful if you love infinite loops.
gaze -t 1000 complicated.py
Specify multiple commands in quotations, separated by newlines.
gaze "*.cpp" -c "gcc {{file}} -o a.out
ls -l a.out
./a.out"
Output when a.cpp was updated.
[gcc a.cpp -o a.out](1/3)
[ls -l a.out](2/3)
-rwxr-xr-x 1 user group 42155 Mar 3 00:31 a.out
[./a.out](3/3)
hello, world!
If a certain command exited with non-zero, Gaze doesn't invoke the next command.
[gcc a.cpp -o a.out](1/3)
a.cpp: In function 'int main()':
a.cpp:5:28: error: expected ';' before '}' token
printf("hello, world!\n")
^
;
}
~
exit status 1
Gaze is Language-agnostic.
For convenience, it has useful default configurations for some major languages (e.g. Go, Python, Ruby, JavaScript, Rust, and so forth)
Thanks to the default configurations, the command below is valid.
gaze a.py
The above command is equivalent to gaze a.py -c 'python "{{file}}"'
.
You can display the default YAML configuration by gaze -y
.
commands:
- ext: .go
cmd: go run "{{file}}"
- ext: .py
cmd: python "{{file}}"
- ext: .rb
cmd: ruby "{{file}}"
- ext: .js
cmd: node "{{file}}"
- ext: .d
cmd: dmd -run "{{file}}"
- ext: .groovy
cmd: groovy "{{file}}"
- ext: .php
cmd: php "{{file}}"
- ext: .java
cmd: java "{{file}}"
- ext: .kts
cmd: kotlinc -script "{{file}}"
- ext: .rs
cmd: |
rustc "{{file}}" -o"{{base0}}.out"
./"{{base0}}.out"
- ext: .cpp
cmd: |
gcc "{{file}}" -o"{{base0}}.out"
./"{{base0}}.out"
- ext: .ts
cmd: |
tsc "{{file}}" --out "{{base0}}.out"
node ./"{{base0}}.out"
- re: ^Dockerfile$
cmd: docker build -f "{{file}}" .
Note:
- To specify both ext and re for one cmd is prohibited
- cmd can have multiple commands. Use vertical line(|) to write multiple commands
If you want to customize it, please set up your own configuration file.
gaze -y > ~/.gaze.yml
vi ~/.gaze.yml
Gaze searches a configuration file according to its priority rule.
- A file specified by -f option
- ~/.config/gaze/gaze.yml
- ~/.gaze.yml
- (Default)
Usage: gaze [options...] file(s)
Options:
-c Command(s) to run when files are changed.
-r Restart mode. Sends SIGTERM to the ongoing process before invoking the next command.
-t Timeout(ms). Sends SIGTERM to the ongoing process after the specified time has elapsed.
-f Specify a YAML configuration file.
-v Verbose mode. Displays additional information.
-q Quiet mode. Suppresses normal output.
-y Displays the default YAML configuration.
-h Displays help.
--color Color mode (0:plain, 1:colorful).
--version Display version information.
Examples:
gaze .
gaze main.go
gaze a.rb b.rb
gaze -c make "**/*.c"
gaze -c "eslint {{file}}" "src/**/*.js"
gaze -r server.py
gaze -t 1000 complicated.py
For more information: https://github.com/wtetsu/gaze
You can write Mustache templates for commands.
gaze -c "echo {{file}} {{ext}} {{abs}}" .
Parameter | Example |
---|---|
{{file}} | src/mod1/main.py |
{{ext}} | .py |
{{base}} | main.py |
{{base0}} | main |
{{dir}} | src/mod1 |
{{abs}} | /my/proj/src/mod1/main.py |
- Great Go libraries
- See go.mod and license.zip