2 Commits

Author SHA1 Message Date
cooper
8604a8f365 Merge b43a67eb1a into 3d746ec49a 2025-09-30 03:32:03 +00:00
zxr
b43a67eb1a feat: auto ping after sshm turn on. 2025-09-30 11:27:32 +08:00
5 changed files with 83 additions and 65 deletions

66
CONFIG.md Normal file
View File

@@ -0,0 +1,66 @@
# SSHM Configuration
SSHM supports configurable key bindings through a configuration file located at:
- Linux/macOS: `~/.config/sshm/config.json`
- Windows: `%APPDATA%\sshm\config.json`
## Configuration Options
### Key Bindings
The key bindings section allows you to customize how you exit the application.
#### Example Configuration
```json
{
"key_bindings": {
"quit_keys": ["q", "ctrl+c"],
"disable_esc_quit": true
}
}
```
#### Options
- **quit_keys**: Array of keys that will quit the application. Default: `["q", "ctrl+c"]`
- **disable_esc_quit**: Boolean flag to disable ESC key from quitting the application. Default: `false`
## For Vim Users
If you're a vim user and frequently press ESC accidentally causing the application to quit, set `disable_esc_quit` to `true`:
```json
{
"key_bindings": {
"quit_keys": ["q", "ctrl+c"],
"disable_esc_quit": true
}
}
```
With this configuration:
- ESC will no longer quit the application
- You can still quit using 'q' or Ctrl+C
- All other functionality remains the same
## Default Configuration
If no configuration file exists, SSHM will create one with these defaults:
```json
{
"key_bindings": {
"quit_keys": ["q", "ctrl+c"],
"disable_esc_quit": false
}
}
```
This ensures backward compatibility - ESC will continue to work as a quit key by default.
## Configuration Location
The configuration file will be automatically created when you first run SSHM. You can manually edit it to customize the key bindings to your preference.
If you encounter any issues with the configuration file, you can delete it and SSHM will recreate it with default settings on the next run.

View File

@@ -553,34 +553,6 @@ This will be automatically converted to:
StrictHostKeyChecking no
```
### Custom Key Bindings
SSHM supports customizable key bindings through a configuration file. This is particularly useful for users who want to modify the default quit behavior.
**Configuration File Location:**
- **Linux/macOS**: `~/.config/sshm/config.json`
- **Windows**: `%APPDATA%\sshm\config.json`
**Example Configuration:**
```json
{
"key_bindings": {
"quit_keys": ["q", "ctrl+c"],
"disable_esc_quit": true
}
}
```
**Available Options:**
- **quit_keys**: Array of keys that will quit the application. Default: `["q", "ctrl+c"]`
- **disable_esc_quit**: Boolean flag to disable ESC key from quitting the application. Default: `false`
**For Vim Users:**
If you frequently press ESC accidentally causing the application to quit, set `disable_esc_quit` to `true`. This will disable ESC as a quit key while preserving all other functionality.
**Default Configuration:**
If no configuration file exists, SSHM will automatically create one with default settings that maintain backward compatibility.
## 🛠️ Development
### Prerequisites
@@ -697,8 +669,6 @@ This project is licensed under the MIT License - see the [LICENSE](LICENSE) file
- [Charm](https://charm.sh/) for the amazing TUI libraries
- [Cobra](https://cobra.dev/) for the excellent CLI framework
- [@yimeng](https://github.com/yimeng) for contributing SSH Include directive support
- [@ldreux](https://github.com/ldreux) for contributing multi-word search functionality
- [@qingfengzxr](https://github.com/qingfengzxr) for contributing custom key bindings support
- The Go community for building such fantastic tools
---

View File

@@ -37,64 +37,35 @@ func sortHostsByName(hosts []config.SSHHost) []config.SSHHost {
// filterHosts filters hosts according to the search query (name or tags)
func (m Model) filterHosts(query string) []config.SSHHost {
subqueries := strings.Split(query, " ")
subqueriesLength := len(subqueries)
subfilteredHosts := make([][]config.SSHHost, subqueriesLength)
for i, subquery := range subqueries {
subfilteredHosts[i] = m.filterHostsByWord(subquery)
}
// return the intersection of search results
result := make([]config.SSHHost, 0)
tempMap := map[string]int{}
for _, hosts := range subfilteredHosts {
for _, host := range hosts {
if _, ok := tempMap[host.Name]; !ok {
tempMap[host.Name] = 1
} else {
tempMap[host.Name] = tempMap[host.Name] + 1
}
if tempMap[host.Name] == subqueriesLength {
result = append(result, host)
}
}
}
return result
}
// filterHostsByWord filters hosts according to a single word
func (m Model) filterHostsByWord(word string) []config.SSHHost {
var filtered []config.SSHHost
if word == "" {
if query == "" {
filtered = m.hosts
} else {
word = strings.ToLower(word)
query = strings.ToLower(query)
for _, host := range m.hosts {
// Check the hostname
if strings.Contains(strings.ToLower(host.Name), word) {
if strings.Contains(strings.ToLower(host.Name), query) {
filtered = append(filtered, host)
continue
}
// Check the hostname
if strings.Contains(strings.ToLower(host.Hostname), word) {
if strings.Contains(strings.ToLower(host.Hostname), query) {
filtered = append(filtered, host)
continue
}
// Check the user
if strings.Contains(strings.ToLower(host.User), word) {
if strings.Contains(strings.ToLower(host.User), query) {
filtered = append(filtered, host)
continue
}
// Check the tags
for _, tag := range host.Tags {
if strings.Contains(strings.ToLower(tag), word) {
if strings.Contains(strings.ToLower(tag), query) {
filtered = append(filtered, host)
break
}

View File

@@ -152,6 +152,12 @@ func RunInteractiveMode(hosts []config.SSHHost, configFile, currentVersion strin
// Start the application in alt screen mode for clean output
p := tea.NewProgram(m, tea.WithAltScreen())
// Send initial command to start auto-ping when the program starts
go func() {
p.Send(autoPingMsg{})
}()
_, err := p.Run()
if err != nil {
return fmt.Errorf("error running TUI: %w", err)

View File

@@ -20,6 +20,7 @@ type (
versionCheckMsg *version.UpdateInfo
versionErrorMsg error
errorMsg string
autoPingMsg struct{}
)
// startPingAllCmd creates a command to ping all hosts concurrently
@@ -145,6 +146,10 @@ func (m Model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
}
return m, nil
case autoPingMsg:
// Handle auto-ping on startup - start pinging all hosts
return m, m.startPingAllCmd()
case versionCheckMsg:
// Handle version check result
if msg != nil {