Notice that init.el
translates this org-mode file into an emacs lisp file
when emacs is started, and then loads the emacs lisp file.
Some initial settings to configure basic behaviour.
For emacs 28.2, there’s a bug in the default image-types
. Fix can be removed at emacs 29:
(add-to-list 'image-types 'svg)
Put point on variable and do C-h v
to find appropriate docs quickly.
These settings are the ones that are not specific to individual buffers or modes. Remove some cruft from the screen, and add useful info instead:
(tool-bar-mode 0)
(column-number-mode t)
(setq blink-matching-paren-on-screen t)
(show-paren-mode 1)
(setq lazy-highlight-max-at-a-time nil) ;; Highlight all search matches
(setq show-trailing-whitespace t)
(setq visible-bell t) ;; flash rather than beep
(set-face-attribute 'default nil :font "Monaco" :height 160) ;; Use monaco fixed width font at a sensible size
And some behaviour changes:
(fset 'yes-or-no-p 'y-or-n-p) ;; change all prompts to y or n
(setq confirm-kill-emacs (quote yes-or-no-p))
(setq kill-whole-line t)
(setq kill-read-only-ok t) ;; ctrl-k yanks read only text (DWIM rather than error)
(setq case-fold-search t)
Tweak a few settings for default behaviour:
(setq-default fill-column 78)
(setq default-major-mode 'text-mode)
;; These three disable attempts to make emacs more windows-like:
(setq cua-enable-cua-keys nil)
(setq shift-select-mode nil)
(setq delete-selection-mode nil)
(setq backup-directory-alist '(("." . "~/.emacs.backups"))) ;; backup files to stand alone directory
(setq revert-without-query '(".*\\.err" ".*\\.out"))
(setq switch-to-buffer-in-dedicated-window 'prompt) ;; better compilation window handling - useful for qmk
(setq-default frame-title-format "%b (%f)") ;; Show file path in frame title
Restores buffers across emacs sessions:
(desktop-save-mode 1)
(setq desktop-path '("~/.emacs.d/desktop" "~/.emacs.d/" "~"))
Keep a list of recent files:
(require 'recentf)
(recentf-mode t)
(setq recentf-max-saved-items 50)
Persistent minibuffer history
(savehist-mode t)
(setq backward-delete-char-untabify-method t)
(setq indent-tabs-mode nil) ;; Indent inserts spaces always; never tabs.
(setq require-final-newline t)
(setq colon-double-space t)
(setq tab-always-indent 'complete) ;; attempt to indent, if that doesn't work trigger completion.
(setq tab-stop-list '(16 32)) ;; make tabs stupidly wide to better identify accidental tabs
(setq comment-empty-lines t)
(setq comment-padding 1) ;; Put 1 space between comment markers and code/text.
(setq comment-style (quote multi-line))
Working on parts of text:
C-x n n
is narrow-to-regionC-x n p
is narrow-to-pageC-x n w
is widen
(put 'narrow-to-region 'disabled nil)
(put 'narrow-to-page 'disabled nil)
(put 'upcase-region 'disabled nil)
(put 'downcase-region 'disabled nil)
(put 'scroll-left 'disabled nil)
Initialises the package interface and enable MELPA packages.
(require 'package)
(add-to-list 'package-archives
'("melpa" . "https://melpa.org/packages/"))
(package-initialize)
(when (not package-archive-contents)
(package-refresh-contents))
And setup for use-package for simpler installation and configuration:
(unless (package-installed-p 'use-package)
(package-install 'use-package))
(require 'use-package)
(setq use-package-always-ensure t)
There’s a couple of essential packages that need to be installed, and don’t need any configuration:
- magit - a usable git interface.
- markdown-mode - does what it says on the tin.
(use-package magit)
(use-package markdown-mode)
Ivy is a better completion mechanism for interacting with emacs (e.g. anything using the minibuffer, search, find file etc):
(use-package swiper :ensure t)
(use-package ivy
:diminish ;; diminish keeps mode out of modeline
:bind (("C-s" . swiper) ;; bind edits keymap
:map ivy-minibuffer-map
("TAB" . ivy-alt-done)
("C-l" . ivy-alt-done)
:map ivy-switch-buffer-map
("C-l" . ivy-done)
("C-d" . ivy-switch-buffer-kill)
:map ivy-reverse-i-search-map
("C-d" . ivy-reverse-i-search-kill))
:config
(ivy-mode t))
Configure completion within a buffer via company for all modes, and trigger immediately when typing:
(use-package company
:diminish
:init (global-company-mode)
:config
(setq company-minimum-prefix-length 1
company-idle-delay 0.0) ;; default is 0.2
)
Set up minibuffer pop up to complete partially entered key combinations via which-key.
(use-package which-key
:init
(which-key-setup-minibuffer)
(which-key-mode))
Add multiple-cursors - handy for batch editing.
(use-package multiple-cursors
:bind (
("C-S-<mouse-1>" . mc/add-cursor-on-click)))
Not just the stock python
package, but some additional helper packages too.
To use with emacs with a venv, use pyvenv-activate <venv-path>
. Any
existing python buffers need to be refreshed (e.g. with revert-buffer
) to
benefit. The venv should include python-lsp-server
for code completion etc
and debugpy
for debugger integration.
Some initial config for the interpreter and code folding:
(use-package python
:ensure nil
:config
(outline-minor-mode t)
:custom
(python-shell-interpreter "python3") ;; TODO: ipython/jupyter console
(python-shell-completion-native-enable nil)
:bind (:map python-mode-map
("M-o" . outline-mode-prefix-map)))
Flycheck is faster and generally better than the built in flymake:
(use-package flycheck
:ensure t
:init (global-flycheck-mode))
Python venv support via pyvenv:
This should make lsp, project and dap modes use the right python when working with virtual environments (but not conda envs):
(use-package pyvenv
:config
(pyvenv-mode 1))
See the docs for details. This will need configuring depending on where conda and the environments are installed:
(use-package conda
:init
(setq conda-anaconda-home "/opt/homebrew/Caskroom/miniforge/base/")
(setq conda-env-home-directory "/opt/homebrew/Caskroom/miniforge/base/")
:commands
(conda-env-initialize-interactive-shells
;; if you want eshell support, include:
conda-env-initialize-eshell
;; if you want auto-activation (see below for details), include:
;; conda-env-autoactivate-mode t
;; if you want to automatically activate a conda environment on the opening of a file:
;; (add-to-hook 'find-file-hook (lambda () (when (bound-and-true-p conda-project-env-path)
;; (conda-env-activate-for-buffer))))
)
)
Turning on autoactivate
means needing to identify the conda environment to load. From the docs:
- check for a per-directory local variable setting the conda-project-env-path variable with either the name or the full path to an existing conda environment
- search up the directory tree for a file defining a conda environment, such as an environment.yml file, and try to activate the named environment
Needs pytest to be in the activated environment.
Use projectile-test-project
, and use recompile
for repeating the test.
There’s no other configuration needed here, it works out of the box.
Trying out lsp-mode. Note that lsp relies on a suitable python virtualenv or conda env, so some configuration for other languages is here too:
(use-package lsp-mode
:init
;; set prefix for lsp-command-keymap (few alternatives - "C-l", "C-c l")
(setq lsp-keymap-prefix "C-l")
:hook (;; replace XXX-mode with concrete major-mode(e. g. python-mode)
(python-mode . lsp) ;; needs ~pip install "python-lsp-server[all]"~
(f90-mode . lsp) ;; needs ~pip install fortls~ in a python venv
(rustic-mode . lsp) ;; needs rust-analyser installed in PATH
(cc-mode . lsp)
;; if you want which-key integration
(lsp-mode . lsp-enable-which-key-integration))
:config
(lsp-register-custom-settings
'(("pyls.plugins.pyls_mypy.enabled" t t)
("pyls.plugins.pyls_mypy.live_mode" nil t)
("pyls.plugins.pyls_black.enabled" t t)
("pyls.plugins.pyls_isort.enabled" nil t)
("pyls.plugins.flake8.enabled" nil t)
("pyls.plugins.ruff.enabled" t t)
))
:commands lsp)
;; TODO: good keyboard shortcut for ~lsp-rename~
;; optionally
(use-package lsp-ui
:commands lsp-ui-mode
:config (setq lsp-ui-doc-enable t)
)
;; if you are helm user
;; (use-package helm-lsp :commands helm-lsp-workspace-symbol)
;; if you are ivy user
(use-package lsp-ivy :commands lsp-ivy-workspace-symbol)
(use-package lsp-treemacs :commands lsp-treemacs-errors-list)
;; optionally if you want to use debugger
(use-package dap-mode)
;; debugger for python:
(require 'dap-python)
(setq dap-python-debugger 'debugpy) ;; Needs ~pip install debugpy~ in the venv being used.
;; performance tuning
(setq gc-cons-threshold 100000000)
(setq read-process-output-max (* 1024 1024)) ;; 1mb
This does need to have an LSP server installed in a virtual env - tested with pylsp: https://github.com/python-lsp/python-lsp-server
Use dap-toggle-breakpoint
to add a breakpoint. Use dap-debug
to run. dap-debug-edit-template
to specify more complex options.
Use yas-new-snippet
to define a template to be expanded.
(use-package yasnippet
:ensure t
:init
(yas-global-mode t)
:config
(setq yas-snippet-dirs
'("~/.emacs.d/snippets")))
Global key bindings (some duplicates to account for OS X/MacOS intercepting some and preventing them being seen by emacs):
;; Commenting these out so see if emacs defaults are more sensible now
;; (global-set-key [M-left] 'backward-sentence)
;; (global-set-key [M-right] 'forward-sentence)
;; (global-set-key [M-up] 'beginning-of-defun)
;; (global-set-key [M-down] 'end-of-defun)
;;
;; (global-set-key [C-left] 'backward-word)
;; (global-set-key [C-right] 'forward-word)
;; (global-set-key [C-up] 'beginning-of-line)
;; (global-set-key [C-down] 'end-of-line)
f1
, f4
, f5
, f8
, f9
and f12
are
usually the easiest f keys to use (least likely to fat finger), so use those
for the most common functions.
;; (global-set-key [S-insert] 'insert-file)
;;
(global-set-key [f1] 'find-file-at-point)
;; (global-set-key [f9] 'find-file-at-point)
;; (global-set-key [pause] 'toggle-read-only)
;; (global-set-key [f10] 'toggle-read-only)
;;
;; (global-set-key [f5] 'bookmark-set-no-overwrite)
;; (global-set-key [f8] 'bookmark-jump)
;;
;; (global-set-key [f6] 'execute-extended-command)
;; (global-set-key [f7] 'buffer-menu)
;;
(global-set-key [C-tab] 'other-window) ;; Collision with org-mode and magit -
;; need to sort out how to handle this
;; (it's muscle memory now, probably
;; need to set alternative for
;; org-mode and tolerate it for
;; magit).
(global-set-key [C-iso-lefttab] 'other-window) ;; Attempted fix
;; ;; (ctrl-shift-tab) for above
;; (global-set-key [M-delete] 'kill-word)
;;
;; (global-set-key [insert] 'abbrev-mode)
(global-set-key [f12] 'recompile)
;;
;; (global-set-key [print] 'ps-print-buffer-with-faces)
;;
;; (global-set-key "\M-?" 'hippie-expand)
;; ;; get rid of `find-file-read-only' and replace it with something
;; ;; more useful.
;; (global-set-key (kbd "C-x C-r") 'ido-recentf-open)
;; ;; disable C-x C-c as quit. Instead, save all buffers with attached files:
(global-set-key (kbd "C-x C-c") 'save-some-buffers)
;;
;; (global-set-key "\C-cl" 'org-store-link)
;; (global-set-key "\C-cc" 'org-capture)
;; (global-set-key "\C-ca" 'org-agenda)
;; (global-set-key "\C-cb" 'org-iswitchb)
Emacs built-in project provides support for projects within emacs. But the
default keybinding isn’t great - let’s use C-z
as a prefix instead (bonus:
this disables a common typo that suspends emacs):
(use-package project
:bind-keymap ("C-z" . project-prefix-map))
Built-in eshell is optimised for interactive work, but is not bash compatible. In particular, it does not support environment modules or scripting. So it’s the best bet for things that it does do, but we’ll also configure other shells for work that needs bash compatibility.
Really want a bigger shell history to avoid having to retype commands:
(setq eshell-buffer-maximum-lines 10240)
(setq eshell-cmpl-compare-entry-function (quote string-lessp))
(setq eshell-cmpl-cycle-completions nil)
(setq eshell-history-size 100000)
While eshell
is ideal for interactive use, occasionally a more conventional
shell is needed. From stack exchange, there’s three steps to improve shell
buffers in emacs.
Additional package installs for exec-path-from-shell which sanitises
environment variables in emacs (particularly useful under MacOS), and dash
which simplifies lists in lisp (needed for exec-path-from-shell
)
(use-package dash :ensure t)
(use-package exec-path-from-shell
:ensure t
:init
(exec-path-from-shell-initialize)
(exec-path-from-shell-copy-env "HISTFILE"))
Persistent shell history. Other modes can be added as appropriate. May be worth doing for python?
(defun turn-on-comint-history (history-file)
(setq comint-input-ring-file-name history-file)
(comint-read-input-ring 'silent))
(add-hook 'shell-mode-hook
(lambda ()
(turn-on-comint-history (getenv "HISTFILE"))))
(add-hook 'kill-buffer-hook #'comint-write-input-ring)
(add-hook 'kill-emacs-hook
(lambda ()
(--each (buffer-list)
(with-current-buffer it (comint-write-input-ring)))))
Pycharm has some pretty ligature support. Let’s see if we can do similar in
the one true editor. The built-in prettify-symbols
mode looks to be a good
place to start. By default, this replaces lambda
, and
, and or
with
symbols (check the buffer local variable prettify-symbols-alist
for the
current value in a buffer). Let’s add a few more symbols. From this aliquote
blog post, there’s a few suitable suggestions:
(defun add-python-mode-symbols ()
(mapc (lambda (pair) (push pair prettify-symbols-alist))
'(
("->" . 8594)
("=>" . 8658)
("<=" . 8804)
(">=" . 8805)
("<-" . 8592)
("!=" . 8800)
)))
(add-hook 'python-mode-hook (lambda ()
(add-python-mode-symbols)
(prettify-symbols-mode t)
))
This modern emacs blog post describes using describe-char
and insert-char
to work out the number needed for a particular symbol, and the use of mapc
for adding the symbols in a sensible manner. I’ve opted to isolate the
definitions in a function to make it a little more transparent what is being
added to the python hook. I think (but haven’t confirmed) that the symbols
list needs to be defined before enabling prettify-symbols-mode
.
(use-package rustic
:custom
(rustic-analyzer-command '("rustup" "run" "stable" "rust-analyzer")))
Setup a few extra TODO states:
;; org-mode config
(setq org-todo-keywords
'((sequence "TODO" "VERIFY" "DELAYED" "|" "DONE" "CANCELLED")))
Enable python code blocks in org-babel:
(org-babel-do-load-languages
'org-babel-load-languages
'((emacs-lisp . t)
(shell . t)
(python . t)))
QoL improvements:
(setq org-return-follows-link t)
(setq org-src-fontify-natively t)
Enable tab to expand snippets like <s
(as of org 9.2, preferred method is
C-c C-,
, but muscle memory…):
(require 'org-tempo)
Compile commands have been producing output in colour for some time now. But the emacs compilation buffer tends to display escape characters rather than output in colour. This fixes that (source):
(require 'ansi-color)
(defun my/ansi-colorize-buffer ()
(let ((buffer-read-only nil))
(ansi-color-apply-on-region (point-min) (point-max))))
(add-hook 'compilation-filter-hook 'my/ansi-colorize-buffer)
(setq compilation-scroll-output t)
If there’s a local configuration file, load it. Use this for e.g. printer settings.
(if (file-readable-p "~/.emacs.d/config/local.el")
(load "~/.emacs.d/config/local.el" nil t))
Two more packages: doom-modeline for a more informative modeline, and all-the-icons for icons used in the modeline. Customised via the instructions.
(use-package all-the-icons :ensure t)
(use-package doom-modeline :ensure t)
;; Initial requirements
(require 'doom-modeline)
(doom-modeline-mode 1)
;; How tall the mode-line should be. It's only respected in GUI.
;; If the actual char height is larger, it respects the actual height.
(setq doom-modeline-height 25)
;; How wide the mode-line bar should be. It's only respected in GUI.
(setq doom-modeline-bar-width 4)
;; Whether to use hud instead of default bar. It's only respected in GUI.
(setq doom-modeline-hud t)
;; The limit of the window width.
;; If `window-width' is smaller than the limit, some information won't be displayed.
(setq doom-modeline-window-width-limit fill-column)
;; How to detect the project root.
;; The default priority of detection is `ffip' > `projectile' > `project'.
;; nil means to use `default-directory'.
;; The project management packages have some issues on detecting project root.
;; e.g. `projectile' doesn't handle symlink folders well, while `project' is unable
;; to hanle sub-projects.
;; You can specify one if you encounter the issue.
(setq doom-modeline-project-detection 'project)
;; Determines the style used by `doom-modeline-buffer-file-name'.
;;
;; Given ~/Projects/FOSS/emacs/lisp/comint.el
;; auto => emacs/lisp/comint.el (in a project) or comint.el
;; truncate-upto-project => ~/P/F/emacs/lisp/comint.el
;; truncate-from-project => ~/Projects/FOSS/emacs/l/comint.el
;; truncate-with-project => emacs/l/comint.el
;; truncate-except-project => ~/P/F/emacs/l/comint.el
;; truncate-upto-root => ~/P/F/e/lisp/comint.el
;; truncate-all => ~/P/F/e/l/comint.el
;; truncate-nil => ~/Projects/FOSS/emacs/lisp/comint.el
;; relative-from-project => emacs/lisp/comint.el
;; relative-to-project => lisp/comint.el
;; file-name => comint.el
;; buffer-name => comint.el<2> (uniquify buffer name)
;;
;; If you are experiencing the laggy issue, especially while editing remote files
;; with tramp, please try `file-name' style.
;; Please refer to https://github.com/bbatsov/projectile/issues/657.
(setq doom-modeline-buffer-file-name-style 'relative-from-project)
;; Whether display icons in the mode-line.
;; While using the server mode in GUI, should set the value explicitly.
(setq doom-modeline-icon (display-graphic-p))
;; Whether display the icon for `major-mode'. It respects `doom-modeline-icon'.
(setq doom-modeline-major-mode-icon t)
;; Whether display the colorful icon for `major-mode'.
;; It respects `all-the-icons-color-icons'.
(setq doom-modeline-major-mode-color-icon t)
;; Whether display the icon for the buffer state. It respects `doom-modeline-icon'.
(setq doom-modeline-buffer-state-icon t)
;; Whether display the modification icon for the buffer.
;; It respects `doom-modeline-icon' and `doom-modeline-buffer-state-icon'.
(setq doom-modeline-buffer-modification-icon t)
;; Whether to use unicode as a fallback (instead of ASCII) when not using icons.
(setq doom-modeline-unicode-fallback t)
;; Whether display the minor modes in the mode-line.
(setq doom-modeline-minor-modes nil)
;; If non-nil, a word count will be added to the selection-info modeline segment.
(setq doom-modeline-enable-word-count t)
;; Major modes in which to display word count continuously.
;; Also applies to any derived modes. Respects `doom-modeline-enable-word-count'.
;; If it brings the sluggish issue, disable `doom-modeline-enable-word-count' or
;; remove the modes from `doom-modeline-continuous-word-count-modes'.
(setq doom-modeline-continuous-word-count-modes '(markdown-mode gfm-mode org-mode text-mode))
;; Whether display the buffer encoding.
(setq doom-modeline-buffer-encoding nil)
;; Whether display the indentation information.
(setq doom-modeline-indent-info nil)
;; If non-nil, only display one number for checker information if applicable.
(setq doom-modeline-checker-simple-format nil)
;; The maximum number displayed for notifications.
(setq doom-modeline-number-limit 99)
;; The maximum displayed length of the branch name of version control.
(setq doom-modeline-vcs-max-length 12)
;; Whether display the workspace name. Non-nil to display in the mode-line.
(setq doom-modeline-workspace-name t)
;; Whether display the perspective name. Non-nil to display in the mode-line.
(setq doom-modeline-persp-name t)
;; If non nil the default perspective name is displayed in the mode-line.
(setq doom-modeline-display-default-persp-name nil)
;; If non nil the perspective name is displayed alongside a folder icon.
(setq doom-modeline-persp-icon t)
;; Whether display the `lsp' state. Non-nil to display in the mode-line.
(setq doom-modeline-lsp t)
;; Whether display the GitHub notifications. It requires `ghub' package.
(setq doom-modeline-github nil)
;; The interval of checking GitHub.
(setq doom-modeline-github-interval (* 30 60))
;; Whether display the modal state icon.
;; Including `evil', `overwrite', `god', `ryo' and `xah-fly-keys', etc.
(setq doom-modeline-modal-icon nil)
;; Whether display the mu4e notifications. It requires `mu4e-alert' package.
(setq doom-modeline-mu4e nil)
;; Whether display the gnus notifications.
(setq doom-modeline-gnus nil)
;; Wheter gnus should automatically be updated and how often (set to 0 or smaller than 0 to disable)
(setq doom-modeline-gnus-timer 0)
;; Wheter groups should be excludede when gnus automatically being updated.
(setq doom-modeline-gnus-excluded-groups '("dummy.group"))
;; Whether display the IRC notifications. It requires `circe' or `erc' package.
(setq doom-modeline-irc nil)
;; Function to stylize the irc buffer names.
(setq doom-modeline-irc-stylize 'identity)
;; Whether display the environment version.
(setq doom-modeline-env-version t)
;; Or for individual languages
;; (setq doom-modeline-env-enable-python t)
;; (setq doom-modeline-env-enable-ruby t)
;; (setq doom-modeline-env-enable-perl t)
;; (setq doom-modeline-env-enable-go t)
;; (setq doom-modeline-env-enable-elixir t)
;; (setq doom-modeline-env-enable-rust t)
;; Change the executables to use for the language version string
(setq doom-modeline-env-python-executable python-shell-interpreter) ; or `python-shell-interpreter'
(setq doom-modeline-env-ruby-executable "ruby")
(setq doom-modeline-env-perl-executable "perl")
(setq doom-modeline-env-go-executable "go")
(setq doom-modeline-env-elixir-executable "iex")
(setq doom-modeline-env-rust-executable "rustc")
;; What to display as the version while a new one is being loaded
(setq doom-modeline-env-load-string "...")
;; Hooks that run before/after the modeline version string is updated
(setq doom-modeline-before-update-env-hook nil)
(setq doom-modeline-after-update-env-hook nil)
Note: this needs M-x all-the-icons-install-fonts
to be run once within emacs.
(require 'all-the-icons)
And a better theme than any of the built in default themes:
(use-package doom-themes
:ensure t
:config
;; Global settings (defaults)
(setq doom-themes-enable-bold t ; if nil, bold is universally disabled
doom-themes-enable-italic t) ; if nil, italics is universally disabled
(load-theme 'doom-one t)
;; Enable flashing mode-line on errors
(doom-themes-visual-bell-config)
;; Enable custom neotree theme (all-the-icons must be installed!)
;; (doom-themes-neotree-config)
;; or for treemacs users
(setq doom-themes-treemacs-theme "doom-colors") ; use "doom-colors" for less minimal icon theme
(doom-themes-treemacs-config)
;; Corrects (and improves) org-mode's native fontification.
(doom-themes-org-config))
Move minibuffer to top center of the frame.
(use-package ivy-posframe
:diminish
:custom
(ivy-posframe-display-functions-alist '((t . ivy-posframe-display)))
;; (setq ivy-posframe-display-functions-alist '((t . ivy-posframe-display-at-frame-center)))
;; (setq ivy-posframe-display-functions-alist '((t . ivy-posframe-display-at-window-center)))
;; (setq ivy-posframe-display-functions-alist '((t . ivy-posframe-display-at-frame-bottom-left)))
;; (setq ivy-posframe-display-functions-alist '((t . ivy-posframe-display-at-window-bottom-left)))
(ivy-posframe-display-functions-alist '((t . ivy-posframe-display-at-frame-top-center)))
:config
(ivy-posframe-mode t))
Generate a temporary buffer. Very useful when combined with eshells
capability to redirect output to a buffer (e.g. ncdump -h >C-c M-b
).
(defun generate-temp-buffer ()
(interactive)
(switch-to-buffer (make-temp-name "temp-")))
Configuration for mastodon within emacs. I’ve opted to install the optional
emojify, lingva, and discover dependencies, of which discover
needs to be
explicitly enabled:
(use-package emojify)
(use-package lingva)
(use-package discover)
(use-package mastodon
:ensure t
:config
(mastodon-discover))
Also need to configure variables for server mastodon-instance-url
and
username mastodon-active-user
e.g. in "~/.emacs.d/config/local.el"
configuration file.