;; Cheatsheet

;; Projectile - open project    C-c p p
;; Projectile - open file       C-c p f
;; Projectile - ag search       C-c p s s
;; Projectile - jump in file    C-c p j
;; Projectile - replace         C-c p r
;; Windows - split horizontally C-x 2
;; Windows - spit vertically    C-x 3
;; Cycle through windows        C-x 0
;; Go to line                   M-g g [linenum] <RET>
;; Column edition               C-SPC, then <DOWN>, then C-x r t
;; Rectangle kill               C-SPC, then mv, then C-x r k



;; Package management

(require 'package)
(setq package-enable-at-startup nil)
(add-to-list 'package-archives '("melpa" . "http://melpa.org/packages/"))
(add-to-list 'package-archives '("marmalade" . "http://marmalade-repo.org/packages/"))
(add-to-list 'package-archives '("gnu" . "http://elpa.gnu.org/packages/"))

(package-initialize)

(unless (package-installed-p 'use-package)
  (package-refresh-contents)
  (package-install 'use-package))

(eval-when-compile
  (require 'use-package))


;; Ask "y" or "n" instead of "yes" or "no". Yes, laziness is great.

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

;; Highlight corresponding parentheses when cursor is on one

(show-paren-mode t)

;; Highlight tabulations

(setq-default highlight-tabs t)

;; Show trailing white spaces

(setq-default show-trailing-whitespace t)

;; Remove useless whitespace before saving a file

(add-hook 'before-save-hook 'whitespace-cleanup)
(add-hook 'before-save-hook (lambda() (delete-trailing-whitespace)))

;; Final newline handling

(setq require-final-newline t)

;; Save do not use backup files (we have git for this)

(setq backup-directory-alist '(("." . "~/.saves")))
(setq make-backup-files nil)
(setq auto-save-default nil)
(setq create-lockfiles nil)

(setq inhibit-splash-screen t
      initial-scratch-message nil)
(scroll-bar-mode -1)
(tool-bar-mode -1)
(menu-bar-mode -1)
(setq column-number-mode t)
(electric-pair-mode 1)

;; Replace audible alarm with a visual bell

(setq ring-bell-function
      (lambda ()
	(let ((orig-fg (face-foreground 'mode-line)))
	  (set-face-foreground 'mode-line "#F2804F")
	  (run-with-idle-timer 0.1 nil
			       (lambda (fg) (set-face-foreground 'mode-line fg))
			       orig-fg))))

;; Useful when coding

(global-set-key (kbd "C-c C-c") 'comment-or-uncomment-region)

;; Better modeline

(use-package smart-mode-line
  :ensure t
  :init
  (setq sml/no-confirm-load-theme t)
  (setq sml/theme 'dark)
  (sml/setup))

;; Tabs

;; (use-package centaur-tabs
;;   :ensure t
;;   :demand
;;   :config
;;   (centaur-tabs-mode t)
;;   (setq centaur-tabs-set-icons t)
;;   (setq centaur-tabs-set-bar 'under)
;;   (centaur-tabs-group-by-projectile-project)
;;   (centaur-tabs-headline-match)
;;   :bind
;;   ("C-<prior>" . centaur-tabs-backward)
;;   ("C-<next>" . centaur-tabs-forward))

;; Editor theme

(use-package gruvbox-theme
  :ensure t
  :config
  (defun frame-config (frame)
    "Custom behavior on new frames"
    (with-selected-frame frame
      (when (display-graphic-p)
	(setq frame-title-format '(buffer-file-name "%f" ("%b")))
	(set-face-attribute 'default nil
			    :font "Inconsolata-16"))
      (if (display-graphic-p)
	  (load-theme 'gruvbox-dark-hard t)
	(load-theme 'gruvbox-dark-hard t))
      ))
  (frame-config (selected-frame))
  (add-hook 'after-make-frame-functions 'frame-config))


;; Correctly find environment variables

(use-package exec-path-from-shell
  :ensure t
  :init
  (setq shell-file-name "/bin/zsh")
    (setq exec-path-from-shell-variables '("PATH" "MANPATH" "PKG_CONFIG_PATH"))
    (exec-path-from-shell-initialize))

;; Magit -- git mode

(use-package magit
  :ensure t
  :defer t)

;; Helm -- Search tool

(use-package helm
    :ensure t
    :config
    (setq helm-split-window-default-side 'other)
    (helm-mode 1)
    (helm-autoresize-mode 1)
    (define-key helm-find-files-map
      (kbd "<backtab>") #'helm-select-action)
    (define-key helm-find-files-map
      (kbd "C-i")  #'helm-execute-persistent-action)
    :bind
    (("M-x" . helm-M-x)
     ("M-y" . helm-show-kill-ring)
     ("C-x C-f" . helm-find-files)
     ;("C-c o" . helm-occur)
     ("C-x b" . helm-mini)
     ;("C-x r b" . helm-bookmarks)
     ;("C-h a" . helm-apropos)
     ;("C-h d" . helm-info-at-point)
     ;("C-c L" . helm-locate)
     ;("C-c r" . helm-resume)
     ;("C-c i" . helm-imenu)
     ))

(use-package helm-ag
  :ensure t)

;; Projectile -- Project management

(use-package helm-projectile
  :ensure t)

(use-package projectile
  :ensure t
  :config
  (require 'helm)
  (require 'helm-projectile)
  (projectile-mode t)
  (helm-projectile-on)
  (setq projectile-completion-system 'helm)
  (define-key projectile-mode-map (kbd "C-c p") 'projectile-command-map))




;; Company -- Autocompletion

(use-package company
  :ensure t
  :defer t
  :diminish (company-mode . " ⓐ")
  :init
  (global-company-mode)
  :config
  (setq company-tooltip-align-annotations t
	company-idle-delay 0.2
	company-minimum-prefix-length 1
	company-require-match nil
	company-begin-commands '(self-insert-command)
	company-echo-delay 0
	company-tooltip-limit 20
	))

;; Show help in tooltip

(use-package company-quickhelp
    :ensure t
    :defer t
    :init (with-eval-after-load 'company
	    (company-quickhelp-mode)))

;; LSP

(use-package lsp-mode
  :ensure t
  :commands (lsp lsp-deferred)
  :hook (go-mode . lsp-deferred))

(use-package lsp-ui
  :ensure t
  :commands lsp-ui-mode
  :init
  (setq lsp-ui-doc-enable nil
	lsp-ui-peek-enable t
	lsp-ui-sideline-enable t
	lsp-ui-imenu-enable t
	lsp-ui-flycheck-enable t))

(use-package company-lsp
  :ensure t
  :commands company-lsp)

;; Go

(use-package go-mode
  :defer t
  :ensure t
  :mode ("\\.go\\'" . go-mode)
  :bind (("M-." . godef-jump)))

(defun lsp-go-install-save-hooks ()
  (add-hook 'before-save-hook #'lsp-format-buffer t t)
  (add-hook 'before-save-hook #'lsp-organize-imports t t))
(add-hook 'go-mode-hook #'lsp-go-install-save-hooks)

;; Bazel

(use-package bazel-mode
  :defer t
  :ensure t)

(add-hook 'bazel-mode-hook (lambda () (add-hook 'before-save-hook #'bazel-format nil t)))

;; Protobuf

(use-package protobuf-mode
  :ensure t
  :defer t)

;; CQL

(use-package cql-mode
  :ensure t
  :defer t)

;; Rust

(use-package flycheck-rust
  :ensure t
  :defer t)

(use-package rust-mode
  :ensure t
  :defer t
  :init
  (require 'rust-mode)
  (global-company-mode)
  (add-to-list 'auto-mode-alist '("\\.rs\\'" . rust-mode))

  :config
  (use-package flycheck-rust))

(use-package yaml-mode
  :ensure t
  :defer t)

;; Automatic stuff
(custom-set-variables
 ;; custom-set-variables was added by Custom.
 ;; If you edit it by hand, you could mess it up, so be careful.
 ;; Your init file should contain only one such instance.
 ;; If there is more than one, they won't work right.
 '(package-selected-packages
   (quote
    (magit rust-mode use-package smart-mode-line protobuf-mode lsp-ui helm-projectile helm-ag gruvbox-theme go-mode exec-path-from-shell cql-mode company-quickhelp company-lsp centaur-tabs bazel-mode))))
(custom-set-faces
 ;; custom-set-faces was added by Custom.
 ;; If you edit it by hand, you could mess it up, so be careful.
 ;; Your init file should contain only one such instance.
 ;; If there is more than one, they won't work right.
 )