Emacs vs. Vi vs. Eclipse vs. anyIDE

The full HTML document is available in the Sphinx HTML build directory

Author:Wolfgang Scherer

Abstract

The pro’s and con’s in the religious editor war.

How to install latest stable Emacs in Ubuntu

Prerequisites:

apt-get install apel

For latest emacs stable releases on ubuntu (also recommended by How to Install GNU Emacs 26.1 in Ubuntu):

add-apt-repository ppa:kelleyk/emacs

apt-get update && \
apt-get install emacs26 emacs26-el && \
update-alternatives --set emacs /usr/bin/emacs26

Setup for emacsen-common

Integration with emacsen-common is not so hard. Here are the one-time actions:

touch /var/lib/emacsen-common/state/flavor/installed/emacs26

mkdir -p /etc/emacs26/site-start.d
mkdir -p /usr/share/emacs26/site-lisp
test -L /usr/share/emacs/26.?/site-lisp || \
mv /usr/share/emacs/26.?/site-lisp/* /usr/share/emacs26/site-lisp/

Followed by the upgrade actions, after a new emacs release was installed:

test -L /usr/share/emacs/26.?/site-lisp || \
rm -rf /usr/share/emacs/26.?/site-lisp
rm -f /usr/share/emacs/26.?/site-lisp
ln -s ../../emacs26/site-lisp  /usr/share/emacs/26.?/

If /usr/share/emacs26/site-lisp/subdirs.el has previously been updated, it is not necessary to apply the following modifications.

Since subdirs.el is loaded before site-init is inhibited, it can be used as replacement for startup.el. Create /usr/share/emacs26/site-lisp/subdirs.el:

;; |:here:|
cat <<'EOF' >/usr/share/emacs26/site-lisp/subdirs.el
(defvar package--builtin-versions
  ;; Mostly populated by loaddefs.el via autoload-builtin-package-versions.
  (purecopy `((emacs . ,(version-to-list emacs-version))))
  "Alist giving the version of each versioned builtin package.
I.e. each element of the list is of the form (NAME . VERSION) where
NAME is the package name as a symbol, and VERSION is its version
as a list.")

(defun package--description-file (dir)
  (concat (let ((subdir (file-name-nondirectory
                         (directory-file-name dir))))
            (if (string-match "\\([^.].*?\\)-\\([0-9]+\\(?:[.][0-9]+\\|\\(?:pre\\|beta\\|alpha\\)[0-9]+\\)*\\)" subdir)
                (match-string 1 subdir) subdir))
          "-pkg.el"))

(defconst debian-emacs-flavor 'emacs26
  "A symbol representing the particular debian flavor of emacs running.
Something like 'emacs20, 'xemacs20, etc.")

(if (fboundp 'normal-top-level-add-subdirs-to-load-path)
    (normal-top-level-add-subdirs-to-load-path))

(let ((local-site-lisp "/usr/local/share/emacs/26.3/site-lisp/"))
  (make-directory local-site-lisp t)
  (if (not (member local-site-lisp load-path))
      (setq load-path (cons local-site-lisp load-path))))
EOF
;; |:here:| `

Now add the debian specific startup to /usr/share/emacs26/site-lisp/site-start.el:

;; |:here:|
cat <<'EOF' >/usr/share/emacs26/site-lisp/site-start.el
(if (load "debian-startup" t t nil)
    (debian-startup debian-emacs-flavor))
EOF
;; |:here:| `

Obsolete packages

Remove these packages, since they do not work:

apt-get purge prolog-el
apt-get purge dash-el

Modify/repair packages

If necessary (Ubuntu 16.04/18.04):

grep '(("\\\\\\\\\[Ss]ubref{\\\\(\[^{}\\n\\r\\\\%,\]\*\\\\)" 1 LaTeX-label-list "}")))' /usr/share/emacs/site-lisp/auctex/style/subfigure.el

apply auctex patch manually (obviously this will not work with patch(1), since TABs are lost):

--- /usr/share/emacs/site-lisp/auctex/style/subfigure.el-000 2015-11-19 15:26:11.000000000 +0100
+++ /usr/share/emacs/site-lisp/auctex/style/subfigure.el     2019-09-03 21:03:22.354599330 +0200
@@ -47,8 +47,8 @@
    ;; Install completion for labels:
    (setq TeX-complete-list
         (append
-      '(("\\\\[Ss]ubref{\\([^{}\n\r\\%,]*\\)" 1 LaTeX-label-list "}")))
-      TeX-complete-list)
+      '(("\\\\[Ss]ubref{\\([^{}\n\r\\%,]*\\)" 1 LaTeX-label-list "}"))
+      TeX-complete-list))

    ;; Fontification
    (when (and (featurep 'font-latex)

Before installing the new emacs, repair package apel. If necessary (Ubuntu 16.04):

grep '[^\][\]N' /usr/share/emacs/site-lisp/apel/poe.el

replace \N in doc strings of /usr/share/emacs/site-lisp/apel/poe.el with \\N:

vi /usr/share/emacs/site-lisp/apel/poe.el
:
1,$s,\\N,\\\\N,g

Hint: the substitution command works also fine in sed(1).

Activate packages

Add emacs26 to packages depending on emacs flavor. If emacs25 is also installed from kelleyk/emacs repository, additionally remove emacs25:

/bin/grep --color -nH -e 'emacs2[45]' /usr/lib/emacsen-common/packages/*/* /usr/sbin/update-auctex-elisp

