<commit_before>-- Copyright 2007-2014 Mitchell mitchell.<EMAIL>. See LICENSE.

local M = {}

--[[ This comment is for LuaDoc.
---
-- The ansi_c module.
-- It provides utilities for editing C code.
--
-- ## Key Bindings
--
-- + `Ctrl+L, M` (`⌘L, M` on Mac OSX | `M-L, M` in curses)
--   Open this module for editing.
-- + `Shift+Enter` (`⇧↩` | `S-Enter`)
--   Add ';' to the end of the current line and insert a newline.
module('_M.ansi_c')]]

-- Autocompletion and documentation.

---
-- List of ctags files to use for autocompletion.
-- @class table
-- @name tags
M.tags = {_HOME..'/modules/ansi_c/tags', _USERHOME..'/modules/ansi_c/tags'}

local XPM = textadept.editing.XPM_IMAGES
local xpms = setmetatable({
  c = XPM.CLASS, d = XPM.SLOT, e = XPM.VARIABLE, f = XPM.METHOD,
  g = XPM.TYPEDEF, m = XPM.VARIABLE, s = XPM.STRUCT, t = XPM.TYPEDEF,
  v = XPM.VARIABLE
}, {__index = function(t, k) return 0 end})

textadept.editing.autocompleters.ansi_c = function()
  local list = {}
  -- Retrieve the symbol behind the caret.
  local line, pos = buffer:get_cur_line()
  local symbol, op, part = line:sub(1, pos):match('([%w_]-)([%.%->]*)([%w_]*)$')
  if symbol == '' and part == '' and op ~= '' then return nil end -- lone ., ->
  if op ~= '' and op ~= '.' and op ~= '->' then return nil end
  -- Attempt to identify the symbol type.
  local buffer = buffer
  local declaration = '([%w_]+)[%s%*&]+'..symbol:gsub('(%p)', '%%%1')..'[^%w_]'
  for i = buffer:line_from_position(buffer.current_pos) - 1, 0, -1 do
    local class = buffer:get_line(i):match(declaration)
    if class then symbol = class break end
  end
  -- Search through ctags for completions for that symbol.
  local name_patt = '^'..part
  local sep = string.char(buffer.auto_c_type_separator)
  for i = 1, #M.tags do
    if lfs.attributes(M.tags[i]) then
      for line in io.lines(M.tags[i]) do
        local name = line:match('^%S+')
        if name:find(name_patt) and not name:find('^!') and not list[name] then
          local fields = line:match(';"\t(.*)$')
          if (fields:match('class:(%S+)') or fields:match('enum:(%S+)') or
              fields:match('struct:(%S+)') or fields:match('typedef:(%S+)') or
              '') == symbol then
            local k = xpms[fields:sub(1, 1)]
            list[#list + 1] = ("%s%s%d"):format(name, sep, xpms[k])
            list[name] = true<commit_msg>Fixed bug in ANSI C autocompletion; modules/ansi_c/init.lua<commit_after>-- Copyright 2007-2014 Mitchell mitchell.att.foicica.com. See LICENSE.

local M = {}

--[[ This comment is for LuaDoc.
---
-- The ansi_c module.
-- It provides utilities for editing C code.
--
-- ## Key Bindings
--
-- + `Ctrl+L, M` (`⌘L, M` on Mac OSX | `M-L, M` in curses)
--   Open this module for editing.
-- + `Shift+Enter` (`⇧↩` | `S-Enter`)
--   Add ';' to the end of the current line and insert a newline.
module('_M.ansi_c')]]

-- Autocompletion and documentation.

---
-- List of ctags files to use for autocompletion.
-- @class table
-- @name tags
M.tags = {_HOME..'/modules/ansi_c/tags', _USERHOME..'/modules/ansi_c/tags'}

local XPM = textadept.editing.XPM_IMAGES
local xpms = setmetatable({
  c = XPM.CLASS, d = XPM.SLOT, e = XPM.VARIABLE, f = XPM.METHOD,
  g = XPM.TYPEDEF, m = XPM.VARIABLE, s = XPM.STRUCT, t = XPM.TYPEDEF,
  v = XPM.VARIABLE
}, {__index = function(t, k) return 0 end})

textadept.editing.autocompleters.ansi_c = function()
  local list = {}
  -- Retrieve the symbol behind the caret.
  local line, pos = buffer:get_cur_line()
  local symbol, op, part = line:sub(1, pos):match('([%w_]-)([%.%->]*)([%w_]*)$')
  if symbol == '' and part == '' and op ~= '' then return nil end -- lone ., ->
  if op ~= '' and op ~= '.' and op ~= '->' then return nil end
  -- Attempt to identify the symbol type.
  if symbol ~= '' then
    local buffer = buffer
    local declaration = '([%w_]+)[%s%*&]+'..symbol:gsub('(%p)', '%%%1')..'[^%w_]'
    for i = buffer:line_from_position(buffer.current_pos) - 1, 0, -1 do
      local class = buffer:get_line(i):match(declaration)
      if class then symbol = class break end
    end
  end
  -- Search through ctags for completions for that symbol.
  local name_patt = '^'..part
  local sep = string.char(buffer.auto_c_type_separator)
  for i = 1, #M.tags do
    if lfs.attributes(M.tags[i]) then
      for line in io.lines(M.tags[i]) do
        local name = line:match('^%S+')
        if name:find(name_patt) and not name:find('^!') and not list[name] then
          local fields = line:match(';"\t(.*)$')
          if (fields:match('class:(%S+)') or fields:match('enum:(%S+)') or
              fields:match('struct:(%S+)') or fields:match('typedef:(%S+)') or
              '') == symbol then
            local k = xpms[fields:sub(1, 1)]
            list[#list + 1] = ("%s%s%d"):format(name, sep, xpms[k])
            list[name] = true
{'fraction_non_alphanumeric': 0.18663356093523692, 'fraction_numerical': 0.0074487895716946, 'mean_word_length': 2.955810147299509, 'pattern_counts': {'":': 0, '<': 4, '<?xml version=': 0, '>': 10, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3590210', 'n_tokens_mistral': 1827, 'n_tokens_neox': 1787, 'n_words': 493}