Rory Becker - DevExpress CodeRush Blog

July 2012 - Posts

  • New CodeRush Plugin: CR_RefreshTemplate

    Background

    A customer came to me asking about Templates and what could be done with them.

    The desired use case seemed simple enough:

    • The user types a few characters, hits space and the template expands as usual.
    • The user fills out one piece of information, and that information is replicated to several other locations around the expanded text.
    • The user fills out a 2nd value and that is also replicated to several location.

    Normally I would assume the job would be done at this stage. However our customer was after something a little beyond the usual.

    They required that Fields used within the template should not be removed once the data had been entered. 

    I asked what the motivation for this was and was told : “I’d like them to remain, in case a user wanted to come back and alter them at some point in the future.”

    Whilst a little unconventional, this didn’t seem unreasonable. However Fields have some limitations…

    Field Limitations

    As it turns out, Fields are not very (read ‘at all’) persistent.

    They are removed when:

    • They are used (values set and enter pressed).
    • Another template is expanded.
    • The project\solution is closed\reopened.

    As you can see, this leaves a very narrow window in which to make modifications. As such Fields are not suited to the customer’s needs.

    Alternatives

    Note: This section details some alternative approaches to solving this problem that were considered. If you’re not interested in this, feel free to skip to “The Solution: Refresh Template” (below)

    So I sat down to consider what alternatives might be available.

    The brief: To allow someone to expand a template which would normally use fields and links, in such a way as they can come back (potentially much later) and edit the fields and, by proxy, the linked text.

    Ideas:

    • Rename: Suggest user could use our rename refactoring when they come back to change the linked value to something else.
    • Reconfigure Field Interaction: Alter CodeRush’s behaviour regarding fields through configuration.
    • Persistable Fields: Create new type of persistent field.
    • Recreate Fields on Demand: Recreate the fields when user returned to this area.
    • Refresh Template: Wipe and replay the template.

    Strategy: Rename

    If the fields and links created by a template are equivalent to the links generated by the act of triggering a Rename refactoring on some token generated by the template, then this prevents the need to leave fields intact after template expansion.

    However this is rarely the case. Fields and links within templates are often used to create related identifiers with the same prefix or suffix. They may also be used to create documentation (standard and non standard). Sometimes these links and fields may affect the types emitted by the template.

    In all these cases, the Rename refactoring is incapable of recreating the fields and links from the final static output of the template.

    Strategy: Reconfigure Field Interaction

    Imagine we take a configuration approach.

    We could create a new context (IsInPersistableField) which would determine if we were within a Field which should be considered persistable.

    Note: Without further plugin work the template would need to emit something which might mark all fields within it as Persistable.

    We would alter the shortcut for FieldAccept (Enter) and enable it only if the condition were not met.
    We would create a new shortcut for FieldNext (Enter) and enable it only if the condition were met.

    This allows us to redirect the use of Enter to navigate between Fields without killing them assuming that we were in the result of a particular type of template

    However this is just the tip of the iceberg. It does not make the field truly persistent. It merely prevents the premature removal of the field due to it receiving confirmed data. Additionally over time this would lead to a growing number of fields to manage.

    Strategy: Create Persistable Field

    Potentially we could create a plugin which introduces an additional type of Field. One which is persisted between sessions. This new field would need to reproduce all functionality of the existing field except the elimination of itself when enter was pressed. This would also need to be repeated with a persistable version of the Link TextCommand

    This is possible, but complex. Additionally it would create an even greater number of fields to manage over time, since none would appear to ever be removed.

    Strategy: Recreate Fields on Demand

    If there were some way we could infer the prior existence of a field and set of links, from the text its template had previously produced, we could recreate them on demand.

    Yeah this struck me as a bit far fetched as well :) It’s a bit like reassembling a egg and some wheat when given a cake.

    The Solution: Refresh Template

    Refresh (or replay) Template is the idea that you re-execute a template over the top of itself so that you can re-specify the values for any fields within.

    If we modify a template so that it emits its own name into the final text, we could then build a plugin that knows how to use that meta data as a way of clearing and re-executing that template at some later point.

    Consider the following template called DateNow which outputs the current Date and Time:

    DateNowBasic

    In order to allow this template to refresh, we need to augment it with a header and footer.

    DateNow

    Now we have all the information we need. If only we had a plugin that could make use of this information…

    Enter CR_RefreshTemplate:

    CR_RefreshTemplate provides a new CodeProvider Refresh Template, which is available when the caret is between an appropriate header and footer.

    CodeProviderRefreshTemplate

    Once triggered it will…

    • Read the name of the template from the header and footer.
    • Clear the Text between the header and footer inclusive.
    • Re-execute the original template by name.

    At this point you, the user, will need to re-enter data for any fields that were re-created by the template.

    Thus each time you invoke ‘Refresh Template’ on our example DateNow template(above), the output of the previous template expansion will be wiped and replaced with the latest date and time.

    ie The date\time is updated each time you refresh the template.

    So how long do you have to wait to get your hands on this little gem?

    I guess that depends how quickly you can click a link. CR_RefreshTemplate is fully functional and available now :)

    Limitations

    This approach is limited in that it proceeds from the assumption that your template expands into a single block of text. This means that text generated elsewhere in your project (or even file) will not be removed, and may therefore collide with later generated code.

    For example you would not be able to engineer this to work with the version of property templates which generates backing store variables elsewhere in the file.

    Added Bonuses

    It turns out that there are 1 or 2 interesting bonus features to this plugin.

    Bonus1: Code Upgrades

    Refresh Template can only execute the latest version of the specified template. Therefore if you have upgraded the template to be faster, more efficient, or just generally more awesome, the act of refreshing it will update the existing code to use the better version rather than the older less awesome version.

    You will still have to re-enter any old field values (assuming you don’t want to change them from their defaults), but this is a pretty small trade of for the optimization you could be receiving.

    One can even envisage a point in the future where you might issue an instruction to regenerate \ upgrade all Refreshable templates to their latest version throughout a file, project or solution.

    Bonus2: Sequenced Templates

    It turns out that the header and template don’t need to specify the template that generated the existing output.

    Say what?

    Yes that’s right. Instead you could indicate any other template which could be expanded given the same context.

    Why would I want to do that?

    Let’s imagine you’re in a presentation where you’re demonstrating a series of incremental changes to some code.

    Your existing options for this scenario are:

    • Rewrite\ adjust the code at each stage including the new incremental changes.
    • Load different projects, each one with a slightly improved version
    • Load different files, again with slightly differing versions of the code.
    • Skip about in source control history and have studio reload everything (hopefully) each time you do.

    With CR_RefreshTemplate, you can pre-create a chain of templates, each with a RefreshTemplate link to the next template in sequence.

    You could give a mini presentation, jumping from one code sample to another by repeatedly issuing the ‘Refresh Template’ command.

    Consider Step1<space>

    Step1

    …which could be refreshed to Step2

    Step2

    …which could be refreshed to Step3

    Step3

    …which, if you want, could be refreshed back to Step1 again.

    Summary

    So we’ve got a simple little plugin CR_RefreshTemplate which can:

    • Refresh code previously generated by an appropriate template.
    • Upgrade your code to the latest version of a template.
    • Proceed through a sequence of template driven steps in order to demonstrate the evolution of some code during a presentation.

    So what are you waiting for?
    Download now and let’s see what develops.

  • CodeRush: ‘Friction Free’ mode and Setting Schemes

    So in 12.1 we shipped a new feature. Well we shipped quite a few really, but I want to talk to you about one of the more subtle features, which might well change the way you use CodeRush.

    Setting schemes are conceptually quite simple, but have far reaching implications.

    Background

    Everyone has their own opinion on how any given feature should work. It can be very hard, some would say impossible, to keep everyone happy. So we try to make our product as configurable as possible. The idea being, that if our default configuration isn’t quite to your liking, you should be able to tweak it so that it is.

    The up side of this, is that there are lots of options you can tweak to make sure our product works exactly how you want it to. Of course the down side of this, is that there are lots of options you might have to tweak to get our product working just the way you want it to.

    Obviously we try to come up with sensible defaults so that as few people as possible will need to tweak the settings, and can use the product straight ‘out of the box’ so to speak :)

    However one man’s default can be another man’s disaster.

    Enter Setting Schemes

    A setting scheme is a named set of settings which has been customized for a specific purpose.

    CodeRush ships with 2 such schemes which you may switch between using the new drop down on the DXCore Visualize toolbar:

    The ‘Default’ scheme

    DXCoreVisualiseToolbar3

    The first scheme (‘Default’) is derived from the classic CodeRush settings as they have been up until 12.1. This set will also include any customizations you have made using previous versions of CodeRush. If such settings exist when CodeRush 12.1 installs, then it is these which will be selected by default.

    The ‘Friction Free’ scheme

    DXCoreVisualiseToolbar4

    The second scheme (‘Friction Free’) is a new set which is designed to remove as much friction as possible for a New User of CodeRush as they seek to go about their daily tasks. It does this by disabling or altering any CodeRush features which might otherwise clash with base Visual studio functionality.

    Alterations include:

  • Auto Complete for Brackets and Parenthesis is disabled.
  • Smart Enter is disabled.
  • Intelli Assist is disabled.
  • The Default Template Expansion shortcut is changed from Space to Tab.
  • Several Code Issues are disabled.
  • Most visual glyphs are turned off (Including SpellcheckMember IconsFlow break indicators and the Metrics icon)
  • Structural Highlighting, Region Painting and Current Line Highlighting are also disabled.

    If the CodeRush installer detects no previous settings, then it is this scheme which will be selected by default.

    Create your own schemes

    In addition to the inclusion of the ‘Default’ and new ‘Friction Free’ schemes, you are also able to create new schemes of your own. These schemes will be stored in parallel with the 2 that ship ‘out of the box’ and can be switched between at any time.

    To create or alter the high level components of a scheme, open the options screen and locate the ‘Settings schemes’ page: 

    SettingsLandingPage

    Once on this page you may create a new scheme, by copying it from an existing scheme.

    SettingsCreateScheme

    Select the preferred source scheme from the drop down, and then click ‘Add New Scheme’. 

    SettingNewScheme

    Choose a suitable name for your proposed scheme and click ok.

    Your scheme is created and added to the dropdown list. You can switch to it and immediately start customizing it to your liking.

    Tweaking

    You can also perform high level customization of your scheme from this page. Simply check or uncheck features as you see fit and save then with the Ok \ Apply buttons as usual.

    If you need to tweak the detail of a section, you can click it’s ellipsis button and you will be taken to an appropriate options page.

    SettingSchemeHighLevel

    Your newly created scheme will exist as an alternate named set, alongside the ‘Default’ and ‘Friction Free’ schemes. Customize this scheme as you see fit and then switch between any of them at will.

    Other Potential Schemes

    Schemes are a powerful feature which you might choose.

    You might create schemes for different purposes, moods or even people. :)

    So what other schemes could you create? Here are some ideas.

  • ‘Teach me’  - I need every prompt I can get. I’m a beginner and I’m happy to admit it.
  • ’Refactor Pro’ – Hide all but the refactoring functionality.
  • ‘The Generator’ - Templates and Code Gen Refactorings only please.
  • ‘The Minimalist’ - Hide all shortcut prompts and graphics. I know exactly what I’m doing already
  • ‘Clean Up Duty’ - Full on CodeIssues and Refactorings, but nothing else.
  • ‘Compiler Plus’ – Hide CodeIssues which pertain to style or readability and just show me things about my code which might be broken.
  • ‘Style Ninja’ – Inverse of ‘Compiler Plus’. Show me only style or readability Code Issues. I’ll fix stuff later.

    ProTip: Name one or more setting schemes after yourself, and copy them to your co-worker’s machines for when you have to pair with them.

    Feel free to suggest more. Tell us how you think this feature should evolve?

    The Future

    So what would you like to see us do in this space for the future?

    • Should we add some more schemes out of the box? Which ones?
    • Should we alter the ‘Friction Free’ scheme further?
    • Should we prevent any alteration of our ‘out of the box’ schemes and force you to copy them first. This would allow you a really quick method of restoring to any of our defaults.
    • Should we provide a “Copy page from Scheme…” button for slicing and dicing schemes?

    So take ‘Setting Schemes’ (including ‘Friction Free’) for a spin, tell us what you think and then let’s see what develops.

LIVE CHAT

Chat is one of the many ways you can contact members of the DevExpress Team.
We are available Monday-Friday between 7:30am and 4:30pm Pacific Time.

If you need additional product information, write to us at info@devexpress.com or call us at +1 (818) 844-3383

FOLLOW US

DevExpress engineers feature-complete Presentation Controls, IDE Productivity Tools, Business Application Frameworks, and Reporting Systems for Visual Studio, along with high-performance HTML JS Mobile Frameworks for developers targeting iOS, Android and Windows Phone. Whether using WPF, ASP.NET, WinForms, HTML5 or Windows 10, DevExpress tools help you build and deliver your best in the shortest time possible.

Copyright © 1998-2017 Developer Express Inc.
All trademarks or registered trademarks are property of their respective owners