Function and Variable Naming
Conkeror uses snake_case for variable and function names. That means they are lower case with words separated by underscores. By contrast, the Mozilla codebase uses camelCase style. This difference makes it easy to tell at a glance whether a given identifier is part of Conkeror or part of the underlying Mozilla platform. We also find the underscore style easier to read.
If the identifier is part of a module, it should begin with the name of the module. Abbreviate sparingly --- abbreviations in identifier names don't really make anyone's life easier.
Note that exceptions to this guideline can be found in the Conkeror source, but only for historical reasons. All new identifiers should follow this guideline for style.
New User Variables
If you use define_variable to add a new user variable to Conkeror, document it in UserVariables or in a page about the module the variable belongs to on this wiki.
Avoid pushing merge commits
We like to keep our commit history tidy. We also like it to be, whenever possible, a linear sequence of complete patches, each specific to one feature or fix, etc. Taking care up front to make good patches and keep the git history clean pays off later when we need to backtrack for whatever reason, like finding when a bug was introduced. Git provides all the tools to make this possible, from rebase to commit --amend to git-gui. Refer to GitHelp and other git documentation for more details.
Never rebase or otherwise edit the commit history of any branch on our official repository. (People depend on that one.) On your own clones, however, rebasing can be a nice way to keep your patches tidy for other developers and users. We won't mind.
Breaking Changes
If you make a change to Conkeror that is likely to break users' rc scripts, or a non-trivial change to the UI, announce it far and wide. Note it on BreakingChanges in this wiki, and announce it on irc and the mailing list. Update any documentation relevant to the change.
Long Strings
Break up long strings into several short strings, concatenated with the + operator.
Commit Messages
In order to play nice with GitWeb, it is best if commit messages are in the following form:
<blank line> 1 line briefly describing the change. try for less than 60 characters. <blank line> The change described in full detail. Wrap paragraphs to 60 or 70 characters.
Whitespace & Style
- basic indent is 4 spaces.
- no tabs, not no way, no how.
- no extra end-of-line space.
- one blank line at the end of a file.
in function calls, no space between the function name and the following opening paren, e.g: foo().
in function definitions, one space between the name of the function and the following paren, e.g: function foo () {....
in inline functions, one space between the keyword function and the following opening paren.
one space between the name of any javascript statement keyword and the following opening paren, e.g: if (foo).
opening curly braces usually on the same line as the accompanying keyword: if (foo) { and function foo () {.
- the exception to that rule is that if the conditional form of an "if" spans multiple lines, the curly brace may need to go on the following line to provide visual separation between conditional and body.
- no parens around the "argument" to "typeof", because typeof is a keyword, not a function.
prefer not to perform an assignment inside of the conditional part of an if or a while, but if there is a good reason to, put an extra set of parens around it.
in javascript objects, no space between the key and the colon...e.g: { foo: "bar" }.
- generally follow the 80 column rule, but occasionally it's okay to make exceptions.
prefer var to let; use let only where meaningful to do so.
- and the one rule that might drive some people crazy, but works well in practice is that long strings like docstrings, or inline functions that get passed to define_* or interactive forms only get indented by 4 spaces, instead of lining up with the opening paren of the function. Conkeror makes extensive use of this style in order to have a lisp-like declarative API. Just pretend these forms are macros because indenting them this way keeps the source code from running ridiculously far to the right. Incidentally, the first argument to these forms should be on the same line as the function name because it makes grepping easier. Example:
interactive("paste-x-primary-selection", "Insert the contents of the X primary selection into the selected field or "+ "minibuffer. Deactivates the region if it is active, and leaves the point "+ "after the inserted text.", function (I) call_on_focused_field(I, paste_x_primary_selection));
conkeror-minor-mode
If you're an emacs user, there's an emacs minor mode designed to help you follow these guidelines. It's called conkeror-minor-mode and:
- It automatically follows this indentation style for "macro"-like functions.
- It warns you if you break any of the other whitespace guidelines.
- It provides syntax coloring of functions and variables.