Skip to content

Latest commit

 

History

History
482 lines (414 loc) · 15.7 KB

File metadata and controls

482 lines (414 loc) · 15.7 KB

Adisbladis emacs configuration

Bootstrap this configuration

This configuration is designed to follow the XDG guidelines. This means that I configure locations for files of quite a lot of things.

To use this configuration of Emacs, save this file in ~/.config/emacs/config.org.

This is a minimal bootstrap which should live in ~/.emacs:

;; Define XDG directories
(setq-default user-emacs-config-directory
              (concat (getenv "HOME") "/.config/emacs"))
(setq-default user-emacs-data-directory
              (concat (getenv "HOME") "/.local/share/emacs"))
(setq-default user-emacs-cache-directory
              (concat (getenv "HOME") "/.cache/emacs"))

;; Load config
(org-babel-load-file (concat user-emacs-config-directory "/config.org"))

General configuration

Window resizing

More convenient window resizing

Backup Files

Unless the $XGD_DATA_DIR/emacs/backup directory exists, create it. Then set as backup directory.

(let ((backup-dir (concat user-emacs-data-directory "/backup")))
  (unless (file-directory-p backup-dir)
    (mkdir backup-dir t))

  (setq-default backup-directory-alist (cons (cons "." backup-dir) nil)))

Ido

(ido-mode)

Lock-files

Disable creation of lock-files named .#<filename>.

(setq-default create-lockfiles nil)

Theme

