Rich text copy-paste from Visual Studio line spacing issue - c#

In Visual Studio (2019, 2022 etc.) I have enabled this option in order to copy-paste code that is syntax highlighted:
Tools\Options\Text Editor\Advanced\Copy rich text on copy/cut
This is a feature I've used for a very long time (so long in fact that I hope this isn't just my feeble mind giving out). The way that I recall this working is that a paste operation into Word or WordPad or a RichTextBox would look identical to the source with no added spacing after NewLine or Paragraph. For example:
Good
static class Extensions
{
public static void RunWithWrapper(this Action action, [CallerMemberName] string caller = null)
{
Debug.WriteLine($"The {caller} method has been invoked.");
action();
}
}
Lately, however, this is producing bad behavior. My question is whether there's a new switch for this somewhere because "every so often" Visual Studio will add some new option and enable it by default (essentially making a breaking change to how one is accustomed to the IDE behaving).
I'm looking for any way to avoid having the pasted code look like this:
Bad
static class Extensions
{
public static void RunWithWrapper(this Action action, [CallerMemberName] string caller = null)
{
Debug.WriteLine($"The {caller} method has been invoked.");
action();
}
}
And yes, it's important (at least to me) I use this constantly.

Related

In Visual Studio, is there a way to sort private methods by usage?

In Visual Studio, with or without an extension, is there a way to automatically sort private methods inside a class based on the order of their usage (their location in the call stack)?
For example consider the following class:
public class MyClass
{
public void MyMethod()
{
TestC();
}
private void TestA()
{
TestB();
}
private void TestB()
{
Console.WriteLine("Hello");
}
private void TestC()
{
TestA();
}
}
The public method in this class is MyMethod, it calls TestC which calls TestA which calls TestB. I would like to (automatically) order these methods by this order so that the class looks like this:
public class MyClass
{
public void MyMethod()
{
TestC();
}
private void TestC()
{
TestA();
}
private void TestA()
{
TestB();
}
private void TestB()
{
Console.WriteLine("Hello");
}
}
I need to be able to select a class, request such method sorting, and have the methods sorted automatically. I.e., I don't want to manually sort these methods.
I understand that there are some nuances. For example, there could be a private method that is called from two methods which are at two different levels in the call stack. I guess in this case it makes sense to consider the smallest (call stack) distance from the public method.
UPDATE:
This idea of sorting the methods in this way comes from the Clean Code book by Robert C. Martin. In chapter 3, the Stepdown rule is defined which talks about having the higher level functions appear before the low level functions.
Doing a quick search for stepdown rule on google, I found a netbeans plugin at: http://plugins.netbeans.org/plugin/58863/stepdownruleplugin
I would guess that it does something similar to what I need, but for netbeans.
The ReSharper Plugin "Greenkeeper" does the job:
https://bitbucket.org/denniskniep/greenkeeper
The plugin can sort the methods in "newspapermode": Important code first and details at the bottom. The newspapermode has the same behaviour as the "Stepdown rule".
https://bitbucket.org/denniskniep/greenkeeper/wiki/SortingDeclarations
I don't know whether it's possible to do this natively within Visual Studio. However, I think that the best method would be to use ReSharper (a Visual Studio extension) to do this.
It provides at least two options that comes to mind:
1) Using the File and Type Layout preferences with patterns,
2) Using the File Structure window (this might be the quickest way if the class you want to reorder doesn't have too many methods). You can check it out here.
Hope that helps.
Here are the other products that no one has referenced that could add the functionality with a friendly request:
NArrange
CodeSorter
CodeMaid
Its not that hard to write this yourself. The new Visual Studio VSIX Project templates are available in the VS2015 setup, if you cant find them under (File > New > Project.. Visual C# > Extensibility) just Modify the Install (cmd > appwiz.cpl > VS2015 Change/Modify).
The great news is that the CodeMaid project is open source and contains most of the code & logic you will need to reorder chunks of code.
The other thing you will need is the Call Stack and one of our helpful fellow Stackoverflow'rs has provided the code for that here: How to get stack trace of a running process from within a Visual Studio add-in?
Given this is a bounty you were probably expecting a full solution, sorry I dont have time to code it up for you right now but am happy to give you a hand if you run into any issues. Let me know in the comments.
To get up and running quickly I'd personally just copy the code in this Visual Studio extension and replace the guts with Re-Ordering by Call Stack: Debug Single Thread.
if you want to trigger that logic manually and you use vs 2015, you can create a visual studio CodeFix that will use Roslyn.
see: Build CodeFix ex
The steps that you should do are:
Create CodeFix project
The logic of the CodeFix, using Roslyn, will analyze all the methods in the document and create a dependency graph between the methods. Than it will change the order and rewrite the code to the document
Install the CodeFix, as an analyzer, and use it for every visual studio document you want
Short answer is NO
See the reason is simply because majority of developers try to write code that is easily readable. If I need to make an update to TestB and looking at the code I would expect TestB to be defined after TestA and before TestC. Then you also take into account defined fields for the class and the use of get/set methods for setting and getting the value of a defined field.
The code below shows 2 classes. The first class is in the layout that I personally use for readability should another developer need to update the code they aren't wasting time hunting down through the code. The second class follows the way you are wanting them to be re-arranged.
public class MyClass
{
private string _HelloWorld;
public string HelloWorld
{
get {return _HelloWorld;}
set {_HelloWorld = value;}
}
public void MyMethod
{
TestC();
}
public void TestA()
{
TestB();
}
public void TestB()
{
Console.WriteLine(HelloWorld);
}
public void TestC()
{
TestA();
}
}
public class MyClass2
{
private string _HelloWorld;
public void MyMethod
{
TestC();
}
public void TestC()
{
TestA();
}
public void TestA()
{
TestB();
}
public void TestB()
{
Console.WriteLine(HelloWorld);
}
public string HelloWorld
{
get {return _HelloWorld;}
set {_HelloWorld = value;}
}
}

Is there a publicly accessible event to mark a ModalDialog close?

I recently made a custom ribbon in Sitecore. The two buttons in it fire off a command which activate a Xaml application using SheerResponse.ShowModalDialog. These applications effect the state of a database being read by another component on the ribbon.
I either need to be able to fire a custom event or function from the Xaml application to make the other ribbon component, or I need to be able to make the component on the ribbon aware that it needs to re-render when the ModalDialogs close. I don't see any obvious events which would do this, and I've gone about as far as I can when looking through the raw code with DotPeek and I haven't seen anything which even looks promising.
Apparently, the answer was there the whole time and I had missed it.
SheerResponse has a five parameter version of ShowModalDialog which accepts a boolean as a final parameter. This means I can couple it with ClientPage.Start:
Context.ClientPage.Start(this, "Run", kv);
}
private void Run(ClientPipelineArgs args)
{
var id = args.Parameters["id"];
if(!args.IsPostBack)
{
string controlUrl = string.Format("{0}&id={1}", UIUtil.GetUri("control:AltDelete"), id);
SheerResponse.ShowModalDialog(controlUrl,"","","",true);
args.WaitForPostBack();
}
else
{
Logger.LogDebug("post back");
}
Logger.LogDebug("out of if");
}

Visual Studio creates a property instead of a method event handler. Why?

I just had VS generate an event handler for me, and it created a property instead of a method. I don't understand that. I just tried a separate test in VS 2012, and it worked as expected.
First, this is my test that worked as I thought it would:
private static void EventTest()
{
Geek skeet = new Geek();
skeet.SomeEvent += skeet_SomeEvent;
}
When I had VS generate the handler for me, it created this.
static void skeet_SomeEvent(object sender, EventArgs e)
{
throw new NotImplementedException();
}
That makes sense. That method will be called when the event is invoked.
Now, the problem... I'm working on an existing project, in VS 2010, and when I do the same thing (have VS generate the handler):
private void SubscribeToPlcDataChangeEvents()
{
_plc.PlcLoggerEventHandler += _plcLoggerEventHandler;
}
It creates a property:
public EventHandler<PlcLoggerEventArgs> _plcLoggerEventHandler { get; set; }
Why? I don't get that. I want to handle the event in a method.
EDIT - This is how the event handler is declared:
public event EventHandler<PlcLoggerEventArgs> PlcLoggerEventHandler;
If you hit Tab twice you will notice that it is generated "properly" in cases of event handlers.
In the case where you use the "Options to help bind the item" shortcut Alt+Shift+F10 in Visual Studio 2010, your two possible actions in this case are:
Generate property stub for 'PlcLoggerEventHandler' in ...
Generate field stub for 'PlcLoggerEventHandler' in ...
So, the fact that a property is then created when you use this seems to be By Design, even though in the case of an event handler it makes no sense.

How to use ApprovalTests on Teamcity?

I am using Approval Tests. On my dev machine I am happy with DiffReporter that starts TortoiseDiff when my test results differ from approved:
[UseReporter(typeof (DiffReporter))]
public class MyApprovalTests
{ ... }
However when the same tests are running on Teamcity and results are different tests fail with the following error:
System.Exception : Unable to launch: tortoisemerge.exe with arguments ...
Error Message: The system cannot find the file specified
---- System.ComponentModel.Win32Exception : The system cannot find the file
specified
Obviously it cannot find tortoisemerge.exe and that is fine because it is not installed on build agent. But what if it gets installed? Then for each fail another instance of tortoisemerge.exe will start and nobody will close it. Eventually tons of tortoisemerge.exe instances will kill our servers :)
So the question is -- how tests should be decorated to run Tortoise Diff on local machine
and just report errors on build server? I am aware of #IF DEBUG [UseReporter(typeof (DiffReporter))] but would prefer another solution if possible.
There are a couple of solutions to the question of Reporters and CI. I will list them all, then point to a better solution, which is not quite enabled yet.
Use the AppConfigReporter. This allows you to set the reporter in your AppConfig, and you can use the QuietReporter for CI.
There is a video here, along with many other reporters. The AppConfigReporter appears at 6:00.
This has the advantage of separate configs, and you can decorate at the assembly level, but has the disadvantage of if you override at the class/method level, you still have the issue.
Create your own (2) reporters. It is worth noting that if you use a reporter, it will get called, regardless as to if it is working in the environment. IEnvironmentAwareReporter allows for composite reporters, but will not prevent a direct call to the reporter.
Most likely you will need 2 reporters, one which does nothing (like a quiet reporter) but only works on your CI server, or when called by TeamCity. Will call it the TeamCity Reporter. And One, which is a multiReporter which Calls teamCity if it is working, otherwise defers to .
Use a FrontLoadedReporter (not quite ready). This is how ApprovalTests currently uses NCrunch. It does the above method in front of whatever is loaded in your UseReporter attribute. I have been meaning to add an assembly level attribute for configuring this, but haven't yet (sorry) I will try to add this very soon.
Hope this helps.
Llewellyn
I recently came into this problem myself.
Borrowing from xunit and how they deal with TeamCity logging I came up with a TeamCity Reporter based on the NCrunch Reporter.
public class TeamCityReporter : IEnvironmentAwareReporter, IApprovalFailureReporter
{
public static readonly TeamCityReporter INSTANCE = new TeamCityReporter();
public void Report(string approved, string received) { }
public bool IsWorkingInThisEnvironment(string forFile)
{
return Environment.GetEnvironmentVariable("TEAMCITY_PROJECT_NAME") != null;
}
}
And so I could combine it with the NCrunch reporter:
public class TeamCityOrNCrunchReporter : FirstWorkingReporter
{
public static readonly TeamCityOrNCrunchReporter INSTANCE =
new TeamCityOrNCrunchReporter();
public TeamCityOrNCrunchReporter()
: base(NCrunchReporter.INSTANCE,
TeamCityReporter.INSTANCE) { }
}
[assembly: FrontLoadedReporter(typeof(TeamCityOrNCrunchReporter))]
I just came up with one small idea.
You can implement your own reporter, let's call it DebugReporter
public class DebugReporter<T> : IEnvironmentAwareReporter where T : IApprovalFailureReporter, new()
{
private readonly T _reporter;
public static readonly DebugReporter<T> INSTANCE = new DebugReporter<T>();
public DebugReporter()
{
_reporter = new T();
}
public void Report(string approved, string received)
{
if (IsWorkingInThisEnvironment())
{
_reporter.Report(approved, received);
}
}
public bool IsWorkingInThisEnvironment()
{
#if DEBUG
return true;
#else
return false;
#endif
}
}
Example of usage,
[UseReporter(typeof(DebugReporter<FileLauncherReporter>))]
public class SomeTests
{
[Test]
public void test()
{
Approvals.Verify("Hello");
}
}
If test is faling, it still would be red - but reporter would not came up.
The IEnvironmentAwareReporter is specially defined for that, but unfortunatelly whatever I return there, it still calls Report() method. So, I put the IsWorkingInThisEnvironment() call inside, which is a little hackish, but works :)
Hope that Llywelyn can explain why it acts like that. (bug?)
I'm using CC.NET and I do have TortoiseSVN installed on the server.
I reconfigured my build server to allow the CC.NET service to interact with the desktop. When I did that, TortiseMerge launched. So I think what's happening is that Approvals tries to launch the tool, but it cant because CC.NET is running as a service and the operating system prevents that behavior by default. If TeamCity runs as a service, you should be fine, but you might want to test.

Constructor of attribute decorating the main method does not get called in release builds

Does anyone know why the constructor of an attribute decorating the main method is called in debug builds, but not in release builds?
How can I ensure that the constructor is called in release builds as well? Without calling it manually of course.
Any insight on this subject would be very much appreciated.
I can reproduce this (in both debug and release), when executed via the IDE with the "Debug" => "Enable the Visual Studio hosting process" option enabled, via the below. At the command-line it will print "hello", where-as via the IDE it will print "world". It looks like the IDE is doing some different reflection on the attributes.
This is not expected behaviour, and you should not rely on this behaviour. If you want some particular code to execute: invoke the desired code explicitly. To get predictable behaviour, disable the Debug" => "Enable the Visual Studio hosting process" option.
using System;
public class MyTestAttribute : Attribute {
public MyTestAttribute() {
Program.text = "world";
}
}
class Program {
public static string text = "hello";
[MyTest]
static void Main() {
Console.WriteLine(text);
Console.ReadKey();
}
}

Categories