def run(self, edit):
        (module_word, ident, _) = get_qualified_symbol_at_region(self.view, self.view.sel()[0])

        full_name = '.'.join([module_word, ident]) if module_word else ident

        current_file_name = self.view.file_name()
        current_project = get_cabal_project_dir_of_file(current_file_name)

        module_candidates = []
        candidates = []

        with autocompletion.database.symbols as decl_symbols:
            if ident not in decl_symbols:
                show_status_message('Declaration for {0} not found'.format(ident), False)
                return

            decls = decl_symbols[ident]

            modules_dict = symbols.flatten(symbols.declarations_modules(decls, lambda ms: list(filter(symbols.is_by_sources, ms))).values())

            with autocompletion.database.files as files:
                if current_file_name in files:
                    cur_info = files[current_file_name]

                    if not module_word:
                        # this module declarations
                        candidates.extend([m.declarations[ident] for m in modules_dict if symbols.is_this_module(cur_info, m) and ident in m.declarations])
                    if not candidates:
                        # declarations from imported modules within this project
                        candidates.extend([m.declarations[ident] for m in modules_dict if symbols.is_imported_module(cur_info, m, module_word) and symbols.is_within_project(m, cur_info.location.project) and ident in m.declarations])
                    if not candidates:
                        # declarations from imported modules within other projects
                        candidates.extend([m.declarations[ident] for m in modules_dict if symbols.is_imported_module(cur_info, m, module_word) and ident in m.declarations])
                    if not candidates:
                        # show all possible candidates
                        candidates.extend([m.declarations[ident] for m in modules_dict if ident in declarations])

                # No info about imports for this file, just add all declarations
                else:
                    candidates.extend([m.declarations[ident] for m in modules_dict if ident in declarations])

        with autocompletion.database.modules as modules:
            if full_name in modules:
                modules_list = list(filter(symbols.is_by_sources, modules[full_name]))

                # Find module in this project
                module_candidates.extend([m for m in modules_list if symbols.is_within_project(m, current_project)])
                if not module_candidates:
                    # Modules from other projects
                    module_candidates.extend(modules_list)

        if not candidates and not module_candidates:
            show_status_message('Declaration for {0} not found'.format(ident), False)
            return

        if len(candidates) + len(module_candidates) == 1:
            if len(module_candidates) == 1:
                self.view.window().open_file(module_candidates[0].location.filename)
                return
            if len(candidates) == 1:
                self.view.window().open_file(candidates[0].location.position(), sublime.ENCODED_POSITION)
                return

        # many candidates
        self.select_candidates = [([c.name, c.location.position()], True) for c in candidates] + [([m.name, m.location.filename], False) for m in module_candidates]
        self.view.window().show_quick_panel([c[0] for c in self.select_candidates], self.on_done)
    def run(self, edit, filename = None, module_name = None, decl = None):
        if decl and filename:
            with autocompletion.database.files as files:
                if filename in files:
                    m = files[filename]
                    if decl in m.declarations:
                        self.show_symbol_info(m.declarations[decl])
                    else:
                        show_status_message('Symbol {0} not found in {1}'.format(decl, filename))
                else:
                    show_status_message('No info about module in {0}'.format(filename))
            return

        if decl and module_name:
            cur_cabal = current_cabal()
            with autocompletion.database.cabal_modules as cabal_modules:
                modules = cabal_modules[cur_cabal]
                if module_name in modules:
                    m = modules[module_name]
                    if decl in m.declarations:
                        self.show_symbol_info(m.declarations[decl])
                    else:
                        show_status_message('Symbol {0} not found in {1}'.format(decl, ))
                else:
                    show_status_message('No info about module {0}'.format(module_name))
            return

        (module_word, ident, _) = get_qualified_symbol_at_region(self.view, self.view.sel()[0])
        full_name = '{0}.{1}'.format(module_word, ident) if module_word else ident

        current_file_name = self.view.file_name()

        candidates = []

        imported_symbol_not_found = False

        with autocompletion.database.symbols as decl_symbols:
            if ident not in decl_symbols:
                # Sometimes ghc-mod returns no info about module, but module exists
                # So there are no info about valid symbol
                # But if user sure, that symbol exists, he can force to call for ghci to get info
                import_list = []
                with autocompletion.database.files as files:
                    if current_file_name in files:
                        import_list.extend(files[current_file_name].imports.keys())

                if module_word:
                    # Full qualified name, just call to ghci_info
                    info = ghci_info(module_word, ident)
                    if info:
                        self.show_symbol_info(info)
                        return
                elif import_list:
                    # Allow user to select module
                    self.candidates = [(m, ident) for m in import_list]
                    self.view.window().show_quick_panel(['{0}.{1}'.format(m, ident) for m in import_list], self.on_candidate_selected)
                    return

                show_status_message('Symbol {0} not found'.format(ident), False)
                return

            decls = decl_symbols[ident]

            modules_dict = symbols.declarations_modules(decls, lambda ms: symbols.get_visible_module(ms, current_file_name)).values()

            with autocompletion.database.files as files:
                if current_file_name in files:
                    cur_info = files[current_file_name]

                    if not module_word:
                        # this module declaration
                        candidates.extend([m.declarations[ident] for m in modules_dict if symbols.is_this_module(cur_info, m) and ident in m.declarations])
                    if not candidates:
                        # declarations from imported modules
                        candidates.extend([m.declarations[ident] for m in modules_dict if symbols.is_imported_module(cur_info, m, module_word) and ident in m.declarations])
                    if not candidates:
                        imported_symbol_not_found = True
                        # show all possible candidates
                        candidates.extend([m.declarations[ident] for m in modules_dict if ident in m.declarations])

                # No info about imports for this file, just add all declarations
                else:
                    candidates.extend([m.declarations[ident] for m in modules_dict if ident in m.declarations])

        if imported_symbol_not_found:
            browse_for_module = False
            browse_module_candidate = None
            with autocompletion.database.modules as modules:
                if full_name in modules:
                    # Browse symbols in module
                    browse_for_module = True
                    browse_module_candidate = symbols.get_preferred_module(modules[full_name], current_file_name)

            if browse_for_module:
                if browse_module_candidate:
                    self.view.window().run_command('sublime_haskell_browse_module', {
                        'module_name': browse_module_candidate.name,
                        'filename': current_file_name })
                    return
                else:
                    show_status_message("No info about module {0}".format(full_name))
                    return


        if not candidates:
            show_status_message('Symbol {0} not found'.format(ident), False)
            return

        if len(candidates) == 1:
            self.show_symbol_info(candidates[0])
            return

        self.candidates = candidates
        self.view.window().show_quick_panel([[c.qualified_name()] for c in candidates], self.on_done)