diff -ur v9/argmnt.py v10/argmnt.py --- v9/argmnt.py 2018-10-22 02:30:19.000000000 +0900 +++ v10/argmnt.py 2018-10-25 03:14:33.000000000 +0900 @@ -54,6 +54,9 @@ setattr( o_, k, cp_if_need( getattr(o, k) ) ) return o_ +def copy_olst(olst): + return list( map( copy_o, olst ) ) + def get_vh(dxy): (dx, dy) = dxy if dx != 0 and dy == 0: @@ -263,6 +266,8 @@ step_modes = ('normal', 'move', 'resize', 'line', 'rect') + is_sel = lambda o: o in e.sel + def key_dxy(k): dxy = key.dxy( k, (0,0) ) if e.mode in step_modes: @@ -274,7 +279,7 @@ return False if o.frm.kind != '': return True - if o != e.sel: + if not is_sel(o): return False return e.mode in ('sel_2', 'sel_kind') @@ -289,22 +294,23 @@ if rect.is_cross(r_, r): return True return False + def get_atts(o, buf): - if o == e.sel: + if is_sel(o): if is_line(o) or is_rect(o): if e.mode in ('sel_2', 'sel_kind'): return [ buf.uline ] if e.mode in ('sel_3', 'resize'): return [ buf.rev ] - if e.mode in ('sel', 'move', 'frm_align', 'depth'): + if e.mode in ('sel', 'move', 'frm_align', 'depth', 'msel'): return [ buf.rev ] if e.mode in ('sel_align'): return [ buf.uline ] return [] def get_frm_atts(o, buf): - if o == e.sel: - if e.mode in ('sel', 'move', 'sel_3', 'resize', 'depth'): + if is_sel(o): + if e.mode in ('sel', 'move', 'sel_3', 'resize', 'depth', 'msel'): return [ buf.rev ] if e.mode in ('sel_2', 'sel_kind'): return [ buf.uline ] @@ -325,9 +331,13 @@ def do_cursor(): if not rect.in_rect(e.cur, r): return False - if ( is_rect(e.sel) or is_line(e.sel) ) and e.mode in ('sel_3', 'resize'): - return True - return e.mode in ('normal', 'sel_4', 'line', 'sel_5', 'rect', 'depth', 'step') + + if e.mode in ('sel_3', 'resize'): + f = lambda o: is_sel(o) and ( is_rect(o) or is_line(o) ) + if list( filter( f, get_olst_under_cursor() ) ): + return True + + return e.mode in ('normal', 'sel_4', 'line', 'sel_5', 'rect', 'depth', 'step', 'msel') if do_cursor(): (x, y) = e.cur @@ -343,6 +353,8 @@ c = 'd' elif e.mode in ('step'): c = str(e.step) + elif e.mode in ('msel'): + c = 'm' buf.set(x, y, c, atts) buf.adjust() @@ -394,54 +406,63 @@ for p in (bak, e.cur): draw_r( rect.p_wh_to( p, (1,1) ), term.out ) - def get_o_under_cursor(): - for o in reversed(lst): - if rect.p_in_rects( e.cur, get_o_rects(o) ): - return o - return None + def move_cur_key(k): + dxy = key_dxy(k) + if dxy != (0,0): + move_cur(dxy) + return + ((x1,y1),(x2,y2)) = rect.to_p2( rect.resize( view.get_rect(), (-1,-1) ) ) + d = key.allow(k) + (x, y) = e.cur + if d == 'pu': + y = y1 + elif d == 'pd': + y = y2 + elif d == 'pl': + x = x1 + elif d == 'pr': + x = x2 + move_cur_to((x, y)) + + def get_olst_under_cursor(): + return list( filter( lambda o: rect.p_in_rects( e.cur, get_o_rects(o) ), reversed(lst) ) ) def set_mode(mode): - if mode == 'sel': - e.sel = get_o_under_cursor() - o = e.sel - e.mode_bak = ( copy_o(o) if o else None, lst.index(o) if o and o in lst else -1, e.cur, e.step, e.mode ) - f = new_draw(o) if o else None + bak_sel = e.mode_bak[1] + rs = list( map( get_o_rect, bak_sel + e.sel ) ) + + idxs = list( map( lst.index, e.sel ) ) + bak = copy_olst(lst) + bak_sel = list( map( lambda i: bak[i], idxs ) ) + e.mode_bak = ( bak, bak_sel, e.cur, e.step, e.mode ) + e.mode = mode - if mode == 'normal': - e.sel = None - if is_line(o) and o.kind == 'd': - lst.remove(o) - if is_rect(o) and o.kind == '': - lst.remove(o) - if f: - f() + if mode == 'normal' and e.sel: + e.sel = [] + + rs += list( map( get_o_rect, e.sel ) ) + if rs: + r = contain_rect(rs) + draw_r( r, term.out ) draw_cur() def f_normal(k): if key.is_ok(k): - set_mode( 'sel' if get_o_under_cursor() else 'sel_4' ) + olst = get_olst_under_cursor() + if olst: + e.sel = olst[:1] + set_mode('sel') + else: + set_mode('sel_4') elif key.is_allow(k): - dxy = key_dxy(k) - if dxy != (0,0): - move_cur(dxy) - return - ((x1,y1),(x2,y2)) = rect.to_p2( rect.resize( view.get_rect(), (-1,-1) ) ) - d = key.allow(k) - (x, y) = e.cur - if d == 'pu': - y = y1 - elif d == 'pd': - y = y2 - elif d == 'pl': - x = x1 - elif d == 'pr': - x = x2 - move_cur_to((x, y)) + move_cur_key(k) elif e.clipboard and k == 'v': # paste - (o, p) = e.clipboard - o = copy_o(o) - move_o( o, p_sub(e.cur, p) ) - lst.append(o) + (olst, p) = e.clipboard + olst = copy_olst(olst) + for o in olst: + move_o( o, p_sub(e.cur, p) ) + lst.append(o) + e.sel = olst set_mode('sel') elif k == '\t': set_mode('step') @@ -452,29 +473,32 @@ elif key.is_allow(k): call( [ 'move', move ], k ) elif e.sel and k in ('c', 'x'): - o = e.sel - e.clipboard = ( copy_o(o), e.cur ) - set_mode('normal') + e.clipboard = ( copy_olst(e.sel), e.cur ) if k == 'x': - f = new_draw(o) - lst.remove(o) - f() + for o in e.sel: + f = new_draw(o) + lst.remove(o) + f() + e.sel = [] + set_mode('normal') elif k == 'd': set_mode('depth') + elif k == 'm': + set_mode('msel') elif key.is_cancel(k): set_mode('normal') - return None def f_sel2_ok(k): - if p_on_frm(e.cur, e.sel): + o = e.sel[0] + if p_on_frm(e.cur, o): set_mode('sel_3') - elif not is_line(e.sel) and len(e.sel.s) > 1: + elif not has_typ(o) and len(o.s) > 1: set_mode('sel_align') else: set_mode('normal') def resize(k): - o = e.sel + o = e.sel[0] dxy = key_dxy(k) f = new_draw(o) if is_rect(o): @@ -497,7 +521,7 @@ move_cur(dxy) def sel_align(k): - o = e.sel + o = e.sel[0] f = new_draw(o) o.a = get_next( ['l', 'c', 'r'], o.a ) f() @@ -514,15 +538,15 @@ (o.x, o.y) = (o.x + dx, o.y + dy) def move(k): - o = e.sel - dxy = key_dxy(k) - f = new_draw(o) - move_o(o, dxy) - f() - move_cur(dxy) # hidden + for o in e.sel: + dxy = key_dxy(k) + f = new_draw(o) + move_o(o, dxy) + f() + move_cur(dxy) def sel_kind(k): - o = e.sel + o = e.sel[0] f = new_draw(o) rlst = sorted( frm_info.keys() ) if is_line(o): @@ -534,7 +558,7 @@ f() def frm_align(k): - o = e.sel + o = e.sel[0] f = new_draw(o) d = key.allow(k) if d in 'ud': @@ -550,13 +574,13 @@ if dxy == (0, 0): return if e.sel: - o = e.sel + o = e.sel[0] else: o = Empty() o.typ = 'line' o.lst = [ list(e.cur) ] o.kind = '' - e.sel = o + e.sel = [o] lst.append(o) vh = get_vh(dxy) @@ -575,14 +599,14 @@ if dxy == (0, 0): return if e.sel: - o = e.sel + o = e.sel[0] else: o = Empty() o.typ = 'rect' (cx, cy) = e.cur o.r = [ cx, cy, 1, 1 ] o.kind = 'a' - e.sel = o + e.sel = [o] lst.append(o) f = new_draw(o) @@ -591,18 +615,18 @@ move_cur(dxy) def f_depth(k): - (dx, dy) = key_dxy(k) - o = e.sel + o = e.sel[0] f = new_draw(o) i = lst.index(o) n = len(lst) o = lst.pop(i) + (dx, dy) = key_dxy(k) i = (i + dx + dy + n) % n lst.insert(i, o) f() def f_step(k): - (bak, bak_i, p, step, mode) = e.mode_bak + ( bak, bak_sel, p, step, mode ) = e.mode_bak if key.is_ok(k) or k == '\t': set_mode(mode) elif key.is_cancel(k): @@ -613,29 +637,45 @@ e.step = min( max( int( e.step * (2 if dx + dy > 0 else 0.5) ), 1 ), 8 ) draw_cur() + def f_msel(k): + if key.is_ok(k): + olst = get_olst_under_cursor() + if olst: + o = olst[0] + f = new_draw(o) + if is_sel(o): + e.sel.remove(o) + else: + e.sel.append(o) + f() + elif key.is_allow(k): + move_cur_key(k) + elif k == 'm': + set_mode('sel') + elif key.is_cancel(k): + f_cancel(k) + def f_cancel(k): - (bak, bak_i, p, step, mode) = e.mode_bak - if e.sel: - f = new_draw(e.sel) - i = lst.index(e.sel) - lst.pop(i) - if bak: - if bak_i >= 0 and bak_i != i: - i = bak_i - lst.insert(i, bak) - f(bak) - else: - f() + ( bak, bak_sel, p, step, mode ) = e.mode_bak + move_cur_to(p) e.step = step - set_mode('normal') + + e.mode_bak = ( lst, e.sel, e.cur, e.step, e.mode ) + + del lst[:] + lst.extend(bak) + e.sel = bak_sel + + set_mode(mode) def has_bdr(k): - o = e.sel - if has_typ(o): - return False - (bx, by) = o.frm.bdr - return bx > 0 or by > 0 + o = e.sel[0] + if not has_typ(o): + (bx, by) = o.frm.bdr + if bx > 0 or by > 0: + return True + return False hdl = { 'normal': f_normal, @@ -659,6 +699,7 @@ 'rect': { 'ok': 'normal', 'allow': f_rect, 'cancel': f_cancel, 'key_\t': 'step' }, 'depth': { 'ok': 'normal', 'allow': f_depth, 'cancel': f_cancel }, 'step': f_step, + 'msel': f_msel, } def call(o, k): @@ -701,8 +742,8 @@ e.mode = 'normal' e.step = 1 - e.mode_bak = ( None, -1, e.cur, e.step, e.mode ) - e.sel = None + e.mode_bak = ( [], [], e.cur, e.step, e.mode ) + e.sel = [] e.clipboard = None draw_r( r, term.out )