Lugaru's Epsilon
Programmer's
Editor 14.04

Context:
Epsilon User's Manual and Reference
   Commands by Topic
      . . .
      Changing Text
         Inserting and Deleting
         Killing Text
         Clipboard Access
         . . .
         Hex Mode
      Language Modes
         Asm Mode
         Batch Mode
         C Mode
            Other C mode Features
         Configuration File Mode
         GAMS Mode
         . . .
      More Programming Features
         Navigating in Source Code
         Pulling Words
         Accessing Help
         Context-Sensitive Help
         Commenting Commands
      . . .

Previous   Up    Next
Batch Mode  Commands by Topic   Other C mode Features


Epsilon User's Manual and Reference > Commands by Topic > Language Modes >

C Mode

The c-mode command puts the current buffer in C mode. C mode provides smart indenting for programs written in C, C++, C#, JavaScript, Java, Epsilon's extension language EEL, Objective-C, and other C-like languages. Pressing <Enter> or <Tab> examines previous lines to find the correct indentation. Epsilon supports several common styles of indentation, controlled by some extension language variables.

The closeback variable controls the position of the closing brace:

closeback = 0;
if (foo){
    bar();
    baz();
    }

closeback = 1;
if (foo){
    bar();
    baz();
}

By placing the opening brace on the following line, you may also use these styles:

closeback = 0;
if (foo)
    {
    bar();
    baz();
    }

closeback = 1;
if (foo)
{
    bar();
    baz();
}

Closeback by default has a value of 1. This variable also recognizes the value 2 to indicate that lines starting with a right parenthesis should be indented to match the start of the line with its matching left parenthesis, not the left parenthesis itself.

Use the Topindent variable to control the indentation of top-level statements in a function:

Topindent = 0;
foo()
{
if (bar)
    baz();
}

Topindent = 1;
foo()
{
    if (bar)
        baz();
}

Topindent by default has a value of 1.

