Editors

From Mu2eWiki
Jump to navigation Jump to search


Introduction

Please configure your editor(s) so that they do not write tab characters to source code files. You can copy examples from Bootstrap repo. Please do configure your editor so that, when you hit the tab key, it inserts the appropriate number of spaces to achieve the desired formatting.


Also below are some tips for using editors in the mu2e offline environment.

emacs

Tabs

Using tab characters in source files is disfavored because different users may have different display setting for tabs, so what looks well-formatted to one user will look incorrect to another. Space characters with a monospace font will have the same visual appearance to all users.

Tab key fills with spaces

Please add the following line to the end of your ~/.emacs file

(setq-default indent-tabs-mode nil)

If you are using xemacs, add the same line to your ~/.xemacs/init.el file.


Checking if a File Has Tabs

There are two ways, using emacs, to check if a file contains tab characters. You can pull down the "Edit" menu from the menu bar near the top of the window; select "Find ..." this will pop up a dialog box. Move the mouse to the input box, press the tab key and then click on "Find next". If there are tab characters in the file, this will repaint the screen and move the cursor to the first tab character. If there are no tab characters in the file the message "Search failed" will appear in the box at the bottom of the screen.

You can also do this from command mode:

  1. ctrl-s
    • Press down the Ctrl key and simultaneously the s key. Release both keys.
    • You will get the following prompt at the bottom of the window: "I-Search: "
  2. type the tab key.
    • If there is a tab character in the file, the screen will repaint with the cursor moved to the first tab character.
    • If there is no tab character in the file, then following message will appear at the bottom of the screen: "Failing I-search: ".

Changing Existing Tabs

This is the recommended procedure for removing tabs from a file.

  1. Select the full file by setting the mark at the top of the file and moving the cursor to the bottom of the file.
  2. ESC-x untabify
    Here ESC-x means to hit the escape key, followed by the letter x. This will open a mini-buffer at the bottom of the window into which you type the command untabify. This command will remove tabs from the selected region and replace them with the appropriate number of spaces.

Inserting a Tab Character on Purpose

If you really want to insert a tab character into a file, then quote it using ctrl-q; that is, simultaneously hold down ctrl key and the q key, release both and type the tab key. You should rarely need to do this. In C++ mode, emacs will usually accept a tab as a tab if it is typed within a character string; moreover one can always use the sequence \t to insert a tab into a string; this is preferred to typing an actual tab character.

Trailing whitespace

Unnecessary whitespace at the end of lines causes source file differences with no meaning. While git has switches to ignore whitespace differences, it is more convenient to avoid it in the first place.

The following .emacs code will cause this whitespace to be highlighted. It also includes the indent-tab switches.

;; ----------------------------------------------------------------
;; See http://www.emacswiki.org/emacs/WhiteSpace
(require 'whitespace)
(setq whitespace-style '(face empty tabs trailing))
(add-hook 'c++-mode-hook
           '(lambda ()
                   (whitespace-mode)))
(add-hook 'c++-mode-hook
         '(lambda ()
            (setq indent-tabs-mode nil)))
(add-hook 'sh-mode-hook
           '(lambda ()
                   (whitespace-mode)))
(add-hook 'sh-mode-hook
         '(lambda ()
            (setq indent-tabs-mode nil)))
(add-hook 'latex-mode-hook
           '(lambda ()
                   (whitespace-mode)))
(add-hook 'latex-mode-hook
         '(lambda ()
            (setq indent-tabs-mode nil)))
;; ----------------------------------------------------------------

Forcing a newline at the end of File

In all cases that are relevant for Mu2e, a properly formatted text file must end in a newline character ( this is the character created by pressing the enter key on your keyboard ). This is true for source code files, FHiCL files, the geometry file and so on. Without this newline, some odd things can happen, like line counts will be unexpected and printed lines will run together.

Some of the applications that digest these files, such as the g++ compiler, are forgiving about a missing terminal newline. Other applications are not. In particular:

  1. In the mu2egrid scripts, the option --prestage-spec=file.list says that the file named "file.list" contains a list of files to be pre-staged to the worker node. If this file does not end in a newline, the last line in the file will be ignored and that file will not be pre-staged.
  2. cron will ignore the last line in a crontab file if terminal newline is missing.

If you use emacs, you tell emacs to check for the terminal newline and to add one if it is missing. There are several ways to do this. In your .emacs file you can add the line:

(setq-default require-final-newline t)

This will force a newline whenever you save a file. Alternatively, you can add the following to your .emacs file

