1
1
import PropTypes from 'prop-types' ;
2
- import React from 'react' ;
2
+ import React , { useState , useEffect } from 'react' ;
3
3
import CodeMirror from 'codemirror' ;
4
4
import { Encode } from 'console-feed' ;
5
5
6
6
import RightArrowIcon from '../../../images/right-arrow.svg' ;
7
7
import { dispatch } from '../../../utils/dispatcher' ;
8
8
9
+ // heavily inspired by
10
+ // https://github.com/codesandbox/codesandbox-client/blob/92a1131f4ded6f7d9c16945dc7c18aa97c8ada27/packages/app/src/app/components/Preview/DevTools/Console/Input/index.tsx
11
+
9
12
class ConsoleInput extends React . Component {
13
+ constructor ( props ) {
14
+ super ( props ) ;
15
+ this . state = {
16
+ commandHistory : [ ] ,
17
+ commandCursor : - 1
18
+ } ;
19
+ }
20
+
10
21
componentDidMount ( ) {
11
22
this . _cm = CodeMirror ( this . codemirrorContainer , { // eslint-disable-line
12
23
theme : `p5-${ this . props . theme } ` ,
@@ -16,15 +27,10 @@ class ConsoleInput extends React.Component {
16
27
inputStyle : 'contenteditable'
17
28
} ) ;
18
29
19
- this . _cm . setOption ( 'extraKeys' , {
20
- Up : cm => cm . undo ( ) ,
21
- Down : cm => cm . redo ( )
22
- } ) ;
23
-
24
- this . _cm . setCursor ( { line : 1 , ch : 5 } ) ;
25
-
26
30
this . _cm . on ( 'keydown' , ( cm , e ) => {
27
- if ( e . keyCode === 13 ) {
31
+ if ( e . key === 'Enter' && ! e . shiftKey ) {
32
+ e . preventDefault ( ) ;
33
+ e . stopPropagation ( ) ;
28
34
const value = cm . getValue ( ) ;
29
35
if ( value . trim ( ' ' ) === '' ) {
30
36
return false ;
@@ -37,23 +43,51 @@ class ConsoleInput extends React.Component {
37
43
} ) ;
38
44
this . props . dispatchConsoleEvent ( consoleEvent ) ;
39
45
cm . setValue ( '' ) ;
40
- }
41
- return true ;
42
- } ) ;
46
+ this . setState ( state => ( {
47
+ commandCursor : - 1 ,
48
+ commandHistory : [ value , ...state . commandHistory ] ,
49
+ } ) ) ;
50
+ } else if ( e . key === 'ArrowUp' ) {
51
+ const lineNumber = this . _cm . getDoc ( ) . getCursor ( ) . line ;
52
+ if ( lineNumber !== 0 ) {
53
+ return false ;
54
+ }
43
55
44
- this . _cm . on ( 'beforeChange' , ( cm , changeObj ) => {
45
- const typedNewLine = changeObj . origin === '+input' && changeObj . text . join ( '' ) === '' ;
46
- if ( typedNewLine ) {
47
- return changeObj . cancel ( ) ;
48
- }
56
+ // also need to set cursor position
57
+ this . setState ( ( state ) => {
58
+ const newCursor = Math . min (
59
+ state . commandCursor + 1 ,
60
+ state . commandHistory . length - 1
61
+ ) ;
62
+ this . _cm
63
+ . getDoc ( )
64
+ . setValue ( state . commandHistory [ newCursor ] || '' ) ;
65
+ const cursorPos = this . _cm . getDoc ( ) . getLine ( 0 ) . length - 1 ;
66
+ console . log ( cursorPos ) ;
67
+ this . _cm . setCursor ( { line : 0 , ch : cursorPos } ) ;
68
+ return { commandCursor : newCursor } ;
69
+ } ) ;
70
+ } else if ( e . key === 'ArrowDown' ) {
71
+ const lineNumber = this . _cm . getDoc ( ) . getCursor ( ) . line ;
72
+ const lineCount = this . _cm . getValue ( ) . split ( '\n' ) . length ;
73
+ if ( lineNumber + 1 !== lineCount ) {
74
+ return false ;
75
+ }
49
76
50
- const pastedNewLine = changeObj . origin === 'paste' && changeObj . text . length > 1 ;
51
- if ( pastedNewLine ) {
52
- const newText = changeObj . text . join ( ' ' ) ;
53
- return changeObj . update ( null , null , [ newText ] ) ;
77
+ // also need to set cursor position
78
+ this . setState ( ( state ) => {
79
+ const newCursor = Math . max ( state . commandCursor - 1 , - 1 ) ;
80
+ this . _cm
81
+ . getDoc ( )
82
+ . setValue ( state . commandHistory [ newCursor ] || '' ) ;
83
+ const newLineCount = this . _cm . getValue ( ) . split ( '\n' ) . length ;
84
+ const newLine = this . _cm . getDoc ( ) . getLine ( newLineCount ) ;
85
+ const cursorPos = newLine ? newLine . length - 1 : 1 ;
86
+ this . _cm . setCursor ( { line : lineCount , ch : cursorPos } ) ;
87
+ return { commandCursor : newCursor } ;
88
+ } ) ;
54
89
}
55
-
56
- return null ;
90
+ return true ;
57
91
} ) ;
58
92
59
93
this . _cm . getWrapperElement ( ) . style [ 'font-size' ] = `${ this . props . fontSize } px` ;
@@ -69,8 +103,6 @@ class ConsoleInput extends React.Component {
69
103
this . _cm = null ;
70
104
}
71
105
72
- // _cm: CodeMirror.Editor
73
-
74
106
render ( ) {
75
107
return (
76
108
< div
0 commit comments