def select_project(self, on_selected, filter_project): '''Select a project from a generated project list. Execution flow continues into the :py:function:`on_selected` function with the project's name and the project's base directory. The :py:function:`filter_project` filters projects before they are shown (see :py:method:`get_projects`.) ''' projs = [(name, info) for (name, info) in self.get_projects().items() if not filter_project or filter_project(name, info)] def run_selected(psel): on_selected(psel[0], psel[1]['path']) if not projs: Common.show_status_message("No active projects found.", is_ok=False, priority=5) elif len(projs) == 1: # There's only one project, build it run_selected(projs[0]) else: _, cabal_project_name = Common.locate_cabal_project_from_view(self.window.active_view()) Logging.log('Current project: {0}'.format(cabal_project_name)) # Sort by name projs.sort(key=lambda p: p[0]) current_project_idx = next((i for i, p in enumerate(projs) if p[0] == cabal_project_name), -1) def on_done(idx): if idx != -1: run_selected(projs[idx]) self.window.show_quick_panel(list(map(lambda m: [m[0], m[1]['path']], projs)), on_done, 0, current_project_idx)
def run(self, edit): selections = list(self.view.sel()) if not self.is_infos_valid(selections): SublimeHaskellExpandSelectionExpression.Infos = [ ExpandSelectionInfo(self.view, s) for s in selections ] if not self.is_infos_valid(selections): Common.show_status_message( 'Unable to retrieve expand selection info', False) return selinfo = [i.expand() for i in self.Infos] self.view.sel().clear() self.view.sel().add_all([sel.region for sel in selinfo]) Common.output_panel( self.view.window(), '\n'.join([ UnicodeOpers.use_unicode_operators(sel.typename) for sel in selinfo ]), panel_name='sublime_haskell_expand_selection_expression', syntax='Haskell-SublimeHaskell')
def show_types(self, types): if not types: Common.show_status_message("Can't infer type", False) return types = sorted(filter( lambda t: t.region(self.view).contains(self.view.sel()[0]), types), key=lambda t: t.region(self.view).size()) self.output_view = Common.output_panel(self.view.window(), '', panel_name=TYPES_PANEL_NAME, syntax='Haskell-SublimeHaskell', panel_display=False) regions = [] for typ in types: Common.output_text(self.output_view, '{0}\n'.format(typ.show(self.view)), clear=False) regions.append( sublime.Region( self.output_view.size() - 1 - len(UnicodeOpers.use_unicode_operators(typ.typename)), self.output_view.size() - 1)) self.output_view.add_regions('types', regions, 'comment', '', sublime.DRAW_OUTLINED) Common.show_panel(self.view.window(), panel_name=TYPES_PANEL_NAME)
def select_project(self, on_selected, filter_project): projs = [(name, info) for (name, info) in self.get_projects().items() if not filter_project or filter_project(name, info)] def run_selected(psel): on_selected(psel[0], psel[1]['path']) if not projs: Common.show_status_message("No active projects found.", is_ok=False, priority=5) elif len(projs) == 1: # There's only one project, build it run_selected(projs[0]) else: _, cabal_project_name = Common.locate_cabal_project_from_view( self.window.active_view()) Logging.log('Current project: {0}'.format(cabal_project_name)) # Sort by name projs.sort(key=lambda p: p[0]) current_project_idx = next( (i for i, p in enumerate(projs) if p[0] == cabal_project_name), -1) def on_done(idx): if idx != -1: run_selected(projs[idx]) self.window.show_quick_panel( list(map(lambda m: [m[0], m[1]['path']], projs)), on_done, 0, current_project_idx)
def run(self, edit, **args): kw_module = args.get('module') self.backend = BackendManager.active_backend() if not kw_module: kw_decl = args.get('decl') if kw_decl is None: qsymbol = Common.get_qualified_symbol_at_region(self.view, self.view.sel()[0]) kw_decl = qsymbol.qualified_name() current_file_name = self.view.file_name() # Phase 1: Get the candidate import modules: the backend's query_import returns the (flag, list) tuple. # If successful (flag == True), then invoke add_import to add the import to the module's existing # modules. (status, self.candidates) = self.backend.query_import(kw_decl, current_file_name) if status: if len(self.candidates) == 1: self.add_import(edit, self.candidates[0].module.name) else: self.view.window().show_quick_panel([[c.module.name] for c in self.candidates], self.on_done) else: if len(self.candidates) == 1: Common.show_status_message(self.candidates[0]) else: sublime.message_dialog('\n'.join(self.candidates)) else: self.add_import(edit, kw_module)
def run(self): self.view = self.window.active_view() if not self.view: Common.show_status_message("No file active", False) else: project_dir, project_name = Common.locate_cabal_project_from_view( self.view) if not project_dir: Common.show_status_message("Not in project", False) ## FIXME: proj_info = BackendManager.active_backend().project(project_name) self.project_name = project_name self.project_dir = project_dir self.names = ['lib:{0}'.format(project_name)] if proj_info: self.names.extend([ 'exe:{0}'.format(executable['name']) for executable in proj_info['description']['executables'] ]) self.names.extend([ 'test:{0}'.format(test['name']) for test in proj_info['description']['tests'] ]) if len(self.names) > 1: self.window.show_quick_panel(self.names, self.on_done) else: self.on_done(0)
def select_project(window, on_selected, filter_project=None): projs = [(name, info) for (name, info) in get_projects().items() if not filter_project or filter_project(name, info)] def run_selected(psel): on_selected(psel[0], psel[1]['path']) if len(projs) == 0: Common.show_status_message( "No projects found, did you add a '.cabal' file?", is_ok=False, priority=5) return if len(projs) == 1: # There's only one project, build it run_selected(projs[0]) return _, cabal_project_name = Common.get_cabal_project_dir_and_name_of_view( window.active_view()) Logging.log('Current project: {0}'.format(cabal_project_name)) # Sort by name projs.sort(key=lambda p: p[0]) current_project_idx = next( (i for i, p in enumerate(projs) if p[0] == cabal_project_name), -1) def on_done(idx): if idx != -1: run_selected(projs[idx]) window.show_quick_panel(list(map(lambda m: [m[0], m[1]['path']], projs)), on_done, 0, current_project_idx)
def on_done(self, inp): self.packages = hsdev.client.cabal_list(input) if not self.packages: Common.show_status_message("Package {0} not found".format(inp)) else: self.window.show_quick_panel( [([p.name] + ([p.synopsis] if p.synopsis else [])) for p in self.packages], self.on_select)
def show_types(self, types): if types: self.types = types self.output_view = Common.output_panel(self.view.window(), '', panel_name=TYPES_PANEL_NAME, syntax='Haskell-SublimeHaskell') self.view.window().show_quick_panel([t.typename for t in self.types], self.on_done, 0, -1, self.on_changed) else: Common.show_status_message("Can't infer type", False)
def on_resp(self, resp): self.status_msg.stop() self.decls.extend(resp) if not self.decls: Common.show_status_message("Search '{0}' not found".format(self.search_str)) else: hayoo_results = [[decl.module.name + ': ' + decl.brief(use_unicode=False), decl.defined_module().location] for decl in self.decls] self.window.show_quick_panel(hayoo_results, self.on_select)
def on_resp(self, resp): self.status_msg.stop() self.decls = resp if not self.decls: Common.show_status_message("Hayoo '{0}': not found".format(self.search_str)) return brief_decls = [[decl.module.name + ': ' + decl.brief(use_unicode=False), decl.defined_module().location] for decl in self.decls] self.window.show_quick_panel(brief_decls, self.on_select)
def on_done(self, sym): self.decls = BackendManager.active_backend().symbol(lookup=sym, search_type='regex') self.decls.sort(key=lambda d: d.module.name) if self.decls: module_decls = [['{0}: {1}'.format(decl.module.name, decl.brief(use_unicode=True)), str(decl.defined_module().location)] for decl in self.decls] self.window.show_quick_panel(module_decls, self.on_select) else: Common.show_status_message("Nothing found for: {0}".format(sym))
def on_candidate_selected(self, idx): if idx >= 0: (module_name, ident_name) = self.candidates[idx] info = BackendManager.active_backend().whois('{0}.{1}'.format(module_name, ident_name), self.view.file_name()) if info: self.show_symbol_info(info[0]) else: Common.show_status_message("Can't get info for {0}.{1}".format(module_name, ident_name), False)
def run(self, _edit): qsymbol = Common.get_qualified_symbol_at_region(self.view, self.view.sel()[0]) if Common.is_haskell_symbol_info(self.view): # Go to within symbol info window loc = self.view.settings().get('location') if loc: self.view.window().open_file(loc, sublime.ENCODED_POSITION) else: Common.show_status_message('Source location of {0} not found'.format(qsymbol.name), False) else: backend = BackendManager.active_backend() whois_name = qsymbol.qualified_name() full_name = qsymbol.full_name() current_file_name = self.view.file_name() candidates = [] module_candidates = [] if not qsymbol.is_module(): candidates = [decl for decl in backend.whois(whois_name, current_file_name) if decl.by_source()] if candidates: if candidates[0].has_source_location(): self.view.window().open_file(candidates[0].get_source_location(), sublime.ENCODED_POSITION) else: cands = candidates[:] candidates = [] for cand in cands: for i in cand.imported: candidates = [sym for sym in backend.symbol(lookup=cand.name, search_type='exact', source=True) if sym.module.name == i.module] if candidates and candidates[0].has_source_location(): self.view.window().open_file(candidates[0].get_source_location(), sublime.ENCODED_POSITION) return else: candidates = backend.symbol(lookup=qsymbol.name, search_type='exact', source=True) else: module_candidates = [m for m in backend.list_modules(source=True, module=full_name) if m.name == full_name] if not candidates and not module_candidates: Common.show_status_message('Declaration {0} not found'.format(qsymbol.name), False) else: candidates_len = len(candidates) if candidates is not None else 0 module_candidates_len = len(module_candidates) if module_candidates is not None else 0 if candidates_len + module_candidates_len == 1: if candidates_len == 1: self.view.window().open_file(candidates[0].get_source_location(), sublime.ENCODED_POSITION) elif module_candidates_len == 1: self.view.window().open_file(module_candidates[0].location.filename) return else: # many candidates self.select_candidates = [([c.brief(use_unicode=False), c.get_source_location()], True) for c in candidates] self.select_candidates += [([m.name, m.location.filename], False) for m in module_candidates] just_names = [c[0] for c in self.select_candidates] self.view.window().show_quick_panel(just_names, self.on_done, 0, 0, self.on_highlighted)
def on_inspected(self, result): imp_module = None if self.view.is_dirty(): # Use the buffer's contents pyresult = json.loads(result).get('result') if pyresult is not None: if Logging.is_log_level(Logging.LOG_DEBUG): pprint.pprint(pyresult, width=80) modinfo = pyresult.get('module') if modinfo is not None: imp_module = HsDevResultParse.parse_module(modinfo) else: # Otherwise, use the actual file imp_module = Utils.head_of( hsdev.client.module(file=self.current_file_name)) if imp_module is not None: imports = sorted(imp_module.imports, key=lambda i: i.position.line) after = [i for i in imports if i.module > self.module_name] insert_line = 0 insert_gap = False if len(after) > 0: # Insert before after[0] insert_line = after[0].position.line - 1 elif len(imports) > 0: # Insert after all imports insert_line = imports[-1].position.line elif len(imp_module.declarations) > 0: # Insert before first declaration insert_line = min([ d.position.line for d in imp_module.declarations.values() ]) - 1 insert_gap = True else: # Try to add the import just after the "where" of the module declaration contents = self.view.substr(sublime.Region( 0, self.view.size())) mod_decl = re.search('module.*where', contents, re.MULTILINE) if mod_decl is not None: insert_line = mod_decl.end() insert_gap = True else: # Punt! Insert at the end of the file insert_line = self.view.rowcol(self.view.size())[0] insert_text = 'import {0}\n'.format( self.module_name) + ('\n' if insert_gap else '') point = self.view.text_point(insert_line, 0) self.view.insert(self.edit, point, insert_text) Common.show_status_message( 'Import {0} added'.format(self.module_name), True)
def run_build(view, project_name, project_dir, config): # Don't build if a build is already running for this project # We compare the project_name for simplicity (projects with same # names are of course possible, but unlikely, so we let them wait) if project_name in PROJECTS_BEING_BUILT: Logging.log( "Waiting for build action on '%s' to complete." % project_name, Logging.LOG_WARNING) Common.show_status_message('Already building %s' % project_name, is_ok=False, priority=5) return # Set project as building PROJECTS_BEING_BUILT.add(project_name) build_tool_name = Settings.PLUGIN.haskell_build_tool if build_tool_name == 'stack' and not is_stack_project( project_dir): # rollback to cabal build_tool_name = 'cabal' tool = BUILD_TOOL[build_tool_name] # Title of tool: Cabal, Stack tool_title = tool['name'] # Title of action: Cleaning, Building, etc. action_title = config['message'] # Tool name: cabal tool_name = tool['command'] # Tool arguments (commands): build, clean, etc. tool_steps = config['steps'][build_tool_name] # Config override override_config = Settings.get_project_setting(view, 'stack_config_file') override_args = [] if override_config: override_args = ['--stack-yaml', override_config] # Assemble command lines to run (possibly multiple steps) commands = [[tool_name] + step + override_args for step in tool_steps] Logging.log('running build commands: {0}'.format(commands), Logging.LOG_TRACE) def done_callback(): # Set project as done being built so that it can be built again PROJECTS_BEING_BUILT.remove(project_name) # Run them ParseOutput.run_chain_build_thread(view, project_dir, '{0} {1} with {2}'.format( action_title, project_name, tool_title), commands, on_done=done_callback)
def run(self): view = self.window.active_view() if not view: Common.show_status_message("No file active", False) else: project_dir = Common.locate_cabal_project_from_view(view)[0] if not project_dir: self.window.run_command( "sublime_haskell_repl_ghci_current_file", {}) else: self.window.run_command("sublime_haskell_repl_cabal", {})
def run_build(self, view, project_name, project_dir, config): # Don't build if a build is already running for this project # We compare the project_name for simplicity (projects with same # names are of course possible, but unlikely, so we let them wait) if project_name in self.PROJECTS_BEING_BUILT: Logging.log("Waiting for build action on '%s' to complete." % project_name, Logging.LOG_WARNING) Common.show_status_message('Already building %s' % project_name, is_ok=False, priority=5) return # Set project as building self.PROJECTS_BEING_BUILT.add(project_name) Logging.log('project build tool: {0}'.format(Settings.get_project_setting(view, 'haskell_build_tool')), Logging.LOG_DEBUG) Logging.log('settings build tool: {0}'.format(Settings.PLUGIN.haskell_build_tool), Logging.LOG_DEBUG) build_tool_name = Settings.get_project_setting(view, 'haskell_build_tool', Settings.PLUGIN.haskell_build_tool) if build_tool_name == 'stack' and not self.is_stack_project(project_dir): # rollback to cabal build_tool_name = 'cabal' tool = self.BUILD_TOOL[build_tool_name] # Title of tool: Cabal, Stack tool_title = tool['name'] # Title of action: Cleaning, Building, etc. action_title = config['message'] # Tool name: cabal tool_name = tool['command'] # Tool arguments (commands): build, clean, etc. tool_steps = config['steps'][build_tool_name] # Config override override_config = Settings.get_project_setting(view, 'active_stack_config') override_args = [] if override_config: override_args = ['--stack-yaml', override_config] # Assemble command lines to run (possibly multiple steps) commands = [[tool_name] + override_args + step if isinstance(step, list) else step for step in tool_steps] Logging.log('running build commands: {0}'.format(commands), Logging.LOG_TRACE) def done_callback(): # Set project as done being built so that it can be built again self.PROJECTS_BEING_BUILT.remove(project_name) # Run them msg = '{0} {1} with {2}\ncommands:\n{3}'.format(action_title, project_name, tool_title, commands) Logging.log(msg, Logging.LOG_DEBUG) Common.show_status_message_process(msg, priority=3) Utils.run_async('wait_for_chain_to_complete', self.wait_for_chain_to_complete, view, project_dir, msg, commands, on_done=done_callback)
def run(self, _edit): errs = errors_for_view(self.view) if not errs: Common.show_status_message("No errors or warnings!", priority=5) else: cur_point = symbols.Region.from_region(self.view, self.view.sel()[0]) prev_err = next(filter(lambda e: e.region < cur_point, reversed(errs)), None) # Cycle around to the last error if we run off the first if prev_err is None: prev_err = errs[-1] self.view.sel().clear() self.view.sel().add(prev_err.region.to_region(self.view)) goto_error(self.view, prev_err)
def run(self, _edit, **kwargs): filename = kwargs.get('filename') module_name = kwargs.get('module_name') package_name = kwargs.get('package_name') symdb = kwargs.get('db') name = kwargs.get('name') qname = kwargs.get('qname') no_browse = kwargs.get('no_browse') or False if qname: self.full_name = qname self.current_file_name = self.view.file_name() # Try whois it, followed by file symbol and wider module searches self.candidates = self.collect_candidates(qname, name, filename, module_name, package_name, symdb) else: self.current_file_name = self.view.file_name() qsymbol = Common.get_qualified_symbol(qname) \ if qname \ else Common.get_qualified_symbol_at_region(self.view, self.view.sel()[0]) module_word = qsymbol.module ident = qsymbol.name if ident is None: # module if not no_browse: self.view.window().run_command('sublime_haskell_browse_module', {'module_name': module_word, 'scope': self.current_file_name}) return if not module_word and not ident: Common.show_status_message('No symbol selected', False) return self.whois_name = qsymbol.qualified_name() self.full_name = qsymbol.full_name() self.candidates = (BackendManager.active_backend().whois(self.whois_name, self.current_file_name) or [])[:1] if not self.candidates: self.candidates = BackendManager.active_backend().lookup(self.full_name, self.current_file_name) if not self.candidates: self.candidates = BackendManager.active_backend().symbol(lookup=self.full_name, search_type='exact') if not self.candidates: Common.show_status_message('Symbol {0} not found'.format(self.full_name)) elif len(self.candidates) == 1: self.show_symbol_info(self.candidates[0]) elif not no_browse: results = [[c.qualified_name(), c.defined_module().location.to_string()] for c in self.candidates] self.view.window().show_quick_panel(results, self.on_done)
def run(self): view = self.window.active_view() if not view: Common.show_status_message("No file active", False) else: opts = Settings.PLUGIN.ghci_opts or [] self.window.run_command( "repl_open", repl_args(cmd=["ghci", "$file"] + opts, loaded=view.file_name(), caption="ghci: {0}".format( os.path.basename(view.file_name())))) KNOWN_REPLS.set_repl_view( sublimerepl.repl_external_id(view.file_name()), view)
def wrapper(self, *args, **kwargs): if Settings.PLUGIN.enable_hsdev: Logging.log("Invoking '{0}' command via hsdev".format(cmdname), Logging.LOG_TRACE) return outer_fn(self, *args, **kwargs) elif Settings.PLUGIN.enable_ghc_mod: Logging.log( "Invoking '{0}' command via ghc-mod".format(cmdname), Logging.LOG_TRACE) self.view.window().run_command( 'sublime_haskell_ghc_mod_{0}'.format(cmdname)) else: Common.show_status_message( 'Check/Lint: both hsdev and ghc-mod are disabled', False)
def add_import(self, edit, module_name): contents = self.view.substr(sublime.Region(0, self.view.size())) # Truncate contents to the module declaration and the imports list, if present. imports_list = list(re.finditer('^import.*$', contents, re.MULTILINE)) if len(imports_list) > 0: contents = contents[0:imports_list[-1].end()] # Phase 2: Ask the backend to turn the contents into a list of Module objects: imp_module = self.backend.contents_to_module(contents) if imp_module is not None: imports = sorted(imp_module.imports, key=lambda i: i.position.line) after = [imp for imp in imports if imp.module > module_name] insert_line = 0 insert_gap = False if len(after) > 0: # Insert before after[0] insert_line = after[0].position.line - 1 elif len(imports) > 0: # Insert after all imports insert_line = imports[-1].position.line elif len(imp_module.declarations) > 0: # Insert before first declaration insert_line = min([ d.position.line for d in imp_module.declarations.values() ]) - 1 insert_gap = True else: # Try to add the import just after the "where" of the module declaration contents = self.view.substr(sublime.Region( 0, self.view.size())) mod_decl = re.search('module.*where', contents, re.MULTILINE) if mod_decl is not None: insert_line = mod_decl.end() insert_gap = True else: # Punt! Insert at the end of the file insert_line = self.view.rowcol(self.view.size())[0] insert_text = 'import {0}\n'.format(module_name) + ( '\n' if insert_gap else '') point = self.view.text_point(insert_line, 0) self.view.insert(edit, point, insert_text) Common.show_status_message('Import {0} added'.format(module_name), True)
def run(self, _edit, **kwargs): module_name = kwargs.get('module_name') filename = kwargs.get('filename') symdb = kwargs.get('db') scope = kwargs.get('scope') self.candidates = [] self.current_file_name = self.view.window().active_view().file_name() the_module = None project_name = Common.locate_cabal_project_from_view(self.view.window().active_view())[1] if filename: the_module = Utils.head_of(BackendManager.active_backend().module(project_name, file=filename)) if not the_module: Common.show_status_message('Module {0} not found'.format(filename)) return elif module_name: cand_mods = self.candidate_modules(project_name, module_name, scope, symdb) if len(cand_mods) == 0: Common.show_status_message('Module {0} not found'.format(module_name)) return elif len(cand_mods) == 1: the_module = self.get_module_info(project_name, cand_mods[0], module_name) if the_module: the_module = Utils.head_of(the_module) else: self.candidates.extend([(m, [m.name, m.location.to_string()]) for m in cand_mods]) else: if self.current_file_name: cand_mods = BackendManager.active_backend().scope_modules(project_name, self.current_file_name) else: symbol_db = symbols.PackageDb.from_string(symdb) if symdb else None cand_mods = BackendManager.active_backend().list_modules(symdb=symbol_db) self.candidates.extend([(m, [m.name, m.location.to_string()]) for m in cand_mods]) if the_module: self.candidates = sorted(list(the_module.declarations.values()), key=lambda d: d.brief()) results = [[decl.brief(use_unicode=False), decl.docs.splitlines()[0] if decl.docs else ''] for decl in self.candidates] self.view.window().show_quick_panel(results, self.on_symbol_selected) else: self.candidates.sort(key=lambda c: c[1][0]) self.view.window().show_quick_panel([c[1] for c in self.candidates], self.on_done)
def run(self, _edit): if Common.is_haskell_symbol_info(self.view): pack = self.view.settings().get('package') mod = self.view.settings().get('module') if pack and mod: webbrowser.open('http://hackage.haskell.org/package/{0}/docs/{1}.html'.format(pack, mod.replace('.', '-'))) else: project_name = Common.locate_cabal_project_from_view(self.view)[1] qsymbol = Common.get_qualified_symbol_at_region(self.view, self.view.sel()[0]) modules = [] if qsymbol.is_module(): # module scope = self.view.file_name() if scope: modules = [m for m in BackendManager.active_backend().scope_modules(project_name, scope, lookup=qsymbol.module, search_type='exact') if m.by_cabal()] else: modules = [m for m in BackendManager.active_backend().list_modules(symdb=m.location.db) if m.name == qsymbol.module and m.by_cabal()] else: # symbol scope = self.view.file_name() if scope: decls = BackendManager.active_backend().whois(qsymbol.qualified_name(), file=scope) or \ BackendManager.active_backend().lookup(qsymbol.full_name(), file=scope) or \ BackendManager.active_backend().symbol(lookup=qsymbol.full_name(), search_type='exact') if not decls: Common.show_status_message('Module for symbol {0} not found'.format(qsymbol.full_name())) return modules = [decl.defined_module() for decl in decls] if len(modules) == 0: Common.show_status_message('Module {0} not found'.format(qsymbol.module)) elif len(modules) == 1: pkg_id = modules[0].location.package.package_id() pkg_name = modules[0].name.replace('.', '-') webbrowser.open('http://hackage.haskell.org/package/{0}/docs/{1}.html'.format(pkg_id, pkg_name)) else: self.candidates = modules[:] mod_strings = [[m.name, m.location.package.package_id()] for m in self.candidates] self.view.window().show_quick_panel(mod_strings, self.on_done)
def run(self, _edit): errs = errors_for_view(self.view) if not errs: Common.show_status_message('No errors or warnings!', priority=5) else: view_pt = self.view.sel()[0] # Bump just past the view's point, just in case we're sitting on top of the current cur_point = symbols.Region.from_region(self.view, view_pt) err_iter = filter(lambda e: e.region > cur_point, errs) next_err = next(err_iter, None) # If the view's point is really on top of the start of an error, move to the next, otherwise, # we'll just keep sitting on top of the current error and never move. if next_err is not None and next_err.region.start == cur_point.start: next_err = next(err_iter, None) # Cycle around to the first error if we run off the end of the list. if next_err is None: next_err = errs[0] self.view.sel().clear() self.view.sel().add(next_err.region.to_region(self.view)) goto_error(self.view, next_err)
def run(self, edit, **kwargs): current_file_name = kwargs.get('filename', self.view.file_name()) project_name = Common.locate_cabal_project_from_view(self.view)[1] backend = BackendManager.active_backend() imp_module = Utils.head_of(backend.module(project_name, file=current_file_name)) if imp_module: imports = sorted(imp_module.imports, key=lambda i: i.position.line) supported, result = backend.clean_imports(current_file_name) print(result) if supported: if len(imports) == len(result): Logging.log('replacing imports for {0}'.format(current_file_name), Logging.LOG_TRACE) erased = 0 for imp, new_imp in zip(imports, result): point = self.view.text_point(imp.position.line - 1 - erased, 0) if new_imp.endswith('()'): self.view.erase(edit, self.view.full_line(point)) erased = erased + 1 else: self.view.replace(edit, self.view.line(point), new_imp) else: Common.show_status_message('different number of imports: {0} and {1}'.format(len(imports), len(result))) else: if len(result) == 1: Common.show_status_message(result[0]) else: sublime.message_dialog('\n'.join(result)) else: Common.show_status_message('Clean Imports failed: module not scanned')
def run(self, edit, **kwargs): filename = kwargs.get('filename') decl = kwargs.get('decl') module_name = kwargs.get('module_name') self.full_name = decl self.current_file_name = filename self.edit = edit if module_name is not None: self.add_import(module_name) return if not self.current_file_name: self.current_file_name = self.view.file_name() if not self.full_name: qsymbol = Common.get_qualified_symbol_at_region( self.view, self.view.sel()[0]) self.full_name = qsymbol.qualified_name() if hsdev.client.whois(self.full_name, self.current_file_name): Common.show_status_message('Symbol {0} already in scope'.format( self.full_name)) else: self.candidates = hsdev.client.lookup(self.full_name, self.current_file_name) if not self.candidates: Common.show_status_message('Symbol {0} not found'.format( self.full_name)) elif len(self.candidates) == 1: self.add_import(self.candidates[0].module.name) else: self.view.window().show_quick_panel([[c.module.name] for c in self.candidates], self.on_done)
def run(self, **kwargs): project = kwargs.get('project') or False decls = [] if project: project_name = Common.locate_cabal_project_from_view(self.view)[1] modules = BackendManager.active_backend().module(project_name, file=self.current_filename) current_project = Utils.head_of(modules).location.project if not current_project: Common.show_status_message('File {0} is not in project'.format(self.current_filename), False) return decls = self.sorted_decls_name(BackendManager.active_backend().symbol(project=current_project)) self.declarations = [[decl.brief(True, use_unicode=False), decl.module.name] for decl in decls] else: decls = self.sorted_decls_pos(BackendManager.active_backend().symbol(file=self.current_filename, local_names=True)) self.declarations = [[(decl.position.column * ' ') + decl.brief(True, use_unicode=False)] for decl in decls] self.decls = decls[:] if decls: self.window.show_quick_panel(self.declarations, self.on_done, 0, self.closest_idx(decls), self.on_highlighted if not project else None)
def on_err(self, err, _details): Common.show_status_message('Browse declarations: {0}'.format(err))