@@ -41,64 +41,118 @@ var codeInput = {
4141 }
4242
4343 check_tab ( event ) {
44- if ( this . template . isCode ) {
45- let input_element = this . querySelector ( "textarea" ) ;
46- let code = input_element . value ;
47- if ( event . key == "Tab" ) {
48- /* Tab key pressed */
49- event . preventDefault ( ) ; // stop normal
50-
51- if ( input_element . selectionStart == input_element . selectionEnd ) {
52-
53- let before_selection = code . slice ( 0 , input_element . selectionStart ) ; // text before tab
54- let after_selection = code . slice ( input_element . selectionEnd , input_element . value . length ) ; // text after tab
55-
56- let cursor_pos = input_element . selectionEnd + 1 ; // where cursor moves after tab - moving forward by 1 char to after tab
57- input_element . value = before_selection + "\t" + after_selection ; // add tab char
58-
59- // move cursor
60- input_element . selectionStart = cursor_pos ;
61- input_element . selectionEnd = cursor_pos ;
62-
63- } else {
64- let lines = input_element . value . split ( "\n" ) ;
65- let letter_i = 0 ;
66-
67- let selection_start = input_element . selectionStart ; // where cursor moves after tab - moving forward by 1 indent
68- let selection_end = input_element . selectionEnd ; // where cursor moves after tab - moving forward by 1 indent
69-
70- let number_indents = 0 ;
71- let first_line_indents = 0 ;
72-
73- for ( let i = 0 ; i < lines . length ; i ++ ) {
74- letter_i += lines [ i ] . length ;
75- if ( input_element . selectionStart < letter_i && input_element . selectionEnd > letter_i - lines [ i ] . length ) {
76- if ( event . shiftKey ) {
77- if ( lines [ i ] [ 0 ] == "\t" ) {
78- lines [ i ] = lines [ i ] . slice ( 1 ) ;
79- if ( number_indents == 0 ) first_line_indents -- ;
80- number_indents -- ;
81- }
82- } else {
83- lines [ i ] = "\t" + lines [ i ] ;
84- if ( number_indents == 0 ) first_line_indents ++ ;
85- number_indents ++ ;
86- }
87-
44+ if ( event . key != "Tab" || ! this . template . isCode ) {
45+ return ;
46+ }
47+ let input_element = this . querySelector ( "textarea" ) ;
48+ let code = input_element . value ;
49+ event . preventDefault ( ) ; // stop normal
50+
51+ if ( input_element . selectionStart == input_element . selectionEnd ) {
52+
53+ let before_selection = code . slice ( 0 , input_element . selectionStart ) ; // text before tab
54+ let after_selection = code . slice ( input_element . selectionEnd , input_element . value . length ) ; // text after tab
55+
56+ let cursor_pos = input_element . selectionEnd + 1 ; // where cursor moves after tab - moving forward by 1 char to after tab
57+ input_element . value = before_selection + "\t" + after_selection ; // add tab char
58+
59+ // move cursor
60+ input_element . selectionStart = cursor_pos ;
61+ input_element . selectionEnd = cursor_pos ;
62+
63+ } else {
64+ let lines = input_element . value . split ( "\n" ) ;
65+ let letter_i = 0 ;
66+
67+ let selection_start = input_element . selectionStart ; // where cursor moves after tab - moving forward by 1 indent
68+ let selection_end = input_element . selectionEnd ; // where cursor moves after tab - moving forward by 1 indent
69+
70+ let number_indents = 0 ;
71+ let first_line_indents = 0 ;
72+
73+ for ( let i = 0 ; i < lines . length ; i ++ ) {
74+ letter_i += lines [ i ] . length ;
75+ if ( input_element . selectionStart < letter_i && input_element . selectionEnd > letter_i - lines [ i ] . length ) {
76+ if ( event . shiftKey ) {
77+ if ( lines [ i ] [ 0 ] == "\t" ) {
78+ lines [ i ] = lines [ i ] . slice ( 1 ) ;
79+ if ( number_indents == 0 ) first_line_indents -- ;
80+ number_indents -- ;
8881 }
82+ } else {
83+ lines [ i ] = "\t" + lines [ i ] ;
84+ if ( number_indents == 0 ) first_line_indents ++ ;
85+ number_indents ++ ;
8986 }
90- input_element . value = lines . join ( "\n" ) ;
87+
88+ }
89+ }
90+ input_element . value = lines . join ( "\n" ) ;
9191
92- // move cursor
93- input_element . selectionStart = selection_start + first_line_indents ;
94- input_element . selectionEnd = selection_end + number_indents ;
92+ // move cursor
93+ input_element . selectionStart = selection_start + first_line_indents ;
94+ input_element . selectionEnd = selection_end + number_indents ;
95+ }
9596
96- }
97+ this . update ( input_element . value ) ;
98+ }
9799
98- this . update ( input_element . value ) ;
100+ check_enter ( event ) {
101+ if ( event . key != "Enter" || ! this . template . isCode ) {
102+ return ;
103+ }
104+ event . preventDefault ( ) ; // stop normal
105+
106+ let input_element = this . querySelector ( "textarea" ) ;
107+ let lines = input_element . value . split ( "\n" ) ;
108+ let letter_i = 0 ;
109+ let current_line = lines . length - 1 ;
110+ let new_line = "" ;
111+ let number_indents = 0 ;
112+
113+ // find the index of the line our cursor is currently on
114+ for ( let i = 0 ; i < lines . length ; i ++ ) {
115+ letter_i += lines [ i ] . length + 1 ;
116+ if ( input_element . selectionEnd <= letter_i ) {
117+ current_line = i ;
118+ break ;
99119 }
100120 }
121+
122+ // count the number of indents the current line starts with (up to our cursor position in the line)
123+ let cursor_pos_in_line = lines [ current_line ] . length - ( letter_i - input_element . selectionEnd ) + 1 ;
124+ for ( let i = 0 ; i < cursor_pos_in_line ; i ++ ) {
125+ if ( lines [ current_line ] [ i ] == "\t" ) {
126+ number_indents ++ ;
127+ } else {
128+ break ;
129+ }
130+ }
131+
132+ // determine the text before and after the cursor and chop the current line at the new line break
133+ let text_after_cursor = "" ;
134+ if ( cursor_pos_in_line != lines [ current_line ] . length ) {
135+ text_after_cursor = lines [ current_line ] . substring ( cursor_pos_in_line ) ;
136+ lines [ current_line ] = lines [ current_line ] . substring ( 0 , cursor_pos_in_line ) ;
137+ }
138+
139+ // insert our indents and any text from the previous line that might have been after the line break
140+ for ( let i = 0 ; i < number_indents ; i ++ ) {
141+ new_line += "\t" ;
142+ }
143+ new_line += text_after_cursor ;
144+
145+ // splice our new line into the list of existing lines and join them all back up
146+ lines . splice ( current_line + 1 , 0 , new_line ) ;
147+ input_element . value = lines . join ( "\n" ) ;
148+
149+ // move cursor to new position
150+ input_element . selectionStart += number_indents + 1 ; // count the indent level and the newline character
151+ input_element . selectionEnd += number_indents + 1 ;
152+
153+ this . update ( input_element . value ) ;
101154 }
155+
102156 escape_html ( text ) {
103157 return text . replace ( new RegExp ( "&" , "g" ) , "&" ) . replace ( new RegExp ( "<" , "g" ) , "<" ) ; /* Global RegExp */
104158 }
@@ -129,7 +183,7 @@ var codeInput = {
129183
130184 textarea . setAttribute ( "oninput" , "this.parentElement.update(this.value); this.parentElement.sync_scroll();" ) ;
131185 textarea . setAttribute ( "onscroll" , "this.parentElement.sync_scroll();" ) ;
132- textarea . setAttribute ( "onkeydown" , "this.parentElement.check_tab(event);" ) ;
186+ textarea . setAttribute ( "onkeydown" , "this.parentElement.check_tab(event); this.parentElement.check_enter(event); " ) ;
133187
134188 this . append ( textarea ) ;
135189
0 commit comments