Browse Source

feat(FindPlugin): support include and exclude files (#443)

pull/444/head
Pier CeccoPierangioliEugenio 7 months ago committed by GitHub
parent
commit
e7103c7b61
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
  1. 59
      apps/ttkode/ttkode/plugins/_010/findwidget.py

59
apps/ttkode/ttkode/plugins/_010/findwidget.py

@ -70,26 +70,32 @@ def _load_gitignore_patterns(gitignore_path):
return patterns
return []
def _should_ignore(path, patterns):
for pattern in patterns:
if fnmatch.fnmatch(path, pattern):
return True
return False
def _custom_walk(directory:str, patterns:List[str]=[]) -> Generator[Tuple[str, str], None, None]:
def _glob_match_patterns(path, patterns) -> bool:
if path == '.':
check_path = ''
elif path.startswith('./'):
check_path = path[2:]
else:
check_path = path
return any(f"/{_p}/" in path for _p in patterns if _p) or any(fnmatch.fnmatch(check_path, _p) for _p in patterns if _p)
def _custom_walk(directory:str, include_patterns:List[str]=[], exclude_patterns:List[str]=[]) -> Generator[Tuple[str, str], None, None]:
gitignore_path = os.path.join(directory, '.gitignore')
patterns = patterns + _load_gitignore_patterns(gitignore_path)
exclude_patterns = exclude_patterns + _load_gitignore_patterns(gitignore_path)
for entry in sorted(os.listdir(directory)):
full_path = os.path.join(directory, entry)
if _should_ignore(full_path, patterns):
if _glob_match_patterns(full_path, exclude_patterns):
continue
if not os.path.exists(full_path):
continue
if os.path.isdir(full_path):
if entry == '.git':
continue
yield from _custom_walk(full_path, patterns)
yield from _custom_walk(full_path, include_patterns, exclude_patterns)
else:
if include_patterns and not _glob_match_patterns(full_path, include_patterns):
# ttk.TTkLog.debug(f"{include_patterns=} {full_path=}")
continue
yield directory, entry
def _walk_with_gitignore(root):
@ -97,7 +103,7 @@ def _walk_with_gitignore(root):
gitignore_path = os.path.join(dirpath, '.gitignore')
patterns = _load_gitignore_patterns(gitignore_path)
filenames[:] = [f for f in filenames if not _should_ignore(os.path.join(dirpath, f), patterns)]
filenames[:] = [f for f in filenames if not _glob_match_patterns(os.path.join(dirpath, f), patterns)]
yield dirpath, filenames
@ -182,6 +188,9 @@ class FindWidget(ttk.TTkContainer):
btn_expand.clicked.connect(self._results_tree.expandAll)
btn_collapse.clicked.connect(self._results_tree.collapseAll)
search.returnPressed.connect(self._search)
replace.returnPressed.connect(self._search)
ft_incl.returnPressed.connect(self._search)
ft_excl.returnPressed.connect(self._search)
res_tree.itemActivated.connect(self._activated)
@ttk.pyTTkSlot(str)
@ -203,14 +212,17 @@ class FindWidget(ttk.TTkContainer):
def _search(self):
self._runId += 1
search_pattern = str(self._search_le.text())
replace_pattern = str(self._replace_le.text())
include_patterns = _s.split(',') if (_s:=str(self._files_inc_le.text())) else []
exclude_patterns = _s.split(',') if (_s:=str(self._files_exc_le.text())) else []
if not search_pattern:
return
def _search_threading():
self._results_tree.clear()
group = []
groupSize = 1
for (file,root,matches) in self._search_files('.',str(search_pattern),self._runId):
ttk.TTkLog.debug((file,matches))
for (file,root,matches) in self._search_files('.',str(search_pattern),self._runId,include_patterns,exclude_patterns):
# ttk.TTkLog.debug((file,matches))
item = ttk.TTkTreeWidgetItem([
ttk.TTkString(
ttk.TTkCfg.theme.fileIcon.getIcon(file),
@ -222,13 +234,19 @@ class FindWidget(ttk.TTkContainer):
line = line.lstrip(' ')
# index = line.find(search_pattern)
# outLine =
item.addChild(
_MatchTreeWidgetItem([
ttk.TTkString(str(num)+" ",ttk.TTkColor.CYAN) +
ttk.TTkString(line.replace('\n','')).completeColor(
if replace_pattern:
_s = line.replace('\n','').split(search_pattern)
_j = (
ttk.TTkString(search_pattern,ttk.TTkColor.RED + ttk.TTkColor.STRIKETROUGH) +
ttk.TTkString(replace_pattern,ttk.TTkColor.GREEN) + ttk.TTkColor.RST)
ttkLine = _j.join(_s)
else:
ttkLine = ttk.TTkString(line.replace('\n','')).completeColor(
match=search_pattern,
color=ttk.TTkColor.GREEN)
],
item.addChild(
_MatchTreeWidgetItem([ttk.TTkString(str(num)+" ",ttk.TTkColor.CYAN) + ttkLine] ,
match=line,
lineNumber=num,
path=os.path.join(root,file)))
@ -242,9 +260,8 @@ class FindWidget(ttk.TTkContainer):
self._results_tree.addTopLevelItems(group)
Thread(target=_search_threading).start()
def _search_files(self, root_folder, match, runId):
matches = []
for root, file in _custom_walk(root_folder):
def _search_files(self, root_folder, match, runId, include_patterns, exclude_patterns):
for root, file in _custom_walk(root_folder,include_patterns,exclude_patterns):
if runId != self._runId:
return
if True: # file.endswith('.py'): # file.endswith(file_extension):

Loading…
Cancel
Save