init
This commit is contained in:
commit
f6140a1fc3
18
cmd/cat.go
Normal file
18
cmd/cat.go
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
package cmd
|
||||||
|
|
||||||
|
import (
|
||||||
|
"gosh/types"
|
||||||
|
"os"
|
||||||
|
|
||||||
|
"github.com/fatih/color"
|
||||||
|
)
|
||||||
|
|
||||||
|
func GoshCat(sh *types.Shell, filename string) types.CmdOutput {
|
||||||
|
data, err := os.ReadFile(filename)
|
||||||
|
red := color.New(color.FgRed).SprintFunc()
|
||||||
|
if err != nil {
|
||||||
|
return types.CmdOutput{Id: 1, Output: red(err)}
|
||||||
|
}
|
||||||
|
|
||||||
|
return types.CmdOutput{Id: 0, Output: string(data)}
|
||||||
|
}
|
||||||
22
cmd/cd.go
Normal file
22
cmd/cd.go
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
package cmd
|
||||||
|
|
||||||
|
import (
|
||||||
|
"os"
|
||||||
|
|
||||||
|
"gosh/types"
|
||||||
|
|
||||||
|
"github.com/fatih/color"
|
||||||
|
)
|
||||||
|
|
||||||
|
func GoshCd(sh *types.Shell, dir string) types.CmdOutput {
|
||||||
|
err := os.Chdir(dir)
|
||||||
|
red := color.New(color.FgRed).SprintFunc()
|
||||||
|
if err != nil {
|
||||||
|
return types.CmdOutput{Id: 1, Output: red(err)}
|
||||||
|
}
|
||||||
|
|
||||||
|
dir, _ = os.Getwd()
|
||||||
|
sh.Cd = dir
|
||||||
|
|
||||||
|
return types.CmdOutput{Id: 0, Output: ""}
|
||||||
|
}
|
||||||
7
cmd/clear.go
Normal file
7
cmd/clear.go
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
package cmd
|
||||||
|
|
||||||
|
import "fmt"
|
||||||
|
|
||||||
|
func GoshClear() {
|
||||||
|
fmt.Print("\033[H\033[2J")
|
||||||
|
}
|
||||||
60
cmd/grep.go
Normal file
60
cmd/grep.go
Normal file
@ -0,0 +1,60 @@
|
|||||||
|
package cmd
|
||||||
|
|
||||||
|
import (
|
||||||
|
"gosh/types"
|
||||||
|
"regexp"
|
||||||
|
"strconv"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"github.com/fatih/color"
|
||||||
|
)
|
||||||
|
|
||||||
|
func GoshGrep(sh *types.Shell, args map[string]string, input string, regex string) types.CmdOutput {
|
||||||
|
re := regexp.MustCompile(regex)
|
||||||
|
lines := strings.Split(input, "\n")
|
||||||
|
|
||||||
|
red := color.New(color.FgRed).SprintFunc()
|
||||||
|
|
||||||
|
value, ok := args["-C"]
|
||||||
|
var err error
|
||||||
|
context_lines := 0
|
||||||
|
|
||||||
|
if ok {
|
||||||
|
context_lines, err = strconv.Atoi(value)
|
||||||
|
if err != nil {
|
||||||
|
return types.CmdOutput{Id: 1, Output: red(err)}
|
||||||
|
}
|
||||||
|
context_lines++
|
||||||
|
}
|
||||||
|
|
||||||
|
var output strings.Builder
|
||||||
|
for i, line := range lines {
|
||||||
|
if re.MatchString(line) {
|
||||||
|
// Print behind
|
||||||
|
if context_lines != 0 {
|
||||||
|
for bi := i - context_lines; bi < i; bi++ {
|
||||||
|
if bi < 0 {
|
||||||
|
continue
|
||||||
|
} else {
|
||||||
|
output.WriteString(lines[bi] + "\n")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
output.WriteString(line + "\n")
|
||||||
|
|
||||||
|
// Print after
|
||||||
|
if context_lines != 0 {
|
||||||
|
for ai := i + 1; ai < i+context_lines; ai++ {
|
||||||
|
if ai > len(lines)-1 {
|
||||||
|
continue
|
||||||
|
} else {
|
||||||
|
output.WriteString(lines[ai] + "\n")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return types.CmdOutput{Id: 0, Output: output.String()}
|
||||||
|
}
|
||||||
28
cmd/ls.go
Normal file
28
cmd/ls.go
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
package cmd
|
||||||
|
|
||||||
|
import (
|
||||||
|
"gosh/types"
|
||||||
|
"os"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"github.com/fatih/color"
|
||||||
|
)
|
||||||
|
|
||||||
|
func GoshLs(sh *types.Shell) types.CmdOutput {
|
||||||
|
children, err := os.ReadDir(sh.Cd)
|
||||||
|
red := color.New(color.FgRed).SprintFunc()
|
||||||
|
if err != nil {
|
||||||
|
return types.CmdOutput{Id: 1, Output: red(err)}
|
||||||
|
}
|
||||||
|
|
||||||
|
var output strings.Builder
|
||||||
|
for _, child := range children {
|
||||||
|
if child.IsDir() {
|
||||||
|
output.WriteString(color.CyanString(child.Name()+"/") + "\n")
|
||||||
|
} else {
|
||||||
|
output.WriteString(child.Name() + "\n")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return types.CmdOutput{Id: 0, Output: output.String()}
|
||||||
|
}
|
||||||
9
cmd/pwd.go
Normal file
9
cmd/pwd.go
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
package cmd
|
||||||
|
|
||||||
|
import (
|
||||||
|
"gosh/types"
|
||||||
|
)
|
||||||
|
|
||||||
|
func GoshPwd(sh *types.Shell) types.CmdOutput {
|
||||||
|
return types.CmdOutput{Id: 0, Output: sh.Cd}
|
||||||
|
}
|
||||||
10
go.mod
Normal file
10
go.mod
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
module gosh
|
||||||
|
|
||||||
|
go 1.21.5
|
||||||
|
|
||||||
|
require (
|
||||||
|
github.com/fatih/color v1.18.0 // indirect
|
||||||
|
github.com/mattn/go-colorable v0.1.13 // indirect
|
||||||
|
github.com/mattn/go-isatty v0.0.20 // indirect
|
||||||
|
golang.org/x/sys v0.25.0 // indirect
|
||||||
|
)
|
||||||
11
go.sum
Normal file
11
go.sum
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
github.com/fatih/color v1.18.0 h1:S8gINlzdQ840/4pfAwic/ZE0djQEH3wM94VfqLTZcOM=
|
||||||
|
github.com/fatih/color v1.18.0/go.mod h1:4FelSpRwEGDpQ12mAdzqdOukCy4u8WUtOY6lkT/6HfU=
|
||||||
|
github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA=
|
||||||
|
github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg=
|
||||||
|
github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
|
||||||
|
github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
|
||||||
|
github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
|
||||||
|
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
|
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
|
golang.org/x/sys v0.25.0 h1:r+8e+loiHxRqhXVl6ML1nO3l1+oFoWbnlu2Ehimmi34=
|
||||||
|
golang.org/x/sys v0.25.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||||
126
main.go
Normal file
126
main.go
Normal file
@ -0,0 +1,126 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bufio"
|
||||||
|
"fmt"
|
||||||
|
"gosh/cmd"
|
||||||
|
"gosh/types"
|
||||||
|
"os"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"github.com/fatih/color"
|
||||||
|
)
|
||||||
|
|
||||||
|
func gosh_print_output(cmdo types.CmdOutput) {
|
||||||
|
switch cmdo.Id {
|
||||||
|
case 0:
|
||||||
|
fmt.Printf(cmdo.Output)
|
||||||
|
case 1:
|
||||||
|
fmt.Printf("Error: %s\n", cmdo.Output)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func parse_flags(parts []string) (map[string]string, []string) {
|
||||||
|
flags := make(map[string]string)
|
||||||
|
args := []string{}
|
||||||
|
i := 0
|
||||||
|
for i < len(parts) {
|
||||||
|
if strings.HasPrefix(parts[i], "-") {
|
||||||
|
key := parts[i]
|
||||||
|
val := ""
|
||||||
|
if i+1 < len(parts) && !strings.HasPrefix(parts[i+1], "-") {
|
||||||
|
val = parts[i+1]
|
||||||
|
i++
|
||||||
|
}
|
||||||
|
flags[key] = val
|
||||||
|
} else {
|
||||||
|
args = append(args, parts[i])
|
||||||
|
}
|
||||||
|
i++
|
||||||
|
}
|
||||||
|
return flags, args
|
||||||
|
}
|
||||||
|
|
||||||
|
func gosh_process_input(sh *types.Shell, input string) {
|
||||||
|
// Split by pipe and trim spaces
|
||||||
|
commands := strings.Split(input, "|")
|
||||||
|
var prevOutput types.CmdOutput
|
||||||
|
|
||||||
|
for _, cmdStr := range commands {
|
||||||
|
cmdStr = strings.TrimSpace(cmdStr)
|
||||||
|
parts := strings.Fields(cmdStr)
|
||||||
|
if len(parts) == 0 {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
switch parts[0] {
|
||||||
|
case "pwd":
|
||||||
|
prevOutput = cmd.GoshPwd(sh)
|
||||||
|
case "cd":
|
||||||
|
if len(parts) < 2 {
|
||||||
|
fmt.Println("Usage: cd <dir>")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
prevOutput = cmd.GoshCd(sh, parts[1])
|
||||||
|
case "ls":
|
||||||
|
prevOutput = cmd.GoshLs(sh)
|
||||||
|
case "cat":
|
||||||
|
if len(parts) < 2 {
|
||||||
|
fmt.Println("Usage: cat <path to file>")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
prevOutput = cmd.GoshCat(sh, parts[1])
|
||||||
|
case "grep":
|
||||||
|
if len(parts) < 2 {
|
||||||
|
fmt.Println("Usage: grep <pattern>")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
flags, args := parse_flags(parts)
|
||||||
|
|
||||||
|
// Feed previous output to grep
|
||||||
|
prevOutput = cmd.GoshGrep(sh, flags, prevOutput.Output, args[len(args)-1])
|
||||||
|
case "clear":
|
||||||
|
cmd.GoshClear()
|
||||||
|
default:
|
||||||
|
fmt.Println("Unknown command: ", parts[0])
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
gosh_print_output(prevOutput)
|
||||||
|
}
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
reader := bufio.NewReader(os.Stdin)
|
||||||
|
|
||||||
|
c := color.New(color.FgCyan)
|
||||||
|
|
||||||
|
dir, _ := os.Getwd()
|
||||||
|
sh := types.Shell{Cd: dir}
|
||||||
|
|
||||||
|
var should_exit = false
|
||||||
|
for {
|
||||||
|
c.Print(sh.Cd)
|
||||||
|
fmt.Print("> ")
|
||||||
|
|
||||||
|
input, err := reader.ReadString('\n')
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println("Error reading input: ", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
input = strings.TrimSpace(input)
|
||||||
|
|
||||||
|
switch input {
|
||||||
|
case "exit":
|
||||||
|
should_exit = true
|
||||||
|
default:
|
||||||
|
gosh_process_input(&sh, input)
|
||||||
|
}
|
||||||
|
|
||||||
|
if should_exit {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
7
readme.md
Normal file
7
readme.md
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
# GoLSh
|
||||||
|
|
||||||
|
Go Lang Shell
|
||||||
|
|
||||||
|
## Commands
|
||||||
|
|
||||||
|
`cd`, `ls`, `pwd`, `grep`, `cat`, `clear`
|
||||||
10
types/shell.go
Normal file
10
types/shell.go
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
package types
|
||||||
|
|
||||||
|
type Shell struct {
|
||||||
|
Cd string
|
||||||
|
}
|
||||||
|
|
||||||
|
type CmdOutput struct {
|
||||||
|
Id int
|
||||||
|
Output string
|
||||||
|
}
|
||||||
Loading…
x
Reference in New Issue
Block a user