# -*- coding: utf-8 -*- # # Copyright (C) 2009-2010 Per Arneng # # 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: