A terminal-based text editor wrapper that adds comprehensive syntax validation to your editing workflow. Built as a validation layer on top of the filetype package, editfile provides automatic file type detection, syntax validation for 10+ languages/formats, and safe atomic file operations.
- Features
- How It Works
- Installation
- Quick Start
- Usage
- Supported File Types
- Validation Workflow
- Editor Configuration
- Dependencies
- Use Cases
- Security
- Troubleshooting
- Testing
- Contributing
- License
- Automatic Syntax Validation - Built-in validators for JSON, YAML, XML, Python, Shell, PHP, HTML, INI, CSV, and TOML
- Intelligent File Type Detection - Recognizes 46+ file types via extension, shebang, or content analysis
- Interactive Error Recovery - When validation fails, choose to re-edit, force save, or quit
- Atomic File Operations - Uses temporary files for safe editing; original never corrupted
- PATH Search - Automatically finds and edits executables/scripts in your PATH
- Binary Protection - Refuses to edit binary files to prevent corruption
- Line Positioning - Jump directly to specific line numbers
- Shellcheck Integration - Optional advanced shell script analysis (with
-sflag)
- Syntax Highlighting - Automatic syntax configuration for 46+ file types
- Multi-Editor Support - Works with joe, nano, vim, emacs, VS Code
- Auto-Detection - Finds available editors or uses
$EDITORenvironment variable
- Symlink resolution (edits actual file, not the link)
- Permission checking (file and directory)
- Self-edit protection (prevents corrupting the running script)
- Change detection (skips validation if file unchanged)
- Temporary file cleanup on exit/interrupt
editfile is a validation wrapper built on the filetype package:
┌─────────────────────────────────────────────┐
│ editfile (this project) │
│ • Validation logic │
│ • Atomic file operations │
│ • Interactive error handling │
│ • PATH search │
└─────────────────┬───────────────────────────┘
│ uses
┌─────────────────▼───────────────────────────┐
│ filetype package (dependency) │
│ • editcmd - Editor launcher │
│ • filetype-lib.sh - Type detection (46+) │
│ • Syntax highlighting configuration │
└─────────────────┬───────────────────────────┘
│ launches
┌─────────────────▼───────────────────────────┐
│ Your Editor │
│ vim, nano, joe, emacs, VS Code, etc. │
└─────────────────────────────────────────────┘
- File Resolution - Searches locally, then in PATH if not found
- Binary Check - Verifies file is text (using
filecommand and null-byte detection) - Type Detection - Identifies file type using filetype-lib.sh (extension, shebang, or content)
- Temporary Copy - Creates temp file with preserved extension for proper syntax highlighting
- Editor Launch - Uses editcmd to open file with correct syntax highlighting
- Change Detection - Compares temp file with original to detect actual changes
- Validation - Runs appropriate validator based on file type (if enabled)
- Interactive Handling - On validation failure, prompts: [e]dit again, [s]ave anyway, or [q]uit
- Atomic Replace - Moves validated temp file to final location
The easiest way to install editfile with all dependencies:
# Clone the repository
git clone https://github.com/Open-Technology-Foundation/editfile.git
cd editfile
# Run the installer (automatically installs filetype package if needed)
sudo ./install.shThe installer will:
- Check for git
- Install the filetype package dependency (if not already installed)
- Install editfile to
/usr/local/bin - Check which optional validators are available
If you prefer to install manually:
# Quick install (one-liner)
git clone https://github.com/Open-Technology-Foundation/filetype.git && cd filetype && sudo ./install.sh
# Or step-by-step
git clone https://github.com/Open-Technology-Foundation/filetype.git
cd filetype
sudo ./install.shThis installs editcmd and filetype-lib.sh to /usr/local/bin/.
# Clone this repository
git clone https://github.com/Open-Technology-Foundation/editfile.git
cd editfile
# Make executable
chmod +x editfile
# Install to PATH
sudo cp editfile /usr/local/bin/editfileFor full validation support:
# Ubuntu/Debian
sudo apt install jq yamllint libxml2-utils shellcheck php-cli tidy
# macOS with Homebrew
brew install jq yamllint libxml2 shellcheck php tidy-html5
# Fedora/RHEL/Rocky
sudo dnf install jq yamllint libxml2 ShellCheck php-cli tidy
# Python-based validators
pip install PyYAML tomli # For YAML and TOML validationNote: Missing validators generate warnings but don't prevent editing.
# Standard installation
sudo ./install.sh
# Install editfile only (skip filetype check)
sudo ./install.sh --skip-filetype
# Uninstall editfile
sudo ./install.sh --uninstall
# View installer help
./install.sh --help# Edit with validation
editfile config.json
# Edit without validation (faster for large files)
editfile -n script.py
# Jump to specific line
editfile -l 42 server.py
# Edit shell script with shellcheck analysis
editfile -s deploy.sh
# Edit executable from PATH
editfile backup-script
# Create new file (with prompt)
editfile newfile.yamleditfile [OPTIONS] filename| Option | Description |
|---|---|
-n, --no-validate |
Skip syntax validation (faster for large files) |
-l, --line LINE |
Jump to specified line number |
-s, --shellcheck |
Run shellcheck on shell scripts (in addition to bash -n) |
-V, --version |
Show version and exit |
-h, --help |
Display help message |
editfile script.py # Edit Python with validation
editfile config.json # Edit JSON with validation
editfile data.yaml # Edit YAML with validation
editfile -n large_data.xml # Skip validation for large fileseditfile -l 42 script.py # Jump to line 42
editfile -l 100 /etc/hosts # Edit system file at line 100
# Integration with grep
line=$(grep -n "TODO" script.py | head -1 | cut -d: -f1)
editfile -l "$line" script.pyeditfile deploy.sh # Edit with bash -n validation
editfile -s deploy.sh # Edit with bash -n + shellcheck
editfile -s -l 50 install.sh # Jump to line 50, run shellcheckeditfile myscript # Searches PATH if not local
editfile backup-script # Edit from /usr/local/bin
editfile cln # Edit custom command
# When found in PATH, editfile prompts:
# "Edit executable '/usr/local/bin/backup-script'? y/n"editfile newfile.py # Prompts: "Create 'newfile.py'? y/n"
editfile config/app.yaml # Creates directory if needededitfile ~/.bashrc # Shell configuration
editfile /etc/nginx/nginx.conf # System config (requires sudo)
editfile docker-compose.yml # Docker configuration
editfile package.json # npm configuration# Find error and edit at line
error_line=$(python script.py 2>&1 | grep -oP 'line \K\d+' | head -1)
editfile -l "$error_line" script.py
# Edit and validate JSON from curl
curl https://api.example.com/config > config.json
editfile config.json
# Batch edit with validation check
for file in *.json; do
editfile "$file" || echo "Failed: $file"
done| Type | Extensions | Primary Validator | Fallback |
|---|---|---|---|
| JSON | .json, .jsonld, .jsonc | jq | python3 json.tool |
| YAML | .yaml, .yml | yamllint | python3 PyYAML |
| XML | .xml, .xsl, .xslt, .svg | xmllint | python3 xml.etree |
| HTML | .html, .htm, .xhtml | tidy | (basic check) |
| Python | .py, .pyw, .pyi | python3 -m py_compile | - |
| Shell | .sh, .bash, .zsh, .ksh, shebang | bash -n | (+ optional shellcheck) |
| PHP | .php, .phtml | php -l | - |
| INI | .ini, .conf, .cfg | awk validation | - |
| CSV | .csv, .tsv | awk column check | - |
| TOML | .toml, .tml | python3 tomli/toml | - |
All files get syntax highlighting even without validators:
Programming Languages: JavaScript, TypeScript, C, C++, Java, Go, Rust, Ruby, Perl, Lua, TCL, Erlang, Elixir, Haskell, Lisp, OCaml, Scala, Swift, R
Markup/Config: Markdown, LaTeX, reStructuredText, AsciiDoc, SQL, Nginx config, Apache config, systemd units
Data/Build: Dockerfile, Makefile, CMake, Gradle, Maven, Terraform, Ansible
Other: Diff/Patch files, Git config, SSH config, and more
See the filetype package for the complete list of 46+ supported types.
Edit file → Make changes → Save → Validation passes → File saved ✓
Edit file → Make changes → Save → Validation fails ✗
↓
editfile presents three options:
[e] Edit again - Fix errors and retry (changes preserved in temp file)
[s] Save anyway - Force save despite errors (not recommended)
[q] Quit - Discard changes and exit
$ editfile config.json
editfile: ◉ Launching editor with syntax highlighting
# (you edit and save the file with a syntax error)
editfile: ◉ Validating json file 'config.json'
parse error: Expected separator between values at line 5, column 12
editfile: ✗ Validation failed:
Options:
[e] - Edit again
[s] - Save anyway (not recommended)
[q] - Quit without saving
editfile: What would you like to do? [e/s/q]: e
# (editor reopens with your changes still there)
# (you fix the error and save)
editfile: ◉ Validating json file 'config.json'
editfile: ✓ Validated
editfile: ✓ 'config.json' savedEach file type uses the best available validator:
- Specialized tools first (jq, yamllint, xmllint, shellcheck)
- Fallback to Python (if specialized tool missing)
- Warn if no validator (but still allow editing)
$EDITORenvironment variable (if set)- Auto-detection searches for: joe → nano → vim → vi → emacs
- Default fallback: vim
# In ~/.bashrc or ~/.bash_profile
export EDITOR=nano # Use nano
export EDITOR=vim # Use vim
export EDITOR=joe # Use joe
export EDITOR=emacs # Use emacs
export EDITOR=code # Use VS Code (if installed)- joe - Joe's Own Editor
- nano - GNU nano
- vim - Vi IMproved
- vi - Classic vi
- emacs - GNU Emacs
- VS Code - Visual Studio Code (via
codecommand)
All editors receive proper syntax highlighting configuration via editcmd.
- bash 5.2+ - Shell interpreter
- filetype package - Provides editcmd and filetype-lib.sh
- Standard Unix tools - grep, awk, sed, file, od, readlink
- Text editor - At least one: vim, nano, joe, emacs, vi
Install these for enhanced validation (any combination works):
# Ubuntu/Debian
apt install jq yamllint libxml2-utils shellcheck php-cli tidy
# macOS
brew install jq yamllint libxml2 shellcheck php tidy-html5
# Fedora/RHEL
dnf install jq yamllint libxml2 ShellCheck php-cli tidy
# Arch Linux
pacman -S jq yamllint libxml2 shellcheck php tidy
# Alpine Linux
apk add jq yamllint libxml2-utils shellcheck php tidy# YAML support
pip install PyYAML
# TOML support
pip install tomli # Python 3.11+
pip install toml # Older Python versions# Check which validators are available
command -v jq yamllint xmllint shellcheck php tidy python3Prevent broken config files from being deployed:
editfile nginx.conf # Catch nginx config errors
editfile docker-compose.yml # Validate Docker configs
editfile .gitlab-ci.yml # Check CI/CD syntax
editfile terraform.tfvars # Verify Terraform variablesCatch syntax errors immediately:
editfile -s deploy.sh # Bash with shellcheck
editfile backup.py # Python syntax check
editfile install.php # PHP lint checkQuick editing of scripts in system paths:
editfile backup-script # Edit from /usr/local/bin
editfile cleanup # Edit system maintenance scripts
editfile -l 42 monitor # Jump to specific line in monitoring scriptEnsure data integrity:
editfile users.csv # Column consistency check
editfile api-response.json # JSON structure validation
editfile translations.yaml # YAML format verification
editfile config.toml # TOML syntax checkeditfile api-spec.json # OpenAPI/Swagger spec
editfile schema.xml # XML schema validation
editfile index.html # HTML validation
editfile endpoints.yaml # API endpoint configeditfile implements multiple security measures:
- Command Injection Prevention - All validators use safe argument passing (sys.argv[], not eval)
- Filename Sanitization - Temporary filenames sanitized to prevent shell injection
- Binary File Protection - Refuses to edit binary files (prevents corruption/exploitation)
- Path Resolution - Uses canonical paths to prevent traversal attacks
- Self-Edit Protection - Prevents editing the running script (avoids corruption during atomic replace)
- Null Byte Detection - Multiple methods to detect binary content
- Always validate configuration files before deployment
- Use
-sflag for shell scripts to catch common security issues via shellcheck - Review validation output carefully
- Don't use
-n(skip validation) for security-critical configs
For detailed security information and testing, see SECURITY.md.
Problem: editfile can't find the filetype package
Solution:
# Install filetype package
git clone https://github.com/Open-Technology-Foundation/filetype.git
cd filetype
sudo ./install.sh
# Verify installation
command -v editcmd
ls -l /usr/local/bin/editcmd
ls -l /usr/local/bin/filetype-lib.shProblem: Validation tool not installed
Solution:
# Install the specific validator needed
sudo apt install jq # For JSON
sudo apt install yamllint # For YAML
sudo apt install libxml2-utils # For XML
pip install PyYAML # Python YAML fallback
# Or edit without validation
editfile -n file.yamlProblem: editfile can't find your preferred editor
Solution:
# Set EDITOR environment variable
export EDITOR=nano
editfile file.txt
# Or add to ~/.bashrc
echo 'export EDITOR=nano' >> ~/.bashrc
source ~/.bashrcProblem: Validator is too strict or has false positives
Options:
# 1. Fix the actual issue (recommended)
editfile file.json # Choose [e] to edit again
# 2. Save anyway (use with caution)
editfile file.json # Choose [s] to force save
# 3. Skip validation entirely
editfile -n file.json # No validationProblem: No write access to file or directory
Solution:
# For system files, use sudo
sudo editfile /etc/hosts
# For user files, check permissions
ls -la file.txt
chmod u+w file.txt # Add write permissionProblem: editfile refuses to edit a text file it thinks is binary
Diagnosis:
# Check file type
file filename
od -An -tx1 filename | head # Look for null bytes (00)
# If truly text, it may have null bytes - handle carefullyProblem: Can't find executable in PATH
Debug:
# Check if file exists in PATH
command -v scriptname
which scriptname
# Check PATH variable
echo "$PATH"
# Use absolute path instead
editfile /usr/local/bin/scriptname# Enable bash debug output
bash -x editfile file.txt
# Check validation manually
jq empty file.json # Test JSON
yamllint file.yaml # Test YAML
bash -n script.sh # Test shell script- Check the help output:
editfile --help - Review validator output carefully (it usually shows the exact error)
- Test validators manually to isolate issues
- Check file permissions and ownership
- Verify filetype package installation
- Report issues: https://github.com/Open-Technology-Foundation/editfile/issues
# Basic validation tests
./tests/test_validation.sh
# Security tests
./tests/test_security.shThe validation test suite verifies:
- ✓ JSON, YAML, Python, Shell script validation (valid & invalid files)
- ✓ Editor detection and fallback
- ✓ Command-line argument parsing
- ✓ Temporary file naming and cleanup
- ✓ Binary file detection
- ✓ PATH search functionality
The security test suite verifies:
- ✓ Command injection prevention
- ✓ Filename sanitization
- ✓ Unicode and special character handling
- ✓ Path traversal prevention
- ✓ Validator security
# Test JSON validation
echo '{"valid": "json"}' > test.json
editfile test.json
echo '{invalid json}' > bad.json
editfile bad.json # Should fail validation
# Test shellcheck integration
echo '#!/bin/bash' > test.sh
echo 'var=foo' >> test.sh
echo 'echo $var' >> test.sh
editfile -s test.sh # Should warn about quoting
# Test PATH search
editfile bash # Should find /bin/bashContributions welcome! Please ensure:
-
Code Quality
- Follow the Bash Coding Standard
- Pass shellcheck without errors:
shellcheck editfile - Use 2-space indentation (not tabs)
- Declare all variables with
declareorlocal
-
Testing
- Add tests for new validators
- Ensure existing tests pass:
./tests/test_validation.sh - Test security implications:
./tests/test_security.sh
-
Documentation
- Update README.md for new features
- Update help text in the script
- Add usage examples
- Add file type detection in
detect_file_type()function (or rely on filetype-lib.sh) - Create
validate_<type>()function following existing patterns - Add case in
validate_file()dispatcher - Update the validators table in README.md
- Add test case in
tests/test_validation.sh
Example:
validate_rust() {
local -- filepath="$1"
if command -v rustc >/dev/null 2>&1; then
if ! rustc --crate-type lib --emit metadata "$filepath" 2>&1; then
return 1
fi
return 0
fi
warn 'Rust compiler not available for validation'
return 0
}This project is licensed under the GNU General Public License v3.0.
See the GNU GPL v3 for full license text.
- Ensures the software remains free and open source
- Requires derivative works to also be open source
- Protects against patent claims
- Promotes community collaboration
- Repository: https://github.com/Open-Technology-Foundation/editfile
- Issues: https://github.com/Open-Technology-Foundation/editfile/issues
- Security: SECURITY.md
- Dependencies: filetype package
Open Technology Foundation
A community-driven organization focused on creating practical, well-documented open source tools for developers and system administrators.
Note: editfile is designed for developer workflows. It provides validation as a helpful safety net, but always review changes before committing to production systems.