A powerful Neovim plugin for SFTP-based file synchronization with incremental sync capabilities. Built with Rust for performance and Lua for Neovim integration.
- SFTP Integration: Secure file transfer over SSH
- Incremental Sync: Only sync modified files for efficiency
- Real-time Monitoring: Auto-sync on file changes or save events
- Dual Direction Support: Upload and download files
- Multi-Format Configuration: Support for TOML, VSCode SFTP, and legacy JSON formats
- Configuration Discovery: Automatic detection of configuration files with priority fallback
- VSCode Compatibility: Works with existing VSCode SFTP configuration files
- Neovim Commands: Seamless integration with Neovim commands
- Performance Optimized: Rust core for high-speed operations
- Rust (latest stable version)
- Neovim (0.8+)
- SSH access to your remote server
- Build the Rust core:
cd astra-core
cargo build --release- Add the plugin to your Neovim configuration (using your favorite plugin manager):
Lazy.nvim:
{
dir = "/path/to/astra.nvim",
config = function()
require("astra").setup({
host = "your-server.com",
username = "your-username",
password = "your-password", -- or use private_key_path
remote_path = "/remote/directory",
sync_on_save = true,
})
end
}Packer.nvim:
use {
"/path/to/astra.nvim",
config = function()
require("astra").setup({
host = "your-server.com",
username = "your-username",
password = "your-password",
remote_path = "/remote/directory",
sync_on_save = true,
})
end
}require("astra").setup({
host = "your-server.com", -- Remote server hostname
port = 22, -- SSH port
username = "your-username", -- SSH username
password = "your-password", -- SSH password (optional)
private_key_path = "/path/to/key", -- Private key path (optional)
remote_path = "/remote/directory", -- Remote directory
local_path = vim.loop.cwd(), -- Local directory
auto_sync = false, -- Enable auto-sync
sync_on_save = true, -- Sync on file save
sync_interval = 30000, -- Auto-sync interval (ms)
})Password Authentication:
require("astra").setup({
host = "server.com",
username = "user",
password = "password",
remote_path = "/remote/path",
})SSH Key Authentication:
require("astra").setup({
host = "server.com",
username = "user",
private_key_path = "/home/user/.ssh/id_rsa",
remote_path = "/remote/path",
}):AstraInit- Initialize configuration file:AstraSync [mode]- Synchronize files (upload/download/auto):AstraStatus- Check sync status:AstraUpload <local_path> <remote_path>- Upload single file:AstraDownload <remote_path> <local_path>- Download single file
Initialize Configuration:
:AstraInitManual Sync:
:AstraSync upload -- Upload local changes to remote
:AstraSync download -- Download remote changes to local
:AstraSync auto -- Bidirectional syncCheck Status:
:AstraStatusUpload Single File:
:AstraUpload /local/file.txt /remote/file.txtDownload Single File:
:AstraDownload /remote/file.txt /local/file.txt┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐
│ Neovim Lua │ │ Rust Core │ │ Remote Server │
│ (Frontend) │◄──►│ (astra-core) │◄──►│ (SFTP) │
└─────────────────┘ └─────────────────┘ └─────────────────┘
- File Tracking: Monitors local and remote file timestamps and checksums
- Change Detection: Identifies modified files since last sync
- Incremental Transfer: Only transfers changed files
- Conflict Resolution: Handles conflicting changes intelligently
- Status Reporting: Provides detailed sync results
The plugin uses a multi-factor approach to determine file changes:
- File Timestamps: Compare modification times
- File Size: Detect size changes
- Checksum Verification: SHA-256 hash for content verification
- Metadata Comparison: File permissions and attributes
# Build the Rust core
cd astra-core
cargo build
# Run tests
cargo test
# Build with optimizations
cargo build --release
# Run linting
cargo clippy# Run all tests
cargo test
# Run specific test module
cargo test types_tests
# Run integration tests
cargo test integration_testsastra.nvim/
├── astra-core/ # Rust core implementation
│ ├── src/
│ │ ├── main.rs # Main entry point
│ │ ├── types.rs # Data structures
│ │ ├── error.rs # Error handling
│ │ ├── sftp.rs # SFTP operations
│ │ ├── cli.rs # CLI interface
│ │ ├── config.rs # Configuration management
│ │ ├── types_tests.rs # Type tests
│ │ ├── sftp_tests.rs # SFTP tests
│ │ ├── cli_tests.rs # CLI tests
│ │ └── integration_tests.rs # Integration tests
│ └── Cargo.toml # Rust dependencies
├── lua/
│ ├── astra.lua # Main plugin module
│ └── astra-example.lua # Configuration example
└── README.md # This file
The plugin supports multiple configuration file formats with the following priority order:
- TOML Configuration (
.astra-settings/settings.toml) - VSCode SFTP Configuration (
.vscode/sftp.json) - Legacy Astra Configuration (
astra.json)
The recommended format for new projects:
[sftp]
host = "your-server.com"
port = 22
username = "your-username"
password = "your-password" # optional
private_key_path = "/path/to/private/key" # optional
remote_path = "/remote/directory"
local_path = "/local/directory"
[sync]
auto_sync = true
sync_on_save = true
sync_interval = 30000Compatible with VSCode SFTP extension:
{
"name": "My Server",
"host": "your-server.com",
"protocol": "sftp",
"port": 22,
"username": "your-username",
"password": "your-password",
"remotePath": "/remote/directory",
"uploadOnSave": true
}The original format:
{
"host": "your-server.com",
"port": 22,
"username": "your-username",
"password": "your-password",
"private_key_path": "/path/to/private/key",
"remote_path": "/remote/directory",
"local_path": "/local/directory"
}The plugin automatically searches for configuration files in the following order:
- TOML Configuration: Looks for
.astra-settings/settings.tomlin the current directory or parent directories - VSCode SFTP Configuration: Looks for
.vscode/sftp.jsonin the current directory or parent directories - Legacy Astra Configuration: Looks for
astra.jsonin the current directory
The plugin will automatically detect and use the first available configuration file format. This allows for seamless migration between formats and compatibility with existing VSCode SFTP setups.
Connection Failed:
- Verify SSH credentials and server accessibility
- Check firewall settings
- Ensure SFTP is enabled on the remote server
Permission Denied:
- Verify user permissions on remote directory
- Check SSH key permissions (600)
- Ensure password is correct
Sync Issues:
- Check file permissions
- Verify disk space
- Ensure network connectivity
Enable debug logging:
export RUST_LOG=debug
cargo run sync- Use SSH Keys: Key-based authentication is faster than password
- Incremental Sync: Only sync changed files
- Network Conditions: Consider bandwidth and latency
- File Size: Large files may need special handling
- Concurrent Transfers: Multiple files can be transferred simultaneously
- Memory: Minimal memory footprint
- CPU: Low CPU usage during idle, moderate during transfers
- Network: Efficient protocol usage with compression support
- SSH Keys: Use key-based authentication when possible
- Password Storage: Avoid storing passwords in plain text
- Network Security: Use encrypted connections
- File Permissions: Set appropriate file permissions
- Access Control: Limit remote directory access
- SSH Encryption: All transfers are encrypted via SSH
- Authentication: Multiple authentication methods
- Session Management: Secure session handling
- Error Handling: Graceful error recovery
- Fork the repository
- Create a feature branch
- Make your changes
- Add tests
- Submit a pull request
- Follow Rust coding standards
- Use proper error handling
- Add comprehensive tests
- Document your code
This project is licensed under the MIT License.
For issues and questions:
- Create an issue on GitHub
- Check the troubleshooting section
- Review the configuration examples
