GithubHelp home page GithubHelp logo

michaelmacinnis / oh Goto Github PK

View Code? Open in Web Editor NEW
1.3K 40.0 55.0 2.11 MB

A new Unix shell.

License: MIT License

Go 100.00%
unix shell scheme language scripting-language command-line functional interpreter concurrent

oh's People

Contributors

klaidliadon avatar michaelmacinnis avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

oh's Issues

Add docs for simple usability features

I tried Oh, and it seems interesting. Certainly the programmability aspect is cool, and I like the idea of the type system. However, there's no documentation about how to customize anything (your prompt, for instance). I could read the source code, but I decided to try the shell on a whim at work, and I can't reasonably spend the time. I think it would be pretty easy to put together some guidance on how to perform basic operations like changing the prompt or the readline behavior, and it would make it easier for people like me to try things out comfortably.

If the above isn't supported yet, some docs indicating that would be just as good. ;P

It's a cool project though. I appreciate your hard work to improve the UNIX ecosystem!

Automated testing of job control features

There are currently no automated tests for oh's job control features. Automated, cross-platform (well cross-Unix anyway) tests with minimal dependencies would be nice.

Configuration examples

Hi
Thanks for your work
Can you provide configuration examples ? (prompt, alias, functions, etc.)

Thanks

Raphael

Please make a Release

Thanks for your work, I really like this concept!
I would like to use oh, and create a package for it for Void Linux (voidlinux.org).

I'd really appreciate if you could make some sort of release. Policy in the distro repository makes it difficult to commit a package build if there is no versioned release. There don't need to be binaries, Basically just a source tarball with a version number.

Thanks!

Command History Is not Saved

I realize this is more of a feature request than a bug, but I'd definitely call the lack of this feature an issue.

'unknown operand' on OS X

compilation is smooth, with libtecla installed. However, when invoking oh, it initially prints [: ]: unknown operand, and then the prompt '>'. What's worse, the 'script' mode does not work, in which the oh shell only prints the warning mentioned above, then exits.

I've used grep to see where the warning comes from. However the go src and oh do not contains this string.

I believe the warning is produced around the function engine.go/Evaluate.

btw, Linux does not have this issue.

build error

OS: Windows 10 64 bit
GO:1.5 64 bit

$ go get github.com/michaelmacinnis/oh
# github.com/michaelmacinnis/oh/pkg/task
..\michaelmacinnis\oh\pkg\task\os_windows.go:44: undefined: Cell

Better completion candidates

Depends on #30.

The method complete is currently called to allow completion candidates to be generated in oh. With more fine-grained control over the parser it should be possible to pass more detail to a completion hook. It should be possible to query, set and invoke the completion hook from a background task. Similar to the way import works.

Losing [my]self hacking oh :)

Hi! This all started when I wanted to reduce the noise of ... | while (define ln: readline) ...; so, I created a function abstraction to help the cause. (Yeah, yeah, I know: one person's noise is another person's music. :)

$ define mapl: method (f) = : while (define ln: readline): $f $ln

And in case f doesn't print/echo anything, but we want to use its value down the pipeline, there is a variant which prints f's images.

$ define maplp: method (f) = : while (define ln: readline): echo: $f $ln

Works look a charm!

$ echo rick michael | xargs -n1 | mapl: method (x) = : echo "-->" $x
--> rick
--> michael

The more common use case for me is that such a function is already defined, as so.

$ define echo-with-arrow: method (:args) = : echo "-->" @$args

Then, the pipeline works the same as before -- no surprises.

$ echo rick michael | xargs -n1 | mapl $echo-with-arrow
--> rick
--> michael

Now, here's where things start to get interesting: I needed a little caching mechanism that spied on items coming down that pipeline and "remembered" "seeing" those items. Here's what I used.

$ define things-seen: method () =: object {
$     define what-seen: list
$ 
$     export show: method self () = {
$         echo $self::what-seen
$     }
$     export seen-this?: method self (this) = {
$         member? $this $self::what-seen
$     }
$     export see-this: method self (this) = {
$         if (not: seen-this? $this) {
$             set $self::what-seen: cons $this $self::what-seen
$         }
$         return $this
$     }
$ }

Oh yeah, you're gonna need this dependency too (list membership predicate).

$ define member: method (x xs) = {
$     if (or (is-null $xs) (eq $x : xs::head)) {
$         return $xs
$     } else {
$         member $x : xs::tail
$     }
$ }
$ define member?: method (:args) = : boolean : member @$args

