From cb610055d0be81ef8de7c9ea4881981351d2d34d Mon Sep 17 00:00:00 2001 From: liquidev Date: Wed, 26 May 2021 19:16:56 +0200 Subject: [PATCH] support for font changing in the syntax highlighter --- changelog.md | 13 ++++++++++++ data/core/docview.lua | 47 +++++++++++++++++++++++++++++-------------- data/core/style.lua | 7 +++++++ 3 files changed, 52 insertions(+), 15 deletions(-) diff --git a/changelog.md b/changelog.md index 19e0522e..4c72c929 100644 --- a/changelog.md +++ b/changelog.md @@ -2,6 +2,19 @@ Lite XL is following closely [rxi/lite](https://github.com/rxi/lite) but with so This files document the changes done in Lite XL for each release. +### 1.16.11 + +[#126](https://github.com/franko/lite-xl/issues/126): Implemented changing fonts per syntax group. +Example user module snippet that makes all comments italic: + +```lua +local style = require "core.style" + +-- italic.ttf must be provided by the user +local italic = renderer.font.load("italic.ttf", 14) +style.syntax_fonts["comment"] = italic +``` + ### 1.16.10 Improved syntax highlight system thanks to @liquidev and @adamharrison. diff --git a/data/core/docview.lua b/data/core/docview.lua index 68b242f3..070ee0c4 100644 --- a/data/core/docview.lua +++ b/data/core/docview.lua @@ -141,29 +141,45 @@ end function DocView:get_col_x_offset(line, col) - local text = self.doc.lines[line] - if not text then return 0 end - return self:get_font():get_width(text:sub(1, col - 1)) + local default_font = self:get_font() + local column = 1 + local xoffset = 0 + for _, type, text in self.doc.highlighter:each_token(line) do + local font = style.syntax_fonts[type] or default_font + for char in common.utf8_chars(text) do + if column == col then + return xoffset / font:subpixel_scale() + end + xoffset = xoffset + font:get_width_subpixel(char) + column = column + #char + end + end + + return xoffset / default_font:subpixel_scale() end function DocView:get_x_offset_col(line, x) - local text = self.doc.lines[line] + local line_text = self.doc.lines[line] local xoffset, last_i, i = 0, 1, 1 - local subpixel_scale = self:get_font():subpixel_scale(); + local default_font = self:get_font() + local subpixel_scale = default_font:subpixel_scale() local x_subpixel = subpixel_scale * x + subpixel_scale / 2 - for char in common.utf8_chars(text) do - local w = self:get_font():get_width_subpixel(char) - if xoffset >= subpixel_scale * x then - return (xoffset - x_subpixel > w / 2) and last_i or i + for _, type, text in self.doc.highlighter:each_token(line) do + local font = style.syntax_fonts[type] or default_font + for char in common.utf8_chars(text) do + local w = font:get_width_subpixel(char) + if xoffset >= subpixel_scale * x then + return (xoffset - x_subpixel > w / 2) and last_i or i + end + xoffset = xoffset + w + last_i = i + i = i + #char end - xoffset = xoffset + w - last_i = i - i = i + #char end - return #text + return #line_text end @@ -308,11 +324,12 @@ end function DocView:draw_line_text(idx, x, y) - local font = self:get_font() - local subpixel_scale = font:subpixel_scale() + local default_font = self:get_font() + local subpixel_scale = default_font:subpixel_scale() local tx, ty = subpixel_scale * x, y + self:get_line_text_y_offset() for _, type, text in self.doc.highlighter:each_token(idx) do local color = style.syntax[type] + local font = style.syntax_fonts[type] or default_font if config.draw_whitespace then tx = renderer.draw_text_subpixel(font, text, tx, ty, color, core.replacements, style.syntax.comment) else diff --git a/data/core/style.lua b/data/core/style.lua index bce8c07e..7001cdc1 100644 --- a/data/core/style.lua +++ b/data/core/style.lua @@ -57,4 +57,11 @@ style.syntax["string"] = { common.color "#f7c95c" } style.syntax["operator"] = { common.color "#93DDFA" } style.syntax["function"] = { common.color "#93DDFA" } +-- This can be used to override fonts per syntax group. +-- The syntax highlighter will take existing values from this table and +-- override style.code_font on a per-token basis, so you can choose to eg. +-- render comments in an italic font if you want to. +style.syntax_fonts = {} +-- style.syntax_fonts["comment"] = renderer.font.load(path_to_font, size_of_font, rendering_options) + return style