Skip to content
New issue

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

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

Already on GitHub? # to your account

Add option to suggest words in different cases #60

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
120 changes: 120 additions & 0 deletions lua/cmp_buffer/cases.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
-- slice a word to individual slices. "my_cool_word" -> { "my", "cool", "word" }
function get_word_slices(name)
local slices = {}
local current_word = ""
local last_character_uppercase = true

for i = 1, #name do
local character = name:sub(i, i)

if character == "_" or character == "-" then
if current_word ~= "" then
table.insert(slices, current_word)
current_word = ""
end

last_character_uppercase = false
elseif string.upper(character) == character then

if last_character_uppercase or current_word == "" then
current_word = current_word .. string.lower(character)
else
table.insert(slices, current_word)
current_word = string.lower(character)
end

last_character_uppercase = true
else
current_word = current_word .. character
last_character_uppercase = false
end
end

if current_word ~= "" then
table.insert(slices, current_word)
end

return slices
end

-- e.g. my_cool_word
function snake_case(slices)
local word = ""

for index, slice in ipairs(slices) do
if index > 1 then
word = word .. "_"
end

word = word .. slice
end

return word
end

-- e.g. my-cool-word
function kebab_case(slices)
local word = ""

for index, slice in ipairs(slices) do
if index > 1 then
word = word .. "-"
end

word = word .. slice
end

return word
end

-- e.g. myCoolWord
function camel_case(slices)
local word = ""

for index, slice in ipairs(slices) do
if index == 1 then
word = word .. slice
else
word = word .. string.upper(string.sub(slice, 1, 1))
word = word .. string.sub(slice, 2, -1)
end
end

return word
end

-- e.g. MyCoolWord
function pascal_case(slices)
local word = ""

for _, slice in ipairs(slices) do
word = word .. string.upper(string.sub(slice, 1, 1))
word = word .. string.sub(slice, 2, -1)
end

return word
end

-- e.g. MY_COOL_WORD
function macro_case(slices)
local word = ""

for index, slice in ipairs(slices) do
if index > 1 then
word = word .. "_"
end

word = word .. string.upper(slice)
end

return word
end

-- lookup table for all cases that are suppored out of the box
return {
["snake"] = snake_case,
["camel"] = camel_case,
["pascal"] = pascal_case,
["kebab"] = kebab_case,
["macro"] = macro_case,
}
31 changes: 31 additions & 0 deletions lua/cmp_buffer/source.lua
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
local buffer = require('cmp_buffer.buffer')
local case_lookup = require('cmp_buffer.cases')

---@class cmp_buffer.Options
---@field public keyword_length number
Expand All @@ -7,6 +8,7 @@ local buffer = require('cmp_buffer.buffer')
---@field public indexing_batch_size number
---@field public indexing_interval number
---@field public max_indexed_line_length number
---@field public cases table

---@type cmp_buffer.Options
local defaults = {
Expand All @@ -18,6 +20,7 @@ local defaults = {
indexing_batch_size = 1000,
indexing_interval = 100,
max_indexed_line_length = 1024 * 40,
cases = {},
}

local source = {}
Expand All @@ -37,6 +40,7 @@ source._validate_options = function(_, params)
get_bufnrs = { opts.get_bufnrs, 'function' },
indexing_batch_size = { opts.indexing_batch_size, 'number' },
indexing_interval = { opts.indexing_interval, 'number' },
cases = { opts.cases, 'table' },
})
return opts
end
Expand Down Expand Up @@ -71,6 +75,33 @@ source.complete = function(self, params, callback)
label = word,
dup = 0,
})

if opts.cases ~= {} then
local slices = get_word_slices(word)

for _, case in ipairs(opts.cases) do
local new_word

if type(case) == "function" then
new_word = case(slices)
else
local converter = case_lookup[case]
if converter ~= nil then
new_word = converter(slices)
end
end

if type(new_word) == "string" then
if not words[new_word] then
words[new_word] = true
table.insert(items, {
label = new_word,
dup = 0,
})
end
end
end
end
end
end
end
Expand Down