@@ -6,40 +6,18 @@ package editor
66import (
77 "strings"
88 "unicode"
9+
10+ "github.com/gopherjs/gopherjs.github.io/playground/internal/common"
911)
1012
1113const (
1214 // TabWidth is the number of spaces per tab.
1315 TabWidth = 4
1416
15- EscapeEvent = `escape`
16- SaveEvent = `save`
17- UndoEvent = `undo`
18- RedoEvent = `redo`
19-
2017 commentPrefix = `// `
2118 commentPrefixLen = len (commentPrefix )
2219)
2320
24- type CodeBoxWrapper interface {
25- Code () string
26- GetSelection () Selection
27- SetCode (sel Selection , code string )
28- EmitEvent (event string )
29- }
30-
31- type Selection struct {
32- Start int
33- End int
34- }
35-
36- // IsCaret returns true if the selection represents a caret position
37- // (i.e. start and end are the same).
38- // See https://en.wikipedia.org/wiki/Caret_navigation
39- func (sel Selection ) IsCaret () bool {
40- return sel .Start == sel .End
41- }
42-
4321// MeasureLineLength returns the length of the line.
4422// This counts tabs as multiple spaces so that the visual horizontal offset
4523// is correct, assuming a monospace font.
@@ -84,12 +62,12 @@ func LongestMeasuredLineLength(code string) int {
8462 return longest
8563}
8664
87- func ProcessKeyDown (wrapper CodeBoxWrapper , key string , shift , ctrl bool ) bool {
65+ func ProcessKeyDown (wrapper common. CodeBoxWrapper , key string , shift , ctrl bool ) bool {
8866 ce := & codeEditor {CodeBoxWrapper : wrapper }
8967 return ce .handleKeyDown (key , shift , ctrl )
9068}
9169
92- type codeEditor struct { CodeBoxWrapper }
70+ type codeEditor struct { common. CodeBoxWrapper }
9371
9472func (ce * codeEditor ) handleKeyDown (key string , shift , ctrl bool ) bool {
9573 switch key {
@@ -184,7 +162,7 @@ func (ce *codeEditor) handleSpace(shift, ctrl bool) bool {
184162 write (newCode , code [caret :])
185163
186164 caret = lineStart + tabs + spaces
187- newSel := Selection {Start : caret , End : caret }
165+ newSel := common. Selection {Start : caret , End : caret }
188166 ce .SetCode (newSel , newCode .String ())
189167 return true
190168}
@@ -215,7 +193,7 @@ func (ce *codeEditor) handleTab(shift, ctrl bool) bool {
215193func (ce * codeEditor ) addIndents () bool {
216194 lineSel := ce .getSelectedLines ()
217195 nonBlankLines := 0
218- ce .foreachLine (lineSel , func (line string , _ Selection ) bool {
196+ ce .foreachLine (lineSel , func (line string , _ common. Selection ) bool {
219197 if ! isBlankLine (line ) {
220198 nonBlankLines ++
221199 }
@@ -233,7 +211,7 @@ func (ce *codeEditor) addIndents() bool {
233211 newCode .Grow (len (code ) + nonBlankLines )
234212
235213 write (newCode , code [:lineSel .Start ])
236- ce .foreachLine (lineSel , func (line string , curLineSel Selection ) bool {
214+ ce .foreachLine (lineSel , func (line string , curLineSel common. Selection ) bool {
237215 if isBlankLine (line ) {
238216 write (newCode , line ) // Empty line, just add as-is.
239217 return true
@@ -253,7 +231,7 @@ func (ce *codeEditor) addIndents() bool {
253231func (ce * codeEditor ) removeIndents () bool {
254232 lineSel := ce .getSelectedLines ()
255233 indentedLines := 0
256- ce .foreachLine (lineSel , func (line string , _ Selection ) bool {
234+ ce .foreachLine (lineSel , func (line string , _ common. Selection ) bool {
257235 if line [0 ] == '\t' || line [0 ] == ' ' {
258236 indentedLines ++
259237 }
@@ -271,7 +249,7 @@ func (ce *codeEditor) removeIndents() bool {
271249 newCode .Grow (len (code ) - indentedLines ) // assumes tabs are being removed
272250
273251 write (newCode , code [:lineSel .Start ])
274- ce .foreachLine (lineSel , func (line string , curLineSel Selection ) bool {
252+ ce .foreachLine (lineSel , func (line string , curLineSel common. Selection ) bool {
275253 // Trim up to one tab or equivalent spaces.
276254 removeChars := 0
277255 for i := 0 ; i < len (line ); i ++ {
@@ -367,12 +345,12 @@ func (ce *codeEditor) handleSave(shift, ctrl bool) bool {
367345 return false
368346 }
369347
370- ce .EmitEvent (SaveEvent )
348+ ce .EmitEvent (common . SaveEvent )
371349 return true
372350}
373351
374352func (ce * codeEditor ) handleEscape () bool {
375- ce .EmitEvent (EscapeEvent )
353+ ce .EmitEvent (common . EscapeEvent )
376354 return true
377355}
378356
@@ -383,11 +361,11 @@ func (ce *codeEditor) handleUndo(shift, ctrl bool) bool {
383361 }
384362
385363 if shift {
386- ce .EmitEvent (RedoEvent )
364+ ce .EmitEvent (common . RedoEvent )
387365 return true
388366 }
389367
390- ce .EmitEvent (UndoEvent )
368+ ce .EmitEvent (common . UndoEvent )
391369 return true
392370}
393371
@@ -397,7 +375,7 @@ func (ce *codeEditor) handleRedo(shift, ctrl bool) bool {
397375 return false
398376 }
399377
400- ce .EmitEvent (RedoEvent )
378+ ce .EmitEvent (common . RedoEvent )
401379 return true
402380}
403381
@@ -411,7 +389,7 @@ func (ce *codeEditor) handleCommentToggle(shift, ctrl bool) bool {
411389 lineSel := ce .getSelectedLines ()
412390 containsOnlyBlankLines := true
413391 containsUncommentedLine := false
414- ce .foreachLine (lineSel , func (line string , _ Selection ) bool {
392+ ce .foreachLine (lineSel , func (line string , _ common. Selection ) bool {
415393 if trimmed := trimLeftSpace (line ); trimmed != `` {
416394 containsOnlyBlankLines = false
417395 if ! strings .HasPrefix (trimmed , commentPrefix ) {
@@ -438,10 +416,10 @@ func (ce *codeEditor) handleCommentToggle(shift, ctrl bool) bool {
438416
439417// addCommenting will add the comment prefix to each non-blank line in
440418// the given range including any lines that already are commented.
441- func (ce * codeEditor ) addCommenting (lineSel Selection ) {
419+ func (ce * codeEditor ) addCommenting (lineSel common. Selection ) {
442420 leastIndent := - 1
443421 nonBlankLines := 0
444- ce .foreachLine (lineSel , func (line string , _ Selection ) bool {
422+ ce .foreachLine (lineSel , func (line string , _ common. Selection ) bool {
445423 if trimmed := trimLeftSpace (line ); trimmed != `` {
446424 if indent := len (line ) - len (trimmed ); leastIndent < 0 || indent < leastIndent {
447425 leastIndent = indent
@@ -465,7 +443,7 @@ func (ce *codeEditor) addCommenting(lineSel Selection) {
465443 newCode .Grow (len (code ) + nonBlankLines * commentPrefixLen )
466444
467445 write (newCode , code [:lineSel .Start ])
468- ce .foreachLine (lineSel , func (line string , curLineSel Selection ) bool {
446+ ce .foreachLine (lineSel , func (line string , curLineSel common. Selection ) bool {
469447 if isBlankLine (line ) {
470448 write (newCode , line ) // Empty line, just add as-is.
471449 return true
@@ -483,15 +461,15 @@ func (ce *codeEditor) addCommenting(lineSel Selection) {
483461
484462// removeCommenting will uncomment any line that starts with the comment prefix
485463// (and preceding whitespace).
486- func (ce * codeEditor ) removeCommenting (lineSel Selection ) {
464+ func (ce * codeEditor ) removeCommenting (lineSel common. Selection ) {
487465 code := ce .Code ()
488466 sel := ce .GetSelection ()
489467 newSel := sel
490468 newCode := & strings.Builder {}
491469 newCode .Grow (len (code ))
492470
493471 write (newCode , code [:lineSel .Start ])
494- ce .foreachLine (lineSel , func (line string , curLineSel Selection ) bool {
472+ ce .foreachLine (lineSel , func (line string , curLineSel common. Selection ) bool {
495473 if trimmed := trimLeftSpace (line ); trimmed != `` {
496474 if index := strings .Index (line , commentPrefix ); index >= 0 {
497475 write (newCode , line [:index ])
@@ -514,11 +492,11 @@ func (ce *codeEditor) removeCommenting(lineSel Selection) {
514492// or at the front of all the code.
515493// The returned end should be after the "\n" after the selection
516494// or at the end of all the code.
517- func (ce * codeEditor ) getSelectedLines () Selection {
495+ func (ce * codeEditor ) getSelectedLines () common. Selection {
518496 code := ce .Code ()
519497 codeLen := len (code )
520498 sel := ce .GetSelection ()
521- lineSel := Selection {Start : 0 , End : codeLen }
499+ lineSel := common. Selection {Start : 0 , End : codeLen }
522500 if inRange (sel .Start , 0 , codeLen ) {
523501 lineSel .Start = findStartOfLastLine (code [:sel .Start ])
524502 }
@@ -542,12 +520,12 @@ func (ce *codeEditor) getSelectedLines() Selection {
542520//
543521// If the yield function returns false, iteration stops and
544522// foreachLine returns false. Otherwise, it returns true.
545- func (ce * codeEditor ) foreachLine (sel Selection , yield func (line string , curLineSel Selection ) bool ) bool {
523+ func (ce * codeEditor ) foreachLine (sel common. Selection , yield func (line string , curLineSel common. Selection ) bool ) bool {
546524 code := ce .Code ()
547525 for i := sel .Start ; i < sel .End ; {
548526 lineEnd := findEndOfLineAfter (i , code [:sel .End ])
549527 line := code [i :lineEnd ]
550- if ! yield (line , Selection {i , lineEnd }) {
528+ if ! yield (line , common. Selection {Start : i , End : lineEnd }) {
551529 return false
552530 }
553531 i = lineEnd
@@ -568,7 +546,7 @@ func (ce *codeEditor) insertPair(ctrl bool, before, after string) bool {
568546func (ce * codeEditor ) insertAtSelection (before , after string , keepSelection bool ) {
569547 code := ce .Code ()
570548 sel := ce .GetSelection ()
571- newSel := Selection {Start : sel .Start , End : sel .Start } // set both to start initially
549+ newSel := common. Selection {Start : sel .Start , End : sel .Start } // set both to start initially
572550
573551 beforeLen := len (before )
574552 afterLen := len (after )
@@ -670,7 +648,7 @@ func inRange(value, start, end int) bool {
670648// if the current selection is after the given limit.
671649// This moves the selection based on where new text is being inserted at or
672650// removed from the limit position.
673- func adjustSel (newSel * Selection , curSel Selection , limit , adjustment int ) {
651+ func adjustSel (newSel * common. Selection , curSel common. Selection , limit , adjustment int ) {
674652 if curSel .Start > limit {
675653 newSel .Start += adjustment
676654 }
0 commit comments