#!/usr/local/bin/newlisp

; - nls - newLISP shell combines interactive OS and LISP shell
;
; v.1.0 - adapted to new manual HTML formatting 2009-08-04
; v.1.1 - better regex string for syntax filtering 2011-11-01
;         now formats dolist, dotimes ... etc. correctly
; v.1.2 - fix for Windows probelm passing cr-lf in command-event
; c.1.3 - cut off cr-lf only on versions < 10.4.1
;
; Directory and file commands to not work yet on names containing spaces!
; Does not work with <,>,<<,>>
;
;
; Use the prompt as if a Bash shell. Commands not starting with an opening
; parenthesis or space are interpreted as UNIX shell cmomands, commands
; starting with parenthesis or space are interpreted as interacive newLISP
; commands.

(define (help func-name)
  (when (= func-name "help") (set 'func-name ""))
  (if (find func-name "|+*-") (push "\\" func-name))
  (set 'helpfile (read-file (if (= ostype "Win32")
    (string (env "NEWLISPDIR") "/newlisp_manual.html") 
    "/usr/local/share/doc/newlisp/newlisp_manual.html")))
  (set 'html-text (join 
    (find-all (format {(syntax: \(%s.*?)(<br/>|</h4>)} func-name ) helpfile $1) "\n"))
  (replace "<.*?>" html-text "" 0)
  (replace "&lt;" html-text "<")
  (replace "&gt;" html-text ">")
  (replace "&amp;" html-text "&")
  (println html-text)
  "")

; set the prompt to the current path
(prompt-event (fn (ctx) (string ctx ":" (real-path) "> ")))

; handle some special commands, newLISP expressions and shell commands
(command-event (fn (s) 
  (if (and (< (sys-info -2) 10401) (= ostype "Win32"))
        (set 's (chop s 2)))
  (if 
    ; get syntax help
    (starts-with s "\\?|help" 0)
    (help (last (parse s " ")))

    ; restart newLISP
    (starts-with s "reset")
    (reset true) ; restart

    ; avoid X-windows beeing started on OS X
    (starts-with s "x")
    ""

    ; all directory changes must be done inside newLISP
    ; previous directory cd -
    (starts-with s "cd -")
    (begin
        (set 'new-dir prev-dir)
        (set 'prev-dir (real-path))
        (string " " (true? (change-dir new-dir))))
	
    ; pushd
    (starts-with s "pushd")
    (begin
        (set 'prev-dir (real-path))
        (push prev-dir dir-stack)
        (string " " (true? (change-dir (last (parse s " "))))))

    ; popd
    (starts-with s "popd")
    (begin
        (set 'prev-dir (real-path))
        (string " " (true? (change-dir (pop dir-stack)))))

    ; go to home directory
    (= s "cd")
    (begin
        (set 'prev-dir (real-path))
        (string " " (true? (change-dir (env "HOME")))))

    ; change directory cd
    (starts-with s "cd") 
    (begin
        (set 'prev-dir (real-path))
        (string " " (true? (change-dir (last (parse s " "))))))

    ; else handle as a shell command, start newLISP expressions
    ; with either a space or a parenthesis
    (starts-with s "[\\.a-zA-Z]" 0)
    (append "!" s)

    true s)))

;; eof

