Thank you! That was the key idea: not generating the message at all in some circumstances, by doing a check in the subscription.
On Thursday, October 19, 2017 at 11:31:25 AM UTC-7, Simon wrote: > > I think you need to add a variable to your model that records whether the > editor is being used and then in yout subscription you have > > myKbdSubs model = > if model.editorBeingUsed then > Sub.none > else <whatever you already have> > > On Thursday, 19 October 2017 00:34:35 UTC+2, Dave Doty wrote: > > I am using this Ace Editor adapted to Elm: >> https://github.com/DenisKolodin/elm-ace >> >> However, my problem seems not specific to that editor, but applies to any >> program that wants to support an embedded editor whose contents can be >> updated by the program, and also that can respond to global keypress events. >> >> The editor text can be updated either by >> >> 1) the user typing, or >> 2) the program updating the text (e.g., pressing a "load default text" >> button) >> >> The user can also press some keyboard shortcuts (',' and '.') to do >> other actions. These are handled by my update function: >> >> update msg model = >> ... >> KeyMsg keyCode -> >> if keyCode == Char.toCode ',' then >> update Backward model >> else if keyCode == Char.toCode '.' then >> update Forward model >> else >> ( model, Cmd.none ) >> >> This is called whenever the user presses any key because of this >> subscription that uses the elm-lang/keyboard library: >> >> subscriptions model = >> Keyboard.presses KeyMsg >> >> The problem is that all of the keypresses made when editing cause the >> update function to be called, not just the two that I care about. Most of >> them are not ',' or '.' so the model is returned unchanged in the else >> clause above. >> >> But this causes the following problem: in my view function, the editor >> updates its contents to be whatever the model says the text should be (for >> instance, the user may press a button that loads some default text): >> >> view model = >> ... >> Ace.toHtml >> [ Ace.value model.text -- updates editor to display model. >> text >> , Ace.onSourceChange NewText -- updates model.text to be latest >> editor contents >> ] >> [] >> >> The purpose of onSourceChange above is to trigger another call to the >> update function, which allows me to update my model text with the new >> editor contents. In other words, the two lines above are the bi-directional >> data binding between model.text and the editor's text contents. The >> second one implies a call to the update function: >> >> update msg model = >> ... >> NewText newText -> >> ( {model | text = newText}, Cmd.none ) >> >> The problem is that the Elm runtime is ordering events so that the text >> in the editor never gets updated when the user tries to type new text. >> >> Here is the order of events: >> >> 1. User types to edit text in the editor. >> 2. Because of the subscription I registered for global keystroke >> events, Elm runtime calls update with the message KeyMsg indicating >> which key was pressed. >> 3. Model is updated (in the KeyMsg case of my update function) to the >> "new" model, but most of the time this is identical to the old model >> since >> only ',' and '.' actually return a changed model. Importantly, this >> is the *old* text, not containing the new character that the user >> typed. >> 4. The view function is called, and the Ace.toHtml updates the text >> contents of the editor to be what the model.text field is... which erases >> in the editor the new character that the user just tried to enter, since >> model.text still has the old, pre-keystroke text. >> 5. The update function is called with a NewText message, but it's too >> late. By now the editor has had its new text erased and replaced with the >> old text. Ideally, this event would have happened in between steps 1 and >> 2, >> but steps 2,3,4 seem to happen before this does. >> >> I'm not sure how to get around this. >> >> *Idea 1:* figure out a way to prevent the update function from being >> called at all when a keystroke other than ',' or '.' occurs. This is not >> ideal because then they can't type ',' or '.' in the editor, but it would >> be a workaround because I could perhaps assign Ctrl+... keys or something. >> >> *Idea 2:* Re-order the updates so that, when the user enters new text in >> the editor, it is guaranteed that update is called with the NewText message >> before it is called with the KeyMsg message. I don't know of any way to do >> this. >> >> *Idea 3:* Re-design how I'm passing messages through the system so that, >> no matter the order in which messages are delivered, if the user tries to >> enter new text, eventually that new text makes its way into the model. >> >> *Idea 4:* don't use the Keyboard library to respond to global keypress >> events, and find something that is more specific to what I want (to give >> the user a couple of keyboard shortcuts, without calling the update >> function every time any key is pressed). Suggestions for such a library? >> > > -- You received this message because you are subscribed to the Google Groups "Elm Discuss" group. To unsubscribe from this group and stop receiving emails from it, send an email to [email protected]. For more options, visit https://groups.google.com/d/optout.
