1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
|
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 (config.Arg.Variable 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 mimeMatcherCase =
λ(shellEscape2 : Text → Text) →
λ(file2 : Text) →
λ(m : config.MimeMatch) →
[ "${renderMime m.match})"
, "${shellEscapeCommand shellEscape2 file2 m.cmd}"
, ";;"
]
let mimeGlobCase =
λ(g : config.UriMimeGlob) →
List/concatMap
Text
Text
( λ(match : Text) →
[ "${match})", "mime=${renderMime g.mime}", ";;" ]
)
g.glob
: List Text
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"
( ''
# TODO: --dry-run to display what would be opened and why
# partially taken from
# https://github.com/march-linux/mimi/blob/master/xdg-open
set -e
file="$1"
case "$file" in
${prettyLines
{ indent = 2
, lines =
List/concatMap
config.UriMimeGlob
Text
mimeGlobCase
config.uriMimeGlobs
}}
*)
# it’s a file
# strip possible protocol
file=''
++ "\$"
++ ''
{file#file://}
mime=$(file -E --brief --mime-type "$file") \
|| (echo "$mime" 1>&2; exit 1)
# ^ echo the error message of file
;;
esac
case "$mime" in
${prettyLines
{ indent = 2
, lines =
List/concatMap
config.MimeMatch
Text
(mimeMatcherCase shellEscape "\"\$file\"")
(config.mimeMatcher pkgs special)
}}
esac
''
)
in xdg-open
|