/usr/lib/emacsen-common/packages/install/auctex:116:    (emacs24|emacs26|emacs-snapshot)
/usr/lib/emacsen-common/packages/install/psgml:50:    emacs26 | emacs24)
/usr/lib/emacsen-common/packages/remove/auctex:60:    (emacs24|emacs26|emacs-snapshot)
/usr/lib/emacsen-common/packages/remove/psgml:52:    emacs21 | emacs22 | emacs23 | emacs24 | emacs26 | emacs-snapshot)
/usr/sbin/update-auctex-elisp:56:FLAVORS=${*:-'emacs24 emacs26 emacs-snapshot'}

|:todo:| do it manually a couple of times, then write a script (python(1) or sed(1))

Optional packages

If dvc is installed, put this at the start of /etc/emacs/site-start.d/50dvc.el to activate the ewoc system package.

;; |:here:| `
(condition-case err
    (let ((load-path (reverse load-path)))
      ;; search system libraries first
      (require 'ewoc))
  (error (message "error: %s" (error-message-string err))))
;; |:here:| `

Integrate emacs into emacsen-common

Now update site-lisp with the intstalled debian packages:

/usr/lib/emacsen-common/emacs-install emacs26

Note

if emacs26 was already installed before the emacsen-common integration was conducted, reconfigure emacsen-common packages:

