Forum Archive

Find in files script?

jmmelko

Hi,

has anyone written a « find in files » script for Pythonista?
Basically a script that would search .py or text files within a folder and return results in the console.

The first few weeks after installing Pythonista, I was astonished not to find many of the basic functions of most script editors, such as « comment line(s) », and « Find/Replace ».

After searching this forum and the web, I finally found what I needed, but it took me some time, and I was quite surprised that these scripts were not stored in an organized place. The search feature of this forum is not very efficient for that purpose.

If anyone could help me, I would give him... all my gratitude!

JonB

Search/replace within a file is already/part of the editor. There is a little switch to switch from find only to find/replace.

There are context menu options to comment or indent a section of code, iirc.

If suggest reading through the About Pythonista section of the help docs, as there are a few really useful features that might not be obvious when you first pick up the app.

If you are trying to find text within a not opened file, you should install stash, which includes a grep command

As for community written tools/scripts... The forum search doesn't work that well, but Google with the host:omz-software.com works well. Also, on GitHub
https://github.com/topics/pythonista
there is the pythonista-tools repo, which isn't really actively maintained but has some old stuff which can get you going.

https://github.com/tdamdouni/Pythonista
Is a good repository of scripts shared in the forums.

JonB

BTW, there used to be a repo called editmenu, which can be found on GitHub, which included some features missing from the editor at the time --but most of those features exist in a nicer form in app now, so we stopped working on it.

Black Mamba adds a lot of keyboard shortcut support, if you use an external keyboard.

cvp

@jmmelko you could put this kind of (quick and dirty) script as Pythonista tool (it searchs in the .py or .txt files of the folder of the edited file)

You can edit and run it for testing, without setting it as a tool

import console
import editor
import os
import ui

def main():
    t = console.input_alert('text to search',hide_cancel_button=True)
    if t == '':
        return
    t = t.lower()
    path = editor.get_path()
    path = path[:path.rfind('/')]
    fileslist = os.listdir(path)
    for file in fileslist:
        if file.lower()[-3:] == '.py' or file.lower()[-4:] == '.txt':
            with open(path+'/'+file,mode='rt', encoding='utf-8') as fil:
                content = fil.read().lower()
            lines = content.split('\n')
            first = True
            for line in lines:
                if line.find(t) >= 0:
                    if first:
                        first = False
                        print(file)
                    print('  ',line)

if __name__ == '__main__':
    main() 
ccc

if os.path.splitext(file)[-1].lower() in (".py", ".txt"):

cvp

@ccc marvelous

jmmelko

@JonB thank you very much for your comprehensive answer.

Search/replace within a file is already/part of the editor. There is a little switch to switch from find only to find/replace.

Honestly, I can’t find it. Where is it located?

There are context menu options to comment or indent a section of code, iirc.

They exist for indenting, not for commenting.

I am using Pythonista in an iPhone,
and I fear that some options available on iPad have been disabled on iPhone due to a lack of space.

omz

Built-in search/replace is currently only available on iPad.

jmmelko

@cvp thank you very much. I have added your script as a wrench tool. I just modified the last lines to get a more visual-friendly output to:

    print('\n%%%Found in ' + repr(file)+':')
print('l.'+str(i)+':',line.strip())
kaan191

Slight adjustment to above script so that all files in project directory are found. Note: requires hard-coding the directory that holds project directories. Standard Pythonista projects sit in the Documents directory. Working Copy projects sit in a directory called Repositories. Etc. Etc.

import console
import editor
import os
import pathlib
import ui

# "parent" directories that contain project roots
ROOTS = ['Documents', 'Repositories']

def get_project_root(path):
    '''Determines the root of the project, returns PosixPath()
    '''
    if path.parent.name in ROOTS:
        return path
    else:
        return get_project_root(path.parent)

def find_files(path):
    '''Recurses through project tree, returns PosixPath() list of all files
    '''
    file_paths = []
    for item in os.listdir(path):
        item_path = pathlib.Path(os.path.join(path, item))
        if item_path.is_file():
            file_paths.append(item_path)
        elif item_path.is_dir() and '.git' not in item_path.name:
            file_paths.extend(find_files(item_path))

    return file_paths


def main():
    t = console.input_alert('text to search',hide_cancel_button=True)
    if t == '':
        return
    t = t.lower()
    path = pathlib.Path(editor.get_path())

    project_root = get_project_root(path)
    files_list = find_files(project_root)

    for file in files_list:
        if os.path.splitext(file)[-1].lower() in (".py", ".txt"):
            with open(os.path.join(path, file), mode='rt', encoding='utf-8') as fil:
                content = fil.read().lower()
            lines = content.split('\n')
            first = True
            for i, line in enumerate(lines, 1):
                if line.find(t) >= 0:
                    if first:
                        first = False
                        print(
                            '\n%%%Found in ' + 
                            file.as_posix().split(
                                project_root.parent.as_posix() + '/'
                            )[-1] +':'
                        )
                    print('l.'+str(i)+':',line.strip())

if __name__ == '__main__':
    main()