Here's a non-pipeline usage, to get an idea.

$ define seen: things-seen
$ seen::show
()
$ seen::see-this "rick"
$ seen::see-this "michael"
$ seen::show
"michael" "rick"

Now, when we stick it in the pipeline with mapl, we'll see some sparks flying. :)

$ echo rick michael | xargs -n1 | maplp $seen::see-this
xargs: /bin/echo: terminated with signal 13; aborting
issue-minimal-example.oh: 25: error/runtime: 'what-seen' undefined

Oops. It's as if we are losing track of that "slot" in the object -- actually, I think we've lost the self reference somehow, but that's just a guess.

Replacing mapl with what it's supposed to do, all is right again.

$ echo rick michael | xargs -n1 | while (define ln: readline): echo: $seen::see-this $ln
rick
michael

(BTW, I checked that the caching was also happening. :)

So, what am I doing wrong?

Here's the code all in one place to plop into a file, for convenience. Thanks! --Rick

define mapl: method (f) = : while (define ln: readline): $f $ln

define maplp: method (f) = : while (define ln: readline): echo: $f $ln

define member: method (x xs) = {
    if (or (is-null $xs) (eq $x : xs::head)) {
        return $xs
    } else {
        member $x : xs::tail
    }
}
define member?: method (:args) = : boolean : member @$args

define things-seen: method () =: object {
    define what-seen: list

    export show: method self () = {
        echo $self::what-seen
    }
    export seen-this?: method self (this) = {
        member? $this $self::what-seen
    }
    export see-this: method self (this) = {
        if (not: seen-this? $this) {
            set $self::what-seen: cons $this $self::what-seen
        }
        return $this
    }
}

define echo-with-arrow: method (:args) = : echo "-->" @$args

# These both give same output (of course).
# $ echo rick michael | xargs -n1 | mapl: method (x) = : echo "-->" $x
# $ echo rick michael | xargs -n1 | mapl $echo-with-arrow

# Make an instance of things-seen (for use in the next two pipeline commands).
# $ define seen: things-seen

# This blows up.
# $ echo rick michael | xargs -n1 | maplp $seen::see-this

# This doesn't.
# $ echo rick michael | xargs -n1 | while (define ln: readline): echo: $seen::see-this $ln

Prompt configuration

Hi, I would like to use oh and having a configurable prompt is a must to me. What do you think?

I did some changes to the code and added the current directory to the "prompt":

oh > cd ~
bpinto > cd ~/src/
src >

Ideally, this would be configurable and colourful. :)

Member access syntax is too noisy

I know this is bike-shedding, but I think using double colons for member access syntax is too noisy in combination with the single colon syntax. Compare this:

set self::x: add self::x a

to this:

set self.x: add self.x a

The latter is much more readable to me, even as someone used to using :: in other languages, and I propose making it the new syntax.

