Cancel Auto-complete If Single Item Matches Text #283
-
I have my auto-complete set to automatically show up after every character insert. I find this helps me use the auto-complete a lot more than if I had to hit a key combo to activate it. I'm doing this with: buffer.auto_c_choose_single = false
events.connect(events.CHAR_ADDED, function()
textadept.editing.autocomplete('word')
end) Overall this is working fairly well. One thing that would make it nicer is if there is a single item in the auto-complete list and it entirely matches what has already been typed it would be nice if it could auto-cancel. For example if I type I attempted to look for some way to do that. My pseudo code might be something like: events.connect(events.AUTO_C_OPTIONS, function()
local single_item = buffer.auto_c_items_count == 1
local typed_text = buffer:text_range(buffer:auto_c_pos_start(), buffer.current_pos)
local typed_completely = buffer.auto_c_current_text == typed_text
if single_item and typed_completely then
buffer:auto_c_cancel()
end
end) What I'm missing in the above is:
Are there some aspects to the API that I could use to implement something like this? |
Beta Was this translation helpful? Give feedback.
Replies: 3 comments 2 replies
-
I use a similar setup and this seems to work for me: events.connect(events.CHAR_ADDED, function(code)
if code >= 48 and code <= 57 or code >= 65 and code <= 90 or code >= 97 and code <= 122 or code == 95 then
textadept.editing.autocomplete('word')
if buffer:auto_c_active() then
return
end
textadept.editing.autocomplete(buffer:get_lexer(true))
end
end)
events.connect(events.KEYPRESS, function(code)
if buffer:auto_c_active() and code ~= 65505 then
buffer:auto_c_cancel()
end
end) Additionally I also cancel on some other keys: keys['\n'] = function()
if buffer:auto_c_active() then
buffer:auto_c_complete()
return true
end
return false
end
keys.up = function()
if buffer:auto_c_active() then
buffer:auto_c_cancel()
return false
end
return false
end
keys.down = function()
if buffer:auto_c_active() then
buffer:auto_c_cancel()
return false
end
return false
end
keys['home'] = function()
if buffer:auto_c_active() then
buffer:auto_c_cancel()
return false
end
return false
end
keys['end'] = function()
if buffer:auto_c_active() then
buffer:auto_c_cancel()
return false
end
return false
end |
Beta Was this translation helpful? Give feedback.
-
Just to follow up on this. I think I may have a way to auto-cancel the auto-complete if there is only a single suggested item and that item has been fully typed out. The following is my entire auto-complete customization code: -- Since we auto-activate auto complete we don't want to auto-choose on single
-- in case they are typing an entirely new term.
buffer.auto_c_choose_single = false
-- It is typical for one buffer to make use of structures in another buffer
-- so scan all open buffers for auto-complete.
textadept.editing.autocomplete_all_words = true
-- Monkey-patch buffer.auto_c_show to record the most recently displayed list
buffer.autocomplete_items = ''
events.connect(events.INITIALIZED, function()
if not buffer.old_auto_c_show then
buffer.old_auto_c_show = buffer.auto_c_show
buffer.auto_c_show = function (buffer, len_entered, items)
buffer.autocomplete_items = items
return buffer:old_auto_c_show(len_entered, items)
end
end
end)
local function cancel()
if buffer:auto_c_active() then
buffer:auto_c_cancel()
end
end
-- Each time a character is added activate auto-complete. If there is only a
-- single item and it has already been fully typed out then auto-close the list
events.connect(events.CHAR_ADDED, function()
-- Clear list from last activiation
buffer.autocomplete_items = ''
textadept.editing.autocomplete('word')
-- No matches were made so cancel and return early
if( buffer.autocomplete_items == '' ) then return cancel() end
local _, sep_count = buffer.autocomplete_items:gsub(string.char(buffer.auto_c_separator), "")
local single_item = sep_count == 0
if not single_item then return end
local recent_chars = buffer:text_range(buffer.current_pos - buffer.autocomplete_items:len(), buffer.current_pos)
local fully_typed = recent_chars == buffer.autocomplete_items
if not fully_typed then return end
cancel()
end) The trick here is that I am monkey-patching |
Beta Was this translation helpful? Give feedback.
-
I think I made this whole thing way too hard. I think it should just be: buffer.auto_c_choose_single = false
events.connect(events.CHAR_ADDED, function()
if buffer:auto_c_active() then
buffer:auto_c_cancel()
end
textadept.editing.autocomplete('word')
end) This isn't much more complicated than what I had originally. The only change is that I close the auto complete if it is already open. This works because Textadept is only looking for matching terms that are larger than what I already typed. The reason this doesn't work without closing first is because if you exactly match the only item in your list then that means it doesn't find any terms it returns early never displaying the auto-complete. But if the auto-complete list was already displayed from the previous character (when the item was bigger than the typed term) you still had the old list displayed. By closing the list before attempting to display again it clears out that old list. |
Beta Was this translation helpful? Give feedback.
I think I made this whole thing way too hard. I think it should just be:
This isn't much more complicated than what I had originally. The only change is that I close the auto complete if it is already open. This works because Textadept is only looking for matching terms that are larger than what I already typed.
The reason this doesn't work without closing first is because if you exactly match the only item in your list then that means it doesn't find any terms it returns early never displaying the…