How to implement syntax highlighting

Questions about the LÖVE API, installing LÖVE and other support related questions go here.
Forum rules
Before you make a thread asking for help, read this.
Post Reply
User avatar
MicroMacro
Citizen
Posts: 92
Joined: Fri May 30, 2014 2:30 am
Location: Boston, MA, USA
Contact:

How to implement syntax highlighting

Post by MicroMacro »

Hi there!
I'm developing a text pad / code editor in Love2D. Here's a screenie: Image

I want to be able to highlight lua ( or other language ) keywords using a table. I have a table that looks like this: Image

How do I get a loop to go through the text of a line and find the positions of the selected text and draw it a different colour depending on what type of statement it is?

Thanks!
https://github.com/ebernerd- where you can find all my work.
User avatar
airstruck
Party member
Posts: 650
Joined: Thu Jun 04, 2015 7:11 pm
Location: Not being time thief.

Re: How to implement syntax highlighting

Post by airstruck »

You might try porting something from a similar language, like highlight.js.
User avatar
arampl
Party member
Posts: 248
Joined: Mon Oct 20, 2014 3:26 pm

Re: How to implement syntax highlighting

Post by arampl »

I'm using approach from PIL:

Code: Select all

local function Set(list)
	local set = {}
	for _, l in ipairs(list) do set[l] = true end
	return set
end

local keywords = Set{"and", "break", "do", "else", "elseif", "end", "false", "for", "function", "if", "in", "local",
												"nil", "not", "or", "repeat", "return", "then", "true", "until", "while"}

local separators	=	Set{" ", "\n", "\t", "\"", "\'", "+", "-", "*", "/", "%", "^", "#", "=", "~", "<", ">",
												"(", ")", "{", "}", "[", "]", ";", ":", ",", "."}

Text is splitted by lines in a table (and to fold blocks of code I temporarily concatenate lines into one with "\n"'s). To highlight keywords I split lines by separators to words (check string library - gmatch, gsub etc.) then check like "if keyword[curWord] then <highlight code> ...".
Not the best method but it works for me. Looks like this (WIP):
editor.png
editor.png (314.17 KiB) Viewed 4366 times
User avatar
MicroMacro
Citizen
Posts: 92
Joined: Fri May 30, 2014 2:30 am
Location: Boston, MA, USA
Contact:

Re: How to implement syntax highlighting

Post by MicroMacro »

arampl wrote:--snip--
That's what I was wondering: I did it once in the past; how do I separate words after each space?

EDIT! I GOT IT! Image

Now my next question is how do I do stuff inside of quotes?
This is how I do it now, spaces work only after one space, and tabs don't work at all. How do I fix that?

Code: Select all

for k, v in pairs( lines ) do
	local y = k * font:getHeight( " " ) + 50
	local x = 150
	for word in v:gmatch( "%S+" ) do
		if keywords[ word ] ~= nil then
			love.graphics.setColour( unpack( theme[ keywords[ word ] ] ) )
		else
			love.graphics.setColour( unpack( theme.normal ) )
		end
		if word == "__tab" then
			local tab = ""
			for i = 1, tabWidth do
				tab = tab .. " "
			end
			love.graphics.print( tab .. " ", x, y )
			x = x + font:getWidth( tab .. " " )
		else
			love.graphics.print( word .. " ", x, y )
			x = x + font:getWidth( word .. " " )
			love.graphics.setColour( 255, 255, 255 )
		end
	end
end
https://github.com/ebernerd- where you can find all my work.
User avatar
arampl
Party member
Posts: 248
Joined: Mon Oct 20, 2014 3:26 pm

Re: How to implement syntax highlighting

Post by arampl »

Text is UTF-8 so I'm using "gmatch(".[\128-\191]*")" to check for spaces, tabs, etc.
And separator for tab is ["\t"].
Quotes still not implemented fully in my code. Right now it's just switching state after each quote then checks current state.
User avatar
technomancy
Prole
Posts: 49
Joined: Thu Oct 29, 2015 8:25 am
Location: Thailand
Contact:

Re: How to implement syntax highlighting

Post by technomancy »

Looks interesting. I've got an editor of my own in my game:

https://gitlab.com/technomancy/bussard/ ... r/edit.lua
https://gitlab.com/technomancy/bussard/ ... keymap.lua
https://gitlab.com/technomancy/bussard/ ... config.lua

I'm still a ways away from implementing coloring and indentation, but I'm definitely interested in hearing more about how you do this.
User avatar
MicroMacro
Citizen
Posts: 92
Joined: Fri May 30, 2014 2:30 am
Location: Boston, MA, USA
Contact:

Re: How to implement syntax highlighting

Post by MicroMacro »

arampl wrote:Text is UTF-8 so I'm using "gmatch(".[\128-\191]*")" to check for spaces, tabs, etc.
And separator for tab is ["\t"].
Quotes still not implemented fully in my code. Right now it's just switching state after each quote then checks current state.
Arampl, would it be possible that I could get a LOVE file so I can look at how you do that? Because right now I'm a little lost. That would be much appreciated. Thank you!
https://github.com/ebernerd- where you can find all my work.
User avatar
arampl
Party member
Posts: 248
Joined: Mon Oct 20, 2014 3:26 pm

Re: How to implement syntax highlighting

Post by arampl »

OK, guys. Here you go.
You need to use LÖVE v.0.10.0 to run .love file.
Code is ugly, not consistent, uncommented, etc. It was just an experiment with GUI and text handling.

EDIT: text selection, undo/redo not implemented yet. Clipboard supported. You can also fold code then ctrl-x/c/v.
LICENSE: no license. use as if it is just a code example from some book.
Attachments
texteditor.love
requires LÖVE v.0.10.0
(306.46 KiB) Downloaded 134 times
User avatar
MicroMacro
Citizen
Posts: 92
Joined: Fri May 30, 2014 2:30 am
Location: Boston, MA, USA
Contact:

Re: How to implement syntax highlighting

Post by MicroMacro »

I couldn't understand how your highlighting really works.

The only problem with the "%S+" that I have is that I then cannot draw spaces, but if I use that ".[\128-\191]*" it separates everything by individual character. How do I get it so that I can either draw or insert spaces using %S+?
https://github.com/ebernerd- where you can find all my work.
User avatar
arampl
Party member
Posts: 248
Joined: Mon Oct 20, 2014 3:26 pm

Re: How to implement syntax highlighting

Post by arampl »

MicroMacro wrote:...if I use that ".[\128-\191]*" it separates everything by individual character. ...
Visible part of text is splitted to words by analysing each individual character. If it is one of the separators it is added to a table as a new word, else it continues to append next character to the current word. Then words from this table checked for is they are keywords or not.
MicroMacro wrote:How do I get it so that I can either draw or insert spaces using %S+?
I really don't know and don't care. I'm just satisfied with the way it works for now. Maybe using some smart patterns can improve performance, but I have other riddles to solve before diving into such optimization.

Maybe I didn't paid too much attention to all this things because this project was started for LÖVE v.0.9.2 where utf8.char was broken (it is fixed for LÖVE v.0.10.0). Maybe now it all can be made much simpler using "utf8" module since then you can use utf8's offset function, etc.
Post Reply

Who is online

Users browsing this forum: Google [Bot] and 54 guests