2828import org .eclipse .jface .internal .text .codemining .CodeMiningLineHeaderAnnotation ;
2929
3030import org .eclipse .jface .text .ITextViewer ;
31+ import org .eclipse .jface .text .Position ;
3132import org .eclipse .jface .text .source .Annotation ;
3233import org .eclipse .jface .text .source .AnnotationPainter .IDrawingStrategy ;
3334
@@ -154,7 +155,8 @@ public static void draw(AbstractInlinedAnnotation annotation, GC gc, StyledText
154155 private static void draw (LineHeaderAnnotation annotation , GC gc , StyledText textWidget , int offset , int length ,
155156 Color color ) {
156157 int line = textWidget .getLineAtOffset (offset );
157- if (isDeleted (annotation )) {
158+ int charCount = textWidget .getCharCount ();
159+ if (isDeleted (annotation , charCount )) {
158160 // When annotation is deleted, update metrics to null to remove extra spaces of the line header annotation.
159161 if (textWidget .getLineVerticalIndent (line ) > 0 )
160162 textWidget .setLineVerticalIndent (line , 0 );
@@ -180,9 +182,16 @@ private static void draw(LineHeaderAnnotation annotation, GC gc, StyledText text
180182 textWidget .setLineVerticalIndent (line , 0 );
181183 }
182184 // Compute the location of the annotation
183- Rectangle bounds = textWidget .getTextBounds (offset , offset );
184- int x = bounds .x ;
185- int y = bounds .y ;
185+ int x , y ;
186+ if (offset < charCount ) {
187+ Rectangle bounds = textWidget .getTextBounds (offset , offset );
188+ x = bounds .x ;
189+ y = bounds .y ;
190+ } else {
191+ Point locAtOff = textWidget .getLocationAtOffset (offset );
192+ x = locAtOff .x ;
193+ y = locAtOff .y - height ;
194+ }
186195 // Draw the line header annotation
187196 gc .setBackground (textWidget .getBackground ());
188197 annotation .setLocation (x , y );
@@ -193,7 +202,11 @@ private static void draw(LineHeaderAnnotation annotation, GC gc, StyledText text
193202 Rectangle client = textWidget .getClientArea ();
194203 textWidget .redraw (0 , bounds .y , client .width , bounds .height , false );
195204 } else {
196- textWidget .redrawRange (offset , length , true );
205+ if (offset >= charCount ) {
206+ textWidget .redrawRange (charCount - 1 , 1 , true );
207+ } else {
208+ textWidget .redrawRange (offset , length , true );
209+ }
197210 }
198211 }
199212
@@ -212,7 +225,11 @@ private static void draw(LineContentAnnotation annotation, GC gc, StyledText tex
212225 Color color ) {
213226 if (annotation instanceof CodeMiningLineContentAnnotation a ) {
214227 if (a .isAfterPosition ()) {
215- drawAsLeftOf1stCharacter (annotation , gc , textWidget , widgetOffset , length , color );
228+ if (widgetOffset < textWidget .getCharCount ()) {
229+ drawAsLeftOf1stCharacter (annotation , gc , textWidget , widgetOffset , length , color );
230+ } else {
231+ drawAtEndOfDocumentInFirstColumn (annotation , gc , textWidget , widgetOffset , length , color );
232+ }
216233 return ;
217234 }
218235 }
@@ -226,7 +243,7 @@ private static void draw(LineContentAnnotation annotation, GC gc, StyledText tex
226243 }
227244
228245 private static void drawAfterLine (LineContentAnnotation annotation , GC gc , StyledText textWidget , int widgetOffset , int length , Color color ) {
229- if (isDeleted (annotation )) {
246+ if (isDeleted (annotation , textWidget . getCharCount () )) {
230247 return ;
231248 }
232249 if (gc != null ) {
@@ -247,14 +264,38 @@ private static void drawAfterLine(LineContentAnnotation annotation, GC gc, Style
247264 }
248265 }
249266
267+ private static void drawAtEndOfDocumentInFirstColumn (LineContentAnnotation annotation , GC gc , StyledText textWidget , int widgetOffset , int length , Color color ) {
268+ if (isDeleted (annotation , textWidget .getCharCount ())) {
269+ return ;
270+ }
271+ if (gc != null ) {
272+ Point locAtOff = textWidget .getLocationAtOffset (widgetOffset );
273+ int x = locAtOff .x ;
274+ int y = locAtOff .y ;
275+ annotation .setLocation (x , y );
276+ annotation .draw (gc , textWidget , widgetOffset , length , color , x , y );
277+ int width = annotation .getWidth ();
278+ if (width != 0 ) {
279+ if (!gc .getClipping ().contains (x , y )) {
280+ Rectangle client = textWidget .getClientArea ();
281+ int height = textWidget .getLineHeight ();
282+ textWidget .redraw (x , y , client .width , height , false );
283+ }
284+ }
285+ } else {
286+ int charCount = textWidget .getCharCount ();
287+ textWidget .redrawRange (charCount - 1 , 1 , true );
288+ }
289+ }
290+
250291 protected static void drawAsLeftOf1stCharacter (LineContentAnnotation annotation , GC gc , StyledText textWidget , int widgetOffset , int length , Color color ) {
251292 StyleRange style = null ;
252293 try {
253294 style = textWidget .getStyleRangeAtOffset (widgetOffset );
254295 } catch (Exception e ) {
255296 return ;
256297 }
257- if (isDeleted (annotation )) {
298+ if (isDeleted (annotation , textWidget . getCharCount () )) {
258299 // When annotation is deleted, update metrics to null to remove extra spaces of the line content annotation.
259300 if (style != null && style .metrics != null ) {
260301 style .metrics = null ;
@@ -369,7 +410,7 @@ protected static void drawAsRightOfPreviousCharacter(LineContentAnnotation annot
369410 } catch (Exception e ) {
370411 return ;
371412 }
372- if (isDeleted (annotation )) {
413+ if (isDeleted (annotation , textWidget . getCharCount () )) {
373414 // When annotation is deleted, update metrics to null to remove extra spaces of the line content annotation.
374415 if (style != null && style .metrics != null ) {
375416 style .metrics = null ;
@@ -449,7 +490,17 @@ protected static void drawAsRightOfPreviousCharacter(LineContentAnnotation annot
449490 * @param annotation the inlined annotation to check
450491 * @return <code>true</code> if inlined annotation is deleted and <code>false</code> otherwise.
451492 */
452- private static boolean isDeleted (AbstractInlinedAnnotation annotation ) {
453- return annotation .isMarkedDeleted () || annotation .getPosition ().isDeleted () || annotation .getPosition ().getLength () == 0 ;
493+ private static boolean isDeleted (AbstractInlinedAnnotation annotation ,int maxOffset ) {
494+ if (annotation .isMarkedDeleted ()) {
495+ return true ;
496+ }
497+ Position pos = annotation .getPosition ();
498+ if (pos .isDeleted ()) {
499+ return true ;
500+ }
501+ if (pos .getLength () == 0 && pos .getOffset () < maxOffset ) {
502+ return true ;
503+ }
504+ return false ;
454505 }
455506}
0 commit comments