def f(view, s): # If: # * motion hasn't completed # * we are at EOL # * we are not on an empty line # ... skip the new line character. Othwerwise, S3 will count it as a WORD. Note that # empty lines do count as WORDs. if (not is_last_iteration and view.substr(s.b) == '\n' and not view.line(s.b).empty()): return sublime.Region(s.a, s.b + 1) # On the last iteration, encompass the whole line if we're at EOL and .a and .b are # on different lines. if is_last_iteration: if (view.line(s.a) != view.line(s.b) and view.substr(s.b) == '\n' and not view.line(s.b - 1).empty()): return sublime.Region(s.a, s.b + 1) # On the last iteration, if .a and .b are on different lines, we need to select # NEXTWORD and any following WHITESPACE too. if (is_last_iteration and view.line(s.a) != view.line(s.b) and # Is the leading text on this line white space? If so, delete that, the next WORD # and any WHITESPACE after it. view.substr(sublime.Region(view.line(s.b).a, s.b) ).isspace()): pt = utils.next_non_white_space_char(self.view, s.b) pt = utils.next_non_white_space_char(self.view, view.word(pt).b) return sublime.Region(s.a, pt) return s
def word_starts(view, start, count=1, internal=False): assert start >= 0 assert count > 0 pt = start for i in range(count): # On the last motion iteration, we must do some special stuff if we are still on the # starting line of the motion. if (internal and (i == count - 1) and (view.line(start) == view.line(pt))): if view.substr(pt) == '\n': return pt + 1 return next_word_start(view, pt, internal=True) pt = next_word_start(view, pt) if not internal or (i != count - 1): pt = next_non_white_space_char(view, pt, white_space=' \t') while not (view.size() == pt or view.line(pt).empty() or view.substr(view.line(pt)).strip()): pt = next_word_start(view, pt) pt = next_non_white_space_char(view, pt, white_space=' \t') if (internal and (view.line(start) != view.line(pt)) and (start != view.line(start).a and not view.substr(view.line(pt - 1)).isspace()) and at_eol(view, pt - 1)): pt -= 1 return pt
def f(view, s): if mode == _MODE_INTERNAL_NORMAL: if view.line(s).empty(): return s elif mode == MODE_VISUAL: if view.line(s.b - 1).empty() and s.size() == 1: return s state = VintageState(self.view) autoindent = state.settings.vi['autoindent'] if mode == _MODE_INTERNAL_NORMAL: if not autoindent: return self.view.line(s) else: pt = utils.next_non_white_space_char( view, self.view.line(s).a) return sublime.Region(pt, self.view.line(s).b) elif mode == MODE_VISUAL: if not autoindent: return self.view.line(sublime.Region(s.a, s.b - 1)) else: pt = utils.next_non_white_space_char( view, self.view.line(s.a).a) return sublime.Region(pt, self.view.line(s.b - 1).b)
def big_word_starts(view, start, count=1, internal=False): assert start >= 0 assert count > 0 pt = start for i in range(count): if internal and i == count - 1 and view.line(start) == view.line(pt): if view.substr(pt) == '\n': return pt + 1 return next_big_word_start(view, pt, internal=True) pt = next_big_word_start(view, pt) if not internal or i != count - 1: pt = next_non_white_space_char(view, pt, white_space=' \t') while not (view.size() == pt or view.line(pt).empty() or view.substr(view.line(pt)).strip()): pt = next_big_word_start(view, pt) pt = next_non_white_space_char(view, pt, white_space=' \t') if (internal and (view.line(start) != view.line(pt)) and (start != view.line(start).a and not view.substr(view.line(pt - 1)).isspace()) and at_eol(view, pt - 1)): pt -= 1 return pt
def word_starts(view, start, count=1, internal=False): assert start >= 0 assert count > 0 pt = start for i in range(count): # On the last motion iteration, we must do some special stuff if we are still on the # starting line of the motion. if (internal and (i == count - 1) and (view.line(start) == view.line(pt))): if view.substr(pt) == '\n': return pt + 1 return next_word_start(view, pt, internal=True) pt = next_word_start(view, pt) if not internal or (i != count - 1): pt = next_non_white_space_char(view, pt, white_space=' \t') while not (view.size() == pt or view.line(pt).empty() or view.substr(view.line(pt)).strip()): pt = next_word_start(view, pt) pt = next_non_white_space_char(view, pt, white_space=' \t') if (internal and (view.line(start) != view.line(pt)) and (start != view.line(start).a and not view.substr(view.line(pt - 1)).isspace()) and at_eol(view, pt - 1)): pt -= 1 return pt
def big_word_starts(view, start, count=1, internal=False): assert start >= 0 assert count > 0 pt = start for i in range(count): if internal and i == count - 1 and view.line(start) == view.line(pt): if view.substr(pt) == '\n': return pt + 1 return next_big_word_start(view, pt, internal=True) pt = next_big_word_start(view, pt) if not internal or i != count - 1: pt = next_non_white_space_char(view, pt, white_space=' \t') while not (view.size() == pt or view.line(pt).empty() or view.substr(view.line(pt)).strip()): pt = next_big_word_start(view, pt) pt = next_non_white_space_char(view, pt, white_space=' \t') if (internal and (view.line(start) != view.line(pt)) and (start != view.line(start).a and not view.substr(view.line(pt - 1)).isspace()) and at_eol(view, pt - 1)): pt -= 1 return pt
def f(view, s): is_last_iteration = (current_iteration == total_iterations - 1) if mode == _MODE_INTERNAL_NORMAL: # If we're at BOL one LINE down; move to NEXTWORD WORDEND inclusive. if utils.is_at_bol(self.view, s): next = utils.next_non_white_space_char(self.view, s.b, white_space='\t \n') next = self.view.word(next) return sublime.Region(s.a, next.b) else: return s elif mode == MODE_NORMAL: # If we're at BOL one LINE down; move to NEXTWORD WORDEND exclusive. if utils.is_at_bol(self.view, s): next = utils.next_non_white_space_char(self.view, s.b, white_space='\t \n') next = self.view.word(next) return sublime.Region(next.b - 1, next.b - 1) # Last motion; ensure caret ends up at a WORDEND exclusive. The native 'move' # command will have left us on the next character. elif is_last_iteration: return sublime.Region(s.a - 1, s.b - 1) else: return s elif mode == MODE_VISUAL: # If we're at BOL one LINE down, move to NEXTWORD WORDEND inclusive. if utils.is_at_bol(self.view, s): next = utils.next_non_white_space_char(self.view, s.b, white_space='\t \n') next = self.view.word(next) return sublime.Region(s.a, next.b) else: return s
def f(view, s): # If: # * motion hasn't completed # * we are at EOL # * we are not on an empty line # ... skip the new line character. Othwerwise, S3 will count it as a WORD. Note that # empty lines do count as WORDs. if (not is_last_iteration and view.substr(s.b) == '\n' and not view.line(s.b).empty()): return sublime.Region(s.a, s.b + 1) # On the last iteration, encompass the whole line if we're at EOL and .a and .b are # on different lines. if is_last_iteration: if (view.line(s.a) != view.line(s.b) and view.substr(s.b) == '\n' and not view.line(s.b - 1).empty()): return sublime.Region(s.a, s.b + 1) # On the last iteration, if .a and .b are on different lines, we need to select # NEXTWORD and any following WHITESPACE too. if (is_last_iteration and view.line(s.a) != view.line(s.b) and # Is the leading text on this line white space? If so, delete that, the next WORD # and any WHITESPACE after it. view.substr(sublime.Region(view.line(s.b).a, s.b)).isspace()): pt = utils.next_non_white_space_char(self.view, s.b) pt = utils.next_non_white_space_char(self.view, view.word(pt).b) return sublime.Region(s.a, pt) return s
def f(view, s): state = VintageState(view) if state.mode == MODE_NORMAL: if s.b == view.size(): return sublime.Region(view.size() - 1, view.size() - 1) elif view.substr(s.b) == '\n': if not view.line(s.b).empty(): r = sublime.Region(s.b + 1, s.b + 1) pt = utils.next_non_white_space_char(view, r.b, white_space='\t ') return sublime.Region(pt, pt) if state.mode == MODE_VISUAL: if not utils.is_region_reversed(view, s): # FIXME: Moving from EMPTYLINE to NONEMPTYLINE should select FIRSTCHAR on NEXTLINE # only, but it selects a WORD and the FIRSTCHAR of the following WORD too. # When starting from an empty line, select only the FIRSTCHAR of the FIRSTWORD on # NEXTLINE. if view.size() == s.b: return sublime.Region(s.a, s.b) if ViExecutionState.select_word_begin_from_empty_line: ViExecutionState.reset_word_state() return sublime.Region(s.a, view.word(view.line(s.b).a).a + 1) # If after the motion we're on an empty line, stay there. if view.substr(s.b - 1) == '\n' and view.line(s.b - 1).empty(): return s # Always select the FIRSTCHAR of NEXTWORD skipping any WHITESPACE. # XXX: Possible infinite loop at EOF. pt = s.b while True: pt = utils.next_non_white_space_char(view, pt, white_space='\t ') # We're on an EMPTYLINE, so stay here. if view.substr(pt) == '\n' and view.line(pt).empty(): break # NEWLINECHAR after NONEMPTYLINE; keep going. elif view.substr(pt) == '\n': pt += 1 continue # Any NONWHITESPACECHAR; stop here. else: break s = sublime.Region(s.a, pt + 1) # Reversed selections... else: # Skip over NEWLINECHAR at EOL if on NONEMPTYLINE. if view.substr(s.b) == '\n' and not view.line(s.b).empty(): # FIXME: Don't swallow empty lines. pt = utils.next_non_white_space_char(view, s.b, white_space='\t \n') return sublime.Region(s.a, pt) return s
def f(view, s): # We've made a selection with _vi_cc_motion just before this. if mode == _MODE_INTERNAL_NORMAL: pt = utils.next_non_white_space_char(view, s.a, white_space=' \t') view.erase(edit, sublime.Region(pt, view.line(s.b).b)) self.view.run_command('_vi_int_reindent', {'mode': mode}) pt = utils.next_non_white_space_char(view, pt, white_space=' \t') return sublime.Region(pt, pt) return s
def f(view, s): if mode == MODE_VISUAL: line = view.line(s.b - 1) pt = utils.next_non_white_space_char(view, line.a) return sublime.Region(s.a, pt + 1) elif mode != MODE_VISUAL_LINE: line = view.line(s.b) pt = utils.next_non_white_space_char(view, line.a) return sublime.Region(pt, pt) return s
def f(view, s): if mode == MODE_VISUAL: line = view.line(s.b - 1) pt = utils.next_non_white_space_char(view, line.a) return sublime.Region(s.a, pt + 1) elif mode != MODE_VISUAL_LINE: line = view.line(s.b) pt = utils.next_non_white_space_char(view, line.a) return sublime.Region(pt, pt) return s
def f(view, s): # We've made a selection with _vi_cc_motion just before this. if mode == _MODE_INTERNAL_NORMAL: view.erase(edit, s) if self.row_at(s.a) != self.row_at(self.view.size()): pt = utils.next_non_white_space_char(view, s.a, white_space=' \t') else: pt = utils.next_non_white_space_char(view, self.view.line(s.a).a, white_space=' \t') return sublime.Region(pt, pt) return s
def f(view, s): if mode == MODE_NORMAL: return sublime.Region(target, target) elif mode == _MODE_INTERNAL_NORMAL: if s.b >= target: return sublime.Region(s.a + 1, target) return sublime.Region(s.a, target) elif mode == MODE_VISUAL: if s.b >= target: new_target = utils.next_non_white_space_char(view, target) return sublime.Region(s.a + 1, new_target) new_target = utils.next_non_white_space_char(view, target) return sublime.Region(s.a, new_target + 1) else: return s
def f(view, s): if mode == MODE_NORMAL: return sublime.Region(target, target) elif mode == _MODE_INTERNAL_NORMAL: if s.b >= target: return sublime.Region(s.a + 1, target) return sublime.Region(s.a, target) elif mode == MODE_VISUAL: if s.b >= target: new_target = utils.next_non_white_space_char(view, target) return sublime.Region(s.a + 1, new_target) new_target = utils.next_non_white_space_char(view, target) return sublime.Region(s.a, new_target + 1) else: return s
def f(view, s): if mode == MODE_NORMAL: pt = utils.next_non_white_space_char(view, s.b) return sublime.Region(pt, pt) elif mode == MODE_VISUAL: line = view.line(s.b) pt = utils.next_non_white_space_char(view, line.a) return sublime.Region(s.a, pt) elif mode == _MODE_INTERNAL_NORMAL: if not s.empty() and view.substr(s.b - 1) == '\n': return s else: return sublime.Region(s.a, view.full_line(s.b).b) return s
def f(view, s): if mode == MODE_NORMAL: pt = utils.next_non_white_space_char(view, s.b) return sublime.Region(pt, pt) elif mode == MODE_VISUAL: line = view.line(s.b) pt = utils.next_non_white_space_char(view, line.a) return sublime.Region(s.a, pt) elif mode == _MODE_INTERNAL_NORMAL: if not s.empty() and view.substr(s.b - 1) == '\n': return s else: return sublime.Region(s.a, view.full_line(s.b).b) return s
def words(view, start, count=1, internal=False): assert start >= 0 assert count > 0 classes = (CLASS_VI_WORD_START if not internal else CLASS_VI_INTERNAL_WORD_START) pt = start for i in range(count): # Special case. Don't eat up next leading white space if moving from empty line in # internal mode. # For example, dw (starting in line 1): # # 1| # 2| foo bar # if (internal and (i == count - 1) and view.line(pt).empty() and (pt < view.size())): pt += 1 continue pt = next_word_start(view, pt, classes=classes) if internal: if (i != count - 1): if (not view.line(pt).empty()) and at_eol(view, pt): pt += 1 pt = next_non_white_space_char(view, pt, white_space=' \t') if (internal and (view.line(start) != view.line(pt)) and (not view.line(pt).empty()) and at_eol(view, pt)): pt += 1 return pt
def f(view, s): # We've made a selection with _vi_cc_motion just before this. if mode == _MODE_INTERNAL_NORMAL: self.view.run_command('reindent', {'force_indent': False}) pt = utils.next_non_white_space_char(view, s.a, white_space=' \t') return sublime.Region(pt, pt) return s
def f(view, s): if mode == MODE_VISUAL_BLOCK: return sublime.Region(s.begin()) elif mode == MODE_VISUAL: line = view.line(s.b - 1) pt = utils.next_non_white_space_char(view, line.a) return sublime.Region(pt) elif mode == MODE_VISUAL_LINE: line = view.line(s.a) pt = utils.next_non_white_space_char(view, line.a) return sublime.Region(pt) elif mode != _MODE_INTERNAL_NORMAL: return s line = view.line(s.b) pt = utils.next_non_white_space_char(view, line.a) return sublime.Region(pt, pt)
def f(view, s): # TODO: must skip empty paragraphs. start = utils.next_non_white_space_char(view, s.b, white_space='\n \t') par_as_region = view.expand_by_class(start, sublime.CLASS_EMPTY_LINE) if mode == MODE_NORMAL: min_pt = max(0, min(par_as_region.b, view.size() - 1)) return sublime.Region(min_pt, min_pt) elif mode == MODE_VISUAL: return sublime.Region(s.a, par_as_region.b + 1) elif mode == _MODE_INTERNAL_NORMAL: return sublime.Region(s.a, par_as_region.b - 1) elif mode == MODE_VISUAL_LINE: if s.a <= s.b: return sublime.Region(s.a, par_as_region.b + 1) else: if par_as_region.b > s.a: return sublime.Region( view.line(s.a - 1).a, par_as_region.b + 1) return sublime.Region(s.a, par_as_region.b) return s
def f(view, s): # We've made a selection with _vi_big_s_motion just before this. if mode == _MODE_INTERNAL_NORMAL: pt = utils.next_non_white_space_char(view, s.a, white_space=' \t') view.erase(edit, sublime.Region(pt, view.line(s.b).b)) return sublime.Region(pt, pt) return s
def f(view, s): # We've made a selection with _vi_big_s_motion just before this. if mode == _MODE_INTERNAL_NORMAL: pt = utils.next_non_white_space_char(view, s.a, white_space=' \t') view.erase(edit, sublime.Region(pt, view.line(s.b).b)) return sublime.Region(pt, pt) return s
def f(view, s): is_last_iteration = (current_iteration == total_iterations - 1) if mode == _MODE_INTERNAL_NORMAL: # If we're at BOL one LINE down; move to NEXTWORD WORDEND inclusive. if utils.is_at_bol(self.view, s): next = utils.next_non_white_space_char(self.view, s.b, white_space='\t \n') next = self.view.word(next) return sublime.Region(s.a, next.b) else: return s elif mode == MODE_NORMAL: # If we're at BOL one LINE down; move to NEXTWORD WORDEND exclusive. if utils.is_at_bol(self.view, s): next = utils.next_non_white_space_char(self.view, s.b, white_space='\t \n') next = self.view.word(next) return sublime.Region(next.b - 1, next.b - 1) # Last motion; ensure caret ends up at a WORDEND exclusive. The native 'move' # command will have left us on the next character. elif is_last_iteration: return sublime.Region(s.a - 1, s.b - 1) else: return s elif mode == MODE_VISUAL: # If we're at BOL one LINE down, move to NEXTWORD WORDEND inclusive. if utils.is_at_bol(self.view, s): next = utils.next_non_white_space_char(self.view, s.b, white_space='\t \n') next = self.view.word(next) return sublime.Region(s.a, next.b) else: return s
def f(view, s): if mode == _MODE_INTERNAL_NORMAL: if s.a <= s.b: if view.substr(s.b) != "\n": end = view.word(s.b).b end = utils.next_non_white_space_char(view, end, white_space="\t ") if end == s.b: end = view.expand_by_class(s.b, sublime.CLASS_PUNCTUATION_END).b return sublime.Region(s.a, end) elif view.line(s.b).empty(): return sublime.Region(s.a, s.b + 1) return s
def f(view, s): if mode == _MODE_INTERNAL_NORMAL: if s.a <= s.b: if view.substr(s.b) != '\n': end = view.word(s.b).b if view.classify(end) & sublime.CLASS_PUNCTUATION_START == sublime.CLASS_PUNCTUATION_START: end = view.expand_by_class(end, sublime.CLASS_PUNCTUATION_END).b end = utils.next_non_white_space_char(view, end, white_space='\t ') return sublime.Region(s.a, end) elif view.line(s.b).empty(): return sublime.Region(s.a, s.b + 1) return s
def f(view, s): if mode == _MODE_INTERNAL_NORMAL: if view.line(s).empty(): return s elif mode == MODE_VISUAL: if view.line(s.b - 1).empty() and s.size() == 1: return s state = VintageState(self.view) autoindent = state.settings.vi['autoindent'] if mode == _MODE_INTERNAL_NORMAL: if not autoindent: return self.view.line(s) else: pt = utils.next_non_white_space_char(view, self.view.line(s).a) return sublime.Region(pt, self.view.line(s).b) elif mode == MODE_VISUAL: if not autoindent: return self.view.line(sublime.Region(s.a, s.b - 1)) else: pt = utils.next_non_white_space_char(view, self.view.line(s.a).a) return sublime.Region(pt, self.view.line(s.b - 1).b)
def f(view, s): if mode == _MODE_INTERNAL_NORMAL: if s.a <= s.b: if view.substr(s.b) != '\n': end = view.word(s.b).b end = utils.next_non_white_space_char( view, end, white_space='\t ') if end == s.b: end = view.expand_by_class( s.b, sublime.CLASS_PUNCTUATION_END).b return sublime.Region(s.a, end) elif view.line(s.b).empty(): return sublime.Region(s.a, s.b + 1) return s
def find_next_sentence_end(self, r): sen = r non_ws = utils.next_non_white_space_char(self.view, sen.b, '\t \n') sen = sublime.Region(non_ws, non_ws) while True: sen = self.view.expand_by_class(sen, sublime.CLASS_PUNCTUATION_START | sublime.CLASS_LINE_END) if (sen.b == self.view.size() or self.view.substr(sublime.Region(sen.b, sen.b + 2)).endswith(('. ', '.\t')) or self.view.substr(self.view.line(sen.b)).strip() == ''): if self.view.substr(sen.b) == '.': return sublime.Region(sen.a, sen.b + 1) else: if self.view.line(sen.b).empty(): return sublime.Region(sen.a, sen.b) else: return self.view.full_line(sen.b)
def find_next_sentence_end(self, r): sen = r non_ws = utils.next_non_white_space_char(self.view, sen.b, '\t \n') sen = sublime.Region(non_ws, non_ws) while True: sen = self.view.expand_by_class( sen, sublime.CLASS_PUNCTUATION_START | sublime.CLASS_LINE_END) if (sen.b == self.view.size() or self.view.substr( sublime.Region(sen.b, sen.b + 2)).endswith(('. ', '.\t')) or self.view.substr(self.view.line(sen.b)).strip() == ''): if self.view.substr(sen.b) == '.': return sublime.Region(sen.a, sen.b + 1) else: if self.view.line(sen.b).empty(): return sublime.Region(sen.a, sen.b) else: return self.view.full_line(sen.b)
def inner_lines(view, s, count=1): """ Returns a region spanning @count inner lines. Inner lines are lines excluding leading/trailing whitespace at outer ends. Assumes we're operating in INTERNAL_NORMAL mode. @view Target view. @s Selection in @view taken as starting point. @count Number of lines to include in returned region. """ end = view.text_point(utils.row_at(view, s.b) + (count - 1), 0) begin = view.line(s.b).a begin = utils.next_non_white_space_char(view, begin, white_space=' \t') return sublime.Region(begin, view.line(end).b)
def inner_lines(view, s, count=1): """ Returns a region spanning @count inner lines. Inner lines are lines excluding leading/trailing whitespace at outer ends. Assumes we're operating in INTERNAL_NORMAL mode. @view Target view. @s Selection in @view taken as starting point. @count Number of lines to include in returned region. """ end = view.text_point(utils.row_at(view, s.b) + (count - 1), 0) begin = view.line(s.b).a begin = utils.next_non_white_space_char(view, begin, white_space=' \t') return sublime.Region(begin, view.line(end).b)
def f(view, s): # TODO: must skip empty paragraphs. start = utils.next_non_white_space_char(view, s.b, white_space='\n \t') par_as_region = view.expand_by_class(start, sublime.CLASS_EMPTY_LINE) if mode == MODE_NORMAL: return sublime.Region(min(par_as_region.b, view.size() - 1), min(par_as_region.b, view.size() - 1)) elif mode == MODE_VISUAL: return sublime.Region(s.a, par_as_region.b + 1) elif mode == _MODE_INTERNAL_NORMAL: return sublime.Region(s.a, par_as_region.b - 1) elif mode == MODE_VISUAL_LINE: if s.a <= s.b: return sublime.Region(s.a, par_as_region.b + 1) else: if par_as_region.b > s.a: return sublime.Region(view.line(s.a - 1).a, par_as_region.b + 1) return sublime.Region(s.a, par_as_region.b) return s
def f(view, s): line = view.line(s.b) pt = utils.next_non_white_space_char(view, line.a) return sublime.Region(pt, pt)
def ff(view, s): # We've made a selection with _vi_cc_motion just before this. if mode == _MODE_INTERNAL_NORMAL: pt = utils.next_non_white_space_char(view, s.b, white_space=' \t') return sublime.Region(pt) return s
def f(view, s): line = view.line(s.b) pt = utils.next_non_white_space_char(view, line.a) return sublime.Region(pt, pt)
def f(view, s): state = VintageState(view) if state.mode == MODE_NORMAL: if s.b == view.size(): return sublime.Region(view.size() - 1, view.size() - 1) elif view.substr(s.b) == '\n': if not view.line(s.b).empty(): r = sublime.Region(s.b + 1, s.b + 1) pt = utils.next_non_white_space_char(view, r.b, white_space='\t ') return sublime.Region(pt, pt) if state.mode == MODE_VISUAL: if not utils.is_region_reversed(view, s): # FIXME: Moving from EMPTYLINE to NONEMPTYLINE should select FIRSTCHAR on NEXTLINE # only, but it selects a WORD and the FIRSTCHAR of the following WORD too. # When starting from an empty line, select only the FIRSTCHAR of the FIRSTWORD on # NEXTLINE. if view.size() == s.b: return sublime.Region(s.a, s.b) if ViExecutionState.select_word_begin_from_empty_line: ViExecutionState.reset_word_state() return sublime.Region( s.a, view.word(view.line(s.b).a).a + 1) # If after the motion we're on an empty line, stay there. if view.substr(s.b - 1) == '\n' and view.line(s.b - 1).empty(): return s # Always select the FIRSTCHAR of NEXTWORD skipping any WHITESPACE. # XXX: Possible infinite loop at EOF. pt = s.b while True: pt = utils.next_non_white_space_char(view, pt, white_space='\t ') # We're on an EMPTYLINE, so stay here. if view.substr(pt) == '\n' and view.line(pt).empty(): break # NEWLINECHAR after NONEMPTYLINE; keep going. elif view.substr(pt) == '\n': pt += 1 continue # Any NONWHITESPACECHAR; stop here. else: break s = sublime.Region(s.a, pt + 1) # Reversed selections... else: # Skip over NEWLINECHAR at EOL if on NONEMPTYLINE. if view.substr(s.b) == '\n' and not view.line(s.b).empty(): # FIXME: Don't swallow empty lines. pt = utils.next_non_white_space_char( view, s.b, white_space='\t \n') return sublime.Region(s.a, pt) if state.mode == _MODE_INTERNAL_NORMAL: if current_iteration == total_iterations: if view.substr(s.b - 1) == '\n' and not view.line(s.b - 1).empty(): return sublime.Region(s.a, s.b - 1) return s
def first_non_white_space_char(self, where): start = self.view.text_point(self.view.rowcol(where)[0], 0) pt = utils.next_non_white_space_char(self.view, start, white_space=' \t') return pt
def first_non_white_space_char(self, where): start = self.view.text_point(self.view.rowcol(where)[0], 0) pt = utils.next_non_white_space_char(self.view, start, white_space=" \t") return pt