Created
May 9, 2017 22:24
-
-
Save hodzanassredin/00156fef933007e5c3ae43b9659b68d3 to your computer and use it in GitHub Desktop.
bash like interface for BCL(fast and dirty)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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