nerd_tree/src/tree_find.py

152 lines
4.5 KiB
Python

import re
from src.colors import RED, YELLOW, GREEN, CYAN , BLUE, PURPLE
from src.tree import NerdTree
class NerdTreeFind(NerdTree):
'''
@param startpath string: the startpath from which to generate
the json_tree member (the tree representation)
@param opts dict: the opts for the tree representation
'''
def __init__(self, startpath, opts={}, find_opts={}):
self.item_name = ''
self.re_item_name = None
self.results = []
## computed tree for find
self.json_tree_find = {}
self.find_opts = find_opts
NerdTree.__init__(self, startpath, opts=opts)
def find_node_recursively(self, node):
# if node['name'] == self.item_name:
if self.re_item_name.match(node['name']):
node_copy = node.copy()
node_copy.update({'color_formatter' : YELLOW, 'found' : 1})
self.results.append(node_copy)
children = node.get('children') or []
for item_child in children:
if item_child['type'] == 'd':
self.find_node_recursively(item_child)
else:
# if item_child['name'] == self.item_name:
if self.re_item_name.match(item_child['name']):
item_child_copy = item_child.copy()
item_child_copy.update({'color_formatter' : YELLOW, 'found' : 1})
self.results.append(item_child_copy)
def find_node(self):
self.find_node_recursively(self.json_tree)
return self.results
def find_children(self, tree, item_abs_path):
'''
It returns a tuple:
first value True if father of node with item_abs_path is found,
second value represents the children of parent node with item_abs_path
'''
if tree['abs_path'] == item_abs_path:
if not tree.get('children'):
tree['children'] = []
return (True, tree['children'])
children = tree.get('children') or []
if not children:
return (False, [])
for child in children:
found, fchildren = self.find_children(child, item_abs_path)
if found:
return (True, fchildren)
return (False, [])
def find_tree_struct(self):
'''
'''
results = self.find_node()
## remove from this level the option
if not results:
return {}
# if dont_show_children_nodes:
# for result in results:
# children = result.get('children') or []
# result['nchildren'] = len(children)
# result['children'] = []
dont_show_children_nodes = self.find_opts['dont_show_children_nodes'] if self.find_opts.get('dont_show_children_nodes') is not None else False
self.opts['dont_show_children_nodes'] = dont_show_children_nodes
tree_struct = {}
for node in results:
path = node['path']
for n,p in enumerate(path):
pcopy = p.copy()
pname = p['name']
if pname == './':
if tree_struct: continue
tree_struct = pcopy
tree_struct['children'] = []
continue
parent = path[n-1]
found, children = self.find_children(tree_struct, parent['abs_path'])
if not found:
raise Exception('Bug!!!')
if p['abs_path'] in [c['abs_path'] for c in children]:
continue
islastpath = True if (n== len(path)-1) else False
if not islastpath: children.append(pcopy)
else : children.append(node)
# key size is lost in preceding code!!!!!!!!!!!!
self.compute_aggregate_recursively(tree_struct)
return tree_struct
def reset(self, new_item_name, new_opts):
self.find_opts = new_opts
self.results = []
self.item_name = new_item_name
print('Regexp: %s' % (new_item_name,))
try:
self.re_item_name = re.compile(r'^%s$' % (new_item_name,))
except re.error:
raise Exception('Can\'t compile regexp %s, exit' % (new_item_name,))
self.json_tree_find = {}
def print(self, item_name='', opts={}):
if not item_name and not self.item_name:
print('Please use a valid search string')
return
if item_name != self.item_name or self.find_opts != opts:
self.reset(item_name, opts)
self.json_tree_find = self.find_tree_struct()
if not self.json_tree_find:
print('No results')
return
print(self.tree_from_struct(self.json_tree_find))
def find(self, item_name, opts={}):
'''
@param item_name the string to search in the tree
@param opts dict for the find option
'''
return self.print(item_name, opts=opts)