##// END OF EJS Templates
Working implementation of cell mode with regular expressions - cleaner.
Fernando Perez -
Show More
@@ -141,6 +141,7 b' def num_ini_spaces(s):'
141 else:
141 else:
142 return 0
142 return 0
143
143
144 last_blank_re = re.compile(r'^.*\n\s+$', re.MULTILINE)
144
145
145 def last_blank(src):
146 def last_blank(src):
146 """Determine if the input source ends in a blank.
147 """Determine if the input source ends in a blank.
@@ -152,9 +153,22 b' def last_blank(src):'
152 src : string
153 src : string
153 A single or multiline string.
154 A single or multiline string.
154 """
155 """
155 if not src: return False
156 return src == '\n' or bool(last_blank_re.match(src))
156 ll = src.splitlines()[-1]
157
157 return (ll == '') or ll.isspace()
158
159 last_two_blanks_re = re.compile(r'^.*\n\s*\n\s*$', re.MULTILINE)
160
161 def last_two_blanks(src):
162 """Determine if the input source ends in two blanks.
163
164 A blank is either a newline or a line consisting of whitespace.
165
166 Parameters
167 ----------
168 src : string
169 A single or multiline string.
170 """
171 return bool(last_two_blanks_re.match(src))
158
172
159
173
160 def remove_comments(src):
174 def remove_comments(src):
@@ -820,6 +834,76 b' class IPythonInputSplitter(InputSplitter):'
820 out = push(line)
834 out = push(line)
821 return out
835 return out
822
836
837
838 def _push_cell_mode(self, lines):
839 """Push in cell mode.
840
841 This means that we get the entire cell with each call. Between resets,
842 the calls simply add more text to the input."""
843
844 if lines.startswith('%%'):
845 # Cell magics bypass all further transformations
846 self.cell_magic_mode = True
847 first, _, body = lines.partition('\n')
848 magic_name, _, line = first.partition(' ')
849 magic_name = magic_name.lstrip(ESC_MAGIC)
850 # We store the body of the cell and create a call to a method that
851 # will use this stored value. This is ugly, but it's a first cut to
852 # get it all working, as right now changing the return API of our
853 # methods would require major refactoring.
854 self.cell_magic_parts = [body]
855 tpl = 'get_ipython()._cell_magic(%r, %r)'
856 tlines = tpl % (magic_name, line)
857 self._store(tlines)
858 self._store(lines, self._buffer_raw, 'source_raw')
859 self._is_complete = last_two_blanks(lines)
860 return self._is_complete
861
862 lines_list = lines.splitlines()
863
864 transforms = [transform_ipy_prompt, transform_classic_prompt,
865 transform_help_end, transform_escaped,
866 transform_assign_system, transform_assign_magic]
867
868 # Transform logic
869 #
870 # We only apply the line transformers to the input if we have either no
871 # input yet, or complete input, or if the last line of the buffer ends
872 # with ':' (opening an indented block). This prevents the accidental
873 # transformation of escapes inside multiline expressions like
874 # triple-quoted strings or parenthesized expressions.
875 #
876 # The last heuristic, while ugly, ensures that the first line of an
877 # indented block is correctly transformed.
878 #
879 # FIXME: try to find a cleaner approach for this last bit.
880
881 # In cell mode, since we're going to pump the parent class by hand line
882 # by line, we need to temporarily switch out to 'line' mode, do a
883 # single manual reset and then feed the lines one by one. Note that
884 # this only matters if the input has more than one line.
885 self.reset()
886 self.input_mode = 'line'
887
888 # Store raw source before applying any transformations to it. Note
889 # that this must be done *after* the reset() call that would otherwise
890 # flush the buffer.
891 self._store(lines, self._buffer_raw, 'source_raw')
892
893 try:
894 push = super(IPythonInputSplitter, self).push
895 buf = self._buffer
896 for line in lines_list:
897 if self._is_complete or not buf or \
898 (buf and buf[-1].rstrip().endswith((':', ','))):
899 for f in transforms:
900 line = f(line)
901
902 out = push(line)
903 finally:
904 self.input_mode = 'cell'
905 return out
906
823 def push(self, lines):
907 def push(self, lines):
824 """Push one or more lines of IPython input.
908 """Push one or more lines of IPython input.
825
909
@@ -843,8 +927,6 b' class IPythonInputSplitter(InputSplitter):'
843 this value is also stored as a private attribute (_is_complete), so it
927 this value is also stored as a private attribute (_is_complete), so it
844 can be queried at any time.
928 can be queried at any time.
845 """
929 """
846 print('mode:', self.input_mode)
847 print('lines:',repr(lines))
848 if not lines:
930 if not lines:
849 return super(IPythonInputSplitter, self).push(lines)
931 return super(IPythonInputSplitter, self).push(lines)
850
932
@@ -853,9 +935,8 b' class IPythonInputSplitter(InputSplitter):'
853
935
854 if self.input_mode == 'line':
936 if self.input_mode == 'line':
855 return self._push_line_mode(lines)
937 return self._push_line_mode(lines)
856
938 else:
857 ## else:
939 return self._push_cell_mode(lines)
858 ## return self._push_cell_mode(lines)
859
940
860 lines_list = lines.splitlines()
941 lines_list = lines.splitlines()
861
942
@@ -604,12 +604,27 b' def test_last_blank():'
604 nt.assert_false(isp.last_blank('abc'))
604 nt.assert_false(isp.last_blank('abc'))
605 nt.assert_false(isp.last_blank('abc\n'))
605 nt.assert_false(isp.last_blank('abc\n'))
606 nt.assert_false(isp.last_blank('abc\na'))
606 nt.assert_false(isp.last_blank('abc\na'))
607
607 nt.assert_true(isp.last_blank('\n'))
608 nt.assert_true(isp.last_blank('\n'))
608 nt.assert_true(isp.last_blank('\n '))
609 nt.assert_true(isp.last_blank('\n '))
609 nt.assert_true(isp.last_blank('abc\n '))
610 nt.assert_true(isp.last_blank('abc\n '))
610 nt.assert_true(isp.last_blank('abc\n\n'))
611 nt.assert_true(isp.last_blank('abc\n\n'))
611
612
612
613
614 def test_last_two_blanks():
615 nt.assert_false(isp.last_two_blanks(''))
616 nt.assert_false(isp.last_two_blanks('abc'))
617 nt.assert_false(isp.last_two_blanks('abc\n'))
618 nt.assert_false(isp.last_two_blanks('abc\n\na'))
619
620 nt.assert_true(isp.last_two_blanks('\n\n'))
621 nt.assert_true(isp.last_two_blanks('\n\n '))
622 nt.assert_true(isp.last_two_blanks('\n \n'))
623 nt.assert_true(isp.last_two_blanks('abc\n \n'))
624 nt.assert_true(isp.last_two_blanks('abc\n\n '))
625 nt.assert_true(isp.last_two_blanks('abc\n\n'))
626
627
613 def test_cell_magics():
628 def test_cell_magics():
614 from IPython.core import magic
629 from IPython.core import magic
615
630
General Comments 0
You need to be logged in to leave comments. Login now