What I'm using right now:
numlines := strings.Count(editor.Text(), "\n")
fmt.Print(strconv.Itoa(numlines))
message.SetText(strconv.Itoa(numlines))
This is run whenever a text box is updated. What the most go-like way to do this?
If you want to get the lines of code of a single file, you can use cloc <filename>. We're using the command to get the lines of codes of a simple Vue file. It also recognized that it is a VueJS component. We can check all of the lines of code in a file or directory by the command cloc --by-file.
The only way to find the line count is to read the whole file and count the number of line-end characters. The fastest way to do this is probably to read the whole file into a large buffer with one read operation and then go through the buffer counting the '\n' characters.
That is perfectly fine. But don't forget that if the last character is not a newline character, you have to add 1 to the number of occurrences, as that will be the number of lines (the last line may not end with a newline).
What we might think is that since the substring you're counting is only a single character (a single rune
), we could create a custom solution counting only the occurrence of this single character (instead of counting substrings). It may look like this:
func countRune(s string, r rune) int {
count := 0
for _, c := range s {
if c == r {
count++
}
}
return count
}
(A for range
on a string
value iterates over its rune
s.)
And testing it (try it on the Go Playground):
fmt.Println(countRune("asdf\nasdf\nasdf\n", '\n')) // Prints 3
In practice this won't be faster counting newline characters, as that is a single byte
in UTF-8 encoding, and strings.Count()
is already optimized for counting substrings where the length of the substring is 1:
// Count counts the number of non-overlapping instances of substr in s.
// If substr is an empty string, Count returns 1 + the number of Unicode code points in s.
func Count(s, substr string) int {
if len(substr) == 1 && cpu.X86.HasPOPCNT {
return countByte(s, byte(substr[0]))
}
return countGeneric(s, substr)
}
func countByte(s string, c byte) int // ../runtime/asm_amd64.s
What could improve the performance of this operation (counting lines) is if you would have access to the "internal" byte or rune array of the editor, so you would not have to call its Text()
method, which creates and returns a copy of its content.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With