dpkg-reconfigure $( ls -1 /usr/lib/emacsen-common/packages/install/* | sed 's,.*/,,' | sort | uniq )

Point, mark, region, kill ring

In Emacs, the point is the current position of cursor:

Some text POINTat some position
continued on next line. Lorem ipsum dolor.

The key sequence C-SPC sets the position of the mark to the position of point:

Some text MARKPOINTat some position
continued on next line. Lorem ipsum dolor.

When point is moved, the mark stays in place:

Some text MARKat some position
continuedPOINT on next line. Lorem ipsum dolor.

The region is the text between mark and point:

at some position
continued

C-x C-x exchanges point and mark. It also activates the region:

Some text POINTat some position
continuedMARK on next line. Lorem ipsum dolor.

The region can always be moved or copied onto the kill ring, which acts like a clipboard with a history of killed/copied strings. If the region is active (highlighted), pressing BACKSPC removes the region without copying it to the kill ring.

Emacs Notepad Description
C-SPC SHIFT mark beginning of region
C-w C-x move region to kill ring
M-w C-c copy region to kill ring
C-y C-v insert last string from kill ring
M-y
directly after C-y or M-y replaces inserted string with previous string from kill ring
C-u - M-y
directly after C-y or M-y replaces inserted string with next string from kill ring

Emacs allows to handle line ends without explicitely setting the mark:

Emacs Notepad Description
C-k S-end C-x move line without line break to kill ring
C-k C-k S-end right C-x move line to kill ring
C-k C-k C-y S-end right C-c copy line to kill ring

Emulating the special kill-line functionality with the region is more involved:

Emacs Notepad Description
C-SPC C-e right C-w S-end C-x move line without line break to kill ring
C-SPC C-e right C-w S-end right C-x move line to kill ring
C-SPC C-e right M-w S-end right C-c copy line to kill ring
C-SPC C-e right BACKSPC S-end right <ANYTHING> delete line without affecting kill ring

Other commands for killing text entities:

Shortcut Command Description
M-d M-x kill-word kill word
C-M-k M-x kill-sexp kill S-expression
  M-x kill-sentence kill sentence
  M-x kill-paragraph kill paragraph
  M-x kill-comment kill comment

Undo

  • The Emacs undo semantics is lossless.
  • Vi has a lossless (and persistent) undo tree and so does Emacs (Emacs: Undo Tree package)

Standard Undo Function

The standard undo semantics of adding edits, undo some and – with the next edit – loose everything that was undone is just silly.

Step Action Description
Edit 4 chunks added a, b, c, d
Undo 2 chunks removed d, c
Edit 2 chunks added e, f
Undo 2 chunks removed f, e
  Undo 1 chunk removed b

digraph graph0 { subgraph cluster_graph0 { n0 [label="1",shape=circle;fontsize=10,widht=0.4,height=0.4;fixedsize=true]; a0 [label="a"]; b0 [label="b"]; c0 [label="c"]; d0 [label="d"]; edge [style=solid,dir=forward,color=green]; a0 -> b0 -> c0 -> d0; } subgraph cluster_graph1 { n1 [label="2",shape=circle;fontsize=10,widht=0.4,height=0.4;fixedsize=true]; a1 [label="a"]; b1 [label="b"]; c1 [label="c"]; d1 [label="d"]; edge [style=dashed,dir=none,color=green]; a1 -> b1 -> c1 -> d1; edge [style=solid,dir=forward,color=red]; d1 -> c1 -> b1; } subgraph cluster_graph2 { n2 [label="3",shape=circle;fontsize=10,widht=0.4,height=0.4;fixedsize=true]; a2 [label="a"]; b2 [label="b"]; c2 [label="c",style=invis]; d2 [label="d",style=invis]; e2 [label="e"]; f2 [label="f"]; edge [style=dashed,dir=none,color=green]; a2 -> b2; edge [style=invis,dir=none,color=red]; b2 -> c2 -> d2 -> c2 -> b2; edge [style=solid,dir=forward,color=green]; b2 -> e2 -> f2; } subgraph cluster_graph3 { n3 [label="4",shape=circle;fontsize=10,widht=0.4,height=0.4;fixedsize=true]; a3 [label="a"]; b3 [label="b"]; c3 [label="c",style=invis]; d3 [label="d",style=invis]; e3 [label="e"]; f3 [label="f"]; edge [style=dashed,dir=none,color=green]; a3 -> b3; edge [style=invis,dir=none,color=red]; b3 -> c3 -> d3 -> c3 -> b3; edge [style=dashed,dir=none,color=green]; b3 -> e3 -> f3; edge [style=solid,dir=forward,color=red]; f3 -> e3 -> b3 -> a3; } }

Emacs Undo Function

For Emacs an undo that removes a previous edit is just another action that can be undone later.

Step Action Description
Edit 4 chunks added a, b, c, d
Undo 2 chunks removed d, c
Edit 2 chunks added e, f
Undo 2 chunks removed f, e
  Undo 2 chunks added c, d

digraph graph0 { subgraph cluster_graph0 { n0 [label="1",shape=circle;fontsize=10,widht=0.4,height=0.4;fixedsize=true]; a0 [label="a"]; b0 [label="b"]; c0 [label="c"]; d0 [label="d"]; // edge [style=invis]; // n0 -> a0; edge [style=solid,dir=forward,color=green]; a0 -> b0 -> c0 -> d0; } subgraph cluster_graph1 { n1 [label="2",shape=circle;fontsize=10,widht=0.4,height=0.4;fixedsize=true]; a1 [label="a"]; b1 [label="b"]; c1 [label="c"]; d1 [label="d"]; edge [style=dashed,dir=none,color=green]; a1 -> b1 -> c1 -> d1; edge [style=solid,dir=forward,color=red]; d1 -> c1 -> b1; } subgraph cluster_graph2 { n2 [label="3",shape=circle;fontsize=10,widht=0.4,height=0.4;fixedsize=true]; a2 [label="a"]; b2 [label="b"]; c2 [label="c"]; d2 [label="d"]; e2 [label="e"]; f2 [label="f"]; edge [style=dashed,dir=none,color=green]; a2 -> b2 -> c2 -> d2; edge [style=dashed,dir=none,color=red]; d2 -> c2 -> b2; edge [style=solid,dir=forward,color=green]; b2 -> e2 -> f2; } subgraph cluster_graph3 { n3 [label="4",shape=circle;fontsize=10,widht=0.4,height=0.4;fixedsize=true]; a3 [label="a"]; b3 [label="b"]; c3 [label="c"]; d3 [label="d"]; e3 [label="e"]; f3 [label="f"]; edge [style=dashed,dir=none,color=green]; a3 -> b3 -> c3 -> d3; edge [style=dashed,dir=none,color=red]; d3 -> c3 -> b3; edge [style=dashed,dir=none,color=green]; b3 -> e3 -> f3; edge [style=solid,dir=forward,color=red]; f3 -> e3 -> b3; edge [style=solid,dir=forward,color=green]; b3 -> c3 -> d3; } }

Emacs Undo Tree

The Emacs: Undo Tree package realizes the previously described tree structure removing the recursion from branches. It offers a visual interface (C-x u) for easy navigation and fancy display of diffs .

C-/ undo-tree-undo
C-_ undo-tree-undo
C-? undo-tree-redo
C-x u undo-tree-visualize

Abbreviations

vi(1) supports abbreviations and mappings with :abbrev (:iabbrev) and :map.

In order to define an abbreviation local to major mode with replacement of @here@ tag in Emacs, type:

C-SPC (if SPC @here@ SPC run-a-command) C-x a x l xxif RETURN

Both, automatic expansion in abbrev mode:

xxif SPC

and explicit expansion with inactive abbrev mode:

xxif C-x a e

expand to:

(if POINT run-a-command)
Shortcut Command Description
C-x a x m M-x abbrevx-toggle-abbrev-mode private command to toggle abbrev mode globally
C-x a x g M-x abbrevx-add-global-abbrev private command to define global abbreviation from current region, replacing @here@ tag on expansion
C-x a x l M-x abbrevx-add-mode-abbrev private command to define mode specific abbreviation from current region, replacing @here@ tag on expansion
C-x a e M-x expand-abbrev expand abbreviation before point
C-x a g M-x add-global-abbrev define global abbreviation, which works in all major modes
C-x a l M-x add-mode-abbrev define mode specific abbreviation, which only works in current major mode

Dynamic Abbreviation Expansion

vim(1) supports dynamic abbreviations in insert mode with C-P and C-N. vi(1) does not support this extension.

M-/ = Alt+Shift+7

Start typing a word, e.g. dy, then press M-/ repeatedly. All open buffers (not just project files) are searched for a matching expansion:

dynamic
dylan
dyl
dylan-console
dylan-repl
dylanlid
dylan-lid
dy

This is extremely useful for using long identifiers in programs:

VERY_LONG_IDENTIFIERS_WHICH_NOBODY_WANTS_TO_TYPE = "value"

...

VE RY_LONG_IDENTIFIERS_WHICH_NOBODY_WANTS_TO_TYPE

`Eclipse`_ only has a very limited functionality for mainly strongly typed, object oriented languages:

object. <popup>

Key Sequences

Vi supports key sequences as mappings (:map, :imap).

It seems possible to define key sequences in `Eclipse`_: Eclipse - Bindings.

Extensions

Vi has a macro language.

`Eclipse`_ extensions are realized via Java plugins. The extension points can then be assigned to key sequences. In order to create a plugin, an entire `Eclipse`_ Java package must to be created and all kinds of non-evident manual actions have to be executed. `EASE`_ makes it better with Rhino (Javascript) and Jython integration. Python is supposedly fully integrated since 2017 (not verfied, not investigated). See also |section-doc-relevance-IDE|.

The equivalent of a “package” in Emacs is just a simple file (conventionally with the extension .el (but not necessarily)).

Let’s put it in ~/.emacs.d as ~/.emacs.d/my-file.el. The file contains an interactive function, suitable for assignment to a key sequence:

(defun my-func (arg)
 "Help".
 (interactive "sText: ")
 (insert (concat "//" arg "//"))
 )

To “install” this “package”, add the following code to your .emacs file:

(load-file "~/.emacs.d/my-file.el")

To assign the function my-func() to a key sequence, add the following to your .emacs file:

(global-set-key "C-c uet" 'my-func)

You can also put this in my-file.el for auto-installation of the key sequence shortcut :).

That’s it folks!

Tips and Tricks

|:todo:| English

Leerzeilen entfernen: M-% C-q C-j C-q C-j RET C-q C-j RET

Rechteckblock mit String auffüllen:

  1. Anfang des Rechtecks markieren (C-SPACE)
  2. Cursor am Ende des Rechtecks positionieren
  3. C-x r t <STRING> RET

Useful packages

Table editing

Emacs comes with table.el, which allows editing ASCII tables in a WYSIWYG manner.

To recognize tables in a document, enter M-x table-recognize RET. Besides the Table menu there are shortcuts accessible inside table cells with the prefix C-c C-c. C-c C-c C-h inside a table cell show the key bindings.

|:todo:|

CSV

  1. ProjeQtOr (Semikolon, Westeuropäisch ISO-8895-15)

    1. Öffnen in LibreOffice

    2. Speichern als XLSX

    3. Wandlung in RST-Tabelle:

      xlsx-dump.sh --rest @datei@.xlsx
      
  2. tagIDeasy (Komma, UTF-8)

    kann direkt verarbeitet werden

    xlsx-dump.sh --rest @datei@.csv
    
ID Name Typ Kunde Projektcode Farbe Endedatum bestätigt Plan-Endedatum Fortschritt PSP Status Projektstatus erledigt geschlossen Hyperlink
1 PROJECT - LEAVE PERIOD Administrative           0 1 recorded   0 0 http://scherer.wiedenmann.intern/projeqtor/view/main.php?directAccess=true&objectClass=Project&objectId=1
2 Traverse1 Fixed Price Kunde1 123456   2020-01-23 2020-01-24 82 2 done secured 0 0 http://scherer.wiedenmann.intern/projeqtor/view/main.php?directAccess=true&objectClass=Project&objectId=2
3 Traversenhalterung Fixed Price Kunde1     2019-11-16 2020-01-09 100 2.2 done secured 1 0 http://scherer.wiedenmann.intern/projeqtor/view/main.php?directAccess=true&objectClass=Project&objectId=3
4 Meues Projekt Fixed Price         2020-01-16 0 3 recorded   0 0 http://scherer.wiedenmann.intern/projeqtor/view/main.php?directAccess=true&objectClass=Project&objectId=4
5 Projekt_1 Fixed Price           0 4 recorded   0 0 http://scherer.wiedenmann.intern/projeqtor/view/main.php?directAccess=true&objectClass=Project&objectId=5
6 Projekt_2 Fixed Price           0 5 recorded   0 0 http://scherer.wiedenmann.intern/projeqtor/view/main.php?directAccess=true&objectClass=Project&objectId=6
7 Projekt_3 Fixed Price       2020-02-18 2020-01-24 0 6 recorded   0 0 http://scherer.wiedenmann.intern/projeqtor/view/main.php?directAccess=true&objectClass=Project&objectId=7

Manuell

+----
| spalte 1 | xyz
| | uuu
| . | uux
  1. Tabellenbereich markieren
  2. F5 27: 27 => REGION: Run fmt_tables –border rest on region –headlines 1

Ergebnis:

+------------------+-------------------------------------+
| spalte 1         | xyz                                 |
+==================+=====================================+
| cc               | uuu alskfjjkl asdflkjaslkfj aklsdfj |
+------------------+-------------------------------------+
| aldkk dk kkkk kk | uux                                 |
+------------------+-------------------------------------+

Kann auch mit M-x table-recognize im table mode bearbeitet werden. Im table mode gilt innerhalb der Tabelle die Belegung mit Präfix C-c C-c (Belegungshilfe mit C-c C-c C-h). Table mode beenden mit M-x table-unrecognize.

|:todo:| vi: tables ??
|:todo:| eclipse: tables ??

Symbol tags

vi supports colon-delimited tags: :tag: (I just don’t know how)

For emacs a generalized tagging, tag navigation and tag search package is available (symbol-tag).

The standard navigation is performed with M-right (previous tag) and M-left (next tag) (see :xref:`fig:Basic symbol tag navigation`).

Basic symbol tag navigation
              M-up
           (here tag)
 M-left                 M-right
(any tag)              (any tag)
           M-down
           (here tag)

The here tag is a tag which is directly reachable by navigation keys M-up (previous tag) and M-down (next tag). Initially, the here tag symbol is undefined. The key sequence M-h sets the here tag symbol to here. The here tag symbol can be set to any symbol with C-u M-up or C-u M-down.

M-i inserts a symbol tag, M-k deletes the symbol tag near point.

The alternate delimiter set from a delimiter stack can be activated with C-c C-x. The delimiter stack and quick help is shown with C-c C-d C-v.

An independent delimiter is defined for enclosing symbols at point with M-e (M-x symbol-tag-enclose). The enclosing delimiter can be defined with a prefix arg selecting an entry from the delimiter set menu e.g. C-u 1 3 M-e (see F8).

There are key sequences available for marking the block of lines between two symbol tags with the same symbol (see :xref:`tab:Mark line block between two symbol tags`). With a prefix arg, teh tag symbol can be set explicitely.

Mark line block between two symbol tags
Shortcut Command w/first line w/last line
C-c r r M-x symbol-tag-region
C-c r 1 M-x symbol-tag-region-1 yes
C-c r 2 M-x symbol-tag-region-2
yes
C-c r 3 M-x symbol-tag-region-3 yes yes

A grep-find(), which constructs a correctly quoted pattern for symbol tags is available as M-g (M-x symbol-tag-grep-find).

An occur(), which constructs a correctly quoted pattern for symbol tags is available as M-o (M-x symbol-tag-occur).

C-h m shows mode help. In help buffer move to section about symbol-tag minor-mode.

C-h k M-<down> shows help for key bound to next-symbol-tag()

C-h b shows current key bindings. M-x occur RET -symbol-tag RET in buffer *Help* shows keys for symbol movement.

Directory/filename shortcuts

shortcut description
C-c u d d copy directory of buffer to kill-ring
C-c u d f basename of file, e.g. README-emacs-vi-eclipse.txt
C-u C-c u d f with prefix: full path of file, e.g. /home/da/project/documentation/README-emacs-vi-eclipse.txt
shortcut command
C-c u d d M-x dired-xx-copy-directory-as-kill
C-c u d o M-x dired-xx-copy-directory-as-kill-other-window
C-c u d w M-x dired-xx-copy-directory-as-kill-windos
C-c u d f M-x dired-xx-copy-filename-as-kill

URL key bindings

Enter C-c u l C-h to view all bindings for URLs:

Key sequence Elisp function
C-c u l c wsx-make-link-cite
C-c u l d urlx-decode-url
C-c u l e urlx-encode-string
C-c u l h wsx-make-link-html
C-c u l l wsx-make-link-latex
C-c u l m wsx-make-link-markdown-ref
C-c u l M wsx-make-link-markdown
C-c u l p wsx-make-link-perl
C-c u l r wsx-make-link-rst
C-c u l R wsx-make-link-rst-embedded
C-c u l s wsx-make-link-snip
C-c u l w wsx-make-link-wiki