mos emacs howtos
Table of Contents
- 1. mo-emacs-config
- 2. HOWTOs
1. mo-emacs-config
Ok, so this is my emacs config wiki
1.1. keyboard layout
Ok, you need a usable keyboard layout. This means, the caps lock key has to instead send a ctrl.
Also I want the german and us layout switchable with win+space.
1.1.1. debian
/etc/default/keyboard
XKBMODEL="pc105" XKBLAYOUT="de,us" XKBVARIANT="" XKBOPTIONS="ctrl:nocaps,grp:win_space_toggle,grp_led:scroll" BACKSPACE="guess"
grp_led:scroll
makes a layout indicator out of the the scroll lock led.
1.1.2. other distros
see setxkbmap
setxkbmap -layout us,de -option win_space_toggle,grp_led:scroll -v
1.2. Keybindings/Prefix keys
I use a us keyboard layout, so C-=
is nicely reachable and a
suitable prefix key.
On a terminal using putty, sadly, C-=
doesn't work, so I use <f12>
instead. <f5>
is free, too. <f9>
I use for "compiling" or similar
stuff. (that was the binding in turbo-c and still seems to be used by
some IDEs).
1.2.1. Some of the bindings
(global-set-key (kbd "C-= d") 'find-name-dired) (global-set-key (kbd "C-= l") 'find-lisp-find-dired) (global-set-key (kbd "C-= g") 'find-grep-dired) ;; or find-grep. ;; to complete filenames everywhere (global-set-key (kbd "C-= TAB") 'term-dynamic-complete-filename)
1.3. recent-files
;; recent files (recentf-mode) (global-set-key (kbd "C-= f") 'recentf-open-files)
1.4. emacs server
start a server if there isn't already one running:
(require 'server) (unless (and (fboundp #'server-running-p) (server-running-p)) (server-start))
1.4.1. Troubleshooting
- emacsclient - socket
You normally should not need this but if
emacsclient
doesn't find the emacs server read this:the server creates a unix domain socket. you can find out where by
C-h v server-socket-dir
sadly
emacsclient
doesn't use a config file to look up theserver-socket-dir
, you can only specify it on the command line:emacsclient --socket-name=/<somedir>/server <file>
You can alias emacsclient with this socket name if it doesn't seem to change.
1.5. my multiple cursors shortcuts
I think MCs are cool but I don't use them much. I neither pretend these are the best bindings nor do I claim completeness.
If you're in a terminal check what key is sent by the key
combination. I think it was C-^
instead of C-"
. Adjust
accordingly.
;; multiple cursors (global-set-key (kbd "C-\" a") 'mc/mark-all-like-this-dwim) (global-set-key (kbd "C-\" l") 'mc/mark-next-lines) (global-set-key (kbd "C-\" m") 'mc/mark-next-like-this) (global-set-key (kbd "C-\" s") 'mc/mark-next-like-this-symbol) (global-set-key (kbd "C-\" w") 'mc/mark-next-like-this-word) (global-set-key (kbd "C-\" r") 'mc/mark-all-in-region) (global-set-key (kbd "C-\" R") 'mc/mark-all-in-region-regexp)
1.6. flymake
1.6.1. json (new version)
1.6.2. toml
(load "~/.emacs.d/tomlcheck.el") (add-hook 'conf-toml-mode-hook 'flymake-tomlcheck-setup) (add-hook 'conf-toml-mode-hook 'flymake-mode) (add-hook 'conf-toml-mode-hook 'trailing-whitespace-mode) ;; if you want to add this automatically to .conf.j2 files (add-to-list 'auto-mode-alist '("\\.conf\\.j2\\'" . conf-toml-mode))
tomlcheck.el
;;; flymake-tomlcheck.el --- TOML linter with tomlcheck -*- lexical-binding: t; -*- ;; replace /PATH/TO/TOMLCHECK.PY with actual path to tomlcheck.py ;; the contents should be: ;;;;;;;;;;;; tomlcheck.py ;; #!/usr/bin/env python3 ;; # usage: python3 tomlcheck.py < something.toml ;; # pip3 install --user toml ;; # emacs regex: "^\\(?3:[^(]*\\)(line \\(?1:[0-9]+\\) column \\(?2:[0-9]+\\) char [0-9]+)$" ;; # (match-string 1) = line, (match-string 2) = col, (match-string 3) = msg ;; import sys ;; import toml ;; try: ;; toml.load(sys.stdin) ;; except Exception as e: ;; print(e) ;;;;;;;;;;;;;;;;;; (require 'flymake) (defgroup flymake-tomlcheck nil "Tomlcheck backend for Flymake." :prefix "flymake-tomlcheck-" :group 'tools) (defcustom flymake-tomlcheck-arguments nil "A list of strings to pass to the tomlcheck program as arguments." :type '(repeat (string :tag "Argument"))) (defvar-local flymake-tomlcheck--proc nil) (defun flymake-tomlcheck (report-fn &rest _args) "Flymake backend for tomlcheck report using REPORT-FN." (when (process-live-p flymake-tomlcheck--proc) (kill-process flymake-tomlcheck--proc) (setq flymake-tomlcheck--proc nil)) (let ((source (current-buffer))) (save-restriction (widen) (setq flymake-tomlcheck--proc (make-process :name "flymake-tomlcheck" :noquery t :connection-type 'pipe :buffer (generate-new-buffer " *flymake-tomlcheck*") :command `("/usr/bin/python" "/PATH/TO/TOMLCHECK.PY") :sentinel (lambda (proc _event) (when (eq 'exit (process-status proc)) (unwind-protect (if (with-current-buffer source (eq proc flymake-tomlcheck--proc)) (with-current-buffer (process-buffer proc) (goto-char (point-min)) (let ((diags)) (while (search-forward-regexp "^\\(?3:[^(]*\\)(line \\(?1:[0-9]+\\) column \\(?2:[0-9]+\\) char [0-9]+)$" nil t) (let ((region (flymake-diag-region source (string-to-number (match-string 1)) (string-to-number (match-string 2)))) (error-type (match-string 3))) ;; expect `region' to only have 2 values (start . end) (when (and (car region) (cdr region)) (push (flymake-make-diagnostic source (car region) (cdr region) :error (match-string 3)) diags)))) (funcall report-fn (reverse diags)))) (flymake-log :warning "Canceling obsolete check %s" proc)) (kill-buffer (process-buffer proc))))))) (process-send-region flymake-tomlcheck--proc (point-min) (point-max)) (process-send-eof flymake-tomlcheck--proc)))) ;;;###autoload (defun flymake-tomlcheck-setup () "Enable tomlcheck flymake backend." (make-variable-buffer-local 'flymake-diagnostic-functions) (add-hook 'flymake-diagnostic-functions #'flymake-tomlcheck nil t)) (provide 'flymake-tomlcheck) ;;; flymake-tomlcheck.el ends here
1.6.3. yaml
(load "~/.emacs.d/flymake-yamllint.el") (add-hook 'yaml-mode-hook 'flymake-yamllint-setup) (add-hook 'yaml-mode-hook 'flymake-mode) (add-hook 'yaml-mode-hook 'trailing-whitespace-mode)
1.6.4. python
1.7. ide stuff, languages
For flymaker, see 1.6
1.7.1. python
;;;;;;;; python (require 'auto-complete) (require 'jedi) ;; these seem to be neccessary because of GUI/CUI, idk. (define-key jedi-mode-map (kbd "C-c <tab>") 'jedi:complete) (define-key jedi-mode-map (kbd "C-c TAB") 'jedi:complete) (add-hook 'python-mode-hook 'jedi:setup) (add-hook 'python-mode-hook (lambda () (interactive) (setq header-line-format "C-c TAB:complete | M-\":describe function | C-c ?:python doc"))) ;; don't show this when idle. Don't do anything if I don't ask you! ;; M-" to show info. (how it is shown: defined in customize) ;; this is a monkey patch. may break with a new emacs version (currently working: 28.2) (defun jedi:get-in-function-call-when-idle () ()) (define-key jedi-mode-map (kbd "M-\"") 'jedi:get-in-function-call)
1.7.2. Golang
;; golang (add-hook 'go-mode-hook #'eglot-ensure)
1.8. show git branch in modeline
(defun mo-term-git-mode--get-branch () ;;(vc-call-backend 'git 'mode-line-string ".") ; doesn't work ;;(let ((branches (vc-git-branches))) (let ((branches (vc-call-backend 'git 'branches))) (when branches (car branches)))) (define-minor-mode mo-term-git-mode "show current branch in modeline in terminal-modes" :lighter (:eval (let ((git-branch (mo-term-git-mode--get-branch))) (if git-branch (format " git:%s" git-branch) "")))) (add-hook 'term-mode-hook 'mo-term-git-mode)
1.9. TODO ement.el (matrix client)
1.10. Random stuff
1.10.1. align-regexp
shouldn't use tabs
;; stolen from https://stackoverflow.com/questions/22710040/emacs-align-regexp-with-spaces-instead-of-tabs (defadvice align-regexp (around align-regexp-with-spaces activate) (let ((indent-tabs-mode nil)) ad-do-it))
1.11. misc troubleshooting
- hanging xterm paste (also in putty)
;; in 27.2 ansi-term and some modification of xterm-paste don't work together so good ;; (results in a hang which you can only get out of by ^G ;; this solves it (require 'term) ;; so this gets not overwritten the wrong way round (defun term--xterm-paste (ev) "Insert the text pasted in an XTerm bracketed paste operation." (interactive "e") (term-send-raw-string (cadr ev)))
2. HOWTOs
2.1. Fonts
2.1.1. default font
From the emacs docs:
Add a line to your init file, modifying the variable `default-frame-alist' to specify the `font' parameter (*note Frame Parameters::), like this:
(add-to-list 'default-frame-alist '(font . "DejaVu Sans Mono-10"))
2.1.2. how to let emacs find a font for you
customize-face
expects from you that you know the name and all
parameters of a font. When I wasn't using GTK I found this hard. I
found this way:
Use describe-font
which give you an auto-complete in the minibuffer
which let's you look for and complete your font name. Kill the
complete font name.
Use set-face-font
to set the font for the face you want to change.
After this, use customize-font
to open a customize buffer which is
prefilled with the font you set with set-face-font
and allows you to
save to your ~/.emacs
.
2.1.3. troubleshooting
Sometimes emacs loses the fonts you define. That seems to happen with incompatible themes which redefine them. deinstall those themes and redefine your fonts.
Sometimes there seems to be a face lookup which results in a hangup
and the message that the face "undefined" can't be found. This usually
can't be fixed with a restart. This, too, was caused by a faulty
theme. Grep your ~/.emacs
for undefined
, remove that particular
piece of configuration, remove the fauly theme and restart your emacs.
2.2. How to build an input method
I built one. See here: quail classic german
2.3. Ansi-Term
2.3.1. pasting
There is a function called term-paste
, but it is bound to S-insert
by default. Who wants that? Use
(require 'term) (define-key term-raw-map (kbd "C-c y") 'term-paste) (define-key term-raw-map (kbd "C-c C-y") 'term-paste)
to rebind it to C-c C-y
2.3.2. tmacs
To conveniently open files from terminal even on remote machines, I use tmacswrap
You can define a function to quickly open a tmacs-term with
(defun tmacs--find-free-number () "use this function to create a reasonable buffer name" (cl-do ((num 0 (+ 1 num))) ((not (get-buffer (format "*tmacs<%s>*" num))) num))) (defun tmacs () (interactive) (ansi-term "/bin/bash" (format "tmacs<%s>" (tmacs--find-free-number))))
and then open it with M-x tmacs
.
2.3.3. emacsclient
Add to your ~/.bashrc
:
if [ -n "$INSIDE_EMACS" ]; then export VISUAL=emacsclient # use tmacs here, if you want export EDITOR=$VISUAL fi
Don't use emacsclient -n
because that would confuse programs like
git
when you edit your commit messages with this.
2.3.4. Forbid TRAMP to ask for password
It may be a problem if one mistypes on a password prompt in tramp, because emacs might lock up your account if there is a limit of unsuccessful logins.
- tell ssh to not ask for password
- override tramp function to ask for password and error out.
;; ~/.emacs ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; tramp (setq tramp-ssh-controlmaster-options "-o PasswordAuthentication=no") ;; don't ever ask for passwords! ;; TODO: implement as advice (defun tramp-read-passwd (proc &optional prompt) (message "Tramp tries to ask for password, inhibiting") (error "Tramp tried to ask for password")) ;; just fail
To allow emacs to TRAMP somewhere, nonetheless, use a controlmaster connection
# ~/.ssh/config # use this, if you have a domain. Else something might not work when using shortnames # CanonicalizeHostname yes # CanonicalDomains my.domain.com host * ControlMaster auto ControlPath ~/.ssh/control/%C ControlPersist 15m
2.3.5. troubleshooting
- slow scrolling (emacs 26.1 has this problem)
In older emacs versions ansi-term was allegedly very slow clearing the screen. In version 26.1 the problem seems to be fixed, but still triggered in a different way: Scrolling fast, if the terminal buffer is already full. I solved this problem by using this1
;; Terminal buffer configuration. (add-hook 'term-mode-hook 'my-term-mode-hook) (defun my-term-mode-hook () ;; https://debbugs.gnu.org/cgi/bugreport.cgi?bug=20611 (setq bidi-paragraph-direction 'left-to-right))
- terminal resizing (emacs 26.1 has this problem)
Resizing the terminal in which emacs runs doesn't inform inferior terminals that they should be resized, too. Use this2:
(add-hook 'window-configuration-change-hook (lambda (frame) (window--adjust-process-windows)))