Do something on tab key taken from bpython.cli Does one of the following: 1) add space to move up to the next %4==0 column 2) complete the current word with characters common to all completions 3) select the first or last match 4) select the next or p
(self, back=False)
| 953 | self.push(self.current_line, insert_into_history=new_code) |
| 954 | |
| 955 | def on_tab(self, back=False): |
| 956 | """Do something on tab key |
| 957 | taken from bpython.cli |
| 958 | |
| 959 | Does one of the following: |
| 960 | 1) add space to move up to the next %4==0 column |
| 961 | 2) complete the current word with characters common to all completions |
| 962 | 3) select the first or last match |
| 963 | 4) select the next or previous match if already have a match |
| 964 | """ |
| 965 | |
| 966 | def only_whitespace_left_of_cursor(): |
| 967 | """returns true if all characters before cursor are whitespace""" |
| 968 | return not self.current_line[: self.cursor_offset].strip() |
| 969 | |
| 970 | logger.debug("self.matches_iter.matches: %r", self.matches_iter.matches) |
| 971 | if only_whitespace_left_of_cursor(): |
| 972 | front_ws = len(self.current_line[: self.cursor_offset]) - len( |
| 973 | self.current_line[: self.cursor_offset].lstrip() |
| 974 | ) |
| 975 | to_add = 4 - (front_ws % self.config.tab_length) |
| 976 | for unused in range(to_add): |
| 977 | self.add_normal_character(" ") |
| 978 | return |
| 979 | # if cursor on closing character from pair, |
| 980 | # moves cursor behind it on tab |
| 981 | # ? should we leave it here as default? |
| 982 | if self.config.brackets_completion: |
| 983 | on_closing_char, _ = cursor_on_closing_char_pair( |
| 984 | self._cursor_offset, self._current_line |
| 985 | ) |
| 986 | if on_closing_char: |
| 987 | self._cursor_offset += 1 |
| 988 | # run complete() if we don't already have matches |
| 989 | if len(self.matches_iter.matches) == 0: |
| 990 | self.list_win_visible = self.complete(tab=True) |
| 991 | |
| 992 | # 3. check to see if we can expand the current word |
| 993 | if self.matches_iter.is_cseq(): |
| 994 | cursor_and_line = self.matches_iter.substitute_cseq() |
| 995 | self._cursor_offset, self._current_line = cursor_and_line |
| 996 | # using _current_line so we don't trigger a completion reset |
| 997 | if not self.matches_iter.matches: |
| 998 | self.list_win_visible = self.complete() |
| 999 | elif self.matches_iter.matches: |
| 1000 | self.current_match = ( |
| 1001 | back and self.matches_iter.previous() or next(self.matches_iter) |
| 1002 | ) |
| 1003 | cursor_and_line = self.matches_iter.cur_line() |
| 1004 | self._cursor_offset, self._current_line = cursor_and_line |
| 1005 | # using _current_line so we don't trigger a completion reset |
| 1006 | self.list_win_visible = True |
| 1007 | if self.config.brackets_completion: |
| 1008 | # appends closing char pair if completion is a callable |
| 1009 | if self.is_completion_callable(self._current_line): |
| 1010 | self._current_line = self.append_closing_character( |
| 1011 | self._current_line |
| 1012 | ) |