CodeMirror Line-Break doesn't add line number - Angular

1.9k Views Asked by At

I'm using code mirror from ngx-codemirror. I want to split the line when it fits to the width of the parent. I have found some solutions to split the like using,

lineWrapping: true

and in styles

.CodeMirror-wrap pre {
  word-break: break-word;
}

Using this I was able to split the line but I need to show the line number too. The line number is not shown for the line that was just split. This is the stackblitz link to my issue : code-mirror-line-break-issue

Screenshot : enter image description here

Please help me with this.

1

There are 1 best solutions below

2
On BEST ANSWER

This is not feasible using Code Mirror options, as this is something that is a bit counter intuitive that is rarely (ever?) wanted.

Like I said in my comment, say 2 persons discussing on a phone/web chat about a piece of code/json. They will not see the same thing when one mentions a line number to the other if they have different windows/screen sizes

Solution

As a hack, you can create your own elements representing line numbers and place them over the default line numbers.

Here is the stackblitz demo

Note: This a a very basic example. If you change code mirror settings (font size, gutters,...), you might need to tweak the css or do more calculation based on these settings.

component.html

<div class='codeMirrorContainer'>
  <ngx-codemirror
      #codeMirror
      [options]="codeMirrorOptions"
      [(ngModel)]="codeObj"
    ></ngx-codemirror>

<ul class='lineContainer' [style.top.px]="-topPosition">
  <li [style.width.px]='lineWidth' *ngFor="let line of lines">{{line}}</li>
</ul>
</div>

component.css

li
{
  height: 19px;
  list-style: none;
}

.codeMirrorContainer
{
  position:relative;
  overflow: hidden;
}

.lineContainer
{
  position:absolute;
  top:0;
  left:0;
  margin: 0;
    padding: 5px 0 0 0;
  text-align: center;
  
}

::ng-deep .CodeMirror-linenumber
{
  visibility: hidden; /* Hides default line numbers */
}

component.ts

export class AppComponent
{


  @ViewChild('codeMirror') codeMirrorCmpt: CodemirrorComponent;

  private lineHeight: number;
  public lineWidth;

  public topPosition: number;
  public lines = [];

  codeMirrorOptions: any = ....;
  codeObj :any = ...;

  constructor(private cdr: ChangeDetectorRef)
  {
  }



  ngAfterViewInit()
  {
    this.codeMirrorCmpt.codeMirror.on('refresh', () => this.refreshLines());
    this.codeMirrorCmpt.codeMirror.on('scroll', () => this.refreshLines());
    setTimeout(() => this.refreshLines(), 500)

  }


  refreshLines()
  {
    let editor = this.codeMirrorCmpt.codeMirror;
    let height = editor.doc.height;
    this.lineHeight = editor.display.cachedTextHeight ? editor.display.cachedTextHeight : this.lineHeight;
    if (!this.lineHeight)
    {
      return;
    }
    let nbLines = Math.round(height / this.lineHeight);
    this.lines = Array(nbLines).fill(0).map((v, idx) => idx + 1);
    this.lineWidth = editor.display.lineNumWidth;
    this.topPosition = document.querySelector('.CodeMirror-scroll').scrollTop;
    this.cdr.detectChanges();

  }


}