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 elm-discuss+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to