(load-theme 'zerodark t)
(zerodark-setup-modeline-format)
(menu-bar-mode -1)
(tool-bar-mode -1)
(scroll-bar-mode -1)

Direnv

(direnv-mode)
(add-to-list 'default-frame-alist '(font . "Inconsolata 12"))

Basic code style

(setq c-basic-indent 4)
(setq indent-line-function 'insert-tab)
(setq indent-tabs-mode nil)
(setq tab-stop-list '(4 8 12 16 20 24 28 32))
(setq-default indent-tabs-mode nil)
(setq-default tab-width 4)
(add-hook 'before-save-hook 'delete-trailing-whitespace)

Major modes

Plantuml

(add-to-list 'auto-mode-alist '("\\.plantuml\\'" . plantuml-mode))
(add-to-list 'auto-mode-alist '("\\.puml\\'" . plantuml-mode))
(setq plantuml-jar-path (getenv "PLANTUML_JAR"))

Python jedi completions

(add-hook 'python-mode-hook 'jedi:setup)
(setq-default jedi:setup-keys t)
(setq-default jedi:complete-on-dot t)

C/cpp

;;  (add-hook 'c++-mode-hook 'irony-mode)
;;  (add-hook 'c-mode-hook 'irony-mode)
;;  (add-hook 'objc-mode-hook 'irony-mode)
;;  (eval-after-load 'company
;;    '(add-to-list 'company-backends 'company-irony))

Go mode

(progn
  (add-hook 'before-save-hook 'gofmt-before-save))

Web Mode

Install web-mode, set rules for filetypes and indent.

(progn
  (setq-default web-mode-markup-indent-offset 4) ; HTML
  (setq-default web-mode-css-indent-offset 4)    ; CSS
  (setq-default web-mode-code-indent-offset 4)) ; JS/PHP/etc

Better JS editing

(require 'js2-mode)
(add-to-list 'auto-mode-alist '("\\.js\\'" . js2-mode))
(add-hook 'js2-mode-hook 'ac-js2-mode)
(setq js2-strict-missing-semi-warning nil)
(setq js2-strict-trailing-comma-warning nil)
(add-hook 'js2-mode-hook 'ac-js2-setup-auto-complete-mode)
(define-key js2-mode-map (kbd "M-.") nil)
(add-hook 'js2-mode-hook (lambda ()
  (add-hook 'xref-backend-functions #'xref-js2-xref-backend nil t)))
(require 'indium)
(add-hook 'js-mode-hook #'indium-interaction-mode)
(setq mocha-debugger 'indium)

Utilities

Git frontend

Install magit, bind C-x g to display the main magit popup and bind C-x M-g to display a magit popup with keybinds used in magit.

(global-set-key (kbd "C-x g") 'magit-status) ; Display the main magit popup
(global-set-key (kbd "C-x M-g") 'magit-dispatch-popup) ; Display keybinds for magit

Autocomplete

(progn
  (setq-default company-tooltip-minimum-width 15)
    (setq-default company-idle-delay 0.1)
    (global-company-mode))

Fuzzy Matching

(progn
  (with-eval-after-load 'company
    (company-flx-mode +1)))

Statistics for completions

(progn
  (setq-default company-statistics-file
                  (concat user-emacs-data-directory
                          "/company-statistics.dat"))
    (company-statistics-mode))

go

Utilizes the program gocode as backend. Available in AUR as gocode-git.

(add-hook 'go-mode-hook
  (lambda ()
    (unless (executable-find "gocode")
      (error "Program: gocode is missing"))
                (set (make-local-variable 'company-backends) '(company-go))
                (company-mode t)))

Flexible ido matching

Load ido-mode with flx for flexible matching. Also move the history file to $XGD_DATA_DIR/emacs/ido.dat.

(progn
  ;; Flexible matching
  (setq-default ido-enable-flex-matching t)

  ;; Load ido-mode
  (ido-mode 1)
  (ido-everywhere 1)
  (flx-ido-mode 1)

  ;; History file
  (setq-default ido-save-directory-list-file
                (concat user-emacs-data-directory "/ido.dat"))

  ;; Always open files in current frame
  (setq-default ido-default-file-method 'selected-window)

  ;; Always switch to buffers in current frame
  (setq-default ido-default-buffer-method 'selected-window)
  (ido-mode))

Smooth scrolling

This package makes Emacs scroll before cursor reach top or bottom which makes scrolling smoother.

(progn
  (setq-default smooth-scroll-margin 2))

Fancy search

TODO

(global-set-key (kbd "C-s") 'swiper)
(global-set-key (kbd "C-r") 'swiper)
(progn
  (setq-default ivy-use-virtual-buffers t))

webpaste

Paste whole buffers or parts of buffers to the internet.

(global-set-key (kbd "C-c C-p C-b") 'webpaste-paste-buffer)
(global-set-key (kbd "C-c C-p C-r") 'webpaste-paste-region)

Smart-mode-line

(progn
  (setq sml/theme 'powerline)
  (setq sml/no-confirm-load-theme t)
  (sml/setup))

Syntax checking and linting :flycheck:…

(global-flycheck-mode)

Nicer handling of parens :smartparen:…

(progn
  (add-hook 'js-mode-hook #'smartparens-mode)
  (add-hook 'html-mode-hook #'smartparens-mode)
  (add-hook 'python-mode-hook #'smartparens-mode)
  (add-hook 'lua-mode-hook #'smartparens-mode)
  (add-hook 'ruby-mode-hook #'smartparens-mode)
  (add-hook 'rust-mode-hook #'smartparens-mode))

Org exports

(eval-after-load "org"
  '(require 'ox-gfm nil t))

EXWM

(require 'exwm)
(require 'exwm-randr)
(require 'exwm-config)
  (add-hook 'exwm-randr-screen-change-hook
  (lambda ()
    (start-process-shell-command
      "xrandr" nil "xrandr --output DP-2-2 --right-of eDP-1 --auto")))

  (add-hook 'exwm-manage-finish-hook
          (lambda ()
            (when (and exwm-class-name
                       (string= exwm-class-name "Yakuake"))
              (exwm-floating-toggle-floating))))

(defun pnh-run (command)
  (interactive (list (read-shell-command "$ ")))
  (start-process-shell-command command nil command))
  (define-key exwm-mode-map (kbd "s-!") 'pnh-run)
  (global-set-key (kbd "s-!") 'pnh-run)

(add-hook 'exwm-update-class-hook
          (lambda ()
            (exwm-workspace-rename-buffer exwm-class-name)))

;; Note: This approach does not work with Emacs 25 due to a bug of Emacs.
(add-hook 'exwm-manage-finish-hook
          (lambda ()
            (when (and exwm-class-name
                       (string= exwm-class-name "URxvt"))
              (exwm-input-set-local-simulation-keys '(([?\C-c ?\C-c] . ?\C-c))))))

(add-hook 'exwm-update-title-hook
          (lambda ()
          (let ((tilde-exwm-title
            (replace-regexp-in-string (getenv "HOME") "~" exwm-title)))
            (exwm-workspace-rename-buffer (format "%s: %s" exwm-class-name tilde-exwm-title)))))

;; Display time in modeline
(progn
  (setq display-time-24hr-format t)
  (display-time-mode 1))

;; Battery is useful too
(display-battery-mode)

(require 'desktop-environment)
(desktop-environment-mode)
(setq desktop-environment-brightness-set-command "light %s")
(setq desktop-environment-brightness-normal-decrement "-U 10")
(setq desktop-environment-brightness-small-decrement "-U 5")
(setq desktop-environment-brightness-normal-increment "-A 10")
(setq desktop-environment-brightness-small-increment "-A 5")
(setq desktop-environment-brightness-get-command "light")
(setq desktop-environment-brightness-get-regexp "\\([0-9]+\\)\\.[0-9]+")
(setq desktop-environment-screenlock-command "loginctl lock-session")
(setq desktop-environment-screenshot-command "flameshot gui")

(require 'exwm-systemtray)
(exwm-systemtray-enable)
(setq exwm-systemtray-height 16)

(setq exwm-manage-configurations
      '(((equal exwm-class-name "Firefox Developer Edition")
         simulation-keys (([?\C-q] . [?\C-w])  ; close tab instead of quitting Firefox
                          ([?\C-b] . [left])
                          ([?\C-f] . [right])
                          ([?\C-p] . [up])
                          ([?\C-n] . [down])
                          ([?\C-t] . [?\C-n])
                          ([?\C-s] . [?\C-f])
                          ([?\C-a] . [home])
                          ([?\C-e] . [end])
                          ([?\M-v] . [prior])
                          ([?\C-v] . [next])
                          ([?\C-d] . [delete])))
                          ))

(exwm-input-set-simulation-keys
 (mapcar (lambda (c) (cons (kbd (car c)) (cdr c)))
         `(("C-b" . left)
           ("C-f" . right)
           ("C-p" . up)
           ("C-n" . down)
           ("C-a" . home)
           ("C-e" . end)
           ("M-v" . prior)
           ("C-v" . next)
           ("C-d" . delete)
           ("C-m" . return)
           ("C-i" . tab)
           ("C-g" . escape)
           ("C-s" . ?\C-f)
           ("C-y" . ?\C-v)
           ("M-w" . ?\C-c)
           ("M-<" . C-home)
           ("M->" . C-end)
           ("C-M-h" . C-backspace))))

;; Using ido to change "tabs" in Firefox!
;;
;; For this to work properly you need to stop opening new tabs and open
;; everything in new windows. It sounds crazy, but then you can use ido
;; to switch between "tabs" and everything is wonderful.
;;
;; Step 1: about:config -> browser.tabs.opentabfor.middleclick -> false
;; Step 2: change whatever "open link in new tab" binding in Saka Key or
;;         whatever you use to open the link in a new window
;; Step 3: rebind ctrl-t to open a new window as well
;; Step 4: place the following in chrome/userChrome.css in your FF profile:
;;         #tabbrowser-tabs { visibility: collapse !important; }
;; Step 5: add this code to your exwm config:
;; Step 6: restart your browser and enjoy your new C-x b fanciness!
(defun pnh-trim-non-ff ()
  (cl-delete-if-not (apply-partially 'string-match "- Mozilla Firefox$")
                 ido-temp-list))

(add-hook 'exwm-manage-finish-hook
          (defun pnh-exwm-manage-hook ()
            (when (string-match "Firefox" exwm-class-name)
              (setq ido-make-buffer-list-hook 'pnh-trim-non-ff))))


(exwm-input-set-key (kbd "s-g")
  (defun pnh-ff-gsearch ()
    (interactive)
     (browse-url
     (format "https://google.com/search?q=%s"
     (read-string "Terms: ")))))

(exwm-input-set-key (kbd "s-s")
  (defun pnh-ff-url ()
    (interactive)
     (browse-url
     (read-string "URL: "))))

(exwm-input-set-key (kbd "s-t")
  (defun pnh-terminal ()
    (interactive)
    (start-process-shell-command "urxvtc" nil "urxvtc")))

(setq browse-url-firefox-arguments '("-new-window"))

(defun x11-wm-init () (progn
  (setq exwm-randr-workspace-output-plist '(1 "DP-2-2"))
  (require 'exwm-config)
  (exwm-config-default)
  (exwm-randr-enable))
  (server-start))

Terminal emulation

(require 'vterm)

Email

;; (add-hook 'message-setup-hook
;;           (lambda ()
;;             (gnus-alias-determine-identity)
;;             (define-key message-mode-map (kbd "C-c f")
;;               (lambda ()
;;                 (interactive)
;;                 (message-remove-header "Fcc")
;;                 (message-remove-header "Organization")
;;                 (gnus-alias-select-identity)
;;                 (notmuch-fcc-header-setup)))
;;             (flyspell-mode)))

;; ; gnus-alias
(autoload 'gnus-alias-determine-identity "gnus-alias" "" t)
(setq gnus-alias-identity-alist
      '(("adisbladis-gmail"
         nil ;; Does not refer to any other identity
         "Adam Hose <adisbladis@gmail.com>"
         nil ;; No organization header
         nil ;; No extra headers
         nil ;; No extra body text
         nil ;; No signature
         )
        ("enuma"
         nil
         "Adam Hose <adam.hose@enuma.io>"
         "Enuma Technologies"
         nil
         nil
         nil
         )
        ("trustedkey"
         nil
         "Adam Hose <adam.hose@trustedkey.com>"
         "Trusted Key"
         nil
         nil
         nil
         )
        ))

(setq gnus-alias-default-identity "adisbladis-gmail")
(setq gnus-alias-identity-rules
      '(("@enuma.io" ("any" "@enuma\\.io" both) "enuma")
        ("@trustedkey.com" ("any" "@trustedkey\\.com" both) "trustedkey")))

(setq mail-user-agent 'message-user-agent)
(setq message-send-mail-function 'message-send-mail-with-sendmail)
(setq message-kill-buffer-on-exit t)
(setq mail-specify-envelope-from t)

(setq sendmail-program "msmtp"
      mail-specify-envelope-from t
      mail-envelope-from 'header
      message-sendmail-envelope-from 'header)
;; Sign messages by default.
(add-hook 'message-setup-hook 'mml-secure-message-sign-pgpmime)