C++ completion with clang & indentation with uncrustify

From: Jean-Baptiste Mouret / Mandor <mou....at.isir.upmc.fr>
Date: Sun, 28 Aug 2011 17:06:51 +0200

Hello all

I'm a happy user of textadept but I mostly code in c++ (and not in
LUA). I wrote two small scripts to help c++ programmers during this
week-end; I hope you will find them interesting and maybe help me to
improve them.

* Completion in c++
C++ is very hard to parse and it is therefore very hard to write a
good autocompletion engine. Fortunately, clang can now parse most c++
correctly and they included an auto-completion mode. You obviously
need a recent version of clang to use this script:

keys.ci = { function()
  local buffer = buffer
  -- configure here your path to clang
  local cmd ="~/sandbox/clang+llvm-2.9-i686-linux/bin/clang++ "
  cmd = cmd.." -cc1 -fsyntax-only -fno-caret-diagnostics"
  -- add common paths
  cmd = cmd.." -I /usr/local/include/boost-1_42 "
  cmd = cmd.." -I. -I.. -I../.."
  cmd = cmd.." -fdiagnostics-print-source-range-info"
  cmd = cmd.." -code-completion-at="
  line = ""..(buffer:line_from_position(buffer.current_pos) + 1);
  col = ""..(buffer.column[buffer.current_pos]+1)
  cmd = cmd..buffer.filename ..":"..line..":"..col.." "..buffer.filename
  buffer:save()
  local p = io.popen(cmd)
  local s = ""
  for line in p:lines() do
      local tag_name= line:match('^COMPLETION: (.+) :')
      if tag_name ~= nil then
        local s1 = string.gsub(tag_name, "(%W)", "%%%1")
        if (s:find(s1) == nil) then
          s = s..tag_name.." "
        end
      end
  end
  buffer.auto_c_show(buffer, 0, s)
end }

* Indentation
I come from emacs and I took the (bad?) habit of typing "tab" on every
line to have the right indentation level. Since it is not the default
behavior of textadept, I've tried several strategies and the simplest
one is to call uncrustify (a command-line utility which indent code).
Uncrustify is easier to use than indent and I like it better for C++,
but the same thing can easily be achieved with any other indenter.
Uncrustify indent the whole file: a nice consequence is that it can
split your lines and make a lot of style adjustement; however, this
means that (1) your co-workers have to use the same style (otherwise
you will have a lot of conflicts during the next commit) and (2) a
mistake in the middle of a file can lead to a wroong indentation for
the whole file (whereas in emacs, everything is local).

you need uncrustify (http://uncrustify.sourceforge.net/) and a
~/.textadept/crust.cfg with your indentation style (something like
this: http://uncrustify.sourceforge.net/default.cfg)

keys.cpp = {
  al = {
    m = { io.open_file,
          (_HOME..'/modules/cpp/init.lua'):iconv('UTF-8', _CHARSET) },
  },
  ['s\n'] = { function()
    buffer:line_end()
    buffer:add_text(';')
    buffer:new_line()
  end },
    ['\t'] = {
    function()
      local buffer = buffer
      local input = buffer:get_text()
      local tmpfile = _USERHOME..'/.ft'
      local conf = _USERHOME..'/crust.cfg'
      local f = io.open(tmpfile, 'wb')
      local s, e = buffer.selection_start, buffer.selection_end
      f:write(input)
      f:close()
      local cmd = table.concat({"uncrustify -c ", conf, ' -f
"'..tmpfile..'"'}, ' ')
      local p = io.popen(cmd)
      local fv2 = buffer.first_visible_line
      buffer:set_text(p:read('*all'))
      buffer:line_scroll(0, fv2);
      buffer:goto_pos(s)
      os.remove(tmpfile)
   end
    },
  [not OSX and 'ci' or 'cesc'] = { sense.complete, sense },
  ch = { sense.show_apidoc, sense },
}

Best regards,

--
Jean-Baptiste Mouret / Mandor
Received on Sun 28 Aug 2011 - 11:06:51 EDT

This archive was generated by hypermail 2.2.0 : Thu 08 Mar 2012 - 12:21:19 EST