(P.S. Great project, I think mashing scheme and bash together is the best approach to a glue language that I've seen.)

String status type

Oh has a status type to solve the zero exit status is true / non-zero exit status is false mismatch. On Plan 9, processes return a string status. Currently, oh's status type is a string type on Plan 9 and an integer type on other platforms. Instead of the status type behaving differently on different platforms, both the integer and string status types should be available on all platforms. Just need a name for the string status type...

Clarify POSIX / nonPOSIX compliance

Thanks for uploading oh shell! Incidentally, is oh POSIX compliant? In other words, would oh work as a substitute for /bin/sh, or is oh really different?

Build problem; quoting syntax crash

1st:

(earth)% go build .
# _/home/mb/src/oh
./cell.go:1659: unknown syscall.SysProcAttr field 'Sigdfl' in struct literal
./cell.go:1663: attr.Sys.Foreground undefined (type *syscall.SysProcAttr has no field or method Foreground)
./cell.go:1665: attr.Sys.Joinpgrp undefined (type *syscall.SysProcAttr has no field or method Joinpgrp)

(I comment them out, so it's likely that it cause pipes to sometimes fail)

2nd: (may i suggest to copy rc's quoting mechanism? it makes everything much simple
than eg. with bash. also, rc's pipelines are neat, but that's another story ;-))

(earth)% ./oh 
> "
> "
panic: runtime error: index out of range

goroutine 1 [running]:
runtime.panic(0x813d3e0, 0x827a2d7)
        /home/mb/go/src/pkg/runtime/panic.c:266 +0x9a
main.(*scanner).Lex(0x185ac240, 0x185b2160, 0x0)
        /home/mb/src/oh/parser.y:410 +0x887
main.yylex1(0xb75cdb80, 0x185ac240, 0x185b2160, 0x1)
        /home/mb/src/oh/yaccpar:33 +0x3c
main.yyParse(0xb75cdb80, 0x185ac240, 0x8)
        /home/mb/src/oh/yaccpar:106 +0x4217
main.Parse(0xb75cef40, 0x1855c170, 0x8182bd4)
        /home/mb/src/oh/parser.y:465 +0xbe
main.main()
        /home/mb/src/oh/main.go:1705 +0x273c

goroutine 3 [syscall]:
os/signal.loop()
        /home/mb/go/src/pkg/os/signal/signal_unix.go:21 +0x1e
created by os/signal.init·1
        /home/mb/go/src/pkg/os/signal/signal_unix.go:27 +0x31

goroutine 4 [chan receive]:
main.monitor(0x1851c1b0, 0x1851c1e0)
        /home/mb/src/oh/monitor.go:31 +0x30
created by main.init·2
        /home/mb/src/oh/monitor.go:26 +0xa2

goroutine 5 [select]:
main.registrar(0x1851c1b0, 0x1851c1e0)
        /home/mb/src/oh/monitor.go:64 +0x1d2
created by main.init·2
        /home/mb/src/oh/monitor.go:27 +0xbf

goroutine 6 [syscall]:
runtime.goexit()
        /home/mb/go/src/pkg/runtime/proc.c:1394

goroutine 7 [chan receive]:
main.func·011()
        /home/mb/src/oh/main.go:364 +0x44
created by main.listen
        /home/mb/src/oh/main.go:385 +0x11e

goroutine 8 [select]:
main.func·108()
        /home/mb/src/oh/main.go:1454 +0xcb
created by main.main
        /home/mb/src/oh/main.go:1507 +0x253d

goroutine 9 [finalizer wait]:
runtime.park(0x807abc0, 0x8287efc, 0x827b6a8)
        /home/mb/go/src/pkg/runtime/proc.c:1342 +0x59
runfinq()
        /home/mb/go/src/pkg/runtime/mgc0.c:2279 +0x78
runtime.goexit()
        /home/mb/go/src/pkg/runtime/proc.c:1394

Oh returns error on Windows 10 (x64)

When I tried to get latest version on Oh on my Windows 10 machine with x64 arch. First it asked me to enable 'object type list' flag needed by the OH utility and execute 'oh -otl' command to enable it. That will take effect next time you boot.

So after rebooting, I tried to access 'oh' via command-line but it returned

> oh
RtlAdjustPrivilege(SE_DEBUG) failed with status = C0000061. -u may not work.//
// TIME: 2018-06-19 16:51
// MACHINE: LP-5CD7436N0Z
// BUILD: 9200
// OH version:  built by: dnsrv_dev(v-smgum)
//
//

followed by some kind of dump.

Then I tried to open the command-line using 'Run as administrator' but again got

> oh
//
// TIME: 2018-06-19 16:55
// MACHINE: LP-5CD7436N0Z
// BUILD: 9200
// OH version:  built by: dnsrv_dev(v-smgum)
//
//

followed by some kind of dump.

Although 'oh -help' command works and displays all the switches/options available and returns

> oh -help
oh - Object handles dump -- built by: dnsrv_dev(v-smgum)
Copyright (c) Microsoft Corporation. All rights reserved.

OH [DUMP_OPTIONS ...]
OH [FLAGS_OPTIONS ...]
OH -c [COMPARE_OPTIONS ...] BEFORE_LOG AFTER_LOG

DUMP_OPTIONS are:

    -p N - displays only open handles for process with ID of n. If not
           specified perform a system wide dump.
    -t TYPENAME - displays only open object names of specified type.
    -o FILENAME - specifies the name of the file to write the output to.
    -a includes objects with no name.
    -s display summary information
    -h display stack traces for handles (a process ID must be specified)
    -u display only handles with no references in process memory
    -v verbose mode (used for debugging oh)
    NAME - displays only handles that contain the specified name.

FLAGS_OPTIONS are:

    [+kst|-kst] - enable or disable kst flag (kernel mode stack traces).
    [+otl|-otl] - enable or disable otl flag (object lists).

The `OH [+otl] [+kst]' command can be used to set the global flags
needed by OH. `+otl' is needed for all OH options and `+kst' is needed
by the `-h' option. The changes will take effect only after reboot.
The flags can be disabled by using `-otl' or `-kst' respectively.

COMPARE_OPTIONS are:

    -l     Print most interesting increases in a separate initial section.
    -t     Do not add TRACE id to the names if files contain traces.
    -all   Report decreases as well as increases.

If the OH files have been created with -h option (they contain traces)
then handle names will be printed using this syntax: (TRACEID) NAME.
In case of a potential leak just search for the TRACEID in the original
OH file to find the stack trace.

No `command` equivalent

Without a command builtin, it's impossible to emulate this line of sh:

alias rm='rm -i'

I would expect the following bit of code to work:

define rm: method (: args) as {
    command rm -i @args
}

How to make bindshell environment work after dup2(new_sockfd, 0) ?

In this bindshell https://github.com/deadbits/shells/blob/master/bindshell.c I try to simple replace /bin/bash to /bin/oh
got unexpected error. After a little debug. I change to execl(SHELL, "main", "--interactive");
It still can't work.

after I remove err = process.BecomeForegroundGroup()
I still got inappropriate ioctl for device
I want to ask about the question. Is it possible to use oh in the bindshell environment after

        dup2(new_sockfd, 2);
        dup2(new_sockfd, 1);
        dup2(new_sockfd, 0);

and transmitted and executed in different environments

In your BSDCan 2018 talk, I think there was some sort of throwaway line about using the FEXPRs and environments such that you transmitted an AND and executed it in the receiving environment.

Is that written down and documented somewhere?

Thanks.

Fail to install: "sys.Foreground undefined" and "sys.Joinpgrp undefined"

So when I attempt to install Oh, I get this error:

code/go/src/github.com/michaelmacinnis/oh/unix.go:137: sys.Foreground undefined (type *syscall.SysProcAttr has no field or method Foreground)
code/go/src/github.com/michaelmacinnis/oh/unix.go:139: sys.Joinpgrp undefined (type *syscall.SysProcAttr has no field or method Joinpgrp)

Does this have to do with the syscall.SysProcAttr type not having the specified attributes? If so, what's this supposed to be doing? Also, if you need this:

$ go version
go version go1.3.3 linux/amd64

openbsd amd64 ls

I am running oh shell on a Dell Optiplex 990 on openbsd 6.8 amd64. Regardless whether I install OH through the amd64 binary or through go, I get the following result when I attempt to issue the ls command:

root@openbsd:/root/go/bin>ls -l
total 7744
-rwxr-xr-x 1 root wheel 3947543 Feb 8 14:12 oh
root@openbsd:/root/go/bin>./oh
[email protected]:/go/bin: ls
ls: unknown option -- -
usage: ls [-1AaCcdFfgHhikLlmnopqRrSsTtux] [file ...]
[email protected]:
/go/bin: ls -l
ls: unknown option -- -
usage: ls [-1AaCcdFfgHhikLlmnopqRrSsTtux] [file ...]
[email protected]:~/go/bin:

I am able to use ls appropriately on Opensuse Linux.

exits abruptly?

Not sure if this is by design or not -- could just be a misunderstanding of intended behaviour. While experimenting with the syntax, I noticed that a simple string ending with a colon drops me out of the shell. e.g. "x:"

Syntactic issues suggestions, some based on rc

In no particular order:

  1. The ability to redirect file descriptors other than 0, 1, 2 is not often used but is important to have when constructing graphs (as opposed to pipelines) of commands. I think the rc syntax <[3]foo.bar is better than the Posix syntax 3<foo.bar.

  2. You need to say what characters are allowed in a variable name without braces. Also, it seems like variable references are only allowed inside double quotes, which strikes me as an unnecessary restriction. I see no problem with allowing echo $foo as well as echo "$foo".

  3. Your quote system is too messy and Posixy. I suggest adopting the rc system, which is this: single-quoted text can run over lines and has only one escape, namely doubled single-quote for a single-quote. Double quotes aren't used. That turns your example echo "xx**\"**xx" into echo 'xx**''**xx. In combination with bare variable interpolation, you can then say 'Hello, '$username', welcome to the system.', which passes just one argument to echo.

  4. I like >! better than>! since ! is well understood as "do something destructive". If you want a filename beginning with !, insert a space.

  5. Your remark "This avoids inadvertent matching of the names . and .. which mean the current directory and the parent directory, respectively." does not seem to be true of the pattern .*. I always end up writing .[a-zA-Z] instead. It might be good if globs never match . or ...

  6. Brace expansion is very handy, and you can distinguish it from C-type braces by requiring the latter to be surrounded by whitespace, as they usually are. So echo {a,b}{c,d} outputs ac ad bc bd. This is not a must.

  7. Your syntax command provides unhygienic macros, which will bite users in the butt eventually. The hard part is making sure that names get the bindings in the macro body that are those available where the macro was defined, not where it was called.

Please release `oh` binaries (like many Go projects do)

First: thank you for putting this quite interesting bash alternative out there! To foster more adoption I would suggest to generate ready platform specific binaries, so it would be much simpler to test oh without having to install the Golang toolchain.

To simplify it, one could use Goreleaser

Cheers,
Roman

Where should I start?

I like this project. Do you have any pointers or suggestions on how to get started with this? I've read TTY Demystified a couple of times, but I am still lacking in tons of foundational concepts. Yet, I would like to contribute to this project.

Answering to any of the following questions would help:

  1. Where to start reading your code?
  2. Where should I focus first?
  3. What are the tricky parts I should try to get out of the way first?

I've been dabbling with bash and fish for a while and I've come to love fish's orthogonality and terseness, while at the same time I've grown fond of bash crypticness. Oh, I want to try this one too.

not finding libtecla.so.1

Trying out oh, but despite apparently successful builds of libtecla and go-tecla, oh returns the following error when executed (oh also builds):

./oh

./oh: error while loading shared libraries: libtecla.so.1: cannot open shared object file: No such file or directory

libtecla.so.1 is present:

locate libtecla.so.1

/usr/local/lib/libtecla.so.1
/usr/local/lib/libtecla.so.1.6.1
/usr/local/src/libtecla-1.6.1/libtecla.so.1
/usr/local/src/libtecla-1.6.1/libtecla.so.1.6.1

Checked out commit of oh is 4a0e6ae.

6g -V

6g version release.r57.1 8340+

Any suggestions?

installation instructions need update. cli output of version silently fails.

go get: installing executables with 'go get' in module mode is deprecated.
Use 'go install pkg@version' instead.
For more information, see https://golang.org/doc/go-get-install-deprecation
or run 'go help get' or 'go help install'.

As I understand it, the package needs semver defined somewhere, if one does not install from within a source folder with go install.

Related: ./oh -v and ./oh --version dont return the version number.

comparison with choc

Thank you for this very interesting project!

Is there a detailed comparison anywhere of oh with choc (as defined in your Masters thesis)? Just for example, does oh have a built-in clone operation?

Better Task type

Oh is currently ~ 8000 lines of code. Almost 3000 of those are in task.go. It would be nice if the Task type could be made more modular. Job control features in particular were added as an afterthought and currently work because of a combination of fine-grained locking, the go race detector, and dumb luck.

doc examples yield operation not permitted

example from the docs produces an error

> who; date
jasona   console  Sep 15 13:06 
jasona   ttys000  Sep 18 20:37 
jasona   ttys001  Sep 15 13:14 
jasona   ttys002  Sep 15 13:14 
jasona   ttys003  Sep 18 21:13 
jasona   ttys004  Sep 18 21:27 
jasona   ttys005  Sep 16 14:34 
jasona   ttys006  Sep 18 17:38 
oh: fork/exec /bin/date: operation not permitted
> date
Thu Sep 18 23:42:26 PDT 2014
> date; who
Thu Sep 18 23:42:49 PDT 2014
oh: fork/exec /usr/bin/who: operation not permitted
> 

Two small issues when goinstall'ing oh

Hello,
I faced this:

goinstall -u -v github.com/michaelmacinnis/oh

6g -I "/home/fgudin/go/pkg/linux_amd64" -o go.6 engine.go main.go cell.go parser.go
engine.go:192: too few values in struct initializer
engine.go:1906: too many arguments in call to strings.Split
make: *** [go.6] Erreur 1
--- exit status 2

gofix «fixed stringssplit» and adding a nil as Sys *syscall.SysProcAttr in os.ProcAttr to the call of os.StartProcess seem to fix it:
diff --git a/engine.go b/engine.go
index eace71e..e2049ad 100644
--- a/engine.go
+++ b/engine.go
@@ -189,7 +189,7 @@ func external(p *Process, args Cell) bool {
wpipe(Resolve(p.Lexical, p.Dynamic, NewSymbol("$stdout")).GetValue()),
wpipe(Resolve(p.Lexical, p.Dynamic, NewSymbol("$stderr")).GetValue()))

  • proc, err := os.StartProcess(name, argv, &os.ProcAttr{dir, nil, fd})
  • proc, err := os.StartProcess(name, argv, &os.ProcAttr{dir, nil, fd, nil})
    if err != nil {
    panic(err)
    }
    @@ -1903,7 +1903,7 @@ func Start() {

/* Environment variables. */
for _, s := range os.Environ() {

  •    kv := strings.Split(s, "=", 2)
    
  •    kv := strings.SplitN(s, "=", 2)
     e.Add(NewSymbol("$" + kv[0]), NewSymbol(kv[1]))
    

Thanks for oh'l !
Best regards,

Hitting tab can cause panic

This is great, I've been looking for a functional alternative shell to try for a while!

Here is a small bug report.

I've tried to type cd /<tab> and this is what I got:

> oh
foo> cd /panic: runtime error: invalid memory address or nil pointer dereference
[signal 0xb code=0x1 addr=0x20 pc=0xa86e7]

goroutine 1 [running]:
panic(0x1f1c40, 0xc82000a140)
    /Users/ilya/Library/Local/Homebrew/Cellar/go/1.6/libexec/src/runtime/panic.go:464 +0x3e6
github.com/michaelmacinnis/oh/pkg/ui.files.func1(0xc8203440a0, 0x9, 0x0, 0x0, 0x3fd7d8, 0xc8201dd080, 0x0, 0x0)
    /Users/ilya/Code/.gopath/src/github.com/michaelmacinnis/oh/pkg/ui/ui.go:233 +0xe7
path/filepath.walk(0xc8204a1f60, 0x7, 0x40beb8, 0xc8203f1520, 0xc8201885d8, 0x0, 0x0)
    /Users/ilya/Library/Local/Homebrew/Cellar/go/1.6/libexec/src/path/filepath/path.go:370 +0x415
path/filepath.walk(0xc82047edec, 0x4, 0x40beb8, 0xc820201380, 0xc8201885d8, 0x0, 0x0)
    /Users/ilya/Library/Local/Homebrew/Cellar/go/1.6/libexec/src/path/filepath/path.go:374 +0x4fc
path/filepath.walk(0xc8204bab44, 0x2, 0x40beb8, 0xc820068a90, 0xc8201885d8, 0x0, 0x0)
    /Users/ilya/Library/Local/Homebrew/Cellar/go/1.6/libexec/src/path/filepath/path.go:374 +0x4fc
path/filepath.Walk(0xc8204bab44, 0x2, 0xc8201885d8, 0x0, 0x0)
    /Users/ilya/Library/Local/Homebrew/Cellar/go/1.6/libexec/src/path/filepath/path.go:396 +0xe1
github.com/michaelmacinnis/oh/pkg/ui.files(0xc8204bab3b, 0x1, 0x0, 0x0, 0x0)
    /Users/ilya/Code/.gopath/src/github.com/michaelmacinnis/oh/pkg/ui/ui.go:263 +0x7e7
github.com/michaelmacinnis/oh/pkg/ui.complete(0xc8204bab38, 0x4, 0x4, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0)
    /Users/ilya/Code/.gopath/src/github.com/michaelmacinnis/oh/pkg/ui/ui.go:130 +0xa31
github.com/peterh/liner.(*State).tabComplete(0xc8200a4000, 0xc820188c20, 0x9, 0x9, 0xc82049e030, 0x4, 0x4, 0x4, 0x0, 0x0, ...)
    /Users/ilya/Code/.gopath/src/github.com/peterh/liner/line.go:348 +0x165
github.com/peterh/liner.(*State).PromptWithSuggestion(0xc8200a4000, 0xc8204baad0, 0x9, 0x0, 0x0, 0x4, 0x0, 0x0, 0x0, 0x0)
    /Users/ilya/Code/.gopath/src/github.com/peterh/liner/line.go:803 +0x2e00
github.com/peterh/liner.(*State).Prompt(0xc8200a4000, 0xc8204baad0, 0x9, 0x0, 0x0, 0x0, 0x0)
    /Users/ilya/Code/.gopath/src/github.com/peterh/liner/line.go:567 +0x6c
github.com/michaelmacinnis/oh/pkg/ui.(*cli).ReadString(0xc82002e028, 0x27f70a, 0x0, 0x0, 0x0, 0x0)
    /Users/ilya/Code/.gopath/src/github.com/michaelmacinnis/oh/pkg/ui/ui.go:88 +0x39b
github.com/michaelmacinnis/oh/pkg/parser.(*scanner).Lex(0xc8200aa480, 0xc8200b82c0, 0x0)
    /Users/ilya/Code/.gopath/src/github.com/michaelmacinnis/oh/pkg/parser/parser.go:112 +0x1a6
github.com/michaelmacinnis/oh/pkg/parser.yylex1(0x3fd928, 0xc8200aa480, 0xc8200b82c0, 0xc8200b82c0, 0x0)
    yaccpar:119 +0x52
github.com/michaelmacinnis/oh/pkg/parser.(*yyParserImpl).Parse(0xc8200b82c0, 0x3fd928, 0xc8200aa480, 0x0)
    yaccpar:208 +0x6307
github.com/michaelmacinnis/oh/pkg/parser.yyParse(0x3fd928, 0xc8200aa480, 0x1dcf20)
    yaccpar:153 +0x9b
github.com/michaelmacinnis/oh/pkg/parser.(*parser).Parse(0xc82002e020, 0x40bf08, 0xc82002e028, 0x3fd8f0, 0xc8200b4000, 0x22e390, 0x2, 0x27fa00, 0x40bf08)
    /Users/ilya/Code/.gopath/src/github.com/michaelmacinnis/oh/pkg/parser/parser.go:356 +0x1a6
github.com/michaelmacinnis/oh/pkg/parser.(*parser).Parse-fm(0x40bf08, 0xc82002e028, 0x3fd8f0, 0xc8200b4000, 0x22e390, 0x2, 0x27fa00, 0xc820011601)
    /Users/ilya/Code/.gopath/src/github.com/michaelmacinnis/oh/main.go:32 +0x69
github.com/michaelmacinnis/oh/pkg/task.Start(0xc82000b400, 0x3fd800, 0xc82002e028)
    /Users/ilya/Code/.gopath/src/github.com/michaelmacinnis/oh/pkg/task/task.go:1819 +0x109e
main.main()
    /Users/ilya/Code/.gopath/src/github.com/michaelmacinnis/oh/main.go:32 +0xf9

undefined: syscall.SYS_IOCTL (build fails on Solaris)

$ go get -u -v github.com/michaelmacinnis/oh

github.com/michaelmacinnis/oh (download)
github.com/michaelmacinnis/adapted (download)
Fetching https://golang.org/x/sys/unix?go-get=1
Parsing meta tags from https://golang.org/x/sys/unix?go-get=1 (status code 200)
get "golang.org/x/sys/unix": found meta tag main.metaImport{Prefix:"golang.org/x/sys", VCS:"git", RepoRoot:"https://go.googlesource.com/sys"} at https://golang.org/x/sys/unix?go-get=1
get "golang.org/x/sys/unix": verifying non-authoritative meta tag
Fetching https://golang.org/x/sys?go-get=1
Parsing meta tags from https://golang.org/x/sys?go-get=1 (status code 200)
golang.org/x/sys (download)
github.com/peterh/liner (download)
github.com/michaelmacinnis/oh/pkg/system
# github.com/michaelmacinnis/oh/pkg/system

go/src/github.com/michaelmacinnis/oh/pkg/system/os_unix.go:49: undefined: syscall.SYS_IOCTL
go/src/github.com/michaelmacinnis/oh/pkg/system/os_unix.go:56: undefined: syscall.SYS_IOCTL
go/src/github.com/michaelmacinnis/oh/pkg/system/os_unix.go:83: undefined: syscall.Getpgrp

Rewrite parser/lexer

The current parser is generated using ohyacc, a version of goyacc that has been modified to allow:

  • The lexer to trigger the parser to exit abnormally (Ctrl-C pressed).
  • The parser to restart with a clear state for each command.

Additionally the lexer/parser have been hacked at to allow a partial parse in order to generate better completion candidates.

This works but a hand-written parser and a lexer that doesn't have to work around the constraints imposed by yacc would allow for more fine-grained control and, hopefully, less convoluted code.

Handling URLs

URLs get parsed as commands (i.e. protocol://blahblah is interpreted as protocol (//blahblah)), which is a bit awkward when writing curl/git/ssh/scp commands. Is it reasonable to parse something like 'http://blahblahblah' as a symbol, and only make it a command when there's a space following the colon? i.e. 'http: //blahblahblah' uses a command called HTTP.

Alternatively, URLs could be matched as their own data type (which might be nice since oh has a stronger type system than most shells). Or the ':' shorthand could be replaced with another symbol like '$' a la ocaml or '@' a la haskell (though it would still have to be surrounded with spaces since scp/mail use @)?

I know that you can wrap it in quotes to make it a string, but URLs are extremely prevalent in shell commands, so wrapping them all in quotes can get tedious.

patch

I'm curious about the patching of exec_linux.go. Is it something that should be submitted to the go maintainers so it becomes a part of the mainline distribution? I would tend to think that a very favorable argument could be made if this is necessary for writing a shell in go.

augmenting built in command behaviour (cd)

While working on my dot files I got trouble trying to augment cd behavior. For reference here is my progress:

bash version: https://github.com/gdiazlo/acme/blob/master/profile
oh version: https://github.com/gdiazlo/acme/blob/master/ohrc

I need to execute an additional command on each cd, only if I'm inside my editor terminal (basically when TERM=dumb)

I tried something like:

define cd: method(:args) = {
	builtin cd @$args
	if (eq $TERM dumb) {
		command awd
	}
}

But the builtin usage is wrong.
I also tried something like:

define acd: method(:args) = {
	cd @$args
	if (eq $TERM dumb) {
		command awd
	}
  }

But when acd returns, the current directory remains unchanged.

What would be the way to change or augment the behavior of a builtin command?

I had a look at boot.oh, but still I can't figure out how to do it.

Compilation failed in OS X

Hi,

I've been trying for a couple of hours to compile oh without much success:

# github.com/michaelmacinnis/oh
./cell.go:1663: unknown syscall.SysProcAttr field 'Sigdfl' in struct literal
./cell.go:1667: attr.Sys.Foreground undefined (type *syscall.SysProcAttr has no field or method Foreground)
./cell.go:1669: attr.Sys.Joinpgrp undefined (type *syscall.SysProcAttr has no field or method Joinpgrp)

Clearly the missing parts are in the exec_linux.go file but it has a build constraint. Even if I remove it, it wont work. I cannot find a way to make sure this is being included during compilation (it seems like it's not). I just cannot find any place saying how to use patches of the core golang syscall when compiling. :(

Any help is appreciated! Thanks

What do you think of this project, I think I could use OH to make it super powerful

https://github.com/Fransebas/sssh_distribution

It's basically a graphic interface for a shell, I know it sounds contradictory but the idea is to help new people that are starting to learn how to use shells and people that are not computer scientist to use a shell.

The GUI helps with some commands that people don't born knowing and I just add the ability to add new interfaces.

OH could really help me because I had to find hacks for a lot of things that are not normally exposed on other shells for example getting and modifying the history in real time, updating the cwd, I tried but couldn't modify the environment variables from the GUI and I think that modifying the OH's code I could make amazing things, for example I could expose to the server as many things as needed for both reading and writing (like the env variables, cwd, history, etc), the shell would automatically send all the require data every time is updated without needing to put expensive hooks that have to be parse instead of being written directly in the shell code.

I would like to hear you opinion on the topic, OH is an amazing project.

readme: why to use? highlight pain points of bash, where oh shines and where not

why to use (and not bash)?

  1. how to use lists instead of the painful IFS or heredoc.
  2. no second prompt, I guess?!
  3. No ${var} to prevent $var from being expanded with $va + r
  4. No ${var[?|-|+|=]} to handle undefined values or null.

why not to use? (assuming the worst possible answer due to missing docs)

  1. No documentation on how multiple files can be used and what constrains/introspection of call history is possible (or if the same limitations as POSIX shell apply, ie no tracking of how and from where a script was called and a pile of other stuff.
  2. create file1 and file2 with setting different variable. Reusing those variables within file3 is cumbersome (either need to be exported or each variable transferred).
  3. (quite unfair, but for reusing efficient programs) It remains unclear, how to utilize faster programs or other languages for (frequent) computing of arithmetic stuff/data mutation.

Personally I think a shell should be a REPL with hacking convenience(piping, path hackery, job control) and control flow introspection, which includes to me leveraging external programs to compute stuff similar how "cyclic scanning mode" works (have the option to kill program used for externalizing execution after timeout).
Unfortunately shells need weird quirks to reuse program results for 3, even though (unless in superuser mode) a program execution may hijack shell sessions leading to no significant security gains on separation.

Any thoughts from you?

Collaboration with Elvish project?

There is another modern shell, written in Go: https://elv.sh
It seems to me more mature, and also has very good ideas.
I don't see any advantages of having two shells developed independently, both are written in Go, with similar ideas, and both lacking developers. What do you think merging the ideas from one shell to the other, and developing it together with @xiaq?

support / ignore -i flag

Some programs execute shells expecting the -i flag to instruct the shell to go into interactive mode. Can oh be instructed to ignore such flag?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.