1 # This program is free software; you can redistribute it and/or modify
2 # it under the terms of the GNU General Public License as published by
3 # the Free Software Foundation; either version 2 of the License, or
4 # (at your option) any later version.
6 # This program is distributed in the hope that it will be useful,
7 # but WITHOUT ANY WARRANTY; without even the implied warranty of
8 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
9 # GNU Library General Public License for more details.
11 # You should have received a copy of the GNU General Public License
12 # along with this program; if not, write to the Free Software
13 # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
15 # See the COPYING file for license information.
17 # Copyright (c) 2008 Guillaume Chazarain <guichaz@gmail.com>
19 from polysh
.rb_tree
import RBTree
21 # {'prefix': <display_name_prefix object>}
24 # Red/black tree with key:len(display_name) value:nr of enabled shells with a
25 # display_name of such a length
26 NR_ENABLED_DISPLAY_NAMES_BY_LENGTH
= RBTree()
28 # Cache the right most element in the NR_ENABLED_DISPLAY_NAMES_BY_LENGTH tree
29 max_display_name_length
= 0
31 class display_name_prefix(object):
37 if len(self
.holes
) == 0:
38 suffix
= self
.next_suffix
41 first_node
= self
.holes
.firstNode()
42 suffix
= first_node
.key
43 self
.holes
.deleteNode(first_node
)
46 def putback_suffix(self
, suffix
):
47 if suffix
+ 1 != self
.next_suffix
:
48 self
.holes
.insertNode(suffix
, suffix
)
51 self
.next_suffix
= suffix
53 prev_suffix
= self
.next_suffix
- 1
54 prev_suffix_node
= self
.holes
.findNode(prev_suffix
)
55 if not prev_suffix_node
:
57 self
.holes
.deleteNode(prev_suffix_node
)
58 self
.next_suffix
= prev_suffix
61 return self
.next_suffix
== 0
63 def make_unique_name(prefix
):
64 prefix_obj
= PREFIXES
.get(prefix
, None)
65 if prefix_obj
is None:
66 prefix_obj
= display_name_prefix()
67 PREFIXES
[prefix
] = prefix_obj
69 suffix
= prefix_obj
.new_suffix()
71 name
= '%s#%d' % (prefix
, suffix
)
77 def update_max_display_name_length():
78 from polysh
import dispatchers
79 if len(NR_ENABLED_DISPLAY_NAMES_BY_LENGTH
) == 0:
82 new_max
= NR_ENABLED_DISPLAY_NAMES_BY_LENGTH
.lastNode().key
83 global max_display_name_length
84 if new_max
!= max_display_name_length
:
85 max_display_name_length
= new_max
86 dispatchers
.update_terminal_size()
88 def change(prev_display_name
, new_prefix
):
89 if new_prefix
and '#' in new_prefix
:
90 raise Exception('Names cannot contain #')
92 if prev_display_name
is not None:
93 if new_prefix
is not None:
94 set_enabled(prev_display_name
, False)
95 split
= prev_display_name
.split('#')
96 prev_prefix
= split
[0]
100 prev_suffix
= int(split
[1])
101 prefix_obj
= PREFIXES
[prev_prefix
]
102 prefix_obj
.putback_suffix(prev_suffix
)
103 if prefix_obj
.empty():
104 del PREFIXES
[prev_prefix
]
105 if new_prefix
is None:
108 name
= make_unique_name(new_prefix
)
109 set_enabled(name
, True)
113 def set_enabled(display_name
, enabled
):
114 length
= len(display_name
)
115 node
= NR_ENABLED_DISPLAY_NAMES_BY_LENGTH
.findNode(length
)
120 NR_ENABLED_DISPLAY_NAMES_BY_LENGTH
.insertNode(length
, 1)
124 NR_ENABLED_DISPLAY_NAMES_BY_LENGTH
.deleteNode(node
)
126 update_max_display_name_length()