nekifirus / .emacs.d

My emacs configuration

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Emacs Configuration

I started programming a lot in 2018. At March I started to feel delay between pressing keyboard buttons and seeing symbols at screen.

I switched my attention to old text editors and try Vim. I configured it for work but it was to hard to extend. And I try spacemacs. At summer this repository started. I felt that vanila Emacs is better.

Year later I read Mastering Emacs, switched of vim-bindings, and started to learn world of Emacs.

This repo started from this starter template and rewriten a lot of times. You can see old branches if you want to.

This is classic Emacs literal configuration. I’m tangling this file after changes.

I using this configuration with my nixos config and don’t need to install packages default way.

I add new packages to nixos config and configure it here. It can be strange a little, but it more reproducible. I’m updating packages versions when I really want to only.

Initial setup

Packages setup

In this section package system initialized only for use-package macro. Package archives disabled at all.

(require 'package)

;; optional. makes unpure packages archives unavailable
(setq package-archives nil)

(setq package-enable-at-startup nil)
(package-initialize)

(unless (package-installed-p 'use-package)
  (package-refresh-contents)
  (package-install 'use-package))
(require 'use-package)
(require 'use-package-ensure)
(setq use-package-always-ensure nil)

(put 'use-package 'lisp-indent-function 1)

(use-package use-package-core
  :custom
  (use-package-verbose t)
  (use-package-minimum-reported-time 0.005)
  (use-package-enable-imenu-support t))
(use-package diminish)

It helps to keep clean emacs config directory.

(use-package no-littering
  :ensure t
  :custom
  (no-littering-var-directory (expand-file-name "data/" user-emacs-directory)))

Custom

I don’t strong about this code. But I use it for a long.

(use-package custom
  :custom
  (custom-safe-themes t))

Emacs

This is configuration of emacs package itself.

(use-package emacs
  :init
  (put 'narrow-to-region 'disabled nil)
  (put 'downcase-region 'disabled nil)
  (fset 'x-popup-menu #'ignore)
  :custom
  (ring-bell-function 'ignore)
  (default-frame-alist '((menu-bar-lines 0)
                         (tool-bar-lines 0)
                         (vertical-scroll-bars)))
  (scroll-step 1)
  (inhibit-startup-screen t "Don't show splash screen")
  (use-dialog-box nil "Disable dialog boxes")
  (x-gtk-use-system-tooltips nil)
  (use-file-dialog nil)
  (enable-recursive-minibuffers t "Allow minibuffer commands in the minibuffer")
  (indent-tabs-mode nil "Spaces!")
  (tab-width 4)
  (debug-on-quit nil)
  (show-paren-delay 0.0)
  (auto-save-default nil)
  (create-lockfiles nil)
  (make-backup-files nil)
  :config
  (fset 'yes-or-no-p 'y-or-n-p)
  (global-set-key (kbd "M-o") 'other-window)
  (setq compilation-scroll-output 'first-error)
  (when (fboundp 'menu-bar-mode) (menu-bar-mode -1))
  (when (fboundp 'tool-bar-mode) (tool-bar-mode -1))
  (when (fboundp 'scroll-bar-mode) (scroll-bar-mode -1))
  (set-face-attribute 'default
                      nil
                      :font "Iosevka Light"
                      :height 150
                      )
  (when (fboundp 'set-fontset-font)
    (set-fontset-font "fontset-default" 'cyrillic
                      (font-spec :registry "iso10646-1" :script 'cyrillic))
    )
  (require 'ansi-color)
  (defun colorize-compilation-buffer ()
    (read-only-mode)
    (ansi-color-apply-on-region compilation-filter-start (point))
    (read-only-mode))
  (add-hook 'compilation-filter-hook 'colorize-compilation-buffer)
  (global-auto-revert-mode t)
  (show-paren-mode t)
  )

Emacs-server

This enables emacs as server. It very useful.

(use-package server
  :config
  (progn
    (defun server-enable ()
      (unless (server-running-p)
        (server-start)))
    (add-hook 'after-init-hook 'server-enable t)))

Time

Time settings. I think time in mode-line must be desabled at all. Will do it in next versions.

(use-package time
  :ensure nil
  :custom
  (display-time-default-load-average nil)
  (display-time-day-and-date nil)
  (display-time-24hr-format nil)
  :config
  (display-time-mode nil))

Themes

Last time I work a lot outside and like Leuven theme. In a dark tomb groovbox is the best.

(use-package leuven-theme
  :init (load-theme 'leuven t))

Useful packages

I’m using this package for a long. It’s simple.

(use-package mood-line
  :custom
  (mood-line-show-cursor-point t)
  :custom-face
  (mode-line ((t (:inherit default (:box (:line-width -1 :style released-button))))))
  :hook
  (after-init . mood-line-mode))

All the icons

All the icons packages. With font in system it shows icons somewhere.

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

(use-package all-the-icons-ivy
  :after ivy projectile
  :config (all-the-icons-ivy-setup))

I think this package must be enabled by default. Really useful. It helps to remember keychords.

(use-package which-key
  :diminish which-key-mode
  :config
  (setq which-key-sort-order #'which-key-prefix-then-key-order
        which-key-sort-uppercase-first nil
        which-key-add-column-padding 1
        which-key-max-display-columns nil
        which-key-min-display-lines 5)
  (which-key-mode))

Completion frontend for Emacs. The best for me yet.

(use-package ivy
  :diminish (ivy-mode . "")
  :demand t
  :config
  (ivy-mode 1)
  ;; add ‘recentf-mode’ and bookmarks to ‘ivy-switch-buffer’.
  (setq ivy-use-virtual-buffers t)
  ;; number of result lines to display
  (setq ivy-height 10))

Various completion functions using Ivy

(use-package counsel
  :diminish counsel-mode
  :bind
  (([remap menu-bar-open] . counsel-tmm)
   ([remap insert-char] . counsel-unicode-char)
   :map mode-specific-map
   :prefix-map counsel-prefix-map
   :prefix "c"
   ("a" . counsel-apropos)
   ("b" . counsel-bookmark)
   ("B" . counsel-bookmarked-directory)
   ("c" . counsel-org-capture)
   ("d" . counsel-dired-jump)
   ("f" . counsel-file-jump)
   ("F" . counsel-faces)
   ("g" . counsel-org-goto)
   ("h" . counsel-command-history)
   ("H" . counsel-minibuffer-history)
   ("i" . counsel-imenu)
   ("j" . counsel-find-symbol)
   ("l" . counsel-locate)
   ("L" . counsel-find-library)
   ("m" . counsel-mark-ring)
   ("o" . counsel-outline)
   ("O" . counsel-find-file-extern)
   ("p" . counsel-package)
   ("r" . counsel-recentf)
   ("s g" . counsel-grep)
   ("s r" . counsel-rg)
   ("s s" . counsel-ag)
   ("t" . counsel-org-tag)
   ("v" . counsel-set-variable)
   ("w" . counsel-wmctrl)
   :map help-map
   ("F" . counsel-describe-face))
  :init
  (counsel-mode))

(use-package counsel-projectile
  :after counsel projectile
  :config
  (counsel-projectile-mode))

Swiper

I replaced with it standart search-forward/backward

(use-package swiper
  :bind
  (([remap isearch-forward] . swiper-isearch)
   ([remap isearch-backward] . swiper-isearch-backward)
   )
  :commands (swiper-isearch swiper-isearch-backward swiper swiper-all))

ag

Fulltext search. I use it thousands time a day

(use-package ag
  :ensure-system-package (ag . silversearcher-ag)
  :custom
  (ag-highlight-search t "Highlight the current search term."))

winner

Good mode. It allows to switch through windows history.

(use-package winner
  :diminish winner-mode
  :init
  (winner-mode))

iBuffer

Sometimes useful to clean list of thousands buffers)

(use-package ibuffer
  :bind ("C-x C-b" . ibuffer))

(use-package ibuffer-vc
  :init
  :config
  (define-ibuffer-column icon
    (:name "Icon" :inline t)
    (all-the-icons-icon-for-mode 'major-mode))
  :custom
  (ibuffer-formats
   '((mark modified read-only vc-status-mini " "
           (name 18 18 :left :elide)
           " "
           (size 9 -1 :right)
           " "
           (mode 16 16 :left :elide)
           " "
           filename-and-process)) "include vc status info")
  :hook
  (ibuffer . (lambda ()
               (ibuffer-vc-set-filter-groups-by-vc-root)
               (unless (eq ibuffer-sorting-mode 'alphabetic)
                 (ibuffer-do-sort-by-alphabetic)))))

Reverse.im

Not working now. But when I used two languages for writing it helps a lot.

(use-package reverse-im
  :config
  (add-to-list 'reverse-im-modifiers 'super)
  (add-to-list 'reverse-im-input-methods "russian-computer")
  (reverse-im-mode t))

direnv

This is fantastic package. With nixos it allows to have specific environments and package versions for each project. I don’t have globally installed python or node.

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

epa

This thing helps with pgp encryption.

(use-package epa
  :init  (setq epg-gpg-home-directory "~/.gnupg/")
  :custom (epa-keyserver "keys.openpgp.org"))

pdf-tools

Only used for viewing pdf

(use-package pdf-tools
  :config
  (require 'pdf-tools)
  (require 'pdf-view)
  (require 'pdf-misc)
  (require 'pdf-occur)
  (require 'pdf-util)
  (require 'pdf-annot)
  (require 'pdf-info)
  (require 'pdf-isearch)
  (require 'pdf-history)
  (require 'pdf-links)
  (pdf-tools-install :no-query))

go-translate

Cool thing. I used google-translate package, but it’s slow. This thing works very fast.

(use-package go-translate
  :custom
  (gts-translate-list '(("ru" "en") ("en" "ru") ("tr" "en")))
  (gts-default-translator (gts-translator
                           :picker (gts-prompt-picker)
                           :engines (list (gts-bing-engine) (gts-google-engine))
                           :render (gts-buffer-render)))
  :bind (("C-c g t" . gts-do-translate)))

flyspell

I need to check English spelling.

I read in comments on grishaev.me that ispell can check 2 languages at once. But I don’t have dictonaries yet. (setq ispell-dictionary “ru_RU_yo,en_GB”)

(use-package flyspell
  :defer t
  :diminish flyspell-mode
  :hook ((prog-mode . flyspell-prog-mode)
         (message-mode . flyspell-mode)
         (text-mode . flyspell-mode)
         (org-mode . flyspell-mode)))

EWW Emacs Web Browser

I read web with Emacs often. EWW helps me a lot. I found this guy and took part of configuration.

(use-package eww
  :commands eww eww-follow-link eww-search-words
  :init
  (setq browse-url-browser-function 'browse-url-default-browser)
  (setq eww-search-prefix "http://www.google.com/search?q=")

  (defun eww-wiki (text)
    "Function used to search wikipedia for the given text."
    (interactive (list (read-string "Wiki for: ")))
    (eww (format "https://en.m.wikipedia.org/wiki/Special:Search?search=%s"
                 (url-encode-url text))))

  :bind (("C-c w w" . eww)
         ("C-c w i" . eww-wiki)
         ("C-c w s" . eww-search-words)
         ("C-c w l" . eww-follow-link)))

Clojure

clojure-mode

Set align style.

(use-package clojure-mode
  :custom (clojure-indent-style 'align-arguments)
  :hook ((clojure-mode . clj-refactor-mode)
         (clojure-mode . subword-mode)))

cider

(use-package cider)

paredit

(use-package paredit
  :hook ((clojure-mode . paredit-mode)
         (clojurescript-mode . paredit-mode)
         (cider-mode . paredit-mode)
         (emacs-lisp-mode . paredit-mode)))

aggressive-indent

(use-package aggressive-indent
  :hook ((clojure-mode . aggressive-indent-mode)
         (clojurescript-mode . aggressive-indent-mode)
         (cider-mode . aggressive-indent-mode)
         (emacs-lisp-mode . aggressive-indent-mode)))

flycheck-kondo

(use-package flycheck-clj-kondo)

;; then install the checker as soon as `clojure-mode' is loaded
(use-package clojure-mode
  :config
  (require 'flycheck-clj-kondo))

Org

(use-package org
  :custom
  (org-default-notes-file "~/org/org-roam/daily/inbox.org.gpg") ; default refile file
  (org-agenda-span 'day)             ; start in day view default
  (org-agenda-files '("~/org/org-roam/daily"))
  (org-refile-targets '((nil :maxlevel . 3) (org-agenda-files :maxlevel . 3))) ; where refile to
  (org-refile-use-outline-path 'file)
  (org-outline-path-complete-in-steps nil)
  (org-todo-keywords '((sequence "TODO(t)" "NEXT(n)" "WAITING(w)" "|" "DONE(d)" "CANCELLED(c)" "PHONE")))
  (org-use-fast-todo-selection t)
  (org-tags-exclude-from-inheritance '("project"))
  (org-capture-templates
   (quote (("t" "todo" entry (file "~/org/org-roam/daily/inbox.org.gpg")
            "* TODO %?\n%U\n%a\n%i" :clock-in t :clock-resume t)
           ("n" "note" entry (file "~/org/org-roam/daily/inbox.org.gpg")
            "* %? :NOTE:\n%U\n%a\n%i" :clock-in t :clock-resume t)
           ("r" "respond" entry (file "~/org/org-roam/daily/inbox.org.gpg")
            "* TODO Respond to %:from on %:subject\nSCHEDULED: %t\n%U\n%a\n" :clock-in t :clock-resume t :immediate-finish t)
           ("w" "From web" entry (file+headline "~/org/org-roam/daily/inbox.org.gpg" "From web")
            "* %? %:annotation\n%U\n#+BEGIN_QUOTE\n%i\n[[%:link][Source]]\n#+END_QUOTE\n\n")
           ("W" "Link" entry (file+headline "~/org/org-roam/daily/inbox.org.gpg" "Links")
            "* %? %:annotation\n%U\n%:annotation")
           ("c" "Current clocked" entry (clock)
            "* %:annotation\n\n#+BEGIN_QUOTE\n%i\n[[%:link][Source]]\n#+END_QUOTE\n\n" :immediate-finish t)
           ("C" "Current clocked link" entry (clock)
            "* %:annotation\n" :immediate-finish t)
           ("p" "Phone call" entry (file "~/org/org-roam/daily/inbox.org.gpg")
            "* PHONE %? :PHONE:\n%U" :clock-in t :clock-resume t))))
  (org-agenda-custom-commands '(("n" . "My commands")           ; prefix discriber
                                ("np" "Projects" tags "project" ((org-agenda-overriding-header "Move it forward!")))
                                ("nn" "Next" todo "NEXT" ((org-agenda-overriding-header "Do it now!")))
                                ("nw" "Waiting "todo "WAITING" ((org-agenda-overriding-header "Still waited?")))
                                ("nd" "Done" todo "DONE" ((org-agenda-overriding-header "Good work!")))
                                ("nc" "Canceled" todo "CANCELLED" ((org-agenda-overriding-header "Ne progoddilos.")))
                                ("ns" "Planned" tags "planned" ((org-agenda-overriding-header "Review it.")))
                                ("nh" "Habbits" search "habit" ((org-agenda-overriding-header "Review it.")))
                                ("nP" "Problems" tags "problem" ((org-agenda-overriding-header "Solve it.")))
                                ("nG" "Goals" tags "goal" ((org-agenda-overriding-header "Achive it.")))))
  (org-clock-history-length 23) ;; Show lot of clocking history so it's easy to pick items off the C-F11 list
  (org-clock-in-resume t) ;; Resume clocking task on clock-in if the clock is open
  (org-clock-into-drawer t) ;; Save clock data and state changes and notes in the LOGBOOK drawer
  (org-clock-out-remove-zero-time-clocks t) ;; removes clocked tasks with 0:00 duration
  (org-clock-out-when-done t) ;; Clock out when moving task to a done state
  (org-clock-persist t) ;; Save the running clock and all clock history when exiting Emacs, load it on startup
  (org-clock-persist-query-resume nil) ;; Do not prompt to resume an active clock
  (org-clock-auto-clock-resolution (quote when-no-clock-is-running)) ;; Enable auto clock resolution for finding open clocks
  (org-clock-report-include-clocking-task t) ;; Include current clocking task in clock reports
  (org-startup-indented t) ;; Startup indented
  (org-log-done t) ;; Log when I've done tasks
  (org-confirm-babel-evaluate nil) ;; I've tired to say yest 100500 times a day
  (org-fontify-done-headline t)
  (org-fontify-whole-heading-line t)
  (org-fontify-quote-and-verse-blocks t)
  (org-image-actual-width '(700)) ;; Set image width to 700
  (org-src-tab-acts-natively t) ;; indent in source blocks
  (org-export-with-sub-superscripts nil) ;; don't export <sub> tags
  :bind
  ("<f12>" . 'org-agenda)
  ("<f9> m" . 'mu4e)
  ("<f9> c" . 'org-roam-dailies-capture-today)
  ("<f9> w" . 'eww)
  ("<f11>" . 'org-clock-goto)
  ("C-<f11>" . 'org-clock-in)
  :config
  (org-clock-persistence-insinuate) ;; Resume clocking task when emacs is restarted
  (add-to-list 'org-modules 'ob-redis)
  (add-to-list 'org-modules 'org-checklist)
  (add-to-list 'org-modules 'org-habit)
  (add-to-list 'org-modules 'org-protocol)

  ;; (require 'org-tempo)
  (org-babel-do-load-languages
   'org-babel-load-languages
   '(
     (sql . t)
     (python . t)
     (ditaa . t)
     (plantuml . t)
     (ledger . t)
     )))

toc-org

This is the package that automatically generates an up to date table of contents for us.

(use-package toc-org
  :after org
  :init (add-hook 'org-mode-hook #'toc-org-enable))

org-bullets

(use-package org-bullets
  :hook (org-mode . org-bullets-mode))

calendar

(use-package calendar
  :ensure nil
  :config
  (setq calendar-week-start-day 1))

plantuml

(use-package plantuml-mode
  :custom
  (org-plantuml-jar-path "~/.emacs.d/plantuml.jar")
  (org-ditaa-jar-path "~/.emacs.d/ditaa.jar")
  :mode "\\.plantuml\\'")

org-roam

org-roam

(use-package org-roam
  :ensure t
  :custom
  (org-roam-v2-ack t)
  (org-roam-directory "~/org/org-roam/")
  (org-roam-dailies-directory "~/org/org-roam/daily/")
  (org-roam-completion-everywhere t)
  (org-roam-dailies-capture-templates
   '(("d" "default" entry
      "* %<%H:%M> \n%U\n%a\n%i %?"
      :target (file+head "%<%Y-%m-%d>.org"
                         "#+title: %<%Y-%m-%d>\n")
      :clock-in t :clock-resume t)
     ))

  :bind (("C-c n l" . org-roam-buffer-toggle)
         ("C-c n f" . org-roam-node-find)
         ("C-c n g" . org-roam-graph)
         ("C-c n i" . org-roam-node-insert)
         ("C-c n m" . org-id-get-create)
         ("C-c n w" . org-roam-refile)
         ;; Dailies
         ("C-c n j" . org-roam-dailies-capture-today)
         ("C-c n t" . org-roam-dailies-goto-today)
         ("C-c n y" . org-roam-dailies-goto-yesterday)
         ("C-c n n" . org-roam-dailies-goto-previous-note)
         ("C-c n p" . org-roam-dailies-goto-next-note))
  :config
  (org-roam-setup)
  (org-roam-db-autosync-mode)
  ;; If using org-roam-protocol
  ;; (require 'org-roam-protocol)
  )

org-mime

(use-package org-mime
  :after (org mu4e)
  :bind ((:map message-mode-map
               ("C-c M-o" . org-mime-htmlize))
         (:map org-mode-map
               ("C-c M-o" . org-mime-org-buffer-htmlize)))
  )

Email

(use-package mu4e
  :ensure-system-package mu
  :custom
  (mail-user-agent 'mu4e-user-agent)
  (mu4e-get-mail-command "mbsync -a")
  (mu4e-maildir "~/Maildir")
  ;; Don't save message to Sent Messages, Gmail/IMAP takes care of this
  ;; Override in context switching for other type of mailboxes
  (mu4e-sent-messages-behavior 'delete)
  ;; This fixes the error 'mbsync error: UID is x beyond highest assigned UID x'
  (mu4e-change-filenames-when-moving t)
  ;; This helps when using a dark theme (shr)
  (shr-color-visible-luminance-min 80)
  (mu4e-update-interval nil)
  (mu4e-headers-fields 
   '((:human-date . 12)
     (:flags . 6)
     (:mailing-list . 10)
     (:from . 22)
     (:thread-subject))) ;; add thread-subject
  ;; (mu4e-index-cleanup nil) ;; faster
  ;; (mu4e-index-lazy-check t)
  ;; index ??
  (mu4e-maildir-shortcuts
   '( (:maildir "/nekifirus/Inbox"  :key ?g)
      (:maildir "/nekifirus-yandex/Inbox"  :key ?y)
      (:maildir "/nekifirus/[Gmail]/All Mail"  :key ?G :hide t)
      ))
  (mu4e-bookmarks
   '((:name "Starred" :key ?s :query "flag:flagged")
     (:name "Unread messages" :query "flag:unread AND NOT flag:trashed" :key ?u)
     (:name "Today's messages" :query "date:today..now" :key ?t)
     (:name "Last 7 days" :query "date:7d..now" :hide-unread t :key ?w)
     ))
  (mu4e-compose-dont-reply-to-self t)
  (mu4e-use-fancy-chars t) 
  (mu4e-view-show-addresses t)
  (mu4e-view-show-images t)
  (mu4e-view-prefer-html t)
  (mu4e-view-show-images t)
  (message-kill-buffer-on-exit t)
  (mu4e-enable-mode-line t)
  (mu4e-enable-notifications t)
  (sendmail-program "msmtp")
  (message-sendmail-f-is-evil t)
  (message-sendmail-extra-arguments '("--read-envelope-from"))
  (message-send-mail-function 'message-send-mail-with-sendmail)
  (user-full-name "Nikita Mistiukov" )
  (mu4e-context-policy 'pick-first)
  (mu4e-contexts
   `( ,(make-mu4e-context
        :name "Gmail"
        :enter-func (lambda () (mu4e-message "Entering gmail context"))
        :leave-func (lambda () (mu4e-message "Leaving gmail context"))
        :match-func (lambda (msg)
                      (when msg
                        (mu4e-message-contact-field-matches msg :to "nekifirus@gmail.com")))
        :vars '( ( user-mail-address	    . "nekifirus@gmail.com"  )
                 (mu4e-sent-folder          . "/nekifirus/[Gmail]/Sent Mail")
                 (mu4e-drafts-folder        . "/nekifirus/[Gmail]/Drafts")
                 (mu4e-trash-folder         . "/nekifirus/[Gmail]/Trash")
                 (smtpmail-smtp-server      . "smtp.gmail.com")
                 (smtpmail-smtp-service     . 587)))
      ,(make-mu4e-context
        :name "Yandex"
        :enter-func (lambda () (mu4e-message "Entering yandex context"))
        :leave-func (lambda () (mu4e-message "Leaving yandex context"))
        :match-func (lambda (msg)
                      (when msg
                        (mu4e-message-contact-field-matches msg :to "nekifirus@yandex.ru")))
        :vars '( ( user-mail-address	    . "nekifirus@yandex.ru"  )
                 (mu4e-sent-folder          . "/nekifirus-yandex/Sent")
                 (mu4e-drafts-folder        . "/nekifirus-yandex/Drafts")
                 (mu4e-trash-folder         . "/nekifirus-yandex/Trash")
                 (smtpmail-smtp-server      . "smtp.yandex.ru")
                 (smtpmail-smtp-service     . 465)))
      )))

Telega

(use-package telega
  :custom
  (telega-use-docker t)
  :config
  (telega-notifications-mode 1)
  (telega-mode-line-mode 1)
  (telega-appindicator-mode 1)
  (define-key global-map (kbd "C-c t") telega-prefix-map)
  :bind 
  :commands (telega))

Editing stuff

copy as format

(use-package copy-as-format
  :custom
  (copy-as-format-default "slack")
  :bind
  (:map mode-specific-map
        :prefix-map copy-as-format-prefix-map
        :prefix "f"
        ("f" . copy-as-format)
        ("a" . copy-as-format-asciidoc)
        ("b" . copy-as-format-bitbucket)
        ("d" . copy-as-format-disqus)
        ("g" . copy-as-format-github)
        ("l" . copy-as-format-gitlab)
        ("c" . copy-as-format-hipchat)
        ("h" . copy-as-format-html)
        ("j" . copy-as-format-jira)
        ("m" . copy-as-format-markdown)
        ("w" . copy-as-format-mediawiki)
        ("o" . copy-as-format-org-mode)
        ("p" . copy-as-format-pod)
        ("r" . copy-as-format-rst)
        ("s" . copy-as-format-slack)))

Whole line or region

(use-package whole-line-or-region
  :diminish whole-line-or-region-local-mode
  :config (whole-line-or-region-global-mode))

multiple-cursors

(use-package multiple-cursors
  :config
  (global-set-key (kbd "C-S-c C-S-c") 'mc/edit-lines)
  (global-set-key (kbd "C-S-w C-S-w") 'mc/mark-all-dwim)
  (global-set-key (kbd "C-S-e C-S-e") 'mc/edit-ends-of-lines)
  (global-set-key (kbd "C->") 'mc/mark-next-like-this)
  (global-set-key (kbd "C-<") 'mc/mark-previous-like-this)
  (global-set-key (kbd "C-c C-<") 'mc/mark-all-like-this))

smartparens

(use-package smartparens
  :demand t
  :diminish smartparens-mode
  :config
  (require 'smartparens-config)
  (smartparens-global-mode))

Rainbow modes

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

(use-package rainbow-identifiers
  :hook (prog-mode . rainbow-identifiers-mode))

(use-package rainbow-mode
  :diminish rainbow-mode
  :hook prog-mode)

marks to navigate

Good thing from this article

(defun push-mark-no-activate ()
  "Pushes `point' to `mark-ring' and does not activate the region
Equivalent to \\[set-mark-command] when \\[transient-mark-mode] is disabled"
  (interactive)
  (push-mark (point) t nil)
  (message "Pushed mark to ring"))
(global-set-key (kbd "C-`") 'push-mark-no-activate)

(defun jump-to-mark ()
  "Jumps to the local mark, respecting the `mark-ring' order.
This is the same as using \\[set-mark-command] with the prefix argument."
  (interactive)
  (set-mark-command 1))
(global-set-key (kbd "M-`") 'counsel-mark-ring)

smart-comment

(use-package smart-comment
  :bind ("M-;" . smart-comment))

poporg

(use-package poporg
  :bind (("C-c C-/" . poporg-dwim)))

avy

Projectile

(use-package projectile
  :diminish projectile-mode
  :demand t
  :config
  (define-key projectile-mode-map (kbd "C-c p") 'projectile-command-map)
  (projectile-mode +1)
  :custom
  (projectile-completion-system 'ivy))

Magit

(use-package magit
  :commands (magit-status magit-blame-addition magit-log-buffer-file magit-log-all)
  :bind (("C-x g" . magit-status)))

(use-package gitignore-mode
  :mode "/\\.gitignore$")

(use-package diff-hl
  ;; Integrate with Magit and highlight changed files in the fringe of dired
  :hook ((magit-post-refresh . diff-hl-magit-post-refresh))
  :config (global-diff-hl-mode 1))

programming

company

(use-package company
  :diminish company-mode
  :custom
  (company-tooltip-limit 10)
  (company-idle-delay 0.2)
  (company-echo-delay 0.1)
  (company-dabbrev-ignore-case nil)
  (company-dabbrev-downcase nil)
  ;; (company-minimum-prefix-length 3)
  ;; (company-require-match nil)
  (company-selection-wrap-around t)
  (company-tooltip-align-annotations t)
  :config
  (global-company-mode))

(use-package company-box
  :diminish company-box-mode
  :hook (company-mode . company-box-mode))

nix-mode

(use-package nix-mode)

flycheck

(use-package flycheck
  :diminish flycheck-mode
  :config (global-flycheck-mode))

yasnippet

(use-package yasnippet
  :diminish yas-minor-mode
  :config
  (yas-global-mode 1))
(use-package yasnippet-snippets)

lsp

(use-package lsp-mode
  :custom
  (lsp-keymap-prefix "C-c l")
  (gc-cons-threshold 100000000)
  (read-process-output-max (* 3 1024 1024))
  (lsp-idle-delay 0.500)

  :hook (
         (vue-mode . lsp)
         (nix-mode . lsp)
         (go-mode . lsp)
         (typescript-mode . lsp)
         (js-mode . lsp))
  :commands lsp)

(use-package lsp-ui :commands lsp-ui-mode)

python

(use-package  python
  :mode ("\\.py'" . python-mode)
  :hook ((python-mode . lsp)
         (before-save-hook . lsp-format-buffer)
         )
  :config
  (setq-default py-separator-char 47)   ;; Use spaces instead tab
  (setq-default python-indent-offset 4) ;; 4 spaces instead 2 for python-mode
  (setq python-shell-completion-native-enable nil) ;; solve warning in repl
  )

(use-package py-autopep8
  :ensure t
  :config (progn (add-hook 'python-mode-hook 'py-autopep8-enable-on-save)))

;;
;; (use-package elpy
;;   :ensure t
;;   :config (progn (add-hook 'python-mode-hook 'elpy-enable)
;;                  (add-hook 'elpy-mode-hook (lambda () (highlight-indentation-mode -1)))))

;; (use-package py-isort
;;    :init
;;    (add-hook 'before-save-hook #'py-isort-before-save))

js

(use-package vue-mode
  :init
  (add-hook 'vue-mode-hook (lambda () (setq syntax-ppss-table nil)))
  :mode "\\.vue\\'"
  :config
  (setq js-indent-level 2)
  :bind
  ("C-c C-C" . vue-mode-edit-indirect-at-point))

(use-package css-mode
  :mode "\\.css\\'"
  :config
  (setq css-indent-level 4)
  (setq css-indent-offset 4))
(use-package web-mode
  :ensure t
  :mode (("\\.tsx" .  web-mode)
         ("\\.svelte" .  web-mode)
         ("\\.html$" .  web-mode))
  :hook (web-mode . lsp-mode))

GO

(use-package go-mode :after lsp-mode)

Protobuf

(use-package protobuf-mode
  :mode ("\\.proto\\'" . protobuf-mode))

elixir

other languages

python lsp

[2020-10-10 Sat 13:24]

(use-package lsp-python-ms :hook (python-mode . (lambda () (require ‘lsp-python-ms) (lsp))) :init (setq lsp-python-ms-executable (executable-find “python-language-server”)))

my functions

org-insert-screenshot

(defun choose-file (dir)
  (let* ((files (->> (directory-files-and-attributes dir nil nil)
                     (--filter (file-regular-p (expand-file-name (car it) dir)))
                     (--sort (not (time-less-p (nth 6 it) (nth 6 other))))))
         (chosen (completing-read "Choose file: " files))
         ) (concat dir chosen)))

(defun nm/org-insert-screenshot ()
  "Insert org-link at point with choosen screenshot form Screenshots folder."
  (interactive)
  (insert (concat "[[" (choose-file "~/Pictures/Screenshots/") "]]\n\n"))
  (org-redisplay-inline-images))

nm/mail-subtree

(defun nm/mail-subtree ()
  "Compose email with subtree heading as subject and whole subtree as html-body"
  (interactive)
  (save-excursion
    (org-copy-subtree)
    (mu4e-compose-new)
    (mu4e-compose-goto-bottom)
    (org-paste-subtree)
    (org-toggle-heading)
    (back-to-indentation)
    (kill-line)
    (org-mime-htmlize)
    (message-goto-subject)
    (yank)
    (message-goto-to)))

nm/refile-to-roam

I’ve not found a good way to use standart org-refile for moving org subtrees to org-roam nodes. But I need it.

What is refile? It gets subtree from one place and pastes it to another.

(defun nm/refile-to-roam ()
  "Moves current org subtree to org-roam node"
  (interactive)
  (save-excursion
    (org-cut-subtree)
    (org-roam-node-find t)
    (end-of-buffer)
    (org-yank)))

ledger

(use-package ledger-mode
  :mode ("\\.dat\\'"
         "\\.ledger\\'")
  :custom
  (ledger-clear-whole-transactions t)
  (ledger-reports '(("bal" "%(binary) -f %(ledger-file) bal")
                    ("bal$" "%(binary) -X $ -f %(ledger-file) bal")
                    ("Assets" "%(binary) -f %(ledger-file) bal ^Assets")
                    ("Budget" "%(binary) -X $ -f %(ledger-file) bal ^Budget")
                    ("Cash flow" "%(binary) -X $ -f %(ledger-file) bal ^income ^expenses")
                    ("Net worth" "%(binary) -X $ -f %(ledger-file) bal ^assets ^liabilities")
                    ("reg" "%(binary) -f %(ledger-file) reg")
                    ("payee" "%(binary) -f %(ledger-file) reg @%(payee)")
                    ("account" "%(binary) -f %(ledger-file) reg %(account)")))
  )

(use-package flycheck-ledger :after ledger-mode)

About

My emacs configuration