def get_replacement_pattern(self, command): buffer = self.document.get_buffer() insert_iter = buffer.get_iter_at_mark(buffer.get_insert()) line_part = self.document.get_line(insert_iter.get_line())[insert_iter.get_line_offset():] command_bracket_count = self.get_command_bracket_count(command) matches_group = list() line_regex = ServiceLocator.get_regex_object(r'((?:\\){0,1}\w*(?:\*){0,1})(?:\{([^\{\[\|\(]+)\}|\[([^\{\[\|\(\\]+)\]|\|([^\{\[\|\(\\]+)\||\(([^\{\[\|\(\\]+)\))*') line_match = line_regex.match(line_part) if line_match == None: return None if not line_regex.fullmatch(command): return None line_part = line_part[:line_match.end()] line_regex = ServiceLocator.get_regex_object(r'(\w*)|\{([^\{\[\|\(]+)\}|\[([^\{\[\|\(\\]+)\]|\|([^\{\[\|\(\\]+)\||\(([^\{\[\|\(\\]+)\)') bracket_count = 0 command_regex_pattern = r'(\w*(?:\*){0,1})' for match in line_regex.finditer(line_part): if match.group(0).startswith('{') and bracket_count < command_bracket_count: command_regex_pattern += r'\{([^\{\[\|\(]+)\}' bracket_count += 1 if match.group(0).startswith('[') and bracket_count < command_bracket_count: command_regex_pattern += r'\[([^\{\[\|\(]+)\]' bracket_count += 1 if match.group(0).startswith('|') and bracket_count < command_bracket_count: command_regex_pattern += r'\|([^\{\[\|\(]+)\|' bracket_count += 1 if match.group(0).startswith('(') and bracket_count < command_bracket_count: command_regex_pattern += r'\(([^\{\[\|\(]+)\)' bracket_count += 1 line_match = ServiceLocator.get_regex_object(command_regex_pattern).match(line_part) if line_match == None: return None return (line_match, command_regex_pattern)
def insert_final_replace(self, command, replacement_pattern): match_object = replacement_pattern[0] text = '' command_regex = ServiceLocator.get_regex_object(r'(?:^\\(\w+(?:\*){0,1}))|\{([^\{\[\|\(]+)\}|\[([^\{\[\|\(]+)\]|\|([^\{\[\|\(]+)\||\(([^\{\[\|\(]+)\)') comma_regex = ServiceLocator.get_regex_object(r'•(\,•)*') count = 1 for match in command_regex.finditer(command): if match.group(0).startswith('\\'): text += '\\' + match.group(1) else: if match.group(0).startswith('{'): inner_text = match.group(2) elif match.group(0).startswith('['): inner_text = match.group(3) elif match.group(0).startswith('|'): inner_text = match.group(4) elif match.group(0).startswith('('): inner_text = match.group(5) if comma_regex.fullmatch(inner_text) and len(match_object.groups()) >= count: for prev_text in match_object.group(count).split(','): inner_text = inner_text.replace('•', prev_text, 1) if match.group(0).startswith('{'): text += '{' + inner_text + '}' if match.group(0).startswith('['): text += '[' + inner_text + ']' if match.group(0).startswith('|'): text += '|' + inner_text + '|' if match.group(0).startswith('('): text += '(' + inner_text + ')' count += 1 current_word = self.document.get_latex_command_at_cursor() offset = self.document.get_cursor_offset() - len(current_word) length = len(current_word) + match_object.end() self.document.replace_range(offset, length, text, indent_lines=True, select_dot=True)
def __init__(self): self.doc_regex = ServiceLocator.get_regex_object(r'( *\((.*\.tex))') self.item_regex = ServiceLocator.get_regex_object(r'((?<!.) *' + r'(?:Overfull \\hbox|Underfull \\hbox|' + r'No file .*\.|File .* does not exist\.|! I can' + "'" + r't find file\.|! File .* not found\.|' + r'(?:LaTeX|pdfTeX|LuaTeX|Package|Class) .*Warning.*:|LaTeX Font Warning:|' + r'! Undefined control sequence\.|! Missing (?:.*) inserted.|! Package .* Error:|! (?:LaTeX|LuaTeX) Error:).*\n)') self.badbox_line_number_regex = ServiceLocator.get_regex_object(r'lines ([0-9]+)--([0-9]+)') self.other_line_number_regex = ServiceLocator.get_regex_object(r'(l\.| input line \n| input line )([0-9]+)( |\.)')
def __init__(self): self.doc_regex = ServiceLocator.get_regex_object(r'(\(([^\(\)]*\.(?:tex|gls)))') self.item_regex = ServiceLocator.get_regex_object(r'((?<!.) *' + r'(?:Overfull \\hbox|Underfull \\hbox|' + r'No file .*\.|File .* does not exist\.|' + r'(?:LaTeX|pdfTeX|LuaTeX|Package|Class) .*Warning.*:|LaTeX Font Warning:|' + r'!(?: )(?:LaTeX|pdfTeX|LuaTeX|Package|Class) error|' + r'! ).*\n)') self.badbox_line_number_regex = ServiceLocator.get_regex_object(r'lines ([0-9]+)--([0-9]+)') self.other_line_number_regex = ServiceLocator.get_regex_object(r'(l\.| input line \n| input line )([0-9]+)( |\.)')
def __init__(self): self.config_folder = ServiceLocator.get_config_folder() self.forward_synctex_regex = ServiceLocator.get_regex_object( r'\nOutput:.*\nPage:([0-9]+)\nx:.*\ny:.*\nh:((?:[0-9]|\.)+)\nv:((?:[0-9]|\.)+)\nW:((?:[0-9]|\.)+)\nH:((?:[0-9]|\.)+)\nbefore:.*\noffset:.*\nmiddle:.*\nafter:.*' ) self.process = None
def __init__(self): builder_build.BuilderBuild.__init__(self) self.bibtex_log_item_regex = ServiceLocator.get_regex_object( r'Warning--(.*)\n--line ([0-9]+) of file (.*)|I couldn' + "'" + r't open style file (.*)\n---line ([0-9]+) of file (.*)|Warning--(.*)' )
def on_text_inserted(self, buffer, location_iter, text, text_length): text_length = len(text) offset = location_iter.get_offset() new_line_count = text.count('\n') line_start = location_iter.get_line() char_count = buffer.get_char_count() before_iter = buffer.get_iter_at_line(line_start) after_iter = buffer.get_iter_at_line(line_start + 1) if not after_iter.get_offset() == char_count: after_iter.backward_char() text_before = buffer.get_text(before_iter, location_iter, True) offset_line_start = before_iter.get_offset() text_after = buffer.get_text(location_iter, after_iter, True) offset_line_end = offset + len(text_after) self.text_length = char_count + text_length text_parse = text_before + text + text_after block_symbol_matches = {'begin_or_end': list(), 'others': list()} for match in self.block_symbol_matches['begin_or_end']: if match[1] < line_start: block_symbol_matches['begin_or_end'].append(match) for match in self.block_symbol_matches['others']: if match[1] < line_start: block_symbol_matches['others'].append(match) other_symbols = list() for match in self.other_symbols: if match[1] < offset_line_start: other_symbols.append((match[0], match[1])) additional_matches = self.parse_for_blocks(text_parse, line_start, offset_line_start) block_symbol_matches['begin_or_end'] += additional_matches[ 'begin_or_end'] block_symbol_matches['others'] += additional_matches['others'] for match in ServiceLocator.get_regex_object( r'\\(label|include|input|bibliography|addbibresource)\{((?:\s|\w|\:|\.|,|\/|\\)*)\}|\\(usepackage)(?:\[[^\{\[]*\]){0,1}\{((?:\s|\w|\:|,)*)\}|\\(bibitem)(?:\[.*\]){0,1}\{((?:\s|\w|\:)*)\}' ).finditer(text_parse): other_symbols.append((match, match.start() + offset_line_start)) for match in self.block_symbol_matches['begin_or_end']: if match[1] > line_start: block_symbol_matches['begin_or_end'].append( (match[0], match[1] + new_line_count, match[2] + text_length)) for match in self.block_symbol_matches['others']: if match[1] > line_start: block_symbol_matches['others'].append( (match[0], match[1] + new_line_count, match[2] + text_length)) for match in self.other_symbols: if match[1] > offset_line_end: other_symbols.append((match[0], match[1] + text_length)) self.block_symbol_matches = block_symbol_matches self.number_of_lines = self.number_of_lines + new_line_count self.parse_blocks() self.other_symbols = other_symbols self.parse_symbols()
def get_synctex_word_bounds(self, text, word, context): if not word: return None word = word.split(' ') if len(word) > 2: word = word[:2] word = ' '.join(word) regex_pattern = re.escape(word) for c in regex_pattern: if ord(c) > 127: regex_pattern = regex_pattern.replace(c, '(?:\w)') matches = list() top_score = 0.1 regex = ServiceLocator.get_regex_object(r'(\W{0,1})' + regex_pattern.replace('\x1b', r'(?:\w{2,3})').replace('\x1c', r'(?:\w{2})').replace('\x1d', r'(?:\w{2,3})').replace('\-', r'(?:-{0,1})') + r'(\W{0,1})') for match in regex.finditer(text): offset1 = context.find(word) offset2 = len(context) - offset1 - len(word) match_text = text[max(match.start() - max(offset1, 0), 0):min(match.end() + max(offset2, 0), len(text))] score = difflib.SequenceMatcher(None, match_text, context).ratio() if bool(match.group(1)) or bool(match.group(2)): if score > top_score + 0.1: top_score = score matches = [[match.start() + len(match.group(1)), match.end() - len(match.group(2))]] elif score > top_score - 0.1: matches.append([match.start() + len(match.group(1)), match.end() - len(match.group(2))]) if len(matches) > 0: return matches else: return None
def parse_symbols(self, text): labels = set() included_latex_files = set() bibliographies = set() bibitems = set() packages = set() packages_detailed = dict() for match in ServiceLocator.get_regex_object(r'\\(label|include|input|bibliography|addbibresource)\{((?:\s|\w|\:|\.|,)*)\}|\\(usepackage)(?:\[[^\{\[]*\]){0,1}\{((?:\s|\w|\:|,)*)\}|\\(bibitem)(?:\[.*\]){0,1}\{((?:\s|\w|\:)*)\}').finditer(text): if match.group(1) == 'label': labels = labels | {match.group(2).strip()} elif match.group(1) == 'include' or match.group(1) == 'input': filename = os.path.normpath(os.path.join(self.dirname, match.group(2).strip())) if not filename.endswith('.tex'): filename += '.tex' included_latex_files = included_latex_files | {filename} elif match.group(1) == 'bibliography': bibfiles = match.group(2).strip().split(',') for entry in bibfiles: bibliographies = bibliographies | {os.path.normpath(os.path.join(self.dirname, entry.strip() + '.bib'))} elif match.group(1) == 'addbibresource': bibfiles = match.group(2).strip().split(',') for entry in bibfiles: bibliographies = bibliographies | {os.path.normpath(os.path.join(self.dirname, entry.strip()))} elif match.group(3) == 'usepackage': packages = packages | {match.group(4).strip()} packages_detailed[match.group(4).strip()] = match elif match.group(5) == 'bibitem': bibitems = bibitems | {match.group(6).strip()} self.document.symbols['labels'] = labels self.document.symbols['included_latex_files'] = included_latex_files self.document.symbols['bibliographies'] = bibliographies self.document.symbols['bibitems'] = bibitems self.document.symbols['packages'] = packages self.document.symbols['packages_detailed'] = packages_detailed
def __init__(self): self.config_folder = ServiceLocator.get_config_folder() self.backward_synctex_regex = ServiceLocator.get_regex_object( r'\nOutput:.*\nInput:(.*\.tex)\nLine:([0-9]+)\nColumn:(?:[0-9]|-)+\nOffset:(?:[0-9]|-)+\nContext:.*\n' ) self.process = None
def insert_begin_end_replace(self, start_iter_begin, insert_iter, replace_previous_command_data): text = replace_previous_command_data[1] match_object = replace_previous_command_data[0] self.document.get_buffer().begin_user_action() end_iter_begin = insert_iter.copy() end_iter_begin.forward_chars(match_object.end()) start_iter_offset = start_iter_begin.get_offset() self.document.get_buffer().replace_range_no_user_action(start_iter_begin, end_iter_begin, text, indent_lines=False, select_dot=True) end_iter_offset = start_iter_offset + len(text) document_text = self.document.get_text_after_offset(end_iter_offset) environment_name = ServiceLocator.get_regex_object(r'(\w*(?:\*){0,1})\{([^\{\[\|\(]+)\}').match(match_object.group(0)).group(2) end_match_object = self.get_end_match_object(document_text, environment_name) if end_match_object != None: start_iter_begin = self.document.get_buffer().get_iter_at_offset(end_iter_offset) start_iter_end = start_iter_begin.copy() start_iter_end.forward_chars(end_match_object.start()) end_iter_end = start_iter_begin.copy() end_iter_end.forward_chars(end_match_object.end()) end_command = text.replace('\\begin', '\\end') end_command_bracket_position = end_command.find('}') if end_command_bracket_position: end_command = end_command[:end_command_bracket_position + 1] self.document.get_buffer().replace_range_no_user_action(start_iter_end, end_iter_end, end_command, indent_lines=False, select_dot=False) self.document.get_buffer().end_user_action()
def get_command_bracket_count(self, command): count = 0 line_regex = ServiceLocator.get_regex_object( r'\{([^\{\[\|\(]+)\}|\[([^\{\[\|\(]+)\]|\|([^\{\[\|\(]+)\||\(([^\{\[\|\(]+)\)' ) for match in line_regex.finditer(command): count += 1 return count
def cursor_at_word_end(self): buffer = self.document.get_buffer() text_iter = buffer.get_iter_at_mark(buffer.get_insert()) current_word = self.get_current_word(text_iter) if ServiceLocator.get_regex_object(r'\\(\w*(?:\*){0,1})').fullmatch( current_word): return text_iter.ends_word() return False
def parse_blocks(self, text): text_length = len(text) matches = {'begin_or_end': list(), 'others': list()} for match in ServiceLocator.get_regex_object(r'\\(begin|end)\{((?:\w|•)+(?:\*){0,1})\}|\\(part|chapter|section|subsection|subsubsection)(?:\*){0,1}\{').finditer(text): if match.group(1) != None: matches['begin_or_end'].append(match) else: matches['others'].append(match) blocks = dict() end_document_offset = None for match in matches['begin_or_end']: if match.group(1) == 'begin': try: blocks[match.group(2)].append([match.start(), None]) except KeyError: blocks[match.group(2)] = [[match.start(), None]] else: if match.group(2).strip() == 'document': end_document_offset = match.start() try: begins = blocks[match.group(2)] except KeyError: pass else: for block in reversed(begins): if block[1] == None: block[1] = match.start() break blocks_list = list() for single_list in blocks.values(): blocks_list += single_list blocks = [list(), list(), list(), list(), list()] relevant_following_blocks = [list(), list(), list(), list(), list()] levels = {'part': 0, 'chapter': 1, 'section': 2, 'subsection': 3, 'subsubsection': 4} for match in reversed(matches['others']): level = levels[match.group(3)] block = [match.start(), None] if len(relevant_following_blocks[level]) >= 1: # - 1 to go one line up block[1] = relevant_following_blocks[level][-1][0] - 1 else: if end_document_offset != None and block[0] < end_document_offset: # - 1 to go one line up block[1] = end_document_offset - 1 else: block[1] = text_length blocks[level].append(block) for i in range(level, 5): relevant_following_blocks[i].append(block) for single_list in blocks: blocks_list += single_list self.document.symbols['blocks'] = sorted(blocks_list, key=lambda block: block[0])
def get_begin_end_offset_word_len(self): line = self.content.get_line_at_cursor() offset = self.content.get_cursor_line_offset() line = line[:offset] + '%•%' + line[offset:] match = ServiceLocator.get_regex_object(r'.*\\(begin|end)\{((?:[^\{\[\(])*)%•%((?:[^\{\[\(])*)\}.*').match(line) if match: word_offset = self.content.get_cursor_offset() - len(match.group(2)) word_len = len(match.group(2)) + len(match.group(3)) return (word_offset, word_len)
def insert_begin_end_check_replace(self, insert_iter, text): line_part = self.document.get_line(insert_iter.get_line())[insert_iter.get_line_offset():] line_regex = ServiceLocator.get_regex_object(r'(\w*(?:\*){0,1})\{([^\{\[\|\(]+)\}') line_match = line_regex.match(line_part) if line_match: document_text = self.document.get_text_after_offset(insert_iter.get_offset() + 1) if self.get_end_match_object(document_text, line_match.group(2)): return (line_match, text) return (None, text)
def cursor_ends_completable_environment_name(self): line = self.content.get_line_at_cursor() offset = self.content.get_cursor_line_offset() line = line[:offset] + '%•%' + line[offset:] match_begin_end = ServiceLocator.get_regex_object(r'.*\\(begin|end)\{((?:[^\{\[\(])*)%•%((?:[^\{\[\(])*)\}.*').match(line) items = self.provider.get_begin_end_items(match_begin_end.group(2)) if len(items) <= 0: return False if items[0]['command'] == match_begin_end.group(2): return False return True
def insert_normal_command(self, command): text = command['command'] replacement_pattern = self.get_replacement_pattern(text) if replacement_pattern != None: command_regex = ServiceLocator.get_regex_object( r'.*' + replacement_pattern[1]) if command_regex.match(text): self.insert_final_replace(text, replacement_pattern) return self.autocomplete.document.replace_latex_command_at_cursor( text, command['dotlabels'], is_full_command=True)
def insert_normal_command(self, text): buffer = self.document.get_buffer() insert_iter = buffer.get_iter_at_mark(buffer.get_insert()) replacement_pattern = self.get_replacement_pattern(insert_iter, text) if replacement_pattern != None: command_regex = ServiceLocator.get_regex_object( r'.*' + replacement_pattern[1]) if command_regex.match(text): self.insert_final_replace(insert_iter, text, replacement_pattern) return self.replace_current_command(text)
def get_end_match_object(self, text, environment_name): count = 0 end_match_object = None for match in ServiceLocator.get_regex_object(r'\\(begin|end)\{' + environment_name + r'\}').finditer(text): if match.group(1) == 'begin': count += 1 elif match.group(1) == 'end': if count == 0: end_match_object = match break else: count -= 1 return end_match_object
def parse_symbols(self, text): with self.parse_jobs_lock: self.parse_symbols_job_running = True bibitems = set() for match in ServiceLocator.get_regex_object( r'@(\w+)\{(\w+)').finditer(text): bibitems = bibitems | {match.group(2).strip()} with self.symbols_lock: self.symbols['bibitems'] = bibitems self.labels_changed = True with self.parse_jobs_lock: self.parse_symbols_job_running = False
def parse_for_blocks(self, text, line_start, offset_line_start): block_symbol_matches = {'begin_or_end': list(), 'others': list()} counter = line_start for match in ServiceLocator.get_regex_object( r'\n|\\(begin|end)\{((?:\w|•|\*)+)\}|\\(part|chapter|section|subsection|subsubsection)(?:\*){0,1}\{' ).finditer(text): if match.group(1) != None: block_symbol_matches['begin_or_end'].append( (match, counter, match.start() + offset_line_start)) elif match.group(3) != None: block_symbol_matches['others'].append( (match, counter, match.start() + offset_line_start)) if match.group(0) == '\n': counter += 1 return block_symbol_matches
def update(self, can_activate=False): if self.is_active(): self.session.update(can_activate) if not self.is_active(): line = self.document.get_line_at_cursor() offset = self.document.get_cursor_line_offset() line = line[:offset] + '%•%' + line[offset:] match = ServiceLocator.get_regex_object(r'.*\\(begin|end)\{((?:[^\{\[\(])*)%•%((?:[^\{\[\(])*)\}.*').match(line) if match: word_offset = self.document.get_cursor_offset() - len(match.group(2)) word_len = len(match.group(2)) + len(match.group(3)) self.start_session(session_begin_end.SessionBeginEnd(self, word_offset, word_len)) self.session.update(can_activate) return current_word = self.document.get_latex_command_at_cursor() if can_activate and self.provider.get_items(current_word): self.start_session(session_default.SessionDefault(self))
def update(self, can_activate=False): line = self.autocomplete.document.get_line_at_cursor() offset = self.autocomplete.document.get_cursor_line_offset() line = line[:offset] + '%•%' + line[offset:] match = ServiceLocator.get_regex_object( r'.*\\(begin|end)\{((?:[^\{\[\(])*)%•%((?:[^\{\[\(])*)\}.*').match( line) if not match: self.cancel() return if self.autocomplete.matching_mark_start.get_deleted( ) or self.autocomplete.matching_mark_end.get_deleted(): self.has_matching_block = False cursor_offset = self.autocomplete.document.get_cursor_offset() start_offset = self.source_buffer.get_iter_at_mark( self.autocomplete.mark_start).get_offset() end_offset = self.source_buffer.get_iter_at_mark( self.autocomplete.mark_end).get_offset() if cursor_offset < start_offset: self.cancel() return if cursor_offset > end_offset: self.cancel() return self.update_current_word() self.autocomplete.items = self.get_items() if len(self.autocomplete.items) == 1 and len(self.current_word) == len( self.autocomplete.items[0]['command']): self.will_show = False else: items_cond = len(self.autocomplete.items) > 0 and len( self.current_word) != len( self.autocomplete.items[0]['command']) self.will_show = self.will_show or (can_activate and items_cond) self.autocomplete.populate(len(self.current_word)) self.autocomplete.update_visibility()
def parse_symbols(self, text): bibitems = set() for match in ServiceLocator.get_regex_object(r'@(\w+)\{(\w+)').finditer(text): bibitems = bibitems | {match.group(2).strip()} self.document.symbols['bibitems'] = bibitems
def cursor_inside_begin_or_end(self): line = self.content.get_line_at_cursor() offset = self.content.get_cursor_line_offset() line = line[:offset] + '%•%' + line[offset:] match_begin_end = ServiceLocator.get_regex_object(r'.*\\(begin|end)\{((?:[^\{\[\(])*)%•%((?:[^\{\[\(])*)\}.*').match(line) return match_begin_end
def on_text_deleted(self, parameter): buffer, start_iter, end_iter = parameter offset_start = start_iter.get_offset() offset_end = end_iter.get_offset() line_start = start_iter.get_line() line_end = end_iter.get_line() char_count = buffer.get_char_count() before_iter = buffer.get_iter_at_line(line_start) after_iter = buffer.get_iter_at_line(line_end + 1) if not after_iter.get_offset() == char_count: after_iter.backward_char() text_length = offset_end - offset_start text = buffer.get_text(start_iter, end_iter, True) deleted_line_count = text.count('\n') text_before = buffer.get_text(before_iter, start_iter, True) text_after = buffer.get_text(end_iter, after_iter, True) offset_line_start = before_iter.get_offset() self.text_length = char_count - offset_end + offset_start block_symbol_matches = {'begin_or_end': list(), 'others': list()} for match in self.block_symbol_matches['begin_or_end']: if match[1] < line_start: block_symbol_matches['begin_or_end'].append(match) for match in self.block_symbol_matches['others']: if match[1] < line_start: block_symbol_matches['others'].append(match) other_symbols = list() for match in self.other_symbols: if match[1] < offset_line_start: other_symbols.append((match[0], match[1])) offset_line_end = offset_end + len(text_after) text = text_before + text_after additional_matches = self.parse_for_blocks(text, line_start, offset_line_start) block_symbol_matches['begin_or_end'] += additional_matches[ 'begin_or_end'] block_symbol_matches['others'] += additional_matches['others'] for match in ServiceLocator.get_regex_object( r'\\(label|include|input|bibliography|addbibresource)\{((?:\s|\w|\:|\.|,)*)\}|\\(usepackage)(?:\[[^\{\[]*\]){0,1}\{((?:\s|\w|\:|,)*)\}|\\(bibitem)(?:\[.*\]){0,1}\{((?:\s|\w|\:)*)\}' ).finditer(text): other_symbols.append((match, match.start() + offset_line_start)) for match in self.block_symbol_matches['begin_or_end']: if match[1] > line_end: block_symbol_matches['begin_or_end'].append( (match[0], match[1] - deleted_line_count, match[2] - text_length)) for match in self.block_symbol_matches['others']: if match[1] > line_end: block_symbol_matches['others'].append( (match[0], match[1] - deleted_line_count, match[2] - text_length)) for match in self.other_symbols: if match[1] > offset_line_end: other_symbols.append((match[0], match[1] - text_length)) self.block_symbol_matches = block_symbol_matches self.number_of_lines = self.number_of_lines - deleted_line_count self.parse_blocks() self.other_symbols = other_symbols self.parse_symbols()
def cursor_inside_latex_command_or_at_end(self): current_word = self.get_latex_command_at_cursor() if ServiceLocator.get_regex_object(r'\\(\w*(?:\*){0,1})').fullmatch( current_word): return True return False
def cursor_at_latex_command_end(self): current_word = self.get_latex_command_at_cursor() if ServiceLocator.get_regex_object(r'\\(\w*(?:\*){0,1})').fullmatch( current_word): return self.get_buffer().cursor_ends_word() return False