summaryrefslogtreecommitdiff
path: root/lua/bulletjava.lua
blob: f38eec779da46957f2a2eb99d9e9ec9cd958f9e0 (plain) (blame)
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
108
109
110
local vim = assert(vim)

local M = {
  yankmap = {}
}

-- Add imports to a java file. Attempts to sort them.
local function add_imports(buffer, buffer_lines, qualified_import_names)
  table.sort(qualified_import_names)

  local l = 1
  local j = 1

  local changed = false

  local new_lines = {}
  local new_line = string.format("import %s;", qualified_import_names[j])

  while l <= #buffer_lines and j <= #qualified_import_names  do
    local line = buffer_lines[l]

    if not string.match(line, "^package") and not string.match(line, "^%s*$") then
      if string.match(line, "^import") then
        if new_line <= line then
          if new_line < line then
            changed = true
            table.insert(new_lines, new_line)
          end
          j = j + 1
          new_line = string.format("import %s;", qualified_import_names[j] or "")
        end
      else
        break
      end
    end

    table.insert(new_lines, line)
    l = l + 1
  end

  while j <= #qualified_import_names do
    table.insert(new_lines, string.format("import %s;", qualified_import_names[j]))
    j = j + 1
  end

  vim.api.nvim_buf_set_lines(buffer, 0, l - 1, 0, new_lines)
end

-- Add all the imports in qualified_import_names to the import list in a Java
-- file.
function M.add_imports(buffer, qualified_import_names)
  add_imports(
      buffer,
      vim.api.nvim_buf_get_lines(buffer, 0, -1, 0),
      qualified_import_names)
end

local function scrape_imported_identifiers(buffer, content_list)
  local content = table.concat(content_list, " ")
  local find_table = {}
  local imports = {}

  for word in string.gmatch(content, "[A-Za-z0-9_]+") do
    find_table[word] = true
  end

  local lines = vim.api.nvim_buf_get_lines(buffer, 0, -1 ,0)
  local l = 1
  while l < #lines do
    local _, _, i = string.find(lines[l], "^import.*%.(%w+);")
    if i and find_table[i] then
      local _, _, q = string.find(lines[l], "^import%s+(.+);")
      table.insert(imports, q)
    elseif not i and
          not string.match(lines[l], "^package") and
          not string.match(lines[l], "^%s*$") then
      break
    end
    l = l + 1
  end

  return imports
end

-- Called when text is yanked
function M.on_text_yanked()
  local regname = vim.v.event.regname

  if vim.o.ft ~= 'java' then
    -- Clear the yankmap for this register.
    M.yankmap[regname] = nil
    M.yankmap['"'] = nil
  else
    local imports = scrape_imported_identifiers(0, vim.v.event.regcontents)
    M.yankmap[regname] = imports
    M.yankmap['"'] = imports
  end
end

function M.on_text_put(regname)
  if vim.o.ft == 'java' then
    local imps = M.yankmap[regname] or {}
    vim.schedule(function ()
      vim.cmd('undojoin') -- Adding the imports should be part of the same action.
      M.add_imports(0, imps)
    end)
  end
end

return M