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

(setq inhibit-startup-message t)
(defalias 'yes-or-no-p 'y-or-n-p)

(set-face-attribute 'default nil :font "FiraCode Nerd Font Mono" :height 49)

(require 'package)
(setq package-archives nil)
(package-initialize)
(require 'use-package)
(use-package use-package-ensure-system-package :ensure t)

(require 'evil)
(evil-mode 1)

(editorconfig-mode 1)

(require 'edit-server)
(edit-server-start)

(require 'mediawiki)
(setq mediawiki-mode-hook
      (lambda ()
	(define-key mediawiki-mode-map (kbd "<C-left>") nil)
	(define-key mediawiki-mode-map (kbd "<C-right>") nil)))

(require 'typescript-mode)

(global-subword-mode)
(global-undo-tree-mode)
(global-fira-code-mode)

(evil-set-undo-system 'undo-tree)

(global-set-key (kbd "RET") 'newline-and-indent)
(global-set-key (kbd "M-g") 'magit-status)
(global-set-key (kbd "M-?") 'vc-git-grep)

(require 'git-gutter)
(global-git-gutter-mode t)
(custom-set-variables '(git-gutter:update-interval 2))
(custom-set-variables '(git-gutter:hide-gutter t))

;; (require 'scratch)
(global-set-key (kbd "C-x B") 'scratch-create)
(setq initial-major-mode 'scratch-mode)
(setq initial-scratch-message "")

(global-set-key (kbd "C-x K") 'kill-current-buffer)

(setq backup-directory-alist `(("." . "~/.saves")))
(setq undo-tree-history-directory-alist `(("." . "~/.undo")))
(setq delete-old-versions t
      kept-new-versions 6
      kept-old-versions 2
      version-control t)

(setq undo-tree-visualizer-timestamps t
      undo-tree-visualizer-diff t
      ;; 10X bump of the undo limits to avoid issues with premature
      ;; Emacs GC which truncages the undo history very aggresively
      undo-limit 800000
      undo-strong-limit 12000000
      undo-outer-limit 120000000)

(add-hook 'haskell-mode-hook 'haskell-indentation-mode)
(add-hook 'haskell-mode-hook 'subword-mode)
(add-hook 'haskell-mode-hook 'highlight-symbol-mode)
(add-hook 'haskell-mode-hook 'highlight-paretheses-mode)

(add-hook 'js-mode-hook 'highlight-symbol-mode)
(add-hook 'js-mode-hook 'highlight-parentheses-mode)
(defun my-js-mode-hook ()
  "Custom `js-mode' behaviours."
  (setq js-indent-level 2)
  )
(add-hook 'js-mode-hook 'my-js-mode-hook)

(setq undo-tree-auto-save-history t)

(defvar expand-file-name-custom-tilde-alist '(("u2w-dev1" . "/ssh:uni2work-dev1:/home/gkleen/projects/uni2work") ("fradrive-dev1" . "/ssh:uni2work-dev1:/home/gkleen/projects/fradrive") ("u2w-srv01" . "/ssh:srv01.uniworx.de:/home/gkleen/projects/uni2work")))
(defun my/add-to-tilde-alist (hash)
  (let* ((tilde:dir (split-string hash "="))
	 (tilde (car tilde:dir))
	 (dir (cadr tilde:dir)))
    (push (cons tilde dir) expand-file-name-custom-tilde-alist)))
(mapc #'my/add-to-tilde-alist
      (split-string (let ((process-environment (cl-copy-list process-environment))) (setenv "TERM" nil) (with-output-to-string (call-process "script" nil standard-output nil "-qec" "zsh -ic \"hash -d\"" "/dev/null")))
		    "\r\n" t))

(defadvice expand-file-name (before expand-file-name-custom-tilde
                             (name &optional default-directory)
                             activate compile)
  "User-defined expansions for ~NAME in file names."
  (save-match-data
    (when (string-match "\\`\\(\\(.*/\\)?~\\([^:/]+\\)\\)/" name)
      (let ((replacement (assoc (match-string 3 name) expand-file-name-custom-tilde-alist)))
        (when replacement
          (setq name (replace-match (cdr replacement) t t name 1)))))))

(setq edit-server-new-frame nil)
(setq edit-server-url-major-mode-alist '(("rzint\\.mathinst\\.loc" . mediawiki-mode)))

;; (setq notmuch-address-internal-completion '(received nil))
;; (setq notmuch-always-prompt-for-sender t)
;; (setq notmuch-command "notmuch-ssh")
;; (setq notmuch-crypto-process-mime t)
;; (setq notmuch-draft-tags '("+draft" "-inbox"))
;; (setq notmuch-fcc-dirs nil)
;; (setq notmuch-hello-sections '(notmuch-hello-insert-header notmuch-hello-insert-saved-searches))
;; (setq notmuch-hello-thousands-separator " ")
;; (setq notmuch-identities '("gkleen@yggdrasil.li" "g@141.li" "kleen@cip.ifi.lmu.de" "Gregor.Kleen@stud.ifi.lmu.de" "G.Kleen@campus.lmu.de" "G.Kleen@lmu.de" "gregor.kleen@ifi.lmu.de" "uni2work@ifi.lmu.de" "gregor@kleen.li"))
;; (setq notmuch-message-headers '("Subject" "To" "Cc" "Date"))
;; (setq notmuch-message-replied-tags '("+replied" "-unread" "-inbox"))
;; (setq notmuch-saved-searches
;;       (quote
;;        ((:name "inbox" :query "tag:inbox" :key "i")
;; 	(:name "unread" :query "tag:unread AND tag:inbox" :key "u")
;; 	(:name "drafts" :query "tag:draft" :key "d")
;; 	(:name "all mail" :query "date:month.." :key "a" :count-query "*")
;; 	(:name "sent" :query "is:sent" :key "s" :count-query "is:sent")
;;       )))
;; (setq notmuch-search-oldest-first nil)
;; (setq notmuch-show-all-tags-list t)
;; (setq notmuch-show-logo nil)

(setq send-mail-function 'sendmail-send-it)
(setq mail-envelope-from 'header)
(setq mail-specify-envelope-from 't)
(setq mail-default-headers nil)
(setq message-default-headers "")
(setq message-default-mail-headers "")
(setq message-sendmail-envelope-from 'header)

(setq highlight-symbol-idle-delay 0)

(setq indent-tabs-mode nil)

(setq ido-enable-flex-matching t)
(setq ido-everywhere t)
(ido-mode 1)

(setq tramp-default-method "ssh")
(customize-set-variable 'tramp-use-ssh-controlmaster-options nil)
(setq tramp-allow-unsafe-temporary-files t)

(setq direnv-enabled-hosts '("uni2work-dev1"))

(setq auth-sources '())

(setq ring-bell-function 'ignore)

(setq-default indicate-empty-lines t)
(setq-default show-trailing-whitespace t)

(defun tramp-sh-handle-start-file-process@my-direnv (args)
  "Enable Direnv for hosts in `direnv-enabled-hosts'."
  (with-parsed-tramp-file-name (expand-file-name default-directory) nil
    (if (member host direnv-enabled-hosts)
        (pcase-let ((`(,name ,buffer ,program . ,args) args))
          `(,name
            ,buffer
            "direnv"
            "exec"
            ,localname
            ,program
            ,@args))
      args)))

(with-eval-after-load "tramp-sh"
  (advice-add 'tramp-sh-handle-start-file-process
              :filter-args #'tramp-sh-handle-start-file-process@my-direnv))

(setq mail-host-address "sif.midgard.yggdrasil")
(setq user-full-name "Gregor Kleen")

(defun tell-emacsclients-for-buffer-to-die ()
  "Sends error exit command to every client for the current buffer."
  (interactive)
  (dolist (proc server-buffer-clients)
    (server-send-string proc "-error die")))

(defun kill-buffer-with-special-emacsclient-handling ()
  "Wrapper around kill-buffer that ensures tell-emacsclients-for-buffer-to-die is on the hooks"
  (interactive)
  (add-hook 'kill-buffer-hook 'tell-emacsclients-for-buffer-to-die nil t)
  (kill-buffer))

;; (global-set-key (kbd "C-x k") 'kill-buffer)

(defun install-emacsclient-wrapped-kill-buffer ()
  "Installs wrapped kill-buffer with special emacsclient handling.
Best not to install it unconditionally because the server is not
necessarily running."
  (interactive)
  (global-set-key (kbd "C-x k") 'kill-buffer-with-special-emacsclient-handling))

(add-hook 'server-switch-hook 'install-emacsclient-wrapped-kill-buffer)

(defun move-file (new-location)
  "Write this file to NEW-LOCATION, and delete the old one."
  (interactive (list (expand-file-name
                      (if buffer-file-name
                          (read-file-name "Move file to: ")
                        (read-file-name "Move file to: "
                                        default-directory
                                        (expand-file-name (file-name-nondirectory (buffer-name))
                                                          default-directory))))))
  (when (file-exists-p new-location)
    (delete-file new-location))
  (let ((old-location (expand-file-name (buffer-file-name))))
    (message "old file is %s and new file is %s"
             old-location
             new-location)
    (write-file new-location t)
    (when (and old-location
               (file-exists-p new-location)
               (not (string-equal old-location new-location)))
      (delete-file old-location))))

(bind-key "C-x C-m" #'move-file)