/src/AddIns/DisplayBindings/AvalonEdit.AddIn/Src/Options/HighlightingOptions.xaml.cs

http://github.com/icsharpcode/SharpDevelop · C# · 891 lines · 799 code · 62 blank · 30 comment · 138 complexity · 7dd6bb80bd8e9a1901105e8ff2db3380 MD5 · raw file

  1. // Copyright (c) 2014 AlphaSierraPapa for the SharpDevelop Team
  2. //
  3. // Permission is hereby granted, free of charge, to any person obtaining a copy of this
  4. // software and associated documentation files (the "Software"), to deal in the Software
  5. // without restriction, including without limitation the rights to use, copy, modify, merge,
  6. // publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons
  7. // to whom the Software is furnished to do so, subject to the following conditions:
  8. //
  9. // The above copyright notice and this permission notice shall be included in all copies or
  10. // substantial portions of the Software.
  11. //
  12. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
  13. // INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
  14. // PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
  15. // FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
  16. // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
  17. // DEALINGS IN THE SOFTWARE.
  18. using System;
  19. using System.Collections.Generic;
  20. using System.Collections.ObjectModel;
  21. using System.ComponentModel.Design;
  22. using System.Globalization;
  23. using System.IO;
  24. using System.Linq;
  25. using System.Windows;
  26. using System.Windows.Controls;
  27. using System.Windows.Media;
  28. using System.Xml;
  29. using System.Xml.Linq;
  30. using ICSharpCode.AvalonEdit.Editing;
  31. using ICSharpCode.AvalonEdit.Folding;
  32. using ICSharpCode.AvalonEdit.Highlighting;
  33. using ICSharpCode.AvalonEdit.Highlighting.Xshd;
  34. using ICSharpCode.AvalonEdit.Rendering;
  35. using ICSharpCode.Core;
  36. using ICSharpCode.NRefactory.Utils;
  37. using ICSharpCode.SharpDevelop;
  38. using ICSharpCode.SharpDevelop.Debugging;
  39. using ICSharpCode.SharpDevelop.Editor;
  40. using ICSharpCode.SharpDevelop.Editor.Bookmarks;
  41. using ICSharpCode.SharpDevelop.Gui;
  42. using Microsoft.Win32;
  43. namespace ICSharpCode.AvalonEdit.AddIn.Options
  44. {
  45. public partial class HighlightingOptions : OptionPanel
  46. {
  47. public HighlightingOptions()
  48. {
  49. // ensure all definitions from AddIns are registered so that they are available for the example view
  50. AvalonEditDisplayBinding.RegisterAddInHighlightingDefinitions();
  51. InitializeComponent();
  52. textEditor.Document.UndoStack.SizeLimit = 0;
  53. CodeEditorOptions.Instance.BindToTextEditor(textEditor);
  54. textEditor.Options = new TextEditorOptions(CodeEditorOptions.Instance);
  55. bracketHighlighter = new BracketHighlightRenderer(textEditor.TextArea.TextView);
  56. foldingManager = FoldingManager.Install(textEditor.TextArea);
  57. textMarkerService = new TextMarkerService(textEditor.Document);
  58. textEditor.TextArea.TextView.BackgroundRenderers.Add(textMarkerService);
  59. textEditor.TextArea.TextView.LineTransformers.Add(textMarkerService);
  60. textEditor.Document.GetRequiredService<IServiceContainer>().AddService(typeof(ITextMarkerService), textMarkerService);
  61. }
  62. BracketHighlightRenderer bracketHighlighter;
  63. FoldingManager foldingManager;
  64. TextMarkerService textMarkerService;
  65. List<CustomizedHighlightingColor> customizationList;
  66. public const string FoldingControls = "Folding controls";
  67. public const string FoldingSelectedControls = "Selected folding controls";
  68. public const string FoldingTextMarkers = "Folding markers";
  69. static SolidColorBrush CreateFrozenBrush(Color color)
  70. {
  71. SolidColorBrush brush = new SolidColorBrush(color);
  72. brush.Freeze();
  73. return brush;
  74. }
  75. public static void ApplyToRendering(TextEditor editor, IEnumerable<CustomizedHighlightingColor> customisations)
  76. {
  77. bool assignedFoldingMarker = false, assignedSelectedFoldingControls = false, assignedFoldingTextMarkers = false;
  78. editor.ClearValue(FoldingMargin.FoldingMarkerBrushProperty);
  79. editor.ClearValue(FoldingMargin.FoldingMarkerBackgroundBrushProperty);
  80. editor.ClearValue(FoldingMargin.SelectedFoldingMarkerBrushProperty);
  81. editor.ClearValue(FoldingMargin.SelectedFoldingMarkerBackgroundBrushProperty);
  82. FoldingElementGenerator.TextBrush = FoldingElementGenerator.DefaultTextBrush;
  83. bool assignedErrorColor = false;
  84. bool assignedWarningColor = false;
  85. bool assignedMessageColor = false;
  86. foreach (var instance in ErrorPainter.Instances) {
  87. instance.ErrorColor = Colors.Red;
  88. instance.WarningColor = Colors.Orange;
  89. instance.MessageColor = Colors.Blue;
  90. }
  91. foreach (CustomizedHighlightingColor color in customisations) {
  92. switch (color.Name) {
  93. case FoldingControls:
  94. if (assignedFoldingMarker)
  95. continue;
  96. assignedFoldingMarker = true;
  97. if (color.Foreground != null)
  98. editor.SetValue(FoldingMargin.FoldingMarkerBrushProperty,
  99. CreateFrozenBrush(color.Foreground.Value));
  100. if (color.Background != null)
  101. editor.SetValue(FoldingMargin.FoldingMarkerBackgroundBrushProperty,
  102. CreateFrozenBrush(color.Background.Value));
  103. break;
  104. case FoldingSelectedControls:
  105. if (assignedSelectedFoldingControls)
  106. continue;
  107. assignedSelectedFoldingControls = true;
  108. if (color.Foreground != null)
  109. editor.SetValue(FoldingMargin.SelectedFoldingMarkerBrushProperty,
  110. CreateFrozenBrush(color.Foreground.Value));
  111. if (color.Background != null)
  112. editor.SetValue(FoldingMargin.SelectedFoldingMarkerBackgroundBrushProperty,
  113. CreateFrozenBrush(color.Background.Value));
  114. break;
  115. case FoldingTextMarkers:
  116. if (assignedFoldingTextMarkers)
  117. continue;
  118. assignedFoldingTextMarkers = true;
  119. if (color.Foreground != null)
  120. FoldingElementGenerator.TextBrush = CreateFrozenBrush(color.Foreground.Value);
  121. break;
  122. case ErrorPainter.ErrorColorName:
  123. if (assignedErrorColor)
  124. continue;
  125. assignedErrorColor = true;
  126. if (color.Foreground != null) {
  127. foreach (var instance in ErrorPainter.Instances) {
  128. instance.ErrorColor = color.Foreground.Value;
  129. }
  130. }
  131. break;
  132. case ErrorPainter.WarningColorName:
  133. if (assignedWarningColor)
  134. continue;
  135. assignedWarningColor = true;
  136. if (color.Foreground != null) {
  137. foreach (var instance in ErrorPainter.Instances) {
  138. instance.WarningColor = color.Foreground.Value;
  139. }
  140. }
  141. break;
  142. case ErrorPainter.MessageColorName:
  143. if (assignedMessageColor)
  144. continue;
  145. assignedMessageColor = true;
  146. if (color.Foreground != null) {
  147. foreach (var instance in ErrorPainter.Instances) {
  148. instance.MessageColor = color.Foreground.Value;
  149. }
  150. }
  151. break;
  152. }
  153. }
  154. }
  155. XshdSyntaxDefinition LoadBuiltinXshd(string name)
  156. {
  157. using (Stream s = typeof(HighlightingManager).Assembly.GetManifestResourceStream(name)) {
  158. using (XmlTextReader reader = new XmlTextReader(s)) {
  159. return HighlightingLoader.LoadXshd(reader);
  160. }
  161. }
  162. }
  163. List<XshdSyntaxDefinition> allSyntaxDefinitions;
  164. public override void LoadOptions()
  165. {
  166. base.LoadOptions();
  167. if (allSyntaxDefinitions == null) {
  168. var builtins = from name in typeof(HighlightingManager).Assembly.GetManifestResourceNames().AsParallel()
  169. where name.StartsWith(typeof(HighlightingManager).Namespace + ".Resources.", StringComparison.OrdinalIgnoreCase)
  170. && name.EndsWith(".xshd", StringComparison.OrdinalIgnoreCase)
  171. select LoadBuiltinXshd(name);
  172. var extended = ICSharpCode.Core.AddInTree.BuildItems<AddInTreeSyntaxMode>(SyntaxModeDoozer.Path, null, false)
  173. .AsParallel()
  174. .Select(m => m.LoadXshd());
  175. allSyntaxDefinitions = extended.AsEnumerable().Concat(builtins)
  176. .DistinctBy(def => def.Name)
  177. .OrderBy(def => def.Name)
  178. .ToList();
  179. }
  180. customizationList = new List<CustomizedHighlightingColor>(CustomizedHighlightingColor.LoadColors());
  181. CreateDefaultEntries(null, out defaultText, defaultEntries);
  182. languageComboBox.Items.Clear();
  183. languageComboBox.Items.Add(new XshdSyntaxDefinition { Name = "All languages" });
  184. foreach (XshdSyntaxDefinition def in allSyntaxDefinitions.Where(d => !d.Name.Equals("XmlDoc", StringComparison.OrdinalIgnoreCase)))
  185. languageComboBox.Items.Add(def);
  186. if (allSyntaxDefinitions.Count > 0)
  187. languageComboBox.SelectedIndex = 0;
  188. }
  189. void LanguageComboBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
  190. {
  191. listBox.ItemsSource = null;
  192. XshdSyntaxDefinition xshd = (XshdSyntaxDefinition)languageComboBox.SelectedItem;
  193. if (xshd != null) {
  194. IHighlightingItem defaultText;
  195. ObservableCollection<IHighlightingItem> list = new ObservableCollection<IHighlightingItem>();
  196. CreateDefaultEntries(languageComboBox.SelectedIndex == 0 ? null : xshd.Name, out defaultText, list);
  197. listBox.ItemsSource = list;
  198. if (languageComboBox.SelectedIndex > 0) {
  199. // Create entries for all customizable colors in the syntax highlighting definition
  200. // (but don't do this for the "All languages" pseudo-entry)
  201. IHighlightingDefinition def = HighlightingManager.Instance.GetDefinition(xshd.Name);
  202. if (def == null) {
  203. throw new InvalidOperationException("Expected that all XSHDs are registered in default highlighting manager; but highlighting definition was not found");
  204. } else {
  205. var visitor = new ColorVisitor(allSyntaxDefinitions);
  206. xshd.AcceptElements(visitor);
  207. foreach (XshdColor namedColor in visitor.foundColors) {
  208. if (namedColor.ExampleText != null) {
  209. IHighlightingItem item = new NamedColorHighlightingItem(defaultText, namedColor) { ParentDefinition = def };
  210. item = new CustomizedHighlightingItem(customizationList, item, xshd.Name);
  211. list.Add(item);
  212. item.PropertyChanged += item_PropertyChanged;
  213. }
  214. }
  215. }
  216. }
  217. if (listBox.Items.Count > 0)
  218. listBox.SelectedIndex = 0;
  219. }
  220. }
  221. class ColorVisitor : IXshdVisitor
  222. {
  223. internal readonly List<XshdColor> foundColors = new List<XshdColor>();
  224. readonly HashSet<XshdSyntaxDefinition> visitedDefinitons = new HashSet<XshdSyntaxDefinition>();
  225. IList<XshdSyntaxDefinition> allSyntaxDefinitions;
  226. public ColorVisitor(IList<XshdSyntaxDefinition> allSyntaxDefinitions)
  227. {
  228. this.allSyntaxDefinitions = allSyntaxDefinitions;
  229. }
  230. public object VisitRuleSet(XshdRuleSet ruleSet)
  231. {
  232. ruleSet.AcceptElements(this);
  233. return null;
  234. }
  235. public object VisitColor(XshdColor color)
  236. {
  237. foundColors.Add(color);
  238. return null;
  239. }
  240. public object VisitKeywords(XshdKeywords keywords)
  241. {
  242. return keywords.ColorReference.AcceptVisitor(this);
  243. }
  244. public object VisitSpan(XshdSpan span)
  245. {
  246. if (span.RuleSetReference.InlineElement != null)
  247. return span.RuleSetReference.AcceptVisitor(this);
  248. XshdSyntaxDefinition definition = allSyntaxDefinitions.SingleOrDefault(def => def.Name == span.RuleSetReference.ReferencedDefinition);
  249. if (definition != null && visitedDefinitons.Add(definition))
  250. foundColors.AddRange(definition.Elements.OfType<XshdColor>());
  251. return null;
  252. }
  253. public object VisitImport(XshdImport import)
  254. {
  255. if (import.RuleSetReference.InlineElement != null)
  256. return import.RuleSetReference.AcceptVisitor(this);
  257. XshdSyntaxDefinition definition = allSyntaxDefinitions.SingleOrDefault(def => def.Name == import.RuleSetReference.ReferencedDefinition);
  258. if (definition != null && visitedDefinitons.Add(definition))
  259. foundColors.AddRange(definition.Elements.OfType<XshdColor>());
  260. return null;
  261. }
  262. public object VisitRule(XshdRule rule)
  263. {
  264. return rule.ColorReference.AcceptVisitor(this);
  265. }
  266. }
  267. void CreateDefaultEntries(string language, out IHighlightingItem defaultText, IList<IHighlightingItem> items)
  268. {
  269. // Create entry for "default text/background"
  270. defaultText = new SimpleHighlightingItem(CustomizingHighlighter.DefaultTextAndBackground, ta => ta.Document.Text = "Normal text") {
  271. Foreground = SystemColors.WindowTextColor,
  272. Background = SystemColors.WindowColor
  273. };
  274. defaultText = new CustomizedHighlightingItem(customizationList, defaultText, language, canSetFont: false);
  275. defaultText.PropertyChanged += item_PropertyChanged;
  276. items.Add(defaultText);
  277. // Create entry for "Selected text"
  278. IHighlightingItem selectedText = new SimpleHighlightingItem(
  279. CustomizingHighlighter.SelectedText,
  280. ta => {
  281. ta.Document.Text = "Selected text";
  282. ta.Selection = Selection.Create(ta, 0, 13);
  283. })
  284. {
  285. Foreground = SystemColors.HighlightTextColor,
  286. Background = SystemColors.HighlightColor
  287. };
  288. selectedText = new CustomizedHighlightingItem(customizationList, selectedText, language, canSetFont: false);
  289. selectedText.PropertyChanged += item_PropertyChanged;
  290. items.Add(selectedText);
  291. // Create entry for "Non-printable characters"
  292. IHighlightingItem nonPrintChars = new SimpleHighlightingItem(
  293. CustomizingHighlighter.NonPrintableCharacters,
  294. ta => {
  295. ta.Document.Text = " \r \r\n \n";
  296. })
  297. {
  298. Foreground = Colors.LightGray
  299. };
  300. nonPrintChars = new CustomizedHighlightingItem(customizationList, nonPrintChars, language, canSetFont: false, canSetBackground: false);
  301. nonPrintChars.PropertyChanged += item_PropertyChanged;
  302. items.Add(nonPrintChars);
  303. // Create entry for "Line numbers"
  304. IHighlightingItem lineNumbers = new SimpleHighlightingItem(
  305. CustomizingHighlighter.LineNumbers,
  306. ta => {
  307. ta.Document.Text = "These are just" + Environment.NewLine +
  308. "multiple" + Environment.NewLine +
  309. "lines of" + Environment.NewLine +
  310. "text";
  311. })
  312. {
  313. Foreground = Colors.Gray
  314. };
  315. lineNumbers = new CustomizedHighlightingItem(customizationList, lineNumbers, language, canSetFont: false, canSetBackground: false);
  316. lineNumbers.PropertyChanged += item_PropertyChanged;
  317. items.Add(lineNumbers);
  318. // Create entry for "Bracket highlight"
  319. IHighlightingItem bracketHighlight = new SimpleHighlightingItem(
  320. BracketHighlightRenderer.BracketHighlight,
  321. ta => {
  322. ta.Document.Text = "(simple) example";
  323. XshdSyntaxDefinition xshd = (XshdSyntaxDefinition)languageComboBox.SelectedItem;
  324. if (xshd == null)
  325. return;
  326. var customizationsForCurrentLanguage = customizationList.Where(c => c.Language == null || c.Language == xshd.Name);
  327. BracketHighlightRenderer.ApplyCustomizationsToRendering(bracketHighlighter, customizationsForCurrentLanguage);
  328. bracketHighlighter.SetHighlight(new BracketSearchResult(0, 1, 7, 1));
  329. })
  330. {
  331. Foreground = BracketHighlightRenderer.DefaultBorder,
  332. Background = BracketHighlightRenderer.DefaultBackground
  333. };
  334. bracketHighlight = new CustomizedHighlightingItem(customizationList, bracketHighlight, language, canSetFont: false);
  335. bracketHighlight.PropertyChanged += item_PropertyChanged;
  336. items.Add(bracketHighlight);
  337. // Create entry for "Current Line highlight"
  338. IHighlightingItem currentLineHighlight = new SimpleHighlightingItem(
  339. CustomizingHighlighter.CurrentLineHighlighter,
  340. ta => {
  341. ta.Document.Text = "example text line";
  342. ta.TextView.Options.HighlightCurrentLine = true;
  343. })
  344. {
  345. Foreground = Color.FromArgb(52, 0, 255, 110),
  346. Background = Color.FromArgb(22, 20, 220, 224)
  347. };
  348. currentLineHighlight = new CustomizedHighlightingItem(customizationList, currentLineHighlight, language, canSetFont: false);
  349. currentLineHighlight.PropertyChanged += item_PropertyChanged;
  350. items.Add(currentLineHighlight);
  351. // Create entry for "Folding controls"
  352. IHighlightingItem foldingControls = new SimpleHighlightingItem(
  353. FoldingControls,
  354. ta => {
  355. ta.Document.Text = "This" + Environment.NewLine +
  356. "is a folding" + Environment.NewLine +
  357. "example";
  358. foldingManager.CreateFolding(0, 10);
  359. })
  360. {
  361. Foreground = Colors.Gray,
  362. Background = Colors.White
  363. };
  364. foldingControls = new CustomizedHighlightingItem(customizationList, foldingControls, language, canSetFont: false);
  365. foldingControls.PropertyChanged += item_PropertyChanged;
  366. items.Add(foldingControls);
  367. // Create entry for "Selected folding controls"
  368. IHighlightingItem selectedFoldingControls = new SimpleHighlightingItem(
  369. FoldingSelectedControls,
  370. ta => {
  371. ta.Document.Text = "This" + Environment.NewLine +
  372. "is a folding" + Environment.NewLine +
  373. "example";
  374. foldingManager.CreateFolding(0, 10);
  375. })
  376. {
  377. Foreground = Colors.Black,
  378. Background = Colors.White
  379. };
  380. selectedFoldingControls = new CustomizedHighlightingItem(customizationList, selectedFoldingControls, language, canSetFont: false);
  381. selectedFoldingControls.PropertyChanged += item_PropertyChanged;
  382. items.Add(selectedFoldingControls);
  383. // Create entry for "Folding text markers"
  384. IHighlightingItem foldingTextMarker = new SimpleHighlightingItem(
  385. FoldingTextMarkers,
  386. ta => {
  387. ta.Document.Text = "This" + Environment.NewLine +
  388. "is a folding" + Environment.NewLine +
  389. "example";
  390. foldingManager.CreateFolding(0, 10).IsFolded = true;
  391. })
  392. {
  393. Foreground = Colors.Gray
  394. };
  395. foldingTextMarker = new CustomizedHighlightingItem(customizationList, foldingTextMarker, language, canSetFont: false, canSetBackground: false);
  396. foldingTextMarker.PropertyChanged += item_PropertyChanged;
  397. items.Add(foldingTextMarker);
  398. IHighlightingItem linkText = new SimpleHighlightingItem(
  399. CustomizingHighlighter.LinkText,
  400. ta => {
  401. ta.Document.Text = "http://icsharpcode.net" + Environment.NewLine + "me@example.com";
  402. })
  403. {
  404. Foreground = Colors.Blue,
  405. Background = Colors.Transparent
  406. };
  407. linkText = new CustomizedHighlightingItem(customizationList, linkText, language, canSetFont: false);
  408. linkText.PropertyChanged += item_PropertyChanged;
  409. items.Add(linkText);
  410. IHighlightingItem errorMarker = new SimpleHighlightingItem(
  411. ErrorPainter.ErrorColorName,
  412. ta => {
  413. ta.Document.Text = "some error";
  414. ITextMarker marker = textMarkerService.Create(0, 5);
  415. marker.Tag = (Action<IHighlightingItem, ITextMarker>)delegate(IHighlightingItem item, ITextMarker m) {
  416. m.MarkerTypes = TextMarkerTypes.SquigglyUnderline;
  417. m.MarkerColor = item.Foreground;
  418. };
  419. })
  420. {
  421. Foreground = Colors.Red
  422. };
  423. errorMarker = new CustomizedHighlightingItem(customizationList, errorMarker, language, canSetFont: false, canSetBackground: false);
  424. errorMarker.PropertyChanged += item_PropertyChanged;
  425. items.Add(errorMarker);
  426. IHighlightingItem warningMarker = new SimpleHighlightingItem(
  427. ErrorPainter.WarningColorName,
  428. ta => {
  429. ta.Document.Text = "some warning";
  430. ITextMarker marker = textMarkerService.Create(0, 5);
  431. marker.Tag = (Action<IHighlightingItem, ITextMarker>)delegate(IHighlightingItem item, ITextMarker m) {
  432. m.MarkerTypes = TextMarkerTypes.SquigglyUnderline;
  433. m.MarkerColor = item.Foreground;
  434. };
  435. })
  436. {
  437. Foreground = Colors.Orange
  438. };
  439. warningMarker = new CustomizedHighlightingItem(customizationList, warningMarker, language, canSetFont: false, canSetBackground: false);
  440. warningMarker.PropertyChanged += item_PropertyChanged;
  441. items.Add(warningMarker);
  442. IHighlightingItem messageMarker = new SimpleHighlightingItem(
  443. ErrorPainter.MessageColorName,
  444. ta => {
  445. ta.Document.Text = "some message";
  446. ITextMarker marker = textMarkerService.Create(0, 5);
  447. marker.Tag = (Action<IHighlightingItem, ITextMarker>)delegate(IHighlightingItem item, ITextMarker m) {
  448. m.MarkerTypes = TextMarkerTypes.SquigglyUnderline;
  449. m.MarkerColor = item.Foreground;
  450. };
  451. })
  452. {
  453. Foreground = Colors.Blue
  454. };
  455. messageMarker = new CustomizedHighlightingItem(customizationList, messageMarker, language, canSetFont: false, canSetBackground: false);
  456. messageMarker.PropertyChanged += item_PropertyChanged;
  457. items.Add(messageMarker);
  458. IHighlightingItem breakpointMarker = new SimpleHighlightingItem(
  459. BookmarkBase.BreakpointMarkerName,
  460. ta => {
  461. ta.Document.Text = "some code with a breakpoint";
  462. ITextMarker marker = textMarkerService.Create(0, ta.Document.TextLength);
  463. marker.Tag = (Action<IHighlightingItem, ITextMarker>)delegate(IHighlightingItem item, ITextMarker m) {
  464. m.BackgroundColor = item.Background;
  465. m.ForegroundColor = item.Foreground;
  466. };
  467. })
  468. {
  469. Background = BookmarkBase.BreakpointDefaultBackground,
  470. Foreground = BookmarkBase.BreakpointDefaultForeground
  471. };
  472. breakpointMarker = new CustomizedHighlightingItem(customizationList, breakpointMarker, language, canSetFont: false);
  473. breakpointMarker.PropertyChanged += item_PropertyChanged;
  474. items.Add(breakpointMarker);
  475. IHighlightingItem currentStatementMarker = new SimpleHighlightingItem(
  476. BookmarkBase.CurrentLineBookmarkName,
  477. ta => {
  478. ta.Document.Text = "current statement line";
  479. ITextMarker marker = textMarkerService.Create(0, ta.Document.TextLength);
  480. marker.Tag = (Action<IHighlightingItem, ITextMarker>)delegate(IHighlightingItem item, ITextMarker m) {
  481. m.BackgroundColor = item.Background;
  482. m.ForegroundColor = item.Foreground;
  483. };
  484. })
  485. {
  486. Background = BookmarkBase.CurrentLineDefaultBackground,
  487. Foreground = BookmarkBase.CurrentLineDefaultForeground
  488. };
  489. currentStatementMarker = new CustomizedHighlightingItem(customizationList, currentStatementMarker, language, canSetFont: false);
  490. currentStatementMarker.PropertyChanged += item_PropertyChanged;
  491. items.Add(currentStatementMarker);
  492. IHighlightingItem columnRuler = new SimpleHighlightingItem(
  493. CustomizingHighlighter.ColumnRuler,
  494. ta => {
  495. ta.Document.Text = "some line with a lot of text";
  496. ta.TextView.Options.ColumnRulerPosition = 15;
  497. ta.TextView.Options.ShowColumnRuler = true;
  498. })
  499. {
  500. Foreground = Colors.LightGray
  501. };
  502. columnRuler = new CustomizedHighlightingItem(customizationList, columnRuler, language, canSetFont: false, canSetBackground: false);
  503. columnRuler.PropertyChanged += item_PropertyChanged;
  504. items.Add(columnRuler);
  505. }
  506. void item_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
  507. {
  508. UpdatePreview();
  509. }
  510. public override bool SaveOptions()
  511. {
  512. CustomizedHighlightingColor.SaveColors(customizationList);
  513. return base.SaveOptions();
  514. }
  515. void ResetButtonClick(object sender, RoutedEventArgs e)
  516. {
  517. IHighlightingItem item = resetButton.DataContext as IHighlightingItem;
  518. if (item != null)
  519. item.Reset();
  520. }
  521. void ListBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
  522. {
  523. UpdatePreview();
  524. }
  525. HighlightingColorizer colorizer;
  526. void UpdatePreview()
  527. {
  528. XshdSyntaxDefinition xshd = (XshdSyntaxDefinition)languageComboBox.SelectedItem;
  529. if (xshd != null) {
  530. var customizationsForCurrentLanguage = customizationList.Where(c => c.Language == null || c.Language == xshd.Name);
  531. CustomizingHighlighter.ApplyCustomizationsToDefaultElements(textEditor, customizationsForCurrentLanguage);
  532. ApplyToRendering(textEditor, customizationsForCurrentLanguage);
  533. var item = (IHighlightingItem)listBox.SelectedItem;
  534. TextView textView = textEditor.TextArea.TextView;
  535. foldingManager.Clear();
  536. textMarkerService.RemoveAll(m => true);
  537. textView.LineTransformers.Remove(colorizer);
  538. colorizer = null;
  539. if (item != null) {
  540. if (item.ParentDefinition != null) {
  541. var highlighter = new CustomizingHighlighter(
  542. new DocumentHighlighter(textView.Document, item.ParentDefinition),
  543. customizationsForCurrentLanguage
  544. );
  545. colorizer = new HighlightingColorizer(highlighter);
  546. textView.LineTransformers.Add(colorizer);
  547. }
  548. textEditor.Select(0, 0);
  549. bracketHighlighter.SetHighlight(null);
  550. textEditor.Options.HighlightCurrentLine = false;
  551. item.ShowExample(textEditor.TextArea);
  552. ITextMarker m = textMarkerService.TextMarkers.SingleOrDefault();
  553. if (m != null && m.Tag != null) {
  554. ((Action<IHighlightingItem, ITextMarker>)m.Tag)(item, m);
  555. }
  556. }
  557. }
  558. }
  559. void ImportButtonClick(object sender, RoutedEventArgs e)
  560. {
  561. OpenFileDialog dialog = new OpenFileDialog {
  562. Filter = @"All known settings|*.vssettings;*.sdsettings|Visual Studio settings (*.vssettings)|*.vssettings|SharpDevelop settings (*.sdsettings)|*.sdsettings",
  563. CheckFileExists = true
  564. };
  565. if (dialog.ShowDialog() != true)
  566. return;
  567. switch (Path.GetExtension(dialog.FileName).ToUpperInvariant()) {
  568. case ".VSSETTINGS":
  569. LoadVSSettings(XDocument.Load(dialog.FileName));
  570. break;
  571. case ".SDSETTINGS":
  572. LoadSDSettings(XDocument.Load(dialog.FileName));
  573. break;
  574. }
  575. }
  576. #region VSSettings
  577. void LoadVSSettings(XDocument document)
  578. {
  579. XElement[] items;
  580. if (!CheckVersionAndFindCategory(document, out items) || items == null) {
  581. Core.MessageService.ShowError("${res:Dialog.HighlightingEditor.NotSupportedMessage}");
  582. return;
  583. }
  584. if (!MessageService.AskQuestion("${res:Dialog.HighlightingEditor.OverwriteCustomizationsMessage}"))
  585. return;
  586. ResetAllButtonClick(null, null);
  587. foreach (var item in items) {
  588. string key = item.Attribute("Name").Value;
  589. var entry = ParseEntry(item);
  590. foreach (var sdKey in mapping[key]) {
  591. IHighlightingItem color;
  592. if (FindSDColor(sdKey, out color)) {
  593. color.Bold = entry.Item3;
  594. color.UseDefaultForeground = !entry.Item1.HasValue;
  595. if (entry.Item1 != null)
  596. color.Foreground = entry.Item1.Value;
  597. color.UseDefaultBackground = !entry.Item2.HasValue;
  598. if (entry.Item2 != null)
  599. color.Background = entry.Item2.Value;
  600. }
  601. }
  602. }
  603. }
  604. readonly List<IHighlightingItem> defaultEntries = new List<IHighlightingItem>();
  605. IHighlightingItem defaultText;
  606. bool FindSDColor(string sdKey, out IHighlightingItem item)
  607. {
  608. string language = null;
  609. int dot = sdKey.IndexOf('.');
  610. if (dot > 0) {
  611. language = sdKey.Substring(0, dot);
  612. sdKey = sdKey.Substring(dot + 1);
  613. }
  614. if ((language == null && languageComboBox.SelectedIndex == 0)
  615. || (language == ((XshdSyntaxDefinition)languageComboBox.SelectedItem).Name)) {
  616. item = listBox.Items.OfType<IHighlightingItem>().FirstOrDefault(i => i.Name == sdKey);
  617. } else if (language == null) {
  618. item = defaultEntries.FirstOrDefault(i => i.Name == sdKey);
  619. } else {
  620. var def = allSyntaxDefinitions.FirstOrDefault(d => d.Name == language);
  621. var highlighting = HighlightingManager.Instance.GetDefinition(language);
  622. item = null;
  623. if (def != null && highlighting != null) {
  624. var visitor = new ColorVisitor(allSyntaxDefinitions);
  625. def.AcceptElements(visitor);
  626. var color = visitor.foundColors.FirstOrDefault(i => i.Name == sdKey);
  627. if (color != null) {
  628. item = new NamedColorHighlightingItem(defaultText, color) { ParentDefinition = highlighting };
  629. item = new CustomizedHighlightingItem(customizationList, item, language);
  630. }
  631. }
  632. }
  633. return item != null;
  634. }
  635. // VS => SD
  636. static readonly MultiDictionary<string, string> mapping = new MultiDictionary<string, string>(StringComparer.Ordinal) {
  637. { "Brace Matching (Rectangle)", BracketHighlightRenderer.BracketHighlight },
  638. { "Collapsible Text", FoldingTextMarkers },
  639. { "Comment", "VB.Comment" },
  640. { "Comment", "C#.Comment" },
  641. { "Compiler Error", ErrorPainter.ErrorColorName },
  642. { "CSS Comment", "CSS.Comment" },
  643. { "CSS Keyword", "" },
  644. { "CSS Property Name", "CSS.Property" },
  645. { "CSS Property Value", "CSS.Value" },
  646. { "CSS Selector", "CSS.Selector" },
  647. { "CSS String Value", "CSS.String" },
  648. { "Excluded Code", "" },
  649. { "HTML Attribute Value", "" },
  650. { "HTML Attribute", "" },
  651. { "HTML Comment", "" },
  652. { "HTML Element Name", "" },
  653. { "HTML Entity", "" },
  654. { "HTML Operator", "" },
  655. { "HTML Server-Side Script", "" },
  656. { "HTML Tag Delimiter", "" },
  657. { "Identifier", "C#.MethodCall" },
  658. { "Inactive Selected Text", "" },
  659. { "Indicator Margin", "" },
  660. { "Keyword", "C#.ThisOrBaseReference" },
  661. { "Keyword", "C#.NullOrValueKeywords" },
  662. { "Keyword", "C#.Keywords" },
  663. { "Keyword", "C#.GotoKeywords" },
  664. { "Keyword", "C#.ContextKeywords" },
  665. { "Keyword", "C#.ExceptionKeywords" },
  666. { "Keyword", "C#.CheckedKeyword" },
  667. { "Keyword", "C#.UnsafeKeywords" },
  668. { "Keyword", "C#.OperatorKeywords" },
  669. { "Keyword", "C#.ParameterModifiers" },
  670. { "Keyword", "C#.Modifiers" },
  671. { "Keyword", "C#.Visibility" },
  672. { "Keyword", "C#.NamespaceKeywords" },
  673. { "Keyword", "C#.GetSetAddRemove" },
  674. { "Keyword", "C#.TrueFalse" },
  675. { "Keyword", "C#.TypeKeywords" },
  676. { "Keyword", "C#.ValueTypes" },
  677. { "Keyword", "C#.ReferenceTypes" },
  678. { "Keyword", "VB.DateLiteral" },
  679. { "Keyword", "VB.Preprocessor" },
  680. { "Keyword", "VB.DataTypes" },
  681. { "Keyword", "VB.Operators" },
  682. { "Keyword", "VB.Constants" },
  683. { "Keyword", "VB.Keywords" },
  684. { "Keyword", "VB.FunctionKeywords" },
  685. { "Keyword", "VB.ContextKeywords" },
  686. { "Line Numbers", CustomizingHighlighter.LineNumbers },
  687. { "MarkerFormatDefinition/HighlightedReference", "" },
  688. { "Number", "C#.NumberLiteral" },
  689. { "Operator", "C#.Punctuation" },
  690. { "outlining.collapsehintadornment", "" },
  691. { "outlining.square", FoldingControls },
  692. { "outlining.square", FoldingSelectedControls },
  693. { "outlining.verticalrule", "" },
  694. { "Plain Text", "" },
  695. { "Plain Text", CustomizingHighlighter.DefaultTextAndBackground },
  696. { "Preprocessor Keyword", "" },
  697. { "Preprocessor Keyword", "C#.Preprocessor" },
  698. { "Razor Code", "" },
  699. { "Script Comment", "" },
  700. { "Script Identifier", "" },
  701. { "Script Keyword", "" },
  702. { "Script Number", "" },
  703. { "Script Operator", "" },
  704. { "Script String", "" },
  705. { "Selected Text", "" },
  706. { "Selected Text", CustomizingHighlighter.SelectedText },
  707. { "String", "VB.String" },
  708. { "String", "C#.String" },
  709. { "String(C# @ Verbatim)", "" },
  710. { "Syntax Error", "" },
  711. { "urlformat", CustomizingHighlighter.LinkText },
  712. { "User Types", "" },
  713. { "User Types(Delegates)", "" },
  714. { "User Types(Enums)", "" },
  715. { "User Types(Interfaces)", "" },
  716. { "User Types(Value types)", "" },
  717. { "Warning", ErrorPainter.WarningColorName },
  718. { "XAML Attribute Quotes", "" },
  719. { "XAML Attribute Value", "" },
  720. { "XAML Attribute", "" },
  721. { "XAML CData Section", "" },
  722. { "XAML Comment", "" },
  723. { "XAML Delimiter", "" },
  724. { "XAML Markup Extension Class", "" },
  725. { "XAML Markup Extension Parameter Name", "" },
  726. { "XAML Markup Extension Parameter Value", "" },
  727. { "XAML Name", "" },
  728. { "XAML Text", "" },
  729. { "XML Attribute Quotes", "" },
  730. { "XML Attribute Value", "XML.AttributeValue" },
  731. { "XML Attribute", "XML.AttributeName" },
  732. { "XML CData Section", "XML.CData" },
  733. { "XML Comment", "XML.Comment" },
  734. { "XML Delimiter", "" },
  735. { "XML Doc Comment", "C#.DocComment" },
  736. { "XML Doc Tag", "C#.KnownDocTags" },
  737. { "XML Doc Comment", "VB.DocComment" },
  738. { "XML Doc Tag", "VB.KnownDocTags" },
  739. { "XML Name", "XML.XmlTag" },
  740. { "XML Name", "XML.XmlDeclaration" },
  741. { "XML Name", "XML.DocType" },
  742. { "XML Text", "XML." + CustomizingHighlighter.DefaultTextAndBackground },
  743. };
  744. Tuple<Color?, Color?, bool> ParseEntry(XElement element)
  745. {
  746. Color? fore = null;
  747. Color? back = null;
  748. bool isBold = false;
  749. var attribute = element.Attribute("Foreground");
  750. if (attribute != null)
  751. fore = ParseColor(attribute.Value);
  752. attribute = element.Attribute("Background");
  753. if (attribute != null)
  754. back = ParseColor(attribute.Value);
  755. attribute = element.Attribute("BoldFont");
  756. if (attribute != null)
  757. isBold = attribute.Value == "Yes";
  758. return Tuple.Create(fore, back, isBold);
  759. }
  760. Color? ParseColor(string s)
  761. {
  762. if (string.IsNullOrWhiteSpace(s))
  763. return null;
  764. if (s.StartsWith("0x", StringComparison.OrdinalIgnoreCase))
  765. s = s.Substring(2);
  766. if (s.Length < 8)
  767. return null;
  768. if (string.CompareOrdinal(s.Substring(0, 2), "02") == 0)
  769. return null;
  770. byte r, g, b;
  771. if (!byte.TryParse(s.Substring(2, 2), NumberStyles.HexNumber, CultureInfo.InvariantCulture, out b))
  772. return Colors.Transparent;
  773. if (!byte.TryParse(s.Substring(4, 2), NumberStyles.HexNumber, CultureInfo.InvariantCulture, out g))
  774. return Colors.Transparent;
  775. if (!byte.TryParse(s.Substring(6, 2), NumberStyles.HexNumber, CultureInfo.InvariantCulture, out r))
  776. return Colors.Transparent;
  777. return Color.FromRgb(r, g, b);
  778. }
  779. bool CheckVersionAndFindCategory(XDocument document, out XElement[] categoryItems)
  780. {
  781. categoryItems = null;
  782. var node = document.Root;
  783. var appID = document.Root.Element("ApplicationIdentity");
  784. var category = document.Root.Descendants("Category").FirstOrDefault(e => e.Attribute("GUID") != null && e.Attribute("GUID").Value == "{A27B4E24-A735-4D1D-B8E7-9716E1E3D8E0}");
  785. if (category != null)
  786. categoryItems = category.Descendants("Item").ToArray();
  787. if (node.Name != "UserSettings" || appID == null || category == null)
  788. return false;
  789. return appID.Attribute("version") != null && appID.Attribute("version").Value == "10.0";
  790. }
  791. #endregion
  792. #region SDSettings
  793. void LoadSDSettings(XDocument document)
  794. {
  795. var version = document.Root.Attribute("version");
  796. if (version != null && version.Value != Properties.FileVersion.ToString()) {
  797. Core.MessageService.ShowError("Settings version not supported!");
  798. return;
  799. }
  800. var p = Properties.Load(document.Root);
  801. customizationList = p.GetList<CustomizedHighlightingColor>("CustomizedHighlightingRules").ToList();
  802. LanguageComboBox_SelectionChanged(null, null);
  803. }
  804. #endregion
  805. void ExportButtonClick(object sender, RoutedEventArgs e)
  806. {
  807. SaveFileDialog dialog = new SaveFileDialog {
  808. Filter = @"SharpDevelop settings (*.sdsettings)|*.sdsettings",
  809. };
  810. if (dialog.ShowDialog() != true)
  811. return;
  812. Save(dialog.FileName);
  813. }
  814. void Save(string fileName)
  815. {
  816. Properties p = new Properties();
  817. p.SetList("CustomizedHighlightingRules", customizationList);
  818. XElement root = p.Save();
  819. root.SetAttributeValue("version", Properties.FileVersion.ToString());
  820. new XDocument(root).Save(fileName);
  821. }
  822. void ResetAllButtonClick(object sender, RoutedEventArgs e)
  823. {
  824. customizationList.Clear();
  825. LanguageComboBox_SelectionChanged(null, null);
  826. UpdatePreview();
  827. }
  828. }
  829. }