@@ -81,6 +81,40 @@ public bool WarnSubjectLength
8181 set => SetAndRaise ( WarnSubjectLengthProperty , ref _warnSubjectLen , value ) ;
8282 }
8383
84+ public static readonly DirectProperty < CommitMessageTextBox , int > DescriptionLengthProperty =
85+ AvaloniaProperty . RegisterDirect < CommitMessageTextBox , int > (
86+ nameof ( DescriptionLength ) ,
87+ static o => o . DescriptionLength ) ;
88+
89+ public int DescriptionLength
90+ {
91+ get => _descriptionLen ;
92+ set => SetAndRaise ( DescriptionLengthProperty , ref _descriptionLen , value ) ;
93+ }
94+
95+ public static readonly DirectProperty < CommitMessageTextBox , int > DescriptionGuideLengthProperty =
96+ AvaloniaProperty . RegisterDirect < CommitMessageTextBox , int > (
97+ nameof ( DescriptionGuideLength ) ,
98+ static o => o . DescriptionGuideLength ,
99+ static ( o , v ) => o . DescriptionGuideLength = v ) ;
100+
101+ public int DescriptionGuideLength
102+ {
103+ get => _descriptionGuideLen ;
104+ set => SetAndRaise ( DescriptionGuideLengthProperty , ref _descriptionGuideLen , value ) ;
105+ }
106+
107+ public static readonly DirectProperty < CommitMessageTextBox , bool > WarnDescriptionLengthProperty =
108+ AvaloniaProperty . RegisterDirect < CommitMessageTextBox , bool > (
109+ nameof ( WarnDescriptionLength ) ,
110+ static o => o . WarnDescriptionLength ) ;
111+
112+ public bool WarnDescriptionLength
113+ {
114+ get => _warnDescriptionLen ;
115+ set => SetAndRaise ( WarnDescriptionLengthProperty , ref _warnDescriptionLen , value ) ;
116+ }
117+
84118 public static readonly DirectProperty < CommitMessageTextBox , List < CommitMessageTextBoxSuggestion > > SuggestionsProperty =
85119 AvaloniaProperty . RegisterDirect < CommitMessageTextBox , List < CommitMessageTextBoxSuggestion > > (
86120 nameof ( Suggestions ) ,
@@ -173,7 +207,7 @@ public override void Render(DrawingContext context)
173207 new Typeface ( font ) ,
174208 ViewModels . Preferences . Instance . DefaultFontSize ,
175209 Brushes . White ) ;
176- var columnGuideX = columnTest . WidthIncludingTrailingWhitespace * 80 + 5.5 ;
210+ var columnGuideX = columnTest . WidthIncludingTrailingWhitespace * _descriptionGuideLen + 5.5 ;
177211 context . DrawLine ( pen , new Point ( columnGuideX , Math . Max ( 0 , y ) ) , new Point ( columnGuideX , Bounds . Height ) ) ;
178212 }
179213
@@ -209,10 +243,12 @@ protected override void OnPropertyChanged(AvaloniaPropertyChangedEventArgs chang
209243 {
210244 _subjectEndCharIdx = - 1 ;
211245 SubjectLength = 0 ;
246+ DescriptionLength = 0 ;
212247 return ;
213248 }
214249
215250 var subjectLen = 0 ;
251+ var descriptionLen = 0 ;
216252 var lastNonLineBreakCharIdx = 0 ;
217253 var lastLineStart = 0 ;
218254 for ( var i = 0 ; i < text . Length ; i ++ )
@@ -226,7 +262,10 @@ protected override void OnPropertyChanged(AvaloniaPropertyChangedEventArgs chang
226262 if ( string . IsNullOrWhiteSpace ( line ) )
227263 {
228264 if ( subjectLen > 0 )
265+ {
266+ descriptionLen = GetMaxLineLength ( text , lastLineStart ) ;
229267 break ;
268+ }
230269
231270 continue ;
232271 }
@@ -253,12 +292,18 @@ protected override void OnPropertyChanged(AvaloniaPropertyChangedEventArgs chang
253292 }
254293
255294 SubjectLength = subjectLen ;
295+ DescriptionLength = descriptionLen ;
256296 _subjectEndCharIdx = lastNonLineBreakCharIdx ;
257297 }
258298 else if ( change . Property == SubjectLengthProperty || change . Property == SubjectGuideLengthProperty )
259299 {
260300 WarnSubjectLength = _subjectLen > _subjectGuideLen ;
261301 }
302+ else if ( change . Property == DescriptionLengthProperty || change . Property == DescriptionGuideLengthProperty )
303+ {
304+ WarnDescriptionLength = _descriptionLen > _descriptionGuideLen ;
305+ InvalidateVisual ( ) ;
306+ }
262307 else if ( change . Property == SubjectEndYProperty )
263308 {
264309 InvalidateVisual ( ) ;
@@ -377,6 +422,28 @@ protected override void OnKeyDown(KeyEventArgs e)
377422 base . OnKeyDown ( e ) ;
378423 }
379424
425+ private static int GetMaxLineLength ( string text , int start )
426+ {
427+ var maxLen = 0 ;
428+ var lineStart = start ;
429+ for ( var i = start ; i <= text . Length ; i ++ )
430+ {
431+ if ( i == text . Length || text [ i ] == '\n ' )
432+ {
433+ var lineLen = i - lineStart ;
434+ while ( lineLen > 0 && char . IsWhiteSpace ( text [ lineStart + lineLen - 1 ] ) )
435+ lineLen -- ;
436+
437+ if ( lineLen > maxLen )
438+ maxLen = lineLen ;
439+
440+ lineStart = i + 1 ;
441+ }
442+ }
443+
444+ return maxLen ;
445+ }
446+
380447 private void OnLayoutUpdated ( object sender , EventArgs e )
381448 {
382449 if ( _textPresenter == null || ! IsEffectivelyVisible )
@@ -447,6 +514,9 @@ private void OnLayoutUpdated(object sender, EventArgs e)
447514 private int _subjectEndCharIdx = - 1 ;
448515 private double _subjectEndY = 0 ;
449516 private bool _warnSubjectLen = false ;
517+ private int _descriptionLen = 0 ;
518+ private int _descriptionGuideLen = 80 ;
519+ private bool _warnDescriptionLen = false ;
450520 private int _suggestionMatchStartIdx = - 1 ;
451521 private List < CommitMessageTextBoxSuggestion > _suggestions = null ;
452522 private int _selectedSuggestionIdx = 0 ;
0 commit comments