# TextArea - LinenumAtCharPos etc.

**URL:** <https://forum.xojo.com/t/textarea-linenumatcharpos-etc/46225>\
**Category:** General\
**Created:** [November 12, 2018, 10:20pm UTC](https://forum.xojo.com/t/textarea-linenumatcharpos-etc/46225 "2018-11-12T22:20:59Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![DaveS](https://forum.xojo.com/letter_avatar_proxy/v4/letter/d/848f3c/32.png) [@DaveS](https://forum.xojo.com/u/DaveS)\
**Post date:** [November 12, 2018, 10:20pm UTC](https://forum.xojo.com/t/textarea-linenumatcharpos-etc/46225/1 "2018-11-12T22:20:59Z")

</div>

Correct me if I’m wrong… but I _thought_ that LineNumAtCharPos returned the linenumber at char position 🙂 … by this I mean if you have a Really long line that wraps in the textarea… and you click in the middle… it should return the linenumber of the beginning of the line … as in… “the character you just selected in on the physical line that is X number of linebreaks from the beginning of the document”

What I am seeing is each wrap is counted… so if the TextArea can show 50 characters wide and your text is 300 characters (no EOL), then it counts as 6, when it should count as 1…

What I am trying to do it go down the left side of a text area and paint line numbers into a canvas

Paint Event of Canvas

```auto
lastLine=(-1)
		for y=0 to g.Height step h
				cp=theEditor.CharPosAtXY(1,y)
				lineNum = theEditor.LineNumAtCharPos(cp)
				if lastLine<>lineNum then g.DrawString str(linenum),1,y+g.TextAscent
lastLine=lineNum
		next y
```

but it is writing a number on each row, when I know the text is wrapped…

So the question is… am I doing something wrong? or is my method flawed because the function doesn work like I thought it did.

Basically “what is a line” in this context?

---

<div class="post-metadata">

**Author:** ![Tim\_Hare](https://forum.xojo.com/user_avatar/forum.xojo.com/tim_hare/32/176_2.png) [@Tim\_Hare](https://forum.xojo.com/u/Tim_Hare)\
**Post date:** [November 12, 2018, 11:07pm UTC](https://forum.xojo.com/t/textarea-linenumatcharpos-etc/46225/2 "2018-11-12T23:07:40Z")

</div>

The function does not do what you think it does. It returns the line # of the textarea, not the line # of the text.

---

<div class="post-metadata">

**Author:** ![Tim\_Hare](https://forum.xojo.com/user_avatar/forum.xojo.com/tim_hare/32/176_2.png) [@Tim\_Hare](https://forum.xojo.com/u/Tim_Hare)\
**Post date:** [November 12, 2018, 11:08pm UTC](https://forum.xojo.com/t/textarea-linenumatcharpos-etc/46225/3 "2018-11-12T23:08:41Z")

</div>

Or as Inigo Montoya would say, You keep using that function. I do not think it does what you think it does.

---

<div class="post-metadata">

**Author:** ![DaveS](https://forum.xojo.com/letter_avatar_proxy/v4/letter/d/848f3c/32.png) [@DaveS](https://forum.xojo.com/u/DaveS)\
**Post date:** [November 12, 2018, 11:10pm UTC](https://forum.xojo.com/t/textarea-linenumatcharpos-etc/46225/4 "2018-11-12T23:10:18Z")

</div>

> [@413988:@Tim Hare](#):
>
> The function does not do what you think it does. It returns the line # of the textarea, not the line # of the text.

came to that sad realization… What a TA considers a line is the text the fits left to right in the view… Where a Paragraph is the entity that I think I need… but the only way to do that is to count from the beginning of the document each time… and that can be slow… since most of the “paragraphs” will be one “line”

---

<div class="post-metadata">

**Author:** ![DaveS](https://forum.xojo.com/letter_avatar_proxy/v4/letter/d/848f3c/32.png) [@DaveS](https://forum.xojo.com/u/DaveS)\
**Post date:** [November 12, 2018, 11:12pm UTC](https://forum.xojo.com/t/textarea-linenumatcharpos-etc/46225/5 "2018-11-12T23:12:41Z")

</div>

this is what I wanted to do… and this was done with a NSTextView (which is supposedly what a TextArea for macOS is)

![](https://raw.githubusercontent.com/yichizhang/NSTextView-LineNumberView/master/screenshot.png)

---

<div class="post-metadata">

**Author:** ![Markus\_Winter](https://forum.xojo.com/user_avatar/forum.xojo.com/markus_winter/32/144_2.png) [@Markus\_Winter](https://forum.xojo.com/u/Markus_Winter)\
**Post date:** [November 12, 2018, 11:38pm UTC](https://forum.xojo.com/t/textarea-linenumatcharpos-etc/46225/6 "2018-11-12T23:38:23Z")

</div>

You want to count paragraphs, not lines. The function is called LineNumAtCharPos. The problem is not the function but your perception.

---

<div class="post-metadata">

**Author:** ![Tim\_Parnell](https://forum.xojo.com/user_avatar/forum.xojo.com/tim_parnell/32/161_2.png) [@Tim\_Parnell](https://forum.xojo.com/u/Tim_Parnell)\
**Post date:** [November 12, 2018, 11:41pm UTC](https://forum.xojo.com/t/textarea-linenumatcharpos-etc/46225/7 "2018-11-12T23:41:58Z")

</div>

You may need TextInputCanvas which extends beyond the basic functionality of TextArea.

---

<div class="post-metadata">

**Author:** ![AlbertoD](https://forum.xojo.com/letter_avatar_proxy/v4/letter/a/dbc845/32.png) [@AlbertoD](https://forum.xojo.com/u/AlbertoD)\
**Post date:** [November 13, 2018, 12:48am UTC](https://forum.xojo.com/t/textarea-linenumatcharpos-etc/46225/8 "2018-11-13T00:48:48Z")

</div>

I was going to say that you could InStr EndOfLine and check in which row there is an EndOfLine so you could only write a line number after that.

But after some tests, I think there is a bug with LineNumAtCharPos. From [https://documentation.xojo.com/index.php/TextEdit.LineNumAtCharPos](https://documentation.xojo.com/index.php/TextEdit.LineNumAtCharPos)

[quote]Characters are numbered consecutively with the first character numbered 1. The first line is numbered zero. Used with ScrollPosition, this lets you scroll the control to a particular place in the text.

The line number reflects line breaks from both hard line breaks in the text and soft line breaks caused by word-wrapping within the control.[/quote]

I made a sample project with 1 TextArea, 1 Listbox and 1 PushButton, on TextArea Open event:

```auto
me.Text = EndOfLine + EndOfLine + EndOfLine + EndOfLine
```

On PushButton Action event:

`Listbox1.DeleteAllRows
Listbox1.AddRow(TextArea1.LineNumAtCharPos(1).ToText)
Listbox1.AddRow(TextArea1.LineNumAtCharPos(2).ToText)
Listbox1.AddRow(TextArea1.LineNumAtCharPos(3).ToText)
Listbox1.AddRow(TextArea1.LineNumAtCharPos(4).ToText)`

By reading the docs, I expected:

`0
1
2
3`

On Mac I get:

`0
0
1
2`

On Windows I get:

`0
1
2
3`

On Linux I get:

`1
2
3
4`

---

<div class="post-metadata">

**Author:** ![DaveS](https://forum.xojo.com/letter_avatar_proxy/v4/letter/d/848f3c/32.png) [@DaveS](https://forum.xojo.com/u/DaveS)\
**Post date:** [November 13, 2018, 1:52am UTC](https://forum.xojo.com/t/textarea-linenumatcharpos-etc/46225/9 "2018-11-13T01:52:41Z")

</div>

> [@414004:@Markus Winter](#):
>
> You want to count paragraphs, not lines. The function is called LineNumAtCharPos. The problem is not the function but your perception.

Yes I want to count paragraphs (as I said above)… but there is no function to do so, with out counting from the beginning every time[quote=414018:@Alberto De Poo] and soft line breaks caused by word-wrapping[/quote]  
Alberto… its the “soft breaks” the make this “difficult”

---

<div class="post-metadata">

**Author:** ![AlbertoD](https://forum.xojo.com/letter_avatar_proxy/v4/letter/a/dbc845/32.png) [@AlbertoD](https://forum.xojo.com/u/AlbertoD)\
**Post date:** [November 13, 2018, 4:20am UTC](https://forum.xojo.com/t/textarea-linenumatcharpos-etc/46225/10 "2018-11-13T04:20:03Z")

</div>

You want to do something like this?  
 ![](https://media.giphy.com/media/1nPJ4oLZSexXAeobGl/giphy.gif)  
I don’t have experience with canvas so I used 2 TextAreas

---

<div class="post-metadata">

**Author:** ![DaveS](https://forum.xojo.com/letter_avatar_proxy/v4/letter/d/848f3c/32.png) [@DaveS](https://forum.xojo.com/u/DaveS)\
**Post date:** [November 13, 2018, 4:38am UTC](https://forum.xojo.com/t/textarea-linenumatcharpos-etc/46225/11 "2018-11-13T04:38:43Z")

</div>

well yeah… although the synch is kind of off… show me what you did? Perhaps I can make something more of it

---

<div class="post-metadata">

**Author:** ![AlbertoD](https://forum.xojo.com/letter_avatar_proxy/v4/letter/a/dbc845/32.png) [@AlbertoD](https://forum.xojo.com/u/AlbertoD)\
**Post date:** [November 13, 2018, 6:00am UTC](https://forum.xojo.com/t/textarea-linenumatcharpos-etc/46225/12 "2018-11-13T06:00:23Z")

</div>

Well, I put the code on resized and not resizing and I did it on Windows because of the bug I mentioned above. Also Windows has a bug with line endings on TextAreas, instead of 0D0A they are just 0D, that’s why I use EndOfLine.Macintosh there.

I’m sure you can make a much better code, basically what I did:

- Use InStr(TextArea2.Text, EndOfLine.Macintosh) to find the first char that is EndOfLine
- Check in what row (line) is in the TextArea
- Put EOL on TextArea1 (left) to have blanks
- Have a counter to know when is paragraph 2, 3 and so on

The code is:

[code]TextArea1.Text = “”  
// using EndOfLine.Macintosh because the TextAreas on Windows just use 0D and not 0D0A  
Dim charPos As Integer = InStr(TextArea2.Text, EndOfLine.Macintosh)  
Dim cp As Integer = 1  
Dim linea As Integer  
Dim ln As Integer = 1

// write 1 in the first row always  
TextArea1.AppendText(cp.ToText)

While charPos \> 0  
// found and EOL, we have another paragraph  
cp = cp + 1  
// find in which line (row) is the EndOfLine (0 based)  
ln = TextArea2.LineNumAtCharPos(charPos) + 1  
// I start at linea + 1 to Append an EOL to the number on TextArea1  
For j As Integer = linea + 1 To ln  
// add EOL  
TextArea1.AppendText(EndOfLine.Macintosh)  
linea = j  
Next  
// Append the paragraph number  
TextArea1.AppendText(cp.ToText)  
// find another EOL  
charPos = InStr(charPos+1,TextArea2.Text,EndOfLine.Macintosh)  
Wend[/code]

I just changed the code to make it work around the mac bug, it makes sure that is not putting 2 numbers in the same line (at least an EOL between them):

[code]TextArea1.Text = “”  
Dim charPos As Integer = InStr(TextArea2.Text, EndOfLine)  
Dim cp As Integer = 1  
Dim linea,lineaorig As Integer  
Dim ln As Integer = 1  
Dim ciclo As Integer

TextArea1.AppendText(cp.ToText)

While charPos \> 0  
cp = cp + 1  
ln = TextArea2.LineNumAtCharPos(charPos) + 1  
// make sure we don’t append a number to another number, must be at least 1 EOL (mac bug)  
If ln = lineaorig Then ln = ln +1  
lineaorig = ln  
For j As Integer = linea + 1 To ln  
TextArea1.AppendText(EndOfLine)  
linea = j  
Next  
TextArea1.AppendText(cp.ToText)  
charPos = InStr(charPos+1,TextArea2.Text,EndOfLine)  
Wend[/code]

Because Linux start with 1 instead of 0, the code will need to change to make it work. I’ll report the bug tomorrow.

Please be kind, the code works (in my tests), but I don’t have much experience, I bet it can be cleaned/fixed.

Edit: I put the code on a Method, now I call that too from TextArea2 TextChange event. On Linux when I paste the paragraphs the numbers on the left are in wrong position, if I add a return after the paste or resize the window then the numbers are set correctly. This doesn’t happen with Windows or Mac.

---

<div class="post-metadata">

**Author:** ![AlbertoD](https://forum.xojo.com/letter_avatar_proxy/v4/letter/a/dbc845/32.png) [@AlbertoD](https://forum.xojo.com/u/AlbertoD)\
**Post date:** [November 13, 2018, 6:34am UTC](https://forum.xojo.com/t/textarea-linenumatcharpos-etc/46225/13 "2018-11-13T06:34:38Z")

</div>

I changed the code to make it work on Windows, Mac and Linux. On a quick test it worked:

[code]TextArea1.Text = “”  
#If TargetWindows Then  
// TextAreas on Windows use EndOfLine.Macintosh and not the standard Windows EndOfLine  
Dim EOL As String = EndOfLine.Macintosh  
#Else  
Dim EOL As String = EndOfLine  
#EndIf  
Dim charPos As Integer = InStr(TextArea2.Text, EOL)  
Dim cp As Integer = 1  
Dim linea,lineaorig As Integer  
Dim ln As Integer = 1  
Dim ciclo As Integer

TextArea1.AppendText(cp.ToText)

While charPos \> 0  
cp = cp + 1  
#If TargetLinux Then  
// it looks like on LInux it is 1 based  
ln = TextArea2.LineNumAtCharPos(charPos)  
#Else  
// Windows and Mac is 0 based  
ln = TextArea2.LineNumAtCharPos(charPos) + 1  
#EndIf  
#If TargetMacOS Then  
If ln = lineaorig Then ln = ln +1  
lineaorig = ln  
#EndIf  
For j As Integer = linea + 1 To ln  
TextArea1.AppendText(EOL)  
linea = j  
Next  
TextArea1.AppendText(cp.ToText)  
charPos = InStr(charPos+1,TextArea2.Text,EOL)  
Wend[/code]

---

<div class="post-metadata">

**Author:** ![Tim\_Hare](https://forum.xojo.com/user_avatar/forum.xojo.com/tim_hare/32/176_2.png) [@Tim\_Hare](https://forum.xojo.com/u/Tim_Hare)\
**Post date:** [November 13, 2018, 8:01am UTC](https://forum.xojo.com/t/textarea-linenumatcharpos-etc/46225/14 "2018-11-13T08:01:57Z")

</div>

> [@414057:@Alberto De Poo](#):
>
> Windows has a bug with line endings on TextAreas, instead of 0D0A they are just 0D

That’s by design and documented.

---

<div class="post-metadata">

**Author:** ![AlbertoD](https://forum.xojo.com/letter_avatar_proxy/v4/letter/a/dbc845/32.png) [@AlbertoD](https://forum.xojo.com/u/AlbertoD)\
**Post date:** [November 13, 2018, 12:54pm UTC](https://forum.xojo.com/t/textarea-linenumatcharpos-etc/46225/15 "2018-11-13T12:54:34Z")

</div>

> [@414066:@Tim Hare](#):
>
> That’s by design and documented.

Sorry, didn’t know that and I can’t find where it say that. I’ll search again.

Maybe because I filed a bug report with 2 entries they just said verified and I assumed there is a bug on Windows TextArea:  
\<[https://xojo.com/issue/53606](https://xojo.com/issue/53606)\>  
From that bug report:

- if you use EndOfLine.Windows on. a Windows TextArea, instead of 0D0A only 0D is used
- if you use EndOfLine.Unix on a Windows TextArea, instead of 0A, only 0D is used  
On Mac and Linux:
- if you use EndOfLine.Windows on a TextArea, 0D0A is used
- if you use EndOfLine.Unix on a TextArea, 0A is used

I will report the bug above in 2 cases, one for Mac and one for Linux

---

<div class="post-metadata">

**Author:** ![DaveS](https://forum.xojo.com/letter_avatar_proxy/v4/letter/d/848f3c/32.png) [@DaveS](https://forum.xojo.com/u/DaveS)\
**Post date:** [November 13, 2018, 3:17pm UTC](https://forum.xojo.com/t/textarea-linenumatcharpos-etc/46225/16 "2018-11-13T15:17:37Z")

</div>

Ok… I woke up in the middle of the night and realized that I was making a major mis-assumption is my requirements.

- The textarea SHOULD not wrap to begin with. Now that will obviously make determining linenumbers much easier.  
but that now begs a follow on question.

Since the scroll events for a TextArea are not exposed (ie. Valuechanged) has anyone figured out a way to

- disable the built in TextArea Scrollbars
- but still maintain WordWrap = FALSE
- and use an external HScroll and VScroll that remains properly synced to the TextArea

To make it easier the TextArea will ALWAYS (in this situation) contain a single size, mono-spaced font.

---

<div class="post-metadata">

**Author:** ![AlbertoD](https://forum.xojo.com/letter_avatar_proxy/v4/letter/a/dbc845/32.png) [@AlbertoD](https://forum.xojo.com/u/AlbertoD)\
**Post date:** [November 13, 2018, 3:40pm UTC](https://forum.xojo.com/t/textarea-linenumatcharpos-etc/46225/17 "2018-11-13T15:40:41Z")

</div>

If I understand correctly, you want something like the IDE code editor, right?  
 ![](https://image.ibb.co/n95vs0/IDE.jpg)

Edit: Sorry I can’t help you with that, too complex for me at this time.

---

<div class="post-metadata">

**Author:** ![DaveS](https://forum.xojo.com/letter_avatar_proxy/v4/letter/d/848f3c/32.png) [@DaveS](https://forum.xojo.com/u/DaveS)\
**Post date:** [November 13, 2018, 3:48pm UTC](https://forum.xojo.com/t/textarea-linenumatcharpos-etc/46225/18 "2018-11-13T15:48:17Z")

</div>

[quote=414102:@Alberto De Poo]If I understand correctly, you want something like the IDE code editor, right?  
[/quote]  
exactly… the syntax highlighting part I have handled… the code folding I will do without

and CustomEditField is not an option… it won’t survive thru the next macOS without a major overhaul

---

<div class="post-metadata">

**Author:** ![Jason\_Parsley](https://forum.xojo.com/user_avatar/forum.xojo.com/jason_parsley/32/152_2.png) [@Jason\_Parsley](https://forum.xojo.com/u/Jason_Parsley)\
**Post date:** [November 13, 2018, 6:26pm UTC](https://forum.xojo.com/t/textarea-linenumatcharpos-etc/46225/19 "2018-11-13T18:26:39Z")

</div>

Maybe a TextInputCanvas. While it means you have to draw everything yourself, it gives you the control to do whatever you want _and_ handles the various input mechanisms on macOS, Windows & Linux.

TextInputCanvas can be found here:

[https://github.com/xojo/TextInputCanvas](https://github.com/xojo/TextInputCanvas)

---

<div class="post-metadata">

**Author:** ![DaveS](https://forum.xojo.com/letter_avatar_proxy/v4/letter/d/848f3c/32.png) [@DaveS](https://forum.xojo.com/u/DaveS)\
**Post date:** [November 13, 2018, 6:30pm UTC](https://forum.xojo.com/t/textarea-linenumatcharpos-etc/46225/20 "2018-11-13T18:30:56Z")

</div>

I am assuming that is the magic control that everyone talks about, but for which there is no documentation or examples

[Next page](https://forum.xojo.com/t/textarea-linenumatcharpos-etc/46225.md?page=2)
