This is the configuration of my EMACS-Editor written in Org mode in literate style programming. I’ve sort of hoarded a lot of different packages and different .emacs
files from all over the internet and just stucked them together.
Using the configuration as is it is is not really advisable. Some things may seem weird and ‘wrongly’ configured, but hey…this is EMACS.\
Still, you may found some hidden gems in here that can greatly simplify your work with the editor. I don’t use [[https://github.com/jwiegley/use-package][use-package]]
as I found that it actually makes my emacs sluggish on windows and I actually prefer to have everything in my local config all the time.\
Download the repo with
git clone https://github.com/palikar/dotfiles
and setup emacs
. setup-emacs.sh
// I’ve drawn a lot of inspiration for my Emacs configuration form:
Lets let Emacs know who I am. Probably not a good idea cut them CIA know everything but hey, we trust our “free software”, right!
(setq user-full-name "Stanislav Arnaudov")
The default packages repository for emacs is ELPA. ELPA is not super good, we also want MELPA. MELPA is configured in the .emacs file but here we also add ELPA for good measures Everything is here now!
Edit: It’s anoying when starting emacs it takes so long to connect to all the sites for the packages and I don’t need package-install
that regularly. With the current setup I fist have to call setup-packages
in order to install new one but the emacs init time significantly lower. You may or may not care about that time if you run emacs like emacs --daemon
.
(require 'package)
(setq package-archives '())
(package-initialize)
(package-refresh-contents)
I use a lot of additional packages and like to keep them local and installed. I’ve tried use-package
but I had some issues and I’ve opted out for installing everything. The initial waiting when setting up emacs config from scratch is fine by me.
; all of my packages that I want in my config
; starting-packages
(setq package-list '(ac-R ac-ja aggressive-indent alect-themes anzu atom-dark-theme auto-complete-clang auto-complete-clang-async auto-complete-nxml auto-org-md base16-theme bash-completion beacon blacken clang-format cmake-font-lock cmake-ide cmake-mode cmake-project color-theme-modern company-anaconda anaconda-mode company-auctex auctex company-bibtex company-c-headers company-cmake company-emacs-eclim company-ghci company-irony company-irony-c-headers company-jedi company-lsp company-math company-quickhelp company-reftex company-rtags company-web company-ycmd cppcheck cquery crux ctags-update dap-mode bui dashboard diminish dired-collapse dired-details dired-du dired-hide-dotfiles dired-icon dired-imenu dired-nav-enhance dired-sidebar dired-subtree dired-hacks-utils dmenu docker docker-tramp dockerfile-mode doom-themes dot-mode drag-stuff dumb-jump easy-hugo easy-kill eclim ein elf-mode elpy emlib emmet-mode emojify eslint-fix esxml expand-region eyebrowse fancy-battery fill-column-indicator find-file-in-project firefox-controller fireplace flycheck-clang-analyzer flycheck-clang-tidy flycheck-clangcheck flycheck-irony flycheck-pycheckers flycheck-ycmd flyspell-correct-popup flyspell-correct flyspell-popup fontawesome function-args ghub git-timemachine gitignore-templates gnu-elpa-keyring-update go-mode god-mode golden-ratio google-this google-translate goto-line-preview gradle-mode graphql graphviz-dot-mode haskell-mode helm-ag helm-bibtex biblio biblio-core helm-bibtexkey helm-c-yasnippet helm-company helm-flycheck helm-ispell helm-lsp helm-projectile helm-rtags helm-spotify helm-spotify-plus helm helm-core hide-mode-line highlight-indent-guides highlight-indentation highlight-sexp highlight-symbol hugo hungry-delete ibuffer-projectile iedit image-dired+ imenu-list irony-eldoc irony iy-go-to-char java-file-create java-imports java-snippets jedi auto-complete jedi-core epc ctable concurrent json-mode json-reformat json-snatcher keyfreq latex-pretty-symbols latex-preview-pane levenshtein lorem-ipsum lsp-java lsp-treemacs lsp-ui lsp-mode dash-functional magit git-commit magit-popup markdown-mode math-symbol-lists maven-test-mode meghanada flycheck company modalka modern-cpp-font-lock moe-theme molokai-theme monokai-theme moz mu4e-alert alert log4e gntp mu4e-conversation multi multi-web-mode multiple-cursors mustache-mode mvn mvn-help neotree nlinum-relative nlinum noflet org-attach-screenshot org-bullets org-page git mustache org-pdfview org-plus-contrib org2blog metaweblog htmlize organize-imports-java ov ox-epub ox-gfm ox-hugo ox-reveal ox-twbs ox-twiki package-lint page-break-lines parsebib password-store auth-source-pass pcache pdf-tools pip-requirements plantuml-mode pod-mode polymode popup-complete popup popwin pos-tip powerline-evil evil goto-chg pretty-mode prodigy py-yapf pyenv-mode pymacs python-environment python-pylint python-x folding pythonic pyvenv quickrun ranger rmsbolt rtags scala-mode skewer-mode js2-mode simple-httpd smart-hungry-delete smart-mode-line-powerline-theme smart-mode-line rich-minority smartparens solarized-theme spaceline-all-the-icons spaceline powerline spacemacs-theme sphinx-doc spinner spotify srefactor sublimity super-save swiper ivy symbol-overlay syntax-subword tabbar tablist telephone-line template transient tree-mode treemacs-projectile treemacs ht hydra lv pfuture ace-window projectile treepy try typing typit mmt undo-tree use-package bind-key vimrc-mode virtualenvwrapper visible-mark visual-regexp-steroids visual-regexp volatile-highlights vscdark-theme vue-mode edit-indirect ssass-mode vue-html-mode mmm-mode web-beautify web-completion-data web-mode websocket wgrep-helm wgrep which-key with-editor async workgroups workgroups2 f anaphora wrap-region wttrin xelb xkcd xlicense xml-rpc xterm-color yagist yaml-mode yasnippet-snippets yasnippet ycmd pkg-info epl request-deferred request let-alist deferred s dash zeal-at-point zerodark-theme all-the-icons memoize zygospore zzz-to-char avy))
; ending-packages
; activate all the packages (in particular autoloads)
(package-initialize)
; fetch the list of packages available
(unless package-archive-contents
(package-refresh-contents))
(setq gnutls-algorithm-priority "NORMAL:-VERS-TLS1.3")
(defvar packages-setup-state 'nil)
(setq package-check-signature 'nil)
(defun setup-packages ()
(interactive)
(setq package-archives '())
(add-to-list 'package-archives '("melpa" . "http://melpa.milkbox.net/packages/"))
(add-to-list 'package-archives '("org" . "https://orgmode.org/elpa/") )
(add-to-list 'package-archives '("marmalade" . "http://marmalade-repo.org/packages/") )
(add-to-list 'package-archives '("gnu" . "https://elpa.gnu.org/packages/") )
(package-refresh-contents)
(setq packages-setup-state t)
)
(dolist (package package-list)
(unless (package-installed-p package)
(progn
(unless packages-setup-state
(setup-packages))
(package-install package))))
Some major modes overwrite some of my custom keybindings. Therefore I define a custom global minor mode and use the key map of this mode to define my custom key bindings. This sets their precedence ‘above’ the precedence of the key bindings of other modes
(define-minor-mode my-keys-mode
"Minor mode for my personal keybindings."
:global t
:keymap (make-sparse-keymap))
(require 'bind-key)
(setf (cdr my-keys-mode-map) nil)
(my-keys-mode t)
Making the whole emacs
experience a tiny bit better with those fixes of the interface of the editor
- Startup screen is anoying
- The toolbar is wasting space
f5
should function as a refresh in firefox- Fringes waste space
- Numbered lines come in handy
- Highlighting the current line is pretty
übersichtlich
- Pretty sybols like λ over the whole place is pretty cool
- nlinum - a mode to display the line numbers but it’s much more efficient than the build in linum-mode. nlinum can handle big files without a hiccup while scrolling.
(setq inhibit-startup-message t)
(setq frame-title-format '("Emacs " emacs-version))
(setq cursor-type 'box)
(setq visible-bell 'nil)
(tool-bar-mode -1)
(menu-bar-mode -1)
(fset 'yes-or-no-p 'y-or-n-p)
(fringe-mode '(0 . 0))
(global-nlinum-mode -1)
(global-visual-line-mode 1)
(global-hl-line-mode 1)
(global-prettify-symbols-mode +1)
(scroll-bar-mode 0)
;; (set-frame-parameter (selected-frame) 'alpha '(85 . 85))
(add-to-list 'default-frame-alist '(alpha . (85 . 85)))
(set-fill-column 80)
(face-spec-set 'secondary-selection '((t (:background "light sky blue" :foreground "black"))))
;; (set-face-attribute 'default nil :font "SauceCodePro Nerd Font Mono:size=16")
;;(set-frame-font "SauceCodePro Nerd Font Mono:size=15" nil t)
;; (set-default-font "SauceCodePro Nerd Font Mono:size=15")
Displaying emojies in a proper way.
(add-hook 'after-init-hook #'global-emojify-mode)
Some quick fixes for intuitive and straight forward editing. Generally I strive for the cleanest design the interface possible so I remove a lot from the unnecessary things that come by default with EMACS.
(setq debug-on-error nil)
(setq indent-tabs-mode nil)
(setq auto-save-default nil)
(setq backup-inhibited t)
(setq mouse-wheel-scroll-amount '(1 ((shift) . 1)))
(setq mouse-wheel-follow-mouse nil)
(setq scroll-step 1) ;;smooth-ish scrolling
(setq confirm-kill-emacs 'y-or-n-p) ;; Sometimes I fat finger C-x C-c
(setq save-interprogram-paste-before-kill t)
(setq auto-revert-verbose nil) ;; everything is seemless
(setq vc-follow-symlinks t) ;; it asks you everytime otherwise
(delete-selection-mode 1) ;; it's really weird working without that
(load "~/.emacs.d/lisp/syntax-subword")
(global-syntax-subword-mode 1) ;; easy workings with camel case, snake case and pretty much anything else
(global-auto-revert-mode 1) ;; see changes on disc as quick as possible
(prefer-coding-system 'utf-8)
(set-default-coding-systems 'utf-8)
(set-terminal-coding-system 'utf-8)
(set-keyboard-coding-system 'utf-8)
(put 'upcase-region 'disabled nil)
(put 'downcase-region 'disabled nil)
(setq tab-always-indent 'complete)
(setq require-final-newline t)
(setq mouse-yank-at-point t)
(setq create-lockfiles nil)
(auto-compression-mode t)
(setenv "LD_LIBRARY_PATH" (concat (getenv "PATH") ":" (expand-file-name "~/core.d/usr/lib/")))
(setenv "PATH" (concat (getenv "PATH") ":" (expand-file-name "~/core.d/usr/bin")))
(setq exec-path (append exec-path (list (expand-file-name "~/core.d/usr/bin"))))
(bind-key* "M-c" 'capitalize-dwim)
(bind-key* "<deletechar>" 'hungry-delete-forward)
(require 'volatile-highlights)
(volatile-highlights-mode t)
(require 'super-save)
(add-to-list 'super-save-triggers 'ace-window)
(super-save-mode +1)
(require 'savehist) ;; savehist keeps track of some history
(setq savehist-additional-variables
'(search-ring regexp-search-ring))
(setq savehist-autosave-interval 60)
(savehist-mode +1)
(require 'recentf) ;; save recent files
(setq recentf-max-saved-items 500
recentf-max-menu-items 15
recentf-auto-cleanup 'never)
(recentf-mode +1)
(add-to-list 'recentf-exclude "\\.windows\\'")
(add-to-list 'recentf-exclude "\\.revive\\'")
(add-to-list 'recentf-exclude "\\/ssh:\\'")
(require 'uniquify)
(setq uniquify-buffer-name-style 'forward)
(setq uniquify-separator "/")
(setq uniquify-after-kill-buffer-p t) ; rename after killing uniquified
(setq uniquify-ignore-buffers-re "^\\*") ; don't muck with special buffers
(require 'saveplace) ;; saves your cursor's position in buffers and jumps to it on reopening
(setq save-place t)
(setq save-place-file (locate-user-emacs-file "places" ".emacs-places"))
(setq save-place-forget-unreadable-files nil)
Use Alt-up/down
as in any other editor to copy lines
(defun duplicate-line-down()
(interactive)
(let ((saved-position (point)))
(move-beginning-of-line 1)
(kill-line)
(yank)
(open-line 1)
(next-line 1)
(yank)
(goto-char saved-position)
)
)
(defun duplicate-line-up()
(interactive)
(let ((saved-position (point)))
(move-beginning-of-line 1)
(kill-line)
(yank)
(move-beginning-of-line 1)
(open-line 1)
(yank)
(goto-char saved-position)
(next-line 1)
)
)
Those are pretty much a must when editing code…and also anything else
- Select region and wrap it up with a sybol
- Cofigured with the standards
- Cofigured with the formating of
org-mode
- Insert a opening bracecket and the closing is inserted automagically!
(require 'wrap-region)
(wrap-region-add-wrapper "=" "=")
(wrap-region-add-wrapper "/" "/")
(wrap-region-add-wrapper "_" "_")
(wrap-region-add-wrapper "+" "+")
(wrap-region-add-wrapper "*" "*")
(wrap-region-add-wrapper "~" "~")
(wrap-region-add-wrapper "$" "$")
(wrap-region-add-wrapper "<" ">")
(wrap-region-add-wrapper ">" "<")
(wrap-region-global-mode t)
(require 'smartparens)
(smartparens-global-mode 1)
This function will bytecompile everything that it finds in the .emacs.d directory. This could boots the performance of emacs
(defun byte-compile-init-dir ()
"Byte-compile all your dotfiles."
(interactive)
(byte-recompile-directory user-emacs-directory 0))
(defun remove-elc-on-save ()
"If you're saving an elisp file, likely the .elc is no longer valid."
(add-hook 'after-save-hook
(lambda ()
(if (file-exists-p (concat buffer-file-name "c"))
(delete-file (concat buffer-file-name "c"))))
nil
t))
(add-hook 'emacs-lisp-mode-hook 'remove-elc-on-save)
(defun smarter-move-beginning-of-line (arg)
"Move point back to indentation of beginning of line.
Move point to the first non-whitespace character on this line.
If point is already there, move to the beginning of the line.
Effectively toggle between the first non-whitespace character and
the beginning of the line.
If ARG is not nil or 1, move forward ARG - 1 lines first. If
point reaches the beginning or end of the buffer, stop there."
(interactive "^p")
(setq arg (or arg 1))
;; Move lines first
(when (/= arg 1)
(let ((line-move-visual nil))
(forward-line (1- arg))))
(let ((orig-point (point)))
(back-to-indentation)
(when (= orig-point (point))
(move-beginning-of-line 1))))
- Keybindings
(bind-key* "C-a" 'smarter-move-beginning-of-line)
When you run Emacs as daemon and you connect clients to it, hitting C-x C-c
will close the client without asking even though confirm-kill-emacs
is set to true. This snippet will notice if Emacs is ran as daemon and will always ask me to close the current client.
(when (daemonp)
(bind-key* "C-x C-c" 'ask-before-closing))
The default scrolling behavior of Emacs is god awful. This fixes more of the issues.
(setq scroll-margin 7)
(setq scroll-conservatively 0)
(setq scroll-up-aggressively 0.01)
(setq scroll-down-aggressively 0.01)
(setq-default scroll-up-aggressively 0.01
scroll-down-aggressively 0.01)
(scroll-all-mode -1)
(setq scroll-conservatively most-positive-fixnum)
(setq scroll-preserve-screen-position t)
(setq gdb-many-windows t
gdb-show-main t)
(setq ediff-window-setup-function 'ediff-setup-windows-plain
ediff-split-window-function 'split-window-horizontally)
;; (tramp-unload-tramp)
;; (require 'tramp)
;; (setq tramp-default-method "ssh"
;; tramp-backup-directory-alist backup-directory-alist
;; tramp-ssh-controlmaster-options "ssh")
(setq doc-view-continuous t)
(require 'dired)
(setq dired-dwim-target t)
(setq dired-recursive-copies 'top)
(setq dired-recursive-deletes 'top)
(setq dired-listing-switches "-alh")
(add-hook 'dired-mode-hook 'dired-hide-details-mode)
My choice of terminal envinroment in my emacs is Terminal Emulator/(term). There are two modes to it - /char and line. Switching between them is made easier with one simple function and some custom key-bindings.
//
May other IDEs use F5
for building and compiling projects and I’ve gotten used to that. Therefore…custom keybinding.
(require 'term)
(define-key term-mode-map (kbd "C-c C-j") 'my/term-toggle-mode)
(define-key term-mode-map (kbd "C-c C-k") 'my/term-toggle-mode)
(define-key term-raw-map (kbd "C-c C-j") 'my/term-toggle-mode)
(define-key term-raw-map (kbd "C-c C-k") 'my/term-toggle-mode)
(bind-key* "C-<f5>" 'compile)
(defun display-startup-echo-area-message ()
(message "Let the games begin!"))
(defun ask-before-closing ()
"Close only if y was pressed."
(interactive)
(if (y-or-n-p (format "Are you sure you want to close this frame? ")) (save-buffers-kill-emacs)
(message "Canceled frame close")))
(defun list-installed-packages ()
"docstring"
(interactive)
(describe-variable 'package-activated-list)
)
(defun transpose-windows (arg) ;; yes, I know, there is also a crux-function that does the exact same thing...still...!!!
"Transpose the buffers shown in two windows."
(interactive "p")
(let ((selector (if (>= arg 0) 'next-window 'previous-window)))
(while (/= arg 0)
(let ((this-win (window-buffer))
(next-win (window-buffer (funcall selector))))
(set-window-buffer (selected-window) next-win)
(set-window-buffer (funcall selector) this-win)
(select-window (funcall selector)))
(setq arg (if (plusp arg) (1- arg) (1+ arg))))))
(defun find-myinit-file ()
"Open the myinit.org file which is my actual configuration file."
(interactive)
(find-file-other-window "~/.emacs.d/myinit.org"))
(defun comment-or-uncomment-region-or-line ()
"Comments or uncomments the region or the current line if there's no active region."
(interactive)
(save-excursion
(let (beg end)
(if (region-active-p)
(setq beg (region-beginning) end (region-end))
(setq beg (line-beginning-position) end (line-end-position)))
(comment-or-uncomment-region beg end))))
(defun my/term-toggle-mode ()
"Toggles term between line mode and char mode"
(interactive)
(if (term-in-line-mode)
(term-char-mode)
(term-line-mode)))
(defun fd-switch-dictionary ()
(interactive)
(let* ((dic ispell-current-dictionary)
(change (if (string= dic "deutsch8") "english" "deutsch8")))
(ispell-change-dictionary change)
(message "Dictionary switched from %s to %s" dic change)
))
(defun toggle-transparency ()
(interactive)
(let ((alpha (frame-parameter nil 'alpha)))
(set-frame-parameter
nil 'alpha
(if (eql (cond ((numberp alpha) alpha)
((numberp (cdr alpha)) (cdr alpha))
((numberp (cadr alpha)) (cadr alpha)))
100)
'(85 . 80) '(100 . 100)))))
(defun hot-expand (str)
"Expand org template."
(insert str)
(org-try-structure-completion))
(defun kill-whole-word ()
(interactive)
(backward-word)
(kill-word 1))
(defun kill-whole-line ()
(interactive)
(move-beginning-of-line 'nil)
(kill-line))
(defun replace-or-delete-pair (open)
"Replace pair at point by OPEN and its corresponding closing character.
The closing character is lookup in the syntax table or asked to
the user if not found."
(interactive
(list
(read-char
(format "Replacing pair %c%c by (or hit RET to delete pair):"
(char-after)
(save-excursion
(forward-sexp 1)
(char-before))))))
(if (memq open '(?\n ?\r))
(delete-pair)
(let ((close (cdr (aref (syntax-table) open))))
(when (not close)
(setq close
(read-char
(format "Don't know how to close character %s (#%d) ; please provide a closing character: "
(single-key-description open 'no-angles)
open))))
(replace-pair open close))))
(defun replace-pair (open close)
"Replace pair at point by respective chars OPEN and CLOSE.
If CLOSE is nil, lookup the syntax table. If that fails, signal
an error."
(let ((close (or close
(cdr-safe (aref (syntax-table) open))
(error "No matching closing char for character %s (#%d)"
(single-key-description open t)
open)))
(parens-require-spaces))
(insert-pair 1 open close))
(delete-pair)
(backward-char 1))
(defun pass () "A function that does nothing" (interactive))
(defun load-if-present (file-name)
"Load the FILE-NAME if the file is present."
(if (file-readable-p file-name)
(progn
(load-file file-name)
't)
'nil))
(toggle-transparency)
(setq custom-file "~/.emacs.d/custom.el")
(load custom-file)
(bind-key* "C-<f1>" 'toggle-transparency)
(bind-key* "M-<f8>" 'fci-mode)
(bind-key* "<f9>" 'menu-bar-mode)
(bind-key* "C-<f9>" 'hide-mode-line-mode)
(bind-key* "<f10>" 'tool-bar-mode)
(bind-key* "C-<f10>" 'scroll-bar-mode)
(bind-key* "C-<f12>" 'nlinum-mode)
(bind-key* "M-n" 'forward-paragraph)
(bind-key* "M-p" 'backward-paragraph)
(bind-key* "<f5>" 'revert-buffer)
(bind-key* "C-<prior>" 'scroll-down-line)
(bind-key* "C-<next>" 'scroll-up-line)
(bind-key* "C-S-<prior>" 'scroll-down-line)
(bind-key* "C-S-<next>" 'scroll-up-line)
(bind-key* "C-M-<prior>" 'scroll-down)
(bind-key* "C-M-<next>" 'scroll-up)
(bind-key* "C-c d" 'delete-file)
(bind-key* "C-S-<down>" 'duplicate-line-down)
(bind-key* "C-S-<up>" 'duplicate-line-up)
(bind-key* "C-+" 'text-scale-increase)
(bind-key* "C--" 'text-scale-decrease)
(bind-key* "C-z" 'zap-up-to-char)
(bind-key* "C-x r e" 'eval-region)
(bind-key* "<f5>" 'revert-buffer)
(bind-key* "M-j <f1>" 'customize-group)
(bind-key* "M-j <f2>" 'setup-packages)
(bind-key* "M-j <f3>" 'package-install)
(bind-key* "C-x k" 'kill-this-buffer)
(bind-key* "C-x K" 'kill-buffer)
(bind-key* "C-c w r" 'replace-or-delete-pair)
(bind-key* "C-c w w" 'kill-whole-word)
(bind-key* "C-c w l" 'kill-whole-line)
(bind-key* "M-<f1>" 'whitespace-cleanup)
(bind-key* "C-<Scroll_Lock>" 'list-installed-packages)
(bind-key* "C-<f7>" 'toggle-transparency)
(bind-key* "M-+" 'backward-paragraph)
(bind-key* "M-#" 'forward-paragraph)
Disable some keybindgs cuz’ those are just annoying
(global-unset-key ( kbd "<prior>"))
(global-unset-key ( kbd "<next>"))
(global-unset-key ( kbd "<home>"))
(global-unset-key ( kbd "<end>"))
(global-unset-key ( kbd "<insert>"))
(global-unset-key ( kbd "<insert>"))
(global-unset-key ( kbd "C-<home>"))
(global-unset-key ( kbd "C-<end>"))
Couple of minor setups that make working with frames a little bit easier. In a lot of cases I just want to switch the position of two windows so there is handy function there. Also, navigating around windows can be a bit weird and slow with just using C-x o
so windmove
is set up to work with C-c
and the arrow keys
For easy navigation between several monitors. It’s helpful to be able to quickly switch between different frames of emacs on different monitors.
(require 'ace-window)
My little thingy that is kind of useless but I like it. I implemented a mode so that you can resize the windows in Emacs… functionality that already exist in vanilla Emacs.
(load-if-present "~/.emacs.d/lisp/arnaud-framer.el")
(when (require 'arnaud-framer nil t)
(global-framer-mode 'nil))
When used, it keeps the focused window the biggest while still having the other ones in a “golder ratioed” size.
;; (require 'golden-ratio)
Sometimes… I make mistakes. I hit C-x 1
and bam! I’ve lost may window config that I actually don’t necessarily wanted destroyed. This package fixes this “issue”. If I hit C-x 1
again, I was just where I was before
(require 'zygospore)
(global-set-key (kbd "C-x 1") 'zygospore-toggle-delete-other-windows)
(bind-key* "C-x 4 t" 'transpose-windows)
(bind-key* "C-c <left>" 'windmove-left)
(bind-key* "C-c <right>" 'windmove-right)
(bind-key* "C-c <up>" 'windmove-up)
(bind-key* "C-c <down>" 'windmove-down)
(bind-key* "C-x o" 'ace-window)
I often alternate between these two and can’t really decide which is my favorite one. I depends on the day, I guess. In this case, better to gave them both at one place!
(setq custom-enabled-themes (quote (spacemacs-dark)))
(setq custom-enabled-themes (quote (vscdark-dark)))
(setq custom-safe-themes t)
;; this loads the theme correctly even in daemon mode
(if (daemonp)
(add-hook 'after-make-frame-functions
(lambda (frame)
(with-selected-frame frame
(load-theme 'spacemacs-dark t))))
(load-theme 'spacemacs-dark t))
;; (load-theme 'monokai)
These packages add some minor tweak to EMACS to make text editing easier.
beacon - flashes your cursor after the cursor has been re-positioned.
(require 'beacon)
(beacon-mode 1)
hungry-delete - deletes all of the white spaces that are ‘on the way’ after hitting delete or backspace. It’s weird at first but then you get use to it and kinda crave it and feel its lack if not there.
(require 'hungry-delete)
(global-hungry-delete-mode)
expand-region - kinda of a wannabe of that one vim functionality where you select everything between two braces with few simple strokes. This is more powerful but not that precise, to put it mildly. Not that it’s not good. Just hit key binding and you can grow the region in both sides by ‘semantic increments’, whatever that’s supposed to mean.
(require 'expand-region)
(bind-key* "C-c =" 'er/expand-region)
CRUX is an abrabiation for A Collection of Ridiculously Useful eXtensions for Emacs, so yeah, pretty self-explenatory. Its just a collection of functions that make your emacs-live a little bit easier. -crux
(require 'crux)
(bind-key* "C-c o" nil)
;; (bind-key* "C-c o" 'crux-open-with)
(bind-key* "C-c r" 'crux-rename-file-and-buffer)
(bind-key* "C-c i" 'find-myinit-file)
(bind-key* "C-c I" 'crux-find-user-init-file)
(bind-key* "C-c 1" 'crux-create-scratch-buffer)
(bind-key* "C-c S" 'crux-find-shell-init-file)
(bind-key* "M-k" 'crux-kill-line-backwards)
(bind-key* "C-c t" 'crux-visit-term-buffer)
Through this packages, I can browse 4chan (only /g
of course!) threads in my Emacs. It uses the json API of 4chan and renders everything in the editor itself. It even provides some nifty features that are not available in the vanilla 4chan website. I can browser through the replies of a given post, quickly jump to replies of replies and then go back up and also download (through wget) images/webms from 4chan directly from here, in my editor. God, I love Emacs.
;; (when (load-if-present "/home/arnaud/code_ext/q4/q4.el")
;; (bind-key* "M-j q" 'q4/browse-board))
This is absolutely a genius thing! Mark something, simple key-stroke, BAM!! Google! You are there! You have no idea how much copying and windows switching this package saves. Again, for intuition sake, C-c g
is the prefix. After that:
w
for words
for selectiong
for googling from prompted inputSPC
for regionl
for linec
for cpp-reference
I also frequanlty use Zeal. It’s an application housing tons of usefull documentations and look ups in it while working on somethings are a must. Therefore I have package named zeal-at-point that allows me to perform quick search actions in the application with query take form the point. The keybinding for that is C-c g z
(*Z*eal).
(require 'google-this)
(setq browse-url-browser-function 'browse-url-generic
browse-url-generic-program "firefox")
(google-this-mode 1)
(bind-key* "C-c g" 'google-this-mode-submap)
(bind-key* "C-c g c" 'google-this-cpp-reference)
(bind-key* "C-c g z " 'zeal-at-point)
Viewing pdf files in emacs! Not really indented for big and heavy files but when I have to check on something is does the trick. If emacs is compiled with ImageMagic, the provided features are much more.
;; (require 'pdf-tools)
;; (require 'org-pdfview)
Markdown is not as pretty as Org-mode but is widely used throughout the Internet. I often have to open .md files and therefore it’s worth making them look pretty in my emacs. The markdown-mode
provies exaclty that.
-markdown-mode
(autoload 'markdown-mode "markdown-mode"
"Major mode for editing Markdown files" t)
(add-to-list 'auto-mode-alist '("\\.md\\'" . markdown-mode))
(add-to-list 'auto-mode-alist '("\\.markdown\\'" . markdown-mode))
(add-to-list 'auto-mode-alist '("\\.text\\'" . markdown-mode))
(add-to-list 'auto-mode-alist '("\\.txt\\'" . markdown-mode))
(add-to-list 'auto-mode-alist '("README\\.md\\'" . gfm-mode))
Org-mode is awesome not just for note taking but also for general text editing, formating and all and all just plain old writing. Therefore some basic org-mode configuration comes at handy when working with .org
files (this init file is written in org-mode so…yeah!!). The org-bullets
makes the heading look pretty. I have couple of extra exporters for .org
files that just make my life easier.
(require 'org-bullets)
;; (require 'org-tempo)
(setq org-agenda-files '("~/Documents/orgfiles/todos/todos.org"))
(setq org-support-shift-select (quote always))
(setq org-startup-indented t)
(setq org-hide-leading-stars t)
(setq org-babel-python-command "python")
(setq org-directory "~/Documents/orgfiles")
(setq org-default-notes-file (concat org-directory "/notes.org"))
(setq org-export-html-postamble nil)
(setq org-startup-folded (quote overview))
(setq org-log-done 'time)
(setq org-pretty-entities t)
(setq org-export-babel-evaluate nil)
(setq org-export-with-smart-quotes t)
(setq org-enable-priority-commands nil)
(setq org-html-htmlize-output-type 'css)
(setq org-latex-listings 'minted
org-latex-packages-alist '(("" "minted"))
org-latex-pdf-process
'("pdflatex -shell-escape -interaction nonstopmode -output-directory %o %f"
"pdflatex -shell-escape -interaction nonstopmode -output-directory %o %f"))
(setq org-highlight-latex-and-related '(latex script entities))
(add-hook 'org-mode-hook (lambda ()
(org-bullets-mode 1)
(flyspell-mode 1)))
The codeblocks should be formated with the native envinroment of the language
(setq org-src-fontify-natively t)
(setq org-src-tab-acts-natively t)
(setq org-confirm-babel-evaluate nil)
(setq org-edit-src-content-indentation 0)
(defun org-summary-todo (n-done n-not-done)
"Switch entry to DONE when all subentries are done, to TODO otherwise."
(let (org-log-done org-log-states) ; turn off logging
(org-todo (if (= n-not-done 0) "DONE" "TODO"))))
(add-hook 'org-after-todo-statistics-hook 'org-summary-todo)
;; (setq org-structure-template-alist '(("a" . "export ascii")
;; ("c" . "center")
;; ("C" . "comment")
;; ("e" . "example")
;; ("E" . "export")
;; ("h" . "export html")
;; ("l" . "export latex")
;; ("q" . "quote")
;; ("s" . "src")
;; ("v" . "verse")))
(setq org-structure-template-alist '())
Some extra export backends for org-mode that come in handy.
- Beamer - for making those awesome-ish presentations
- twbs(Tweeter Bootstrap) - quickly make your org files look really pretty
- hugo - I use Hugo for blogging and the exporter allows me to write every single content page in org-mode
- gfm (Github Flavored Markdown) - this makes writing README.md files easy (i.e. writing them in org-mode)
(require 'ox-beamer)
(require 'ox-twbs)
(require 'ox-hugo)
(require 'ox-gfm)
;; (setq org-hugo-external-file-extensions-allowed-for-copying
;; '("png" "jpg" "jpeg" "pdf" "txt"))
Remove headlines with :no_title:
tag.
(require 'ox-extra)
(defun org-remove-headlines (backend)
(org-map-entries (lambda () (delete-region (point-at-bol) (point-at-eol)))
"no_title"))
(add-hook 'org-export-before-processing-hook #'org-remove-headlines)
(ox-extras-activate '(ignore-headlines))
(setq org-reverse-note-order t)
(setq org-capture-templates
'(("t" "Todo" entry (file+headline "~/Documents/orgfiles/todos/todos.org" "Captured")
"* TODO %?\nAdded: %U\n" :prepend t :kill-buffer t)
("i" "Idea" entry (file+headline "~/Documents/orgfiles/notes.org" "Someday/Maybe")
"* IDEA %?\nAdded: %U\n" :prepend t :kill-buffer t)
))
This style of presenting looks cool but I don’t use it that much. Still, I want to have the possibility in my emacs.
(require 'ox-reveal)
(require 'htmlize)
(setq org-reveal-root "http://cdn.jsdelivr.net/reveal.js/3.0.0/")
(setq org-reveal-mathjax t)
(setq org-export-allow-bind-keywords 't)
(setq org-latex-prefer-user-labels 't)
(add-to-list 'org-latex-classes
'("llncs"
"\\documentclass{llncs}"
("\\section{%s}" . "\\section*{%s}")
("\\subsection{%s}" . "\\subsection*{%s}")
("\\subsubsection{%s}" . "\\subsubsection*{%s}")))
- Source block with this line in the header:
dot :file ./img/example1.png :cmdline -Kdot -Tpng
will produce a graph-png at the end....it’s awesome!
(org-babel-do-load-languages
(quote org-babel-load-languages)
(quote (
(emacs-lisp . t)
(java . t)
(dot . t)
(ditaa . t)
(R . t)
(python . t)
(ruby . t)
(gnuplot . t)
(clojure . t)
(shell . t)
(ledger . t)
(org . t)
(plantuml . t)
(plantuml . t)
(latex . t))))
(setq org-plantuml-jar-path
(expand-file-name "~/code_ext/plantuml.jar"))
(bind-key* "C-c a" 'org-agenda)
(bind-key* "C-c c" 'org-capture)
(bind-key* "C-c C-x s" 'org-attach-screenshot org-mode-map)
(setq org-replace-disputed-keys 't)
(add-hook 'org-shiftup-final-hook 'windmove-up)
(add-hook 'org-shiftleft-final-hook 'windmove-left)
(add-hook 'org-shiftdown-final-hook 'windmove-down)
(add-hook 'org-shiftright-final-hook 'windmove-right)
For some reason I must set the right python command each time I start emacs. This does the trick…sometimes. Running random snippets of code in .org files…how bonkers is that. The answer is pretty bonkers!!(You know if you are into emacs if you get this “reference”)
(setq org-babel-python-command "python")
(defun org-include-img-from-pdf (&rest _)
"Convert pdf files to image files in org-mode bracket links.
# ()convertfrompdf:t # This is a special comment; tells that the upcoming
# link points to the to-be-converted-to file.
# If you have a foo.pdf that you need to convert to foo.png, use the
# foo.png file name in the link.
[[./foo.png]]
"
(interactive)
(if (executable-find "convert")
(save-excursion
(goto-char (point-min))
(while (re-search-forward "^[ \t]*#\\s-+()convertfrompdf\\s-*:\\s-*t"
nil :noerror)
;; Keep on going to the next line till it finds a line with bracketed
;; file link.
(while (progn
(forward-line 1)
(not (looking-at org-bracket-link-regexp))))
;; Get the sub-group 1 match, the link, from `org-bracket-link-regexp'
(let ((link (match-string-no-properties 1)))
(when (stringp link)
(let* ((imgfile (expand-file-name link))
(pdffile (expand-file-name
(concat (file-name-sans-extension imgfile)
"." "pdf")))
(cmd (concat "convert -density 96 -quality 85 "
pdffile " " imgfile)))
(when (and (file-readable-p pdffile)
(file-newer-than-file-p pdffile imgfile))
;; This block is executed only if pdffile is newer than
;; imgfile or if imgfile does not exist.
(shell-command cmd)
(message "%s" cmd)))))))
(user-error "`convert' executable (part of Imagemagick) is not found")))
(defun my/org-include-img-from-pdf-before-save ()
"Execute `org-include-img-from-pdf' just before saving the file."
(add-hook 'before-save-hook #'org-include-img-from-pdf nil :local))
;; Do not include this, it freezes when used in huge org buffers!
;; (add-hook 'org-mode-hook #'my/org-include-img-from-pdf-before-save)
For some reasons I have to call this after I’ve require-d all the exporters’ backends in order to make them available in the export dispatcher of org-mode.
(require 'org)
(org-reload)
I used to use /TexMaker/ for writing my
- auctex - full fledged environment for writing, editing and compiling .tex documents. Almost everything comes out of the box. Only a simple setup and configuration is required.
- latex-preview-pane - The very cool feature of Tex/Maker/ where your generated pdf-document is displayed on the side. Yes. Emacs can do it too…surprise, surprise!!
(require 'tex)
(require 'latex-preview-pane)
(setq TeX-auto-save t)
(setq TeX-parse-self t)
(setq-default TeX-master nil)
(add-hook 'LaTeX-mode-hook 'visual-line-mode)
(add-hook 'LaTeX-mode-hook 'flyspell-mode)
(add-hook 'LaTeX-mode-hook 'LaTeX-math-mode)
(add-hook 'LaTeX-mode-hook 'pretty-mode)
(add-hook 'LaTeX-mode-hook 'prettify-symbols-mode)
(add-hook 'LaTeX-mode-hook 'turn-on-reftex)
(setq reftex-plug-into-AUCTeX t)
(TeX-global-PDF-mode t)
(setq TeX-view-program-list '(("Evince" "evince --page-index=%(outpage) %o")))
(setq TeX-view-program-selection '((output-pdf "Evince")))
(add-hook 'LaTeX-mode-hook 'TeX-source-correlate-mode)
(setq TeX-source-correlate-start-server t)
(setq org-latex-pdf-process (list
"latexmk -pdflatex='lualatex -shell-escape -interaction nonstopmode' -pdf -f %f"))
(bind-key* "C-c l p" 'latex-preview-pane-mode latex-mode-map)
(bind-key* "C-c l b" 'helm-bibtex-with-local-bibliography latex-mode-map)
(bind-key* "C-c l M-p" 'latex-preview-pane-update latex-mode-map)
(bind-key* "C-c l l" 'TeX-command-master latex-mode-map)
I don’t have all that much tweaks in here in the general programming section. Commenting out regions or lines is probably the thing I use the most. The other things are just very minor things that are standard in every other IDE.
- function-args - package that provies smart completion for function arguments. Works perfectly with yasnippets.
(setq c-default-style '((java-mode . "java") (other . "awk")))
(setq-default c-default-style "awk")
(setq-default indent-tabs-mode nil)
(setq-default c-basic-offset 2)
(add-hook 'proge-mode-hook 'semmantic-highlight-func-mode)
(show-paren-mode 1)
(set-default 'semantic-case-fold t)
(add-to-list 'auto-mode-alist '("\\.h\\'" . c++-mode))
(set-default 'semantic-case-fold t)
The most of the configuration work is done in each of the following sections. There I extensively have tweaked the environment for each language so that editing it is as easy as possible. There are also several “feature” oriented sections that target some cool feature provided by your standard IDE but by Emacs by default.
(bind-key* "C-/" 'comment-or-uncomment-region-or-line)
A standard IDE feature that comes out of the box with emacs. Just a little tweak to give it nice keybindings. To note is that I use german QWERTZ keyboard so this won’t work for all you QWERTY-Normies out there.
(add-hook 'prog-mode-hook 'hs-minor-mode)
(bind-key* "M-ü" 'hs-show-all)
(bind-key* "C-M-ü" 'hs-hide-all)
(bind-key* "C-ü" 'hs-toggle-hiding)
At my work I use this emacs-configuration for a lot of c++ programming. Yet, similar to other sections, the c++ tweaks are…pretty much nothing. Emacs is just that good with no special c++ tweaks. Note: At some time I plan to experiment with cquery
(require 'irony)
;; (require 'ycmd)
;; (require 'company-ycmd)
;; (require 'flycheck-ycmd)
;; (require 'function-args)
;; (require 'modern-cpp-font-lock)
(require 'flycheck-clangcheck)
;; (require 'flycheck-clang-analyzer)
;; (modern-c++-font-lock-global-mode t)
;; (fa-config-default)
;; (set-variable 'ycmd-server-command '("python" "/home/arnaud/code_ext/ycmd/ycmd"))
;; (set-variable 'ycmd-extra-conf-whitelist '("~/.ycm_extra_conf.py"))
;; (set-variable 'ycmd-global-config "~/.ycm_extra_conf.py")
;; (add-hook 'c++-mode-hook 'ycmd-mode)
;; (add-hook 'c++-mode-hook 'flycheck-ycmd-setup)
;; (add-hook 'c++-mode-hook 'company-ycmd-setup)
;; (add-hook 'c++-mode-hook 'function-args-mode)
(add-hook 'c++-mode-hook 'irony-mode)
(add-hook 'irony-mode-hook 'irony-cdb-autosetup-compile-options)
(add-hook 'flycheck-mode-hook #'flycheck-irony-setup)
;; (add-hook 'flycheck-mode-hook #'flycheck-clang-tidy-setup)
;; (add-hook 'flycheck-mode-hook #'flycheck-clang-analyzer-setup)
;; (add-hook 'c++-mode-hook #'flycheck-clang-check-setup)
(defun flycheck-clang-check-setup ()
(setq flycheck-clangcheck-extra-arg "-Wall -std=c++17 -x c++")
(flycheck-set-checker-executable 'c/c++-clangcheck "/usr/bin/clang-check-7")
(flycheck-clang-analyzer-setup))
(setq c-default-style "linux")
(setq c-basic-offset 4)
(setq tab-width 4)
(setq indent-tabs-mode t)
(setq c-noise-macro-names '("constexpr"))
;; (c-set-offset 'substatement-open 0)
;; (c-set-offset 'inline-open '0)
(defun vlad-cc-style()
(c-set-style "linux")
(setq c-basic-offset 4)
(setq tab-width 4)
(setq indent-tabs-mode nil)
(c-set-offset 'innamespace '0)
(c-set-offset 'inextern-lang '0)
(c-set-offset 'inline-open '0)
(c-set-offset 'label '*)
(c-set-offset 'arglist-intro '+)
(c-set-offset 'arglist-close 0)
(c-set-offset 'case-label '*)
(c-set-offset 'access-label '/)
(c-set-offset 'inlambda 0)
(c-set-offset 'arglist-cont-nonempty 0)
(c-set-offset 'lambda-intro-cont 0)
(c-set-offset 'brace-list-open 0)
(c-set-offset 'brace-list-close 0)
(c-set-offset 'brace-list-intro '+))
(add-hook 'c++-mode-hook 'vlad-cc-style)
(add-hook 'c++-mode-hook (lambda () (setq sp-escape-quotes-after-insert nil)))
(setq gdb-many-windows nil)
(defun set-gdb-layout(&optional c-buffer)
(if (not c-buffer)
(setq c-buffer (window-buffer (selected-window)))) ;; save current buffer
;; from http://stackoverflow.com/q/39762833/846686
(set-window-dedicated-p (selected-window) nil) ;; unset dedicate state if needed
(switch-to-buffer gud-comint-buffer)
(delete-other-windows) ;; clean all
(let* (
(w-source (selected-window)) ;; left top
(w-gdb (split-window w-source nil 'right)) ;; right bottom
(w-locals (split-window w-gdb nil 'above)) ;; right middle bottom
(w-stack (split-window w-locals nil 'above)) ;; right middle top
(w-breakpoints (split-window w-stack nil 'above)) ;; right top
(w-io (split-window w-source (floor(* 0.9 (window-body-height)))
'below)) ;; left bottom
)
(set-window-buffer w-io (gdb-get-buffer-create 'gdb-inferior-io))
(set-window-dedicated-p w-io t)
(set-window-buffer w-breakpoints (gdb-get-buffer-create 'gdb-breakpoints-buffer))
(set-window-dedicated-p w-breakpoints t)
(set-window-buffer w-locals (gdb-get-buffer-create 'gdb-locals-buffer))
(set-window-dedicated-p w-locals t)
(set-window-buffer w-stack (gdb-get-buffer-create 'gdb-stack-buffer))
(set-window-dedicated-p w-stack t)
(set-window-buffer w-gdb gud-comint-buffer)
(select-window w-source)
(set-window-buffer w-source c-buffer)
))
(defadvice gdb (around args activate)
"Change the way to gdb works."
(setq global-config-editing (current-window-configuration)) ;; to restore: (set-window-configuration c-editing)
(let (
(c-buffer (window-buffer (selected-window))) ;; save current buffer
)
ad-do-it
(set-gdb-layout c-buffer))
)
(defadvice gdb-reset (around args activate)
"Change the way to gdb exit."
ad-do-it
(set-window-configuration global-config-editing))
(defun generate-tags-and-classes ()
"Documentation."
(interactive)
(if (projectile-project-root)
(progn
(if (not (file-exists-p (concat (projectile-project-root) "BROWSE")))
(shell-command-to-string (format "find %s -name '*.cpp' -o -name '*.hpp' | ebrowse -o '%s/BROWSE'" (projectile-project-root) (projectile-project-root))))
(if (not (file-exists-p (concat (projectile-project-root) "TAGS")))
(shell-command-to-string (format "find %s -name '*.cpp' -o -name '*.hpp' | xargs etags --append -o '%s/TAGS'" (projectile-project-root) (projectile-project-root)))))
(progn
(message "Currently not in project!"))))
;; (add-hook 'c++-mode-hook 'function-args-mode)
(bind-key* "M-j l" 'clang-format)
(bind-key* "C-c ." 'xref-find-definitions 'c++-mode-map)
;; (load-if-present "/home/arnaud/.emacs.d/lisp/tempo.el")
;; (load-if-present "/home/arnaud/.emacs.d/lisp/xml-parse.el")
;; (load-if-present "/home/arnaud/.emacs.d/lisp/doxymacs.el")
;; (when (require 'doxymacs nil t)
;; (setq doxymacs-doxygen-style "JavaDoc")
;; (setq doxymacs-use-external-xml-parser 't)
;; (add-hook 'c-mode-common-hook 'doxymacs-mode)
;; (add-hook 'c-mode-common-hook 'doxymacs-mode)
;; (defun my-doxymacs-font-lock-hook ()
;; (if (or (eq major-mode 'c-mode) (eq major-mode 'c++-mode))
;; (doxymacs-font-lock)))
;; (add-hook 'font-lock-mode-hook 'my-doxymacs-font-lock-hook))
(bind-key* "M-j o o" 'doxymacs-insert-function-comment)
(bind-key* "M-j o m" 'doxymacs-insert-member-comment)
(bind-key* "M-j o f" 'doxymacs-insert-file-comment)
(bind-key* "M-j o l" 'doxymacs-insert-blank-singleline-comment)
(bind-key* "M-j o b" 'doxymacs-insert-blank-multiline-comment)
(bind-key* "M-j o c" 'doxymacs-insert-command)
A minimal Cmake setup, more or less to make my CMakeLists.txt files pleasant to the eyes. I don’t really need more as I don’t spend that much time writing cmake scripts.
(require 'cmake-mode)
(require 'cmake-project)
(autoload 'cmake-font-lock-activate "cmake-font-lock" nil t)
(add-hook 'cmake-mode-hook 'cmake-font-lock-activate)
(setq cmake-tab-width 4)
(setq auto-mode-alist
(append '(("CMakeLists.txt\\'" . cmake-mode)
("\\.cmake\\'" . cmake-mode))
auto-mode-alist))
(defun maybe-cmake-project-hook ()
(if (file-exists-p "CMakeLists.txt") (cmake-project-mode)))
(add-hook 'c-mode-hook 'maybe-cmake-project-hook)
(add-hook 'c++-mode-hook 'maybe-cmake-project-hook)
I use Python a lot these days. Yet, my python setup in Emacs is less than minimal. I don’t know what to say to you. I guess Emacs is that good with python by default.
Myeah, that was a lie from the past. My python setup has evolved since then. I use quite a few packages that transform my Emacs into fully fledged python IDE.
(require 'anaconda-mode)
(require 'py-yapf)
(require 'pip-requirements)
(require 'sphinx-doc)
(require 'elpy)
(add-to-list 'auto-mode-alist '("\\.py\\'" . python-mode))
(add-to-list 'auto-mode-alist '("\\requirements.txt\\'" . pip-requirements-mode))
(setq elpy-rpc-backend "jedi")
(setq jedi:setup-keys t)
(setq jedi:complete-on-dot t)
(setq jedi:tooltip-method nil)
(setq jedi:get-in-function-call-delay 0)
(setq elpy-company-add-completion-from-shell t)
(setq python-shell-interpreter "python")
(setq python-shell-interpreter-args "-i")
; move quick-help tooltips to the minibuffer
(setq jedi:tooltip-method nil)
; disable all auto-completion unless explicitly invoked with M-tab
(setq ac-auto-show-menu nil)
(setq ac-auto-start nil)
;;
(add-hook 'python-mode-hook 'jedi:setup)
;; (add-hook 'python-mode-hook 'jedi:ac-setup)
;; (add-hook 'python-mode-hook 'elpy-mode)
(add-hook 'python-mode-hook 'sphinx-doc-mode)
(add-hook 'jedi-mode-hook (lambda () (global-auto-complete-mode -1)))
(define-key elpy-mode-map [remap elpy-nav-forward-block] nil)
(define-key elpy-mode-map [remap elpy-nav-backward-block] nil)
(define-key elpy-mode-map [remap elpy-nav-backward-indent] nil)
(define-key elpy-mode-map [remap elpy-nav-forward-indent] nil)
(bind-key* "M-j e d" 'sphinx-doc)
(bind-key* "M-j e t" 'elpy-test)
(bind-key* "M-j e f" 'elpy-format-code)
(bind-key* "M-." 'elpy-goto-definition python-mode-map)
;; (bind-key* "M-TAB" 'auto-complete)
I don’t really use EMACS for java development as it can be tedious and the packages are not really on part with some other modern IDEs (like Netbeans ;) ). Still, I do have some basic setup for meghanada
to make my life easier if I have to edit some java program really quick through emacs.
(require 'meghanada)
(add-hook 'java-mode-hook
(lambda ()
;; (meghanada-mode t)
(flycheck-mode +1)
(setq c-basic-offset 2)
(add-hook 'before-save-hook 'meghanada-code-beautify-before-save)))
(cond
((eq system-type 'windows-nt)
(setq meghanada-java-path (expand-file-name "bin/java.exe" (getenv "JAVA_HOME")))
(setq meghanada-maven-path "mvn.cmd"))
(t
(setq meghanada-java-path "java")
(setq meghanada-maven-path "mvn")))
From time to time I have to write HTML and other ‘web-stuff’ and this setup gets me by. It’s not really sophisticated and complex but.... come on, it web-programming…no offense. There are a lot Key bindings that come with web-mode
that I don’t really know, mostly because I don’t use it that much but if you do, be sure to check them out.
- emmet-mode -
C-j
Expands the emmet code given the minor mode is active
(require 'web-mode)
(require 'emmet-mode)
(defun my-web-mode-hook ()
(emmet-mode 1)
(setq web-mode-markup-indent-offset 2)
(setq web-mode-css-indent-offset 2)
(setq web-mode-code-indent-offset 2)
(setq web-mode-style-padding 1)
(setq web-mode-script-padding 1)
(setq web-mode-block-padding 0)
(setq web-mode-markup-indent-offset 2)
(setq web-mode-extra-auto-pairs '(("erb" . (("beg" "end")))
("php" . (("beg" "end")
("beg" "end")))))
(setq web-mode-enable-auto-pairing t)
(setq web-mode-enable-current-column-highlight t)
(setq web-mode-ac-sources-alist '(("css" . (ac-source-css-property))
("html" . (ac-source-words-in-buffer ac-source-abbrev)))))
(add-to-list 'auto-mode-alist '("\\.html\\'" . web-mode))
(add-to-list 'auto-mode-alist '("\\.tpl\\.php\\'" . web-mode))
(add-to-list 'auto-mode-alist '("\\.[agj]sp\\'" . web-mode))
(add-to-list 'auto-mode-alist '("\\.as[cp]x\\'" . web-mode))
(add-to-list 'auto-mode-alist '("\\.erb\\'" . web-mode))
(add-to-list 'auto-mode-alist '("\\.mustache\\'" . web-mode))
(add-to-list 'auto-mode-alist '("\\.djhtml\\'" . web-mode))
(add-to-list 'auto-mode-alist '("\\.api\\'" . web-mode))
(add-to-list 'auto-mode-alist '("/some/react/path/.*\\.js[x]?\\'" . web-mode))
(add-to-list 'auto-mode-alist '("\\.html?\\'" . web-mode))
(add-hook 'web-mode-hook 'my-web-mode-hook)
;; (require 'multi-web-mode)
;; (setq mweb-default-major-mode 'web-mode)
;; (setq mweb-tags '((js-mode "<script *>" "</script>")
;; (css-mode "<style *>" "</style>")))
;; (add-to-list 'auto-mode-alist '("\\.vue\\'" . multi-web-mode))
One of the most useful packages that is pretty much a must for a emacs configuration. The package provides a whole bunch of very handy snippets for code/text/structures in almost all major modes of emacs. The default prefix for some of the yas functions is C-c &
but this really doesn’t work for me. Therefore I’ve defined custom keybindings for the important functions. Also, I write a lot in c++, so I often found myself in the situation where I first expand a std::vector
and then I want to give it a type of std::sting
. Stacked snippets are my best friend when it comes to this problem.
(require 'yasnippet)
(require 'yasnippet-snippets)
(require 'helm-c-yasnippet)
(setq yas-snippet-dirs '())
(setq yas-snippet-dirs `(,(concat user-emacs-directory "snippets")))
(yas-global-mode 1)
(setq helm-yas-space-match-any-greedy t)
(setq yas-triggers-in-field t)
(bind-key* "C-c y n" 'yas/new-snippet)
(bind-key* "C-c y v" 'yas/visit-snippet-file)
(bind-key* "C-c y r" 'yas/reload-all)
(bind-key* "C-<tab>" 'helm-yas-complete)
Syntax error-checking on the fly (haha!) while working on code. It’s convenient to avoid small errors that screw up your compilation and are just being anoying.
(require 'flycheck)
(global-flycheck-mode t)
When writing code I lot of times I mark the things I’ve just typed and hit Tab to indent it properly. This packages help me not to do that so often as it indents things right before your eyes in the moment you write them. It gets annoying at times but you get used to it pretty quickly.
(require 'aggressive-indent)
(global-aggressive-indent-mode 1)
(add-to-list 'aggressive-indent-excluded-modes 'html-mode)
(add-to-list
'aggressive-indent-dont-indent-if
'(and (derived-mode-p 'c++-mode)
(null (string-match "\\([;{}]\\|\\b\\(if\\|for\\|while\\)\\b\\)"
(thing-at-point 'line)))))
(bind-key* "M-j j b" 'json-pretty-print-buffer)
(bind-key* "M-j j r" 'json-pretty-print)
(define-skeleton c++-basic-skeleton
""
""
"#inlcude <iostream>
#include <string>
#include <vector>
#include <unordered_map>
int main(int argc, char *argv[])
{
std::cout << \"Starting the program\" << \"\\n\";
return 0;
}")
(define-skeleton python-basic-skeleton
""
""
"\#!\/usr\/bin\/python
import sys
import os
import json
def main():
print(\"The program works\")
if __name__ == \'__main__\':
main()")
(define-skeleton json-basic-skeleton
""
""
"{
\"field_1\": \"value\",
\"field_2\": {
\"field_3\": \"value\"
}
}")
(define-skeleton org-basic-skeleton
""
""
"#+OPTIONS: ':t *:t -:t ::t <:t H:3 \\n:nil ^:t arch:headline author:t
#+OPTIONS: broken-links:nil c:nil creator:nil d:(not \"LOGBOOK\")
#+OPTIONS: date:t e:t email:nil f:t inline:t num:t p:nil pri:nil
#+OPTIONS: prop:nil stat:t tags:t tasks:t tex:t timestamp:t title:t
#+OPTIONS: toc:t todo:t |:t
#+TITLE: Title
#+AUTHOR: Stanislav Arnaudov
#+EMAIL: arnaud@localhost
#+LANGUAGE: en
#+SELECT_TAGS: export
#+EXCLUDE_TAGS: noexport
#+CREATOR: Emacs 26.1 (Org mode 9.1.13)
\* Title 1
\* Title 2")
(defmacro buffer-from-template (name macro mode)
""
`(let ((new-buff (generate-new-buffer ,name)))
(switch-to-buffer new-buff)
(,macro)
(,mode)))
(bind-key* "C-c 2" '@(buffer-from-template "*c++*" c++-basic-skeleton c++-mode))
(bind-key* "C-c 3" '@(buffer-from-template "*python*" python-basic-skeleton python-mode))
(bind-key* "C-c 4" '@(buffer-from-template "*json*" json-basic-skeleton json-mode))
(bind-key* "C-c 5" '@(buffer-from-template "*org*" org-basic-skeleton org-mode))
(require 'quickrun)
(defun my/quickrun-hook ()
(goto-char (point-min)))
(add-hook 'quickrun-after-run-hook 'my/quickrun-hook)
(quickrun-add-command "c++/warnings"
'((:command . "g++")
(:exec . (
"%c -std=c++17 -Wall -Wextra -Wshadow -Wnon-virtual-dtor -pedantic %o -o %e %s" "%e %a"))
(:remove . ("%e"))
(:description "Compile C++ file with g++ and all of the warnings."))
:default "c++")
(quickrun-add-command "simple-python-run"
'((:command . "python")
(:exec . ("%c %s"))
(:description "")
(:timeout . 42))
:default "python")
(quickrun-add-command "python/virtualenv"
'((:command . "python_virt")
(:exec . (
"/usr/bin/env python %s"))
(:description "Run python with virtual env"))
:default "python")
(quickrun-add-command "go/run"
'((:command . "go_run")
(:exec . (
"/usr/bin/env go run %s"))
(:description "Run the file with go run"))
:default "go")
(quickrun-add-command "alisp/run"
'((:command . "alisp")
(:exec . (
"/usr/bin/env alisp %s"))
(:description "Run the file with alisp"))
:mode 'emacs-lisp-mode
:default "emacs-lisp")
(bind-key* "M-j r h" 'helm-quickrun)
(bind-key* "M-j r r" 'quickrun-with-arg)
(bind-key* "<f7>" 'quickrun)
(require 'lsp-mode)
(add-to-list 'auto-mode-alist '("\\.al\\'" . emacs-lisp-mode))
(require 'lsp)
(require 'lsp-mode)
(setq go-mode-hook '())
(add-hook 'go-mode-hook
(lambda ()
;; (add-hook 'before-save-hook 'gofmt-before-save)
(setq tab-width 4)
(setq indent-tabs-mode 1)
(setq lsp-gopls-staticcheck t)
(setq lsp-eldoc-render-all t)
(setq lsp-gopls-complete-unimported t)
(local-set-key (kbd "M-.") 'godef-jump)
(local-set-key (kbd "M-*") 'pop-tag-mark)))
(lsp-register-client
(make-lsp-client :new-connection (lsp-stdio-connection "gopls")
:major-modes '(go-mode)
:server-id 'gopls))
(bind-key* "C-x M-e" 'eval-defun)
(define-key python-mode-map (kbd "C-c x") (lambda () (interactive) (insert "import pdb; pdb.set_trace()")))
;; (global-set-key (kbd "C-c j") "your text here")
Another ‘standard feature’ of most editors but in emacs we have to set it up because this is how we roll. This is just moving the selected block up and down while holding Alt
(require 'drag-stuff)
(drag-stuff-global-mode)
(bind-key* "M-<up>" 'drag-stuff-up)
(bind-key* "M-<down>" 'drag-stuff-down)
Not exactly what the heading suggests but I’ve recently learned some vim keybindings and my god those get things done fast. Emacs is kind of lacking on this end, but you know what they say
Emacs is a nice Operating System but it lacks decent editor — Someone big in the Emacs Community
This package adds some handy functionality to M-w
. Basically, after the initial command, through key strokes one can select very precisely-ish what is to be put in the kill ring. You can for example hit M-w
once to “select” the current region but then press w
again to select the current word. After that you can continue pressing w
to select one more word.
(require 'easy-kill)
(define-key my-keys-mode-map [remap kill-ring-save] 'easy-kill)
Yeso, I am a hirroble horrible speller. Thank god that there are tools that help me live my miserable uneducated life. I often have to write in german too so I have custom dictionary switching key-binding. Other than that, I find C-c s
to be most intuitive for correcting misspelled words. flyspell-popup is a handy little thing that is pretty much company for showing a list of possible correct words. The mode can be swithed on and off with C-<f8>
flyspell-popup
(require 'flyspell)
(define-key flyspell-mode-map (kbd "C-c s") #'flyspell-popup-correct)
(bind-key* "<f8>" 'fd-switch-dictionary)
(bind-key* "C-<f8>" 'flyspell-mode)
As previously stated, I know tiny bit of vim key-bindings and holy cow those can do a lot of things in very few keystrokes. Emacs is not really like that. I’ve written some simple functions thal with saving, marking and killing /sexp/s. I really like that feature of vim ”d*elete *i*nside *(-block” and it kills everything inside the parentesies....or copies it into kill ring or marks it, basically - it’s pretty awesome and here I am trying to ripp off exxaclty that.
The commands that come in handy in a lot of the times are:
Keystroke | Description |
---|---|
C-M-k | Kill erverything inside the current sexp |
C-M-K | Kill the current sexp and the |
C-M-SPC | Mark erverything inside the current sexp |
C-M-S-SPC | Mar the current sexp |
C-M-w | Save everything inside the current sexp into kill ring |
C-M-W | Save the current sexp into kill ring |
C-c w i | Mark inside thing |
C-c w o | Mark outside thing |
As you’ve probably noticed C-M
in like kind of a prefix for all sexp-operations. The last two commands will first prompt you for character and will then mark the right region closed in the symbol. If the entered symbol is a bracket, the marked region will be between the corresponding brackets (just like in Vim).
;; (require 'load-directory)
;; (load-directory "~/.emacs.d/my-lisp")
(load-if-present "~/.emacs.d/lisp/vsexp.el")
(when (require 'vsexp nil t)
(bind-key* "C-M-y" 'sp-backward-up-sexp)
(bind-key* "C-M-x" 'sp-up-sexp)
(bind-key* "C-M-SPC" 'vsexp-mark-sexp)
(bind-key* "C-M-k" 'vsexp-kill-sexp)
(bind-key* "C-M-S-SPC" 'vsexp-mark-sexp-whole)
(bind-key* "C-M-S-k" 'vsexp-kill-sexp-whole)
(bind-key* "C-M-w" 'vsexp-kill-save-sexp)
(bind-key* "C-M-S-w" 'vsexp-kill-save-sexp-whole)
(bind-key* "C-c w i" 'vsexp-mark-inside)
(bind-key* "C-c w o" 'vsexp-mark-outside))
(require 'multiple-cursors)
(define-key mc/keymap (kbd "<return>") nil)
(global-set-key (kbd "C-S-c C-S-c") 'mc/edit-lines)
(global-set-key (kbd "C->") 'mc/mark-next-like-this)
(global-set-key (kbd "C-<") 'mc/mark-previous-like-this)
(global-set-key (kbd "C-c C-<") 'mc/mark-all-like-this)
(global-set-key (kbd "C-\"") 'mc/skip-to-next-like-this)
(global-set-key (kbd "C-:") 'mc/skip-to-previous-like-this)
Extensions/Applications/Packages for Emacs that just plainly do by life easier. The key to getting the job done in an effective manner in having the right tools for it. And you know the Emacs philosophy… “Put everything in your editor!”
;;(require 'undo-tree)
;; (bind-key* "C-x u" 'undo-tree-visualize)
The de-facto standard for project management for emacs. Not sure if I utilize half of its functionality but this file searching and opening…man that feels good when putting it to use. When in a project(which is just a git-repo btw) just type C-c p f
and be blown away. When you we helm with projectile, we pretty much get one of the most powerful features in the history of IDEs ever. Some of my relevant keybindings include:
f4
- switch to other file. For working with .cpp and .hpp filesC-c p f
for finding files the easiest way possible.C-c p d
for finding directories the easiest way possible.M-s
helm-projectile-grep - really cool for searching a phrase of something in a entire projectC-c p 4 f
- find file and open it in another windowC-c p F
- find file in all known projectsC-c p 4 F
find file in all known projects and open it in another windowC-c p e
- see recent filesC-c p x s
run shell at the root of the projectC-c p S
save all files of the current project
Get it here -> PROJECTILE!!!
(require 'projectile)
(setq projectile-completion-system 'helm)
(setq projectile-project-search-path '("/home/arnaud/code" "/home/arnaud/code_ext" "/home/arnaud/code_sys" ))
(setq projectile-indexing-method 'native)
(setq projectile-enable-caching t)
(define-key projectile-mode-map (kbd "C-c p") 'projectile-command-map)
(projectile-mode)
My tree browser of choice. Was blown away when I found that emacs has the ability to pull of something like tree browser. This was probably the functionality that showed me that emacs can be a substitute for every other IDE/text editor(on which the hippsters web-developers write their ‘web-apps’)
;; (load-file "/home/arnaud/core.d/code/all-the-icons.el/all-the-icons.el")
;; (load-file "/home/arnaud/core.d/code/all-the-icons.el/all-the-icons-faces.el")
;; (load-file "/home/arnaud/code_sys/emacs-neotree-fork/neotree.el")
(require 'neotree)
(require 'all-the-icons)
(add-hook 'neo-after-create-hook
#'(lambda (_)
(with-current-buffer (get-buffer neo-buffer-name)
(setq truncate-lines t)
(setq word-wrap nil)
(make-local-variable 'auto-hscroll-mode)
(setq auto-hscroll-mode nil))))
;;(advice-add 'display-graphic-p :override (lambda () t))
(setq neo-theme 'icons)
(defun neotree-project-dir ()
"Open NeoTree using the projectile."
(interactive)
(let ((project-dir (projectile-project-root))
(file-name (buffer-file-name)))
(neotree-toggle)
(if project-dir
(if (neo-global--window-exists-p)
(progn
(neotree-dir project-dir)
(neotree-find file-name)))
(message "Could not find vc project root."))))
(bind-key* "<f1>" 'neotree-toggle)
(bind-key* "C-<f1>" 'neotree-project-dir)
(bind-key* "<f2>" 'neotree-find)
(setq neo-model-line-type 'none)
(setq neo-window-width 40)
(setq neo-window-fixed-size nil)
;; (setq neo-theme (if (display-graphic-p) 'icons 'arrow))
(setq neo-show-hidden-files t)
;;(setq projectile-switch-project-action 'neotree-projectile-action)
(setq neo-theme 'icons)
(setq neo-hidden-regexp-list (quote ("^\\." "\\.pyc$" "~$" "^#.*#$" "\\.elc$" "\\.o$" "__pycache__")))
(face-spec-set 'neo-button-face '((t (:foreground "gold" :underline nil))))
(face-spec-set 'neo-button-face '((t (:inherit bold :foreground "#268bd2" :underline t :height 1.1 :width semi-condensed))))
(face-spec-set 'neo-file-link-face '((t (:foreground "light sky blue"))))
(face-spec-set 'neo-open-dir-link-face '((t (:foreground "gold" :underline t :height 1.1))))
(face-spec-set 'neo-dir-link-face '((t (:underline t :height 1.1))))
(face-spec-set 'neo-dir-icon-face '((t (:foreground "light sky blue"))))
(face-spec-set 'neo-open-dir-icon-face '((t (:foreground "gold"))))
The best and the most fully fledged completion engine for emacs IMO. I cannot be productive in my emacs without this. When you are in minibuffer and start typing, things just appear as you type, you can select multiple items, perform actions on all of the (example: open multiple files with single C-x C-f
) and many more features that I should probably use on more regular basis.
(require 'helm)
(require 'helm-config)
(setq helm-split-window-in-side-p t ; open helm buffer inside current window, not occupy whole other window
helm-move-to-line-cycle-in-source t ; move to end or beginning of source when reaching top or bottom of source.
helm-ff-search-library-in-sexp t ; search for library in `require' and `declare-function' sexp.
helm-scroll-amount 8 ; scroll 8 lines other window using M-<next>/M-<prior>
helm-ff-file-name-history-use-recentf t
helm-echo-input-in-header-line t)
(setq helm-buffers-fuzzy-matching t
helm-recentf-fuzzy-match t)
(setq helm-semantic-fuzzy-match t
helm-imenu-fuzzy-match t)
(setq helm-M-x-fuzzy-match t)
(setq helm-exit-idle-delay 0)
(setq helm-ag-fuzzy-match t)
(setq helm-autoresize-max-height 0)
(setq helm-autoresize-min-height 50)
(helm-mode 1)
;; (helm-autoresize-mode 1)
This will keep the buffers listed in the helm-mini menu neatly organized.
(defclass tohiko/helm-source-file-buffers (helm-source-buffers)
((candidate-transformer :initform (lambda (buffers)
(cl-loop for buf in buffers
when (with-current-buffer
buf buffer-file-name)
collect buf)))))
(defclass tohiko/helm-source-nonfile-buffers (helm-source-buffers)
((candidate-transformer :initform (lambda (buffers)
(cl-loop for buf in buffers
unless (with-current-buffer
buf buffer-file-name)
collect buf)))))
(setq tohiko/helm-source-file-buffers-list
(helm-make-source "File Buffers" 'tohiko/helm-source-file-buffers))
(setq tohiko/helm-source-nonfile-buffers-list
(helm-make-source "Non-file Buffers" 'tohiko/helm-source-nonfile-buffers))
(setq helm-mini-default-sources '(tohiko/helm-source-file-buffers-list
tohiko/helm-source-nonfile-buffers-list
helm-source-recentf
helm-source-buffer-not-found))
(customize-set-variable 'helm-ff-lynx-style-map t)
(bind-key* "C-x C-f" 'helm-find-files)
(bind-key* "M-x" 'helm-M-x)
(bind-key* "C-x b" 'helm-mini)
(bind-key* "C-c b" 'helm-semantic-or-imenu)
(bind-key* "M-s" 'helm-projectile-ag)
(bind-key* "C-x c C-a" 'helm-apt)
(bind-key* "C-x c M-m" 'helm-complete-file-name-at-point)
(bind-key* "C-x c C-s" 'helm-occur-from-isearch)
(bind-key* "C-x r h" 'helm-register)
(bind-key* "C-x c k" 'helm-execute-kmacro)
(bind-key* "M-y" 'helm-show-kill-ring)
This package makes your C-x C-b
(list-buffers) pretty. You can even specify custom sections where the buffers are to be put depending on certain conditions - name, mode, etc. There is also projectile integration but I don’t find that very useful. I like the buffers grouped in small more groups.
(require 'ibuffer)
(require 'ibuffer-projectile)
(setq ibuffer-expert t)
(setq ibuffer-show-empty-filter-groups nil)
(setq ibuffer-saved-filter-groups
'(("home"
("Emacs-config" (or (filename . ".emacs")
(filename . "myinit.org")))
("Org" (or (mode . org-mode)
(filename . "OrgMode")))
("C++"
(or
(mode . c-mode)
(mode . c++-mode)
))
("Go"
(or
(mode . c-mode)
(mode . c++-mode)
))
("Python"
(mode . python-mode)
)
("Configurations"
(or
(mode . conf-mode)
(mode . conf-space-mode)
(name . ".json")
(name . ".yaml")
(name . ".yml")
))
("Source Code"
(or
(mode . emacs-lisp-mode)
(mode . shell-script-mode)
(mode . json-mode)
))
("Dired"
(mode . dired-mode))
("Sripts"
(name . ".sh")
)
("Documents"
(mode . doctex-mode)
)
("LaTeX"
(or
(mode . tex-mode)
(mode . latex-mode)
(name . ".tex")
(name . ".bib")))
("4Chan"
(mode . q4))
("Text" (name . ".txt"))
("JS"
(or (mode . "JavaScript")
(name . ".js")
(mode . javascript-mode)))
("Web Dev" (or (mode . html-mode)
(mode . css-mode)
(mode . webmode-mode)))
("Emacs-created"
(or
(name . "^\\*")))
)))
(define-ibuffer-column size-h
(:name "Size" :inline t)
(cond
((> (buffer-size) 1000000) (format "%7.1fM" (/ (buffer-size) 1000000.0)))
((> (buffer-size) 100000) (format "%7.0fk" (/ (buffer-size) 1000.0)))
((> (buffer-size) 1000) (format "%7.1fk" (/ (buffer-size) 1000.0)))
(t (format "%8d" (buffer-size)))))
(setq ibuffer-formats
'((mark modified read-only " "
(name 18 18 :left :elide)
" "
(size-h 9 -1 :right)
" "
(mode 16 16 :left :elide)
" "
filename-and-process)))
(add-hook 'ibuffer-mode-hook
'(lambda ()
(ibuffer-auto-mode 1)
(ibuffer-switch-to-saved-filter-groups "home")))
(defadvice ibuffer-update-title-and-summary (after remove-column-titles)
(with-current-buffer "*Ibuffer*"
(read-only-mode 1)
(goto-char 1)
(search-forward "-\n" nil t)
(delete-region 1 (point))
(let ((window-min-height 1))
(shrink-window-if-larger-than-buffer))
(read-only-mode)))
(ad-activate 'ibuffer-update-title-and-summary)
(bind-key* "C-x C-b" 'ibuffer)
(require 'magit)
;; Open magit window full-screen
(setq magit-display-buffer-function #'magit-display-buffer-fullframe-status-v1)
;; When calling magit-status, save all buffers without further ado
(setq magit-save-repository-buffers 'dontask)
;; Anything longer will be highlighted
(setq git-commit-summary-max-length 70)
(setq magit-commit-show-diff t)
(setq magit-status-sections-hook '(
;;magit-insert-status-headers
magit-insert-unstaged-changes
magit-insert-staged-changes
magit-insert-untracked-files
magit-insert-merge-log
magit-insert-rebase-sequence magit-insert-am-sequence
magit-insert-sequencer-sequence magit-insert-bisect-output
magit-insert-bisect-rest magit-insert-bisect-log
magit-insert-stashes
magit-insert-unpulled-from-upstream
magit-insert-unpulled-from-pushremote
magit-insert-unpushed-to-upstream
magit-insert-unpushed-to-pushremote))
;; make [MASTER] appear at the end of the summary line
(setq magit-log-show-refname-after-summary t)
(defun my-magit-browse-github ()
"Browse to the project's github URL, if available"
(interactive)
(let ((url (with-temp-buffer
(unless (zerop (call-process-shell-command
"git remote -v" nil t))
(error "Failed: 'git remote -v'"))
(goto-char (point-min))
(when (re-search-forward
"github\\.com[:/]\\(.+?\\)\\.git" nil t)
(format "https://github.com/%s" (match-string 1))))))
(unless url
(error "Can't find repository URL"))
(browse-url url))
(with-temp-buffer
(insert "bind_raise_or_run_web()")
(call-process-region (point-min) (point-max) "awesome-client" t)))
(setq magit-repository-directories
'(
("~/code" . 1)
("~/code_ext/" . 1))
magit-repolist-columns
'(
("Name" 25 magit-repolist-column-ident nil)
("Version" 25 magit-repolist-column-version nil)
("Push" 4 magit-repolist-column-unpushed-to-upstream (:right-align t))
("Path" 99 magit-repolist-column-path)))
(bind-key* "M-j m g" 'my-magit-browse-github magit-mode-map)
(bind-key* "M-j m l" 'magit-list-repositories)
(bind-key* "M-j m s" 'magit-status)
(bind-key* "M-j m c" 'magit-commit)
(bind-key* "M-j m i" 'magit-init)
(bind-key* "M-j m C" 'magit-checkout-file)
(bind-key* "M-j m M-c" 'magit-checkout)
(bind-key* "M-j m p" 'magit-push)
;; (bind-key "q" 'my--kill-buffer-and-window magit-mode-map)
Hydra is a package that allows you to create hydras. Those are like munues with keybindings that popout on the bottom of the buffer and prompt you to type one(or more) of the listed keybindings. This provides really cool way of structuring commands in a menu-like fashion. There are some predifined hydras that come with the package but those are not that good and therefore I’ve ‘borrowed’ a few from the mighty internet.
C-c h
is like the prefix for all my hydras. After that comes another letter (or C-letter) that selects the desired hydra.
Keybinding | Hydra |
---|---|
<prefix> b | Bookmarks |
<prefix> r | Rectangle |
<prefix> R | Registers |
<prefix> C-o m | Org Tress movement |
<prefix> C-o t | Org Templates |
<prefix> f | Formating |
<prefix> p | Projectile |
<prefix> M | Modes |
<prefix> m | Magit |
<prefix> F | Files |
There is also a ‘special’ Hydra that lists all other hydras and it’s bound to C-c h h
(require 'hydra)
(require 'hydra-examples)
(defhydra arnaud-hydra-windowing (:color blue
:hint nil)
"
^Ace-window^ ^^
^^^^------------------------------------------------------------------
^ _s_: Select window^ ^ _o_: Ace^
^ _d_: Delete window^
^ _m_: Maximize window^
^ _c_: Close other windows^
^ _t_: Transpose windows^
"
("s" ace-select-window)
("d" ace-delete-window)
("m" ace-maximize-window)
("c" ace-delete-other-windows)
("t" ace-swap-windows)
("o" ace-window)
("q" nil :color blue))
(bind-key* "C-c h w" 'arnaud-hydra-windowing/body)
(defhydra arnaud-hydra-bookmarks (:color blue
:hint nil)
"
_s_: set _b_: bookmark _j_: jump _d_: delete _q_: quit
"
("s" bookmark-set)
("b" bookmark-save)
("j" bookmark-jump)
("d" bookmark-delete)
("q" nil :color blue))
(bind-key* "C-c h b" 'arnaud-hydra-bookmarks/body)
(defhydra arnaud-hydra-rectangle (:pre (rectangle-mark-mode 1)
:color blue
:hint nil)
"
_p_: paste _r_: replace _I_: insert
_y_: copy _o_: open _V_: reset
_d_: kill _n_: number _q_: quit
"
("h" backward-char nil)
("l" forward-char nil)
("k" previous-line nil)
("j" next-line nil)
("y" copy-rectangle-as-kill)
("d" kill-rectangle)
("x" clear-rectangle)
("o" open-rectangle)
("p" yank-rectangle)
("r" string-rectangle)
("n" rectangle-number-lines)
("I" string-insert-rectangle)
("V" (if (region-active-p)
(deactivate-mark)
(rectangle-mark-mode 1)) nil)
("q" keyboard-quit :color blue))
(bind-key* "C-c h r" 'arnaud-hydra-rectangle/body)
(defhydra arnaud-hydra-registers (:color blue
:hint nil)
"
_a_: append _c_: copy-to _j_: jump _r_: rectangle-copy _q_: quit
_i_: insert _n_: number-to _f_: frameset _w_: window-config
_+_: increment _p_: point-to _h_: helm-register
"
("a" append-to-register)
("c" copy-to-register)
("i" insert-register)
("f" frameset-to-register)
("j" jump-to-register)
("n" number-to-register)
("r" copy-rectangle-to-register)
("w" window-configuration-to-register)
("+" increment-register)
("p" point-to-register)
("h" helm-register)
("q" nil :color blue))
(bind-key* "C-c h R" 'arnaud-hydra-registers/body)
(defhydra arnaud-hydra-active-modes (:color red
:hint nil)
"
_b_: fancy battery _C-c_: flycheck _c_: company _j_: jedi
_l_: linenum _v_: visual-line _h_: hs-minor _g_: golden-ratio
_f_: flyspell _y_: yas _e_: emmet _f_: framer
_q_: quit
"
("b" fancy-battery-mode)
("l" global-nlinum-mode)
("f" flyspell-mode)
("C-c" global-flycheck-mode)
("v" visual-line-mode)
("y" yas-global-mode)
("c" company-mode)
("h" hs-minor-mode)
("e" emmet-mode)
("j" jedi-mode)
("g" golden-ratio-mode)
("f" global-framer-mode)
("q" nil :color blue))
(bind-key* "C-c h M" 'arnaud-hydra-active-modes/body)
(defhydra arnaud-hydra-org-organize (:color red
:hint nil)
"
^Meta^
^^--------------------------------------------------------------------
^ _<up>_ ^ _q_: quit
_<right>_ ^+^ _<left>_
^_<down>_^
"
("<left>" org-metaleft)
("<right>" org-metaright)
("<down>" org-metadown)
("<up>" org-metaup)
("q" nil :color blue))
(bind-key* "C-c h C-o m" 'arnaud-hydra-org-organize/body)
(defhydra arnaud-hydra-org-template (:color blue
:hint nil)
"
^One liners^ ^Blocks^ ^Properties^
--------------------------------------------------------------------------------------------------------------------------------------------------------
_a_: author _i_: interleave _D_: description _C_: center _p_: python src _n_: notes _d_: defaults _r_: properties _<_: insert '<'
_A_: date _l_: label _S_: subtitle _e_: elisp src _Q_: quote _L_: latex _I_: interleave _q_: quit
_c_: caption _N_: name _k_: keywords _E_: example _s_: src _x_: export _T_: drill two-sided
_f_: file tags _o_: options _M_: minted _h_: html _v_: verbatim _X_: noexport
_H_: latex header _t_: title _P_: publish _m_: matlab src _V_: verse
"
("a" (hot-expand "<a"))
("A" (hot-expand "<A"))
("c" (hot-expand "<c"))
("f" (hot-expand "<f"))
("H" (hot-expand "<H"))
("i" (hot-expand "<i"))
("I" (hot-expand "<I"))
("l" (hot-expand "<l"))
("n" (hot-expand "<n"))
("N" (hot-expand "<N"))
("P" (hot-expand "<P"))
("o" (hot-expand "<o"))
("t" (hot-expand "<t"))
("C" (hot-expand "<C"))
("D" (hot-expand "<D"))
("e" (hot-expand "<e"))
("E" (hot-expand "<E"))
("h" (hot-expand "<h"))
("k" (hot-expand "<k"))
("M" (hot-expand "<M"))
("m" (hot-expand "<m"))
("p" (hot-expand "<p"))
("Q" (hot-expand "<q"))
("s" (hot-expand "<s"))
("S" (hot-expand "<S"))
("v" (hot-expand "<v"))
("V" (hot-expand "<V"))
("x" (hot-expand "<x"))
("X" (hot-expand "<X"))
("d" (hot-expand "<d"))
("L" (hot-expand "<L"))
("r" (hot-expand "<r"))
("I" (hot-expand "<I"))
("T" (hot-expand "<T"))
("b" (hot-expand "<b"))
("<" self-insert-command)
("q" nil :color blue))
(bind-key* "C-c h C-o t" 'arnaud-hydra-org-template/body)
(defhydra arnaud-hydra-format (:color blue
:hint nil)
"
^Beautify^
^^^^^^^^^^--------------------------------------
_h_: html _c_: css _j_: js _q_: quit
_H_: html buf _C_: css buf _J_: js buf
_p_: py buf _P_: py on-sav
"
("h" web-beautify-html)
("H" web-beautify-html-buffer)
("c" web-beautify-css)
("C" web-beautify-css-buffer)
("j" web-beautify-js)
("J" web-beautify-js-buffer)
("p" py-yapf-buffer)
("P" py-yapf-enable-on-save)
("q" nil :color blue))
(bind-key* "C-c h f" 'arnaud-hydra-format/body)
(defhydra hydra-projectile-other-window (:color teal)
"projectile-other-window"
("f" projectile-find-file-other-window "file")
("g" projectile-find-file-dwim-other-window "file dwim")
("d" projectile-find-dir-other-window "dir")
("b" projectile-switch-to-buffer-other-window "buffer")
("q" nil "cancel" :color blue))
(defhydra arnaud-hydra-projectile (:color teal :hint nil)
"
PROJECTILE: %(projectile-project-root)
Find File Search/Tags Buffers Cache
------------------------------------------------------------------------------------------
_s-f_: file _a_: ag _i_: Ibuffer _c_: cache clear
_ff_: file dwim _g_: update gtags _b_: switch to buffer _x_: remove known project
_fd_: file curr dir _o_: multi-occur _s-k_: Kill all buffers _X_: cleanup non-existing
_r_: recent file ^^^^_z_: cache current
_d_: dir
"
("<ESC>" nil "quit")
("<" hydra-project/body "back")
("a" projectile-ag)
("b" projectile-switch-to-buffer)
("c" projectile-invalidate-cache)
("d" projectile-find-dir)
("s-f" projectile-find-file)
("ff" projectile-find-file-dwim)
("fd" projectile-find-file-in-directory)
("g" ggtags-update-tags)
("s-g" ggtags-update-tags)
("i" projectile-ibuffer)
("K" projectile-kill-buffers)
("s-k" projectile-kill-buffers)
("m" projectile-multi-occur)
("o" projectile-multi-occur)
("s-p" projectile-switch-project "switch project")
("p" projectile-switch-project)
("s" projectile-switch-project)
("r" projectile-recentf)
("x" projectile-remove-known-project)
("X" projectile-cleanup-known-projects)
("z" projectile-cache-current-file)
("`" hydra-projectile-other-window/body "other window" :color blue)
("q" nil "cancel" :color blue))
(bind-key* "C-c h p" 'arnaud-hydra-projectile/body)
(defhydra arnaud-hydra-magit (:color blue :hint nil)
"
Magit: %(magit-get \"remote\" \"origin\" \"url\")
^Status^ ^Remote^ ^Operations^
^^^^^^------------------------------------------------------------------------------------------
_s_: Status _f_: Pull _c_ : Commit
_l_: Log all _p_: Push _C-s_: Stage
_d_: Diff _C-c_: Clone _S_ : Stage modified
^^ ^^ ^_C-f_: Stage file^
^^ ^^ ^_M-f_: Unstage file^
"
("f" magit-pull)
("p" magit-push)
("c" magit-commit)
("C-c" magit-clone)
("d" magit-diff)
("l" magit-log-all )
("s" magit-status)
("C-s" magit-stage)
("C-f" magit-stage-file)
("M-f" magit-unstage-file)
("S" magit-stage-modified)
("q" nil "Cancel" :color blue))
(bind-key* "C-c h m" 'arnaud-hydra-magit/body)
(defhydra arnaud-hydra-files (:color teal :hint nil)
"
^^ ^Files^ ^^
^^^^^^------------------------------------------------------------------------
^_n_^ : Notes
^_t_^ : Todos
^_a_^ : About(Blog)
^_i_^ : Myinit
"
("n" (find-file "~/Dropbox/orgfiles/notes.org") )
("t" (find-file "~/Dropbox/orgfiles/todos/todos.org"))
("a" (find-file "~/code/palikar.github.io/org/about.org"))
("i" (find-file "~/code/dotfiles/.emacs.d/myinit.org"))
("q" nil "Cancel" :color blue))
(bind-key* "C-c h F" 'arnaud-hydra-files/body)
(defhydra arnaud-hydra-hydras (:color teal :hint nil)
"
^^ ^Available Hydras^ ^^
^^^^^^------------------------------------------------------------------------
^_w_^ : Windowing ^_R_^ : Registers ^_f_^ : Formating
^_b_^ : Bookmarks ^_M_ ^ : Modes ^_p_^ : Projectile
^_r_^ : Rectangle ^_C-o m_^ : Org treee move ^_m_^ : Magit
^_l_^ : LaTeX ^_C-o t_^ : Org templates ^_F_^ : Files
"
("w" arnaud-hydra-windowing/body)
("b" arnaud-hydra-bookmarks/body)
("r" arnaud-hydra-rectangle/body)
("R" arnaud-hydra-registers/body)
("M" arnaud-hydra-modes/body)
("C-o m" arnaud-hydra-org-organize/body)
("C-o t" arnaud-hydra-org-template/body)
("f" arnaud-hydra-formating/body)
("p" arnaud-hydra-projectile/body)
("m" arnaud-hydra-magit/body)
("l" arnaud-hydra-latex/body)
("F" arnaud-hydra-files/body)
("q" nil "Cancel" :color blue))
(bind-key* "C-c h h" 'arnaud-hydra-hydras/body)
IMenu is like that one thingy that nobody uses but its in almost every IDE. IMenu can create a buffer showing the “structure” of what you are currently editing. If you are writing a C++ class, it will show you all the member functions and fields. If you are working on \Latex document, the IMenu buffer will contain the sections and the subsections. The whole thing is occasionally useful but certainly does not need to clutter your workspace the whole time.
(require 'imenu-list)
(setq imenu-list-auto-resize t)
(setq imenu-list-after-jump-hook nil)
(bind-key* "<f12>" 'imenu-list-smart-toggle)
Complete Anything! I am yet to find an effective setup that is as fast as well as feature rich. I’ve defined hooks for some of the major modes that I use so that I don’t hold too many active backends at the start. A lot of times I found myself turning off company-mode because it just makes the typing slower at some moments. The company-idle-delay
makes the automatic popup impossible immediate so that I would wouldn’t have to call it manually through M-m
.
(global-auto-complete-mode 'nil)
(setq company-minimum-prefix-length 3
company-tooltip-align-annotations nil
company-tooltip-flip-when-above nil
company-idle-delay 'nil
company-show-numbers nil
company-echo-truncate-lines nil
company-tooltip-maximum-width 100
company-tooltip-minimum-width 100)
(global-company-mode t)
(bind-key* "M-m" 'company-complete)
(define-key company-active-map (kbd "C-n") 'company-select-next-or-abort)
(define-key company-active-map (kbd "C-p") 'company-select-previous-or-abort)
(setq company-backends '())
(setq company-frontends '(company-pseudo-tooltip-unless-just-one-frontend))
(setq company-tooltip-maximum-width 100)
(setq company-tooltip-minimum-width 100)
(face-spec-set 'company-preview '((t (:background "#444444" :foreground "light sky blue"))))
(face-spec-set 'company-tooltip '((t (:background "#444444" :foreground "light sky blue"))))
(face-spec-set 'company-tooltip-annotation '((t (:foreground "deep sky blue"))))
(require 'company-meghanada)
(require 'company)
(require 'company-cmake)
(require 'company-jedi)
(require 'company-meghanada)
(require 'company-irony)
(require 'company-nxml)
(require 'company-anaconda)
In my experience, setting up the backends of company properly is not the easiest thing. I’ve tried a lot of things and I’ve finally come up with this approach. I’ve defined a function that sets up the right backends for each task of mine. The functions are first bound to hooks so that the whole thing is kinda automatic. This, however, does not seem to work in one hundred percent of the cases. Therefore, I also can call the functions through some keybindings and/or hydra.
The definitions of all the functions for the backends setups.
- basic packages variable - I use the backends in this variable across all modes
(defvar basic-company-backends '(company-files
company-capf
company-dabbrev-code
company-keywords
company-dabbrev))
- functions
(defun my-company-basic-backends (args)
(interactive)
(setq company-backends `(,basic-company-backends)))
(defun my-company-nxml-backends ()
(interactive)
(message "Basic backends engaged.")
(setq company-backends `(company-capf
,basic-company-backends)))
(defun my-company-nxml-backends ()
(interactive)
(message "xXML backends engaged.")
(setq company-backends `(company-capf
,basic-company-backends)))
(defun my-company-java-backends ()
(interactive)
(message "Java backends engaged.")
(setq company-backends `(company-lsp
,basic-company-backends)))
(defun my-company-c++-backends ()
(interactive)
(message "C++ backends engaged.")
(setq company-backends `(
company-irony
company-irony-c-headers
company-c-headers
,basic-company-backends)))
(defun my-company-go-backends ()
(interactive)
(message "Go backends engaged.")
(setq company-backends `(
company-lsp
,basic-company-backends)))
(defun my-company-cmake-backends ()
(interactive)
(message "CMake backends engaged.")
(setq company-backends `(company-cmake
,basic-company-backends)))
(defun my-company-python-backends ()
(interactive)
(message "Python backends engaged.")
(setq company-backends `(company-jedi
elpy-company-backend
,basic-company-backends)))
(defun my-company-latex-backends ()
(interactive)
(message "Latex backends engaged.")
(setq company-backends `( (company-auctex-bibs
company-auctex-macros
company-auctex-labels
company-auctex-symbols
company-auctex-environments)
(company-bibtex company-reftex-labels company-reftex-citations)
,basic-company-backends)))
(defun my-company-elisp-backends ()
(interactive)
(message "ELisp backends engaged.")
(setq company-backends `(company-capf
,basic-company-backends)))
Automation…60% of the time it works every time!
(add-hook 'python-mode-hook 'my-company-python-backends)
(add-hook 'nxml-mode-hook 'my-company-nxml-backends)
(add-hook 'meghanada-mode-hook 'my-company-java-backends)
(add-hook 'latex-mode-hook 'my-company-latex-backends)
(add-hook 'cmake-mode-hook 'my-company-cmake-backends)
(add-hook 'c++-mode-hook 'my-company-c++-backends)
(add-hook 'emacs-lisp-mode-hook 'my-company-elisp-backends)
(add-hook 'go-mode-hook 'my-company-go-backends)
Hooks are nice but sometimes I want some finer control of which backends are activated in company.
(defhydra arnaud-hydra-company (:color red
:hint nil)
"
Company backends
----------------------------------------------------------
_p_: Python _l_: Latex _e_: ELisp
_x_: nXML _m_: CMake
_j_: Java _c_: C++
_b_: Basic
_q_: quit
"
("p" my-company-python-backends)
("x" my-company-nxml-backends )
("j" my-company-java-backends )
("l" my-company-latex-backends )
("m" my-company-cmake-backends )
("c" my-company-c++-backends )
("e" my-company-elisp-backends )
("b" my-company-basic-backends )
("q" nil :color blue))
(face-spec-set 'company-preview '((t (:background "#444444" :foreground "light sky blue"))))
(face-spec-set 'company-tooltip '((t (:background "#444444" :foreground "light sky blue"))))
(face-spec-set 'company-tooltip-annotation '((t (:foreground "deep sky blue"))))
Hydras are nice but sometimes I just want hit some keys and have what I want
- Quick keybinds to swtich backends
(bind-key* "M-j c p" 'my-company-python-backends)
(bind-key* "M-j c x" 'my-company-nxml-backends )
(bind-key* "M-j c j" 'my-company-java-backends )
(bind-key* "M-j c l" 'my-company-latex-backends )
(bind-key* "M-j c m" 'my-company-cmake-backends )
(bind-key* "M-j c c" 'my-company-c++-backends )
(bind-key* "M-j c e" 'my-company-elisp-backends )
(bind-key* "M-j c b" 'my-company-basic-backends )
(bind-key* "M-j c g" 'my-company-go-backends)
- The Hydry-thingy
(bind-key* "C-c h c" 'arnaud-hydra-company/body)
Navigate by searching for a letter on the screen and jumping to it. Useful for quick navigation and getting to places on the screen.
(require 'avy)
(bind-key* "<f13>" 'avy-goto-word-1)
(bind-key* "C-<f13>" 'avy-goto-char)
Go to next CHAR which is similar to “f” and ” t” in vim. To note is that I don’t think that this package will remember the state of your mark when you make the jump. So if you have the expression int funcName(int a, int b)
, the cursor is at the beginning of the expression and you type C-SPC C-c f (
you won’t mark everything till the (
(now I believer this sentence to be lie). Still useful though.
(require 'iy-go-to-char)
(bind-key* "C-c f" 'iy-go-up-to-char)
(bind-key* "C-c F" 'iy-go-up-to-char-backward)
Isearch
is great but I have ever wanted a isearch on steroids…or something with helm infused isearch. Swiper
is exaclty that. Anzu
is a mode line tweak that displays the number of found things by isearch but not by swiper. Yes, I should probably fix that some time in the future.
Note: I do also sometimes use helm-occur-from-isearch in order to find something. I still like to have different possibilities while performing an action and picking the best one in each individual case.
\
Update: I’ve switched back to isearch for now
;; (require 'ivy)
;; (require 'anzu)
;; (setq ivy-display-style (quote fancy))
;; (setq search-whitespace-regexp ".*?")
;; (global-anzu-mode +1)
(bind-key* "C-s" 'isearch-forward)
;; (bind-key* "C-c M-s" 'swiper)
;; (bind-key* "M-%" 'anzu-query-replace)
;; (bind-key* "C-M-%" 'anzu-query-replace-regexp)
IEdit is kinda like real time search and replace. It’s similar to that one vim feature that I see people using from time to time. After a word is selected by the region, you can go into iedit-mode with M-i
and while editing the marked region, all other occurrences will be changed accordingly.
(require 'iedit)
(face-spec-set 'iedit-occurrence '((t (:background "pale green" :foreground "black"))))
;; (require 'visual-regexp)
;; (require 'visual-regexp-steroids)
;; (bind-key* "M-%" 'vr/select-query-replace)
(bind-key* "M-%" 'query-replace)
(bind-key* "M-i" 'iedit-mode)
;; (bind-key* "C-M-i" 'iedit-mode-toggle-on-function)
(require 'yagist)
(bind-key* "M-j g l" 'yagist-list)
(bind-key* "M-j g r" 'yagist-region)
(bind-key* "M-j g b" 'yagist-buffer)
;; (load-if-present "~/.emacs.d/lisp/sunrise-commander.el")
;; (require 'sunrise-commander nil t)
;; (require 'sunrise-x-buttons nil t)
;; (require 'sunrise-x-modeline nil t)
;; (require 'gitignore-templates)
;; (bind-key* "M-j i i" 'gitignore-templates-insert)
;; (bind-key* "M-j i f" 'gitignore-templates-new-file)
;; (require 'prodigy)
;; (prodigy-define-service
;; :name "Python Server"
;; :command "python"
;; :args '("-m" "http.server" "6001")
;; :cwd "/home/arnaud/core.d/www"
;; :tags '(server)
;; :stop-signal 'sigkill
;; :kill-process-buffer-on-stop t)
;; (prodigy-define-service
;; :name "Hugo Local Blog"
;; :command "hugo"
;; :args '("server" "-D" )
;; :cwd "/home/arnaud/code/blog-hugo-files"
;; :tags '(server)
;; :stop-signal 'sigkill
;; :kill-process-buffer-on-stop t)
(bind-key* "M-j p" 'prodigy)
RMSBolt is an equivalent of Compiler Explorer but it runs right in my editor. With it I can quickly expect the generated binary from a C++ program, for example. A more common case in my case is to test macro expansions of the C preprocessor when writing C++ code.
https://github.com/emacsmirror/rmsbolt
;; (require 'rmsbolt)
// Local Variables:
// rmsbolt-command: "gcc -O0"
// rmsbolt-disassemble: nil
// End:
;; (bind-key* "M-j b c" 'rmsbolt-compile)
;; (bind-key* "M-j b s" 'rmsbolt-starter)
This package updates the point’s potions as you type numbers for goto-line
. It makes the whole experience of using goto-line
less chunky.
(require 'goto-line-preview)
(bind-key* "M-g g" 'goto-line-preview)
(bind-key* "M-g M-g" 'goto-line-preview)
Helm-Swooper is similar to swiper but offers better user experience IMO. I use it to quickly inspect the file for lines matching a pattern and then jump to one of the lines. This is somewhat nicer than using incremental search all of the time.
(require 'helm-swoop)
(bind-key* "C-x q" 'helm-swoop)
A dashboard(yeah, I know, pretend the name didn’t say it) kind of thing that display on startup of/Emacs/ and gives quick access to recent files and projectile-projects. It works with sessions too but I haven’t configured that yet. A image can also be displayed so I guess that is pretty. Custom startup message is a must of course!!
(require 'dashboard)
(setq initial-buffer-choice (lambda () (get-buffer "*dashboard*")))
(setq dashboard-banner-logo-title "Welcome to the Emacs of Stanislav Arnaudov")
;; (setq dashboard-startup-banner 'official)
;; (setq dashboard-banner-logo-title "W I T C H M A C S")
(setq dashboard-startup-banner "~/.emacs.d/chika_new.png")
(setq dashboard-center-content t)
(setq dashboard-show-shortcuts nil)
(setq dashboard-items '((recents . 10)
(bookmarks . 5)
(projects . 10)
(agenda . 5)
(registers . 5)))
(setq dashboard-set-heading-icons t)
(setq dashboard-set-file-icons t)
(setq dashboard-set-navigator t)
(setq dashboard-footer-icon (all-the-icons-octicon "dashboard"
:height 1.1
:v-adjust -0.05
:face 'font-lock-keyword-face))
(setq dashboard-footer "Dashboard is pretty cool!")
(setq show-week-agenda-p t)
(setq dashboard-navigator-buttons
`(;; line1
((,(all-the-icons-octicon "mark-github" :height 1.1 :v-adjust 0.0)
"Homepage"
"Browse homepage"
(lambda (&rest _) (browse-url "https://palikar.github.io/")))
("★" "Star" "Show stars" (lambda (&rest _) (browse-url "https://palikar.github.io/")) warning)
("?" "" "?/h" #'show-help nil "<" ">"))
;; line 2
((,(all-the-icons-faicon "linkedin" :height 1.1 :v-adjust 0.0)
"Linkedin"
""
(lambda (&rest _) (browse-url "https://www.linkedin.com/in/stanislav-arnaudov-37b475164/")))
("⚑" nil "Show flags" (lambda (&rest _) (message "flag")) error))))
(dashboard-setup-startup-hook)
Sometimes it gets really annoying when I close my emacs and have a bunch of buffers opened, the next time I launch the program, the buffers are gone and I have to open them again. Mind-blowing, I know, “So why do you close emacs?” - shut up, that’s not the point . This package addresses my issues. I can even have custom sessions and open whole groups of tabs all at once From the documentation:
<prefix> <key> <prefix> c - create workgroup <prefix> A - rename workgroup <prefix> k - kill workgroup <prefix> v - switch to workgroup <prefix> C-s - save session <prefix> C-f - load session
(kinda like cheat sheet)
;; (require 'workgroups2)
;; (workgroups-mode 1)
;; (setq wg-prefix-key (kbd "C-c z"))
;; (setq wg-session-file "~/.emacs.d/.emacs_workgroups")
;; (setq wg-emacs-exit-save-behavior 'save)
;; (setq wg-workgroups-mode-exit-save-behavior 'save)
;; (setq wg-mode-line-display-on t)
;; (setq wg-flag-modified t)
;; (setq wg-mode-line-decor-left-brace "["
;; wg-mode-line-decor-right-brace "]"
;; wg-mode-line-decor-divider ":")
Making the modeline a little bit prettier and more spece efficient than the default. I should say that I am kind of guilty for liking the Spacemacs modeline a little too much. My current setup is more or less resembling that. The current package that I am using is spaceline which as far as I understand is created for people like me.
Some of the packages for modelines that I’ve gone over are:
(require 'spaceline)
(require 'spaceline-config)
(require 'spaceline-all-the-icons)
(spaceline-helm-mode)
(spaceline-info-mode)
(setq powerline-default-separator 'wave)
(setq powerline-height 20)
(setq spaceline-all-the-icons-separator-type 'wave)
(spaceline-highlight-face-default)
(spaceline-toggle-all-the-icons-minor-modes-off)
(spaceline-toggle-all-the-icons-hud-on)
(spaceline-toggle-projectile-root-on)
(spaceline-toggle-version-control-on)
(spaceline-toggle-buffer-modified-on)
(spaceline-toggle-minor-modes-on)
(spaceline-toggle-projectile-root-on)
(spaceline-toggle-hud-off)
(spaceline-toggle-buffer-encoding-abbrev-off)
(if (daemonp)
(add-hook 'after-make-frame-functions
(lambda (frame)
(with-selected-frame frame
(spaceline-emacs-theme))))
(spaceline-emacs-theme))
;; (spaceline-all-the-icons--setup-anzu)
;; (spaceline-all-the-icons--setup-package-updates)
;; (spaceline-all-the-icons--setup-git-ahead)
;; (spaceline-all-the-icons--setup-neotree)
;; (spaceline-all-the-icons-theme)
Vim+Emacs
Yes, from time to time I do find myself saying “Ugh, vim has that one nice feature which can so usefull here in Emacsland”. For that reason, I’ve created a binding that allows me to quickly jump in and out of evil-mode. Evil – or emulating vim layers as they call it – is more or less full blown vim simulated in Emacs. The modal editing commands of vim are supported and are a joy to be used from time to time, even when one is hardcore Emacs fanboy.
(defun quick-evil ()
(interactive)
(if (bound-and-true-p evil-local-mode)
(progn
;; (evil-local-mode (or -1 1))
;; (undo-tree-mode (or -1 1))
(set-cursor-color "#d0d0d0")
)
(progn
;; (evil-mode)
;; (evil-local-mode (or 1 1))
;; (set-variable 'cursor-type 'box)
(set-cursor-color "#8968cd"))))
(set-cursor-color "#98fb98")
(bind-key* "M-<f13>" 'quick-evil)
Now, I generally know my Emacs keybindings but from time to time I have to look somethings up. The which-key packages in awesome in this regard. If I the start of some keybinding, a popup will show me how can I follow the binding and which functions will be I executing if I type something.
;; (require 'which-key)
;; (which-key-mode)
;; (which-key-setup-side-window-bottom)
;; ;; the default setup for the package
;; (setq which-key-idle-delay 1.0)
;; (setq which-key-max-description-length 27)
;; (setq which-key-add-column-padding 0)
;; (setq which-key-max-display-columns nil)
;; (setq which-key-separator " → " )
;; (setq which-key-unicode-correction 3)
;; (setq which-key-prefix-prefix "+" )
;; (setq which-key-special-keys nil)
;; (setq which-key-show-prefix 'left)
;; (setq which-key-show-remaining-keys nil)
The modeline can get pretty cluttered with minor modes pretty quickly. To avoid that I use the diminish package. It allows me to specify modes that will not have any text in the modeline.
(require 'diminish)
(defun diminish-em-all ()
"docstring"
(interactive)
(diminish 'smartparens-mode)
(diminish 'wrap-region-mode)
(diminish 'super-save-mode)
(diminish 'volatile-highlights-mode)
(diminish 'isearch-mode)
(diminish 'yas-minor-mode)
(diminish 'google-this-mode)
(diminish 'wg-mode)
(diminish 'workgroups-mode)
(diminish 'drag-stuff-mode)
(diminish 'flyspell-mode)
(diminish 'helm-mode)
(diminish 'eldoc-mode)
(diminish 'global-framer-mode)
(diminish 'framer-mode)
(diminish 'anzu-mode)
(diminish 'company-mode)
(diminish 'beacon-mode)
(diminish 'flycheck-mode)
(diminish 'hungry-delete-mode)
(diminish 'org-indent-mode)
(diminish 'hs-minor-mode)
(diminish 'which-key-mode)
(diminish 'iedit-mode)
(diminish 'modalka-mode "μ")
(diminish 'visual-line-mode)
(diminish 'hs-minor-mode)
(diminish 'aggressive-indent-mode)
(diminish 'org-indent-mode)
(diminish 'irony-mode)
(diminish 'function-args-mode)
(diminish 'abbrev-mode)
(diminish 'sphinx-doc-mode)
(diminish 'org-indent-mode)
(diminish 'ycmd-mode)
(diminish 'modern-c++-font-lock-mode)
(diminish 'doxymacs-mode)
(message "The modes should be away now!"))
(diminish-em-all)
(bind-key* "M-j d" 'diminish-em-all)
;; (require 'highlight-symbol)
;; (highlight-symbol-nav-mode)
;; (setq highlight-symbol-colors (quote ("cyan")))
;; (face-spec-set 'highlight-symbol-face '((t (:background "royal blue" :foreground "black"))))
;; (face-spec-set 'highlight-indentation-current-column-face '((t (:background "gray"))))
;; (face-spec-set 'highlight-symbol-face '((t (:background "light blue"))))
;; (bind-key* "M-o o" 'highlight-symbol)
;; (bind-key* "M-o M-o" 'highlight-symbol)
;; (bind-key* "M-n" 'highlight-symbol-next)
;; (bind-key* "M-p" 'highlight-symbol-prev)
;; (bind-key* "M-o c" 'highlight-symbol-remove-all)
;; (bind-key* "M-o M-c" 'highlight-symbol-remove-all)
;; (add-to-list 'load-path "~/code_ext/mu/mu4e")
;; (require 'mu4e)
;; (setq mu4e-maildir "/home/arnaud/.mail")
;; (setq
;; message-send-mail-function 'smtpmail-send-it
;; starttls-use-gnutls t
;; mu4e-sent-messages-behavior 'sent
;; user-mail-address "[email protected]"
;; user-full-name "Stanislav Arnaudov"
;; smtpmail-default-smtp-server "smtp.gmail.comg"
;; smtpmail-smtp-user "stanislav.arn"
;; smtpmail-smtp-server "smtp.gmail.com"
;; smtpmail-stream-type 'starttls
;; smtpmail-smtp-service 587)
;; (setq mu4e-trash-folder "/mu4e/Trash"
;; mu4e-refile-folder "/mu4e/Archive"
;; mu4e-sent-folder "/mu4e/Sent"
;; mu4e-drafts-folder "/mu4e/Drafts"
;; mu4e-attachment-dir "/mu4e/Downloads"
;; mu4e-get-mail-command "offlineimap -q"
;; mu4e-update-interval 300 ;; second
;; mu4e-compose-signature-auto-include nil
;; mu4e-view-show-images t
;; mu4e-view-show-addresses t
;; mu4e-use-fancy-chars t
;; )
;; (setq mu4e-contexts
;; `( ,(make-mu4e-context
;; :name "Gmail"
;; :enter-func (lambda () (mu4e-message "Entering Gmail context"))
;; :leave-func (lambda () (mu4e-message "Leaving Gmail context"))
;; ;; we match based on the contact-fields of the message
;; :match-func (lambda (msg)
;; (when msg
;; (string-match-p "^/Gmail" (mu4e-message-field msg :maildir))))
;; :vars '(
;; (mu4e-trash-folder . "/Gmail/[Gmail].Bin/")
;; ( user-mail-address . "[email protected]" )
;; ( user-full-name . "Stanislav Arnaudov" )))))
;; (setq mu4e-context-policy 'pick-first)
;; (setq mu4e-compose-context-policy nil)
;; (require 'org-mu4e)
;; (setq org-mu4e-convert-to-html t)
;; (add-to-list 'mu4e-view-actions '("ViewInBrowser" . mu4e-action-view-in-browser) t)
;; (setq mu4e-maildir-shortcuts
;; '( ("/INBOX" . ?i)
;; ("/[Gmail].Sent Mail" . ?s)
;; ("/[Gmail].Trash" . ?t)
;; ("/[Gmail].All Mail" . ?a)))
;; (setq
;; user-mail-address "[email protected]"
;; user-full-name "Foo X. Bar"
;; mu4e-compose-signature
;; (concat
;; "Foo X. Bar\n"
;; "http://www.example.com\n"))
;; (require 'mu4e-alert)
(bind-key* "C-x m" 'mu4e-compose-new)
The world is full of useless things! We should use them all!! Emacs agrees!!
;; (require 'visible-mark)
;; (global-visible-mark-mode 1)
;; (setq visible-mark-max 1)
;; (setq visible-mark-faces `(visible-mark-face1 visible-mark-face2))
That one cool site - wttr - that I even use in my system setup to get weather information. It can also be used in Emacs so why the hell not.
;; (require 'wttrin)
;; (setq wttrin-default-cities '("Karlsruhe"
;; "Sliven"
;; "Sofia"))
;; (setq wttrin-default-accept-language
;; '("Accept-Language" . "en-US"))
;; (bind-key* "M-j w" 'wttrin)
This cute little thing with those cool little nerdy cody comics
;; (require 'xkcd)
;; (bind-key* "M-j x" 'xkcd)
I… am not exactly a fast typist but I’ve really put time and effort into it. I regularly use this one but Emacs is Emacs and everything should be Emacs. Just put everything in Emacs they said! So, typit is a small package that lets you practice touch typing right here into Emacs.
;; (require 'typit)
;; (bind-key* "M-j t b" 'typit-basic-test)
;; (bind-key* "M-j t a" 'typit-advanced-test)
This things will track which command is being run and how many times… I just think it’s cool.
;; (require 'keyfreq)
;; (setq keyfreq-excluded-commands
;; '(self-insert-command
;; org-self-insert-command
;; company-ignore
;; abort-recursive-edit
;; forward-char
;; modalka-mode
;; backward-char
;; previous-line
;; next-line))
;; (keyfreq-mode 1)
;; (keyfreq-autosave-mode 1)