From be43605785732a92fba1f95e3337fa1f60f6f124 Mon Sep 17 00:00:00 2001 From: Profpatsch Date: Fri, 5 Mar 2021 22:42:55 +0100 Subject: pkgs/profpatsch/xdg-open: improve tool a bit --- pkgs/profpatsch/xdg-open/config.dhall | 68 +++++++++++++++++++++++---------- pkgs/profpatsch/xdg-open/default.nix | 23 +++++++++-- pkgs/profpatsch/xdg-open/mini-url.rs | 2 +- pkgs/profpatsch/xdg-open/read-http.rs | 17 ++++++--- pkgs/profpatsch/xdg-open/xdg-open.dhall | 27 +++++++++---- 5 files changed, 99 insertions(+), 38 deletions(-) (limited to 'pkgs/profpatsch/xdg-open') diff --git a/pkgs/profpatsch/xdg-open/config.dhall b/pkgs/profpatsch/xdg-open/config.dhall index 9820df96..a66c888e 100644 --- a/pkgs/profpatsch/xdg-open/config.dhall +++ b/pkgs/profpatsch/xdg-open/config.dhall @@ -35,36 +35,52 @@ let mime = let renderMime = λ(m : Mime) → 32 -let UriMimeGlob = { desc : Text, glob : List Text, mime : Mime } - -let uriMimeGlobs - : List UriMimeGlob - = [ { desc = "http link" - , glob = [ "http://*", "https://*" ] - , mime = mime.text.html - } - , { glob = [ "mailto:*" ] - , desc = "mail address" - , mime = mime.mail-address - } - , { glob = [ "magnet:*" ] - , desc = "bittorrent magnet link" - , mime = mime.torrent - } - , { desc = "irc channel", glob = [ "irc:*" ], mime = mime.irc } - , { desc = "local file", glob = [ "file://*" ], mime = mime.file } - ] +let + -- Handler of an uri glob. Mime maps the uri to a file handler. Transparent is a command which, when run, returns a mimetype of the file. + UriGlobHandler = + < Transparent : Command | Mime : Mime > -let MimeMatch = { match : Mime, cmd : Command } +let UriMimeGlob = { desc : Text, glob : List Text, handler : UriGlobHandler } let Special = { open-in-editor : Command , open-in-browser : Command + , fetch-http-url-mime : Command , compose-mail-to : Command , exec-in-terminal-emulator : ∀(args : Command) → Command , dmenu-list-binaries-and-exec : Command } +let uriMimeGlobs + : Special → List UriMimeGlob + = λ(special : Special) → + [ { desc = "http link" + , glob = [ "http://*", "https://*" ] + , handler = + let TODO = UriGlobHandler.Transparent special.fetch-http-url-mime + + in UriGlobHandler.Mime mime.text.html + } + , { glob = [ "mailto:*" ] + , desc = "mail address" + , handler = UriGlobHandler.Mime mime.mail-address + } + , { glob = [ "magnet:*" ] + , desc = "bittorrent magnet link" + , handler = UriGlobHandler.Mime mime.torrent + } + , { desc = "irc channel" + , glob = [ "irc:*" ] + , handler = UriGlobHandler.Mime mime.irc + } + , { desc = "local file" + , glob = [ "file://*" ] + , handler = UriGlobHandler.Mime mime.file + } + ] + +let MimeMatch = { match : Mime, cmd : Command } + let mimeMatcher = λ(pkgs : { package : Text, binary : Text } → Executable) → λ(special : Special) → @@ -75,6 +91,17 @@ let mimeMatcher = , binary = packageAndBinaryName } + let wrapCommand = + λ(wrapper : Command) → + λ(cmd : Command) → + { exe = wrapper.exe + , args = + λ(template : Arg) → + wrapper.args template + # [ Arg.String cmd.exe ] + # cmd.args template + } + let oneArg = λ(exe : Executable) → { exe, args = λ(file : Arg) → [ file ] } @@ -114,6 +141,7 @@ in { mimeMatcher , UriMimeGlob , Executable , Command + , UriGlobHandler , MimeMatch , Special , Mime diff --git a/pkgs/profpatsch/xdg-open/default.nix b/pkgs/profpatsch/xdg-open/default.nix index e73f8093..89114b92 100644 --- a/pkgs/profpatsch/xdg-open/default.nix +++ b/pkgs/profpatsch/xdg-open/default.nix @@ -83,6 +83,14 @@ let ] ++ args file; }; + fetch-http-url-mime = { + exe = writeExecline "fetch-http-url-mime" { readNArgs = 1; } [ + "pipeline" [ read-headers-and-follow-redirect "$1" ] + record-get [ "content-type" ] + printenv "content-type" + ]; + args = file: [ file ]; + }; Prelude = let src = (import ./imports.nix { inherit pkgs; }).Prelude; @@ -106,6 +114,7 @@ let : { compose-mail-to : Command , dmenu-list-binaries-and-exec : Command , exec-in-terminal-emulator : ∀ ( args: Command) → Command + , fetch-http-url-mime : Command , open-in-browser : Command , open-in-editor : Command } @@ -132,6 +141,7 @@ let inherit compose-mail-to open-in-browser + fetch-http-url-mime open-in-editor dmenu-list-binaries-and-exec exec-in-terminal-emulator @@ -150,11 +160,11 @@ let ]; stderr-prog = writeExecline "stderr-prog" {} [ - "foreground" [ bins.echo "$@" ] + "if" [ "fdmove" "-c" "1" "2" bins.echo "$@" ] "$@" ]; - http-request = writeExecline "http-request-for-url" { } [ + http-request = writeExecline "http-request" { } [ "importas" "-i" "protocol" "protocol" "ifelse" [ bins.s6-test "$protocol" "=" "http" ] [ (http-https-request false) ] "ifelse" [ bins.s6-test "$protocol" "=" "https" ] [ (http-https-request true) ] @@ -177,9 +187,15 @@ let "" ]) "$path" "$host" ] + stderr-tee + stderr-prog + "pipeline" ([ bins.nc ] ++ lib.optional isHttps "-c" ++ [ - "-N" "$host" "$port" + "-v" "-N" "$host" "$port" + ]) + stderr-tee + "cat" ]); printenv = writeRustSimple "printenv" {} @@ -245,7 +261,6 @@ let go ]); - read-http = writeRustSimple "read-http" { dependencies = [ httparse netencode-rs ]; buildInputs = [ pkgs.skalibs ]; diff --git a/pkgs/profpatsch/xdg-open/mini-url.rs b/pkgs/profpatsch/xdg-open/mini-url.rs index ad2578cc..8a557747 100644 --- a/pkgs/profpatsch/xdg-open/mini-url.rs +++ b/pkgs/profpatsch/xdg-open/mini-url.rs @@ -94,7 +94,7 @@ fn main() -> std::io::Result<()> { std::env::set_var("protocol", protocol.string()); std::env::set_var("path", path); - el_exec::xpathexec0(&args[prog_index..]); + el_exec::xmexec0(&args[prog_index..]); Ok(()) } diff --git a/pkgs/profpatsch/xdg-open/read-http.rs b/pkgs/profpatsch/xdg-open/read-http.rs index 9fe8d6a9..3ec4c39a 100644 --- a/pkgs/profpatsch/xdg-open/read-http.rs +++ b/pkgs/profpatsch/xdg-open/read-http.rs @@ -25,7 +25,7 @@ fn main() -> std::io::Result<()> { Ok(_start_of_body) => { match resp.code { Some(code) => write_dict(code, resp.reason, resp.headers)?, - None => die(format!("no http status")) + None => die(format!("no http status in {:?}", resp)) } } }; @@ -41,11 +41,18 @@ fn write_dict<'buf>(code: u16, reason: Option<&'buf str>, headers: &mut [httpars http.push(("status-text", Box::new(U::Text(t.as_bytes())))) }; + let lowercase_headers = headers.iter_mut().map( + |httparse::Header { name, value }| + // lowercase the headers, since the standard doesn’t care + // and we want unique strings to match agains + (name.to_lowercase(), value) + ).collect::>(); + + http.push(("headers", Box::new(U::Record( - headers.iter_mut().map( - |httparse::Header { name, value }| - (*name, - Box::new(U::Binary(value))) + lowercase_headers.iter().map( + |(name, value)| + (name.as_str(), Box::new(U::Binary(value))) ).collect::>() )))); diff --git a/pkgs/profpatsch/xdg-open/xdg-open.dhall b/pkgs/profpatsch/xdg-open/xdg-open.dhall index 03f168c3..30cf45e0 100644 --- a/pkgs/profpatsch/xdg-open/xdg-open.dhall +++ b/pkgs/profpatsch/xdg-open/xdg-open.dhall @@ -13,11 +13,6 @@ let let config = ./config.dhall -let foo = - { match = [ "image", "png" ] - , cmd = λ(_ : Text) → { exe = "echo", args = [ "foo" ] } - } - let renderMime = Text/concatSep "/" let shellEscapeCommand = @@ -66,12 +61,28 @@ let xdg-open = ] let mimeGlobCase = + λ(shellEscape2 : Text → Text) → + λ(file2 : Text) → λ(g : config.UriMimeGlob) → List/concatMap Text Text ( λ(match : Text) → - [ "${match})", "mime=${renderMime g.mime}", ";;" ] + merge + { Mime = + λ(mime : config.Mime) → + [ "${match})", "mime=${renderMime mime}", ";;" ] + , Transparent = + λ(cmd : config.Command) → + [ "${match})" + , "mime=\"\$(${shellEscapeCommand + shellEscape2 + file2 + cmd})\"" + , ";;" + ] + } + g.handler ) g.glob : List Text @@ -102,8 +113,8 @@ let xdg-open = List/concatMap config.UriMimeGlob Text - mimeGlobCase - config.uriMimeGlobs + (mimeGlobCase shellEscape "\"\$file\"") + (config.uriMimeGlobs special) }} *) # it’s a file -- cgit 1.4.1