Regular expression searching, faster find in file. GREAT tool now!
This commit is contained in:
parent
5381042d48
commit
a9bb73ece7
|
@ -111,7 +111,10 @@ def get_theme():
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def find_in_file(string):
|
old_file_list = None
|
||||||
|
|
||||||
|
def find_in_file(string, demo_files_dict, regex=False, verbose=False):
|
||||||
|
global old_file_list
|
||||||
"""
|
"""
|
||||||
Search through the demo files for a string.
|
Search through the demo files for a string.
|
||||||
The case of the string and the file contents are ignored
|
The case of the string and the file contents are ignored
|
||||||
|
@ -121,6 +124,7 @@ def find_in_file(string):
|
||||||
:rtype: List[str]
|
:rtype: List[str]
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
# So you face a prediciment here. You wish to read files, both small and large; however the bigger the file/bigger the list, the longer to read the file.
|
# So you face a prediciment here. You wish to read files, both small and large; however the bigger the file/bigger the list, the longer to read the file.
|
||||||
# This probably isn't what you want, right?
|
# This probably isn't what you want, right?
|
||||||
# Well, we can't use a direct command line to run grep and parse. But it is an option. The user may not have it.
|
# Well, we can't use a direct command line to run grep and parse. But it is an option. The user may not have it.
|
||||||
|
@ -135,25 +139,40 @@ def find_in_file(string):
|
||||||
# This will allow the fastest searching and loading of a file without sacrificing read times.
|
# This will allow the fastest searching and loading of a file without sacrificing read times.
|
||||||
# 2.8 seconds on the highend for both small and large files in memory.
|
# 2.8 seconds on the highend for both small and large files in memory.
|
||||||
# We also don't have to iterate over lines this way.
|
# We also don't have to iterate over lines this way.
|
||||||
file_list_dict = get_file_list_dict()
|
|
||||||
file_list = []
|
file_list = []
|
||||||
|
new_demo_files_dict = {}
|
||||||
|
|
||||||
|
for file in demo_files_dict:
|
||||||
for file in file_list_dict:
|
|
||||||
try:
|
try:
|
||||||
full_filename = file_list_dict[file]
|
full_filename = demo_files_dict[file]
|
||||||
|
|
||||||
with open(full_filename, 'rb', 0) as f, mmap.mmap(f.fileno(), 0, access=mmap.ACCESS_READ) as s:
|
with open(full_filename, 'rb', 0) as f, mmap.mmap(f.fileno(), 0, access=mmap.ACCESS_READ) as s:
|
||||||
if re.search(br'(?i)' + bytes(re.escape(string.lower()), 'utf-8'), s):
|
if (regex):
|
||||||
# ^^^^^^^^^-----------------------------------> re.escape
|
matches = re.finditer(bytes(string, 'utf-8'), s, re.MULTILINE)
|
||||||
# (In case the user types ( or any other character that can be treated like a regex)
|
for match in matches:
|
||||||
|
if verbose:
|
||||||
|
sg.cprint(f"{file}: ", c = 'white on green')
|
||||||
|
sg.cprint(f"{match.group(0).decode('utf-8')}\n")
|
||||||
file_list.append(file)
|
file_list.append(file)
|
||||||
|
#if re.search(bytes(string, 'utf-8'), s, re.MULTILINE):
|
||||||
|
# file_list.append(file)
|
||||||
|
else:
|
||||||
|
if re.search(br'(?i)' + bytes(re.escape(string.lower()), 'utf-8'), s):
|
||||||
|
# ^^^^^^^^^-----------------------------------> re.escape (In case the user types ( or any other character that can be treated like a regex)
|
||||||
|
file_list.append(file)
|
||||||
|
# DICT
|
||||||
|
if file not in new_demo_files_dict.keys():
|
||||||
|
new_demo_files_dict[file] = full_filename
|
||||||
|
else:
|
||||||
|
new_demo_files_dict[f'{file}_1'] = fname_full
|
||||||
except ValueError:
|
except ValueError:
|
||||||
pass # caused by an empty file so no problem skipping it
|
pass
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
print(f'{file}', e)
|
print(f'{file}', e, file=sys.stderr)
|
||||||
|
|
||||||
return list(set(file_list))
|
old_file_list = new_demo_files_dict
|
||||||
|
|
||||||
|
file_list = list(set(file_list))
|
||||||
|
return file_list
|
||||||
|
|
||||||
|
|
||||||
def settings_window():
|
def settings_window():
|
||||||
|
@ -211,7 +230,6 @@ def make_window():
|
||||||
:return: The main window object
|
:return: The main window object
|
||||||
:rtype: (Window)
|
:rtype: (Window)
|
||||||
"""
|
"""
|
||||||
|
|
||||||
theme = get_theme()
|
theme = get_theme()
|
||||||
if not theme:
|
if not theme:
|
||||||
theme = sg.OFFICIAL_PYSIMPLEGUI_THEME
|
theme = sg.OFFICIAL_PYSIMPLEGUI_THEME
|
||||||
|
@ -220,16 +238,22 @@ def make_window():
|
||||||
|
|
||||||
find_tooltip = "Find in file\nEnter a string in box to search for string inside of the files.\nFile list will update with list of files string found inside."
|
find_tooltip = "Find in file\nEnter a string in box to search for string inside of the files.\nFile list will update with list of files string found inside."
|
||||||
filter_tooltip = "Filter files\nEnter a string in box to narrow down the list of files.\nFile list will update with list of files with string in filename."
|
filter_tooltip = "Filter files\nEnter a string in box to narrow down the list of files.\nFile list will update with list of files with string in filename."
|
||||||
|
find_re_tooltip = "Find in file using Regular Expression\nEnter a string in box to search for string inside of the files.\nSearch is performed after clicking the FindRE button."
|
||||||
|
|
||||||
ML_KEY = '-ML-' # Multline's key
|
ML_KEY = '-ML-' # Multline's key
|
||||||
|
|
||||||
left_col = [
|
left_col = sg.Col([
|
||||||
[sg.Listbox(values=get_file_list(), select_mode=sg.SELECT_MODE_EXTENDED, size=(50, 20), key='-DEMO LIST-')],
|
[sg.Listbox(values=get_file_list(), select_mode=sg.SELECT_MODE_EXTENDED, size=(50, 20), key='-DEMO LIST-')],
|
||||||
[sg.Text('Filter:', tooltip=filter_tooltip), sg.Input(size=(25, 1), enable_events=True, key='-FILTER-', tooltip=filter_tooltip),
|
[sg.Text('Filter:', tooltip=filter_tooltip), sg.Input(size=(25, 1), enable_events=True, key='-FILTER-', tooltip=filter_tooltip),
|
||||||
sg.T(size=(20,1), k='-FILTER NUMBER-')],
|
sg.T(size=(20,1), k='-FILTER NUMBER-')],
|
||||||
[sg.Button('Run'), sg.B('Edit'), sg.B('Clear')],
|
[sg.Button('Run'), sg.B('Edit'), sg.B('Clear')],
|
||||||
[sg.Text('Find:', tooltip=find_tooltip), sg.Input(size=(25, 1), enable_events=True, key='-FIND-', tooltip=find_tooltip),
|
[sg.Text('Find:', tooltip=find_tooltip), sg.Input(size=(25, 1), enable_events=True, key='-FIND-', tooltip=find_tooltip),
|
||||||
sg.T(size=(20,1), k='-FIND NUMBER-')]]
|
sg.T(size=(20,1), k='-FIND NUMBER-')],
|
||||||
|
], element_justification='c')
|
||||||
|
|
||||||
|
lef_col_find_re = sg.Col([
|
||||||
|
[sg.Text('Find:', tooltip=find_re_tooltip), sg.Input(size=(25, 1),key='-FIND RE-', tooltip=find_re_tooltip),sg.B('Find RE'), sg.CB('Verbose', k='-VERBOSE-')]
|
||||||
|
])
|
||||||
|
|
||||||
right_col = [
|
right_col = [
|
||||||
[sg.Multiline(size=(70, 21), write_only=True, key=ML_KEY, reroute_stdout=True, echo_stdout_stderr=True)],
|
[sg.Multiline(size=(70, 21), write_only=True, key=ML_KEY, reroute_stdout=True, echo_stdout_stderr=True)],
|
||||||
|
@ -242,7 +266,7 @@ def make_window():
|
||||||
layout = [[sg.Text('PySimpleGUI Project File Searcher & Launcher', font='Any 20')],
|
layout = [[sg.Text('PySimpleGUI Project File Searcher & Launcher', font='Any 20')],
|
||||||
[sg.T('Click settings to set top of your tree or choose a previously chosen folder'),
|
[sg.T('Click settings to set top of your tree or choose a previously chosen folder'),
|
||||||
sg.Combo(sg.user_settings_get_entry('-folder names-', []), default_value=sg.user_settings_get_entry('-demos folder-', ''), size=(50, 1), key='-FOLDERNAME-', enable_events=True, readonly=True)],
|
sg.Combo(sg.user_settings_get_entry('-folder names-', []), default_value=sg.user_settings_get_entry('-demos folder-', ''), size=(50, 1), key='-FOLDERNAME-', enable_events=True, readonly=True)],
|
||||||
sg.vtop([sg.Column(left_col, element_justification='c'), sg.Col(right_col, element_justification='c') ])]
|
sg.vtop([sg.Column([[left_col],[ lef_col_find_re]], element_justification='l'), sg.Col(right_col, element_justification='c') ])]
|
||||||
|
|
||||||
# --------------------------------- Create Window ---------------------------------
|
# --------------------------------- Create Window ---------------------------------
|
||||||
window = sg.Window('PSG Finder Launcher', layout, finalize=True, icon=icon)
|
window = sg.Window('PSG Finder Launcher', layout, finalize=True, icon=icon)
|
||||||
|
@ -257,6 +281,8 @@ def main():
|
||||||
It will call the make_window function to create the window.
|
It will call the make_window function to create the window.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
old_typed_value = None
|
||||||
|
|
||||||
editor_program = get_editor()
|
editor_program = get_editor()
|
||||||
file_list_dict = get_file_list_dict()
|
file_list_dict = get_file_list_dict()
|
||||||
file_list = get_file_list()
|
file_list = get_file_list()
|
||||||
|
@ -291,7 +317,24 @@ def main():
|
||||||
window['-FIND NUMBER-'].update('')
|
window['-FIND NUMBER-'].update('')
|
||||||
window['-FIND-'].update('')
|
window['-FIND-'].update('')
|
||||||
elif event == '-FIND-':
|
elif event == '-FIND-':
|
||||||
file_list = find_in_file(values['-FIND-'])
|
global old_file_list
|
||||||
|
current_typed_value = str(values['-FIND-'])
|
||||||
|
if old_file_list is None or old_typed_value is None:
|
||||||
|
# New search.
|
||||||
|
old_typed_value = current_typed_value
|
||||||
|
file_list = find_in_file(values['-FIND-'], get_file_list_dict())
|
||||||
|
elif current_typed_value.startswith(old_typed_value):
|
||||||
|
old_typed_value = current_typed_value
|
||||||
|
file_list = find_in_file(values['-FIND-'], old_file_list)
|
||||||
|
else:
|
||||||
|
old_typed_value = current_typed_value
|
||||||
|
file_list = find_in_file(values['-FIND-'], get_file_list_dict())
|
||||||
|
window['-DEMO LIST-'].update(sorted(file_list))
|
||||||
|
window['-FIND NUMBER-'].update(f'{len(file_list)} files')
|
||||||
|
window['-FILTER NUMBER-'].update('')
|
||||||
|
window['-FILTER-'].update('')
|
||||||
|
elif event == 'Find RE':
|
||||||
|
file_list = find_in_file(values['-FIND RE-'], get_file_list_dict(), True, values['-VERBOSE-'])
|
||||||
window['-DEMO LIST-'].update(sorted(file_list))
|
window['-DEMO LIST-'].update(sorted(file_list))
|
||||||
window['-FIND NUMBER-'].update(f'{len(file_list)} files')
|
window['-FIND NUMBER-'].update(f'{len(file_list)} files')
|
||||||
window['-FILTER NUMBER-'].update('')
|
window['-FILTER NUMBER-'].update('')
|
||||||
|
@ -305,11 +348,14 @@ def main():
|
||||||
file_list = get_file_list()
|
file_list = get_file_list()
|
||||||
window['-FILTER NUMBER-'].update(f'{len(file_list)} files')
|
window['-FILTER NUMBER-'].update(f'{len(file_list)} files')
|
||||||
elif event == 'Clear':
|
elif event == 'Clear':
|
||||||
|
file_list = get_file_list()
|
||||||
window['-FILTER-'].update('')
|
window['-FILTER-'].update('')
|
||||||
window['-FILTER NUMBER-'].update(f'{len(file_list)} files')
|
window['-FILTER NUMBER-'].update(f'{len(file_list)} files')
|
||||||
window['-FIND-'].update('')
|
window['-FIND-'].update('')
|
||||||
window['-DEMO LIST-'].update(file_list)
|
window['-DEMO LIST-'].update(file_list)
|
||||||
window['-FIND NUMBER-'].update('')
|
window['-FIND NUMBER-'].update('')
|
||||||
|
window['-FIND RE-'].update('')
|
||||||
|
window['-ML-'].update('')
|
||||||
elif event == '-FOLDERNAME-':
|
elif event == '-FOLDERNAME-':
|
||||||
sg.user_settings_set_entry('-demos folder-', values['-FOLDERNAME-'])
|
sg.user_settings_set_entry('-demos folder-', values['-FOLDERNAME-'])
|
||||||
file_list_dict = get_file_list_dict()
|
file_list_dict = get_file_list_dict()
|
||||||
|
|
Loading…
Reference in New Issue