11import  PropTypes  from  'prop-types' ; 
2- import  React  from  'react' ; 
2+ import  React ,   {   useState ,   useEffect   }  from  'react' ; 
33import  CodeMirror  from  'codemirror' ; 
44import  {  Encode  }  from  'console-feed' ; 
55
66import  RightArrowIcon  from  '../../../images/right-arrow.svg' ; 
77import  {  dispatch  }  from  '../../../utils/dispatcher' ; 
88
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+ 
912class  ConsoleInput  extends  React . Component  { 
13+   constructor ( props )  { 
14+     super ( props ) ; 
15+     this . state  =  { 
16+       commandHistory : [ ] , 
17+       commandCursor : - 1 
18+     } ; 
19+   } 
20+ 
1021  componentDidMount ( )  { 
1122    this . _cm  =  CodeMirror ( this . codemirrorContainer ,  {  // eslint-disable-line 
1223      theme : `p5-${ this . props . theme }  , 
@@ -16,15 +27,10 @@ class ConsoleInput extends React.Component {
1627      inputStyle : 'contenteditable' 
1728    } ) ; 
1829
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- 
2630    this . _cm . on ( 'keydown' ,  ( cm ,  e )  =>  { 
27-       if  ( e . keyCode  ===  13 )  { 
31+       if  ( e . key  ===  'Enter'  &&  ! e . shiftKey )  { 
32+         e . preventDefault ( ) ; 
33+         e . stopPropagation ( ) ; 
2834        const  value  =  cm . getValue ( ) ; 
2935        if  ( value . trim ( ' ' )  ===  '' )  { 
3036          return  false ; 
@@ -37,23 +43,51 @@ class ConsoleInput extends React.Component {
3743        } ) ; 
3844        this . props . dispatchConsoleEvent ( consoleEvent ) ; 
3945        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+         } 
4355
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+         } 
4976
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+         } ) ; 
5489      } 
55- 
56-       return  null ; 
90+       return  true ; 
5791    } ) ; 
5892
5993    this . _cm . getWrapperElement ( ) . style [ 'font-size' ]  =  `${ this . props . fontSize }  ; 
@@ -69,8 +103,6 @@ class ConsoleInput extends React.Component {
69103    this . _cm  =  null ; 
70104  } 
71105
72-   // _cm: CodeMirror.Editor 
73- 
74106  render ( )  { 
75107    return  ( 
76108      < div 
0 commit comments