@@ -45,64 +45,122 @@ var codeInput = {
4545 }
4646
4747 check_tab ( event ) {
48- if ( this . template . isCode ) {
49- let input_element = this . querySelector ( "textarea" ) ;
50- let code = input_element . value ;
51- if ( event . key == "Tab" ) {
52- /* Tab key pressed */
53- event . preventDefault ( ) ; // stop normal
54-
55- if ( input_element . selectionStart == input_element . selectionEnd ) {
56-
57- let before_selection = code . slice ( 0 , input_element . selectionStart ) ; // text before tab
58- let after_selection = code . slice ( input_element . selectionEnd , input_element . value . length ) ; // text after tab
59-
60- let cursor_pos = input_element . selectionEnd + 1 ; // where cursor moves after tab - moving forward by 1 char to after tab
61- input_element . value = before_selection + "\t" + after_selection ; // add tab char
62-
63- // move cursor
64- input_element . selectionStart = cursor_pos ;
65- input_element . selectionEnd = cursor_pos ;
66-
67- } else {
68- let lines = input_element . value . split ( "\n" ) ;
69- let letter_i = 0 ;
70-
71- let selection_start = input_element . selectionStart ; // where cursor moves after tab - moving forward by 1 indent
72- let selection_end = input_element . selectionEnd ; // where cursor moves after tab - moving forward by 1 indent
73-
74- let number_indents = 0 ;
75- let first_line_indents = 0 ;
76-
77- for ( let i = 0 ; i < lines . length ; i ++ ) {
78- letter_i += lines [ i ] . length ;
79- if ( input_element . selectionStart < letter_i && input_element . selectionEnd > letter_i - lines [ i ] . length ) {
80- if ( event . shiftKey ) {
81- if ( lines [ i ] [ 0 ] == "\t" ) {
82- lines [ i ] = lines [ i ] . slice ( 1 ) ;
83- if ( number_indents == 0 ) first_line_indents -- ;
84- number_indents -- ;
85- }
86- } else {
87- lines [ i ] = "\t" + lines [ i ] ;
88- if ( number_indents == 0 ) first_line_indents ++ ;
89- number_indents ++ ;
90- }
91-
48+ if ( event . key != "Tab" || ! this . template . isCode ) {
49+ return ;
50+ }
51+ let input_element = this . querySelector ( "textarea" ) ;
52+ let code = input_element . value ;
53+ event . preventDefault ( ) ; // stop normal
54+
55+ if ( input_element . selectionStart == input_element . selectionEnd ) {
56+
57+ let before_selection = code . slice ( 0 , input_element . selectionStart ) ; // text before tab
58+ let after_selection = code . slice ( input_element . selectionEnd , input_element . value . length ) ; // text after tab
59+
60+ let cursor_pos = input_element . selectionEnd + 1 ; // where cursor moves after tab - moving forward by 1 char to after tab
61+ input_element . value = before_selection + "\t" + after_selection ; // add tab char
62+
63+ // move cursor
64+ input_element . selectionStart = cursor_pos ;
65+ input_element . selectionEnd = cursor_pos ;
66+
67+ } else {
68+ let lines = input_element . value . split ( "\n" ) ;
69+ let letter_i = 0 ;
70+
71+ let selection_start = input_element . selectionStart ; // where cursor moves after tab - moving forward by 1 indent
72+ let selection_end = input_element . selectionEnd ; // where cursor moves after tab - moving forward by 1 indent
73+
74+ let number_indents = 0 ;
75+ let first_line_indents = 0 ;
76+
77+ for ( let i = 0 ; i < lines . length ; i ++ ) {
78+ letter_i += lines [ i ] . length ;
79+ if ( input_element . selectionStart < letter_i && input_element . selectionEnd > letter_i - lines [ i ] . length ) {
80+ if ( event . shiftKey ) {
81+ if ( lines [ i ] [ 0 ] == "\t" ) {
82+ lines [ i ] = lines [ i ] . slice ( 1 ) ;
83+ if ( number_indents == 0 ) first_line_indents -- ;
84+ number_indents -- ;
9285 }
86+ } else {
87+ lines [ i ] = "\t" + lines [ i ] ;
88+ if ( number_indents == 0 ) first_line_indents ++ ;
89+ number_indents ++ ;
9390 }
94- input_element . value = lines . join ( "\n" ) ;
91+
92+ }
93+ }
94+ input_element . value = lines . join ( "\n" ) ;
9595
96- // move cursor
97- input_element . selectionStart = selection_start + first_line_indents ;
98- input_element . selectionEnd = selection_end + number_indents ;
96+ // move cursor
97+ input_element . selectionStart = selection_start + first_line_indents ;
98+ input_element . selectionEnd = selection_end + number_indents ;
99+ }
99100
100- }
101+ this . update ( input_element . value ) ;
102+ }
103+
104+ check_enter ( event ) {
105+ if ( event . key != "Enter" || ! this . template . isCode ) {
106+ return ;
107+ }
108+ event . preventDefault ( ) ; // stop normal
109+
110+ let input_element = this . querySelector ( "textarea" ) ;
111+ let lines = input_element . value . split ( "\n" ) ;
112+ let letter_i = 0 ;
113+ let current_line = lines . length - 1 ;
114+ let new_line = "" ;
115+ let number_indents = 0 ;
101116
102- this . update ( input_element . value ) ;
117+ // find the index of the line our cursor is currently on
118+ for ( let i = 0 ; i < lines . length ; i ++ ) {
119+ letter_i += lines [ i ] . length + 1 ;
120+ if ( input_element . selectionEnd <= letter_i ) {
121+ current_line = i ;
122+ break ;
103123 }
104124 }
125+
126+ // count the number of indents the current line starts with (up to our cursor position in the line)
127+ let cursor_pos_in_line = lines [ current_line ] . length - ( letter_i - input_element . selectionEnd ) + 1 ;
128+ for ( let i = 0 ; i < cursor_pos_in_line ; i ++ ) {
129+ if ( lines [ current_line ] [ i ] == "\t" ) {
130+ number_indents ++ ;
131+ } else {
132+ break ;
133+ }
134+ }
135+
136+ // determine the text before and after the cursor and chop the current line at the new line break
137+ let text_after_cursor = "" ;
138+ if ( cursor_pos_in_line != lines [ current_line ] . length ) {
139+ text_after_cursor = lines [ current_line ] . substring ( cursor_pos_in_line ) ;
140+ lines [ current_line ] = lines [ current_line ] . substring ( 0 , cursor_pos_in_line ) ;
141+ }
142+
143+ // insert our indents and any text from the previous line that might have been after the line break
144+ for ( let i = 0 ; i < number_indents ; i ++ ) {
145+ new_line += "\t" ;
146+ }
147+ new_line += text_after_cursor ;
148+
149+ // save the current cursor position
150+ let selection_start = input_element . selectionStart ;
151+ let selection_end = input_element . selectionEnd ;
152+
153+ // splice our new line into the list of existing lines and join them all back up
154+ lines . splice ( current_line + 1 , 0 , new_line ) ;
155+ input_element . value = lines . join ( "\n" ) ;
156+
157+ // move cursor to new position
158+ input_element . selectionStart = selection_start + number_indents + 1 ; // count the indent level and the newline character
159+ input_element . selectionEnd = selection_end + number_indents + 1 ;
160+
161+ this . update ( input_element . value ) ;
105162 }
163+
106164 escape_html ( text ) {
107165 return text . replace ( new RegExp ( "&" , "g" ) , "&" ) . replace ( new RegExp ( "<" , "g" ) , "<" ) ; /* Global RegExp */
108166 }
@@ -133,7 +191,7 @@ var codeInput = {
133191
134192 textarea . setAttribute ( "oninput" , "this.parentElement.update(this.value); this.parentElement.sync_scroll();" ) ;
135193 textarea . setAttribute ( "onscroll" , "this.parentElement.sync_scroll();" ) ;
136- textarea . setAttribute ( "onkeydown" , "this.parentElement.check_tab(event);" ) ;
194+ textarea . setAttribute ( "onkeydown" , "this.parentElement.check_tab(event); this.parentElement.check_enter(event); " ) ;
137195
138196 this . append ( textarea ) ;
139197
0 commit comments