• Stars
    star
    372
  • Rank 114,858 (Top 3 %)
  • Language
    C
  • License
    MIT License
  • Created over 5 years ago
  • Updated almost 5 years ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

A powerful new shell that uses the janet programming language for both the implementation and repl.

Janetsh

Gitter

Website

Mailing list

CI

A new system shell that uses the Janet programming language for high level scripting while also supporting the things we love about sh.

Minimal knowledge of janet is required for basic shell usage, but know that as you become more familiar with janet, your shell will gain the power of:

  • A powerful standard library.
  • Functional and imperative programming.
  • Powerful lisp macros.
  • Runtime loadable extension modules written in C/C++/rust/zig...
  • Coroutines and exceptions.
  • Much much more.

Help develop janetsh donate via paypal

Status

Janetsh development has slowed and I am not actively working on it for now. Some of it is no longer compatible with the latest janet release.

That being said, I consider janetsh a successful proof of concept and place to draw code and ideas from whenever the next attempt at fixing shells gets my attention.

One potential avenue for janetsh2 in the future is to integrate janet syntax with the shell library:

https://github.com/emersion/mrsh

If we do this, we can have POSIX compatibility when we need it, as well as avoid implementing most of the complexity in a shell, and can instead focusing on delivering on the important ideas of janetsh.

See it in action

asciicast

demo source code demo rc file

Examples

Basic shell usage

As you would expect:

$ ls -la | head -n 3
total 100
drwxr-xr-x 1 ac users   220 May 13 20:16 .
drwxr-xr-x 1 ac users   760 May 12 21:08 ..
0

$ echo foo > /dev/null
0

$ sleep 5 &
@{:pgid 82190 :procs @[@{:args @["sleep" "5"]
      :pid 82190
      :stopped false
      :redirs @[]}]}

