Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
B
baas-ide
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
JIRA
JIRA
Merge Requests
1
Merge Requests
1
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
guxukai
baas-ide
Commits
77810a86
Commit
77810a86
authored
Oct 12, 2021
by
yann300
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
reducer refactor
parent
bc4cee99
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
183 additions
and
94 deletions
+183
-94
editor.js
apps/remix-ide/src/app/editor/editor.js
+32
-21
editor.ts
libs/remix-ui/editor/src/lib/actions/editor.ts
+125
-0
remix-ui-editor.tsx
libs/remix-ui/editor/src/lib/remix-ui-editor.tsx
+26
-73
No files found.
apps/remix-ide/src/app/editor/editor.js
View file @
77810a86
...
...
@@ -40,7 +40,6 @@ class Editor extends Plugin {
this
.
renderComponent
()
})
this
.
currentTheme
=
translateTheme
(
this
.
_deps
.
themeModule
.
currentTheme
())
this
.
models
=
[]
// Init
this
.
event
=
new
EventManager
()
this
.
sessions
=
{}
...
...
@@ -65,12 +64,14 @@ class Editor extends Plugin {
rs
:
'rust'
}
this
.
onBreakPointAdded
=
(
file
,
line
)
=>
this
.
triggerEvent
(
'breakpointAdded'
,
[
file
,
line
])
this
.
onBreakPointCleared
=
(
file
,
line
)
=>
this
.
triggerEvent
(
'breakpointCleared'
,
[
file
,
line
])
this
.
activated
=
false
this
.
onDidChangeContent
=
(
file
)
=>
this
.
_onChange
(
file
)
this
.
onEditorMounted
=
()
=>
this
.
triggerEvent
(
'editorMounted'
,
[])
this
.
events
=
{
onBreakPointAdded
:
(
file
,
line
)
=>
this
.
triggerEvent
(
'breakpointAdded'
,
[
file
,
line
]),
onBreakPointCleared
:
(
file
,
line
)
=>
this
.
triggerEvent
(
'breakpointCleared'
,
[
file
,
line
]),
onDidChangeContent
:
(
file
)
=>
this
.
_onChange
(
file
),
onEditorMounted
:
()
=>
this
.
triggerEvent
(
'editorMounted'
,
[])
}
// to be implemented by the react component
this
.
api
=
{}
...
...
@@ -96,7 +97,15 @@ class Editor extends Plugin {
renderComponent
()
{
ReactDOM
.
render
(
<
EditorUI
editorAPI
=
{
this
.
api
}
theme
=
{
this
.
currentTheme
}
currentFile
=
{
this
.
currentFile
}
sourceAnnotationsPerFile
=
{
this
.
sourceAnnotationsPerFile
}
markerPerFile
=
{
this
.
markerPerFile
}
onBreakPointAdded
=
{
this
.
onBreakPointAdded
}
onBreakPointCleared
=
{
this
.
onBreakPointCleared
}
onDidChangeContent
=
{
this
.
onDidChangeContent
}
onEditorMounted
=
{
this
.
onEditorMounted
}
/
>
<
EditorUI
editorAPI
=
{
this
.
api
}
theme
=
{
this
.
currentTheme
}
currentFile
=
{
this
.
currentFile
}
sourceAnnotationsPerFile
=
{
this
.
sourceAnnotationsPerFile
}
markerPerFile
=
{
this
.
markerPerFile
}
events
=
{
this
.
events
}
plugin
=
{
this
}
/
>
,
this
.
el
)
}
...
...
@@ -106,6 +115,7 @@ class Editor extends Plugin {
}
onActivation
()
{
this
.
activated
=
true
this
.
on
(
'sidePanel'
,
'focusChanged'
,
(
name
)
=>
{
this
.
keepDecorationsFor
(
name
,
'sourceAnnotationsPerFile'
)
this
.
keepDecorationsFor
(
name
,
'markerPerFile'
)
...
...
@@ -120,10 +130,6 @@ class Editor extends Plugin {
this
.
off
(
'sidePanel'
,
'pluginDisabled'
)
}
setTheme
(
type
)
{
this
.
api
.
setTheme
(
this
.
_themes
[
type
])
}
_onChange
(
file
)
{
const
currentFile
=
this
.
_deps
.
config
.
get
(
'currentFile'
)
if
(
!
currentFile
)
{
...
...
@@ -180,18 +186,19 @@ class Editor extends Plugin {
* @param {string} mode Mode for this file [Default is `text`]
*/
_createSession
(
path
,
content
,
mode
)
{
this
.
api
.
addModel
(
content
,
mode
,
path
,
false
)
if
(
!
this
.
activated
)
return
this
.
emit
(
'addModel'
,
content
,
mode
,
path
,
false
)
return
{
path
,
language
:
mode
,
setValue
:
(
content
)
=>
{
this
.
api
.
setValue
(
path
,
content
)
this
.
emit
(
'setValue'
,
path
,
content
)
},
getValue
:
()
=>
{
return
this
.
api
.
getValue
(
path
,
content
)
},
dispose
:
()
=>
{
this
.
api
.
disposeModel
(
path
)
this
.
emit
(
'disposeModel'
,
path
)
}
}
}
...
...
@@ -208,9 +215,9 @@ class Editor extends Plugin {
* Display an Empty read-only session
*/
displayEmptyReadOnlySession
()
{
if
(
!
this
.
activated
)
return
this
.
currentFile
=
null
this
.
api
.
addModel
(
''
,
'text'
,
'_blank'
,
true
)
this
.
api
.
setCurrentPath
(
'_blank'
)
this
.
emit
(
'addModel'
,
''
,
'text'
,
'_blank'
,
true
)
}
/**
...
...
@@ -324,9 +331,10 @@ class Editor extends Plugin {
* @param {number} incr The amount of pixels to add to the font.
*/
editorFontSize
(
incr
)
{
if
(
!
this
.
activated
)
return
const
newSize
=
this
.
api
.
getFontSize
()
+
incr
if
(
newSize
>=
6
)
{
this
.
api
.
setFontSize
(
newSize
)
this
.
emit
(
'setFontSize'
,
newSize
)
}
}
...
...
@@ -335,7 +343,8 @@ class Editor extends Plugin {
* @param {boolean} useWrapMode Enable (or disable) wrap mode
*/
resize
(
useWrapMode
)
{
this
.
api
.
setWordWrap
(
useWrapMode
)
if
(
!
this
.
activated
)
return
this
.
emit
(
'setWordWrap'
,
useWrapMode
)
}
/**
...
...
@@ -344,8 +353,9 @@ class Editor extends Plugin {
* @param {number} col
*/
gotoLine
(
line
,
col
)
{
this
.
api
.
focus
()
this
.
api
.
revealLine
(
line
+
1
,
col
)
if
(
!
this
.
activated
)
return
this
.
emit
(
'focus'
)
this
.
emit
(
'revealLine'
,
line
+
1
,
col
)
}
/**
...
...
@@ -353,7 +363,8 @@ class Editor extends Plugin {
* @param {number} line The line to scroll to
*/
scrollToLine
(
line
)
{
this
.
api
.
revealLine
(
line
)
if
(
!
this
.
activated
)
return
this
.
emit
(
'revealLine'
,
line
,
0
)
}
/**
...
...
libs/remix-ui/editor/src/lib/actions/editor.ts
0 → 100644
View file @
77810a86
export
interface
Action
{
type
:
string
;
payload
:
Record
<
string
,
any
>
monaco
:
any
}
export
const
initialState
=
{}
export
const
reducerActions
=
(
models
=
initialState
,
action
:
Action
)
=>
{
const
monaco
=
action
.
monaco
switch
(
action
.
type
)
{
case
'ADD_MODEL'
:
{
if
(
!
monaco
)
return
models
const
uri
=
action
.
payload
.
uri
const
value
=
action
.
payload
.
value
const
language
=
action
.
payload
.
language
const
readOnly
=
action
.
payload
.
readOnly
if
(
models
[
uri
])
return
models
// already existing
const
model
=
monaco
.
editor
.
createModel
(
value
,
language
,
monaco
.
Uri
.
parse
(
uri
))
model
.
onDidChangeContent
(()
=>
action
.
payload
.
onDidChangeContent
(
uri
))
models
[
uri
]
=
{
language
,
uri
,
readOnly
,
model
}
return
models
}
case
'DISPOSE_MODEL'
:
{
const
uri
=
action
.
payload
.
uri
const
model
=
models
[
uri
]?.
model
if
(
model
)
model
.
dispose
()
delete
models
[
uri
]
return
models
}
case
'SET_VALUE'
:
{
if
(
!
monaco
.
editor
)
return
models
const
uri
=
action
.
payload
.
uri
const
value
=
action
.
payload
.
value
const
model
=
models
[
uri
]?.
model
if
(
model
)
{
model
.
setValue
(
value
)
}
return
models
}
case
'REVEAL_LINE'
:
{
if
(
!
monaco
.
editor
)
return
models
const
line
=
action
.
payload
.
line
const
column
=
action
.
payload
.
column
monaco
.
editor
.
revealLine
(
line
)
monaco
.
editor
.
setPosition
({
column
,
lineNumber
:
line
})
return
models
}
case
'FOCUS'
:
{
if
(
!
monaco
.
editor
)
return
models
monaco
.
editor
.
focus
()
return
models
}
case
'SET_FONTSIZE'
:
{
if
(
!
monaco
.
editor
)
return
models
const
size
=
action
.
payload
.
size
monaco
.
editor
.
updateOptions
({
fontSize
:
size
})
return
models
}
case
'SET_WORDWRAP'
:
{
if
(
!
monaco
.
editor
)
return
models
const
wrap
=
action
.
payload
.
wrap
monaco
.
editor
.
updateOptions
({
wordWrap
:
wrap
?
'on'
:
'off'
})
return
models
}
}
}
export
const
reducerListener
=
(
plugin
,
dispatch
,
monaco
)
=>
{
plugin
.
on
(
'editor'
,
'addModel'
,
(
value
,
language
,
uri
,
readOnly
)
=>
{
dispatch
({
type
:
'ADD_MODEL'
,
payload
:
{
uri
,
value
,
language
,
readOnly
},
monaco
})
})
plugin
.
on
(
'editor'
,
'disposeModel'
,
(
uri
)
=>
{
dispatch
({
type
:
'DISPOSE_MODEL'
,
payload
:
{
uri
},
monaco
})
})
plugin
.
on
(
'editor'
,
'setValue'
,
(
uri
,
value
)
=>
{
dispatch
({
type
:
'SET_VALUE'
,
payload
:
{
uri
,
value
},
monaco
})
})
plugin
.
on
(
'editor'
,
'revealLine'
,
(
line
,
column
)
=>
{
dispatch
({
type
:
'REVEAL_LINE'
,
payload
:
{
line
,
column
},
monaco
})
})
plugin
.
on
(
'editor'
,
'focus'
,
()
=>
{
dispatch
({
type
:
'FOCUS'
,
payload
:
{},
monaco
})
})
plugin
.
on
(
'editor'
,
'setFontSize'
,
(
size
)
=>
{
dispatch
({
type
:
'SET_FONTSIZE'
,
payload
:
{
size
},
monaco
})
})
plugin
.
on
(
'editor'
,
'setWordWrap'
,
(
wrap
)
=>
{
dispatch
({
type
:
'SET_WORDWRAP'
,
payload
:
{
wrap
},
monaco
})
})
}
libs/remix-ui/editor/src/lib/remix-ui-editor.tsx
View file @
77810a86
import
React
,
{
useState
,
useRef
,
useEffect
}
from
'react'
import
React
,
{
useState
,
useRef
,
useEffect
,
useReducer
}
from
'react'
import
Editor
from
'@monaco-editor/react'
import
{
reducerActions
,
reducerListener
,
initialState
}
from
'./actions/editor'
import
'./remix-ui-editor.css'
...
...
@@ -44,31 +45,29 @@ type sourceMarkerMap = {
/* eslint-disable-next-line */
export
interface
EditorUIProps
{
activated
:
boolean
theme
:
string
currentFile
:
string
sourceAnnotationsPerFile
:
sourceAnnotationMap
markerPerFile
:
sourceMarkerMap
onBreakPointAdded
:
(
file
:
string
,
line
:
number
)
=>
void
onBreakPointCleared
:
(
file
:
string
,
line
:
number
)
=>
void
onDidChangeContent
:
(
file
:
string
)
=>
void
onEditorMounted
:
()
=>
void
events
:
{
onBreakPointAdded
:
(
file
:
string
,
line
:
number
)
=>
void
onBreakPointCleared
:
(
file
:
string
,
line
:
number
)
=>
void
onDidChangeContent
:
(
file
:
string
)
=>
void
onEditorMounted
:
()
=>
void
}
plugin
:
{
on
:
(
plugin
:
string
,
event
:
string
,
listener
:
any
)
=>
void
}
editorAPI
:{
findMatches
:
(
uri
:
string
,
value
:
string
)
=>
any
addModel
:
(
value
:
string
,
language
:
string
,
uri
:
string
,
readOnly
:
boolean
)
=>
void
disposeModel
:
(
uri
:
string
)
=>
void
,
setFontSize
:
(
fontSize
:
number
)
=>
void
,
getFontSize
:
()
=>
number
,
getValue
:
(
uri
:
string
)
=>
string
getCursorPosition
:
()
=>
cursorPosition
revealLine
:
(
line
:
number
,
column
:
number
)
=>
void
focus
:
()
=>
void
setWordWrap
:
(
wrap
:
boolean
)
=>
void
setValue
:
(
uri
:
string
,
value
:
string
)
=>
void
}
}
export
const
EditorUI
=
(
props
:
EditorUIProps
)
=>
{
const
[
models
,
setModels
]
=
useState
({})
const
[,
setCurrentBreakpoints
]
=
useState
({})
const
[
currentAnnotations
,
setCurrentAnnotations
]
=
useState
({})
const
[
currentMarkers
,
setCurrentMarkers
]
=
useState
({})
...
...
@@ -76,6 +75,8 @@ export const EditorUI = (props: EditorUIProps) => {
const
monacoRef
=
useRef
(
null
)
const
currentFileRef
=
useRef
(
''
)
const
[
editorModelsState
,
dispatch
]
=
useReducer
(
reducerActions
,
initialState
)
useEffect
(()
=>
{
if
(
!
monacoRef
.
current
)
return
monacoRef
.
current
.
editor
.
setTheme
(
props
.
theme
)
...
...
@@ -83,7 +84,7 @@ export const EditorUI = (props: EditorUIProps) => {
const
setAnnotationsbyFile
=
(
uri
)
=>
{
if
(
props
.
sourceAnnotationsPerFile
[
uri
])
{
const
model
=
models
[
uri
]?.
model
const
model
=
editorModelsState
[
uri
]?.
model
const
newAnnotations
=
[]
for
(
const
annotation
of
props
.
sourceAnnotationsPerFile
[
uri
])
{
if
(
!
annotation
.
hide
)
{
...
...
@@ -106,7 +107,7 @@ export const EditorUI = (props: EditorUIProps) => {
const
setMarkerbyFile
=
(
uri
)
=>
{
if
(
props
.
markerPerFile
[
uri
])
{
const
model
=
models
[
uri
]?.
model
const
model
=
editorModelsState
[
uri
]?.
model
const
newMarkers
=
[]
for
(
const
marker
of
props
.
markerPerFile
[
uri
])
{
if
(
!
marker
.
hide
)
{
...
...
@@ -134,8 +135,8 @@ export const EditorUI = (props: EditorUIProps) => {
useEffect
(()
=>
{
if
(
!
editorRef
.
current
)
return
currentFileRef
.
current
=
props
.
currentFile
editorRef
.
current
.
setModel
(
models
[
props
.
currentFile
].
model
)
editorRef
.
current
.
updateOptions
({
readOnly
:
models
[
props
.
currentFile
].
readOnly
})
editorRef
.
current
.
setModel
(
editorModelsState
[
props
.
currentFile
].
model
)
editorRef
.
current
.
updateOptions
({
readOnly
:
editorModelsState
[
props
.
currentFile
].
readOnly
})
setAnnotationsbyFile
(
props
.
currentFile
)
setMarkerbyFile
(
props
.
currentFile
)
},
[
props
.
currentFile
])
...
...
@@ -150,80 +151,31 @@ export const EditorUI = (props: EditorUIProps) => {
props
.
editorAPI
.
findMatches
=
(
uri
:
string
,
value
:
string
)
=>
{
if
(
!
editorRef
.
current
)
return
const
model
=
models
[
uri
]?.
model
const
model
=
editorModelsState
[
uri
]?.
model
if
(
model
)
return
model
.
findMatches
(
value
)
}
props
.
editorAPI
.
addModel
=
(
value
:
string
,
language
:
string
,
uri
:
string
,
readOnly
:
boolean
)
=>
{
if
(
!
monacoRef
.
current
)
return
if
(
models
[
uri
])
return
// already existing
const
model
=
monacoRef
.
current
.
editor
.
createModel
(
value
,
language
,
monacoRef
.
current
.
Uri
.
parse
(
uri
))
model
.
onDidChangeContent
(()
=>
props
.
onDidChangeContent
(
uri
))
setModels
(
prevState
=>
{
prevState
[
uri
]
=
{
language
,
uri
,
readOnly
,
model
}
return
prevState
})
}
props
.
editorAPI
.
disposeModel
=
(
uri
:
string
)
=>
{
const
model
=
models
[
uri
]?.
model
if
(
model
)
model
.
dispose
()
setModels
(
prevState
=>
{
delete
prevState
[
uri
]
return
prevState
})
}
props
.
editorAPI
.
getValue
=
(
uri
:
string
)
=>
{
if
(
!
editorRef
.
current
)
return
const
model
=
models
[
uri
]?.
model
const
model
=
editorModelsState
[
uri
]?.
model
if
(
model
)
{
return
model
.
getValue
()
}
}
props
.
editorAPI
.
setValue
=
(
uri
:
string
,
value
:
string
)
=>
{
if
(
!
editorRef
.
current
)
return
const
model
=
models
[
uri
]?.
model
if
(
model
)
{
model
.
setValue
(
value
)
}
}
props
.
editorAPI
.
getCursorPosition
=
()
=>
{
if
(
!
monacoRef
.
current
)
return
const
model
=
models
[
currentFileRef
.
current
]?.
model
const
model
=
editorModelsState
[
currentFileRef
.
current
]?.
model
if
(
model
)
{
return
model
.
getOffsetAt
(
editorRef
.
current
.
getPosition
())
}
}
props
.
editorAPI
.
revealLine
=
(
line
:
number
,
column
:
number
)
=>
{
if
(
!
editorRef
.
current
)
return
editorRef
.
current
.
revealLine
(
line
)
editorRef
.
current
.
setPosition
({
column
,
lineNumber
:
line
})
}
props
.
editorAPI
.
focus
=
()
=>
{
if
(
!
editorRef
.
current
)
return
editorRef
.
current
.
focus
()
}
props
.
editorAPI
.
setFontSize
=
(
size
:
number
)
=>
{
if
(
!
editorRef
.
current
)
return
editorRef
.
current
.
updateOptions
({
fontSize
:
size
})
}
props
.
editorAPI
.
getFontSize
=
()
=>
{
if
(
!
editorRef
.
current
)
return
return
editorRef
.
current
.
getOption
(
42
).
fontSize
}
props
.
editorAPI
.
setWordWrap
=
(
wrap
:
boolean
)
=>
{
if
(
!
editorRef
.
current
)
return
editorRef
.
current
.
updateOptions
({
wordWrap
:
wrap
?
'on'
:
'off'
})
}
(
window
as
any
).
addRemixBreakpoint
=
(
position
)
=>
{
// make it available from e2e testing...
const
model
=
editorRef
.
current
.
getModel
()
if
(
model
)
{
...
...
@@ -232,11 +184,11 @@ export const EditorUI = (props: EditorUIProps) => {
if
(
!
prevState
[
currentFile
])
prevState
[
currentFile
]
=
{}
const
decoration
=
Object
.
keys
(
prevState
[
currentFile
]).
filter
((
line
)
=>
parseInt
(
line
)
===
position
.
lineNumber
)
if
(
decoration
.
length
)
{
props
.
onBreakPointCleared
(
currentFile
,
position
.
lineNumber
)
props
.
events
.
onBreakPointCleared
(
currentFile
,
position
.
lineNumber
)
model
.
deltaDecorations
([
prevState
[
currentFile
][
position
.
lineNumber
]],
[])
delete
prevState
[
currentFile
][
position
.
lineNumber
]
}
else
{
props
.
onBreakPointAdded
(
currentFile
,
position
.
lineNumber
)
props
.
events
.
onBreakPointAdded
(
currentFile
,
position
.
lineNumber
)
const
decorationIds
=
model
.
deltaDecorations
([],
[{
range
:
new
monacoRef
.
current
.
Range
(
position
.
lineNumber
,
1
,
position
.
lineNumber
,
1
),
options
:
{
...
...
@@ -254,7 +206,7 @@ export const EditorUI = (props: EditorUIProps) => {
function
handleEditorDidMount
(
editor
)
{
editorRef
.
current
=
editor
monacoRef
.
current
.
editor
.
setTheme
(
props
.
theme
)
props
.
onEditorMounted
()
props
.
events
.
onEditorMounted
()
editor
.
onMouseUp
((
e
)
=>
{
if
(
e
&&
e
.
target
&&
e
.
target
.
toString
().
startsWith
(
'GUTTER'
))
{
(
window
as
any
).
addRemixBreakpoint
(
e
.
target
.
position
)
...
...
@@ -264,6 +216,7 @@ export const EditorUI = (props: EditorUIProps) => {
function
handleEditorWillMount
(
monaco
)
{
monacoRef
.
current
=
monaco
reducerListener
(
props
.
plugin
,
dispatch
,
monacoRef
.
current
)
// see https://microsoft.github.io/monaco-editor/playground.html#customizing-the-appearence-exposed-colors
const
backgroundColor
=
window
.
getComputedStyle
(
document
.
documentElement
).
getPropertyValue
(
'--light'
).
trim
()
const
infoColor
=
window
.
getComputedStyle
(
document
.
documentElement
).
getPropertyValue
(
'--info'
).
trim
()
...
...
@@ -285,7 +238,7 @@ export const EditorUI = (props: EditorUIProps) => {
width=
"100%"
height=
"100%"
path=
{
props
.
currentFile
}
language=
{
models
[
props
.
currentFile
]
?
models
[
props
.
currentFile
].
language
:
'text'
}
language=
{
editorModelsState
[
props
.
currentFile
]
?
editorModelsState
[
props
.
currentFile
].
language
:
'text'
}
onMount=
{
handleEditorDidMount
}
beforeMount=
{
handleEditorWillMount
}
options=
{
{
glyphMargin
:
true
}
}
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment