taro-ls: implement search, refile, trash; taro-ctl: search and trash commands refined
This commit is contained in:
parent
09ec048f53
commit
6f278d2b8e
3 changed files with 147 additions and 33 deletions
|
@ -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
|
43
taro-ctl.cr
43
taro-ctl.cr
|
@ -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
|
||||||
|
|
131
taro-ls.tal
131
taro-ls.tal
|
@ -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,13 +580,26 @@ 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
|
||||||
|
|
||||||
@noop_list_click ( list -- )
|
@noop_list_click ( list -- )
|
||||||
|
@ -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
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue