chore(commands): more commands for suggestions (#10)
## What's new - color completion message command green https://github.com/versenilvis/IRIS/pull/10/commits/6e141f5e6909fad1ec42725cce38d51729acf399 - new flat command folder structure https://github.com/versenilvis/IRIS/pull/10/commits/87026a854a529ec5d5baed967d5f7a7f0085a24b - fix some linter problems https://github.com/versenilvis/IRIS/pull/10/commits/536de790cefda912f50bf4022e40ce2b965db2e2 - fix some gemini fix suggestions
This commit is contained in:
@@ -0,0 +1,57 @@
|
||||
package sys
|
||||
|
||||
import (
|
||||
"os"
|
||||
"strings"
|
||||
|
||||
"github.com/versenilvis/iris/commands/core"
|
||||
)
|
||||
|
||||
func envVarGenerator(tokens []string, _ string, _ string) []core.Suggestion {
|
||||
var results []core.Suggestion
|
||||
for _, env := range os.Environ() {
|
||||
parts := strings.SplitN(env, "=", 2)
|
||||
name := parts[0]
|
||||
val := ""
|
||||
if len(parts) == 2 {
|
||||
val = parts[1]
|
||||
// truncate long values
|
||||
if len(val) > 60 {
|
||||
val = val[:57] + "..."
|
||||
}
|
||||
}
|
||||
results = append(results, core.Suggestion{Cmd: name, Desc: val})
|
||||
}
|
||||
return results
|
||||
}
|
||||
|
||||
func init() {
|
||||
core.Register(&core.Spec{
|
||||
Name: "export",
|
||||
Description: "set environment variable",
|
||||
Generator: envVarGenerator,
|
||||
})
|
||||
|
||||
core.Register(&core.Spec{
|
||||
Name: "env",
|
||||
Description: "print environment",
|
||||
Generator: envVarGenerator,
|
||||
Options: []core.Option{
|
||||
{Name: "-i", Description: "start with empty env"},
|
||||
{Name: "-u", Description: "unset variable"},
|
||||
{Name: "-0", Description: "null delimited"},
|
||||
},
|
||||
})
|
||||
|
||||
core.Register(&core.Spec{
|
||||
Name: "printenv",
|
||||
Description: "print environment variables",
|
||||
Generator: envVarGenerator,
|
||||
})
|
||||
|
||||
core.Register(&core.Spec{
|
||||
Name: "unset",
|
||||
Description: "unset variable",
|
||||
Generator: envVarGenerator,
|
||||
})
|
||||
}
|
||||
@@ -0,0 +1,156 @@
|
||||
package sys
|
||||
|
||||
import (
|
||||
"github.com/versenilvis/iris/commands/core"
|
||||
)
|
||||
|
||||
func init() {
|
||||
core.Register(&core.Spec{
|
||||
Name: "curl",
|
||||
Description: "transfer data via URL",
|
||||
Generator: core.FileGenerator(),
|
||||
Options: []core.Option{
|
||||
{Name: "-X", Description: "request method (GET/POST/PUT/DELETE)"},
|
||||
{Name: "-H", Description: "request header"},
|
||||
{Name: "-d", Description: "request body data"},
|
||||
{Name: "-o", Description: "output to file"},
|
||||
{Name: "-O", Description: "save with remote filename"},
|
||||
{Name: "-s", Description: "silent mode"},
|
||||
{Name: "-S", Description: "show error in silent"},
|
||||
{Name: "-L", Description: "follow redirects"},
|
||||
{Name: "-k", Description: "insecure (skip TLS verify)"},
|
||||
{Name: "-I", Description: "fetch headers only"},
|
||||
{Name: "-v", Description: "verbose"},
|
||||
{Name: "-u", Description: "user:password"},
|
||||
{Name: "-b", Description: "send cookie"},
|
||||
{Name: "-c", Description: "save cookie to file"},
|
||||
{Name: "-F", Description: "multipart form data"},
|
||||
{Name: "--json", Description: "send JSON body"},
|
||||
{Name: "--compressed", Description: "request compressed response"},
|
||||
{Name: "--max-time", Description: "max time in seconds"},
|
||||
{Name: "--retry", Description: "retry count"},
|
||||
{Name: "-A", Description: "custom user-agent"},
|
||||
{Name: "--proxy", Description: "use proxy"},
|
||||
{Name: "-T", Description: "upload file"},
|
||||
},
|
||||
})
|
||||
|
||||
core.Register(&core.Spec{
|
||||
Name: "wget",
|
||||
Description: "non-interactive downloader",
|
||||
Generator: core.FileGenerator(),
|
||||
Options: []core.Option{
|
||||
{Name: "-O", Description: "output filename"},
|
||||
{Name: "-q", Description: "quiet"},
|
||||
{Name: "-v", Description: "verbose"},
|
||||
{Name: "-r", Description: "recursive"},
|
||||
{Name: "-P", Description: "output directory"},
|
||||
{Name: "-c", Description: "continue download"},
|
||||
{Name: "--no-check-certificate", Description: "skip TLS verify"},
|
||||
{Name: "-b", Description: "background"},
|
||||
{Name: "--limit-rate", Description: "limit rate"},
|
||||
{Name: "-U", Description: "custom user-agent"},
|
||||
{Name: "--spider", Description: "check URL only"},
|
||||
{Name: "-np", Description: "no parent directories"},
|
||||
{Name: "-nH", Description: "no host directories"},
|
||||
},
|
||||
})
|
||||
|
||||
core.Register(&core.Spec{
|
||||
Name: "nc",
|
||||
Description: "netcat - TCP/UDP tool",
|
||||
Options: []core.Option{
|
||||
{Name: "-l", Description: "listen mode"},
|
||||
{Name: "-p", Description: "local port"},
|
||||
{Name: "-z", Description: "port scan mode"},
|
||||
{Name: "-v", Description: "verbose"},
|
||||
{Name: "-u", Description: "UDP mode"},
|
||||
{Name: "-n", Description: "no DNS"},
|
||||
{Name: "-w", Description: "timeout"},
|
||||
},
|
||||
})
|
||||
|
||||
core.Register(&core.Spec{
|
||||
Name: "ping",
|
||||
Description: "test network connectivity",
|
||||
Options: []core.Option{
|
||||
{Name: "-c", Description: "packet count"},
|
||||
{Name: "-i", Description: "interval"},
|
||||
{Name: "-t", Description: "TTL"},
|
||||
{Name: "-s", Description: "packet size"},
|
||||
{Name: "-q", Description: "quiet output"},
|
||||
},
|
||||
})
|
||||
|
||||
core.Register(&core.Spec{
|
||||
Name: "dig",
|
||||
Description: "DNS lookup",
|
||||
Options: []core.Option{
|
||||
{Name: "+short", Description: "short output"},
|
||||
{Name: "+noall", Description: "no output flags"},
|
||||
{Name: "+answer", Description: "answer section only"},
|
||||
{Name: "-t", Description: "record type"},
|
||||
{Name: "@", Description: "nameserver"},
|
||||
},
|
||||
})
|
||||
|
||||
core.Register(&core.Spec{
|
||||
Name: "nslookup",
|
||||
Description: "query DNS",
|
||||
})
|
||||
|
||||
core.Register(&core.Spec{
|
||||
Name: "ifconfig",
|
||||
Description: "configure network interface",
|
||||
Options: []core.Option{
|
||||
{Name: "-a", Description: "all interfaces"},
|
||||
},
|
||||
})
|
||||
|
||||
core.Register(&core.Spec{
|
||||
Name: "ip",
|
||||
Description: "show/manage network",
|
||||
Subcommands: []core.Subcommand{
|
||||
{Name: "addr", Description: "address management"},
|
||||
{Name: "link", Description: "network device management"},
|
||||
{Name: "route", Description: "routing table management"},
|
||||
{Name: "neigh", Description: "ARP table"},
|
||||
{Name: "rule", Description: "routing policy"},
|
||||
},
|
||||
Options: []core.Option{
|
||||
{Name: "-4", Description: "IPv4 only"},
|
||||
{Name: "-6", Description: "IPv6 only"},
|
||||
{Name: "-br", Description: "brief output"},
|
||||
{Name: "-c", Description: "colorize"},
|
||||
},
|
||||
})
|
||||
|
||||
core.Register(&core.Spec{
|
||||
Name: "netstat",
|
||||
Description: "network statistics",
|
||||
Options: []core.Option{
|
||||
{Name: "-t", Description: "TCP connections"},
|
||||
{Name: "-u", Description: "UDP connections"},
|
||||
{Name: "-l", Description: "listening only"},
|
||||
{Name: "-n", Description: "numeric addresses"},
|
||||
{Name: "-p", Description: "show PID"},
|
||||
{Name: "-r", Description: "routing table"},
|
||||
{Name: "-s", Description: "statistics"},
|
||||
},
|
||||
})
|
||||
|
||||
core.Register(&core.Spec{
|
||||
Name: "ss",
|
||||
Description: "socket statistics",
|
||||
Options: []core.Option{
|
||||
{Name: "-t", Description: "TCP"},
|
||||
{Name: "-u", Description: "UDP"},
|
||||
{Name: "-l", Description: "listening"},
|
||||
{Name: "-n", Description: "numeric"},
|
||||
{Name: "-p", Description: "show process"},
|
||||
{Name: "-a", Description: "all"},
|
||||
{Name: "-4", Description: "IPv4"},
|
||||
{Name: "-6", Description: "IPv6"},
|
||||
},
|
||||
})
|
||||
}
|
||||
@@ -0,0 +1,109 @@
|
||||
package sys
|
||||
|
||||
import (
|
||||
"context"
|
||||
"os/exec"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/versenilvis/iris/commands/core"
|
||||
)
|
||||
|
||||
func processGenerator(tokens []string, _ string, _ string) []core.Suggestion {
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
|
||||
defer cancel()
|
||||
|
||||
// output: "pid command"
|
||||
cmd := exec.CommandContext(ctx, "ps", "-eo", "pid,comm")
|
||||
out, err := cmd.Output()
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
seen := make(map[string]bool)
|
||||
var results []core.Suggestion
|
||||
for _, line := range strings.Split(string(out), "\n") {
|
||||
line = strings.TrimSpace(line)
|
||||
if line == "" {
|
||||
continue
|
||||
}
|
||||
parts := strings.Fields(line)
|
||||
if len(parts) < 2 {
|
||||
continue
|
||||
}
|
||||
pid := parts[0]
|
||||
if pid[0] < '0' || pid[0] > '9' {
|
||||
continue
|
||||
}
|
||||
name := parts[1]
|
||||
|
||||
// suggest both PID and process name
|
||||
if !seen[pid] {
|
||||
seen[pid] = true
|
||||
results = append(results, core.Suggestion{Cmd: pid, Desc: name})
|
||||
}
|
||||
}
|
||||
return results
|
||||
}
|
||||
|
||||
func init() {
|
||||
core.Register(&core.Spec{
|
||||
Name: "ps",
|
||||
Description: "report processes",
|
||||
Options: []core.Option{
|
||||
{Name: "-e", Description: "all processes"},
|
||||
{Name: "-f", Description: "full format"},
|
||||
{Name: "-u", Description: "by user"},
|
||||
{Name: "aux", Description: "all + user + x"},
|
||||
{Name: "-o", Description: "custom format"},
|
||||
{Name: "--pid", Description: "filter by PID"},
|
||||
{Name: "--sort", Description: "sort by field"},
|
||||
},
|
||||
})
|
||||
|
||||
core.Register(&core.Spec{
|
||||
Name: "kill",
|
||||
Description: "send signal to process",
|
||||
Generator: processGenerator,
|
||||
Options: []core.Option{
|
||||
{Name: "-9", Description: "SIGKILL (force)"},
|
||||
{Name: "-15", Description: "SIGTERM (graceful)"},
|
||||
{Name: "-2", Description: "SIGINT"},
|
||||
{Name: "-HUP", Description: "SIGHUP (reload)"},
|
||||
{Name: "-l", Description: "list signal names"},
|
||||
},
|
||||
})
|
||||
|
||||
core.Register(&core.Spec{
|
||||
Name: "killall",
|
||||
Description: "kill by process name",
|
||||
Generator: processGenerator,
|
||||
Options: []core.Option{
|
||||
{Name: "-9", Description: "SIGKILL"},
|
||||
{Name: "-s", Description: "specify signal"},
|
||||
{Name: "-u", Description: "only for user"},
|
||||
{Name: "-i", Description: "confirm each"},
|
||||
},
|
||||
})
|
||||
|
||||
core.Register(&core.Spec{
|
||||
Name: "pkill",
|
||||
Description: "kill by pattern",
|
||||
Options: []core.Option{
|
||||
{Name: "-9", Description: "SIGKILL"},
|
||||
{Name: "-f", Description: "match full command"},
|
||||
{Name: "-u", Description: "match by user"},
|
||||
},
|
||||
})
|
||||
|
||||
core.Register(&core.Spec{
|
||||
Name: "pgrep",
|
||||
Description: "find process by pattern",
|
||||
Options: []core.Option{
|
||||
{Name: "-l", Description: "list name and PID"},
|
||||
{Name: "-f", Description: "match full command"},
|
||||
{Name: "-u", Description: "match by user"},
|
||||
{Name: "-a", Description: "list command line"},
|
||||
},
|
||||
})
|
||||
}
|
||||
Reference in New Issue
Block a user