taro-ls: add theme, font-loading support, more keybinds, finishing touches; build, readme, assets...

This commit is contained in:
Iris Lightshard 2023-03-27 22:54:20 -06:00
parent 0b85806136
commit 6b797697e7
Signed by: Iris Lightshard
GPG key ID: 3B7FBC22144E6398
11 changed files with 300 additions and 84 deletions

3
.gitignore vendored
View file

@ -2,4 +2,5 @@ taro-ls
*.sym *.sym
test* test*
taro-ctl taro-ctl
taro.sock taro.sock
config.cr

View file

@ -2,28 +2,43 @@
[mblaze](https://git.vuxu.org/mblaze) frontend in [uxn](https://wiki.xxiivv.com/site/uxn.html) and [crystal](https://crystal-lang.org) [mblaze](https://git.vuxu.org/mblaze) frontend in [uxn](https://wiki.xxiivv.com/site/uxn.html) and [crystal](https://crystal-lang.org)
[![screenshot - taro-ls showing Archives/2022 mailbox selected with a search query active listing mail from the uxn mailing list, and a reader window open next to it reading the initial uxn metadata proposal, with a prompt at the bottom for managing attachments, replying, forwarding, or quitting](./screenshot.png)](./screenshot.png)
## build and install ## build and install
1. [Install and configure mblaze](https://git.vuxu.org/mblaze/about/man/mblaze-profile.5) 1. [Install](https://git.vuxu.org/mblaze) and [configure mblaze](https://git.vuxu.org/mblaze/about/man/mblaze-profile.5) (as well as probably [mbsync](https://isync.sourceforge.io) and [msmtp](https://marlam.de/msmtp))
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 [config.cr](./config.cr) and probably the `mhandle` function in [taro-reader](./taro-reader) (see next section) 3. Edit [config](./config) and probably the `mhandle` function in [taro-reader](./taro-reader) (see next section)
4. Run [build.sh](./build.sh) 4. Run [build.sh](./build.sh) (optionally with the `desktopfile` argument to fill out the `taro.desktop` file and put it in your user-level apps)
5. Copy `taro-ctl` to your path 5. Copy `taro-ctl` to your path
## configuration ## configuration
The `config.cr` file is a bunch of constants for `taro-ctl` to use. Adjust them to your needs: ### taro-ctl
- `MBOX_ROOT`: the directory where your maildirs are The `config` file is processed into a bunch of constants for `taro-ctl` by the build script. Adjust them to your needs:
- `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 - `MBOX_ROOT`: the directory where your maildirs are.
- `UXN_EMU`: name of the `uxnemu` executable. You can copy `uxnemu` to, eg `taro` and it will have that _NET_WM_CLASS - `TARO_LIB`: the directory where your runtime files (`taro-ls` rom, `taro-reader` script, `.theme` and `font.icn` files, etc.) will be installed to; probably just where you clone this repo to.
- `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 - `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` - `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` - `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. Environment variable and tilde expansion in the config are not supported.
### taro-ls
The [.theme](https://wiki.xxiivv.com/site/theme.html) file format is supported - it can be crafted with [nasu](https://git.sr.ht/~rabbits/nasu) and should be located at `TARO_LIB/.theme`. The following details the purpose (and default) of each color:
1. Background and text color when hilighted (black)
2. Hilight, scrollbar, button hover color (turquoise)
3. Soft fg color eg. resize handle, textbox help (medium gray)
4. Foreground/text color (whitish gray)
Any 8x8 1bpp ASCII font in [icn](https://wiki.xxiivv.com/site/icn_format.html) format can be used. They can be created/edited in [nasu](https://git.sr.ht/~rabbits/nasu) and located at `TARO_LIB/font.icn`.
## usage ## usage
`taro` is a multi-window MUA with three types of windows: `taro` is a multi-window MUA with three types of windows:
@ -48,13 +63,20 @@ The buttons on the bottom are as follows (with equivalent keybinds):
- compose [`n`]: open a compose window to write new mail - compose [`n`]: open a compose window to write new mail
- refresh [`r`]: refresh the current mailbox, removing search query - refresh [`r`]: refresh the current mailbox, removing search query
- mark all read ['.']: this - mark all read [`.`]: this
- search [`/`]: search mail with a regex (only headers, case insensitive) - search [`/`]: search mail with a regex (only headers, case insensitive)
- refile [`m`]: move mail to the given folder - refile [`m`]: move mail to the given folder
- trash [`Del`]: move mail to the Trash folder, unless it's already in the Trash, in which case it's deleted - trash [`Del`]: move mail to the Trash folder, unless it's already in the Trash, in which case it's deleted
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.
Additional keybindings:
- `[shift+]tab`: change mailboxes
- `up/down`: navigate through mail
- `shift+<up|down>`: naive multiselect
- `alt+<up|down|left|right>`: resize
At the bottom-left, a small indicator will appear if you have a search query active. Performing the refresh action or switching mailboxes will make it disappear. At the bottom-left, a small indicator will appear if you have a search query active. Performing the refresh action or switching mailboxes will make it disappear.
### reading mail ### reading mail
@ -63,8 +85,8 @@ Reading mail is currently done in a terminal that pipes the mail content into `l
- `q`: quit - `q`: quit
- `r`: reply - `r`: reply
- 'f': forward - `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. - `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` - `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. The attachment actions loop until you enter nothing or a non-numeric value. The whole script loops until you quit.
@ -79,8 +101,7 @@ If you try to decrypt/sign with either `pinenetry-tty` or `pinentry-curses`, GPG
## TODO ## TODO
- Implement keybinds for changing mailbox, selecting/scrolling mail, resizing - Add options to search (case-sensitive, search mail body, etc)
- 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
@ -103,9 +124,9 @@ Odd messages go from the `uxn` windows to `taro-ctl` (or from `taro-ctl` to itse
- `1`: change/refresh mailbox; payload is the mailbox to read - `1`: change/refresh mailbox; payload is the mailbox to read
- `3`: mark all as read in current mailbox; no payload - `3`: mark all as read in current mailbox; no payload
- `5`: search mail; payload is the regex - `5`: search mail; payload is the regex
- `7`: refile mail; payload is the beginning and end of the mmsg range in u16, and then the mailbox name - `7`: refile mail; payload is the beginning and end of the `mmsg` range in u16, and then the mailbox name
- `9`: trash mail; payload is the beginning and end of the mmsg range in u16 - `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 - `11`: read mail; payload is a single u16 `mmsg` number in the current sequence
- `13`: compose mail; no payload - `13`: compose mail; no payload
- `15`: push view update (keeps search query, for after replying/writing mail or when new mail comes in) - `15`: push view update (keeps search query, for after replying/writing mail or when new mail comes in)

View file

@ -1,5 +1,43 @@
#!/bin/sh #!/bin/sh
uxnasm taro-ls.tal taro-ls # build config into crystal constants
echo "Generating config.cr"
crystal build taro-ctl.cr . ./config
cat << END > config.cr
MBOX_ROOT = "${MBOX_ROOT}"
TARO_LIB = "${TARO_LIB}"
TARO_DOWNLOADS = "${TARO_DOWNLOADS}"
UXN_EMU = "${UXN_EMU}"
TARO_ENV = "${TARO_ENV}"
READER_PROG = "${READER_PROG}"
COMPOSE_PROG = "${COMPOSE_PROG}"
END
if ! which ${UXN_EMU}; then
echo "${UXN_EMU} is not in PATH! Beware..."
sleep 1
fi
# build
echo "Building taro-ls"
uxnasm taro-ls.tal taro-ls
echo "Building taro-ctl"
crystal build --release --no-debug -s taro-ctl.cr
# setup TARO_LIB
if [ ${TARO_LIB} != ${PWD} ]; then
mkdir -p ${TARO_LIB}
for x in "taro-ls taro-reader lesskey .theme font.icn taro-ctl taro.svg"; do
if [ -e ${x} ]; then
cp ${x} ${TARO_LIB}
fi
done
echo "TARO_LIB is in ${TARO_LIB}; add it to your PATH or you can just copy taro-ctl there."
fi
if [ "$1" = "desktopfile" ]; then
sed -e "s#TARO_LIB#${TARO_LIB}#g" -e "s#UXN_EMU#${UXN_EMU}#g" taro.desktop > ~/.local/share/applications/taro.desktop
fi

16
config Normal file
View file

@ -0,0 +1,16 @@
# where your maildir folders live
MBOX_ROOT=${HOME}/lib/mail/zoho
# where runtime files live (probably this git repo for simplicity)
TARO_LIB=${PWD}
# where attachments are saved to
TARO_DOWNLOADS=${HOME}/tmp
# name of your uxnemu executable; it must be in PATH; i copy mine to "taro" so it gets the _NET_WM_CLASS=taro
UXN_EMU=taro
# any custom env you want to set for reader/compose wins
TARO_ENV="PINENTRY_USER_DATA=taro"
# reader and compose progs - I use st, you may use your own terminal although the command line options may differ so read the manual
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"

View file

@ -1,17 +0,0 @@
# where your maildir folders live
MBOX_ROOT = "/home/nilix/lib/mail/zoho"
# where the rom and scripts will live (probably the git repo)
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_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"

BIN
font.icn Normal file

Binary file not shown.

BIN
screenshot.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 334 KiB

View file

@ -76,6 +76,9 @@
#028d .System/r DEO2 #028d .System/r DEO2
#0a8d .System/g DEO2 #0a8d .System/g DEO2
#098d .System/b DEO2 #098d .System/b DEO2
load_theme
load_font
#0280 .Screen/width DEO2 #0280 .Screen/width DEO2
#01c0 .Screen/height DEO2 #01c0 .Screen/height DEO2
@ -90,6 +93,7 @@
#01 .refresh/btns STZ #01 .refresh/btns STZ
#01 .refresh/fg STZ #01 .refresh/fg STZ
#01 .refresh/etc STZ
#03 .btn_colors/compose STZ #03 .btn_colors/compose STZ
#03 .btn_colors/refresh STZ #03 .btn_colors/refresh STZ
@ -158,6 +162,8 @@ BRK
&count_2 &count_2
.Console/read DEI .decoding/count INC STZ .Console/read DEI .decoding/count INC STZ
#00 .decoding/counting STZ #00 .decoding/counting STZ
( handle empty payload )
.decoding/count LDZ2 #0000 NEQ2 ,&has_data JCN .decoding/count LDZ2 #0000 NEQ2 ,&has_data JCN
.decoding/msg_type LDZ .decoding/msg_type LDZ
DUP MBOX_LIST NEQ ,&no_mbox_empty JCN DUP MBOX_LIST NEQ ,&no_mbox_empty JCN
@ -203,6 +209,10 @@ JMP2r
;selected_mbox strlen SWP .Console/write DEO .Console/write DEO ;selected_mbox strlen SWP .Console/write DEO .Console/write DEO
;selected_mbox send_str ;selected_mbox send_str
#0000 .list/select_index STZ2
#0001 .list/select_len STZ2
#0000 .list/top STZ2
#00 .textbox/searching STZ #00 .textbox/searching STZ
#01 .refresh/etc STZ #01 .refresh/etc STZ
@ -251,8 +261,8 @@ JMP2r
( reset the mouse state since if a window opens over the uxn window mid-click ( 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 ) and steals focus, the click never releases until we click the button again )
#00 .Mouse/state DEO #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
@ -263,8 +273,8 @@ JMP2r
( reset the mouse state since if a window opens over the uxn window mid-click ( 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 ) and steals focus, the click never releases until we click the button again )
#00 .Mouse/state DEO #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 )
@ -297,14 +307,7 @@ JMP2r
BRK BRK
&no_text_entry &no_text_entry
( TODO: add shortcuts for common actions ( check keys for shortcuts )
- up/dn: change selection (mail)
- tab: change selection (mailbox)
- shift+up/dn: multiselect
- return: read (first in selection)
- n: compose
)
.Controller/key DEI .Controller/key DEI
DUP #7f NEQ ,&no_del JCN DUP #7f NEQ ,&no_del JCN
send_trash send_trash
@ -330,8 +333,9 @@ JMP2r
DUP #09 NEQ ,&no_tab JCN DUP #09 NEQ ,&no_tab JCN
;mbox_select_handler .mboxes [ .Controller/button DEI #04 AND ] nav_list_by_key ;mbox_select_handler .mboxes [ .Controller/button DEI #04 AND ] nav_list_by_key
&no_tab &no_tab
&check_btns
POP POP
( check buttons (LRUD, tab, shift, alt) for shortcuts )
.Controller/button DEI .Controller/button DEI
DUP #10 NEQ ,&no_up JCN DUP #10 NEQ ,&no_up JCN
;noop_list_click .list #01 nav_list_by_key ;noop_list_click .list #01 nav_list_by_key
@ -340,13 +344,80 @@ JMP2r
;noop_list_click .list #00 nav_list_by_key ;noop_list_click .list #00 nav_list_by_key
&no_down &no_down
DUP #14 NEQ ,&no_select_up JCN DUP #14 NEQ ,&no_select_up JCN
#01 change_select_len_by_key
#01 .refresh/list STZ
&no_select_up &no_select_up
DUP #24 NEQ ,&no_select_down JCN DUP #24 NEQ ,&no_select_down JCN
#00 change_select_len_by_key
#01 .refresh/list STZ
&no_select_down &no_select_down
DUP #12 NEQ ,&no_dec_y JCN
#10 resize_by_keyboard
&no_dec_y
DUP #22 NEQ ,&no_inc_y JCN
#20 resize_by_keyboard
&no_inc_y
DUP #42 NEQ ,&no_dec_x JCN
#40 resize_by_keyboard
&no_dec_x
DUP #82 NEQ ,&no_inc_x JCN
#80 resize_by_keyboard
&no_inc_x
POP POP
BRK BRK
@resize_by_keyboard ( dir -- )
DUP #10 NEQ ,&no_up JCN
.Screen/height DEI2 #0100 EQU2 ,&no_down JCN
.Screen/height DEI2 #0008 SUB2 .Screen/height DEO2
&no_up
DUP #20 NEQ ,&no_down JCN
.Screen/height DEI2 #0008 ADD2 .Screen/height DEO2
&no_down
DUP #40 NEQ ,&no_left JCN
.Screen/width DEI2 #0100 EQU2 ,&no_down JCN
.Screen/width DEI2 #0008 SUB2 .Screen/width DEO2
&no_left
DUP #80 NEQ ,&no_right JCN
.Screen/width DEI2 #0008 ADD2 .Screen/width DEO2
&no_right
POP
#01 .refresh/list STZ
#01 .refresh/mboxes STZ
#01 .refresh/textbox STZ
#01 .refresh/btns STZ
#01 .refresh/etc STZ
#01 .refresh/fg STZ
JMP2r
@change_select_len_by_key ( up? -- )
,&back JCN
( fwd )
.list/select_index LDZ2 .list/select_len LDZ2 ADD2 .list/len LDZ2 LTH2 ,&inc_sel_len JCN
JMP2r &inc_sel_len
.list/select_len LDZ2 INC2 .list/select_len STZ2
.list/top LDZ2 #00 .list/height LDZ ADD2 .list/select_index LDZ2 .list/select_len LDZ2 ADD2 LTH2 ,&scroll_down JCN
JMP2r &scroll_down
.list/top LDZ2 INC2 .list/top STZ2
JMP2r
&back
.list/select_len LDZ2 #0001 GTH2 ,&dec_sel_len JCN
JMP2r &dec_sel_len
.list/select_len LDZ2 #0001 SUB2 .list/select_len STZ2
.list/top LDZ2 INC2 .list/select_index LDZ2 .list/select_len LDZ2 ADD2 GTH2 ,&scroll_up JCN
JMP2r &scroll_up
.list/top LDZ2 #0001 SUB2 .list/top STZ2
JMP2r
@nav_list_by_key ( onchange* list up? -- ) @nav_list_by_key ( onchange* list up? -- )
,&back JCN ,&back JCN
( fwd ) ( fwd )
STHk LB_SELECT_IDX LDZ2 INC2 STHkr LB_LEN LDZ2 NEQ2 ,&can_go_fwd JCN STHk LB_SELECT_IDX LDZ2 INC2 STHkr LB_LEN LDZ2 NEQ2 ,&can_go_fwd JCN
@ -359,6 +430,7 @@ BRK
STHkr LB_SELECT_IDX LDZ2 #00 STHkr LB_HEIGHT LDZ STHkr LB_TOP LDZ2 ADD2 LTH2 ,&no_scroll_down JCN STHkr LB_SELECT_IDX LDZ2 #00 STHkr LB_HEIGHT LDZ STHkr LB_TOP LDZ2 ADD2 LTH2 ,&no_scroll_down JCN
STHkr LB_TOP LDZ2 INC2 STHkr LB_TOP STZ2 STHkr LB_TOP LDZ2 INC2 STHkr LB_TOP STZ2
&no_scroll_down ,&end JMP &no_scroll_down ,&end JMP
&back &back
STHk LB_SELECT_IDX LDZ2 #0000 NEQ2 ,&can_go_back JCN STHk LB_SELECT_IDX LDZ2 #0000 NEQ2 ,&can_go_back JCN
STHkr LB_LEN LDZ2 #0001 SUB2 STHkr LB_SELECT_IDX STZ2 STHkr LB_LEN LDZ2 #0001 SUB2 STHkr LB_SELECT_IDX STZ2
@ -368,12 +440,15 @@ BRK
STHkr LB_SELECT_IDX LDZ2 #0001 SUB2 STHkr LB_SELECT_IDX STZ2 STHkr LB_SELECT_IDX LDZ2 #0001 SUB2 STHkr LB_SELECT_IDX STZ2
STHkr LB_SELECT_IDX LDZ2 INC2 STHkr LB_TOP LDZ2 GTH2 ,&no_scroll_up JCN STHkr LB_SELECT_IDX LDZ2 INC2 STHkr LB_TOP LDZ2 GTH2 ,&no_scroll_up JCN
STHkr LB_TOP LDZ2 #0001 SUB2 STHkr LB_TOP STZ2 STHkr LB_TOP LDZ2 #0001 SUB2 STHkr LB_TOP STZ2
&no_scroll_up ,&end JMP &no_scroll_up
&end &end
( onchange ) ( onchange )
STHr ROT ROT JSR2 STHr ROT ROT JSR2
#01 .refresh/mboxes STZ #01 .refresh/mboxes STZ
#01 .refresh/list STZ #01 .refresh/list STZ
JMP2r JMP2r
@handle_textbox ( -> ) @handle_textbox ( -> )
@ -418,6 +493,7 @@ JMP2r
.textbox/len LDZ #01 SUB .textbox/len STZ .textbox/len LDZ #01 SUB .textbox/len STZ
#00 ;textbox_text .textbox/cursor LDZ #00 SWP ADD2 STA #00 ;textbox_text .textbox/cursor LDZ #00 SWP ADD2 STA
JMP2r JMP2r
&its_complicated &its_complicated
( otherwise loop through characters from cursor to len, ( otherwise loop through characters from cursor to len,
and copy them to their location - 1 ) and copy them to their location - 1 )
@ -430,9 +506,11 @@ JMP2r
.textbox/cursor LDZ #01 SUB .textbox/cursor STZ .textbox/cursor LDZ #01 SUB .textbox/cursor STZ
.textbox/len LDZ #01 SUB .textbox/len STZ .textbox/len LDZ #01 SUB .textbox/len STZ
#00 ;textbox_text .textbox/len LDZ #00 SWP ADD2 STA #00 ;textbox_text .textbox/len LDZ #00 SWP ADD2 STA
JMP2r JMP2r
@insert_char ( key -- ) @insert_char ( key -- )
STH STH
( if cursor = len, then add the charater, increment both counters, and add a null byte ) ( if cursor = len, then add the charater, increment both counters, and add a null byte )
.textbox/cursor LDZ .textbox/len LDZ NEQ ,&its_complicated JCN .textbox/cursor LDZ .textbox/len LDZ NEQ ,&its_complicated JCN
@ -442,6 +520,7 @@ JMP2r
#00 ;textbox_text .textbox/len LDZ #00 SWP ADD2 STA #00 ;textbox_text .textbox/len LDZ #00 SWP ADD2 STA
.textbox/cursor LDZk INC SWP STZ .textbox/cursor LDZk INC SWP STZ
JMP2r JMP2r
&its_complicated &its_complicated
( otherwise loop through characters from len to cursor, ( otherwise loop through characters from len to cursor,
and copy them to their location + 1 ) and copy them to their location + 1 )
@ -458,6 +537,7 @@ JMP2r
JMP2r JMP2r
@check_enter_or_esc ( key -- bit ) @check_enter_or_esc ( key -- bit )
DUP #0d NEQ ,&no_enter JCN DUP #0d NEQ ,&no_enter JCN
.textbox/mode LDZ ENTRY_SEARCH NEQ ,&no_search JCN .textbox/mode LDZ ENTRY_SEARCH NEQ ,&no_search JCN
send_search send_search
@ -468,6 +548,7 @@ JMP2r
ENTRY_OFF reset_textbox ENTRY_OFF reset_textbox
#01 .refresh/textbox STZ #01 .refresh/textbox STZ
#01 ,&done JMP #01 ,&done JMP
&no_enter &no_enter
DUP #1b NEQ ,&no_esc JCN DUP #1b NEQ ,&no_esc JCN
ENTRY_OFF reset_textbox ENTRY_OFF reset_textbox
@ -479,6 +560,7 @@ JMP2r
#00 #00
&done &done
NIP NIP
JMP2r JMP2r
@on_mouse ( -> ) @on_mouse ( -> )
@ -509,6 +591,7 @@ JMP2r
&done &done
#01 .refresh/fg STZ #01 .refresh/fg STZ
BRK BRK
@mouse_event_buttons ( numBtns -- ) @mouse_event_buttons ( numBtns -- )
@ -587,7 +670,8 @@ JMP2r
( check bounds ) ( check bounds )
.Mouse/x DEI2 .Screen/width DEI2 #0008 SUB2 GTH2 ,&almost_done JCN .Mouse/x DEI2 .Screen/width DEI2 #0008 SUB2 GTH2 ,&almost_done JCN
.Mouse/y DEI2 ,&y LDR2 LTH2 ,&almost_done JCN .Mouse/y DEI2 ,&y LDR2 LTH2 ,&almost_done JCN
.Mouse/y DEI2 ,&y LDR2 [ STHkr LB_HEIGHT LDZ #00 SWP #30 SFT2 ] ADD2 #0001 SUB2 GTH2 ,&almost_done JCN .Mouse/y DEI2 [ [ ,&y LDR2 ] [ #00 STHkr LB_HEIGHT LDZ #30 SFT2 ] ADD2 #0001 SUB2 ] GTH2 ,&almost_done JCN
.Mouse/y DEI2 [ [ ,&y LDR2 ] [ STHkr LB_LEN LDZ2 #30 SFT2 ] ADD2 #0001 SUB2 ] GTH2 ,&almost_done JCN
( check scrollwheel ) ( check scrollwheel )
.Mouse/scrolly DEI2 #0000 EQU2 ,&no_scroll JCN .Mouse/scrolly DEI2 #0000 EQU2 ,&no_scroll JCN
@ -685,6 +769,7 @@ JMP2r
POP2 POP2 POP2 POP2
POPr POPr
send_get_mbox send_get_mbox
JMP2r JMP2r
@enter_search_mode ( -> ) @enter_search_mode ( -> )
@ -717,16 +802,11 @@ JMP2r
JMP2r JMP2r
@noop_button_click ( -> )
JMP2r
@right_click_mail_list ( list -- ) @right_click_mail_list ( list -- )
send_reader send_reader
JMP2r JMP2r
@try_scroll_up_mouse ( list -- ) @try_scroll_up_mouse ( list -- )
@ -955,7 +1035,6 @@ JMP2r
( ypos ) .Screen/y DEO2 ( ypos ) .Screen/y DEO2
( .list ) STH ( .list ) STH
&begin
#0000 STHkr LB_OFFSET STZ2 #0000 STHkr LB_OFFSET STZ2
STHkr LDZ2 #0000 &while EQU2k ,&end JCN STHkr LDZ2 #0000 &while EQU2k ,&end JCN
DUP2 STHkr LB_DATA LDZ2 ADD2 LDA DUP2 STHkr LB_DATA LDZ2 ADD2 LDA
@ -1105,9 +1184,31 @@ JMP2r
JMP2r JMP2r
@load_theme ( -- )
;theme_file .File0/name DEO2
#0006 .File0/length DEO2
;theme_data .File0/read DEO2
.File0/success DEI2 DUP2 debug_u16 #0006 NEQ2 ,&no_theme_file JCN
;theme_data LDA2 .System/r DEO2
;theme_data #0002 ADD2 LDA2 .System/g DEO2
;theme_data #0004 ADD2 LDA2 .System/b DEO2
&no_theme_file
JMP2r
@load_font ( -- )
;font_file .File0/name DEO2
#0300 .File0/length DEO2
;font .File0/read DEO2
JMP2r
( -== data ==- ) ( -== data ==- )
@search_indicator "$ 00 @search_indicator "$ 00
@theme_file ".theme 00
@font_file "font.icn 00
@search_lbl "SEARCHING: 20 "type 20 "query 20 "and 20 "press 20 "{enter}; 20 "{esc} 20 "to 20 "go 20 "back 00 @search_lbl "SEARCHING: 20 "type 20 "query 20 "and 20 "press 20 "{enter}; 20 "{esc} 20 "to 20 "go 20 "back 00
@refile_lbl "REFILING: 20 "type 20 "destination 20 "and 20 "press 20 "{enter}; 20 "{esc} 20 "to 20 "go 20 "back 00 @refile_lbl "REFILING: 20 "type 20 "destination 20 "and 20 "press 20 "{enter}; 20 "{esc} 20 "to 20 "go 20 "back 00
@ -1149,35 +1250,10 @@ JMP2r
@bone [ e040 4040 4040 40e0 ] @bone [ e040 4040 4040 40e0 ]
@font [ @selected_mbox "INBOX 00 $f9 ( default mailbox is INBOX, total space #06 + #f9 = #ff bytes )
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 @font $300
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 @theme_data $6
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
00 38 44 38 44 44 38 00 00 38 44 44 3c 04 38 00 00 18 18 00 00 18 18 00 00 18 18 00 00 18 10 20
00 00 08 10 20 10 08 00 00 00 00 3e 00 3e 00 00 00 00 10 08 04 08 10 00 00 38 44 1c 10 00 10 00
00 38 44 5c 58 40 3c 00 00 10 28 44 7c 44 44 00 00 78 44 78 44 44 78 00 00 38 44 40 40 44 38 00
00 78 44 44 44 44 78 00 00 7c 40 7c 40 40 7c 00 00 7c 40 7c 40 40 40 00 00 38 44 40 4c 44 3c 00
00 44 44 7c 44 44 44 00 00 7c 10 10 10 10 7c 00 00 7c 08 08 48 48 30 00 00 44 48 70 48 44 44 00
00 40 40 40 40 40 7c 00 00 44 6c 7c 54 44 44 00 00 44 64 74 5c 4c 44 00 00 38 44 44 44 44 38 00
00 78 44 44 78 40 40 00 00 38 44 44 4c 4c 3e 00 00 78 44 44 78 44 44 00 00 3c 40 38 04 04 78 00
00 7c 10 10 10 10 10 00 00 44 44 44 44 44 3c 00 00 44 44 28 28 10 10 00 00 44 44 44 54 6c 44 00
00 44 44 38 38 44 44 00 00 44 44 28 10 10 10 00 00 7c 04 18 30 40 7c 00 00 3c 30 30 30 30 3c 00
00 40 20 10 08 04 02 00 00 3c 0c 0c 0c 0c 3c 00 00 10 38 6c 00 00 00 00 00 00 00 00 00 00 7e 00
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 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
00 10 10 10 10 10 10 00 00 00 00 08 08 08 78 00 00 00 00 32 4c 00 00 00 3c 42 99 a1 a1 99 42 3c
]
@textbox_text $ff @textbox_text $ff
@word $ff @word $ff
@selected_mbox "INBOX 00 $f9 ( default mailbox is INBOX, total space #06 + #f9 = #ff bytes )
@list_data $8000 @list_data $8000
@mbox_data $1000 @mbox_data $1000

View file

@ -29,7 +29,7 @@ save_attachments() {
read n read n
case ${n} in case ${n} in
''|*[!0-9]*) return ;; ''|*[!0-9]*) return ;;
*) file=$(mshow -x . ${n}); mv ${file} ${TARO_DOWNLOADS} ;; *) file=$(mshow -x . ${n}); mv "${file}" ${TARO_DOWNLOADS} ;;
esac esac
done done
} }

14
taro.desktop Normal file
View file

@ -0,0 +1,14 @@
[Desktop Entry]
Comment[en_US]=Taro Email Client
Comment=Taro Email Client
Exec=taro-ctl
GenericName[en_US]=Email
GenericName=Email
Icon=TARO_LIB/taro.svg
Name[en_US]=Taro
Name=taro
Terminal=false
Type=Application
StartupWMClass=UXN_EMU
SingleMainWindow=true
Version=1.5

67
taro.svg Normal file
View file

@ -0,0 +1,67 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
width="350"
height="350"
viewBox="0 0 92.604424 92.604491"
version="1.1"
id="svg5"
inkscape:version="1.1.1 (3bf5ae0d25, 2021-09-20)"
sodipodi:docname="taro.svg"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<sodipodi:namedview
id="namedview7"
pagecolor="#505050"
bordercolor="#ffffff"
borderopacity="1"
inkscape:pageshadow="0"
inkscape:pageopacity="0"
inkscape:pagecheckerboard="1"
inkscape:document-units="mm"
showgrid="true"
units="px"
width="500px"
inkscape:snap-perpendicular="false"
inkscape:zoom="0.76438387"
inkscape:cx="114.47128"
inkscape:cy="183.15405"
inkscape:window-width="1600"
inkscape:window-height="858"
inkscape:window-x="0"
inkscape:window-y="24"
inkscape:window-maximized="1"
inkscape:current-layer="layer1" />
<defs
id="defs2" />
<g
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1">
<path
style="fill:none;stroke:#1f9b92;stroke-width:5.29167;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="M 26.866845,27.166583 C 8.4495789,8.7493184 8.7220849,9.1384624 8.7220849,9.1384624"
id="path2012" />
<circle
style="fill:#000000;stroke-width:0.264999;stroke-opacity:0"
id="path864"
cx="46.61657"
cy="47.635529"
r="38.059872" />
<path
style="fill:#1f9b92;fill-opacity:1;stroke:#1f9b92;stroke-width:1.32292;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="M 19.124758,74.277187 73.100214,20.301733"
id="path1272" />
<path
style="fill:#1f9b92;fill-opacity:1;stroke:#1f9b92;stroke-width:1.32292;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="M 9.4518689,56.430288 55.420232,10.461927"
id="path1272-3" />
<path
style="mix-blend-mode:normal;fill:#1f9b92;fill-opacity:1;stroke:#1f9b92;stroke-width:1.32292;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="M 38.799911,85.021886 84.233748,39.58804"
id="path1272-6" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 2.5 KiB