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 } px` ;
@@ -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