diff --git a/.gitignore b/.gitignore index 5534bc9..b197394 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,5 @@ taro-ls *.sym test* -taro-ctl \ No newline at end of file +taro-ctl +taro.sock \ No newline at end of file diff --git a/README.md b/README.md index d3ea7f5..aa98dbc 100644 --- a/README.md +++ b/README.md @@ -6,10 +6,24 @@ 1. [Install and configure mblaze](https://git.vuxu.org/mblaze/about/man/mblaze-profile.5) 2. Install [uxn](https://git.sr.ht/~rabbits/uxn) and [crystal](https://crystal-lang.org/install/) -3. Edit [config.cr](./config.cr) and probably the `mhandle` function in [taro-reader](./taro-reader) +3. Edit [config.cr](./config.cr) and probably the `mhandle` function in [taro-reader](./taro-reader) (see next section) 4. Run [build.sh](./build.sh) 5. Copy `taro-ctl` to your path +## configuration + +The `config.cr` file is a bunch of constants for `taro-ctl` to use. Adjust them to your needs: + +- `MBOX_ROOT`: the directory where your maildirs are +- `TARO_LIB`: the directory where the `taro-ls` rom, `taro-reader` script, `lesskey` file, and `taro.sock` files go (probably just where you cloned this repository. +- `TARO_DOWNLOADS`: directory where attachments are downloaded to +- `UXN_EMU`: name of the `uxnemu` executable. You can copy `uxnemu` to, eg `taro` and it will have that _NET_WM_CLASS +- `TARO_ENV`: environment variables as you type them in the terminal, that you can use for the `READER_PROG` and `COMPOSE_PROG` commands +- `READER_PROG`: command to spawn to read mail - by default it calls the `st` terminal with some environment variables and options set, and runs `taro-reader` +- `COMPOSE_PROG`: command to spawn to write mail - by default it calls the `st` terminal with some environment variables and options set and runs `mcom` from `mblaze` + +Environment variable and tilde expansion in the config are not supported. + ## usage `taro` is a multi-window MUA with three types of windows: @@ -93,4 +107,8 @@ Odd messages go from the `uxn` windows to `taro-ctl` (or from `taro-ctl` to itse - `9`: trash mail; payload is the beginning and end of the mmsg range in u16 - `11`: read mail; payload is a single u16 message number in the current sequence - `13`: compose mail; no payload -- `15`: push view update (keeps search query, for after replying/writing mail) +- `15`: push view update (keeps search query, for after replying/writing mail or when new mail comes in) + +## socket (other IPC) + +`taro-ctl` creates a socket at `TARO_LIB/taro.sock` and listens for bytes on it. Every time a byte is written to the socket, `taro-ctl` will use message `15` to update the inbox. Whatever method you use to sync your maildirs to your mailserver, it can write a byte to this socket when you receive mail! \ No newline at end of file diff --git a/config.cr b/config.cr index a1c3c3c..bb2ce4b 100644 --- a/config.cr +++ b/config.cr @@ -5,7 +5,13 @@ TARO_LIB = "/home/nilix/src/taro" # where attachments are saved TARO_DOWNLOADS = "/home/nilix/tmp" +# name of the uxnemu program - I copy it to taro so it gets the _NET_WM_CLASS=taro +UXN_EMU = "taro" + +# custom environment variables you may want to set +TARO_ENV = "PINENTRY_USER_DATA=taro EDITOR=micro" + # terminal commands to wrap reading and writing mail # use your own favorite terminal - cmdline syntax may differ -READER_PROG = "TARO_DOWNLOADS=#{TARO_DOWNLOADS} LESSKEYIN=#{TARO_LIB}/lesskey st -t \"taro-reader\" -e #{TARO_LIB}/taro-reader" -COMPOSE_PROG = "st -t \"taro-compose\" -e mcom" +READER_PROG = "#{TARO_ENV} TARO_DOWNLOADS=#{TARO_DOWNLOADS} LESSKEYIN=#{TARO_LIB}/lesskey st -c taro -n taro -t \"taro-reader\" -e #{TARO_LIB}/taro-reader" +COMPOSE_PROG = "#{TARO_ENV} st -c taro -n taro -t \"taro-compose\" -e mcom" diff --git a/taro-ctl.cr b/taro-ctl.cr index 7fff63a..da3e92e 100644 --- a/taro-ctl.cr +++ b/taro-ctl.cr @@ -1,6 +1,6 @@ require "process" -require "io/memory" require "io" +require "socket" require "./config" @@ -70,8 +70,9 @@ module Taro when WinType::LIST then spawn do Process.run( - command: "uxnemu", + command: UXN_EMU, args: [ "-s", "1", "taro-ls" ], + shell: true, chdir: TARO_LIB, input: @stdin_r, output: @stdout_w, @@ -213,13 +214,15 @@ module Taro end def refile_mail(range_start : UInt16, range_end : UInt16, to_mbox : String) - cmd = "mrefile #{range_start}:#{range_end} #{MBOX_ROOT}/#{to_mbox}" + to_mbox = to_mbox.gsub("'", "\'").gsub("../", "./").gsub("..", "") + cmd = "mrefile #{range_start}:#{range_end} '#{MBOX_ROOT}/#{to_mbox}'" run_cmd(cmd) end def search_mail(query : String, body : Bool, case_sensitive : Bool) : String + query = query.gsub("'", "\'") @@search_regex = query - cmd = "mlist #{MBOX_ROOT}/#{@@mailbox} | magrep #{case_sensitive ? "" : "-i"} #{body ? "/" : "*"}:#{query} | msort -dr | uniq | mseq -S | mscan" + cmd = "mlist #{MBOX_ROOT}/#{@@mailbox} | magrep #{case_sensitive ? "" : "-i"} #{body ? "/" : "*"}:'#{query}' | msort -dr | uniq | mseq -S | mscan" return run_cmd(cmd) end end @@ -263,10 +266,23 @@ module Taro end taro = Taro::TaroCtl.new +srv = UNIXServer.new("#{TARO_LIB}/taro.sock") + +spawn do + while client = srv.accept? + spawn do + b = Slice(UInt8).new(1) + client.read(b) + Taro::ChildWindow.msg.send(Taro::Mesg.new(15_u8, Slice(UInt8).new(0))) + end + end +end + loop do select when taro.mainWindow.lifetime.receive? + srv.close exit when m = Taro::ChildWindow.msg.receive case m.type diff --git a/taro-ls.tal b/taro-ls.tal index 0aacdf7..86496a3 100644 --- a/taro-ls.tal +++ b/taro-ls.tal @@ -1115,7 +1115,7 @@ JMP2r @font [ 00 00 00 00 00 00 00 00 00 18 18 18 08 00 08 00 00 14 14 00 00 00 00 00 00 24 7e 24 24 7e 24 00 00 10 3c 50 38 14 78 10 00 00 44 08 10 20 44 00 00 18 20 32 2c 24 1a 00 00 18 10 20 00 00 00 00 - 00 04 08 08 08 08 04 00 00 20 10 10 10 10 20 00 00 00 44 28 10 28 44 00 00 00 10 10 7c 10 10 00 + 00 04 08 08 08 08 04 00 00 20 10 10 10 10 20 00 00 10 54 28 10 28 54 10 00 00 10 10 7c 10 10 00 00 00 00 00 00 0c 08 10 00 00 00 00 3e 00 00 00 00 00 00 00 00 0c 0c 00 00 02 04 08 10 20 40 00 00 38 44 54 54 44 38 00 00 30 10 10 10 10 38 00 00 38 44 04 38 40 7c 00 00 38 44 18 04 44 38 00 00 08 18 28 48 7c 08 00 00 7c 40 78 04 44 38 00 00 38 40 78 44 44 38 00 00 7c 04 08 10 10 10 00 @@ -1132,7 +1132,7 @@ JMP2r 00 18 08 04 00 00 00 00 00 00 38 04 3c 44 3c 00 00 40 40 78 44 44 78 00 00 00 38 44 40 44 38 00 00 04 04 3c 44 44 3c 00 00 00 38 44 7c 40 3c 00 00 1c 20 78 20 20 20 00 00 00 3c 44 3c 04 44 38 00 40 40 78 44 44 44 00 00 30 00 70 10 10 18 00 00 0c 00 3c 04 04 44 38 00 00 44 48 70 48 44 00 - 00 70 10 10 10 10 1c 00 00 00 44 6c 7c 54 44 00 00 00 78 44 44 44 44 00 00 00 38 44 44 44 38 00 + 00 70 10 10 10 10 1c 00 00 00 78 54 54 54 44 00 00 00 78 44 44 44 44 00 00 00 38 44 44 44 38 00 00 00 78 44 44 78 40 40 00 00 3c 44 44 3d 06 04 00 00 4c 50 60 40 40 00 00 00 3c 40 38 04 78 00 00 20 78 20 20 24 38 00 00 00 44 44 44 44 3c 00 00 00 44 44 28 28 10 00 00 00 44 44 54 7c 28 00 00 00 44 28 10 28 44 00 00 00 44 44 3c 04 78 00 00 00 7c 04 38 40 7c 00 00 1e 10 10 10 00 00 00