about summary refs log tree commit diff
path: root/pkgs/profpatsch/xdg-open
diff options
context:
space:
mode:
authorProfpatsch <mail@profpatsch.de>2020-05-09 21:12:03 +0200
committerProfpatsch <mail@profpatsch.de>2020-05-09 21:13:09 +0200
commit0adf4290a0eaab8b907d34f66c4831c3493b25fb (patch)
treeb8987cbc41f64fb8be3fbecd8a40f73161250f31 /pkgs/profpatsch/xdg-open
parentb4248f32786039908c2268b8608b46935fc6c31e (diff)
pkgs/profpatsch: add xdg-open, WIP
Diffstat (limited to 'pkgs/profpatsch/xdg-open')
-rw-r--r--pkgs/profpatsch/xdg-open/config.dhall119
-rw-r--r--pkgs/profpatsch/xdg-open/default.nix88
-rw-r--r--pkgs/profpatsch/xdg-open/imports.nix12
-rw-r--r--pkgs/profpatsch/xdg-open/imports/Prelude.dhall1
-rw-r--r--pkgs/profpatsch/xdg-open/imports/Prelude/List/concatMap1
-rw-r--r--pkgs/profpatsch/xdg-open/imports/Prelude/List/map1
-rw-r--r--pkgs/profpatsch/xdg-open/imports/Prelude/Text/concat1
-rw-r--r--pkgs/profpatsch/xdg-open/imports/Prelude/Text/concatMap1
-rw-r--r--pkgs/profpatsch/xdg-open/imports/Prelude/Text/concatMapSep1
-rw-r--r--pkgs/profpatsch/xdg-open/imports/Prelude/Text/concatSep1
-rw-r--r--pkgs/profpatsch/xdg-open/xdg-open.dhall92
11 files changed, 318 insertions, 0 deletions
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