Home Download Buy Blog Forum Support

Code cleanup help request

Code cleanup help request

Postby tanc on Sun Feb 19, 2012 3:43 am

I've created a basic plugin for a specific use and was hoping someone could lend an expert eye to comment or help clean up my noob python code?

The plugin's use is to generate a completions file on a per project basis for Drupal PHP projects. It scans up from the current file location on save and looks for the *.sublime-project file in which case it recursively walks through the project looking for php files which it uses to create a Drupal.sublime-projectcompletions file in the project's root directory (alongside the sublime-project file). The plugin then uses this to populate the autocomplete suggestions through the API.

In basic testing this seems to be working ok but I'd like to know if there is a more efficient way of doing this? Can I store the completions file in memory to speed things up? Maybe call it from disk only when the file has changed? Should I be using shelve to store the data, or mmap to map it to memory?

Note that I've never programmed in Python before (its very nice!) so please forgive my sloppy code. Any advice or direction is greatly appreciated.

The plugin code looks like this:
Code: Select all
import os, glob, fnmatch, re, threading, sublime, sublime_plugin

class ProjectCompletionsScan(threading.Thread):

    def __init__(self, rootPath, timeout):
        threading.Thread.__init__(self)
        self.rootPath = rootPath
        self.timeout = timeout
        self.result = None

    def run(self):
        try:
            patterns = ['.inc', '.php', '.module']
            search = re.compile(r'^function\s(.+?)\((?:(.+?))?\)\s{$', re.MULTILINE)
            compPath = os.path.dirname(self.rootPath) + '/Drupal.sublime-projectcompletions'
            cfp = open(compPath, 'w')
            cfp.close()
            cfp = open(compPath, 'a')

            for root, dirs, files in os.walk(os.path.dirname(self.rootPath)):
                for p in patterns:
                    for f in files:
                        if f.endswith(p):
                            # Open the file.
                            fp = open(os.path.join(root, f), 'r')
                            content = fp.read()
                            # Retrieve functions from file.
                            funcs = search.findall(content)
                            if funcs:
                                # Write the functions to file
                                for row in funcs:
                                    args = ''
                                    arglist = row[1].replace(', ', ',').split(',')
                                    i = 0
                                    if arglist:
                                        for i, val in enumerate(arglist):
                                            arglist[i] = '${' + str(i) + ':' + arglist[i].replace('$', '') + '}'
                                    line = row[0] + "\t" + row[0] + "(" + ', '.join(arglist) + ")"
                                    # Append to file
                                    cfp.write(line + "\n")
                            fp.close()
            cfp.close()
            return
        except OSError, e:
            sublime.error_message("An unknown issue occured.")


class ProjectCompletions(sublime_plugin.EventListener):

    def find_file(self, start_at, look_for):
        start_at = os.path.abspath(start_at)
        if not os.path.isdir(start_at):
            start_at = os.path.dirname(start_at)
        while True:
            for filename in os.listdir(start_at):
                if fnmatch.fnmatch(filename, look_for):
                    return os.path.join(start_at, filename)
            continue_at = os.path.abspath(os.path.join(start_at, '..'))
            if continue_at == start_at:
                return None
            start_at = continue_at
   
    def on_post_save(self, view):
        path = view.file_name()
        rootPath = None

        if path:
            # Try to find the myproject.sublime-project file
            for filename in ['*.sublime-project']:
                rootPath = self.find_file(path, filename)
        if rootPath:
            threads = []
            thread = ProjectCompletionsScan(rootPath, 5)
            threads.append(thread)
            thread.start()

    def on_query_completions(self, view, prefix, locations):
        path = view.file_name()
        completions_location = None
        if path:
            # Try to find the Drupal.sublime-completions file
            for filename in ['*.sublime-projectcompletions']:
                completions_location = self.find_file(path, filename)
        if completions_location:
            fp = open(completions_location, 'r')

            t = ()
            data = []
            line = fp.readline()

            while len(line) != 0:
               e1, e2 = line.split("\t")
               t = e1, e2.rstrip()
               data.append(t)
               line = fp.readline()
               
            fp.close()
            return data
        else:
            return None
tanc
 
Posts: 5
Joined: Tue Apr 19, 2011 8:11 am

Re: Code cleanup help request

Postby Cjkjvfnby on Mon Feb 20, 2012 9:58 am

Code: Select all
try:
    ....
except OSError, e:
            sublime.error_message("An unknown issue occured.")

Is sublime crushed if error? I usually don`t change stack trace and current error to uninformative string.

I use with (http://www.effbot.org/zone/python-with-statement.htm) to open files

String formating via % or string.format
Code: Select all
#arglist[i] = '${' + str(i) + ':' + arglist[i].replace('$', '') + '}'
arglist[i] = '${%s':%s'}'   % (i, arglist[i].replace('$', ''))


I prefer to create list of strings and then:
Code: Select all
with open('file', w) as f:
    f.write('\n'.join(list_of_strings))



Code: Select all
funcs = search.findall(content)
                            if funcs:
                                # Write the functions to file
                                for row in funcs:
funcs is all ways list. If it is empty iteration will do nothing. Remove condition and save one indent level.
Cjkjvfnby
 
Posts: 20
Joined: Wed Feb 01, 2012 11:35 am

Re: Code cleanup help request

Postby tanc on Mon Feb 20, 2012 8:39 pm

Thank you Cjkjvfnby! Really appreciate the tips.
tanc
 
Posts: 5
Joined: Tue Apr 19, 2011 8:11 am


Return to Plugin Development

Who is online

Users browsing this forum: No registered users and 9 guests

cron