   "Insert string for the current time formatted like '[HH:MM]'."
   (interactive)
   (insert (format-time-string "[%H:%M] ")))
+
+(defun esel/kill-dired-buffers ()
+  (interactive)
+  (mapc (lambda (buffer)
+          (when (eq 'dired-mode (buffer-local-value 'major-mode buffer))
+            (kill-buffer buffer)))
+        (buffer-list)))
+
+(defun esel/sync-gpu-submodules ()
+  (interactive)
+  (magit-shell-command-topdir "git submodule sync && git submodule update --init --force"))
+
+(defun esel/narrow-or-widen-dwim (p)
+    "Widen if buffer is narrowed, narrow-dwim otherwise.
+Dwim means: region, org-src-block, org-subtree, or defun,
+whichever applies first. Narrowing to org-src-block actually
+calls `org-edit-src-code'.
+
+With prefix P, don't widen, just narrow even if buffer
+is already narrowed."
+    (interactive "P")
+    (declare (interactive-only))
+    (cond ((and (buffer-narrowed-p) (not p)) (widen))
+          ((region-active-p)
+           (narrow-to-region (region-beginning)
+                             (region-end)))
+          ((derived-mode-p 'org-mode)
+           ;; `org-edit-src-code' is not a real narrowing
+           ;; command. Remove this first conditional if
+           ;; you don't want it.
+           (cond ((ignore-errors (org-edit-src-code) t)
+                  (delete-other-windows))
+                 ((ignore-errors (org-narrow-to-block) t))
+                 (t (org-narrow-to-subtree))))
+          ((derived-mode-p 'latex-mode)
+           (LaTeX-narrow-to-environment))
+                  (t (narrow-to-defun))))
+
+;; ediff usability enhancements, from https://oremacs.com/2015/01/17/setting-up-ediff/
+(csetq ediff-window-setup-function 'ediff-setup-windows-plain)
+(csetq ediff-split-window-function 'split-window-horizontally)
+(csetq ediff-diff-options "-w")
+
+(winner-mode)
+(add-hook 'ediff-after-quit-hook-internal 'winner-undo)
+
+(csetq magit-diff-use-overlays nil)
+(csetq magit-log-margin-show-committer-date t)
+(csetq org-confirm-babel-evaluate nil)
+(csetq send-mail-function 'sendmail-send-it)
+(csetq sentence-end-double-space nil)
+(csetq org-duration-format 'h:mm)
+
+(setq ivy-use-virtual-buffers t)
+(global-set-key (kbd "C-x l") 'counsel-locate)
+(global-set-key (kbd "C-c b") 'counsel-bookmark)
+(global-set-key (kbd "C-c g") 'counsel-git)
+
+;; System locale to use for formatting time values.
+; Make sure that the weekdays in the time stamps of your Org mode
+; files and in the agenda appear in English.
+(setq system-time-locale "C")
+
+(ignore-errors
+  (push (format "%s/share/emacs/site-lisp"
+                (string-trim (shell-command-to-string "opam config var prefix 2> /dev/null")))
+        load-path))
+
+;; Multi-file search-and-replace from dired should use the function
+;; that respects emacs variables.
+(with-eval-after-load 'dired
+  (define-key dired-mode-map (kbd "Q") 'dired-do-query-replace-regexp))
+
+(defun esel/dont-kill-emacs()
+  "Disable C-x C-c binding execute kill-emacs."
+  (interactive)
+  (error (substitute-command-keys "To exit emacs: \\[kill-emacs]")))
+(global-set-key (kbd "C-x C-c") 'esel/dont-kill-emacs)
+
+;; ============================================================
+;; Automatic stuff below.
+;; ============================================================
+

(global-set-key (kbd "<S-C-up>") (lambda () (interactive) (shrink-window -1)))
(global-set-key (kbd "<S-C-up>") (lambda () (interactive) (shrink-window -1)))
(global-set-key (kbd "C-x C-r") 'ido-recentf-open)

;; Org-mode tables are best without truncation, but prose looks best with.
(global-set-key (kbd "<f1>") 'toggle-truncate-lines)
;; Insert current time
(global-set-key (kbd "<f2>") 'esel/now)

(menu-bar-mode -1)
(tool-bar-mode -1)

(defvar bootstrap-version)
(let ((bootstrap-file
       (expand-file-name "straight/repos/straight.el/bootstrap.el" user-emacs-directory))
      (bootstrap-version 5))
  (unless (file-exists-p bootstrap-file)
    (with-current-buffer
(url-retrieve-synchronously
"https://raw.githubusercontent.com/raxod502/straight.el/develop/install.el"
'silent 'inhibit-cookies)
      (goto-char (point-max))
      (eval-print-last-sexp)))
  (load bootstrap-file nil 'nomessage))

(straight-use-package 'use-package)
(setq straight-use-package-by-default t)

;; From https://oremacs.com/2015/01/17/setting-up-ediff/
(defmacro csetq (variable value)
  `(funcall (or (get ',variable 'custom-set)
                'set-default)
            ',variable ,value))

(use-package guix)

(use-package geiser)

(use-package undo-tree
  :config (progn (global-undo-tree-mode)))

;; NOTE: I don't want to use ivy since I prefer selectrum and friends.
;; However I do like some functions in counsel. I can pull in counsel
;; without enabling (ivy-mode) or (counsel-mode) and it seems to work
;; fine.
(use-package counsel)

(use-package selectrum
  :config (selectrum-mode +1))

(use-package prescient)
(use-package company-prescient)
(use-package selectrum-prescient
  :config
  (progn
    (company-prescient-mode +1)
    (selectrum-prescient-mode +1)
    (prescient-persist-mode +1)))

(use-package ctrlf
  :config (ctrlf-mode +1))

(use-package deadgrep
  :bind ("<f5>" . deadgrep))

(use-package magit
  :bind (("C-x g" . magit-status)
         ("C-x M-g" . magit-dispatch))
  :config
  (progn
    ;; Disabled submodule section because it slows things down quite a bit.
    ;;(magit-add-section-hook 'magit-status-sections-hook 'magit-insert-modules nil t nil)
    ;; Ensure we can write commit messages in org-mode!
    (setq git-commit-major-mode 'org-mode)))

(use-package ace-window
  :bind ("M-o" . ace-window))

(use-package beacon
  :config
  (beacon-mode 1))

(use-package company
  :init (global-company-mode)
  :config
  (progn
    ;; Use Company for completion
    (bind-key [remap completion-at-point] #'company-complete company-mode-map)

    ;; Disable silly completions
    (push (apply-partially #'cl-remove-if
                         (lambda (c)
                         (or (string-match-p "[^\x00-\x7F]+" c) ;; remove non-ansi strings
                             (string-match-p "^[0-9]+" c))))    ;; remove strings starting with numbers
          company-transformers)))

(with-eval-after-load 'company
  (define-key company-active-map (kbd "M-n") nil)
  (define-key company-active-map (kbd "M-p") nil)
  (define-key company-active-map (kbd "C-n") #'company-select-next)
  (define-key company-active-map (kbd "C-p") #'company-select-previous)
  (define-key company-active-map (kbd "C-j") #'company-complete))

(use-package smartparens
  :config
  (progn
    (show-smartparens-global-mode t)
    (define-key smartparens-mode-map (kbd "C-M-f") 'sp-forward-sexp)
    (define-key smartparens-mode-map (kbd "C-M-b") 'sp-backward-sexp)
    (define-key smartparens-mode-map (kbd "C-M-d") 'sp-down-sexp)
    (define-key smartparens-mode-map (kbd "C-M-a") 'sp-backward-down-sexp)
    (define-key smartparens-mode-map (kbd "C-S-d") 'sp-beginning-of-sexp)
    (define-key smartparens-mode-map (kbd "C-S-a") 'sp-end-of-sexp)
    (define-key smartparens-mode-map (kbd "C-M-e") 'sp-up-sexp)
    (define-key smartparens-mode-map (kbd "C-M-u") 'sp-backward-up-sexp)
    (define-key smartparens-mode-map (kbd "C-M-t") 'sp-transpose-sexp)
    (define-key smartparens-mode-map (kbd "C-M-n") 'sp-forward-hybrid-sexp)
    (define-key smartparens-mode-map (kbd "C-M-p") 'sp-backward-hybrid-sexp)
    (define-key smartparens-mode-map (kbd "C-M-k") 'sp-kill-sexp)
    (define-key smartparens-mode-map (kbd "C-M-w") 'sp-copy-sexp)
    (define-key smartparens-mode-map (kbd "M-<delete>") 'sp-unwrap-sexp)
    (define-key smartparens-mode-map (kbd "M-<backspace>") 'sp-backward-unwrap-sexp)
    (define-key smartparens-mode-map (kbd "C-<right>") 'sp-forward-slurp-sexp)
    (define-key smartparens-mode-map (kbd "C-<left>") 'sp-forward-barf-sexp)
    (define-key smartparens-mode-map (kbd "C-M-<left>") 'sp-backward-slurp-sexp)
    (define-key smartparens-mode-map (kbd "C-M-<right>") 'sp-backward-barf-sexp)
    (define-key smartparens-mode-map (kbd "M-D") 'sp-splice-sexp)
    (define-key smartparens-mode-map (kbd "C-M-<delete>") 'sp-splice-sexp-killing-forward)
    (define-key smartparens-mode-map (kbd "C-M-<backspace>") 'sp-splice-sexp-killing-backward)
    (define-key smartparens-mode-map (kbd "C-S-<backspace>") 'sp-splice-sexp-killing-around)
    (define-key smartparens-mode-map (kbd "C-]") 'sp-select-next-thing-exchange)
    (define-key smartparens-mode-map (kbd "C-<left_bracket>") 'sp-select-previous-thing)
    (define-key smartparens-mode-map (kbd "C-M-]") 'sp-select-next-thing)
    (define-key smartparens-mode-map (kbd "M-F") 'sp-forward-symbol)
    (define-key smartparens-mode-map (kbd "M-B") 'sp-backward-symbol)
    (define-key smartparens-mode-map (kbd "C-\"") 'sp-change-inner)
    (define-key smartparens-mode-map (kbd "M-i") 'sp-change-enclosing)))

(add-hook 'prog-mode-hook 'turn-on-smartparens-mode)
(add-hook 'markdown-mode-hook 'turn-on-smartparens-mode)

(use-package monokai-theme
  :config
  (load-theme 'monokai t))

(use-package tuareg)

(use-package ocp-indent
  :after tuareg)

(use-package merlin
  :after tuareg
  :config
  (add-hook 'tuareg-mode-hook 'merlin-mode t))

(use-package scala-mode
  :mode "\\.s\\(cala\\|bt\\)$"
  :config (csetq scala-indent:step 4))

(use-package htmlize)

(use-package org
  :after htmlize
  :config
  (progn
    (global-set-key (kbd "<f1>") 'org-clock-in-last)
    (global-set-key (kbd "<f2>") 'org-clock-out)
    (global-set-key (kbd "<f12>") 'org-agenda)
    (global-set-key (kbd "C-c c") 'org-capture)
    (global-set-key (kbd "C-c s") 'org-insert-structure-template)
    (global-set-key (kbd "C-c l") 'org-store-link)

    (setq org-agenda-window-setup (quote current-window))
    (setq org-directory (quote "~/org"))
    (setq org-agenda-files (quote ("~/org")))
    (setq org-default-notes-file (concat org-directory "/refile.org"))
    (setq org-adapt-indentation nil)
    (setq org-completion-use-ido t)
    ;; Targets include this file and any file contributing to the agenda - up to 9 levels deep
    (setq org-refile-targets (quote ((nil :maxlevel . 9)
