Ecosyste.ms: Awesome

An open API service indexing awesome lists of open source software.

Awesome Lists | Featured Topics | Projects

https://github.com/lefterisjp/malinka

A C/C++ project configuration package for Emacs
https://github.com/lefterisjp/malinka

Last synced: 27 days ago
JSON representation

A C/C++ project configuration package for Emacs

Awesome Lists containing this project

README

        

#+DESCRIPTION: A C/C++ project configuration package for Emacs
#+OPTIONS: H:2

* Information
Malinka is a project management Emacs package for C/C++

It acts as a glue between different C/C++ packages to provide them with the
right data for a project. All the data are organized and can be configured on a per project basis.
The packages that malinka can work with are:

** Rtags
Rtags help the user jump around the code easily and provide integration with many clang utilities like Clang fixits.
The main functionality that malinka provides is to properly populate and communicate the
compiler commands to the rtags daemons depending on the project you are working
on.

If you have not installed rtags yet, visit their [[https://github.com/Andersbakken/rtags][github page]] and read more information
about how you can acquire and use rtags. Alternatively if you used [[https://github.com/dimitri/el-get][el-get]] to get malinka
rtags should have been downloaded and built as a dependency

** Flycheck
Optionally and if you also have [[https://github.com/flycheck/flycheck][flycheck]] with the clang syntax-checker activated,
malinka will communicate to flycheck's clang syntax checker the appropriate
=cpp-defines= and =include-paths= so that flycheck can do its syntax checking.

** Projectile
If you are using [[https://github.com/bbatsov/projectile][projectile]] then malinka can provide projectile with the compile and test commands
to build and test your project respectively. Projectile also helps with the detection
of root directory for projects.

** Irony
If you are using [[https://github.com/Sarcasm/irony-mode][irony mode]] malinka can then provide the json compilation database for your project
that will be indexed by the irony server

* Example Setup
:PROPERTIES:
:CUSTOM_ID: example_setup
:END:
Working with malinka requires that you define your project somewhere in your emacs
file using =(malinka-define-project)=.

#+BEGIN_SRC emacs-lisp
(require 'malinka)

(add-hook 'c-mode-common-hook 'malinka-mode)

(malinka-define-project
:name "ethereum"
:root-directory "/home/lefteris/ew/cpp-ethereum"
:build-directory "/home/lefteris/ew/cpp-ethereum/build"
:configure-cmd "cmake .. -DCMAKE_BUILD_TYPE=Debug -DHEADLESS=1"
:compile-cmd "make -j4"
:test-cmd "./test/testeth")
#+END_SRC

In the above example we can see malinka's initialization and a sample definition of a project.
You need to hook =malinka-mode= to c/c++ mode so that all malinka functionality can operate only
on the loading of those type of buffers.

Let's look now at the arguments of a project's definition one by one.

** name
This is the name of the project. This is how malinka will refer to your project everywhere. Must be unique.
** root-directory
This is the root directory of the project.

** build-directory
This is the directory where the =build-cmd= and =compile-cmd= will be executed in.

** configure-cmd
This is the command to configure the project for malinka. This is what malinka will use to create the
json compilation database. There are 2 different ways to achieve this and depends on the type of build system you
use to build your project.
*** cmake > 2.85
If malinka detects you are using cmake with version greater than 2.85 then it will use cmake to create
the compilation database in the build directory.
*** all others
For all other cases, simple makefiles, scons, waf e.t.c. you have to provide the build command here making sure that it will
provide visible compile output. You can simply add the =--dry-run= option in most build systems as this command should be used
just to create the compilation database. The output will be parsed by malinka and the compilation database will be created.
** compile-db-cmd
This command instructs malinka in what way to generate the compilation database. =compile-db-cmd= takes precedence over configure-cmd. When =configure-cmd= is not enough to generate a correct compilation database, you should use =compile-db-cmd=. One example is when using ninja or bear to generate a compilation database. You should provide a command that could always generate a compilation database correctly. For example, you may add =bear make -B= to make sure it always generate a compilation database whenever current project has been already built.
** compile-cmd
This is the command to compile the whole project. This is what will be given to projectile's =projectile-compile-project=
to compile your project with your chosen keybinding. Default is: =C-c p c=
** test-cmd
This is the command to test the project. This is what will be given to projectile's =projectile-test-project=
to test your project with your chosen keybinding. Default is: =C-c p P=. It is an optional project attribute.
** run-cmd
This is the command to run the executable or anything else generated by the project. It is bound to =projectile-run-command=
and the default keybinding is =C-c p u=. This is an optional project attribute.
* Usage
As shown in the [[#example_setup][example setup]] section the basic configuration that needs to exist in order to use malinka is to define your
projects using =(malinka-define-project)= Following that the way to interact with the defined projects is
via the following interactive API:

- =(malinka-project-configure name given-root-dir)=

You will be prompted with a list of the known projects and you will have to select the one you need to configure.
Basically this command will create the compilation database for your project and feed the data to the packages you use.
Depending on project size this may take quite a bit of time.

The given-root-dir is optional and will only be asked if you failed to provide one in the project definition.

- =(malinka-project-select name given-root-dir)=

You will be prompted with a list of the known projects and you will have to select the one you need to select.
Basically this command will search for the compilation database in the selected project, read it and feed
the data to the packages you are using.

The given-root-dir is optional and will only be asked if you failed to provide one in the project definition.
* Operation
Malinka will attempt to feed data to all the C/C++ relevant packages that it can detect while a buffer of
a malinka project is currently visited.
** Idle Check
If `malinka-enable-idle-project-check' is non-nil then at the specified interval of
`malinka-idle-project-check-seconds' the visited buffer's file will be checked against
all the known malinka projects.

If it is found to be under a project's root then that project is considered the current
project and is selected by malinka. Selection basically means feeding the appropriate
data to each of the other C/C++ packages.

* Customization
As a user you have ample customization choices when using malinka. These are:
- *malinka-completion-system*:
As a user you have a choice of the completion system to choose when selecting a defined project.
As inspired by [[https://github.com/flycheck/flycheck][flycheck]]'s customization there are currently two choices offered:
- [[http://www.emacswiki.org/emacs/InteractivelyDoThings][IDO]]: the built-in completion system with fuzzy searching. Powerful though it is, one can really
improve it by using [[https://github.com/lewang/flx][flx-ido]].

- [[http://www.gnu.org/software/emacs/manual/html_node/elisp/Minibuffer-Completion.html][Completing Read]]: The very simple and not fancy emacs built-in completion system. Is the default.

- *malinka-ignored-directories*:
A list of directories to ignore for file searching

- *malinka-supported-compilers*:
A list of compiler executable names that are recognized and supported by malinka.

- *malinka-supported-file-types*:
File extensions that malinka will treat as related source and header files.

- *malinka-supported-header-types*:
File extensions that malinka will treat as related header files.

- *malinka-idle-project-check-seconds*:
The idle time in seconds to wait until we perform a project idle [[Idle Check][check]]. Can be nil or 0 to disable idle project checks.

- *malinka-mode-line*:
The string to show on the modeline when malinka minor mode is active

- *malinka-print-info?*:
If true malinka will be printing some info messages of the actions it takes.
- *malinka-print-warning?*:
If true malinka will be printing warning messages in case things go wrong but can be taken care of
- *malinka-print-debug?*:
If true malinka will be printing a lot of DEBUG messages. Only useful for debugging
- *malinka-print-xdebug?*:
If true malinka will be printing extreme DEBUG messages. Only useful for debugging. Warning: This WILL spam the *Messages* buffer
* Issues
If you have problems, bugs or feature requests feel free to open an issue in [[https://github.com/LefterisJP/malinka/issues][github]]
and I will take a look at it when I find the time.

** Common Issues

- *Can't index file*

To get a view of the connection between Emacs and the rtags daemon you can always
check the =*rdm*= buffer. There you can see after a ~M-x malinka-project-configure~
if the files are indexed properly.

If for some reason a file can't be indexed and in the =*rdm*= buffer you get
something like below:
#+BEGIN_SRC sh
Failed to make location from [filename:line:column]
#+END_SRC
Then I would suggest removing the rtags cache kept under =~/.rtags= by default
and then redoing a ~M-x malinka-project-configure~. Also killing the =rdm= daemon is a good idea.

* Contributions
All contributions are welcome. If you would like to help you can open a pull request with your suggested contribution.
** Running tests
#+begin_src sh :tangle yes
cask
make compile
make lint
make test
#+end_src
** Styling
The malinka code is written in elisp and for styling we use the [elisp-formatter](https://www.emacswiki.org/emacs/ElispFormat) tool.
If you make any contributions please make sure they adhere to the elisp style rules by also running it on your Pull Request.