I'd like explicit expand/collapse as well so added them back, also with some trivial renaming of a couple of things I don't like the look of and a nuclear reformat of the mode-key.c tables. Look ok?
Index: mode-key.c =================================================================== RCS file: /cvs/src/usr.bin/tmux/mode-key.c,v retrieving revision 1.47 diff -u -p -r1.47 mode-key.c --- mode-key.c 27 Aug 2012 21:29:23 -0000 1.47 +++ mode-key.c 2 Oct 2012 07:48:30 -0000 @@ -83,6 +83,9 @@ const struct mode_key_cmdstr mode_key_cm { MODEKEYCHOICE_SCROLLDOWN, "scroll-down" }, { MODEKEYCHOICE_SCROLLUP, "scroll-up" }, { MODEKEYCHOICE_STARTNUMBERPREFIX, "start-number-prefix" }, + { MODEKEYCHOICE_TREE_COLLAPSE_ALL, "tree-collapse-all" }, + { MODEKEYCHOICE_TREE_EXPAND_ALL, "tree-expand-all" }, + { MODEKEYCHOICE_TREE_TOGGLE, "tree-toggle" }, { MODEKEYCHOICE_UP, "up" }, { 0, NULL } @@ -138,288 +141,296 @@ const struct mode_key_cmdstr mode_key_cm /* vi editing keys. */ const struct mode_key_entry mode_key_vi_edit[] = { - { '\003' /* C-c */, 0, MODEKEYEDIT_CANCEL }, - { '\010' /* C-h */, 0, MODEKEYEDIT_BACKSPACE }, - { '\011' /* Tab */, 0, MODEKEYEDIT_COMPLETE }, - { '\025' /* C-u */, 0, MODEKEYEDIT_DELETELINE }, - { '\027' /* C-w */, 0, MODEKEYEDIT_DELETEWORD }, - { '\033' /* Escape */, 0, MODEKEYEDIT_SWITCHMODE }, - { '\r', 0, MODEKEYEDIT_ENTER }, - { KEYC_BSPACE, 0, MODEKEYEDIT_BACKSPACE }, - { KEYC_DC, 0, MODEKEYEDIT_DELETE }, - { KEYC_DOWN, 0, MODEKEYEDIT_HISTORYDOWN }, - { KEYC_LEFT, 0, MODEKEYEDIT_CURSORLEFT }, - { KEYC_RIGHT, 0, MODEKEYEDIT_CURSORRIGHT }, - { KEYC_UP, 0, MODEKEYEDIT_HISTORYUP }, - { KEYC_HOME, 0, MODEKEYEDIT_STARTOFLINE }, - { KEYC_END, 0, MODEKEYEDIT_ENDOFLINE }, - - { '$', 1, MODEKEYEDIT_ENDOFLINE }, - { '0', 1, MODEKEYEDIT_STARTOFLINE }, - { 'A', 1, MODEKEYEDIT_SWITCHMODEAPPENDLINE }, - { 'B', 1, MODEKEYEDIT_PREVIOUSSPACE }, - { 'D', 1, MODEKEYEDIT_DELETETOENDOFLINE }, - { 'E', 1, MODEKEYEDIT_NEXTSPACEEND }, - { 'I', 1, MODEKEYEDIT_SWITCHMODEBEGINLINE }, - { 'W', 1, MODEKEYEDIT_NEXTSPACE }, - { 'X', 1, MODEKEYEDIT_BACKSPACE }, - { '\003' /* C-c */, 1, MODEKEYEDIT_CANCEL }, - { '\010' /* C-h */, 1, MODEKEYEDIT_BACKSPACE }, - { '\r', 1, MODEKEYEDIT_ENTER }, - { '^', 1, MODEKEYEDIT_STARTOFLINE }, - { 'a', 1, MODEKEYEDIT_SWITCHMODEAPPEND }, - { 'b', 1, MODEKEYEDIT_PREVIOUSWORD }, - { 'd', 1, MODEKEYEDIT_DELETELINE }, - { 'e', 1, MODEKEYEDIT_NEXTWORDEND }, - { 'h', 1, MODEKEYEDIT_CURSORLEFT }, - { 'i', 1, MODEKEYEDIT_SWITCHMODE }, - { 'j', 1, MODEKEYEDIT_HISTORYDOWN }, - { 'k', 1, MODEKEYEDIT_HISTORYUP }, - { 'l', 1, MODEKEYEDIT_CURSORRIGHT }, - { 'p', 1, MODEKEYEDIT_PASTE }, - { 'w', 1, MODEKEYEDIT_NEXTWORD }, - { 'x', 1, MODEKEYEDIT_DELETE }, - { KEYC_BSPACE, 1, MODEKEYEDIT_BACKSPACE }, - { KEYC_DC, 1, MODEKEYEDIT_DELETE }, - { KEYC_DOWN, 1, MODEKEYEDIT_HISTORYDOWN }, - { KEYC_LEFT, 1, MODEKEYEDIT_CURSORLEFT }, - { KEYC_RIGHT, 1, MODEKEYEDIT_CURSORRIGHT }, - { KEYC_UP, 1, MODEKEYEDIT_HISTORYUP }, + { '\003' /* C-c */, 0, MODEKEYEDIT_CANCEL }, + { '\010' /* C-h */, 0, MODEKEYEDIT_BACKSPACE }, + { '\011' /* Tab */, 0, MODEKEYEDIT_COMPLETE }, + { '\025' /* C-u */, 0, MODEKEYEDIT_DELETELINE }, + { '\027' /* C-w */, 0, MODEKEYEDIT_DELETEWORD }, + { '\033' /* Escape */, 0, MODEKEYEDIT_SWITCHMODE }, + { '\r', 0, MODEKEYEDIT_ENTER }, + { KEYC_BSPACE, 0, MODEKEYEDIT_BACKSPACE }, + { KEYC_DC, 0, MODEKEYEDIT_DELETE }, + { KEYC_DOWN, 0, MODEKEYEDIT_HISTORYDOWN }, + { KEYC_LEFT, 0, MODEKEYEDIT_CURSORLEFT }, + { KEYC_RIGHT, 0, MODEKEYEDIT_CURSORRIGHT }, + { KEYC_UP, 0, MODEKEYEDIT_HISTORYUP }, + { KEYC_HOME, 0, MODEKEYEDIT_STARTOFLINE }, + { KEYC_END, 0, MODEKEYEDIT_ENDOFLINE }, + + { '$', 1, MODEKEYEDIT_ENDOFLINE }, + { '0', 1, MODEKEYEDIT_STARTOFLINE }, + { 'A', 1, MODEKEYEDIT_SWITCHMODEAPPENDLINE }, + { 'B', 1, MODEKEYEDIT_PREVIOUSSPACE }, + { 'D', 1, MODEKEYEDIT_DELETETOENDOFLINE }, + { 'E', 1, MODEKEYEDIT_NEXTSPACEEND }, + { 'I', 1, MODEKEYEDIT_SWITCHMODEBEGINLINE }, + { 'W', 1, MODEKEYEDIT_NEXTSPACE }, + { 'X', 1, MODEKEYEDIT_BACKSPACE }, + { '\003' /* C-c */, 1, MODEKEYEDIT_CANCEL }, + { '\010' /* C-h */, 1, MODEKEYEDIT_BACKSPACE }, + { '\r', 1, MODEKEYEDIT_ENTER }, + { '^', 1, MODEKEYEDIT_STARTOFLINE }, + { 'a', 1, MODEKEYEDIT_SWITCHMODEAPPEND }, + { 'b', 1, MODEKEYEDIT_PREVIOUSWORD }, + { 'd', 1, MODEKEYEDIT_DELETELINE }, + { 'e', 1, MODEKEYEDIT_NEXTWORDEND }, + { 'h', 1, MODEKEYEDIT_CURSORLEFT }, + { 'i', 1, MODEKEYEDIT_SWITCHMODE }, + { 'j', 1, MODEKEYEDIT_HISTORYDOWN }, + { 'k', 1, MODEKEYEDIT_HISTORYUP }, + { 'l', 1, MODEKEYEDIT_CURSORRIGHT }, + { 'p', 1, MODEKEYEDIT_PASTE }, + { 'w', 1, MODEKEYEDIT_NEXTWORD }, + { 'x', 1, MODEKEYEDIT_DELETE }, + { KEYC_BSPACE, 1, MODEKEYEDIT_BACKSPACE }, + { KEYC_DC, 1, MODEKEYEDIT_DELETE }, + { KEYC_DOWN, 1, MODEKEYEDIT_HISTORYDOWN }, + { KEYC_LEFT, 1, MODEKEYEDIT_CURSORLEFT }, + { KEYC_RIGHT, 1, MODEKEYEDIT_CURSORRIGHT }, + { KEYC_UP, 1, MODEKEYEDIT_HISTORYUP }, - { 0, -1, 0 } + { 0, -1, 0 } }; struct mode_key_tree mode_key_tree_vi_edit; /* vi choice selection keys. */ const struct mode_key_entry mode_key_vi_choice[] = { - { '0' | KEYC_ESCAPE, 0, MODEKEYCHOICE_STARTNUMBERPREFIX }, - { '1' | KEYC_ESCAPE, 0, MODEKEYCHOICE_STARTNUMBERPREFIX }, - { '2' | KEYC_ESCAPE, 0, MODEKEYCHOICE_STARTNUMBERPREFIX }, - { '3' | KEYC_ESCAPE, 0, MODEKEYCHOICE_STARTNUMBERPREFIX }, - { '4' | KEYC_ESCAPE, 0, MODEKEYCHOICE_STARTNUMBERPREFIX }, - { '5' | KEYC_ESCAPE, 0, MODEKEYCHOICE_STARTNUMBERPREFIX }, - { '6' | KEYC_ESCAPE, 0, MODEKEYCHOICE_STARTNUMBERPREFIX }, - { '7' | KEYC_ESCAPE, 0, MODEKEYCHOICE_STARTNUMBERPREFIX }, - { '8' | KEYC_ESCAPE, 0, MODEKEYCHOICE_STARTNUMBERPREFIX }, - { '9' | KEYC_ESCAPE, 0, MODEKEYCHOICE_STARTNUMBERPREFIX }, - { '\002' /* C-b */, 0, MODEKEYCHOICE_PAGEUP }, - { '\003' /* C-c */, 0, MODEKEYCHOICE_CANCEL }, - { '\005' /* C-e */, 0, MODEKEYCHOICE_SCROLLDOWN }, - { '\006' /* C-f */, 0, MODEKEYCHOICE_PAGEDOWN }, - { '\031' /* C-y */, 0, MODEKEYCHOICE_SCROLLUP }, - { '\r', 0, MODEKEYCHOICE_CHOOSE }, - { 'j', 0, MODEKEYCHOICE_DOWN }, - { 'k', 0, MODEKEYCHOICE_UP }, - { 'q', 0, MODEKEYCHOICE_CANCEL }, - { KEYC_BSPACE, 0, MODEKEYCHOICE_BACKSPACE }, - { KEYC_DOWN | KEYC_CTRL,0, MODEKEYCHOICE_SCROLLDOWN }, - { KEYC_DOWN, 0, MODEKEYCHOICE_DOWN }, - { KEYC_NPAGE, 0, MODEKEYCHOICE_PAGEDOWN }, - { KEYC_PPAGE, 0, MODEKEYCHOICE_PAGEUP }, - { KEYC_UP | KEYC_CTRL, 0, MODEKEYCHOICE_SCROLLUP }, - { KEYC_UP, 0, MODEKEYCHOICE_UP }, + { '0' | KEYC_ESCAPE, 0, MODEKEYCHOICE_STARTNUMBERPREFIX }, + { '1' | KEYC_ESCAPE, 0, MODEKEYCHOICE_STARTNUMBERPREFIX }, + { '2' | KEYC_ESCAPE, 0, MODEKEYCHOICE_STARTNUMBERPREFIX }, + { '3' | KEYC_ESCAPE, 0, MODEKEYCHOICE_STARTNUMBERPREFIX }, + { '4' | KEYC_ESCAPE, 0, MODEKEYCHOICE_STARTNUMBERPREFIX }, + { '5' | KEYC_ESCAPE, 0, MODEKEYCHOICE_STARTNUMBERPREFIX }, + { '6' | KEYC_ESCAPE, 0, MODEKEYCHOICE_STARTNUMBERPREFIX }, + { '7' | KEYC_ESCAPE, 0, MODEKEYCHOICE_STARTNUMBERPREFIX }, + { '8' | KEYC_ESCAPE, 0, MODEKEYCHOICE_STARTNUMBERPREFIX }, + { '9' | KEYC_ESCAPE, 0, MODEKEYCHOICE_STARTNUMBERPREFIX }, + { '\002' /* C-b */, 0, MODEKEYCHOICE_PAGEUP }, + { '\003' /* C-c */, 0, MODEKEYCHOICE_CANCEL }, + { '\005' /* C-e */, 0, MODEKEYCHOICE_SCROLLDOWN }, + { '\006' /* C-f */, 0, MODEKEYCHOICE_PAGEDOWN }, + { '\031' /* C-y */, 0, MODEKEYCHOICE_SCROLLUP }, + { '\r', 0, MODEKEYCHOICE_CHOOSE }, + { 'j', 0, MODEKEYCHOICE_DOWN }, + { 'k', 0, MODEKEYCHOICE_UP }, + { 'q', 0, MODEKEYCHOICE_CANCEL }, + { KEYC_BSPACE, 0, MODEKEYCHOICE_BACKSPACE }, + { KEYC_DOWN | KEYC_CTRL, 0, MODEKEYCHOICE_SCROLLDOWN }, + { KEYC_DOWN, 0, MODEKEYCHOICE_DOWN }, + { KEYC_NPAGE, 0, MODEKEYCHOICE_PAGEDOWN }, + { KEYC_PPAGE, 0, MODEKEYCHOICE_PAGEUP }, + { KEYC_UP | KEYC_CTRL, 0, MODEKEYCHOICE_SCROLLUP }, + { KEYC_UP, 0, MODEKEYCHOICE_UP }, + { ' ', 0, MODEKEYCHOICE_TREE_TOGGLE }, + { KEYC_LEFT | KEYC_CTRL, 0, MODEKEYCHOICE_TREE_COLLAPSE_ALL }, + { KEYC_RIGHT | KEYC_CTRL, 0, MODEKEYCHOICE_TREE_EXPAND_ALL }, - { 0, -1, 0 } + { 0, -1, 0 } }; struct mode_key_tree mode_key_tree_vi_choice; /* vi copy mode keys. */ const struct mode_key_entry mode_key_vi_copy[] = { - { ' ', 0, MODEKEYCOPY_STARTSELECTION }, - { '$', 0, MODEKEYCOPY_ENDOFLINE }, - { ',', 0, MODEKEYCOPY_JUMPREVERSE }, - { ';', 0, MODEKEYCOPY_JUMPAGAIN }, - { '/', 0, MODEKEYCOPY_SEARCHDOWN }, - { '0', 0, MODEKEYCOPY_STARTOFLINE }, - { '1', 0, MODEKEYCOPY_STARTNUMBERPREFIX }, - { '2', 0, MODEKEYCOPY_STARTNUMBERPREFIX }, - { '3', 0, MODEKEYCOPY_STARTNUMBERPREFIX }, - { '4', 0, MODEKEYCOPY_STARTNUMBERPREFIX }, - { '5', 0, MODEKEYCOPY_STARTNUMBERPREFIX }, - { '6', 0, MODEKEYCOPY_STARTNUMBERPREFIX }, - { '7', 0, MODEKEYCOPY_STARTNUMBERPREFIX }, - { '8', 0, MODEKEYCOPY_STARTNUMBERPREFIX }, - { '9', 0, MODEKEYCOPY_STARTNUMBERPREFIX }, - { ':', 0, MODEKEYCOPY_GOTOLINE }, - { '?', 0, MODEKEYCOPY_SEARCHUP }, - { 'B', 0, MODEKEYCOPY_PREVIOUSSPACE }, - { 'D', 0, MODEKEYCOPY_COPYENDOFLINE }, - { 'E', 0, MODEKEYCOPY_NEXTSPACEEND }, - { 'F', 0, MODEKEYCOPY_JUMPBACK }, - { 'G', 0, MODEKEYCOPY_HISTORYBOTTOM }, - { 'H', 0, MODEKEYCOPY_TOPLINE }, - { 'J', 0, MODEKEYCOPY_SCROLLDOWN }, - { 'K', 0, MODEKEYCOPY_SCROLLUP }, - { 'L', 0, MODEKEYCOPY_BOTTOMLINE }, - { 'M', 0, MODEKEYCOPY_MIDDLELINE }, - { 'N', 0, MODEKEYCOPY_SEARCHREVERSE }, - { 'T', 0, MODEKEYCOPY_JUMPTOBACK }, - { 'W', 0, MODEKEYCOPY_NEXTSPACE }, - { '\002' /* C-b */, 0, MODEKEYCOPY_PREVIOUSPAGE }, - { '\003' /* C-c */, 0, MODEKEYCOPY_CANCEL }, - { '\004' /* C-d */, 0, MODEKEYCOPY_HALFPAGEDOWN }, - { '\005' /* C-e */, 0, MODEKEYCOPY_SCROLLDOWN }, - { '\006' /* C-f */, 0, MODEKEYCOPY_NEXTPAGE }, - { '\010' /* C-h */, 0, MODEKEYCOPY_LEFT }, - { '\025' /* C-u */, 0, MODEKEYCOPY_HALFPAGEUP }, - { '\031' /* C-y */, 0, MODEKEYCOPY_SCROLLUP }, - { '\033' /* Escape */, 0, MODEKEYCOPY_CLEARSELECTION }, - { '\r', 0, MODEKEYCOPY_COPYSELECTION }, - { '^', 0, MODEKEYCOPY_BACKTOINDENTATION }, - { 'b', 0, MODEKEYCOPY_PREVIOUSWORD }, - { 'e', 0, MODEKEYCOPY_NEXTWORDEND }, - { 'f', 0, MODEKEYCOPY_JUMP }, - { 'g', 0, MODEKEYCOPY_HISTORYTOP }, - { 'h', 0, MODEKEYCOPY_LEFT }, - { 'j', 0, MODEKEYCOPY_DOWN }, - { 'k', 0, MODEKEYCOPY_UP }, - { 'l', 0, MODEKEYCOPY_RIGHT }, - { 'n', 0, MODEKEYCOPY_SEARCHAGAIN }, - { 't', 0, MODEKEYCOPY_JUMPTO }, - { 'q', 0, MODEKEYCOPY_CANCEL }, - { 'v', 0, MODEKEYCOPY_RECTANGLETOGGLE }, - { 'w', 0, MODEKEYCOPY_NEXTWORD }, - { KEYC_BSPACE, 0, MODEKEYCOPY_LEFT }, - { KEYC_DOWN | KEYC_CTRL,0, MODEKEYCOPY_SCROLLDOWN }, - { KEYC_DOWN, 0, MODEKEYCOPY_DOWN }, - { KEYC_LEFT, 0, MODEKEYCOPY_LEFT }, - { KEYC_NPAGE, 0, MODEKEYCOPY_NEXTPAGE }, - { KEYC_PPAGE, 0, MODEKEYCOPY_PREVIOUSPAGE }, - { KEYC_RIGHT, 0, MODEKEYCOPY_RIGHT }, - { KEYC_UP | KEYC_CTRL, 0, MODEKEYCOPY_SCROLLUP }, - { KEYC_UP, 0, MODEKEYCOPY_UP }, + { ' ', 0, MODEKEYCOPY_STARTSELECTION }, + { '$', 0, MODEKEYCOPY_ENDOFLINE }, + { ',', 0, MODEKEYCOPY_JUMPREVERSE }, + { ';', 0, MODEKEYCOPY_JUMPAGAIN }, + { '/', 0, MODEKEYCOPY_SEARCHDOWN }, + { '0', 0, MODEKEYCOPY_STARTOFLINE }, + { '1', 0, MODEKEYCOPY_STARTNUMBERPREFIX }, + { '2', 0, MODEKEYCOPY_STARTNUMBERPREFIX }, + { '3', 0, MODEKEYCOPY_STARTNUMBERPREFIX }, + { '4', 0, MODEKEYCOPY_STARTNUMBERPREFIX }, + { '5', 0, MODEKEYCOPY_STARTNUMBERPREFIX }, + { '6', 0, MODEKEYCOPY_STARTNUMBERPREFIX }, + { '7', 0, MODEKEYCOPY_STARTNUMBERPREFIX }, + { '8', 0, MODEKEYCOPY_STARTNUMBERPREFIX }, + { '9', 0, MODEKEYCOPY_STARTNUMBERPREFIX }, + { ':', 0, MODEKEYCOPY_GOTOLINE }, + { '?', 0, MODEKEYCOPY_SEARCHUP }, + { 'B', 0, MODEKEYCOPY_PREVIOUSSPACE }, + { 'D', 0, MODEKEYCOPY_COPYENDOFLINE }, + { 'E', 0, MODEKEYCOPY_NEXTSPACEEND }, + { 'F', 0, MODEKEYCOPY_JUMPBACK }, + { 'G', 0, MODEKEYCOPY_HISTORYBOTTOM }, + { 'H', 0, MODEKEYCOPY_TOPLINE }, + { 'J', 0, MODEKEYCOPY_SCROLLDOWN }, + { 'K', 0, MODEKEYCOPY_SCROLLUP }, + { 'L', 0, MODEKEYCOPY_BOTTOMLINE }, + { 'M', 0, MODEKEYCOPY_MIDDLELINE }, + { 'N', 0, MODEKEYCOPY_SEARCHREVERSE }, + { 'T', 0, MODEKEYCOPY_JUMPTOBACK }, + { 'W', 0, MODEKEYCOPY_NEXTSPACE }, + { '\002' /* C-b */, 0, MODEKEYCOPY_PREVIOUSPAGE }, + { '\003' /* C-c */, 0, MODEKEYCOPY_CANCEL }, + { '\004' /* C-d */, 0, MODEKEYCOPY_HALFPAGEDOWN }, + { '\005' /* C-e */, 0, MODEKEYCOPY_SCROLLDOWN }, + { '\006' /* C-f */, 0, MODEKEYCOPY_NEXTPAGE }, + { '\010' /* C-h */, 0, MODEKEYCOPY_LEFT }, + { '\025' /* C-u */, 0, MODEKEYCOPY_HALFPAGEUP }, + { '\031' /* C-y */, 0, MODEKEYCOPY_SCROLLUP }, + { '\033' /* Escape */, 0, MODEKEYCOPY_CLEARSELECTION }, + { '\r', 0, MODEKEYCOPY_COPYSELECTION }, + { '^', 0, MODEKEYCOPY_BACKTOINDENTATION }, + { 'b', 0, MODEKEYCOPY_PREVIOUSWORD }, + { 'e', 0, MODEKEYCOPY_NEXTWORDEND }, + { 'f', 0, MODEKEYCOPY_JUMP }, + { 'g', 0, MODEKEYCOPY_HISTORYTOP }, + { 'h', 0, MODEKEYCOPY_LEFT }, + { 'j', 0, MODEKEYCOPY_DOWN }, + { 'k', 0, MODEKEYCOPY_UP }, + { 'l', 0, MODEKEYCOPY_RIGHT }, + { 'n', 0, MODEKEYCOPY_SEARCHAGAIN }, + { 't', 0, MODEKEYCOPY_JUMPTO }, + { 'q', 0, MODEKEYCOPY_CANCEL }, + { 'v', 0, MODEKEYCOPY_RECTANGLETOGGLE }, + { 'w', 0, MODEKEYCOPY_NEXTWORD }, + { KEYC_BSPACE, 0, MODEKEYCOPY_LEFT }, + { KEYC_DOWN | KEYC_CTRL, 0, MODEKEYCOPY_SCROLLDOWN }, + { KEYC_DOWN, 0, MODEKEYCOPY_DOWN }, + { KEYC_LEFT, 0, MODEKEYCOPY_LEFT }, + { KEYC_NPAGE, 0, MODEKEYCOPY_NEXTPAGE }, + { KEYC_PPAGE, 0, MODEKEYCOPY_PREVIOUSPAGE }, + { KEYC_RIGHT, 0, MODEKEYCOPY_RIGHT }, + { KEYC_UP | KEYC_CTRL, 0, MODEKEYCOPY_SCROLLUP }, + { KEYC_UP, 0, MODEKEYCOPY_UP }, - { 0, -1, 0 } + { 0, -1, 0 } }; struct mode_key_tree mode_key_tree_vi_copy; /* emacs editing keys. */ const struct mode_key_entry mode_key_emacs_edit[] = { - { '\001' /* C-a */, 0, MODEKEYEDIT_STARTOFLINE }, - { '\002' /* C-b */, 0, MODEKEYEDIT_CURSORLEFT }, - { '\003' /* C-c */, 0, MODEKEYEDIT_CANCEL }, - { '\004' /* C-d */, 0, MODEKEYEDIT_DELETE }, - { '\005' /* C-e */, 0, MODEKEYEDIT_ENDOFLINE }, - { '\006' /* C-f */, 0, MODEKEYEDIT_CURSORRIGHT }, - { '\010' /* C-H */, 0, MODEKEYEDIT_BACKSPACE }, - { '\011' /* Tab */, 0, MODEKEYEDIT_COMPLETE }, - { '\013' /* C-k */, 0, MODEKEYEDIT_DELETETOENDOFLINE }, - { '\016' /* C-n */, 0, MODEKEYEDIT_HISTORYDOWN }, - { '\020' /* C-p */, 0, MODEKEYEDIT_HISTORYUP }, - { '\024' /* C-t */, 0, MODEKEYEDIT_TRANSPOSECHARS }, - { '\025' /* C-u */, 0, MODEKEYEDIT_DELETELINE }, - { '\027' /* C-w */, 0, MODEKEYEDIT_DELETEWORD }, - { '\031' /* C-y */, 0, MODEKEYEDIT_PASTE }, - { '\033' /* Escape */, 0, MODEKEYEDIT_CANCEL }, - { '\r', 0, MODEKEYEDIT_ENTER }, - { 'b' | KEYC_ESCAPE, 0, MODEKEYEDIT_PREVIOUSWORD }, - { 'f' | KEYC_ESCAPE, 0, MODEKEYEDIT_NEXTWORDEND }, - { 'm' | KEYC_ESCAPE, 0, MODEKEYEDIT_STARTOFLINE }, - { KEYC_BSPACE, 0, MODEKEYEDIT_BACKSPACE }, - { KEYC_DC, 0, MODEKEYEDIT_DELETE }, - { KEYC_DOWN, 0, MODEKEYEDIT_HISTORYDOWN }, - { KEYC_LEFT, 0, MODEKEYEDIT_CURSORLEFT }, - { KEYC_RIGHT, 0, MODEKEYEDIT_CURSORRIGHT }, - { KEYC_UP, 0, MODEKEYEDIT_HISTORYUP }, - { KEYC_HOME, 0, MODEKEYEDIT_STARTOFLINE }, - { KEYC_END, 0, MODEKEYEDIT_ENDOFLINE }, + { '\001' /* C-a */, 0, MODEKEYEDIT_STARTOFLINE }, + { '\002' /* C-b */, 0, MODEKEYEDIT_CURSORLEFT }, + { '\003' /* C-c */, 0, MODEKEYEDIT_CANCEL }, + { '\004' /* C-d */, 0, MODEKEYEDIT_DELETE }, + { '\005' /* C-e */, 0, MODEKEYEDIT_ENDOFLINE }, + { '\006' /* C-f */, 0, MODEKEYEDIT_CURSORRIGHT }, + { '\010' /* C-H */, 0, MODEKEYEDIT_BACKSPACE }, + { '\011' /* Tab */, 0, MODEKEYEDIT_COMPLETE }, + { '\013' /* C-k */, 0, MODEKEYEDIT_DELETETOENDOFLINE }, + { '\016' /* C-n */, 0, MODEKEYEDIT_HISTORYDOWN }, + { '\020' /* C-p */, 0, MODEKEYEDIT_HISTORYUP }, + { '\024' /* C-t */, 0, MODEKEYEDIT_TRANSPOSECHARS }, + { '\025' /* C-u */, 0, MODEKEYEDIT_DELETELINE }, + { '\027' /* C-w */, 0, MODEKEYEDIT_DELETEWORD }, + { '\031' /* C-y */, 0, MODEKEYEDIT_PASTE }, + { '\033' /* Escape */, 0, MODEKEYEDIT_CANCEL }, + { '\r', 0, MODEKEYEDIT_ENTER }, + { 'b' | KEYC_ESCAPE, 0, MODEKEYEDIT_PREVIOUSWORD }, + { 'f' | KEYC_ESCAPE, 0, MODEKEYEDIT_NEXTWORDEND }, + { 'm' | KEYC_ESCAPE, 0, MODEKEYEDIT_STARTOFLINE }, + { KEYC_BSPACE, 0, MODEKEYEDIT_BACKSPACE }, + { KEYC_DC, 0, MODEKEYEDIT_DELETE }, + { KEYC_DOWN, 0, MODEKEYEDIT_HISTORYDOWN }, + { KEYC_LEFT, 0, MODEKEYEDIT_CURSORLEFT }, + { KEYC_RIGHT, 0, MODEKEYEDIT_CURSORRIGHT }, + { KEYC_UP, 0, MODEKEYEDIT_HISTORYUP }, + { KEYC_HOME, 0, MODEKEYEDIT_STARTOFLINE }, + { KEYC_END, 0, MODEKEYEDIT_ENDOFLINE }, - { 0, -1, 0 } + { 0, -1, 0 } }; struct mode_key_tree mode_key_tree_emacs_edit; /* emacs choice selection keys. */ const struct mode_key_entry mode_key_emacs_choice[] = { - { '0' | KEYC_ESCAPE, 0, MODEKEYCHOICE_STARTNUMBERPREFIX }, - { '1' | KEYC_ESCAPE, 0, MODEKEYCHOICE_STARTNUMBERPREFIX }, - { '2' | KEYC_ESCAPE, 0, MODEKEYCHOICE_STARTNUMBERPREFIX }, - { '3' | KEYC_ESCAPE, 0, MODEKEYCHOICE_STARTNUMBERPREFIX }, - { '4' | KEYC_ESCAPE, 0, MODEKEYCHOICE_STARTNUMBERPREFIX }, - { '5' | KEYC_ESCAPE, 0, MODEKEYCHOICE_STARTNUMBERPREFIX }, - { '6' | KEYC_ESCAPE, 0, MODEKEYCHOICE_STARTNUMBERPREFIX }, - { '7' | KEYC_ESCAPE, 0, MODEKEYCHOICE_STARTNUMBERPREFIX }, - { '8' | KEYC_ESCAPE, 0, MODEKEYCHOICE_STARTNUMBERPREFIX }, - { '9' | KEYC_ESCAPE, 0, MODEKEYCHOICE_STARTNUMBERPREFIX }, - { '\003' /* C-c */, 0, MODEKEYCHOICE_CANCEL }, - { '\016' /* C-n */, 0, MODEKEYCHOICE_DOWN }, - { '\020' /* C-p */, 0, MODEKEYCHOICE_UP }, - { '\026' /* C-v */, 0, MODEKEYCHOICE_PAGEDOWN }, - { '\033' /* Escape */, 0, MODEKEYCHOICE_CANCEL }, - { '\r', 0, MODEKEYCHOICE_CHOOSE }, - { 'q', 0, MODEKEYCHOICE_CANCEL }, - { 'v' | KEYC_ESCAPE, 0, MODEKEYCHOICE_PAGEUP }, - { KEYC_BSPACE, 0, MODEKEYCHOICE_BACKSPACE }, - { KEYC_DOWN | KEYC_CTRL,0, MODEKEYCHOICE_SCROLLDOWN }, - { KEYC_DOWN, 0, MODEKEYCHOICE_DOWN }, - { KEYC_NPAGE, 0, MODEKEYCHOICE_PAGEDOWN }, - { KEYC_PPAGE, 0, MODEKEYCHOICE_PAGEUP }, - { KEYC_UP | KEYC_CTRL, 0, MODEKEYCHOICE_SCROLLUP }, - { KEYC_UP, 0, MODEKEYCHOICE_UP }, + { '0' | KEYC_ESCAPE, 0, MODEKEYCHOICE_STARTNUMBERPREFIX }, + { '1' | KEYC_ESCAPE, 0, MODEKEYCHOICE_STARTNUMBERPREFIX }, + { '2' | KEYC_ESCAPE, 0, MODEKEYCHOICE_STARTNUMBERPREFIX }, + { '3' | KEYC_ESCAPE, 0, MODEKEYCHOICE_STARTNUMBERPREFIX }, + { '4' | KEYC_ESCAPE, 0, MODEKEYCHOICE_STARTNUMBERPREFIX }, + { '5' | KEYC_ESCAPE, 0, MODEKEYCHOICE_STARTNUMBERPREFIX }, + { '6' | KEYC_ESCAPE, 0, MODEKEYCHOICE_STARTNUMBERPREFIX }, + { '7' | KEYC_ESCAPE, 0, MODEKEYCHOICE_STARTNUMBERPREFIX }, + { '8' | KEYC_ESCAPE, 0, MODEKEYCHOICE_STARTNUMBERPREFIX }, + { '9' | KEYC_ESCAPE, 0, MODEKEYCHOICE_STARTNUMBERPREFIX }, + { '\003' /* C-c */, 0, MODEKEYCHOICE_CANCEL }, + { '\016' /* C-n */, 0, MODEKEYCHOICE_DOWN }, + { '\020' /* C-p */, 0, MODEKEYCHOICE_UP }, + { '\026' /* C-v */, 0, MODEKEYCHOICE_PAGEDOWN }, + { '\033' /* Escape */, 0, MODEKEYCHOICE_CANCEL }, + { '\r', 0, MODEKEYCHOICE_CHOOSE }, + { 'q', 0, MODEKEYCHOICE_CANCEL }, + { 'v' | KEYC_ESCAPE, 0, MODEKEYCHOICE_PAGEUP }, + { KEYC_BSPACE, 0, MODEKEYCHOICE_BACKSPACE }, + { KEYC_DOWN | KEYC_CTRL, 0, MODEKEYCHOICE_SCROLLDOWN }, + { KEYC_DOWN, 0, MODEKEYCHOICE_DOWN }, + { KEYC_NPAGE, 0, MODEKEYCHOICE_PAGEDOWN }, + { KEYC_PPAGE, 0, MODEKEYCHOICE_PAGEUP }, + { KEYC_UP | KEYC_CTRL, 0, MODEKEYCHOICE_SCROLLUP }, + { KEYC_UP, 0, MODEKEYCHOICE_UP }, + { ' ', 0, MODEKEYCHOICE_TREE_TOGGLE }, + { KEYC_LEFT, 0, MODEKEYCHOICE_TREE_COLLAPSE }, + { KEYC_RIGHT, 0, MODEKEYCHOICE_TREE_EXPAND }, + { KEYC_LEFT | KEYC_CTRL, 0, MODEKEYCHOICE_TREE_COLLAPSE_ALL }, + { KEYC_RIGHT | KEYC_CTRL, 0, MODEKEYCHOICE_TREE_EXPAND_ALL }, - { 0, -1, 0 } + { 0, -1, 0 } }; struct mode_key_tree mode_key_tree_emacs_choice; /* emacs copy mode keys. */ const struct mode_key_entry mode_key_emacs_copy[] = { - { ' ', 0, MODEKEYCOPY_NEXTPAGE }, - { ',', 0, MODEKEYCOPY_JUMPREVERSE }, - { ';', 0, MODEKEYCOPY_JUMPAGAIN }, - { '1' | KEYC_ESCAPE, 0, MODEKEYCOPY_STARTNUMBERPREFIX }, - { '2' | KEYC_ESCAPE, 0, MODEKEYCOPY_STARTNUMBERPREFIX }, - { '3' | KEYC_ESCAPE, 0, MODEKEYCOPY_STARTNUMBERPREFIX }, - { '4' | KEYC_ESCAPE, 0, MODEKEYCOPY_STARTNUMBERPREFIX }, - { '5' | KEYC_ESCAPE, 0, MODEKEYCOPY_STARTNUMBERPREFIX }, - { '6' | KEYC_ESCAPE, 0, MODEKEYCOPY_STARTNUMBERPREFIX }, - { '7' | KEYC_ESCAPE, 0, MODEKEYCOPY_STARTNUMBERPREFIX }, - { '8' | KEYC_ESCAPE, 0, MODEKEYCOPY_STARTNUMBERPREFIX }, - { '9' | KEYC_ESCAPE, 0, MODEKEYCOPY_STARTNUMBERPREFIX }, - { '<' | KEYC_ESCAPE, 0, MODEKEYCOPY_HISTORYTOP }, - { '>' | KEYC_ESCAPE, 0, MODEKEYCOPY_HISTORYBOTTOM }, - { 'F', 0, MODEKEYCOPY_JUMPBACK }, - { 'N', 0, MODEKEYCOPY_SEARCHREVERSE }, - { 'R' | KEYC_ESCAPE, 0, MODEKEYCOPY_TOPLINE }, - { 'R', 0, MODEKEYCOPY_RECTANGLETOGGLE }, - { 'T', 0, MODEKEYCOPY_JUMPTOBACK }, - { '\000' /* C-Space */, 0, MODEKEYCOPY_STARTSELECTION }, - { '\001' /* C-a */, 0, MODEKEYCOPY_STARTOFLINE }, - { '\002' /* C-b */, 0, MODEKEYCOPY_LEFT }, - { '\003' /* C-c */, 0, MODEKEYCOPY_CANCEL }, - { '\005' /* C-e */, 0, MODEKEYCOPY_ENDOFLINE }, - { '\006' /* C-f */, 0, MODEKEYCOPY_RIGHT }, - { '\007' /* C-g */, 0, MODEKEYCOPY_CLEARSELECTION }, - { '\013' /* C-k */, 0, MODEKEYCOPY_COPYENDOFLINE }, - { '\016' /* C-n */, 0, MODEKEYCOPY_DOWN }, - { '\020' /* C-p */, 0, MODEKEYCOPY_UP }, - { '\022' /* C-r */, 0, MODEKEYCOPY_SEARCHUP }, - { '\023' /* C-s */, 0, MODEKEYCOPY_SEARCHDOWN }, - { '\026' /* C-v */, 0, MODEKEYCOPY_NEXTPAGE }, - { '\027' /* C-w */, 0, MODEKEYCOPY_COPYSELECTION }, - { '\033' /* Escape */, 0, MODEKEYCOPY_CANCEL }, - { 'N', 0, MODEKEYCOPY_SEARCHREVERSE }, - { 'b' | KEYC_ESCAPE, 0, MODEKEYCOPY_PREVIOUSWORD }, - { 'f', 0, MODEKEYCOPY_JUMP }, - { 'f' | KEYC_ESCAPE, 0, MODEKEYCOPY_NEXTWORDEND }, - { 'g', 0, MODEKEYCOPY_GOTOLINE }, - { 'm' | KEYC_ESCAPE, 0, MODEKEYCOPY_BACKTOINDENTATION }, - { 'n', 0, MODEKEYCOPY_SEARCHAGAIN }, - { 'q', 0, MODEKEYCOPY_CANCEL }, - { 'r' | KEYC_ESCAPE, 0, MODEKEYCOPY_MIDDLELINE }, - { 't', 0, MODEKEYCOPY_JUMPTO }, - { 'v' | KEYC_ESCAPE, 0, MODEKEYCOPY_PREVIOUSPAGE }, - { 'w' | KEYC_ESCAPE, 0, MODEKEYCOPY_COPYSELECTION }, - { KEYC_DOWN | KEYC_CTRL,0, MODEKEYCOPY_SCROLLDOWN }, - { KEYC_DOWN | KEYC_ESCAPE, 0, MODEKEYCOPY_HALFPAGEDOWN }, - { KEYC_DOWN, 0, MODEKEYCOPY_DOWN }, - { KEYC_LEFT, 0, MODEKEYCOPY_LEFT }, - { KEYC_NPAGE, 0, MODEKEYCOPY_NEXTPAGE }, - { KEYC_PPAGE, 0, MODEKEYCOPY_PREVIOUSPAGE }, - { KEYC_RIGHT, 0, MODEKEYCOPY_RIGHT }, - { KEYC_UP | KEYC_CTRL, 0, MODEKEYCOPY_SCROLLUP }, - { KEYC_UP | KEYC_ESCAPE, 0, MODEKEYCOPY_HALFPAGEUP }, - { KEYC_UP, 0, MODEKEYCOPY_UP }, + { ' ', 0, MODEKEYCOPY_NEXTPAGE }, + { ',', 0, MODEKEYCOPY_JUMPREVERSE }, + { ';', 0, MODEKEYCOPY_JUMPAGAIN }, + { '1' | KEYC_ESCAPE, 0, MODEKEYCOPY_STARTNUMBERPREFIX }, + { '2' | KEYC_ESCAPE, 0, MODEKEYCOPY_STARTNUMBERPREFIX }, + { '3' | KEYC_ESCAPE, 0, MODEKEYCOPY_STARTNUMBERPREFIX }, + { '4' | KEYC_ESCAPE, 0, MODEKEYCOPY_STARTNUMBERPREFIX }, + { '5' | KEYC_ESCAPE, 0, MODEKEYCOPY_STARTNUMBERPREFIX }, + { '6' | KEYC_ESCAPE, 0, MODEKEYCOPY_STARTNUMBERPREFIX }, + { '7' | KEYC_ESCAPE, 0, MODEKEYCOPY_STARTNUMBERPREFIX }, + { '8' | KEYC_ESCAPE, 0, MODEKEYCOPY_STARTNUMBERPREFIX }, + { '9' | KEYC_ESCAPE, 0, MODEKEYCOPY_STARTNUMBERPREFIX }, + { '<' | KEYC_ESCAPE, 0, MODEKEYCOPY_HISTORYTOP }, + { '>' | KEYC_ESCAPE, 0, MODEKEYCOPY_HISTORYBOTTOM }, + { 'F', 0, MODEKEYCOPY_JUMPBACK }, + { 'N', 0, MODEKEYCOPY_SEARCHREVERSE }, + { 'R' | KEYC_ESCAPE, 0, MODEKEYCOPY_TOPLINE }, + { 'R', 0, MODEKEYCOPY_RECTANGLETOGGLE }, + { 'T', 0, MODEKEYCOPY_JUMPTOBACK }, + { '\000' /* C-Space */, 0, MODEKEYCOPY_STARTSELECTION }, + { '\001' /* C-a */, 0, MODEKEYCOPY_STARTOFLINE }, + { '\002' /* C-b */, 0, MODEKEYCOPY_LEFT }, + { '\003' /* C-c */, 0, MODEKEYCOPY_CANCEL }, + { '\005' /* C-e */, 0, MODEKEYCOPY_ENDOFLINE }, + { '\006' /* C-f */, 0, MODEKEYCOPY_RIGHT }, + { '\007' /* C-g */, 0, MODEKEYCOPY_CLEARSELECTION }, + { '\013' /* C-k */, 0, MODEKEYCOPY_COPYENDOFLINE }, + { '\016' /* C-n */, 0, MODEKEYCOPY_DOWN }, + { '\020' /* C-p */, 0, MODEKEYCOPY_UP }, + { '\022' /* C-r */, 0, MODEKEYCOPY_SEARCHUP }, + { '\023' /* C-s */, 0, MODEKEYCOPY_SEARCHDOWN }, + { '\026' /* C-v */, 0, MODEKEYCOPY_NEXTPAGE }, + { '\027' /* C-w */, 0, MODEKEYCOPY_COPYSELECTION }, + { '\033' /* Escape */, 0, MODEKEYCOPY_CANCEL }, + { 'N', 0, MODEKEYCOPY_SEARCHREVERSE }, + { 'b' | KEYC_ESCAPE, 0, MODEKEYCOPY_PREVIOUSWORD }, + { 'f', 0, MODEKEYCOPY_JUMP }, + { 'f' | KEYC_ESCAPE, 0, MODEKEYCOPY_NEXTWORDEND }, + { 'g', 0, MODEKEYCOPY_GOTOLINE }, + { 'm' | KEYC_ESCAPE, 0, MODEKEYCOPY_BACKTOINDENTATION }, + { 'n', 0, MODEKEYCOPY_SEARCHAGAIN }, + { 'q', 0, MODEKEYCOPY_CANCEL }, + { 'r' | KEYC_ESCAPE, 0, MODEKEYCOPY_MIDDLELINE }, + { 't', 0, MODEKEYCOPY_JUMPTO }, + { 'v' | KEYC_ESCAPE, 0, MODEKEYCOPY_PREVIOUSPAGE }, + { 'w' | KEYC_ESCAPE, 0, MODEKEYCOPY_COPYSELECTION }, + { KEYC_DOWN | KEYC_CTRL, 0, MODEKEYCOPY_SCROLLDOWN }, + { KEYC_DOWN | KEYC_ESCAPE, 0, MODEKEYCOPY_HALFPAGEDOWN }, + { KEYC_DOWN, 0, MODEKEYCOPY_DOWN }, + { KEYC_LEFT, 0, MODEKEYCOPY_LEFT }, + { KEYC_NPAGE, 0, MODEKEYCOPY_NEXTPAGE }, + { KEYC_PPAGE, 0, MODEKEYCOPY_PREVIOUSPAGE }, + { KEYC_RIGHT, 0, MODEKEYCOPY_RIGHT }, + { KEYC_UP | KEYC_CTRL, 0, MODEKEYCOPY_SCROLLUP }, + { KEYC_UP | KEYC_ESCAPE, 0, MODEKEYCOPY_HALFPAGEUP }, + { KEYC_UP, 0, MODEKEYCOPY_UP }, - { 0, -1, 0 } + { 0, -1, 0 } }; struct mode_key_tree mode_key_tree_emacs_copy; Index: tmux.h =================================================================== RCS file: /cvs/src/usr.bin/tmux/tmux.h,v retrieving revision 1.358 diff -u -p -r1.358 tmux.h --- tmux.h 25 Sep 2012 07:41:22 -0000 1.358 +++ tmux.h 2 Oct 2012 07:48:07 -0000 @@ -552,6 +552,11 @@ enum mode_key_cmd { MODEKEYCHOICE_SCROLLDOWN, MODEKEYCHOICE_SCROLLUP, MODEKEYCHOICE_STARTNUMBERPREFIX, + MODEKEYCHOICE_TREE_COLLAPSE, + MODEKEYCHOICE_TREE_COLLAPSE_ALL, + MODEKEYCHOICE_TREE_EXPAND, + MODEKEYCHOICE_TREE_EXPAND_ALL, + MODEKEYCHOICE_TREE_TOGGLE, MODEKEYCHOICE_UP, /* Copy keys. */ @@ -891,12 +896,16 @@ struct window_mode { /* Structures for choose mode. */ struct window_choose_data { struct client *client; - struct session *session; + struct session *session; /* Session of current client. */ + struct session *tree_session; /* Session of items in tree. */ struct format_tree *ft; struct winlink *wl; char *ft_template; char *command; u_int idx; + int type; +#define TREE_WINDOW 0x1 +#define TREE_SESSION 0x2 int pane_id; }; @@ -904,6 +913,8 @@ struct window_choose_mode_item { struct window_choose_data *wcd; char *name; int pos; + int state; +#define TREE_EXPANDED 0x1 }; /* Child window structure. */ Index: window-choose.c =================================================================== RCS file: /cvs/src/usr.bin/tmux/window-choose.c,v retrieving revision 1.26 diff -u -p -r1.26 window-choose.c --- window-choose.c 3 Sep 2012 09:57:57 -0000 1.26 +++ window-choose.c 2 Oct 2012 07:50:04 -0000 @@ -40,6 +40,11 @@ void window_choose_write_line( void window_choose_scroll_up(struct window_pane *); void window_choose_scroll_down(struct window_pane *); +void window_choose_collapse(struct window_pane *, struct session *); +void window_choose_expand(struct window_pane *, struct session *, u_int); +void window_choose_collapse_all(struct window_pane *); +void window_choose_expand_all(struct window_pane *); + enum window_choose_input_type { WINDOW_CHOOSE_NORMAL = -1, WINDOW_CHOOSE_GOTO_ITEM, @@ -60,6 +65,7 @@ struct window_choose_mode_data { struct mode_key_data mdata; ARRAY_DECL(, struct window_choose_mode_item) list; + ARRAY_DECL(, struct window_choose_mode_item) old_list; int width; u_int top; u_int selected; @@ -89,6 +95,7 @@ window_choose_add(struct window_pane *wp item->name = format_expand(wcd->ft, wcd->ft_template); item->wcd = wcd; item->pos = ARRAY_LENGTH(&data->list) - 1; + item->state = 0; data->width = xsnprintf (tmp, sizeof tmp , "%u", item->pos); } @@ -108,6 +115,9 @@ window_choose_ready(struct window_pane * data->callbackfn = callbackfn; data->freefn = freefn; + ARRAY_CONCAT(&data->old_list, &data->list); + + window_choose_collapse_all(wp); window_choose_redraw_screen(wp); } @@ -127,6 +137,7 @@ window_choose_init(struct window_pane *w data->input_prompt = NULL; ARRAY_INIT(&data->list); + ARRAY_INIT(&data->old_list); data->top = 0; s = &data->screen; @@ -154,9 +165,11 @@ window_choose_data_create(struct cmd_ctx wcd->ft_template = NULL; wcd->command = NULL; wcd->wl = NULL; + wcd->tree_session = NULL; wcd->client = ctx->curclient; wcd->session = ctx->curclient->session; wcd->idx = -1; + wcd->type = 0; return (wcd); } @@ -175,6 +188,7 @@ window_choose_free(struct window_pane *w free(item->name); } ARRAY_FREE(&data->list); + ARRAY_FREE(&data->old_list); free(data->input_str); screen_free(&data->screen); @@ -228,6 +242,166 @@ window_choose_prompt_input(enum window_c window_choose_redraw_screen(wp); } +void +window_choose_collapse(struct window_pane *wp, struct session *s) +{ + struct window_choose_mode_data *data = wp->modedata; + struct window_choose_mode_item *item, *chosen; + struct window_choose_data *wcd; + u_int i, pos; + + ARRAY_DECL(, struct window_choose_mode_item) list_copy; + ARRAY_INIT(&list_copy); + + pos = data->selected; + + chosen = &ARRAY_ITEM(&data->list, pos); + chosen->state &= ~TREE_EXPANDED; + + /* + * Trying to mangle the &data->list in-place has lots of problems, so + * assign the actual result we want to render and copy the new one over + * the top of it. + */ + for (i = 0; i < ARRAY_LENGTH(&data->list); i++) + { + item = &ARRAY_ITEM(&data->list, i); + wcd = item->wcd; + + if (s == wcd->tree_session) { + /* We only show the session when collapsed. */ + if (wcd->type & TREE_SESSION) { + item->state &= ~TREE_EXPANDED; + + ARRAY_ADD(&list_copy, + ARRAY_ITEM(&data->list, i)); + /* + * Update the selection to this session item so + * we don't end up highlighting a non-existent + * item. + */ + data->selected = i; + } + } else + ARRAY_ADD(&list_copy, ARRAY_ITEM(&data->list, i)); + } + + if (!ARRAY_EMPTY(&list_copy)) { + ARRAY_FREE(&data->list); + ARRAY_CONCAT(&data->list, &list_copy); + } +} + +void +window_choose_collapse_all(struct window_pane *wp) +{ + struct window_choose_mode_data *data = wp->modedata; + struct window_choose_mode_item *item, *chosen; + struct session *s; + u_int i; + + chosen = &ARRAY_ITEM(&data->list, data->selected); + + RB_FOREACH(s, sessions, &sessions) + window_choose_collapse(wp, s); + + /* Reset the selection back to the starting session. */ + for (i = 0; i < ARRAY_LENGTH(&data->list); i++) { + item = &ARRAY_ITEM(&data->list, i); + + if (chosen->wcd->session != item->wcd->tree_session) + continue; + + if (item->wcd->type & TREE_SESSION) + data->selected = i; + } + window_choose_redraw_screen(wp); +} + +void +window_choose_expand_all(struct window_pane *wp) +{ + struct window_choose_mode_data *data = wp->modedata; + struct window_choose_mode_item *item; + struct session *s; + u_int i; + + RB_FOREACH(s, sessions, &sessions) { + for (i = 0; i < ARRAY_LENGTH(&data->list); i++) { + item = &ARRAY_ITEM(&data->list, i); + + if (s != item->wcd->tree_session) + continue; + + if (item->wcd->type & TREE_SESSION) + window_choose_expand(wp, s, i); + } + } + + window_choose_redraw_screen(wp); +} + +void +window_choose_expand(struct window_pane *wp, struct session *s, u_int pos) +{ + struct window_choose_mode_data *data = wp->modedata; + struct window_choose_mode_item *item, *chosen; + struct window_choose_data *wcd; + u_int i, items; + + chosen = &ARRAY_ITEM(&data->list, pos); + items = ARRAY_LENGTH(&data->old_list) - 1; + + /* It's not possible to expand anything other than sessions. */ + if (!(chosen->wcd->type & TREE_SESSION)) + return; + + /* Don't re-expand a session which is already expanded. */ + if (chosen->state & TREE_EXPANDED) + return; + + /* Mark the session entry as expanded. */ + chosen->state |= TREE_EXPANDED; + + /* + * Go back through the original list of all sessions and windows, and + * pull out the windows where the session matches the selection chosen + * to expand. + */ + for (i = items; i > 0; i--) { + item = &ARRAY_ITEM(&data->old_list, i); + item->state |= TREE_EXPANDED; + wcd = item->wcd; + + if (s == wcd->tree_session) { + /* + * Since the session is already displayed, we only care + * to add back in window for it. + */ + if (wcd->type & TREE_WINDOW) { + /* + * If the insertion point for adding the + * windows to the session falls inside the + * range of the list, then we insert these + * entries in order *AFTER* the selected + * session. + */ + if (pos < i ) { + ARRAY_INSERT(&data->list, + pos + 1, + ARRAY_ITEM(&data->old_list, + i)); + } else { + /* Ran out of room, add to the end. */ + ARRAY_ADD(&data->list, + ARRAY_ITEM(&data->old_list, + i)); + } + } + } + } +} + /* ARGSUSED */ void window_choose_key(struct window_pane *wp, unused struct session *sess, int key) @@ -237,7 +411,7 @@ window_choose_key(struct window_pane *wp struct screen_write_ctx ctx; struct window_choose_mode_item *item; size_t input_len; - u_int items, n; + u_int items, n; int idx; items = ARRAY_LENGTH(&data->list); @@ -285,6 +459,37 @@ window_choose_key(struct window_pane *wp window_choose_fire_callback(wp, item->wcd); window_pane_reset_mode(wp); break; + case MODEKEYCHOICE_TREE_TOGGLE: + item = &ARRAY_ITEM(&data->list, data->selected); + if (item->state & TREE_EXPANDED) + window_choose_collapse(wp, item->wcd->tree_session); + else { + window_choose_expand(wp, item->wcd->tree_session, + data->selected); + } + window_choose_redraw_screen(wp); + break; + case MODEKEYCHOICE_TREE_COLLAPSE: + item = &ARRAY_ITEM(&data->list, data->selected); + if (item->state & TREE_EXPANDED) { + window_choose_collapse(wp, item->wcd->tree_session); + window_choose_redraw_screen(wp); + } + break; + case MODEKEYCHOICE_TREE_COLLAPSE_ALL: + window_choose_collapse_all(wp); + break; + case MODEKEYCHOICE_TREE_EXPAND: + item = &ARRAY_ITEM(&data->list, data->selected); + if (!(item->state & TREE_EXPANDED)) { + window_choose_expand(wp, item->wcd->tree_session, + data->selected); + window_choose_redraw_screen(wp); + } + break; + case MODEKEYCHOICE_TREE_EXPAND_ALL: + window_choose_expand_all(wp); + break; case MODEKEYCHOICE_UP: if (items == 0) break; @@ -469,7 +674,13 @@ window_choose_write_line( else xsnprintf (label, sizeof label, "(%d)", item->pos); screen_write_nputs(ctx, screen_size_x(s) - 1, &gc, utf8flag, - "%*s %s", data->width + 2, label, item->name); + "%*s %s %s", data->width + 2, label, + /* + * Add indication to tree if necessary about whether it's + * expanded or not. + */ + (item->wcd->type & TREE_SESSION) ? + (item->state & TREE_EXPANDED ? "-" : "+") : "", item->name); } while (s->cx < screen_size_x(s)) screen_write_putc(ctx, &gc, ' '); @@ -623,6 +834,8 @@ window_choose_add_session(struct window_ wcd = window_choose_data_create(ctx); wcd->idx = s->idx; + wcd->tree_session = s; + wcd->type = TREE_SESSION; wcd->command = cmd_template_replace(action, s->name, 1); wcd->ft_template = xstrdup(template); format_add(wcd->ft, "line", "%u", idx); @@ -684,6 +897,8 @@ window_choose_add_window(struct window_p wcd->idx = wl->idx; wcd->wl = wl; + wcd->tree_session = s; + wcd->type = TREE_WINDOW; wcd->ft_template = xstrdup(template); format_add(wcd->ft, "line", "%u", idx); format_session(wcd->ft, s); On Mon, Oct 01, 2012 at 01:24:46PM +0100, Thomas Adam wrote: > This patch adds the ability to expand/collapse a single session using the > spacebar. > > Likewise, C-Left and C-Right will collapse and expand all sessions, > respectively. > --- > This is the second version of the original patch, which takes Romain's > suggestion. Now, spacebar will expand/collapse a single session. There is > no longer explicit expand/collapse bindings -- only COLLAPSE_EXPAND_TOGGLE. > > Fixed a minor bug with selecting sessions after collapsing them too. > > I've still left the bindings for expand_all and collapse_all unchanged -- > if they need to change, feel free to do so. I suppose I'll have to update > the man page? > > mode-key.c | 9 +++ > tmux.h | 11 ++- > window-choose.c | 206 > +++++++++++++++++++++++++++++++++++++++++++++++++++++++- > 3 files changed, 223 insertions(+), 3 deletions(-) > > diff --git a/mode-key.c b/mode-key.c > index cacdb91..887abf4 100644 > --- a/mode-key.c > +++ b/mode-key.c > @@ -77,7 +77,10 @@ const struct mode_key_cmdstr mode_key_cmdstr_choice[] = { > { MODEKEYCHOICE_BACKSPACE, "backspace" }, > { MODEKEYCHOICE_CANCEL, "cancel" }, > { MODEKEYCHOICE_CHOOSE, "choose" }, > + { MODEKEYCHOICE_COLLAPSE_ALL, "collapse-all" }, > + { MODEKEYCHOICE_COLLAPSE_EXPAND_TOGGLE, "collapse-toggle" }, > { MODEKEYCHOICE_DOWN, "down" }, > + { MODEKEYCHOICE_EXPAND_ALL, "expand-all" }, > { MODEKEYCHOICE_PAGEDOWN, "page-down" }, > { MODEKEYCHOICE_PAGEUP, "page-up" }, > { MODEKEYCHOICE_SCROLLDOWN, "scroll-down" }, > @@ -218,6 +221,9 @@ const struct mode_key_entry mode_key_vi_choice[] = { > { KEYC_PPAGE, 0, MODEKEYCHOICE_PAGEUP }, > { KEYC_UP | KEYC_CTRL, 0, MODEKEYCHOICE_SCROLLUP }, > { KEYC_UP, 0, MODEKEYCHOICE_UP }, > + { ' ', 0, MODEKEYCHOICE_COLLAPSE_EXPAND_TOGGLE }, > + { KEYC_LEFT | KEYC_CTRL,0, MODEKEYCHOICE_COLLAPSE_ALL }, > + { KEYC_RIGHT | KEYC_CTRL,0,MODEKEYCHOICE_EXPAND_ALL }, > > { 0, -1, 0 } > }; > @@ -355,6 +361,9 @@ const struct mode_key_entry mode_key_emacs_choice[] = { > { KEYC_PPAGE, 0, MODEKEYCHOICE_PAGEUP }, > { KEYC_UP | KEYC_CTRL, 0, MODEKEYCHOICE_SCROLLUP }, > { KEYC_UP, 0, MODEKEYCHOICE_UP }, > + { ' ', 0, MODEKEYCHOICE_COLLAPSE_EXPAND_TOGGLE }, > + { KEYC_LEFT | KEYC_CTRL,0, MODEKEYCHOICE_COLLAPSE_ALL }, > + { KEYC_RIGHT | KEYC_CTRL,0,MODEKEYCHOICE_EXPAND_ALL }, > > { 0, -1, 0 } > }; > diff --git a/tmux.h b/tmux.h > index c18499b..25d5bf5 100644 > --- a/tmux.h > +++ b/tmux.h > @@ -542,7 +542,10 @@ enum mode_key_cmd { > MODEKEYCHOICE_BACKSPACE, > MODEKEYCHOICE_CANCEL, > MODEKEYCHOICE_CHOOSE, > + MODEKEYCHOICE_COLLAPSE_ALL, > + MODEKEYCHOICE_COLLAPSE_EXPAND_TOGGLE, > MODEKEYCHOICE_DOWN, > + MODEKEYCHOICE_EXPAND_ALL, > MODEKEYCHOICE_PAGEDOWN, > MODEKEYCHOICE_PAGEUP, > MODEKEYCHOICE_SCROLLDOWN, > @@ -887,12 +890,16 @@ struct window_mode { > /* Structures for choose mode. */ > struct window_choose_data { > struct client *client; > - struct session *session; > + struct session *session; /* Session of current client. */ > + struct session *tree_session; /* Session of items in tree. */ > struct format_tree *ft; > struct winlink *wl; > char *ft_template; > char *command; > u_int idx; > + int type; > +#define TREE_WINDOW 0x1 > +#define TREE_SESSION 0x2 > int pane_id; > }; > > @@ -900,6 +907,8 @@ struct window_choose_mode_item { > struct window_choose_data *wcd; > char *name; > int pos; > + int state; > +#define TREE_EXPANDED 0x1 > }; > > /* Child window structure. */ > diff --git a/window-choose.c b/window-choose.c > index c77a1d3..acde980 100644 > --- a/window-choose.c > +++ b/window-choose.c > @@ -40,6 +40,12 @@ void window_choose_write_line( > void window_choose_scroll_up(struct window_pane *); > void window_choose_scroll_down(struct window_pane *); > > +void window_choose_collapse(struct window_pane *, struct session *); > +void window_choose_expand(struct window_pane *, struct session *, u_int); > + > +void window_choose_collapse_all(struct window_pane *); > +void window_choose_expand_all(struct window_pane *); > + > enum window_choose_input_type { > WINDOW_CHOOSE_NORMAL = -1, > WINDOW_CHOOSE_GOTO_ITEM, > @@ -60,6 +66,7 @@ struct window_choose_mode_data { > struct mode_key_data mdata; > > ARRAY_DECL(, struct window_choose_mode_item) list; > + ARRAY_DECL(, struct window_choose_mode_item) list_orig; > int width; > u_int top; > u_int selected; > @@ -89,6 +96,7 @@ window_choose_add(struct window_pane *wp, struct > window_choose_data *wcd) > item->name = format_expand(wcd->ft, wcd->ft_template); > item->wcd = wcd; > item->pos = ARRAY_LENGTH(&data->list) - 1; > + item->state = 0; > > data->width = xsnprintf (tmp, sizeof tmp , "%u", item->pos); > } > @@ -108,6 +116,9 @@ window_choose_ready(struct window_pane *wp, u_int cur, > data->callbackfn = callbackfn; > data->freefn = freefn; > > + ARRAY_CONCAT(&data->list_orig, &data->list); > + > + window_choose_collapse_all(wp); > window_choose_redraw_screen(wp); > } > > @@ -127,6 +138,7 @@ window_choose_init(struct window_pane *wp) > data->input_prompt = NULL; > > ARRAY_INIT(&data->list); > + ARRAY_INIT(&data->list_orig); > data->top = 0; > > s = &data->screen; > @@ -154,9 +166,11 @@ window_choose_data_create(struct cmd_ctx *ctx) > wcd->ft_template = NULL; > wcd->command = NULL; > wcd->wl = NULL; > + wcd->tree_session = NULL; > wcd->client = ctx->curclient; > wcd->session = ctx->curclient->session; > wcd->idx = -1; > + wcd->type = 0; > > return (wcd); > } > @@ -175,6 +189,7 @@ window_choose_free(struct window_pane *wp) > free(item->name); > } > ARRAY_FREE(&data->list); > + ARRAY_FREE(&data->list_orig); > free(data->input_str); > > screen_free(&data->screen); > @@ -228,6 +243,168 @@ window_choose_prompt_input(enum > window_choose_input_type input_type, > window_choose_redraw_screen(wp); > } > > +void > +window_choose_collapse(struct window_pane *wp, struct session *s) > +{ > + struct window_choose_mode_data *data = wp->modedata; > + struct window_choose_mode_item *item, *chosen; > + struct window_choose_data *wcd; > + u_int i, pos; > + > + ARRAY_DECL(, struct window_choose_mode_item) list_copy; > + ARRAY_INIT(&list_copy); > + > + pos = data->selected; > + > + chosen = &ARRAY_ITEM(&data->list, pos); > + chosen->state &= ~TREE_EXPANDED; > + > + /* > + * Trying to mangle the &data->list in-place has lots of problems, so > + * assign the actual result we want to render and copy the new one > + * over the top of it. > + */ > + for (i = 0; i < ARRAY_LENGTH(&data->list); i++) > + { > + item = &ARRAY_ITEM(&data->list, i); > + wcd = item->wcd; > + > + if (s == wcd->tree_session) { > + /* We only show the session when collapsed. */ > + if (wcd->type & TREE_SESSION) { > + item->state &= ~TREE_EXPANDED; > + > + ARRAY_ADD(&list_copy, > + ARRAY_ITEM(&data->list, i)); > + /* > + * Update the selection to this session item > + * so we don't end up highlighting a > + * non-existent item. > + */ > + data->selected = i; > + } > + } else > + ARRAY_ADD(&list_copy, ARRAY_ITEM(&data->list, i)); > + } > + > + if (!ARRAY_EMPTY(&list_copy)) { > + ARRAY_FREE(&data->list); > + ARRAY_CONCAT(&data->list, &list_copy); > + } > +} > + > +void > +window_choose_collapse_all(struct window_pane *wp) > +{ > + struct window_choose_mode_data *data = wp->modedata; > + struct window_choose_mode_item *item, *chosen; > + struct session *s; > + u_int i; > + > + chosen = &ARRAY_ITEM(&data->list, data->selected); > + > + RB_FOREACH(s, sessions, &sessions) > + window_choose_collapse(wp, s); > + > + /* Reset the selection back to the starting session. */ > + for (i = 0; i < ARRAY_LENGTH(&data->list); i++) > + { > + item = &ARRAY_ITEM(&data->list, i); > + > + if (chosen->wcd->session != item->wcd->tree_session) > + continue; > + > + if (item->wcd->type & TREE_SESSION) > + data->selected = i; > + } > + window_choose_redraw_screen(wp); > +} > + > +void > +window_choose_expand_all(struct window_pane *wp) > +{ > + struct window_choose_mode_data *data = wp->modedata; > + struct window_choose_mode_item *item; > + struct session *s; > + u_int i; > + > + RB_FOREACH(s, sessions, &sessions) { > + for (i = 0; i < ARRAY_LENGTH(&data->list); i++) > + { > + item = &ARRAY_ITEM(&data->list, i); > + > + if (s != item->wcd->tree_session) > + continue; > + > + if (item->wcd->type & TREE_SESSION) > + window_choose_expand(wp, s, i); > + } > + } > + > + window_choose_redraw_screen(wp); > +} > + > +void > +window_choose_expand(struct window_pane *wp, struct session *s, u_int pos) > +{ > + struct window_choose_mode_data *data = wp->modedata; > + struct window_choose_mode_item *item, *chosen; > + struct window_choose_data *wcd; > + u_int i, items; > + > + chosen = &ARRAY_ITEM(&data->list, pos); > + items = ARRAY_LENGTH(&data->list_orig) - 1; > + > + /* It's not possible to expand anything other than sessions. */ > + if (!(chosen->wcd->type & TREE_SESSION)) > + return; > + > + /* Don't re-expand a session which is already expanded. */ > + if (chosen->state & TREE_EXPANDED) > + return; > + > + /* Mark the session entry as expanded. */ > + chosen->state |= TREE_EXPANDED; > + > + /* > + * Go back through the original list of all sessions and windows, and > + * pull out the windows where the session matches the selection chosen > + * to expand. > + */ > + for (i = items; i > 0; i--) > + { > + item = &ARRAY_ITEM(&data->list_orig, i); > + item->state |= TREE_EXPANDED; > + wcd = item->wcd; > + > + if (s == wcd->tree_session) { > + /* > + * Since the session is already displayed, we only > + * care to add back in window for it. > + */ > + if (wcd->type & TREE_WINDOW) { > + /* If the insertion point for adding the > + * windows to the session falls inside the > + * range of the list, then we insert these > + * entries in order *AFTER* the selected > + * session. > + */ > + if (pos < i ) { > + ARRAY_INSERT(&data->list, pos + 1, > + ARRAY_ITEM(&data->list_orig, > + i)); > + } else > + /* > + * Ran out of room, add it to the end. > + */ > + ARRAY_ADD(&data->list, > + ARRAY_ITEM(&data->list_orig, > + i)); > + } > + } > + } > +} > + > /* ARGSUSED */ > void > window_choose_key(struct window_pane *wp, unused struct session *sess, int > key) > @@ -237,7 +414,7 @@ window_choose_key(struct window_pane *wp, unused struct > session *sess, int key) > struct screen_write_ctx ctx; > struct window_choose_mode_item *item; > size_t input_len; > - u_int items, n; > + u_int items, n; > int idx; > > items = ARRAY_LENGTH(&data->list); > @@ -285,6 +462,21 @@ window_choose_key(struct window_pane *wp, unused struct > session *sess, int key) > window_choose_fire_callback(wp, item->wcd); > window_pane_reset_mode(wp); > break; > + case MODEKEYCHOICE_COLLAPSE_EXPAND_TOGGLE: > + item = &ARRAY_ITEM(&data->list, data->selected); > + if (item->state & TREE_EXPANDED) > + window_choose_collapse(wp, item->wcd->tree_session); > + else > + window_choose_expand(wp, item->wcd->tree_session, > + data->selected); > + window_choose_redraw_screen(wp); > + break; > + case MODEKEYCHOICE_COLLAPSE_ALL: > + window_choose_collapse_all(wp); > + break; > + case MODEKEYCHOICE_EXPAND_ALL: > + window_choose_expand_all(wp); > + break; > case MODEKEYCHOICE_UP: > if (items == 0) > break; > @@ -469,7 +661,13 @@ window_choose_write_line( > else > xsnprintf (label, sizeof label, "(%d)", item->pos); > screen_write_nputs(ctx, screen_size_x(s) - 1, &gc, utf8flag, > - "%*s %s", data->width + 2, label, item->name); > + "%*s %s %s", data->width + 2, label, > + /* > + * Add indication to tree if necessary about whether it's > + * expanded or not. > + */ > + (item->wcd->type & TREE_SESSION) ? > + (item->state & TREE_EXPANDED ? "-" : "+") : "", item->name); > } > while (s->cx < screen_size_x(s)) > screen_write_putc(ctx, &gc, ' '); > @@ -623,6 +821,8 @@ window_choose_add_session(struct window_pane *wp, struct > cmd_ctx *ctx, > > wcd = window_choose_data_create(ctx); > wcd->idx = s->idx; > + wcd->tree_session = s; > + wcd->type = TREE_SESSION; > wcd->command = cmd_template_replace(action, s->name, 1); > wcd->ft_template = xstrdup(template); > format_add(wcd->ft, "line", "%u", idx); > @@ -684,6 +884,8 @@ window_choose_add_window(struct window_pane *wp, struct > cmd_ctx *ctx, > > wcd->idx = wl->idx; > wcd->wl = wl; > + wcd->tree_session = s; > + wcd->type = TREE_WINDOW; > wcd->ft_template = xstrdup(template); > format_add(wcd->ft, "line", "%u", idx); > format_session(wcd->ft, s); > -- > 1.7.11.4 > > > ------------------------------------------------------------------------------ > Got visibility? > Most devs has no idea what their production app looks like. > Find out how fast your code is with AppDynamics Lite. > http://ad.doubleclick.net/clk;262219671;13503038;y? > http://info.appdynamics.com/FreeJavaPerformanceDownload.html > _______________________________________________ > tmux-users mailing list > tmux-users@lists.sourceforge.net > https://lists.sourceforge.net/lists/listinfo/tmux-users ------------------------------------------------------------------------------ Don't let slow site performance ruin your business. Deploy New Relic APM Deploy New Relic app performance management and know exactly what is happening inside your Ruby, Python, PHP, Java, and .NET app Try New Relic at no cost today and get our sweet Data Nerd shirt too! http://p.sf.net/sfu/newrelic-dev2dev _______________________________________________ tmux-users mailing list tmux-users@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/tmux-users