The Matchdelim variable controls whether typing ), ], or } displays the corresponding (, [, or { using the show-matching-delimiter command. The Matchdelim variable normally has a value of 1, which means that Epsilon shows matching delimiters. You can change these variables as described in Variables.

In C mode, the <Tab> key reindents the current line if pressed with point in the current line's indentation. <Tab> just inserts a tab if pressed with point somewhere else, or if pressed two or more times successively. If you set the variable c-tab-always-indents to 1, then the <Tab> key will reindent the current line, regardless of your position on the line. If you press it again, it will insert another tab. The <Enter> key indents the line it inserts, as well as the current line (but see the c-reindent-previous-line variable).

When you yank text into a buffer in C mode, Epsilon automatically reindents it. This is similar to the "smart paste" feature in some other editors. You can set the variable reindent-after-c-yank to zero to disable this behavior. Epsilon doesn't normally reindent comments when yanking; set the reindent-c-comments and reindent-one-line-c-comments variables to change that. Also see the reindent-c-preprocessor-lines variable.

By default, Epsilon uses the value of the buffer-specific tab-size variable to determine how far to indent. For example, if the tab size has a value of 5, Epsilon will indent the line following an if statement five additional columns.

If you want the width of a tab character in C mode buffers to be different than in other buffers, set the variable c-tab-override to the desired value. C mode will change the buffer's tab size to the specified number of columns. The eel-tab-override variable does the same in EEL buffers (which use a variation of C mode). Also see the description of file variables in File Variables for a way in which individual files can indicate they should use a particular tab size.

If you want to use one value for the tab size and a different one for C indentation, set the buffer-specific c-indent variable to the desired indentation using the set-variable command. When c-indent has a value of zero, as it has by default, Epsilon uses the tab-size variable for its indentation. (Actually, the <Tab> key in C mode doesn't necessarily insert a tab when you press it two or more times in succession. Instead, it indents according to c-indent. If the tab size differs from the C indent, it may have to insert spaces to reach the proper column.)

In Java files, Epsilon uses the similar variable java-indent to set the column width of one level of indentation.

The c-case-offset variable controls the indentation of case statements. Normally, Epsilon indents them one level more than their controlling switch statements. Epsilon adds the value of this variable to its normal indentation, though. If you normally indent by 8 spaces, for example, and want case statements to line up with their surrounding switch statements, set c-case-offset to -8.

Similarly, the c-access-spec-offset variable controls the indentation of public:, private:, protected: (and, for C#, internal:) access specifiers.

The c-label-indent variable provides the indentation of lines starting with labels. Normally, Epsilon moves labels to the left margin.

Epsilon offsets the indentation of a left brace on its own line by the value of the variable c-brace-offset. For example, with a tab size of eight and default settings for other variables, a c-brace-offset of 2 produces:

        if (a)
          {
                b();
          }

The variable c-top-braces controls how much Epsilon indents the braces of the top-level block of a function. By default, Epsilon puts these braces at the left margin. Epsilon indents pre-ANSI K&R-style parameter declarations according to the variable c-param-decl. Epsilon indents parts of a top-level structure or union according to c-top-struct, and indents continuation lines outside of any function body according to c-top-contin. Continuation lines for classes and functions that use C++ inheritance syntax may be indented according to c-align-inherit.

Additional C mode indentation variables that may be customized include c-indent-after-extern-c, c-align-break-with-case, c-indent-after-namespace, and reindent-c-preprocessor-lines.

By default, the C indenter tries to align continuation lines under parentheses and other syntactic items on prior lines. If Epsilon can't find anything on prior lines to align under, it indents continuation lines two levels more than the original line. (With default settings, Epsilon indents unalignable continuation lines 8 positions to the right of the original line.) Epsilon adds the value of the variable c-contin-offset to this indentation, though. If you want Epsilon to indent unalignable continuation lines ten columns less, set c-contin-offset to -10 (it's 0 by default).

If aligning the continuation line would make it start in a column greater than the value of the variable c-align-contin-lines (default 48), Epsilon won't align the continuation line. It will indent by two levels plus the value of c-contin-offset, as described above. A negative value for c-align-contin-lines removes the limit entirely. Also see the c-align-extra-space variable for an adjustment Epsilon makes for continuation lines that would be indented exactly one level.

As a special case, setting the c-align-contin-lines to zero makes Epsilon never try to align continuation lines under syntactic features on prior lines. Epsilon will then indent all continuation lines by one level more than the original line (one extra tab, normally), plus the value of the variable c-contin-offset.

If the continuation line contains only a left parenthesis character (ignoring comments), Epsilon can align it with the start of the current statement if you set c-align-open-paren nonzero. If the variable is zero, it's aligned like other continuation lines.

You can also have Epsilon use less indentation when a line is very wide. The variable c-align-contin-max-width sets a maximum line width for continuation lines, when nonzero. Set it to -1 to use the current window's width.

When a continuation line is wider than that many columns, the c-align-contin-max-offset variable says what to do about it. If greater than zero, Epsilon indents by that amount past the base line (similar to how c-contin-offset works). If zero, Epsilon right-aligns the wide line to c-align-contin-max-width. If negative, it right-aligns but with that amount of extra space.

These "max" variables, unlike c-align-contin-lines, look at the total width of the line, not just the width of its indentation.

C mode also provides special indenting logic for various macros used in Microsoft development environments that function syntactically like braces, such as BEGIN_ADO_BINDING(). See the use-c-macro-rules variable.

In Objective-C code, Epsilon right-aligns the selectors (argument labels) of multi-line messages, according to the c-align-selectors variable.

In C mode, you can use the find-linked-file command on Ctrl-x Ctrl-l to read the header file included with a #include or #import statement on the current line, or use the copy-include-file-name on Ctrl-c Alt-i in a header file to create a suitable #include statement. See the include-directories variable, and the mac-framework-dirs variable for includes that depend on Macintosh framework search paths.

Disabling C Mode Indenting

If you prefer manual indenting, various aspects of C mode's automatic indentation can be disabled. If you don't want keys like # or : or curly braces to reindent the current line, just bind those keys in C mode to normal-character. Set reindent-after-c-yank and c-reindent-previous-line to zero to disable reindenting when yanking, and keep indenting commands from fixing up earlier lines. If you want the <Enter> key to go to the next line without indenting, while Ctrl-j still does both, you can define a keyboard macro for the former key. Similarly, if you want smart indenting from the <Tab> key but a plainer indent from Ctrl-i, you can define that by binding do-c-indent to the former and one of indent-previous, indent-under, indent-like-tab, or normal-character to Ctrl-i.

(In a Unix terminal environment, Epsilon can't distinguish keys like <Enter> and <Tab> from Ctrl-m and Ctrl-i, respectively, so you'd need to pick different keys.)

Here is an example of the changes to accomplish this.

~c-tab "#": normal-character
~c-tab ")": normal-character
~c-tab ":": normal-character
~c-tab "]": normal-character
~c-tab "{": normal-character
~c-tab "}": normal-character
(set-variable "reindent-after-c-yank" 0)
(set-variable "c-reindent-previous-line" 0)
(define-macro "plain-enter" "C-QC-J")
~c-tab "<EnterKey>": plain-enter
~c-tab "<TabKey>": do-c-indent
~c-tab "C-I": indent-previous

Pick the customizations you want, modify them as appropriate, and copy them to your einit.ecm customization file (see Command Files). Epsilon will begin using the changes the next time it starts up (or use load-buffer to load them immediately).

A useful technique when customizing language mode bindings like the above is to run the list-all command, then copy the particular lines you want to change into your einit.ecm file and modify them. See Bindings.

Standard bindings:

    c-mode
 C Mode only: <Tab>  do-c-indent
 C Mode only: {  c-open
 C Mode only: }  c-close
 C Mode only: :  c-colon
 C Mode only: #  c-hash-mark
 C Mode only: ), ]  show-matching-delimiter
 

Subtopics:

Other C mode Features



Previous   Up    Next
Batch Mode  Commands by Topic   Other C mode Features


Lugaru Epsilon Programmer's Editor 14.04 manual. Copyright (C) 1984, 2021 by Lugaru Software Ltd. All rights reserved.