From taleinat at gmail.com Tue Jun 10 20:30:43 2014 From: taleinat at gmail.com (Tal Einat) Date: Tue, 10 Jun 2014 21:30:43 +0300 Subject: [Idle-dev] Requesting a review of the revised extension config dialog before commit Message-ID: Hi everyone, Saimadhav mentioned earlier this evening that the extension config dialog proposed on issue #3068 [1] will be useful later in his GSoC work. I recently uploaded a new patch, reworked to apply cleanly and work properly on recent Python 3. I'd very much appreciate a review of the new patch! I intend to apply this as my first direct commit to Python. - Tal Einat ..[1]: http://bugs.python.org/issue3068 -------------- next part -------------- An HTML attachment was scrubbed... URL: From saimadhavheblikar at gmail.com Wed Jun 11 08:39:22 2014 From: saimadhavheblikar at gmail.com (Saimadhav Heblikar) Date: Wed, 11 Jun 2014 12:09:22 +0530 Subject: [Idle-dev] KeyConfig, KeyBinding and other related issues. Message-ID: The following are the issues related to shortcuts, keybinding dialog, where the shortcuts are set and config-keys.def where the shortcuts are stored. 1) Issue12387: Very simple way to reproduce the bug: With/without CAPS, Ctrl + x key, performs Cut action(windows keyset). This is agreeable because both those keybindings are set. The bindings are and But, with/without CAPS, Ctrl + Shift + x key also performs Cut action. The bindings are and *Workaround*: Bind the redundant and to <>.(already exists). This has to be done for all existing key combinations. For sake of completeness, If the user wants Control + Shift + *x key*, we have to remove both from <> keybinding and add it to whatever binding that the user wants. This has to be done in the current validity checking method or a new parsing method. I have tested this solution, and am convinced it would work. 2) Issue11437: Its hard to explain this issue in short. Please read the issue at http://bugs.python.org/issue11437 Workaround: This is easy to solve, if we use the solution from issue12387. With the parser method, both "simple" and "advanced" dialogs will be parsed, and we will have a 1-to-1 mapping. For the case when someone tries to directly "hand-edit" the config files, with http://bugs.python.org/issue21696 and tests for the parser method in place, we should able to raise an earlier, ideally before IDLE starts. We should also be able to pinpoint where the error occurs. 3) Issue20580: This does not involve coding, but is about providing platform specific default config. This can only be done, once we agree on 1 and 2. 4) Issue21519: Again dependent on 1 and 2. Not too sure, if it is going to be an issue with 1 and 2. If we go ahead with 2, and have a parser method which is testable, we can also validate the "advanced" dialog. For other issues which are caused by typo in config, http://bugs.python.org/issue21696 along with testable parser method should catch them. ----------------- I plan to work on these issues in test driven style as suggested by Tal Einat, especially keeping in mind the above issues, their current outcome and the required outcome. -- Regards Saimadhav Heblikar From tjreedy at udel.edu Wed Jun 11 09:31:34 2014 From: tjreedy at udel.edu (Terry Reedy) Date: Wed, 11 Jun 2014 03:31:34 -0400 Subject: [Idle-dev] KeyConfig, KeyBinding and other related issues. In-Reply-To: References: Message-ID: <539805D6.8020201@udel.edu> On 6/11/2014 2:39 AM, Saimadhav Heblikar wrote: > The following are the issues related to shortcuts, keybinding dialog, > where the shortcuts are set and config-keys.def where the shortcuts > are stored. Great: I have been collecting a list of configuration and especially keybinding issues, with the thought of suggesting this as a coherent group of issues you could work on. 3068: extension CONFIG dialog, Tal new PATCH, review 12274: CONFIG syntax error crash 12387: CONFIG KEYboard shortcuts 4765: CONFIG custom KEYset deletion, patch fixes (Mark) 11437: CONFIG-KEY type causes crash; startup is inefficient. Serwy patch 1517993: CONFIG KEY and Macs: (me) Alt to Meta (closed) 20580: CONFIG KEY and and Macs 694339: dedenting with shift-tab CONFIG KEY I just added 21519. Related ideas I have not opened issues for: Save config-KEYs sorted on disk instead of when present in CONFIG DIALOG. Would be much easier to read, just a matter of when sort. Make CONFIG DIALOG wide enough for all KEY definitions. Also lengthen. Change some names so they sort better: possible example region-dedent, region-indent instead of dedent-region, indent-region. Since I have a backlog of new test files to review, + Tal's config-extensions patch (+ a patch by Lita), I was about to suggest that you find something like this (configuration and keybinding) to work on that Tal knows better than me, and could help you with. It would be great to fix some of these issues that have dragged on for years. If either of you think that some fixes need deeper changes than the typical surface patches, please say so so we can discuss. The better we make the tests, the more confidently we can consider refactorings. I will look at the specifics below tomorrow. I would like to see Tal's comments either by email or on the tracker. Terry > 1) Issue12387: Very simple way to reproduce the bug: > With/without CAPS, Ctrl + x key, performs Cut action(windows keyset). > This is agreeable because both those keybindings are set. The bindings > are > and > But, with/without CAPS, Ctrl + Shift + x key also performs Cut action. > The bindings are and > *Workaround*: > Bind the redundant and to > <>.(already exists). > > This has to be done for all existing key combinations. > For sake of completeness, If the user wants Control + Shift + *x key*, > we have to remove both from <> keybinding and add it to > whatever binding that the user wants. > This has to be done in the current validity checking method or a new > parsing method. > I have tested this solution, and am convinced it would work. > > > 2) Issue11437: Its hard to explain this issue in short. Please read the issue > at http://bugs.python.org/issue11437 > Workaround: > This is easy to solve, if we use the solution from issue12387. With > the parser method, both "simple" and "advanced" dialogs will be > parsed, and we will have a 1-to-1 mapping. > For the case when someone tries to directly "hand-edit" the config > files, with http://bugs.python.org/issue21696 and tests for the parser > method in place, we should able to raise an earlier, ideally before > IDLE starts. We should also be able to pinpoint where the error > occurs. > > > 3) Issue20580: This does not involve coding, but is about providing > platform specific default config. This can only be done, once we agree > on 1 and 2. > > > 4) Issue21519: Again dependent on 1 and 2. Not too sure, if it is > going to be an issue with 1 and 2. If we go ahead with 2, and have a > parser method which is testable, we can also validate the "advanced" > dialog. > > > For other issues which are caused by typo in config, > http://bugs.python.org/issue21696 along with testable parser method > should catch them. > ----------------- > > I plan to work on these issues in test driven style as suggested by > Tal Einat, especially keeping in mind the above issues, their current > outcome and the required outcome. PS. For me, feedback after every 'code unit' change* makes coding more fun. I hope my F5 key doesn't wear out '-). *a minimal change that should increase or restore passing tests. From taleinat at gmail.com Wed Jun 11 13:21:14 2014 From: taleinat at gmail.com (Tal Einat) Date: Wed, 11 Jun 2014 14:21:14 +0300 Subject: [Idle-dev] KeyConfig, KeyBinding and other related issues. In-Reply-To: <539805D6.8020201@udel.edu> References: <539805D6.8020201@udel.edu> Message-ID: On Wed, Jun 11, 2014 at 10:31 AM, Terry Reedy wrote: > > On 6/11/2014 2:39 AM, Saimadhav Heblikar wrote: >> >> The following are the issues related to shortcuts, keybinding dialog, >> where the shortcuts are set and config-keys.def where the shortcuts >> are stored. > > > Great: I have been collecting a list of configuration and especially keybinding issues, with the thought of suggesting this as a coherent group of issues you could work on. > > 3068: extension CONFIG dialog, Tal new PATCH, review > 12274: CONFIG syntax error crash > 12387: CONFIG KEYboard shortcuts > 4765: CONFIG custom KEYset deletion, patch fixes (Mark) > 11437: CONFIG-KEY type causes crash; startup is inefficient. Serwy patch > 1517993: CONFIG KEY and Macs: (me) Alt to Meta (closed) > 20580: CONFIG KEY and and Macs > 694339: dedenting with shift-tab CONFIG KEY > > I just added 21519. Related ideas I have not opened issues for: > > Save config-KEYs sorted on disk instead of when present in CONFIG DIALOG. Would be much easier to read, just a matter of when sort. > > Make CONFIG DIALOG wide enough for all KEY definitions. Also lengthen. > > Change some names so they sort better: possible example region-dedent, region-indent instead of dedent-region, indent-region. > > Since I have a backlog of new test files to review, + Tal's config-extensions patch (+ a patch by Lita), I was about to suggest that you find something like this (configuration and keybinding) to work on that Tal knows better than me, and could help you with. > > It would be great to fix some of these issues that have dragged on for years. If either of you think that some fixes need deeper changes than the typical surface patches, please say so so we can discuss. The better we make the tests, the more confidently we can consider refactorings. > > I will look at the specifics below tomorrow. I would like to see Tal's comments either by email or on the tracker. > > Terry > > >> 1) Issue12387: Very simple way to reproduce the bug: >> With/without CAPS, Ctrl + x key, performs Cut action(windows keyset). >> This is agreeable because both those keybindings are set. The bindings >> are >> and >> But, with/without CAPS, Ctrl + Shift + x key also performs Cut action. >> The bindings are and >> *Workaround*: >> Bind the redundant and to >> <>.(already exists). >> >> This has to be done for all existing key combinations. >> For sake of completeness, If the user wants Control + Shift + *x key*, >> we have to remove both from <> keybinding and add it to >> whatever binding that the user wants. >> This has to be done in the current validity checking method or a new >> parsing method. >> I have tested this solution, and am convinced it would work. >> >> >> 2) Issue11437: Its hard to explain this issue in short. Please read the issue >> at http://bugs.python.org/issue11437 >> Workaround: >> This is easy to solve, if we use the solution from issue12387. With >> the parser method, both "simple" and "advanced" dialogs will be >> parsed, and we will have a 1-to-1 mapping. >> For the case when someone tries to directly "hand-edit" the config >> files, with http://bugs.python.org/issue21696 and tests for the parser >> method in place, we should able to raise an earlier, ideally before >> IDLE starts. We should also be able to pinpoint where the error >> occurs. >> >> >> 3) Issue20580: This does not involve coding, but is about providing >> platform specific default config. This can only be done, once we agree >> on 1 and 2. >> >> >> 4) Issue21519: Again dependent on 1 and 2. Not too sure, if it is >> going to be an issue with 1 and 2. If we go ahead with 2, and have a >> parser method which is testable, we can also validate the "advanced" >> dialog. >> >> >> For other issues which are caused by typo in config, >> http://bugs.python.org/issue21696 along with testable parser method >> should catch them. >> ----------------- >> >> I plan to work on these issues in test driven style as suggested by >> Tal Einat, especially keeping in mind the above issues, their current >> outcome and the required outcome. > > > PS. For me, feedback after every 'code unit' change* makes coding more fun. I hope my F5 key doesn't wear out '-). > > *a minimal change that should increase or restore passing tests. Saimadhav and I discussed this a bit on IRC yesterday. We started by discussing caps-lock's effect on key bindings. My conclusions are: 1) We don't want caps-lock to affect IDLE's key bindings. 2) Tk reacts to caps-lock in different ways on different platforms. I think we should ignore it on all platforms, which means non-trivial work to get that working right with Tk. 3) Specifically, Tk sometimes changes the case of the letter in the event it generates depending on whether caps-lock and/or shift are active. For example, we could get Ctrl-S instead of Ctrl-s if caps lock is on. How exactly this behaves differs by platform (!). For example, caps-lock + shift can result on either an upper- or lower-case letter in the event string, depending on platform. This is causing the issues with keyboard shortcuts not working with caps-lock active on some platforms. 4) A possible solution is to treat all keyboard shortcuts which are bound to a letter in a case-insensitive manner. This would seem to require parsing Tk event definition strings in order to normalize them, and binding to both the upper- and lower-case letter Tk events. 5) Parsing the event strings has additional benefits, such as proper validation of custom events defined in the "advanced" section of the key binding config. (Validations include checking if there are already bindings which would catch that event). This is basically what Terry suggests in his "1)" above, and he says he's already tested the approach and is convinced it would work. So it seems we are all agreed on the suggested implementation method :) Additionally, I suggested that if we go down the route of such a "deep" change, it could be useful to write at least some tests in advance for things that do and don't currently work. This will help make sure that we have a good definition of what currently doesn't work properly, and that we get it working properly at the end. However, how good idea this is depends on how difficult it is to write such tests for the current implementation. Finally, there is some existing relevant code which parses and normalizes TK event strings in idlelib/MultiCall.py. It would perhaps be better to write simpler, more specifically appropriate code, but that could be a starting point. Terry, perhaps you have something better that you used in the test you mentioned? - Tal Einat From tjreedy at udel.edu Wed Jun 11 23:20:40 2014 From: tjreedy at udel.edu (Terry Reedy) Date: Wed, 11 Jun 2014 17:20:40 -0400 Subject: [Idle-dev] KeyConfig, KeyBinding and other related issues. In-Reply-To: References: <539805D6.8020201@udel.edu> Message-ID: On 6/11/2014 7:21 AM, Tal Einat wrote: > On Wed, Jun 11, 2014 at 10:31 AM, Terry Reedy wrote: >> >> On 6/11/2014 2:39 AM, Saimadhav Heblikar wrote: >>> >>> The following are the issues related to shortcuts, keybinding dialog, >>> where the shortcuts are set and config-keys.def where the shortcuts >>> are stored. >> >> >> Great: I have been collecting a list of configuration and especially keybinding issues, with the thought of suggesting this as a coherent group of issues you could work on. >> >> 3068: extension CONFIG dialog, Tal new PATCH, review >> 12274: CONFIG syntax error crash >> 12387: CONFIG KEYboard shortcuts >> 4765: CONFIG custom KEYset deletion, patch fixes (Mark) >> 11437: CONFIG-KEY type causes crash; startup is inefficient. Serwy patch >> 1517993: CONFIG KEY and Macs: (me) Alt to Meta (closed) >> 20580: CONFIG KEY and and Macs >> 694339: dedenting with shift-tab CONFIG KEY >> >> I just added 21519. Related ideas I have not opened issues for: >> >> Save config-KEYs sorted on disk instead of when present in CONFIG DIALOG. Would be much easier to read, just a matter of when sort. >> >> Make CONFIG DIALOG wide enough for all KEY definitions. Also lengthen. >> >> Change some names so they sort better: possible example region-dedent, region-indent instead of dedent-region, indent-region. >> >> Since I have a backlog of new test files to review, + Tal's config-extensions patch (+ a patch by Lita), I was about to suggest that you find something like this (configuration and keybinding) to work on that Tal knows better than me, and could help you with. >> >> It would be great to fix some of these issues that have dragged on for years. If either of you think that some fixes need deeper changes than the typical surface patches, please say so so we can discuss. The better we make the tests, the more confidently we can consider refactorings. >> >> I will look at the specifics below tomorrow. I would like to see Tal's comments either by email or on the tracker. >> >> Terry >> >> >>> 1) Issue12387: Very simple way to reproduce the bug: Your example below misses the point of http://bugs.python.org/issue12387. An example of the bug is given in the first message: "IDLE [on Windows] fails to save using the ctrl-s keyboard shortcut when caps-lock is enabled". This is because for CapsLock to have no effect on Windows, save-window= needs to be, as changed in the patch, save-window= In general, this issue and patch is about adding missing members of such pairs. The only reason I have not applied the patch yet because I think there is a better solution, which is to make it unnecessary to have the other case version in config-keys.def. However, since a deeper change is in the future, if ever, and since the current inconsistent and buggy state of the Windows section of config-keys.def makes proper testing impossible without failures, I am reviewing the patch now and will probably commit it today. Then test_configuration can and should test that in the Windows section, both prefix-Key-x, for x alpha, and prefix-Key-X, are present in the set of bindings. The test can change if the duplication is made unnecessary. -- After writing this, I discovered that ConfigHandler.IdleConf.GetCurrentKeySet adjusts definitions on 'Darwin' by changing 'Alt' to 'Option'. On Windows and Linux, instead of replacing, uppercased key definitions could be added, as appropriate. --- >>> With/without CAPS, Ctrl + x key, performs Cut action(windows keyset). >>> This is agreeable because both those keybindings are set. The bindings >>> are >>> and >>> But, with/without CAPS, Ctrl + Shift + x key also performs Cut action. Correct, and this should continue as is except where there is an explict Control-Shift binding. The current examples of such explicit bindings for Windows are redo= save-window-as-file= The patch adds the lowercase versions needed for these binding to work with CapsLock on. I have already confirmed that with the patch, ^s and ^shift-s each work as expected without and with caps-lock on. Ditto for ^x and ^shift-z. So the patch fixes the bugs it is aimed at. >>> The bindings are and >>> *Workaround*: >>> Bind the redundant and to >>> <>.(already exists). >>> >>> This has to be done for all existing key combinations. >>> For sake of completeness, If the user wants Control + Shift + *x key*, >>> we have to remove both from <> keybinding and add it to >>> whatever binding that the user wants. >>> This has to be done in the current validity checking method or a new >>> parsing method. >>> I have tested this solution, and am convinced it would work. Disabling ^shift-alpha would be new issue. It might break current habits and should probably be rejected on that basis. In the absence of users claiming that they are confused, it would be a waste of time. >>> 2) Issue11437: Its hard to explain this issue in short. In long: 12387 is about the config-keys.def that we deliver. 21696 is about testing all the default confix-xyz.defs we deliver. However, that is not enough because users can edit these files (but should not) and more so because they can easily make bad user .defs either with the key dialog or by direct editing. (Indeed, the Basic method prevents making the alpha pairs, discussed above, needed for Windows. Fixing this is a separate issue.) 11437 is about what Idle should do other than closing when it encounters a bad key binding. Serwy's patch validate keys when read. There are two sub-issues. The patch validates by binding to a temporary Tk() instance and catching the TclException. An alternative is to to developed a parser sufficient to own needs that also gives more specific errors and which can be used with the key dialog. I agree that we should attempt this. To work around the fact that Idle "calls GetCurrentKeySet for each loaded extension" and to avoid repeated error messages, the patch tries to save errors that have been reported. The comments indicate that this hack has glitches. I would strongly prefer avoiding the repeated calls. >>> Please read the issue >>> at http://bugs.python.org/issue11437 >>> Workaround: >>> This is easy to solve, if we use the solution from issue12387. Completing windows binding pairs in config-keys.def has little to do with this issue. >>> With the parser method, both "simple" and "advanced" dialogs >>> will be parsed, and we will have a 1-to-1 mapping. I am not exactly sure what you mean by 1-to-1 mapping in this context. Between what and what? >>> For the case when someone tries to directly "hand-edit" the config >>> files, with http://bugs.python.org/issue21696 and tests for the parser >>> method in place, we should able to raise an earlier, ideally before >>> IDLE starts. I don't see how we can do anything between when Idle leaves the factory and when the user starts Idle -- unless the user happens to run the tests. >>> We should also be able to pinpoint where the error occurs. >>> >>> >>> 3) Issue20580: This does not involve coding, but is about providing >>> platform specific default config. This can only be done, once we agree >>> on 1 and 2. This presents somewhat vague problems and little solution. I added a few comments. This is an example of where we need specific (failing) tests to provide specific targets for improvement. >>> 4) Issue21519: Again dependent on 1 and 2. Not too sure, if it is >>> going to be an issue with 1 and 2. If we go ahead with 2, and have a >>> parser method which is testable, we can also validate the "advanced" >>> dialog. >>> >>> >>> For other issues which are caused by typo in config, >>> http://bugs.python.org/issue21696 along with testable parser method >>> should catch them. >>> ----------------- >>> >>> I plan to work on these issues in test driven style as suggested by >>> Tal Einat, especially keeping in mind the above issues, their current >>> outcome and the required outcome. > Saimadhav and I discussed this a bit on IRC yesterday. We started by > discussing caps-lock's effect on key bindings. My conclusions are: > > 1) We don't want caps-lock to affect IDLE's key bindings. Right. As I reported > 2) Tk reacts to caps-lock in different ways on different platforms. I > think we should ignore it on all platforms, which means non-trivial > work to get that working right with Tk. As I reported on 12387. http://wiki.tcl.tk/28331 appears to say that it Shift undoes ShiftLock except on Mac, where it does nothing. Hence the issue applied to both Windows and Unix. On the other hand, Roger, who reported a problem on Linux, only patch the Windows defs. Perhaps that is because the Unix defs are consistent in never having the uppercase version, and he wanted a test on Windows first where the file is inconsistent and a majority already have the uppercase version. > 3) Specifically, Tk sometimes changes the case of the letter in the > event it generates depending on whether caps-lock and/or shift are > active. For example, we could get Ctrl-S instead of Ctrl-s if caps > lock is on. How exactly this behaves differs by platform (!). For > example, caps-lock + shift can result on either an upper- or > lower-case letter in the event string, depending on platform. This is > causing the issues with keyboard shortcuts not working with caps-lock > active on some platforms. > 4) A possible solution is to treat all keyboard shortcuts which are > bound to a letter in a case-insensitive manner. This would seem to > require parsing Tk event definition strings in order to normalize > them, and binding to both the upper- and lower-case letter Tk events. We agree. When this is done, the duplicates would be stripped from the Windows definitions. > 5) Parsing the event strings has additional benefits, such as proper > validation of custom events defined in the "advanced" section of the > key binding config. (Validations include checking if there are already > bindings which would catch that event). I agree here too. > This is basically what Terry suggests in his "1)" above, and he says I believe you meant Saimadhav. I read him as also suggesting a complicated fix to disable non-specific Alt-Shift, which I think should not be done. > he's already tested the approach and is convinced it would work. So it > seems we are all agreed on the suggested implementation method :) Except for the above, I think so. > Additionally, I suggested that if we go down the route of such a > "deep" change, it could be useful to write at least some tests in > advance for things that do and don't currently work. This will help > make sure that we have a good definition of what currently doesn't > work properly, and that we get it working properly at the end. > However, how good idea this is depends on how difficult it is to write > such tests for the current implementation. > > Finally, there is some existing relevant code which parses and > normalizes TK event strings in idlelib/MultiCall.py. It would perhaps > be better to write simpler, more specifically appropriate code, but > that could be a starting point. Terry, perhaps you have something > better that you used in the test you mentioned? /Terry/Saimadhav/? -- Terry Jan Reedy From saimadhavheblikar at gmail.com Thu Jun 12 13:35:02 2014 From: saimadhavheblikar at gmail.com (Saimadhav Heblikar) Date: Thu, 12 Jun 2014 17:05:02 +0530 Subject: [Idle-dev] KeyConfig, KeyBinding and other related issues. In-Reply-To: References: <539805D6.8020201@udel.edu> Message-ID: On 12 June 2014 02:50, Terry Reedy wrote: > > After writing this, I discovered that ConfigHandler.IdleConf.GetCurrentKeySet adjusts definitions on 'Darwin' by changing 'Alt' to 'Option'. On Windows and Linux, instead of replacing, uppercased key definitions could be added, as appropriate. > --- > I tried that in http://bugs.python.org/issue12387#msg220338. Let me know if that is OK. IIUC, next step would be to revert the changes made in Windows key set (http://hg.python.org/cpython/rev/25fd9aeeff91/). AFA tests are concerned to validate the key defs in config-keys.def, I have started writing something as below: Tokenize the key sequence by splitting on '-'(as in Control-Key-r). and do the following: 1. ascertain the tokens follow correct order I will try various combinations in the existing key def and make a note of those orderings, which raise an error. Then ensure those orderings should fail during testing 2. In alphabet keybindings(Prefix-Key-x),(x is any alphabet) is it necessary that x be the lower case? If yes, this is something which can be tested. 3. Test simple scenarios like incomplete keybinding like missing '>' at the end. The above tests will go into test_keys in test_configuration.py(http://bugs.python.org/issue21696). We can also run the above 3 tests on extension keybindings in config-extensions.def. On 12 June 2014 02:50, Terry Reedy wrote: >>> >>> On 6/11/2014 2:39 AM, Saimadhav Heblikar wrote: >>>> >>>> With/without CAPS, Ctrl + x key, performs Cut action(windows keyset). >>>> This is agreeable because both those keybindings are set. The bindings >>>> are >>>> and >>>> But, with/without CAPS, Ctrl + Shift + x key also performs Cut action. > > > >>>> The bindings are and >>>> *Workaround*: >>>> Bind the redundant and to >>>> <>.(already exists). >>>> >>>> This has to be done for all existing key combinations. >>>> For sake of completeness, If the user wants Control + Shift + *x key*, >>>> we have to remove both from <> keybinding and add it to >>>> whatever binding that the user wants. >>>> This has to be done in the current validity checking method or a new >>>> parsing method. >>>> I have tested this solution, and am convinced it would work. > > > Disabling ^shift-alpha would be new issue. It might break current habits and should probably be rejected on that basis. In the absence of users claiming that they are confused, it would be a waste of time. > Means, we wont go ahead and fix the "bug" from my example? (Just for clarification.) On 12 June 2014 03:16, Terry Reedy wrote: > > Q2. Do all of you read Idle-dev or should I continue responding to emails direct to all? > I am subscribed to idle-dev list. I will reply to other part of your(Terry Reedy) and Tal Einat's mail next. From saimadhavheblikar at gmail.com Thu Jun 12 16:13:03 2014 From: saimadhavheblikar at gmail.com (Saimadhav Heblikar) Date: Thu, 12 Jun 2014 19:43:03 +0530 Subject: [Idle-dev] KeyConfig, KeyBinding and other related issues. In-Reply-To: References: <539805D6.8020201@udel.edu> Message-ID: On 12 June 2014 02:50, Terry Reedy wrote: > > > 2) Issue11437: Its hard to explain this issue in short. >>>> >>> > In long: 12387 is about the config-keys.def that we deliver. 21696 is > about testing all the default confix-xyz.defs we deliver. However, that is > not enough because users can edit these files (but should not) and more so > because they can easily make bad user .defs either with the key dialog or > by direct editing. (Indeed, the Basic method prevents making the alpha > pairs, discussed above, needed for Windows. Fixing this is a separate > issue.) 11437 is about what Idle should do other than closing when it > encounters a bad key binding. > > Serwy's patch validate keys when read. There are two sub-issues. > > The patch validates by binding to a temporary Tk() instance and catching > the TclException. An alternative is to to developed a parser sufficient to > own needs that also gives more specific errors and which can be used with > the key dialog. I agree that we should attempt this. > > I detailed how I plan to accomplish in an earlier message.(Please see the tests part in https://mail.python.org/pipermail/idle-dev/2014-June/003435.html). Mention any validity test that I have missed. The tests will go into test_configuration.py. Could we can run that unittest method, before IDLE starts? If the test fails, provide appropriate error message, as in R. Serwy's patch? > To work around the fact that Idle "calls GetCurrentKeySet for each loaded > extension" and to avoid repeated error messages, the patch tries to save > errors that have been reported. The comments indicate that this hack has > glitches. I would strongly prefer avoiding the repeated calls. The repeated calls happen in line 1055 load_standard_extensions method where it repeatedly calls load_extension method->GetExtensionKeys->GetCurrentKeySet. One obvious way, is to cache the result(activeKeys) in EditorWindow at startup. Add an optional arg "activeKeys" in the above method chain. I am linking to the diff file here as i could not find an open issue on tracker. https://gist.github.com/sahutd/474031c15ee0154ef4bc#file-avoid-repeated-calls-diff Command used to profile: ./python -m cProfile -s ncalls Lib/idlelib/idle.py >profile.txt && cat profile.txt | grep "configHandler.py" > file.txt I have also added before and after profile. Notice that the TOTAL number of calls to methods in configHandler.py ~== the number of calls made to just Get earlier. https://gist.github.com/sahutd/474031c15ee0154ef4bc#file-profile-before-txt https://gist.github.com/sahutd/474031c15ee0154ef4bc#file-profile-after-txt > > > >>> Please read the issue > >> at http://bugs.python.org/issue11437 >>>> Workaround: >>>> This is easy to solve, if we use the solution from issue12387. >>>> >>> > Completing windows binding pairs in config-keys.def has little to do with > this issue. > > I was referring to binding "redundant" and un-used respective shift events to <>. But since I did http://bugs.python.org/issue12387#msg220338 based on your comments, my workaround is not applicable. > > With the parser method, both "simple" and "advanced" dialogs >>>> >>> >>> will be parsed, and we will have a 1-to-1 mapping. > > I am not exactly sure what you mean by 1-to-1 mapping in this context. > Between what and what? > > For eg, Control Key press + alphabet should not depend on on status of CAPS. In retrospect, I should have put it as " one to many mapping." i.e. Control Key press + alphabet -> {Control-Key-x and Control-Key-X} But this too, should not apply now. > > For the case when someone tries to directly "hand-edit" the config >>>> files, with http://bugs.python.org/issue21696 and tests for the parser >>>> method in place, we should able to raise an earlier, ideally before >>>> IDLE starts. >>>> >>> > I don't see how we can do anything between when Idle leaves the factory > and when the user starts Idle -- unless the user happens to run the tests. > > Perhaps along the lines of R. Serwy's patch. I described how I intend to do it earlier in this mail. Regards Saimadhav Heblikar -------------- next part -------------- An HTML attachment was scrubbed... URL: From tjreedy at udel.edu Thu Jun 12 21:10:37 2014 From: tjreedy at udel.edu (Terry Reedy) Date: Thu, 12 Jun 2014 15:10:37 -0400 Subject: [Idle-dev] KeyConfig, KeyBinding and other related issues. In-Reply-To: References: <539805D6.8020201@udel.edu> Message-ID: <5399FB2D.1050208@udel.edu> On 6/12/2014 7:35 AM, Saimadhav Heblikar wrote: > On 12 June 2014 02:50, Terry Reedy wrote: >> >> ConfigHandler.IdleConf.GetCurrentKeySet adjusts definitions on 'Darwin' by changing 'Alt' to 'Option'. On Windows and Linux, instead of replacing, uppercased key definitions could be added, as appropriate. > I tried that in http://bugs.python.org/issue12387#msg220338. Let me > know if that is OK. IIUC, next step would be to revert the changes > made in Windows key set > (http://hg.python.org/cpython/rev/25fd9aeeff91/). We should make the 'officially approved' versions be the ones produced by the basic mode of the key dialog: Control/Alt/Meta-Key-alpha and Control/Alt/Meta-Shift-Key-Alpha. (Or we should change what basic mode produces.) Not needing the alternate binding versions will eliminate the need to use advanced mode to produce alternate binding versions. There should be a new patch removing *all* the extraneous definitions, not just the new ones. Write a program to remove Control/Alt/Meta-Key-Alpha and ()-Shift-Key-alpha. (You could do the few latter forms by hand if you prefer). > AFA tests are concerned to validate the key defs in config-keys.def, I > have started writing something as below: > Tokenize the key sequence by splitting on '-'(as in Control-Key-r). > and do the following: > > 1. ascertain the tokens follow correct order > I will try various combinations in the existing key def and make a > note of those orderings, which raise an error. Then ensure those > orderings should fail during testing > > 2. In alphabet keybindings(Prefix-Key-x),(x is any alphabet) is it > necessary that x be the lower case? If yes, this is something which > can be tested. I think accepting the 'wrong' versions (such as the ones we remove from the Windows defs) either as an alternative or as supplement to the wrong versions, depends on the place encountered. We need to list all and decide for each. 0. Key dialog, basic mode - only produces official versions, I believe. 1. Key dialog, advanced mode - either reject or convert to official version, if not present, as part of added validation. A message box could give the user a choice. 2. Runtime: I would be inclined to accept without comment (message box). However, I do not know how 3rd party extensions get 'installed'. 3. test_configuration, on default files, should fail on wrong versions. The assert should have a message argument that would be useful to users that mis-edit the default files. 4. test_configuration: we could consider looking for and testing user configuration files. Either configHandler or keybindingDialog should gain a key-binding test function that can be imported and used in other modules. > 3. Test simple scenarios like incomplete keybinding like missing '>' at the end. > > The above tests will go into test_keys in > test_configuration.py(http://bugs.python.org/issue21696). > > We can also run the above 3 tests on extension keybindings in > config-extensions.def. Terry From taleinat at gmail.com Fri Jun 13 00:20:34 2014 From: taleinat at gmail.com (Tal Einat) Date: Fri, 13 Jun 2014 01:20:34 +0300 Subject: [Idle-dev] KeyConfig, KeyBinding and other related issues. In-Reply-To: <5399FB2D.1050208@udel.edu> References: <539805D6.8020201@udel.edu> <5399FB2D.1050208@udel.edu> Message-ID: On Thu, Jun 12, 2014 at 10:10 PM, Terry Reedy wrote: > We should make the 'officially approved' versions be the ones produced by > the basic mode of the key dialog: Control/Alt/Meta-Key-alpha and > Control/Alt/Meta-Shift-Key-Alpha. (Or we should change what basic mode > produces.) Not needing the alternate binding versions will eliminate the > need to use advanced mode to produce alternate binding versions. What about Ctrl-Alt-Key-Alpha or even Ctrl-Alt-Shift-Key-Alpha? Even if there are now such bindings right now, they should be possible to enter via the simple key binding dialog, and they should be considered valid. > There should be a new patch removing *all* the extraneous definitions, not > just the new ones. Write a program to remove Control/Alt/Meta-Key-Alpha and > ()-Shift-Key-alpha. (You could do the few latter forms by hand if you > prefer). Indeed. We'll need to manually review this by hand, but it might be better to do most of this automatically to reduce the risk of human error. Possibly a few good search/replace in an editor could do the trick. > 2. Runtime: I would be inclined to accept without comment (message box). > However, I do not know how 3rd party extensions get 'installed'. What do you mean "installed"? I know a lot about the extension mechanism and will happily help here. - Tal Einat From tjreedy at udel.edu Fri Jun 13 02:01:29 2014 From: tjreedy at udel.edu (Terry Reedy) Date: Thu, 12 Jun 2014 20:01:29 -0400 Subject: [Idle-dev] Meta-Key on Windows. Message-ID: Copying from email On 6/12/2014 6:22 PM, Tal Einat wrote:> On Thu, Jun 12, 2014 at 12:46 AM, Terry Reedy wrote: >> Q1. Do any of you know what 'Meta' is supposed to refer to on Windows? >> On my systems, it does not correspond to the Windows key, the (useless?) >> Page-with-Pointer key to the left of right Cntl, Escape, or the three >> PrtScrn/SyqReq, ScreenLock, or Pause/Break keys. Are these entries of use to >> anyone? > > I don't know if Meta can be generated by a keyboard on Windows, and > have no use for those other modifier keys you mentioned. Some other > people might, however, so we shouldn't disallow using them without > good reason. If a Meta-Key-x event can be generated Windows, the means should be documented. If not, the Meta-Key-x bindings should be delelted from the Windows definitions. For Key-X, I would also allow all key names that Tk recognizes; they should also be listed in the Basic Key Binding entry box. (The set/list used to populate the box might as well be the same one used to validate 'advanced' entries.) I do not see of the keys above listed now. I don't know if it is Tk or earlier Idle devs that limited the list to keys found on all pretty much all modern systems. -- Terry Jan Reedy From tjreedy at udel.edu Fri Jun 13 02:55:33 2014 From: tjreedy at udel.edu (Terry Reedy) Date: Thu, 12 Jun 2014 20:55:33 -0400 Subject: [Idle-dev] KeyConfig, KeyBinding and other related issues. In-Reply-To: References: <539805D6.8020201@udel.edu> <5399FB2D.1050208@udel.edu> Message-ID: <539A4C05.8060100@udel.edu> On 6/12/2014 6:20 PM, Tal Einat wrote: > On Thu, Jun 12, 2014 at 10:10 PM, Terry Reedy wrote: >> We should make the 'officially approved' versions be the ones produced by >> the basic mode of the key dialog: Control/Alt/Meta-Key-alpha and >> Control/Alt/Meta-Shift-Key-Alpha. (Or we should change what basic mode >> produces.) Not needing the alternate binding versions will eliminate the >> need to use advanced mode to produce alternate binding versions. > > What about Ctrl-Alt-Key-Alpha or even Ctrl-Alt-Shift-Key-Alpha? Even > if there are now such bindings right now, they should be possible to > enter via the simple key binding dialog, and they should be considered > valid. Each of the three can be independently selected. The RE for what basic produces is something like '<(Control-)?(Alt-)?(Shift-)?Key-(any from list)>" >> There should be a new patch removing *all* the extraneous definitions, not >> just the new ones. Write a program to remove Control/Alt/Meta-Key-Alpha and >> ()-Shift-Key-alpha. (You could do the few latter forms by hand if you >> prefer). > > Indeed. We'll need to manually review this by hand, but it might be > better to do most of this automatically to reduce the risk of human > error. Possibly a few good search/replace in an editor could do the > trick. An RE search-delete with ", <(Control-|Alt-|Meta-)Key-[A-Z]>" should do it for in the Windows section. I did not see any matches in the Unix section but did not look in the Mac/OSX sections. Those should be left alone anyway except as Ned thinks they should be changed. >> 2. Runtime: I would be inclined to accept without comment (message box). >> However, I do not know how 3rd party extensions get 'installed'. > > What do you mean "installed"? I know a lot about the extension > mechanism and will happily help here. I think I found much of the current answer in the config-extensions.def comments. Someone puts an extension file in idlelib and, adds *by hand*, a corresponding entry to idlelib/config-extensions.def. This entry defines the system defaults for the extension and constitutes 'installation' as I meant it. A user on the system customizes added extensions just like built-in extensions: hand-edit .idlerc/config-extensions.cfg to add a custom entry. As I understand it, your extensions dialog will take care of the second part, editing the user file, but depends on entries already being in the default file. Idle does not seem to have anticipated an ecosystem of 3rd-party extensions, and the waste of 1000s of people hand-editing config-extensions.def. A feature complementary to editing existing entries would be automatic recognition of new extensions and copying of an config entry from extension file to the .def file. Are there any some extensions that come with a script to do this? Proposal: define a format for config entries in .py files, perhaps copying one already in use if there are any. Add a directory, such as /extensions to contain files that have such entries. The rest should be easy enough to work out. Terry From taleinat at gmail.com Fri Jun 13 13:04:58 2014 From: taleinat at gmail.com (Tal Einat) Date: Fri, 13 Jun 2014 14:04:58 +0300 Subject: [Idle-dev] KeyConfig, KeyBinding and other related issues. In-Reply-To: <539A4C05.8060100@udel.edu> References: <539805D6.8020201@udel.edu> <5399FB2D.1050208@udel.edu> <539A4C05.8060100@udel.edu> Message-ID: On Fri, Jun 13, 2014 at 3:55 AM, Terry Reedy wrote: > On 6/12/2014 6:20 PM, Tal Einat wrote: >> >> On Thu, Jun 12, 2014 at 10:10 PM, Terry Reedy wrote: >>> >>> 2. Runtime: I would be inclined to accept without comment (message box). >>> However, I do not know how 3rd party extensions get 'installed'. >> >> What do you mean "installed"? I know a lot about the extension >> mechanism and will happily help here. > > I think I found much of the current answer in the config-extensions.def > comments. Someone puts an extension file in idlelib and, adds *by hand*, a > corresponding entry to idlelib/config-extensions.def. This entry defines the > system defaults for the extension and constitutes 'installation' as I meant > it. A user on the system customizes added extensions just like built-in > extensions: hand-edit .idlerc/config-extensions.cfg to add a custom entry. Precisely. > As I understand it, your extensions dialog will take care of the second > part, editing the user file, but depends on entries already being in the > default file. Yes. Still, considering the large number of extensions bundled with IDLE and how major the features supplied by some of them are, IMO an extension config dialog would be immensely useful even as things are. > Idle does not seem to have anticipated an ecosystem of 3rd-party extensions, > and the waste of 1000s of people hand-editing config-extensions.def. A > feature complementary to editing existing entries would be automatic > recognition of new extensions and copying of an config entry from extension > file to the .def file. Are there any some extensions that come with a > script to do this? Not that I am aware of. I'm also not aware of 1000's of people actually installing IDLE extensions. The few extensions to be found on PyPI (some of which I made) are hardly ever downloaded. > Proposal: define a format for config entries in .py files, perhaps copying > one already in use if there are any. Add a directory, such as /extensions to > contain files that have such entries. The rest should be easy enough to work > out. Better installation of IDLE extensions has come up before. But that's an entirely different matter, and much lower priority IMO. Relevant: Roger Serwy's IdleX [1] has an extension manager. .. [1]: http://idlex.sourceforge.net/ - Tal From taleinat at gmail.com Fri Jun 13 13:14:42 2014 From: taleinat at gmail.com (Tal Einat) Date: Fri, 13 Jun 2014 14:14:42 +0300 Subject: [Idle-dev] Meta-Key on Windows. In-Reply-To: References: Message-ID: On Fri, Jun 13, 2014 at 3:01 AM, Terry Reedy wrote: > Copying from email > On 6/12/2014 6:22 PM, Tal Einat wrote:> On Thu, Jun 12, 2014 at 12:46 AM, > Terry Reedy wrote: >>> Q1. Do any of you know what 'Meta' is supposed to refer to on Windows? >>> On my systems, it does not correspond to the Windows key, the (useless?) >>> Page-with-Pointer key to the left of right Cntl, Escape, or the three >>> PrtScrn/SyqReq, ScreenLock, or Pause/Break keys. Are these entries of use >>> to >>> anyone? >> >> I don't know if Meta can be generated by a keyboard on Windows, and >> have no use for those other modifier keys you mentioned. Some other >> people might, however, so we shouldn't disallow using them without >> good reason. > > If a Meta-Key-x event can be generated Windows, the means should be > documented. If not, the Meta-Key-x bindings should be delelted from the > Windows definitions. I agree. According to the Tk documentation on bindings [1], Meta (a.k.a. "M") doesn't exist when there is no Meta key on the keyboard: "Meta and M refer to whichever of the M1 through M5 modifiers is associated with the Meta key(s) on the keyboard (keysyms Meta_R and Meta_L). If there are no Meta keys, or if they are not associated with any modifiers, then Meta and M will not match any events." I think it safe to assume that nobody today uses Windows with a keyboard that has a Meta key. .. [1]: http://www.tcl.tk/man/tcl8.5/TkCmd/bind.htm#M6 - Tal Einat From saimadhavheblikar at gmail.com Fri Jun 13 13:22:54 2014 From: saimadhavheblikar at gmail.com (Saimadhav Heblikar) Date: Fri, 13 Jun 2014 16:52:54 +0530 Subject: [Idle-dev] KeyConfig, KeyBinding and other related issues. In-Reply-To: References: <539805D6.8020201@udel.edu> <5399FB2D.1050208@udel.edu> <539A4C05.8060100@udel.edu> Message-ID: Just a heads up to both: I am writing a keyseq validator method. It currently works for over 800 permutations of ['Shift', 'Control', 'Alt', 'Meta', 'Key-a', 'Key-A', 'Up', 'Key-Up', 'a', 'A']. It works for permutations of length 2 and 3. Beyond that its not worth it IMO. I am currently trying to integrate it with test_configuration.py and catching permutations i missed out. I post this, so that we dont duplicate work. I hope it to be ready by the end of the day.(UTC +5.5) On 13 June 2014 16:34, Tal Einat wrote: > On Fri, Jun 13, 2014 at 3:55 AM, Terry Reedy wrote: >> On 6/12/2014 6:20 PM, Tal Einat wrote: >>> >>> On Thu, Jun 12, 2014 at 10:10 PM, Terry Reedy wrote: >>>> >>>> 2. Runtime: I would be inclined to accept without comment (message box). >>>> However, I do not know how 3rd party extensions get 'installed'. >>> >>> What do you mean "installed"? I know a lot about the extension >>> mechanism and will happily help here. >> >> I think I found much of the current answer in the config-extensions.def >> comments. Someone puts an extension file in idlelib and, adds *by hand*, a >> corresponding entry to idlelib/config-extensions.def. This entry defines the >> system defaults for the extension and constitutes 'installation' as I meant >> it. A user on the system customizes added extensions just like built-in >> extensions: hand-edit .idlerc/config-extensions.cfg to add a custom entry. > > Precisely. > >> As I understand it, your extensions dialog will take care of the second >> part, editing the user file, but depends on entries already being in the >> default file. > > Yes. Still, considering the large number of extensions bundled with > IDLE and how major the features supplied by some of them are, IMO an > extension config dialog would be immensely useful even as things are. > >> Idle does not seem to have anticipated an ecosystem of 3rd-party extensions, >> and the waste of 1000s of people hand-editing config-extensions.def. A >> feature complementary to editing existing entries would be automatic >> recognition of new extensions and copying of an config entry from extension >> file to the .def file. Are there any some extensions that come with a >> script to do this? > > Not that I am aware of. > > I'm also not aware of 1000's of people actually installing IDLE > extensions. The few extensions to be found on PyPI (some of which I > made) are hardly ever downloaded. > >> Proposal: define a format for config entries in .py files, perhaps copying >> one already in use if there are any. Add a directory, such as /extensions to >> contain files that have such entries. The rest should be easy enough to work >> out. > > Better installation of IDLE extensions has come up before. But that's > an entirely different matter, and much lower priority IMO. Relevant: > Roger Serwy's IdleX [1] has an extension manager. > > .. [1]: http://idlex.sourceforge.net/ > > - Tal -- Regards Saimadhav Heblikar From taleinat at gmail.com Fri Jun 13 13:28:57 2014 From: taleinat at gmail.com (Tal Einat) Date: Fri, 13 Jun 2014 14:28:57 +0300 Subject: [Idle-dev] KeyConfig, KeyBinding and other related issues. In-Reply-To: References: <539805D6.8020201@udel.edu> <5399FB2D.1050208@udel.edu> <539A4C05.8060100@udel.edu> Message-ID: On Fri, Jun 13, 2014 at 2:22 PM, Saimadhav Heblikar wrote: > Just a heads up to both: I am writing a keyseq validator method. > It currently works for over 800 permutations of ['Shift', 'Control', > 'Alt', 'Meta', 'Key-a', 'Key-A', 'Up', 'Key-Up', 'a', 'A']. It works > for permutations of length 2 and 3. Beyond that its not worth it IMO. > I am currently trying to integrate it with test_configuration.py and > catching permutations i missed out. > > I post this, so that we dont duplicate work. I hope it to be ready by > the end of the day.(UTC +5.5) What is the method you are using? What do you mean by "permutations"? If you mean what I think, then I'm not sure I agree with >3 not being worth it. I've used keyboard bindings with more than 2 modifiers before, and we should certainly support this properly. If you'd like guidance during your work, rather than comments once you're done, I'll be highly available for the next several hours. - Tal From saimadhavheblikar at gmail.com Fri Jun 13 13:45:49 2014 From: saimadhavheblikar at gmail.com (Saimadhav Heblikar) Date: Fri, 13 Jun 2014 17:15:49 +0530 Subject: [Idle-dev] KeyConfig, KeyBinding and other related issues. In-Reply-To: References: <539805D6.8020201@udel.edu> <5399FB2D.1050208@udel.edu> <539A4C05.8060100@udel.edu> Message-ID: On 13 June 2014 16:58, Tal Einat wrote: > On Fri, Jun 13, 2014 at 2:22 PM, Saimadhav Heblikar > wrote: >> Just a heads up to both: I am writing a keyseq validator method. >> It currently works for over 800 permutations of ['Shift', 'Control', >> 'Alt', 'Meta', 'Key-a', 'Key-A', 'Up', 'Key-Up', 'a', 'A']. It works >> for permutations of length 2 and 3. Beyond that its not worth it IMO. >> I am currently trying to integrate it with test_configuration.py and >> catching permutations i missed out. >> >> I post this, so that we dont duplicate work. I hope it to be ready by >> the end of the day.(UTC +5.5) > > What is the method you are using? Regex. It is not something elegant. The permutations are coded in.(Not all 800+ obviously, but around 15-20 general ones.). The only advantage is it can be used without creating a new Tk instance. > > What do you mean by "permutations"? If you mean what I think, then I'm > not sure I agree with >3 not being worth it. I've used keyboard > bindings with more than 2 modifiers before, and we should certainly > support this properly. > I am sorry. I meant to write >3 modifier permutations. (i.eControl-Shift-Alt-Meta+Key-X is not covered. But Control-Shift-Alt-Key-X is.) -- Regards Saimadhav Heblikar From saimadhavheblikar at gmail.com Fri Jun 13 17:44:40 2014 From: saimadhavheblikar at gmail.com (Saimadhav Heblikar) Date: Fri, 13 Jun 2014 21:14:40 +0530 Subject: [Idle-dev] KeyConfig, KeyBinding and other related issues. In-Reply-To: References: <539805D6.8020201@udel.edu> <5399FB2D.1050208@udel.edu> <539A4C05.8060100@udel.edu> Message-ID: Hi, I would like the keyseq validator to be reviewed. The diff file: https://gist.github.com/sahutd/0a471db8138383fd73b2#file-test-keyseq-diff A sample test runner file: https://gist.github.com/sahutd/0a471db8138383fd73b2#file-test-keyseq-runner-py In its current form, it supports/has modifiers = ['Shift', 'Control', 'Alt', 'Meta'] alpha_uppercase = ['A'] alpha_lowercase = ['a'] direction = ['Up',] direction_key = ['Key-Up'] It supports validating combinations upto 4 in length. Please test for the above set only. (It will extended easily to fully represent the respective complete sets. The reason it cant be done *now* is the due to how RE optionals are coded differently in my patch. See CLEANUP below). I will also add remaining keys like Backspace, Slash etc tomorrow. # Cleanup: If we decide to go ahead with RE validating keys as in the above patch, 0. I made the mistake of not coding RE optionals -> ((pat)|(pat)) same for all sets. The result is that, extending the current key set is not possible without making all RE optional patterns similar.(Read the starting lines of is_valid_keyseq method). 1. There is a lot of places where refactoring can be done and appropriate comment added. 2. I left the asserts as-is. They can be used in testing the validator method itself. 3. The above patch still needs support for Backspace, slash etc to be added. I decided to add, once I am sure we will use it. 4. I would like to know how it will affect Mac? What are system specific differences? Please run the test-runner script on it and do let me know. --- My friend told that this thing can be done by "defining a grammar and automata." I did read up about it, but found it hard to grasp everything. Can you say whether it would be easier to solve it that way than RE? Regards From tjreedy at udel.edu Fri Jun 13 18:39:41 2014 From: tjreedy at udel.edu (Terry Reedy) Date: Fri, 13 Jun 2014 12:39:41 -0400 Subject: [Idle-dev] KeyConfig, KeyBinding and other related issues. In-Reply-To: References: <539805D6.8020201@udel.edu> <5399FB2D.1050208@udel.edu> <539A4C05.8060100@udel.edu> Message-ID: On 6/13/2014 7:45 AM, Saimadhav Heblikar wrote: > On 13 June 2014 16:58, Tal Einat wrote: >> On Fri, Jun 13, 2014 at 2:22 PM, Saimadhav Heblikar >> wrote: >>> Just a heads up to both: I am writing a keyseq validator method. >>> It currently works for over 800 permutations of ['Shift', 'Control', >>> 'Alt', 'Meta', 'Key-a', 'Key-A', 'Up', 'Key-Up', 'a', 'A']. It works >>> for permutations of length 2 and 3. Beyond that its not worth it IMO. >>> I am currently trying to integrate it with test_configuration.py and >>> catching permutations i missed out. We do not need 'permutations', as least not for validating in canonical form. Basic mode produces Control? Alt? Shift? in that order. The regex for that is trivial. If Tk accepts in *any* order, the regex is only slightly more complicated. >>> I post this, so that we dont duplicate work. I hope it to be ready by >>> the end of the day.(UTC +5.5) >> >> What is the method you are using? > > Regex. It is not something elegant. The permutations are coded in.(Not > all 800+ obviously, but around 15-20 general ones.). Whether specific combination (unordered) and permutation (ordered) must be coded in depends of the grammer Tk uses. See comment on next post. > The only advantage is it can be used without creating a new Tk instance. I am not sure I get this. -- Terry Jan Reedy From tjreedy at udel.edu Fri Jun 13 18:58:37 2014 From: tjreedy at udel.edu (Terry Reedy) Date: Fri, 13 Jun 2014 12:58:37 -0400 Subject: [Idle-dev] KeyConfig, KeyBinding and other related issues. In-Reply-To: References: <539805D6.8020201@udel.edu> <5399FB2D.1050208@udel.edu> <539A4C05.8060100@udel.edu> Message-ID: On 6/13/2014 11:44 AM, Saimadhav Heblikar wrote: > I would like the keyseq validator to be reviewed. I will let Tal take first whack at the code. > > The diff file: https://gist.github.com/sahutd/0a471db8138383fd73b2#file-test-keyseq-diff > A sample test runner file: > https://gist.github.com/sahutd/0a471db8138383fd73b2#file-test-keyseq-runner-py Incomplete patches can be posted to the tracker, where Rietveld can be used for review. Create a separate issue for 'Tk key-combination validator.' Make it a dependency of the test_combination and key-entry issues. If a function looks useful outside of Idle, we can propose adding it to tkinter. > In its current form, it supports/has > modifiers = ['Shift', 'Control', 'Alt', 'Meta'] > alpha_uppercase = ['A'] > alpha_lowercase = ['a'] > direction = ['Up',] > direction_key = ['Key-Up'] > > It supports validating combinations upto 4 in length. > > Please test for the above set only. (It will extended easily to fully > represent the respective complete sets. The reason it cant be done > *now* is the due to how RE optionals are coded differently in my > patch. See CLEANUP below). I will also add remaining keys like > Backspace, Slash etc tomorrow. > > # Cleanup: > If we decide to go ahead with RE validating keys as in the above patch, > > 0. I made the mistake of not coding RE optionals -> ((pat)|(pat)) same > for all sets. The result is that, extending the current key set is not > possible without making all RE optional patterns similar.(Read the > starting lines of is_valid_keyseq method). > > 1. There is a lot of places where refactoring can be done and > appropriate comment added. > > 2. I left the asserts as-is. They can be used in testing the validator > method itself. > > 3. The above patch still needs support for Backspace, slash etc to be > added. I decided to add, once I am sure we will use it. > > 4. I would like to know how it will affect Mac? What are system > specific differences? Please run the test-runner script on it and do > let me know. > > --- > My friend told that this thing can be done by "defining a grammar and > automata." I did read up about it, but found it hard to grasp > everything. Can you say whether it would be easier to solve it that > way than RE? A regex (in the original form, without latter additions) defines a regular grammar and gets translated to an automaton automatically. The later additions make the languages parsed somewhere between regular languages and context-free languages. The translated automata are more complicated than the originals. So, if something can sensibly be done with regex, and not something simpler, there unlikely to be any advantage to writing the automaton by hand. Does the Tk manual (at Active state, for instance) anywhere defined the key-combination language that .bind() accepts? If not, we might have to settle for a function with three possible answers: definitely ok, unsure, and definitely not ok (mispelling such as 'Atl', suffix after the key such as 'Key-a-Shift', repeated modifiers such as 'Alt-Alt-Key-x' (even if Tk would allow that), missing key such as 'Alt-Shift') -- Terry Jan Reedy From taleinat at gmail.com Sat Jun 14 00:51:55 2014 From: taleinat at gmail.com (Tal Einat) Date: Sat, 14 Jun 2014 01:51:55 +0300 Subject: [Idle-dev] KeyConfig, KeyBinding and other related issues. In-Reply-To: References: <539805D6.8020201@udel.edu> <5399FB2D.1050208@udel.edu> <539A4C05.8060100@udel.edu> Message-ID: On Fri, Jun 13, 2014 at 7:58 PM, Terry Reedy wrote: > On 6/13/2014 11:44 AM, Saimadhav Heblikar wrote: >> I would like the keyseq validator to be reviewed. > > I will let Tal take first whack at the code. Sure thing. I didn't get to it today and I'm going to sleep now, but I'll write comments tomorrow morning. In the meantime, Saimadhav, can you explain why you decided to use regexps instead of the straightforward approach of splitting by '-' and checking the pieces? - Tal Einat From saimadhavheblikar at gmail.com Sat Jun 14 08:52:04 2014 From: saimadhavheblikar at gmail.com (Saimadhav Heblikar) Date: Sat, 14 Jun 2014 12:22:04 +0530 Subject: [Idle-dev] KeyConfig, KeyBinding and other related issues. In-Reply-To: References: <539805D6.8020201@udel.edu> <5399FB2D.1050208@udel.edu> <539A4C05.8060100@udel.edu> Message-ID: On 13 June 2014 22:09, Terry Reedy wrote: > > On 6/13/2014 7:45 AM, Saimadhav Heblikar wrote: >> >> On 13 June 2014 16:58, Tal Einat wrote: >>> >>> On Fri, Jun 13, 2014 at 2:22 PM, Saimadhav Heblikar >>> wrote: >>>> >>>> Just a heads up to both: I am writing a keyseq validator method. >>>> It currently works for over 800 permutations of ['Shift', 'Control', >>>> 'Alt', 'Meta', 'Key-a', 'Key-A', 'Up', 'Key-Up', 'a', 'A']. It works >>>> for permutations of length 2 and 3. Beyond that its not worth it IMO. >>>> I am currently trying to integrate it with test_configuration.py and >>>> catching permutations i missed out. > > > We do not need 'permutations', as least not for validating in canonical form. Basic mode produces Control? Alt? Shift? in that order. The regex for that is trivial. If Tk accepts in *any* order, the regex is only slightly more complicated. > My thinking was to use the validator method across IDLE(in tests, validating key config before IDLE starts and of course in the key binding dialog KeyOk method) If we need it only for the dialog, then I will extract those regex's only. > > >>>> I post this, so that we dont duplicate work. I hope it to be ready by >>>> the end of the day.(UTC +5.5) >>> >>> >>> What is the method you are using? >> >> >> Regex. It is not something elegant. The permutations are coded in.(Not >> all 800+ obviously, but around 15-20 general ones.). > > > Whether specific combination (unordered) and permutation (ordered) must be coded in depends of the grammer Tk uses. See comment on next post. > > >> The only advantage is it can be used without creating a new Tk instance. > > > I am not sure I get this. > Referring to http://bugs.python.org/file25226/windows_caps_lock.patch by Roger Serwy. In the patch, a live Tk object is used to validate keys. On 14 June 2014 04:21, Tal Einat wrote: > > In the meantime, Saimadhav, can you explain why you decided to use > regexps instead of the straightforward approach of splitting by '-' > and checking the pieces? As mentioned above, I understood that the method would be used in many places, not only KeyBindingDialog. So I wanted it work under all possible cases. Why regex and splitting by '-'? No particular reason. I had a feeling splitting method could get messy. But if its for a small set that the validity method is going to be required for, splitting method is better. From taleinat at gmail.com Sat Jun 14 09:29:21 2014 From: taleinat at gmail.com (Tal Einat) Date: Sat, 14 Jun 2014 10:29:21 +0300 Subject: [Idle-dev] KeyConfig, KeyBinding and other related issues. In-Reply-To: References: <539805D6.8020201@udel.edu> <5399FB2D.1050208@udel.edu> <539A4C05.8060100@udel.edu> Message-ID: On Sat, Jun 14, 2014 at 9:52 AM, Saimadhav Heblikar wrote: > My thinking was to use the validator method across IDLE(in tests, > validating key config before IDLE starts and of course in the key > binding dialog KeyOk method) > If we need it only for the dialog, then I will extract those regex's only. We're going to need two different keysym checking functions, for use in several places: 1) Check that a keysym is valid for Tk. This will be used for manually defined key bindings in the advanced dialog and user config files. This should use the method from Roger Serwy's patch, which creates a temporary Tk object and tries to bind the keysym with it. It could also include a preliminary check (via simple parsing) to give informative error messages for obviously invalid keysyms such as "". 2) Check that a keysym is in our canonical form. This will be used to test the default config files shipped with IDLE and for testing the "basic" key config dialog. Both of these should use some common code for the basic parsing of a keysym into its parts. > No particular reason. I had a feeling splitting method could get > messy. But if its for a small set that the validity method is going to > be required for, splitting method is better. As can be seen in your patch, parsing with regexps tends to get even messier. I believe removing the '<' and '>' and the ends and splitting by '-' will be much simpler. Just make sure to group the pieces into the three relevant groups: modifier(s), type and detail (see [1]), while preserving the order of the items in each group. .. [1]: http://effbot.org/tkinterbook/tkinter-events-and-bindings.htm - Tal Einat From taleinat at gmail.com Sat Jun 14 12:16:06 2014 From: taleinat at gmail.com (Tal Einat) Date: Sat, 14 Jun 2014 13:16:06 +0300 Subject: [Idle-dev] KeyConfig, KeyBinding and other related issues. In-Reply-To: References: <539805D6.8020201@udel.edu> <5399FB2D.1050208@udel.edu> <539A4C05.8060100@udel.edu> Message-ID: On Sat, Jun 14, 2014 at 10:29 AM, Tal Einat wrote: > As can be seen in your patch, parsing with regexps tends to get even > messier. I believe removing the '<' and '>' and the ends and splitting > by '-' will be much simpler. Just make sure to group the pieces into > the three relevant groups: modifier(s), type and detail (see [1]), > while preserving the order of the items in each group. To give a bit more direction on the implementation, the steps for the parsing function should be roughly: 1) basic parsing: remove '<' and '>' and ends and split by '-' 2) group parts into the three groups while checking that they are valid (not empty, etc.) 3) return the groups Each step should give an informative message if an error is encountered. The validity checking function could check that each group is valid, e.g. no modifier appears more than once, no more than one type and one detail appear, etc. The canonization function could take that output and build a keysym from it. - Tal From saimadhavheblikar at gmail.com Sun Jun 15 13:53:29 2014 From: saimadhavheblikar at gmail.com (Saimadhav Heblikar) Date: Sun, 15 Jun 2014 17:23:29 +0530 Subject: [Idle-dev] KeyConfig, KeyBinding and other related issues. In-Reply-To: References: <539805D6.8020201@udel.edu> <5399FB2D.1050208@udel.edu> <539A4C05.8060100@udel.edu> Message-ID: Hi, I followed the above direction and made some progress. Lib/tkinter/__init__.py Line 998, gives some more info on the syntax for keysequence. https://gist.github.com/sahutd/289d2297eb83a020a6dd#file-test-keyseq-v2-diff. It only covers a few exceptions. I am posting this early, before I am far away in the wrong direction. Also, is the key_ok method intended as a replacement for the existing KeysOk method? Or are both going to exist? On 14 June 2014 15:46, Tal Einat wrote: > > To give a bit more direction on the implementation, the steps for the > parsing function should be roughly: > > 1) basic parsing: remove '<' and '>' and ends and split by '-' > 2) group parts into the three groups while checking that they are > valid (not empty, etc.) > Grouping required a single line of regex. pat = '^<(?P(({modifier})-){{0,3}})(({type})-)?({detail})>$'.format(modifier=modifier_regex,type=type_regex, detail=detail_regex) > > 3) return the groups > > Each step should give an informative message if an error is encountered. > For the above point, should key_ok method raise an error or return False or display a tkMessageBox ? -- Regards Saimadhav Heblikar From taleinat at gmail.com Sun Jun 15 14:39:31 2014 From: taleinat at gmail.com (Tal Einat) Date: Sun, 15 Jun 2014 15:39:31 +0300 Subject: [Idle-dev] KeyConfig, KeyBinding and other related issues. In-Reply-To: References: <539805D6.8020201@udel.edu> <5399FB2D.1050208@udel.edu> <539A4C05.8060100@udel.edu> Message-ID: On Sun, Jun 15, 2014 at 2:53 PM, Saimadhav Heblikar wrote: > Hi, > I followed the above direction and made some progress. > Lib/tkinter/__init__.py Line 998, gives some more info on the syntax > for keysequence. > > https://gist.github.com/sahutd/289d2297eb83a020a6dd#file-test-keyseq-v2-diff. > It only covers a few exceptions. I am posting this early, before I am > far away in the wrong direction. > > Also, is the key_ok method intended as a replacement for the existing > KeysOk method? Or are both going to exist? > > > On 14 June 2014 15:46, Tal Einat wrote: >> >> To give a bit more direction on the implementation, the steps for the >> parsing function should be roughly: >> >> 1) basic parsing: remove '<' and '>' and ends and split by '-' >> 2) group parts into the three groups while checking that they are >> valid (not empty, etc.) >> > Grouping required a single line of regex. > pat = '^<(?P(({modifier})-){{0,3}})(({type})-)?({detail})>$'.format(modifier=modifier_regex,type=type_regex, > detail=detail_regex) I usually avoid building regexps from pieces, though, because I've had bad experiences after doing that myself. More importantly, how will you give informative error messages if the regexp fails? For example, how will you tell the difference between a missing '>', an invalid modifier, and a missing detail? That's the downside with a regexp - it either matches or doesn't, and if not you can't tell why. I'll let Terry answer your other questions. - Tal From saimadhavheblikar at gmail.com Sun Jun 15 16:13:31 2014 From: saimadhavheblikar at gmail.com (Saimadhav Heblikar) Date: Sun, 15 Jun 2014 19:43:31 +0530 Subject: [Idle-dev] KeyConfig, KeyBinding and other related issues. In-Reply-To: References: <539805D6.8020201@udel.edu> <5399FB2D.1050208@udel.edu> <539A4C05.8060100@udel.edu> Message-ID: On 15 June 2014 18:09, Tal Einat wrote: > > More importantly, how will you give informative error messages if the > regexp fails? For example, how will you tell the difference between a > missing '>', an invalid modifier, and a missing detail? That's the > downside with a regexp - it either matches or doesn't, and if not you > can't tell why. > As you can see in the above link, simple cases like missing '<' at start, repeated modifier, missing '>' at end, errors with appropriate messages are raised. I now updated the diff file at https://gist.github.com/sahutd/289d2297eb83a020a6dd. It can now ascertain which part of (whether modifier, type or detail) is invalid. It can also say why it is invalid(Not all reasons are covered ATM, though it can be done quite easily. Just a matter of checking for that condition and adding a suitable error message). See the tests in the same diff for an example. -- Regards Saimadhav Heblikar From saimadhavheblikar at gmail.com Sun Jun 15 16:50:55 2014 From: saimadhavheblikar at gmail.com (Saimadhav Heblikar) Date: Sun, 15 Jun 2014 20:20:55 +0530 Subject: [Idle-dev] IDLE Line numbering initial plan Message-ID: Hi, An open issue for this topic[1]. This email details how I want to add line numbering to IDLE. The mock is at [2] This will be only added to EditorWindow and OutputWindow. The tk.Text class will be replaced by a Text class which inherits from tk.Text as in the mock(line 50). Basically, a virtual event called <> is going to be generated when the following actions take place: insert, delete, replace, when 'insert' is changed, the window moves etc. The Text object will intercept this call, trigger <>. It will propagate the original call, as well. The line number canvas will be at the left of the text area. It will be redrawn, whenever the above events take place. I was worried about memory usage due to constant redrawing, but the memory never increased beyond 5.3 MiB. This is good, given a text widget on its own takes 5.0 MiB. Processor usage was same in both cases. As far as details like background, color of text etc are concerned, they will be added to config-highlight.def. There will be a menu option to toggle the line numbering canvas on-off. Would something like the "Code Context" option in "Options" menu be good? The open issue[1] says it should be enabled by default. That to me seems like the right way to do it. But if we were to do it as an extension, will the existing extension mechanism allow it?(Especially the tk.Text overriding part). Could someone familiar with the mechanism could fill me in on it? Should the linenumbering related code go into a new class and the Text widget be imported from there, or should it be added into EditorWindow itself?(LineNumber canvas, the interception mechansim etc) --- [1] http://bugs.python.org/issue17535 [2] https://bitbucket.org/sahutd/linenumbering-mockup/src/d311c81a6fbcfa10d125279d616fb90c9745aab6/line-numbering-mockup.py?at=default -- Regards Saimadhav Heblikar From taleinat at gmail.com Mon Jun 16 00:06:21 2014 From: taleinat at gmail.com (Tal Einat) Date: Mon, 16 Jun 2014 01:06:21 +0300 Subject: [Idle-dev] IDLE Line numbering initial plan In-Reply-To: References: Message-ID: On Sun, Jun 15, 2014 at 5:50 PM, Saimadhav Heblikar wrote: > Hi, > > An open issue for this topic[1]. > > This email details how I want to add line numbering to IDLE. The mock is at > [2] > > This will be only added to EditorWindow and OutputWindow. > > The tk.Text class will be replaced by a Text class which inherits from > tk.Text as in the mock(line 50). Basically, a virtual event called > <> is going to be generated when the following actions take > place: > insert, delete, replace, when 'insert' is changed, the window moves etc. > The Text object will intercept this call, trigger <>. It will > propagate the original call, as well. > The line number canvas will be at the left of the text area. It will > be redrawn, whenever the above events take place. I'm guessing this is based largely on the code here, right? http://stackoverflow.com/questions/16369470/tkinter-adding-line-number-to-text-widget That does look like a very robust approach. > I was worried about memory usage due to constant redrawing, but the > memory never increased beyond 5.3 MiB. This is good, given a text > widget on its own takes 5.0 MiB. > Processor usage was same in both cases. > > As far as details like background, color of text etc are concerned, > they will be added to config-highlight.def. > > There will be a menu option to toggle the line numbering canvas > on-off. Would something like the "Code Context" option in "Options" > menu be good? I think it would be more natural for this setting to be under the "General" tab in the config dialog. > The open issue[1] says it should be enabled by default. That to me > seems like the right way to do it. But if we were to do it as an > extension, will the existing extension mechanism allow it?(Especially > the tk.Text overriding part). Could someone familiar with the > mechanism could fill me in on it? There's no need to implement this as an extension. Doing so would be unwise, I think, considering that this will be messing around under the hood with the Text widget. > Should the linenumbering related code go into a new class and the Text > widget be imported from there, or should it be added into EditorWindow > itself?(LineNumber canvas, the interception mechansim etc) You should use separate classes, but they do not necessarily have to be in a separate file. IDLE already has too many code files around. In this case, however, I think you should put these in a new file. This code could be useful for other projects as well, and it will be easier for them to find the code an reuse it if it is in a file of its own. Other notes and questions: 1) If you'd like to allow separate configuration of the text and background colors for the line numbers, you will eventually have to add those to the "highlighting" tab of the config dialog as well. This could be left until after we have a satisfactory initial working version though. 2) Will this support non-standard line heights in the text widget, such as those inserted by the Squeezer extension? If so, how? If this makes the implementation slower or more complex then it can be left out. 3) If this event is going to be triggered for every change in the Text widget, I'm more concerned about performance than memory. I'd like for us to test the effect this has on weak computers, e.g. Raspberry Pi. These are all quite minor notes. Overall I think you're on to a good approach. I really like that you thought in advance of possible ill effects, such as memory usage, and went on to check those before beginning. I think you're about ready to get started on this, and I'll be excited to see your progress! Good night, - Tal Einat From tjreedy at udel.edu Mon Jun 16 04:05:59 2014 From: tjreedy at udel.edu (Terry Reedy) Date: Sun, 15 Jun 2014 22:05:59 -0400 Subject: [Idle-dev] KeyConfig, KeyBinding and other related issues. In-Reply-To: References: <539A4C05.8060100@udel.edu> Message-ID: On 6/15/2014 7:53 AM, Saimadhav Heblikar wrote: > Hi, > I followed the above direction and made some progress. > Lib/tkinter/__init__.py Line 998, gives some more info on the syntax > for keysequence. > > https://gist.github.com/sahutd/289d2297eb83a020a6dd#file-test-keyseq-v2-diff. > It only covers a few exceptions. I am posting this early, before I am > far away in the wrong direction. > > Also, is the key_ok method intended as a replacement for the existing > KeysOk method? Or are both going to exist? My thoughts as of this evening: What we want is a broader check function usable in multiple places. Whatever you write for testing may need to be modified for use in multiple places. If we imagine putting a module-level function into KeybindingDialog.py, definitions of constants (in LaodFinalKeyList and TranslateKey) could be moved from class to module scope to make them available to a new check function. The TranslateKey methods could also be elevated, as it has no dependence on 'self' and is not really an instance method. Parameterless KeysOK is specific to and intertwined with the basic dialog (which is why it can work without overt inputs). Since it mostly works with the pieces used to create the keystring, it avoids parsing the keystrings (which is why it cannot work with advanced mode). This make it awful to test, compared with a function that take the keystring as a parameter and parses it without other info. After the keystring is fetched, the rest of the body could be replaced with a call to a function that *does* parse. But that is not important either way at the moment. Since KeysOK shows at most one error message, the tkMessagebox call could be factored out of the switch, with each branch setting msg (else: would set it to ''). Then add at the end 'if msg: tkMessageBox.showerror( parent=self, title='Key Sequence Error', message='Keystring {}: {}'.format(keys, msg)) I might actually do this. Once done, the logic of KeysOK could be inverted to KeysNotOk (or KeysBad) by returning msg. The caller could replace 'self.KeysOk' with 'not self.KeysBad'. And additional refinement would make KeysBad even easier to test: a dictionary of error messages (which also makes it easy to see the conditions tested). keyerrors = { 'empty' : 'no keys specified.', 'end' : 'missing the final Key'. 'mod' : 'no modifier key(s) specified.'. 'shift' : 'the shift modifier by itself may not be used with' ' this key symbol.'. 'dup' : 'this key combination is already in use.', } Now, if KeysBad sets messages with statements like if not keys: msg = keyerrors['empty'] a test such as self.assertIn(keyerrors['empty'], KeysBad('')) is not only clear and easy to write, but is also robust against message edits in the one and only location, the dictionary. As you might have guessed, I am writing the above to answer your question below. keyerrors = { ... } def key_bad(keystring, showerror=True): # False in test files if msg and showerror: tkMessage.... return msg If you decide or plan to detect and report multiple errors, the details of message construction can be altered. When Idle initializes from .def files, keystrings should first be given to tk, as now, and the check function only used to display an error message after catching tcl_error. If key_bad returns '' when tk has rejected it, display a backup message: 'tk rejects %s, but we cannot determine why' % keystring. > On 14 June 2014 15:46, Tal Einat wrote: >> >> To give a bit more direction on the implementation, the steps for the >> parsing function should be roughly: >> >> 1) basic parsing: remove '<' and '>' and ends and split by '_'. Perhaps the person who suggested a finite automaton was suggesting transitions based on words after such a split, rather than character based transitions, as with re engines. My main concern is that errors get detected and reported. >> 2) group parts into the three groups while checking that they are >> valid (not empty, etc.) > Grouping required a single line of regex. > pat = '^<(?P(({modifier})-){{0,3}})(({type})-)?({detail})>$'.format(modifier=modifier_regex,type=type_regex, > detail=detail_regex) > >> >> 3) return the groups >> >> Each step should give an informative message if an error is encountered. > For the above point, should key_ok method raise an error or return > False or display a tkMessageBox ? See above. -- Terry Jan Reedy From tjreedy at udel.edu Mon Jun 16 04:18:00 2014 From: tjreedy at udel.edu (Terry Reedy) Date: Sun, 15 Jun 2014 22:18:00 -0400 Subject: [Idle-dev] IDLE Line numbering initial plan In-Reply-To: References: Message-ID: On 6/15/2014 6:06 PM, Tal Einat wrote: > On Sun, Jun 15, 2014 at 5:50 PM, Saimadhav Heblikar > wrote: >> Hi, >> >> An open issue for this topic[1]. >> >> This email details how I want to add line numbering to IDLE. The mock is at >> [2] >> >> This will be only added to EditorWindow and OutputWindow. Since there may be more EditorWindow subclasses, it should be selectable. > I'm guessing this is based largely on the code here, right? > http://stackoverflow.com/questions/16369470/tkinter-adding-line-number-to-text-widget > > That does look like a very robust approach. I will try to read that. ... > In this case, however, I think you should put these in a new file. > This code could be useful for other projects as well, and it will be > easier for them to find the code an reuse it if it is in a file of its > own. If possible, try to segregate idle independent code from idle dependent code. Code used by anything other than Idle and extensions should be in tkinter package. (This is part of and implied by PEP 434.) -- Terry Jan Reedy From saimadhavheblikar at gmail.com Tue Jun 17 15:01:49 2014 From: saimadhavheblikar at gmail.com (Saimadhav Heblikar) Date: Tue, 17 Jun 2014 18:31:49 +0530 Subject: [Idle-dev] IDLE Line numbering initial plan In-Reply-To: References: Message-ID: Hi, I have integrated line numbering into IDLE. All the code related to it, are in idlelib/LineNumber.py for the moment, for easier debugging. I'd like to say, that there is a memory leak. The leak is, events like insert, scroll etc cause the memory to increase continuously. AFA I can tell, the number of objects after every re-render is constant. Objects are first deleted before new ones are created. I have tried reusing existing objects and moving them to the required screen coordinate, instead of deleting and creating anew. This did not work. I can almost certainly say that it is related MultiCallCreator's MultiCall class and not with the way LineNumberCanvas rerender's itself. In the past two days, I have been trying to understand the MultiCall module and how values related to <> virtual event have to be added to it. I have not made a breakthrough yet. The current changes to MultiCall.py goes some way to reduce the sluggishness. This make me feel more strongly that some optmization in MultiCall, will fix the memory leak. I have also added a file text-without-multicall.py to show the above. In this, using tkinter.Text, the memory usage does not change. I have attached the patch in this email. -- Regards Saimadhav Heblikar -------------- next part -------------- diff -r 601a08fcb507 Lib/idlelib/EditorWindow.py --- a/Lib/idlelib/EditorWindow.py Sat Jun 14 18:51:34 2014 -0700 +++ b/Lib/idlelib/EditorWindow.py Tue Jun 17 18:28:18 2014 +0530 @@ -13,6 +13,7 @@ import webbrowser from idlelib.MultiCall import MultiCallCreator +from idlelib.LineNumber import LineNumberCanvas, Text from idlelib import idlever from idlelib import WindowList from idlelib import SearchDialog @@ -227,6 +228,10 @@ vbar['command'] = text.yview vbar.pack(side=RIGHT, fill=Y) text['yscrollcommand'] = vbar.set + if self.__class__.__name__ != 'PyShell': + self.linenumber_canvas = LineNumberCanvas(text_frame) + self.linenumber_canvas.connect(text=self.text, side=LEFT, fill=Y) + fontWeight = 'normal' if idleConf.GetOption('main', 'EditorWindow', 'font-bold', type='bool'): fontWeight='bold' diff -r 601a08fcb507 Lib/idlelib/LineNumber.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Lib/idlelib/LineNumber.py Tue Jun 17 18:28:18 2014 +0530 @@ -0,0 +1,65 @@ +import tkinter as tk + +class LineNumberCanvas(tk.Canvas): + def __init__(self,*args, **kwargs): + tk.Canvas.__init__(self, *args, **kwargs) + + def connect(self, text, *arg, **kwargs): + self.text = text + self.text.bind("<>", self.re_render) + self.text.bind("", self.re_render) + self.number_of_digits = 0 + self.pack(*arg, **kwargs) + + def disconnect(self, text_widget): + pass + + def re_render(self, event): + """Re-render the line canvas""" + self.delete('all') + if self.number_of_digits != len(self.text.index('end')): + self.number_of_digits = len(self.text.index('end')) + self['width'] = self.number_of_digits * 8 + + temp = self.text.index("@0,0") + while True : + dline= self.text.dlineinfo(temp) + if not dline: + break + y, height = dline[1], dline[4] + linenum = str(temp).split(".")[0] + linenum_text = ' '*(self.number_of_digits - len(linenum)) \ + + linenum + self.create_text(5, y + height/4, anchor="nw", text=linenum_text) + temp = self.text.index("%s+1line" % temp) + +class Text(tk.Text): + def __init__(self, *args, **kwargs): + tk.Text.__init__(self, *args, **kwargs) + + self.tk.eval(''' + proc widget_interceptor {widget command args} { + + set orig_call [uplevel [linsert $args 0 $command]] + + if { + ([lindex $args 0] == "insert") || + ([lindex $args 0] == "delete") || + ([lindex $args 0] == "replace") || + ([lrange $args 0 2] == {mark set insert}) || + ([lrange $args 0 1] == {xview moveto}) || + ([lrange $args 0 1] == {xview scroll}) || + ([lrange $args 0 1] == {yview moveto}) || + ([lrange $args 0 1] == {yview scroll})} { + + event generate $widget <> -when tail + } + + #return original command + return $orig_call + } + ''') + self.tk.eval(''' + rename {widget} new_{widget} + interp alias {{}} ::{widget} {{}} widget_interceptor {widget} new_{widget} + '''.format(widget=str(self))) diff -r 601a08fcb507 Lib/idlelib/MultiCall.py --- a/Lib/idlelib/MultiCall.py Sat Jun 14 18:51:34 2014 -0700 +++ b/Lib/idlelib/MultiCall.py Tue Jun 17 18:28:18 2014 +0530 @@ -34,8 +34,8 @@ import tkinter # the event type constants, which define the meaning of mc_type -MC_KEYPRESS=0; MC_KEYRELEASE=1; MC_BUTTONPRESS=2; MC_BUTTONRELEASE=3; -MC_ACTIVATE=4; MC_CIRCULATE=5; MC_COLORMAP=6; MC_CONFIGURE=7; +MC_CHANGED=0; MC_KEYPRESS=0; MC_KEYRELEASE=1; MC_BUTTONPRESS=2; MC_BUTTONRELEASE=3; +MC_ACTIVATE=4; MC_CIRCULATE=5; MC_COLORMAP=6; MC_CONFIGURE=7; MC_DEACTIVATE=8; MC_DESTROY=9; MC_ENTER=10; MC_EXPOSE=11; MC_FOCUSIN=12; MC_FOCUSOUT=13; MC_GRAVITY=14; MC_LEAVE=15; MC_MAP=16; MC_MOTION=17; MC_MOUSEWHEEL=18; MC_PROPERTY=19; MC_REPARENT=20; MC_UNMAP=21; MC_VISIBILITY=22; @@ -251,7 +251,7 @@ # define the list of event types to be handled by MultiEvent. the order is # compatible with the definition of event type constants. _types = ( - ("KeyPress", "Key"), ("KeyRelease",), ("ButtonPress", "Button"), + ("KeyPress", "Key", "Changed"), ("KeyRelease",), ("ButtonPress", "Button"), ("ButtonRelease",), ("Activate",), ("Circulate",), ("Colormap",), ("Configure",), ("Deactivate",), ("Destroy",), ("Enter",), ("Expose",), ("FocusIn",), ("FocusOut",), ("Gravity",), ("Leave",), ("Map",), diff -r 601a08fcb507 text-without-multicall.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/text-without-multicall.py Tue Jun 17 18:28:18 2014 +0530 @@ -0,0 +1,27 @@ +from idlelib.LineNumber import LineNumberCanvas, Text +import tkinter as tk + +class EditorWindow(tk.Frame): + def __init__(self, *args, **kwargs): + tk.Frame.__init__(self, *args, **kwargs) + self.text = Text(self) + self.scrollbar = tk.Scrollbar(orient="vertical", command=self.text.yview) + + self.text.configure(yscrollcommand=self.scrollbar.set) + + self.linenumbers = LineNumberCanvas(self, width=40) + self.linenumbers.connect(self.text) + + self.scrollbar.pack(side="right", fill="y") + self.linenumbers.pack(side="left", fill="y") + + self.text.bind("<>", self.linenumbers.re_render) + self.text.bind("", self.linenumbers.re_render) + self.text.pack(side="right", fill="both", expand=True) + for i in range(1000): + self.text.insert('end','sample text'+'\n') + +root = tk.Tk() +editwin = EditorWindow() +editwin.pack() +root.mainloop() From saimadhavheblikar at gmail.com Wed Jun 18 18:23:53 2014 From: saimadhavheblikar at gmail.com (Saimadhav Heblikar) Date: Wed, 18 Jun 2014 21:53:53 +0530 Subject: [Idle-dev] KeyConfig, KeyBinding and other related issues. In-Reply-To: References: <539805D6.8020201@udel.edu> <5399FB2D.1050208@udel.edu> <539A4C05.8060100@udel.edu> Message-ID: In this version, I have attempted an API like solution. It does not raise any error.(except for couple of asserts for REALLY bad input, and that too only in internal functions) All mistakes are caught(i.e. it does not fail on the first "mistake".). I have documented every where, so should be easy to read. Each aspect is a method. So is easy to unittest and has been unittested. It can detect invalid begin character, invalid end character, repeated keys, invalid keys, invalid ordering and with reason, where not directly obvious. -- Regards Saimadhav Heblikar -------------- next part -------------- diff -r 4cf322536328 Lib/idlelib/idle_test/test_keybinding.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Lib/idlelib/idle_test/test_keybinding.py Wed Jun 18 21:49:40 2014 +0530 @@ -0,0 +1,254 @@ +"""Unittest for idlelib.keybindingDialog.py""" +import unittest +import string +from unittest.mock import Mock + +modifierKeys = ['Control', 'Alt', 'Shift', 'Meta'] +typeKeys = ['Key'] +functionKeys = ('F1', 'F2', 'F3', 'F4', 'F5', 'F6', 'F7', 'F8', 'F9', + 'F10', 'F11', 'F12') +alphanumKeys = tuple(string.ascii_lowercase + string.digits) +whitespaceKeys = ('Tab', 'space', 'Return') +editKeys = ('BackSpace', 'Delete', 'Insert') +moveKeys = ('Home', 'End', 'Prior', 'Next', 'Left', + 'Right', 'Up', 'Down') +otherKeys = ('Escape', 'bracketright', 'bracketleft', 'KP_Enter') +detailKeys = alphanumKeys + functionKeys + editKeys + moveKeys + \ + whitespaceKeys + otherKeys + +MODIFERS = 1 +TYPEKEY = 2 +DETAIL = 3 + + +class Keyseq: + + def __init__(self, keyseq): + """ + keyseq - A tkinter keysequence starting that has to be validated + process_keyseq - bool + """ + self.keyseq = keyseq + self.result = self.process_keyseq() + + def process_keyseq(self): + """Return result dict described below: + The dict is as below + valid_beginning - bool + has_invalid_keys - bool + invalid_keys - List of invalid keys, [] if there are none + has_repeated_keys - bool, whether keyseq contains repeated keys + repeated_keys - List of repeated keys, [] if there are none + valid_ending - bool + is_valid - bool, whether keyseq is semantically valid/not valid + + """ + result = {} + result['valid_beginning'] = self.is_valid_beginning() + result['invalid_keys'] = self.tokenize()['invalid_keys'] + result['has_invalid_keys'] = result['invalid_keys'] != [] + result['has_repeated_keys'] = self.has_repeated_keys() + result['repeated_keys'] = self.repeated_keys() + result['valid_ending'] = self.is_valid_ending() + result['is_valid'] = result['valid_beginning'] \ + and result['valid_ending'] \ + and not result['has_invalid_keys'] \ + and not result['has_repeated_keys'] + + return result + + def _get_type(self, key): + """Given a key, return its type. + Invalid key raises ValueError""" + if key in modifierKeys: + return MODIFERS + if key in typeKeys: + return TYPEKEY + if key in detailKeys: + return DETAIL + raise ValueError('invalid key beginning key') + + def tokenize(self): + """Tokenize a keysequence. + Return a dict containing keys: + valid_keys - list of tuple of form (key, type) + invalid_keys - list of tuple of form (invalid_keys, reason) + """ + keyseq = self.keyseq + if self.is_valid_beginning(): + keyseq = keyseq[1:] + if self.is_valid_ending(): + keyseq = keyseq[:-1] + self.keyseq_split = keyseq_split = keyseq.split('-') + d = {'valid_keys': [], + 'invalid_keys': [] + } + prev_type = current_type = -1 + for i in range(len(keyseq_split)): + key = keyseq_split[i] + try: + current_type = self._get_type(key) + + except ValueError: + d['invalid_keys'].append(key) + continue + + if prev_type == MODIFERS: + if current_type != MODIFERS and current_type != TYPEKEY and current_type != DETAIL: + d['invalid_keys'].append((key, ('{} key is invalid key for this position. Was expecting' + ' a modifier key, a type key or a detail key.'.format(key)))) + continue + if prev_type == TYPEKEY: + if current_type == MODIFERS: + d['invalid_keys'].append((key, ( + '{} key is invalid to be used after Typekey'.format(key)))) + continue + if prev_type == DETAIL: + d['invalid_keys'].append((key, ( + '{} key is invalid to be used after Detail key.'.format(key)))) + continue + + d['valid_keys'].append((key, current_type)) + prev_type = current_type + + return d + + def is_valid_beginning(self): + return self.keyseq[0] is '<' + + def is_valid_ending(self): + return self.keyseq[-1] is '>' + + def has_repeated_keys(self): + return len(set(self.keyseq_split)) < len(self.keyseq_split) + + def repeated_keys(self): + """Return list of repated keys or [] if there are none""" + return [key for key in set(self.keyseq_split) if self.keyseq_split.count(key) > 1] + + def has_invalid_keys(self): + return self.tokenize()['invalid_keys'] != [] + + def invalid_keys(self): + """Return list of invalid keys or [] if there are none""" + return self.tokenize()['invalid_keys'] + + def is_valid(self): + """Return whether keyseq is logically valid. + Fail early if keyseq has invalid/repeated keys""" + assert self.has_repeated_keys() == False + assert self.tokenize()['invalid_keys'] == [] + keyseq_split = self.tokenize()['valid_keys'] + prev_type = current_type = -1 + + +class TestIsValidKeyseq(unittest.TestCase): + + def test_get_type(self): + s = Mock() + get = Keyseq._get_type + + self.assertEqual(get(s, 'Control'), MODIFERS) + self.assertEqual(get(s, 'Key'), TYPEKEY) + self.assertEqual(get(s, 'x'), DETAIL) + self.assertEqual(get(s, 'space'), DETAIL) + with self.assertRaises(ValueError) as ve: + get(s, 'Space') + self.assertIn('invalid key', str(ve.exception)) + with self.assertRaises(ValueError) as ve: + get(s, 'Contro') + self.assertIn('invalid key', str(ve.exception)) + + def test_tokenize(self): + k = Keyseq('') + self.assertTupleEqual(k.tokenize()['valid_keys'][1], ('Alt', MODIFERS)) + self.assertTupleEqual(k.tokenize()['valid_keys'][2], ('Key', TYPEKEY)) + self.assertTupleEqual(k.tokenize()['valid_keys'][3], ('x', DETAIL)) + + k = Keyseq('') + self.assertListEqual(k.tokenize()['invalid_keys'], ['Contro']) + + k = Keyseq('') + invalid_keys = k.tokenize()['invalid_keys'] + self.assertEqual(invalid_keys[0][0], 'Control') + self.assertIn('after Typekey', invalid_keys[0][1]) + + k = Keyseq('') + invalid_keys = k.tokenize()['invalid_keys'] + self.assertEqual(invalid_keys[0][0], 'Alt') + self.assertIn('after Detail key', invalid_keys[0][1]) + + def test_valid_beginning(self): + valid = Keyseq.is_valid_beginning + k = Mock() + k.keyseq = '' + self.assertTrue(valid(k)) + k.keyseq = 'Control-x' + self.assertFalse(valid(k)) + + def test_valid_ending(self): + valid = Keyseq.is_valid_ending + k = Mock() + k.keyseq = '' + self.assertTrue(valid(k)) + k.keyseq = '') + self.assertFalse(k.has_repeated_keys()) + + k = Keyseq('') + self.assertTrue(k.has_repeated_keys()) + + def test_repeated_keys(self): + k = Keyseq('') + self.assertEqual(k.repeated_keys(), []) + + k = Keyseq('') + self.assertEqual(k.repeated_keys(), ['Control']) + + k = Keyseq('') + self.assertListEqual(sorted(k.repeated_keys()), ['Alt', 'Control']) + + def test_has_invalid_keys(self): + k = Keyseq('') + self.assertFalse(k.has_invalid_keys()) + + k = Keyseq('') + self.assertTrue(k.has_invalid_keys()) + + def test_invalid_keys(self): + k = Keyseq('') + self.assertListEqual(k.invalid_keys(), []) + + k = Keyseq('') + self.assertListEqual(k.invalid_keys(), ['Contro']) + + def test_is_valid(self): + k = Keyseq('') + with self.assertRaises(AssertionError): + k.is_valid() + k = Keyseq('') + with self.assertRaises(AssertionError): + k.is_valid() + + def test_process_keyseq(self): + k = Keyseq('') + result = k.result + self.assertTrue(result['valid_beginning']) + self.assertTrue(result['valid_ending']) + self.assertFalse(result['has_invalid_keys']) + self.assertFalse(result['has_repeated_keys']) + self.assertTrue(result['is_valid']) + + k = Keyseq(' References: <539805D6.8020201@udel.edu> <5399FB2D.1050208@udel.edu> <539A4C05.8060100@udel.edu> Message-ID: I see you went with an entirely different design for this than either what you originally suggested or what I suggested. Could you explain why? Technical notes: 1) _get_type() should be a class method instead of a normal method (using the @classmethod decorator). This will also make testing it simpler. 2) Never use "is" to compare strings! 3) Why not use Counter when generated the list of duplicate keys, as I suggested in my code sample? It's more straightforward and elegant. 4) I prefer to call the parts something other than "keys", perhaps "parts" or "pieces". In some cases, such as mouse events, they are not keyboard keys. On Wed, Jun 18, 2014 at 7:23 PM, Saimadhav Heblikar < saimadhavheblikar at gmail.com> wrote: > In this version, I have attempted an API like solution. It does not > raise any error.(except for couple of asserts for REALLY bad input, > and that too only in internal functions) > > All mistakes are caught(i.e. it does not fail on the first > "mistake".). I have documented every where, so should be easy to read. > Each aspect is a method. So is easy to unittest and has been > unittested. > > It can detect invalid begin character, invalid end character, repeated > keys, invalid keys, invalid ordering and with reason, where not > directly obvious. > > -- > Regards > Saimadhav Heblikar > -------------- next part -------------- An HTML attachment was scrubbed... URL: From saimadhavheblikar at gmail.com Thu Jun 19 09:24:01 2014 From: saimadhavheblikar at gmail.com (Saimadhav Heblikar) Date: Thu, 19 Jun 2014 12:54:01 +0530 Subject: [Idle-dev] KeyConfig, KeyBinding and other related issues. In-Reply-To: References: <539805D6.8020201@udel.edu> <5399FB2D.1050208@udel.edu> <539A4C05.8060100@udel.edu> Message-ID: On 18 June 2014 23:03, Tal Einat wrote: > I see you went with an entirely different design for this than either what > you originally suggested or what I suggested. Could you explain why? > I dont think I have gone with a different design. I have incorporated what you suggested and what I had suggested, but put every aspect into a method of its own. I felt it was best not to raise errors when there was one, because I remember Terry Reedy and you mentioning that it will be used in more than one place. I felt it would be better to leave it to the user(the different places in Idlelib where it will be used) to decide what to do in case there are mistakes. > Technical notes: > > 1) _get_type() should be a class method instead of a normal method (using > the @classmethod decorator). This will also make testing it simpler. > 2) Never use "is" to compare strings! I did not know these two things. Thanks for pointing them out. > 3) Why not use Counter when generated the list of duplicate keys, as I > suggested in my code sample? It's more straightforward and elegant. > 4) I prefer to call the parts something other than "keys", perhaps "parts" > or "pieces". In some cases, such as mouse events, they are not keyboard > keys. > Will do 3 and 4. Do we proceed with this?(incorporating the changes from Technical Notes) -- Regards Saimadhav Heblikar From saimadhavheblikar at gmail.com Thu Jun 19 15:25:19 2014 From: saimadhavheblikar at gmail.com (Saimadhav Heblikar) Date: Thu, 19 Jun 2014 18:55:19 +0530 Subject: [Idle-dev] IDLE Line numbering initial plan In-Reply-To: References: Message-ID: http://bugs.python.org/issue17535#msg220973 contains the latest patch, and also fixes the memory leak. The reason for the leak is in the message. AFA this issue goes, I am currently working on menu and config(files and dialog) additions. I think peformance should not be an issue anymore, but if it is, please say so. -- Regards Saimadhav Heblikar From saimadhavheblikar at gmail.com Tue Jun 24 11:37:15 2014 From: saimadhavheblikar at gmail.com (Saimadhav Heblikar) Date: Tue, 24 Jun 2014 15:07:15 +0530 Subject: [Idle-dev] IDLE extension to integrate 3rd party checkers and analyzers Message-ID: Hi all, 1. Overall idea Two files Analyzer.py and configAnalyze.def to be added to Lib/idlelib. Analyzer.py will contain GUI components for a) Letting the user to install/uninstall 3rd party analyzers, via pip. There will be predefined templates for most commonly used analyzers like pyflakes, pylint, pep8 etc. If the user chooses to install their own, they should supply the parameters for it - Name, pypi url/pip name, optional arguments to be passed on to the analyzer when it is run, command line name for that program/ module name. b) There will be options for the user to reinstall/delete a analyser installed via IDLE c) If a analyzer is already installed, the user can skip reinstall by not mentioning the pypi url/pip name. We can perform checks to ensure that it is present,and prompt the user to enter a url/name if not. d) A list of currently installed checkers. Clicking it will bring up the above dialog with values filled in. The user can modify options in this dialog. configAnalyze.def a) Example: [PyFlakes] pip_name = pyflakes pypip url = https://pypi.python.org/pypi/pyflakes commandline_name = pyflakes commandline_parameters = enable_shell = 0 enable_editor = 1 add_file = 0 # should filename be prefixed in outputwindow output? regex = see below for explanation 2. Installation process This refers to the installation of the packages and not this extension. Once the details are ready, do pip.main(args) What to do if pip not available? 1. Try to install using ensurepip after asking user 2. Tell the user we cant proceed without pip. Ensure completion of instalation by doing simple checks like either importing that module/ calling it via command line and ensuring that no "file not found" type of errors are raised. 3. Process of analyzing a python file Retrieve settings for the analyzer. Make menu additions in PyShellEditorWindow programmatically, to display all extensions which the user has selected to use. Once the user wants to run it, ensure file is saved. Extract all required information like current file, the interpreter(2/3), and other settings as required. Call the standard runner method from Analyze.py, which will use subprocess. It will return the result, which will be displayed in outputwindow. (RightClick -> GotoLine capability already present!) All analyzers will not format the results in the same way. So we use the regex value to format the result in the same way. At minimum, we could extract the linenumber component. Format it according to our format and append the remaining part of the result before sending it to outputwindow. Using ensurepip means it will be 3.4+ feature, unless the target system already has pip, or atleast easy_install. -- Regards Saimadhav Heblikar