aboutsummaryrefslogtreecommitdiff
path: root/modules/textadept/command_entry.lua
blob: 6226ff6ca21c0c206150b52713de24f783ede4b0 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
-- Copyright 2007-2012 Mitchell mitchell.att.foicica.com. See LICENSE.
-- Modified by Jay Gould.

--[[ This comment is for LuaDoc.
---
-- Textadept's Command Entry.
-- @field entry_text (string)
--   The text in the entry.
module('gui.command_entry')]]

-- Environment for abbreviated commands.
-- @class table
-- @name env
local env = setmetatable({}, {
  __index = function(t, k)
    local f = buffer[k]
    if f and type(f) == 'function' then
      f = function(...) buffer[k](buffer, ...) end
    elseif f == nil then
      f = view[k] or gui[k] or _G[k]
    end
    return f
  end,
  __newindex = function(t, k, v)
    for _, t2 in ipairs{buffer, view, gui} do
      if t2[k] ~= nil then t2[k] = v return end
    end
    rawset(t, k, v)
  end,
})

local events = events

-- Execute a Lua command.
events.connect(events.COMMAND_ENTRY_COMMAND, function(command)
  local f, err = load(command, nil, 'bt', env)
  if err then error(err) end
  if not NCURSES then gui.command_entry.focus() end -- toggle focus to hide
  f()
  events.emit(events.UPDATE_UI)
end)

events.connect(events.COMMAND_ENTRY_KEYPRESS, function(code)
  if keys.KEYSYMS[code] == 'esc' then
    gui.command_entry.focus() -- toggle focus to hide
  elseif not NCURSES and keys.KEYSYMS[code] == '\t' or code == 9 then
    local substring = gui.command_entry.entry_text:match('[%w_.:]+$') or ''
    local path, o, prefix = substring:match('^([%w_.:]-)([.:]?)([%w_]*)$')
    local f, err = load('return ('..path..')', nil, 'bt', env)
    local ok, tbl = pcall(f)
    local cmpls = {}
    prefix = '^'..prefix
    if not ok then -- shorthand notation
      for _, t in ipairs{buffer, view, gui, _G} do
        for k in pairs(t) do
          if type(k) == 'string' and k:find(prefix) then
            cmpls[#cmpls + 1] = k
          end
        end
      end
      for f in pairs(_SCINTILLA.functions) do
        if f:find(prefix) then cmpls[#cmpls + 1] = f end
      end
      for p in pairs(_SCINTILLA.properties) do
        if p:find(prefix) then cmpls[#cmpls + 1] = p end
      end
    else
      if type(tbl) ~= 'table' then return end
      for k in pairs(tbl) do
        if type(k) == 'string' and k:find(prefix) then cmpls[#cmpls + 1] = k end
      end
      if path == 'buffer' then
        if o == ':' then
          for f in pairs(_SCINTILLA.functions) do
            if f:find(prefix) then cmpls[#cmpls + 1] = f end
          end
        else
          for p in pairs(_SCINTILLA.properties) do
            if p:find(prefix) then cmpls[#cmpls + 1] = p end
          end
        end
      end
    end
    table.sort(cmpls)
    gui.command_entry.show_completions(cmpls)
    return true
  end
end)

--[[ The function below is a Lua C function.

---
-- Focuses the command entry.
-- @class function
-- @name focus
local focus

---
-- Shows the given list of completions for the current word prefix.
-- On selection, the current word prefix is replaced with the completion. Word
-- prefix characters are alphanumerics and underscores.
-- @param completions The table of completions to show. Non-string values are
--   ignored.
-- @class function
-- @name show_completions
local show_completions
]]