Skip to content
Dominique Lasserre edited this page Aug 15, 2014 · 3 revisions

"Code is read much more often than it is written" (Guido Van Rossum)

A consistent programming style helps to read and understand code much more easily. Following sections define the style by source language. Please ask on #valama if unsure.

These guidelines are never finished so please report any missing or ambiguous items.

General

Length of source lines

The soft-limit is 79 characters, the hard limit is 119 characters (without newline).

Trailing whitespaces

No whitespaces at end if line. Git's pre-commit example hook may be help.

Vala

Indentation

One indentation level is 4 spaces (no tabs). Opening braces appear on same line as proceeding code.

using GLib;

public static int main() {
    if (1 == 2) {
        if (2 == 3) {
            print ("Should never happen!\n");
            return 40;
        } else {
            print ("Should never happen too!\n");
            return 41;
        }
    } else {
        print ("Should always happen!\n");
        return 42;
    }
}

using directives and type interference

Make use of using directives and var keyword, also name default GLib directive.

using GLib;
using Gtk;

public void show_about_dialog() {
    var dlg = new AboutDialog();
    dlg.authors = {"Me"};
    dlg.run();
}

Braces and whitespaces

There is no whitespace before empty braces, but a single one before non-empty braces. There is a single whitespace before : of parent class or interfaces.

using GLib;
using Gtk;

public MyApp : Object {
    public static void main (string[] args) {
        Gtk.init (ref args);

        var window = new Window();
        window.destroy.connect (Gtk.main_quit);

        var btn = new Button.with_label (args[0]);
        window.add (btn);

        int i = 0;
        btn.forall_internal (true, () => {
            print ("child no. %d\n", ++i);
        });

        window.show_all();

        Gtk.main();
    }
}

Optional braces

Omit optional braces.

using GLib;

