diff --git a/README.md b/README.md index cb1008a..fb5fb93 100644 --- a/README.md +++ b/README.md @@ -12,12 +12,12 @@ Messages are in the format `[1][2:3][...]`: Even messages go from `taro-ctl` to the `uxn` windows. - `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`. - `1`: change/refresh mailbox; payload is the mailbox to read - `3`: mark all as read in current mailbox; no payload - `5`: search mail; payload is the regex -- `7`: refile mail; payload is a mblaze msg number/range, a space, and then the mailbox name -- `9`: trash mail; payload is a mblaze msg number/range \ No newline at end of file +- `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 \ No newline at end of file diff --git a/taro-ctl.cr b/taro-ctl.cr index 7086341..af57219 100644 --- a/taro-ctl.cr +++ b/taro-ctl.cr @@ -2,6 +2,16 @@ require "process" require "io/memory" 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 enum WinType LIST @@ -109,9 +119,7 @@ module Taro elsif @sizing szslice = Slice(UInt8).new(2) @stdout_r.read_fully(szslice) - szlow : UInt16 = UInt16.new(szslice[0])*256 - szhigh : UInt16 = UInt16.new(szslice[1]) - @szshort = szlow + szhigh + @szshort = u8arr_tou16(szslice) @sizing = false if @szshort == 0 @decoding = false @@ -126,6 +134,7 @@ module Taro break end end + puts data return Mesg.new(msgType, data) end @@ -170,19 +179,23 @@ module Taro @mailbox = box 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) end - def refile_mail(range : String, to_mbox : String) - cmd = "mrefile #{range} ${MBOX_ROOT}/#{to_mbox}" + def refile_mail(range_start : UInt16, range_end : UInt16, to_mbox : String) + cmd = "mrefile #{range_start}:#{range_end} ${MBOX_ROOT}/#{to_mbox}" run_cmd(cmd) end 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) end end @@ -239,6 +252,20 @@ loop do when 3 then taro.mblaze.mark_all_read 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 diff --git a/taro-ls.tal b/taro-ls.tal index 2b4aa4e..04399ea 100644 --- a/taro-ls.tal +++ b/taro-ls.tal @@ -5,6 +5,10 @@ %MBOX_LIST { #00 } %GET_MBOX { #01 } %MAIL_LIST { #02 } +%MARK_ALL_READ { #03 } +%SEARCH_MAIL { #05 } +%REFILE_MAIL { #07 } +%TRASH_MAIL { #09 } ( UI constants ) @@ -96,8 +100,8 @@ ;send_get_mbox .btn_fns/refresh STZ2 ;send_mark_all_read .btn_fns/read_all STZ2 ;enter_search_mode .btn_fns/search STZ2 - ;noop_button_click .btn_fns/refile STZ2 - ;noop_button_click .btn_fns/trash STZ2 + ;enter_refile_mode .btn_fns/refile STZ2 + ;send_trash .btn_fns/trash STZ2 ;on_screen .Screen/vector DEO2 @@ -200,9 +204,40 @@ JMP2r JMP2r @send_mark_all_read ( -> ) - #03 .Console/write DEO + + MARK_ALL_READ .Console/write DEO #00 .Console/write DEOk DEO ( 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 @send_str ( str* -- ) @@ -214,30 +249,49 @@ 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 ==- ) @on_key ( -> ) .textbox/mode LDZ #00 EQU ,&no_text_entry JCN handle_textbox + BRK &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 @handle_textbox ( -> ) .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 POP ( handle backspace ) - .textbox/cursor LDZ #00 EQU ,&also_done JCN + .textbox/cursor LDZ #00 EQU ,&done JCN delete_char ,&done JMP &no_delete + ( ascii printable chars only ) DUP #20 LTH OVR #7e GTH ORA ,&no_btn JCN - ( TODO: handle inserting character when bone is in middle of string ) - ( or when string is already max length ) + .textbox/len LDZ #fe EQU ,&no_btn JCN insert_char - &also_done ,&done JMP &no_key POP @@ -292,7 +346,7 @@ JMP2r &its_complicated ( otherwise loop through characters from len to cursor, 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 INC STHr SWP #00 SWP ;textbox_text ADD2 STA #01 SUB @@ -304,9 +358,28 @@ JMP2r .textbox/cursor LDZk INC SWP STZ JMP2r -@check_enter_or_esc ( key -- ) - POP - ( check mode and either cancel or send appropriate message ) +@check_enter_or_esc ( key -- bit ) + DUP #0d NEQ ,&no_enter JCN + .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 @on_mouse ( -> ) @@ -343,8 +416,6 @@ BRK STH - ( TODO: check if any button is active and only refresh if it is ) - STHkr #00 &while EQUk ,&end JCN DUP .btn_colors ADD DUP LDZ #01 NEQ ,&continue JCN @@ -509,13 +580,26 @@ JMP2r @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/cursor STZ #00 ;textbox_text STA - ;search_lbl .textbox/msg STZ2 #01 .refresh/textbox STZ - + JMP2r @noop_list_click ( list -- ) @@ -581,8 +665,8 @@ JMP2r &no_btns .refresh/textbox LDZ #00 EQU ,&no_textbox JCN - .textbox/mode LDZ #00 EQU ,&no_textbox JCN clear_textbox + .textbox/mode LDZ #00 EQU ,&no_textbox JCN ;textbox_text #0008 .Screen/height DEI2 #0018 SUB2 #03 draw_str draw_bone .textbox/msg LDZ2 #0008 .Screen/height DEI2 #0010 SUB2 #02 draw_str @@ -608,10 +692,12 @@ JMP2r @clear_textbox ( -> ) - .Screen/height DEI2 #0018 SUB2 .Screen/y DEO2 + ;blank .Screen/addr DEO2 .Screen/width DEI2 #0008 &while EQU2k ,&end JCN 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 #0008 ADD2 ,&while JMP &end POP2 POP2 @@ -790,7 +876,7 @@ JMP2r INC ,&while_trough JMP &end_trough POP2 ( 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 &no_handle @@ -828,6 +914,7 @@ JMP2r .Screen/x DEO2 ( set x ) ( now the string address is at the top of the stack ) + LDAk #00 EQU ,&done JCN &loop .Screen/x DEI2 .Screen/width DEI2 #0010 SUB2 GTH2 ,&done JCN LDAk DUP @@ -836,7 +923,7 @@ JMP2r STHkr .Screen/sprite DEO .Screen/x DEI2 #0008 ADD2 .Screen/x DEO2 INC2 - LDAk #00 NEQ ,&loop JCN &done + LDAk ,&loop JCN &done POP2 POPr