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.

Reply via email to