public static main() {
    if (1 == 2)
        print ("1 == 2 (!)\n");
    else
        foreach (var word in new string[] {"We", "had", "luck", "!\n"};
            print (word);
}

Naming conventions

Follow Vala conventions.

Empty body

Empty bodies may be written within a single line.

public void some_method() {}

Comments

Use block comments for long comments and important notes. Use line comments for short (and unimportant) and temporary comments. Comments should treat the line length soft limit of 79 characters as hard limit. Line comments are at least two whitespaces next to code. Aligning comments is allowed.

It's recommend to use Valadoc comments for code elements.

Use FIXME indicator for serious bugs, TODO for minor bugs or enhancements, NOTE to explain why this implementation was chosen and TRANSLATORS for translators notes (place translators notes directly above string to translate). It's recommend to name bug number of related bug (no need to differentiate between Valama Github issues and GNOME issues because there are << 10000 issues in Github bugtracker).

using GLib;

/**
 * Useless method for demonstration purposes.
 *
 * This is btw. a [[http://www.valadoc.org/#!wiki=markup|Valadoc comment]].
 */
public static void main() {
     Intl.textdomain ("mypackage");
     Intl.bindtextdomain ("mypackage", "/usr/share/locale");

     Menu menu = null;  //TODO: Do we need this?

     var i = 0;     // aligned comment
     var j_two = 1  // aligned comment

     //NOTE: Test this condition to make sure the world behaves like normal.
     if (j_two == i)
         //TRANSLATORS: No need to translate this.
         print (_("ASDFAsdF\n"));  // comment (two whitespaces to code)
     else
         //FIXME: Does not work!
         menu.append ("some text");
}

Wrapping long lines

Try to wrap lines longer than 79 characters. Align wrapped lines. Keep operators in proceeding line (and add additional indentation level to separate expression and following code).

using GLib;

extern bool some_other_chuck_test (string db);

public static void main() {
    var db = Path.build_path (Path.DIR_SEPARATOR_S,
                              Environment.get_user_cache_dir(),
                              "appname",
                              "foobar.db");

    if ((Environment.get_home_dir() == "/home/chucknorris") &&
            some_other_chuck_test (db))  // extra indentation level
        print ("Nice to meet you Chuck!\n");
    else
        print ("Db path: %s\n", db);
}

Aligning code

If some code looks very similar aligning and compacting the code is allowed.

using GLib;

public static int main() {
    if (1 == 0)     return 1;
    if (42 == 0)    return 1;
    if (222 == 123) return 1;
    return 0;
}

Access keywords

Always name access keywords (don't omit private keyword).

using GLib;

public class FooBar {
    private int internal_number = 0;
    public int public_number = 0;
}

Header and footer

Use following header (replace PATH/TO/FILENAME.vala accordingly):

/*
 * PATH/TO/FILENAME.vala
 * Copyright (C) YEARS, Valama development team
 *
 * Valama is free software: you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by the
 * Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * Valama is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 * See the GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License along
 * with this program.  If not, see <http://www.gnu.org/licenses/>.
 *
 */

Use following footer:

// vim: set ai ts=4 sts=4 et sw=4

CMake

Indentation

One indentation level is 2 spaces (no tabs). Break line on macros/functions with lots of arguments and indent both parameter and additionally argument (exception is empty COMMENT "").

function(some_function)
  if(1 EQUAL 2)
    message("strange behavior!")
    if(1 EQUAL 1)
      message("at least this one works")
    endif()
  endif()

  install(FILES "some_file" DESTINATION "${CMAKE_INSTALL_PREFIX}/share/myapp")
  add_custom_command(
    OUTPUT
      "foobar.stamp"
    COMMAND
      "${CMAKE_COMMAND}" -E touch "foobar.stamp"
    COMMENT ""
  )
endfunction()

Braces and whitespaces

There is no whitespace before all kind of braces. See example above.

Middle/ending tags

Middle (else/elseif) or ending (enfunction/endif/endforeach etc.) tags don't include start tag content. See example above.

Naming conventions

  • Options are written UPPER_CASE.
  • (Local) variables are written lower_case.
  • Functions/macros are written lower_case.
  • Parameters of functions/macros and operators are written UPPERCASE
option(MY_OPTION "descriptive help" ON)
set(foobar_list)
list(APPEND foobar_list "123")

Comments

Comments should treat the line length soft limit of 79 characters as hard limit. Line comments are at least two whitespaces next to code. Aligning comments is allowed.

All macros and functions have to have explaining comment strings (see example).

Use FIXME indicator for serious bugs, TODO for minor bugs or enhancements and NOTE to explain why this implementation was chosen. It's recommend to name bug number of related bug (no need to differentiate between Valama Github issues and GNOME issues because there are << 10000 issues in Github bugtracker).

##
# Short description
#
# Long description.
#
# Usage:
# ARG_WITHOUT_ARG
#   Some description.
#
# ARG_WITH_ONE_ARG
#   Some description.
#
# ARG_WITH_MULTIPLE_ARGS
#   Some description.
#
# SECOND
#   Some description.
#
#
# Simple example:
#
#   set(some_list "1" "2" "3" "4")
#   some_function(
#     ARG_WITHOUT_ARGS
#     ARG_WITH_ONE_ARG
#       "some_arg"
#     ARG_WITH_MULTIPLE_ARGS
#       ${some_list}
#     SECOND
#       "some other arg (which also could be a list)"
#   )
# 
function(some_function)
  include(CMakeParseArguments)
  cmake_parse_arguments(ARGS "ARG_WITHOUT_ARG" "ARG_WITH_ONE_ARG" "ARG_WITH_MULTIPLE_ARGS;SECOND" ${ARGN})
  if(ARGS_ARG_WITHOUT_ARG)
    if(NOT "" STREQUAL ARGS_ARG_WITH_ONE_ARG)
      message("arg: ${ARGS_ARG_WITH_ONE_ARG}")
    endif()
  endif()
  foreach(args ${ARGS_ARG_WITH_MULTIPLE_ARGS} ${ARGS_SECOND})
    message ("mult args: ${args}")  #TODO: actual implementation
  endforeach()
endfunction()

Wrapping long lines

Try to wrap lines longer than 79 characters. Align wrapped lines. Keep operators in proceeding line (and add additional indentation level to separate expression and following code).

configure_file(
  "${CMAKE_SOURCE_DIR}/some_very_very_long_file_name_and_very_very_long_file_path.in"
  "${CMAKE_BINARY_DIR}/some_very_very_long_file_name_and_very_very_long_file_path"
  @ONLY
)
if("${foobar}" STREQUAL "some_long_file_name" AND
    "${barfoo}" STREQUAL "some_other_long_file_name")
  execute_command(
    COMMAND
      "${CMAKE_COMMAND}" -D "some_var=${foobar}"
                         -D "some_other_var=${barfoo}"
                         -P "${CMAKE_BINARY_DIR}/some_very_very_long_file_name_and_very_very_long_file_path"
  )
endif()

Quoting

Quote as much as possible.

Header and footer

Use following header (replace PATH/TO/FILENAME accordingly):

#
# PATH/TO/FILENAME
# Copyright (C) YEARS, Valama development team
#
# Valama is free software: you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by the
# Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# Valama is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
# See the GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License along
# with this program.  If not, see <http://www.gnu.org/licenses/>.
#

Use following footer:

# vim: set ai ts=2 sts=2 et sw=2

XML (.xml, .info, .vlp)

Indentation

One indentation level is 2 spaces for .xml files and 4 spaces for .info files and one tab for .vlp files.