   "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)

                               (?B . (:foreground "LightSteelBlue"))
                               (?C . (:foreground "OliveDrab"))))
    (setq org-capture-templates
          '(("t" "Todo" entry (file+headline "~/org/todo.org" "Tasks")
             "* TODO [#A] %?")
            ("j" "Journal" entry (file+datetree "~/org/journal.org")
             "* %U\n  %?")
            ("i" "Idea" entry (file+headline "~/org/idea.org" "Ideas")
             "* %?\n  %U")
            ("r" "Read" entry (file+headline "~/org/read.org" "Read")
             "* %?\n  %U")))
    (setq org-log-done 'time)
    (setq org-log-into-drawer t)
    (setq org-babel-python-command "python3")
    (org-babel-do-load-languages
     'org-babel-load-languages
     '((emacs-lisp . t)
       (python . t)
       (shell . t)))))

(use-package org-roam
  :after org
  :hook
  (after-init . org-roam-mode)
  :custom
  (org-roam-directory "~/org/ideas")
  :bind (:map org-roam-mode-map
              (("C-c z l" . org-roam)
               ("C-c z f" . org-roam-find-file)
               ("C-c z g" . org-roam-show-graph))
              :map org-mode-map
              (("C-c z i" . org-roam-insert))))

(use-package deft
  :bind ("<f8>" . deft)
  :commands (deft)
  :config
  (setq deft-auto-save-interval 0)
  (setq deft-default-extension "org")
  (setq deft-directory "~/org/ideas"))

;; ===============================================================
;; Misc
;; ===============================================================

;; Macbook "command" key should be meta because it's next to "space" where alt normally is
(setq ns-command-modifier (quote meta))
