Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature Request: Option for hexadecimals to not be displayed as decimals on mouseover #3059

Open
Lumariano opened this issue Feb 3, 2025 · 1 comment

Comments

@Lumariano
Copy link

Currently if you have defined a number like this for example:

WS_BORDER = 0x00800000

Hovering over WS_BORDER displays:

(global) WS_BORDER : integer = 8388608

Would it be possible to add an option so that numbers that are not defined as decimals are not resolved to decimals when hovering over them? I. e. :

(global) WS_BORDER : integer = 0x00800000
@tomlau10
Copy link
Contributor

tomlau10 commented Feb 6, 2025

string literals can be displayed according to their defined quotes

For string literals, currently luals is capable to distinguish between different quote styles

local s1 = 's1'
-- hover: local s1: string = 's1'

local s2 = "s2"
-- hover: local s2: string = "s2"

local s3 = [[s3]]
-- hover: local s3: string = [[s3]]
  • By looking at the code, I believe this is done by storing the mark when parsing string literals:
    local str = {
    type = 'string',
    start = startPos,
    finish = lastRightPosition(),
    escs = #escs > 0 and escs or nil,
    [1] = stringResult,
    [2] = mark,
    }
  • and then pass this mark to util.viewString()
    function mt:viewLiterals()
    if not self.node then
    return nil
    end
    local mark = {}
    local literals = {}
    for n in self.node:eachObject() do
    if n.type == 'string'
    or n.type == 'number'
    or n.type == 'integer'
    or n.type == 'boolean' then
    local literal
    if n.type == 'string' then
    literal = util.viewString(n[1], n[2])
  • and finally the formatting
    function m.viewString(str, quo)
    if not quo then
    if str:find('[\r\n]') then
    quo = '[['
    elseif not str:find("'", 1, true) and str:find('"', 1, true) then
    quo = "'"
    else
    quo = '"'
    end
    end
    if quo == "'" then
    str = str:gsub('[\000-\008\011-\012\014-\031\127]', function (char)
    return ('\\%03d'):format(char:byte())
    end)
    return quo .. str:gsub([=[['\r\n]]=], esc) .. quo
    elseif quo == '"' then
    str = str:gsub('[\000-\008\011-\012\014-\031\127]', function (char)
    return ('\\%03d'):format(char:byte())
    end)
    return quo .. str:gsub([=[["\r\n]]=], esc) .. quo
    else
    local eqnum = #quo - 2
    local fsymb = ']' .. ('='):rep(eqnum) .. ']'
    if not str:find(fsymb, 1, true) then
    str = str:gsub('[\000-\008\011-\012\014-\031\127]', '')
    return quo .. str .. fsymb
    end
    for i = 0, 10 do
    local fsymb = ']' .. ('='):rep(i) .. ']'
    if not str:find(fsymb, 1, true) then
    local ssymb = '[' .. ('='):rep(i) .. '['
    str = str:gsub('[\000-\008\011-\012\014-\031\127]', '')
    return ssymb .. str .. fsymb
    end
    end
    return m.viewString(str, '"')
    end
    end

borrowing this idea for viewing integer?

By applying the same method, I think we can:

  • firstly, store the integer mode when parsing integers here:
    elseif firstChar == '0' then
    local nextChar = ssub(Lua, offset + 1, offset + 1)
    if CharMapN16[nextChar] then
    number, offset, integer = parseNumber16(offset + 2)
    elseif CharMapN2[nextChar] then
    number, offset = parseNumber2(offset + 2)
    integer = true
    else
    number, offset, integer = parseNumber10(offset)
    end
    elseif CharMapNumber[firstChar] then
    number, offset, integer = parseNumber10(offset)
    else
    return nil
    end
    if not number then
    number = 0
    end
    if neg then
    number = - number
    end
    local result = {
    type = integer and 'integer' or 'number',
    start = startPos,
    finish = getPosition(offset - 1, 'right'),
    [1] = number,
    }
  • then add a util.viewInteger() and format as hex if it is in hexadecimal mode
function m.viewInteger(int, mode)
    if mode == 'x' then
        -- view as hex integer
        return ('0x%x'):format(int)
    end
    return tostring(int)
end
  • finally add an elseif case for n.type == 'integer' in mt:viewLiterals() of vm/infer.lua

the POC patch

Here is a POC patch file you might want to try, you may work from here and PR it after testing 😄

click to expand
From c0359b7cfb6b147c5c60e1c97c211cc3bf335ed3 Mon Sep 17 00:00:00 2001
From: Tom Lau <tomandfatboy@gmail.com>
Date: Thu, 6 Feb 2025 12:10:24 +0800
Subject: [PATCH] poc: hex integer hover

---
 script/parser/compile.lua | 4 +++-
 script/utility.lua        | 8 ++++++++
 script/vm/infer.lua       | 2 ++
 3 files changed, 13 insertions(+), 1 deletion(-)

diff --git a/script/parser/compile.lua b/script/parser/compile.lua
index 41b0da17..333bc4e0 100644
--- a/script/parser/compile.lua
+++ b/script/parser/compile.lua
@@ -1353,7 +1353,7 @@ local function parseNumber()
         neg = true
         offset = offset + 1
     end
-    local number, integer
+    local number, integer, mode
     local firstChar = ssub(Lua, offset, offset)
     if     firstChar == '.' then
         number, offset = parseNumber10(offset)
@@ -1362,6 +1362,7 @@ local function parseNumber()
         local nextChar = ssub(Lua, offset + 1, offset + 1)
         if CharMapN16[nextChar] then
             number, offset, integer = parseNumber16(offset + 2)
+            mode = 'x'
         elseif CharMapN2[nextChar] then
             number, offset = parseNumber2(offset + 2)
             integer = true
@@ -1384,6 +1385,7 @@ local function parseNumber()
         start  = startPos,
         finish = getPosition(offset - 1, 'right'),
         [1]    = number,
+        [2]    = integer and mode or nil,
     }
     offset = dropNumberTail(offset, integer)
     fastForwardToken(offset)
diff --git a/script/utility.lua b/script/utility.lua
index 7a1fd0ff..ba33b4a5 100644
--- a/script/utility.lua
+++ b/script/utility.lua
@@ -504,6 +504,14 @@ function m.viewString(str, quo)
     end
 end
 
+function m.viewInteger(int, mode)
+    if mode == 'x' then
+        -- view as hex integer
+        return ('0x%x'):format(int)
+    end
+    return tostring(int)
+end
+
 function m.viewLiteral(v)
     local tp = type(v)
     if tp == 'nil' then
diff --git a/script/vm/infer.lua b/script/vm/infer.lua
index 6f21a76a..200d5059 100644
--- a/script/vm/infer.lua
+++ b/script/vm/infer.lua
@@ -510,6 +510,8 @@ function mt:viewLiterals()
             local literal
             if n.type == 'string' then
                 literal = util.viewString(n[1], n[2])
+            elseif n.type == 'integer' then
+                literal = util.viewInteger(n[1], n[2])
             else
                 literal = util.viewLiteral(n[1])
             end
-- 
2.45.2

result:

(global) WS_BORDER: integer = 0x800000

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants