diff --git a/ICSharpCode.Decompiler/Output/TextTokenWriter.cs b/ICSharpCode.Decompiler/Output/TextTokenWriter.cs
index 0562bcedd..d225feeaa 100644
--- a/ICSharpCode.Decompiler/Output/TextTokenWriter.cs
+++ b/ICSharpCode.Decompiler/Output/TextTokenWriter.cs
@@ -457,7 +457,7 @@ namespace ICSharpCode.Decompiler
{
if (node is EntityDeclaration && !(node.Parent is LocalFunctionDeclarationStatement))
return true;
- if (node is VariableInitializer && node.Parent is FieldDeclaration)
+ if (node is VariableInitializer && node.Parent is FieldDeclaration or EventDeclaration)
{
node = node.Parent;
return true;
diff --git a/ILSpy/ILSpy.csproj b/ILSpy/ILSpy.csproj
index 276a32493..74f845893 100644
--- a/ILSpy/ILSpy.csproj
+++ b/ILSpy/ILSpy.csproj
@@ -64,16 +64,11 @@
license.txt
-
-
-
-
-
diff --git a/ILSpy/Images/DarkMode.png b/ILSpy/Images/DarkMode.png
deleted file mode 100644
index 843dc5363..000000000
Binary files a/ILSpy/Images/DarkMode.png and /dev/null differ
diff --git a/ILSpy/Languages/CSharpHighlightingTokenWriter.cs b/ILSpy/Languages/CSharpHighlightingTokenWriter.cs
index e4ce9eba6..fe229607a 100644
--- a/ILSpy/Languages/CSharpHighlightingTokenWriter.cs
+++ b/ILSpy/Languages/CSharpHighlightingTokenWriter.cs
@@ -23,6 +23,7 @@ using ICSharpCode.AvalonEdit.Highlighting;
using ICSharpCode.Decompiler.CSharp;
using ICSharpCode.Decompiler.CSharp.OutputVisitor;
using ICSharpCode.Decompiler.CSharp.Syntax;
+using ICSharpCode.Decompiler.IL;
using ICSharpCode.Decompiler.TypeSystem;
using ICSharpCode.ILSpyX.Extensions;
@@ -55,9 +56,15 @@ namespace ICSharpCode.ILSpy
HighlightingColor methodCallColor;
HighlightingColor methodDeclarationColor;
-
HighlightingColor fieldDeclarationColor;
HighlightingColor fieldAccessColor;
+ HighlightingColor propertyDeclarationColor;
+ HighlightingColor propertyAccessColor;
+ HighlightingColor eventDeclarationColor;
+ HighlightingColor eventAccessColor;
+
+ HighlightingColor variableColor;
+ HighlightingColor parameterColor;
HighlightingColor valueKeywordColor;
HighlightingColor thisKeywordColor;
@@ -95,12 +102,16 @@ namespace ICSharpCode.ILSpy
this.enumerationTypeColor = highlighting.GetNamedColor("EnumTypes");
this.typeParameterTypeColor = highlighting.GetNamedColor("TypeParameters");
this.delegateTypeColor = highlighting.GetNamedColor("DelegateTypes");
- this.methodDeclarationColor = this.methodCallColor = highlighting.GetNamedColor("MethodCall");
- //this.eventDeclarationColor = this.eventAccessColor = defaultTextColor;
- //this.propertyDeclarationColor = this.propertyAccessColor = defaultTextColor;
- this.fieldDeclarationColor = this.fieldAccessColor = highlighting.GetNamedColor("FieldAccess");
- //this.variableDeclarationColor = this.variableAccessColor = defaultTextColor;
- //this.parameterDeclarationColor = this.parameterAccessColor = defaultTextColor;
+ this.methodDeclarationColor = highlighting.GetNamedColor("MethodDeclaration");
+ this.methodCallColor = highlighting.GetNamedColor("MethodCall");
+ this.fieldDeclarationColor = highlighting.GetNamedColor("FieldDeclaration");
+ this.fieldAccessColor = highlighting.GetNamedColor("FieldAccess");
+ this.propertyDeclarationColor = highlighting.GetNamedColor("PropertyDeclaration");
+ this.propertyAccessColor = highlighting.GetNamedColor("PropertyAccess");
+ this.eventDeclarationColor = highlighting.GetNamedColor("EventDeclaration");
+ this.eventAccessColor = highlighting.GetNamedColor("EventAccess");
+ this.variableColor = highlighting.GetNamedColor("Variable");
+ this.parameterColor = highlighting.GetNamedColor("Parameter");
this.valueKeywordColor = highlighting.GetNamedColor("NullOrValueKeywords");
this.thisKeywordColor = highlighting.GetNamedColor("ThisOrBaseReference");
this.trueKeywordColor = highlighting.GetNamedColor("TrueFalse");
@@ -338,13 +349,25 @@ namespace ICSharpCode.ILSpy
public override void WriteIdentifier(Identifier identifier)
{
HighlightingColor color = null;
- if (identifier.Name == "value"
- && identifier.Parent?.GetResolveResult() is ILVariableResolveResult rr
- && rr.Variable.Kind == Decompiler.IL.VariableKind.Parameter
- && identifier.Ancestors.OfType().FirstOrDefault() is Accessor accessor
- && accessor.Role != PropertyDeclaration.GetterRole)
+ if (identifier.Parent?.GetResolveResult() is ILVariableResolveResult rr)
{
- color = valueKeywordColor;
+ if (rr.Variable.Kind == VariableKind.Parameter)
+ {
+ if (identifier.Name == "value"
+ && identifier.Ancestors.OfType().FirstOrDefault() is { } accessor
+ && accessor.Role != PropertyDeclaration.GetterRole)
+ {
+ color = valueKeywordColor;
+ }
+ else
+ {
+ color = parameterColor;
+ }
+ }
+ else
+ {
+ color = variableColor;
+ }
}
if (identifier.Parent is AstType)
{
@@ -361,60 +384,40 @@ namespace ICSharpCode.ILSpy
switch (GetCurrentDefinition())
{
case ITypeDefinition t:
- switch (t.Kind)
- {
- case TypeKind.Delegate:
- color = delegateTypeColor;
- break;
- case TypeKind.Class:
- color = referenceTypeColor;
- break;
- case TypeKind.Interface:
- color = interfaceTypeColor;
- break;
- case TypeKind.Enum:
- color = enumerationTypeColor;
- break;
- case TypeKind.Struct:
- color = valueTypeColor;
- break;
- }
+ ApplyTypeColor(t, ref color);
break;
- case IMethod m:
+ case IMethod:
color = methodDeclarationColor;
break;
- case IField f:
+ case IField:
color = fieldDeclarationColor;
break;
+ case IProperty:
+ color = propertyDeclarationColor;
+ break;
+ case IEvent:
+ color = eventDeclarationColor;
+ break;
}
switch (GetCurrentMemberReference())
{
case IType t:
- switch (t.Kind)
- {
- case TypeKind.Delegate:
- color = delegateTypeColor;
- break;
- case TypeKind.Class:
- color = referenceTypeColor;
- break;
- case TypeKind.Interface:
- color = interfaceTypeColor;
- break;
- case TypeKind.Enum:
- color = enumerationTypeColor;
- break;
- case TypeKind.Struct:
- color = valueTypeColor;
- break;
- }
+ ApplyTypeColor(t, ref color);
break;
case IMethod m:
color = methodCallColor;
+ if (m.IsConstructor)
+ ApplyTypeColor(m.DeclaringType, ref color);
break;
- case IField f:
+ case IField:
color = fieldAccessColor;
break;
+ case IProperty:
+ color = propertyAccessColor;
+ break;
+ case IEvent:
+ color = eventAccessColor;
+ break;
}
if (color != null)
{
@@ -427,6 +430,28 @@ namespace ICSharpCode.ILSpy
}
}
+ void ApplyTypeColor(IType type, ref HighlightingColor color)
+ {
+ switch (type?.Kind)
+ {
+ case TypeKind.Delegate:
+ color = delegateTypeColor;
+ break;
+ case TypeKind.Class:
+ color = referenceTypeColor;
+ break;
+ case TypeKind.Interface:
+ color = interfaceTypeColor;
+ break;
+ case TypeKind.Enum:
+ color = enumerationTypeColor;
+ break;
+ case TypeKind.Struct:
+ color = valueTypeColor;
+ break;
+ }
+ }
+
public override void WritePrimitiveValue(object value, Decompiler.CSharp.Syntax.LiteralFormat format)
{
HighlightingColor color = null;
diff --git a/ILSpy/MainWindow.xaml b/ILSpy/MainWindow.xaml
index bf9860abe..9335d38a1 100644
--- a/ILSpy/MainWindow.xaml
+++ b/ILSpy/MainWindow.xaml
@@ -92,8 +92,6 @@
-
-
@@ -164,17 +162,13 @@
@@ -209,9 +203,9 @@
ItemsSource="{Binding SelectedItem.LanguageVersions, ElementName=languageComboBox, UpdateSourceTrigger=PropertyChanged}"
SelectedItem="{Binding Workspace.ActiveTabPage.FilterSettings.LanguageVersion, UpdateSourceTrigger=PropertyChanged}"/>
-
-
-
+
diff --git a/ILSpy/MainWindow.xaml.cs b/ILSpy/MainWindow.xaml.cs
index aa8eb92b2..eaa65475b 100644
--- a/ILSpy/MainWindow.xaml.cs
+++ b/ILSpy/MainWindow.xaml.cs
@@ -184,7 +184,7 @@ namespace ICSharpCode.ILSpy
case nameof(SessionSettings.ActiveAssemblyList):
ShowAssemblyList(sessionSettings.ActiveAssemblyList);
break;
- case nameof(SessionSettings.IsDarkMode):
+ case nameof(SessionSettings.Theme):
// update syntax highlighting and force reload (AvalonEdit does not automatically refresh on highlighting change)
DecompilerTextView.RegisterHighlighting();
DecompileSelectedNodes(DockWorkspace.Instance.ActiveTabPage.GetState() as DecompilerTextViewState);
diff --git a/ILSpy/Properties/Resources.Designer.cs b/ILSpy/Properties/Resources.Designer.cs
index 60114829a..f9002b35d 100644
--- a/ILSpy/Properties/Resources.Designer.cs
+++ b/ILSpy/Properties/Resources.Designer.cs
@@ -1,7 +1,6 @@
//------------------------------------------------------------------------------
//
// This code was generated by a tool.
-// Runtime Version:4.0.30319.42000
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
@@ -567,15 +566,6 @@ namespace ICSharpCode.ILSpy.Properties {
}
}
- ///
- /// Looks up a localized string similar to Dark Mode.
- ///
- public static string DarkMode {
- get {
- return ResourceManager.GetString("DarkMode", resourceCulture);
- }
- }
-
///
/// Looks up a localized string similar to DEBUG -- Decompile All.
///
@@ -2646,6 +2636,15 @@ namespace ICSharpCode.ILSpy.Properties {
}
}
+ ///
+ /// Looks up a localized string similar to Theme.
+ ///
+ public static string Theme {
+ get {
+ return ResourceManager.GetString("Theme", resourceCulture);
+ }
+ }
+
///
/// Looks up a localized string similar to Toggle All Folding.
///
diff --git a/ILSpy/Properties/Resources.resx b/ILSpy/Properties/Resources.resx
index 9f873ec56..f9e949fa8 100644
--- a/ILSpy/Properties/Resources.resx
+++ b/ILSpy/Properties/Resources.resx
@@ -222,9 +222,6 @@ Are you sure you want to continue?
DEBUG -- Dump PDB as XML
-
- Dark Mode
-
Debug Steps
@@ -907,6 +904,9 @@ Do you want to continue?
Tab size:
+
+ Theme
+
Toggle All Folding
diff --git a/ILSpy/Properties/Resources.zh-Hans.resx b/ILSpy/Properties/Resources.zh-Hans.resx
index bf8f4d400..3715d1004 100644
--- a/ILSpy/Properties/Resources.zh-Hans.resx
+++ b/ILSpy/Properties/Resources.zh-Hans.resx
@@ -222,9 +222,6 @@
调试 -- PDB 转储为 XML
-
- 深色
-
调试步骤
diff --git a/ILSpy/SessionSettings.cs b/ILSpy/SessionSettings.cs
index a39262ee2..245dd99d1 100644
--- a/ILSpy/SessionSettings.cs
+++ b/ILSpy/SessionSettings.cs
@@ -64,7 +64,7 @@ namespace ICSharpCode.ILSpy
this.TopPaneSplitterPosition = FromString((string)doc.Element("TopPaneSplitterPosition"), 0.3);
this.BottomPaneSplitterPosition = FromString((string)doc.Element("BottomPaneSplitterPosition"), 0.3);
this.SelectedSearchMode = FromString((string)doc.Element("SelectedSearchMode"), SearchMode.TypeAndMember);
- this.IsDarkMode = FromString((string)doc.Element(nameof(IsDarkMode)), false);
+ this.Theme = FromString((string)doc.Element(nameof(Theme)), ThemeManager.Current.DefaultTheme);
string currentCulture = (string)doc.Element(nameof(CurrentCulture));
this.CurrentCulture = string.IsNullOrEmpty(currentCulture) ? null : currentCulture;
@@ -81,10 +81,10 @@ namespace ICSharpCode.ILSpy
public FilterSettings FilterSettings { get; internal set; }
public SearchMode SelectedSearchMode { get; set; }
- public bool IsDarkMode {
- get => ThemeManager.Current.IsDarkMode;
+ public string Theme {
+ get => ThemeManager.Current.Theme;
set {
- ThemeManager.Current.IsDarkMode = value;
+ ThemeManager.Current.Theme = value;
OnPropertyChanged();
}
}
@@ -149,7 +149,7 @@ namespace ICSharpCode.ILSpy
doc.Add(new XElement("TopPaneSplitterPosition", ToString(this.TopPaneSplitterPosition)));
doc.Add(new XElement("BottomPaneSplitterPosition", ToString(this.BottomPaneSplitterPosition)));
doc.Add(new XElement("SelectedSearchMode", ToString(this.SelectedSearchMode)));
- doc.Add(new XElement(nameof(IsDarkMode), ToString(this.IsDarkMode)));
+ doc.Add(new XElement(nameof(Theme), ToString(this.Theme)));
if (this.CurrentCulture != null)
{
doc.Add(new XElement(nameof(CurrentCulture), this.CurrentCulture));
diff --git a/ILSpy/TextView/Asm-Mode-Dark.xshd b/ILSpy/TextView/Asm-Mode-Dark.xshd
deleted file mode 100644
index 9953acbf0..000000000
--- a/ILSpy/TextView/Asm-Mode-Dark.xshd
+++ /dev/null
@@ -1,1211 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
- aaa
- aad
- aam
- aas
- adc
- add
- and
- call
- cbw
- cdqe
- clc
- cld
- cli
- cmc
- cmp
- cmps
- cmpsb
- cmpsw
- cwd
- daa
- das
- dec
- div
- esc
- hlt
- idiv
- imul
- in
- inc
- int
- into
- iret
- ja
- jae
- jb
- jbe
- jc
- jcxz
- je
- jg
- jge
- jl
- jle
- jmp
- jna
- jnae
- jnb
- jnbe
- jnc
- jne
- jng
- jnge
- jnl
- jnle
- jno
- jnp
- jns
- jnz
- jo
- jp
- jpe
- jpo
- js
- jz
- lahf
- lds
- lea
- les
- lods
- lodsb
- lodsw
- loop
- loope
- loopew
- loopne
- loopnew
- loopnz
- loopnzw
- loopw
- loopz
- loopzw
- mov
- movabs
- movs
- movsb
- movsw
- mul
- neg
- nop
- not
- or
- out
- pop
- popf
- push
- pushf
- rcl
- rcr
- ret
- retf
- retn
- rol
- ror
- sahf
- sal
- sar
- sbb
- scas
- scasb
- scasw
- shl
- shr
- stc
- std
- sti
- stos
- stosb
- stosw
- sub
- test
- wait
- xchg
- xlat
- xlatb
- xor
- bound
- enter
- ins
- insb
- insw
- leave
- outs
- outsb
- outsw
- popa
- pusha
- pushw
- arpl
- lar
- lsl
- sgdt
- sidt
- sldt
- smsw
- str
- verr
- verw
- clts
- lgdt
- lidt
- lldt
- lmsw
- ltr
- bsf
- bsr
- bt
- btc
- btr
- bts
- cdq
- cmpsd
- cwde
- insd
- iretd
- iretdf
- iretf
- jecxz
- lfs
- lgs
- lodsd
- loopd
- looped
- loopned
- loopnzd
- loopzd
- lss
- movsd
- movsx
- movsxd
- movzx
- outsd
- popad
- popfd
- pushad
- pushd
- pushfd
- scasd
- seta
- setae
- setb
- setbe
- setc
- sete
- setg
- setge
- setl
- setle
- setna
- setnae
- setnb
- setnbe
- setnc
- setne
- setng
- setnge
- setnl
- setnle
- setno
- setnp
- setns
- setnz
- seto
- setp
- setpe
- setpo
- sets
- setz
- shld
- shrd
- stosd
- bswap
- cmpxchg
- invd
- invlpg
- wbinvd
- xadd
- lock
- rep
- repe
- repne
- repnz
- repz
- cflush
- cpuid
- emms
- femms
- cmovo
- cmovno
- cmovb
- cmovc
- cmovnae
- cmovae
- cmovnb
- cmovnc
- cmove
- cmovz
- cmovne
- cmovnz
- cmovbe
- cmovna
- cmova
- cmovnbe
- cmovs
- cmovns
- cmovp
- cmovpe
- cmovnp
- cmovpo
- cmovl
- cmovnge
- cmovge
- cmovnl
- cmovle
- cmovng
- cmovg
- cmovnle
- cmpxchg486
- cmpxchg8b
- loadall
- loadall286
- ibts
- icebp
- int1
- int3
- int01
- int03
- iretw
- popaw
- popfw
- pushaw
- pushfw
- rdmsr
- rdpmc
- rdshr
- rdtsc
- rsdc
- rsldt
- rsm
- rsts
- salc
- smi
- smint
- smintold
- svdc
- svldt
- svts
- syscall
- sysenter
- sysexit
- sysret
- ud0
- ud1
- ud2
- umov
- xbts
- wrmsr
- wrshr
-
-
- f2xm1
- fabs
- fadd
- faddp
- fbld
- fbstp
- fchs
- fclex
- fcom
- fcomp
- fcompp
- fdecstp
- fdisi
- fdiv
- fdivp
- fdivr
- fdivrp
- feni
- ffree
- fiadd
- ficom
- ficomp
- fidiv
- fidivr
- fild
- fimul
- fincstp
- finit
- fist
- fistp
- fisub
- fisubr
- fld
- fld1
- fldcw
- fldenv
- fldenvw
- fldl2e
- fldl2t
- fldlg2
- fldln2
- fldpi
- fldz
- fmul
- fmulp
- fnclex
- fndisi
- fneni
- fninit
- fnop
- fnsave
- fnsavew
- fnstcw
- fnstenv
- fnstenvw
- fnstsw
- fpatan
- fprem
- fptan
- frndint
- frstor
- frstorw
- fsave
- fsavew
- fscale
- fsqrt
- fst
- fstcw
- fstenv
- fstenvw
- fstp
- fstsw
- fsub
- fsubp
- fsubr
- fsubrp
- ftst
- fwait
- fxam
- fxch
- fxtract
- fyl2x
- fyl2xp1
- fsetpm
- fcos
- fldenvd
- fnsaved
- fnstenvd
- fprem1
- frstord
- fsaved
- fsin
- fsincos
- fstenvd
- fucom
- fucomp
- fucompp
- fcomi
- fcomip
- ffreep
- fcmovb
- fcmove
- fcmovbe
- fcmovu
- fcmovnb
- fcmovne
- fcmovnbe
- fcmovnu
-
-
- ah
- al
- ax
- bh
- bl
- bp
- bx
- ch
- cl
- cr0
- cr2
- cr3
- cr4
- cs
- cx
- dh
- di
- dl
- dr0
- dr1
- dr2
- dr3
- dr6
- dr7
- ds
- dx
- eax
- ebp
- ebx
- ecx
- edi
- edx
- es
- esi
- esp
- fs
- gs
- rax
- rbx
- rcx
- rdx
- rdi
- rsi
- rbp
- rsp
- r8
- r9
- r10
- r11
- r12
- r13
- r14
- r15
- r8d
- r9d
- r10d
- r11d
- r12d
- r13d
- r14d
- r15d
- r8w
- r9w
- r10w
- r11w
- r12w
- r13w
- r14w
- r15w
- r8b
- r9b
- r10b
- r11b
- r12b
- r13b
- r14b
- r15b
- si
- sp
- ss
- st
- tr3
- tr4
- tr5
- tr6
- tr7
- st0
- st1
- st2
- st3
- st4
- st5
- st6
- st7
- mm0
- mm1
- mm2
- mm3
- mm4
- mm5
- mm6
- mm7
- xmm0
- xmm1
- xmm2
- xmm3
- xmm4
- xmm5
- xmm6
- xmm7
- xmm8
- xmm9
- xmm10
- xmm11
- xmm12
- xmm13
- xmm14
- xmm15
-
-
- .186
- .286
- .286c
- .286p
- .287
- .386
- .386c
- .386p
- .387
- .486
- .486p
- .8086
- .8087
- .alpha
- .break
- .code
- .const
- .continue
- .cref
- .data
- .data?
- .dosseg
- .else
- .elseif
- .endif
- .endw
- .err
- .err1
- .err2
- .errb
- .errdef
- .errdif
- .errdifi
- .erre
- .erridn
- .erridni
- .errnb
- .errndef
- .errnz
- .exit
- .fardata
- .fardata?
- .if
- .lall
- .lfcond
- .list
- .listall
- .listif
- .listmacro
- .listmacroall
- .model
- .no87
- .nocref
- .nolist
- .nolistif
- .nolistmacro
- .radix
- .repeat
- .sall
- .seq
- .sfcond
- .stack
- .startup
- .tfcond
- .type
- .until
- .untilcxz
- .while
- .xall
- .xcref
- .xlist
- alias
- align
- assume
- catstr
- comm
- comment
- db
- dd
- df
- dosseg
- dq
- dt
- dup
- dw
- echo
- else
- elseif
- elseif1
- elseif2
- elseifb
- elseifdef
- elseifdif
- elseifdifi
- elseife
- elseifidn
- elseifidni
- elseifnb
- elseifndef
- end
- endif
- endm
- endp
- ends
- eq
- equ
- even
- exitm
- extern
- externdef
- extrn
- for
- forc
- ge
- goto
- group
- gt
- high
- highword
- if
- if1
- if2
- ifb
- ifdef
- ifdif
- ifdifi
- ife
- ifidn
- ifidni
- ifnb
- ifndef
- include
- includelib
- instr
- invoke
- irp
- irpc
- label
- le
- length
- lengthof
- local
- low
- lowword
- lroffset
- lt
- macro
- mask
- mod
- .msfloat
- name
- ne
- offset
- opattr
- option
- org
- %out
- page
- popcontext
- proc
- proto
- ptr
- public
- purge
- pushcontext
- record
- repeat
- rept
- seg
- segment
- short
- size
- sizeof
- sizestr
- struc
- struct
- substr
- subtitle
- subttl
- textequ
- this
- title
- type
- typedef
- union
- while
- width
- resb
- resw
- resd
- resq
- rest
- incbin
- times
- %define
- %idefine
- %xdefine
- %xidefine
- %undef
- %assign
- %iassign
- %strlen
- %substr
- %macro
- %imacro
- %endmacro
- %rotate
- %if
- %elif
- %else
- %endif
- %ifdef
- %ifndef
- %elifdef
- %elifndef
- %ifmacro
- %ifnmacro
- %elifmacro
- %elifnmacro
- %ifctk
- %ifnctk
- %elifctk
- %elifnctk
- %ifidn
- %ifnidn
- %elifidn
- %elifnidn
- %ifidni
- %ifnidni
- %elifidni
- %elifnidni
- %ifid
- %ifnid
- %elifid
- %elifnid
- %ifstr
- %ifnstr
- %elifstr
- %elifnstr
- %ifnum
- %ifnnum
- %elifnum
- %elifnnum
- %error
- %rep
- %endrep
- %exitrep
- %include
- %push
- %pop
- %repl
- endstruc
- istruc
- at
- iend
- alignb
- %arg
- %stacksize
- %local
- %line
- bits
- use16
- use32
- section
- absolute
- global
- common
- cpu
- import
- export
-
-
- $
- ?
- @b
- @f
- addr
- basic
- byte
- c
- carry?
- dword
- far
- far16
- fortran
- fword
- near
- near16
- overflow?
- parity?
- pascal
- qword
- real4
- real8
- real10
- sbyte
- sdword
- sign?
- stdcall
- sword
- syscall
- tbyte
- vararg
- word
- zero?
- flat
- near32
- far32
- abs
- all
- assumes
- at
- casemap
- common
- compact
- cpu
- dotname
- emulator
- epilogue
- error
- export
- expr16
- expr32
- farstack
- forceframe
- huge
- language
- large
- listing
- ljmp
- loadds
- m510
- medium
- memory
- nearstack
- nodotname
- noemulator
- nokeyword
- noljmp
- nom510
- none
- nonunique
- nooldmacros
- nooldstructs
- noreadonly
- noscoped
- nosignextend
- nothing
- notpublic
- oldmacros
- oldstructs
- os_dos
- para
- private
- prologue
- radix
- readonly
- req
- scoped
- setif2
- smallstack
- tiny
- use16
- use32
- uses
- a16
- a32
- o16
- o32
- nosplit
- $$
- seq
- wrt
- small
- .text
- .data
- .bss
- %0
- %1
- %2
- %3
- %4
- %5
- %6
- %7
- %8
- %9
-
-
- addpd
- addps
- addsd
- addss
- andpd
- andps
- andnpd
- andnps
- cmpeqpd
- cmpltpd
- cmplepd
- cmpunordpd
- cmpnepd
- cmpnltpd
- cmpnlepd
- cmpordpd
- cmpeqps
- cmpltps
- cmpleps
- cmpunordps
- cmpneps
- cmpnltps
- cmpnleps
- cmpordps
- cmpeqsd
- cmpltsd
- cmplesd
- cmpunordsd
- cmpnesd
- cmpnltsd
- cmpnlesd
- cmpordsd
- cmpeqss
- cmpltss
- cmpless
- cmpunordss
- cmpness
- cmpnltss
- cmpnless
- cmpordss
- comisd
- comiss
- cvtdq2pd
- cvtdq2ps
- cvtpd2dq
- cvtpd2pi
- cvtpd2ps
- cvtpi2pd
- cvtpi2ps
- cvtps2dq
- cvtps2pd
- cvtps2pi
- cvtss2sd
- cvtss2si
- cvtsd2si
- cvtsd2ss
- cvtsi2sd
- cvtsi2ss
- cvttpd2dq
- cvttpd2pi
- cvttps2dq
- cvttps2pi
- cvttsd2si
- cvttss2si
- divpd
- divps
- divsd
- divss
- fxrstor
- fxsave
- ldmxscr
- lfence
- mfence
- maskmovdqu
- maskmovdq
- maxpd
- maxps
- paxsd
- maxss
- minpd
- minps
- minsd
- minss
- movapd
- movaps
- movdq2q
- movdqa
- movdqu
- movhlps
- movhpd
- movhps
- movd
- movq
- movlhps
- movlpd
- movlps
- movmskpd
- movmskps
- movntdq
- movnti
- movntpd
- movntps
- movntq
- movq2dq
- movsd
- movss
- movupd
- movups
- mulpd
- mulps
- mulsd
- mulss
- orpd
- orps
- packssdw
- packsswb
- packuswb
- paddb
- paddsb
- paddw
- paddsw
- paddd
- paddsiw
- paddq
- paddusb
- paddusw
- pand
- pandn
- pause
- paveb
- pavgb
- pavgw
- pavgusb
- pdistib
- pextrw
- pcmpeqb
- pcmpeqw
- pcmpeqd
- pcmpgtb
- pcmpgtw
- pcmpgtd
- pf2id
- pf2iw
- pfacc
- pfadd
- pfcmpeq
- pfcmpge
- pfcmpgt
- pfmax
- pfmin
- pfmul
- pmachriw
- pmaddwd
- pmagw
- pmaxsw
- pmaxub
- pminsw
- pminub
- pmovmskb
- pmulhrwc
- pmulhriw
- pmulhrwa
- pmulhuw
- pmulhw
- pmullw
- pmuludq
- pmvzb
- pmvnzb
- pmvlzb
- pmvgezb
- pfnacc
- pfpnacc
- por
- prefetch
- prefetchw
- prefetchnta
- prefetcht0
- prefetcht1
- prefetcht2
- pfrcp
- pfrcpit1
- pfrcpit2
- pfrsqit1
- pfrsqrt
- pfsub
- pfsubr
- pi2fd
- pinsrw
- psadbw
- pshufd
- pshufhw
- pshuflw
- pshufw
- psllw
- pslld
- psllq
- pslldq
- psraw
- psrad
- psrlw
- psrld
- psrlq
- psrldq
- psubb
- psubw
- psubd
- psubq
- psubsb
- psubsw
- psubusb
- psubusw
- psubsiw
- pswapd
- punpckhbw
- punpckhwd
- punpckhdq
- punpckhqdq
- punpcklbw
- punpcklwd
- punpckldq
- punpcklqdq
- pxor
- rcpps
- rcpss
- rsqrtps
- rsqrtss
- sfence
- shufpd
- shufps
- sqrtpd
- sqrtps
- sqrtsd
- sqrtss
- stmxcsr
- subpd
- subps
- subsd
- subss
- ucomisd
- ucomiss
- unpckhpd
- unpckhps
- unpcklpd
- unpcklps
- xorpd
- xorps
-
-
- ;
-
-
- \b(0[xXhH])?[0-9a-fA-F_`]+[h]? # hex number
- |
- ( \b\d+(\.[0-9]+)? #number with optional floating point
- | \.[0-9]+ #or just starting with floating point
- )
- ([eE][+-]?[0-9]+)? # optional exponent
-
-
-
-
- TODO
- FIXME
-
-
- HACK
- UNDONE
-
-
-
\ No newline at end of file
diff --git a/ILSpy/TextView/Asm-Mode.xshd b/ILSpy/TextView/Asm-Mode.xshd
index 9bf688b83..8d4fb8c2f 100644
--- a/ILSpy/TextView/Asm-Mode.xshd
+++ b/ILSpy/TextView/Asm-Mode.xshd
@@ -8,7 +8,8 @@
-
+
+
aaa
@@ -1189,6 +1190,9 @@
;
+
+ ^ \s* [0-9A-F]+ \s+ [0-9A-F]+
+
\b(0[xXhH])?[0-9a-fA-F_`]+[h]? # hex number
|
diff --git a/ILSpy/TextView/CSharp-Mode-Dark.xshd b/ILSpy/TextView/CSharp-Mode-Dark.xshd
deleted file mode 100644
index 7d7c7aa73..000000000
--- a/ILSpy/TextView/CSharp-Mode-Dark.xshd
+++ /dev/null
@@ -1,149 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- TODO
- FIXME
-
-
- HACK
- UNDONE
-
-
-
-
-
-
- \#
-
-
-
- (define|undef|if|elif|else|endif|line)\b
-
-
-
- //
-
-
-
-
-
- (region|endregion|error|warning|pragma)\b
-
-
-
-
-
-
- ///(?!/)
-
-
-
-
-
-
-
- //
-
-
-
- /\*
- \*/
-
-
-
- "
- "
-
-
-
-
-
-
-
- '
- '
-
-
-
-
-
-
-
- @"
- "
-
-
-
-
-
-
-
- \$"
- "
-
-
-
-
-
-
-
-
-
-
-
- \b0[xX][0-9a-fA-F]+ # hex number
- |
- ( \b\d+(\.[0-9]+)? #number with optional floating point
- | \.[0-9]+ #or just starting with floating point
- )
- ([eE][+-]?[0-9]+)? # optional exponent
-
-
-
diff --git a/ILSpy/TextView/CSharp-Mode.xshd b/ILSpy/TextView/CSharp-Mode.xshd
index 5f5e0a2fd..d2db08534 100644
--- a/ILSpy/TextView/CSharp-Mode.xshd
+++ b/ILSpy/TextView/CSharp-Mode.xshd
@@ -39,8 +39,18 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/ILSpy/TextView/DecompilerTextView.cs b/ILSpy/TextView/DecompilerTextView.cs
index 21991df25..b7e5f3211 100644
--- a/ILSpy/TextView/DecompilerTextView.cs
+++ b/ILSpy/TextView/DecompilerTextView.cs
@@ -127,6 +127,7 @@ namespace ICSharpCode.ILSpy.TextView
// SearchPanel
SearchPanel searchPanel = SearchPanel.Install(textEditor.TextArea);
searchPanel.RegisterCommands(Application.Current.MainWindow.CommandBindings);
+ searchPanel.SetResourceReference(SearchPanel.MarkerBrushProperty, ResourceKeys.SearchResultBackgroundBrush);
searchPanel.Loaded += (_, _) => {
// HACK: fix the hardcoded but misaligned margin of the search text box.
var textBox = searchPanel.VisualDescendants().OfType().FirstOrDefault();
@@ -139,10 +140,6 @@ namespace ICSharpCode.ILSpy.TextView
ShowLineMargin();
SetHighlightCurrentLine();
- // add marker service & margin
- textEditor.TextArea.TextView.BackgroundRenderers.Add(textMarkerService);
- textEditor.TextArea.TextView.LineTransformers.Add(textMarkerService);
-
ContextMenuProvider.Add(this);
textEditor.TextArea.TextView.SetResourceReference(ICSharpCode.AvalonEdit.Rendering.TextView.LinkTextForegroundBrushProperty, ResourceKeys.LinkTextForegroundBrush);
@@ -1364,15 +1361,8 @@ namespace ICSharpCode.ILSpy.TextView
string[] extensions,
string resourceName)
{
- if (ThemeManager.Current.IsDarkMode)
- {
- resourceName += "-Dark";
- }
-
- resourceName += ".xshd";
-
Stream? resourceStream = typeof(DecompilerTextView).Assembly
- .GetManifestResourceStream(typeof(DecompilerTextView), resourceName);
+ .GetManifestResourceStream(typeof(DecompilerTextView), resourceName + ".xshd");
if (resourceStream != null)
{
@@ -1382,7 +1372,9 @@ namespace ICSharpCode.ILSpy.TextView
using (resourceStream)
using (XmlTextReader reader = new XmlTextReader(resourceStream))
{
- return HighlightingLoader.Load(reader, manager);
+ var highlightingDefinition = HighlightingLoader.Load(reader, manager);
+ ThemeManager.Current.ApplyHighlightingColors(highlightingDefinition);
+ return highlightingDefinition;
}
});
}
diff --git a/ILSpy/TextView/DecompilerTextView.xaml b/ILSpy/TextView/DecompilerTextView.xaml
index 6ff6d2130..4776d1397 100644
--- a/ILSpy/TextView/DecompilerTextView.xaml
+++ b/ILSpy/TextView/DecompilerTextView.xaml
@@ -6,7 +6,8 @@
xmlns:local="clr-namespace:ICSharpCode.ILSpy.TextView"
xmlns:ae="clr-namespace:ICSharpCode.AvalonEdit;assembly=ICSharpCode.AvalonEdit"
xmlns:folding="clr-namespace:ICSharpCode.AvalonEdit.Folding;assembly=ICSharpCode.AvalonEdit"
- xmlns:styles="urn:TomsToolbox.Wpf.Styles">
+ xmlns:styles="urn:TomsToolbox.Wpf.Styles"
+ xmlns:themes="clr-namespace:ICSharpCode.ILSpy.Themes">
@@ -15,8 +16,8 @@
-
-
-
-
-
-
-
-
-
- nop
- break
- ldarg.0
- ldarg.1
- ldarg.2
- ldarg.3
- ldloc.0
- ldloc.1
- ldloc.2
- ldloc.3
- stloc.0
- stloc.1
- stloc.2
- stloc.3
- ldarg.s
- ldarga.s
- starg.s
- ldloc.s
- ldloca.s
- stloc.s
- ldnull
- ldc.i4.m1
- ldc.i4.0
- ldc.i4.1
- ldc.i4.2
- ldc.i4.3
- ldc.i4.4
- ldc.i4.5
- ldc.i4.6
- ldc.i4.7
- ldc.i4.8
- ldc.i4.s
- ldc.i4
- ldc.i8
- ldc.r4
- ldc.r8
- dup
- pop
- jmp
- call
- calli
- ret
- br.s
- brfalse.s
- brtrue.s
- beq.s
- bge.s
- bgt.s
- ble.s
- blt.s
- bne.un.s
- bge.un.s
- bgt.un.s
- ble.un.s
- blt.un.s
- br
- brfalse
- brtrue
- beq
- bge
- bgt
- ble
- blt
- bne.un
- bge.un
- bgt.un
- ble.un
- blt.un
- switch
- ldind.i1
- ldind.u1
- ldind.i2
- ldind.u2
- ldind.i4
- ldind.u4
- ldind.i8
- ldind.i
- ldind.r4
- ldind.r8
- ldind.ref
- stind.ref
- stind.i1
- stind.i2
- stind.i4
- stind.i8
- stind.r4
- stind.r8
- add
- sub
- mul
- div
- div.un
- rem
- rem.un
- and
- or
- xor
- shl
- shr
- shr.un
- neg
- not
- conv.i1
- conv.i2
- conv.i4
- conv.i8
- conv.r4
- conv.r8
- conv.u4
- conv.u8
- callvirt
- cpobj
- ldobj
- ldstr
- newobj
- castclass
- isinst
- conv.r.un
- unbox
- throw
- ldfld
- ldflda
- stfld
- ldsfld
- ldsflda
- stsfld
- stobj
- conv.ovf.i1.un
- conv.ovf.i2.un
- conv.ovf.i4.un
- conv.ovf.i8.un
- conv.ovf.u1.un
- conv.ovf.u2.un
- conv.ovf.u4.un
- conv.ovf.u8.un
- conv.ovf.i.un
- conv.ovf.u.un
- box
- newarr
- ldlen
- ldelema
- ldelem
- ldelem.i1
- ldelem.u1
- ldelem.i2
- ldelem.u2
- ldelem.i4
- ldelem.u4
- ldelem.i8
- ldelem.i
- ldelem.r4
- ldelem.r8
- ldelem.ref
- stelem
- stelem.i
- stelem.i1
- stelem.i2
- stelem.i4
- stelem.i8
- stelem.r4
- stelem.r8
- stelem.ref
- conv.ovf.i1
- conv.ovf.u1
- conv.ovf.i2
- conv.ovf.u2
- conv.ovf.i4
- conv.ovf.u4
- conv.ovf.i8
- conv.ovf.u8
- refanyval
- ckfinite
- mkrefany
- ldtoken
- conv.u2
- conv.u1
- conv.i
- conv.ovf.i
- conv.ovf.u
- add.ovf
- add.ovf.un
- mul.ovf
- mul.ovf.un
- sub.ovf
- sub.ovf.un
- endfinally
- leave
- leave.s
- stind.i
- conv.u
- prefix7
- prefix6
- prefix5
- prefix4
- prefix3
- prefix2
- prefix1
- prefixref
- arglist
- ceq
- cgt
- cgt.un
- clt
- clt.un
- ldftn
- ldvirtftn
- ldarg
- ldarga
- starg
- ldloc
- ldloca
- stloc
- localloc
- endfilter
- unaligned.
- volatile.
- tail.
- initobj
- cpblk
- initblk
- rethrow
- sizeof
- refanytype
- illegal
- endmac
- brnull
- brnull.s
- brzero
- brzero.s
- brinst
- brinst.s
- ldind.u8
- ldelem.u8
- ldc.i4.M1
- endfault
-
-
- void
- bool
- char
- wchar
- int
- int8
- int16
- int32
- int64
- uint8
- uint16
- uint32
- uint64
- float
- float32
- float64
- refany
- typedref
- object
- string
- native
- unsigned
- value
- valuetype
- class
- const
- vararg
- default
- stdcall
- thiscall
- fastcall
- unmanaged
- not_in_gc_heap
- beforefieldinit
- instance
- filter
- catch
- static
- public
- private
- synchronized
- interface
- extends
- implements
- handler
- finally
- fault
- to
- abstract
- auto
- sequential
- explicit
- wrapper
- ansi
- unicode
- autochar
- import
- enum
- virtual
- notremotable
- special
- il
- cil
- optil
- managed
- preservesig
- runtime
- method
- field
- bytearray
- final
- sealed
- specialname
- family
- assembly
- famandassem
- famorassem
- privatescope
- nested
- hidebysig
- newslot
- rtspecialname
- pinvokeimpl
- unmanagedexp
- reqsecobj
- .ctor
- .cctor
- initonly
- literal
- notserialized
- forwardref
- internalcall
- noinlining
- aggressiveinlining
- nomangle
- lasterr
- winapi
- cdecl
- stdcall
- thiscall
- fastcall
- as
- pinned
- modreq
- modopt
- serializable
- at
- tls
- true
- false
- strict
- type
-
-
- .class
- .namespace
- .method
- .field
- .emitbyte
- .try
- .maxstack
- .locals
- .entrypoint
- .zeroinit
- .pdirect
- .data
- .event
- .addon
- .removeon
- .fire
- .other
- protected
- .property
- .set
- .get
- default
- .import
- .permission
- .permissionset
- .line
- .language
- .interfaceimpl
- #line
-
-
- request
- demand
- assert
- deny
- permitonly
- linkcheck
- inheritcheck
- reqmin
- reqopt
- reqrefuse
- prejitgrant
- prejitdeny
- noncasdemand
- noncaslinkdemand
- noncasinheritance
-
-
-
- .custom
-
- init
-
- .size
- .pack
-
- .file
- nometadata
- .hash
- .assembly
- implicitcom
- noappdomain
- noprocess
- nomachine
- .publickey
- .publickeytoken
- algorithm
- .ver
- .locale
- extern
- .export
- .manifestres
- .mresource
- .localized
-
-
- .module
- marshal
- custom
- sysstring
- fixed
- variant
- currency
- syschar
- decimal
- date
- bstr
- tbstr
- lpstr
- lpwstr
- lptstr
- objectref
- iunknown
- idispatch
- struct
- safearray
- byvalstr
- lpvoid
- any
- array
- lpstruct
-
-
- .vtfixup
- fromunmanaged
- callmostderived
- .vtentry
-
-
- in
- out
- opt
- lcid
- retval
- .param
-
-
- .override
- with
-
-
- null
- error
- hresult
- carray
- userdefined
- record
- filetime
- blob
- stream
- storage
- streamed_object
- stored_object
- blob_object
- cf
- clsid
- vector
-
-
- nullref
-
-
- .subsystem
- .corflags
- .stackreserve
- alignment
- .imagebase
-
-
- //
-
-
- /\*
- \*/
-
-
- "
- "
-
-
- '
- '
-
-
-
-
- TODO
- FIXME
-
-
- HACK
- UNDONE
-
-
-
\ No newline at end of file
diff --git a/ILSpy/TextView/ILAsm-Mode.xshd b/ILSpy/TextView/ILAsm-Mode.xshd
index 0c2750f25..29e187b43 100644
--- a/ILSpy/TextView/ILAsm-Mode.xshd
+++ b/ILSpy/TextView/ILAsm-Mode.xshd
@@ -5,7 +5,8 @@
-
+
+
nop
@@ -522,6 +523,9 @@
'
'
+
+ ^ \s* \w+ :
+
diff --git a/ILSpy/TextView/XML-Mode-Dark.xshd b/ILSpy/TextView/XML-Mode-Dark.xshd
deleted file mode 100644
index cea0680a7..000000000
--- a/ILSpy/TextView/XML-Mode-Dark.xshd
+++ /dev/null
@@ -1,63 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
- <!--
- -->
-
-
- <!\[CDATA\[
- ]]>
-
-
- <!DOCTYPE
- >
-
-
- <\?
- \?>
-
-
- <
- >
-
-
-
- "
- "|(?=<)
-
-
- '
- '|(?=<)
-
- [\d\w_\-\.]+(?=(\s*=))
- =
-
-
-
-
-
-
-
- &
- [\w\d\#]+
- ;
-
-
-
- &
- [\w\d\#]*
- #missing ;
-
-
-
\ No newline at end of file
diff --git a/ILSpy/Themes/DarkTheme.xaml b/ILSpy/Themes/Base.Dark.xaml
similarity index 92%
rename from ILSpy/Themes/DarkTheme.xaml
rename to ILSpy/Themes/Base.Dark.xaml
index 94d96ab0b..4005dec0a 100644
--- a/ILSpy/Themes/DarkTheme.xaml
+++ b/ILSpy/Themes/Base.Dark.xaml
@@ -6,6 +6,10 @@
+
+
+
+
#333337
#464646
#252526
@@ -60,4 +64,6 @@
MediumVioletRed
CornflowerBlue
-
\ No newline at end of file
+
+
+
diff --git a/ILSpy/Themes/LightTheme.xaml b/ILSpy/Themes/Base.Light.xaml
similarity index 92%
rename from ILSpy/Themes/LightTheme.xaml
rename to ILSpy/Themes/Base.Light.xaml
index e9c01f691..8e7e5076b 100644
--- a/ILSpy/Themes/LightTheme.xaml
+++ b/ILSpy/Themes/Base.Light.xaml
@@ -6,6 +6,10 @@
+
+
+ LightGreen
+
#FCFCFC
#D8D8E0
#F5F5F5
@@ -53,4 +57,5 @@
-
\ No newline at end of file
+
+
diff --git a/ILSpy/Themes/ResourceKeys.cs b/ILSpy/Themes/ResourceKeys.cs
index e36346589..1d78f24dc 100644
--- a/ILSpy/Themes/ResourceKeys.cs
+++ b/ILSpy/Themes/ResourceKeys.cs
@@ -22,10 +22,14 @@ namespace ICSharpCode.ILSpy.Themes
{
public static class ResourceKeys
{
- public static ResourceKey TextMarkerBackgroundColor = new ComponentResourceKey(typeof(ResourceKeys), "TextMarkerBackgroundColor");
- public static ResourceKey TextMarkerDefinitionBackgroundColor = new ComponentResourceKey(typeof(ResourceKeys), "TextMarkerDefinitionBackgroundColor");
- public static ResourceKey LinkTextForegroundBrush = new ComponentResourceKey(typeof(ResourceKeys), "LinkTextForegroundBrush");
- public static ResourceKey BracketHighlightBackgroundBrush = new ComponentResourceKey(typeof(ResourceKeys), "BracketHighlightBackgroundBrush");
- public static ResourceKey BracketHighlightBorderPen = new ComponentResourceKey(typeof(ResourceKeys), "BracketHighlightBorderPen");
+ public static ResourceKey TextBackgroundBrush = new ComponentResourceKey(typeof(ResourceKeys), nameof(TextBackgroundBrush));
+ public static ResourceKey TextForegroundBrush = new ComponentResourceKey(typeof(ResourceKeys), nameof(TextForegroundBrush));
+ public static ResourceKey TextMarkerBackgroundColor = new ComponentResourceKey(typeof(ResourceKeys), nameof(TextMarkerBackgroundColor));
+ public static ResourceKey TextMarkerDefinitionBackgroundColor = new ComponentResourceKey(typeof(ResourceKeys), nameof(TextMarkerDefinitionBackgroundColor));
+ public static ResourceKey SearchResultBackgroundBrush = new ComponentResourceKey(typeof(ResourceKeys), nameof(SearchResultBackgroundBrush));
+ public static ResourceKey LinkTextForegroundBrush = new ComponentResourceKey(typeof(ResourceKeys), nameof(LinkTextForegroundBrush));
+ public static ResourceKey BracketHighlightBackgroundBrush = new ComponentResourceKey(typeof(ResourceKeys), nameof(BracketHighlightBackgroundBrush));
+ public static ResourceKey BracketHighlightBorderPen = new ComponentResourceKey(typeof(ResourceKeys), nameof(BracketHighlightBorderPen));
+ public static ResourceKey ThemeAwareButtonEffect = new ComponentResourceKey(typeof(ResourceKeys), nameof(ThemeAwareButtonEffect));
}
}
diff --git a/ILSpy/Themes/SyntaxColor.cs b/ILSpy/Themes/SyntaxColor.cs
new file mode 100644
index 000000000..cf9a29b00
--- /dev/null
+++ b/ILSpy/Themes/SyntaxColor.cs
@@ -0,0 +1,32 @@
+#nullable enable
+
+using System.Windows;
+using System.Windows.Media;
+
+using ICSharpCode.AvalonEdit.Highlighting;
+
+namespace ICSharpCode.ILSpy.Themes;
+
+public class SyntaxColor
+{
+ public Color? Foreground { get; set; }
+ public Color? Background { get; set; }
+ public FontWeight? FontWeight { get; set; }
+ public FontStyle? FontStyle { get; set; }
+
+ public void ApplyTo(HighlightingColor color)
+ {
+ color.Foreground = Foreground is { } foreground ? new SimpleHighlightingBrush(foreground) : null;
+ color.Background = Background is { } background ? new SimpleHighlightingBrush(background) : null;
+ color.FontWeight = FontWeight ?? FontWeights.Normal;
+ color.FontStyle = FontStyle ?? FontStyles.Normal;
+ }
+
+ public static void ResetColor(HighlightingColor color)
+ {
+ color.Foreground = null;
+ color.Background = null;
+ color.FontWeight = null;
+ color.FontStyle = null;
+ }
+}
diff --git a/ILSpy/Themes/Theme.Dark.xaml b/ILSpy/Themes/Theme.Dark.xaml
new file mode 100644
index 000000000..76d3abfbb
--- /dev/null
+++ b/ILSpy/Themes/Theme.Dark.xaml
@@ -0,0 +1,91 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/ILSpy/Themes/Theme.Light.xaml b/ILSpy/Themes/Theme.Light.xaml
new file mode 100644
index 000000000..ca08971e2
--- /dev/null
+++ b/ILSpy/Themes/Theme.Light.xaml
@@ -0,0 +1,91 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/ILSpy/Themes/Theme.RSharpDark.xaml b/ILSpy/Themes/Theme.RSharpDark.xaml
new file mode 100644
index 000000000..62bfddf03
--- /dev/null
+++ b/ILSpy/Themes/Theme.RSharpDark.xaml
@@ -0,0 +1,96 @@
+
+
+
+
+
+
+
+
+
+ #995A23
+
+ #483D8B
+ #800000
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/ILSpy/Themes/Theme.RSharpLight.xaml b/ILSpy/Themes/Theme.RSharpLight.xaml
new file mode 100644
index 000000000..8eb28d77c
--- /dev/null
+++ b/ILSpy/Themes/Theme.RSharpLight.xaml
@@ -0,0 +1,96 @@
+
+
+
+
+
+
+
+
+
+ #F6B94D
+
+ #87CEFA
+ #FFB6C1
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/ILSpy/Themes/Theme.VSCodeDarkPlus.xaml b/ILSpy/Themes/Theme.VSCodeDarkPlus.xaml
new file mode 100644
index 000000000..7a94d4fab
--- /dev/null
+++ b/ILSpy/Themes/Theme.VSCodeDarkPlus.xaml
@@ -0,0 +1,101 @@
+
+
+
+
+
+
+
+
+
+
+
+ #264F78
+ #343A40
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/ILSpy/Themes/Theme.VSCodeLightPlus.xaml b/ILSpy/Themes/Theme.VSCodeLightPlus.xaml
new file mode 100644
index 000000000..2ab0d1000
--- /dev/null
+++ b/ILSpy/Themes/Theme.VSCodeLightPlus.xaml
@@ -0,0 +1,101 @@
+
+
+
+
+
+
+
+
+
+
+
+ #ADD6FF
+ #D6EAFF
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/ILSpy/Themes/ThemeManager.cs b/ILSpy/Themes/ThemeManager.cs
index 08e117815..fe03b32c2 100644
--- a/ILSpy/Themes/ThemeManager.cs
+++ b/ILSpy/Themes/ThemeManager.cs
@@ -16,36 +16,46 @@
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
+#nullable enable
+
using System;
+using System.Collections;
+using System.Collections.Generic;
+using System.Linq;
using System.Windows;
using System.Windows.Controls;
+using ICSharpCode.AvalonEdit.Highlighting;
+
namespace ICSharpCode.ILSpy.Themes
{
- internal class ThemeManager
+ public class ThemeManager
{
- private bool _isDarkMode;
- private readonly ResourceDictionary _themeDictionaryContainer = new ResourceDictionary();
-
+ private string? _theme;
+ private readonly ResourceDictionary _themeDictionaryContainer = new();
+ private readonly Dictionary _syntaxColors = new();
- public static readonly ThemeManager Current = new ThemeManager();
+ public static readonly ThemeManager Current = new();
private ThemeManager()
{
Application.Current.Resources.MergedDictionaries.Add(_themeDictionaryContainer);
}
- public bool IsDarkMode {
- get => _isDarkMode;
- set {
- _isDarkMode = value;
+ public string DefaultTheme => "Light";
- _themeDictionaryContainer.MergedDictionaries.Clear();
+ public static IReadOnlyCollection AllThemes => new[] {
+ "Light",
+ "Dark",
+ "VS Code Light+",
+ "VS Code Dark+",
+ "R# Light",
+ "R# Dark"
+ };
- string theme = value ? "Dark" : "Light";
-
- _themeDictionaryContainer.MergedDictionaries.Add(new ResourceDictionary { Source = new Uri($"themes/{theme}Theme.xaml", UriKind.Relative) });
- }
+ public string? Theme {
+ get => _theme;
+ set => UpdateTheme(value);
}
public Button CreateButton()
@@ -64,5 +74,51 @@ namespace ICSharpCode.ILSpy.Themes
{
return new Style(typeof(Button), (Style)Application.Current.FindResource(ToolBar.ButtonStyleKey));
}
+
+ public void ApplyHighlightingColors(IHighlightingDefinition highlightingDefinition)
+ {
+ // Make sure all color values are taken from the theme
+ foreach (var color in highlightingDefinition.NamedHighlightingColors)
+ SyntaxColor.ResetColor(color);
+
+ var prefix = $"SyntaxColor.{highlightingDefinition.Name}.";
+
+ foreach (var (key, syntaxColor) in _syntaxColors)
+ {
+ var color = highlightingDefinition.GetNamedColor(key.Substring(prefix.Length));
+ if (color is not null)
+ syntaxColor.ApplyTo(color);
+ }
+ }
+
+ private void UpdateTheme(string? themeName)
+ {
+ _theme = themeName ?? DefaultTheme;
+ if (!AllThemes.Contains(_theme))
+ _theme = DefaultTheme;
+
+ var themeFileName = _theme
+ .Replace("+", "Plus")
+ .Replace("#", "Sharp")
+ .Replace(" ", "");
+
+ _themeDictionaryContainer.MergedDictionaries.Clear();
+ _themeDictionaryContainer.MergedDictionaries.Add(new ResourceDictionary { Source = new Uri($"themes/Theme.{themeFileName}.xaml", UriKind.Relative) });
+
+ _syntaxColors.Clear();
+ ProcessDictionary(_themeDictionaryContainer);
+
+ void ProcessDictionary(ResourceDictionary resourceDictionary)
+ {
+ foreach (DictionaryEntry entry in resourceDictionary)
+ {
+ if (entry is { Key: string key, Value: SyntaxColor syntaxColor })
+ _syntaxColors.TryAdd(key, syntaxColor);
+ }
+
+ foreach (ResourceDictionary mergedDictionary in resourceDictionary.MergedDictionaries)
+ ProcessDictionary(mergedDictionary);
+ }
+ }
}
}