diff options
Diffstat (limited to 'plugins/externaltools/tools/filelookup.py')
-rw-r--r-- | plugins/externaltools/tools/filelookup.py | 165 |
1 files changed, 165 insertions, 0 deletions
diff --git a/plugins/externaltools/tools/filelookup.py b/plugins/externaltools/tools/filelookup.py new file mode 100644 index 0000000..f256eea --- /dev/null +++ b/plugins/externaltools/tools/filelookup.py @@ -0,0 +1,165 @@ +# -*- coding: utf-8 -*- +# +# Copyright (C) 2009-2010 Per Arneng <per.arneng@anyplanet.com> +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +import os +from gi.repository import Gio, Gedit +from .functions import * + + +class FileLookup: + """ + This class is responsible for looking up files given a part or the whole + path of a real file. The lookup is delegated to providers wich use + different methods of trying to find the real file. + """ + + def __init__(self, window): + self.providers = [] + self.providers.append(AbsoluteFileLookupProvider()) + self.providers.append(BrowserRootFileLookupProvider(window)) + self.providers.append(CwdFileLookupProvider()) + self.providers.append(OpenDocumentRelPathFileLookupProvider()) + self.providers.append(OpenDocumentFileLookupProvider()) + + def lookup(self, path): + """ + Tries to find a file specified by the path parameter. It delegates to + different lookup providers and the first match is returned. If no file + was found then None is returned. + + path -- the path to find + """ + found_file = None + for provider in self.providers: + found_file = provider.lookup(path) + if found_file is not None: + break + + return found_file + + +class FileLookupProvider: + """ + The base class of all file lookup providers. + """ + + def lookup(self, path): + """ + This method must be implemented by subclasses. Implementors will be + given a path and will try to find a matching file. If no file is found + then None is returned. + """ + raise NotImplementedError("need to implement a lookup method") + + +class AbsoluteFileLookupProvider(FileLookupProvider): + """ + This file tries to see if the path given is an absolute path and that the + path references a file. + """ + + def lookup(self, path): + if os.path.isabs(path) and os.path.isfile(path): + return Gio.file_new_for_path(path) + else: + return None + + +class BrowserRootFileLookupProvider(FileLookupProvider): + """ + This lookup provider tries to find a file specified by the path relative to + the file browser root. + """ + def __init__(self, window): + self.window = window + + def lookup(self, path): + root = file_browser_root(self.window) + if root: + real_path = os.path.join(root, path) + if os.path.isfile(real_path): + return Gio.file_new_for_path(real_path) + + return None + + +class CwdFileLookupProvider(FileLookupProvider): + """ + This lookup provider tries to find a file specified by the path relative to + the current working directory. + """ + + def lookup(self, path): + try: + cwd = os.getcwd() + except OSError: + cwd = os.getenv('HOME') + + real_path = os.path.join(cwd, path) + + if os.path.isfile(real_path): + return Gio.file_new_for_path(real_path) + else: + return None + + +class OpenDocumentRelPathFileLookupProvider(FileLookupProvider): + """ + Tries to see if the path is relative to any directories where the + currently open documents reside in. Example: If you have a document opened + '/tmp/Makefile' and a lookup is made for 'src/test2.c' then this class + will try to find '/tmp/src/test2.c'. + """ + + def lookup(self, path): + if path.startswith('/'): + return None + + for doc in Gio.Application.get_default().get_documents(): + if doc.get_file().is_local(): + location = doc.get_file().get_location() + if location: + rel_path = location.get_parent().get_path() + joined_path = os.path.join(rel_path, path) + if os.path.isfile(joined_path): + return Gio.file_new_for_path(joined_path) + + return None + + +class OpenDocumentFileLookupProvider(FileLookupProvider): + """ + Makes a guess that the if the path that was looked for matches the end + of the path of a currently open document then that document is the one + that is looked for. Example: If a document is opened called '/tmp/t.c' + and a lookup is made for 't.c' or 'tmp/t.c' then both will match since + the open document ends with the path that is searched for. + """ + + def lookup(self, path): + if path.startswith('/'): + return None + + for doc in Gio.Application.get_default().get_documents(): + if doc.get_file().is_local(): + location = doc.get_file().get_location() + if location and location.get_uri().endswith(path): + return location + return None + +# ex:ts=4:et: |