(server-start)

(require 'cl)

;; User details
(setq user-full-name "Iván Ávalos")
(setq user-mail-address "ivan.avalos.diaz@hotmail.com")

;; Startup
(modify-frame-parameters
 nil '((user-position . t) (left . 240)))
(add-to-list 'default-frame-alist '(height . 51))
(add-to-list 'default-frame-alist '(width . 132))
(tool-bar-mode -1)
(scroll-bar-mode -1)
(setq default-directory "~/")

(defvar avalos/vendor-dir (expand-file-name "vendor" user-emacs-directory))
(defun load-directory (dir) "Load eLisp files on DIR."
       (let ((load-it (lambda (f)
                        (load-file (concat (file-name-as-directory dir) f)))))
         (mapc load-it (directory-files dir nil "\\.el$"))))
(load-directory avalos/vendor-dir)

;; Package Management
(load "package")
(package-initialize)
(add-to-list 'package-archives
             '("melpa-stable" . "https://stable.melpa.org/packages/") t)
(add-to-list 'package-archives
	         '("melpa" . "https://melpa.org/packages/") t)
(add-to-list 'package-archives
             '("melpa" . "http://melpa.milkbox.net/packages/") t)
(defvar avalos/packages '(markdown-mode
                          emmet-mode
                          org
                          web-mode
                          yaml-mode
                          go-mode
                          flycheck
                          company
                          company-go
                          company-irony
                          lsp-mode
                          lsp-ui
			              use-package
                          auto-package-update
                          projectile
                          magit
                          platformio-mode
                          irony
                          irony-eldoc
                          flycheck-irony
                          geiser
                          dart-mode
                          lsp-dart
                          flutter
                          flutter-l10n-flycheck
                          smartparens
                          yasnippet-snippets
                          password-store
                          which-key
                          vc-fossil
                          sublime-themes)
  "Default packages.")

(defun avalos/packages-installed-p ()
  "Install listed packages if not installed."
  (loop for pkg in avalos/packages
        when (not (package-installed-p pkg)) do (return nil)
        finally (return t)))

(unless (avalos/packages-installed-p)
  (message "%s" "Refreshing package database...")
  (package-refresh-contents)
  (dolist (pkg avalos/packages)
    (when (not (package-installed-p pkg))
      (package-install pkg))))

(use-package auto-package-update
  :config
  (setq auto-package-update-delete-old-versions t)
  (setq auto-package-update-hide-results t)
  (auto-package-update-maybe))

;; Load environment variables
(setenv "GOPATH" "/Users/avalos/go")
(setenv "PATH" (concat
                "/usr/local/bin" ":"
                "/Users/avalos/go/bin" ":"
                "/Library/TeX/texbin" ":"
                (getenv "PATH")))
(setq exec-path (append exec-path
                        '("/usr/bin"
                          "/usr/local/bin"
                          "/Users/avalos/flutter/bin"
                          "/Users/avalos/.cargo/bin"
                          "/Users/avalos/flutter/bin/cache/dart-sdk/bin"
                          "/Users/avalos/go/bin"
                          "/Users/avalos/go"
                          "/Library/TeX/texbin")))

;; Start-up options
(load-theme 'spolsky t)
(add-to-list 'default-frame-alist '(font . "Fira Code" ))
(set-face-attribute 'default t :font "Fira Code" )

(setq inhibit-splash-screen t
      initial-scratch-message nil
      initial-major-mode 'org-mode)

(setq mac-right-option-modifier 'meta
      mac-right-option-modifier nil)

(setq select-enable-clipboard t)

(setq-default tab-width 4
              indent-tabs-mode nil
              c-basic-offset 4)

(setq make-backup-files nil)

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

(global-set-key (kbd "RET") 'newline-and-indent)

(setq echo-keystrokes 0.1
      use-dialog-box nil
      visible-bell t)

(show-paren-mode t)

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

(use-package which-key
  :init (which-key-mode))

(use-package smartparens-config
  :init (smartparens-global-mode))

;; Flycheck
(use-package flycheck
  :ensure t
  :init (global-flycheck-mode))

;; LSP
(setq gc-cons-threshold 100000000)
(setq read-process-output-max (* 1024 1024))
(use-package lsp-mode
  :ensure t
  :commands (lsp lsp-deferred)
  :config
  (setq lsp-response-timeout 25)
  (setq lsp-completion-provider :capf)
  (setq lsp-idle-delay 0.500))
(defun lsp-install-save-hooks () "Install save hooks for lsp."
       (add-hook 'before-save-hook #'lsp-format-buffer t t)
       (add-hook 'before-save-hook #'lsp-organize-imports t t))
(use-package lsp-ui
  :ensure t
  :commands lsp-ui-mode
  :config
  (setq lsp-ui-doc-position 'at-point)
  (setq lsp-ui-doc-alignment 'window))
(use-package company
  :ensure t
  :config
  ;; Optionally enable completion-as-you-type behavior.
  (setq company-idle-delay 0)
  (setq company-minimum-prefix-length 1)
  :init (global-company-mode))
(use-package company-lsp
  :ensure t
  :commands company-lsp)
(use-package yasnippet
  :ensure t
  :commands yas-minor-mode)
(require 'yasnippet)
(yas-reload-all)

;; Language hooks
(add-to-list 'auto-mode-alist '("\\.zsh$" . shell-script-mode))
(add-to-list 'auto-mode-alist '("\\.gitconfig$" . conf-mode))
(add-to-list 'auto-mode-alist '("\\.yml$" . yaml-mode))
(add-to-list 'auto-mode-alist '("\\.yaml$" . yaml-mode))
(add-to-list 'auto-mode-alist '("\\.js$" . js-mode))
(add-to-list 'auto-mode-alist '("\\.wiki$" . html-mode))
(add-to-list 'auto-mode-alist '("\\.vala$" . vala-mode))
(add-to-list 'auto-mode-alist '("\\.vapi$" . vala-mode))
(add-to-list 'file-coding-system-alist '("\\.vala$" . utf-8))
(add-to-list 'file-coding-system-alist '("\\.vapi$" . utf-8))

(require 'emmet-mode)
(add-hook 'sgml-mode-hook 'emmet-mode) ;; Auto-start on any markup modes
(add-hook 'css-mode-hook  'emmet-mode) ;; enable Emmet's css abbreviation.

;; Org Mode
(require 'org)
(add-to-list 'org-latex-packages-alist
             '("" "tikz" t))
(eval-after-load "preview"
  '(add-to-list preview-default-preamble "\\PreviewEnvironment{tikzpicture}" t))
(setq org-preview-latex-default-process 'imagemagick)

;; Golang
(require 'lsp-go)
(use-package lsp-mode
  :ensure t
  :commands (lsp lsp-deferred)
  :hook (go-mode . lsp-deferred))
(lsp-register-custom-settings
 '(("gopls.completeUnimported" t t)))
;;(setq lsp-gopls-use-placeholders t)
(add-hook 'go-mode-hook #'lsp-install-save-hooks)
(add-hook 'go-mode-hook 'yas-minor-mode)

;; Flutter
(use-package dart-mode
  :hook (dart-mode . flutter-test-mode)
  :custom (dart-format-on-save t))
(add-hook 'dart-mode-hook 'lsp)
(add-hook 'dart-mode-hook #'lsp-install-save-hooks)
(add-hook 'dart-mode-hook 'yas-minor-mode)
(use-package flutter
  :after dart-mode
  :bind (:map dart-mode-map
			  ("C-M-x" . #'flutter-run-or-hot-reload))
  :custom (flutter-sdk-path "/Users/avalos/flutter/"))

;; Web Development
(add-hook 'js-mode-hook 'lsp)
(add-hook 'js-mode-hook #'lsp-install-save-hooks)
(add-hook 'js-mode-hook 'yas-minor-mode)

;; PlatformIO
(require 'platformio-mode)
(add-to-list 'company-backends 'company-irony)
(add-hook 'c++-mode-hook (lambda ()
                           (irony-mode)
                           (irony-eldoc)
                           (platformio-conditionally-enable)))
(add-hook 'irony-mode-hook
          (lambda ()
            (define-key irony-mode-map [remap completion-at-point]
              'irony-completion-at-point-async)
            (define-key irony-mode-map [remap complete-symbol]
              'irony-completion-at-point-async)
            (irony-cdb-autosetup-compile-options)))
(add-hook 'flycheck-mode-hook 'flycheck-irony-setup)

;; Custom
(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.
 '(ansi-color-faces-vector
   [default default default italic underline success warning error])
 '(ansi-color-names-vector
   ["#2e3436" "#a40000" "#4e9a06" "#c4a000" "#204a87" "#5c3566" "#729fcf" "#eeeeec"])
 '(custom-safe-themes
   '("d7491c599885571b264596b825f9d37af4eba08bf09d9645f955f46059481cdc" default))
 '(inhibit-startup-screen t)
 '(package-selected-packages
   '(jsx-mode company-php kotlin-mode company-nginx markdown-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.
 '(default ((t (:background nil)))))
