Mohamed Aziz Knani configuration file

Introduction

I like very much the idea of literate programming, it appears that Org-mode in Emacs shines in doing this, the code here is tangled into an emacs lisp file and loaded by emacs, I also weave it into an html file and post it on my website.

I suggest you start with a starter kit like bbatsov's prelude not with mine since I make some decision you might not like.

First backup your old configuration

mv ~/.emacs.d ~/.emacs.d-back

Then can download my config doing:

git clone https://github.com/mohamed-aziz/.emacs.d-new.git ~/.emacs.d

Then install all the dependencies, for now I have no automated way of doing this.

In the beginning this must be found in your init.el, this will just tangle Knani.org, reload init.el and byte compile it.

(require 'org)
(org-babel-tangle-file (concat user-emacs-directory "Knani.org"))
(load-file (concat user-emacs-directory "init.el"))
(byte-compile-file (concat user-emacs-directory "init.el"))

If you are done with changes just re-tangle Knani.org using C-c C-v t.

Initialize

Personal Information

(setq user-full-name "Mohamed Aziz Knani"
  user-mail-address "medazizknani@gmail.com")

Package sources

If the system has gnutls use ssl.

(require 'package)
(package-initialize)
(let* ((no-ssl (and (memq system-type '(windows-nt ms-dos))
                    (not (gnutls-available-p))))
       (url (concat (if no-ssl "http" "https") "://melpa.org/packages/")))
  (add-to-list 'package-archives (cons "melpa" url) t))

(let* ((no-ssl (and (memq system-type '(windows-nt ms-dos))
                    (not (gnutls-available-p))))
       (url (concat (if no-ssl "http" "https") "://orgmode.org/elpa/")))
  (add-to-list 'package-archives (cons "org" url) t))

from glyph's blog

(setq tls-program "gnutls-cli")

(let ((trustfile
       (replace-regexp-in-string
        "\\\\" "/"
        (replace-regexp-in-string
         "\n" ""
         (shell-command-to-string "python -m certifi")))))
  (setq tls-program
        (list
         (format "gnutls-cli%s --x509cafile %s -p %%p %%h"
                 (if (eq window-system 'w32) ".exe" "") trustfile))))

Load custom file

Load custom settings

(setq custom-file (expand-file-name "custom.el" user-emacs-directory))

(when (file-exists-p custom-file)
  (load custom-file))

Look and feel

Define themes

(defconst dark-theme 'solarized-zenburn)
(defconst light-theme 'solarized-light)
(tool-bar-mode   0)
(menu-bar-mode   0)

(when (> emacs-major-version 24)
  (scroll-bar-mode 0))

;; arabic font
(when window-system
  (set-fontset-font "fontset-default" '(#x600 . #x6ff)
                    "Kawkab Mono"))


Set no-fringes mode

(set-fringe-style '(0 . 0))

Default font

(set-frame-font "Input Mono 13" nil t)

Add load paths

(add-to-list 'load-path
             (expand-file-name "lisp" user-emacs-directory))
(add-to-list 'load-path "/usr/share/emacs/site-lisp/mu4e")

Gnome dark window bar

(defun set-selected-frame-dark ()
  (interactive)
  (let ((winid (frame-parameter (selected-frame) 'outer-window-id)))
    (call-process "xprop" nil nil nil "-f" "_GTK_THEME_VARIANT" "8u" "-set" "_GTK_THEME_VARIANT" "dark" "-id" winid)))

(if (window-system)
    (set-selected-frame-dark))

UI

Beacon

(require 'beacon)
(beacon-mode +1)

Ivy

Enable Ivy

(require 'ivy)

(ivy-mode 1)t
(setq ivy-use-virtual-buffers t)
(setq enable-recursive-minibuffers t)
(global-set-key "\C-s" 'swiper)
(global-set-key (kbd "C-c C-r") 'ivy-resume)
(global-set-key (kbd "<f6>") 'ivy-resume)
(global-set-key (kbd "M-x") 'counsel-M-x)
(global-set-key (kbd "C-x C-f") 'counsel-find-file)
(global-set-key (kbd "<f1> f") 'counsel-describe-function)
(global-set-key (kbd "<f1> v") 'counsel-describe-variable)
(global-set-key (kbd "<f1> l") 'counsel-find-library)
(global-set-key (kbd "<f2> i") 'counsel-info-lookup-symbol)
(global-set-key (kbd "<f2> u") 'counsel-unicode-char)
(global-set-key (kbd "C-c g") 'counsel-git)
(global-set-key (kbd "C-c j") 'counsel-git-grep)
(global-set-key (kbd "C-c k") 'counsel-ag)
(global-set-key (kbd "C-x l") 'counsel-locate)
(global-set-key (kbd "C-S-o") 'counsel-rhythmbox)
(define-key minibuffer-local-map (kbd "C-r") 'counsel-minibuffer-history)

Dired

(require 'dired)

Keybindings

(define-key dired-mode-map (kbd "C-c f") 'find-name-dired)
(define-key dired-mode-map (kbd "C-c o") 'crux-open-with)

Hide details

This just hides details and just displays the files and directory names, this can be toggled using '('

(add-hook 'dired-mode-hook '(lambda ()
                            (dired-hide-details-mode)))

Switches

Dired uses the ls program from GNU coreutils to get stuff, so you can do this

(setq dired-listing-switches "-lah")

Download file

An interactive function to download files from here

(require 'url)

(defun download-file (&optional url download-dir download-name)
  (interactive)
  (let ((url (or url
                 (read-string "Enter download URL: "))))
    (let ((download-buffer (url-retrieve-synchronously url)))
      (with-current-buffer download-buffer
        ;; we may have to trim the http response
        (goto-char (point-min))
        (re-search-forward "^$" nil 'move)
        (forward-char)
        (delete-region (point-min) (point))
        (write-file (concat (or default-directory
                                download-dir
                                "~/Downloads"
                                (or download-name
                                    (car (last (split-string url "/" t)))))))))))

Normalize filenames

I have some functions to normalize filenames, this has some bugs though

(defun normalize-name (filename)
  "Replace space with underscore"
  (replace-regexp-in-string " " "_" filename))

(defun dired-do-rename-file ()
  "Call dired-rename-file"
  (let ((file (file-name-base (dired-get-filename nil t))))
    (print file)
    (dired-rename-file file (normalize-name file) nil)))

(defun dired-normalize-name (&optional arg)
  "Normalize files from dired"
  (interactive "P")
  (dired-map-over-marks-check (function dired-do-rename-file) arg 'normalize t)
  (revert-buffer))

Open with xdg-open

This just lets me open files (or directories) with their default applications, it doesn't support windows though since I don't think that it has a facility to open files like that.

This is stolen from bbatsov's crux package

(defun crux-open-with (arg)
  "Open visited file in default external program.
When in dired mode, open file under the cursor.
With a prefix ARG always prompt for command to use."
  (interactive "P")
  (let* ((current-file-name
          (if (eq major-mode 'dired-mode)
              (dired-get-file-for-visit)
            buffer-file-name))
         (open (pcase system-type
                 (`darwin "open")
                 ((or `gnu `gnu/linux `gnu/kfreebsd) "xdg-open")))
         (program (if (or arg (not open))
                      (read-shell-command "Open current file with: ")
                    open)))
    (call-process program nil 0 nil current-file-name)))

Dired async

I like using dired async

(require 'dired-async)
(dired-async-mode 1)

Dired subtree

This requires dired-hacks-utils

(require 'dired-subtree)

(define-key dired-mode-map "i" 'dired-subtree-insert)
(define-key dired-mode-map ";" 'dired-subtree-remove)

Some other stuff

Some other stuff like dwim and dired-fixups

(require 'dired-fixups)
(setq dired-dwim-target t)

ERC

ERC is my default IRC client

(require 'erc)
(require 'erc-log)

(setq erc-log-channels-directory "~/.erc/logs/")
(erc-truncate-mode +1)
(erc-spelling-mode 1)
(setq erc-server-coding-system '(utf-8 . utf-8))
(setq erc-autojoin-channels-alist '(("freenode.net" . (
                                                       "#emacs"
                                                       "#gnu"
                                                       "#crypto"
                                                       "##programming"))
                                    ("oftc.net" . ("#suckless"
                                    "#debian"))))

Enable notifications

(require 'erc-desktop-notifications)

Smiley mode

(erc-smiley-enable)

Eshell

Eshell toggle

code from multi-term.el

(defvar eshell-dedicated-exists-p nil)
(defun eshell-dedicated-toggle ()
  "Toggle dedicated `multi-term' window."
  (interactive)
  (if (eshell-dedicated-exist-p)
      (progn
        (multi-term-dedicated-close)
        (if (and multi-term-dedicated-close-back-to-open-buffer-p
                 multi-term-dedicated-close-buffer)
            (switch-to-buffer multi-term-dedicated-close-buffer)
          ))
    (if multi-term-dedicated-close-back-to-open-buffer-p
        (setq multi-term-dedicated-close-buffer (current-buffer)))
    (multi-term-dedicated-open)
    ))

;;;###autoload
(defun multi-term-dedicated-select ()
  "Select the `multi-term' dedicated window."
  (interactive)
  (if (multi-term-dedicated-exist-p)
      (select-window multi-term-dedicated-window)
    (message "`multi-term' window is not exist.")))

Background makes

from emacswiki

(defun eshell/ec (&rest args)
  "Use `compile' to do background makes."
  (if (eshell-interactive-output-p)
      (let ((compilation-process-setup-function
             (list 'lambda nil
                   (list 'setq 'process-environment
                         (list 'quote (eshell-copy-environment))))))
        (compile (eshell-flatten-and-stringify args))
        (pop-to-buffer compilation-last-buffer))
    (throw 'eshell-replace-command
           (let ((l (eshell-stringify-list (eshell-flatten-list args))))
             (eshell-parse-command (car l) (cdr l))))))
(put 'eshell/ec 'eshell-no-numeric-conversions t)

Pyvenv integration

Integration of pyvenv within Eshell

(with-eval-after-load 'eshell
  (defvar eshell-path-env)
  (dolist (hook '(pyvenv-post-activate-hooks pyvenv-post-deactivate-hooks))
    (add-hook hook                  ; eshell
              (lambda ()
                (let ((path-env (mapconcat (lambda (x) (or x "."))
                                           exec-path
                                           path-separator)))
                  (setq-default eshell-path-env path-env)
                  (dolist (buffer (buffer-list))
                    (with-current-buffer buffer
                      (and (derived-mode-p 'eshell-mode)
                           (setq eshell-path-env path-env)))))))))

Org

(require 'org)

What to record when a task is marked done

(setq org-log-done 'time)

Org directory

(setq org-directory "~/Documents/org")

For better viewing math equations

(setq org-format-latex-options (plist-put org-format-latex-options :scale 1.7))

setting program for rendering latex fragments

(setq org-preview-latex-default-process 'dvipng)

For easier math symbols input for latex

Org-tangle disable confirmation

(setq  org-confirm-babel-evaluate nil)

Some eye candy stuff

What is olivetti-mode?

(add-hook 'org-mode-hook '(lambda ()
                            (setq left-margin-width 5)
                            (setq right-margin-width 5)
                            (visual-line-mode)
                            (flyspell-mode)))

This is my agenda files

Org personal files:

(load-file (expand-file-name "~/orgfiles.el"))

Keybindings

(global-set-key (kbd "C-c a") 'org-agenda)
;; (define-key org-mode-map (kbd "M-RET") 'org-insert-heading)
(define-key global-map "\C-cc" 'org-capture)
(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)

C/C++

For working with C/C++/D source code

(org-babel-do-load-languages
 'org-babel-load-languages '((C . t)
                             (shell . t)
                             (calc . t)
                             (python . t)))

Shoot and insert

Utility function I use to take a screenshot of a dosbox window and then inserting the image in a org-mode buffer.

Screenshot

(defun insert-shot ()
  (interactive)
  (let*
      ((filename (concat (format "%04x" (random (expt 16 4))) ".png" )))
    ;; change to window; take shot; and insert it
    (shell-command (concat "wmctrl -a WINXP && import -window $(xdotool getactivewindow) " filename))
    ;; return to emacs
    (shell-command "wmctrl -a Emacs")
    ;; insert image to org file
    (insert (format "
#+CAPTION: caption
#+LABEL: fig:label
#+ATTR_LATEX: :float

[[file:%s]]" filename))))

(define-key org-mode-map (kbd "<f8>") 'insert-shot)

Org crypt

auto crypt org files using EasyPG

(require 'org-crypt)
(org-crypt-use-before-save-magic)

Org modules

Add org-habit

(add-to-list 'org-modules 'org-habit)

Org capture

Org contacts

mu4e, get email form name

(defun org-contacts-mu4e-get-name-email ()
  "Get name and email address from Gnus message."
  (if (gnus-alive-p)
      (gnus-with-article-headers
        (mail-extract-address-components
         (or (mail-fetch-field "From") "")))))

Org contacts phone number template:

(defun org-contacts-template-phone (&optional return-value)
  "Try to return the contact phne for a template.
If not found return RETURN-VALUE or something that would ask the user."
  (or (cadr (org-contacts-gnus-get-name-email))
      return-value
      (concat "%^{PHONE}p")))

org-capture contacts template:

(require 'org-capture)
(add-to-list 'org-capture-templates
             `("c" "Contacts" entry (file+headline mylifefile "People")
               "\n* %(org-contacts-template-name)
:PROPERTIES:
:EMAIL: %(org-contacts-template-email)
:PHONE: %(org-contacts-template-phone)
:END:"))

Capture web content

(add-to-list 'org-capture-templates
             `("w" "Web site" entry
               (file ,(concat org-directory "/websites.org"))
               "\n* %a %^g \n\ncaptured on: %U \n\n%?\n\n%:initial"))

todo template

(add-to-list 'org-capture-templates
             `("t" "Todo" entry (file+headline mylifefile "Tasks")
               "\n* TODO %?\n  %i\n  %a\n\n"))

Template to capture an elfeed-entry copied from https://github.com/skeeto/elfeed/pull/206

(add-to-list 'org-capture-templates 
             `("l" "To read" entry (file+headline mylifefile "Bookmarks")
              "\n* TODO %?%:description :toread:
- %:link
%(when (< 0 (length \"%:elfeed-entry-link\")) (concat \"- web link: \" \"%:elfeed-entry-link\"))\n"))

Capture web bookmarks

(add-to-list 'org-capture-templates
            `("b" "Web site bookmark" entry
               (file ,(concat org-directory "/bookmarks.org"))
               "* %a %^g\n\n  %?\n  captured on: %U\n\n%:initial\n\n"))

Capture code snippets and computer stuff

(add-to-list 'org-capture-templates
             `("T" "Tip" entry (file ,(concat org-directory "/tip.org"))
               "\n* %? %^g\n  %x\n  %a\n  captured on: %U\n\n"))

Capture passwords

(add-to-list 'org-capture-templates `("P" "Password" entry (file ,(concat org-directory "/passwords.org.gpg"))
                 "\n* %^{Title}\n  %^{URL}p %^{USERNAME}p %^{PASSWORD}p"))

Journal

(add-to-list 'org-capture-templates `("j" "Journal" entry (file+olp+datetree mylifefile "Journal")
                                      "\n* %?\nEntered on %U\n  %i\n  %a\n"))

Blog post

(defun capture-report-data-file ()
  (let ((name (read-string "Name: ")))
    (find-file (expand-file-name (format "%s-%s.org"
                                         (format-time-string "%Y-%m-%d")
                                         name) "~/Documents/org/emacs_site/blog/"))))


(add-to-list 'org-capture-templates
             `("B"
                "Blog post"

                plain
                (function capture-report-data-file)
                "#+TITLE: %^{prompt}\n#+DATE: %T\n\n%?"))

This might be deprecated in the future

Org protocol capture

Org protocol stuff

(require 'org-protocol)
(require 'org-protocol-capture-html)

template

(add-to-list 'org-capture-templates 
             `("p" "Protocol" entry (file+headline ,(concat org-directory "protocol.org") "Inbox")
               "* %^{Title}\nSource: %u, %c\n #+BEGIN_QUOTE\n%i\n#+END_QUOTE\n\n\n%?"))

(add-to-list 'org-capture-templates 
             `("L" "Protocol Link" entry (file+headline ,(concat org-directory "protocol.org") "Inbox")
                                       "* %? [[%:link][%:description]] \nCaptured On: %U"))

Fix org cpature with counsel

(eval-after-load 'org
  `(load "~/.emacs.d/lisp/org-fix-capture-counsel.el"))

Org contact

Set org contact files

(require 'org-contacts)
(setq  org-contacts-files `(,(concat org-directory "/people.org")))

org-contacts-files

set org

Latex export code stuff

(setq org-latex-listings 'minted
      org-latex-packages-alist '(("" "minted"))
      org-src-fontify-natively t
      org-latex-pdf-process
      '("pdflatex -shell-escape -interaction nonstopmode -output-directory %o %f"
        "pdflatex -shell-escape -interaction nonstopmode -output-directory %o %f"))

Org passwords

(setq org-passwords-file (concat org-directory "/passwords.org.gpg"))

Split code block

this function will say if the cursor is any org-block:

(defun my/org-in-any-block-p ()
  "Return non-nil if the point is in any Org block.

The Org block can be *any*: src, example, verse, etc., even any
Org Special block.

This function is heavily adapted from `org-between-regexps-p'."
  (save-match-data
    (let ((pos (point))
          (case-fold-search t)
          (block-begin-re "^[[:blank:]]*#\\+begin_\\(?1:.+?\\)\\(?: .*\\)*$")
          (limit-up (save-excursion (outline-previous-heading)))
          (limit-down (save-excursion (outline-next-heading)))
          beg end)
      (save-excursion
        ;; Point is on a block when on BLOCK-BEGIN-RE or if
        ;; BLOCK-BEGIN-RE can be found before it...
        (and (or (org-in-regexp block-begin-re)
                 (re-search-backward block-begin-re limit-up :noerror))
             (setq beg (match-beginning 0))
             ;; ... and BLOCK-END-RE after it...
             (let ((block-end-re (concat "^[[:blank:]]*#\\+end_"
                                         (match-string-no-properties 1)
                                         "\\( .*\\)*$")))
               (goto-char (match-end 0))
               (re-search-forward block-end-re limit-down :noerror))
             (> (setq end (match-end 0)) pos)
             ;; ... without another BLOCK-BEGIN-RE in-between.
             (goto-char (match-beginning 0))
             (not (re-search-backward block-begin-re (1+ beg) :noerror))
             ;; Return value.
             (cons beg end))))))

This function will split the block

(defun my/org-split-block ()
  "Sensibly split the current Org block at point."
  (interactive)
  (if (my/org-in-any-block-p)
      (save-match-data
        (save-restriction
          (widen)
          (let ((case-fold-search t)
                (at-bol (bolp))
                block-start
                block-end)
            (save-excursion
              (re-search-backward "^\\(?1:[[:blank:]]*#\\+begin_.+?\\)\\(?: .*\\)*$" nil nil 1)
              (setq block-start (match-string-no-properties 0))
              (setq block-end (replace-regexp-in-string
                               "begin_" "end_" ;Replaces "begin_" with "end_", "BEGIN_" with "END_"
                               (match-string-no-properties 1))))
            ;; Go to the end of current line, if not at the BOL
            (unless at-bol
              (end-of-line 1))
            (insert (concat (if at-bol "" "\n")
                            block-end
                            "\n\n"
                            block-start
                            (if at-bol "\n" "")))
            ;; Go to the line before the inserted "#+begin_ .." line
            (beginning-of-line (if at-bol -1 0)))))
    (message "Point is not in an Org block")))

Split if in an org block, add this as an advice to org-meta-return:

(defun my/org-meta-return-advice (&rest args)
  "Do not call the original function if point is in an Org block."
  (let ((do-not-run-orig-fn (my/org-in-any-block-p)))
    (when do-not-run-orig-fn
      (my/org-split-block))
    do-not-run-orig-fn))
(advice-add 'org-meta-return :before-until #'my/org-meta-return-advice)

The agenda stuff

Function to print the current agenda view:

(defun my/print-agenda (bool)
  (interactive
   (list (y-or-n-p "Print the current agenda view ? ")))
  (cond (bool
         (org-agenda-write "~/file.ps")
         (async-shell-command "lp ~/file.ps"))))

Org agenda exporter settings

(setq org-agenda-exporter-settings
      '((ps-print-color-p 'black-white)
        (htmlize-output-type 'css)))

Org bullets

(require 'org-bullets)
(add-hook 'org-mode-hook (lambda () (org-bullets-mode 1)))

Org books

Give rating to book:

(defun my/org-books-rate-book (position rating)
  "Apply RATING to book at given POSITION."
  (interactive "d\nnRating (stars 1-5): ")
  (if (> rating 0)
      (org-set-property "RATING" (s-repeat rating "★"))))

Disable paredit

(add-hook 'org-mode-hook (lambda ()
                           (electric-pair-mode 0)))

Gnome clock

(add-hook
 'org-mode-hook
 (lambda ()

   ;; Org clock string to Gnome top bar. Needs :
   ;; https://extensions.gnome.org/extension/974/short-memo/
   (defun current-task-to-status ()
     (interactive)
     (if (fboundp 'org-clocking-p)
         (if (org-clocking-p)
             (call-process "dconf" nil nil nil "write"
                           "/org/gnome/shell/extensions/short-memo/message"
                           (concat "'" (org-clock-get-clock-string) "'"))
           (call-process "dconf" nil nil nil "write"
                         "/org/gnome/shell/extensions/short-memo/message"
                         "'No active clock'"))))
   ;; update clock message every minute
   (run-with-timer 0 60 'current-task-to-status)

   ;; update clock immediately on clock-in / clock-out
   (defun my-org-clock-message (old-function &rest arguments)
     (apply old-function arguments)
     (current-task-to-status))
   (advice-add #'org-clock-in :around #'my-org-clock-message)
   (advice-add #'org-clock-out :around #'my-org-clock-message)))

Custom faces

(custom-set-faces
 '(org-block ((t (:height 1.1)))))

Presentations

zpresent is what I use for presentations

(require 'ox-reveal)

(setq org-reveal-root "file:///home/mo/code/reveal.js")

This needs xwidget support

(require 'bodil-revealjs)

Org tempo

(require 'org-tempo)
(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")
 ("n" . "notes")))

Development

Javascript

(add-to-list 'auto-mode-alist '("\\.js\\'" . js2-mode))

Allow not ending with semi-colon

(setq js2-strict-missing-semi-warning nil)

Common Lisp

set inferior lisp program.

(setq inferior-lisp-program "sbcl"
      slime-contribs '(slime-fancy))

CL hook:

(add-hook 'lisp-mode-hook (lambda ()
                           (paredit-mode)))

Python

I'm a heavy python user, but my config is less than 2 instructions, which is great since elpy offers tons of things out of the box

(elpy-enable)

(setenv "WORKON_HOME" "/home/mo/.virtualenvs/")

C

Cflow

(autoload 'cflow-mode "cflow-mode")
(setq auto-mode-alist (append auto-mode-alist
                              '(("\\.cflow$" . cflow-mode))))

C++

Setting compile command and recompile key

(add-hook 'c++-mode-hook (lambda ()
                          (when (buffer-file-name)
                            (setq compile-command (concat "g++ -g " (buffer-file-name))))))
(define-key c++-mode-map (kbd "C-c C-r") 'recompile)

Clojure

(add-hook 'clojure-mode-hook (lambda ()
                               (paredit-mode)))

Web dev

I mainly do vuejs, I use ES6, but I use js-mode not js2-mode since MMM-mode doesn't seem to support it.

(require 'vue-mode)
(require 'emmet-mode)
(require 'web-mode)

(setq js-indent-level 2)

(add-hook 'vue-mode-hook 'emmet-mode)
(add-hook 'css-mode-hook 'emmet-mode)
(add-hook 'web-mode-hook 'emmet-mode)

(add-to-list 'auto-mode-alist '("\\.html?\\'" . web-mode))

Elisp

Enable show-paren and paredit for Emacs lisp code

(add-hook 'emacs-lisp-mode-hook (lambda ()
                                  (show-paren-mode 1)
                                  (paredit-mode 1)))

Pomodoro

I use the pomodoro technique when working on writing or programming projects

(require 'pomodoro) 
(pomodoro-add-to-mode-line)

Prettify symbols

Some stuff to prettify

Prog-mode

(global-prettify-symbols-mode 1)
(add-hook 'prog-mode-hook
          (lambda ()
            (push '("!="      . ?≠) prettify-symbols-alist)
            (push '("<="      . ?≤) prettify-symbols-alist)
            (push '(">="      . ?≥) prettify-symbols-alist)
            (push '("alpha"   . ?α) prettify-symbols-alist)
            (push '("beta"    . ?β) prettify-symbols-alist)
            (push '("gamma"   . ?γ) prettify-symbols-alist)
            (push '("delta"   . ?Δ) prettify-symbols-alist)
            (push '("epsilon" . ?ε) prettify-symbols-alist)
            (push '("theta"   . ?θ) prettify-symbols-alist)
            (push '("pi"      . ?π) prettify-symbols-alist)
            (push '("sqrt"    . ?√) prettify-symbols-alist)))

Python-mode

(add-hook 'python-mode-hook
          (lambda ()
            (electric-pair-mode 1)
            (push '("def" . ?ƒ) prettify-symbols-alist)
            (push '("sum" . ?∑) prettify-symbols-alist)
            (push '("**2" . ?²) prettify-symbols-alist)
            (push '("**3" . ?³) prettify-symbols-alist)))

Unprettify at point

(setq prettify-symbols-unprettify-at-point t)

Projectile

(require 'projectile)
(define-key projectile-mode-map (kbd "C-c p") 'projectile-command-map)
(projectile-mode 1)    

use grep only on files tracked by git

(setq projectile-use-git-grep nil)

enable counsel-projectile

(require 'counsel-projectile)
(counsel-projectile-mode 1)

Elfeed

(require 'elfeed)

(load-file (expand-file-name "~/feeds.el"))

set default search filter

(setq  elfeed-search-filter "@1-week-ago +unread")

Magit

I use magit and magithub to work with github

(require 'magit)
;; (require 'magithub)
(global-set-key (kbd "C-x g") 'magit-status)
;; (magithub-feature-autoinject t)
(put 'magit-clean 'disabled nil)

(global-set-key (kbd "<f12>") 'menu-bar-mode)

This needs github's hub installed.

Images

(require 'image+)

hydra stuff

(eval-after-load 'image+
  `(when (require 'hydra nil t)
     (defhydra imagex-sticky-binding (global-map "C-x C-l")
       "Manipulating Image"
       ("+" imagex-sticky-zoom-in "zoom in")
       ("-" imagex-sticky-zoom-out "zoom out")
       ("M" imagex-sticky-maximize "maximize")
       ("O" imagex-sticky-restore-original "restore original")
       ("S" imagex-sticky-save-image "save file")
       ("r" imagex-sticky-rotate-right "rotate right")
       ("l" imagex-sticky-rotate-left "rotate left"))))
(imagex-global-sticky-mode 1)

W3m

Set default search engine

(setq w3m-search-default-engine "duckduckgo")

Key chord

First require key chord

(require 'key-chord)
(key-chord-mode +1)

Switch to previous buffer

from bbatsov's blog

(defun switch-to-previous-buffer ()
  "Switch to previously open buffer.
Repeated invocations toggle between the two most recently open buffers."
  (interactive)
  (switch-to-buffer (other-buffer (current-buffer) 1)))

(key-chord-define-global "JJ" 'switch-to-previous-buffer)

Find file

(key-chord-define-global "FF" #'counsel-find-file)

Beginning and end of buffer

(key-chord-define-global "jk" 'beginning-of-buffer)
(key-chord-define-global "JK" 'end-of-buffer)

Ace-jump

(key-chord-define-global "jj" 'ace-jump-mode)

Other

Increment and decrements numbers

Functions to replicate the Vim feature to increment and decrement number at point.

(defun number-at-point (fn)
  (skip-chars-backward "0-9")
  (or (looking-at "[0-9]+")
      (error "No number at point"))
  (replace-match (number-to-string (funcall fn (string-to-number (match-string 0))))))

(defun increment-number-at-point()
  (interactive)
  (number-at-point '1+))

(defun decrement-number-at-point()
  (interactive)
  (number-at-point '1-))


(global-set-key (kbd "C-c +") 'increment-number-at-point)
(global-set-key (kbd "C-c -") 'decrement-number-at-point)

To "zoom" in and out using mouse

Sometimes I like to use my mouse for stuff

(global-set-key [C-mouse-4] 'text-scale-increase)
(global-set-key [C-mouse-5] 'text-scale-decrease)

Resize window interactively

Resize windows in speed, I use resize-window it is not position aware, meaning if I'm in the bottom most window it isn't as natural as if resize from the left most window, this happens also in i3wm so I think it's normal, also I don't think it's hard to implement so I would love to see this feature.

(require 'resize-window)
(global-set-key (kbd "C-c ;") 'resize-window)

Winner

This just returns to the previous window configuration, sadly it doesn't work as excepted when using perspective mode, I hope it gets fixed though

(winner-mode 1)

yas

(yas-global-mode 1)

expand region

This package is very helpful to navigate code, it's most helpful in languages that use S-expressions which are mainly lisps, but it also works with C and Javascript

(require 'expand-region)
(global-set-key (kbd "C-c =") 'er/expand-region)

ace-jump mode

(require 'ace-jump-mode)
(define-key global-map (kbd "C-c SPC") 'ace-jump-mode)
(define-key global-map (kbd "C-x SPC") 'ace-jump-mode-pop-mark)

Recreate scratch buffer

just recreates scratch buffer when it's killed, I got this from the EmacsWiki

(with-current-buffer "*scratch*"
  (lisp-interaction-mode)
  (make-local-variable 'kill-buffer-query-functions)
  (add-hook 'kill-buffer-query-functions 'kill-scratch-buffer))

(defun kill-scratch-buffer ()
  ;; The next line is just in case someone calls this manually
  (set-buffer (get-buffer-create "*scratch*"))
  ;; Kill the current (*scratch*) buffer
  (remove-hook 'kill-buffer-query-functions 'kill-scratch-buffer)
  (kill-buffer (current-buffer))
  ;; Make a brand new *scratch* buffer
  (set-buffer (get-buffer-create "*scratch*"))
  (lisp-interaction-mode)
  (make-local-variable 'kill-buffer-query-functions)
  (add-hook 'kill-buffer-query-functions 'kill-scratch-buffer)
  ;; Since we killed it, don't let caller do that.
  nil)

Backups

Save backups in another directory

(setq backup-directory-alist '(("." . "~/.emacs.d/backup"))
      backup-by-copying t    ; Don't delink hardlinks
      version-control t      ; Use version numbers on backups
      delete-old-versions t  ; Automatically delete excess backups
      kept-new-versions 20   ; how many of the newest versions to keep
      kept-old-versions 5    ; and how many of the old
      )

Web browser

sets my default web browser

(setq browse-url-chrome-program "/usr/bin/google-chrome")
(setq browse-url-browser-function 'browse-url-chrome)

Smarter beginning of line

I got this from sacha chua's config which she got from crux package I think

(defun my/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))))

;; remap C-a to `smarter-move-beginning-of-line'
(global-set-key [remap move-beginning-of-line]
                'my/smarter-move-beginning-of-line)

Add timestamp

Adds timestamp before saving each file

(add-hook 'before-save-hook 'time-stamp)

Tramp sudo edit

Use tramp to edit files with root, I got this from bbatsov blog

(defun sudo-edit (&optional arg)
  "Edit currently visited file as root.
With a prefix ARG prompt for a file to visit.
Will also prompt for a file to visit if current
buffer is not visiting a file."
  (interactive "P")
  (if (or arg (not buffer-file-name))
      (find-file (concat "/sudo:root@localhost:"
                         (ido-read-file-name "Find file(as root): ")))
    (find-alternate-file (concat "/sudo:root@localhost:" buffer-file-name))))

Company mode

(require 'company)
(add-hook 'after-init-hook 'global-company-mode)

Terminal stuff

Stuff I use when I run Emacs in a terminal emulator

(define-key input-decode-map "\e[1;2A" [S-up])
(define-key input-decode-map "\e[1;2B" [S-down])
;; xclip
(require 'xclip)
(xclip-mode 1)
;; let the terminal decide the background color
(custom-set-faces (if (not window-system) '(default ((t (:background "nil"))))))
;; to avoid delay in terminal
(setq-default xterm-query-timeout nil)

This needs xclip installed on the machine to facilitate copying and pasting between Emacs and other X windows.

Scratch message

(setq initial-scratch-message ";; ╔═╗┌─┐┬─┐┌─┐┌┬┐┌─┐┬ ┬\n;; ╚═╗│  ├┬┘├─┤ │ │  ├─┤\n;; ╚═╝└─┘┴└─┴ ┴ ┴ └─┘┴ ┴\n\n")
(setq inhibit-startup-screen t)

Proced

auto update proced

(defun proced-settings ()
  (proced-toggle-auto-update 1))

Hide some minor modes

Hide some minor modes

(defvar hidden-minor-modes

  '(flycheck-mode
    flyspell-mode
    highlight-parentheses-mode
    paredit-mode
    auto-revert-mode
    which-key-mode
    abbrev-mode
    visual-line-mode
    emmet-mode
    mmm-mode
    highlight-indentation-mode
    elpy-mode
    projectile-mode
    dired-async-mode
    ivy-mode))

(defun purge-minor-modes ()
  (interactive)
  (dolist (x hidden-minor-modes nil)
    (diminish x)))

(add-hook 'after-change-major-mode-hook 'purge-minor-modes)

ace-window

This is like ace-jump but for windows

(require 'ace-window)
(global-set-key (kbd "C-x o") 'ace-window)

set scope to frame

(setq aw-scope 'frame)

Flycheck

(require 'flycheck)
(global-flycheck-mode 1)

require engine-search

Some other packages I require

(require 'engine-search)

Windmove

(global-set-key (kbd "S-<up>") 'windmove-up)
(global-set-key (kbd "S-<down>") 'windmove-down)
(global-set-key (kbd "S-<left>") 'windmove-left)
(global-set-key (kbd "S-<right>") 'windmove-right)

Startup

(switch-to-buffer "*scratch*")

Tea

Timer code for brewing my tea.

(require 'tea-time)
(setq tea-time-sound-command "espeak  \"Your tea is ready\"")
(setq tea-time-sound t)
(define-key global-map "\C-ct" 'tea-time)

Multi term

This will toggle and select a dedicated multi term buffer.

(global-set-key (kbd "C-c x") (lambda ()
                                (interactive)
                                (require 'multi-term)
                                (multi-term-dedicated-toggle)
                                (multi-term-dedicated-select)))

Add term-line-mode and char-line-mode keybindings

(eval-after-load 'multi-term
  `(setq term-bind-key-alist
         (cons '("C-c C-z" . term-stop-subjob)
               (cons '("C-c C-k" . term-char-mode)
                     (cons '("C-c C-l" . term-line-mode) term-bind-key-alist)))))

Cursor stuff

(blink-cursor-mode t)
(setq-default cursor-type 'box)

Flip theme function

I use a light theme in the morning with colors and all because I work besides my window and it's always sunny where I live so a dark color scheme is not good for my eyes.

In the evening I just use a dark theme like most people do

(defvar *last-theme* dark-theme
  "The last recorded theme")

(defun flip-theme ()
  (interactive)
  (if (eq light-theme *last-theme*)
      (progn
        (setq *last-theme* dark-theme)
        (disable-theme light-theme)
        (load-theme dark-theme)
        (custom-set-faces
       '(default ((t (:height 113 :stipple nil :background nil :foreground nil :inverse-video nil :box nil :strike-through nil :overline nil :underline nil :slant normal :weight normal :width normal :family "DejaVu Sans Mono"))))))
    (progn
      (disable-theme dark-theme)
      (custom-set-faces
       '(default ((t (:height 113 :stipple nil :background nil :foreground nil :inverse-video nil :box nil :strike-through nil :overline nil :underline nil :slant normal :weight normal :width normal :family "DejaVu Sans Mono")))))
      (setq *last-theme* light-theme)
      (load-theme light-theme))))

Paredit stuff

(define-key paredit-mode-map (kbd "{") 'paredit-open-curly)

Hl line mode

(global-hl-line-mode 1)

Make prompts y or n

(fset 'yes-or-no-p 'y-or-n-p)

Setting the executable directory for gtags

(setq ggtags-executable-directory "/usr/bin")

Display current time

(defun get-current-time ()
  (interactive)
  (message (format-time-string "%H:%M %b %d %a")))

Mitigate slow next-line

(setq auto-window-vscroll nil)

Enable ggtags mode

(add-hook 'c-mode-common-hook
          (lambda ()
            (when (derived-mode-p 'c-mode 'c++-mode 'java-mode)
              (ggtags-mode 1))))

Pinentry

(setq epa-pinentry-mode 'loopback)

Start server

(if (not (boundp 'dontstartserver))
    (server-start))

Author: Mohamed Aziz Knani

Date: 2019-12-10 Tue 17:47

Emacs 26.3 (Org mode 9.2.6)

Validate

hacker emblem