import TextEditor from "../components/TextEditor" ; import { EditorState } from "@codemirror/state" ; import EditorTab from "../modules/editor_tab" ; import { FileFormat } from "../utils/client" ; import { basicSetup , EditorView } from "@codemirror/basic-setup" ; import { keymap , KeyBinding , Command } from "@codemirror/view" ; import { javascript } from "@codemirror/lang-javascript" ; import { rust } from "@codemirror/lang-rust" ; import { clientState } from "../utils/atoms" ; import { getRecoil } from "recoil-nexus" ; import { Tab } from "../modules/tab" ; interface SavedState { scrollHeight : number ; } function getKeymap ( tab ) { const save = ( ) => { tab . save ( ) ; return false ; } ; const conf = [ { key : "ctrl-s" , run : save } ] ; return keymap . of ( conf ) ; } function createDefaulState ( { initialValue , tab , } ) { return EditorState . create ( { extensions : [ basicSetup , javascript ( ) , rust ( ) , getKeymap ( tab ) ] , doc : initialValue , } ) ; } /**
 * A tab that displays a CodeMirror editor inside it
 */ class TextEditorTab extends EditorTab { private state : SavedState = { scrollHeight : 0 , } ; private view : EditorView ; public setEditedComp : ( state : boolean ) => void ; private path : string ; param path param initialContent constructor ( filename , path , initialContent ) { super ( filename , path , initialContent ) ; this . path = path ; this . setEditedComp = ( ) => { console . error ( "Tried changing an unmounted tab" ) ; } ; this . view = new EditorView ( { state : createDefaulState ( { initialValue : initialContent , tab : this , } ) , dispatch : ( tx ) => { if ( tx . docChanged ) setEdited ( true ) ; this . view . update ( [ tx ] ) ; } , } ) ; const saveScroll = ( height ) => { this . state . scrollHeight = height ; } ; const setEdited = ( state ) => { if ( this . edited != state ) { this . setEdited ( state ) ; } this . edited = state ; } ; this . container = ( { setEdited } ) => { this . setEditedComp = setEdited ; return ( < TextEditor view = { this . view } scrollHeight = { this . state . scrollHeight } saveScroll = { saveScroll } / > ) ; } ; } public close ( ) { this . view . destroy ( ) ; return ; } static isCompatible ( format ) { return format !== "Binary" ; } public setEdited ( state ) { if ( this . edited != state ) { this . setEditedComp ( state ) ; } this . edited = state ; } public async save ( ) { if ( this . edited ) { const client = getRecoil ( clientState ) ; const newContent = this . view . state . doc . sliceString ( 0 ) ; await client . write_file_by_path ( this . path , newContent , "local" ) ; this . setEdited ( false ) ; } return ; } } export default TextEditorTab ;