From 0adf4290a0eaab8b907d34f66c4831c3493b25fb Mon Sep 17 00:00:00 2001 From: Profpatsch Date: Sat, 9 May 2020 21:12:03 +0200 Subject: pkgs/profpatsch: add xdg-open, WIP --- pkgs/profpatsch/xdg-open/config.dhall | 119 +++++++++++++++++++++ pkgs/profpatsch/xdg-open/default.nix | 88 +++++++++++++++ pkgs/profpatsch/xdg-open/imports.nix | 12 +++ pkgs/profpatsch/xdg-open/imports/Prelude.dhall | 1 + .../xdg-open/imports/Prelude/List/concatMap | 1 + pkgs/profpatsch/xdg-open/imports/Prelude/List/map | 1 + .../xdg-open/imports/Prelude/Text/concat | 1 + .../xdg-open/imports/Prelude/Text/concatMap | 1 + .../xdg-open/imports/Prelude/Text/concatMapSep | 1 + .../xdg-open/imports/Prelude/Text/concatSep | 1 + pkgs/profpatsch/xdg-open/xdg-open.dhall | 92 ++++++++++++++++ 11 files changed, 318 insertions(+) create mode 100644 pkgs/profpatsch/xdg-open/config.dhall create mode 100644 pkgs/profpatsch/xdg-open/default.nix create mode 100644 pkgs/profpatsch/xdg-open/imports.nix create mode 100644 pkgs/profpatsch/xdg-open/imports/Prelude.dhall create mode 100644 pkgs/profpatsch/xdg-open/imports/Prelude/List/concatMap create mode 100644 pkgs/profpatsch/xdg-open/imports/Prelude/List/map create mode 100644 pkgs/profpatsch/xdg-open/imports/Prelude/Text/concat create mode 100644 pkgs/profpatsch/xdg-open/imports/Prelude/Text/concatMap create mode 100644 pkgs/profpatsch/xdg-open/imports/Prelude/Text/concatMapSep create mode 100644 pkgs/profpatsch/xdg-open/imports/Prelude/Text/concatSep create mode 100644 pkgs/profpatsch/xdg-open/xdg-open.dhall (limited to 'pkgs/profpatsch/xdg-open') diff --git a/pkgs/profpatsch/xdg-open/config.dhall b/pkgs/profpatsch/xdg-open/config.dhall new file mode 100644 index 00000000..32b5d7cf --- /dev/null +++ b/pkgs/profpatsch/xdg-open/config.dhall @@ -0,0 +1,119 @@ +let Mime = List Text + +let + -- TODO use library like with shell commands + Executable = + Text + +let Arg = < String : Text | Variable : Text > + +let CommandTemplate = + λ(templates : Type) → { exe : Executable, args : templates → List Arg } + +let Command = CommandTemplate Text + +let mime = + { text = + { html = [ "text", "html" ] + , xml = [ "text", "xml" ] + , any = [ "text", "*" ] + } + , mail-address = [ "special", "mailaddress" ] + , torrent = [ "application", "x-bittorrent" ] + , irc = [ "x-scheme-handler", "irc" ] + , file = [ "x-scheme-handler", "file" ] + , image = + { gif = [ "image", "gif" ] + , svg = [ "image", "svg+xml" ] + , any = [ "image", "*" ] + } + , pdf = [ "application", "pdf" ] + , pgp-key = [ "application", "pgp-keys" ] + , directory = [ "inode", "directory" ] + , any = [ "*" ] + } + +let renderMime = λ(m : Mime) → 32 + +let uriMimeGlobs = + [ { 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 MimeMatch = { match : Mime, cmd : Command } + +let Special = + { open-in-editor : Command + , open-in-browser : Command + , compose-mail-to : Command + , exec-in-terminal-emulator : ∀(args : Command) → Command + , dmenu-list-binaries-and-exec : Command + } + +let mimeMatcher = + λ(pkgs : { package : Text, binary : Text } → Executable) + → λ(special : Special) + → let pkgSame = + λ(packageAndBinaryName : Text) + → pkgs + { package = packageAndBinaryName + , binary = packageAndBinaryName + } + + let oneArg = + λ(exe : Executable) + → { exe = exe, args = λ(file : Text) → [ Arg.Variable file ] } + + let m = + λ(match : Mime) → λ(cmd : Command) → { match = match, cmd = cmd } + + in [ { match = mime.mail-address, cmd = special.compose-mail-to } + , { match = mime.text.html, cmd = special.open-in-browser } + , { match = mime.text.xml, cmd = special.open-in-browser } + , { match = mime.text.any, cmd = special.open-in-editor } + , { match = mime.image.gif, cmd = special.open-in-browser } + , { match = mime.image.svg, cmd = oneArg (pkgSame "inkscape") } + , { match = mime.image.any, cmd = oneArg (pkgSame "feh") } + , { match = mime.pdf, cmd = oneArg (pkgSame "zathura") } + , { match = mime.pgp-key + , cmd = + { exe = pkgs { package = "gnupg", binary = "gpg" } + , args = + λ(file : Text) + → [ Arg.String "--import" + , Arg.String "--import-options" + , Arg.String "show-only" + , Arg.Variable file + ] + } + } + , { match = mime.directory + , cmd = + special.exec-in-terminal-emulator + (oneArg (pkgSame "ranger")) + } + , { match = mime.any, cmd = special.dmenu-list-binaries-and-exec } + ] + : List MimeMatch + +in { mimeMatcher = mimeMatcher + , uriMimeGlobs = uriMimeGlobs + , Executable = Executable + , Command = Command + , MimeMatch = MimeMatch + , Special = Special + , Mime = Mime + , Arg = Arg + } diff --git a/pkgs/profpatsch/xdg-open/default.nix b/pkgs/profpatsch/xdg-open/default.nix new file mode 100644 index 00000000..a2d914d2 --- /dev/null +++ b/pkgs/profpatsch/xdg-open/default.nix @@ -0,0 +1,88 @@ +{ pkgs, getBins, importDhall2, writeExecline, dhall, buildDhallPackage }: + +let + lib = pkgs.lib; + bins = getBins pkgs.libnotify [ "notify-send" ] + // getBins pkgs.file [ "file" ]; + + notify = msg: { + exe = writeExecline "notify" { readNArgs = 2; } [ + bins.notify-send + ("\${1} \${2}") + ]; + args = file: [ + ({String, Variable}: String msg) + ({String, Variable}: Variable file) + ]; + }; + + get-mime-type = writeExecline "get-mime-type" { readNArgs = 1; } [ + bins.file "-E" "--brief" "--mime-type" "$1" + ]; + + Prelude = + let src = (import ./imports.nix { inherit pkgs; }).Prelude; + # TODO: bs, make dhall version overridable + in buildDhallPackage { + name = "Prelude"; + code = "${src.repo}/${src.mainFile}"; + }; + + xdg-open = importDhall2 { + type = '' + ∀(bins : { get-mime-type : Text }) +→ ∀(write-dash : Text → Text → Text) +→ ∀(shellEscape : Text → Text) +→ ∀(pkgs : { binary : Text, package : Text } → Text) +→ ∀ ( special + : { compose-mail-to : + { args : Text → List < String : Text | Variable : Text >, exe : Text } + , dmenu-list-binaries-and-exec : + { args : Text → List < String : Text | Variable : Text >, exe : Text } + , exec-in-terminal-emulator : + ∀ ( args + : { args : Text → List < String : Text | Variable : Text > + , exe : Text + } + ) + → { args : Text → List < String : Text | Variable : Text > + , exe : Text + } + , open-in-browser : + { args : Text → List < String : Text | Variable : Text >, exe : Text } + , open-in-editor : + { args : Text → List < String : Text | Variable : Text >, exe : Text } + } + ) +→ Text + ''; + root = ./.; + main = "xdg-open.dhall"; + files = [ + "config.dhall" + "imports/Prelude/Text/concatSep" + "imports/Prelude/Text/concatMap" + "imports/Prelude/Text/concat" + "imports/Prelude/List/map" + "imports/Prelude/List/concatMap" + ]; + deps = [ Prelude ]; + } + { inherit get-mime-type; } + pkgs.writers.writeDash + pkgs.lib.escapeShellArg + ({binary, package}: "${lib.getBin pkgs.${package}}/bin/${package}") + { + compose-mail-to = notify "compose-mail-to"; + dmenu-list-binaries-and-exec = notify "dmenu"; + exec-in-terminal-emulator = exec: notify ("to exec: " + lib.generators.toPretty {} exec); + open-in-browser = notify "browser"; + open-in-editor = notify "editor"; + }; + +in { + inherit + xdg-open + Prelude + ; +} diff --git a/pkgs/profpatsch/xdg-open/imports.nix b/pkgs/profpatsch/xdg-open/imports.nix new file mode 100644 index 00000000..0ff61852 --- /dev/null +++ b/pkgs/profpatsch/xdg-open/imports.nix @@ -0,0 +1,12 @@ +{ pkgs }: +{ Prelude = + { repo = + pkgs.fetchFromGitHub + { owner = "dhall-lang"; + repo = "dhall-lang"; + rev = "bbf87ad50626061f20f70f37dae97d3175b92dcf"; + sha256 = "09ldjssgwywm6mm7akry1axhajrbxhia3288rrif5bd3ds8phxac"; + }; + mainFile = "Prelude/package.dhall"; + }; +} diff --git a/pkgs/profpatsch/xdg-open/imports/Prelude.dhall b/pkgs/profpatsch/xdg-open/imports/Prelude.dhall new file mode 100644 index 00000000..c384c481 --- /dev/null +++ b/pkgs/profpatsch/xdg-open/imports/Prelude.dhall @@ -0,0 +1 @@ +https://raw.githubusercontent.com/dhall-lang/dhall-lang/bbf87ad50626061f20f70f37dae97d3175b92dcf/Prelude/package.dhall sha256:6b90326dc39ab738d7ed87b970ba675c496bed0194071b332840a87261649dcd diff --git a/pkgs/profpatsch/xdg-open/imports/Prelude/List/concatMap b/pkgs/profpatsch/xdg-open/imports/Prelude/List/concatMap new file mode 100644 index 00000000..e49b1266 --- /dev/null +++ b/pkgs/profpatsch/xdg-open/imports/Prelude/List/concatMap @@ -0,0 +1 @@ +https://raw.githubusercontent.com/dhall-lang/dhall-lang/bbf87ad50626061f20f70f37dae97d3175b92dcf/Prelude/List/concatMap sha256:3b2167061d11fda1e4f6de0522cbe83e0d5ac4ef5ddf6bb0b2064470c5d3fb64 diff --git a/pkgs/profpatsch/xdg-open/imports/Prelude/List/map b/pkgs/profpatsch/xdg-open/imports/Prelude/List/map new file mode 100644 index 00000000..0c948866 --- /dev/null +++ b/pkgs/profpatsch/xdg-open/imports/Prelude/List/map @@ -0,0 +1 @@ +https://raw.githubusercontent.com/dhall-lang/dhall-lang/bbf87ad50626061f20f70f37dae97d3175b92dcf/Prelude/List/map sha256:dd845ffb4568d40327f2a817eb42d1c6138b929ca758d50bc33112ef3c885680 diff --git a/pkgs/profpatsch/xdg-open/imports/Prelude/Text/concat b/pkgs/profpatsch/xdg-open/imports/Prelude/Text/concat new file mode 100644 index 00000000..7a96e263 --- /dev/null +++ b/pkgs/profpatsch/xdg-open/imports/Prelude/Text/concat @@ -0,0 +1 @@ +https://raw.githubusercontent.com/dhall-lang/dhall-lang/bbf87ad50626061f20f70f37dae97d3175b92dcf/Prelude/Text/concat sha256:731265b0288e8a905ecff95c97333ee2db614c39d69f1514cb8eed9259745fc0 diff --git a/pkgs/profpatsch/xdg-open/imports/Prelude/Text/concatMap b/pkgs/profpatsch/xdg-open/imports/Prelude/Text/concatMap new file mode 100644 index 00000000..e0986052 --- /dev/null +++ b/pkgs/profpatsch/xdg-open/imports/Prelude/Text/concatMap @@ -0,0 +1 @@ +https://raw.githubusercontent.com/dhall-lang/dhall-lang/bbf87ad50626061f20f70f37dae97d3175b92dcf/Prelude/Text/concatMap sha256:7a0b0b99643de69d6f94ba49441cd0fa0507cbdfa8ace0295f16097af37e226f diff --git a/pkgs/profpatsch/xdg-open/imports/Prelude/Text/concatMapSep b/pkgs/profpatsch/xdg-open/imports/Prelude/Text/concatMapSep new file mode 100644 index 00000000..5a140976 --- /dev/null +++ b/pkgs/profpatsch/xdg-open/imports/Prelude/Text/concatMapSep @@ -0,0 +1 @@ +https://raw.githubusercontent.com/dhall-lang/dhall-lang/bbf87ad50626061f20f70f37dae97d3175b92dcf/Prelude/Text/concatMapSep sha256:c272aca80a607bc5963d1fcb38819e7e0d3e72ac4d02b1183b1afb6a91340840 diff --git a/pkgs/profpatsch/xdg-open/imports/Prelude/Text/concatSep b/pkgs/profpatsch/xdg-open/imports/Prelude/Text/concatSep new file mode 100644 index 00000000..c585d712 --- /dev/null +++ b/pkgs/profpatsch/xdg-open/imports/Prelude/Text/concatSep @@ -0,0 +1 @@ +https://raw.githubusercontent.com/dhall-lang/dhall-lang/bbf87ad50626061f20f70f37dae97d3175b92dcf/Prelude/Text/concatSep sha256:e4401d69918c61b92a4c0288f7d60a6560ca99726138ed8ebc58dca2cd205e58 diff --git a/pkgs/profpatsch/xdg-open/xdg-open.dhall b/pkgs/profpatsch/xdg-open/xdg-open.dhall new file mode 100644 index 00000000..cbd9654e --- /dev/null +++ b/pkgs/profpatsch/xdg-open/xdg-open.dhall @@ -0,0 +1,92 @@ +let Text/concatSep = ./imports/Prelude/Text/concatSep + +let Text/concatMap = ./imports/Prelude/Text/concatMap + +let List/concatMap = ./imports/Prelude/List/concatMap + +let List/map = ./imports/Prelude/List/map + +let + -- TODO use library like with shell commands + Executable = + Text + +let config = ./config.dhall + +let foo = + { match = [ "image", "png" ] + , cmd = λ(_ : Text) → { exe = "echo", args = [ "foo" ] } + } + +let renderMime = Text/concatSep "/" + +let shellEscapeCommand = + λ(shellEscape : Text → Text) + → λ(file : Text) + → λ(cmd : config.Command) + → Text/concatSep + " " + ( [ shellEscape cmd.exe ] + # List/map + config.Arg + Text + ( λ(arg : config.Arg) + → merge + { String = λ(t : Text) → shellEscape t + , Variable = λ(t : Text) → t + } + arg + ) + (cmd.args file) + ) + : Text + +let repeatText = + λ(t : Text) + → λ(n : Natural) + → Natural/fold n Text (λ(t2 : Text) → t ++ t2) "" + +let Lines = { indent : Natural, lines : List Text } + +let prettyLines = + λ(lines : Lines) + → Text/concatMap + Text + (λ(line : Text) → repeatText " " lines.indent ++ line ++ "\n") + lines.lines + +let xdg-open = + let case = + λ(shellEscape2 : Text → Text) + → λ(file2 : Text) + → λ(m : config.MimeMatch) + → [ "${renderMime m.match})" + , "${shellEscapeCommand shellEscape2 file2 m.cmd}" + , ";;" + ] + + in λ(bins : { get-mime-type : Executable }) + → λ(write-dash : Text → Text → Executable) + → λ(shellEscape : Text → Text) + → λ(pkgs : { package : Text, binary : Text } → Executable) + → λ(special : config.Special) + → write-dash + "xdg-open" + '' + file="$1" + mime=$(${bins.get-mime-type} "$file") + + case "$mime" in + ${prettyLines + { indent = 2 + , lines = + List/concatMap + config.MimeMatch + Text + (case shellEscape "\"\$file\"") + (config.mimeMatcher pkgs special) + }} + esac + '' + +in xdg-open -- cgit 1.4.1