Skip to content

Artawower/.emacs.d

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Emacs config

Installation

For install emacs on macos use brew:

brew install emacs-plus@28 --with-xwidgets --with-nobu417-big-sur-icon --with-no-frame-refocus --with-native-comp --with-dbus --with-imagemagick

Initial configs

Modern package manager.

Elpaca package.

(defvar elpaca-installer-version 0.7)
(defvar elpaca-directory (expand-file-name "elpaca/" user-emacs-directory))
(defvar elpaca-builds-directory (expand-file-name "builds/" elpaca-directory))
(defvar elpaca-repos-directory (expand-file-name "repos/" elpaca-directory))
(defvar elpaca-order '(elpaca :repo "https://github.com/progfolio/elpaca.git"
                              :ref nil :depth 1
                              :files (:defaults "elpaca-test.el" (:exclude "extensions"))
                              :build (:not elpaca--activate-package)))
(let* ((repo  (expand-file-name "elpaca/" elpaca-repos-directory))
       (build (expand-file-name "elpaca/" elpaca-builds-directory))
       (order (cdr elpaca-order))
       (default-directory repo))
  (add-to-list 'load-path (if (file-exists-p build) build repo))
  (unless (file-exists-p repo)
    (make-directory repo t)
    (when (< emacs-major-version 28) (require 'subr-x))
    (condition-case-unless-debug err
        (if-let ((buffer (pop-to-buffer-same-window "*elpaca-bootstrap*"))
                 ((zerop (apply #'call-process `("git" nil ,buffer t "clone"
                                                 ,@(when-let ((depth (plist-get order :depth)))
                                                     (list (format "--depth=%d" depth) "--no-single-branch"))
                                                 ,(plist-get order :repo) ,repo))))
                 ((zerop (call-process "git" nil buffer t "checkout"
                                       (or (plist-get order :ref) "--"))))
                 (emacs (concat invocation-directory invocation-name))
                 ((zerop (call-process emacs nil buffer nil "-Q" "-L" "." "--batch"
                                       "--eval" "(byte-recompile-directory \".\" 0 'force)")))
                 ((require 'elpaca))
                 ((elpaca-generate-autoloads "elpaca" repo)))
            (progn (message "%s" (buffer-string)) (kill-buffer buffer))
          (error "%s" (with-current-buffer buffer (buffer-string))))
      ((error) (warn "%s" err) (delete-directory repo 'recursive))))
  (unless (require 'elpaca-autoloads nil t)
    (require 'elpaca)
    (elpaca-generate-autoloads "elpaca" repo)
    (load "./elpaca-autoloads")))
(add-hook 'after-init-hook #'elpaca-process-queues)
(elpaca `(,@elpaca-order))

Elpaca use-package

;; Install use-package support
(elpaca elpaca-use-package
  ;; Enable :ensure use-package keyword.
  (elpaca-use-package-mode)
  ;; Assume :ensure t unless otherwise specified.
  (setq elpaca-use-package-by-default t))

;; Block until current queue processed.
(elpaca-wait)

Elpaca general

(with-eval-after-load 'general
  (general-define-key
   :states '(normal visual)
   :prefix "SPC"
   "pm" 'elpaca-status)

  (general-define-key
    :states '(normal)
    :keymaps 'elpaca-ui-mode-map
    "i" 'elpaca-ui-mark-install
    "s" 'elpaca-ui-execute-marks
    "S" 'elpaca-ui-search
    "d" 'elpaca-ui-mark-delete
    "u" 'elpaca-ui-mark-update
    "U" 'elpaca-update-all
    "r" 'elpaca-ui-mark-rebuild)
)

Elpaca fixese

(use-package closql :ensure (closql :depth nil) :defer t)
;; (use-package seq
;; :defer t)

;; (use-package subr :ensure nil)

;;   :preface
;;    (unload-feature 'subr t)
;; :ensure (:type git :host github :repo "emacs-mirror/emacs"))
(use-package jsonrpc
 :ensure (jsonrpc :depth 1)
 :defer t)

Env

https://www.reddit.com/r/emacs/comments/f8xwau/hack_replace_execpathfromshell/

;;; Code to replace exec-path-from-shell
;; Need to create file in $HOME/.emacs.d/.local/env
;; use this command to create the file  `printenv > $home/.emacs.d/.local/env'
(defconst my-local-dir (concat user-emacs-directory ".local/"))

(defconst my-env-file (concat my-local-dir "env"))

(defun my-load-envvars-file (file &optional noerror)
  "Read and set envvars from FILE.
If NOERROR is non-nil, don't throw an error if the file doesn't exist or is
unreadable. Returns the names of envvars that were changed."
  (if (not (file-readable-p file))
      (unless noerror
        (signal 'file-error (list "Couldn't read envvar file" file)))
    (let (envvars environment)
      (with-temp-buffer
        (save-excursion
          (insert "\n")
          (insert-file-contents file))
        (while (re-search-forward "\n *\\([^#= \n]*\\)=" nil t)
          (push (match-string 1) envvars)
          (push (buffer-substring
                 (match-beginning 1)
                 (1- (or (save-excursion
                           (when (re-search-forward "^\\([^= ]+\\)=" nil t)
                             (line-beginning-position)))
                         (point-max))))
                environment)))
      (when environment
        (setq process-environment
              (append (nreverse environment) process-environment)
              exec-path
              (if (member "PATH" envvars)
                  (append (split-string (getenv "PATH") path-separator t)
                          (list exec-directory))
                exec-path)
              shell-file-name
              (if (member "SHELL" envvars)
                  (or (getenv "SHELL") shell-file-name)
                shell-file-name))
        envvars))))

(when (and (or (display-graphic-p)
               (daemonp))
           (file-exists-p my-env-file))
  (my-load-envvars-file my-env-file))
;;; Code to replace exec-path-from-shell

Warning level

(setq warning-minimum-level :emergency)
(setq warning-suppress-log-types '((comp) (undo discard-info)))

Garbage collector

(let* ((normal-gc-cons-threshold (* 20 1024 1024))
     (init-gc-cons-threshold (* 128 1024 1024)))
(setq gc-cons-threshold init-gc-cons-threshold)
(add-hook 'emacs-startup-hook
          (lambda () (setq gc-cons-threshold (* 20 1024 1024)))))

Max process

(setq read-process-output-max (* 1024 1024))

Melpa

(require 'package)

(customize-set-variable 'package-archives
                        `(,@package-archives
                          ("melpa" . "http://melpa.org/packages/")
                          ("melpa" . "http://melpa.milkbox.net/packages/")
                          ("jcs-elpa" . "https://jcs-emacs.github.io/jcs-elpa/packages/")
                          ("melpa-stable" . "http://stable.melpa.org/packages/")
                          ("org" . "https://orgmode.org/elpa/")
                          ;; ("emacswiki" . "https://mirrors.tuna.tsinghua.edu.cn/elpa/emacswiki/")
                          ))
(customize-set-variable 'package-enable-at-startup nil)
;; (package-initialize)

Startup time boost

(use-package fnhh
  :ensure (:type git :host github :repo "a13/fnhh")
  :config
  (fnhh-mode 1))

Common

Backup

;; Change backup folders
(setq backup-directory-alist '(("." . "/Users/darkawower/tmp/emacs-backups")))
(setq lock-file-name-transforms
      '(("\\`/.*/\\([^/]+\\)\\'" "/var/tmp/\\1" t)))

Alias for yes/no

(ignore-errors
  (setq confirm-kill-emacs 'y-or-n-p)
  (defalias 'yes-or-no-p 'y-or-n-p))

Initial buffer

(setq initial-major-mode (quote fundamental-mode))

Environment variables

(use-package direnv
  :config
  (direnv-mode))

Patches

Alias for doom use-package!

(defalias 'use-package! 'use-package
"Alias for call use-package from doom modules")

Variables

Private configs

Load private configs

(ignore-errors
  (load "~/apps/pure-emacs/private.el"))
(elpaca-wait)

Browser

(when (eq system-type 'darwin)
  (setq browse-url-firefox-program nil)
  (setq browse-url-generic-program "/Applications/Brave Browser.app/Contents/MacOS/Brave Browser"
        browse-url-browser-function 'browse-url-generic))

Truncate lines

(set-default 'truncate-lines t)

No window mode

(defun @reset-nw-background ()
  (unless (display-graphic-p (selected-frame))
    (set-face-background 'default "unspecified-bg" (selected-frame))))

(add-hook 'window-setup-hook '@reset-nw-background)

Libs (functions and macros)

Doom libs (honestly spizjeno)

(use-package doom-lib
  :ensure (doom-lib
             :host github
             :repo "hlissner/doom-emacs"
             :files ("lisp/doom-lib.el" "lisp/lib/buffers.el")))

Bulk push

(defmacro pushnew! (place &rest values)
  "Push VALUES sequentially into PLACE, if they aren't already present.
This is a variadic `cl-pushnew'."
  (let ((var (make-symbol "result")))
    `(dolist (,var (list ,@values) (with-no-warnings ,place))
       (cl-pushnew ,var ,place :test #'equal))))

Some doom macros

Return EXP unquoted.

(defun doom-unquote (exp)
  "Return EXP unquoted."
  (declare (pure t) (side-effect-free t))
  (while (memq (car-safe exp) '(quote function))
    (setq exp (cadr exp)))
  exp)

macro for adding N functions to M hooks.

(defmacro add-hook! (hooks &rest rest)
  "A convenience macro for adding N functions to M hooks.

This macro accepts, in order:

  1. The mode(s) or hook(s) to add to. This is either an unquoted mode, an
     unquoted list of modes, a quoted hook variable or a quoted list of hook
     variables.
  2. Optional properties :local, :append, and/or :depth [N], which will make the
     hook buffer-local or append to the list of hooks (respectively),
  3. The function(s) to be added: this can be a quoted function, a quoted list
     thereof, a list of `defun' or `cl-defun' forms, or arbitrary forms (will
     implicitly be wrapped in a lambda).

\(fn HOOKS [:append :local [:depth N]] FUNCTIONS-OR-FORMS...)"
  (declare (indent (lambda (indent-point state)
                     (goto-char indent-point)
                     (when (looking-at-p "\\s-*(")
                       (lisp-indent-defform state indent-point))))
           (debug t))
  (let* ((hook-forms (doom--resolve-hook-forms hooks))
         (func-forms ())
         (defn-forms ())
         append-p local-p remove-p depth)
    (while (keywordp (car rest))
      (pcase (pop rest)
        (:append (setq append-p t))
        (:depth  (setq depth (pop rest)))
        (:local  (setq local-p t))
        (:remove (setq remove-p t))))
    (while rest
      (let* ((next (pop rest))
             (first (car-safe next)))
        (push (cond ((memq first '(function nil))
                     next)
                    ((eq first 'quote)
                     (let ((quoted (cadr next)))
                       (if (atom quoted)
                           next
                         (when (cdr quoted)
                           (setq rest (cons (list first (cdr quoted)) rest)))
                         (list first (car quoted)))))
                    ((memq first '(defun cl-defun))
                     (push next defn-forms)
                     (list 'function (cadr next)))
                    ((prog1 `(lambda (&rest _) ,@(cons next rest))
                       (setq rest nil))))
              func-forms)))
    `(progn
       ,@defn-forms
       (dolist (hook (nreverse ',hook-forms))
         (dolist (func (list ,@func-forms))
           ,(if remove-p
                `(remove-hook hook func ,local-p)
              `(add-hook hook func ,(or depth append-p) ,local-p)))))))

Converts a list of modes into a list of hook symbols.

(defun doom--resolve-hook-forms (hooks)
  "Converts a list of modes into a list of hook symbols.

If a mode is quoted, it is left as is. If the entire HOOKS list is quoted, the
list is returned as-is."
  (declare (pure t) (side-effect-free t))
  (let ((hook-list (ensure-list (doom-unquote hooks))))
    (if (eq (car-safe hooks) 'quote)
        hook-list
      (cl-loop for hook in hook-list
               if (eq (car-safe hook) 'quote)
               collect (cadr hook)
               else collect (intern (format "%s-hook" (symbol-name hook)))))))

Custom hooks

(defvar @before-buffer-changed-hook nil
  "Hook run before a buffer is changed.")

Dependencies

(use-package transient :ensure t)

Custom functions

Org

Add additional space before link insert

(defun my-add-additional-space-when-not-exist (_)
  "Add additional sapce if previous char is not space!"
  (unless (eq (char-before) ? )
    (insert " ")))

(advice-add 'org-insert-link :before 'my-add-additional-space-when-not-exist)

Format org mode block

(defun format-org-mode-block ()
  "Format org mode code block"
  (interactive "p")
  (org-edit-special)
  (format-all-ensure-formatter)
  (format-all-buffer)
  (org-edit-src-exit))

Init org mode faces for headlines

(defun @setup-org-mode-faces ()
  "Setup faces for org mode"
  (custom-set-faces
   '(org-document-title ((t (:inherit outline-1 :height 2.5)))))
   ;; '(org-level-1 ((t (:inherit outline-5 :height 2.0))))
   ;; '(org-level-2 ((t (:inherit outline-5 :height 2.0))))
   ;; '(org-level-3 ((t (:inherit outline-5 :height 2.0))))
   ;; '(org-level-4 ((t (:inherit outline-5 :height 2.0))))
   ;; '(org-level-5 ((t (:inherit outline-5 :height 2.0)))))
)

Browser

(defun my-switch-to-xwidget-buffer (&optional a b)
  "Switch to xwidget buffer."
  (interactive)
  (switch-to-first-matching-buffer "xwidget webkit"))

(defun my-toggle-default-browser ()
  "Toggle default browser for preview"
  (interactive)
  (if (eq browse-url-browser-function #'browse-url-default-browser)
      (progn (setq browse-url-browser-function #'xwidget-webkit-browse-url)
             (advice-add 'browse-url :after #'my-switch-to-xwidget-buffer))
    (progn
      (setq browse-url-browser-function #'browse-url-default-browser)
      (advice-remove 'browse-url #'my-switch-to-xwidget-buffer))))

KILL Navigation

(defun switch-to-first-matching-buffer (regex)
  (switch-to-buffer (car (remove-if-not (apply-partially #'string-match-p regex)
                                        (mapcar #'buffer-name (buffer-list))))))

Focus buffer by name

(defun +select-window-by-name (regexp)
  "Selects the window with buffer NAME"
  (select-window
   (car (seq-filter
     (lambda (window)
       (string-match-p regexp (buffer-name (window-buffer window))))
     (window-list-1 nil 0 t)))))

Workspaces

(defun toggle-maximize-buffer ()
	"Maximize buffer"
  (interactive)
  (if (= 1 (length (window-list)))
      (jump-to-register '_)
    (progn
      (window-configuration-to-register '_)
      (delete-other-windows))))

Register copy

Copy selected text to special register

(defun xah-copy-to-register-1 ()
  "Copy current line or text selection to register 1.
See also: `xah-paste-from-register-1', `copy-to-register'.

;;;; Register copy past
URL `http://xahlee.info/emacs/emacs/elisp_copy-paste_register_1.html'
Version 2017-01-23"
  (interactive)
  (let ($p1 $p2)
    (if (region-active-p)
        (progn (setq $p1 (region-beginning))
               (setq $p2 (region-end)))
      (progn (setq $p1 (line-beginning-position))
             (setq $p2 (l(defun xah-paste-from-register-1 ()
                           "Paste text from register 1.
See also: `xah-copy-to-register-1', `insert-register'.
URL `http://xahlee.info/emacs/emacs/elisp_copy-paste_register_1.html'
Version 2015-12-08"
                           (interactive)
                           (when (use-region-p)
                             (delete-region (region-beginning) (region-end)))
                           (insert-register ?1 t))ine-end-position))))
    (copy-to-register ?1 $p1 $p2)
    (message "Copied to register 1: 「%s」." (buffer-substring-no-properties $p1 $p2))))

Paste copied text from register

(defun xah-paste-from-register-1 ()
  "Paste text from register 1.
See also: `xah-copy-to-register-1', `insert-register'.
URL `http://xahlee.info/emacs/emacs/elisp_copy-paste_register_1.html'
Version 2015-12-08"
  (interactive)
  (when (use-region-p)
    (delete-region (region-beginning) (region-end)))
  (insert-register ?1 t))

Delete current file

(defun @delete-this-file (&optional path force-p)
  "Delete PATH, kill its buffers and expunge it from vc/magit cache.
If PATH is not specified, default to the current buffer's file.
If FORCE-P, delete without confirmation."
  (interactive
   (list (buffer-file-name (buffer-base-buffer))
         current-prefix-arg))
  (let* ((path (or path (buffer-file-name (buffer-base-buffer))))
         (short-path (and path (abbreviate-file-name path))))
    (unless path
      (user-error "Buffer is not visiting any file"))
    (unless (file-exists-p path)
      (error "File doesn't exist: %s" path))
    (unless (or force-p (y-or-n-p (format "Really delete %S?" short-path)))
      (user-error "Aborted"))
    (let ((buf (current-buffer)))
      (unwind-protect
          (progn (delete-file path t) t)
        (if (file-exists-p path)
            (error "Failed to delete %S" short-path)
          ;; Ensures that windows displaying this buffer will be switched to
          ;; real buffers (`doom-real-buffer-p')
          (doom/kill-this-buffer-in-all-windows buf t)
          (doom-files--update-refs path)
          (message "Deleted %S" short-path))))))

Forge open remote file

(defun @forge-browse-buffer-file ()
  (interactive)
  (browse-url
   (let
       ((rev (cond ((and (boundp git-timemachine-mode) git-timemachine-mode) (git-timemachine-kill-revision))
                   ((and (boundp magit-gitflow-mode) magit-gitflow-mode) (magit-copy-buffer-revision))
                   (t "master")))
        (repo (forge-get-repository 'stub))
        (file (magit-file-relative-name buffer-file-name))
        (highlight
         (if
             (use-region-p)
             (let ((l1 (line-number-at-pos (region-beginning)))
                   (l2 (line-number-at-pos (- (region-end) 1))))
               (format "#L%d-L%d" l1 l2))
           ""
           )))
     (if (not file)
         (if-let ((path (forge--split-remote-url (forge--get-remote))))
                  (message "https://%s/%s/%s/commit/%s" (nth 0 path) (nth 1 path) (nth 2 path) rev)
           (user-error "Cannot browse non-forge remote %s" (forge--get-remote)))

       (forge--format repo "https://%h/%o/%n/blob/%r/%f%L"
                      `((?r . ,rev) (?f . ,file) (?L . ,highlight)))))))

Highlight selection

(use-package selection-highlight-mode
  :ensure (selection-highlight-mode :type git
                                      :host github
                                      :repo "balloneij/selection-highlight-mode")
  :config (selection-highlight-mode))

Toggle transparency

(setq my-transparency-disabled-p t)
(defun @toggle-transparency ()
  "Toggle transparency"
  (interactive)
  (let* ((not-transparent-p (and (boundp 'my-transparency-disabled-p) my-transparency-disabled-p))
         (alpha (if not-transparent-p 100 85)))
    (setq my-transparency-disabled-p (not not-transparent-p))
    (message "%s" alpha)
    (progn
      (set-frame-parameter (selected-frame) 'alpha `(,alpha . ,alpha))
      (add-to-list 'default-frame-alist `(alpha . (,alpha . ,alpha))))))

Insert TODO attached to current git branch

Base function

(defun @insert--todo-by-current-git-branch (todo-type)
  "Insert todo for current git branch."
  (let* ((branch-name (magit-get-current-branch))
         (vw (string-match "\\(?1:[A-Za-z0-9]+\/\\)\\(?2:VW-[0-9]+\\)" branch-name))
         (task-number (match-string 2 branch-name))
         (todo-msg (or task-number branch-name)))
    (insert (format "%s: %s " todo-type todo-msg))
    (comment-line 1)
    ;; (forward-line 1)
    (previous-line)
    (end-of-line)
    (indent-according-to-mode)
    (evil-insert 1)))
(defun @insert-todo-by-current-git-branch ()
  "Insert todo for current git branch."
  (interactive)
  (@insert--todo-by-current-git-branch "TODO"))

(defun @insert-debug-by-current-git-branch ()
  "Insert debug for current git branch."
  (interactive)
  (@insert--todo-by-current-git-branch "DEBUG"))

(defun @insert-note-by-current-git-branch ()
  "Insert note for current git branch."
  (interactive)
  (@insert--todo-by-current-git-branch "NOTE"))

Insert tab

(defun @insert-tab ()
  "Insert simple tab"
  (interactive)
  (insert "\t"))

Open fodler with emacs config

TODO: check why it doesn;t work

(defun @open-emacs-config ()
  "Open folder with emacs config"
  (interactive)
  (let ((default-directory "~/apps/pure-emacs/README.org"))
    (call-interactively 'find-file)))

Window

(defun @window-split-toggle ()
  "Toggle between horizontal and vertical split with two windows."
  (interactive)
  (if (> (length (window-list)) 2)
      (error "Can't toggle with more than 2 windows!")
    (let ((func (if (window-full-height-p)
                    #'split-window-vertically
                  #'split-window-horizontally)))
      (delete-other-windows)
      (funcall func)
      (save-selected-window
        (other-window 1)
        (switch-to-buffer (other-buffer))))))

Sass autofix

For correct work you need to install sass-lint-auto-fix yarn global add sass-lint-auto-fix

(defun @run-sass-auto-fix ()
  "Run sass auto fix if cli tool exist"
  (interactive)
  (save-window-excursion
    (let ((default-directory (file-name-directory buffer-file-name)))
      (async-shell-command "sass-lint-auto-fix")
      ;; (revert-buffer-no-confirm)
      (message "SASS FORMATTED"))))

open finder here!

Need to steal from doom emacs!

Always open message Messages in the vertical column

(defun @open-messages ()
  "Open *Messages* buffer."
  (interactive)
  (if (one-window-p)
      (split-window-horizontally))
  (pop-to-buffer "*Messages*"))

(defun @open-clear-messages ()
  "Open *Messages* buffer and clear it."
  (interactive)
  (if (one-window-p)
      (split-window-horizontally))
  (pop-to-buffer "*Messages*")
  (read-only-mode -1)
  (erase-buffer))

LSP

Go to definition

(defun @find-definition ()
  "Find lsp definition when lsp exist and enabled, or find evil definition."
  (interactive)
  (cond ((bound-and-true-p lsp-bridge-mode) (lsp-bridge-find-def))
        ((and (bound-and-true-p eglot--managed-mode) eglot--managed-mode) (evil-goto-definition))
        ((and (bound-and-true-p lsp-mode) (bound-and-true-p lsp-ui-mode) lsp-ui-mode) (lsp-ui-peek-find-definitions))
        ((and (bound-and-true-p lsp-mode) lsp-mode) (lsp-find-definition))
        (t (evil-goto-definition))))

Avy + goto definition

(defun @avy-go-to-definition ()
  (interactive)
  (evil-avy-goto-word-1 nil)
  (@find-definition))

Performance

Uncomment when u need to profile ;p

Profiler

(use-package explain-pause-mode
  :ensure (explain-pause-mode :type git :host github :repo "lastquestion/explain-pause-mode")
  :defer t)

HOLD Package startup speed

(use-package esup)

Use package startup time

(setq use-package-verbose t)

UI

All the icons.

(use-package all-the-icons
  :ensure t)
  ;; :config
  ;; (set-fontset-font t 'unicode (font-spec :family "all-the-icons") nil 'prepend)
  ;; (set-fontset-font t 'unicode (font-spec :family "file-icons") nil 'prepend)
  ;; (set-fontset-font t 'unicode (font-spec :family "Material Icons") nil 'prepend)
  ;; (set-fontset-font t 'unicode (font-spec :family "github-octicons") nil 'prepend)
  ;; (set-fontset-font t 'unicode (font-spec :family "FontAwesome") nil 'prepend)
  ;; (set-fontset-font t 'unicode (font-spec :family "Weather Icons") nil 'prepend)
  ;; (setq inhibit-compacting-font-caches t))
(use-package all-the-icons-completion
  :after (marginalia all-the-icons)
  :hook (marginalia-mode . all-the-icons-completion-marginalia-setup)
  :init
  (all-the-icons-completion-mode))

Full size from startup

(add-to-list 'default-frame-alist '(fullscreen . maximized))

Disable default splash screen

(setq inhibit-splash-screen t)
(setq inhibit-startup-message t)

Titlebar color

Very pretty titlebar for Mac os

(use-package ns-auto-titlebar
  :config
  (when (eq system-type 'darwin) (ns-auto-titlebar-mode)))

Variables

(setq +m-color-main "#61AFEF"
      +m-color-secondary "#FF3399"
      +m-color-yellow "#FFAA00"
      +m-color-blue "#00AEE8"
      +m-color-cyan "#00CED1"
      +m-color-green "#00D364"
      +org-todo-onhold "#FFAA00")

Faces

(defface +org-todo-onhold-face
  `((t (:foreground ,+org-todo-onhold :weight bold)))
  "Face for TODO items with the ONHOLD keyword."
  :group 'org-faces)

Custom italic-like faces

(defface italic-string-face
  '((t (:inherit font-lock-string-face :slant italic)))
  "Face for italic strings."
  :group 'faces)

Custom italic build-in face

(defface italic-builtin-face
  '((t (:inherit font-lock-builtin-face :slant italic)))
  "Face for italic keywords."
  :group 'faces)

Dired icons

(use-package all-the-icons-dired
  :after dired
  :hook (dired-mode . all-the-icons-dired-mode))

Highlight keywords

(use-package hl-todo
  :ensure (hl-todo :depth nil)
  :defer 2
  :config
  (setq hl-todo-keyword-faces
        '(("TODO"   . "#E5C07B")
          ("FIXME"  . "#E06C75")
          ("DEBUG"  . "#C678DD")
          ("REFACTOR"  . "#C678DD")
          ("GOTCHA" . "#FF4500")
          ("NOTE"   . "#98C379")
          ("QUESTION"   . "#98C379")
          ("STUB"   . "#61AFEF")))
  (global-hl-todo-mode 1))

Rainbow extension

(use-package colorful-mode
  :ensure (:type git :host github :repo "DevelopmentCool2449/colorful-mode"))
            

Pixel scroll

(pixel-scroll-mode)

Smooth scroll by jump

(use-package scroll-on-jump
  :custom
  (scroll-on-jump-smooth t)
  (scroll-on-jump-duration 0.1337)
  :config
  (scroll-on-jump-advice-add beginning-of-buffer)
  (scroll-on-jump-advice-add end-of-buffer)
  (scroll-on-jump-advice-add flyspell-goto-next-error)
  (when (featurep 'smartparens)
    (define-key smartparens-mode-map
      (kbd "C-M-f") (scroll-on-jump-interactive 'sp-forward-sexp))
    (define-key smartparens-mode-map
      (kbd "C-M-b") (scroll-on-jump-interactive 'sp-backward-sexp)))
  ;; (scroll-on-jump-with-scroll-advice-add scroll-up-command)
  (scroll-on-jump-with-scroll-advice-add View-scroll-half-page-backward)
  (scroll-on-jump-with-scroll-advice-add View-scroll-half-page-backward)
  (scroll-on-jump-with-scroll-advice-add evil-scroll-down)
  (scroll-on-jump-with-scroll-advice-add evil-scroll-up)
  ;; (scroll-on-jump-with-scroll-advice-add ccm-scroll-down)
  ;; (scroll-on-jump-with-scroll-advice-add ccm-scroll-up)
  (scroll-on-jump-with-scroll-advice-add isearch-update)
  (scroll-on-jump-with-scroll-advice-add recenter-top-bottom))

Fringes

(use-package spacious-padding
:config
(spacious-padding-mode))
(defun @correct-my-fringe (&optional ignore)
  "Set fringes for current active window."
  (interactive)
  (unless (eq fringe-mode '16)
    (fringe-mode '16)))


(add-hook 'after-init-hook #'@correct-my-fringe)
(add-hook 'buffer-list-update-hook #'@correct-my-fringe)
(setq-default left-margin-width 2 right-margin-width 2)

Column indicator. display-fill-column-indicator. 80 Line ;)

(use-package display-fill-column-indicator
  :defer t
  :ensure nil
  :config
  (setq display-fill-column-indicator-column 80))

Centered mode

(use-package centered-cursor-mode
  :hook (prog-mode . centered-cursor-mode)
  :demand)

Theme

Functions

Hook on theme changed

 (defvar after-load-theme-hook nil
    "Hook run after a color theme is loaded using `load-theme'.")
  (defadvice load-theme (after run-after-load-theme-hook activate)
    "Run `after-load-theme-hook'."
    (run-hooks 'after-load-theme-hook))

(add-hook 'after-load-theme-hook #'@reset-nw-background)

Automatic reset theme

(defadvice load-theme (before theme-dont-propagate activate)
 (mapcar #'disable-theme custom-enabled-themes))

Paddings

(fringe-mode '16)

Common ui

Doesn’t work for mac os unfortunately ;c

(progn
  (set-frame-parameter (selected-frame) 'alpha '(100 . 100))
  (add-to-list 'default-frame-alist '(alpha . (100 . 100))))

Doom emacs themes

Theme

(use-package doom-themes
  :ensure t
  :config
  ;; Global settings (defaults)
  (setq doom-themes-enable-bold t    ; if nil, bold is universally disabled
        doom-themes-enable-italic t) ; if nil, italics is universally disabled
  (load-theme 'doom-moonlight t)

  ;; Enable flashing mode-line on errors
  (doom-themes-visual-bell-config)
  ;; Enable custom neotree theme (all-the-icons must be installed!)
  (doom-themes-neotree-config)
  ;; or for treemacs users
  (setq doom-themes-treemacs-theme "doom-atom") ; use "doom-colors" for less minimal icon theme
  (doom-themes-treemacs-config)
  ;; Corrects (and improves) org-mode's native fontification.
  (doom-themes-org-config))

Doom Modeline

(use-package doom-modeline
  :defer t
  :hook (after-init . doom-modeline-mode)
  :config
  (setq doom-modeline-buffer-file-name-style 'file-name))

Hide modeline

Hide modeline mode

(use-package hide-mode-line
  :hook
  (prog-mode . hide-mode-line-mode)
  (text-mode . hide-mode-line-mode)
  (org-mode . hide-mode-line-mode))

Window divider

(setq window-divider-default-places t
      window-divider-default-bottom-width 1
      window-divider-default-right-width 0)
(window-divider-mode +1)

Catppuccini theme

Original

(defun @set-catppucin-theme ()
  (interactive)
  (message "AUTO DARK SET CATPPUCIN")
  (setq catppuccin-flavor (if (eq auto-dark--last-dark-mode-state 'dark) 'frappe 'latte))
  (message "CATppUCCIN FLAVOR %s" catppuccin-flavor)
  (catppuccin-reload))

(use-package catppuccin-theme
  :after auto-dark
  :config
  (defface font-lock-object-key-face
    `((t (:inherit font-lock-property-name-face :foreground ,(catppuccin-get-color 'lavender))))
    "Face for object keys."
    :group 'font-lock-faces)
  ;; (set-face-attribute 'font-lock-property-name-face nil :foreground (catppuccin-get-color 'lavender))
  (add-hook 'auto-dark-dark-mode-hook #'@set-catppucin-theme)
  (add-hook 'auto-dark-light-mode-hook #'@set-catppucin-theme)
  (@set-catppucin-theme)
  (set-face-attribute 'highlight nil :background "#dce0e8")

  ;; https://github.com/catppuccin/emacs/issues/55
  (add-hook 'yaml-mode-hook
            (lambda ()
              (face-remap-add-relative 'font-lock-variable-name-face
                                       (list :foreground (catppuccin-get-color 'blue))))))

Deps

(use-package autothemer
  :ensure t)

Dashboard

Doesn’t work with chemacs and emacs 29 emacs-dashboard/emacs-dashboard#421

(use-package dashboard
  :config
  (dashboard-setup-startup-hook))

Fonts

Default font

(set-frame-font "JetBrainsMono Nerd Font 14" nil t)
;; (set-frame-font "Monaspace Neon 14" nil t)
;; (set-frame-font "Menlo 14" nil t)
;; (set-frame-font "Monaco Font 15" nil t)

Ligatures

(defconst jetbrains-ligature-mode--ligatures
  '("-->" "//" "/**" "/*" "*/" "<!--" ":=" "->>" "<<-" "->" "<-"
    "<=>" "==" "!=" "<=" ">=" "=:=" "!==" "&&" "||" "..." ".."
    "|||" "///" "&&&" "===" "++" "--" "=>" "|>" "<|" "||>" "<||"
    "|||>" "<|||" ">>" "<<" "::=" "|]" "[|" "{|" "|}"
    "[<" ">]" ":?>" ":?" "/=" "[||]" "!!" "?:" "?." "::"
    "+++" "??" "###" "##" ":::" "####" ".?" "?=" "=!=" "<|>"
    "<:" ":<" ":>" ">:" "<>" "***" ";;" "/==" ".=" ".-" "__"
    "=/=" "<-<" "<<<" ">>>" "<=<" "<<=" "<==" "<==>" "==>" "=>>"
    ">=>" ">>=" ">>-" ">-" "<~>" "-<" "-<<" "=<<" "---" "<-|"
    "<=|" "/\\" "\\/" "|=>" "|~>" "<~~" "<~" "~~" "~~>" "~>"
    "<$>" "<$" "$>" "<+>" "<+" "+>" "<*>" "<*" "*>" "</>" "</" "/>"
    "<->" "..<" "~=" "~-" "-~" "~@" "^=" "-|" "_|_" "|-" "||-"
    "|=" "||=" "#{" "#[" "]#" "#(" "#?" "#_" "#_(" "#:" "#!" "#="
    "&="))

(sort jetbrains-ligature-mode--ligatures (lambda (x y) (> (length x) (length y))))

(dolist (pat jetbrains-ligature-mode--ligatures)
  (set-char-table-range composition-function-table
                        (aref pat 0)
                        (nconc (char-table-range composition-function-table (aref pat 0))
                               (list (vector (regexp-quote pat)
                                             0
                                             'compose-gstring-for-graphic)))))

Auto dark mode. Theme switcher.

Function for setting terminal color after theme switch

(defun @set-colors-after-theme-loaded ()
  "Change color of autocomplete inside vterm"
  (interactive)
  ;; Face for completion navigation
  (set-face-attribute 'highlight nil :background "#dce0e8")
  (when (facep 'vterm-color-black)
    (set-face-attribute 'vterm-color-black nil :foreground +m-color-secondary :background +m-color-secondary)))

Override function for auto-dark mode for applying function for nano theme changing, instead of them applying

(use-package auto-dark
  :after posframe
  :config
  (add-hook 'auto-dark-dark-mode-hook #'@set-colors-after-theme-loaded)
  (add-hook 'auto-dark-light-mode-hook #'@set-colors-after-theme-loaded)
  (add-hook 'auto-dark-dark-mode-hook #'posframe-delete-all)
  (add-hook 'auto-dark-light-mode-hook #'posframe-delete-all)
  (setq auto-dark-dark-theme 'catppuccin)
  (setq auto-dark-light-theme 'catppuccin)
  (auto-dark-mode))

Disable menu bar mode and other stuff

(menu-bar-mode -1)
(tool-bar-mode -1)
(toggle-scroll-bar -1)
(setq ring-bell-function 'ignore)

Keybindings

Key checker

(use-package which-key
  :defer t
  :config
  (which-key-setup-side-window-right)
  (which-key-mode))

Common

(define-key global-map (kbd "C-h") (make-sparse-keymap))
(global-set-key (kbd "C-S-l") 'enlarge-window-horizontally)
(global-set-key (kbd "C-S-h") 'shrink-window-horizontally)
(global-set-key (kbd "<C-S-up>") 'shrink-window)
(global-set-key (kbd "C-S-j") 'enlarge-window)
(global-set-key (kbd "<C-S-down>") 'enlarge-window)
(global-set-key (kbd "C-S-k") 'shrink-window)

General

Global keys

Evil. Isert mode.

Evil. Normal space state map.

Evil normal/visual state map

(general-define-key
 :states '(normal visual)
 :keymaps 'override
 "C-u" 'evil-scroll-up
 "C-e" 'pixel-scroll-up
 "gf" '@avy-go-to-definition
 "C-y" 'pixel-scroll-down
 "s-Y" 'xah-copy-to-register-1
 "s-r" (lambda () (interactive) (set-mark-command nil) (evil-avy-goto-char))
 "s-P" 'xah-paste-from-register-1)

Minibuffer mode map

(general-define-key
 :keymaps '(minibuffer-local-map read--expression-map minibuffer-local-shell-command-map evil-ex-completion-map)
 "C-w" 'backward-kill-word
 "C-k" 'previous-history-element
 "C-p" 'previous-history-element
 "C-u" 'evil-delete-back-to-indentation
 ;; "<tab>" 'completion-at-point
 ;; "<tab>" 'completion-at-point
 "C-j" 'next-history-element
 "C-n" 'next-history-element
 "<escape>" 'keyboard-escape-quit
 "C-x" (lambda () (interactive) (end-of-line) (kill-whole-line)))

Evil

Evil. Leader.

(general-define-key
 :states '(visual normal)
 :keymaps 'override
 :prefix "\\"
  "f" 'avy-goto-char
  "b" 'my-switch-to-xwidget-buffer
  "w" 'avy-goto-word-0
  "]" 'flycheck-next-error
  "[" 'flycheck-previous-error
  "d" 'dap-debug

  "o" 'org-mode
  "q" 'kill-current-buffer
  "v" 'vterm
  "`" 'vterm-toggle-cd
  "i" 'git-messenger:popup-message
  "t" 'google-translate-smooth-translate
  "T" 'google-translate-query-translate
  "a" 'counsel-org-agenda-headlines
  "c" 'dired-create-empty-file
  "s" 'publish-org-blog
  "g" 'codegpt
  ;; Evil
  "=" 'evil-record-macro
  "-" 'evil-execute-macro
  "0" 'my-toggle-default-browser
  "h" 'lsp-ui-doc-toggle
  "e" 'lsp-treemacs-errors-list
  "l" 'lsp-execute-code-action
  "r" 'treemacs-select-window
  "m" 'toggle-maximize-buffer)

Configs

Universal keybindings across keyboard layouts

(use-package char-fold
  :ensure nil
  :custom
  (char-fold-symmetric t)
  (search-default-mode #'char-fold-to-regexp))
(use-package reverse-im
  :demand t ; always load it
  :after char-fold ; but only after `char-fold' is loaded
  :custom
  (reverse-im-char-fold t) ; use lax matching
  (reverse-im-read-char-advice-function #'reverse-im-read-char-include)
  (reverse-im-input-methods '("russian-computer")) ; translate these methods
  :config
  (reverse-im-mode t))

Navigation

Evil

Patch for recover visual line after shifting

(define-key evil-visual-state-map (kbd ">") '@evil-shift-right-visual)
(define-key evil-visual-state-map (kbd "<") '@evil-shift-left-visual)
(define-key evil-visual-state-map [tab] '@evil-shift-right-visual)
(define-key evil-visual-state-map [S-tab] '@evil-shift-left-visual)

(defun @evil-shift-left-visual ()
  (interactive)
  (evil-shift-left (region-beginning) (region-end))
  (evil-normal-state)
  (evil-visual-restore))

(defun @evil-shift-right-visual ()
  (interactive)
  (evil-shift-right (region-beginning) (region-end))
  (evil-normal-state)
  (evil-visual-restore))

Evil should respect visual line mode

(defun evil-next-line--check-visual-line-mode (orig-fun &rest args)
  (if visual-line-mode
      (apply 'evil-next-visual-line args)
    (apply orig-fun args)))

(advice-add 'evil-next-line :around 'evil-next-line--check-visual-line-mode)

(defun evil-previous-line--check-visual-line-mode (orig-fun &rest args)
  (if visual-line-mode
      (apply 'evil-previous-visual-line args)
    (apply orig-fun args)))

(advice-add 'evil-previous-line :around 'evil-previous-line--check-visual-line-mode)
(use-package evil-collection
  :after evil
  :config
  (evil-collection-init))

(use-package evil
  :init
  (setq evil-want-keybinding nil)
  :config

  (modify-syntax-entry ?_ "w")
  (setq evil-v$-excludes-newline t)
  <<evil-shifting-config>>
  <<evil-respect-visual-line-mode>>
  (setq evil-respect-visual-line-mode t)
  (evil-set-undo-system 'undo-fu)
  (setq-default evil-kill-on-visual-paste nil)
  (evil-mode 1)
  <<general-minibuffer-mode-map>>)

Evil commentrary

(use-package evil-commentary
  :bind (:map evil-normal-state-map
              ("gc" . evil-commentary)))

Bookmarks

Bookmark for navigation inside file

(use-package bm
:defer t
:custom-face
(bm-face ((t (:foreground ,+m-color-secondary :background unspecified))))
:custom
(bm-in-lifo-order t)
:bind (("C-M-n" . bm-next)
        ("C-M-p" . bm-previous)
        ("s-b" . bm-toggle)))

Avy. fast jump

(use-package avy
  :defer t
  :general
  (:states '(normal visual)
           :keymaps 'override
           "f" 'avy-goto-word-1
           "gD" '@avy-go-to-definition
           "SPC k l" 'avy-kill-whole-line
           "SPC k r" 'avy-kill-region)
  (:keymaps '(minibuffer-local-mode-map read--expression-map)
            "C-l" 'avy-goto-char
            "C-f" 'avy-goto-char)
  :custom
  (avy-single-candidate-jump t)
  (avy-keys '(?q ?w ?e ?r ?t ?y ?u ?i ?o ?p ?a ?s ?d ?f ?h ?j ?k ?l ?z ?x ?c ?v ?b ?n ?m)))

Ace window. Fast jump between opened windows and frames

(defun @avy-ignore-current-buffer ()
  "Ignore current buffer when using avy."
  (interactive)
  (add-to-list 'aw-ignored-buffers (buffer-name)))
(use-package ace-window
  :general
  (:keymaps 'override
            :states
            '(normal visual insert)
            "s-." #'ace-window
            "s-g" #'ace-window)
  :bind (:map evil-normal-state-map
              ("s-." . ace-window)
              ("s-g" . ace-window)
              ("SPC a i" . @avy-ignore-current-buffer))
  :defer t
  :config
  (setq aw-ignored-buffers (delq 'treemacs-mode aw-ignored-buffers))
  ;; (add-to-list 'aw-ignored-buffers 'dap-ui--locals-buffer)
  <<avy-ignore-current-buffer-fn>>)

Evil matchit. Quick jump by pairtags

(use-package evil-matchit
  :hook
  (html-mode . evil-matchit-mode)
  (ng2-html-mode . evil-matchit-mode)
  (web-mode . evil-matchit-mode)
  :init
  (evilmi-load-plugin-rules '(ng2-html-mode) '(html)))

Better jump

(defun @better-jump-preserve-pos-advice (oldfun &rest args)
  "Preserve position when jumping."
  (let ((old-pos (point)))
    (apply oldfun args)
    (when (> (abs (- (line-number-at-pos old-pos) (line-number-at-pos (point))))
             1)
      (better-jumper-set-jump old-pos))))
(use-package better-jumper
  :demand t
  :general
  (:states '(normal, visual)
           "C-o" 'better-jumper-jump-backward
           "C-i" 'better-jumper-jump-forward
           "SPC sp" 'better-jumper-set-jump)
  :custom
  ;; (better-jumper-add-jump-behavior #'replace)
  (better-jumper-use-evil-jump-advice nil)
  :config
  <<better-jump-fn>>
  (advice-add 'evil-next-line :around #'@better-jump-preserve-pos-advice)
  (advice-add 'evil-previous-line :around #'@better-jump-preserve-pos-advice)
  (advice-add '@find-definition :before (lambda () (call-interactively #'better-jumper-set-jump)))
  (advice-add 'evil-jump-item :around #'@better-jump-preserve-pos-advice)
  (better-jumper-mode 1))

Buffer frog. Another one buffer navigation

(use-package frog-jump-buffer
  :ensure (:host github :repo "waymondo/frog-jump-buffer")
  :bind
  (("s-t" . frog-jump-buffer))
  :config
  (setq frog-jump-buffer-default-filter 'frog-jump-buffer-filter-same-project)
  ;; (defun frog-jump-buffer-filter-persp-buffers (buffer)
  ;;   (with-current-buffer buffer
  ;;     (let ((persp-name (if (and (fboundp 'safe-persp-name) (fboundp 'get-current-persp))
  ;;                           (safe-persp-name (get-current-persp))
  ;;                         "default"))
  ;;           )
  ;;       )
  ;;     (-any? #'derived-mode-p '(comint-mode magit-mode inf-ruby-mode rg-mode compilation-mode))))

  ;; (setq frog-jump-buffer-filter-actions
  ;;       '(("p" "[persp]" frog-jump-buffer-filter-persp-buffers)))

  (defun frog-jump-buffer-same-project ()
    (interactive)
    (let ((frog-jump-buffer-current-filter-function #'frog-jump-buffer-filter-same-project))
      (frog-jump-buffer)))
  (setq frog-jump-buffer-use-all-the-icons-ivy t)
  (dolist (regexp '("TAGS" "^\\*" "^\\*elpaca" "^\\*lsp" "^\\*calendar" "^\\*Google" "^\\*copilot" "^\\*dashboard" "^\\*direnv" "^\\*Compile-log" "-debug\\*$" "^\\:" "errors\\*$" "^\\*Backtrace" "-ls\\*$"
                    "stderr\\*$" "^\\*Flymake" "^\\*vc" "^\\*Warnings" "^\\*eldoc" "\\^*Shell Command"))
    (push regexp frog-jump-buffer-ignore-buffers)))

Common emacs packages

Autorevert

(setq global-auto-revert-mode nil)
(setq auto-revert-verbose nil)

Files

Treemacs

(use-package treemacs
  :defer t
  :bind
  (:map treemacs-mode-map
        ("@" . evil-execute-macro)
        :map evil-normal-state-map
        ("SPC o p" . treemacs))
  :custom-face
  (font-lock-doc-face ((t (:inherit nil))))
  (doom-themes-treemacs-file-face ((t (:inherit font-lock-doc-face :slant italic))))
  (doom-themes-treemacs-root-face ((t (:inherit nil :slant italic))))
  (treemacs-root-face ((t (:inherit variable-pitch :slant italic))))
  :custom
  (treemacs-width 45)
  :config
  (setq doom-themes-treemacs-theme "doom-colors") ; use "doom-colors" for less minimal icon theme
  (doom-themes-treemacs-config)
  (doom-themes-org-config))

Treemacs projectile

(use-package treemacs-projectile
  :after treemacs projectile
  :defer t)

Dired configs

(use-package dired
  :defer t
  :ensure nil
  :general
  (:keymaps 'override
            :states 'normal
            "SPC fi" 'image-dired)
  (:keymaps 'dired-mode-map
	          "C-c C-e" 'wdired-change-to-wdired-mode)
  :config
  (setq dired-dwim-target t)
  (setq insert-directory-program "gls" dired-use-ls-dired t)
  (add-hook 'dired-mode-hook 'auto-revert-mode))

Dirvish. Dired batteries ;3

Doesn’t work on mac properly. Very laggy unfortunately Dirvish.

(use-package dirvish
  :init
  (dirvish-override-dired-mode)
  :custom
  (dirvish-quick-access-entries ; It's a custom option, `setq' won't work
   '(("h" "~/"                          "Home")
     ("d" "~/Downloads/"                "Downloads")))
  :config
  ;; (dirvish-peek-mode) ; Preview files in minibuffer
  ;; (dirvish-side-follow-mode) ; similar to `treemacs-follow-mode'
  ;; (remove-hook 'dired-mode-hook 'treemacs-icons-dired-mode)
  ;; (remove-hook 'dired-after-readin-hook 'treemacs-icons-dired--display)
  ;; (setq dirvish-mode-line-format
  ;;       '(:left (sort symlink) :right (omit yank index)))
  (setq dirvish-attributes
        '(file-time collapse subtree-state))
  ;; (setq dirvish-attributes
  ;;       '(file-time collapse subtree-state vc-state git-msg))
  (setq delete-by-moving-to-trash t)
  ;; (setq dired-listing-switches
  ;;       "-l --almost-all --human-readable --group-directories-first --no-group")
  :bind
  ;; Bind `dirvish|dirvish-side|dirvish-dwim' as you see fit
  (("C-c f" . dirvish)
   :map dirvish-mode-map
   ("q" . dirvish-quit)
   :map dired-mode-map ; Dirvish respects all the keybindings in this map
   ("q" . dirvish-quit)
   ("h" . dired-up-directory)
   ("j" . dired-next-line)
   ("k" . dired-previous-line)
   ("l" . dired-find-file)
   ("i" . wdired-change-to-wdired-mode)
   ("." . dired-omit-mode)
   ("b"   . dirvish-bookmark-jump)
   ("f"   . dirvish-file-info-menu)
   ("y"   . dirvish-yank-menu)
   ("N"   . dirvish-narrow)
   ("^"   . dirvish-history-last)
   ("s"   . dirvish-quicksort) ; remapped `dired-sort-toggle-or-edit'
   ("?"   . dirvish-dispatch)  ; remapped `dired-summary'
   ("TAB" . dirvish-subtree-toggle)
   ("M-n" . dirvish-history-go-forward)
   ("M-p" . dirvish-history-go-backward)
   ("M-l" . dirvish-ls-switches-menu)
   ("M-m" . dirvish-mark-menu)
   ("M-f" . dirvish-toggle-fullscreen)
   ("M-s" . dirvish-setup-menu)
   ("M-e" . dirvish-emerge-menu)
   ("M-j" . dirvish-fd-jump)))

Dired commands

(use-package casual-dired
  :ensure (:type git :host github :repo "kickingvegas/casual-dired")
  :general
  (:states '(normal visual)
           :kemaps '(dired-mode-map)
           "E" 'casual-dired-tmenu))

File info

(use-package file-info
  :bind
  (("C-c d" . 'file-info-show)
   ("s-'" . 'file-info-show))
  :defer t
  :config
  (setq hydra-hint-display-type 'posframe)
  (setq hydra-posframe-show-params '(:poshandler posframe-poshandler-frame-center
                                                 :internal-border-width 2
                                                 :internal-border-color "#61AFEF"
                                                 :left-fringe 16
                                                 :right-fringe 16)))

Open in finder

(use-package reveal-in-osx-finder
  :defer t
  :bind (:map evil-normal-state-map
              ("SPC o f" . reveal-in-osx-finder))
  :ensure t)

Terminal

Vterm functions

Clear vterm history.

(defun @clear-term-history ()
  "Clear terminal history inside vterm."
  (interactive)
  (when (eq major-mode 'vterm-mode)
    (vterm--self-insert)
    (vterm-send-string "clear")
    (vterm-send-return)))
  

(advice-add 'vterm-clear-scrollback :before #'@clear-term-history)

Open vterm in the current buffer. When vterm doesn’t exist, create one.

(defun @vterm-open-here ()
  "Open vterm inside current buffer!"
  (interactive)
  (let ((nodejs-repl-buffer-name "*vterm*"))
    (if (get-buffer nodejs-repl-buffer-name)
        (switch-to-buffer nodejs-repl-buffer-name)
      (progn
        (pop-to-buffer vterm-buffer-name)
        (vterm)))))

(defun @vterm-open-last ()
  "Open vterm inside current buffer!"
  (interactive)
  (let ((vterm-buffer-name "*vterm*"))
    (if (get-buffer vterm-buffer-name)
        (pop-to-buffer vterm-buffer-name)
      (progn
        (pop-to-buffer vterm-buffer-name)
        (vterm)))))

Vterm

(use-package vterm
  :defer t
  :hook (vterm-mode . (lambda () (set-face-attribute 'vterm-color-black nil :foreground +m-color-secondary :background +m-color-secondary)))
  :custom
  (vterm-max-scrollback 5000)
  :general
  (:states '(normal visual)
           "SPC ov" 'vterm
           "SPC oV" '@vterm-open-here
           "SPC oL" '@vterm-open-last)
  (:keymaps '(vterm-mode-map vterm-copy-mode-map)
            "C-u" 'vterm--self-insert)

  (:keymaps '(vterm-mode-map vterm-copy-mode-map)
            :states '(normal visual)
            "SPC mc" 'vterm-copy-mode)
  :config
  (set-face-attribute 'vterm-color-black nil :foreground +m-color-secondary :background +m-color-secondary)
  <<vterm-function-clear>>)

Vterm toggle

Open vterm for current buffer

(defun @vterm-change-current-directory-to-active-buffer-pwd ()
  "Just exec CD to pwd of active buffer."
  (interactive)
  (when-let* ((file-name (buffer-file-name))
              (file-dir (file-name-directory file-name))
              (file-dir (replace-regexp-in-string " " "\\\\\  " file-dir)))
    ;; (save-window-excursion
      (vterm-toggle-show)
      (switch-to-first-matching-buffer "vterm")
      (evil-insert 0)
      (vterm-send-C-c)
      (vterm-send-string (concat "cd " file-dir))
      (vterm-send-return)
      ;; )
    (evil-window-down 1)))

Open vterm at bottom position

Vterm package

(use-package vterm-toggle
  :defer t
  :commands (vterm-toggle-show)
  :general (:states '(normal visual)
                    :keymaps 'override
                    "SPC oh" (lambda () (interactive)
                               (+vterm/toggle t))
                    "SPC th" 'vterm-toggle-hide
                    "SPC ot" 'vterm-toggle-cd
                    "SPC oT" '@vterm-change-current-directory-to-active-buffer-pwd
                    "SPC tk" 'my-open-kitty-right-here)
  (:states '(normal visual)
           :keymaps 'vterm-mode-map
           "SPC t]" 'vterm-toggle-forward
           "SPC t[" 'vterm-toggle-backward
           "SPC tn" (lambda () (interactive)
                      (let ((current-buffer-name (buffer-name)))
                        (vterm-toggle--new)
                        (delete-window)
                        (display-buffer current-buffer-name)
                        (vterm-toggle-forward)))
           "SPC tx" (lambda (args) (interactive "P")
                      (when (string-match "vterm" (buffer-name))
                        (let ((kill-buffer-query-functions nil))
                          (kill-this-buffer)
                          (+vterm/toggle args)))))

  :config
  (setq vterm-always-compile-module t)
  (setq vterm-kill-buffer-on-exit nil)
  (setq vterm-toggle-scope 'project)
  <<vterm-open-bottom-config>>)

Detached. Background commands

(defun @projectile-detached-shell-command ()
  "Execute detached shell command at the project root."
  (interactive)
  
  (projectile-with-default-dir (projectile-acquire-root)
    (call-interactively #'detached-shell-command)))

(use-package detached
  :init
  (detached-init)
  :general 
  (:states '(normal visual)
           :keymaps 'override
           "SPC dj" '@projectile-detached-shell-command
           "SPC dv" 'detached-list-sessions)
  (:keymaps 'detached-list-mode-map
           "x" 'detached-list-kill-session)
  :bind (;; Replace `async-shell-command' with `detached-shell-command'
         ([remap async-shell-command] . detached-shell-command)
         ;; Replace `compile' with `detached-compile'
         ([remap compile] . detached-compile)
         ([remap recompile] . detached-compile-recompile)
         ;; Replace built in completion of sessions with `consult'
         ([remap detached-open-session] . detached-consult-session))
  :custom ((detached-show-output-on-attach t)
           (detached-terminal-data-command system-type)))

Secret mode

Something like screensaver

(use-package redacted
  :ensure (:type git :host github :repo "bkaestner/redacted.el")
  :defer t)

Workspace

Persp mode

Kill other buffers from current workspace

(defun @persp-kill-other-buffers ()
  "Kill all buffers except current buffer."
  (interactive)
  (let ((current-buffer (current-buffer))
        (killed-buffer-count 0))
    (mapc (lambda (buffer)
            (unless (eq buffer current-buffer)
              (setq killed-buffer-count (1+ killed-buffer-count))
              (kill-buffer buffer)))
          (persp-buffer-list))
    (message "Killed %s buffers" killed-buffer-count)))

Persp doom configs

(load "~/apps/pure-emacs/vendor/doom-workspaces.el")
(elpaca-wait)

Persp buffer advices

Persp mode custom

(persp-autokill-buffer-on-remove 'kill-weak)
(persp-reset-windows-on-nil-window-conf nil)
(persp-add-buffer-on-after-change-major-mode t)
(persp-nil-hidden t)
(persp-nil-name "default")
(persp-auto-save-fname "autosave")
(persp-save-dir (concat default-directory "workspaces/"))
(persp-set-last-persp-for-new-frames t)
(persp-switch-to-added-buffer nil)
(persp-kill-foreign-buffer-behaviour 'kill)
(persp-remove-buffers-from-nil-persp-behaviour nil)
(persp-auto-resume-time -1) ; Don't auto-load on startup
(persp-auto-save-opt (if noninteractive 0 1))
(persp-save-dir "~/tmp/workspaces/")

Buffers

Add new buffer to current persp

(add-hook 'after-switch-to-buffer-functions
            #'(lambda (bn) (when (and persp-mode
                                      (not persp-temporarily-display-buffer))
                             (persp-add-buffer bn))))

Variables for tabs

Variables for define colors of tab

(defface +workspace-tab-selected-face
  '((t :inherit nano-face-header-popout))
  "Face for selected persp tab bar"
  :group 'persp-tabbar)

(defface +workspace-tab-face
  '((t :inherit nano-face-popout ))
  "Face for persp tab bar"
  :group 'persp-tabbar)

Configs from doom

(defvar +workspaces-main "main"
  "The name of the primary and initial workspace, which cannot be deleted.")

(defvar +workspaces-switch-project-function #'doom-project-find-file
  "The function to run after `projectile-switch-project' or
`counsel-projectile-switch-project'. This function must take one argument: the
new project directory.")

(defvar +workspaces-on-switch-project-behavior 'non-empty
  "Controls the behavior of workspaces when switching to a new project.")
(add-hook! '(persp-mode-hook persp-after-load-state-functions)
  (defun +workspaces-ensure-no-nil-workspaces-h (&rest _)
    (when persp-mode
      (dolist (frame (frame-list))
        (when (string= (safe-persp-name (get-current-persp frame)) persp-nil-name)
          ;; Take extra steps to ensure no frame ends up in the nil perspective
          (persp-frame-switch (or (cadr (hash-table-keys *persp-hash*))
                                  +workspaces-main)
                              frame))))))

(add-hook! 'persp-mode-hook
  (defun +workspaces-init-first-workspace-h (&rest _)
    "Ensure a main workspace exists."
    (when persp-mode
      (let (persp-before-switch-functions)
        ;; Try our best to hide the nil perspective.
        (when (equal (car persp-names-cache) persp-nil-name)
          (pop persp-names-cache))
        ;; ...and create a *real* main workspace to fill this role.
        (unless (or (persp-get-by-name +workspaces-main)
                    ;; Start from 2 b/c persp-mode counts the nil workspace
                    (> (hash-table-count *persp-hash*) 2))
          (persp-add-new +workspaces-main))
        ;; HACK Fix #319: the warnings buffer gets swallowed when creating
        ;;      `+workspaces-main', so display it ourselves, if it exists.
        (when-let (warnings (get-buffer "*Warnings*"))
          (save-excursion
            (display-buffer-in-side-window
             warnings '((window-height . shrink-window-if-larger-than-buffer))))))))

  (defun +workspaces-init-persp-mode-h ()
    (cond (persp-mode
           ;; `uniquify' breaks persp-mode. It renames old buffers, which causes
           ;; errors when switching between perspective (their buffers are
           ;; serialized by name and persp-mode expects them to have the same
           ;; name when restored).
           (when uniquify-buffer-name-style
             (setq +workspace--old-uniquify-style uniquify-buffer-name-style))
           (setq uniquify-buffer-name-style nil)
           ;; Ensure `persp-kill-buffer-query-function' is last
           (remove-hook 'kill-buffer-query-functions #'persp-kill-buffer-query-function)
           (add-hook 'kill-buffer-query-functions #'persp-kill-buffer-query-function t)
           ;; Restrict buffer list to workspace
           (advice-add #'doom-buffer-list :override #'+workspace-buffer-list))
          (t
           (when +workspace--old-uniquify-style
             (setq uniquify-buffer-name-style +workspace--old-uniquify-style))
           (advice-remove #'doom-buffer-list #'+workspace-buffer-list)))))

Create new workspace quickly

(defun +workspace/quick-new ()
  "Create new workspace quickly"
  (interactive)
  (let ((name (format "#%s" (+workspace--generate-id))))
    (persp-switch name)
    (switch-to-buffer (doom-fallback-buffer))
    (with-current-buffer (doom-fallback-buffer)
      (delete-other-windows)
      (+workspace/display))))

Workgroups

(use-package workgroups)

Persp mode keybindings general

(:keymaps 'global
:states '(normal visual insert)
          "C-1" '+workspace/switch-to-0
          "C-2" '+workspace/switch-to-1
          "C-3" '+workspace/switch-to-2
          "C-4" '+workspace/switch-to-3
          "C-5" '+workspace/switch-to-4
          "C-6" '+workspace/switch-to-5
          "C-7" '+workspace/switch-to-6
          "C-8" '+workspace/switch-to-7
          "C-9" '+workspace/switch-to-8
          "s-1" '+workspace/switch-to-0
          "s-2" '+workspace/switch-to-1
          "s-3" '+workspace/switch-to-2
          "s-4" '+workspace/switch-to-3
          "s-5" '+workspace/switch-to-4
          "s-6" '+workspace/switch-to-5
          "s-7" '+workspace/switch-to-6
          "s-8" '+workspace/switch-to-7
          "s-9" '+workspace/switch-to-8)

(:keymaps 'override
          :states '(normal visual)
          "SPC bO" '@persp-kill-other-buffers
          "SPC bb" 'consult-projectile-switch-to-buffer
          "SPC bk" 'persp-kill-buffer
          "SPC pc" 'persp-copy
          "SPC pk" 'persp-kill
          "SPC pS" '+workspace/save
          "SPC ps" 'persp-save-state-to-file
          "SPC pL" '+workspace/load
          "SPC pl" 'persp-load-state-from-file
          "SPC pd" '+workspace/delete
          "SPC <tab>d" '+workspace/delete
          "SPC TAB d" '+workspace/delete
          "SPC pr" '+workspace/rename
          "SPC pj" 'persp-switch
          "SPC pn" '+workspace/quick-new
          "SPC <tab>n" '+workspace/quick-new
          "SPC TAB n" '+workspace/quick-new
          "SPC po" '+workspace/other
          "SPC b O" '@persp-kill-other-buffers
          "SPC <tab> <tab>" '+workspace/display
          "SPC TAB TAB" '+workspace/display
          "SPC b i" (lambda (arg)
                      (interactive "P")
                      (with-persp-buffer-list () (ibuffer arg))))

Persp mode package

TODO: change binding to general

(use-package persp-mode
  :after workgroups
  :general
  <<persp-mode-map-general>>
  :init
  (add-hook 'window-setup-hook (lambda () (persp-mode 1)))
	:custom
  <<persp-mode-custom>>
  :config
  (set-persp-parameter 'dont-save-to-file t nil)
  <<kill-other-buffers-fn>>
  <<persp-buffer-advices>>
  (persp-mode 1)
  ;; <<persp-add-buffer>>
  <<workspaces-doom-config>>
  <<workspaces-doom-patch>>)

Ibuffer

Auto workspace switch

This function also stolen from doom emacs. It provide functionality for automatic switch to workspace when you open buffer from ibuffer.

(defun +ibuffer/visit-workspace-buffer (&optional select-first)
  "Visit buffer, but switch to its workspace if it exists."
  (interactive "P")
  (let ((buf (ibuffer-current-buffer t)))
    (unless (buffer-live-p buf)
      (user-error "Not a valid or live buffer: %s" buf))
    (if-let (workspaces
             (cl-loop for wk in (+workspace-list)
                      if (+workspace-contains-buffer-p buf wk)
                      collect wk))
        (+workspace-switch
         (if (and (not select-first) (cdr workspaces))
             (or (completing-read "Select workspace: " (mapcar #'persp-name workspaces))
                 (user-error "Aborted"))
           (persp-name (car workspaces))))
      ;; Or add the buffer to the current workspace
      (persp-add-buffer buf))
    (switch-to-buffer buf)))

package

(use-package ibuffer
  :defer t
  :ensure nil
  :general
  (:states '(normal visual)
           :keymaps 'override
           "SPC bI" 'projectile-ibuffer
           "SPC bi" 'ibuffer)
  (:states '(normal visual)
           :keymaps 'ibuffer-mode-map
           "<return>" '+ibuffer/visit-workspace-buffer))

Collect ibuffers for all workspaces

(with-eval-after-load "ibuffer"
  (require 'ibuf-ext)

  (define-ibuffer-filter persp
      "Toggle current view to buffers of current perspective."
    (:description "persp-mode"
     :reader (persp-prompt nil nil (safe-persp-name (get-frame-persp)) t))
    (find buf (safe-persp-buffers (persp-get-by-name qualifier))))

  (defun persp-add-ibuffer-group ()
    (let ((perspslist (mapcar #'(lambda (pn)
                                  (list pn (cons 'persp pn)))
                              (nconc
                               (delete* persp-nil-name
                                        (persp-names-current-frame-fast-ordered)
                                        :test 'string=)
                               (list persp-nil-name)))))
      (setq ibuffer-saved-filter-groups
            (delete* "persp-mode" ibuffer-saved-filter-groups
                     :test 'string= :key 'car))
      (push
       (cons "persp-mode" perspslist)
       ibuffer-saved-filter-groups)))

  (defun persp-ibuffer-visit-buffer ()
    (let ((buf (ibuffer-current-buffer t))
          (persp-name (get-text-property
                       (line-beginning-position) 'ibuffer-filter-group)))
      (persp-switch persp-name)
      (switch-to-buffer buf)))

  (define-key ibuffer-mode-map (kbd "RET") 'persp-ibuffer-visit-buffer)

  (add-hook 'ibuffer-mode-hook
            #'(lambda ()
                (persp-add-ibuffer-group)
                (ibuffer-switch-to-saved-filter-groups "persp-mode"))))

Projectile integration with workspaces

(use-package persp-mode-project-bridge
  :after persp-mode
  :config
  (with-eval-after-load "persp-mode-projectile-bridge-autoloads"
    (add-hook 'persp-mode-projectile-bridge-mode-hook
              #'(lambda ()
                  (if persp-mode-projectile-bridge-mode
                      (persp-mode-projectile-bridge-find-perspectives-for-all-buffers)
                    (persp-mode-projectile-bridge-kill-perspectives))))
    (add-hook 'after-init-hook
              #'(lambda ()
                  (persp-mode-projectile-bridge-mode 1))
              t)))

Backups

(use-package no-littering
  :demand t
  :config
  (setq backup-directory-alist `(("." . "~/.emacs-saves")))
  (setq auto-save-file-name-transforms
        `((".*" ,(no-littering-expand-var-file-name "auto-save/") t)))
  (setq backup-by-copying t))

Folding (origami)

(use-package origami
  :hook ((org-mode
          dart-mode
          yaml-mode
          js-ts-mode
          yaml-ts-mode
          python-mode
          python-ts-mode
          html-mode
          ng2-html-mode
          emacs-lisp-mode
          typescript-ts-mode
          go-ts-mode
          python-ts-mode) . origami-mode)
  :after evil)

Folding (tree-sitter based) ts-fold

Funtions for better folding depends on mode

(defun @fold-close-all ()
  "Close all folds."

  (interactive)
  (cond ((equal major-mode 'org-mode) (+org/close-all-folds))
        ((bound-and-true-p origami-mode) (call-interactively 'origami-close-all-nodes))
        ((bound-and-true-p treesit-fold-mode) (treesit-fold-close-all))
        (t (evil-close-folds))))

(defun @fold-close ()
  "Close the fold under the cursor."

  (interactive)
  (cond ((equal major-mode 'org-mode) (+org/close-fold))
        ((bound-and-true-p origami-mode) (call-interactively 'origami-close-node))
        ((bound-and-true-p treesit-fold-mode) (treesit-fold-close))
        (t (evil-close-fold))))


(defun @fold-open-all ()
  "Open all folds."

  (interactive)
  (cond ((equal major-mode 'org-mode) (+org/open-all-folds))
        ((bound-and-true-p origami-mode) (call-interactively 'origami-open-all-nodes))
        ((bound-and-true-p treesit-fold-mode) (treesit-fold-open-all))
        (t (evil-open-folds))))

(defun @fold-open ()
  "Open the fold under the cursor."

  (interactive)
  (cond ((equal major-mode 'org-mode) (+org/open-fold))
        ((bound-and-true-p origami-mode) (call-interactively 'origami-open-node))
        ((bound-and-true-p treesit-fold-mode) (treesit-fold-open))
        (t (evil-open-fold))))

(defun @fold-toggle-all ()
  "Toggle all folds."

  (interactive)
  (cond ((equal major-mode 'org-mode) (+org/toggle-fold))
        ((bound-and-true-p origami-mode) (call-interactively 'origami-toggle-all-nodes))
        ((bound-and-true-p treesit-fold-mode) (treesit-fold-toggle-all))
        (t (evil-toggle-fold))))

(defun @fold-toggle ()
  "Toggle fold at point."

  (interactive)
  (save-excursion
    (end-of-line)
    (cond ((equal major-mode 'org-mode) (+org/toggle-fold))
          ((bound-and-true-p origami-mode) (call-interactively 'origami-toggle-node))
          ((bound-and-true-p treesit-fold-mode) (treesit-fold-toggle))
          (t (evil-toggle-fold)))))


(defun @fold-next ()
  "Go to the next fold."

  (interactive)
  (cond ((bound-and-true-p origami-mode) (call-interactively 'origami-next-fold))
        ((bound-and-true-p treesit-fold-mode) (treesit-fold-next))
        (t (evil-next-fold))))

(defun @fold-previous ()
  "Go to the previous fold."

  (interactive)
  (cond ((bound-and-true-p origami-mode) (call-interactively 'origami-previous-fold))
        ((bound-and-true-p treesit-fold-mode) (treesit-fold-previous))
        (t (evil-previous-fold))))

Tsfold improved bindings (general)

Init hook

(defun @treesit-fold-init ()
  "Init ts-fold."
  (interactive)
  (when (and (bound-and-true-p tree-sitter-mode)
             (member major-mode '(ng2-ts-mode
                                  typescript-mode
                                  js-mode
                                  python-mode
                                  html-mode
                                  json-mode
                                  go-mode
                                  scss-mode
                                  css-mode
                                  typescript-ts-mode
                                  go-ts-mode
                                  bash-ts-mode
                                  python-ts-mode
                                  json-ts-mode
                                  html-ts-mode
                                  scss-ts-mode
                                  css-ts-mode
                                  bash-mode)))
    (treesit-fold-mode 1)))

Treesit fold. Core package

(use-package treesit-fold
  :ensure (treesit-fold :type git :host github :repo "abougouffa/treesit-fold")
  :hook ((tree-sitter-mode
          web-mode
          ng2-html-mode
          ng2-ts-mode
          typescript-mode
          js-mode
          python-mode
          html-mode
          json-mode
          go-mode
          bash-mode
          css-mode
          scss-mode
          go-ts-mode
          typescript-ts-mode) . @treesit-fold-init)
  :general
  <<ts-fold-general-keybindings>>
  :config
  (add-to-list 'ts-fold-range-alist '(ng2-ts-mode . ((export_clause . ts-fold-range-seq)
                                                     (statement_block . ts-fold-range-seq)
                                                     (comment . ts-fold-range-c-like-comment))) t)

  (add-to-list 'ts-fold-range-alist '(web-mode . (html-mode
                                                  (element . ts-fold-range-html)
                                                  (comment ts-fold-range-seq 1 -1))))

  (add-to-list 'ts-fold-range-alist '(ng2-html-mode . (html-mode
                                                       (element . ts-fold-range-html)
                                                       (comment ts-fold-range-seq 1 -1))))
  (add-to-list 'ts-fold-range-alist '(scss-mode . ((keyframe_block_list . ts-fold-range-seq)
                                                   (block . ts-fold-range-seq)
                                                   (comment . ts-fold-range-c-like-comment))) t)


  (add-to-list 'ts-fold-range-alist '(typescript-ts-mode . ((export_clause . ts-fold-range-seq)
                                                            (statement_block . ts-fold-range-seq)
                                                            (comment . ts-fold-range-c-like-comment))))

  (add-to-list 'ts-fold-range-alist `(typescript-ts-mode . ,(ts-fold-parsers-typescript)))
  (add-to-list 'ts-fold-range-alist `(go-ts-mode . ,(ts-fold-parsers-go)))
  ;; (add-to-list 'ts-fold-range-alist '(go-ts-mode . ts-fold-summary-go))

  ;; TODO: DOESN'T WORK for scss, needs another rules (check it later for custom pareser)
  (add-to-list 'ts-fold-range-alist '(scss-mode . (css-mode
                                                   (keyframe_block_list . ts-fold-range-seq)
                                                   (block . ts-fold-range-seq)
                                                   (comment . ts-fold-range-c-like-comment)))))


  ;; TODO: check changes for correct mode cast
  ;; (add-to-list 'ts-fold-foldable-node-alist '(ng2-ts-mode comment statement_block export_clause))
  ;; (add-to-list 'ts-fold-foldable-node-alist '(web-mode comment element))
  ;; (add-to-list 'ts-fold-foldable-node-alist '(scss-mode comment block keyframe_block_list))
  ;; (add-to-list 'ts-fold-foldable-node-alist '(ng2-html-mode comment element)))

Notes

Settings

Display buffer of quick note always at bottom

(add-to-list 'display-buffer-alist '("^\\*scratch\\*$" (display-buffer-below-selected) (window-height . 0.4)))
(add-to-list 'display-buffer-alist '("^\\*quicknote\\*$"
                                     (display-buffer-in-side-window)
                                     (inhibit-same-window . t)
                                     (side . bottom)
                                     (window-width . full)
                                     (window-height . 0.3)))

Switch to scratch buffer

(defun @switch-to-scratch ()
  "Switch to scratch buffer"
  (interactive)
  ;; (persistent-scratch-autosave-mode -1)
  (let* ((buffer-name "*quicknote*")
         (buffer (get-buffer buffer-name)))

    (unless buffer
      (persistent-scratch-setup-default)
      (setq buffer (get-buffer-create buffer-name))
      (persistent-scratch-restore))
    
    (message "current buffer: %s" buffer)
    (with-current-buffer buffer
      (pop-to-buffer buffer)
      ;; (when (equal (s-trim (buffer-substring-no-properties (point-min) (point-max))) "")
      ;;   (message "Persistent scratch restored")
      ;;   (persistent-scratch-setup-default))
      ;; (goto-char (point-max))
      ;; (unless (eq major-mode 'org-mode)
      ;;   (org-mode))
      (org-mode)
      (evil-insert-state))))

Persistent scratch

Override function for autosaving

(defvar @persistent-scratch-last-content nil)

(defun @persistent-scratech-savable-p ()
  "Return non-nil if the current buffer is savable."
  (when-let* ((current-buffer-scratch-p (string= (buffer-name) "*quicknote*"))
              (scratch-buffer (get-buffer "*quicknote*"))
              (scratch-buffer-content (with-current-buffer scratch-buffer
                                        (buffer-string)))
              (scratch-buffer-content-not-empty (not (equal scratch-buffer-content ""))))
    ;; (scratch-buffer-content-changed (not (equal scratch-buffer-content @persistent-scratch-last-content)))
    ;; (scratch-string-not-nil (not (equal scratch-buffer-content "nil"))))

    ;; (setq @persistent-scratch-last-content scratch-buffer-content)
    ;; (message "buffer name %s, buffer content %s, content true? %s"
    ;;          (get-buffer "*quicknote*")
    ;;          (with-current-buffer "*quicknote*"
    ;;            (buffer-string))
    ;;          (with-current-buffer "*quicknote*"
    ;;            (not (equal (buffer-string) ""))))
    t))

(defun @save-scratch-buffer-p ()
  "Return non-nil if the current buffer is the scratch buffer."

  (let ((persistent-scrach-savable-p (@persistent-scratech-savable-p)))
    persistent-scrach-savable-p))

(setq persistent-scratch-scratch-buffer-p-function #'@save-scratch-buffer-p)
(defun @preserve-persistent-scratch ()
  "Preserve the persistent scratch buffer. Make backup."
  (interactive)
  (persistent-scratch-save)
  (persistent-scratch-new-backup))
(defun persistent-scratch-save (&optional file)
  "Save the current state of scratch buffers.
When FILE is non-nil, the state is saved to FILE; when nil or when called
interactively, the state is saved to `persistent-scratch-save-file'.
What state exactly is saved is determined by `persistent-scratch-what-to-save'.

When FILE is nil and `persistent-scratch-backup-directory' is non-nil, a copy of
`persistent-scratch-save-file' is stored in that directory, with a name
representing the time of the last `persistent-scratch-new-backup' call."
  (interactive)
  (let* ((actual-file (or file persistent-scratch-save-file))
         (tmp-file (concat actual-file ".new"))
         (saved-state (persistent-scratch--save-buffers-state)))
    (when (car saved-state)
      (let ((old-umask (default-file-modes)))
        (set-default-file-modes #o600)
        (unwind-protect
            (let ((coding-system-for-write 'utf-8-unix))
              (write-region (cdr saved-state) nil tmp-file nil 0))
          (set-default-file-modes old-umask)))
      (run-hook-with-args 'persistent-scratch-before-save-commit-functions tmp-file)
      (rename-file tmp-file actual-file t)
      (dolist (buffer (car saved-state))
        (with-current-buffer buffer
          (set-buffer-modified-p nil)))
      (when (called-interactively-p 'interactive)
        (message "Wrote persistent-scratch file %s" actual-file)))
    (unless file
      (persistent-scratch--update-backup)
      (persistent-scratch--cleanup-backups))))

Override autosave function. What is the sense save buffer whic doesn’t exist???

(use-package persistent-scratch
 :demand t
 :general
 (:states '(normal visual)
          :keymaps 'override
          "SPC x" '@switch-to-scratch)
  :config
  <<persistent-scratch-save>>
  (setq persistent-scratch-backup-directory "~/apps/pure-emacs/backups")
  (persistent-scratch-autosave-mode)
  (setq persistent-scratch-autosave-interval 5)
)

Override autosave function. What is the sense save buffer whic doesn’t exist???

Programming

Tempel (Snippets)

(use-package tempel
  :general
  (:keymaps 'override
            :states '(normal visual insert)
            "s-\\" 'tempel-done)
  (:keymaps 'override
            :states '(insert)
            "s-y" 'tempel-complete
            "s-Y" 'tempel-insert)

  :init
  ;; Setup completion at point
  (defun tempel-setup-capf ()
    ;; Add the Tempel Capf to `completion-at-point-functions'.
    ;; `tempel-expand' only triggers on exact matches. Alternatively use
    ;; `tempel-complete' if you want to see all matches, but then you
    ;; should also configure `tempel-trigger-prefix', such that Tempel
    ;; does not trigger too often when you don't expect it. NOTE: We add
    ;; `tempel-expand' *before* the main programming mode Capf, such
    ;; that it will be tried first.
    (setq-local completion-at-point-functions
                (cons #'tempel-expand
                      completion-at-point-functions)))

  (add-hook 'prog-mode-hook 'tempel-setup-capf)
  (add-hook 'text-mode-hook 'tempel-setup-capf)

  ;; Optionally make the Tempel templates available to Abbrev,
  ;; either locally or globally. `expand-abbrev' is bound to C-x '.
  ;; (add-hook 'prog-mode-hook #'tempel-abbrev-mode)
  ;; (global-tempel-abbrev-mode)
  :config
  ;; FIX https://github.com/minad/tempel/issues/34#issuecomment-1035915789
  (defun tempel--disable (&optional st)
    "Disable last template."
    (let* ((region-start (tempel--beginning))
	         (region-end (tempel--end)))
      (when-let (st (pop tempel--active))
        (lsp-on-change region-start region-end (- region-end region-start))
        (mapc #'delete-overlay (car st))
        (unless tempel--active
	        (setq minor-mode-overriding-map-alist
		            (delq (assq-delete-all 'tempel--active minor-mode-overriding-map-alist)
			                minor-mode-overriding-map-alist))))))

  ;; TODO: main need to get all from directory.
  (setq tempel-path
        '("~/apps/pure-emacs/templates/common"
          "~/apps/pure-emacs/templates/readme"
          "~/apps/pure-emacs/templates/org-mode"
          "~/apps/pure-emacs/templates/emacs-lisp"
          "~/apps/pure-emacs/templates/golang")))

Tempel collection

(use-package tempel-collection
  :ensure t
  :after tempel)

LSP Snippets

(use-package lsp-snippet-tempel
  :ensure (lsp-snippet-tempel :type git
                              :host github
                              :repo "svaante/lsp-snippet")
  :config
  (lsp-snippet-tempel-lsp-mode-init))

Default Tabs/spaces

(setq-default indent-tabs-mode nil)
(setq-default tab-width 2)

Formatters

Prettier

(use-package prettier
  :defer t
  :bind (:map evil-normal-state-map
              ("SPC fp" . prettier-prettify))
  :config
  (add-to-list 'prettier-major-mode-parsers '(typescript-ts-mode . (typescript babel-ts))))

Apheleia formatter

Another all formtter. Based on prettier and black

(use-package apheleia
  :hook (prog-mode . apheleia-global-mode)
  :general
  (:states '(normal visual)
           :keymaps 'override
           "\\p" 'apheleia-format-buffer)
  :config
  (add-to-list 'apheleia-mode-alist '(emacs-lisp-mode . lisp-indent))
  (add-to-list 'apheleia-mode-alist '(html-mode . prettier)))

Flycheck

(use-package flycheck
  :general (:keymaps 'flycheck-mode-map
                     :states '(normal visual)
                     "C-j" 'flycheck-next-error
                     "C-k" 'flycheck-previous-error)
  :bind 
  (:map evil-normal-state-map
        ("SPC f ]" . flycheck-next-error)
        ("SPC f [" . flycheck-previous-error)
        ("SPC e l" . flycheck-list-errors))
  :init
  (global-flycheck-mode)
  :config
  ;; Change flycheck errors on save
  (setq flycheck-check-syntax-automatically '(save idle-change new-line mode-enabled))
  (setq flycheck-idle-change-delay 0.2)

  (set-face-attribute 'flycheck-fringe-error nil :background nil :foreground +m-color-secondary)
  (set-face-attribute 'flycheck-error-list-error nil :background nil :foreground +m-color-secondary)
  (set-face-attribute 'error nil :background nil :foreground +m-color-secondary)

  (flycheck-add-mode 'javascript-eslint 'web-mode)
  (flycheck-add-mode 'javascript-eslint 'typescript-mode)
  (flycheck-add-mode 'javascript-eslint 'ng2-ts-mode)
  (flycheck-add-mode 'javascript-eslint 'typescript-ts-mode))

AST treesit

Treesit colors presets

(defun @setup-typescript-highlights ()
  "Setup TypeScript highlights via treesit."
  (interactive)

  (message "SETUP TS MODE")

  (setq typescript--treesit-settings
        (treesit-font-lock-rules
         :language 'typescript
         :feature 'decorator-identifier
         :override t
         '((decorator (call_expression function: (identifier) @font-lock-number-face)))


         :language 'typescript
         :feature 'decorator-identifier
         :override t
         '((decorator (identifier) @font-lock-number-face))


         :language 'typescript
         :feature 'named-import
         :override t
         '((import_specifier) @font-lock-number-face)

         :language 'typescript
         :feature 'this
         :override t
         '((member_expression object: (this) @font-lock-builtin-face))

         :language 'typescript
         :feature 'predefined
         :override t
         '((predefined_type) @font-lock-builtin-face)

         :language 'typescript
         :feature 'property
         :override t
         '((object (pair key: (property_identifier) @font-lock-object-key-face)))

         :language 'typescript
         :feature 'object-values
         :override t
         '((object (pair key: (property_identifier) value: (string) @italic-string-face)))

         :language 'typescript
         :feature 'object-values
         :override t
         '((object (pair key: (property_identifier) value: (true) @italic-string-face)))

         :language 'typescript
         :feature 'object-values
         :override t
         '((object (pair key: (property_identifier) value: (false) @italic-builtin-face)))

         :language 'typescript
         :feature 'object-values
         :override t
         '((object (pair key: (property_identifier) value: (true) @italic-builtin-face)))


         :language 'typescript
         :feature 'object-values
         :override t
         '((object (pair key: (property_identifier) value: (null) @italic-builtin-face)))

         :language 'typescript
         :feature 'object-values
         :override t
         '((object (pair key: (property_identifier) value: (undefined) @italic-builtin-face)))

         :language 'typescript
         :feature 'object-values
         :override t
         '((object (pair key: (property_identifier) value: (number) @italic-builtin-face)))

         :language 'typescript
         :feature 'object-values
         :override t
         '((object (pair key: (property_identifier) value: (identifier) @italic)))


         ;; :language 'typescript
         ;; :feature 'class-property
         ;; :override t
         ;; '((accessibility_modifier) name: (property_identifier) @font-lock-variable-name-face)
         ))

  (setq-local treesit-font-lock-settings (append treesit-font-lock-settings typescript--treesit-settings))
  ;; (setq-local treesit-font-lock-settings typescript--treesit-settings)
  (setq-local treesit-font-lock-rules typescript--treesit-settings)
  (setq-local treesit-font-lock-feature-list
              '((comment declaration identifier class-property)
                (keyword string escape-sequence named-import decorator-identifier type-annotation predefined_type decorator)
                (constant expression identifier number pattern property predefined this)
                (operator function bracket delimiter object-values)))

  (treesit-major-mode-setup))

Combobulate

(use-package combobulate
  :after treesit
  :ensure (:host github :repo "mickeynp/combobulate")
  :preface
  ;; You can customize Combobulate's key prefix here.
  ;; Note that you may have to restart Emacs for this to take effect!
  (setq combobulate-key-prefix "C-c o")
  :hook
  ((python-ts-mode . combobulate-mode)
   (js-ts-mode . combobulate-mode)
   (html-ts-mode . combobulate-mode)
   (css-ts-mode . combobulate-mode)
   (yaml-ts-mode . combobulate-mode)
   (typescript-ts-mode . combobulate-mode)
   (json-ts-mode . combobulate-mode)
   (tsx-ts-mode . combobulate-mode))
  ;; Amend this to the directory where you keep Combobulate's source
  ;; code.
  )

Treesit core

(use-package treesit                    ;
  :ensure nil
  ;; :commands (treesit-install-language-grammar nf/treesit-install-all-languages)
  ;; :hook ((typescript-ts-base-mode
  ;;         go-ts-mode
  ;;         python-ts-mode
  ;;         css-ts-mode) . init-tree-sitter-hl-mode)
  :hook
  (go-ts-mode . (lambda () (setq-local tab-width 2)))
  :custom
  (go-ts-mode-indent-offset 2)
  :config
  (add-hook 'typescript-ts-mode-hook #'@setup-typescript-highlights)
  (setq treesit-font-lock-level 4))

Tree sitterm automatic grammar installation

(use-package treesit-auto
  :config
  (setq treesit-auto-install 'prompt)
  (treesit-auto-add-to-auto-mode-alist 'all)
  (global-treesit-auto-mode))

Tree sitter movement. Ts hopper

(use-package ts-hopper
  :ensure (ts-hopper :type git :host github :repo "artawower/ts-hopper.el")
  :init
  (ts-hopper-init)
  :general (:states '(normal visual)
                 :keymaps 'override
                 "\'" 'ts-hopper-define-context
                 "\\k" 'ts-hopper-mode
                 "," 'ts-hopper-select
                 "[" 'ts-hopper-hop-prev-context
                 "]" 'ts-hopper-hop-next-context)
  :config
  (add-hook 'ts-hopper--after-hop-hook (lambda () (call-interactively 'evil-scroll-line-to-center))))

Autocomplete

Corfu

Corfu package

(use-package corfu
  ;; Optional customizations
  :defer 2
  :custom
  (corfu-cycle t)                ;; Enable cycling for `corfu-next/previous'
  (corfu-auto t)                 ;; Enable auto completion
  (corfu-commit-predicate t)   ;; Do not commit selected candidates on next input
  (corfu-quit-at-boundary t)     ;; Automatically quit at word boundary
  (corfu-quit-no-match t)        ;; Automatically quit if there is no match
  (corfu-auto-delay 0.1)
  (corfu-echo-documentation nil) ;; Do not show documentation in the echo area
  (corfu-preselect-first t)
  (corfu-auto-prefix 2)
  (corfu-separator ?\s) 
  ;; Optionally use TAB for cycling, default is `corfu-complete'.
  :general

  (:keymaps 'corfu-map
            "TAB" 'corfu-next
            [tab] 'corfu-next
            "C-j" 'corfu-next
            "C-k" 'corfu-previous
            "S-TAB" 'corfu-previous
            "<return>" 'corfu-insert
            "C-<return>" 'corfu-insert-seporator
            [backtab] 'corfu-previous)
  (:keymaps 'override
            :map evil-insert-state-map
            "C-x C-o" 'completion-at-point
            "C-SPC" 'completion-at-point)
  :config
  ;; (advice-add 'corfu--setup :after 'evil-normalize-keymaps)
  ;; (advice-add 'corfu--teardown :after 'evil-normalize-keymaps)
  (evil-make-overriding-map corfu-map)
  (setq lsp-completion-provider :none)

  (global-corfu-mode))

Disalbe company mode

(global-company-mode -1)
(company-mode -1)
(add-hook 'prog-mode-hook (lambda () (company-mode -1)))

Corfu doc

(use-package corfu-popupinfo
  :ensure (corfu-info :host github :repo "minad/corfu" :files ("extensions/corfu-popupinfo.el"))
  :after corfu
  :config
  (setq corfu-popupinfo-delay '(0.5 . 0.5)))

Corfu save history

(use-package corfu-history
  :ensure (corfu-history :host github :repo "minad/corfu" :files ("extensions/corfu-history.el"))
  :after corfu
  :config
  (with-eval-after-load 'safehist
    (cl-pushnew 'corfu-history savehist-additional-variables))
   (setq corfu-sort-override-function 'corfu-history--sort)

  (corfu-history-mode))

Corfu popup doc

(use-package corfu-popupinfo
  :ensure (corfu-popupinfo :host github :repo "minad/corfu" :files ("extensions/corfu-popupinfo.el"))
  :bind (:map corfu-map
              ("C-m" . corfu-popupinfo-documentation))
  :custom
  (corfu-echo-delay nil)
  :after corfu
  :config
  (corfu-popupinfo-mode))

Pretty icon

(use-package kind-icon
  :after corfu
  :custom
  (kind-icon-default-face 'corfu-default) ; to compute blended backgrounds correctly
  :config
  (add-to-list 'corfu-margin-formatters #'kind-icon-margin-formatter))

Paren checker

(show-paren-mode 1)
(custom-set-faces
 `(show-paren-mismatch ((t (:foreground ,+m-color-secondary)))))

Lsp mode

LSP sonarlint

(use-package lsp-sonarlint
  :ensure (:files ("*.el" "languages" "languages/*/*.el" "server" "server/*"))
  :after lsp-mode
  :config
  (setq lsp-sonarlint-server-path (expand-file-name "sonarlint-language-server.jar" (concat user-emacs-directory "/elpaca/builds/lsp-sonarlint/server")))
  (add-to-list 'lsp-sonarlint-modes-enabled 'ng2-ts-mode)
  (add-to-list 'lsp-sonarlint-modes-enabled 'ng2-html-mode)
  (add-to-list 'lsp-sonarlint-modes-enabled 'ng2-mode)
  (require 'lsp-sonarlint-go)
  (setq lsp-sonarlint-go-enabled t)

  (require 'lsp-sonarlint-html)
  (setq lsp-sonarlint-html-enabled t)

  (require 'lsp-sonarlint-javascript)
  (setq lsp-sonarlint-javascript-enabled t)

  (require 'lsp-sonarlint-typescript)
  (setq lsp-sonarlint-typescript-enabled t)
  (setq lsp-sonarlint-ng2-ts-enabled t))

Lsp functions

Uninstall server

(defun @lsp/uninstall-server (dir)
  "Delete a LSP server from `lsp-server-install-dir'."
  (interactive
   (list (read-directory-name "Uninstall LSP server: " lsp-server-install-dir nil t)))
  (unless (file-directory-p dir)
    (user-error "Couldn't find %S directory" dir))
  (delete-directory dir 'recursive)
  (message "Uninstalled %S" (file-name-nondirectory dir)))

LSP-mode Core package

(use-package lsp-mode
  ;; :ensure (:host github :repo "emacs-lsp/lsp-mode" :rev "8c57bcfa4b0cf9187011425cf276aed006f27df4")
  :after (flycheck lsp-sonarlint)
  :hook
  ((clojure-mode
    scss-mode
    go-mode
    css-mode
    js-mode
    typescript-mode
    vue-mode
    web-mode
    html-mode
    ng2-ts-mode
    python-mode
    dart-mode
    typescript-tsx-mode

    ;; Treesit
    html-ts-mode
    typescript-ts-mode
    go-ts-mode
    js-ts-mode
    bash-ts-mode
    tsx-ts-mode) . lsp-deferred)
  (web-mode . lsp-deferred)
  (lsp-completion-mode . my/lsp-mode-setup-completion)
  :general (:states '(normal visual)
                    :keymaps 'override
                    "SPC fn" 'flycheck-next-error
                    "gi" 'p-goto-implementation
                    "SPC la" 'lsp-execute-code-action
                    "SPC im" 'lsp-ui-imenu
                    "SPC lr" 'lsp-find-references
                    "SPC lw" 'lsp-workspace-restart
                    "SPC rl" 'lsp
                    "gd" '@find-definition
                    "SPC la" 'lsp-execute-code-action
                    "SPC cr" 'lsp-rename)
  :init
  (setq lsp-headerline-breadcrumb-enable nil)
  ;; Configuration for corfu
  ;; https://github.com/minad/corfu/wiki#configuring-corfu-for-lsp-mode
  (defun my/lsp-mode-setup-completion ()
    (setf (alist-get 'styles (alist-get 'lsp-capf completion-category-defaults))
          '(flex))) ;; Configure flex
  :custom
  (lsp-headerline-breadcrumb-enable nil)
  (lsp-idle-delay 0.3)
  (lsp-completion-provider :capf)
  (lsp-enable-on-type-formatting nil)
  (lsp-eldoc-render-all nil)
  (lsp-prefer-flymake nil)
  (lsp-modeline-diagnostics-scope :workspace)
  ;; (lsp-clients-typescript-server-args '("--stdio" "--tsserver-log-file" "/dev/stderr"))
  (lsp-clients-typescript-server-args '("--stdio"))
  (lsp-completion-default-behaviour :insert)
  (lsp-yaml-schemas '((kubernetes . ["/auth-reader.yaml", "/deployment.yaml"])))
  (lsp-disabled-clients '(html-ls))
  (setq lsp-pyright-venv-path (concat (getenv "HOME") "/.virtualenvs"))
  ;; (lsp-completion-provider :none)
  ;; (lsp-completion-provider :capf)
  ;; Disable bottom help info
  (lsp-signature-render-documentation nil)
  (lsp-signature-auto-activate nil)
  (lsp-enable-snippet nil)
  ;; (lsp-use-plists t)
  (lsp-enable-file-watchers t)
  (lsp-file-watch-threshold 8000)
  :config
  (add-to-list 'lsp-file-watch-ignored-directories "[/\\\\]\\.bun\\'")
  (add-to-list 'lsp-file-watch-ignored-directories "[/\\\\]\\.npm\\'")
  (setq lsp-auto-execute-action nil)
  (setq lsp-javascript-display-return-type-hints t)
  (setq lsp-json-schemas
        `[
          (:fileMatch ["ng-openapi-gen.json"] :url "https://raw.githubusercontent.com/cyclosproject/ng-openapi-gen/master/ng-openapi-gen-schema.json")
          (:fileMatch ["package.json"] :url "http://json-schema.org/draft-07/schema")
          ])
  (set-face-attribute 'lsp-face-highlight-read nil :foreground "#61AFEF" :bold t :underline nil)
  ;; Flycheck patch checkers
  (require 'flycheck)
  (require 'lsp-diagnostics)
  (lsp-diagnostics-flycheck-enable)
  (mapc #'lsp-flycheck-add-mode '(typescript-mode js-mode css-mode vue-html-mode))
  ;; Golang
  (defun lsp-go-install-save-hooks ()
    (flycheck-add-next-checker 'lsp '(warning . go-gofmt) 'append)
    (flycheck-add-next-checker 'lsp '(warning . go-golint))
    (flycheck-add-next-checker 'lsp '(warning . go-errcheck))
    (flycheck-add-next-checker 'lsp '(warning . go-staticcheck))

    ;; (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)

  (setq lsp-enable-symbol-highlighting t
        lsp-enable-snippet nil  ;; Not supported by company capf, which is the recommended company backend
        lsp-pyls-plugins-flake8-enabled nil)
  (set-face-foreground 'lsp-face-highlight-read +m-color-secondary)
  (set-face-foreground 'lsp-face-highlight-textual +m-color-secondary)


  (add-to-list 'lsp-file-watch-ignored "[/\\\\]\\venv\\'")
  (add-to-list 'lsp-file-watch-ignored "[/\\\\]\\pyenv\\'")
  (add-to-list 'lsp-file-watch-ignored "[/\\\\]\\.cache\\'")
  (set-face-attribute 'lsp-face-highlight-textual nil :background "#c0caf5")
  ;; Install corfu completion for lsp
  ;; (defun corfu-lsp-setup ()
  ;; (setq-local completion-styles '(orderless basic)
  ;;             completion-category-defaults nil))
  ;; (add-hook 'lsp-mode-hook #'corfu-lsp-setup)
  (@setup-compilation-errors)
  (setq lsp-disabled-clients '(html-ls))
  (setq lsp-eldoc-hook nil))

YAML

YAML PRO

(use-package yaml-pro
  :defer t
  :hook (yaml-mode . yaml-pro-mode))

LSP UI

(use-package lsp-ui
  :hook (lsp-mode . lsp-ui-mode)
  :bind (:map lsp-ui-peek-mode-map
              ("C-j" . lsp-ui-peek--select-next)
              ("C-k" . lsp-ui-peek--select-prev))
  :config
  (setq lsp-ui-sideline-diagnostic-max-line-length 100
        lsp-ui-sideline-diagnostic-max-lines 8
        lsp-ui-doc-delay 1
        lsp-ui-doc-position 'top
        lsp-ui-doc-show-with-mouse nil
        lsp-ui-doc-border +m-color-main))

Flutter (dart)

(use-package lsp-dart
  :defer t
  :hook (dart-mode . (lambda () (interactive)
                       (add-hook 'after-save-hook
                                 (lambda ()
                                   ;; (flutter-run-or-hot-reload)
                                   (flutter-hot-restart)
                                   )
                                 t t)))
  :custom
  (lsp-dart-dap-flutter-hot-reload-on-save t)
  :config
  (defun lsp-dart-flutter-widget-guide--add-overlay-to (buffer line col string)
    "Add to BUFFER at LINE and COL a STRING overlay."
    (save-excursion
      (goto-char (point-min))
      (forward-line line)
      (move-to-column col)
      (when (string= lsp-dart-flutter-widget-guide-space (string (following-char)))
        (let ((ov (make-overlay (point) (1+ (point)) buffer)))
          (overlay-put ov 'category 'lsp-dart-flutter-widget-guide)
          (overlay-put ov 'display (propertize string
                                               'face 'custom-comment-tag)))))))

Lsp optimisation

See detail

;; (define-advice json-parse-buffer (:around (old-fn &rest args) lsp-booster-parse-bytecode)
;;   "Try to parse bytecode instead of json."
;;   (or
;;    (when (equal (following-char) ?#)
;;      (let ((bytecode (read (current-buffer))))
;;        (when (byte-code-function-p bytecode)
;;          (funcall bytecode))))
;;    (apply old-fn args)))

;; (define-advice lsp-resolve-final-command (:around (old-fn cmd &optional test?) add-lsp-server-booster)
;;   "Prepend emacs-lsp-booster command to lsp CMD."
;;   (let ((orig-result (funcall old-fn cmd test?)))
;;     (if (and (not test?)                             ;; for check lsp-server-present?
;;              (not (file-remote-p default-directory)) ;; see lsp-resolve-final-command, it would add extra shell wrapper
;;              lsp-use-plists
;;              (not (functionp 'json-rpc-connection))  ;; native json-rpc
;;              (executable-find "emacs-lsp-booster"))
;;         (progn
;;           (message "Using emacs-lsp-booster for %s!" orig-result)
;;           (cons "emacs-lsp-booster" orig-result))
;;       orig-result)))

Compilation

Functions

Find filename for eslint error

(defun compile-eslint--find-filename ()
  "Find the filename for current error."
  (save-match-data
    (save-excursion
      (when (re-search-backward (rx bol (group "/" (+ any)) eol))
        (list (match-string 1))))))

Buffer position

(add-to-list 'display-buffer-alist '("^\\*compilation\\*$" . (display-buffer-at-bottom)))

(defun @display-buffer-other-vertical (buffer &optional alist)
  "Display BUFFER in another window. If only one window, split vertical before."
(message "is one window? %s " (one-window-p))
    (if (one-window-p)
        (split-window-horizontally))
  (display-buffer-use-some-window buffer alist))
  

 (add-to-list 'display-buffer-alist
      '(("\\*Messages\\*"
         (display-buffer-reuse-window  display-buffer-in-side-window @display-buffer-other-vertical display-buffer-use-some-window)
         (side . right))))

Setup compilation errors

(defun @setup-compilation-errors ()
  (interactive)
  (setq compilation-scroll-output t)
  (setq compilation-error-regexp-alist '())
  (setq compilation-error-regexp-alist-alist '())


  ;; eslint https://github.com/Fuco1/compile-eslint/blob/master/compile-eslint.el
  (when (not compilation-error-regexp-alist-alist)
    (setq compilation-error-regexp-alist-alist '()))

  (let ((form `(eslint
                ,(rx-to-string
                  '(and (group (group (+ digit)) ":" (group (+ digit)))
                        (+ " ") (or "error" "warning")))
                compile-eslint--find-filename
                2 3 2 1)))

    (if (assq 'eslint compilation-error-regexp-alist-alist)
        (setf (cdr (assq 'eslint compilation-error-regexp-alist-alist)) (cdr form))
      (push form compilation-error-regexp-alist-alist)))
  (push 'eslint compilation-error-regexp-alist)



  (add-to-list 'compilation-error-regexp-alist '("^[[:blank:]]*\\([/_-\\.[:alnum:]]+\\):\\([[:digit:]]+\\):\\([[:digit:]]+\\) - error.*$" 1 2 3))
  ;; React
  (add-to-list 'compilation-error-regexp-alist '("[[:blank:]]*\\([/_\\.[:alnum:]-]+\\):\\([[:digit:]]+\\):\\([[:digit:]]+\\) - error.*$" 1 2 3))
  ;; Angular
  (add-to-list 'compilation-error-regexp-alist '("^Error: \\([_[:alnum:]-/.]*\\):\\([0-9]+\\):\\([0-9]+\\)" 1 2 3))
  ;; Angular vite
  (add-to-list 'compilation-error-regexp-alist '("\\([_[:alnum:]-/.]*\\):\\([0-9]+\\):\\([0-9]+\\)" 1 2 3))

  ;; New eslint
  (add-to-list 'compilation-error-regexp-alist '("^\\([_[:alnum:]-/.]*\\)\n[[:blank:]]*\\([0-9]+\\):\\([0-9]+\\)" 1 2 3))

  ;; Flutter
  ;; (add-to-list 'compilation-error-regexp-alist '("[[:blank:]]*\\([/_\\.[:alnum:]-]+\\):\\([[:digit:]]+\\):\\([[:digit:]]+\\): Error.*$"))
  (add-to-list 'compilation-error-regexp-alist 'dart-analyze)
  (add-to-list 'compilation-error-regexp-alist-alist '(dart-analyze "\\([^ ]*\\.dart\\):\\([0-9]+\\):\\([0-9]+\\)" 1 2 3)))

Display compilation buffer

By default compile-goto-error open new window. Its redundant.

(defun display-buffer-from-compilation-p (_buffer-name _action)
  (unless current-prefix-arg
    (with-current-buffer (window-buffer)
      (derived-mode-p 'compilation-mode))))

(push '(display-buffer-from-compilation-p
        display-buffer-use-some-window
        (inhibit-same-window . nil))
      display-buffer-alist)

Compile package

(use-package compile
  :defer t
  :ensure nil
  :general
  (:states '(normal visual)
           :keymaps 'override
           "SPC cc" 'projectile-compile-project
           "SPC cC" 'recompile
           "SPC cv" (lambda ()
                      (interactive)
                      (compilation-display-error)
                      (+select-window-by-name "*compilation.*")))
  (:states '(normal visual)
           :keymaps 'compilation-mode-map
           "C-j" 'compilation-next-error
           "C-k" 'compilation-previous-error)
  :config
  <<display-compilation-buffer>>
  (@setup-compilation-errors))

Collaborations

(use-package floobits
  :defer t)

Collaborative editing

Context: https://www.reddit.com/r/emacs/comments/1bg7tgn/introducing_chromeemacs_elevate_your_live_coding/

(use-package atomic-chrome
  :defer t
  :demand t
  :ensure
  (atomic-chrome
   :repo "KarimAziev/atomic-chrome"
   :type git
   :flavor nil
   :host github)
  :commands
  (atomic-chrome-start-server)
  :config
  (setq-default atomic-chrome-extension-type-list '(atomic-chrome))
  (setq-default atomic-chrome-buffer-open-style 'frame)
  (setq-default atomic-chrome-auto-remove-file t)
  (setq-default atomic-chrome-url-major-mode-alist
                '(("ramdajs.com" . js-ts-mode)
                  ("github.com" . gfm-mode)
                  ("gitlab.com" . gfm-mode)
                  ("leetcode.com" . typescript-ts-mode)
                  ("codesandbox.io" . js-ts-mode)
                  ("typescriptlang.org" . typescript-ts-mode)
                  ("jsfiddle.net" . js-ts-mode)
                  ("w3schools.com" . js-ts-mode)))
  (add-to-list 'atomic-chrome-create-file-strategy
               '("~/repos/ts-scratch/src/" :extension
                 ("js" "ts" "tsx" "jsx" "cjs" "mjs")))
  (atomic-chrome-start-server))

Debugger DAPE

Clone this repo for js debug git@github.com:microsoft/vscode-js-debug.git

(use-package dape
  :defer 2
  :ensure (dape :type git :host github :repo "svaante/dape")
  :bind (:map evil-normal-state-map
              ("SPC d d" . dape)
              ("SPC d n" . dape-next)
              ("SPC d i" . dape-step-in)
              ("SPC d o" . dape-step-out)
              ("SPC d b" . dape-breakpoint-toggle)
              ("SPC d c" . dape-continue)
              ("SPC d q" . dape-disconnect-quit)
              ("SPC d r" . dape-restart)
              ("SPC d k" . dape-kill)
              ("SPC d X" . dape-remove-breakpoint-at-point)
              ("SPC d s" . dape-select-stack)
              ("SPC d t" . dape-select-thread)
              ("SPC d x" . dape-breakpoint-remove-all))
  :config
  (setq dape-inline-variables t))

Brackets

(use-package rainbow-delimiters
  :defer t
  :hook (prog-mode . rainbow-delimiters-mode))

Codemetrics

(use-package codemetrics
  :hook (typescript-mode . codemetrics-mode)
  :ensure (:host github :repo "jcs-elpa/codemetrics")
  :defer t)

Editing

Undo redo

Undo mode

(use-package undo-fu
  :defer t
  :bind (:map evil-normal-state-map
              ("u" . undo-fu-only-undo)
              ("C-r" . undo-fu-only-redo)))

Undo sessions (history saving)

(use-package undo-fu-session
  :config
  (global-undo-fu-session-mode))

Surround

Package for quick editing/deleting brackets and bracket-likes symbols

(use-package evil-surround
  :config
  (global-evil-surround-mode 1))

Copilot

TODO: check copilot + blamer

(use-package copilot
  :defer 5
  :ensure (:host github :repo "copilot-emacs/copilot.el" :files ("*.el"))
  :hook
  (prog-mode . copilot-mode)
  (text-mode . copilot-mode)
  :general
  (:keymaps 'override
            "s-]" 'copilot-next-completion
            "s-[" 'copilot-previous-completion
            "s-l" 'copilot-accept-completion
            "s-j" 'copilot-complete
            "s-;" 'copilot-accept-completion-by-word
            "s-/" 'copilot-accept-completion-by-line)
  :custom
  (copilot-idle-delay 0.3)
  :config
  (setq copilot--previous-point nil)
  (setq copilot--previous-window-width nil)

  (copilot-diagnose)
  ;; (global-copilot-mode)
  (add-hook 'evil-insert-state-entry-hook (lambda ()
                                            (setq blamer--block-render-p t)
                                            (when (fboundp 'blamer--clear-overlay)

                                              (blamer--clear-overlay))))
  (add-hook 'evil-normal-state-entry-hook (lambda ()
                                            (setq blamer--block-render-p nil)
                                            (copilot-clear-overlay))))

Autopairs

Electric

(use-package electric
  :ensure nil
  :hook
  (html-mode . sgml-electric-tag-pair-mode)
  (ng2-html-mode . sgml-electric-tag-pair-mode)
  :config
  (setq electric-pair-preserve-balance t
        electric-pair-delete-adjacent-pairs t
        electric-pair-skip-whitespace nil
        electric-pair-open-newline-between-pairs t)
  (electric-pair-mode))

Correct position after blamer flicker

(defun @electric-pair--verify-cursor-position (&optional char)
  "Verify cusor position after inserting CHAR bracket."

  (when (member (char-before) '(?\) ?}))
    ;; (when (member (char-before) '(?\) ))
    (copilot-clear-overlay)
    (backward-char))

  (when (and (member (char-after) '(?\( ?\{))
             (member (chart-after (1+ (point))) '(?\) ?\})))
    (forward-char)))

(advice-add 'electric-pair--insert :after #'@electric-pair--verify-cursor-position)

Turbo log. Quick log inserting

(use-package turbo-log
  :defer t
  :ensure (turbo-log :type git :host github :repo "Artawower/turbo-log.el" :branch "feat/treesit-migration")
  :commands (turbo-log--get-context)
  :bind (("C-s-l" . turbo-log-print)
         ("C-s-i" . turbo-log-print-immediately)
         ("C-s-h" . turbo-log-comment-all-logs)
         ("C-s-s" . turbo-log-uncomment-all-logs)
         ("C-s-x" . turbo-log-delete-all-logs)
         ("C-s-[" . turbo-log-paste-as-logger )
         ("C-s-]" . turbo-log-paste-as-logger-immediately))
  :custom
  (turbo-log-allow-insert-without-tree-sitter-p t)
  ;; (turbo-log-payload-format-template "")
  ;; (turbo-log-payload-format-template "\x1b[35m%s: ")
  (turbo-log-payload-format-template "%s: ")
  :config
  (turbo-log-configure
   :modes (typescript-ts-mode tsx-ts-mode typescript-mode js2-mode web-mode ng2-ts-mode js-mode)
   :strategy merge
   :post-insert-hooks ((lambda () (interactive) (call-interactively 'apheleia-format-buffer)) lsp)
   ;; :msg-format-template "'🦄: %s'"
   :msg-format-template "'✎: %s'"))

Automatic rename html/xml tags

Patch for correct flycheck run, see emacs-vs/auto-rename-tag#9 (comment)

(defvar auto-rename-tag--after-change-active nil)

(defun auto-rename-tag--before-change-functions (_begin _end)
  "Do stuff before buffer is changed.
BEGIN : beginning of the changes.
END : end of the changes."
  (unless auto-rename-tag--after-change-active

    ;; Reset record.
    (setq auto-rename-tag--record-prev-word "")
    ;; Reset flag.
    (setq auto-rename-tag--pre-command-actived nil)

    (when (and (not undo-in-progress)
               (auto-rename-tag--inside-tag-p)
               (not (auto-rename-tag--self-tag-p)))
      (save-excursion
        ;; Set active flag.
        (setq auto-rename-tag--pre-command-actived t)

        (setq auto-rename-tag--record-prev-word (auto-rename-tag--get-tag-name-at-point))

        (when (string= auto-rename-tag--record-prev-word "/")
          (setq auto-rename-tag--record-prev-word ""))

        ;; Ensure `auto-rename-tag--record-prev-word' is something other than nil.
        (unless auto-rename-tag--record-prev-word
          (setq auto-rename-tag--record-prev-word ""))))))

(defun auto-rename-tag--after-change-function (_begin _end _length)
  "Do stuff after buffer is changed.
BEGIN : beginning of the changes.
END : end of the changes.
LENGTH : deletion length."
  (when auto-rename-tag--pre-command-actived
    (run-at-time 0 nil (lambda () 
                         (save-excursion
                           (let ((is-end-tag nil)
                                 (current-word "") (pair-tag-word "")
                                 (auto-rename-tag--after-change-active nil))
                             ;; Goto the first character inside the tag.
                             (auto-rename-tag--goto-the-start-of-tag-name)

                             (setq is-end-tag (auto-rename-tag--is-closing-tag-p))

                             (setq current-word (auto-rename-tag--get-tag-name-at-point))

                             (unless (string= current-word auto-rename-tag--record-prev-word)
                               ;; NOTE: Is closing tag.
                               (when is-end-tag
                                 (auto-rename-tag--resolve-nested 'backward)

                                 ;; Get the tag name and ready to be compare.
                                 (setq pair-tag-word (auto-rename-tag--get-tag-name-at-point))

                                 ;; Ensure `pair-tag-word' is something other than nil.
                                 (unless pair-tag-word (setq pair-tag-word ""))

                                 (when (string= auto-rename-tag--record-prev-word pair-tag-word)
                                   ;; Delete the pair word.
                                   (unless (string= pair-tag-word "")
                                     (auto-rename-tag--delete-tag-name))
                                   ;; Insert new word.
                                   (insert current-word)))

                               ;; NOTE: Is opening tag.
                               (unless is-end-tag
                                 (auto-rename-tag--resolve-nested 'forward)

                                 (setq is-end-tag (auto-rename-tag--is-closing-tag-p))

                                 ;; Get the tag name and ready to be compare.
                                 (setq pair-tag-word (auto-rename-tag--get-tag-name-at-point))

                                 ;; Ensure `pair-tag-word' is something other than nil.
                                 (unless pair-tag-word (setq pair-tag-word ""))

                                 (when (string= auto-rename-tag--record-prev-word pair-tag-word)
                                   ;; Delete the pair word.
                                   (unless (string= pair-tag-word "")
                                     (auto-rename-tag--delete-tag-name))
                                   ;; Insert new word.
                                   (insert current-word))))))))))
(use-package auto-rename-tag
  :defer t
  :hook ((html-mode ng2-html-mode-hook vue-mode web-mode) . auto-rename-tag-mode)
  :config
  (auto-rename-tag-mode 1)
  <<auto-rename-tag-patch>>)

Case converter

Allow to transform PASCAL_CASE -> camelCase -> snake_case

(use-package string-inflection
  :defer t
  :bind ("C-s-c" . string-inflection-all-cycle))

Macros

(use-package persistent-soft
  :defer t)
(use-package persistent-kmacro
  :ensure (:host github :repo "artawower/persistent-kmacro.el")
  :defer t
  :general (:keymaps 'override
                     :states 'normal
                     "SPC me" 'persistent-kmacro-execute-macro
                     "SPC ma" 'persistent-kmacro-name-last-kbd-macro
                     "SPC mr" 'persistent-kmacro-remove-macro))

GIT

Magit

(use-package magit
  :defer t
  :ensure t
  :commands
  (magit-get-current-branch)
  :general
  (:keymaps 'magit-mode-map
            :states '(normal visual)
            "C-1" 'magit-section-show-level-1
            "C-2" 'magit-section-show-level-2
            "C-3" 'magit-section-show-level-3
            "C-4" 'magit-section-show-level-4
            "q" 'kill-current-buffer
            "Q" 'bury-buffer
            "Z" 'magit-stash
            "zz" 'evil-scroll-line-to-center
            "1" 'digit-argument
            "2" 'digit-argument
            "3" 'digit-argument
            "4" 'digit-argument
            "P" 'magit-fetch
            "f" 'evil-avy-goto-word-1)
  :custom-face
  (git-commit-overlong-summary ((t :inherit error :weight bold)))
  :bind (:map magit-mode-map
              ("s-<return>" . magit-diff-visit-worktree-file)
              :map evil-normal-state-map
              ("SPC g g" . magit-status)
              ("SPC g n" . magit-todo-list)
              ("SPC g i" . (lambda () (interactive) (wakatime-ui--clear-modeline) (magit-status))))
  :hook
  (magit-process-mode . compilation-minor-mode)
  :config
  (setq magit-process-timestamp-format "%H:%M")
  (setq magit-display-buffer-function #'magit-display-buffer-fullcolumn-most-v1)
  (define-key transient-map        "q" 'transient-quit-one)
  (define-key transient-edit-map   "q" 'transient-quit-one)
  (define-key transient-sticky-map "q" 'transient-quit-seq)
  (add-hook 'magit-process-mode #'disable-magit-hooks)
  ;; (add-hook 'magit-process-mode-hook #'compilation-mode)
  (setcdr magit-process-mode-map (cdr (make-keymap)))
  (set-keymap-parent magit-process-mode-map special-mode-map)
  (advice-add
   'ansi-color-apply-on-region
   :before
   #'my-remove-cr)
  (setq magit-process-finish-apply-ansi-colors t))

Magit todos

(use-package magit-todos
  :defer t
  :general
  (:states '(normal visual)
   :keymaps 'override
   "SPC g n" 'magit-todos-list))

Gists 2

(use-package jist
  :ensure t
  :custom
  (jist-github-token (getenv "GITHUB_TOKEN"))
  :general
  (:keymaps 'override
            :states '(normal visual)
            "SPC gcl" 'jist-commit
            "SPC glg" 'jist-list
            "SPC gpg" 'jist-refetch-gists)
  (:keymaps 'jist-gist-list-mode-map
            :states '(normal visual)
            "<return>" 'jist-browse-gist)
  )

Gitgutter

(use-package git-gutter
  :after git-gutter-fringe
  :bind (:map evil-normal-state-map
              ("SPC g [" . git-gutter:previous-hunk)
              ("SPC g ]" . git-gutter:next-hunk)
              ("SPC g r" . git-gutter:revert-hunk))
  :config
  (setq git-gutter:update-interval 2)
  (set-face-foreground 'git-gutter:modified +m-color-main) ;; background color
  (set-face-foreground 'git-gutter:added +m-color-green)
  (set-face-foreground 'git-gutter:deleted +m-color-secondary)
  :init
  (global-git-gutter-mode))

Improved styles for git changes

(use-package git-gutter-fringe
  :config
  (define-fringe-bitmap 'git-gutter-fr:added [224] nil nil '(center repeated))
  (define-fringe-bitmap 'git-gutter-fr:modified [224] nil nil '(center repeated))
  (define-fringe-bitmap 'git-gutter-fr:deleted [128 192 224 240] nil nil 'bottom))

Blamer

(use-package blamer
  ;; :ensure (:type git :host github :repo "artawower/blamer.el" :branch "fix/emacs-buffers-spawns")
  :bind (("C-c i" . blamer-show-commit-info)
         ("C-c h" . (lambda () (interactive) (blamer-show-commit-info 'visual)))
         ("s-i" . blamer-show-posframe-commit-info))
  :custom
  (blamer-idle-time 0.8)
  (blamer-min-offset 20)
  (blamer-max-commit-message-length 65)
  (blamer-commit-formatter "◉ %s")
  (blamer-view 'overlay)
  (blamer-uncommitted-changes-message "uncommitted yet")
  :custom-face
  (blamer-face ((t :inherit font-lock-comment-face
                   :italic t
                   :font "Fira Code 14"
                   :height 0.9
                   :background unspecified)))
  :config
  (tooltip-mode)
  (setq blamer-tooltip-function 'blamer-tooltip-commit-message)


  (defun blamer-callback-show-commit-diff (commit-info)
    (interactive)
    (let ((commit-hash (plist-get commit-info :commit-hash)))
      (when commit-hash
        (magit-show-commit commit-hash))))

  (defun blamer-callback-open-remote (commit-info)
    (interactive)
    (let ((commit-hash (plist-get commit-info :commit-hash)))
      (when commit-hash
        (forge-browse-commit commit-hash))))

  (setq blamer-bindings '(("<mouse-3>" . blamer-callback-open-remote)
                          ("<mouse-1>" . blamer-callback-show-commit-diff)))

  (global-blamer-mode 1))

Timemachine

(use-package git-timemachine
  :defer t
  :bind (:map evil-normal-state-map
              ("SPC g t" . git-timemachine)))

Smerge

(global-set-key (kbd "C-c l") 'smerge-keep-lower)
(global-set-key (kbd "C-c u") 'smerge-keep-upper)
(global-set-key (kbd "C-c a") 'smerge-keep-all)
(global-set-key (kbd "C-c j") 'smerge-next)
(global-set-key (kbd "C-c k") 'smerge-prev)
 

Browse at remote

(use-package browse-at-remote
  :defer t
  :general
  (:states '(normal visual)
   :keymaps 'override
   "SPC o r" 'browse-at-remote))

Forge. Remote access to repo

(use-package forge
  :after magit
  :config
  (setq auth-sources '("~/.authinfo")))

Code review

(use-package code-review
  :defer t
  :general
  (:states '(normal insert) :keymaps 'magit-mode-map
            "C-c C-r" 'code-review-forge-pr-at-point)
  (:states '(normal insert) :keymaps 'code-review-mode-map
            "r" 'code-review-transient-api)
  :config
  (setq code-review-fill-column 80)
  (setq code-review-download-dir "/tmp/code-review/")
  (setq code-review-new-buffer-window-strategy #'switch-to-buffer)
  (setq code-review-auth-login-marker 'forge))

Languages

Emacs lisp mode (elisp)

Paren mode

(use-package paren-face :defer t)

Main mode

(use-package elisp-mode
  :defer t
  :ensure nil
  :hook ((emacs-lisp-mode . paren-face-mode)
         (emacs-lisp-mode . (lambda () (setq fill-column 80))))

  :bind (("C-c o" . outline-cycle)
         ("C-c r" . outline-show-all)
         ("C-c m" . outline-hide-body)
         ("C-c ]" . outline-next-heading)
         ("C-c [" . outline-previous-heading)
         ("C-c c" . counsel-outline)
         ("C-c e" . outline-hide-entry)
         ("C-c t" . outline-toggle-children)
         ("C-c b" . outline-cycle-buffer)
         ;; TODO: eval buffer or region
         ("C-c C-c" . eval-buffer))

  :config
  (add-hook 'emacs-lisp-mode-hook (lambda () (setq rainbow-delimiters-mode -1))))

(use-package package-build
  :defer t)

(use-package package-lint

  :defer t)

Clojure

Main mode

(use-package clojure-mode
  :hook ((clojure-mode . paren-face-mode))
  :defer t)

Repl

(use-package cider
  :defer t)

Typescript

Typescript package

(setenv "TSSERVER_LOG_FILE" "/tmp/tsserver.log")
(use-package typescript-mode
  :defer t  
  :hook (typescript-mode . (lambda () (setq-local fill-column 120)))
                             ;; (typescript-ts-mode)))
  :custom
  (lsp-clients-typescript-server-args '("--stdio"))
  :config
  (setq typescript-indent-level 2)
  ;; (add-to-list 'auto-mode-alist '("\.ts\'" . typescript-mode))
  (@setup-compilation-errors))

Angular

(use-package ng2-mode
  :after typescript-mode
  :hook
  (ng2-html-mode . web-mode)
  :config
  (setq lsp-clients-angular-language-server-command
        '("node"
          "/opt/homebrew/lib/node_modules/@angular/language-server"
          "--ngProbeLocations"
          "/opt/homebrew/lib/node_modules"
          "--tsProbeLocations"
          "/opt/homebrew/lib/node_modules"
          "--stdio")))

Js

Main mode

(use-package js2-mode
  :defer t
  :hook (js2-mode . js2-highlight-unused-variables-mode)
  :config
  (setq js-indent-level 2))

NPM

(use-package npm
  :ensure (npm :repo "Artawower/npm.el" :host github)
  :defer t)

REPL

NodeJs repl functions

(defun @open-nodejs-repl-here ()
  "Open nodejs repl inside current buffer!"
  (interactive)
  (let ((nodejs-repl-buffer-name "*nodejs*"))
    (if (get-buffer nodejs-repl-buffer-name)
        (switch-to-buffer nodejs-repl-buffer-name)
      (progn
        (switch-to-buffer nodejs-repl-buffer-name)
        (nodejs-repl)))))

NodeJs repl

(use-package nodejs-repl
  :ensure t
  :general
  (:states '(normal visual)
           :keymaps 'override
           "SPC rn" 'nodejs-repl)

  (:states '(insert)
           :keymaps 'nodejs-repl-mode-map
           "C-j" 'comint-next-input
           "C-k" 'comint-previous-input)

  :defer t
  :config
  <<nodejs-repl-buffer-func>>
  (add-to-list 'display-buffer-alist '("^\\*nodejs\\*$" . (display-buffer-same-window))))

Golang

(use-package go-playground
  :defer t)

Rust

(defun rk/rustic-mode-hook ()
  (when buffer-file-name
    (setq-local buffer-save-without-query t)))

(use-package rustic
  :defer t
  :bind (:map rustic-mode-map
              ("M-j" . lsp-ui-imenu)
              ("M-?" . lsp-find-references)
              ("C-c C-c l" . flycheck-list-errors)
              ("C-c C-c a" . lsp-execute-code-action)
              ("C-c C-c r" . lsp-rename)
              ("C-c C-c q" . lsp-workspace-restart)
              ("C-c C-c Q" . lsp-workspace-shutdown)
              ("C-c C-c s" . lsp-rust-analyzer-status))
  :config
  (setq rustic-format-on-save t
        rustic-format-display-method 'ignore)
  (add-hook 'rustic-mode-hook 'rk/rustic-mode-hook))

Python

Python repl

Function for open repl in the current buffer

(defun @open-ipython-repl-here ()
  "Open python repl inside current buffer!"
  (interactive)
  (let ((python-repl-buffer-name "*Python*"))
    (if (get-buffer python-repl-buffer-name)
        (switch-to-buffer python-repl-buffer-name)
      (progn
        (switch-to-buffer python-repl-buffer-name)
        (run-python)))))
(use-package python
  :defer t
  :ensure nil
  :general
  (:states '(normal visual)
           :keymaps 'override
           "SPC r p" '@open-ipython-repl-here)
  :config
  
  (setq python-shell-interpreter "ipython"
        python-interpreter "python3"
        python-shell-interpreter-args "--simple-prompt -i"))

Mode

(use-package python-mode
  :defer t
  :after treesit
  :ensure nil
  :config
  (setq python-indent-level 4)
  (add-hook 'python-mode-hook
            (lambda ()
              (require 'lsp-pyright)
              ;; (lsp-deferred)
              (setq indent-tabs-mode nil)
              (setq tab-width 4))))

LSP. Pyright

(setq lsp-pyright-multi-root nil)
(use-package lsp-pyright
  :hook (python-mode . (lambda ()
                          (require 'lsp-pyright)
                          (lsp-deferred)))
  :config
  (setq lsp-pyright-auto-import-completions t)
  (setq lsp-pyright-auto-search-paths t)
  (setq lsp-pyright-log-level "trace")
  (setq lsp-pyright-multi-root nil)
  (setq lsp-pyright-use-library-code-for-types t)
  ;; (setq lsp-pyright-venv-directory "/Users/darkawower/.local/share/virtualenvs/spice-farm-YhO8T07I")
  (setq lsp-pyright-diagnostic-mode "workspace"))

Pipenv

(use-package pipenv
  :defer t
  :hook (python-mode . pipenv-mode)
  :config
  (setenv "WORKON_HOME" (concat (getenv "HOME") "/.virtualenvs"))
  

  (add-hook 'pyvenv-post-activate-hooks #'lsp-restart-workspace)
  ;; This hook will copy venv from pyvenv to lsp pyright
  (add-hook 'pyvenv-post-activate-hooks (lambda ()
                                          (setq lsp-pyright-venv-directory pyvenv-virtual-env)
                                          (lsp-restart-workspace)))

  (setq pipenv-projectile-after-switch-function #'pipenv-projectile-after-switch-extended))

Keys

I don’t remember why I need this code. Currently commented.

(setq python-mode-map
      (let ((map (make-sparse-keymap)))
        ;; Movement
        (define-key map [remap backward-sentence] 'python-nav-backward-block)
        (define-key map [remap forward-sentence] 'python-nav-forward-block)
        (define-key map [remap backward-up-list] 'python-nav-backward-up-list)
        (define-key map [remap mark-defun] 'python-mark-defun)
        (define-key map "\C-c\C-j" 'imenu)
        ;; Indent specific
        (define-key map "\177" 'python-indent-dedent-line-backspace)
        (define-key map (kbd "<backtab>") 'python-indent-dedent-line)
        (define-key map "\C-c<" 'python-indent-shift-left)
        (define-key map "\C-c>" 'python-indent-shift-right)
        ;; Skeletons
        (define-key map "\C-c\C-tc" 'python-skeleton-class)
        (define-key map "\C-c\C-td" 'python-skeleton-def)
        (define-key map "\C-c\C-tf" 'python-skeleton-for)
        (define-key map "\C-c\C-ti" 'python-skeleton-if)
        (define-key map "\C-c\C-tm" 'python-skeleton-import)
        (define-key map "\C-c\C-tt" 'python-skeleton-try)
        (define-key map "\C-c\C-tw" 'python-skeleton-while)
        ;; Shell interaction
        (define-key map "\C-c\C-p" 'run-python)
        (define-key map "\C-c\C-s" 'python-shell-send-string)
        (define-key map "\C-c\C-e" 'python-shell-send-statement)
        (define-key map "\C-c\C-r" 'python-shell-send-region)
        (define-key map "\C-\M-x" 'python-shell-send-defun)
        (define-key map "\C-c\C-c" 'python-shell-send-buffer)
        (define-key map "\C-c\C-l" 'python-shell-send-file)
        (define-key map "\C-c\C-z" 'python-shell-switch-to-shell)
        ;; Some util commands
        (define-key map "\C-c\C-v" 'python-check)
        (define-key map "\C-c\C-f" 'python-eldoc-at-point)
        (define-key map "\C-c\C-d" 'python-describe-at-point)
        ;; Utilities
        (substitute-key-definition 'complete-symbol 'completion-at-point
                                   map global-map)
        (easy-menu-define python-menu map "Python Mode menu"
          '("Python"
            :help "Python-specific Features"
            ["Shift region left" python-indent-shift-left :active mark-active
             :help "Shift region left by a single indentation step"]
            ["Shift region right" python-indent-shift-right :active mark-active
             :help "Shift region right by a single indentation step"]
            "-"
            ["Start of def/class" beginning-of-defun
             :help "Go to start of outermost definition around point"]
            ["End of def/class" end-of-defun
             :help "Go to end of definition around point"]
            ["Mark def/class" mark-defun
             :help "Mark outermost definition around point"]
            ["Jump to def/class" imenu
             :help "Jump to a class or function definition"]
            "--"
            ("Skeletons")
            "---"
            ["Start interpreter" run-python
             :help "Run inferior Python process in a separate buffer"]
            ["Switch to shell" python-shell-switch-to-shell
             :help "Switch to running inferior Python process"]
            ["Eval string" python-shell-send-string
             :help "Eval string in inferior Python session"]
            ["Eval buffer" python-shell-send-buffer
             :help "Eval buffer in inferior Python session"]
            ["Eval statement" python-shell-send-statement
             :help "Eval statement in inferior Python session"]
            ["Eval region" python-shell-send-region
             :help "Eval region in inferior Python session"]
            ["Eval defun" python-shell-send-defun
             :help "Eval defun in inferior Python session"]
            ["Eval file" python-shell-send-file
             :help "Eval file in inferior Python session"]
            ["Debugger" pdb :help "Run pdb under GUD"]
            "----"
            ["Check file" python-check
             :help "Check file for errors"]
            ["Help on symbol" python-eldoc-at-point
             :help "Get help on symbol at point"]
            ["Complete symbol" completion-at-point
             :help "Complete symbol before point"]))
        map))

WEB mode development

(use-package web-mode
  :defer t
  :mode
  ("\\.vue\\'" . web-mode)
  ;; ("\\.tsx\\'" . typescript-tsx-mode)
  ("\\.tsx\\'" . web-mode)
  ("\\.jsx\\'" . web-mode)
  ("\\.astro\\'" . web-mode)
  :config
  (setq web-mode-enable-auto-quoting nil)
  (setq web-mode-comment-formats
        '(("java"       . "/*")
          ("javascript" . "//")
          ("typescript" . "//")
          ("vue"        . "//")
          ("php"        . "/*")
          ("pug"        . "//")
          ("css"        . "/*")))
  (setq web-mode-script-padding 0)
  (setq web-mode-style-padding 0)
  (setq web-mode-code-indent-offset 2)
  (setq web-mode-css-indent-offset 2))

PUG

(use-package pug-mode
  :defer t)

HTML

Emmet. Quick tag expanding

(use-package emmet-mode
  :hook ((scss-mode . emmet-mode) (css-mode . emmet-mode) (ng2-html-mode . emmet-mode) (html-mode . emmet-mode))
  :general 
  (:keymaps 'override
   :states 'insert
   "s-e" 'emmet-expand-line)
  :defer t)

SCSS/CSS

(use-package css-mode
  :ensure nil
  :defer 10
  :config
  (setq css-indent-offset 2)
  (defun revert-buffer-no-confirm ()
    "Revert buffer without confirmation."
    (interactive)
    (revert-buffer :ignore-auto :noconfirm)))

Tailwind css

(use-package lsp-tailwindcss
  :init
  (setq lsp-tailwindcss-add-on-mode t)
  :config
  (add-hook 'before-save-hook 'lsp-tailwindcss-rustywind-before-save))

Json mode

(use-package json-mode
  :defer 5
  :hook (json-mode . format-all-mode)
  :config
  (setq js-indent-level 2))

Flutter

Dart

(use-package dart-mode
  :defer t
  ;; Optional
  :hook (dart-mode . flutter-test-mode))

Flutter mode

(use-package flutter
  :after dart-mode
  :general
  (:keymaps 'dart-mode-map
            "C-c C-r" #'flutter-run-or-hot-reload)
  (:states '(normal visual)
           :keymaps '(dart-mode-map flutter-mode-map)
           "SPC m f s" #'flutter-run
           "SPC m f R" #'flutter-hot-restart
           "SPC m f r" #'flutter-run-or-hot-reload)
  :custom
  (flutter-sdk-path "/Applications/flutter/"))

LUA mode

(use-package lua-mode
  :defer t)

CI/infrastructure

Docker compose

(use-package docker-compose-mode
  :defer t)

Docker

Dockerfile mode

(use-package dockerfile-mode
  :defer t
  :config
  (add-hook 'compilation-filter-hook #'my-remove-cr -90))

Docker manager

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

Jenkins

(use-package jenkinsfile-mode
  :defer t
  :config)

K8S

(use-package kubernetes
  :defer 6
  :commands (kubernetes-overview)
  :bind (:map evil-normal-state-map
              ("SPC o K" . kubernetes-overview))
  :config
  (setq kubernetes-poll-frequency 3600
        kubernetes-redraw-frequency 3600))

(use-package k8s-mode
  :defer t)

Navigation for kuber

(use-package kubernetes-evil
  :after kubernetes)

NGINX

(use-package nginx-mode
  :defer t)

Jinja

(use-package jinja2-mode
  :defer t)

Markdown

Function for generating table of content TOC

(defun @markdown-toc ()
  "Extract level 2 and 3 headings from the current Markdown buffer.
   The generated and indented TOC will be inserted at point."
  (interactive)
  (let (toc-list markdown-toc)
    (save-excursion
      (goto-char (point-min))
      (while (re-search-forward "^\\(##+\\)\\s-+\\(.*\\)" nil t)
        (let* ((level (length (match-string 1)))
               (heading-text (match-string 2))
               (heading-id (downcase (replace-regexp-in-string "[[:space:]]+" "-" heading-text))))
          (push (cons level (cons heading-text heading-id)) toc-list))))
    (setq toc-list (reverse toc-list))
    (dolist (item toc-list)
      (let* ((level (car item))
             (heading-text (cadr item))
             (heading-id (cddr item))
             (indentation (make-string (* 2 (1- level)) ?\ ))
             (line (format "- [%s](#%s)\n" heading-text heading-id)))
        (setq markdown-toc (concat markdown-toc (concat indentation line)))))
    (insert markdown-toc)))

Face

(custom-set-faces
 `(markdown-table-face ((t (:inherit default :foreground ,+m-color-secondary)))))

Realtime preview

(use-package grip-mode
  :defer t
  :custom
  (browse-url-browser-function 'browse-url-generic)
  ;; (grip-url-browser #'browse-url-firefox-program)
  :config
  (let ((credential (auth-source-user-and-password "api.github.com")))
    (setq grip-github-user (car credential)
          grip-github-password (cadr credential))))

Xwidget preview

(use-package markdown-xwidget
  :after markdown-mode
  :ensure (markdown-xwidget
             :type git
             :host github
             :repo "cfclrk/markdown-xwidget"
             :files (:defaults "resources"))
  :bind (:map markdown-mode-command-map
              ("x" . markdown-xwidget-preview-mode))
  :custom
  (markdown-xwidget-command "pandoc")
  (markdown-xwidget-github-theme "light")
  (markdown-xwidget-mermaid-theme "default")
  (markdown-xwidget-code-block-theme "default"))

Org mode

Org GPG encryption

(use-package org-crypt
  :ensure nil
  :config
  (org-crypt-use-before-save-magic)
  (setq org-tags-exclude-from-inheritance (quote ("crypt")))
  ;; GPG key to use for encryption
  ;; Either the Key ID or set to nil to use symmetric encryption.
  (setq org-crypt-key nil))

Org babels

async code

(use-package ob-async
  :defer t
  :config
  (setq ob-async-no-async-languages-alist '("ipython")))

HTTP requests

Dependency

(use-package restclient
  :after org)
(use-package ob-restclient
  :after org)

Dart

(use-package ob-dart
  :after org
  :defer t
  :config
  (add-to-list 'org-babel-load-languages  '(dart . t)))

Typescript

(use-package ob-typescript
  :after org)

(elpaca-wait)

Golang

(use-package ob-go :after org)

SQL

(org-babel-do-load-languages
 'org-babel-load-languages
 '((sql . t)))

Rust

(use-package ob-rust :after org)

Org package

(use-package org
  :ensure nil
  :defer t
  :mode (("\\.org$" . org-mode))
  :hook
  (org-mode . org-indent-mode)
  (org-mode . (lambda () (setq corfu-mode -1)))
  :general
  (:states '(normal visual)
   :keymaps 'override
   "SPC m t" 'org-todo
   "SPC m n" 'org-store-link
   "SPC m l l" 'org-insert-link
   "SPC nl" 'org-store-link 
   "SPC dt" 'org-time-stamp-inactive
   "SPC mlt" 'org-toggle-link-display)
  (:states '(normal visual)
   :keymaps 'org-mode-map
   "SPC dt" 'org-time-stamp-inactive
   "SPC st" 'org-set-tags-command
   "SPC mx" 'org-toggle-checkbox
   "<return>" '+org/dwim-at-point)
  (:keymaps 'org-read-date-minibuffer-local-map
            "C-s" 'org-goto-calendar)
  (:keymaps 'calendar-mode-map
            "<return>" 'org-calendar-select)

  :bind (:map evil-normal-state-map
              ("SPC h ]" . org-next-visible-heading)
              ("SPC h [" . org-previous-visible-heading))
  :config
  (setq org-babel-python-command "python3")
  (setq org-confirm-babel-evaluate nil)
  (setq org-src-preserve-indentation t)
  (setq org-latex-create-formula-image-program 'dvisvgm)
  (setq org-format-latex-options (plist-put org-format-latex-options :scale 2.0))
  ;; https://www.reddit.com/r/orgmode/comments/jwf7ya/python_org_code_blocks_and_indentation/
	(setq org-adapt-indentation nil)
  (add-hook 'org-mode-hook
            (lambda () (imenu-add-to-menubar "Imenu")))
  (setq org-imenu-depth 8)
  (@setup-org-mode-faces)

  (setq org-src-window-setup 'current-window)
  (setq org-todo-keywords
        '((sequence
           "TODO(t)"     ; A task that needs doing & is ready to do
           "PROJ(p)"     ; A project, which usually contains other tasks
           "IDEA(i)"     ; Idea
           "PROGRESS(s)" ; A task that is in progress
           "WAIT(w)"     ; Something external is holding up this task
           "TEST(c)"     ; In TEST statement
           "BLOCK(b)"    ; task blocked
           "REJECTED(x)" ; somebody rejected idea :(
           "FEEDBACK(f)" ; Feedback required
           "REVIEW(r)"   ; Somebody reviewed your feature
           "HOLD(h)"     ; This task is paused/on hold because of me
           "|"
           "DONE(d)"     ; Task successfully completed
           "KILL(k)")    ; Task was cancelled, aborted or is no longer applicable
          (sequence
           "[ ](T)"      ; A task that needs doing
           "[-](S)"      ; Task is in progress
           "[?](W)"      ; Task is being held up or paused
           "|"
           "[X](D)"))    ; Task was completed
        org-todo-keyword-faces
        '(("[-]"        . +org-todo-active)
          ("PROGRESS"   . org-todo)
          ("DONE"       . org-todo)
          ("IDEA"       . org-todo)
          ("[?]"        . +org-todo-onhold-face)
          ("WAIT"       . +org-todo-onhold-face)
          ("TEST"       . +org-todo-active-face)
          ("FEEDBACK"   . +org-todo-onhold-face)
          ("REVIEW"     . +org-todo-onhold-face)
          ("HOLD"       . +org-todo-onhold-face)
          ("PROJ"       . +org-todo-project)
          ("BLOCK"      . +org-todo-cancel)
          ("REJECTED"   . +org-todo-cancel)
          ("KILL"       . +org-todo-cancel)))

  (setq org-hide-emphasis-markers t)
  (setq org-use-property-inheritance t)

  (add-to-list 'org-tag-faces '("@.*" . (:foreground "red")))

  ;; Increase priorities count
  (setq org-highest-priority ?A
        org-default-priority ?C
        org-lowest-priority ?E)


  (defun publish-org-blog()
    "Publish this note to du-blog!"
    (interactive)
    (require 'ox-gfm)
    (setq org-export-with-sub-superscripts '{})
    (defun org-gfm-format-toc (headline) "")
    (org-gfm-export-to-markdown)
    (let ((file-path (replace-regexp-in-string " " "\\\\\  " (buffer-file-name))))
      (shell-command
       (concat
        "node /Users/darkawower/projects/pet/it-blog/emacs-blog/index.js "
        file-path))))

  (setenv "NODE_PATH"
          (concat
           (getenv "HOME") "/org-node/node_modules"  ":"
           (getenv "NODE_PATH")))

  (org-babel-do-load-languages
   'org-babel-load-languages
   '(
     ;; (typescript . t)
     (js . t)
     (python . t)
     (restclient . t)
     (shell . t)))

  (defun org-babel-execute:typescript (body params)
    (let ((org-babel-js-cmd "npx ts-node < "))
      (org-babel-execute:js body params)))

  (defvar org-babel-js-function-wrapper
    ""
    "Javascript code to print value of body.")
  ;; Applications for opening from org files
  ;; (if (assoc "\\.pdf\\'" org-file-apps)
  ;;     (setcdr (assoc "\\.pdf\\'" org-file-apps) 'emacs)
  ;;   (add-to-list 'org-file-apps '("\\.pdf\\'" . emacs) t))

  ;; (add-to-list 'org-file-apps
  ;;              '("\\.pdf\\'" . (lambda (file link)
  ;;                                (org-pdfview-open link))))
  (add-hook 'org-mode-hook
            (lambda () (imenu-add-to-menubar "Imenu"))))

Ligatures for org mode

(add-hook 'org-mode-hook (lambda ()
                           "Beautify Org Checkbox Symbol"
                           (push '("[ ]" .  "") prettify-symbols-alist)
                           (push '("[X]" . "" ) prettify-symbols-alist)
                           (push '("[-]" . "" ) prettify-symbols-alist)
                           (push '("#+BEGIN_SRC" . "" ) prettify-symbols-alist)
                           (push '("#+END_SRC" . "" ) prettify-symbols-alist)
                           (push '("#+BEGIN_EXAMPLE" . "" ) prettify-symbols-alist)
                           (push '("#+END_EXAMPLE" . "" ) prettify-symbols-alist)
                           (push '("#+BEGIN_QUOTE" . "" ) prettify-symbols-alist)
                           (push '("#+END_QUOTE" . "" ) prettify-symbols-alist)
                           (push '("#+begin_quote" . "" ) prettify-symbols-alist)
                           (push '("#+end_quote" . "" ) prettify-symbols-alist)
                           (push '("#+begin_example" . "" ) prettify-symbols-alist)
                           (push '("#+end_example" . "" ) prettify-symbols-alist)
                           (push '("#+begin_src" . "" ) prettify-symbols-alist)
                           (push '("#+end_src" . "" ) prettify-symbols-alist)

                           (push '("#+TITLE:" . "") prettify-symbols-alist)
                           (push '("#+DESCRIPTION:" . "") prettify-symbols-alist)
                           (push '("#+LANG:" . "") prettify-symbols-alist)
                           (push '("#+ID:" . "") prettify-symbols-alist)
                           (push '("#+FILETAGS:" . "") prettify-symbols-alist)
                           (push '("#+STARTUP:" . "") prettify-symbols-alist)
                           (push '("#+ACTIVE:" . "") prettify-symbols-alist)
                           (push '("#+START_SPOILER" . "") prettify-symbols-alist)
                           (push '("#+CLOSE_SPOILER" . "") prettify-symbols-alist)
                           (push '("#+BEGIN_HIDDEN" . "") prettify-symbols-alist)
                           (push '("#+END_HIDDEN" . "") prettify-symbols-alist)


                           ;; (push '("#+TITLE:" . "") prettify-symbols-alist)
                           ;; (push '("#+DESCRIPTION:" . "") prettify-symbols-alist)
                           ;; (push '("#+ID:" . "") prettify-symbols-alist)
                           ;; (push '("#+FILETAGS:" . "") prettify-symbols-alist)
                           ;; (push '("#+STARTUP:" . "") prettify-symbols-alist)
                           ;; (push '("#+ACTIVE:" . "") prettify-symbols-alist)
                           ;; (push '("#+START_SPOILER" . "") prettify-symbols-alist)
                           ;; (push '("#+CLOSE_SPOILER" . "") prettify-symbols-alist)
                           ;; (push '("#+BEGIN_HIDDEN" . "") prettify-symbols-alist)
                           ;; (push '("#+END_HIDDEN" . "") prettify-symbols-alist)

                           (prettify-symbols-mode)))

Prettify org priority

(use-package org-fancy-priorities
  :after org
  :ensure t
  :hook (org-mode . org-fancy-priorities-mode)
  :config
  (setq org-fancy-priorities-list '((?A . "🔥")
                                    (?B . "")
                                    (?C . "")
                                    (?D . "")
                                    (?E . "")
                                    (?1 . "🔥")
                                    (?2 . "")
                                    (?3 . "")
                                    (?4 . "")
                                    (?I . "Important"))))

Pretty org stars

(use-package org-superstar
  :after org
  :hook (org-mode . org-superstar-mode)
  :config
  (setq org-directory "~/Yandex.Disk.localized/Dropbox/org"))

Org roam

One of the best Zettelkasten implementation

(use-package org-roam
  ;; :ensure (:package "org-roam" :protocol https :inherit t :depth 1 :fetcher github :repo "org-roam/org-roam")
  :bind
  (:map evil-normal-state-map
        ("SPC n r i" . org-roam-node-insert)
        ("SPC n r f" . org-roam-node-find))
  (:map evil-visual-state-map
        ("SPC n r i" . org-roam-node-insert))
  :init
  (setq org-roam-v2-ack t)
  :config

  (org-roam-db-autosync-enable)
  (cl-defmethod org-roam-node-mtitle ((node org-roam-node))
    "Return customized title of roam node"
    (let* ((tags (org-roam-node-tags node))
           (title (org-roam-node-title node)))
      (if (not tags)
          title
        (setq joined-text (string-join tags ", "))
        (concat (propertize (format "(%s) " joined-text) 'face `(:foreground ,+m-color-main :weight bold :slant italic)) title))))
  ;; (setq org-roam-completion-system 'ivy)
  (setq org-roam-completion-system 'vertico)
  (setq org-roam-node-display-template "${mtitle:100}")
  (setq org-roam-directory (file-truename "~/org-roam")))

(use-package websocket
  :after org-roam)

Image inserting to org documents

(use-package org-yt
  :after org
  :ensure (:host github :repo "TobiasZawada/org-yt")
  :config
  (defun org-image-link (protocol link _description)
    "Interpret LINK as base64-encoded image data."
    (cl-assert (string-match "\\`img" protocol) nil
               "Expected protocol type starting with img")
    (let ((buf (url-retrieve-synchronously (concat (substring protocol 3) ":" link))))
      (cl-assert buf nil
                 "Download of image \"%s\" failed." link)
      (with-current-buffer buf
        (goto-char (point-min))
        (re-search-forward "\r?\n\r?\n")
        (buffer-substring-no-properties (point) (point-max)))))

  (org-link-set-parameters
   "imghttp"
   :image-data-fun #'org-image-link)

  (org-link-set-parameters
   "imghttps"
   :image-data-fun #'org-image-link))

Orgnote. Roam publisher for second bran project

My own package for publish roam files

(use-package orgnote
  :ensure (:host github :repo "Artawower/orgnote.el")
  :general
  (:states '(normal visual)
           :keymaps 'org-mode-map
           "SPC np" 'orgnote-publish-file)
  (:states '(normal visual)
           :keymaps 'override
           "SPC nP" 'orgnote-publish-all
           "SPC nL" 'orgnote-load
           "SPC nF" 'orgnote-force-sync
           "SPC nS" 'orgnote-sync)
  :custom
  (orgnote-debug-p t)
  (orgnote-execution-script "node /Users/darkawower/projects/pet/orgnote/orgnote-cli/dist/index.js"))

Org functions for pretty inserting

(use-package org-insert
  :after org
  :bind (:map org-mode-map
              ("<C-return>" . +org/insert-item-below)
              ("<C-S-return>" . +org/insert-item-above))
  :ensure (org-insert
           :type git
           :host github
           :repo "hlissner/doom-emacs"
           :files ("modules/lang/org/autoload/org.el")
           :main "modules/lang/org/autoload/org.el"))

Table of contents

(use-package org-make-toc
  :after org
  :bind (:map org-mode-map
              ("C-c g" . org-make-toc)))

Org exporters

(use-package ox-gfm
  :defer t
  :ensure (ox-gfm :type git :host github :repo "larstvei/ox-gfm"))

IDEA Latex preview

Debug for my own project

(use-package org-latex-impatient
  :defer t
  :hook (org-mode . org-latex-impatient-mode)
  :init
  (setq org-latex-impatient-tex2svg-bin
        ;; location of tex2svg executable
        "tex2svg"))

Org AI.

(use-package org-ai
  :ensure nil
  :load-path (lambda () "~/apps/pure-emacs/vendor/org-ai")
  :commands (org-ai-mode)
  :init
  (add-hook 'org-mode-hook #'org-ai-mode)
  :config
  (setq org-ai-openai-api-token open-ai-key)
  (advice-add 'keyboard-quit :before #'org-ai-keyboard-quit))

Org Download

(use-package org-download
  :defer 2
  :hook (dired-mode-hook . org-download-enable)
  :ensure (org-download :type git :host github :repo "abo-abo/org-download")
  :config
  (setq org-download-method 'directory)
  (setq org-download-link-format "[[./%s]]\n")
  (setq org-download-heading-lvl nil))

Spell checker

Spelling

(defun my-set-spellfu-faces ()
  "Set faces for correct spell-fu working"
  (interactive)
  (setq spell-fu-faces-include '(tree-sitter-hl-face:comment
                                 tree-sitter-hl-face:doc
                                 tree-sitter-hl-face:string
                                 tree-sitter-hl-face:function
                                 tree-sitter-hl-face:variable
                                 tree-sitter-hl-face:type
                                 tree-sitter-hl-face:method
                                 tree-sitter-hl-face:function.method
                                 tree-sitter-hl-face:function.special
                                 tree-sitter-hl-face:attribute
                                 font-lock-comment-face
                                 font-lock-doc-face
                                 font-lock-string-face
                                 lsp-face-highlight-textual
                                 default))
  (if (boundp 'spell-fu-faces-exclude)
    (setq spell-fu-faces-exclude (append spell-fu-faces-exclude
                                         '(diredfl-file-name)))
    (defvar spell-fu-faces-exclude
          '(diredfl-file-name))))

(use-package spell-fu
  :bind (:map evil-normal-state-map
              ("z g" . spell-fu-word-add))
  :defer 5
  :config
  (setq ispell-program-name "aspell")
  (setq spell-fu-directory "~/.doom.d/dictionary")
  (setq ispell-program-name "aspell"
        ;;           ;; Notice the lack of "--run-together"
        ispell-extra-args '("--sug-mode=ultra" "--lang=en_US" "--run-together" "--run-together-limit=56"))
  (setq spell-fu-ignore-modes '(dired-mode vterm-mode elfeed-search-mode))

  (add-hook 'spell-fu-mode-hook
            (lambda ()
              (spell-fu-dictionary-add (spell-fu-get-ispell-dictionary "en"))
              (spell-fu-dictionary-add (spell-fu-get-ispell-dictionary "ru"))
              (spell-fu-dictionary-add
               (spell-fu-get-personal-dictionary "en-personal" "/Users/darkawower/.doom.d/dictionary/.pws"))
              (spell-fu-dictionary-add
               (spell-fu-get-personal-dictionary "ru-personal" "/Users/darkawower/.doom.d/dictionary/ru.pws"))))

  ;; Camel case support
  (setq-default spell-fu-word-regexp
                (rx
                 (or
                  ;; lowercase
                  (seq
                   (one-or-more lower)
                   (opt
                    (any "'’")
                    (one-or-more lower)
                    word-end))

                  ;; capitalized
                  (seq
                   upper
                   (zero-or-more lower)
                   (opt
                    (any "'’")
                    (one-or-more lower)
                    word-end))

                  ;; uppercase
                  (seq
                   (one-or-more upper)
                   (opt
                    (any "'’")
                    (one-or-more upper)
                    word-end)))))

  (defun cs/spell-fu-check-range (pos-beg pos-end)
    (let (case-fold-search)
      (spell-fu-check-range-default pos-beg pos-end)))

  (setq-default spell-fu-check-range #'cs/spell-fu-check-range)
  (global-spell-fu-mode)
  (my-set-spellfu-faces))

Grammarly lsp

Didn’t mange to start work

(use-package lsp-grammarly
  :hook
  (text-mode . (lambda ()
                 (require 'lsp-grammarly)
                 (lsp-deferred))))

Lsp ltex. Grammarly lsp server

(use-package lsp-ltex
  :ensure t)
  ;; :hook
  ;; (text-mode . (lambda ()
  ;;                (require 'lsp-ltex)
  ;;                (lsp-deferred)))  ; or lsp-deferred
  ;; (org-mode . (lambda ()
  ;;                (require 'lsp-ltex)
  ;;                (lsp-deferred)))
  ;; :init
  ;; (setq lsp-ltex-version "15.2.0-mac-x64"))

Google translate

(use-package google-translate
  :defer 10
  :bind (:map google-translate-minibuffer-keymap
        ("C-k" . google-translate-next-translation-direction)
        ("C-n" . google-translate-next-translation-direction)
        :map evil-normal-state-map
        ("\\ t" . google-translate-smooth-translate))
  :config
  (require 'google-translate-smooth-ui)
  (setq google-translate-backend-method 'curl)
  (setq google-translate-pop-up-buffer-set-focus t)
  (setq google-translate-translation-directions-alist
        '(("en" . "ru") ("ru" . "en") ))
  (defun google-translate--search-tkk () "Search TKK." (list 430675 2721866130)))

Reverso

(use-package reverso
  :general
  (:states '(normal visual) :keymaps 'override
           "SPC rr" 'reverso
           "SPC rt" 'reverso-translate
           "SPC rh" 'reverso-history)
  :ensure (:host github :repo "SqrtMinusOne/reverso.el"))

Tools

Wakatime. Be productive.

Main package

(use-package wakatime-mode
  :defer 2
  :config
  (global-wakatime-mode))

Ui

(use-package wakatime-ui
  :after wakatime-mode
  :ensure (wakatime-ui :host github :repo "Artawower/wakatime-ui.el")
  :custom
  (wakatim-ui-schedule-url "https://wakatime.com/share/@darkawower/af1bfb85-2c8b-44e4-9873-c4a91b512e8d.png")
  :config
  (wakatime-ui-mode))

Recent

(use-package recentf
  :after consult
  :ensure nil
  :init
  (recentf-mode 1)
  :config
  (setq recentf-max-menu-items 100))

Projectile

Projectile package

(use-package projectile
  :ensure nil
  :general
  (:states 'normal
           "SPC pa" 'projectile-add-known-project
           "SPC ki" '@kill-invisible-buffers)
  :config
  <<projectile-persp-hook>>
  (projectile-mode +1))

Projectil persp hook

(defun @set-perps-workspace-name-by-switched-project ()
  "Set perps workspace name by switched project"
  (interactive)
  (when (and (bound-and-true-p persp-mode)
             (bound-and-true-p projectile-mode))
    (persp-rename (projectile-project-name))))

(add-hook 'projectile-after-switch-project-hook
          #'@set-perps-workspace-name-by-switched-project)

(add-hook 'projectile-find-file-hook
          #'@set-perps-workspace-name-by-switched-project)

Projectile. Remove invisible buffers

(defun @kill-invisible-buffers ()
  "Kill all buffers that are invisible in the current project."
  (interactive)
  (dolist (buf  (project-buffers (project-current)))
    ;; when buffer name doesn't start with a *
    (when (and (not (string-prefix-p "*" (buffer-name buf)))
               ;; and buffer is not visible
               (not (get-buffer-window buf 'visible)))
      ;; kill buffer
      (kill-buffer buf))))

Helpful

(use-package helpful
  :defer t
  :bind (("C-h k" . helpful-key)
         :map evil-normal-state-map
         ("SPC h v" . helpful-variable)
         ("SPC h f" . helpful-function)
         ("SPC h ." . helpful-at-point)))

Completion

Vertico

(use-package vertico
  :ensure (:host github :repo "minad/vertico" :files ("vertico.el" "extensions/*.el"))
  :bind (:map evil-normal-state-map
              ("SPC ;" . vertico-repeat-last)
              ("SPC '" . vertico-repeat)
              :map vertico-map
              ("C-j" . vertico-next)
              ("C-k" . vertico-previous)
              ("C-n" . vertico-next-group)
              ("C-p" . vertico-previous-group)
              ("C-l" . vertico-quick-jump)
              ("C-d" . vertico-scroll-up)
              ("C-u" . vertico-scroll-down)
              ("C-o" . embark-act)
              ("C-q" . vertico-exit-input)
              ("C-n" . vertico-next-group)
              ("C-p" . vertico-previous-group)
              ("<escape>" . abort-minibuffers)
              ("C-d" . (lambda ()
                         (interactive)
                         (kill-whole-line)
                         (insert "~/")))
              ("C-o" . (lambda ()
                         (interactive)
                         (embark-act)))
              ("C-r" . (lambda ()
                         (interactive)
                         (kill-whole-line)
                         (insert "/"))))
  :init
  (vertico-mode)
  (setq vertico-cycle t)
  :config
  (setq read-file-name-completion-ignore-case t
        read-buffer-completion-ignore-case t
        completion-ignore-case t)
  (require 'vertico-repeat)
  (add-hook 'minibuffer-setup-hook 'vertico-repeat-save))

(elpaca-wait)

(use-package vertico-repeat
   :ensure nil
   :after vertico)

(use-package orderless
  :init
  (setq completion-styles '(orderless)
        completion-category-defaults nil
        completion-category-overrides '((file (styles partial-completion)))))

;; Persist history over Emacs restarts. Vertico sorts by history position.
(use-package savehist
  :ensure nil
  :config
  (savehist-mode))

;; A few more useful configurations...
(use-package emacs
  :ensure nil
  :init
  ;; Add prompt indicator to `completing-read-multiple'.
  ;; Alternatively try `consult-completing-read-multiple'.
  (defun crm-indicator (args)
    (cons (concat "[CRM] " (car args)) (cdr args)))
  (advice-add #'completing-read-multiple :filter-args #'crm-indicator)

  ;; Do not allow the cursor in the minibuffer prompt
  (setq minibuffer-prompt-properties
        '(read-only t cursor-intangible t face minibuffer-prompt))
  (add-hook 'minibuffer-setup-hook #'cursor-intangible-mode)

  ;; Emacs 28: Hide commands in M-x which do not work in the current mode.
  ;; Vertico commands are hidden in normal buffers.
  ;; (setq read-extended-command-predicate
  ;;       #'command-completion-default-include-p)

  ;; Enable recursive minibuffers
  (setq enable-recursive-minibuffers t))

Completion for eval expression

(setq completion-in-region-function
      (lambda (&rest args)
        (apply (if vertico-mode
                   #'consult-completion-in-region
                 #'completion--in-region)
               args)))

Completion annotations

(use-package marginalia
  :after vertico
  ;; Either bind `marginalia-cycle` globally or only in the minibuffer
  :bind (("M-A" . marginalia-cycle)
         :map minibuffer-local-map
         ("M-A" . marginalia-cycle))

  ;; The :init configuration is always executed (Not lazy!)
  :init
  (marginalia-mode)
  :config
  (pushnew! marginalia-command-categories
          '(+default/find-file-under-here . file)
          '(flycheck-error-list-set-filter . builtin)
          '(persp-switch-to-buffer . buffer)
          '(projectile-find-file . project-file)
          '(projectile-recentf . project-file)
          '(projectile-switch-to-buffer . buffer)
          '(projectile-switch-project . project-file)))

**

Consult

Consult. Main package

Function for search in buffer depends or visual or normal line

(defun @consult-line-or-region ()
  "Search in buffer depends or visual or normal line"
  (interactive)
  (if (region-active-p)
      (let ((substring (buffer-substring (region-beginning) (region-end))))
        (deactivate-mark)
        (consult-line substring))
    (consult-line)))
(use-package consult
  :defer t
  :general (:states '(normal visual)
                    :keymaps 'override
                    "s-f" '@consult-line-or-region
                    "SPC bB" 'consult-buffer
                    "SPC fP" '@open-emacs-config
                    "SPC /" 'consult-ripgrep
                    "SPC *" (lambda () (interactive) (consult-ripgrep nil (thing-at-point 'symbol)))
                    "SPC si" 'consult-imenu
                    "SPC RET" 'consult-bookmark
                    "SPC cm" 'consult-mark
                    "SPC fR" 'consult-recent-file
                    "SPC fr" 'projectile-recentf
                    "SPC SPC" 'consult-projectile-find-file
                    "M-n" (lambda () (interactive) (search-forward (car consult--line-history)))
                    "M-p" (lambda () (interactive) (search-backward (car consult--line-history))))

  ;; Enable automatic preview at point in the *Completions* buffer. This is
  ;; relevant when you use the default completion UI. You may want to also
  ;; enable `consult-preview-at-point-mode` in Embark Collect buffers.
  :hook (completion-list-mode . consult-preview-at-point-mode)

  ;; The :init configuration is always executed (Not lazy)
  :init

  ;; Optionally configure the register formatting. This improves the register
  ;; preview for `consult-register', `consult-register-load',
  ;; `consult-register-store' and the Emacs built-ins.
  (setq recentf-max-saved-items 3000)
  (setq register-preview-delay 0
        register-preview-function #'consult-register-format)

  ;; Optionally tweak the register preview window.
  ;; This adds thin lines, sorting and hides the mode line of the window.
  ;; (advice-add #'register-preview :override #'consult-register-window)

  ;; Optionally replace `completing-read-multiple' with an enhanced version.
  ;; (advice-add #'completing-read-multiple :override #'consult-completing-read-multiple)

  ;; Use Consult to select xref locations with preview
  (setq xref-show-xrefs-function #'consult-xref
        xref-show-definitions-function #'consult-xref)

  ;; Configure other variables and modes in the :config section,
  ;; after lazily loading the package.
  :config

  ;; Optionally configure preview. The default value
  ;; is 'any, such that any key triggers the preview.
  ;; (setq consult-preview-key 'any)
  ;; (setq consult-preview-key (kbd "M-."))
  ;; (setq consult-preview-key (list (kbd "<S-down>") (kbd "<S-up>")))
  ;; For some commands and buffer sources it is useful to configure the
  ;; :preview-key on a per-command basis using the `consult-customize' macro.
  (consult-customize
   consult-projectile-find-file consult-git-grep consult-grep consult-projectile-recentf consult-ripgrep
   consult-bookmark consult-recent-file consult-xref consult--source-bookmark consult--source-file-register
   consult--source-recent-file consult--source-project-recent-file
   ;; my/command-wrapping-consult    ;; disable auto previews inside my command
   :preview-key (list :debounce 0.2 "C-SPC"))

  ;; Optionally configure the narrowing key.
  ;; Both < and C-+ work reasonably well.
  (setq consult-narrow-key "<") ;; (kbd "C-SPC")

  ;; Optionally make narrowing help available in the minibuffer.
  ;; You may want to use `embark-prefix-help-command' or which-key instead.
  ;; (define-key consult-narrow-map (vconcat consult-narrow-key "?") #'consult-narrow-help)

  ;; Optionally configure a function which returns the project root directory.
  ;; There are multiple reasonable alternatives to chose from.
        ;;;; 1. project.el (project-roots)
  (setq consult-project-root-function
        (lambda ()
          (when-let (project (project-current))
            (car (project-roots project)))))
        ;;;; 2. projectile.el (projectile-project-root)
  ;; (autoload 'projectile-project-root "projectile")
  ;; (setq consult-project-root-function #'projectile-project-root)
        ;;;; 3. vc.el (vc-root-dir)
  ;; (setq consult-project-root-function #'vc-root-dir)
        ;;;; 4. locate-dominating-file
  ;; (setq consult-project-root-function (lambda () (locate-dominating-file "." ".git")))
  )

Consult flycheck

(use-package consult-flycheck
  :after consult)

Consult lsp

(use-package consult-lsp
  :defer t
  :general (:states 'normal
                    "SPC ss" 'consult-lsp-symbols
                    "SPC sl" 'consult-lsp-diagnostics))

Projectile

(use-package consult-projectile
  :general (:states 'normal
                    "SPC pp" 'consult-projectile-switch-project
                    "SPC pi" 'projectile-invalidate-cache
                    "SPC pa" 'projectile-add-known-project)
  :config
  (setq consult-projectile-use-projectile-switch-project t)
  (add-to-list 'projectile-globally-ignored-directories "node_modules")
  :defer t)

Embark

Embark functions

Copy only content (not category) For more details check https://www.reddit.com/r/emacs/comments/zou9x0/comment/j1afu1c/?utm_source=share&utm_medium=web2x&context=3

(defun copy-grep-results-as-kill (strings)
  (embark-copy-as-kill
   (mapcar (lambda (string)
             (substring string
                        (1+ (next-single-property-change
                             (1+ (next-single-property-change 0 'face string))
                             'face string))))
           strings)))

(add-to-list 'embark-multitarget-actions 'copy-grep-results-as-kill)

(defvar-keymap embark-consult-grep-map
  :doc "Keymap for actions for consult-grep results."
  :parent embark-general-map
  "w" #'copy-grep-results-as-kill)

(setf (alist-get 'consult-grep embark-keymap-alist) 'embark-consult-grep-map)

Delete project

(defvar-keymap embark-projectile-map
  :doc "Example keymap with a few file actions"
  :parent embark-general-map
  "d" #'projectile-remove-known-project)

(add-to-list 'embark-keymap-alist '(consult-projectile-project . embark-projectile-map))

Embark package

(defun +vertico/embark-preview ()
  "Previews candidate in vertico buffer, unless it's a consult command"
  (interactive)
  (unless (bound-and-true-p consult--preview-function)
    (save-selected-window
      (let ((embark-quit-after-action nil))
        (embark-dwim)))))

(use-package embark
  :custom
  (embark-indicators '(embark-minimal-indicator embark-highlight-indicator embark-isearch-highlight-indicator))
  :general
  ("C-." 'embark-act         ;; pick some comfortable binding
   "C-;" 'embark-dwim        ;; good alternative: M-.
   "C-h B" 'embark-bindings)
  (:keymaps '(minibuffer-local-mode-map read--expression-map vertico-map)
            "C-SPC" '+vertico/embark-preview
            ;; "C-SPC" 'consult-preview-at-point
            ;; "C-SPC" 'consult--buffer-preview
 						"C-u" 'evil-delete-back-to-indentation
            "C-<return>" '+vertico/embark-preview)
  :init
  ;; Optionally replace the key help with a completing-read interface
  (setq prefix-help-command #'embark-prefix-help-command)
  :config
  (add-to-list 'display-buffer-alist '("^\\*Embark Export\\*$" (display-buffer-in-side-window) (window-height . 0.4)))
  <<embark-delete-project>>
  <<embark-content-copy-function>>)

;; Consult users will also want the embark-consult package.
(use-package embark-consult
  :after (embark consult)
  :demand t ; only necessary if you have the hook below
  ;; if you want to have consult previews as you move around an
  ;; auto-updating embark collect buffer
  :hook
  (embark-collect-mode . consult-preview-at-point-mode))

Bulk grep operation

(use-package wgrep
  :general 
  (:keymaps 'override
            "C-c C-w" 'wgrep-change-to-wgrep-mode)
  :after vertico)

Emacs for everything

Tramp

(use-package tramp
  :ensure nil
  :config
  (setenv "SHELL" "/bin/bash")
  (setq remote-file-name-inhibit-cache nil)
  (setq vc-ignore-dir-regexp
        (format "%s\\|%s"
                vc-ignore-dir-regexp
                tramp-file-name-regexp))
  (setq tramp-verbose 1)
  (add-to-list 'tramp-connection-properties
               (list (regexp-quote "/sshx:user@host:")
                     "remote-shell" "/usr/bin/bash"))
  (add-to-list 'tramp-connection-properties
               (list ".*" "locale" "LC_ALL=C")))

Pdf tools

(use-package pdf-tools
  :ensure t
  :defer t
  :config
  (pdf-tools-install))

Org pdf

;; (use-package org-pdftools)
  ;; :hook (org-mode . org-pdftools-setup-link))

Pocket

(use-package pocket-reader
  :general
  (:keymaps 'override
            :states '(normal visual)
            "SPC ep" 'pocket-reader)
  (:keymaps 'pocket-reader-mode-map
            :states '(normal visual)
            "<return>" 'pocket-reader-open-in-external-browser
            "s" 'pocket-reader-search
            "d" 'pocket-reader-delete
            "r" 'pocket-reader-refresh
            "a" 'pocket-reader-add-link
            "ta" 'pocket-reader-add-tags
            "m" 'pocket-reader-more
            "w" 'pocket-reader-copy-url
            "tf" 'pocket-reader-tag-search)
  :defer t)

GPTel

(use-package gptel
  :config
  ;; (setq gptel-api-key gpt-key)
  ;; Make gpt4all the default
  ;; (setq-default
  ;;  gptel-backend
  ;;  (gptel-make-openai                    ;Not a typo, same API as OpenAI
  ;;   "llama-cpp"                          ;Any name
  ;;   :stream t                            ;Stream responses
  ;;   :protocol "http"
  ;;   :host "localhost:8080"               ;Llama.cpp server location, typically localhost:8080 for Llamafile
  ;;   :key nil                             ;No key needed
  ;;   :models '("test")))
  ;; (setq-default gptel-model "test")
  (setq-default gptel-backend
                (gptel-make-ollama
                 "Ollama"                       
                 :host "localhost:11434"         
                 :models '("codellama:latest")      
                 :stream t))
  (setq-default gptel-model "codellama")
  ;; (setq-default
  ;;  gptel-backend
  ;;  (gptel-make-gpt4all
  ;;   "GPT4All"                             ;Any name of your choosing
  ;;   :protocol "http"                       
  ;;   :host "localhost:4891"                       ;Where it's running
  ;;   :models '("mistral-7b-openorca.Q4_0.gguf"))) ;Available models


  ;; Don't limit token count:
  (setq-default gptel-max-tokens 800)
  )

PlantUML

(use-package plantuml-mode
  :defer t
  :init
  (add-to-list 'auto-mode-alist '("\\.plantuml\\'" . plantuml-mode))
  (add-to-list 'auto-mode-alist '("\\.pu\\'" . plantuml-mode))
  (add-to-list 'auto-mode-alist '("\\.puml\\'" . plantuml-mode))
  :config
  (setq plantuml-indent-level 2)
  (setq plantuml-output-type "png")
  (setq plantuml-exec-mode 'executable)
  (setq plantuml-jar-path "/usr/share/plantuml/plantuml.jar"))

Telega.el

How to run on m1

(use-package telega
  :commands (telega)
  :custom
  (telega-use-docker nil)
  :defer t)

About

Vanila config

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published