forked from x/icebergs
add iterm.go
This commit is contained in:
parent
b3b37b37d5
commit
bd15da5f40
@ -192,8 +192,6 @@ func init() {
|
||||
m.PushSearch(mdb.TEXT, m.MergePod(value[mdb.NAME]), value)
|
||||
}
|
||||
})
|
||||
} else if arg[0] == mdb.FOREACH && arg[1] == ssh.SHELL {
|
||||
m.PushSearch(mdb.TYPE, ssh.SHELL, mdb.TEXT, "ice.bin space dial dev ops")
|
||||
}
|
||||
}},
|
||||
DOMAIN: {Hand: func(m *ice.Message, arg ...string) { m.Echo(_space_domain(m)) }},
|
||||
|
@ -101,28 +101,22 @@ func init() {
|
||||
Index.MergeCommands(ice.Commands{
|
||||
GO: {Name: "go path auto", Help: "后端编程", Actions: ice.MergeActions(ice.Actions{
|
||||
mdb.RENDER: {Hand: func(m *ice.Message, arg ...string) {
|
||||
if arg[1] == "main.go" {
|
||||
// ProcessXterm(m, ssh.WEBIO, "", arg[1])
|
||||
ProcessXterm(m, "ice.bin source stdio", "", arg[1])
|
||||
return
|
||||
}
|
||||
ctx.ProcessCommand(m, yac.STACK, kit.Simple(path.Join(arg[2], arg[1])))
|
||||
return
|
||||
cmds, text := "ice.bin source stdio", ctx.GetFileCmd(path.Join(arg[2], arg[1]))
|
||||
if text != "" {
|
||||
ls := strings.Split(text, nfs.PT)
|
||||
text = "~" + kit.Join(kit.Slice(ls, 0, -1), nfs.PT) + lex.NL + kit.Slice(ls, -1)[0]
|
||||
if arg[1] == "misc/xterm/iterm.go" {
|
||||
ProcessXterm(m, "ish", "", arg[1])
|
||||
} else if arg[1] == "main.go" {
|
||||
ProcessXterm(m, "ish", "", arg[1])
|
||||
} else {
|
||||
text = "cli.system go run " + path.Join(arg[2], arg[1])
|
||||
ctx.ProcessCommand(m, yac.STACK, kit.Simple(path.Join(arg[2], arg[1])))
|
||||
}
|
||||
ProcessXterm(m, cmds, text, arg[1])
|
||||
}},
|
||||
mdb.ENGINE: {Hand: func(m *ice.Message, arg ...string) {
|
||||
if cmd := ctx.GetFileCmd(path.Join(arg[2], arg[1])); cmd != "" {
|
||||
if arg[1] == "misc/xterm/iterm.go" {
|
||||
ProcessXterm(m, "ish", "", arg[1])
|
||||
} else if arg[1] == "main.go" {
|
||||
ProcessXterm(m, "ish", "", arg[1])
|
||||
} else if cmd := ctx.GetFileCmd(path.Join(arg[2], arg[1])); cmd != "" {
|
||||
ctx.ProcessCommand(m, cmd, kit.Simple())
|
||||
return
|
||||
}
|
||||
if msg := m.Cmd(yac.STACK, path.Join(arg[2], arg[1])); msg.Option("__index") != "" {
|
||||
} else if msg := m.Cmd(yac.STACK, path.Join(arg[2], arg[1])); msg.Option("__index") != "" {
|
||||
ctx.ProcessCommand(m, msg.Option("__index"), kit.Simple())
|
||||
} else {
|
||||
ctx.ProcessCommand(m, yac.STACK, kit.Simple(path.Join(arg[2], arg[1])))
|
||||
|
@ -17,7 +17,7 @@ import (
|
||||
kit "shylinux.com/x/toolkits"
|
||||
)
|
||||
|
||||
func _xterm_get(m *ice.Message, h string) *xterm.XTerm {
|
||||
func _xterm_get(m *ice.Message, h string) xterm.XTerm {
|
||||
h = kit.Select(m.Option(mdb.HASH), h)
|
||||
m.Assert(h != "")
|
||||
mdb.HashModify(m, mdb.TIME, m.Time(), cli.DAEMON, m.Option(ice.MSG_DAEMON))
|
||||
@ -32,7 +32,7 @@ func _xterm_get(m *ice.Message, h string) *xterm.XTerm {
|
||||
m.Go(func() {
|
||||
defer term.Close()
|
||||
defer mdb.HashRemove(m, mdb.HASH, h)
|
||||
m.Log(cli.START, strings.Join(term.Args, lex.SP))
|
||||
// m.Log(cli.START, strings.Join(term.Args, lex.SP))
|
||||
buf := make([]byte, ice.MOD_BUFS)
|
||||
for {
|
||||
if n, e := term.Read(buf); !m.Warn(e) && e == nil {
|
||||
@ -52,11 +52,12 @@ func _xterm_get(m *ice.Message, h string) *xterm.XTerm {
|
||||
}
|
||||
})
|
||||
return term
|
||||
}).(*xterm.XTerm)
|
||||
}).(xterm.XTerm)
|
||||
}
|
||||
func _xterm_echo(m *ice.Message, h string, str string) {
|
||||
m.Options(ice.MSG_DAEMON, mdb.HashSelectField(m, h, cli.DAEMON))
|
||||
m.Option(ice.LOG_DISABLE, ice.TRUE)
|
||||
// m.Option(ice.LOG_DISABLE, ice.TRUE)
|
||||
m.Debug("what ---%o--- ---[%v]---", []byte(str), str)
|
||||
web.PushNoticeGrow(m, h, str)
|
||||
}
|
||||
func _xterm_cmds(m *ice.Message, h string, cmd string, arg ...ice.Any) {
|
||||
@ -77,14 +78,15 @@ func init() {
|
||||
return []string{ssh.SHELL, SH, "/bin/sh"}
|
||||
}
|
||||
})
|
||||
mdb.IsSearchForEach(m, arg, func() []string { return []string{ssh.SHELL, "ice", "ish"} })
|
||||
}},
|
||||
mdb.INPUTS: {Hand: func(m *ice.Message, arg ...string) {
|
||||
switch mdb.HashInputs(m, arg); arg[0] {
|
||||
case mdb.TYPE:
|
||||
m.Push(arg[0], "ish", BASH, SH)
|
||||
m.Cmd(mdb.SEARCH, mdb.FOREACH, ssh.SHELL, ice.OptionFields("type,name,text"), func(value ice.Maps) {
|
||||
kit.If(value[mdb.TYPE] == ssh.SHELL, func() { m.Push(arg[0], value[mdb.TEXT]) })
|
||||
})
|
||||
m.Push(arg[0], BASH, SH)
|
||||
case mdb.NAME:
|
||||
m.Push(arg[0], path.Base(m.Option(mdb.TYPE)), ice.Info.Hostname)
|
||||
case nfs.PATH:
|
||||
@ -102,11 +104,13 @@ func init() {
|
||||
m.Cmd(ctx.COMMAND, mdb.SEARCH, ctx.COMMAND, "", "", ice.OptionFields(ctx.INDEX), func(value ice.Maps) { push(ctx.INDEX, value[ctx.INDEX]) })
|
||||
}
|
||||
}},
|
||||
mdb.CREATE: {Hand: func(m *ice.Message, arg ...string) { m.ProcessRewrite(mdb.HASH, mdb.HashCreate(m, arg)) }},
|
||||
web.RESIZE: {Hand: func(m *ice.Message, arg ...string) {
|
||||
_xterm_get(m, "").Setsize(m.OptionDefault("rows", "24"), m.OptionDefault("cols", "80"))
|
||||
}},
|
||||
web.INPUT: {Hand: func(m *ice.Message, arg ...string) {
|
||||
if b, e := base64.StdEncoding.DecodeString(strings.Join(arg, "")); !m.Warn(e) {
|
||||
m.Debug("what ---%o--- ---[%v]---", b, string(b))
|
||||
_xterm_get(m, "").Write(string(b))
|
||||
}
|
||||
}},
|
||||
|
7
exec.go
7
exec.go
@ -102,6 +102,13 @@ func (m *Message) CmdHand(cmd *Command, key string, arg ...string) *Message {
|
||||
}
|
||||
return m
|
||||
}
|
||||
func (m *Message) CmdList(arg ...string) []string {
|
||||
msg, list := m.Cmd(arg), []string{}
|
||||
kit.For(msg._cmd.List, func(value Map) {
|
||||
kit.If(!kit.IsIn(kit.Format(kit.Value(value, TYPE)), "button"), func() { list = append(list, kit.Format(kit.Value(value, NAME))) })
|
||||
})
|
||||
return msg.Appendv(kit.Select(kit.Select("", list, 0), list, len(arg)-1))
|
||||
}
|
||||
func (m *Message) ActionHand(cmd *Command, key, sub string, arg ...string) *Message {
|
||||
if action, ok := cmd.Actions[sub]; !m.Warn(!ok, ErrNotFound, sub, cmd.FileLines()) {
|
||||
return m.Target()._action(m, cmd, key, sub, action, arg...)
|
||||
|
311
misc/xterm/iterm.go
Normal file
311
misc/xterm/iterm.go
Normal file
@ -0,0 +1,311 @@
|
||||
package xterm
|
||||
|
||||
import (
|
||||
"os"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
ice "shylinux.com/x/icebergs"
|
||||
"shylinux.com/x/icebergs/base/cli"
|
||||
"shylinux.com/x/icebergs/base/ctx"
|
||||
"shylinux.com/x/icebergs/base/lex"
|
||||
"shylinux.com/x/icebergs/base/mdb"
|
||||
"shylinux.com/x/icebergs/base/nfs"
|
||||
kit "shylinux.com/x/toolkits"
|
||||
)
|
||||
|
||||
type idata struct {
|
||||
cut string
|
||||
bak string
|
||||
arg string
|
||||
app string
|
||||
tip string
|
||||
due string
|
||||
args []string
|
||||
cmds []string
|
||||
list []string
|
||||
pos int
|
||||
}
|
||||
type iterm struct {
|
||||
m *ice.Message
|
||||
r *os.File
|
||||
w *os.File
|
||||
*idata
|
||||
}
|
||||
|
||||
func newiterm(m *ice.Message) (XTerm, error) {
|
||||
r, w, e := os.Pipe()
|
||||
return &iterm{m: m, r: r, w: w, idata: &idata{cmds: append(append(kit.SortedKey(ice.Info.Index), m.Cmd(ctx.COMMAND).Appendv(ctx.INDEX)...), m.Cmd(nfs.DIR, "/bin", mdb.NAME).Appendv(mdb.NAME)...)}}, e
|
||||
}
|
||||
func (s iterm) Setsize(rows, cols string) error {
|
||||
s.w.Write([]byte(s.prompt()))
|
||||
return nil
|
||||
}
|
||||
func (s iterm) Writeln(data string, arg ...ice.Any) { s.Write(kit.Format(data, arg...) + lex.NL) }
|
||||
func (s iterm) Write(data string) (int, error) {
|
||||
res, ctrl := "", ""
|
||||
for _, c := range data {
|
||||
switch c := string(c); c {
|
||||
case SOH: // Ctrl+A
|
||||
res += s.repeat(s.arg)
|
||||
s.arg, s.app = "", s.arg+s.app
|
||||
case STX: // Ctrl+B
|
||||
res = s.left(res)
|
||||
case ETX: // Ctrl+C
|
||||
s.m.Cmd("web.code.vimer", "compile")
|
||||
case EOT: // Ctrl+D
|
||||
if len(s.app) > 0 {
|
||||
s.app = s.app[1:]
|
||||
res = s.rest(res)
|
||||
}
|
||||
case ENQ: // Ctrl+E
|
||||
res += s.repeat(s.app, ESC_C)
|
||||
s.arg, s.app = s.arg+s.app, ""
|
||||
case ACK: // Ctrl+F
|
||||
res = s.right(res)
|
||||
case BEL: // Ctrl+G
|
||||
res += c
|
||||
case BS: // Ctrl+H
|
||||
res = s.dels(res)
|
||||
case NL: // Ctrl+J
|
||||
res = s.exec(res)
|
||||
case VT: // Ctrl+K
|
||||
if len(s.app) > 0 {
|
||||
s.cut, s.app = s.app, ""
|
||||
res = s.rest(res)
|
||||
}
|
||||
case NP: // Ctrl+L
|
||||
res = s.rest(res + ESC_H + ESC_2J + s.prompt() + s.arg)
|
||||
case CR: // Ctrl+M
|
||||
res = s.exec(res)
|
||||
case SO: // Ctrl+N
|
||||
res = s.hist(res, 1)
|
||||
case SI: // Ctrl+O
|
||||
if s.arg == "" {
|
||||
s.arg = kit.Select("", s.list, -1)
|
||||
res += s.arg
|
||||
res = s.exec(res)
|
||||
} else {
|
||||
res = s.exec(res)
|
||||
}
|
||||
case DLE: // Ctrl+P
|
||||
res = s.hist(res, -1)
|
||||
case DC1: // Ctrl+Q
|
||||
case DC2: // Ctrl+R
|
||||
case DC3: // Ctrl+S
|
||||
case DC4: // Ctrl+T
|
||||
if n := len(s.arg); n > 1 {
|
||||
s.arg = s.arg[:n-2] + string(s.arg[n-1]) + string(s.arg[n-2])
|
||||
res = s.rest(res + BS + BS + s.arg[n-2:])
|
||||
}
|
||||
case NAK: // Ctrl+U
|
||||
if len(s.arg) > 0 {
|
||||
res = res + s.repeat(s.arg)
|
||||
s.cut, s.arg = s.arg, ""
|
||||
res = s.rest(res)
|
||||
}
|
||||
case SYN: // Ctrl+V
|
||||
case ETB: // Ctrl+W
|
||||
arg := s.arg
|
||||
for len(s.arg) > 0 {
|
||||
if c := s.arg[len(s.arg)-1]; c == ' ' {
|
||||
s.arg = s.arg[:len(s.arg)-1]
|
||||
res += s.repeat(string(c))
|
||||
continue
|
||||
}
|
||||
break
|
||||
}
|
||||
for len(s.arg) > 0 {
|
||||
if c := s.arg[len(s.arg)-1]; len(s.arg) == 1 || c != ' ' {
|
||||
s.arg = s.arg[:len(s.arg)-1]
|
||||
res += s.repeat(string(c))
|
||||
continue
|
||||
}
|
||||
break
|
||||
}
|
||||
s.cut = strings.TrimPrefix(arg, s.arg)
|
||||
res = s.rest(res)
|
||||
case CAN: // Ctrl+X
|
||||
case EM: // Ctrl+Y
|
||||
s.arg += s.cut
|
||||
res = s.rest(res + s.cut)
|
||||
case SUB: // Ctrl+Z
|
||||
case DEL:
|
||||
res = s.dels(res)
|
||||
case ESC: // Ctrl+[
|
||||
ctrl = c
|
||||
default:
|
||||
if ctrl == "" {
|
||||
if c == HT { // Ctrl+I
|
||||
if s.tip != "" {
|
||||
s.arg += s.app + s.tip
|
||||
res += s.app + s.tip
|
||||
s.app = ""
|
||||
break
|
||||
}
|
||||
}
|
||||
s.arg += c
|
||||
res = s.rest(res + c)
|
||||
break
|
||||
} else if ctrl == ESC && c == "[" {
|
||||
ctrl += c
|
||||
break
|
||||
} else if ctrl == ESC+"[" {
|
||||
switch c {
|
||||
case "A": // ArrowUp
|
||||
res = s.hist(res, -1)
|
||||
case "B": // ArrowDown
|
||||
res = s.hist(res, 1)
|
||||
case "C": // ArrowRight
|
||||
res = s.right(res)
|
||||
case "D": // ArrowLeft
|
||||
res = s.left(res)
|
||||
}
|
||||
}
|
||||
ctrl = ""
|
||||
}
|
||||
}
|
||||
s.w.Write([]byte(res))
|
||||
return len(data), nil
|
||||
}
|
||||
func (s iterm) Read(buf []byte) (int, error) {
|
||||
return s.r.Read(buf)
|
||||
}
|
||||
func (s iterm) Close() error { return nil }
|
||||
func (s iterm) style(style string, str string) string {
|
||||
return kit.Format("\033[%sm%s\033[0m", style, str)
|
||||
}
|
||||
func (s iterm) prompt() string {
|
||||
return kit.Format("%s%d[%s]$ ", CR+ESC_K, len(s.list), time.Now().Format("15:04:05"))
|
||||
}
|
||||
func (s iterm) repeat(str string, arg ...string) string {
|
||||
count := 0
|
||||
for _, c := range str {
|
||||
switch c {
|
||||
case '\t':
|
||||
count += 4
|
||||
default:
|
||||
count++
|
||||
}
|
||||
}
|
||||
return strings.Repeat(kit.Select(BS, arg, 0), count)
|
||||
}
|
||||
func (s iterm) left(res string) string {
|
||||
if n := len(s.arg); n > 0 {
|
||||
s.arg, s.app = s.arg[:n-1], s.arg[n-1:]+s.app
|
||||
res += BS
|
||||
}
|
||||
return res
|
||||
}
|
||||
func (s iterm) right(res string) string {
|
||||
if len(s.app) > 0 {
|
||||
s.arg, s.app = s.arg+s.app[:1], s.app[1:]
|
||||
res += ESC_C
|
||||
}
|
||||
return res
|
||||
}
|
||||
func (s iterm) dels(res string) string {
|
||||
if len(s.arg) > 0 {
|
||||
s.arg = s.arg[:len(s.arg)-1]
|
||||
res = s.rest(res + BS)
|
||||
}
|
||||
return res
|
||||
}
|
||||
func (s iterm) tips(arg string) (tip string) {
|
||||
if kit.HasSuffix(s.arg+s.app, lex.SP, nfs.PS) {
|
||||
s.args = s.m.CmdList(kit.Split(s.arg + s.app)...)
|
||||
s.due = CRNL + ESC_K + strings.Join(s.args, lex.SP)
|
||||
} else if len(s.args) > 0 {
|
||||
args, key := []string{}, kit.Select("", kit.Split(s.arg+s.app), -1)
|
||||
kit.For(s.args, func(arg string) { kit.If(strings.HasPrefix(arg, key), func() { args = append(args, arg) }) })
|
||||
s.due = CRNL + ESC_K + strings.Join(args, lex.SP)
|
||||
return strings.TrimPrefix(kit.Select("", args, 0), key)
|
||||
}
|
||||
for i := len(s.list) - 1; i >= 0; i-- {
|
||||
if v := s.list[i]; strings.HasPrefix(v, arg) {
|
||||
return strings.TrimPrefix(v, arg)
|
||||
}
|
||||
}
|
||||
for _, v := range s.cmds {
|
||||
if strings.HasPrefix(v, arg) {
|
||||
return strings.TrimPrefix(v, arg)
|
||||
}
|
||||
}
|
||||
return tip
|
||||
}
|
||||
func (s iterm) rest(res string) string {
|
||||
s.tip = s.tips(s.arg + s.app)
|
||||
return res + ESC_K + ESC_s + s.app + s.style("2", s.tip+s.due) + ESC_u
|
||||
}
|
||||
func (s iterm) exec(res string) string {
|
||||
res += CRNL
|
||||
arg := kit.Split(s.arg + s.app)
|
||||
if len(arg) == 0 {
|
||||
return res + s.prompt()
|
||||
} else if len(s.list) == 0 || s.arg+s.app != s.list[len(s.list)-1] {
|
||||
s.list = append(s.list, s.arg+s.app)
|
||||
s.pos = len(s.list)
|
||||
}
|
||||
defer func() { s.arg, s.app, s.due, s.args = "", "", "", []string{} }()
|
||||
msg := s.m.Cmd(arg, kit.Dict(ice.MSG_USERUA, "ish"))
|
||||
kit.If(msg.IsErrNotFound(), func() { msg = s.m.Cmd(cli.SYSTEM, arg) })
|
||||
kit.If(msg.Result() == "", func() { msg.TableEcho() })
|
||||
res += ESC_K + strings.ReplaceAll(msg.Result(), lex.NL, CRNL)
|
||||
kit.If(!strings.HasSuffix(res, CRNL), func() { res += CRNL })
|
||||
return res + s.prompt()
|
||||
}
|
||||
func (s iterm) hist(res string, skip int) string {
|
||||
res += s.repeat(s.arg) + ESC_K
|
||||
kit.If(s.pos == len(s.list), func() { s.bak = s.arg })
|
||||
for s.history(skip); s.pos < len(s.list); s.history(skip) {
|
||||
if strings.Contains(s.list[s.pos], s.bak) {
|
||||
s.arg, s.app = s.list[s.pos], ""
|
||||
res += s.list[s.pos]
|
||||
return res
|
||||
}
|
||||
}
|
||||
s.arg, s.app = s.bak, ""
|
||||
res += s.bak
|
||||
return res
|
||||
}
|
||||
func (s iterm) history(n int) { s.pos = (s.pos + n + len(s.list) + 1) % (len(s.list) + 1) }
|
||||
|
||||
// AEBF UKHD ITWY JMCZ NPRS LGVQ XO
|
||||
const (
|
||||
NUL = "\000"
|
||||
SOH = "\001" // Ctrl+A
|
||||
STX = "\002" // Ctrl+B
|
||||
ETX = "\003" // Ctrl+C
|
||||
EOT = "\004" // Ctrl+D
|
||||
ENQ = "\005" // Ctrl+E
|
||||
ACK = "\006" // Ctrl+F
|
||||
BEL = "\007" // Ctrl+G
|
||||
BS = "\010" // Ctrl+H
|
||||
HT = "\011" // Ctrl+I
|
||||
NL = "\012" // Ctrl+J
|
||||
VT = "\013" // Ctrl+K
|
||||
NP = "\014" // Ctrl+L
|
||||
CR = "\015" // Ctrl+M
|
||||
SO = "\016" // Ctrl+N
|
||||
SI = "\017" // Ctrl+O
|
||||
DLE = "\020" // Ctrl+P
|
||||
DC1 = "\021" // Ctrl+Q
|
||||
DC2 = "\022" // Ctrl+R
|
||||
DC3 = "\023" // Ctrl+S
|
||||
DC4 = "\024" // Ctrl+T
|
||||
NAK = "\025" // Ctrl+U
|
||||
SYN = "\026" // Ctrl+V
|
||||
ETB = "\027" // Ctrl+W
|
||||
CAN = "\030" // Ctrl+X
|
||||
EM = "\031" // Ctrl+Y
|
||||
SUB = "\032" // Ctrl+Z
|
||||
ESC = "\033" // Ctrl+[
|
||||
ESC_C = "\033[C"
|
||||
ESC_K = "\033[K"
|
||||
ESC_H = "\033[H"
|
||||
ESC_2J = "\033[2J"
|
||||
ESC_s = "\033[s"
|
||||
ESC_u = "\033[u"
|
||||
DEL = "\177"
|
||||
CRNL = "\r\n"
|
||||
)
|
@ -17,33 +17,39 @@ type Winsize struct {
|
||||
Y uint16 // ws_ypixel: Height in pixels
|
||||
}
|
||||
|
||||
type XTerm struct {
|
||||
type XTerm interface {
|
||||
Setsize(rows, cols string) error
|
||||
Writeln(data string, arg ...ice.Any)
|
||||
Write(data string) (int, error)
|
||||
Read(buf []byte) (int, error)
|
||||
Close() error
|
||||
}
|
||||
type xterm struct {
|
||||
*exec.Cmd
|
||||
*os.File
|
||||
}
|
||||
|
||||
func (s XTerm) Setsize(rows, cols string) error {
|
||||
func (s xterm) Setsize(rows, cols string) error {
|
||||
return Setsize(s.File, &Winsize{Rows: uint16(kit.Int(rows)), Cols: uint16(kit.Int(cols))})
|
||||
}
|
||||
func (s XTerm) Writeln(data string, arg ...ice.Any) {
|
||||
s.Write(kit.Format(data, arg...) + lex.NL)
|
||||
}
|
||||
func (s XTerm) Write(data string) (int, error) {
|
||||
return s.File.Write([]byte(data))
|
||||
}
|
||||
func (s XTerm) Close() error {
|
||||
return s.Cmd.Process.Kill()
|
||||
}
|
||||
func Command(m *ice.Message, dir string, cli string, arg ...string) (*XTerm, error) {
|
||||
func (s xterm) Writeln(data string, arg ...ice.Any) { s.Write(kit.Format(data, arg...) + lex.NL) }
|
||||
func (s xterm) Write(data string) (int, error) { return s.File.Write([]byte(data)) }
|
||||
func (s xterm) Read(buf []byte) (int, error) { return s.File.Read(buf) }
|
||||
func (s xterm) Close() error { return s.Cmd.Process.Kill() }
|
||||
|
||||
func Command(m *ice.Message, dir string, cli string, arg ...string) (XTerm, error) {
|
||||
if cli == "ish" {
|
||||
return newiterm(m)
|
||||
}
|
||||
cmd := exec.Command(cli, arg...)
|
||||
cmd.Dir = nfs.MkdirAll(m, kit.Path(dir))
|
||||
cmd.Env = append(cmd.Env, os.Environ()...)
|
||||
cmd.Env = append(cmd.Env, "TERM=xterm")
|
||||
pty, tty, err := Open()
|
||||
if err != nil {
|
||||
if pty, tty, err := Open(); err != nil {
|
||||
return nil, err
|
||||
} else {
|
||||
Setsid(cmd)
|
||||
cmd.Stdin, cmd.Stdout, cmd.Stderr = tty, tty, tty
|
||||
return &xterm{cmd, pty}, cmd.Start()
|
||||
}
|
||||
cmd.Stdin, cmd.Stdout, cmd.Stderr = tty, tty, tty
|
||||
Setsid(cmd)
|
||||
return &XTerm{cmd, pty}, cmd.Start()
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user