<commit_before>;; Essential Packages
;; ==================
;;
;; These are essential packages that affect the rest of the init configuration,
;; and therefore need to be loaded first.
(setq straight-enable-use-package-integration t
      straight-use-package-by-default t
      use-package-always-defer t)

;; https://github.com/raxod502/straight.el#getting-started
(let ((bootstrap-file
       (expand-file-name "straight/repos/straight.el/bootstrap.el"
                         user-emacs-directory))
      (bootstrap-version 5))
  (unless (file-exists-p bootstrap-file)
    (with-current-buffer
        (url-retrieve-synchronously
         (concat "https://raw.githubusercontent.com/raxod502/straight.el/"
                 "develop/install.el")
         'silent 'inhibit-cookies)
      (goto-char (point-max))
      (eval-print-last-sexp)))
  (load bootstrap-file nil 'nomessage))

(straight-use-package 'use-package)

(use-package general
  :demand t
  :config
  (general-auto-unbind-keys)
  (general-override-mode)

  (eval-and-compile
    (defalias 'gsetq #'general-setq)
    (defalias 'gsetq-local #'general-setq-local)
    (defalias 'gsetq-default #'general-setq-default))

  (general-create-definer general-my/leader
    :states '(normal visual)
    :keymaps 'override
    :prefix "SPC"))

;; Generic Editor Behaviour
;; ========================
(gsetq-default auto-fill-function 'do-auto-fill
               fill-column 80
               ;; Do not insert tabs when indenting.
               indent-tabs-mode nil
               ;; Make gj/gk work across visually wrapped lines.
               line-move-visual nil
               ;; Vertical cursor padding.
               scroll-margin 5
               scroll-step 1
               tab-width 2)

(gsetq auto-save-list-file-prefix nil
       create-lockfiles nil
       custom-file (expand-file-name "~/dots/emacs/custom.el")
       ;; TODO: Change this to make backup files at ~/archive/backup.
       make-backup-files nil
       mouse-avoidance-banish-position '((frame-or-window . frame)
                                         (side . right)
                                         (side-pos . 0)
                                         (top-or-bottom . bottom)
                                         (top-or-bottom-pos . 0))
       require-final-newline t
       sentence-end-double-space nil
       show-paren-delay 0
       vc-follow-symlinks t
       ;; Show fringe indicators for visually wrapped lines.
       visual-line-fringe-indicators '(left-curly-arrow right-curly-arrow)
       whitespace-line-column fill-column
       whitespace-style '(face empty lines-tail tabs trailing))

(blink-cursor-mode -1)
(column-number-mode)
(global-subword-mode)
(load-file custom-file)
(mouse-avoidance-mode 'banish)
(show-paren-mode)
(tooltip-mode -1)

(defun my/text-mode-functions ()
  (visual-line-mode)
  (whitespace-mode))

(general-add-hook 'text-mode-hook #'my/text-mode-functions)
(general-add-hook 'prog-mode-hook #'my/text-mode-functions)

(use-package aggressive-indent :ghook 'prog-mode-hook)

(use-package hl-line
  :after (evil ivy)
  :straight nil
  :ghook
  'text-mode-hook
  'prog-mode-hook
  :config
  ;; Fix `describe-face' defaulting to hl-line face.
  ;; https://emacs.stackexchange.com/a/45719/8693
  (defun my/face-at-point ()
    (let ((face (get-text-property (point) 'face)))
      (or (and (face-list-p face)
               (car face))
          (and (symbolp face)
               face))))

  (defun my/describe-face (&rest ignore)
    (interactive (list (read-face-name "Describe face"
                                       (or (my/face-at-point) 'default)
                                       t)))
    ;; This only needs to change the `interactive` spec, so:
    nil)

  (general-add-advice 'describe-face :before #'my/describe-face)
  (general-add-advice 'counsel-describe-face :before #'my/describe-face)

  ;; Disable hl-line-mode in evil visual state.
  (general-add-hook 'evil-visual-state-entry-hook
                    (lambda ()
                      (when (or (derived-mode-p 'text-mode)
                                (derived-mode-p 'prog-mode))
                        (hl-line-mode -1))))
  (general-add-hook 'evil-visual-state-exit-hook
                    (lambda ()
                      (when (or (derived-mode-p 'text-mode)
                                (derived-mode-p 'prog-mode))
                        (hl-line-mode)))))

;; Buffer and File Related
;; =======================
(use-package ibuffer
  :straight nil
  :gfhook #'ibuffer-auto-mode
  :init
  (gsetq ibuffer-expert t
         kill-buffer-query-functions
         (remq 'process-kill-buffer-query-function
               kill-buffer-query-functions))
  :config
  (general-def 'normal ibuffer-mode-map
    "x" #'ibuffer-do-delete
    "K" #'ibuffer-do-kill-on-deletion-marks))

(use-package dired
  :straight nil
  :gfhook #'auto-revert-mode
  :init
  (put 'dired-find-alternate-file 'disabled nil))

;; Transitive library dependency that ivy uses to sort completion candidates.
(use-package flx :demand t)

(use-package ivy
  :init
  (gsetq ivy-count-format ""
         ;; Don't insert ^ at beginning of some ivy-related commands and let flx
         ;; sort the entries.
         ivy-initial-inputs-alist nil
         ;; Use fuzzy matching everywhere.
         ivy-re-builders-alist '((t . ivy--regex-fuzzy))
         ivy-wrap t)
  (ivy-mode)

  :config
  ;; Copy pasted everything except last line of function from ivy.el.
  (defun my/ivy-partial-or-next-line ()
    "Complete the minibuffer text as much as possible.
If the text hasn't changed as a result, forward to `ivy-next-line'."<commit_msg>⚙ emacs: disable fuzzy matching for ivy<commit_after>;; Essential Packages
;; ==================
;;
;; These are essential packages that affect the rest of the init configuration,
;; and therefore need to be loaded first.
(setq straight-enable-use-package-integration t
      straight-use-package-by-default t
      use-package-always-defer t)

;; https://github.com/raxod502/straight.el#getting-started
(let ((bootstrap-file
       (expand-file-name "straight/repos/straight.el/bootstrap.el"
                         user-emacs-directory))
      (bootstrap-version 5))
  (unless (file-exists-p bootstrap-file)
    (with-current-buffer
        (url-retrieve-synchronously
         (concat "https://raw.githubusercontent.com/raxod502/straight.el/"
                 "develop/install.el")
         'silent 'inhibit-cookies)
      (goto-char (point-max))
      (eval-print-last-sexp)))
  (load bootstrap-file nil 'nomessage))

(straight-use-package 'use-package)

(use-package general
  :demand t
  :config
  (general-auto-unbind-keys)
  (general-override-mode)

  (eval-and-compile
    (defalias 'gsetq #'general-setq)
    (defalias 'gsetq-local #'general-setq-local)
    (defalias 'gsetq-default #'general-setq-default))

  (general-create-definer general-my/leader
    :states '(normal visual)
    :keymaps 'override
    :prefix "SPC"))

;; Generic Editor Behaviour
;; ========================
(gsetq-default auto-fill-function 'do-auto-fill
               fill-column 80
               ;; Do not insert tabs when indenting.
               indent-tabs-mode nil
               ;; Make gj/gk work across visually wrapped lines.
               line-move-visual nil
               ;; Vertical cursor padding.
               scroll-margin 5
               scroll-step 1
               tab-width 2)

(gsetq auto-save-list-file-prefix nil
       create-lockfiles nil
       custom-file (expand-file-name "~/dots/emacs/custom.el")
       ;; TODO: Change this to make backup files at ~/archive/backup.
       make-backup-files nil
       mouse-avoidance-banish-position '((frame-or-window . frame)
                                         (side . right)
                                         (side-pos . 0)
                                         (top-or-bottom . bottom)
                                         (top-or-bottom-pos . 0))
       require-final-newline t
       sentence-end-double-space nil
       show-paren-delay 0
       vc-follow-symlinks t
       ;; Show fringe indicators for visually wrapped lines.
       visual-line-fringe-indicators '(left-curly-arrow right-curly-arrow)
       whitespace-line-column fill-column
       whitespace-style '(face empty lines-tail tabs trailing))

(blink-cursor-mode -1)
(column-number-mode)
(global-subword-mode)
(load-file custom-file)
(mouse-avoidance-mode 'banish)
(show-paren-mode)
(tooltip-mode -1)

(defun my/text-mode-functions ()
  (visual-line-mode)
  (whitespace-mode))

(general-add-hook 'text-mode-hook #'my/text-mode-functions)
(general-add-hook 'prog-mode-hook #'my/text-mode-functions)

(use-package aggressive-indent :ghook 'prog-mode-hook)

(use-package hl-line
  :after (evil ivy)
  :straight nil
  :ghook
  'text-mode-hook
  'prog-mode-hook
  :config
  ;; Fix `describe-face' defaulting to hl-line face.
  ;; https://emacs.stackexchange.com/a/45719/8693
  (defun my/face-at-point ()
    (let ((face (get-text-property (point) 'face)))
      (or (and (face-list-p face)
               (car face))
          (and (symbolp face)
               face))))

  (defun my/describe-face (&rest ignore)
    (interactive (list (read-face-name "Describe face"
                                       (or (my/face-at-point) 'default)
                                       t)))
    ;; This only needs to change the `interactive` spec, so:
    nil)

  (general-add-advice 'describe-face :before #'my/describe-face)
  (general-add-advice 'counsel-describe-face :before #'my/describe-face)

  ;; Disable hl-line-mode in evil visual state.
  (general-add-hook 'evil-visual-state-entry-hook
                    (lambda ()
                      (when (or (derived-mode-p 'text-mode)
                                (derived-mode-p 'prog-mode))
                        (hl-line-mode -1))))
  (general-add-hook 'evil-visual-state-exit-hook
                    (lambda ()
                      (when (or (derived-mode-p 'text-mode)
                                (derived-mode-p 'prog-mode))
                        (hl-line-mode)))))

;; Buffer and File Related
;; =======================
(use-package ibuffer
  :straight nil
  :gfhook #'ibuffer-auto-mode
  :init
  (gsetq ibuffer-expert t
         kill-buffer-query-functions
         (remq 'process-kill-buffer-query-function
               kill-buffer-query-functions))
  :config
  (general-def 'normal ibuffer-mode-map
    "x" #'ibuffer-do-delete
    "K" #'ibuffer-do-kill-on-deletion-marks))

(use-package dired
  :straight nil
  :gfhook #'auto-revert-mode
  :init
  (put 'dired-find-alternate-file 'disabled nil))

;; Transitive library dependency that ivy uses to sort completion candidates.
(use-package flx :demand t)

(use-package ivy
  :init
  (gsetq ivy-count-format ""
         ;; Don't insert ^ at beginning of some ivy-related commands and let flx
         ;; sort the entries.
         ivy-initial-inputs-alist nil
         ivy-wrap t)
  (ivy-mode)

  :config
  ;; Copy pasted everything except last line of function from ivy.el.
  (defun my/ivy-partial-or-next-line ()
    "Complete the minibuffer text as much as possible.
If the text hasn't changed as a result, forward to `ivy-next-line'."
{'fraction_non_alphanumeric': 0.13388268651426546, 'fraction_numerical': 0.004784688995215311, 'mean_word_length': 2.1196793808734107, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 6, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 22, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2331700', 'n_tokens_mistral': 3670, 'n_tokens_neox': 3457, 'n_words': 806}