Skip to content

Instantly share code, notes, and snippets.

@cvpe
Created April 12, 2020 15:00
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/03723c1198bc2145cf6b9a0562843b1c to your computer and use it in GitHub Desktop.
Save cvpe/03723c1198bc2145cf6b9a0562843b1c to your computer and use it in GitHub Desktop.
find_in_files_new_menu.py
import customMenuItem
from objc_util import *
import os
import threading
import ui
class my_thread(threading.Thread):
global main_view
def __init__(self,view,search_term):
threading.Thread.__init__(self)
self.active = True
self.view = view
self.search_term = search_term
retain_global(self)
def run(self):
path = os.path.expanduser('~/Documents')
se = self.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 not self.active:
return True
if entry.is_dir(follow_symlinks=False):
if scantree(entry.path):
return True
else:
fpath = entry.path
if os.path.splitext(entry.path)[-1].lower() != ".py":
continue
self.n += 1
if (self.n % 100) == 0:
self.view.left_button_items[0].image = ui.Image.named('emj:Clock_' + str(1 + ((self.n // 100) % 12))).with_rendering_mode(ui.RENDERING_MODE_ORIGINAL)
with open(fpath, mode='rt', encoding='utf-8', errors='ignore') as fil:
content = fil.read().lower()
if se in content:
self.view['tableview'].data_source.items.append(fpath)
self.view['tableview'].reload()
return False
self.n = 0
self.view.left_button_items[0].image = ui.Image.named('emj:Clock_12').with_rendering_mode(ui.RENDERING_MODE_ORIGINAL)
scantree(path)
self.view.left_button_items[0].image = None
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
class MyTableView(ui.View):
def __init__(self, search_term):
self.search_term = search_term
tv = ui.TableView(name='tableview')
tv.frame = self.bounds
tv.flex = 'WH'
tv.data_source = ui.ListDataSource(items=[])
tv.delegate = self
tv.data_source.tableview_cell_for_row = self.tableview_cell_for_row
self.add_subview(tv)
bs1 = ui.ButtonItem(title='search',tint_color='black')
bs2 = ui.ButtonItem(title=self.search_term,tint_color='green')
bs3 = ui.ButtonItem(title='in my scripts',tint_color='black')
self.right_button_items = [bs3,bs2,bs1]
bs4 = ui.ButtonItem(tint_color='red')
self.left_button_items = [bs4,]
self.scan_thread = my_thread(self,self.search_term)
def will_close(self):
self.scan_thread.active = False
def tableview_cell_for_row(self,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
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 = self.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()
v = MyTableView(search_term)
v.present()
v.scan_thread.start()
g = customMenuItem.MenuNotificationObserver([(findInSourcesMenu(),'Help')])
g.register()
g.start()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment