Tips on Emacs


Basics of ~/.emacs

We call ~/.emacs historically, but currently refers to one of the following files:

  1. ~/.emacs
  2. ~/.emacs.el
  3. ~/.emacs.d/init.el

Originally it was only the first one, but the .el was added because it needed a suffix and for offline search, and directory was dug for more storage space about Emacs.

One of them is valid in this order, not all of them. Now ~/.emacs.d/init.el is recommended.

Lines automatically put into ~/.emacs

If you are using Emacs, the content may be added into ~/.emacs.d/init.el. For example:

(put 'narrow-to-region 'disabled nil)
(put 'downcase-region 'disabled nil)
(put 'upcase-region 'disabled nil)
(put 'scroll-left 'disabled nil)

These are the lines added to the end of ~/.emacs because Emacs prompted us to turn on the feature when we was trying to execute a command that had the feature turned off for beginners.

Lines automatically inserted into ~/.emacs

In addition, if you mess with variables as prompted by the Emacs customization feature, the following areas will be added to ~/.emacs.d/init.el.

 ;; custom-set-variables was added by Custom.
 ;; If you edit it by hand, you could mess it up, so be careful.
 ;; Your init file should contain only one such instance.
 ;; If there is more than one, they won't work right.
 '(case-fold-search nil)
 '(js-indent-level 2)
 '(scroll-conservatively 1)
 ;; custom-set-faces was added by Custom.
 ;; If you edit it by hand, you could mess it up, so be careful.
 ;; Your init file should contain only one such instance.
 ;; If there is more than one, they won't work right.

It just says that if you manually edit here, you write it in such a simple format, and that more than ~/.emacs will not work even if there are the others.

Session save mode into ~/.emacs.desktop

I wrote “session save function” in the title, but it is a function called “emacs desktop save mode”, which allows you to resume from a previous session from ~/.emacs.d/.emacs.desktop for example, even if you quit Emacs and start it up again. This is very useful.

From the Emacs customizer, set Environment - Frames - Desktop - Desktop Save Mode to Enable, and a line '(desktop-save-mode t) will be added to the custom-set-variables.

You can then resume editing after logging back into the OS desktop by booting up and answering the prompts.

Emacs some toggles

Useful key bindings for Emacs are summarized in detail (but not all) in the “Notes” section of the top navigation area. Here, I will describe the functions considering to describe there.

  1. M-x toggle-case-fold-search … case-sensitive/not in search
  2. M-x isearch-toggle-case-fold … case-sensitive/not in incremental search
  3. M-x isearch-toggle-lax-whitespace … loose/strict whitespace in incremental search
  4. M-x toggle-truncate-lines … truncate/not long lines
  5. M-x toggle-horizontal-scroll-bar … show/hide horizontal scroll bar

We would like to keep the strict settings for 1 to 3 as default values, but it seems that only 1 is maintained by M-x menu-bar-options-save. 4 to 5 are workarounds when Emacs becomes heavy for editing a file that now has no possible line breaks, and you can also use the required horizontal scrolling. Then you may want ~/.emacs to have the following settings as well.

(global-set-key (kbd "<mouse-6>") 'scroll-right)
(global-set-key (kbd "<mouse-7>") 'scroll-left)
(global-set-key [wheel-left] 'scroll-right)
(global-set-key [wheel-right] 'scroll-left)

In the old days, I also brushed ~/.emacs up and prepared shortcuts to make it easier to use. I think that beginners should devise such ideas for studying. However, when the environment is renewed or temporarily changed to another one, the stress of not being able to perform familiar operations is greater, so I will try to live in Emacs with the default values ​​as much as possible. I did so.

The execution of the keyboard macro C-x e is two strokes, and the continuous execution C-x e e ... that was introduced later is often interrupted, so I assigned it to another key, but over time it violates the default value. I think it was necessary to have the courage to reset it once because it was assigned to F4 when I noticed it.

Therefore, in my Emacs environment, with such patience, only the setting that I say by all means survives. Here's an example of that:

Install web-mode

Let us introduce web-mode into Emacs to make plain HTML editing comfortable. However, web-mode is not yet an Emacs standard and is not registered with the standard GNU ELPA package.

Installation by Emacs package

Adding the archive sites

If you want to install elisp archived on a non-standard site like web-mode with a package manager, you need to add an archive site. Add the following to the beginning of ~/.emacs.d/init.el.

(when (require 'package nil t)
  (add-to-list 'package-archives '("melpa"		. "") t)
  (add-to-list 'package-archives '("melpa-stable"	. "") t)

I think it is better to put both melpa and melpa-stable, not just one. Because sometimes you can somehow infer the maturity of a package from both the repository tagging and the last update.

Emacs package installation

To use the Emacs package, mainly execute the following commands.

M-x package-list-packages
open package management buffer
M-x package-refresh-contents
update package list
M-x package-install
install a package

Even from the package management buffer or M-x package-install with web-mode, let us install the web-mode.el.

Installation by hand

As for my situation, I am using both and, and I want to enable both of the installed elisp, so I will take the old-fashioned method without package management.

The personal location of elisp is defined as ~/.emacs.d/lisp here. Let Emacs know the directory. Write the following at the top of ~/.emacs.d/init.el.

(add-to-list 'load-path "~/.emacs.d/lisp")

Then let us place web-mode.el in ~/.emacs.d/lisp/ by terminal operations. It's a single file elisp, so it's easy.

% [ -d ~/.emacs.d/lisp ] || mkdir -p ~/.emacs.d/lisp
% cd ~/.emacs.d/lisp/ &&
curl -ROL -C -

How to use web-mode

Here are some shortcuts that I often use.

Comment out the beginning of the line (of tag)
C-c C-s
Insert snippet as described below
C-c C-w C-l
Whitespace visualization toggle
C-c C-e /
Close element (default closes automatically)
C-c C-e i
Insert element
C-c C-a i
Insert attribute
C-c C-e r
Replace the element at the cursor position
C-c C-e a
Move to the beginning of the element at the cursor position
C-c C-e e
Move to the end of the element at the cursor position

The great thing about web-mode is that it supports multiple languages. Unlike Emacs standard html-mode, web-mode allows you to press the enter key without hesitation even in style, script tags, Javascript, PHP, etc.

However, although it may not be the Emacs standard, I feel that the indentation style does not fit the current situation after HTML5 and Emacs conventions.

web-mode customization

Indentation adjustment

Therefore, although it is my favorite setting, the indentation style should be set in consideration of the current situation after HTML5 and the practice of Emacs. If you follow HTML5 articles, sections, etc., it is not realistic to indent each tag, so leave it out and the other indents follow indentation level 2 in many other modes.

Add the following to ~/.emacs.d/init.el:

(defun local-web-mode-hook ()
  (setq web-mode-markup-indent-offset 0)
  (setq web-mode-css-indent-offset 2)
  (setq web-mode-code-indent-offset 2)
  (setq web-mode-part-padding 0)
  (setq web-mode-script-padding 0)
  (setq web-mode-style-padding 0)
  (setq web-mode-enable-auto-indentation nil)
  (setq web-mode-enable-block-face t)
  (setq web-mode-enable-element-content-fontification t)
  (setq web-mode-enable-element-tag-fontification t)
  (setq web-mode-enable-html-entities-fontification t)
  (setq web-mode-enable-part-face t)

(when (require 'web-mode nil t)
  (add-hook 'web-mode-hook 'local-web-mode-hook)
  (add-to-list 'auto-mode-alist '("\\.\\(html?\\|css\\|js\\|php\\)\\'" . web-mode))

*-face t and *-fontification t are about the appearance that there are many other, but were enabled to choose them that does not get in the way.

Even in an environment where web-mode is not installed, it will not stop due to an error.

The part where is written php is a “regular expression” for automatically setting the mode with the suffix of the file name, so add it as appropriate like PHP.

web-mode snippets extension

Actually, I was worried that I could not do this. It did not work the setq in local-web-mode-hook above.

Well, it is the insertion of snippets by C-c C-s, although very useful, with respect to the HTML, there are only three, html5, table, ul. No, this alone is quite convenient, but let's push this convenience forward.

Define the following variables with ~/.emacs.d/init.el.

(setq web-mode-extra-snippets
      '((nil . (
		("html"		. "<!doctype html>\n<html lang=\"en\">\n<head>\n<meta charset=\"utf-8\"/>\n<title></title>\n</head>\n<body>\n|\n</body>\n</html>")
		("html-lang"	. "<!doctype html>\n<html lang=\"|\">\n<head>\n<meta charset=\"utf-8\"/>\n<title></title>\n</head>\n<body>\n\n</body>\n</html>")
		("title"	. "<title>|</title>")
		("meta-charset"	. "<meta charset=\"|\"/>")
		("meta-viewport"	. "<meta name=\"viewport\" content=\"width=device-width, initial-scale=1\"/>")
		("meta-IE=edge"	. "<meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\"/>")
		("base-href"	. "<base href=\"|\"/>")
		("base-target"	. "<base target=\"_|\"/>")
		("template"	. "<template>|</template>")
		("slot"		. "<slot>|</slot>")
		("stylesheet"	. "<link rel=\"stylesheet\" href=\"|\"/>")
		("touch-icon"	. "<link rel=\"apple-touch-icon\" href=\"|\"/>")
		("touch-icon-precomposed"	. "<link rel=\"apple-touch-icon-precomposed\" href=\"|\"/>")
		("preload"	. "<link rel=\"preload\" href=\"|\" as=\"\" type=\"\" crossorigin=\"anonymous\"/>")
		("script-src"	. "<script src=\"|\"></script>")
		("style"	. "<style>\n|\n</style>")
		("script"	. "<script>\n|\n</script>")
		("noscript"	. "<noscript>\n|</noscript>")
		("header"	. "<header>\n|</header>")
		("footer"	. "<footer>\n|</footer>")
		("nav"		. "<nav>\n|</nav>")
		("aside"	. "<aside>\n|</aside>")
		("main"		. "<main>\n|</main>")
		("article"	. "<article>\n<section>|\n</section>\n<section>\n</section>\n</article>")
		("section"	. "<section>|\n</section>")
		("section-h2"	. "<section><h2>|</h2>\n<p></p>\n</section>")
		("section-h3"	. "<section><h3>|</h3>\n<p></p>\n</section>")
		("section-h4"	. "<section><h4>|</h4>\n<p></p>\n</section>")
		("h1"		. "<h1>|</h1>")
		("h2"		. "<h2>|</h2>")
		("h3"		. "<h3>|</h3>")
		("h4"		. "<h4>|</h4>")
		("h5"		. "<h5>|</h5>")
		("h6"		. "<h6>|</h6>")
		("h2-id"	. "<h2 id=\"|\"></h2>")
		("h3-id"	. "<h3 id=\"|\"></h3>")
		("h4-id"	. "<h4 id=\"|\"></h4>")
		("h5-id"	. "<h5 id=\"|\"></h5>")
		("h6-id"	. "<h6 id=\"|\"></h6>")
		("p"		. "<p>|</p>")
		("div"		. "<div>|</div>")
		("div-style"	. "<div style=\"|\"></div>")
		("div-align"	. "<div style=\"text-align: |;\"></div>")
		("div-align-left"	. "<div style=\"text-align: left;\">|</div>")
		("div-align-center"	. "<div style=\"text-align: center;\">|</div>")
		("div-align-right"	. "<div style=\"text-align: right;\">|</div>")
		("div-float"	. "<div style=\"float: |;\"></div>")
		("div-float-left"	. "<div style=\"float: left;\">|</div>")
		("div-float-right"	. "<div style=\"float: right;\">|</div>")
		("div-position"	. "<div style=\"position: |;\"></div>")
		("div-position-relative"	. "<div style=\"position: relative;\">|</div>")
		("div-position-absolute"	. "<div style=\"position: absolute;\">|</div>")
		("div-position-fixed"	. "<div style=\"position: fixed;\">|</div>")
		("div-position-sticky"	. "<div style=\"position: sticky;\">|</div>")
		("div-columns"	. "<div style=\"columns: 2;\">\n|</div>")
		("div-columns-p"	. "<div style=\"columns: 2;\">\n<p style=\"margin-top: 0;\">\n|</p>\n</div>")
		("hr"		. "<hr/>")
		("hr-clear-float"	. "<hr style=\"clear: both; border: 0; height: 0;\"/>")
		("details-summary"	. "<details>\n<summary>|</summary>\n</details>")
		("details-summary-right"	. "<details>\n<summary style=\"text-align: right;\">|</summary>\n</details>")
		("blockquote"	. "<blockquote>\n|</blockquote>")
		("pre"		. "<pre>\n|</pre>")
		("ol"		. "<ol>\n<li>|</li>\n<li></li>\n</ol>")
		("ul"		. "<ul>\n<li>|</li>\n<li></li>\n</ul>")
		("li"		. "<li>|</li>")
		("dl"		. "<dl>\n<dt>|</dt><dd\t></dd>\n<dt></dt><dd\t></dd>\n</dl>")
		("dt"		. "<dt>|</dt>")
		("dd"		. "<dd>|</dd>")
		("figure"	. "<figure>\n\n<figcaption>|</figcaption>\n</figure>")
		("figcaption"	. "<figcaption>|</figcaption>")
		("table"	. "<table>\n<caption>|</caption>\n</table>")
		("caption"	. "<caption>|</caption>")
		("thead"	. "<thead>\n<tr><th\t>|</th><th\t></th></tr>\n</thead>")
		("tbody"	. "<tbody>\n<tr><td\t>|</td><td\t></td></tr>\n</tbody>")
		("tfoot"	. "<tfoot>\n<tr><td\t>|</td><td\t></td></tr>\n</tfoot>")
		("colgroup/"	. "<colgroup |/>")
		("colgroup"	. "<colgroup>|</colgroup>")
		("col"		. "<col>|</col>")
		("tr"		. "<tr>|</tr>")
		("th"		. "<th>|</th>")
		("td"		. "<td>|</td>")
		("address"	. "<address>|</address>")
		("a"		. "<a>|</a>")
		("a-href"	. "<a href=\"|\"></a>")
		("a-href#"	. "<a href=\"#|\"></a>")
		("img"		. "<img src=\"|\"/>")
		("svg"		. "<svg xmlns=\"\" width=\"\" height=\"\" viewBox=\"\">\n|\n</svg>")
		("span"		. "<span>|</span>")
		("span-style"	. "<span style=\"|\"></span>")
		("code"		. "<code>|</code>")
		("u"		. "<span style=\"text-decoration: underline;\">|</span>")
		("strike"	. "<span style=\"text-decoration: line-through;\">|</span>")
		("s"		. "<s>|</s>")
		("ins"		. "<ins>|</ins>")
		("del"		. "<del>|</del>")
		("strong"	. "<strong>|</strong>")
		("tt"		. "<span style=\"font-family: monospace;\">|</span>")
		("b"		. "<span style=\"font-weight: bold;\">|</span>")
		("i"		. "<span style=\"font-style: italic;\">|</span>")
		("oblique"	. "<span style=\"font-style: oblique 20deg 45deg;\">|</span>")
		("big"		. "<span style=\"font-size: larger;\">|</span>")
		("small"	. "<small>|</small>")
		("font"		. "<span style=\"font-family: |;\"></span>")
		("left"		. "<div style=\"text-align: left;\">|</div>")
		("center"	. "<div style=\"text-align: center;\">|</div>")
		("right"	. "<div style=\"text-align: right;\">|</div>")
		("justify"	. "<div style=\"text-align: justify;\">|</div>")
		("em"		. "<em>|</em>")
		("site"		. "<site>|</site>")
		("q"		. "<q>|</q>")
		("dfn"		. "<dfn>|</dfn>")
		("dfn-title"	. "<dfn title=\"|\"></dfn>")
		("dfn-abbr"	. "<dfn><abbr>|</abbr></dfn>")
		("dfn-abbr-title"	. "<dfn><abbr title=\"|\"></abbr></dfn>")
		("abbr"		. "<abbr>|</abbr>")
		("abbr-title"	. "<abbr title=\"|\"></abbr>")
		("time"		. "<time>|</time>")
		("time-datetime"	. "<time datetime=\"|\"></time>")
		("var"		. "<var>|</var>")
		("samp"		. "<samp>|</samp>")
		("kbd"		. "<kbd>|</kbd>")
		("samp-kbd"	. "<samp><kbd>|</kbd></samp>")
		("kbd-samp"	. "<kbd><samp>|</samp></kbd>")
		("sub"		. "<sub>|</sub>")
		("sup"		. "<sup>|</sup>")
		("mark"		. "<mark>|</mark>")
		("bdo"		. "<bdo>|</bdo>")
		("bdo-dir"	. "<bdo dir=\"|\"></bdo>")
		("bdo-dir-rtl"	. "<bdo dir=\"rtl\">|</bdo>")
		("bdi"		. "<bdi>|</bdi>")
		("br"		. "<br/>")
		("wbr"		. "<wbr/>")
		("ruby"		. "<ruby>|</ruby>")
		("ruby-rt"	. "<ruby>|<rt></rt></ruby>")
		("ruby-rp"	. "<ruby>|<rp>(</rp><rt></rt><rp>)</rp></ruby>")
		("rt"		. "<rt>|</rt>")
		("rp"		. "<rp>(</rp><rt>|</rt><rp>)</rp>")
		("data"		. "<data>|</data>")
		("data-value"	. "<data value=\"|\"></data>")
		;(""	. "")
		("form-legend"	. "<form>\n<fieldset>\n<legend>|</legend>\n</fieldset>\n</form>")
		("fieldset-legend"	. "<fieldset>\n<legend>|</legend>\n</fieldset>")
		("form-fieldset"	. "<form>\n<fieldset>\n|</fieldset>\n</form>")
		("label"	. "<label>|</label>")
		("button"	. "<button\t>|</button>")
		("input-type"	. "<input type=\"|\"\t/>")
		("input-submit"	. "<input type=\"submit\"\t/>")
		("input-reset"	. "<input type=\"reset\"\t/>")
		("input-hidden"	. "<input type=\"hidden\"\t/>")
		("input-button"	. "<input type=\"button\"\t/>")
		("input-radio"	. "<input type=\"radio\"\t/>")
		("input-checkbox"	. "<input type=\"checkbox\"\t/>")
		("input-text"	. "<input type=\"text\"\t/>")
		("input-search"	. "<input type=\"search\"\t/>")
		("input-tel"	. "<input type=\"tel\"\t/>")
		("input-url"	. "<input type=\"url\"\t/>")
		("input-email"	. "<input type=\"email\"\t/>")
		("input-password"	. "<input type=\"password\"\t/>")
		("input-month"	. "<input type=\"month\"\t/>")
		("input-week"	. "<input type=\"week\"\t/>")
		("input-time"	. "<input type=\"time\"\t/>")
		("input-datetime-local"	. "<input type=\"datetime-local\"\t/>")
		("input-number"	. "<input type=\"number\"\t/>")
		("input-range"	. "<input type=\"range\"\t/>")
		("input-color"	. "<input type=\"color\"\t/>")
		("input-file"	. "<input type=\"file\"\t/>")
		("input-image"	. "<input type=\"image\"\t/>")
		("select"	. "<select>\n<option\t>|</option>\n<option\t></option>\n</select>")
		("select-group"	. "<select>\n<optgroup><option\t>|</option>\n<option\t></option>\n</optgroup></select>")
		("textarea"	. "<textarea>|</textarea>")
		("progress"	. "<progress>|</progress>")
		("meter"	. "<meter>|</meter>")
		("menu"		. "<menu>|</menu>")
		("output"	. "<output>|</output>")
		("dialog"	. "<dialog>|</dialog>")
		;("command"	. "<command>|</command>")
		("iframe"	. "<iframe|></iframe>")
		("embed"	. "<embed|></embed>")
		("embed-src"	. "<embed|></embed>")
		("object"	. "<object|></object>")
		("param"	. "<param|/>")
		("canvas"	. "<canvas|></canvas>")
		("video"	. "<video|></video>")
		("video-src"	. "<video|></video>")
		("audio"	. "<audio|></audio>")
		("audio-src"	. "<audio|></audio>")
		("picture"	. "<picture>|</picture>")
		("source"	. "<source|/>")
		("track"	. "<track|/>")
		("map"		. "<map>|</map>")
		("area"		. "<area|></area>")
		("@import-url"	. "@import url(\"|\");")
		("@media-screen"	. "@media screen {\n|\n}")
		("@media-print"	. "@media print {\n|\n}")
		("@media-speech"	. "@media speech {\n|\n}")
		; Javascript
		("js-addEvLoad"	. "window.addEventListener('DOMContentLoaded', function() {\n|});")

Adding snippets is complemented by tab key, so it is efficient to select them even if you remember them. Above, I have prepared a group of snippets that consider HTML5, HTML Living standard and obsolete tags.

ps-print.el Customization

The following information is very old and not in use now.

“ps-print.el” in Emacs/Mule 20.7 can handle BDF fonts and builtin PostScript fonts for multilingual printing. For CJK (Chinese, Japanese and Korean) users, I introduce an example of ~/.emacs to print multi-byte buffer with ps-print.el.

“C-u M-x ps-print-buffer” generates a PostScript file of buffer.

Questions or comments regarding this service?

Copyright (C) 1999-2001, 2021 Taiji Yamada, All rights reserved.