Skip to content

Commit f187c47

Browse files
author
Robert Blackhart
committed
add a function to check for new lines and indent them to match the previous line
1 parent f547f9c commit f187c47

File tree

1 file changed

+105
-51
lines changed

1 file changed

+105
-51
lines changed

code-input.js

Lines changed: 105 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -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"), "&amp;").replace(new RegExp("<", "g"), "&lt;"); /* 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

Comments
 (0)