Instantly share code, notes, and snippets.
Created
April 12, 2020 15:00
-
Star
(1)
1
You must be signed in to star a gist -
Fork
(0)
0
You must be signed in to fork a gist
-
Save cvpe/03723c1198bc2145cf6b9a0562843b1c to your computer and use it in GitHub Desktop.
find_in_files_new_menu.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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