refactor mread into taro-reader, clean up some code, fix mouse bug in taro-ls
This commit is contained in:
parent
c3f5e7a041
commit
5f77c7867e
10 changed files with 146 additions and 104 deletions
4
.gitignore
vendored
4
.gitignore
vendored
|
@ -1,4 +1,4 @@
|
||||||
*.rom
|
taro-ls
|
||||||
*.rom.sym
|
*.sym
|
||||||
test*
|
test*
|
||||||
taro-ctl
|
taro-ctl
|
37
README.md
37
README.md
|
@ -4,14 +4,24 @@
|
||||||
|
|
||||||
## build and install
|
## build and install
|
||||||
|
|
||||||
1. [Configure mblaze](https://git.vuxu.org/mblaze/about/man/mblaze-profile.5)
|
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/)
|
2. Install [uxn](https://git.sr.ht/~rabbits/uxn) and [crystal](https://crystal-lang.org/install/)
|
||||||
3. Edit [conf.cr](./conf.cr) and probably the `handle` function in [mread](./mread)
|
3. Edit [config.cr](./config.cr) and probably the `mhandle` function in [taro-reader](./taro-reader)
|
||||||
4. Run [build.sh](./build.sh)
|
4. Run [build.sh](./build.sh)
|
||||||
5. Copy `taro-ctl` to your path
|
5. Copy `taro-ctl` to your path
|
||||||
|
|
||||||
## usage
|
## usage
|
||||||
|
|
||||||
|
`taro` is a multi-window MUA with three types of windows:
|
||||||
|
|
||||||
|
- `taro-ls`: the main `uxn` window where you will check your inbox and organize your mail
|
||||||
|
- `taro-reader`: a terminal window that runs a shell script to read mail
|
||||||
|
- `taro-compose`: a terminal window running `mcom`
|
||||||
|
|
||||||
|
The windows are managed by a master program, `taro-ctl`, which talks to them with `messages` (see below).
|
||||||
|
|
||||||
|
### mail management
|
||||||
|
|
||||||
The `taro-ls` window has three main areas:
|
The `taro-ls` window has three main areas:
|
||||||
|
|
||||||
- Mailboxes: it's assumed by taro-ctrl that your inbox is named INBOX, and it exists; it's put first, and the rest are shown in alphabetical order
|
- Mailboxes: it's assumed by taro-ctrl that your inbox is named INBOX, and it exists; it's put first, and the rest are shown in alphabetical order
|
||||||
|
@ -31,18 +41,35 @@ The buttons on the bottom are as follows (with equivalent keybinds):
|
||||||
|
|
||||||
There is a resize handle in the bottom right - clicking and dragging it resizes the window.
|
There is a resize handle in the bottom right - clicking and dragging it resizes the window.
|
||||||
|
|
||||||
|
### reading mail
|
||||||
|
|
||||||
|
Reading mail is currently done in a terminal that pipes the mail content into `less` and gives some keybind options:
|
||||||
|
|
||||||
|
- `q`: quit
|
||||||
|
- `r`: reply
|
||||||
|
- 'f': forward
|
||||||
|
- 'o': open an attachment - you are presented with the MIME structure of the mail with parts numbered and prompted to select a number to open. The programs to open each mimetype are in the aforementioned `handle` function of the script.
|
||||||
|
- `s`: save an attachment - like `o` but selecting a MIME part saves it to the folder `TARO_DOWNLOADS` in `config.cr`
|
||||||
|
|
||||||
|
The attachment actions loop until you enter nothing or a non-numeric value. The whole script loops until you quit.
|
||||||
|
|
||||||
|
### writing mail
|
||||||
|
|
||||||
|
Writing mail is currently done by opening a terminal and calling `mcom`, which lets you compose in your `EDITOR` of choice and prompts for additional action.
|
||||||
|
|
||||||
|
### crypto
|
||||||
|
|
||||||
If you try to decrypt/sign with either `pinenetry-tty` or `pinentry-curses`, GPG will attach it to the stdio of `taro-ctl`, not the terminal window where you are viewing/composing mail. Use a graphical pinentry program instead.
|
If you try to decrypt/sign with either `pinenetry-tty` or `pinentry-curses`, GPG will attach it to the stdio of `taro-ctl`, not the terminal window where you are viewing/composing mail. Use a graphical pinentry program instead.
|
||||||
|
|
||||||
## TODO
|
## TODO
|
||||||
|
|
||||||
- Make `mread` more user friendly
|
|
||||||
- Implement keybinds for changing mailbox, selecting/scrolling mail, resizing
|
- Implement keybinds for changing mailbox, selecting/scrolling mail, resizing
|
||||||
- Add options to search for case-insensitivity and including body content
|
- Add options to search for case-insensitivity and including body content
|
||||||
- Add option to refile to copy instead of move
|
- Add option to refile to copy instead of move
|
||||||
- Flag/star messages? I never use this fature if IMAP...
|
- Flag/star messages? I never use this fature if IMAP...
|
||||||
- Real `uxn` implementaions of reader/compose windows? Probably overkill
|
- Real `uxn` implementaions of reader/compose windows? Probably overkill
|
||||||
|
|
||||||
## messages
|
## messages (IPC)
|
||||||
|
|
||||||
Messages are in the format `[1][2:3][...]`:
|
Messages are in the format `[1][2:3][...]`:
|
||||||
|
|
||||||
|
@ -53,7 +80,7 @@ Messages are in the format `[1][2:3][...]`:
|
||||||
Even messages go from `taro-ctl` to the `uxn` windows.
|
Even messages go from `taro-ctl` to the `uxn` windows.
|
||||||
|
|
||||||
- `0`: mailbox list (truncated to 4k - this should be enough)
|
- `0`: mailbox list (truncated to 4k - this should be enough)
|
||||||
- `2`: list mail in current mailbox (or search results) (truncated to 32k - if you need more, use search)
|
- `2`: list mail in current mailbox (or search results) (truncated to 32k - if you need more, use search)
|
||||||
|
|
||||||
Odd messages go from the `uxn` windows to `taro-ctl`.
|
Odd messages go from the `uxn` windows to `taro-ctl`.
|
||||||
|
|
||||||
|
|
4
build.sh
4
build.sh
|
@ -1,5 +1,5 @@
|
||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
|
|
||||||
uxnasm taro-ls.tal taro-ls.rom
|
uxnasm taro-ls.tal taro-ls
|
||||||
|
|
||||||
crystal build taro-ctl.cr
|
crystal build taro-ctl.cr
|
||||||
|
|
3
conf.cr
3
conf.cr
|
@ -1,3 +0,0 @@
|
||||||
TARO_LIB = "/home/nilix/src/taro/"
|
|
||||||
READER_PROG = "st -t \"taro-reader\" -e #{TARO_LIB}/mread"
|
|
||||||
COMPOSE_PROG = "st -t \"taro-compose\" -e mcom"
|
|
8
config.cr
Normal file
8
config.cr
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
# where the rom and scripts will live
|
||||||
|
TARO_LIB = "/home/nilix/src/taro"
|
||||||
|
# where attachments are saved
|
||||||
|
TARO_DOWNLOADS = "/home/nilix/tmp"
|
||||||
|
|
||||||
|
# terminal commands to wrap reading and writing mail
|
||||||
|
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"
|
5
lesskey
Normal file
5
lesskey
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
r quit r
|
||||||
|
f quit f
|
||||||
|
o quit o
|
||||||
|
s quit s
|
||||||
|
q quit q
|
74
mread
74
mread
|
@ -1,74 +0,0 @@
|
||||||
#!/bin/sh
|
|
||||||
|
|
||||||
mhandle() {
|
|
||||||
case $2 in
|
|
||||||
text/html)
|
|
||||||
cp $1 ${1}.html
|
|
||||||
netsurf ${1}.html
|
|
||||||
rm ${1}.html;;
|
|
||||||
image/*)
|
|
||||||
qiv $1;;
|
|
||||||
audio/*|video/*)
|
|
||||||
mpv $1;;
|
|
||||||
pgp/encrypted)
|
|
||||||
gpg --decrypt $1;;
|
|
||||||
application/vnd*)
|
|
||||||
libreoffice $1;;
|
|
||||||
application/pdf)
|
|
||||||
zathura $1;;
|
|
||||||
esac
|
|
||||||
}
|
|
||||||
|
|
||||||
_mread() {
|
|
||||||
local META
|
|
||||||
mflag -S ${this}
|
|
||||||
local this=$(mseq $@)
|
|
||||||
while true; do
|
|
||||||
mshow ${this}
|
|
||||||
|
|
||||||
while true; do
|
|
||||||
META=""
|
|
||||||
printf "\n"
|
|
||||||
mshow -t
|
|
||||||
printf "\n"
|
|
||||||
printf "[1..n] view attachment (add s to save)\n"
|
|
||||||
printf "[r]reply, [f]orward, [q]uit\n"
|
|
||||||
read cmd
|
|
||||||
|
|
||||||
case ${cmd} in
|
|
||||||
1|2|3|4|5|6|7|8|9|10|\
|
|
||||||
11|12|13|14|15|16|17|18|19|20)
|
|
||||||
attachment=$(mktemp)
|
|
||||||
mshow -O . ${cmd} > ${attachment}
|
|
||||||
mimetype=$(mshow -t | grep ${cmd}: | awk '{print $2}')
|
|
||||||
mhandle ${attachment} ${mimetype}
|
|
||||||
rm ${attachment};;
|
|
||||||
1s|2s|3s|4s|5s|6s|7s|8s|9s|10s|\
|
|
||||||
11s|12s|13s|14s|15s|16s|17s|18s|19s|20s)
|
|
||||||
mshow -x . ${cmd%s};;
|
|
||||||
q|quit)
|
|
||||||
META=q;;
|
|
||||||
r|reply)
|
|
||||||
META=r;;
|
|
||||||
f|forward)
|
|
||||||
META=f;;
|
|
||||||
esac
|
|
||||||
|
|
||||||
[ ! -z "${META}" ] && break;
|
|
||||||
done
|
|
||||||
this="."
|
|
||||||
case ${META} in
|
|
||||||
f)
|
|
||||||
mfwd ${this};;
|
|
||||||
r)
|
|
||||||
mrep ${this};;
|
|
||||||
q)
|
|
||||||
return;;
|
|
||||||
*)
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
mseq -f | mseq -S
|
|
||||||
done
|
|
||||||
}
|
|
||||||
|
|
||||||
_mread $@
|
|
26
taro-ctl.cr
26
taro-ctl.cr
|
@ -2,7 +2,7 @@ require "process"
|
||||||
require "io/memory"
|
require "io/memory"
|
||||||
require "io"
|
require "io"
|
||||||
|
|
||||||
require "./conf"
|
require "./config"
|
||||||
|
|
||||||
MSG_SIZES = {
|
MSG_SIZES = {
|
||||||
0_u8 => 4096_u16,
|
0_u8 => 4096_u16,
|
||||||
|
@ -44,13 +44,11 @@ module Taro
|
||||||
|
|
||||||
class ChildWindow
|
class ChildWindow
|
||||||
@@msg : Channel(Mesg) = Channel(Mesg).new
|
@@msg : Channel(Mesg) = Channel(Mesg).new
|
||||||
@@id : UInt16 = 0_u16
|
|
||||||
|
|
||||||
def self.msg
|
def self.msg
|
||||||
@@msg
|
@@msg
|
||||||
end
|
end
|
||||||
|
|
||||||
@id : UInt16
|
|
||||||
@lifetime : Channel(UInt8)
|
@lifetime : Channel(UInt8)
|
||||||
@stdout_w : IO::FileDescriptor
|
@stdout_w : IO::FileDescriptor
|
||||||
@stdout_r : IO::FileDescriptor
|
@stdout_r : IO::FileDescriptor
|
||||||
|
@ -64,22 +62,20 @@ module Taro
|
||||||
@stdout_r, @stdout_w = IO.pipe
|
@stdout_r, @stdout_w = IO.pipe
|
||||||
@stdin_r, @stdin_w = IO.pipe
|
@stdin_r, @stdin_w = IO.pipe
|
||||||
@lifetime = Channel(UInt8).new
|
@lifetime = Channel(UInt8).new
|
||||||
@id = @@id
|
|
||||||
@@id += 1
|
|
||||||
|
|
||||||
uxnrom : String = ""
|
uxnrom : String = ""
|
||||||
|
|
||||||
case w
|
|
||||||
when WinType::LIST then uxnrom = "taro-ls"
|
|
||||||
when WinType::READER then uxnrom = "taro-reader"
|
|
||||||
when WinType::COMPOSE then uxnrom = "taro-compose"
|
|
||||||
end
|
|
||||||
|
|
||||||
uxnargs = ["-s", "1", "#{TARO_LIB}/#{uxnrom}.rom"]
|
uxnargs = ["-s", "1", "#{TARO_LIB}/#{uxnrom}.rom"]
|
||||||
case w
|
case w
|
||||||
when WinType::LIST then
|
when WinType::LIST then
|
||||||
spawn do
|
spawn do
|
||||||
Process.run(command: "uxnemu", args: uxnargs, input: @stdin_r, output: @stdout_w, error: Process::Redirect::Inherit)
|
Process.run(
|
||||||
|
command: "uxnemu",
|
||||||
|
args: [ "-s", "1", "taro-ls" ],
|
||||||
|
chdir: TARO_LIB,
|
||||||
|
input: @stdin_r,
|
||||||
|
output: @stdout_w,
|
||||||
|
error: Process::Redirect::Inherit)
|
||||||
@lifetime.send(0)
|
@lifetime.send(0)
|
||||||
end
|
end
|
||||||
spawn do
|
spawn do
|
||||||
|
@ -101,10 +97,6 @@ module Taro
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def id
|
|
||||||
@id
|
|
||||||
end
|
|
||||||
|
|
||||||
def lifetime
|
def lifetime
|
||||||
@lifetime
|
@lifetime
|
||||||
end
|
end
|
||||||
|
|
10
taro-ls.tal
10
taro-ls.tal
|
@ -243,7 +243,11 @@ JMP2r
|
||||||
JMP2r
|
JMP2r
|
||||||
|
|
||||||
@send_reader ( -> )
|
@send_reader ( -> )
|
||||||
|
|
||||||
|
( reset the mouse state since if a window opens over the uxn window mid-click
|
||||||
|
and steals focus, the click never releases until we click the button again )
|
||||||
|
|
||||||
|
#00 .Mouse/state DEO
|
||||||
READ_MAIL .Console/write DEO
|
READ_MAIL .Console/write DEO
|
||||||
#0002 SWP .Console/write DEO .Console/write DEO
|
#0002 SWP .Console/write DEO .Console/write DEO
|
||||||
.list LB_SELECT_IDX LDZ2 INC2 SWP .Console/write DEO .Console/write DEO
|
.list LB_SELECT_IDX LDZ2 INC2 SWP .Console/write DEO .Console/write DEO
|
||||||
|
@ -252,6 +256,10 @@ JMP2r
|
||||||
|
|
||||||
@send_compose ( -> )
|
@send_compose ( -> )
|
||||||
|
|
||||||
|
( reset the mouse state since if a window opens over the uxn window mid-click
|
||||||
|
and steals focus, the click never releases until we click the button again )
|
||||||
|
|
||||||
|
#00 .Mouse/state DEO
|
||||||
COMPOSE_MAIL .Console/write DEO
|
COMPOSE_MAIL .Console/write DEO
|
||||||
#00 .Console/write DEOk DEO
|
#00 .Console/write DEOk DEO
|
||||||
( message size is 0, no payload )
|
( message size is 0, no payload )
|
||||||
|
|
79
taro-reader
Executable file
79
taro-reader
Executable file
|
@ -0,0 +1,79 @@
|
||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
mhandle() {
|
||||||
|
case $2 in
|
||||||
|
text/html)
|
||||||
|
cp $1 ${1}.html
|
||||||
|
netsurf ${1}.html
|
||||||
|
rm ${1}.html;;
|
||||||
|
image/*)
|
||||||
|
qiv $1;;
|
||||||
|
audio/*|video/*)
|
||||||
|
mpv $1;;
|
||||||
|
pgp/encrypted)
|
||||||
|
gpg --decrypt $1;;
|
||||||
|
application/vnd*)
|
||||||
|
libreoffice $1;;
|
||||||
|
application/pdf)
|
||||||
|
zathura $1;;
|
||||||
|
esac
|
||||||
|
}
|
||||||
|
|
||||||
|
save_attachments() {
|
||||||
|
while true; do
|
||||||
|
printf "\n"
|
||||||
|
mshow -t
|
||||||
|
printf "\n"
|
||||||
|
|
||||||
|
printf "select an attachment to save: "
|
||||||
|
read n
|
||||||
|
case ${n} in
|
||||||
|
''|*[!0-9]*) return ;;
|
||||||
|
*) file=$(mshow -x . ${n}); mv ${file} ${TARO_DOWNLOADS} ;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
}
|
||||||
|
|
||||||
|
open_attachments() {
|
||||||
|
while true; do
|
||||||
|
printf "\n"
|
||||||
|
mshow -t
|
||||||
|
printf "\n"
|
||||||
|
|
||||||
|
printf "select an attachment to open: "
|
||||||
|
read n
|
||||||
|
case $n in
|
||||||
|
''|*[!0-9]*) return ;;
|
||||||
|
*) attachment=$(mktemp)
|
||||||
|
mshow -O . ${n} > ${attachment}
|
||||||
|
mimetype=$(mshow -t | grep ${n}: | awk '{print $2}')
|
||||||
|
mhandle ${attachment} ${mimetype}
|
||||||
|
rm ${attachment};;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
}
|
||||||
|
|
||||||
|
mread() {
|
||||||
|
local META
|
||||||
|
mflag -S ${this}
|
||||||
|
local this=$(mseq $@)
|
||||||
|
local action="q"
|
||||||
|
while true; do
|
||||||
|
(mshow ${this} ; printf "\n"; mshow -t ${this}; printf "\n" ; printf "[o]pen or [s]ave attachments\n" ; printf "[r]reply, [f]orward, [q]uit\n")| less --mouse
|
||||||
|
|
||||||
|
case $? in
|
||||||
|
113) #q
|
||||||
|
break;;
|
||||||
|
102) #f
|
||||||
|
mfwd ${this};;
|
||||||
|
114) #r
|
||||||
|
mrep ${this};;
|
||||||
|
115) #s
|
||||||
|
save_attachments;;
|
||||||
|
111) #o
|
||||||
|
open_attachments;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
}
|
||||||
|
|
||||||
|
mread $@
|
Loading…
Reference in a new issue