fix(blink_cmp_source): Handling of DB patterns after operators
The completion now correctly handles DB patterns after any operator (:=, =>, =, <>, >=, <=, >, <, AND, OR, NOT) by finding the last operator and only matching DB patterns in the active portion after it.
This commit is contained in:
@@ -33,8 +33,8 @@ function M.is_available(context)
|
||||
local char_at = line:sub(col, col)
|
||||
local prev_char = col > 1 and line:sub(col - 1, col - 1) or ""
|
||||
|
||||
-- Only trigger on our specific characters
|
||||
if char_at == "." or char_at == "(" or char_at == "#" or char_at == '"' or
|
||||
-- Only trigger on our specific characters (including space for := assignments)
|
||||
if char_at == "." or char_at == "(" or char_at == "#" or char_at == '"' or char_at == " " or
|
||||
prev_char == "." or prev_char == "(" or prev_char == "#" or prev_char == '"' then
|
||||
return true
|
||||
end
|
||||
@@ -158,30 +158,70 @@ function M:get_completions(context, callback)
|
||||
-- Check for Global DB completion (quoted DB names like "HmiData")
|
||||
local trimmed = line:gsub("^%s+", ""):gsub("%s+$", "")
|
||||
|
||||
-- Check for "DBName" pattern (quoted DB name access with dot)
|
||||
local db_member_pattern = trimmed:match('"([%w_]+)"%.([%w_]*)')
|
||||
-- Find the "active portion" of the line - after the last operator if present
|
||||
-- Operators: :=, =>, =, <>, >=, <=, >, <, AND, OR, NOT
|
||||
-- This ensures we match DB patterns nearest to the cursor, not the first in line
|
||||
local active_portion = line_before_cursor
|
||||
|
||||
-- Check if we're typing a quoted DB name (after " but before closing ")
|
||||
local is_in_db_name = trimmed:match('"[%w_]*$') ~= nil
|
||||
local function find_last_operator_pos(text)
|
||||
local last_pos = 0
|
||||
local operators = {":=", "=>", "<>", ">=", "<=", "=", ">", "<"}
|
||||
for _, op in ipairs(operators) do
|
||||
local search_start = 1
|
||||
while true do
|
||||
local pos = text:find(op, search_start, true)
|
||||
if not pos then break end
|
||||
if pos > last_pos then
|
||||
last_pos = pos + #op
|
||||
end
|
||||
search_start = pos + 1
|
||||
end
|
||||
end
|
||||
-- Also check for AND/OR/NOT keywords (case insensitive)
|
||||
local keywords = {"%sAND%s", "%sOR%s", "%sNOT%s"}
|
||||
for _, kw in ipairs(keywords) do
|
||||
local search_start = 1
|
||||
while true do
|
||||
local pos = text:upper():find(kw, search_start)
|
||||
if not pos then break end
|
||||
if pos > last_pos then
|
||||
last_pos = pos + #kw - 1
|
||||
end
|
||||
search_start = pos + 1
|
||||
end
|
||||
end
|
||||
return last_pos
|
||||
end
|
||||
|
||||
-- Check for partial DB name like "HmiData (unclosed quote)
|
||||
local partial_db_match = trimmed:match('"([%w_]+)$')
|
||||
local is_partial_db = partial_db_match ~= nil and trimmed:match('"[^"]*$') ~= nil
|
||||
local last_op_pos = find_last_operator_pos(line_before_cursor)
|
||||
if last_op_pos > 0 then
|
||||
active_portion = line_before_cursor:sub(last_op_pos):gsub("^%s+", "")
|
||||
end
|
||||
|
||||
-- Check if after a colon followed by quote (type declaration context)
|
||||
-- Check for "DBName" pattern (quoted DB name access with dot) - in active portion only
|
||||
local db_member_pattern = active_portion:match('"([%w_]+)"%.([%w_.]*)')
|
||||
|
||||
-- Check if we're typing a quoted DB name (after " but before closing ") - in active portion
|
||||
local is_in_db_name = active_portion:match('"[%w_]*$') ~= nil
|
||||
|
||||
-- Check for partial DB name like "HmiData (unclosed quote) - in active portion
|
||||
local partial_db_match = active_portion:match('"([%w_]+)$')
|
||||
local is_partial_db = partial_db_match ~= nil and active_portion:match('"[^"]*$') ~= nil
|
||||
|
||||
-- Check if after a colon followed by quote (type declaration context) - use full trimmed line
|
||||
local is_after_colon_quote = trimmed:match(':%s*"$') ~= nil
|
||||
|
||||
-- Check if cursor is right after a closed quoted DB name (before dot)
|
||||
local after_closed_db = trimmed:match('"([%w_]+)"%s*%.') ~= nil
|
||||
-- Check if cursor is right after a closed quoted DB name (before dot) - in active portion
|
||||
local after_closed_db = active_portion:match('"([%w_]+)"%s*%.') ~= nil
|
||||
|
||||
if db_member_pattern or after_closed_db then
|
||||
local db_parser = require("scl.db_parser")
|
||||
local db_name = trimmed:match('"([%w_]+)"')
|
||||
local db_name = active_portion:match('"([%w_]+)"')
|
||||
|
||||
if db_name then
|
||||
local db = db_parser.get_db(db_name)
|
||||
if db then
|
||||
local path = trimmed:match('"[^"]+%"%.([%w_.]*)')
|
||||
local path = active_portion:match('"[^"]+%"%.([%w_.]*)')
|
||||
|
||||
-- Resolve nested path through DB members
|
||||
local current_type = nil
|
||||
@@ -230,7 +270,7 @@ function M:get_completions(context, callback)
|
||||
end
|
||||
|
||||
if not found then
|
||||
wrapped_callback({ items = {} })
|
||||
callback({ items = {}, is_incomplete_backward = false, is_incomplete_forward = false })
|
||||
return
|
||||
end
|
||||
end
|
||||
@@ -239,8 +279,7 @@ function M:get_completions(context, callback)
|
||||
if path and path ~= "" and path:match("%.$") then
|
||||
-- User wants members of the last type
|
||||
elseif path and path ~= "" and not path:match("%.$") then
|
||||
-- User is typing a member name, don't show completions yet
|
||||
wrapped_callback({ items = {} })
|
||||
callback({ items = {}, is_incomplete_backward = false, is_incomplete_forward = false })
|
||||
return
|
||||
end
|
||||
|
||||
|
||||
Reference in New Issue
Block a user