diff --git a/CHANGES b/CHANGES index 95c22f41..70c9be1b 100644 --- a/CHANGES +++ b/CHANGES @@ -631,7 +631,7 @@ Version history - bugzilla 12353: option "Show Type In Tooltip" not saved and restored across restart * miscellanea - - update SDK conversion for VS2013 and Windws SDK 8.1 + - update SDK conversion for VS2013 and Windows SDK 8.1 - bugzilla 11786: change some default colors when using dark theme in VS 2012+ (restart required) - bugzilla 12187: disguise functionality of pipedmd.exe and filemonitor.dll to let it pass most anti-virus checks @@ -640,3 +640,17 @@ Version history * build mago with static C runtime to avoid dependencies on msvcrt120.dll +2014-07-20 Version 0.3.39 + + * added editor margin to display coverage counters and percentage + * support tab/indentation settings set by .editorconfig plugin + * optlink now always called with /DELEXE to avoid keeping broken binary + * added workaround for bad import library being passed by C/C++ projects + * tweaked "Compile & Run" to distinguish between compile and execution errors + * added "Compile & Debug" command + * new mago version 1.0 + - now supports debugging x64 executables + - displays static members of classes and structs + - fixed not closing executable file causing linker to fail when rebuilding + - fixed breakpoints not set in all instances of a template + * new dparser version: 78a007c9aaee915e2824f30c5c7293e8853343c4 diff --git a/Makefile b/Makefile index c769551c..8cf50f58 100644 --- a/Makefile +++ b/Makefile @@ -145,8 +145,12 @@ vdserver: dparser: cd vdc\abothe && $(MSBUILD) vdserver.sln /p:Configuration=Release /t:Rebuild +vdextension: + cd vdextensions && $(MSBUILD) vdextensions.csproj /p:Configuration=Release;Platform=x86 /t:Rebuild + mago: cd ..\..\mago && devenv /Build "Release|Win32" /Project "MagoNatDE" magodbg_2010.sln + cd ..\..\mago && devenv /Build "Release|x64" /Project "MagoRemote" magodbg_2010.sln cv2pdb: cd ..\..\cv2pdb\trunk && devenv /Project "cv2pdb" /Build "Release|Win32" src\cv2pdb_vs12.sln @@ -160,7 +164,7 @@ install: all cpp2d_exe idl2d_exe "$(ZIP)" -j ..\downloads\visuald_pdb.zip bin\release\visuald.pdb bin\release\vdserver.pdb #prerequisites -install_vs: visuald_vs vdserver cv2pdb dparser mago install_only +install_vs: visuald_vs vdserver cv2pdb dparser vdextension mago install_only install_only: cd nsis && "$(NSIS)\makensis" /V1 visuald.nsi diff --git a/TODO b/TODO index c9abdf1b..03e530ac 100644 --- a/TODO +++ b/TODO @@ -145,8 +145,20 @@ Unsorted - goto definition fallback to JSON - highlight compiler-magic identifiers -- compile from selection/buffer (through rdmd) -- save file before "Compile & run" -- coverage line highlight after "Compile & run" doesn't update -- better keeping track of line changes - ++ compile from selection/buffer (through rdmd) ++ save file before "Compile & run" ++ coverage line highlight after "Compile & run" doesn't update ++ better keeping track of line changes + ++ compile & debug ++ margin for profiler + ++ formatting does not work with .editorConfig ++ do not report build failure when run returns non-zero result +- custom file props: switch and apply changes next file + +- compile and run : set VCInstallDir for -m64 ++ mago keeps image locked when terminating debugger +- -gc/-g depending on debug engine +- dub upport +- dustmite support diff --git a/VERSION b/VERSION index 41bfbc33..58d3ac7d 100644 --- a/VERSION +++ b/VERSION @@ -1,5 +1,5 @@ #define VERSION_MAJOR 0 #define VERSION_MINOR 3 -#define VERSION_REVISION 38 -#define VERSION_BETA - +#define VERSION_REVISION 39 +#define VERSION_BETA -beta #define VERSION_BUILD 1 diff --git a/build/sdk.bat b/build/sdk.bat index e67f799a..7057924b 100644 --- a/build/sdk.bat +++ b/build/sdk.bat @@ -28,7 +28,7 @@ if "%VSISDKINC%" == "" if not "%VSSDK90Install%" == "" set VSISDKINC=%VSSDK90Ins if "%VSISDKINC%" == "" if not "%VSSDK80Install%" == "" set VSISDKINC=%VSSDK80Install% if "%VSISDKINC%" == "" (echo could not detect the Visual Studio SDK && exit /B 1) -if not exist "%VSISDKINC%\VisualStudioIntegration\Common\Inc\textmgr.h" (echo unexpected Visual Studio SDK installation at %VSISDKINC% && exit /B 1) +if not exist "%VSISDKINC%\VisualStudioIntegration\Common\Inc\textmgr.h" (echo unexpected Visual Studio SDK installation at "%VSISDKINC%" && exit /B 1) echo Translating Windows SDK and Visual Studio SDK to D, this can take several minutes. Please be patient. echo %VSI2D% --vsi="%VSISDKINC:\=/%" --win="%WINSDKINC:\=/%" --dte="%DTE_IDL_PATH%" --sdk=..\sdk diff --git a/doc/KnownIssues.dd b/doc/KnownIssues.dd index fd275b1f..0a9639ad 100644 --- a/doc/KnownIssues.dd +++ b/doc/KnownIssues.dd @@ -57,5 +57,17 @@ $(P As a result, Windows Defender can harm performance of Visual D. To avoid thi add the Visual Studio process devenv.exe to the list of Excluded Processes in the settings of Windows Defender.) +$(H2 Import libraries from C/C++ projects ) + +$(P A Visual C/C++ DLL project reports two outputs to dependent projects: the DLL and the import library.) + +$(P Unfortunately, the import library reported still contains unexpanded macros and the current working directory prepended +instead of the project directory. The actual replacements are not accessible to Visual D, so it assumes the +the import library to be placed along-side the DLL.) + +$(P If the C++ DLL project is converted to a static library project, the import library setting is kept, though +unaccessible from the configuration page. The import library is falsely reported as an output. To mitigate +this problem, Visual D ignores the import library if the main output is also a library.) + Macros: TITLE=Known Issues diff --git a/nsis/Extensions/extension.vsixmanifest b/nsis/Extensions/extension.vsixmanifest index 13b3982f..c6d56fc0 100644 --- a/nsis/Extensions/extension.vsixmanifest +++ b/nsis/Extensions/extension.vsixmanifest @@ -9,8 +9,8 @@ 0.3 Extension to provide support for the D programming language. 1033 - http://www.dsource.org/projects/visuald - http://www.dsource.org/projects/visuald + http://rainers.github.io/visuald/visuald/StartPage.html + http://rainers.github.io/visuald/visuald/StartPage.html true vdlogo.ico vdlogo.ico @@ -37,5 +37,6 @@ visuald.pkgdef + VDINSTALLPATH\vdextensions.dll diff --git a/nsis/visuald.nsi b/nsis/visuald.nsi index cfdc26a0..2ed4600e 100644 --- a/nsis/visuald.nsi +++ b/nsis/visuald.nsi @@ -12,6 +12,9 @@ ; define DPARSER to include DParser COM server installation (expected at ../bin/Release/DParserCOMServer) !define DPARSER +; define VDEXTENSIONS to include C# extensions (expected at ../bin/Release/vdextensions) +!define VDEXTENSIONS + ;-------------------------------- ;Include Modern UI @@ -87,10 +90,11 @@ !define MAGO_ENGINE_KEY AD7Metrics\Engine\${MAGO_CLSID} !define MAGO_EXCEPTION_KEY AD7Metrics\Exception\${MAGO_CLSID} !define MAGO_ABOUT "A debug engine dedicated to debugging applications written in the D programming language. See the project website at http://www.dsource.org/projects/mago_debugger for more information. Copyright (c) 2010-2013 Aldo J. Nunez" + !define MAGO_SOURCE ..\..\..\mago - !searchparse /file ../../../mago/include/magoversion.h "#define MAGO_VERSION_MAJOR " MAGO_VERSION_MAJOR - !searchparse /file ../../../mago/include/magoversion.h "#define MAGO_VERSION_MINOR " MAGO_VERSION_MINOR - !searchparse /file ../../../mago/include/magoversion.h "#define MAGO_VERSION_BUILD " MAGO_VERSION_BUILD + !searchparse /file ${MAGO_SOURCE}/include/magoversion.h "#define MAGO_VERSION_MAJOR " MAGO_VERSION_MAJOR + !searchparse /file ${MAGO_SOURCE}/include/magoversion.h "#define MAGO_VERSION_MINOR " MAGO_VERSION_MINOR + !searchparse /file ${MAGO_SOURCE}/include/magoversion.h "#define MAGO_VERSION_BUILD " MAGO_VERSION_BUILD !searchreplace MAGO_VERSION_MAJOR ${MAGO_VERSION_MAJOR} " " "" !searchreplace MAGO_VERSION_MINOR ${MAGO_VERSION_MINOR} " " "" @@ -184,7 +188,11 @@ Section "Visual Studio package" SecPackage ${File} ..\ README.md ${File} ..\ LICENSE_1_0.txt ${File} ..\ CHANGES - + + !ifdef VDEXTENSIONS + ${File} ..\bin\${CONFIG}\vdextensions\ vdextensions.dll + !endif + ${SetOutPath} "$INSTDIR\Templates" ${SetOutPath} "$INSTDIR\Templates\Items" ${File} ..\visuald\Templates\Items\ empty.d @@ -284,10 +292,16 @@ ${MementoSection} "Register with VS 2010" SecVS2010 ReadRegStr $1 ${VS_REGISTRY_ROOT} "${VS2010_REGISTRY_KEY}" InstallDir ExecWait 'rundll32 "$INSTDIR\${DLLNAME}" WritePackageDef ${VS2010_REGISTRY_KEY} $1${EXTENSION_DIR}\visuald.pkgdef' + ${SetOutPath} "$1${EXTENSION_DIR}" ${File} ..\nsis\Extensions\ extension.vsixmanifest ${File} ..\nsis\Extensions\ vdlogo.ico + !ifdef VDEXTENSIONS + GetFullPathName /SHORT $0 $INSTDIR + !insertmacro ReplaceInFile "$1${EXTENSION_DIR}\extension.vsixmanifest" "VDINSTALLPATH" "$0" NoBackup + !endif + ${MementoSectionEnd} ;-------------------------------- @@ -299,10 +313,16 @@ ${MementoSection} "Register with VS 2012" SecVS2012 ReadRegStr $1 ${VS_REGISTRY_ROOT} "${VS2012_REGISTRY_KEY}" InstallDir ExecWait 'rundll32 "$INSTDIR\${DLLNAME}" WritePackageDef ${VS2012_REGISTRY_KEY} $1${EXTENSION_DIR}\visuald.pkgdef' + ${SetOutPath} "$1${EXTENSION_DIR}" ${File} ..\nsis\Extensions\ extension.vsixmanifest ${File} ..\nsis\Extensions\ vdlogo.ico + !ifdef VDEXTENSIONS + GetFullPathName /SHORT $0 $INSTDIR + !insertmacro ReplaceInFile "$1${EXTENSION_DIR}\extension.vsixmanifest" "VDINSTALLPATH" "$0" NoBackup + !endif + ${MementoSectionEnd} ;-------------------------------- @@ -314,10 +334,16 @@ ${MementoSection} "Register with VS 2013" SecVS2013 ReadRegStr $1 ${VS_REGISTRY_ROOT} "${VS2013_REGISTRY_KEY}" InstallDir ExecWait 'rundll32 "$INSTDIR\${DLLNAME}" WritePackageDef ${VS2013_REGISTRY_KEY} $1${EXTENSION_DIR}\visuald.pkgdef' + ${SetOutPath} "$1${EXTENSION_DIR}" ${File} ..\nsis\Extensions\ extension.vsixmanifest ${File} ..\nsis\Extensions\ vdlogo.ico - + + !ifdef VDEXTENSIONS + GetFullPathName /SHORT $0 $INSTDIR + !insertmacro ReplaceInFile "$1${EXTENSION_DIR}\extension.vsixmanifest" "VDINSTALLPATH" "$0" NoBackup + !endif + ${MementoSectionEnd} !ifdef EXPRESS @@ -392,12 +418,13 @@ ${MementoSectionEnd} ${MementoSection} "mago" SecMago ${SetOutPath} "$INSTDIR\Mago" - ${File} ..\..\..\mago\Release\ MagoNatDE.dll - ${File} ..\..\..\mago\Release\ MagoNatEE.dll - ${File} ..\..\..\mago\Release\ udis86.dll - ${File} ..\..\..\mago\Release\ CVSTI.dll - ${File} ..\..\..\mago\ LICENSE.TXT - ${File} ..\..\..\mago\ NOTICE.TXT + ${File} ${MAGO_SOURCE}\bin\Win32\Release\ MagoNatDE.dll +;; ${File} ${MAGO_SOURCE}\bin\Win32\Release\ MagoNatEE.dll + ${File} ${MAGO_SOURCE}\bin\Win32\Release\ udis86.dll +;; ${File} ${MAGO_SOURCE}\bin\Win32\Release\ CVSTI.dll + ${File} ${MAGO_SOURCE}\bin\x64\Release\ MagoRemote.exe + ${File} ${MAGO_SOURCE}\ LICENSE.TXT + ${File} ${MAGO_SOURCE}\ NOTICE.TXT ExecWait 'regsvr32 /s "$INSTDIR\Mago\MagoNatDE.dll"' @@ -427,6 +454,8 @@ ${MementoSection} "mago" SecMago Push ${VS2013_REGISTRY_KEY} Call RegisterMago + WriteRegStr HKLM "SOFTWARE\Wow6432Node\MagoDebugger" "Remote_x64" "$INSTDIR\Mago\MagoRemote.exe" + ${MementoSectionEnd} !endif @@ -710,9 +739,12 @@ Function DMDInstallPage IfErrors DMDInstallDirEmpty StrCmp "$DMDInstallDir" "" DMDInstallDirEmpty HasDMDInstallDir DMDInstallDirEmpty: + ReadRegStr $DInstallDir HKLM "SOFTWARE\DMD" "InstallationFolder" + IfErrors 0 HasDInstallationFolder ReadRegStr $DInstallDir HKLM "SOFTWARE\D" "Install_Dir" IfErrors HasDmdInstallDir - StrCpy $DmdInstallDir $DInstallDir\dmd2 + HasDInstallationFolder: + StrCpy $DmdInstallDir $DInstallDir\dmd2 HasDMDInstallDir: WriteINIStr "$PLUGINSDIR\dmdinstall.ini" "Field 1" "State" $DMDInstallDir @@ -809,6 +841,7 @@ enabled: WriteRegDWORD ${VS_REGISTRY_ROOT} "$1\${MAGO_ENGINE_KEY}" "ENC" 0 WriteRegDWORD ${VS_REGISTRY_ROOT} "$1\${MAGO_ENGINE_KEY}" "Disassembly" 1 WriteRegDWORD ${VS_REGISTRY_ROOT} "$1\${MAGO_ENGINE_KEY}" "Exceptions" 1 + WriteRegDWORD ${VS_REGISTRY_ROOT} "$1\${MAGO_ENGINE_KEY}" "AlwaysLoadLocal" 1 ${RegisterException} $1 "D Exceptions" ${RegisterException} $1 "D Exceptions\core.exception.AssertError" diff --git a/stdext/httpget.d b/stdext/httpget.d index 72cc4bc3..43208e0c 100644 --- a/stdext/httpget.d +++ b/stdext/httpget.d @@ -6,7 +6,7 @@ // Distributed under the Boost Software License, Version 1.0. // See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt -module httpget; +module stdext.httpget; import std.string, std.conv, std.stream, std.stdio; import std.socket, std.socketstream; diff --git a/vdc/parser.visualdproj b/vdc/parser.visualdproj index 376ac12a..39fbe1f7 100644 --- a/vdc/parser.visualdproj +++ b/vdc/parser.visualdproj @@ -6,7 +6,7 @@ 1 0 0 - 2 + 0 0 0 0 @@ -89,6 +89,7 @@ $(OutDir)\$(ProjectName).lib 1 + 2 @@ -183,6 +184,7 @@ $(OutDir)\$(ProjectName).lib 1 + 1 @@ -277,6 +279,7 @@ $(OutDir)\$(ProjectName).lib 1 + 1 -gx @@ -371,6 +374,7 @@ $(OutDir)\$(ProjectName).lib 1 + 2 @@ -465,6 +469,7 @@ $(OutDir)\$(ProjectName).lib 1 + 1 @@ -559,6 +564,7 @@ $(OutDir)\$(ProjectName).exe 1 + 1 -debuglib=phobos64_d @@ -653,6 +659,7 @@ $(OutDir)\$(ProjectName).a 1 + 1 @@ -747,6 +754,7 @@ $(OutDir)\$(ProjectName).lib 1 + 1 @@ -841,6 +849,7 @@ $(OutDir)\$(ProjectName).lib 1 + 1 @@ -935,6 +944,7 @@ $(OutDir)\$(ProjectName).lib 1 + 1 @@ -1029,6 +1039,7 @@ $(OutDir)\$(ProjectName).lib 1 + 1 -m32ms @@ -1123,6 +1134,7 @@ $(OutDir)\$(ProjectName).lib 1 + 1 diff --git a/vdextensions/CoverageMargin.cs b/vdextensions/CoverageMargin.cs index 2c84152a..de6570ac 100644 --- a/vdextensions/CoverageMargin.cs +++ b/vdextensions/CoverageMargin.cs @@ -10,10 +10,13 @@ using System.Windows.Controls; using System.Windows; using System.Windows.Media; +using System.ComponentModel; using System.ComponentModel.Composition; using System.Runtime.InteropServices; // DllImport +using Microsoft.VisualStudio.ComponentModelHost; using Microsoft.VisualStudio.Text.Editor; +using Microsoft.VisualStudio.Editor; using Microsoft.VisualStudio.Utilities; using Microsoft.VisualStudio.Text.Classification; using Microsoft.VisualStudio.TextManager.Interop; @@ -22,14 +25,20 @@ namespace vdextensions { - #region covmargin Factory +/* [PackageRegistration(UseManagedResourcesOnly=true)] + class VDExtensionPackage : Package + { + } +*/ + + #region covmargin Factory /// /// Export a , which returns an /// instance of the margin for the editor to use. /// [Export(typeof(IWpfTextViewMarginProvider))] [Name(CoverageMargin.MarginName)] - [Order(After = PredefinedMarginNames.LineNumber)] + [Order(After = "Wpf Line Number Margin")] //PredefinedMarginNames.LineNumber)] [MarginContainer(PredefinedMarginNames.Left)] [ContentType("code")] [TextViewRole(PredefinedTextViewRoles.Document)] @@ -37,9 +46,16 @@ internal sealed class MarginFactory : IWpfTextViewMarginProvider { [Import] internal IEditorFormatMapService FormatMapService = null; - - public IWpfTextViewMargin CreateMargin(IWpfTextViewHost textViewHost, IWpfTextViewMargin containerMargin) + + [Import(typeof(IVsEditorAdaptersFactoryService))] + internal IVsEditorAdaptersFactoryService editorFactory = null; + + public IWpfTextViewMargin CreateMargin(IWpfTextViewHost textViewHost, IWpfTextViewMargin containerMargin) { + if (!VisualDHelper.setFactory(editorFactory)) + return null; + + //MessageBox.Show("CreateMargin"); return new CoverageMargin(textViewHost.TextView, FormatMapService.GetEditorFormatMap(textViewHost.TextView)); } } @@ -50,8 +66,6 @@ public IWpfTextViewMargin CreateMargin(IWpfTextViewHost textViewHost, IWpfTextVi /// class CoverageMargin : Canvas, IWpfTextViewMargin //, IClassifier { - #region Member Variables - public const string MarginName = "CoverageMargin"; public const string CovColorName = "Visual D Text Coverage"; public const string NoCovColorName = "Visual D Text Non-Coverage"; @@ -67,12 +81,23 @@ class CoverageMargin : Canvas, IWpfTextViewMargin //, IClassifier private string _fileName; private Color[] _backgroundColor = new Color[2]; private Color[] _foregroundColor = new Color[2]; - #endregion - [DllImport("visuald.dll")] - public static extern bool GetCoverageData(string fname, int line, int[] data, int cnt); + [DllImport("visuald.dll")] + public static extern bool GetCoverageData(string fname, int line, int[] data, int cnt, out float covPercent); + + static bool GetCoverage(string fname, int line, int[] data, int cnt, out float covPercent) + { + try + { + return GetCoverageData(fname, line, data, cnt, out covPercent); + } + catch + { + covPercent = -1; + return false; + } + } - #region Constructor /// /// Creates a for a given . /// @@ -100,10 +125,7 @@ public CoverageMargin(IWpfTextView textView, IEditorFormatMap formatMap) this.ClipToBounds = true; - _fontFamily = _textView.FormattedLineSource.DefaultTextProperties.Typeface.FontFamily; - _fontEmSize = _textView.FormattedLineSource.DefaultTextProperties.FontRenderingEmSize; - - this.Width = GetMarginWidth(new Typeface(_fontFamily.Source), _fontEmSize) + 2 * _labelOffsetX; + OnFormatMappingChanged(); _textView.ViewportHeightChanged += (sender, args) => DrawLineNumbers(); _textView.LayoutChanged += new EventHandler(OnLayoutChanged); @@ -113,15 +135,11 @@ public CoverageMargin(IWpfTextView textView, IEditorFormatMap formatMap) " Tools -> Options -> Fonts and Colors -> " + CovColorName; } - #endregion - - #region Event Handlers - private void OnLayoutChanged(object sender, TextViewLayoutChangedEventArgs e) { - if (e.VerticalTranslation || e.NewOrReformattedLines.Count > 1) + //if (e.VerticalTranslation || e.NewOrReformattedLines.Count > 1) { - DrawLineNumbers(); + OnFormatMappingChanged(); } } @@ -129,18 +147,25 @@ private void OnFormatMappingChanged() { _fontFamily = _textView.FormattedLineSource.DefaultTextProperties.Typeface.FontFamily; _fontEmSize = _textView.FormattedLineSource.DefaultTextProperties.FontRenderingEmSize; - - this.Width = GetMarginWidth(new Typeface(_fontFamily.Source), _fontEmSize) + 2 * _labelOffsetX; + + float covPercent; + if (GetCoverage(_fileName, 0, null, 0, out covPercent)) + this.MinWidth = GetMarginWidth(new Typeface(_fontFamily.Source), _fontEmSize) + 2 * _labelOffsetX; + else + this.MinWidth = 0; + this.Width = this.MinWidth; DrawLineNumbers(); } - #endregion - - #region DrawLineNumbers private void DrawLineNumbers() { - // Get the index from the line collection where the cursor is currently sitting + if (this.Width <= 0) + return; + if (_textView.InLayout) + return; + + // Get the index from the line collection where the cursor is currently sitting IVsTextBuffer buffer; _textView.TextBuffer.Properties.TryGetProperty(typeof(IVsTextBuffer), out buffer); int firstLine = 0; @@ -160,7 +185,8 @@ private void DrawLineNumbers() int lines = lastLine + 1 - firstLine; int[] covdata = new int[lines]; - bool hasCoverage = GetCoverageData(_fileName, firstLine, covdata, lines); + float covPercent; + bool hasCoverage = GetCoverage(_fileName, firstLine, covdata, lines, out covPercent); // GetColors(); if(!hasCoverage) return; @@ -188,7 +214,8 @@ private void DrawLineNumbers() buffer.GetLineIndexOfPosition(line.End, out last, out col); int cov = -1; bool hasNonCov = false; - for(int ln = first; ln <= last; ln++) + bool showPercent = false; + for (int ln = first; ln <= last; ln++) { int c = ln < firstLine || ln > lastLine ? -1 : covdata[ln - firstLine]; if(c == 0) @@ -198,25 +225,33 @@ private void DrawLineNumbers() else if(c >= 0) cov += c; } - if(cov < 0) - continue; - + if (cov < 0) + { + if (first > 0 || covPercent < 0) + continue; + showPercent = true; + } + + double zoom = _textView.ZoomLevel * 0.01; TextBlock tb = new TextBlock(); - tb.Text = string.Format("{0,4}", cov); - tb.FontFamily = _fontFamily; - tb.FontSize = _fontEmSize; - tb.Foreground = hasNonCov ? fgBrush2 : fgBrush; - tb.FontWeight = hasNonCov ? fontWeight2 : fontWeight; - tb.Background = hasNonCov ? bgBrush2 : bgBrush; - Canvas.SetLeft(tb, _labelOffsetX); - - Canvas.SetTop(tb, _textView.TextViewLines[i].TextTop - _textView.ViewportTop); + tb.FontFamily = _fontFamily; + tb.FontSize = _fontEmSize * zoom; + if (showPercent) + tb.Text = string.Format("{0,3}%", (int)covPercent); + else + { + tb.Text = string.Format("{0,4}", cov); + tb.Foreground = hasNonCov ? fgBrush2 : fgBrush; + tb.FontWeight = hasNonCov ? fontWeight2 : fontWeight; + tb.Background = hasNonCov ? bgBrush2 : bgBrush; + } + Canvas.SetLeft(tb, _labelOffsetX); + + Canvas.SetTop(tb, (_textView.TextViewLines[i].TextTop - _textView.ViewportTop) * zoom); _canvas.Children.Add(tb); } } - #endregion - private SolidColorBrush toBrush(object obj) { if(obj == null) @@ -256,26 +291,21 @@ public static Color ConvertFromWin32Color(uint color) byte b = (byte)((color & 0x00FF0000) >> 16); return Color.FromRgb(r, g, b); } - #region GetMarginWidth private double GetMarginWidth(Typeface fontTypeFace, double fontSize) { FormattedText formattedText = new FormattedText("9999+", System.Globalization.CultureInfo.GetCultureInfo("en-us"), System.Windows.FlowDirection.LeftToRight, fontTypeFace, fontSize, Brushes.Black); - return formattedText.MinWidth; + return formattedText.MinWidth * _textView.ZoomLevel * 0.01; } - #endregion - private void ThrowIfDisposed() { if (_isDisposed) throw new ObjectDisposedException(MarginName); } - #region IWpfTextViewMargin Members - public System.Windows.FrameworkElement VisualElement { get @@ -285,16 +315,13 @@ public System.Windows.FrameworkElement VisualElement } } - #endregion - - #region ITextViewMargin Members - public double MarginSize { get { ThrowIfDisposed(); - if (GetCoverageData(_fileName, 0, null, 0)) + float covPercent; + if (GetCoverage(_fileName, 0, null, 0, out covPercent)) return this.ActualWidth; return 0; } @@ -305,7 +332,8 @@ public bool Enabled get { ThrowIfDisposed(); - return GetCoverageData(_fileName, 0, null, 0); + float covPercent; + return GetCoverage(_fileName, 0, null, 0, out covPercent); } } @@ -322,7 +350,60 @@ public void Dispose() _isDisposed = true; } } - - #endregion } + + public class IID + { + public const string IVisualDHelper = "002a2de9-8bb6-484d-9910-7e4ad4084715"; + public const string VisualDHelper = "002a2de9-8bb6-484d-AA10-7e4ad4084715"; + } + + [ComVisible(true), Guid(IID.IVisualDHelper)] + [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] + public interface IVisualDHelper + { + void GetTextOptions(IVsTextView view, out int flags, out int tabsize, out int indentsize); + } + + [ComVisible(true), Guid(IID.VisualDHelper)] + [ClassInterface(ClassInterfaceType.None)] + public class VisualDHelper : IVisualDHelper + { + [DllImport("visuald.dll")] + public static extern int RegisterHelper(IVisualDHelper helper); + [DllImport("visuald.dll")] + public static extern int UnregisterHelper(IVisualDHelper helper); + + static IVsEditorAdaptersFactoryService editorFactory; + + public static bool setFactory(IVsEditorAdaptersFactoryService factory) + { + editorFactory = factory; + return true; + } + + public VisualDHelper() + { + } + + public void Dispose() + { + } + + public void GetTextOptions(IVsTextView view, out int flags, out int tabsize, out int indentsize) + { + if (editorFactory == null) + throw new COMException(); + + IWpfTextView wv = editorFactory.GetWpfTextView(view); + if (wv == null || wv.Options == null) + throw new COMException(); + + bool spaces = wv.Options.GetOptionValue(DefaultOptions.ConvertTabsToSpacesOptionId); + flags = spaces ? 1 : 0; + tabsize = wv.Options.GetOptionValue(DefaultOptions.TabSizeOptionId); + indentsize = wv.Options.GetOptionValue(DefaultOptions.IndentSizeOptionId); + } + + } } diff --git a/vdextensions/vdextensions.csproj b/vdextensions/vdextensions.csproj index bb882eca..b5c37089 100644 --- a/vdextensions/vdextensions.csproj +++ b/vdextensions/vdextensions.csproj @@ -1,4 +1,4 @@ - + Debug @@ -14,24 +14,51 @@ True full False - ..\bin\Debug\vdextensions + ..\bin\Debug\vdextensions\any\ DEBUG; prompt 4 False - none + full True - ..\bin\Release\vdextensions + ..\bin\Release\vdextensions\any\ prompt 4 False + true + + + true + ..\bin\Debug\vdextensions\ + DEBUG; + full + x86 + prompt + MinimumRecommendedRules.ruleset + + + true + ..\bin\Release\vdextensions\ + true + full + x86 + prompt + MinimumRecommendedRules.ruleset + + False + C:\Windows\Microsoft.NET\assembly\GAC_MSIL\Microsoft.VisualStudio.ComponentModelHost\v4.0_10.0.0.0__b03f5f7f11d50a3a\Microsoft.VisualStudio.ComponentModelHost.dll + + + False + C:\Windows\Microsoft.NET\assembly\GAC_MSIL\Microsoft.VisualStudio.Editor\v4.0_10.0.0.0__b03f5f7f11d50a3a\Microsoft.VisualStudio.Editor.dll + - c:\l\vs10\Common7\IDE\CommonExtensions\Microsoft\Editor\Microsoft.VisualStudio.Text.UI.Wpf.dll + c:\Program Files (x86)\Microsoft Visual Studio 10.0\Common7\IDE\CommonExtensions\Microsoft\Editor\Microsoft.VisualStudio.Text.UI.Wpf.dll @@ -45,16 +72,16 @@ - c:\l\vs10\Common7\IDE\CommonExtensions\Microsoft\Editor\Microsoft.VisualStudio.Text.UI.dll + c:\Program Files (x86)\Microsoft Visual Studio 10.0\Common7\IDE\CommonExtensions\Microsoft\Editor\Microsoft.VisualStudio.Text.UI.dll - c:\l\vs10\Common7\IDE\CommonExtensions\Microsoft\Editor\Microsoft.VisualStudio.CoreUtility.dll + c:\Program Files (x86)\Microsoft Visual Studio 10.0\Common7\IDE\CommonExtensions\Microsoft\Editor\Microsoft.VisualStudio.CoreUtility.dll - c:\l\vs10\Common7\IDE\CommonExtensions\Microsoft\Editor\Microsoft.VisualStudio.Text.Data.dll + c:\Program Files (x86)\Microsoft Visual Studio 10.0\Common7\IDE\CommonExtensions\Microsoft\Editor\Microsoft.VisualStudio.Text.Data.dll - c:\l\vs10\Common7\IDE\CommonExtensions\Microsoft\Editor\Microsoft.VisualStudio.Text.Logic.dll + c:\Program Files (x86)\Microsoft Visual Studio 10.0\Common7\IDE\CommonExtensions\Microsoft\Editor\Microsoft.VisualStudio.Text.Logic.dll @@ -67,7 +94,7 @@ C:\Windows\assembly\GAC\Microsoft.VisualStudio.Shell.Interop.8.0\8.0.0.0__b03f5f7f11d50a3a\microsoft.visualstudio.shell.interop.8.0.dll - C:\l\vs10\Common7\IDE\PrivateAssemblies\Microsoft.VisualStudio.Shell.9.0.dll + c:\Program Files (x86)\Microsoft Visual Studio 10.0\Common7\IDE\PrivateAssemblies\Microsoft.VisualStudio.Shell.9.0.dll C:\Windows\assembly\GAC\Microsoft.VisualStudio.Shell.Interop\7.1.40304.0__b03f5f7f11d50a3a\Microsoft.VisualStudio.Shell.Interop.dll @@ -81,7 +108,5 @@ - - - + \ No newline at end of file diff --git a/vdextensions/vdextensions.sln b/vdextensions/vdextensions.sln new file mode 100644 index 00000000..b3b4f06b --- /dev/null +++ b/vdextensions/vdextensions.sln @@ -0,0 +1,28 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 2013 +VisualStudioVersion = 12.0.21005.1 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "vdextensions", "vdextensions.csproj", "{3A338E86-A08A-4F9A-8DB1-A5C280773BA3}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Debug|x86 = Debug|x86 + Release|Any CPU = Release|Any CPU + Release|x86 = Release|x86 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {3A338E86-A08A-4F9A-8DB1-A5C280773BA3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {3A338E86-A08A-4F9A-8DB1-A5C280773BA3}.Debug|Any CPU.Build.0 = Debug|Any CPU + {3A338E86-A08A-4F9A-8DB1-A5C280773BA3}.Debug|x86.ActiveCfg = Debug|x86 + {3A338E86-A08A-4F9A-8DB1-A5C280773BA3}.Debug|x86.Build.0 = Debug|x86 + {3A338E86-A08A-4F9A-8DB1-A5C280773BA3}.Release|Any CPU.ActiveCfg = Debug|x86 + {3A338E86-A08A-4F9A-8DB1-A5C280773BA3}.Release|Any CPU.Build.0 = Debug|x86 + {3A338E86-A08A-4F9A-8DB1-A5C280773BA3}.Release|x86.ActiveCfg = Release|x86 + {3A338E86-A08A-4F9A-8DB1-A5C280773BA3}.Release|x86.Build.0 = Release|x86 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/visuald/Resources/pkgcmd.ctc b/visuald/Resources/pkgcmd.ctc index 3e93a316..2e4e186a 100644 --- a/visuald/Resources/pkgcmd.ctc +++ b/visuald/Resources/pkgcmd.ctc @@ -89,6 +89,7 @@ CMDS_SECTION g_packageCLSID g_commandSetCLSID:CmdBuildPhobos, g_packageCLSID:IDG_VD_BUILD, 0xF300, guidOfficeIcon:msotcidNoIcon, BUTTON, , "Build Phobos Browse Info", "Build Phobos &Browse Info", "Build Phobos Browse Info", , "BuildPhobosBrowseInfo", "BuildPhobosBrowseInfo"; g_commandSetCLSID:CmdShowProfile, g_packageCLSID:IDG_VD_BUILD, 0xF300, guidOfficeIcon:msotcidNoIcon, BUTTON, , "Open Profiler Window", "&Open Profiler Window", "Open Profiler Window", , "OpenProfilerWindow", "OpenProfilerWindow"; g_commandSetCLSID:CmdCompileAndRun, g_packageCLSID:IDG_VD_BUILD, 0xF300, guidOfficeIcon:msotcidNoIcon, BUTTON, , "Compile and Run", "Compile and Run", "Compile and Run", , "CompileAndRun", "CompileAndRun"; + g_commandSetCLSID:CmdCompileAndDbg, g_packageCLSID:IDG_VD_BUILD, 0xF300, guidOfficeIcon:msotcidNoIcon, BUTTON, , "Compile and Debug", "Compile and Debug", "Compile and Debug", , "CompileAndDebug", "CompileAndDebug"; g_commandSetCLSID:CmdDelLstFiles, g_packageCLSID:IDG_VD_BUILD, 0xF300, guidOfficeIcon:msotcidNoIcon, BUTTON, , "Delete Coverage Files", "Delete Coverage Files", "Delete Coverage Files", , "DeleteCoverageFiles", "DeleteCoverageFiles"; g_commandSetCLSID:CmdConvWizard, g_packageCLSID:IDG_VD_CONVERSION, 0xF300, guidOfficeIcon:msotcidNoIcon, BUTTON, , "C++ Conversion Wizard", "C++ Conversion &Wizard...", "C++ Conversion Wizard", , "ConversionWizard", "ConversionWizard"; g_commandSetCLSID:CmdConvSelection, g_packageCLSID:IDG_VD_CONVERSION, 0xF300, guidOfficeIcon:msotcidNoIcon, BUTTON, , "C++ Convert Selection", "C++ Convert Selection", "C++ Convert Selection", , "ConvertSelection", "ConvertSelection"; diff --git a/visuald/Resources/pkgcmd.cto b/visuald/Resources/pkgcmd.cto index db1eaad5..14748d6a 100644 Binary files a/visuald/Resources/pkgcmd.cto and b/visuald/Resources/pkgcmd.cto differ diff --git a/visuald/Resources/pkgcmd.ctsym b/visuald/Resources/pkgcmd.ctsym index 96b3f28a..6de1bc66 100644 --- a/visuald/Resources/pkgcmd.ctsym +++ b/visuald/Resources/pkgcmd.ctsym @@ -1,6 +1,7 @@ "g_commandSetCLSID:CmdBuildPhobos"={ 0x002a2de9, 0x8bb6, 0x484d, { 0x98, 0x03, 0x7e, 0x4a, 0xd4, 0x08, 0x47, 0x15 } }:0x110 "g_commandSetCLSID:CmdCollapseDisabled"={ 0x002a2de9, 0x8bb6, 0x484d, { 0x98, 0x03, 0x7e, 0x4a, 0xd4, 0x08, 0x47, 0x15 } }:0x121 "g_commandSetCLSID:CmdCollapseUnittest"={ 0x002a2de9, 0x8bb6, 0x484d, { 0x98, 0x03, 0x7e, 0x4a, 0xd4, 0x08, 0x47, 0x15 } }:0x120 +"g_commandSetCLSID:CmdCompileAndDbg"={ 0x002a2de9, 0x8bb6, 0x484d, { 0x98, 0x03, 0x7e, 0x4a, 0xd4, 0x08, 0x47, 0x15 } }:0x117 "g_commandSetCLSID:CmdCompileAndRun"={ 0x002a2de9, 0x8bb6, 0x484d, { 0x98, 0x03, 0x7e, 0x4a, 0xd4, 0x08, 0x47, 0x15 } }:0x114 "g_commandSetCLSID:CmdConvSelection"={ 0x002a2de9, 0x8bb6, 0x484d, { 0x98, 0x03, 0x7e, 0x4a, 0xd4, 0x08, 0x47, 0x15 } }:0x10a "g_commandSetCLSID:CmdConvWizard"={ 0x002a2de9, 0x8bb6, 0x484d, { 0x98, 0x03, 0x7e, 0x4a, 0xd4, 0x08, 0x47, 0x15 } }:0x109 diff --git a/visuald/Resources/resources.h b/visuald/Resources/resources.h index 4cc6bcdc..743cbaa7 100644 --- a/visuald/Resources/resources.h +++ b/visuald/Resources/resources.h @@ -49,6 +49,7 @@ #define CmdCompileAndRun 0x114 #define CmdShowLangPage 0x115 #define CmdDelLstFiles 0x116 +#define CmdCompileAndDbg 0x117 #define CmdCollapseUnittest 0x120 #define CmdCollapseDisabled 0x121 diff --git a/visuald/colorizer.d b/visuald/colorizer.d index 240a2dca..9a79cfc9 100644 --- a/visuald/colorizer.d +++ b/visuald/colorizer.d @@ -241,6 +241,7 @@ class Colorizer : DisposingComObject, IVsColorizer, ConfigModifiedListener bool mConfigNoBoundsCheck; int[] mCoverage; + float mCoveragePercent; string mLastCoverageFile; SysTime mLastTestCoverageFile; SysTime mLastModifiedCoverageFile; @@ -534,7 +535,11 @@ class Colorizer : DisposingComObject, IVsColorizer, ConfigModifiedListener string s; ColorableItemInfo *info = &covColor; if(cov < 0) + { + if (iLine == 0 && mCoveragePercent >= 0) + s = text(mCoveragePercent) ~ "%"; info = &nocovColor; + } else if(cov == 0) { s = "0"; @@ -1436,8 +1441,9 @@ class Colorizer : DisposingComObject, IVsColorizer, ConfigModifiedListener ////////////////////////////////////////////////////////// - static int[] ReadCoverageFile(string lstname) + static int[] ReadCoverageFile(string lstname, out float coveragePercent) { + coveragePercent = -1; try { char[] lst = cast(char[]) std.file.read(lstname); @@ -1453,20 +1459,21 @@ class Colorizer : DisposingComObject, IVsColorizer, ConfigModifiedListener if(num.length) cov = parse!int(num); } - else version(none) + coverage[i] = cov; + } + if (lines.length > 0) + { + char[] ln = lines[$-1]; + auto pos = std.string.indexOf(ln, "% covered"); + if(pos > 0) { - pos = std.string.indexOf(ln, "% covered"); - if(pos > 0) - { - auto end = pos; - while(pos > 0 && isDigit(ln[pos-1])) - pos--; - auto num = ln[pos..end]; - if(num.length) - cov = parse!int(num); // very last entry is percent - } + auto end = pos; + while(pos > 0 && isDigit(ln[pos-1]) || ln[pos - 1] == '.') + pos--; + auto num = ln[pos..end]; + if(num.length) + coveragePercent = parse!float(num); // very last entry is percent } - coverage[i] = cov; } return coverage; } @@ -1512,7 +1519,7 @@ class Colorizer : DisposingComObject, IVsColorizer, ConfigModifiedListener else if(force || lsttm != mLastModifiedCoverageFile) { mLastModifiedCoverageFile = lsttm; - mCoverage = ReadCoverageFile(mLastCoverageFile); + mCoverage = ReadCoverageFile(mLastCoverageFile, mCoveragePercent); mSource.ReColorizeLines(0, -1); } diff --git a/visuald/config.d b/visuald/config.d index 9f44d093..e3a96f15 100644 --- a/visuald/config.d +++ b/visuald/config.d @@ -40,6 +40,7 @@ import visuald.propertypage; import visuald.stringutil; import visuald.fileutil; import visuald.lexutil; +import visuald.vdextensions; // version = hasOutputGroup; @@ -835,7 +836,7 @@ class ProjectOptions if(symdebug) cmd ~= mslink ? " /DEBUG" : "/CO"; - cmd ~= mslink ? " /INCREMENTAL:NO /NOLOGO" : "/NOI"; + cmd ~= mslink ? " /INCREMENTAL:NO /NOLOGO" : "/NOI/DELEXE"; if(mslink) { @@ -1944,7 +1945,11 @@ class Config : DisposingComObject, ShellExecuteW(null, null, toUTF16z(quoteFilename(prg)), toUTF16z(args), toUTF16z(workdir), SW_SHOWNORMAL); return(S_OK); } + return _DebugLaunch(prg, workdir, args, mProjectOptions.debugEngine); + } + HRESULT _DebugLaunch(string prg, string workdir, string args, int engine) + { HRESULT hr = E_NOTIMPL; // When the debug target is the project build output, the project have to use // IVsSolutionDebuggingAssistant2 to determine if the target was deployed. @@ -1987,7 +1992,7 @@ class Config : DisposingComObject, dbgi.dlo = DLO_CreateProcess; // DLO_Custom; // specifies how this process should be launched // clsidCustom is the clsid of the debug engine to use to launch the debugger - switch(mProjectOptions.debugEngine) + switch(engine) { case 1: GUID GUID_MaGoDebugger = uuid("{97348AC0-2B6B-4B99-A245-4C7E2C09D403}"); @@ -2507,15 +2512,21 @@ class Config : DisposingComObject, opts.doHdrGeneration = false; opts.doDocComments = false; opts.lib = OutputType.Executable; - opts.runCv2pdb = false; + //opts.runCv2pdb = false; opts.exefile = "$(OutDir)\\" ~ baseName(stripExtension(outfile)) ~ ".exe"; cmd = "echo Compiling " ~ file.GetFilename() ~ "...\n"; - cmd ~= opts.buildCommandLine(true, false, false, syntaxOnly); + cmd ~= opts.buildCommandLine(true, !syntaxOnly, false, syntaxOnly); if(syntaxOnly) cmd ~= " --build-only"; cmd ~= addopt ~ " " ~ file.GetFilename(); addopt = ""; // must be before filename for rdmd + if (!syntaxOnly) + { + string cv2pdb = opts.appendCv2pdb(); + if (cv2pdb.length) + cmd ~= "\nif errorlevel 1 goto reportError\n" ~ opts.appendCv2pdb(); + } } if(cmd.length) { @@ -2961,6 +2972,7 @@ class Config : DisposingComObject, { scope(exit) release(eo); ULONG fetched; + string lastTarg; IVsOutput pIVsOutput; while(eo.Next(1, &pIVsOutput, &fetched) == S_OK && fetched == 1) { @@ -2970,7 +2982,20 @@ class Config : DisposingComObject, //if(pIVsOutput.get_DisplayName(&target.bstr) == S_OK) { string targ = target.detach(); - libs ~= targ; + if (lastTarg.length && targ.indexOf('$') >= 0) + { + // VC projects report the import library without expanding macros + // (even if building static libraries), so assume it lies along side the DLL + if (targ.extension().toLower() == ".lib" && lastTarg.extension().toLower() != ".lib") + targ = lastTarg.stripExtension() ~ ".lib"; + else + targ = null; + } + if (targ.length) + { + libs ~= targ; + lastTarg = targ; + } } release(pIVsOutput); } diff --git a/visuald/dlangsvc.d b/visuald/dlangsvc.d index f0578e5e..064226d0 100644 --- a/visuald/dlangsvc.d +++ b/visuald/dlangsvc.d @@ -28,6 +28,7 @@ import visuald.windows; import visuald.simpleparser; import visuald.config; import visuald.vdserverclient; +import visuald.vdextensions; version = VDServer; @@ -418,7 +419,7 @@ class LanguageService : DisposingComObject, }; static void shared_static_dtor() { - clear(colorableItems); // to keep GC leak detection happy + destroy(colorableItems); // to keep GC leak detection happy Source.parseTaskPool = null; } @@ -720,7 +721,7 @@ class LanguageService : DisposingComObject, return (mDbgMode & ~ DBGMODE_EncMask) != DBGMODE_Design; } - bool GetCoverageData(string filename, uint line, uint* data, uint cnt) + bool GetCoverageData(string filename, uint line, uint* data, uint cnt, float* covPrecent) { if(!Package.GetGlobalOptions().showCoverageMargin) return false; @@ -738,6 +739,8 @@ class LanguageService : DisposingComObject, uint covLine = src.adjustLineNumberSinceLastBuildReverse(line + ln, true); data[ln] = covLine >= cov.length ? -1 : cov[covLine]; } + if (covPrecent) + *covPrecent = src.mColorizer.mCoveragePercent; return true; } @@ -1044,7 +1047,7 @@ bool jumpToDefinitionInCodeWindow(string symbol, string filename, int line, int /////////////////////////////////////////////////////////////////////////////// -int GetUserPreferences(LANGPREFERENCES *langPrefs) +int GetUserPreferences(LANGPREFERENCES *langPrefs, IVsTextView view) { IVsTextManager textmgr = queryService!(VsTextManager, IVsTextManager); if(!textmgr) @@ -1054,6 +1057,17 @@ int GetUserPreferences(LANGPREFERENCES *langPrefs) langPrefs.guidLang = g_languageCLSID; if(int rc = textmgr.GetUserPreferences(null, null, langPrefs, null)) return rc; + + if (view) + { + int flags, tabsize, indentsize; + if(vdhelper_GetTextOptions(view, &flags, &tabsize, &indentsize) == S_OK) + { + langPrefs.uTabSize = max(1, tabsize); + langPrefs.uIndentSize = max(1, indentsize); + langPrefs.fInsertTabs = (flags & 1) == 0; + } + } return S_OK; } @@ -2690,10 +2704,10 @@ else return indent + labelIndent; } - int ReindentLines(int startline, int endline) + int ReindentLines(IVsTextView view, int startline, int endline) { LANGPREFERENCES langPrefs; - if(int rc = GetUserPreferences(&langPrefs)) + if(int rc = GetUserPreferences(&langPrefs, view)) return rc; if(langPrefs.IndentStyle != vsIndentStyleSmart) return S_FALSE; @@ -2761,10 +2775,10 @@ else ForceUncomment, } - int CommentLines(int startline, int endline, int commentMode) + int CommentLines(IVsTextView view, int startline, int endline, int commentMode) { LANGPREFERENCES langPrefs; - if(int rc = GetUserPreferences(&langPrefs)) + if(int rc = GetUserPreferences(&langPrefs, view)) return rc; wstring[] lines; diff --git a/visuald/dllmain.d b/visuald/dllmain.d index cb13571a..97a1af78 100644 --- a/visuald/dllmain.d +++ b/visuald/dllmain.d @@ -172,10 +172,12 @@ void WritePackageDef(HWND hwnd, HINSTANCE hinst, LPSTR lpszCmdLine, int nCmdShow } extern(Windows) -bool GetCoverageData(const(char)* fname, uint line, uint* data, uint cnt) +bool GetCoverageData(const(char)* fname, uint line, uint* data, uint cnt, float* covPercent) { + if (!Package.s_instance) + return false; // not yet loaded as a package string filename = to!string(fname); - return Package.GetLanguageService().GetCoverageData(filename, line, data, cnt); + return Package.GetLanguageService().GetCoverageData(filename, line, data, cnt, covPercent); } /////////////////////////////////////////////////////////////////////// diff --git a/visuald/dpackage.d b/visuald/dpackage.d index 3672f0d1..8476c499 100644 --- a/visuald/dpackage.d +++ b/visuald/dpackage.d @@ -106,6 +106,9 @@ const GUID g_omLibraryCLSID = uuid("002a2de9-8bb6-484d-980c-7e4ad40 const GUID g_ProjectItemWizardCLSID = uuid("002a2de9-8bb6-484d-980d-7e4ad4084715"); const GUID g_unmarshalCLSID = uuid("002a2de9-8bb6-484d-980e-7e4ad4084715"); + +const GUID g_VisualDHelperCLSID = uuid("002a2de9-8bb6-484d-aa10-7e4ad4084715"); + // more guids in propertypage.d starting with 9810 const LanguageProperty g_languageProperties[] = @@ -1121,6 +1124,8 @@ class GlobalOptions bool UFCSExpansions; string VDServerIID; string compileAndRunOpts; + string compileAndDbgOpts; + int compileAndDbgEngine; string[] coverageBuildDirs; string[] coverageExecutionDirs; @@ -1333,6 +1338,8 @@ class GlobalOptions IncSearchPath = getStringOpt("IncSearchPath"); VDServerIID = getStringOpt("VDServerIID"); compileAndRunOpts = getStringOpt("compileAndRunOpts", "-unittest"); + compileAndDbgOpts = getStringOpt("compileAndDbgOpts", "-g"); + compileAndDbgEngine = getIntOpt("compileAndDbgEngine", 0); string execDirs = getStringOpt("coverageExecutionDirs", ""); coverageExecutionDirs = split(execDirs, ";"); @@ -1426,6 +1433,8 @@ class GlobalOptions keyToolOpts.Set("UFCSExpansions", UFCSExpansions); keyToolOpts.Set("pasteIndent", pasteIndent); keyToolOpts.Set("compileAndRunOpts", toUTF16(compileAndRunOpts)); + keyToolOpts.Set("compileAndDbgOpts", toUTF16(compileAndDbgOpts)); + keyToolOpts.Set("compileAndDbgEngine", compileAndDbgEngine); keyToolOpts.Set("coverageExecutionDirs", toUTF16(join(coverageExecutionDirs, ";"))); keyToolOpts.Set("coverageBuildDirs", toUTF16(join(coverageBuildDirs, ";"))); @@ -1555,8 +1564,6 @@ class GlobalOptions string getLinkerPath(bool x64, string workdir, string dmdpath, string *libs = null, string* options = null) { - getVCLibraryPaths(); - string path = "link.exe"; string inifile = findScIni(workdir, dmdpath, false); if(!inifile.empty) @@ -1698,6 +1705,7 @@ class GlobalOptions } } + version(none) string[] getVCLibraryPaths() { IVsProfileDataManager pdm = queryService!(SVsProfileDataManager,IVsProfileDataManager)(); @@ -1965,7 +1973,7 @@ class GlobalOptions { string[] lstfiles; foreach(f; std.file.dirEntries(dir, SpanMode.shallow)) - if(icmp(extension(f), ".lst") == 0) + if(icmp(extension(f.name), ".lst") == 0) lstfiles ~= f; foreach(lst; lstfiles) collectException(std.file.remove(lst)); diff --git a/visuald/expansionprovider.d b/visuald/expansionprovider.d index 9749c3e4..5fe85645 100644 --- a/visuald/expansionprovider.d +++ b/visuald/expansionprovider.d @@ -519,7 +519,7 @@ class ExpansionProvider : DisposingComObject, IVsExpansionClient // mSource.ReformatSpan(edits, span); // edits.ApplyEdits(); //} - rc = mSource.ReindentLines(ts.iStartLine, ts.iEndLine); + rc = mSource.ReindentLines(mView, ts.iStartLine, ts.iEndLine); } return rc; } diff --git a/visuald/intellisense.d b/visuald/intellisense.d index c9418ffd..4b8597d0 100644 --- a/visuald/intellisense.d +++ b/visuald/intellisense.d @@ -904,7 +904,7 @@ class BrowseInfo mFilename = info.mFilename; mModified = info.mModified; - clear(mModules); + destroy(mModules); createModules(info); if(Config cfg = getProjectConfig(mFilename)) diff --git a/visuald/propertypage.d b/visuald/propertypage.d index eea25f00..7efbca0b 100644 --- a/visuald/propertypage.d +++ b/visuald/propertypage.d @@ -1677,9 +1677,12 @@ class ToolsProperty2Page : GlobalPropertyPage AddControl("", mOptlinkDeps = new CheckBox(mCanvas, "Monitor OPTLINK dependencies")); //AddControl("Remove project item", mDeleteFiles = // new ComboBox(mCanvas, [ "Do not delete file on disk", "Ask", "Delete file on disk" ])); - AddControl("JSON paths", mJSNPath = new MultiLineText(mCanvas)); + mLinesPerMultiLine = 2; + AddControl("JSON paths", mJSNPath = new MultiLineText(mCanvas)); AddControl("Resource includes", mIncPath = new Text(mCanvas)); - AddControl("Compile and Run options", mCompileAndRunOpts = new Text(mCanvas)); + AddControl("Compile + Run options", mCompileAndRunOpts = new Text(mCanvas)); + AddControl("Compile + Debug options", mCompileAndDbgOpts = new Text(mCanvas)); + AddControl(" Debugger", mCompileAndDbgEngine = new ComboBox(mCanvas, [ "Visual Studio", "Mago", "Visual Studio (x86 Mixed Mode)" ], false)); } override void SetControls(GlobalOptions opts) @@ -1694,6 +1697,8 @@ class ToolsProperty2Page : GlobalPropertyPage mIncPath.setText(opts.IncSearchPath); mJSNPath.setText(opts.JSNSearchPath); mCompileAndRunOpts.setText(opts.compileAndRunOpts); + mCompileAndDbgOpts.setText(opts.compileAndDbgOpts); + mCompileAndDbgEngine.setSelection(opts.compileAndDbgEngine); } override int DoApply(GlobalOptions opts, GlobalOptions refopts) @@ -1709,6 +1714,8 @@ class ToolsProperty2Page : GlobalPropertyPage changes += changeOption(mIncPath.getText(), opts.IncSearchPath, refopts.IncSearchPath); changes += changeOption(mJSNPath.getText(), opts.JSNSearchPath, refopts.JSNSearchPath); changes += changeOption(mCompileAndRunOpts.getText(), opts.compileAndRunOpts, refopts.compileAndRunOpts); + changes += changeOption(mCompileAndDbgOpts.getText(), opts.compileAndDbgOpts, refopts.compileAndDbgOpts); + changes += changeOption(mCompileAndDbgEngine.getSelection(), opts.compileAndDbgEngine, refopts.compileAndDbgEngine); return changes; } @@ -1721,6 +1728,8 @@ class ToolsProperty2Page : GlobalPropertyPage //ComboBox mDeleteFiles; Text mIncPath; Text mCompileAndRunOpts; + Text mCompileAndDbgOpts; + ComboBox mCompileAndDbgEngine; MultiLineText mJSNPath; } @@ -1740,7 +1749,7 @@ class ColorizerPropertyPage : GlobalPropertyPage { AddControl("", mColorizeVersions = new CheckBox(mCanvas, "Colorize version and debug statements")); AddControl("", mColorizeCoverage = new CheckBox(mCanvas, "Colorize coverage from .LST file")); -debug AddControl("", mShowCoverageMargin = new CheckBox(mCanvas, "Show coverage margin")); + AddControl("", mShowCoverageMargin = new CheckBox(mCanvas, "Show coverage margin")); AddControl("", mAutoOutlining = new CheckBox(mCanvas, "Add outlining regions when opening D files")); AddControl("", mParseSource = new CheckBox(mCanvas, "Parse source for syntax errors")); AddControl("", mPasteIndent = new CheckBox(mCanvas, "Reindent new lines after paste")); @@ -1751,7 +1760,7 @@ debug AddControl("", mShowCoverageMargin = new CheckBox(mCanvas, "Show coverage { mColorizeVersions.setChecked(opts.ColorizeVersions); mColorizeCoverage.setChecked(opts.ColorizeCoverage); -debug mShowCoverageMargin.setChecked(opts.showCoverageMargin); + mShowCoverageMargin.setChecked(opts.showCoverageMargin); mAutoOutlining.setChecked(opts.autoOutlining); mParseSource.setChecked(opts.parseSource); mPasteIndent.setChecked(opts.pasteIndent); @@ -1765,7 +1774,7 @@ debug mShowCoverageMargin.setChecked(opts.showCoverageMargin); int changes = 0; changes += changeOption(mColorizeVersions.isChecked(), opts.ColorizeVersions, refopts.ColorizeVersions); changes += changeOption(mColorizeCoverage.isChecked(), opts.ColorizeCoverage, refopts.ColorizeCoverage); -debug changes += changeOption(mShowCoverageMargin.isChecked(), opts.showCoverageMargin, refopts.showCoverageMargin); + changes += changeOption(mShowCoverageMargin.isChecked(), opts.showCoverageMargin, refopts.showCoverageMargin); changes += changeOption(mAutoOutlining.isChecked(), opts.autoOutlining, refopts.autoOutlining); changes += changeOption(mParseSource.isChecked(), opts.parseSource, refopts.parseSource); changes += changeOption(mPasteIndent.isChecked(), opts.pasteIndent, refopts.pasteIndent); @@ -1775,7 +1784,7 @@ debug changes += changeOption(mShowCoverageMargin.isChecked(), opts.showCoverage CheckBox mColorizeVersions; CheckBox mColorizeCoverage; -debug CheckBox mShowCoverageMargin; + CheckBox mShowCoverageMargin; CheckBox mAutoOutlining; CheckBox mParseSource; CheckBox mPasteIndent; diff --git a/visuald/register.d b/visuald/register.d index 076456af..850b902c 100644 --- a/visuald/register.d +++ b/visuald/register.d @@ -381,11 +381,13 @@ HRESULT VSDllUnregisterServerInternal(in wchar* pszRegRoot, in bool useRanu) wstring packageGuid = GUID2wstring(g_packageCLSID); wstring languageGuid = GUID2wstring(g_languageCLSID); wstring wizardGuid = GUID2wstring(g_ProjectItemWizardCLSID); + wstring vdhelperGuid = GUID2wstring(g_VisualDHelperCLSID); HRESULT hr = S_OK; hr |= RegDeleteRecursive(keyRoot, registrationRoot ~ "\\Packages\\"w ~ packageGuid); hr |= RegDeleteRecursive(keyRoot, registrationRoot ~ "\\CLSID\\"w ~ languageGuid); hr |= RegDeleteRecursive(keyRoot, registrationRoot ~ "\\CLSID\\"w ~ wizardGuid); + hr |= RegDeleteRecursive(keyRoot, registrationRoot ~ "\\CLSID\\"w ~ vdhelperGuid); foreach (wstring fileExt; g_languageFileExtensions) hr |= RegDeleteRecursive(keyRoot, registrationRoot ~ regPathFileExts ~ "\\"w ~ fileExt); @@ -420,6 +422,7 @@ HRESULT VSDllRegisterServerInternal(in wchar* pszRegRoot, in bool useRanu) wstring registrationRoot = GetRegistrationRoot(pszRegRoot, useRanu); wstring dllPath = GetDLLName(g_hInst); wstring templatePath = GetTemplatePath(dllPath); + wstring vdextPath = dirName(dllPath) ~ "\\vdextensions.dll"w; try { @@ -428,6 +431,7 @@ HRESULT VSDllRegisterServerInternal(in wchar* pszRegRoot, in bool useRanu) wstring debugLangGuid = GUID2wstring(g_debuggerLanguage); wstring exprEvalGuid = GUID2wstring(g_expressionEvaluator); wstring wizardGuid = GUID2wstring(g_ProjectItemWizardCLSID); + wstring vdhelperGuid = GUID2wstring(g_VisualDHelperCLSID); // package scope RegKey keyPackage = new RegKey(keyRoot, registrationRoot ~ "\\Packages\\"w ~ packageGuid); @@ -454,6 +458,14 @@ HRESULT VSDllRegisterServerInternal(in wchar* pszRegRoot, in bool useRanu) keyWizardCLSID.Set("InprocServer32"w, dllPath); keyWizardCLSID.Set("ThreadingModel"w, "Appartment"w); + // VDExtensions + scope RegKey keyHelperCLSID = new RegKey(keyRoot, registrationRoot ~ "\\CLSID\\"w ~ vdhelperGuid); + keyHelperCLSID.Set("InprocServer32"w, "mscoree.dll"); + keyHelperCLSID.Set("ThreadingModel"w, "Both"w); + keyHelperCLSID.Set(null, "vdextensions.VisualDHelper"w); + keyHelperCLSID.Set("Class"w, "vdextensions.VisualDHelper"w); + keyHelperCLSID.Set("CodeBase"w, vdextPath); + // file extensions wstring fileExtensions; foreach (wstring fileExt; g_languageFileExtensions) diff --git a/visuald/vdextensions.d b/visuald/vdextensions.d new file mode 100644 index 00000000..96e0f126 --- /dev/null +++ b/visuald/vdextensions.d @@ -0,0 +1,35 @@ +module visuald.vdextensions; + +import sdk.port.base; +import sdk.win32.oaidl; +import sdk.win32.objbase; +import sdk.win32.oleauto; + +import sdk.vsi.textmgr; +import sdk.vsi.vsshell; + +import visuald.hierutil; +import visuald.dpackage; + +__gshared IVisualDHelper vdhelper; + +interface IVisualDHelper : IUnknown +{ + static const GUID iid = uuid("002a2de9-8bb6-484d-9910-7e4ad4084715"); + + int GetTextOptions(IVsTextView view, int* flags, int* tabsize, int* indentsize); +} + +IVisualDHelper createHelper() +{ + if (!vdhelper) + vdhelper = VsLocalCreateInstance!IVisualDHelper (&g_VisualDHelperCLSID, sdk.win32.wtypes.CLSCTX_INPROC_SERVER); + return vdhelper; +} + +int vdhelper_GetTextOptions(IVsTextView view, int* flags, int* tabsize, int* indentsize) +{ + if (!createHelper()) + return S_FALSE; + return vdhelper.GetTextOptions(view, flags, tabsize, indentsize); +} diff --git a/visuald/viewfilter.d b/visuald/viewfilter.d index 560abf9b..710f433e 100644 --- a/visuald/viewfilter.d +++ b/visuald/viewfilter.d @@ -318,7 +318,7 @@ version(tip) break; case ECMD_COMPILE: - return CompileDoc(false, false); + return CompileDoc(false, false, false); case ECMD_GOTOBRACE: return GotoMatchingPair(false); @@ -351,7 +351,10 @@ version(tip) return ConvertSelection(); case CmdCompileAndRun: - return CompileDoc(true, true); + return CompileDoc(true, true, false); + + case CmdCompileAndDbg: + return CompileDoc(true, false, true); case CmdCollapseUnittest: return mCodeWinMgr.mSource.CollapseDisabled(true, false); @@ -466,7 +469,7 @@ version(tip) else if(ch == '(') { LANGPREFERENCES langPrefs; - if(GetUserPreferences(&langPrefs) == S_OK && langPrefs.fAutoListParams) + if(GetUserPreferences(&langPrefs, null) == S_OK && langPrefs.fAutoListParams) _HandleMethodTip(false); } break; @@ -483,7 +486,7 @@ version(tip) ////////////////////////////// - HRESULT CompileDoc(bool rdmd, bool run) + HRESULT CompileDoc(bool rdmd, bool run, bool dbg) { IVsUIShellOpenDocument pIVsUIShellOpenDocument = queryService!(IVsUIShellOpenDocument); if(!pIVsUIShellOpenDocument) @@ -524,7 +527,7 @@ version(tip) string filename = normalizeDir(tempDir()) ~ "__compile__.vdproj"; string srcfile = Package.GetGlobalOptions().VisualDInstallDir ~ "Templates/ProjectItems/ConsoleApp/ConsoleApp.visualdproj"; - proj = newCom!Project(factory, "__compile__", filename, "Win32", "Debug").addref(); + proj = newCom!Project(factory, "__compile__", filename, "Debug", "Win32").addref(); pFile = newCom!CFileNode(fname); proj.GetProjectNode().Add(pFile); @@ -583,35 +586,41 @@ version(tip) string stool = cfg.GetStaticCompileTool(pFile, cfg.getCfgName()); if(stool == "DMD") stool = "DMDsingle"; - if(stool == "DMDsingle") + if(stool == "DMDsingle" && rdmd) { - if(rdmd) + stool = "RDMD"; + if(selText.length) { - stool = "RDMD"; - if(selText.length) + string[] lines = splitLines(selText); + foreach(ln; lines) { - string[] lines = splitLines(selText); - foreach(ln; lines) - { - string line = strip(detab(ln)); - if(line.length) - addopt ~= " \"--eval=" ~ replace(line, "\"", "\\\\\\\"") ~ "\""; - } + string line = strip(detab(ln)); + if(line.length) + addopt ~= " \"--eval=" ~ replace(line, "\"", "\\\\\\\"") ~ "\""; } } - else if(run) - addopt ~= " -run"; } - if(stool == "RDMD") - addopt = " " ~ Package.GetGlobalOptions().compileAndRunOpts ~ addopt; - string cmd = cfg.GetCompileCommand(pFile, !run, stool, addopt); + if(stool == "RDMD" && run) + addopt = " --build-only " ~ Package.GetGlobalOptions().compileAndRunOpts ~ addopt; + else if(stool == "RDMD" && dbg) + addopt = " --build-only " ~ Package.GetGlobalOptions().compileAndDbgOpts ~ addopt; + + string cmd = cfg.GetCompileCommand(pFile, !dbg && !run, stool, addopt); if(cmd.length) { cmd ~= "if not errorlevel 1 echo Compilation successful.\n"; string workdir = cfg.GetProjectDir(); string outfile = cfg.GetOutputFile(pFile, stool); - string cmdfile = makeFilenameAbsolute(outfile ~ ".syntax", workdir); - removeCachedFileTime(makeFilenameAbsolute(outfile, workdir)); + outfile = makeFilenameAbsolute(outfile, workdir); + string cmdfile = outfile ~ ".syntax"; + removeCachedFileTime(outfile); + + if(run) + { + cmd ~= "if errorlevel 1 exit %ERRORLEVEL% /B\n"; + cmd ~= quoteFilename(outfile) ~ "\n"; + cmd ~= "echo Execution result code: %ERRORLEVEL%\n"; + } auto pane = getBuildOutputPane(); scope(exit) release(pane); clearBuildOutputPane(); @@ -620,7 +629,12 @@ version(tip) HRESULT hr = RunCustomBuildBatchFile(outfile, cmdfile, cmd, pane, cfg.getBuilder()); if(run) - Package.GetGlobalOptions().addExecutionPath(cfg.GetProjectDir(), null); + Package.GetGlobalOptions().addExecutionPath(workdir, null); + + if(dbg && hr == S_OK) + { + cfg._DebugLaunch(outfile, dirName(fname), null, Package.GetGlobalOptions().compileAndDbgEngine); + } } return S_OK; } @@ -697,6 +711,7 @@ version(tip) case CmdToggleComment: case CmdConvSelection: case CmdCompileAndRun: + case CmdCompileAndDbg: case CmdCollapseUnittest: case CmdCollapseDisabled: return OLECMDF_SUPPORTED | OLECMDF_ENABLED; @@ -1062,7 +1077,7 @@ version(tip) int HandleSmartIndent(dchar ch) { LANGPREFERENCES langPrefs; - if(int rc = GetUserPreferences(&langPrefs)) + if(int rc = GetUserPreferences(&langPrefs, mView)) return rc; if(langPrefs.IndentStyle != vsIndentStyleSmart) return S_FALSE; @@ -1112,7 +1127,7 @@ version(tip) if(compAct) compAct.OpenCompoundAction("ReindentLines"w.ptr); - int hr = mCodeWinMgr.mSource.ReindentLines(iStartLine, iEndLine); + int hr = mCodeWinMgr.mSource.ReindentLines(mView, iStartLine, iEndLine); if(compAct) { @@ -1145,7 +1160,7 @@ version(tip) if(compAct) compAct.OpenCompoundAction("CommentLines"w.ptr); - hr = mCodeWinMgr.mSource.CommentLines(iStartLine, iEndLine, commentMode); + hr = mCodeWinMgr.mSource.CommentLines(mView, iStartLine, iEndLine, commentMode); if(compAct) { compAct.CloseCompoundAction(); diff --git a/visuald/visuald.visualdproj b/visuald/visuald.visualdproj index feabd212..ee990027 100644 --- a/visuald/visuald.visualdproj +++ b/visuald/visuald.visualdproj @@ -107,7 +107,7 @@ 0 0 0 - 0 + 1 1 0 0 @@ -170,7 +170,7 @@ 0 - 0 + 1 m:\s\d\cv2pdb\trunk\bin\debug\cv2pdb.exe 0 0 @@ -493,6 +493,7 @@ + @@ -516,7 +517,7 @@ -