Live data from Hacker News

Show HN: Lisp Shell

github.com

21–30 of 61 posts

Re: Show HN: Lisp Shell

#21
post #5

CLASH: CLisp As SHell http://clisp.org/clash.html

I've never used it as a shell per se, but another little tweak I do sometimes for shell script type things in Lisp is install a read macro like

    (set-macro-character
     #\$ #'(lambda (stream char)
             (declare (ignore char))
             `(uiop:getenv ,(symbol-name (read stream)))))
This lets you read environment variables like $home, and write to them like ordinary variables, eg (setf $message "hello"). It reads the variable name as a Lisp symbol, so by default it will be upcased; this happens to be convenient for environment variables, but as with any symbols in Lisp, you can escape lowercase characters using either \ before the character or |'s around the whole symbol, or you could change the readtable case, or just preserve case initially in the read macro.

Re: Show HN: Lisp Shell

#22
post #11

For the Emacs users, there's eshell - a Shell, implemented in Elisp with the common GNU tooling, but also with the option to hook into regular elisp functions. Pretty cool stuff!

With the major caveat that piping commands together doesn't work that well, eshell has been an amazingly useful feature of emacs for me. Combined with TRAMP support, it makes dealing with remote machines much much more friendly. As an example, "cd 'ssh:firstmachine|ssh:secondmachine:/'" works just like you would anticipate, bounces you through first machine to second machine. All commands from that point are executed as if you were on second machine. You can even run "shell" to drop to a more traditional shell at that point. Even better, "cp someFile ~/" will transmit a file back to my local machine so that I don't have to work with the scp commands that it requires. :)

Re: Show HN: Lisp Shell

#23
You might be interested in an experiment of mine, https://github.com/tonyg/racket-something/blob/master/src/so..., which combines an indentation-based reader with a handler for unbound variables to permit fluid interoperation between Racket procedures and external programs.

Here's an example (https://github.com/tonyg/racket-something/blob/master/exampl...):

  #lang something/shell
  // Simple demos

  ls -la $HOME | grep "^d" | fgrep -v "."

  ls -la | wc -l | read-line |> string-split |> car |> string->number |> \
    printf "There are ~a lines here." | sed -e "s: are : seem to be :"
  (newline)

  def ps-output
    pipeline
      ps -wwwax
      preserve-header 1 {: grep "racket" }
      space-separated-columns [string->number]
      |> csv-expr->table
  print ps-output

  def message-box text:
    whiptail --title "Testing" --ok-button "OK" --msgbox text 8 50

  message-box "This is pretty cool."
`ls`, `grep`, `whiptail` and so on are unbound Racket variables, and the macros forming part of the `something/shell` dialect replace them with calls to the external programs, sorting out the plumbing, pipes and so on. `read-line`, `car`, `string-split`, etc are ordinary Racket functions from the standard libraries.

(EDIT): Here's a screencast of an interactive session with the shell. Very simple, but shows some of the basics: https://asciinema.org/a/83450

Re: Show HN: Lisp Shell

#24
post #20

Earlier quoted context omitted.

Another minor issue: cd without arguments should switch to the home directory rather than display the current directory (as your Readme suggests you do). You already have pwd for displaying the current directory.

Unless you’re seven directories deep and accidentally hit the button instead of the button. In which case, uh, you want the current functionality.

You can use "cd -" to go back to the previous directory.

Re: Show HN: Lisp Shell

#25

RASH, RAcket SHell library and language: https://github.com/willghatch/racket-rash Note: I am not the author

I was going to comment about this! The author is a student at my school who studies under Matthew Flatt (so no surprise it's based on Racket). I've worked with him on class projects before and he's not only wicked smart but also a really nice guy.

Re: Show HN: Lisp Shell

#26
post #3

Fun Unix Trivia Time: Touch is supposed to update modified times. That it creates files when they don't exist is only the most common use, not the point of the thing.

Thanks! I implemented this just to create blank files, and didn't bother researching correctness. That's exactly the kind of correction I was hoping for when posting to HN. My first post too.

To create a blank file, another idiom is "> foo".

Re: Show HN: Lisp Shell

#27
post #24
post #20

Earlier quoted context omitted.

Unless you’re seven directories deep and accidentally hit the button instead of the button. In which case, uh, you want the current functionality.

You can use "cd -" to go back to the previous directory.

$OLDPWD also holds the previous directory.

Re: Show HN: Lisp Shell

#28
post #24
post #20

Earlier quoted context omitted.

Unless you’re seven directories deep and accidentally hit the button instead of the button. In which case, uh, you want the current functionality.

You can use "cd -" to go back to the previous directory.

Does that work like a stack or does it just swap?

Re: Show HN: Lisp Shell

#30
post #29
post #28

Earlier quoted context omitted.

Does that work like a stack or does it just swap?

It only swaps; you can use pushd and popd if you want a stack.

Also:

- "cd -" has no interaction with the pushd/popd stack except in the sense that it alters the top of the stack (the current working dir). It doesn't swap the two top entries of the directory stack, but swaps the top with an off-stack saved location ($OLDPWD).

- "pushd" with no arguments swaps the top two stack entries.

Post reply on HN