(setq-default require-final-newline 'visit-save)

When this identifies a missing newline, it will prompt you for whether or not it should add a newline.


Viewing the Geometry Files with C++ Mode

If you use an editor with syntax highlighting, it is helpful to view the the Mu2e geometry files and the Mu2e generator configuration files using C++ mode with syntax highlighting. This is helpful because the language used in these files has a C++-like syntax. For the time being, these files have a file type of .txt which complicates the job of automatically selecting C++-mode when opening the file. In the future we may change the file type from .txt in order to make it easier to choose appropriate syntax highlighting.

Even without this change, if you use the emacs editor, you can automatically enable c++-mode in a geometry or generator configuration file by adding the following comments at the end of the file:

// Local Variables:
// mode:c++
// End:

The capitalization and the : are important. If you have syntax highlighting automatically enabled for c++ mode then these files will be viewed with syntax highlighting. I will add comments like this to the end of most of the geometry and generator configuration files.

This technique is described in the emacs manual under the section that discusses File Variables.


Viewing the FHiCL files with art-fhicl Mode

An emacs mode for editing FHiCL files has been developed and is accessible directly through the Fermilab common UPS products area. For those who use the mu2egpvm*.fnal.gov machines, the mode can be enabled by logging on to the machine, and then typing the following on the command line:

ups configure art_fhicl_mode

This will add the following lines to the end of your ~/.emacs file:

(load (shell-command-to-string (concat ". " (getenv "SETUPS_DIR") "/setups.sh; setup art_fhicl_mode; printf $ART_FHICL_MODE_DIR/art-fhicl-mode.el")) nil t t)
(add-to-list 'auto-mode-alist '("\\.fcl$" . art-fhicl-mode))

In order to ensure that syntax highlighting is enabled, the following line must also be present in your ~/.emacs file:

; enable color syntax highlighting everywhere
(global-font-lock-mode t)


Alternatively, you can download the art-fhicl-mode.el file from Github . Create the directory ~/share/emacs/site-lisp/ and move the art-fhicl-mode.el source code there.Add the following code to your ~/.emacs file:

; extend the search path
(add-to-list 'load-path "~/share/emacs/site-lisp")
; enable color syntax highlighting everywhere
(global-font-lock-mode t)
; load art-fhicl-mode for fcl highlighting, etc.
(load "art-fhicl-mode.el" nil t t)
; associate .fcl files with art-fhicl-mode
(add-to-list 'auto-mode-alist '("\\.fcl$" . art-fhicl-mode))

Note that FHiCL is nearly identical structurally to YAML, and it is possible to use YAML mode to syntax highlight FHiCL, obtained here. The dedicated art-fhicl mode is likely to be more helpful, however.

vim

If you use the vim editor, here are some useful configuration options.

Tabs

  • To change all existing tab characters into spaces so as to match the current tab stop settings, use the 'retab' command. The default tab stops are very 8 columns, but that can be changed by setting the 'tabstop' option to something other than 8.
  • Set the 'expandtab' (abbreviated to 'et') option to convert each tab automatically as you type it into a number of spaces. You can set this option in your ~/.vimrc file.) Once this option is set, use Ctrl-V<Tab> if you want to enter a real tab character.

Removing Trailing Whitespace

  1. To remove trailing whitespace, use the following command: %s/\s\+$//
  2. To remove trailing whitespace automatically when writing a file, put the following in your ~/.vimrc file:
  3. autocmd BufWritePre * :%s/\s\+$//e Some people don't use vim autocommands because every so often they need finer control.


Command line tips

To find files with trailing whitespace:

 LC_ALL=C grep -lr  '[[:space:]]$' *

To find files with leading tabs, or any tabs:

LC_ALL=C grep -rlP "^\t" *
LC_ALL=C grep -rlP "\t" *

To find files with unprintable characters

LC_ALL=C grep -rl '[^[:print:][:blank:]]' *

To find files with CRLF (windows style) end-of-line

LC_ALL=C grep -lr $'\r' *

To remove trailing whitespace:

 LC_ALL=C find <directory> \( -name "*.cc" -o -name "*.hh" -o -name "*.fcl" -o -name "geom*.txt" \) -exec \
   sed -i -e 's/[[:space:]]*$//' {} \;

The "-i" to sed says to edit the file in place.
To replace leading tabs with 8 spaces.

LC_ALL=C find <directory> \( -name "*.cc" -o -name "*.hh" -o -name "*.fcl"  -o -name "geom*.txt" \) -exec \
  sed -i -e 's/^\t/        /g' {} \;

If you want other numbers of spaces, you can change it in the sed command. To change all tabs, not just leading, remove the "^". See also CodeTools

To remove CRLF windows end-of-line:

LC_ALL=C sed -i 's/\r$//' <file>

To ensure that a all selected files end with a newline character:

find . \( -name \*.fcl -o -name \*.cc -o -name \*.hh \) -exec sed -i -e '$a\' {} \;

This does not modify any files that already end in a newline character. For the sed-ology see [1].