Viewing 20 posts - 1 through 20 (of 20 total)
  • Author
    Posts
  • #19704
    LifeTimer
    Participant

    The new advanced filter of EmEditor 14.7 is REALLY great!

    In order to make efficient use of it I would very much like to be able to control it from macros though, and as far as I understand, this is currently not supported (or am I mistaken?).

    What I would like to do is to be able to quickly add a new Advanced Filter “level” from a macro, i.e. the items that are shown in the list in the Advanced Filter dialog, and then be able to “reapply” this updated filter on my currently open text file.

    For example, if I’m working with a textfile called “webserver.log”, I would like to be able to select a certain string on some line in the text file, and then use a hotkey to execute a macro of mine that would add the selected string as a negative filter level in the Advanced Filter and then reapply it, thus removing all lines containing that string in the currently displayed file contents. By repeatedly using this procedure, which would be facilitated by the requested macro support, I would be able to quickly filter out all the unnecessary lines in the file, leaving me just with the lines I really want to see and work with.

    Is this supported by EmEditor’s current functionality, or could you please otherwise consider adding it?

    #19707
    Yutaka Emura
    Keymaster

    Hello LifeTimer,

    You can use multiple levels of “Filter” with a macro.

    For example, if you want to filter with “a” first, and then filter with “b”, you would write:

    
    document.Filter("a", -1, eeFindContinue);
    document.Filter("b", -1, 0);
    

    The “eeFindContinue” keyword means the filter operation will continue to the next filter.

    Thanks!

    #19708
    LifeTimer
    Participant

    Excellent!

    But where can I find a reference documentation for the macro functionality of EmEditor? I tried to download the PDF manual but it was not there, and I also tried to look in the online help (https://www.emeditor.com/help/macro/document/index.htm), but I cannot find any mention of the “Filter” functions there either?

    #19710
    Yutaka Emura
    Keymaster

    Hello LifeTimer,

    The documentation is included in the EmEditor Help. Please type “filter” in EmEditor and press the F1 key while the cursor is inside the “filter” word.

    I also just updated the HTML help:

    https://www.emeditor.com/help/macro/document/filter.htm

    Thanks!

    #19711
    LifeTimer
    Participant

    Thanks!

    Oh, and you might want to make the macro recording functionality correctly record Advanced Filters operations too by the way. One of the other things I tried before to get hold of the macro calls for the advanced filter was to record a macro when I applied advanced filters, but all it got was recorded mouse clicks and keystrokes.

    #19712
    LifeTimer
    Participant

    I just created a macro in order to accomplish what I described in my original post in this thread that I wanted to do, using the calls you mention here above (and also by looking more in the help for additional flags etc). I now have a macro containing only this line:

    document.Filter(document.selection.Text, -1, eeFindContinue | eeFindNegative);

    and I have also connected a shortcut key combination for this.

    When selecting some text and then calling this macro from the shortcut key though, the filter level is indeed added to the Advanced Filter dialog, but it is still not applied to the text contents I’m currently working with?

    How can I “execute”/apply the filter from the macro too? (as you can understand, it’s of course not much use to be able to create the filter from a macro if I still have to go into the Advanced Filter dialog manually to press the Filter button afterwards)

    PS.
    Lately, your forum has been VERY slow when processing login requests. It can take 10-60 seconds to complete a login, and many times it just times out completely. Today I had a very hard time logging in at all, getting only timeouts for very many tries until it finally let me in on like the tenth try or so. Please take a look at this if possible.

    #19713
    Yutaka Emura
    Keymaster

    Hello LifeTimer,

    If you use the eeFindContinue flag, you have to combine with another Filter method after this. If you need only one level of filter, please use the Filter method without the eeFindContinue flag. So your macro should look like:

    
    document.Filter(document.selection.Text, -1, eeFindNegative);
    

    Thanks,

    #19714
    LifeTimer
    Participant

    I see. The problem is that this design of the Advanced Filter macro interface makes is impossible to perform incremental filtering (i.e. adding one filter level at the time while viewing the results inbetween), doesn’t it?

    What I want to be able to do is to filter out all the lines containing some certain string, then review the results, then filter out all the lines containing some other certain string in these, then review the result, then… See what I mean?

    This would either require some macro operation of the kind “document.FilterAddLevel(…)” (which would preserve the current advanced filter, while still executing it as soon as the given new filter level has been added to it) or another command like “document.FilterExecute()” which could be used inbetween “Filter()”-calls that have the “eeFindContinue” flag set, right? Because as it is right now, either the filter is reset, or not executed at all if I try to add filter levels incrementally like this, which in both cases makes it impossible to perform incremental filtering?

    Or is there some clever solution that I’m missing?

    #19715
    Yutaka Emura
    Keymaster

    Hello LifeTimer,

    I will improve the macro feature so that when a macro is finished with the last Filter method, it will still refresh the documents with the last filter.

    Also, I found a bug in the current Filter method with the eeFindContinue flag. So, please don’t use the eeFindContinue flag until the next version.

    Thank you,

    #19716
    LifeTimer
    Participant

    Sounds great, thanks, looking forward to it then!

    #19717
    LifeTimer
    Participant

    Oh, and also please note that in order to get this to work in a coherent fashion, you might need to add another flag along the lines of “eeKeepPreviousFilterLevels”, since it will otherwise be impossible for a macro to know if it should keep any pre-existing filter levels when executing its first Filter() command. Actually, it would be more logical to completely switch out the “eeFindContinue” flag for such a “eeKeepPreviousFilterLevels” flag, which would then solve this problem without having to increase the total number of flags at all.

    Here follows an example to make clear what I mean. Imagine that you want to make two different macros:

    1.
    A macro that will add two new levels to the currently pre-existing advanced filter levels.

    2.
    A macro that will clear any current pre-existing advanced filter levels, and then add two new filter levels.

    As far as I can see, it is impossible to make this distinction using the current flags? Both of these macros would just consist of two lines like follows:

    document.Filter("FirstLevelFilterString", -1, eeFindContinue);
    document.Filter("FirstLevelFilterString", -1);

    And this can only result in either the previous filter levels being cleared in both cases (which is the behavior of the current EmEditor version), or the previous filter levels being preserved in both cases, right?

    If you instead were to switch out the “eeFindContinue” flag for a “eeKeepPreviousFilterLevels” flag, the two macros would instead be possible to implement as follows, and both of them would work according to their individual specification as stated above:

    1.

    document.Filter("FirstLevelFilterString", -1, eeKeepPreviousFilterLevels);
    document.Filter("FirstLevelFilterString", -1, eeKeepPreviousFilterLevels);

    2.

    document.Filter("FirstLevelFilterString", -1);
    document.Filter("FirstLevelFilterString", -1, eeKeepPreviousFilterLevels);

    As far as I can see, there also wouldn’t be any other negative consequences or losses of functionality from dropping the “eeFindContinue” flag and replacing it with the “eeKeepPreviousFilterLevels” flag. Right? Or am I somehow mistaken?

    #19721
    Yutaka Emura
    Keymaster

    Hi LifeTimer,

    I certainly consider your option before I chose the current “eeFindContinue” flag. That is performance. While it is negligible with small files, if you try to filter a very large file, this makes a big difference. With the eeFindContinue flag, EmEditor will wait until all the filter levels were set before it starts filtering. With the eeKeepPreviousFilterLevels flag, EmEditor will try to filter each time the Filter method appears.

    I could implement both flags for conveniences, but I wanted to minimize the number of options.

    As I wrote before, there is a bug in the current release (v14.7.0), so please wait until the next version before you start using the Filter method with the eeFindContinue flag.

    Thank you.

    #19724
    LifeTimer
    Participant

    Thanks for the explanation! I understand what you’re saying, but luckily there are several good solutions for it, where the best one is probably to never actually refresh the filter until a macro exits completely (or, in the most likely quite rare special-cases where it is really needed, a special “ForceFilterRefresh()” method that you can provide is called explicitly from within the macro).

    It would be really great if you could do either that, or just implement the “eeKeepPreviousFilterLevels” flag (in addition to “eeFindContinue” that is), as you so kindly offered in your last post, because otherwise the “incremental filtering” that I need won’t be possible to implement at all with macros, which would be a real shame, and something that probably many other people than me would miss too in the long run.

    Thanks again, really looking forward to the next update now! :-)

    #19725
    Yutaka Emura
    Keymaster

    Hello LifeTimer,

    Some people might need to do something between one filter and another filter.

    For example,

    // first filter
    document.Filter( ... );
    ..  // some operations
    // after this another filter
    document.Filter( ... );
    ..  // some operations
    

    Therefore, we have to filter each time a macro find the Filter method. (refresh and actual filter are actually different). A filter operation consumes much time, while refresh is very fast. Nevertheless, I could implement the “eeKeepPreviousFilterLevels” flag instead and make EmEditor macros smart enough to wait actual filtering until the macro see necessary if there is enough reason to do this. I just dont’ want to make the code too complicated.

    I didn’t quite understand your sentence:

    “because otherwise the “incremental filtering” that I need won’t be possible to implement at all with macros, which would be a real shame, and something that probably many other people than me would miss too in the long run.”

    Can you please describe why you need the “eeKeepPreviousFilterLevels” flag instead of the eeFindContinue flag?

    #19726
    LifeTimer
    Participant

    Thanks again for your reply Mr Emura,

    First of all, I am much aware of the delicate balance between functionality and simplicity in situations like this (I’m a developer myself), so I do indeed understand your hesitation about more functional but at the same time more complex solutions, just so you know.

    About the “refresh” operation, it was apparently just a bad choice of words from my side (I didn’t know there was already another macro operation with that name). So let’s call it “ForceFilterExecution()” instead in my example above. All I meant was that one solution to the performance problem would be to make the default behavior of the “Filter()” command to never perform any filtering until the macro completely exits, and then offer a new macro function called something like “ForceFilterExecution()” that people could execute from the macro if they really need it to perform the filtering in the middle of the macro after all.

    As a developer, I do understand though that there would be users that don’t know about this that would complain and report it as a bug etc. Therefore it might be best to just keep the “eeFindContinue” flag too, and make these two flags possible to use in the same call. As long as the “eeKeepPreviousFilterLevels” flag is included you keep any currently existing advanced filter levels, and as long as the “eeFindContinue” flag is included you don’t perform the filtering right after the call, but otherwise you do, just like it is currently implemented (a more descriptive name for the “eeFindContinue” flag would then perhaps be “eePostponeFiltering” or something like that).

    The core problem with the current design is that both of these separate aspects (that is “keep pre-existing filter levels” and “perform filtering immediately after the Filter() call”) are forced into one single flag, which leaves some combinations of these two aspects impossible to implement, while still being possibly desirable (as in my exact situation for example).

    Finally, you ask the following:

    Can you please describe why you need the “eeKeepPreviousFilterLevels” flag instead of the eeFindContinue flag?

    To answer this as efficiently as possible, I reply with the following counterquestion: If I want to make a macro that adds a new filter level to the currently existing filter levels at the point when the macro is executed (i.e. just like I describe that I want to do in my original post in this thread), how could I do this by only using the “eeFindContinue” flag? The first “Filter()” call in the macro will always clear all the current filter levels (since that flag only instructs what to do with the subsequent “Filter()” calls, but not the previous filter levels), while the “eeKeepPreviousFilterLevels” flag is able to specify also what to do with filter levels that already existed when the macro was executed.

    Again, the real world situation I need to work with is the following:

    I’m working with e.g. a web server log file, and I would then like to be able to select a certain string on some line in the text file, and then use a hotkey to execute a macro of mine that would add the selected string as a negative filter level in the Advanced Filter (and also immediately apply this newly extended advanced filter), thus removing all lines containing that string in the currently displayed file contents (that is, in addition to any previously filtered out lines, which should also remain removed). I would then continue to manually inspect the resulting contents, after which I would want to be able to repeat the same procedure again and again until all “uninteresting” log entry types have been removed, leaving me only with the few interesting “needle in the haystack” lines of interest.

    Or to put it even more simply, I need to be able to:

    • Add a new advanced filter level.
    • Manually inspect the resulting filtered contents.
    • Add a new advanced filter level on top of the existing ones (by calling my macro).
    • Manually inspect the resulting filtered contents.
    • Add a new advanced filter level on top of the existing ones (by calling my macro).
    • Manually inspect the resulting filtered contents.
    • Add a new advanced filter level on top of the existing ones (by calling my macro).
    • … etc

    But since there is seemingly currently no way to instruct the macro to keep any pre-existing macro levels when I call the “Filter()” function the first time in a macro, this is currently impossible. With the “eeKeepPreviousFilterLevels” flag it would be possible to do exactly that though!

    In summary, a solution that would both close this functional void in the macro API while at the same time prevent any performance problems is to:

    • Add a “eeKeepPreviousFilterLevels” flag.
    • Keep the “eeFindContinue” flag (possibly even rename it to “eePostponeFiltering”, in order to make it more clear that it only controls that aspect and not the aspect of keeping pre-existing filter levels in any subsequent call), and also make it possible to use it in the same “Filter()” call as the “eeKeepPreviousFilterLevels” flag, as described in more detail above in this post.

    And again, the core problem with the current design is that both of these separate aspects (that is “keep pre-existing filter levels” and “perform filtering immediately after the Filter() call”) are forced into one single flag, which leaves some combinations of these two aspects impossible to implement, while still being possibly desirable (as in my exact situation for example).

    #19727
    Yutaka Emura
    Keymaster

    Hello LifeTimer,

    I understand. I will consider the new option.

    Thanks!

    #19733
    Yutaka Emura
    Keymaster

    Hello LifeTimer,

    I released a test version of the next version. Please try it and see if macros work as expected.

    https://www.emeditor.com/forums/topic/emeditor-v14-7-1-beta-1/

    Thank you!

    #19734
    LifeTimer
    Participant

    After a quick test I can confirm that the following one-line macro now indeed seems to accomplish exactly what I was after:

    document.Filter(document.selection.Text, -1, eeFindKeepPrevious | eeFindNegative);

    Thanks a lot!!!

    #19744
    Yutaka Emura
    Keymaster

    Hello LifeTimer,

    v14.7.1 beta 2 can now record the filter operations with macros.

    There is a breaking change in beta 2, where the second paramter for the Filter method now specifies one-based index of the specified column.

    https://www.emeditor.com/forums/topic/emeditor-v14-7-1-beta-1/#post-19743

    In case of the example above, you will have to write as this:

    document.Filter(document.selection.Text, 0, eeFindKeepPrevious | eeFindNegative);

    Thanks!

    #19749
    LifeTimer
    Participant

    Excellent, and thanks for the heads up about the breaking change too!

Viewing 20 posts - 1 through 20 (of 20 total)
  • You must be logged in to reply to this topic.