Skip to content

Instantly share code, notes, and snippets.

@hodzanassredin
Created May 9, 2017 22:24
Show Gist options
  • Save hodzanassredin/00156fef933007e5c3ae43b9659b68d3 to your computer and use it in GitHub Desktop.
Save hodzanassredin/00156fef933007e5c3ae43b9659b68d3 to your computer and use it in GitHub Desktop.
bash like interface for BCL(fast and dirty)
open System
// Learn more about F# at http://fsharp.org
// See the 'F# Tutorial' project for more help.
module Consoler =
open System.Reflection
open NReadability
open ReadSharp
let a = Assembly.GetAssembly("".GetType())
let types = a.GetExportedTypes()
type Namespace = string
type Exec = Exec of string * string[]
type Command =
| Ls of Namespace
| Cd of Namespace
| Dot of Exec
| Grep of string
| Pipe of Command * Command
| Exit
| Man of string
let getSingle env =
types |> Seq.where (fun x -> x.FullName.StartsWith(env))
|> Seq.head
type Environment = string
let (|Prefix|_|) (p:string) (s:string) =
if s = p then
Some("")
else if s.StartsWith(p + " ") then
Some(s.Substring(p.Length + 1))
else if s.StartsWith(p) then
Some(s.Substring(p.Length))
else
None
let (|Split|_|) (p:string) (s:string) =
if s.Contains(p) then
Some(s.Split(p.ToCharArray(), 2))
else
None
let rec joinDir (fst:string) snd =
match snd with
| "" -> fst
| Prefix "/" dir -> snd.Replace("/", ".").Substring(1)
| ".." -> fst.Substring(0, fst.LastIndexOf("."))
| Prefix "../" dir -> joinDir (fst.Substring(0, fst.LastIndexOf("."))) snd
| _ -> fst + "." + snd.Replace("/", ".")
let checkDir dir = types |> Seq.exists (fun x -> x.FullName.StartsWith(dir))
let getMan method =
let reader = new Reader()
let article = reader.Read(new Uri("https://msdn.microsoft.com/en-us/library/" + method))
|> Async.AwaitTask
|> Async.RunSynchronously
seq{
yield article.Title
yield "----------------------"
let doc = HtmlAgilityPack.HtmlDocument()
doc.LoadHtml(article.Content)
let cnt = doc.DocumentNode.SelectNodes("//text()")
|> Seq.map (fun x -> x.InnerText)
|> Array.ofSeq
|> Array.reduce (fun x y -> x + y)
yield cnt
}
//use wc = System.Net.WebClient()
//let html = wc.DownloadString("https://msdn.microsoft.com/en-us/library/" + method)
//let transcoder = new NReadabilityTranscoder();
//let mutable success = false
//let transcodedContent = transcoder.Transcode(html, &success)
//if success then
// transcodedContent.Split('\n') |> Seq.ofArray
//else
// Seq.empty
//let doc = HtmlAgilityPack.HtmlDocument()
//doc.LoadHtml(html)
//let root = doc.DocumentNode
//seq{
//for node in root.DescendantNodesAndSelf() do
// if node.HasChildNodes |> not then
// let text = node.InnerText
// if String.IsNullOrEmpty(text) |> not then
// yield text.Trim()
//}
let rec eval (inp : string seq) (env : Environment) cmd : Environment * string seq =
match cmd with
| Ls namespc -> let d = joinDir env namespc
if checkDir d then
env, types |> Seq.where (fun x -> x.FullName.StartsWith(d))
|> Seq.map (fun x -> x.FullName.Substring(d.Length))
else env, ["Not found"] |> Seq.ofList
| Cd namespc -> let d = joinDir env namespc
if checkDir d then d, Seq.empty
else env, ["Not found"] |> Seq.ofList
| Dot (Exec(method, args)) ->
env, getSingle (env)
|> fun x -> [x.GetMethod(method).Invoke(null, args |> Array.map (fun x -> x :> Object)).ToString()]
|> Seq.ofList
| Pipe(cmd1, cmd2) -> let env1, out1 = eval inp env cmd1
eval out1 env1 cmd2
| Grep(filter) -> env, inp |> Seq.where (fun x -> x.Contains(filter))
| Exit -> env, Seq.empty
| Man method -> env, getMan (env + "." + method)
let rec parse (line:string) : Command =
match line.Trim() with
| Split "|" parts -> Pipe(parse parts.[0], parse parts.[1])
| Prefix "cd" dir -> Cd (dir)
| Prefix "ls" dir -> Ls (dir)
| Prefix "man" method -> Man (method)
| Prefix "grep" pattern -> Grep(pattern)
| "exit" -> Exit
| Split " " parts -> Dot (Exec(parts.[0], parts.[1..]))
let rec loop dir =
printf "\n%s>" dir
let cmd = Console.ReadLine() |> parse
match cmd with
| Exit -> ()
| _ ->
let dir, out = eval Seq.empty dir cmd
for s in out do
printfn "%s" s
loop dir
[<EntryPoint>]
let main argv =
Consoler.loop "System"
0 // return an integer exit code
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment