def run(self, edit, text): self.view.set_read_only(False) self.view.replace(edit, sublime.Region(0, self.view.size()), text) self.view.set_read_only(True)
def on_done(self, edit, tags): dataRegion = sublime.Region(0, self.view.size()) data = TagRemoveSelected(self.view.substr(dataRegion), tags, self.view) with Edit(self.view) as edit: edit.replace(dataRegion, data)
def selected_file(self): v = self.view return v.substr(sublime.Region(0, v.size()))
def ss(start, end): return view.substr(sublime.Region(start, end))
def to_region(rng): return sublime.Region(rng[0], rng[1])
def add_sel(view, a=0, b=0): if isinstance(a, sublime.Region): view.sel().add(a) return view.sel().add(sublime.Region(a, b))
def run(self, edit): # Save original point, and convert to row col. Beautify # will change the number of characters in the file, so # need coordinates to know where to go back to. original_region = self.view.sel()[0] original_point = original_region.begin() orig_x, orig_y = self.view.rowcol(original_point) # Create points for a region that define beginning and end. begin = 0 end = self.view.size() - 1 # Slurp up entire buffer whole_region = sublime.Region(begin, end) buffer_str = self.view.substr(whole_region) lines = buffer_str.split('\n') # Get the scope for column 0 of each line. point = 0 scope_list = [] while not util.is_end_line(self, point): scope_list.append(self.view.scope_name(point)) point = util.move_down(self, point) scope_list.append(self.view.scope_name(point)) # Process each line # Left justify vhdl.left_justify(lines) # Because there are some really terrible typists out there # I end up having to MAKE SURE that symbols like : := <= and => # have spaces to either side of them. I'm just going to wholesale # replace them all with padded versions and then I remove extra space # later, which seems wasteful, but easier than trying to come up with # a ton of complicated patterns. vhdl.pad_vhdl_symbols(lines) # Remove extra blank space and convert tabs to spaces vhdl.remove_extra_space(lines) # Align print('vhdl-mode: Aligning symbols.') vhdl.align_block_on_re(lines=lines, regexp=r':(?!=)', scope_data=scope_list) vhdl.align_block_on_re( lines=lines, regexp=r':(?!=)\s?(?:in\b|out\b|inout\b|buffer\b)?\s*', padside='post', scope_data=scope_list) vhdl.align_block_on_re(lines=lines, regexp=r'<|:(?==)', scope_data=scope_list) vhdl.align_block_on_re(lines=lines, regexp=r'=>', scope_data=scope_list) # Indent! Get some settings first. use_spaces = util.get_vhdl_setting(self, 'translate_tabs_to_spaces') tab_size = util.get_vhdl_setting(self, 'tab_size') print('vhdl-mode: Indenting.') vhdl.indent_vhdl(lines=lines, initial=0, tab_size=tab_size, use_spaces=use_spaces) # Post indent alignment vhdl.align_block_on_re(lines=lines, regexp=r'\bwhen\b', scope_data=scope_list) # TBD -- There's a hook for more sophisticated handling of comment # lines which would be required for perfect alignment of inline comment # blocks, however it's not working, so leave that parameter as True for # now. vhdl.align_block_on_re(lines=lines, regexp=r'--', ignore_comment_lines=True, scope_data=scope_list) # Recombine into one big blobbed string. buffer_str = '\n'.join(lines) # Annnd if all went well, write it back into the buffer self.view.replace(edit, whole_region, buffer_str) # Put cursor back to original point (roughly) original_point = self.view.text_point(orig_x, orig_y) util.set_cursor(self, original_point)
def run(self, edit, whole_buffer=False): load_settings() if not check_binary(): return sublime.status_message("Clang format (style: "+ style + ")." ) # The below code has been taken and tweaked from llvm. encoding = st_encodings_trans[self.view.encoding()] if encoding is None: encoding = 'utf-8' # We use 'file' not 'File' when passing to the binary. # But all the other styles are in all caps. _style = style if style == "File": _style = "file" command = [] if style == "Custom": command = [binary, load_custom()] else: command = [binary, '-style', _style] regions = [] if whole_buffer: regions = [sublime.Region(0, self.view.size())] else: regions = self.view.sel() for region in regions: region_offset = region.begin() region_length = region.size() view = sublime.active_window().active_view() # If the command is run at the end of the line, # Run the command on the whole line. if view.classify(region_offset) & sublime.CLASS_LINE_END > 0: region = view.line(region_offset) region_offset = region.begin() region_lenth = region.size() command.extend(['-offset', str(region_offset), '-length', str(region_length)]) # We only set the offset once, otherwise CF complains. command.extend(['-assume-filename', str(self.view.file_name())] ) # TODO: Work out what this does. # command.extend(['-output-replacements-xml']) # Run CF, and set buf to its output. buf = self.view.substr(sublime.Region(0, self.view.size())) startupinfo = None if os_is_windows: startupinfo = subprocess.STARTUPINFO() startupinfo.dwFlags |= subprocess.STARTF_USESHOWWINDOW p = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE, stdin=subprocess.PIPE, startupinfo=startupinfo) output, error = p.communicate(buf.encode(encoding)) # Display any errors returned by clang-format using a message box, # instead of just printing them to the console. Also, we halt on all # errors: e.g. We don't just settle for using using a default style. if error: # We don't want to do anything by default. # If the error message tells us it is doing that, truncate it. default_message = ", using LLVM style" msg = error.decode("utf-8") if msg.strip().endswith(default_message): msg = msg[:-len(default_message)-1] sublime.error_message("Clang format: " + msg) # Don't do anything. return # If there were no errors, we replace the view with the outputted buf. self.view.replace( edit, sublime.Region(0, self.view.size()), output.decode(encoding))
def line_start(view, pos): line = view.line(pos) return sublime.Region(line.begin(), pos)
def run(self, edit): view = self.view sel = view.sel() sel0 = sel[0] if view.substr(sel0).strip().startswith(u'#'): sel0 = sublime.Region(sel0.begin(), sel0.begin()) if sel0.empty(): block = view.line(sel[0]) the_line = view.substr(block) # stripping preceding spaces strip_count = len(the_line) - len(the_line.lstrip()) block = sublime.Region(block.begin()+strip_count, block.end()) elif '\n' in view.substr(sel0): # multiline selection block = view.line(sel[0]) else: block = sel0 code = view.substr(block) code = clear_code(code) # result should be a unicode string def update_result(result, varnames=None): if not sel0.empty(): return if result is None: result = 'None' sel_line = view.line(sel0) line = view.substr(sel_line) if sel0.empty(): varnames = get_assigned_vars(line) else: varnames = None # to_underscore = lambda m: u'"{0}"'.format(u'_'*len(m.group(1))) # line_x = re.sub(ur'"(.*)"', to_underscore, line) # line_x = re.sub(ur"'(.*)'", to_underscore, line_x) # if u'#' in line_x: # i = line_x.rfind(u'#') # line = line[:i].rstrip() line = strip_line_comment(line) if not varnames: append = u' # -> ' + result else: varnames = u', '.join(varnames) append = u' # {0} -> {1}'.format(varnames, result) # selection points line += append a = sel_line.begin() + len(line) b = a - len(append) e = view.begin_edit() view.replace(e, view.line(sel0), line) set_selection(view, sublime.Region(a,b)) view.end_edit(e) def eval_code(): try: result = proxy.execute(code) except RemoteError: row_offset = view.rowcol(block.begin())[0] handle_remote_error(proxy, view, row_offset) return if sel0.empty(): if not code.startswith(( 'from ','import ', '%' # ipython magic commands )): update_result(result) elif '\n' not in code: # selection on single line, we replace it evaled edit = view.begin_edit() view.replace(edit, sel0, result) view.end_edit(edit) a = sel0.begin() b = a + len(result) sel.clear() sel.add(sublime.Region(a,b)) else: pass # do nothing on multiline selection def question_code(): try: result = proxy.question(code) except RemoteError: handle_remote_error(proxy) return window = view.window() panel = window.get_output_panel('ipython_object_info') window.run_command( "show_panel", {"panel": "output.ipython_object_info"} ) window.focus_view(panel) set_view_text(panel, result) panel.settings().set("syntax", "Packages/IPython/ipython_output.tmLanguage") panel.show(panel.size(), False) # scroll to bottom def foo(): view.show_at_center(view.sel()[0].begin()) sublime.set_timeout(foo, 10) if code.endswith(u'?') or code.startswith(u'?'): set_selection(view, block) sublime.set_timeout(question_code, 10) else: flash_select(view, block, callback=eval_code) return []
def on_query_completions(self, view, prefix, locations): items = None class_names = None screens = None for folder in self.instances: if view.file_name() is not None and view.file_name().startswith( os.path.abspath(folder) + os.sep): items = self.instances[folder]['items'] config_items = self.instances[folder]['config_items'] config = self.instances[folder]['config'] class_names = self.instances[folder]['class_names'] screens = self.instances[folder]['screens'] break if items is None: return [] isCss = view.match_selector(locations[0], 'source.css meta.property-list.css') isHtml = view.match_selector( locations[0], 'text.html string.quoted') or view.match_selector( locations[0], 'string.quoted.jsx') if isCss == False and isHtml == False: return [] LIMIT = 250 cursor = locations[0] # - len(prefix) - 1 start = max(0, cursor - LIMIT) line = view.substr(sublime.Region(start, cursor)) if isCss: match = re.match('.*?@apply ([^;}]*)$', line, re.DOTALL | re.IGNORECASE) elif isHtml: match = re.search('\\bclass(Name)?=["\']([^"\']*)$', line, re.IGNORECASE) if match is not None: parts = match.group(len(match.groups())).split(' ') string = parts[-1] if string.startswith('.'): string = string[1:] keys = re.findall('(.*?):', string) if keys is None: return items else: return self.get_items_from_class_names( self.safeget(class_names, keys), screens, keys) elif isCss: match = re.search('config\(["\']([^\'"]*)$', line, re.IGNORECASE) if match is None: return [] keys = match.group(1).split('.') if len(keys) == 1: return config_items else: subset = self.safeget(config, keys[:-1]) if subset is None or not isinstance(subset, dict): return [] return self.get_config_items(subset) else: return []
def run(self, edit, text=''): self.view.replace(edit, sublime.Region(0, self.view.size()), text)
def run(self, edit): view = self.view selection = view.sel() self.tab_size = int(view.settings().get("tab_size", 8)) # 展开配置 fa_alignment_chars = Settings().get("fa_alignment_chars", []) self.fa_alignment_chars = {} for v in fa_alignment_chars: for vv in v["prefixes"]: self.fa_alignment_chars[vv] = { "alignment": v["alignment"], "left_space": v["left_space"], "right_space": v["right_space"], } # 编译匹配正则 words = [] pattern = re.compile(r"\w") for v in self.fa_alignment_chars: if pattern.search(v): words.append('(?<=\W)' + v + '(?=\W)') else: words.append(v) self.alignment_chars_pattern = re.compile(r"({0})".format( "|".join(words))) # 当前行的缩进,内容 main_row = view.rowcol(view.lines(selection[0])[0].a)[0] main_indent_level, main_keys, main_string = self.get_line_feature( self.get_line_text(view, main_row)) if not main_keys: return # 相似行的数据 smiller_lines_data = {} line_count, _ = view.rowcol(view.size()) for direction in [-1, 1]: row_index = main_row + direction while row_index >= 0 and row_index < line_count + 1: indent, keys, string = self.get_line_feature( self.get_line_text(view, row_index)) if indent != main_indent_level: break if not keys or keys[0]["key"] != main_keys[0]["key"]: break smiller_lines_data[row_index] = { "text": string, "keyword": keys } row_index += direction if not smiller_lines_data: return else: smiller_lines_data[main_row] = { "text": main_string, "keyword": main_keys } # 删除已经对齐的keyword while True: is_same_pos = True for row_id in smiller_lines_data: row_data = smiller_lines_data[row_id] if row_data: if row_data["keyword"][0]["key"] != main_keys[0]["key"]: smiller_lines_data[row_id] = False elif row_data["keyword"][0]["pos"] != main_keys[0]["pos"]: is_same_pos = False if is_same_pos: for row_id in smiller_lines_data: row_data = smiller_lines_data[row_id] if row_data: del row_data["keyword"][0] if len(row_data["keyword"]) <= 0: smiller_lines_data[row_id] = False if not smiller_lines_data[main_row]: return else: break # 重新整理这些行 keyword = smiller_lines_data[main_row]["keyword"][0]["key"] align_keyword = self.get_key_word(keyword) row_region = [] new_smiller_lines_data = {} for direction in [-1, 1]: row_id = main_row + direction while True: if not row_id in smiller_lines_data: break row_data = smiller_lines_data[row_id] if row_data: new_smiller_lines_data[row_id] = { "text": row_data["text"], "pos": row_data["keyword"][0]["pos"] } else: break row_id += direction row_region.append(row_id + (-direction)) if len(new_smiller_lines_data) <= 0: return else: new_smiller_lines_data[main_row] = { "text": smiller_lines_data[main_row]["text"], "pos": smiller_lines_data[main_row]["keyword"][0]["pos"] } # 去除关键字周围的空白 for row_id in new_smiller_lines_data: text = new_smiller_lines_data[row_id]["text"] pos = new_smiller_lines_data[row_id]["pos"] region = [0, len(text)] index = 0 for ids in [ range(pos - len(keyword) - 1, 0, -1), range(pos, len(text)) ]: for i in ids: if text[i] != " ": region[index] = i break index = index + 1 text = text[:region[0] + 1] + align_keyword + text[region[1]:] pos = region[0] + len(align_keyword) + 1 new_smiller_lines_data[row_id] = {"text": text, "pos": pos} # 对齐行 pos_max = 0 for row_index in new_smiller_lines_data: pos_max = max(pos_max, new_smiller_lines_data[row_index]["pos"]) for row_index in new_smiller_lines_data: line = new_smiller_lines_data[row_index]["text"] pos = new_smiller_lines_data[row_index]["pos"] dis = pos_max - pos if dis != 0: if self.fa_alignment_chars[keyword]["alignment"] == "left": new_smiller_lines_data[row_index][ "text"] = line[:pos] + " " * (dis) + line[pos:] else: new_smiller_lines_data[row_index][ "text"] = line[:pos - len(align_keyword)] + " " * ( dis) + line[pos - len(align_keyword):] # 拼接行 aligned_lines = [""] for row in range(row_region[0], row_region[1]): aligned_lines.append(new_smiller_lines_data[row]["text"] + "\n") aligned_lines.append(new_smiller_lines_data[row_region[1]]["text"]) # 替换文本 view.replace( edit, sublime.Region( view.text_point(row_region[0], 0), view.line(view.text_point(row_region[1], 0)).b, ), self.get_indent_text(view, main_indent_level).join(aligned_lines))
def on_query_completions(self, view, prefix, locations): selector_scope = "source.scss - meta.selector.css, source.sass - meta.selector.css" prop_name_scope = "meta.property-name.css" prop_value_scope = "meta.property-value.css" loc = locations[0] is_scss = view.match_selector(loc, "source.scss") # When not inside Sass/SCSS, don’t trigger if not view.match_selector(loc, selector_scope): return [] if not self.props: self.props = parse_css_data() if is_scss: self.regex = re.compile(r"([a-zA-Z-]+):\s*$") else: self.regex = re.compile(r":([a-zA-Z-]+)\s*$") l = [] if (view.match_selector(loc, prop_value_scope) or # This will catch scenarios like: # - .foo {font-style: |} view.match_selector(loc - 1, prop_value_scope)): alt_loc = loc - len(prefix) line = view.substr( sublime.Region(view.line(alt_loc).begin(), alt_loc)) match = re.search(self.regex, line) if match: prop_name = match.group(1) if prop_name in self.props: values = self.props[prop_name] if is_scss: add_semi_colon = view.substr( sublime.Region(loc, loc + 1)) != ';' else: add_semi_colon = False for value in values: desc = value + "\t" + prop_name snippet = value if add_semi_colon: snippet += ";" if "$1" in snippet: desc = desc.replace("$1", "") if "${1:" in snippet: desc = desc.replace("${1:", "") if "${2:" in snippet: desc = desc.replace("${2:", "") if "}" in snippet: desc = desc.replace("}", "") l.append((desc, snippet)) return (l, sublime.INHIBIT_WORD_COMPLETIONS) return None else: if is_scss: add_colon = not view.match_selector(loc, prop_name_scope) else: add_colon = False for prop in self.props: if add_colon: l.append((prop + "\tproperty", prop + ": ")) else: l.append((prop + "\tproperty", prop)) return (l, sublime.INHIBIT_WORD_COMPLETIONS)
def on_modified_async_with_thread(self, recheck=True): self.modified = False view = self.view if not javascriptCompletions.get("enable_unused_variables_feature"): view.erase_status("unused_variables") view.erase_regions("unused_variables") return elif view.find_by_selector('source.js.embedded.html'): pass elif not Util.selection_in_js_scope(view): view.erase_status("unused_variables") view.erase_regions("unused_variables") return self.wait() deps_list = list() if view.find_by_selector("source.js.embedded.html") : deps_list = flow_parse_cli_dependencies(view, check_all_source_js_embedded=True) else : deps_list = [flow_parse_cli_dependencies(view)] flag = False for deps in deps_list: flow_cli = "flow" is_from_bin = True chdir = "" use_node = True bin_path = "" settings = get_project_settings() if settings and settings["project_settings"]["flow_cli_custom_path"]: flow_cli = os.path.basename(settings["project_settings"]["flow_cli_custom_path"]) bin_path = os.path.dirname(settings["project_settings"]["flow_cli_custom_path"]) is_from_bin = False chdir = settings["project_dir_name"] use_node = False node = NodeJS(check_local=True) result = node.execute_check_output( flow_cli, [ 'ast', '--from', 'sublime_text' ], is_from_bin=is_from_bin, use_fp_temp=True, fp_temp_contents=deps.contents, is_output_json=True, chdir=chdir, bin_path=bin_path, use_node=use_node ) repetitions = dict() if result[0]: if "body" in result[1]: body = result[1]["body"] items = Util.nested_lookup("type", ["VariableDeclarator", "FunctionDeclaration", "ClassDeclaration", "ImportDefaultSpecifier", "ImportNamespaceSpecifier", "ImportSpecifier", "ArrayPattern", "ObjectPattern"], body) for item in items: if "id" in item and isinstance(item["id"],dict) and "name" in item["id"] and item["id"]["type"] == "Identifier": item = item["id"] elif "local" in item and isinstance(item["local"],dict) and "name" in item["local"] and item["local"]["type"] == "Identifier": item = item["local"] elif "properties" in item: for prop in item["properties"]: if prop["type"] == "Property" and "key" in prop and isinstance(prop["key"],dict) and "name" in prop["key"] and prop["key"]["type"] == "Identifier": items += [prop["key"]] continue elif "elements" in item: for element in item["elements"]: if isinstance(element,dict) and "name" in element and element["type"] == "Identifier": items += [element] continue #else : # item = Util.nested_lookup("type", ["Identifier"], item)[0] variableName = "" try: variableName = item["name"] except (KeyError) as e: continue startRegion = view.text_point(int(item["loc"]["start"]["line"]) + deps.row_offset - 1, int(item["loc"]["start"]["column"])) endRegion = view.text_point(int(item["loc"]["end"]["line"]) + deps.row_offset - 1, int(item["loc"]["end"]["column"])) variableRegion = sublime.Region(startRegion, endRegion) scope = view.scope_name(variableRegion.begin()-1).strip() scope_splitted = scope.split(" ") if scope.endswith(" punctuation.accessor.js") or scope.endswith(" keyword.operator.accessor.js"): continue if view.substr(view.line(variableRegion)).strip().startswith("export") and not scope.startswith("source.js meta.export.js meta.block.js") and not scope.startswith("source.js meta.group.braces.curly.js") and len(scope_splitted) <= 4: continue repetitions[variableName] = [variableRegion] items = Util.nested_lookup("type", ["VariableDeclarator", "MemberExpression", "CallExpression", "BinaryExpression", "ExpressionStatement", "Property", "ArrayExpression", "ObjectPattern", "AssignmentExpression", "IfStatement", "ForStatement", "WhileStatement", "ForInStatement", "ForOfStatement", "LogicalExpression", "UpdateExpression", "ArrowFunctionExpression", "ConditionalExpression", "JSXIdentifier", "ExportDefaultDeclaration", "JSXExpressionContainer", "NewExpression", "ReturnStatement", "SpreadProperty", "TemplateLiteral"], body) for item in items: if "exportKind" in item and "declaration" in item and isinstance(item["declaration"],dict) and "name" in item["declaration"] and item["declaration"]["type"] == "Identifier": item = item["declaration"] elif "object" in item : if "property" in item and isinstance(item["property"],dict) and "name" in item["property"] and item["property"]["type"] == "Identifier": items += [item["property"]] if "object" in item and isinstance(item["object"],dict) and "name" in item["object"] and item["object"]["type"] == "Identifier": item = item["object"] else: continue elif "callee" in item : if "arguments" in item: for argument in item["arguments"]: if isinstance(argument,dict) and "name" in argument and argument["type"] == "Identifier": items += [argument] elif "expressions" in argument and argument["expressions"]: for expression in argument["expressions"]: if isinstance(expression,dict) and "name" in expression and expression["type"] == "Identifier": items += [expression] item = item["callee"] elif "expressions" in item and item["expressions"]: for expression in item["expressions"]: if isinstance(expression,dict) and "name" in expression and expression["type"] == "Identifier": items += [expression] continue elif "left" in item or "right" in item: if "left" in item and isinstance(item["left"],dict) and "name" in item["left"] and item["left"]["type"] == "Identifier": items += [item["left"]] if "right" in item and isinstance(item["right"],dict) and "name" in item["right"] and item["right"]["type"] == "Identifier": items += [item["right"]] elif "test" in item: if "consequent" in item and isinstance(item["consequent"],dict) and "name" in item["consequent"] and item["consequent"]["type"] == "Identifier": items += [item["consequent"]] if "alternate" in item and isinstance(item["alternate"],dict) and "name" in item["alternate"] and item["alternate"]["type"] == "Identifier": items += [item["alternate"]] if isinstance(item["test"],dict) and "name" in item["test"] and item["test"]["type"] == "Identifier": item = item["test"] else: continue elif "expression" in item and isinstance(item["expression"],dict) and "name" in item["expression"] and item["expression"]["type"] == "Identifier": item = item["expression"] elif "argument" in item and isinstance(item["argument"],dict) and "name" in item["argument"] and item["argument"]["type"] == "Identifier": item = item["argument"] elif "elements" in item : for element in item["elements"]: if isinstance(element,dict) and "name" in element and element["type"] == "Identifier": items += [element] continue elif "value" in item and isinstance(item["value"],dict) and "name" in item["value"] and item["value"]["type"] == "Identifier": item = item["value"] elif "init" in item and isinstance(item["init"],dict) and "name" in item["init"] and item["init"]["type"] == "Identifier": item = item["init"] elif "body" in item and isinstance(item["body"],dict) and "name" in item["body"] and item["body"]["type"] == "Identifier": item = item["body"] variableName = "" try: variableName = item["name"] except (KeyError) as e: continue startRegion = view.text_point(int(item["loc"]["start"]["line"]) + deps.row_offset - 1, int(item["loc"]["start"]["column"])) endRegion = view.text_point(int(item["loc"]["end"]["line"]) + deps.row_offset - 1, int(item["loc"]["end"]["column"])) variableRegion = sublime.Region(startRegion, endRegion) scope = view.scope_name(variableRegion.begin()-1).strip() if scope.endswith(" punctuation.accessor.js") or scope.endswith(" keyword.operator.accessor.js"): continue if variableName in repetitions and not variableRegion in repetitions[variableName]: repetitions[variableName] += [variableRegion] if not flag: self.unusedVariableRegions = [] flag = True errorRegions = view.get_regions("flow_error") for variableName in repetitions.keys(): count = len(repetitions[variableName]) if count == 1: intersects = False for errorRegion in errorRegions: if errorRegion.intersects(repetitions[variableName][0]): intersects = True break if not intersects: self.unusedVariableRegions += [repetitions[variableName][0]] if not self.modified : view.erase_regions("unused_variables") if self.unusedVariableRegions: view.add_regions("unused_variables", self.unusedVariableRegions, "string", "dot", sublime.DRAW_NO_FILL | sublime.DRAW_NO_OUTLINE | sublime.DRAW_SQUIGGLY_UNDERLINE) else: view.erase_status("unused_variables") elif (recheck) : sublime.set_timeout_async(lambda: self.on_modified_async_with_thread(recheck=False))
def quick_nav_done(self, view, index, regions, showOnly=False): region = sublime.Region(regions[index].b) if not showOnly: view.sel().add(region) view.show_at_center(region)
def on_query_completions(self, view, prefix, locations): # Only trigger within JS if not view.match_selector(locations[0], "source.js"): return [] qxApi = self._getApi() if not qxApi: return [] isEnvironmentGet = False isSingletonQuery = False isInstantiation = False queryClass = None # get the line text from the cursor back to last space result = [] #selection RegionSet sel = view.sel() region = sel[0] # line containing the selection line = view.line(region) start = line.a end = sel[0].a leftOfCursor = sublime.Region(start, end) lineTextNew = view.substr(leftOfCursor) temp = re.split("[^\w\.]", lineTextNew) lineText = temp[-1] if len(temp) > 2 and temp[-3].endswith(".getInstance"): queryClass = ".".join(temp[-3].split(".")[0:-1]) isSingletonQuery = True if len(temp) > 1 and temp[-2] and temp[-2][-3:] == "new": isInstantiation = True if not queryClass: queryClass = re.search("(.*?[A-Z]\w*)", lineText) if queryClass: queryClass = queryClass.group(1) if queryClass == "qx.core.Environment" and (prefix == "g" or prefix == "ge" or prefix == "get"): isEnvironmentGet = True for className in qxApi.getData(): if queryClass and queryClass == className: result.extend( qxApi.getClassCompletions(className, isEnvironmentGet, isSingletonQuery)) if className.startswith(lineText): result.extend( qxApi.getPartialCompletions(className, prefix, lineText, isInstantiation)) if len(result) > 0: result.sort() return (result, sublime.INHIBIT_WORD_COMPLETIONS | sublime.INHIBIT_EXPLICIT_COMPLETIONS) else: return result
def fetch_entire_file(self): self.entire_file = self.view.substr(sublime.Region( 0, self.view.size())) # load file only when needed
def target_region(self, target): if mode == 1: for cursor in self.view.sel(): return sublime.Region(cursor.begin(), target) return sublime.Region(target)
def get_sym(pos): """Returns the symbol from the current position in editor""" sym = self.view.substr(sublime.Region(pos, pos + 1)) return sym
def run(self, edit): # Assigning this to a string to keep command shorter later. template = "Packages/VHDL Mode/Snippets/vhdl-header.sublime-snippet" # Looking for a name, first the buffer name, then the file name, # then finally a default value. buffname = self.view.name() longname = self.view.file_name() if buffname: filename = buffname elif longname: # Convert Windows slashes to Unix slashes (if any) longname = re.sub(r'\\', '/', longname) namechunks = longname.split('/') filename = namechunks[len(namechunks) - 1] else: filename = '<filename>' # Get the other fields out of settings. linesize = util.get_vhdl_setting(self, 'vhdl-line-length') project = util.get_vhdl_setting(self, 'vhdl-project-name') author = util.get_vhdl_setting(self, 'vhdl-user') company = util.get_vhdl_setting(self, 'vhdl-company') platform = util.get_vhdl_setting(self, 'vhdl-platform') standard = util.get_vhdl_setting(self, 'vhdl-standard') mtime_prefix = util.get_vhdl_setting(self, 'vhdl-modified-time-string') use_copyright = util.get_vhdl_setting(self, 'vhdl-use-copyright-block') use_revision = util.get_vhdl_setting(self, 'vhdl-use-revision-block') copyright_list = util.get_vhdl_setting(self, 'vhdl-copyright-block') revision_list = util.get_vhdl_setting(self, 'vhdl-revision-block') # Set the string to dynamically replace the line field to the chosen # line length. linestr = '-' * linesize # Get the current time and create the modified time string. date = time.ctime(time.time()) year = time.strftime("%Y", time.localtime()) mod_time = mtime_prefix + date # Create the copyright block and revision block. Both need # prefixed newlines because they are optional and the # snippet field is at the end of the preceding line. if use_copyright: copyright = '\n'.join(copyright_list) copyright = re.sub(r'\${YEAR}', year, copyright) copyright = re.sub(r'\${COMPANY}', company, copyright) copyright = re.sub(r'\${LINE}', linestr, copyright) copyright = '\n' + copyright else: copyright = '' if use_revision: revision = '\n'.join(revision_list) revision = re.sub(r'\${LINE}', linestr, revision) revision = '\n' + revision else: revision = '' # Moving insertion point to the beginning of the file. bof = self.view.text_point(0, 0) self.view.sel().clear() self.view.sel().add(sublime.Region(bof)) self.view.show(bof) # Inserting template/snippet self.view.run_command( "insert_snippet", { "name": template, "PROJECT": project, "FILENAME": filename, "AUTHOR": author, "COMPANY": company, "CDATE": date, "MODIFIED_TIME_STRING": mod_time, "MDATE": date, "YEAR": year, "PLATFORM": platform, "STANDARD": standard, "COPYRIGHT_BLOCK": copyright, "REVISION_BLOCK": revision, "LINE": linestr }) print('vhdl-mode: Inserted header template.')
def _event_url(view, point): editor = 'sublime3' filename = quote(path_for_url(realpath(view.file_name()))) hash_ = _md5(view.substr(sublime.Region(0, view.size()))) return ('/api/buffer/{}/{}/{}/hover?cursor_runes={}' .format(editor, filename, hash_, point))
def selectRegions(self, regions): self.view.sel().clear() for regionTuple in regions: self.view.sel().add(sublime.Region(regionTuple[0], regionTuple[1]))
def _get_view_substr(view, start, end): return view.substr(sublime.Region(start, end))
def run(self, edit): dataRegion = sublime.Region(0, self.view.size()) data = TagRemoveAll(self.view.substr(dataRegion), self.view) self.view.replace(edit, dataRegion, data)
def find_cfc(cfml_view): if cfml_view.view.match_selector(cfml_view.position, "meta.function-call.method"): function_name, function_name_region, function_args_region = cfml_view.get_function_call( cfml_view.position) region = sublime.Region(function_name_region.begin(), function_args_region.end()) if cfml_view.view.substr(function_name_region.begin() - 1) == ".": dot_context = cfml_view.get_dot_context( function_name_region.begin() - 1) # check for known cfc name symbol_name, symbol_region = cfcs.search_dot_context_for_cfc( cfml_view.project_name, dot_context) # also check for getter being used to access cfc if not symbol_name and len(dot_context): symbol = dot_context[-1] if (symbol.is_function and symbol.name.startswith("get") and cfcs.has_cfc( cfml_view.project_name, symbol.name[3:])): symbol_name = symbol.name[3:] symbol_region = symbol.name_region if symbol_name: cfc_info = cfcs.get_cfc_info(cfml_view.project_name, symbol_name) metadata = cfcs.get_cfc_metadata(cfml_view.project_name, symbol_name) if function_name in metadata["functions"]: return cfc_info, metadata, function_name, [ region, symbol_region ] # check for cfc cfc_name = None check_position = cfml_view.position if cfml_view.view.match_selector(cfml_view.position, "punctuation.accessor.cfml"): check_position = cfml_view.position + 1 if cfml_view.view.match_selector(check_position, "variable.other, meta.property.cfml"): # we need to find the whole dot context now in order to search for variable names that contain dots dot_context = get_dot_context(cfml_view, check_position) cfc_name, cfc_name_region = cfcs.search_dot_context_for_cfc( cfml_view.project_name, dot_context) if cfc_name and not cfc_name_region.contains(cfml_view.position): cfc_name = None elif cfml_view.view.match_selector(cfml_view.position, "meta.tag.property.name.cfml"): cfc_name_region = cfml_view.view.word(cfml_view.position) cfc_name = cfml_view.view.substr(cfc_name_region).lower() elif cfml_view.view.match_selector( cfml_view.position, "meta.function-call.cfml variable.function.cfml"): cfc_name_region = cfml_view.view.word(cfml_view.position) var_name = cfml_view.view.substr(cfc_name_region).lower() if var_name.startswith("get"): cfc_name = var_name[3:] if cfc_name and cfcs.has_cfc(cfml_view.project_name, cfc_name): metadata = cfcs.get_cfc_metadata(cfml_view.project_name, cfc_name) cfc_info = cfcs.get_cfc_info(cfml_view.project_name, cfc_name) return cfc_info, metadata, None, [cfc_name_region] return None, None, None, None
def on_post_save_async(self, view): file_name = view.file_name() if file_name is None: return project_path = find_project_dir(view) errors = rebuild(project_path, file_name) regions_and_errors = [] regions = [] error_without_position = [] for error in errors: # it's possible to have error with no position like this # # {'suggestion': None, # 'position': None, # 'errorCode': 'UnusableDeclaration', # 'moduleName': 'Localization.Smolder', # 'errorLink': 'https://github.com/purescript/documentation/blob/master/errors/UnusableDeclaration.md', # 'message': " The declaration withEvent is unusable.\n This happens when a constraint couldn't possibly have enough information to work out which instance is required.\n", # 'filename': None # } if error['position'] is None: print(error) error_without_position.append(error) continue start = view.text_point(error['position']['startLine'] - 1, error['position']['startColumn'] - 1) end = view.text_point(error['position']['endLine'] - 1, error['position']['endColumn'] - 1) region = sublime.Region(start, end + 1) if region.size() <= 1: # try to make the region bigger because # zero width region is invisible region = view.word(start) regions_and_errors.append((region, error)) regions.append(region) # The actual "hover -> show popup" effect is handled in text_hints.py error_manager.set_errors(file_name, regions_and_errors) view.add_regions( "errors", regions, "invalid.illegal", # This thing does not exist in doc, but it exists in the default theme. # It might break some days "warning", sublime.DRAW_NO_FILL | sublime.DRAW_NO_OUTLINE | sublime.DRAW_SQUIGGLY_UNDERLINE) ps = sublime.PhantomSet(view) ps.update([ sublime.Phantom( view.sel()[0], "".join([ '<p>%s</p>' % s.replace(' ', ' ') for s in error['message'].split('\n') ]), sublime.LAYOUT_BLOCK) for error in error_without_position ]) self.delete_phantom_in_view(view) self.phantom_sets.append((view, ps))
def on_query_completions(self, view, prefix, locations): if utils.props.get_view_setting(view, 'is_here') and not utils.props.get_setting('offline_mode'): view = sublime.active_window().active_view() # internal links completions cursor_position = locations[0] # view.sel()[0].begin() line_region = view.line(view.sel()[0]) line_before_position = view.substr(sublime.Region(line_region.a, cursor_position)) internal_link = '' if line_before_position.rfind('[[') > line_before_position.rfind(']]'): internal_link = line_before_position[line_before_position.rfind('[[') + 2:] if utils.api.INTERNAL_LINK_SPLITTER in internal_link: # cursor at custom url text zone.. return [] completions = [] if internal_link: word_cursor_min_len = utils.props.get_setting('page_prefix_min_length', 3) ns_text = None ns_text_number = None if utils.api.NAMESPACE_SPLITTER in internal_link: ns_text, internal_link = internal_link.split(utils.api.NAMESPACE_SPLITTER) if len(internal_link) >= word_cursor_min_len: namespaces_search = utils.get_search_ns() if not namespaces_search: return completions if ns_text: ns_text_number = utils.api.call('get_namespace_number', name=ns_text) if internal_link.startswith('/'): internal_link = '{}{}'.format(utils.get_title(), internal_link) # TODO: recheck completions pages = [] for ns in namespaces_search: if not ns_text or ns_text_number and int(ns_text_number) == int(ns): pages = utils.api.call('get_pages', prefix=internal_link, namespace=ns) for p in pages: # name - full page name with namespace # page_title - title of the page wo namespace # For (Main) namespace, shows [page_title (Main)], makes [[page_title]] # For Image, Category namespaces, shows [page_title namespace], makes [[name]] # For other namespace, shows [page_title namespace], makes [[name|page_title]] if int(ns): ns_name = utils.api.page_attr(p, 'namespace_name') page_name = utils.api.page_attr(p, 'name') if not utils.api.is_equal_ns(ns_text, ns_name) else utils.api.page_attr(p, 'page_title') if int(ns) in (utils.api.CATEGORY_NAMESPACE, utils.api.IMAGE_NAMESPACE): page_insert = page_name else: page_insert = '{}|{}'.format(page_name, utils.api.page_attr(p, 'page_title')) else: ns_name = '(Main)' page_insert = utils.api.page_attr(p, 'page_title') page_show = '{}\t{}'.format(utils.api.page_attr(p, 'page_title'), ns_name) completions.append((page_show, page_insert)) return completions return []
def CombineContent(self, view, lines): return view.substr( sublime.Region(lines[0].begin(), lines[len(lines) - 1].end()))
def run(self, edit, regions): for a, b in reversed(regions): self.view.erase(edit, sublime.Region(int(a), int(b)))