*Published: 2025-02-19* Here are some quick notes on the [Oils shell / scripting languages](https://oils.pub). I have tried to get productive with osh and ysh a few times, most recently ysh yesterday, and I have been using osh as my mostly main shell for a couple of years. I love this project and wish I could afford to contribute more; instead I'll just share these fresh subjective experience notes. I'm focussing on "areas of exciting potential for improvement", but I don't mean any of this as complaints or requests for more free stuff. As a FOSS maintainer I value these reports sometimes. For balance I'll end with five things that I love. Here we go! ### Naming is hard It might be too hard to change again, and it has its own charm, but I still don't love the naming. "Oil shell" was simple; the new "Oils" plural and "oils-for-unix" phrase is awkward. If I want to speak about osh+ysh generically, do I have to say "Oils shell" ? Just "Oils" doesn't communicate what I'm talking about (a shell/scripting language) and "Oils for unix" seems to lock in platform dependence. ### Cross platform ? Speaking of that, is Windows out of scope forever, as the name implies ? That's understandable and possibly necessary; personally I hope it might eventually turn out otherwise. All-terrain tools that can work to some extent everywhere are the most attractive to invest in as they give more bang for your buck, eg if you're shipping cross platform FOSS. Either way, apart from the name I didn't see a clear statement about this (or mac support) in the docs, more mention of the platform requirements could be good. ### Docs structure Andy C's prolific docs are amazing and one of the things that brought me to the project. I think they are more structured than in the past but still more structure could be helpful. They link all over the place and I still didn't find a really good single url for YSH showing just the essential docs. The reference docs feel fragmented. It's hard to find your way when there are so many kinds of things and they're all listed in different places. I understand why a `prefix-` or `prefix/` is sometimes used to disambiguate things; sometimes this makes the exact name of things unclear. I also struggled with comprehending the output of `help`; though it says so, I didn't at first understand you have to prefix "ysh-" to most of the topics listed there (including the one that already begins with "ysh-"). In this case, better to list the full names that you must type I think. I finally made this command: ```sh ref() { ### show all reference topics (ysh 0.27) help ysh-type-method help ysh-builtin-func help ysh-builtin-cmd help ysh-stdlib help ysh-front-end help ysh-cmd-lang help ysh-ysh-cmd help ysh-expr-lang help ysh-word-lang help ysh-option help ysh-special-var help ysh-plugin } ``` And I find it quite helpful; there's still too many things in too many similar-sounding places, but at least I can now see them all (with scrolling). Note though how fragile this is, it'll break with a version other than 0.27. Also, in future, once `help` can more often show the doc directly instead of just a hyperlink (which often leads to very minimal help), it'll be more useful. ### Docs accuracy Docs are often out of date / wrong (inevitable when manually maintained). This is a turn off. Getting started docs in particular deserve top priority to avoid losing people; eg the install docs ideally - should be regularly tested (or at least say when/where they were last seen to work) - should state clearly that building from a git checkout is not supported and that they really do require downloading a tarball - should mention which platforms they're expected to work on and the known build problems, eg on mac Setting a prompt is another common early task. There's multiple mentions of PS1-4, but setting these no longer work in ysh; the setglobal method that does work should be shown early on; likewise the working example of a renderPrompt function that's currently hidden in the types-and-methods doc. GIven the scope of the project it seems that extensive docs automation at least of the reference docs will be the only way to keep them fresh and accurate. All the above may be well known, but maybe not; sometimes we lose track of the new user experience. Docs also might be considered a lower priority than "finishing" the software, which is also understandable. This is really just raising the priorities question. IMHO the software that exists is already extremely useful (both osh and ysh), and could use more functional docs today. "Search the zulip" is not enough. Arguably, every day that passes where someone struggles to get started, maybe bouncing off osh/ysh as a result, is a slight but real current of anti-marketing that's hard to repair, sapping potential users and momentum. ### The Zulip As simple matrix/irc/discourse/mail list user, I try hard to like the zulip chat/forum, as usual. It's great in many ways, but at times I still find it hard to use. - The ui and topics can feel busy and overwhelming, with many twisty channels/topics all alike; I have become used to picking the wrong channel and having my conversations moved elsewhere half way through. - I found the ui unstable. While navigating or searching, a number of times I couldn't quite figure out where I was, and/or it "jumped" somewhere else, or scroll position was way out of place, and I had to reload the page and start again. I don't know if tweaking server settings or pruning channels/topics could help. Finally I'll mention the overlap between zulip discussions and github issue tracker, and between oils website and the extensive github wiki; I haven't mapped it all out yet. I know some mirroring is being considered. ### Love it Many thanks to Andy, and the other contributors and funders, for this impactful, strategic project. Here's five random things that I loved, from the latest session: - The smooth upgrade path and strategy works. Osh met me where I was (bash), allowing me to use it productively while exposing myself to newer things at my own pace. Now I'm ready for some easier/more powerful scripting and ysh is right there in the same runtime and still supports many bash/osh constructs. Love it! - I perceived ysh as a rather complex blend of things; but it's a careful blend of principled, well designed things, which can replace a number of complicated, less principled, less well integrated things that I currently use (and forgot I also had to learn). Love it! - Ysh is (becoming) expressive enough to make real world scripting tasks pleasant and ergonomic. I can't really remember a language that seriously attempted or succeeded at this since Ruby and Perl. Love it! - I have seen only a few of the error messages, but they have been impressively clear and helpful. Love it! - Eggex syntax, and the flexible case statement. ### Scripts Here's a script template I already shared on zulip: ```sh #!/usr/bin/env ysh # -*- sh -*- ### script.tmpl.ysh const usage = 'foo [COMMAND] - Do stuff.' # https://oils.pub/release/latest/doc/ysh-tour.html # https://oils.pub/release/latest/doc/ref/ const S = /%start/ const E = /%end/ proc help() { write -n -- """ ------------------------------------------------------------------------------- $usage Commands: """ # grep -E '^(proc +)?\w.*\(\) *{ *#+' "$0" | sed -E -e 's/^proc +//' -e 's/\(\) *\{//' -e 's/#+ /\t /' redir < $0 { for l in (io.stdin) { if (l ~ /S ('proc' space+)? <capture w dot* as name> '()' dot* '###' space* <capture dot* as help>/) { echo "$[_group('name')] $[_group('help')]" } } } } proc baz() { ### the baz command echo baz } proc qux() { ### the qux command echo qux } if (len(ARGV) < 1) { help } else { case (ARGV[0]) { /S'h'('e'('l'('p')?)?)?E/ { help } /S'b'('a'('z')?)?E/ { baz } /S'q'('u'('x')?)?E/ { qux } (else) { echo "Unknown command: $[ARGV[0]]"; return 1 } } } ``` And here's my current `.yshrc`: ```sh # .yshrc -*- sh -*- # For convenience: cd && ln -s ~/.config/oils/yshrc .yshrc s() { source ~/.yshrc } # set the prompt, two ways #setglobal ENV.PS1='ysh> ' func renderPrompt(io) { var parts = [] call parts->append(io.promptVal('h')) call parts->append(':ysh:') call parts->append(io.promptVal('w')) call parts->append(io.promptVal(')) call parts->append(' ') return (join(parts)) } # get help ref() { ### show all reference topics (ysh 0.27) help ysh-type-method help ysh-builtin-func help ysh-builtin-cmd help ysh-stdlib help ysh-front-end help ysh-cmd-lang help ysh-ysh-cmd help ysh-expr-lang help ysh-word-lang help ysh-option help ysh-special-var help ysh-plugin } ```