$ rm ./demos/*.gif
0

Functional programming

$ (map string/ascii-upper ["functional" "programming"])
@["FUNCTIONAL" "PROGRAMMING"]

$ (defn lines [s] (string/split "\n" s))
<function lines>

$ (lines ($$ ls | head -n 3))
@["build.sh" "demos" "janetsh" ""]

$ echo (reduce + 0 [1 2 3])
6
0

Command capture

$ (string/ascii-upper ($$ echo command string capture))
"COMMAND STRING CAPTURE\n"

$ ($$_ echo trimmed capture)
"trimmed capture"

$ (if (= 0 ($? touch /tmp/test.txt)) "success")
"success"

$ (if ($?? touch /tmp/test.txt) "shorthand success")
"shorthand success"

Exceptions/Errors

$ (try
    (do
      ($ rm foo.txt)
      ($ rm bar.txt)
      ($ rm baz.txt))
    ([err] (print "got an error:" err)))

Mixing janet code and shell commands

$ (each f files (sh/$ wc -l [f]))

Subshells

$ ls | head -n 3 | (out-lines string/ascii-upper)
BUILD.SH
DEMOS
JANETSH
0

Reference Documentation

Hopefully in the future this sparse reference set will become more polished, but for now the following snippets may help advanced users play with the shell in it's current state.

RC files

Janetsh runs a user rc script ~/.janetsh.rc at startup when in interactive mode. This file can changed or disabled via command line flags.

Janetsh runs /etc/janetsh.rc on any run if it exists. This file can be changed or disabled via command line flags.

Custom prompts

Users can set a custom prompt:

(set *get-prompt* (fn [p] "$ "))

p is a janet standard library parser, which can be used to find the current repl nesting level.

Custom line completions

Users can set a custom line completion function:

(set *get-completions*
  (fn [line word-start word-end]
    @["your-completion"]))

History file

By default janetsh does not store any history to avoid accidental information leaks.

To enable history add the following line to your janet rc file:

(set *hist-file* (first (sh/expand "~/.janetsh.hist")))

Job control

A list of running jobs can be found in the variable sh/jobs, each of which is a janet table containing the current state of a user job/pipeline.

The sh package has some functions for manipulating jobs, such as putting them in the foreground, or terminating them. This is not a stable interface for now, so you will need to read the code yourself for documentation.

Some examples:

vim
...
Ctrl+Z
$ (sh/fg-job (first sh/jobs))
...
Ctrl+Z
$ sleep 60 &
$ (sh/terminate-all-jobs)
$ (sh/disown-job (sh/$ sleep 60 &))

Custom builtin shell commands

Here is an example of defining a new builtin shell command.

(defn- make-my-builtin
  []
  @{
    :pre-fork
      (fn pre-fork
        [self args]
        (print "hello from shell process"))
    :post-fork
      (fn post-fork
        [self args]
        (print "hello from child process"))
  })

(put sh/*builtins* "my-builtin" make-my-builtin)

It is important to catch any errors and only report them from the child process. This means builtins can manipulate the shell internal state, but still behave like regular processes for the purpose of exit codes, pipes and job control.

Installation

For the default build you will need pre released janet 1.0.0 built from source, readline and pkg-config installed on your system, then you can run:

./configure && make install

If you want libedit instead of readline you can build with:

./configure --with-pkg-config-libedit

If you don't want to depend on readline or libedit, you can use the bundled emulation.

./configure --with-readnoise

You can also manually specify header paths, install paths and flags.

Try ./configure --help for a list of options.

Janetsh Internals

Internally janetsh is implemented as a low level C library for the janet programming language, a janet library and a small launcher that does some necessary setup/teardown.

The janet main implementation is a set of janet functions and macros that perform shell job control, control user input and manage your command pipelines.

At the highest level the user is presented with an interactive repl interface which implicitly invokes a janet macro to give janet the familiar sh syntax. You can escape this implicit macro by prefixing a line with '(' which reverts to regular janet mode.

Janetsh can also be used for scripting, in which case it acts a small job control runtime and launcher for janet programs.

Project Status and Donations

The project is at the proof of concept phase and is only usable by people brave and willing to fix things for themselves.

The author would love donations or help from fellow developers to keep things going forward. Donations will go towards living expenses while developing janetsh and providing upstream support for the janet programming language issues that affect Janetsh.

This project takes considerable time an effort, please donate here via paypal to keep the project alive.

At your request with each donation leave a message and if appropriate, it will be included below.

Sponsors

You - Your message

Authors

This project is being built with care by Andrew Chambers.

Thanks

Special thanks to Calvin Rose for creating the Janet programming language.

Thanks to the authors of closh, rash and xonsh for providing inspiration for the project.

More Repositories

1

bupstash

Easy and efficient encrypted backups.
Rust
892
star
2

c

small self hosting C compiler
C
454
star
3

hermes

Hermes software environment manager
C
312
star
4

cc

Cross platform C preprocessor and compiler.
Go
268
star
5

minias

A mini x86-64 assembler for fun and learning.
C
203
star
6

orderly

Ordered process (re)start, shutdown, and supervision.
Rust
157
star
7

godothecorrectthing

A script to do actions based on the current window and selected text.
Shell
129
star
8

terraform-provider-nix

terraform provider that manages nix builds and nixos machines.
Go
105
star
9

janet-sh

Shorthand shell like functions for janet.
Janet
86
star
10

ws-tcp-bridge

A proxy server, using nodejs which bridges websockets and tcp servers in either direction.
JavaScript
77
star
11

sftpplease

SFTP <-> Cloud service bridge.
Go
69
star
12

cmips

cmips
C
57
star
13

hpkgs

A package repository for hermes
Shell
45
star
14

pycc

compiler
Python
35
star
15

qc

quick c
C
32
star
16

vscode-acmeish

A vscode extension to run system commands.
TypeScript
31
star
17

ddmin

A no frills delta debugger written in myrddin.
Roff
29
star
18

janet-pq

Bindings to libpq.
C
26
star
19

minipeg

A C peg parser generator (a fork of peg/leg)
C
22
star
20

janet-big

A simple big integer library for janet
C
20
star
21

janet-jdn

Janet
20
star
22

jfmt

18
star
23

janet-utf8

Janet routines for utf8 handling
C
17
star
24

coolpkg

The coolest package manager and deployment tool.
Python
16
star
25

poolparty

A synchronous, vm pooling http server for janet.
Go
16
star
26

fspec-tools

Tools to create filesystem images from an fspec filesystem specification.
C
15
star
27

hafs

A high availability distributed filesystem built on FoundationDB and fuse.
Go
15
star
28

janet-redis

Janet redis bindings based on hiredis
C
14
star
29

ShellCodeLinker

A python project that converts coffobject files (.o) built by mingw into an assembly file that can be built using nasm. When built using flat binary output this results in position independant shellcode generated by the c compiler.
Python
14
star
30

janet-uri

rfc3986 compliant url parser for janet.
Janet
13
star
31

janet-jcjit

A C extension jit for janet using libtcc.
C
13
star
32

asymcrypt

A tool for asymmetric cryptography
C
13
star
33

grafana-rrd-datasource

Graph and alert on '.rrd' data using grafana, RRDTool and RRDSrv.
Go
13
star
34

janet-posix-spawn

C
13
star
35

rrdsrv

An api server that exports a subset of rrdtool commands over http.
Go
12
star
36

magnet-linux

A decentralized linux distribution.
Shell
11
star
37

janet-yacc

An implementation of yacc for the janet programming language.
C
11
star
38

crushstore

A horizontally scaling object store based on the CRUSH placement algorithm.
Go
11
star
39

go-janet

A go port of the janet programming language.
Go
10
star
40

janet-process

A janet module for dealing with processes.
C
10
star
41

janet-pico-http-parser

http 1.1 parser for janet
C
10
star
42

bundle

Structured go concurrency with garbage collected goroutines.
Go
10
star
43

janet-ahttp

async aware http server library for janet
9
star
44

p2pkgs

A source based package tree with virtual environments, optional p2p mirrors and optional remote build caching.
Shell
9
star
45

janet-ctrl-c

A library for dealing with ctrl-c in janet
C
9
star
46

janet-where-defined

Lookup where a Janet function was defined
C
9
star
47

plumbtool

A window manager command runner and plumbing tool.
9
star
48

hm3

An embeddable programming language just for fun
C
9
star
49

janet-cloader

C
9
star
50

ddmin-python

A python implementation of delta debugging tool.
Python
9
star
51

go-cdclient

Fast implementation of the collectd network protocol for go.
Go
7
star
52

janet-rlrepl

A jpm module providing a gnu readline repl.
C
7
star
53

janet-httpkit

A framework agnostic toolkit for use when writing janet http handlers.
7
star
54

hpkg

Assembly
7
star
55

janet-md-doc

Generate markdown documentation for a janet-module
7
star
56

janet-nested-text

An implementation of NestedText for the Janet programming language
7
star
57

trusting-trust

Mostly trustworthy paths to self hosted linux userspace.
Shell
7
star
58

hm

6
star
59

janet-glob

Pure janet globbing
Janet
6
star
60

janet-datafog

A janet datalog engine
6
star
61

janet-pgjobq2

Second generation of the janet postgres job queue.
6
star
62

gslite

A lightweight alternative to google cloud sdk gsutil.
Go
5
star
63

janet-unify

5
star
64

ocker

less d than docker, more openbsd
Shell
5
star
65

syshook

Scriptable syscall tracing
C
5
star
66

go-dhallconfig

Dhall config for go.
Go
5
star
67

janet-ll

A low level rust crate providing bindings to the janet interpreter.
C
5
star
68

jsonsort

Sort large amounts of json using coreutils sort
Go
5
star
69

sup

C
5
star
70

shardfs

A sharding filesystem for linux based on the 9P2000L protocol
4
star
71

g

g programming language
Go
4
star
72

janet-logfmt

A logfmt log library for janet.
C
4
star
73

rwpart

Write partitions to raw disk images.
C
4
star
74

janet-base16

Base 16 encoding/decoding of buffers.
C
4
star
75

pkgfs

read only package union file system.
C
4
star
76

EncryptedBackupShootout

Shell
4
star
77

qasm

C
4
star
78

janet-redo

Prototype of redo in janet.
4
star
79

janet-pgjobq

A simple fifo jobq backed by postgres using redis pubsub.
3
star
80

gomodver

A package to parse version information from go.mod version identifiers.
Go
3
star
81

mips-baremetal

gcc toolchain for mips 4kc/p/m processor with no OS
C
3
star
82

fifolog

C
3
star
83

plmap-rust

Parallel pipelined map over iterators.
Rust
3
star
84

emailcontrolledgate

Shell
3
star
85

gosrcs

Print all source code for a given go package or module.
Go
3
star
86

janet-bare1

BARE encoder/decoder for janet
C
3
star
87

janet-shlex

3
star
88

cchan

Go style channels in C.
C
3
star
89

p92000l-rust

9P2000.L library for rust.
Rust
3
star
90

promcron

A simple cron service which exports prometheus metrics
Go
3
star
91

bfjit_x86_64

a brainfuck interpreter for x86_64 that uses jit
C
3
star
92

janet-flock

C
3
star
93

encr

A no frills stream encryption tool.
Roff
3
star
94

cts

c test suite
C
3
star
95

mummipy

bundles a loosely specified python requirements.txt into a standalone tarball.
Shell
3
star
96

srop

Simple remote object protocol
Go
3
star
97

cdcron

A cron daemon that exports collectd metrics.
Go
2
star
98

janet-fork

C
2
star
99

janet-rs

Higher level bindings for the janet C API.
Rust
2
star
100

qlite

A simple command line disk based queue
Python
2
star