taro-ls: implement search, refile, trash; taro-ctl: search and trash commands refined

This commit is contained in:
Iris Lightshard 2023-03-22 20:11:08 -06:00
parent 09ec048f53
commit 6f278d2b8e
Signed by: nilix
GPG key ID: 3B7FBC22144E6398
3 changed files with 147 additions and 33 deletions

View file

@ -12,12 +12,12 @@ 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 - `0`: mailbox list
- `2`: list mail in current mailbox - `2`: list mail in current mailbox (or search results)
Odd messages go from the `uxn` windows to `taro-ctl`. Odd messages go from the `uxn` windows to `taro-ctl`.
- `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 a mblaze msg number/range, a space, 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 a mblaze msg number/range - `9`: trash mail; payload is the beginning and end of the mmsg range in u16

View file

@ -2,6 +2,16 @@ require "process"
require "io/memory" require "io/memory"
require "io" require "io"
def u8arr_tou16(s : Slice(UInt8)) : UInt16
if s.size < 2
return 0_u16
else
low : UInt16 = UInt16.new(s[0])*256
high : UInt16 = UInt16.new(s[1])
return low + high
end
end
module Taro module Taro
enum WinType enum WinType
LIST LIST
@ -109,9 +119,7 @@ module Taro
elsif @sizing elsif @sizing
szslice = Slice(UInt8).new(2) szslice = Slice(UInt8).new(2)
@stdout_r.read_fully(szslice) @stdout_r.read_fully(szslice)
szlow : UInt16 = UInt16.new(szslice[0])*256 @szshort = u8arr_tou16(szslice)
szhigh : UInt16 = UInt16.new(szslice[1])
@szshort = szlow + szhigh
@sizing = false @sizing = false
if @szshort == 0 if @szshort == 0
@decoding = false @decoding = false
@ -126,6 +134,7 @@ module Taro
break break
end end
end end
puts data
return Mesg.new(msgType, data) return Mesg.new(msgType, data)
end end
@ -170,19 +179,23 @@ module Taro
@mailbox = box @mailbox = box
end end
def trash_mail(range : String) def trash_mail(range_start : UInt16, range_end : UInt16)
cmd = "mrefile #{range_start}:#{range_end} ${MBOX_ROOT}/Trash"
cmd = "mlist ${MBOX_ROOT}/#{@mailbox} | mseq -S | mpick #{range} | mrefile ${MBOX_ROOT}/Trash" # destroy mail if we are trashing what's already in the trash!
if @mailbox == "Trash"
cmd = "for x in $(mseq #{range_start}:#{range_end}); do rm $x; done"
end
run_cmd(cmd) run_cmd(cmd)
end end
def refile_mail(range : String, to_mbox : String) def refile_mail(range_start : UInt16, range_end : UInt16, to_mbox : String)
cmd = "mrefile #{range} ${MBOX_ROOT}/#{to_mbox}" cmd = "mrefile #{range_start}:#{range_end} ${MBOX_ROOT}/#{to_mbox}"
run_cmd(cmd) run_cmd(cmd)
end end
def search_mail(query : String, body : Bool) : String def search_mail(query : String, body : Bool) : String
mailCmd = "mlist ${MBOX_ROOT}/#{@mailbox} | magrep #{body ? "/" : "*"} | msort -dr | mseq -S | mscan | uniq" cmd = "mlist ${MBOX_ROOT}/#{@mailbox} | magrep #{body ? "/" : "*"}:#{query} | msort -dr | uniq | mseq -S | mscan"
return run_cmd(cmd) return run_cmd(cmd)
end end
end end
@ -239,6 +252,20 @@ loop do
when 3 then when 3 then
taro.mblaze.mark_all_read taro.mblaze.mark_all_read
taro.mainWindow.write_msg(2_u8, taro.mblaze.list_mail.to_slice) taro.mainWindow.write_msg(2_u8, taro.mblaze.list_mail.to_slice)
when 5 then
search_results = taro.mblaze.search_mail(String.new(m.data), false)
taro.mainWindow.write_msg(2_u8, search_results.to_slice)
when 7 then
range_start = u8arr_tou16(m.data[0..1])
range_end = u8arr_tou16(m.data[2..3])
dest_mbox = String.new(m.data[4..])
taro.mblaze.refile_mail(range_start, range_end, dest_mbox)
taro.mainWindow.write_msg(2_u8, taro.mblaze.list_mail.to_slice)
when 9 then
range_start = u8arr_tou16(m.data[0..1])
range_end = u8arr_tou16(m.data[2..3])
taro.mblaze.trash_mail(range_start, range_end)
taro.mainWindow.write_msg(2_u8, taro.mblaze.list_mail.to_slice)
end end
end end
end end

View file

@ -5,6 +5,10 @@
%MBOX_LIST { #00 } %MBOX_LIST { #00 }
%GET_MBOX { #01 } %GET_MBOX { #01 }
%MAIL_LIST { #02 } %MAIL_LIST { #02 }
%MARK_ALL_READ { #03 }
%SEARCH_MAIL { #05 }
%REFILE_MAIL { #07 }
%TRASH_MAIL { #09 }
( UI constants ) ( UI constants )
@ -96,8 +100,8 @@
;send_get_mbox .btn_fns/refresh STZ2 ;send_get_mbox .btn_fns/refresh STZ2
;send_mark_all_read .btn_fns/read_all STZ2 ;send_mark_all_read .btn_fns/read_all STZ2
;enter_search_mode .btn_fns/search STZ2 ;enter_search_mode .btn_fns/search STZ2
;noop_button_click .btn_fns/refile STZ2 ;enter_refile_mode .btn_fns/refile STZ2
;noop_button_click .btn_fns/trash STZ2 ;send_trash .btn_fns/trash STZ2
;on_screen .Screen/vector DEO2 ;on_screen .Screen/vector DEO2
@ -200,9 +204,40 @@ JMP2r
JMP2r JMP2r
@send_mark_all_read ( -> ) @send_mark_all_read ( -> )
#03 .Console/write DEO
MARK_ALL_READ .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 )
JMP2r
@send_search ( -> )
SEARCH_MAIL .Console/write DEO
;textbox_text strlen SWP .Console/write DEO .Console/write DEO
;textbox_text send_str
JMP2r
@send_refile ( -> )
REFILE_MAIL .Console/write DEO
#0004 ;textbox_text strlen ADD2 SWP .Console/write DEO .Console/write DEO
.list selection_to_range
SWP .Console/write DEO .Console/write DEO
SWP .Console/write DEO .Console/write DEO
;textbox_text send_str
JMP2r
@send_trash ( -> )
TRASH_MAIL .Console/write DEO
#0004 SWP .Console/write DEO .Console/write DEO
.list selection_to_range
SWP .Console/write DEO .Console/write DEO
SWP .Console/write DEO .Console/write DEO
JMP2r JMP2r
@send_str ( str* -- ) @send_str ( str* -- )
@ -214,30 +249,49 @@ JMP2r
JMP2r JMP2r
@selection_to_range ( listbox -- end* start* )
DUP LB_SELECT_IDX LDZ2 INC2 STH2
LB_SELECT_LEN LDZ2 #0001 SUB2 STH2kr ADD2
STH2r
JMP2r
( -== input ==- ) ( -== input ==- )
@on_key ( -> ) @on_key ( -> )
.textbox/mode LDZ #00 EQU ,&no_text_entry JCN .textbox/mode LDZ #00 EQU ,&no_text_entry JCN
handle_textbox handle_textbox
BRK
&no_text_entry &no_text_entry
( TODO: add shortcuts for common actions
- del: trash
- up/dn: change selection (mail)
- tab: change selection (mailbox)
- shift+up/dn: multiselect
- /: search
- r: refresh
- m: refile
- c: compose
- .: all read
)
BRK BRK
@handle_textbox ( -> ) @handle_textbox ( -> )
.Controller/key DEI DUP #00 EQU ,&no_key JCN .Controller/key DEI DUP #00 EQU ,&no_key JCN
DUP check_enter_or_esc DUP check_enter_or_esc #01 EQU ,&no_btn JCN
DUP #08 NEQ ,&no_delete JCN DUP #08 NEQ ,&no_delete JCN
POP POP
( handle backspace ) ( handle backspace )
.textbox/cursor LDZ #00 EQU ,&also_done JCN .textbox/cursor LDZ #00 EQU ,&done JCN
delete_char delete_char
,&done JMP ,&done JMP
&no_delete &no_delete
( ascii printable chars only )
DUP #20 LTH OVR #7e GTH ORA ,&no_btn JCN DUP #20 LTH OVR #7e GTH ORA ,&no_btn JCN
( TODO: handle inserting character when bone is in middle of string ) .textbox/len LDZ #fe EQU ,&no_btn JCN
( or when string is already max length )
insert_char insert_char
&also_done
,&done JMP ,&done JMP
&no_key &no_key
POP POP
@ -292,7 +346,7 @@ 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 )
.textbox/cursor LDZ .textbox/len LDZ #01 ADD &loop EQUk ,&end JCN .textbox/cursor LDZ #01 SUB .textbox/len LDZ &loop EQUk ,&end JCN
DUP #00 SWP ;textbox_text ADD2 LDA STH DUP #00 SWP ;textbox_text ADD2 LDA STH
DUP INC STHr SWP #00 SWP ;textbox_text ADD2 STA DUP INC STHr SWP #00 SWP ;textbox_text ADD2 STA
#01 SUB #01 SUB
@ -304,9 +358,28 @@ JMP2r
.textbox/cursor LDZk INC SWP STZ .textbox/cursor LDZk INC SWP STZ
JMP2r JMP2r
@check_enter_or_esc ( key -- ) @check_enter_or_esc ( key -- bit )
POP DUP #0d NEQ ,&no_enter JCN
( check mode and either cancel or send appropriate message ) .textbox/mode LDZ ENTRY_SEARCH NEQ ,&no_search JCN
send_search
&no_search
.textbox/mode LDZ ENTRY_REFILE NEQ ,&no_refile JCN
send_refile
&no_refile
ENTRY_OFF reset_textbox
#01 .refresh/textbox STZ
#01 ,&done JMP
&no_enter
DUP #1b NEQ ,&no_esc JCN
ENTRY_OFF reset_textbox
#01 .refresh/textbox STZ
#01
,&done JMP
&no_esc
#00
&done
NIP
JMP2r JMP2r
@on_mouse ( -> ) @on_mouse ( -> )
@ -343,8 +416,6 @@ BRK
STH STH
( TODO: check if any button is active and only refresh if it is )
STHkr #00 &while EQUk ,&end JCN STHkr #00 &while EQUk ,&end JCN
DUP .btn_colors ADD DUP .btn_colors ADD
DUP LDZ #01 NEQ ,&continue JCN DUP LDZ #01 NEQ ,&continue JCN
@ -509,11 +580,24 @@ JMP2r
@enter_search_mode ( -> ) @enter_search_mode ( -> )
ENTRY_SEARCH .textbox/mode STZ ENTRY_SEARCH reset_textbox
;search_lbl .textbox/msg STZ2
JMP2r
@enter_refile_mode ( -> )
ENTRY_REFILE reset_textbox
;refile_lbl .textbox/msg STZ2
JMP2r
@reset_textbox ( mode -- )
.textbox/mode STZ
#00 .textbox/len STZ #00 .textbox/len STZ
#00 .textbox/cursor STZ #00 .textbox/cursor STZ
#00 ;textbox_text STA #00 ;textbox_text STA
;search_lbl .textbox/msg STZ2
#01 .refresh/textbox STZ #01 .refresh/textbox STZ
JMP2r JMP2r
@ -581,8 +665,8 @@ JMP2r
&no_btns &no_btns
.refresh/textbox LDZ #00 EQU ,&no_textbox JCN .refresh/textbox LDZ #00 EQU ,&no_textbox JCN
.textbox/mode LDZ #00 EQU ,&no_textbox JCN
clear_textbox clear_textbox
.textbox/mode LDZ #00 EQU ,&no_textbox JCN
;textbox_text #0008 .Screen/height DEI2 #0018 SUB2 #03 draw_str ;textbox_text #0008 .Screen/height DEI2 #0018 SUB2 #03 draw_str
draw_bone draw_bone
.textbox/msg LDZ2 #0008 .Screen/height DEI2 #0010 SUB2 #02 draw_str .textbox/msg LDZ2 #0008 .Screen/height DEI2 #0010 SUB2 #02 draw_str
@ -608,10 +692,12 @@ JMP2r
@clear_textbox ( -> ) @clear_textbox ( -> )
.Screen/height DEI2 #0018 SUB2 .Screen/y DEO2 ;blank .Screen/addr DEO2
.Screen/width DEI2 #0008 &while EQU2k ,&end JCN .Screen/width DEI2 #0008 &while EQU2k ,&end JCN
DUP2 .Screen/x DEO2 DUP2 .Screen/x DEO2
;blank .Screen/addr DEO2 .Screen/height DEI2 #0018 SUB2 .Screen/y DEO2
#01 .Screen/sprite DEO
.Screen/height DEI2 #0010 SUB2 .Screen/y DEO2
#01 .Screen/sprite DEO #01 .Screen/sprite DEO
#0008 ADD2 ,&while JMP &end POP2 POP2 #0008 ADD2 ,&while JMP &end POP2 POP2
@ -790,7 +876,7 @@ JMP2r
INC ,&while_trough JMP &end_trough POP2 INC ,&while_trough JMP &end_trough POP2
( stop here if there is no overflow ) ( stop here if there is no overflow )
STHkr LB_LEN LDZ2 #00 STHkr LB_HEIGHT LDZ LTH2 ,&no_handle JCN STHkr LB_LEN LDZ2 #00 STHkr LB_HEIGHT LDZ INC2 LTH2 ,&no_handle JCN
,&draw_handle JMP ,&draw_handle JMP
&no_handle &no_handle
@ -828,6 +914,7 @@ JMP2r
.Screen/x DEO2 ( set x ) .Screen/x DEO2 ( set x )
( now the string address is at the top of the stack ) ( now the string address is at the top of the stack )
LDAk #00 EQU ,&done JCN
&loop &loop
.Screen/x DEI2 .Screen/width DEI2 #0010 SUB2 GTH2 ,&done JCN .Screen/x DEI2 .Screen/width DEI2 #0010 SUB2 GTH2 ,&done JCN
LDAk DUP LDAk DUP
@ -836,7 +923,7 @@ JMP2r
STHkr .Screen/sprite DEO STHkr .Screen/sprite DEO
.Screen/x DEI2 #0008 ADD2 .Screen/x DEO2 .Screen/x DEI2 #0008 ADD2 .Screen/x DEO2
INC2 INC2
LDAk #00 NEQ ,&loop JCN &done LDAk ,&loop JCN &done
POP2 POP2
POPr POPr