Skip to content

Instantly share code, notes, and snippets.

@cvpe
Created April 9, 2020 12:26
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save cvpe/afb1fa8678d44d75b3114ed1c49fac41 to your computer and use it in GitHub Desktop.
Save cvpe/afb1fa8678d44d75b3114ed1c49fac41 to your computer and use it in GitHub Desktop.
find_in_files_new_menu.py
import customMenuItem
from objc_util import *
class findInSourcesMenu(customMenuItem.PYUIMenuItem):
__selector__ = 'findInSourcesMenu'
__title__ = 'Find'
def action(self, selected_text, selection, editorview):
import console
import os
import ui
search_term = selected_text
if search_term == '': # no text selected
# ask it
search_term = console.input_alert('text to search in sources', '', '')
if search_term == '': # no text entered
return # no action
tv = ui.TableView()
tv.search_term = search_term
sources = []
path = os.path.expanduser('~/Documents')
se = search_term.lower()
# search all .py. Tests show that os.scandir is quicker than os.walk
def scantree(path):
"""Recursively yield DirEntry objects for given directory."""
for entry in os.scandir(path):
if entry.is_dir(follow_symlinks=False):
scantree(entry.path)
else:
fpath = entry.path
if os.path.splitext(entry.path)[-1].lower() != ".py":
continue
with open(fpath, mode='rt', encoding='utf-8', errors='ignore') as fil:
content = fil.read().lower()
if se in content:
sources.append(fpath)
scantree(path)
def tableview_cell_for_row(tableview, section, row):
cell = ui.TableViewCell()
data = tableview.data_source.items[row]
tx = '/Pythonista3/Documents/'
i = data.find(tx) + len(tx)
cell.text_label.text = data[i:]
return cell
class MyTableViewDelegate (object):
def tableview_did_select(self,tableview, section, row):
from pygments import highlight
from pygments.lexers import PythonLexer
from pygments.formatters import HtmlFormatter
from pygments.styles import get_style_by_name
import re
import ui
from wkwebview import WKWebView
fpath = tableview.data_source.items[row]
search_term = tableview.search_term
with open(fpath, mode='rt', encoding='utf-8', errors='ignore') as fil:
code = fil.read()
# Syntax-highlight code
# from omz code at https://forum.omz-software.com/topic/1950/syntax-highlight-python-code-on-screen-while-running
html_formatter = HtmlFormatter(style='colorful')
l = PythonLexer()
l.add_filter('whitespace', tabs=' ', tabsize=2)
highlighted_code = highlight(code, l, html_formatter)
styles = html_formatter.get_style_defs()
# change html code to highlight searched term with yellow background
styles = styles + '\n' + '.search { background-color: #ffff00 } /* search term */'
highlighted_code = highlighted_code.replace(search_term, '</span><span class="search">' + search_term + '</span>')
# add class to searched term independantly of case
src_str = re.compile('('+search_term+')', re.IGNORECASE)
# @Olaf: use \1 to refer to matched text grouped by () in the regex
highlighted_code = src_str.sub(r'</span><span class="search">\1</span>', highlighted_code)
# meta tag UTF-8 is needed to display emojis if present in a script
html = '<html><head><meta charset="UTF-8"><style>%s</style></head><body> %s </body></html>' % (styles, highlighted_code)
wv = WKWebView()
tx = '/Pythonista3/Documents/'
i = fpath.find(tx) + len(tx)
wv.name = fpath[i:]
wv.frame = tableview.frame
wv.load_html(html)
wv.present()
wv.wait_modal()
tv.data_source = ui.ListDataSource(items=sources)
tv.delegate = MyTableViewDelegate()
tv.data_source.tableview_cell_for_row = tableview_cell_for_row
bs1 = ui.ButtonItem(title='search',tint_color='black')
bs2 = ui.ButtonItem(title=search_term,tint_color='green')
bs3 = ui.ButtonItem(title='in my scripts',tint_color='black')
tv.right_button_items = [bs3,bs2,bs1]
tv.present()
g = customMenuItem.MenuNotificationObserver([(findInSourcesMenu(),'Help')])
g.register()
g.start()
@cvpe
Copy link
Author

cvpe commented Apr 12, 2020

I'll not stop the scan background thread even if we select a file to watch because if we come back to watch another file, the list has still increased and should be normally ended. But I'll stop the thread if we close the TableView.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment