;;; kkk-initial.el --- Initial config of Emacs       -*- lexical-binding: t; -*-

;; Copyright (C) 2023  Vinicius Teshima <vini.tes@pm.me>

;; Author: Vinicius Teshima <vini.tes@pm.me>

;; This program is free software; you can redistribute it and/or modify
;; it under the terms of the GNU General Public License as published by
;; the Free Software Foundation, either version 3 of the License, or
;; (at your option) any later version.

;; This program is distributed in the hope that it will be useful,
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
;; GNU General Public License for more details.

;; You should have received a copy of the GNU General Public License
;; along with this program.  If not, see <https://www.gnu.org/licenses/>.

;;; Commentary:

;; This will set the basic config of Emacs

;;; Code:
(defgroup kkk-initial nil
  "Initial Tweaks to Emacs."
  :group 'kkk-emacs)

(defun kkk--display-startup-time()
  "Display the time it took for Emacs to start."
  (message "Emacs loaded in %s with %d garbage collection."
	   (format "%.2f seconds"
		   (float-time
		    (time-subtract after-init-time before-init-time)))
	   gcs-done))

(add-hook 'emacs-startup-hook #'kkk--display-startup-time)

;; This is the default
;; (setq-default indent-tabs-mode t)	; Use Tabs as indentation
;; (setq-default tab-width 8)		; Setting the size of Tabs

(setq inhibit-startup-message t)	; Disable Startup Message
(setq visible-bell t)			; Use Visible Bell instead of Audible
(setq use-dialog-box nil)		; Don't use gtk dialog box

(menu-bar-mode -1)			; Disable Menu Bar

;; Disable various things if is in an Graphical Environment
(when (display-graphic-p)
  (scroll-bar-mode -1)			; Removing scrollbar
  (tool-bar-mode -1)
  (tooltip-mode -1)
  (set-fringe-mode 10)			; Sets the fringe size to 10px
  )

(global-display-fill-column-indicator-mode 't)
(setq-default fill-column 80)

;; Auto Revert Mode:
(require 'autorevert)
(global-auto-revert-mode t)
(setq global-auto-revert-non-file-buffers 't)

;; Numbered Lines:
(require 'kkk-linenumbers)
(setq kkk-linenumbers-global-modes '(not
				     term-mode eshell-mode vterm-mode
				     magit-status-mode magit-revision-mode
				     magit-diff-mode magit-log-mode
				     magit-blob-mode magit-refs-mode
				     magit-blame-mode eww-mode
				     help-mode helpful-mode))
(setq kkk-linenumbers-type 'visual)
(global-kkk-linenumbers-mode t)

;; Whitespace Mode:
(require 'kkk-whitespace)
(setq kkk-whitespace-global-modes '(not
				    term-mode shell-mode eshell-mode vterm-mode
				    magit-status-mode magit-revision-mode
				    magit-diff-mode magit-log-mode
				    magit-blob-mode magit-refs-mode
				    magit-log-select-mode Man-mode
				    magit-blame-mode eww-mode Custom-Mode
				    help-mode helpful-mode Buffer-menu-mode
				    compilation-mode vc-mode vc-dir-mode
				    notmuch-search-mode notmuch-hello-mode
				    notmuch-show-mode gud-mode grep-mode
				    flycheck-error-list-mode dired-mode
				    xref--xref-buffer-mode))
(setq whitespace-style '(face tabs spaces trailing lines-tail space-before-tab
			      newline indentation empty space-after-tab
			      space-mark tab-mark newline-mark
			      missing-newline-at-eof))

;;; To be only ascii
;; (setq whitespace-display-mappings
;;       '((space-mark ?\s [?.] [183]) (space-mark 160 [164] [95])
;;	(newline-mark ?\n [?$ ?\n]) (tab-mark ?\t [?> ?\t])))

(global-kkk-whitespace-mode t)

(setq tab-bar-close-button nil)
(setq tab-bar-new-button-show nil)

;; (setq max-lisp-eval-depth (* 1024 8))	; Increase the eval depth

(electric-pair-mode t)

(show-paren-mode t)
(setq show-paren-style 'mixed)

(column-number-mode t)

(display-battery-mode t)
(savehist-mode t)

(add-hook 'find-file-hook #'auto-insert)

(add-hook 'prog-mode #'glasses-mode)

(setq auth-source-save-behavior nil)

(when (display-graphic-p)
  (require 'kkk-font)
  ;; (setq kkk-font-default-font "Comic Mono")
  (setq kkk-font-default-font "Unifont")
  (setq kkk-font-fixed-font "Unifont")
  (setq kkk-font-variable-font "Unifont")
  (when (string= (system-name) "i7.dp.lat")
    (setq kkk-font-default-font-size 105))
  (add-hook 'emacs-startup-hook       #'kkk-font-set)
  (add-hook 'ef-themes-post-load-hook #'kkk-font-set)
  )

(load-theme 'modus-vivendi)

(require 'kkk-eshell)
(require 'kkk-keepclean)
;; (require 'kkk-package)
;; (require 'kkk-exwm)
;; (require 'kkk-killbuffer)
(require 'kkk-windowsize)
(require 'kkk-abbrev)

;; Setting up to use tree-sitter by default. Stolen from:
;;   https://www.masteringemacs.org/article/how-to-get-started-tree-sitter
;; (setq major-mode-remap-alist
;;  '((yaml-mode . yaml-ts-mode)
;;    (bash-mode . bash-ts-mode)
;;    (js2-mode . js-ts-mode)
;;    (typescript-mode . typescript-ts-mode)
;;    (json-mode . json-ts-mode)
;;    (css-mode . css-ts-mode)
;;   (python-mode . python-ts-mode)))

(require 'kkk-scratch)
(global-unset-key (kbd "C-x s"))
(global-set-key (kbd "C-x s b")   #'kkk-scratch-buffer-dwim)
(global-set-key (kbd "C-x s x v") #'kkk-scratch-vterm-dwim)
(global-set-key (kbd "C-x s x e") #'kkk-scratch-eshell-dwim)

(global-set-key (kbd "<escape>") #'keyboard-escape-quit)

(global-set-key (kbd "C-x m") #'man)

(global-set-key (kbd "M-p") #'isearch-ring-retreat)
(global-set-key (kbd "M-n") #'isearch-ring-advance)

(global-set-key (kbd "C-t") #'transpose-chars)

(defun kkk--pre-angle-brackets (base extra-string)
  "Generate an uniquify name.  <EXTRA-STRING> BASE."
  (setq tmp extra-string)
  (concat "<" (mapconcat #'identity extra-string "/") ">" base))

(setq uniquify-buffer-name-style #'kkk--pre-angle-brackets)

(setq reb-re-syntax 'rx)

;; (defconst kkk-gomode-dir
;;   (locate-user-emacs-file "gitrepos/go-mode.el")
;;   ".")
;; (add-to-list 'load-path kkk-gomode-dir)
;; (autoload 'go-mode "go-mode" nil t)
;; (add-to-list 'auto-mode-alist '("\\.go\\'" . go-mode))

;; (defconst kkk-reformatter-dir
;;   (locate-user-emacs-file "gitrepos/emacs-reformatter")
;;   ".")
;; (add-to-list 'load-path kkk-reformatter-dir)
;; (require 'reformatter)

;; (defconst kkk-zigmode-dir
;;   (locate-user-emacs-file "gitrepos/zig-mode")
;;   ".")
;; (add-to-list 'load-path kkk-zigmode-dir)
;; (autoload 'zig-mode "zig-mode" nil t)
;; (add-to-list 'auto-mode-alist '("\\.zig\\'" . zig-mode))

;; (defconst kkk-fasmmode-dir
;;   (locate-user-emacs-file "gitrepos/fasm-mode")
;;   ".")
;; (add-to-list 'load-path kkk-fasmmode-dir)
;; (autoload 'fasm-mode "fasm-mode" nil t)

(require 'package)
(add-to-list 'package-archives '("melpa" . "https://melpa.org/packages/"))

(setq package-selected-packages '(helpful ##))

(global-set-key (kbd "C-h f") #'helpful-callable)
(global-set-key (kbd "C-h v") #'helpful-variable)
(global-set-key (kbd "C-h k") #'helpful-key)
(global-set-key (kbd "C-h x") #'helpful-command)

(fido-mode 1)

(require 'ispell)
(setq ispell-program-name "aspell")

(require 'flyspell)
(setq flyspell-issue-message-flag nil)

(global-set-key (kbd "M-o") #'complete-tag)
;;(global-set-key (kbd "M-/") #'hippie-expand)
(global-set-key (kbd "M-/") #'dabbrev-expand)
(global-set-key (kbd "C-j") #'join-line)
(global-set-key (kbd "C-%") #'xref-find-references-and-replace)

(setq c-default-style
      '((java-mode . "java") (awk-mode . "awk") (other . "linux")))

(global-subword-mode +1)

;; (hs-minor-mode +1)

(defun narrow-clone(&optional DISPLAY-FLAG)
  (interactive)
  (let ((name "Unknown")
	(line_str (thing-at-point 'line))
	(call_start (point))
	(start (point-min))
	(end (point-max))
	(new_buf nil))
    (save-excursion
      ;; DoWhile
      (while
	  (progn
	    (forward-line -1)
	    (setq line_str (thing-at-point 'line))

	    (and (not (string-prefix-p "//== " line_str))
		 (/= (point-min) (point)))
	    )
	)
      (forward-line 1)
      (setq start (point))
      )

    (when (string-prefix-p "//== " line_str)
      (setq name (string-trim (cadr (string-split line_str " "))))
      )

    (save-excursion
      (forward-line 1)
      (setq line_str (thing-at-point 'line))
      (while (and (not (string-prefix-p "//== " line_str))
		  (/= (point-max) (point)))
	(forward-line 1)
	(setq line_str (thing-at-point 'line))
	)
      (setq end (point))
      )

    (setq new_buf (clone-indirect-buffer name nil))
    (save-excursion
      (set-buffer new_buf)
      (narrow-to-region start end)
     )
    (when (not DISPLAY-FLAG)
      (switch-to-buffer new_buf))
    end
    )
  )

(defun narrow-clone-buffer()
  (interactive)
  (goto-char (point-min))
  (let ((end (narrow-clone t)))
    (while (/= (point-max) end)
      (forward-line 1)
      (setq end (narrow-clone t))
      )
    )
  )

;; Stolen from (http://endlessparentheses.com/ansi-colors-in-the-compilation-buffer-output.html)
(require 'ansi-color)
(defun endless/colorize-compilation ()
  "Colorize from `compilation-filter-start' to `point'."
  (let ((inhibit-read-only t))
    (ansi-color-apply-on-region
     compilation-filter-start (point))))

(add-hook 'compilation-filter-hook
          #'endless/colorize-compilation)

;; Stolen from (https://oleksandrmanzyuk.wordpress.com/2011/11/05/better-emacs-shell-part-i/)
(defun regexp-alternatives (regexps)
  "Return the alternation of a list of regexps."
  (mapconcat (lambda (regexp)
               (concat "\\(?:" regexp "\\)"))
             regexps "\\|"))

(defvar non-sgr-control-sequence-regexp nil
  "Regexp that matches non-SGR control sequences.")

(setq non-sgr-control-sequence-regexp
      (regexp-alternatives
       '(;; icon name escape sequences
         "\033\\][0-2];.*?\007"
         ;; non-SGR CSI escape sequences
         "\033\\[\\??[0-9;]*[^0-9;m]"
         ;; noop
         "\012\033\\[2K\033\\[1F"
         )))

(defun filter-non-sgr-control-sequences-in-region (begin end)
  (save-excursion
    (goto-char begin)
    (while (re-search-forward
            non-sgr-control-sequence-regexp end t)
      (replace-match ""))))

(defun filter-non-sgr-control-sequences-in-output (ignored)
  (let ((start-marker
         (or comint-last-output-start
             (point-min-marker)))
        (end-marker
         (process-mark
          (get-buffer-process (current-buffer)))))
    (filter-non-sgr-control-sequences-in-region
     start-marker
     end-marker)))

(add-hook 'comint-output-filter-functions
          'filter-non-sgr-control-sequences-in-output)


(require 'hare-mode)

(provide 'kkk-initial)
;;; kkk-initial.el ends here
