;; [[file:config.org::*Customizations][Customizations:1]]
(setq-default custom-file (expand-file-name ".custom.el" doom-private-dir))
(when (file-exists-p custom-file)
  (load custom-file))
;; Customizations:1 ends here

;; [[file:config.org::*Personal information][Personal information:1]]
(setq user-full-name "Shaurya Singh"
      user-mail-address "shaunsingh0207@gmail.com")
;; Personal information:1 ends here

;; [[file:config.org::*Window management][Window management:1]]
(setq evil-vsplit-window-right t
      evil-split-window-below t)
;; Window management:1 ends here

;; [[file:config.org::*Window management][Window management:2]]
(defadvice! prompt-for-buffer (&rest _)
  :after '(evil-window-split evil-window-vsplit)
  (consult-buffer))
;; Window management:2 ends here

;; [[file:config.org::*Better Defaults][Better Defaults:1]]
(setq scroll-margin 2
      auto-save-default t
      display-line-numbers-type nil
      delete-by-moving-to-trash t
      truncate-string-ellipsis "…"
      browse-url-browser-function 'xwidget-webkit-browse-url)

(fringe-mode 0)
(global-subword-mode 1)
;; Better Defaults:1 ends here

;; [[file:config.org::*Better Defaults][Better Defaults:2]]
(add-to-list 'default-frame-alist '(inhibit-double-buffering . t))
;; Better Defaults:2 ends here

;; [[file:config.org::*Better Defaults][Better Defaults:3]]
(cond
 ((string-equal system-type "darwin")
  (setq frame-resize-pixelwise  t
        window-resize-pixelwise t)))
;; Better Defaults:3 ends here

;; [[file:config.org::*Evil][Evil:1]]
(after! evil
  (setq evil-ex-substitute-global t     ; I like my s/../.. to by global by default
        evil-move-cursor-back nil       ; Don't move the block cursor when toggling insert mode
        evil-kill-on-visual-paste nil)) ; Don't put overwritten text in the kill ring
;; Evil:1 ends here

;; [[file:config.org::*Evil][Evil:2]]
(setq which-key-allow-multiple-replacements t
      which-key-idle-delay 0.5) ;; I need the help, I really do
(after! which-key
  (pushnew!
   which-key-replacement-alist
   '(("" . "\\`+?evil[-:]?\\(?:a-\\)?\\(.*\\)") . (nil . " \\1"))
   '(("\\`g s" . "\\`evilem--?motion-\\(.*\\)") . (nil . " \\1"))))
;; Evil:2 ends here

;; [[file:config.org::*Magit][Magit:1]]
(after! magit
  (magit-delta-mode +1))
;; Magit:1 ends here

;; [[file:config.org::*Info Colors][Info Colors:1]]
(use-package! info-colors
  :commands (info-colors-fontify-node))

(add-hook 'Info-selection-hook 'info-colors-fontify-node)
;; Info Colors:1 ends here

;; [[file:config.org::*Mini-Frame][Mini-Frame:1]]
(use-package! mini-frame
  :hook (after-init . mini-frame-mode)
  :config
  (defcustom my/minibuffer-position 'top
    "Minibuffer position, one of 'top or 'bottom"
    :type '(choice (const :tag "Top"    top)
                   (const :tag "Bottom" bottom))
    :group 'nano-minibuffer)
  
  (defun my/minibuffer--frame-parameters ()
    "Compute minibuffer frame size and position."

    ;; Quite precise computation to align the minibuffer and the
    ;; modeline when they are both at top position
    (let* ((edges (window-pixel-edges)) ;; (left top right bottom)
           (body-edges (window-body-pixel-edges)) ;; (left top right bottom)
           (left (nth 0 edges)) ;; Take margins into account
           (top (nth 1 edges)) ;; Drop header line
           (right (nth 2 edges)) ;; Take margins into account
           (bottom (nth 3 body-edges)) ;; Drop header line
           (left (if (eq left-fringe-width 0)
                     left
                   (- left (frame-parameter nil 'left-fringe))))
           (right (nth 2 edges))
           (right (if (eq right-fringe-width 0)
                      right
                    (+ right (frame-parameter nil 'right-fringe))))
           (border 1)
           (width (- right left (* 0 border)))

           ;; Window divider mode
           (width (- width (if (and (bound-and-true-p window-divider-mode)
                                    (or (eq window-divider-default-places 'right-only)
                                        (eq window-divider-default-places t))
                                    (window-in-direction 'right (selected-window)))
                               window-divider-default-right-width
                             0)))
           (y (- top border)))

      (append `((left-fringe . 0)
                (right-fringe . 0)
                (user-position . t)
                (foreground-color . ,(face-foreground 'highlight nil 'default))
                (background-color . ,(face-background 'highlight nil 'default)))
              (cond ((and (eq my/minibuffer-position 'bottom))
                     `((top . -1)
                       (left . 0)
                       (width . 1.0)
                       (child-frame-border-width . 0)
                       (internal-border-width . 0)))
                    (t
                     `((left . ,(- left border))
                       (top . ,y)
                       (width . (text-pixels . ,width))
                       (child-frame-border-width . ,border)
                       (internal-border-width . ,border)))))))

    (set-face-background 'child-frame-border (face-foreground 'nano-faded))
    (setq mini-frame-default-height 3)
    (setq mini-frame-create-lazy t)
    (setq mini-frame-show-parameters 'my/minibuffer--frame-parameters)
    (setq mini-frame-ignore-commands
          '("edebug-eval-expression" debugger-eval-expression))
    (setq mini-frame-internal-border-color (face-foreground 'nano-faded))
    (setq mini-frame-resize-min-height 3)
    (setq mini-frame-resize t)
    
  (defun my/mini-frame (&optional height foreground background border)
    "Create a child frame positionned over the header line whose
  width corresponds to the width of the current selected window.

  The HEIGHT in lines can be specified, as well as the BACKGROUND
  color of the frame. BORDER width (pixels) and color (FOREGROUND)
  can be also specified."
    (interactive)
    (let* ((foreground (or foreground
                           (face-foreground 'font-lock-comment-face nil t)))
           (background (or background (face-background 'highlight nil t)))
           (border (or border 1))
           (height (round (* (or height 8) (window-font-height))))
           (edges (window-pixel-edges))
           (body-edges (window-body-pixel-edges))
           (top (nth 1 edges))
           (bottom (nth 3 body-edges))
           (left (- (nth 0 edges) (or left-fringe-width 0)))
           (right (+ (nth 2 edges) (or right-fringe-width 0)))
           (width (- right left))

           ;; Window divider mode
           (width (- width (if (and (bound-and-true-p window-divider-mode)
                                    (or (eq window-divider-default-places 'right-only)
                                        (eq window-divider-default-places t))
                                  (window-in-direction 'right (selected-window)))
                               window-divider-default-right-width
                             0)))
           (y (- top border))
           (child-frame-border (face-attribute 'child-frame-border :background)))
      (set-face-attribute 'child-frame-border t :background foreground)
      (let ((frame (make-frame
                    `((parent-frame . ,(window-frame))
                      (delete-before . ,(window-frame))
                      (minibuffer . nil)
                      (modeline . nil)
                      (left . ,(- left border))
                      (top . ,y)
                      (width . (text-pixels . ,width))
                      (height . (text-pixels . ,height))
                      ;; (height . ,height)
                      (child-frame-border-width . ,border)
                      (internal-border-width . ,border)
                      (background-color . ,background)
                      (horizontal-scroll-bars . nil)
                      (menu-bar-lines . 0)
                      (tool-bar-lines . 0)
                      (desktop-dont-save . t)
                      (unsplittable . nil)
                      (no-other-frame . t)
                      (undecorated . t)
                      (pixelwise . t)
                      (visibility . t)))))
        (set-face-attribute 'child-frame-border t :background child-frame-border)
        frame))))
;; Mini-Frame:1 ends here

;; [[file:config.org::*Vertico][Vertico:1]]
(after! vertico
  ;; settings
  (setq vertico-resize nil        ; How to resize the Vertico minibuffer window.
        vertico-count 10          ; Maximal number of candidates to show.
        vertico-count-format nil) ; No prefix with number of entries

  ;; looks
  (setq vertico-grid-separator
        #("  |  " 2 3 (display (space :width (1))
                               face (:background "#ECEFF1")))
        vertico-group-format
        (concat #(" " 0 1 (face vertico-group-title))
                #(" " 0 1 (face vertico-group-separator))
                #(" %s " 0 4 (face vertico-group-title))
                #(" " 0 1 (face vertico-group-separator
                            display (space :align-to (- right (-1 . right-margin) (- +1)))))))
  (set-face-attribute 'vertico-group-separator nil
                      :strike-through t)
  (set-face-attribute 'vertico-current nil
                      :inherit '(nano-strong nano-subtle))
  (set-face-attribute 'completions-first-difference nil
                      :inherit '(nano-default))

  ;; minibuffer tweaks
  (defun my/vertico--resize-window (height)
    "Resize active minibuffer window to HEIGHT."
      (setq-local truncate-lines t
                  resize-mini-windows 'grow-only
                  max-mini-window-height 1.0)
    (unless (frame-root-window-p (active-minibuffer-window))
      (unless vertico-resize
        (setq height (max height vertico-count)))
      (let* ((window-resize-pixelwise t)
             (dp (- (max (cdr (window-text-pixel-size))
                         (* (default-line-height) (1+ height)))
                    (window-pixel-height))))
        (when (or (and (> dp 0) (/= height 0))
                  (and (< dp 0) (eq vertico-resize t)))
          (window-resize nil dp nil nil 'pixelwise)))))

  (advice-add #'vertico--resize-window :override #'my/vertico--resize-window)

  ;; completion at point
  (setq completion-in-region-function
        (lambda (&rest args)
          (apply (if vertico-mode
                     #'consult-completion-in-region
                   #'completion--in-region)
                 args)))
  (defun minibuffer-format-candidate (orig cand prefix suffix index _start)
    (let ((prefix (if (= vertico--index index)
                      "  "
                    "   ")))
      (funcall orig cand prefix suffix index _start)))
  (advice-add #'vertico--format-candidate
             :around #'minibuffer-format-candidate)
  (defun vertico--prompt-selection ()
    "Highlight the prompt"

    (let ((inhibit-modification-hooks t))
      (set-text-properties (minibuffer-prompt-end) (point-max)
                           '(face (nano-strong nano-salient)))))
  (defun minibuffer-vertico-setup ()
    (setq truncate-lines t)
    (setq completion-in-region-function
          (if vertico-mode
              #'consult-completion-in-region
            #'completion--in-region)))

  (add-hook 'vertico-mode-hook #'minibuffer-vertico-setup)
  (add-hook 'minibuffer-setup-hook #'minibuffer-vertico-setup))
;; Vertico:1 ends here

;; [[file:config.org::*Marginalia][Marginalia:1]]
(after! marginalia
  (setq marginalia--ellipsis "…"    ; Nicer ellipsis
        marginalia-align 'right     ; right alignment
        marginalia-align-offset -1)) ; one space on the right
;; Marginalia:1 ends here

;; [[file:config.org::*Pixel-scroll][Pixel-scroll:1]]
(if (boundp 'mac-mouse-wheel-smooth-scroll)
    (setq  mac-mouse-wheel-smooth-scroll t))

(if (> emacs-major-version 28)
    (pixel-scroll-precision-mode))
;; Pixel-scroll:1 ends here

;; [[file:config.org::*Nano][Nano:1]]
(setq-default line-spacing 0.24)
;; Nano:1 ends here

;; [[file:config.org::*Window Padding][Window Padding:1]]
;; Vertical window divider
(setq-default window-divider-default-right-width 24
              window-divider-default-places 'right-only
              left-margin-width 0
              right-margin-width 0
              window-combination-resize nil) ; Do not resize windows proportionally

(window-divider-mode 1)
;; Window Padding:1 ends here

;; [[file:config.org::*Window Padding][Window Padding:2]]
;; Default frame settings
(setq default-frame-alist '((min-height . 1)  '(height . 45)
                            (min-width  . 1)  '(width  . 81)
                            (vertical-scroll-bars . nil)
                            (internal-border-width . 24)
                            (left-fringe . 0)
                            (right-fringe . 0)
                            (tool-bar-lines . 0)
                            (menu-bar-lines . 0)))

(setq initial-frame-alist default-frame-alist)
;; Window Padding:2 ends here

;; [[file:config.org::*Colorscheme][Colorscheme:1]]
(defun shaunsingh/apply-nano-theme (appearance)
  "Load theme, taking current system APPEARANCE into consideration."
  (mapc #'disable-theme custom-enabled-themes)
  (pcase appearance
    ('light (nano-light))
    ('dark (nano-dark))))
;; Colorscheme:1 ends here

;; [[file:config.org::*Colorscheme][Colorscheme:2]]
(use-package nano-theme
  :hook (after-init . nano-light)
  :config
  ;; If emacs has been built with system appearance detection
  ;; add a hook to change the theme to match the system
  ;; (if (boundp 'ns-system-appearance-change-functions)
  ;;     (add-hook 'ns-system-appearance-change-functions #'shaunsingh/apply-nano-theme))
  ;; Now to add some missing faces
  (custom-set-faces
   `(flyspell-incorrect ((t (:underline (:color ,nano-light-salient :style line)))))
   `(flyspell-duplicate ((t (:underline (:color ,nano-light-salient :style line)))))

   `(git-gutter:modified ((t (:foreground ,nano-light-salient))))
   `(git-gutter-fr:added ((t (:foreground ,nano-light-popout))))
   `(git-gutter-fr:modified ((t (:foreground ,nano-light-salient))))

   `(lsp-ui-doc-url:added ((t (:background ,nano-light-highlight))))
   `(lsp-ui-doc-background:modified ((t (:background ,nano-light-highlight))))

   `(vterm-color-red ((t (:foreground ,nano-light-critical))))
   `(vterm-color-blue ((t (:foreground ,nano-light-salient))))
   `(vterm-color-green ((t (:foreground ,nano-light-popout))))
   `(vterm-color-yellow ((t (:foreground ,nano-light-popout))))
   `(vterm-color-magenta ((t (:foreground ,nano-light-salient))))

   `(scroll-bar ((t (:background ,nano-light-background))))
   `(child-frame-border ((t (:foreground ,nano-light-faded))))

   `(avy-lead-face-1 ((t (:foreground ,nano-light-subtle))))
   `(avy-lead-face ((t (:foreground ,nano-light-popout :weight bold))))
   `(avy-lead-face-0 ((t (:foreground ,nano-light-salient :weight bold))))))
;; Colorscheme:2 ends here

;; [[file:config.org::*Colorscheme][Colorscheme:3]]
;; (use-package! nano-modeline
;;   :hook (after-init . nano-modeline-mode)
;;   :config
;;   (setq nano-modeline-prefix 'status
;;         nano-modeline-prefix-padding 1
;;         nano-modeline-position 'bottom))

(use-package! minions
  :hook (after-init . minions-mode))

;; Add a zero-width tall character to add padding to modeline
(setq-default mode-line-format
              (cons (propertize "\u200b" 'display '((raise -0.35) (height 1.4))) mode-line-format))
;; Colorscheme:3 ends here

;; [[file:config.org::*Dimming][Dimming:1]]
;; Dim inactive windows
(use-package! dimmer
  :hook (after-init . dimmer-mode)
  :config
  (setq dimmer-fraction 0.5
        dimmer-adjustment-mode :foreground
        dimmer-use-colorspace :rgb
        dimmer-watch-frame-focus-events nil)
  (dimmer-configure-which-key)
  (dimmer-configure-magit)
  (dimmer-configure-posframe))
;; Dimming:1 ends here

;; [[file:config.org::*Dimming][Dimming:2]]
(defun add-list-to-list (dst src)
  "Similar to `add-to-list', but accepts a list as 2nd argument"
  (set dst
       (append (eval dst) src)))

(use-package! focus
  :commands focus-mode
  :config
  ;; add whatever lsp servers you use to this list
  (add-list-to-list 'focus-mode-to-thing
                    '((lua-mode . lsp-folding-range)
                      (rust-mode . lsp-folding-range)
                      (latex-mode . lsp-folding-range)
                      (python-mode . lsp-folding-range))))
;; Dimming:2 ends here

;; [[file:config.org::*Writeroom][Writeroom:1]]
(setq +zen-text-scale 0.8)
;; Writeroom:1 ends here

;; [[file:config.org::*Org-Mode][Org-Mode:1]]
(after! org
  (setq org-directory "~/org"                     ; let's put files here
        org-ellipsis "  ﬋"                        ; cute icon for folded org blocks
        org-list-allow-alphabetical t             ; have a. A. a) A) list bullets
        org-use-property-inheritance t            ; it's convenient to have properties inherited
        org-catch-invisible-edits 'smart          ; try not to accidently do weird stuff in invisible regions
        org-log-done 'time                        ; having the time a item is done sounds convenient
        org-roam-directory "~/org/roam/"))        ; same thing, for roam
;; Org-Mode:1 ends here

;; [[file:config.org::*Org-Mode][Org-Mode:2]]
(after! org
  (setq org-src-fontify-natively t
        org-fontify-whole-heading-line t
        org-inline-src-prettify-results '("⟨" . "⟩")
        org-fontify-done-headline t
        org-fontify-quote-and-verse-blocks t))
;; Org-Mode:2 ends here

;; [[file:config.org::*Org-Mode][Org-Mode:3]]
(after! org
  (setq org-babel-default-header-args
        '((:session . "none")
          (:results . "replace")
          (:exports . "code")
          (:cache . "no")
          (:noweb . "no")
          (:hlines . "no")
          (:tangle . "no")
          (:comments . "link"))))
;; Org-Mode:3 ends here

;; [[file:config.org::*Org-Mode][Org-Mode:4]]
(after! org
  (setq org-list-demote-modify-bullet '(("+" . "-") ("-" . "+") ("*" . "+") ("1." . "a."))))
;; Org-Mode:4 ends here

;; [[file:config.org::*Org-Mode][Org-Mode:5]]
(font-lock-add-keywords 'org-mode
                        '(("^ *\\([-]\\) "
                           (0 (prog1 () (compose-region (match-beginning 1) (match-end 1) "•"))))))
(font-lock-add-keywords 'org-mode
                        '(("^ *\\([+]\\) "
                           (0 (prog1 () (compose-region (match-beginning 1) (match-end 1) "◦"))))))
;; Org-Mode:5 ends here

;; [[file:config.org::*Org-Mode][Org-Mode:6]]
(after! ox
  (org-link-set-parameters "yt" :export #'+org-export-yt)
  (defun +org-export-yt (path desc backend _com)
    (cond ((org-export-derived-backend-p backend 'html)
           (format "<iframe width='440' \
height='335' \
src='https://www.youtube.com/embed/%s' \
frameborder='0' \
allowfullscreen>%s</iframe>" path (or "" desc)))
          ((org-export-derived-backend-p backend 'latex)
           (format "\\href{https://youtu.be/%s}{%s}" path (or desc "youtube")))
          (t (format "https://youtu.be/%s" path)))))
;; Org-Mode:6 ends here

;; [[file:config.org::*HTML export][HTML export:1]]
(defun org-inline-css-hook (exporter)
  "Insert custom inline css"
  (when (eq exporter 'html)
    (let* ((dir (ignore-errors (file-name-directory (buffer-file-name))))
           (path (concat dir "style.css"))
           (homestyle (or (null dir) (null (file-exists-p path))))
           (final (if homestyle (expand-file-name "misc/org-css/style.css" doom-private-dir) path)))
      (setq org-html-head-include-default-style nil)
      (setq org-html-head (concat
                           "<style type=\"text/css\">\n"
                           "<!--/*--><![CDATA[/*><!--*/\n"
                           (with-temp-buffer
                             (insert-file-contents final)
                             (buffer-string))
                           "/*]]>*/-->\n"
                           "</style>\n")))))

(defun org-inline-js-hook (exporter)
  "Insert custom inline css"
  (when (eq exporter 'html)
    (let* ((dir (ignore-errors (file-name-directory (buffer-file-name))))
           (path (concat dir "style.js"))
           (homestyle (or (null dir) (null (file-exists-p path))))
           (final (if homestyle (expand-file-name "misc/org-css/style.js" doom-private-dir) path)))
      (setq org-html-head-include-default-style nil)
      (setq org-html-head (concat
                          "<script type=\"text/javascript\">\n"
                           "<!--/*--><![CDATA[/*><!--*/\n"
                           (with-temp-buffer
                             (insert-file-contents final)
                             (buffer-string))
                           "/*]]>*/-->\n"
                           "</script>\n")))))

(defun org-inline-html-hook (exporter)
  "Insert custom inline css"
  (when (eq exporter 'html)
    (let* ((dir (ignore-errors (file-name-directory (buffer-file-name))))
           (path (concat dir "style.html"))
           (homestyle (or (null dir) (null (file-exists-p path))))
           (final (if homestyle (expand-file-name "misc/org-css/style.html" doom-private-dir) path)))
      (setq org-html-head-include-default-style nil)
      (setq org-html-head (concat
                           (with-temp-buffer
                             (insert-file-contents final)
                             (buffer-string))
                           "\n")))))

(add-hook 'org-export-before-processing-hook 'org-inline-css-hook)
(add-hook 'org-export-before-processing-hook 'org-inline-js-hook)
(add-hook 'org-export-before-processing-hook 'org-inline-html-hook)
;; HTML export:1 ends here

;; [[file:config.org::*HTML export][HTML export:2]]
(after! ox-html
  (setq org-html-mathjax-options
        '((path "https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-svg.js" )
          (scale "1")
          (autonumber "ams")
          (multlinewidth "85%")
          (tagindent ".8em")
          (tagside "right")))

  (setq org-html-mathjax-template
        "<script>
     MathJax = {
       chtml: {
         scale: %SCALE
       },
       svg: {
         scale: %SCALE,
         fontCache: \"global\"
       },
       tex: {
         tags: \"%AUTONUMBER\",
         multlineWidth: \"%MULTLINEWIDTH\",
         tagSide: \"%TAGSIDE\",
         tagIndent: \"%TAGINDENT\"
       }
     };
     </script>
     <script id=\"MathJax-script\" async
             src=\"%PATH\"></script>"))
;; HTML export:2 ends here

;; [[file:config.org::*HTML export][HTML export:3]]
(use-package! org-preview-html
  :commands org-preview-html-mode
  :config
  (setq org-preview-html-refresh-configuration 'save
        org-preview-html-viewer 'xwidget))
;; HTML export:3 ends here

;; [[file:config.org::*HTML export][HTML export:4]]
(setq org-startup-with-inline-images t)
;; HTML export:4 ends here
