Emacs Literate Configuration

Table of Contents

1. My dots files   TOC_3_org QUOTE

1.1. config.el

;;; $DOOMDIR/config.el -*- lexical-binding: t; -*-
(setq! vermin/tangle-dir "~/.doom.d/tangle")
(load! "start.el" vermin/tangle-dir)
(load! "middleware.el" vermin/tangle-dir)
(load! "end.el" vermin/tangle-dir)

1.2. start.el

(doom-load-envvars-file "~/.doom.d/myenv")
(global-auto-revert-mode t)
(load! "user.el" "~/.doom.d/tangle")

1.3. middleware.el

(load! "org.el" "~/.doom.d/tangle")
(load! "lisp.el" "~/.doom.d/tangle")
(load! "academic.el" "~/.doom.d/tangle")
(load! "vermin-capture.el" "~/.doom.d/tangle")


(load! "bindings.el" "~/.doom.d/tangle")
(load! "custom.el" "~/.doom.d/tangle")

1.4. end.el

(load! "theme.el" "~/.doom.d/tangle")

(setq! org-journal-carryover-items "TODO=\"TODO\"|TODO=\"STARTED\"|TODO=\"IDEA\"")
;; (let ((f "~/org/bookmark/save"))
;;   (cond ((f-exists? f ) (bookmark-load f 1 ))
;;         (t nil)))
(org-babel-do-load-languages 'org-babel-load-languages
                             '((http . t)
                               (jupyter . t)))

1.5. Init.el

;;; init.el -*- lexical-binding: t; -*-

;; This file controls what Doom modules are enabled and what order they load
;;; in. Remember to run 'doom sync' after modifying it!

;; NOTE Press 'SPC h d h' (or 'C-h d h' for non-vim users) to access Doom's
;;      documentation. There you'll find a link to Doom's Module Index where all
;;      of our modules are listed, including what flags they support.

;; NOTE Move your cursor over a module's name (or its flags) and press 'K' (or
;;      'C-c c k' for non-vim users) to view its documentation. This works on
;;      flags as well (those symbols that start with a plus).
;;
;;      Alternatively, press 'gd' (or 'C-c c d') on a module to browse its
;;      directory (for easy access to its source code).

(doom! :input
       ;;bidi              ; (tfel ot) thgir etirw uoy gnipleh
       ;;chinese
       ;;japanese
       ;;layout            ; auie,ctsrnm is the superior home row

       :completion
       ( company +childframe)           ; the ultimate code completion backend
       ;;helm              ; the *other* search engine for love and life
       ;;ido               ; the other *other* search engine...
       ;;ivy               ; a search engine for love and life
       (vertico      +icons)      ; the search engine of the future

       :ui
       ;;deft              ; notational velocity for Emacs
       doom              ; what makes DOOM look the way it does
       doom-dashboard    ; a nifty splash screen for Emacs
       doom-quit         ; DOOM quit-message prompts when you quit Emacs
       (emoji +unicode)  ; \360\237\231\202
       hl-todo           ; highlight TODO/FIXME/NOTE/DEPRECATED/HACK/REVIEW
       hydra
       ;;indent-guides     ; highlighted indent columns
       ;; (ligatures   +extra)        ; ligatures and symbols to make your code pretty again
       ;;minimap           ; show a map of the code on the side
       modeline          ; snazzy, Atom-inspired modeline, plus API
       nav-flash         ; blink cursor line after big motions
       ;;neotree           ; a project drawer, like NERDTree for vim
       ophints           ; highlight the region an operation acts on
       (popup +defaults)   ; tame sudden yet inevitable temporary windows
       ;;tabs              ; a tab bar for Emacs
       ;;treemacs          ; a project drawer, like neotree but cooler
       unicode           ; extended unicode support for various languages
       ;; vc-gutter         ; vcs diff in the fringe
       ;; vi-tilde-fringe   ; fringe tildes to mark beyond EOB
       window-select     ; visually switch windows
       workspaces        ; tab emulation, persistence & separate workspaces
       ;;zen               ; distraction-free coding or writing

       :editor
       (evil +everywhere); come to the dark side, we have cookies
        file-templates    ; auto-snippets for empty files
       fold              ; (nigh) universal code folding
       (format +onsave)  ; automated prettiness
       ;;god               ; run Emacs commands without modifier keys
       ;;lispy             ; vim for lisp, for people who don't like vim
       ;;multiple-cursors  ; editing in many places at once
       ;;objed             ; text object editing for the innocent
       ;;parinfer          ; turn lisp into python, sort of
       ;;rotate-text       ; cycle region at point between text candidates
       snippets          ; my elves. They type so I don't have to
       word-wrap         ; soft wrapping with language-aware indent

       :emacs
       dired             ; making dired pretty [functional]
       electric          ; smarter, keyword-based electric-indent
       (ibuffer  +icons )        ; interactive buffer management
       undo              ; persistent, smarter undo for your inevitable mistakes
       vc                ; version-control and Emacs, sitting in a tree

       :term
       ;;eshell            ; the elisp shell that works everywhere
       shell             ; simple shell REPL for Emacs
       term              ; basic terminal emulator for Emacs
       vterm             ; the best terminal emulation in Emacs

       :checkers
       (syntax    +childframe)           ; tasing you for every semicolon you forget
       ;;(spell +flyspell) ; tasing you for misspelling mispelling
       ;;grammar           ; tasing grammar mistake every you make

       :tools
       ;;ansible
       ;;biblio            ; Writes a PhD for you (citation needed)
       ;;debugger          ; FIXME stepping through code, to help you add bugs
       ;;direnv
       ;;docker
       ;;editorconfig      ; let someone else argue about tabs vs spaces
       ;;ein               ; tame Jupyter notebooks with emacs
       (eval +overlay)     ; run code, run (also, repls)
       ;;gist              ; interacting with github gists
       lookup              ; navigate your code and its documentation
       lsp               ; M-x vscode
       magit             ; a git porcelain for Emacs
       ;;make              ; run make tasks from Emacs
       ;;pass              ; password manager for nerds
       ;;pdf               ; pdf enhancements
       ;;prodigy           ; FIXME managing external services & code builders
       rgb               ; creating color strings
       ;;taskrunner        ; taskrunner for all your projects
       ;;terraform         ; infrastructure as code
       ;;tmux              ; an API for interacting with tmux
       ;;tree-sitter       ; syntax and parsing, sitting in a tree...
       ;;upload            ; map local to remote projects via ssh/ftp

       :os
       (:if IS-MAC macos)  ; improve compatibility with macOS
       (tty   +osc)              ; improve the terminal Emacs experience

       :lang
       ;;agda              ; types of types of types of types...
       ;;beancount         ; mind the GAAP
       ;;(cc +lsp)         ; C > C++ == 1
       (clojure +lsp )         ; java with a lisp
       ;;common-lisp       ; if you've seen one lisp, you've seen them all
       ;;coq               ; proofs-as-programs
       ;;crystal           ; ruby at the speed of c
       ;;csharp            ; unity, .NET, and mono shenanigans
       ;;data              ; config/data formats
       ;;(dart +flutter)   ; paint ui and not much else
       ;;dhall
       elixir            ; erlang done right
       ;;elm               ; care for a cup of TEA?
       emacs-lisp        ; drown in parentheses
       ;;erlang            ; an elegant language for a more civilized age
       ess               ; emacs speaks statistics
       ;;factor
       ;;faust             ; dsp, but you get to keep your soul
       ;;fortran           ; in FORTRAN, GOD is REAL (unless declared INTEGER)
       ;;fsharp            ; ML stands for Microsoft's Language
       ;;fstar             ; (dependent) types and (monadic) effects and Z3
       ;;gdscript          ; the language you waited for
       (go +lsp)         ; the hipster dialect
       (graphql +lsp)    ; Give queries a REST
       ;;(haskell +lsp)    ; a language that's lazier than I am
       ;;hy                ; readability of scheme w/ speed of python
       ;;idris             ; a language you can depend on
       json              ; At least it ain't XML
       (java +lsp)       ; the poster child for carpal tunnel syndrome
       ( javascript +lsp)        ; all(hope(abandon(ye(who(enter(here))))))
       ;;julia             ; a better, faster MATLAB
       ;;kotlin            ; a better, slicker Java(Script)
       latex             ; writing papers in Emacs has never been so fun
       ;;lean              ; for folks with too much to prove
       ;;ledger            ; be audit you can be
       lua               ; one-based indices? one-based indices
       markdown          ; writing docs for people to ignore
       ;;nim               ; python + lisp at the speed of c
       ;;nix               ; I hereby declare "nix geht mehr!"
       ;;ocaml             ; an objective camel
       ( org
         +dragndrop
         +journal
         +hugo)               ; organize your plain life in plain text
       ;;php               ; perl's insecure younger brother
       ;;plantuml          ; diagrams for confusing people more
       ;;purescript        ; javascript, but functional
       ( python +lsp +pyright)            ; beautiful is better than ugly
       ;;qt                ; the 'cutest' gui framework ever
       (racket   )          ; a DSL for DSLs
       ;;raku              ; the artist formerly known as perl6
       rest              ; Emacs as a REST client
       ;;rst               ; ReST in peace
       ;;(ruby +rails)     ; 1.step {|i| p "Ruby is #{i.even? ? 'love' : 'life'}"}
       ;;rust              ; Fe2O3.unwrap().unwrap().unwrap().unwrap()
       ;;scala             ; java, but good
       ;;(scheme +guile)   ; a fully conniving family of lisps
       (sh +lsp +fish)                ; she sells {ba,z,fi}sh shells on the C xor
       ;;sml
       ;;solidity          ; do you need a blockchain? No.
       ;;swift             ; who asked for emoji variables?
       ;;terra             ; Earth and Moon in alignment for performance.
       web               ; the tubes
       ;;yaml              ; JSON, but readable
       ;;zig               ; C, but simpler

       :email
       ;;(mu4e +org +gmail)
       ;;notmuch
       ;;(wanderlust +gmail)

       :app
       ;;calendar
       emms
       everywhere        ; *leave* Emacs!? You must be joking
       ;;irc               ; how neckbeards socialize
       (rss +org)        ; emacs as an RSS reader
       twitter           ; twitter client https://twitter.com/vnought

       :config
       ;; literate
       (default +bindings +smartparens))

1.6. Package.el

;; -*- no-byte-compile: t; -*-
;;; TODO $DOOMDIR/packages.el

;; To install a package with Doom you must declare them here and run 'doom sync'
;; on the command line, then restart Emacs for the changes to take effect -- or
;; use 'M-x doom/reload'.


;;;
;; To install SOME-PACKAGE from MELPA, ELPA or emacsmirror:
;; (package! some-package)

;; To install a package directly from a remote git repo, you must specify a
;; `:recipe'. You'll find documentation on what `:recipe' accepts here:
;; https://github.com/raxod502/straight.el#the-recipe-format
;; (package! another-package
;;  :recipe (:host github :repo "username/repo"))

;; If the package you are trying to install does not contain a PACKAGENAME.el
;; file, or is located in a subdirectory of the repo, you'll need to specify
;; `:files' in the `:recipe':
;; (package! this-package
;;  :recipe (:host github :repo "username/repo"
;;           :files ("some-file.el" "src/lisp/*.el")))

;; If you'd like to disable a package included with Doom, you can do so here
;; with the `:disable' property:
;; (package! builtin-package :disable t)

;; You can override the recipe of a built in package without having to specify
;; all the properties for `:recipe'. These will inherit the rest of its recipe
;; from Doom or MELPA/ELPA/Emacsmirror:
;; (package! builtin-package :recipe (:nonrecursive t))
;; (package! builtin-package-2 :recipe (:repo "myfork/package"))

;; Specify a `:branch' to install a package from a particular branch or tag.
;; This is required for some packages whose default branch isn't 'master' (which
;; our package manager can't deal with; see raxod502/straight.el#279)
;; (package! builtin-package :recipe (:branch "develop"))

;; Use `:pin' to specify a particular commit to install.
;; (package! builtin-package :pin "1a2b3c4d5e")


;; Doom's packages are pinned to a specific commit and updated from release to
;; release. The `unpin!' macro allows you to unpin single packages...
;; (unpin! pinned-package)
;; ...or multiple packages
;; (unpin! pinned-package another-pinned-package)
;; ...Or *all* packages (NOT RECOMMENDED; will likely break things)
;; (unpin! t)
;; (package! ox-pandoc
;;   :recipe (:host github :repo "kawabata/ox-pandoc"))

(package! key-chord
  :recipe (:host github :repo "emacsorphanage/key-chord"))

;; $DOOMDIR/packages.el
;; (package! org-pandoc-import
;;   :recipe (:host github
;;            :repo "tecosaur/org-pandoc-import"
;;            :files ("*.el" "filters" "preprocessors")))

;; (package! elisp-slime-nav
;;   :recipe (:host github
;;            :repo "purcell/elisp-slime-nav"
;;            ))

;; (package! imenu-list
;;   :recipe (:host github :repo "bmag/imenu-list"))


;; (require 'org-tempo)

(package! org-web-tools
  :recipe (:host github :repo "alphapapa/org-web-tools"))



(package! org-sticky-header
  :recipe (:host github :repo "alphapapa/org-sticky-header"))


(package! org-sidebar
  :recipe (:host github :repo "alphapapa/org-sidebar"))

(package! topsy
  :recipe (:host github :repo "alphapapa/topsy.el"))


(package! highlight-function-calls
  :recipe (:host github :repo "alphapapa/highlight-function-calls"))

;; (package! mosey.el
;;   :recipe (:host github :repo "alphapapa/mosey.el"))

(package! modus-themes
  :recipe (:host gitlab :repo "protesilaos/modus-themes"))

(package! nov
  :recipe (:host nil :type git
           :repo "https://depp.brause.cc/nov.el.git"))

(package! outshine)

(package! dired-narrow
  :disable t)

(package! websocket)


(package! org-roam-ui
  :recipe (:host github
           :repo "org-roam/org-roam-ui"
           :files ("*.el" "out")))

(package! yequake)

(package! ripgrep)

(package! elmacro)

(package! multi-vterm)
(package! vimrc-mode
  :recipe (:host github :repo "mcandre/vimrc-mode"))
(package! i3-config-mode
  :recipe (:host github :repo "Alexander-Miller/i3wm-Config-Mode"))
(package! ob-tmux
  :recipe (:host github :repo "ahendriksen/ob-tmux"))
(package! org-ref
  :recipe (:host github :repo "jkitchin/org-ref"))
(package! page-break-lines
  :recipe (:host github :repo "purcell/page-break-lines"))
(package! wolfram-mode
  :recipe (:host github :repo "kawabata/wolfram-mode"))
(package! citar
  :recipe (:host github :repo "bdarcus/citar"))
(package! org-ref)

(package! ob-clojurescript
  :recipe (:host github :repo "emacsmirror/ob-clojurescript"))

(package! zls
  :recipe (:host github :repo "zigtools/zls"))

(package! copilot
  :recipe (:host github
           :repo "zerolfx/copilot.el"
           :files ("*.el" "dist")))

(package! exec-path-from-shell
  :recipe (:host github :repo "purcell/exec-path-from-shell"))

(package! emacs-refactor
  :recipe (:host github :repo "mhayashi1120/Emacs-erefactor"))

(package! adoc-mode
  :recipe (:host github :repo "sensorflo/adoc-mode"))

(package! asciidoc
  :recipe (:host github :repo "metaperl/asciidoc-el"))

(package! ob-http
  :recipe (:host github :repo "zweifisch/ob-http"))
;; (package! zmq)

(package! jupyter
  :recipe (:host github :repo "nnicandro/emacs-jupyter"))

(package! ob-async
  :recipe (:host github :repo "astahlman/ob-async"))

;; (when IS-LINUX
;;   (package! eaf
;;     :recipe (:host github
;;              :repo "manateelazycat/emacs-application-framework"
;;              :files ("*"))))

(package! emr)


(package! semantic-refactor)

;; (package! tree-sitter)
;; (package! tree-sitter-langs)
;; (package! aweshell
;;   :disable t
;;   :recipe (:host github :repo "manateelazycat/aweshell"))

(package! org-yt
  :recipe (:host github :repo "tobiaszawada/org-yt"))

(package! orgtbl-aggregate
  :recipe (:host github :repo "tbanel/orgaggregate"))



(package! org-scrum)
(package! parse-csv)
(package! leetcode)
(package! polymode)
(package! poly-markdown)
(package! poly-org)
(package! edraw
  :recipe (:host github :repo "misohena/el-easydraw"))
(package! code-stats)
(package! valign)
(package! pollen-mode)
(package! otherweb
  :recipe (:host github :repo "nhannht/emacs-otherweb"))
(package! ssh-config-mode)
(package! xonsh-mode)
(package! yaml-mode)
(package! howdoyou
  :recipe (:host github :repo "thanhvg/emacs-howdoyou"))
(package! counsel)
(package! ob-mermaid
  :recipe (:host github
           :repo "arnm/ob-mermaid"))

1.7. External package

1.7.1. Academic.el

(use-package! citar
  :no-require :custom
  (org-cite-insert-processor 'citar)
  (org-cite-follow-processor 'citar)
  (org-cite-activate-processor 'citar)
  ;; optional: org-cite-insert is also bound to C-c C-x C-@
  (setq! citar-templates
         '((main . "${author editor:30}     ${date year issued:4}     ${title:48}")
           (suffix . "          ${=key= id:15}    ${=type=:12}    ${tags keywords:*}")
           (note . "#+title: Notes on ${author editor}, ${title}")))
  (setq! citar-symbols
         `((file ,(all-the-icons-faicon "file-o" :face 'all-the-icons-green
                                        :v-adjust -0.1)
                 . " ")
           (note ,(all-the-icons-material "speaker_notes" :face 'all-the-icons-blue
                                          :v-adjust -0.3)
                 . " ")
           (link ,(all-the-icons-octicon "link" :face 'all-the-icons-orange
                                         :v-adjust 0.01)
                 . " ")))
  (setq citar-symbol-separator "  "))

;; (setq! org-cite-csl-styles-dir "~/Zotero/styles")
;; (use-package! org-ref
;;   :after org
;;   :demand t ;; Ensure that it loads so that links work immediately.
;;   :config
;;   (setq! org-ref-default-bibliography '("~/.doom.d/references.bib")
;;         ;; org-ref-get-pdf-filename-function '
;;         bibtex-completion-pdf-field "file"
;;         org-ref-default-citation-link "parencite")
;;   (setq! bibtex-completion-bibliography '("references.bib") )
;;     )

1.7.2. other

(use-package! which-key
  :config (setq! which-key-popup-type
                 'minibuffer
                 which-key-min-display-lines
                 10
                 which-key-paging-prefixes
                 '("C-x")
                 which-key-paging-key
                 "<f5>"))

1.7.3. Vermin/capture

(defun vermin/org-factor-goto-file ()
  (interactive)
  (find-file (read-file-name "Project file name: " org-directory
                             nil nil nil))
  (goto-char (point-min)))

(let* ((note-dir "~/org-one"))
  (setq! vermin/custom-org-capture-template
         '(("m" "Capture link outside emacs "
            entry
            (file+headline (file-name-concat note-dir "NOTE.org")
                           "NOTE")
            "** %U %^g:content: \n#+name:%^{name}\n#+begin_src org \n %? \n#+end_src"
            :empty-lines-after 2
            :jump-to-captured t)
           ("l" "Capture link outside emacs "
            entry
            (file+headline (file-name-concat note-dir "LINK.org")
                           "LINK")
            "** %U %^g:link: \n#+name:%^{name}\n#+begin_quote  \n %? \n#+end_quote"
            :empty-lines-after 2)
           ("L" "Capture link inside emacs "
            entry
            (file+headline (file-name-concat note-dir "LINK.org")
                           "LINK")
            "** %U %^g:link: \n#+name:%^{name}\n#+begin_quote  \n %i \n#+end_quote"
            :empty-lines-after 2)
           ("C" "Capture code block inside emacs "
            entry
            (file+headline (file-name-concat note-dir "CODE.org")
                           "CODE")
            "** %U %^g:code: \n#+name:%^{name}\n#+begin_src %^{lang} :results value \n %i \n#+end_src"
            :empty-lines-after 2)
           ("c" "Capture code block outside emacs"
            entry
            (file+headline (file-name-concat note-dir "CODE.org")
                           "CODE")
            "** %U %^g:code:
 \n#+name:%^{name}\n#+begin_src
 %^{lang}
 :results value \n %? \n#+end_src"
            :empty-lines-after 2
            :jump-to-captured t
            :prepend t)
           ("t" "Personal todo"
            entry
            (file+headline +org-capture-todo-file "Inbox")
            "* [ ] %?\n%i\n%a"
            :prepend t)
           ("n" "Personal notes"
            entry
            (file+headline +org-capture-notes-file "Inbox")
            "* %u %?\n%i\n%a"
            :prepend t)
           ("j" "Journal"
            entry
            (file+olp+datetree +org-capture-journal-file)
            "* %U %?\n%i\n%a"
            :prepend t)
           ("p" "Templates for projects")
           ("pt" "Project-local todo"
            entry
            (file+headline +org-capture-project-todo-file
                           "Inbox")
            "* TODO %?\n%i\n%a"
            :prepend t)
           ("pn" "Project-local notes"
            entry
            (file+headline +org-capture-project-notes-file
                           "Inbox")
            "* %U %?\n%i\n%a"
            :prepend t)
           ("pc" "Project-local changelog"
            entry
            (file+headline +org-capture-project-changelog-file
                           "Unreleased")
            "* %U %?\n%i\n%a"
            :prepend t)
           ("o" "Centralized templates for projects")
           ("ot" "Project todo" entry #'+org-capture-central-project-todo-file
            "* TODO %?\n %i\n %a" :heading "Tasks"
            :prepend nil)
           ("on" "Project notes" entry #'+org-capture-central-project-notes-file
            "* %U %?\n %i\n %a" :heading "Notes"
            :prepend t)
           ("oc" "Project changelog" entry #'+org-capture-central-project-changelog-file
            "* %U %?\n %i\n %a" :heading "Changelog"
            :prepend t)
           )))





(defun vermin/org-download-capture (url)
  (interactive "P")
  (let* ((org-download-image-dir (expand-file-name "images"))
         (org-download-abbreviate-filename-function
          #'expand-file-name)
         (str (org-download-image url)))
    (sit-for 0.01)
    str))



(defun vermin/setup-org-capture-template ()
  "Clear doom built-in template and replace by own"
  (interactive)
  (let ((templates vermin/custom-org-capture-template))
    (setq! org-capture-templates
           '())
    (mapcar (lambda (x)
              (add-to-list 'org-capture-templates x))
            templates)))

(vermin/setup-org-capture-template)



(defun vermin/gui-get-selection ()
  (when-let ((selection (gui-get-selection 'PRIMARY 'UTF8_STRING)))
    (gui-backend-set-selection 'PRIMARY "")
    (insert selection)))


(use-package! org-capture
  ;; (add-hook! 'org-capture-mode-hook  #'vermin/gui-get-selection )
  )

1.7.4. Vterm

(use-package! vterm
  :config (set-popup-rules! `(("\\*vterm\\*"
                                        ; node dedicated org-roam buffer :side right
                               :width 0.7
                               :ttl nil
                               :select t
                               :modeline nil
                               :quit nil
                               :slot 1)))(setq! vterm-shell "/usr/bin/fish"))
(use-package! org-download
  :config (setq-default org-download-image-dir "./images")(setq! org-download-method 'directory)(setq! org-download-link-format "[[file:images/%s]]\n"))

;; (use-package! deft
;;   :config (setq! deft-directory org-directory)(setq! deft-use-filename-as-title t)(setq! deft-extensions
;;                                                                                          '("md" "org")
;;                                                                                          deft-recursive
;;                                                                                          t))
;; (use-package! org-protocol-capture-html)
;;

1.7.5. User and email configure

User and email configure go here

;;; -*- lexical-binding: t; -*-
;; Some functionality uses this to identify you, e.g. GPG configuration, email
;; clients, file templates and snippets.
(setq! user-full-name "nhannht" user-mail-address
       "nhanclassroom@gmail.com")


1.7.6. font and theme configure

;; Doom exposes five (optional) variables for controlling fonts in Doom. Here
;; are the three important ones:
;;
;; + `doom-font'
;; + `doom-variable-pitch-font'
;; + `doom-big-font' -- used for `doom-big-font-mode'; use this for
;;   presentations or streaming.
;;
;; They all accept either a font-spec, font string ("Input Mono-12"), or xlfd
;; font string. You generally only need these two:

(let* ((exit-code 1)))

(if IS-LINUX
    (if (string-empty-p (shell-command-to-string "fc-list|grep jetbrain -I "))
        (setq doom-font (font-spec :family "JetBrains Mono"
                                   :size 12))
      (warn "Dont found specific font, install jetbrain mono first"))
  (message "You not using linux"))

(remove-hook '+doom-dashboard-functions #'doom-dashboard-widget-shortmenu)
;; There are two ways to load a theme. Both assume the theme is installed and
;; available. You can either set `doom-theme' or manually load a theme with the
;; `load-theme' function. This is the default:

(setq doom-theme 'modus-operandi)

(setq delete-by-moving-to-trash t)

;; This determines the style of line numbers in effect. If set to `nil', line
;; numbers are disabled. For relative line numbers, set this to `relative'.
(setq display-line-numbers-type nil)

;; Here are some additional functions/macros that could help you configure Doom:
;;
;; - `load!' for loading external *.el files relative to this one
;; - `use-package!' for configuring packages
;; - `after!' for running code after a package has loaded
;; - `add-load-path!' for adding directories to the `load-path', relative to
;;   this file. Emacs searches the `load-path' when you load packages with
;;   `require' or `use-package'.
;; - `map!' for binding new keys
;;
;; To get information about any of these functions/macros, move the cursor over
;; the highlighted symbol at press 'K' (non-evil users must press 'C-c c k').
;; This will open documentation for it, including demos of how they are used.
;;
;; You can also try 'gd' (or 'C-c c d') to jump to their definition and see how
;; they are implemented.

(defun native-comp-available-p ()
  nil)
;; (toggle-debug-on-error)

(plist-put! +ligatures-extra-symbols)

(use-package! highlight-numbers
  :config (add-hook! 'emacs-lisp-mode-hook #'highlight-function-calls-mode))

;; (use-package! pdf-tools
;;   :config
;;   ;; (pdf-tools-install)
;;   )


(after! doom-modeline
  (doom-modeline-def-segment buffer-name
    "Display the current buffer's name, without any other information."
    (concat (doom-modeline-spc)
            (doom-modeline--buffer-name)))
  (doom-modeline-def-segment pdf-icon
    "PDF icon from all-the-icons."
    (concat (doom-modeline-spc)
            (doom-modeline-icon 'octicon
                                "file-pdf"
                                nil
                                nil
                                :face (if (doom-modeline--active)
                                          'all-the-icons-red
                                        'mode-line-inactive)
                                :v-adjust
                                0.02)))
  ;; (defun doom-modeline-update-pdf-pages ()
  ;;   "Update PDF pages."
  ;;   (setq doom-modeline--pdf-pages (let ((current-page-str (number-to-string (eval `(pdf-view-current-page))))
  ;;                                        (total-page-str (number-to-string (pdf-cache-number-of-pages))))
  ;;                                    (concat (propertize (concat (make-string (- (length total-page-str)
  ;;                                                                                (length current-page-str))
  ;;                                                                             ?)
  ;;                                                                " P"
  ;;                                                                current-page-str)
  ;;                                                        'face
  ;;                                                        'mode-line)
  ;;                                            (propertize (concat "/" total-page-str)
  ;;                                                        'face
  ;;                                                        'doom-modeline-buffer-minor-mode)))))
  (doom-modeline-def-segment pdf-pages
    "Display PDF pages."
    (if (doom-modeline--active)
        doom-modeline--pdf-pages
      (propertize doom-modeline--pdf-pages 'face
                  'mode-line-inactive)))
  (doom-modeline-def-modeline 'pdf
    '(bar window-number pdf-pages pdf-icon buffer-name)
    '(misc-info matches major-mode process vcs)))


(use-package! page-break-lines
  :commands page-break-lines-mode
  :init (autoload 'turn-on-page-break-lines-mode "page-break-lines"):config
  (setq global-page-break-lines-mode t)
  (setq page-break-lines-max-width fill-column)
  (map! :prefix "g"
        :desc "Prev page break"
        :nv "["#'backward-page :desc "Next page break"
        :nv "]"#'forward-page))

1.7.7. Org.el

;; If you use `org' and don't want your org files in the default location below,
;; change `org-directory'. It must be set before org loads!
(use-package! org
  :init (setq org-directory "~/org/"):config
  (setq! org-confirm-babel-evaluate nil)
  (set-popup-rule! "^\\*Org Src.*" :width 0.5
    :side 'right
    :select t))


(use-package! org-journal
  :after org
  :init (setq! org-journal-time-prefix "** IDEA ")(setq! org-journal-file-format "%Y%m%d.org")(setq! org-journal-time-format "%Y-%m-%d %R-%S ")(setq! org-journal-enable-agenda-integration
                                                                                                                                                      t))

(use-package! org-sticky-header
  :after org
  :config (add-hook! 'org-mode-hook #'org-sticky-header-mode))

1.7.8. Lisp.el

(after! smartparens
  (add-hook! (clojure-mode emacs-lisp-mode lisp-mode cider-repl-mode
                           racket-mode racket-repl-mode)
             :append #'smartparens-strict-mode)
  (add-hook! smartparens-mode :append #'sp-use-paredit-bindings))

;; (add-hook! org-mode #'lambda()(imenu-add-to-menubar "Imenu"))
(use-package! key-chord
  :config (setq key-chord-two-keys-delay 0.5)(key-chord-define evil-insert-state-map "fd"
                                                               'evil-normal-state)(key-chord-mode 1))

(after! evil
  (define-key evil-normal-state-map (kbd "M-.") nil))

(delete '("\\.org\\'" . poly-org-mode) auto-mode-alist)
(delete '("\\.md\\'" . poly-markdown-mode) auto-mode-alist)
(defun vermin/jump-to-current-buffer-directory ()
  "Jump to current buffer directory, normally Doom handle current directory for you when you jump between buffer,
but in case it suck, use it'"
  (interactive)
  (cd (file-name-directory (buffer-file-name))))

1.8. Custom.el

All minor package that install from community go here

1.8.1. Kmacro menu

(easy-menu-define kmacro-menu
  nil
  "Keyboard Macro Menu."
  '("Keyboard Macro"
    ["Universal Argument" universal-argument :help "Begin a numeric argument for the following command."]
    "--"
    ["Start Macro" kmacro-start-macro :help "Record subsequent keyboard input, defining a keyboard macro."]
    ["End Macro" kmacro-end-macro :help "Finish defining a keyboard macro."]
    ["End And Call Macro" kmacro-end-and-call-macro
     :help "Call last keyboard macro, ending it first if currently being defined."]
    "--"
    ["Kmacro Bind To Key" kmacro-bind-to-key :help "When not defining or executing a macro, offer to bind last macro to a key."]
    ["Name Last Macro" kmacro-name-last-macro
     :help "Assign a name to the last keyboard macro defined."]
    ["Insert Macro" insert-kbd-macro :help "Insert in buffer the #+end_src definition of kbd macro MACRONAME, as Lisp code."]))

(easy-menu-add-item menu-bar-tools-menu nil
                    kmacro-menu "grep")

1.8.2. org-babel-tangle-jump

Jump from org source file to tangled destination file, because org still don't have a built-in way to do it"

(defun vermin/org-babel-tangle-jump ()
  "Jump from org source file to tangled destination file, because org still don't have a built-in way to do it"
  (interactive)
  (let (file org-babel-pre-tangle-hook org-babel-post-tangle-hook)
    (cl-letf (((symbol-function 'write-region) (lambda (start end filename &rest _ignore)
                                                 (setq file filename)))
              ((symbol-function 'delete-file) #'ignore))
      (org-babel-tangle '(4)))
    (when file
      (setq file (expand-file-name file))
      (if (file-readable-p file)
          (find-file file)
        (error "Cannot open tangle file %S" file)))))

(add-to-list 'org-structure-template-alist
             '("t" . "src go :tangle yes :comments yes rue"))

(defun  vermin/md-to-org-region (start end)
  "Convert region from markdown to org"
  (interactive "r")
  (shell-command-on-region start end "pandoc -f markdown -t org" t t))

1.8.3. Emacs everywhere

(setenv "NODE_PATH" "~/IdeaProjects/turndown-plugin-gfm/node_modules/")
(defcustom emacs-everywhere-markdown-windows
  '("Stack Exchange" "Stack Overflow" "Reddit" "Github" "Trello" ; Sites
    "Pull Request" "notion" "Issue" "Flashcards" "Comparing .*\\.\\.\\." "README.md" ; Github
    "Discord")
  "For use with `emacs-everywhere-markdown-p'.
       Patterns which are matched against the window title."
  :type '(rep string)
  :group 'emacs-everywhere)

(defcustom emacs-everywhere-markdown-apps
  '("Discord")
  "For use with `emacs-everywhere-markdown-p'.
       Patterns which are matched against the app name."
  :type '(rep string)
  :group 'emacs-everywhere)

(defhydra vermin/hydra-yasnipet ()
  ("i" #'yas-insert-snippet "insert snippet" :exit t :column "yas")
  ("n" yas-new-snippet "new snippet" :exit t :column "yas")
  ("v" yas-visit-snippet-file "change snippet" :exit t :column "yas"))

(defun vermin/convert-to-org-and-paste ()
  (interactive )
  (let ((clipboard (string-chop-newline
                    (string-as-unibyte (gui-get-selection 'CLIPBOARD))))
        (temp-file (file-name-concat (temporary-file-directory) "clipboard")))
    (progn
      (write-region clipboard nil temp-file )
      (insert
       (shell-command-to-string (format  "pandoc %s --from markdown --to org"
                                         temp-file))))))

1.8.4. Hydra buffer menu

(defhydra hydra-buffer-menu (:color pink
                             :hint nil)
  "
       ^Mark^             ^Unmark^           ^Actions^          ^Search
       ^^^^^^^^-----------------------------------------------------------------
       _m_: mark          _u_: unmark        _x_: execute       _R_: re-isearch
       _s_: save          _U_: unmark up     _b_: bury          _I_: isearch
       _d_: delete        ^ ^                _g_: refresh       _O_: multi-occur
       _D_: delete up     ^ ^                _T_: files only: % -28`Buffer-menu-files-only
       _~_: modified
       "
  ("m" Buffer-menu-mark)
  ("u" Buffer-menu-unmark)
  ("U" Buffer-menu-backup-unmark)
  ("d" Buffer-menu-delete)
  ("D" Buffer-menu-delete-backwards)
  ("s" Buffer-menu-save)
  ("~" Buffer-menu-not-modified)
  ("x" Buffer-menu-execute)
  ("b" Buffer-menu-bury)
  ("g" revert-buffer)
  ("T" Buffer-menu-toggle-files-only)
  ("O" Buffer-menu-multi-occur :color blue)
  ("I" Buffer-menu-isearch-buffers :color blue)
  ("R" Buffer-menu-isearch-buffers-regexp :color blue)
  ("c" nil "cancel")
  ("v" Buffer-menu-select "select" :color blue)
  ("o" Buffer-menu-other-window "other-window" :color blue)
  ("q" quit-window "quit" :color blue))

1.8.5. Topsy

(use-package! topsy
  :config
  (add-hook! 'emacs-lisp-mode-hook #'topsy-mode))

1.8.6. Org sticky header

1.8.7. org sidebar

(use-package org-sidebar
  :after org)

1.8.8. Pop rule for man page

;; (map! :leader
;;       (:prefix-map ("a" . "applications")
;;        (:prefix ("j" . "journal")
;;         :desc "New journal entry" "j" #'org-journal-new-entry
;;         :desc "Search journal entry" "s" #'org-journal-search)))
;;


(set-popup-rule! "^\\*Man.*"
  :size 82
  :side 'right
  :ttl t
  :select t
  :quit t :transient t)

1.8.9. Modus theme

(use-package! modus-themes
  :init
  (setq! modus-themes-italic-constructs t
         modus-themes-bold-constructs t
         modus-themes-mixed-fonts nil
         modus-themes-subtle-line-numbers nil
         modus-themes-intense-markup t
         modus-themes-success-deuteranopia t
         modus-themes-tabs-accented t
         modus-themes-inhibit-reload t ; only applies to `customize-set-variable' and related

         modus-themes-fringes nil ; {nil,'subtle,'intense}

         ;; Options for `modus-themes-lang-checkers' are either nil (the
         ;; default), or a list of properties that may include any of those
         ;; symbols: `straight-underline', `text-also', `background',
         ;; `intense' OR `faint'.
         modus-themes-lang-checkers nil

         ;; Options for `modus-themes-mode-line' are either nil, or a list
         ;; that can combine any of `3d' OR `moody', `borderless',
         ;; `accented', `padded'.
         modus-themes-mode-line '(padded accented borderless)

         ;; This one only works when `modus-themes-mode-line' (above) has
         ;; the `padded' property.  It takes a positive integer.
         modus-themes-mode-line-padding 3

         ;; Options for `modus-themes-syntax' are either nil (the default),
         ;; or a list of properties that may include any of those symbols:
         ;; `faint', `yellow-comments', `green-strings', `alt-syntax'
         modus-themes-syntax '(faint green-strings alt-syntax)

         ;; Options for `modus-themes-hl-line' are either nil (the default),
         ;; or a list of properties that may include any of those symbols:
         ;; `accented', `underline', `intense'
         modus-themes-hl-line '(underline accented)

         ;; Options for `modus-themes-paren-match' are either nil (the
         ;; default), or a list of properties that may include any of those
         ;; symbols: `bold', `intense', `underline'
         modus-themes-paren-match '(underline)

         ;; Options for `modus-themes-links' are either nil (the default),
         ;; or a list of properties that may include any of those symbols:
         ;; `neutral-underline' OR `no-underline', `faint' OR `no-color',
         ;; `bold', `italic', `background'
         modus-themes-links '(neutral-underline background)

         ;; Options for `modus-themes-prompts' are either nil (the
         ;; default), or a list of properties that may include any of those
         ;; symbols: `background', `bold', `gray', `intense', `italic'
         modus-themes-completions '((matches . (extrabold))
                                    (selection . (semibold accented))
                                    (popup . (accented intense)))

         modus-themes-completions 'moderate ; {nil,'moderate,'opinionated}

         modus-themes-mail-citations 'faint ; {nil,'faint,'monochrome}

         ;; Options for `modus-themes-region' are either nil (the default),
         ;; or a list of properties that may include any of those symbols:
         ;; `no-extend', `bg-only', `accented'
         modus-themes-region '(bg-only no-extend)

         ;; Options for `modus-themes-diffs': nil, 'desaturated,
         ;; 'bg-only, 'deuteranopia, 'fg-only-deuteranopia
         modus-themes-diffs 'fg-only-deuteranopia

         modus-themes-org-blocks 'tinted-background ; {nil,'gray-background,'tinted-background}

         ;; modus-themes-org-agenda ; this is an alist: read the manual or its doc string
         ;; '((header-block . (variable-pitch scale-title))
         ;;   (header-date . (grayscale workaholic bold-today))
         ;;   (event . (accented scale-small))
         ;;   (scheduled . uniform)
         ;;   (habit . traffic-light-deuteranopia))

         modus-themes-headings ; this is an alist: read the manual or its doc string
         '((1 . (overline background))
           (2 . (rainbow overline))
           (t . (semibold)))

         modus-themes-variable-pitch-ui nil
         modus-themes-variable-pitch-headings t
         modus-themes-scale-headings t
         modus-themes-scale-1 1.1
         modus-themes-scale-2 1.15
         modus-themes-scale-3 1.21
         modus-themes-scale-4 1.27
         modus-themes-scale-title 1.33)
  )

1.8.10. Flycheck

(use-package! flycheck
  :config
  (flycheck-add-mode 'proselint 'org-mode))

1.8.11. Nov

(use-package! nov
  :hook (nov-mode . variable-pitch-mode)
  :mode ("\\.\\(epub\\|mobi\\)\\'" . nov-mode))

1.8.12. Wolfram-mode

;; (use-package! wolfram-mode
;;   :init
;;   (add-to-list 'auto-mode-alist '("\\.\\(m\\|nb\\|wls\\|wlp\\)\\'" . wolfram-mode)  )
;;   :config
;;   (add-to-list 'exec-path "/use/local/bin/mathematica")
;;   (setq wolfram-path "~/.Mathematica/Applications")
;;   (setq wolfram-program "/usr/bin/wolframscript")
;;   (setq org-babel-mathematica-command "/usr/bin/wolframscript")

;;   (add-to-list 'org-src-lang-modes
;;                '("mathematica" . wolfram))
;;   (add-to-list 'lsp-language-id-configuration
;;                '(wolfram-mode . "Mathematica"))
;; (lsp-register-client
;;  (make-lsp-client :language-id 'wolfram
;;                   :new-connection (lsp-tcp-server-command
;;                                    (lambda (port)
;;                                      `("wolfram"
;;                                        "-script"
;;                                        "~/org-one/lsp-wl/init.wls"
;;                                        ,(concat
;;                                          "--socket="
;;                                          (number-to-string port)
;;                                          ))))
;;                   :major-modes '(wolfram-mode)
;;                   :server-id 'lsp-wl
;;                   )))

1.8.13. Outshine

(use-package! outshine
  :hook (emacs-lisp-mode . outshine-mode))

1.8.14. Websocket

(use-package! websocket
  :after org-roam)

1.8.15. Org-roam-ui

( use-package! org-roam-ui
  :disabled t
  :after org-roam ;; or :after org
  ;;         normally we'd recommend hooking orui after org-roam, but since org-roam does not have
  ;;         a hookable mode anymore, you're advised to pick something yourself
  ;;         if you don't care about startup time, use
  ;;  :hook (after-init . org-roam-ui-mode)
  :config
  (setq org-roam-ui-sync-theme t
        org-roam-ui-follow t
        org-roam-ui-update-on-save t
        org-roam-ui-open-on-start t)
  )

(defun set-doom-avatar ()
  (setq fancy-splash-image "~/.doom.d/fibonacci.png"))
(set-doom-avatar)

1.8.16. Yequake

(use-package! yequake
  :disabled t
  :config
  (setq yequake-frames
        '(("Yequake & scratch" .
           ((width . 0.75)
            (height . 0.5)
            (alpha . 0.95)
            (buffer-fns . ("~/temp/yequake.el"
                           split-window-horizontally
                           "*scratch*"))
            (frame-parameters . ((undecorated . t)))))))
  )

1.8.17. unfill-region

(defun vermin/unfill-region (beg end)
  "Unfill the region, joining text paragraphs into a single
       logical line.  This is useful, e.g., for use with
       `visual-line-mode'."
  (interactive "*r")
  (let ((fill-column (point-max)))
    (fill-region beg end)))

;; Handy key definition
(define-key global-map "\C-\M-Q" 'vermin/unfill-region)

1.8.18. binding

(use-package! emr)
(use-package! srefactor)
(use-package! srefactor-lisp)

(defhydra vermin/hydra-semantic
  ()
  "Expand region base on semantic"
  ("w" er/expand-region "er/expand-region" :exit nil
   :column "semantic")
  ("l" er/mark-url "er/url" :exit t
   :column "other")
  ("e" er/mark-email "er/email" :exit t
   :column "other")
  ("p" er/mark-paragraph "er/paragraph" :exit t
   :column "semantic")
  ("s" er/mark-comment "er/comment" :exit t
   :column "other")
  ("f" er/mark-defun "er/defun" :exit t
   :column "semantic")
  ("O" er/mark-org-code-block "er/org-block-out"
   :exit t
   :column "org")
  ("o" org-babel-mark-block "org-block" :exit t
   :column "org")
  ("q" nil "quit"))

(defhydra vermin/hydra-agenda
  ()
  "Cheating the org agenda"
  ("w" unpackaged/org-agenda-toggle-preview
   "agenda preview" :exit nil
   :column "agenda"))

(defhydra vermin/hydra-tangle
  ()
  "This scholar know how to literature programming"
  ("t" org-babel-tangle "org/tangle" :exit t
   :column "org-src")
  ("j" vermin/org-babel-tangle-jump "vermin/jump-to-src"
   :exit t
   :column "org-src")
  ("q" nil "exit")
  ("d" org-babel-detangle "org/detangle" :exit t
   :column "src-org"))

(defhydra vermin/hydra-image
  (:color pink)
  "This hydra deal with image"
  ("y" org-download-clipboard "download" :exit t
   :column "image")
  ("d" org-download-delete "delete" :exit t
   :column "image"))

(defhydra vermin/hydra-window
  (:color pink)
  ("<left>" windmove-left "\342\254\205" :exit nil)
  ("<down>" windmove-down "" :exit nil)
  ("<up>" windmove-up :exit nil)
  ("<right>" windmove-right :exit nil)
  ("h" split-window-below)
  ("v" split-window-right)
  ("C-<up>" hydra-move-splitter-up)
  ("C-<down>" hydra-move-splitter-down)
  ("C-<left>" hydra-move-splitter-left)
  ("C-<right>" hydra-move-splitter-right)
  ("M-<up>" buf-move-up)
  ("M-<down>" buf-move-down)
  ("M-<left>" buf-move-left)
  ("M-<right>" buf-move-right)
  ("SPC" nil))



(map! :leader (:prefix-map ("v" . "vermin")
               (:desc "vermin/hydra-semantic" "s" #'vermin/hydra-semantic/body)
               (:desc "org-tangle" "o" #'vermin/hydra-tangle/body)
               (:desc "org-agenda" "a" #'vermin/hydra-agenda/body)
               (:desc "vermin-image" "i" #'vermin/hydra-image/body)
               (:desc "vermin-snippet" "c" #'vermin/hydra-yasnipet/body)
               (:desc "vermin/eval-line-or-region" "v" #'+eval/line-or-region)
               (:map pdf-view-mode-map
                (:desc "jump-back-old-location" "C-o" #'pdf-history-backward)
                (:desc "jump-forward-history" "C-i" #'pdf-history-forward))))

(map! :leader (:prefix "i"
               (:in "i" #'all-the-icons-insert)))
(map! :map emacs-lisp-mode-map
      :desc "for elisp refactor"
      :leader :prefix
      "m"
      (:in "r r" #'emr-show-refactor-menu)
      (:in "r e" #'emr-iedit-global)
      (:in "r f" #'srefactor-lisp-format-buffer)
      (:in "r R" #'srefactor-refactor-at-point))

(map! :leader :prefix
      "t"
      (:in "e" #'emacs-everywhere-mode)
      (:in "q" #'clojure-mode))

(map! :map org-lint--report-mode-map
      :leader :prefix
      "m"
      (:g "j" #'org-lint--jump-to-source)
      (:g "J" #'org-lint--show-source))

(map! :g "C-M-w"#'er/expand-region)

;; Take back C-u and C-d in evil mode
(setq! evil-want-C-u-scroll nil evil-want-C-d-scroll
       nil)

1.8.19. Exec path from cell

(use-package! exec-path-from-shell
  :init
  (when (memq window-system '(mac ns x))
    (exec-path-from-shell-initialize))

  (when (daemonp)
    (exec-path-from-shell-initialize)))

1.8.20. Asciidoc

(use-package! adoc-mode
  :defer 1
  :mode "\\.asciidoc\\'")
(use-package! asciidoc
  :defer 1
  :mode "\\.asciidoc\\'")

1.8.21. copilot

(defun my-tab ()
  (interactive)
  (or (copilot-accept-completion)
      (company-indent-or-complete-common nil)))

(use-package! copilot
  :hook ( (prog-mode . copilot-mode)
          )
  :bind (("C-TAB" . 'copilot-accept-completion-by-word)
         ("C-<tab>" . 'copilot-accept-completion-by-word)
         :map company-active-map
         ("<tab>" . 'my-tab)
         ("TAB" . 'my-tab)
         :map company-mode-map
         ("<tab>" . 'my-tab)
         ("TAB" . 'my-tab)))

1.8.22. dired narrow

(use-package! dired-narrow
  :disabled t
  :commands (dired-narrow-fuzzy)
  :after dired
  :config
  (map! :leader  :map dired-mode-map
        :desc "dired narrow" "s" #'dired-narrow))



(defun vermin/md-to-org-region (start end)
  "Convert region from markdown to org"
  (interactive "r")
  (shell-command-on-region start end "pandoc -f markdown -t org" t t))

;; TODO create add-to-list-multi-object macro
;; (add-to-list 'org-capture-templates
;;              '("i" "Inbox" entry  (file "gtd/inbox.org")
;;               ,(concat "* TODO %?\n"
;;                        "/Entered on/ %U"))
;;              '("c" "Org-protocol capture" entry  (file "gtd/inbox.org")
;;               ,(concat "* TODO %a\n"
;;                        "/Entered on/ %U")
;;               :immediate-finish t)
;;              '("@" "Inbox [mu4e]" entry (file "gtd/inbox.org")
;;               ,(concat "* TODO Reply to \"%a\" %?\n"
;;                        "/Entered on/ %U")))
;;

(defun hydra-add-imenu ()
  "Add this to `emacs-lisp-mode-hook' to have hydras in `imenu'."
  (interactive)
  (add-to-list
   'imenu-generic-expression
   '("Hydras"
     "^.*(\\(defhydra\\) \\([a-zA-Z-/]+\\)"
     2)))

(defun map-add-imenu ()
  "map-add-imenu is used to add map to imenu"
  (interactive)
  (add-to-list
   'imenu-generic-expression
   '("Map!"
     "^.*(\\(map!\\) \\(.*\\)"
     2)))


;; (use-package! hydra
;;   :hook ((emacs-lisp-mode . hydra-add-imenu)
;;          (emacs-lisp-mode . map-add-imenu))
;;   )
(defvar ffap-file-at-point-line-number nil
  "Variable to hold line number from the last `ffap-file-at-point' call.")

(defadvice ffap-file-at-point (after ffap-store-line-number activate)
  "Search `ffap-string-at-point' for a line number pattern and
  save it in `ffap-file-at-point-line-number' variable."
  (let* ((string (ffap-string-at-point)) ;; string/name definition copied from `ffap-string-at-point'
         (name
          (or (condition-case nil
                  (and (not (string-match "//" string)) ; foo.com://bar
                       (substitute-in-file-name string))
                (error nil))
              string))
         (line-number-string
          (and (string-match ":[0-9]+" name)
               (substring name (1+ (match-beginning 0)) (match-end 0))))
         (line-number
          (and line-number-string
               (string-to-number line-number-string))))
    (if (and line-number (> line-number 0))
        (setq ffap-file-at-point-line-number line-number)
      (setq ffap-file-at-point-line-number nil))))

(defadvice find-file-at-point (after ffap-goto-line-number activate)
  "If `ffap-file-at-point-line-number' is non-nil goto this line."
  (when ffap-file-at-point-line-number
    (forward-line ffap-file-at-point-line-number)
    (setq ffap-file-at-point-line-number nil)))

(use-package! ox-hugo
  :config
  (setq org-hugo-base-dir "~/hugo"))
;; (use-package! zig-mode
;;   :hook ((zig-mode . lsp-deferred))
;;   :custom (zig-format-on-save nil)
;;   :config
;;   (after! lsp-mode
;;     (add-to-list 'lsp-language-id-configuration '(zig-mode . "zig"))
;;     (lsp-register-client
;;      (make-lsp-client
;;       :new-connection (lsp-stdio-connection "<path to zls>")
;;       :major-modes '(zig-mode)
;;       :server-id 'zls))))
(use-package! emacs-refactor
  :hook ((emacs-lisp-mode . erefactor-lazy-highlight-turn-on )
         (emacs-lisp-mode . erefactor-lazy-highlight-turn-on)))

1.8.23. ob-http

(use-package! ob-http
  :config
  (org-babel-do-load-languages
   'org-babel-load-languages
   '((http . t)
     (jupyter . t))))
(use-package! ob-async)

1.8.24. word-wrap

(add-to-list '+word-wrap-disabled-modes 'org-mode)
(add-hook 'org-mode-hook
          (lambda ()
            (visual-line-mode -1000)))

1.8.25. save bookmark hook

(;; defun vermin/save-book-mark ()
 ;;  (let* ((directory "~/org/bookmark")
 ;;         (file (file-name-concat directory "save")))
 ;;    (cond ((not (file-directory-p directory))
 ;;           (progn
 ;;             (delete-file directory)
 ;;             (mkdir directory)
 ;;             ))
 ;;          (t (bookmark-save nil file t)))
 ;;    )
 )
;; (add-hook! 'kill-emacs-hook #'vermin/save-book-mark )
(setq! bookmark-default-file "~/org/bookmark/save")

1.8.26. eaf

;; (defun vermin--config-for-eaf ()
;;   (progn
;;     (require 'eaf-mindmap)
;;     (require 'eaf-vue-demo)
;;     (require 'eaf-airshare)
;;     ;; (require 'eaf-mermaid)
;;     (require 'eaf-jupyter)
;;     (require 'eaf-markdown-previewer)
;;     (require 'eaf-camera)
;;     (require 'eaf-file-sender)
;;     (require 'eaf-system-monitor)
;;     (require 'eaf-video-player)
;;     (require 'eaf-file-manager)
;;     (require 'eaf-image-viewer)
;;     (require 'eaf-netease-cloud-music)
;;     (require 'eaf-rss-reader)
;;     (require 'eaf-browser)
;;     (require 'eaf-file-browser)
;;     (require 'eaf-org-previewer)
;;     (require 'eaf-terminal)
;;     (require 'eaf-demo)
;;     (require 'eaf-git)
;;     (require 'eaf-music-player)
;;     (require 'eaf-evil)

;;     (define-key key-translation-map (kbd "SPC")
;;       (lambda (prompt)
;;         (if (derived-mode-p 'eaf-mode)
;;             (pcase eaf--buffer-app-name
;;               ("browser" (if  (eaf-call-sync "execute_function" eaf--buffer-id "is_focus")
;;                              (kbd "SPC")
;;                            (kbd eaf-evil-leader-key)))
;;               ("pdf-viewer" (kbd eaf-evil-leader-key))
;;               ("image-viewer" (kbd eaf-evil-leader-key))
;;               (_  (kbd "SPC")))
;;           (kbd "SPC")))))

;;   )
;; (use-package! eaf
;;   :defer 1

;;   :config
;;   (setq! python-shell-interpreter "/usr/bin/python3.10"
;;          eaf-python-command "/usr/bin/python3.10")
;;   (let* ((eaf-dir "/home/vermin/.emacs.d/.local/straight/repos/emacs-application-framework"))

;;     (cond ((not (file-exists-p eaf-dir )) nil)
;;           (t    (vermin--config-for-eaf)    )))
;;   ;; (require 'eaf-pdf-viewer)
;;   )

;; (use-package! tree-sitter
;;   :config
;;   (require 'tree-sitter-hl)
;;   (require 'tree-sitter-langs)
;;   (require 'tree-sitter-debug)
;;   (require 'tree-sitter-query)
;;   ;; (global-tree-sitter-mode)
;;   )
;; (use-package! aweshell
;;   :disabled t
;;   )

1.8.27. Org scrum

(use-package! org-scrum)

1.8.28. orgaggregate

(use-package! orgtbl-aggregate)
(load-file "~/org-one/scratch.el")

1.8.29. Racket

(defun racket-eldoc-set ()
  (setq eldoc-documentation-function #'racket-repl-eldoc-function)
  (setq completion-at-point-functions '(racket-repl-complete-at-point)))

(defun racket-repl-eldoc-config ()
  (setq eldoc-documentation-function #'racket-repl-eldoc-function))

(use-package! racket-mode
  :init
  (add-hook 'racket-mode-hook #'racket-xp-mode)
  (add-hook 'racket-mode-hook #'racket-eldoc-set)
  )

(use-package! racket-repl
  :init (add-hook 'racket-repl-mode-hook #'racket-repl-eldoc-config))

1.8.30. Poly-mode

(use-package! polymode
  ;; :mode ("\.py$" . poly-python-sql-mode)
  :config
  (setq polymode-prefix-key (kbd "C-c n")))

(define-hostmode poly-markdown-hostmode
  :mode 'markdown-mode)
(define-innermode poly-markdown-yaml-metadata-innermode
  :mode 'yaml-mode
  :head-matcher "\`[ \t\n]*---\n"
  :tail-matcher "^---\n"
  :head-mode 'host
  :tail-mode 'host)
(define-auto-innermode poly-markdown-fenced-code-innermode
  :head-matcher (cons "^[ \t]*\\(```{?[[:alpha:]].*\n\\)" 1)
  :tail-matcher (cons "^[ \t]*\\(```\\)[ \t]*$" 1)
  :mode-matcher (cons "```[ \t]*{?\\(?:lang *= *\\)?\\([^ \t\n;=,}]+\\)" 1)
  :head-mode 'host
  :tail-mode 'host)

(define-innermode poly-markdown-org-innermode
  :mode 'org-mode
  :head-matcher "@@[ \t\n]*---\n"
  :tail-matcher "^---\n"
  :head-mode 'host
  :tail-mode 'host)
(define-polymode poly-markdown-mode
  :hostmode 'poly-markdown-hostmode
  :innermodes '(poly-markdown-yaml-metadata-innermode
                poly-markdown-fenced-code-innermode
                poly-markdown-org-innermode))

(use-package! poly-markdown
  :disabled t)
(use-package! poly-org
  :disabled t)
(delete '("\\.md\\'" . poly-markdown-mode)
        auto-mode-alist)

(delete '("\\.org\\'" . poly-org-mode)
        auto-mode-alist)

1.8.31. jupyter org

;; (use-package! zmq
;;   )
(use-package! ob-jupyter
  :config (org-babel-jupyter-override-src-block "python"))
(use-package! howdoyou
  )

1.8.32. ob-mermaid

(use-package! ob-mermaid
  :config
  (setq! ob-mermaid-cli-path "/usr/bin/mmdc")
(org-babel-do-load-languages
    'org-babel-load-languages
    '((mermaid . t)
      ))
  )

1.9. Fish

1.9.1. Oh my fish - omf

  1. Init.fish
    # fish_vi_key_bindings
    fish_default_key_bindings
    if status is-interactive
        # Commands to run in interactive sessions can go here
    end
    bass source $HOME/.profile
    bass source $HOME/.bash_profile
    function fuck -d "Correct your previous console command"
      set -l fucked_up_command $history[1]
      env TF_SHELL=fish TF_ALIAS=fuck PYTHONIOENCODING=utf-8 thefuck $fucked_up_command THEFUCK_ARGUMENT_PLACEHOLDER $argv | read -l unfucked_command
      if [ "$unfucked_command" != "" ]
        eval $unfucked_command
        builtin history delete --exact --case-sensitive -- $fucked_up_command
        builtin history merge
      end
    end
    
    # source $HOME/.config/fish/hugo.fish
    
    # With vterm_cmd you can execute Emacs commands directly from the shell.
    # For example, vterm_cmd message "HI" will print "HI".
    # To enable new commands, you have to customize Emacs's variable
    # vterm-eval-cmds.
    function vterm_cmd --description 'Run an Emacs command among the ones defined in vterm-eval-cmds.'
        set -l vterm_elisp ()
        for arg in $argv
    	set -a vterm_elisp (printf '"%s" ' (string replace -a -r '([\\\\"])' '\\\\\\\\$1' $arg))
        end
        vterm_printf '51;E'(string join '' $vterm_elisp)
    end
    source (/usr/bin/starship init fish --print-full-init | psub)
    
  2. bundle.fish
    package bass
    package colored-man-pages
    package foreign-env
    package https://github.com/jorgebucaran/autopair.fish
    package nvm
    package z
    theme default
    

1.10. Bash

Because I am using Manjaro, I was rarely touch .bashrc, instead that I write my custom config to .profile as the main bash configuration file

1.10.1. .bashprofile

alias vim=nvim
export PATH=$HOME/.local/bin/:$PATH
export PATH=$HOME/bin/:$PATH
export PATH=$HOME/go/bin/:$PATH
export PATH=$HOME/.local/bin/:$PATH
export PATH=/usr/lib/jvm/java-11-openjdk/bin/:$PATH
export PATH=$HOME/math/Executables/:$PATH
export PATH=$HOME/.emacs.d/bin/:$PATH
export PATH=$HOME/script/:$PATH
export PATH=/usr/lib/jvm/java-11-graalvm/bin/:$PATH
export LC_ALL=en_US.UTF-8
export LANG=en_US.UTF-8
export LANGUAGE=en_US.UTF-8
alias e="emacsclient -n"
alias ew="emacsclient -nw"
alias ec="emacsclient -nc"
alias m="mathematica -sl "

# function vterm_printf(){
#     if [ -n "$TMUX" ] && ([ "${TERM%%-*}" = "tmux" ] || [ "${TERM%%-*}" = "screen" ] ); then
#         # Tell tmux to pass the escape sequences through
#         printf "\ePtmux;\e\e]%s\007\e\\" "$1"
#     elif [ "${TERM%%-*}" = "screen" ]; then
#         # GNU screen (screen, screen-256color, screen-256color-bce)
#         printf "\eP\e]%s\007\e\\" "$1"
#     else
#         printf "\e]%s\e\\" "$1"
#     fi
# }

# # Sync directory and host in the shell with Emacs's current directory.
# # You may need to manually specify the hostname instead of $(hostname) in case
# # $(hostname) does not return the correct string to connect to the server.
# #
# # The escape sequence "51;A" has also the role of identifying the end of the
# # prompt
# vterm_prompt_end(){
#     vterm_printf "51;A$(whoami)@$(hostname):$(pwd)"
# }
# PS1=$PS1'\[$(vterm_prompt_end)\]'
# source /usr/share/nvm/init-nvm.sh
[ -z "$NVM_DIR" ] && export NVM_DIR="$HOME/.nvm"
source /usr/share/nvm/nvm.sh
source /usr/share/nvm/bash_completion
source /usr/share/nvm/install-nvm-exec
source /usr/share/nvm/init-nvm.sh 

# eval "$(/home/linuxbrew/.linuxbrew/bin/brew shellenv)"
# source  $(brew --prefix asdf)/libexec/asdf.sh
# source $(brew --prefix asdf)/etc/bash_completion.d/asdf.bash

# export PYENV_ROOT="$HOME/.pyenv"
# command -v pyenv >/dev/null || export PATH="$PYENV_ROOT/bin:$PATH"
# eval "$(pyenv init -)"



# Restart your shell for the changes to take effect.
export PATH="/home/linuxbrew/.linuxbrew/opt/python@3.8/bin:$PATH"
export LDFLAGS="-L/home/linuxbrew/.linuxbrew/opt/python@3.8/lib"
export CPPFLAGS="-I/home/linuxbrew/.linuxbrew/opt/python@3.8/include"
export PKG_CONFIG_PATH="/home/linuxbrew/.linuxbrew/opt/python@3.8/lib/pkgconfig"
export PATH="/home/vermin/.gem/ruby/3.0.0/bin:$PATH"
# eval "$(perl -I$HOME/perl5/lib/perl5 -Mlocal::lib=$HOME/perl5)"

1.10.2. .bashrc

#
# ~/.bashrc
#


source $HOME/.profile
export GTK_IM_MODULE=ibus
export XMODIFIERS=@im=ibus
export QT_IM_MODULE=ibus

source /usr/share/nvm/init-nvm.sh
[ -z "$NVM_DIR" ] && export NVM_DIR="$HOME/.nvm"
source /usr/share/nvm/nvm.sh
source /usr/share/nvm/bash_completion
source /usr/share/nvm/install-nvm-exec

1.11. i3

I3 is my favorite WM, because it just works. I was also try other WM in the past. But now ticking with I3 is the best idea.

exec --no-startup-id ~/set_once_i3.sh
# This file is a modified version based on default i3-config-wizard config
# source is available here:
# https://raw.githubusercontent.com/endeavouros-team/endeavouros-i3wm-setup/master/.config/i3/config
# Maintainer: joekamprad [joekamprad@endeavouros.com]
# https://endeavouros.com
#
# iconic font icon search: https://fontawesome.com/v4.7/cheatsheet/
#
# --> to update this run the following command (will backup existing setup file)
# wget --backups=1 https://raw.githubusercontent.com/endeavouros-team/endeavouros-i3wm-setup/main/.config/i3/config -P ~/.config/i3/
#
# Endeavouros-i3 config file
# Source for complete framework of our i3 config and theming here: https://github.com/endeavouros-team/endeavouros-i3wm-setup
# EndeavourOS wiki holds some Information also: https://discovery.endeavouros.com/window-tiling-managers/i3-wm/
# Please see http://i3wm.org/docs/userguide.html for the official i3 reference!

#######################
# config starts here: #
#######################

# Font for window titles. Will also be used by the bar unless a different font
# is used in the bar {} block below.
# This font is widely installed, provides lots of unicode glyphs, right-to-left
# text rendering and scalability on retina/hidpi displays (thanks to pango).
font pango: Noto Sans Regular 10

# set the mod key to the winkey:
set $mod Mod4

#####################
# workspace layout: #
#####################

# default i3 tiling mode:
workspace_layout default

# i3 stacking layout:
# Each window will be fullscreen and tabbed top to bottom.
#workspace_layout stacking

# i3 tabbed layout:
# Each new window will open fullscreen as a tab (left to right)
#workspace_layout tabbed

##############################
# extra options for windows: #
##############################

#border indicator on windows:
# new_window pixel 1

# thin borders
# hide_edge_borders both

# Set inner/outer gaps
# gaps inner 6
# gaps outer 3

# show window title bars (not officially supported with i3gaps)
#default_border normal

# window title alignment
#title_align center

# Use Mouse+$mod to drag floating windows to their wanted position
floating_modifier $mod

# switch/iterate between workspaces
bindsym $mod+Tab workspace next
bindsym $mod+Shift+Tab workspace prev

# switch to workspace
bindsym $mod+1    workspace  $ws1
bindsym $mod+2    workspace  $ws2
bindsym $mod+3    workspace  $ws3
bindsym $mod+4    workspace  $ws4
bindsym $mod+5    workspace  $ws5
bindsym $mod+6    workspace  $ws6
bindsym $mod+7    workspace  $ws7
bindsym $mod+8    workspace  $ws8
bindsym $mod+9    workspace  $ws9
bindsym $mod+0    workspace  $ws10

# switch to workspace with numpad keys
bindcode $mod+87 workspace 1
bindcode $mod+88 workspace 2
bindcode $mod+89 workspace 3
bindcode $mod+83 workspace 4
bindcode $mod+84 workspace 5
bindcode $mod+85 workspace 6
bindcode $mod+79 workspace 7
bindcode $mod+80 workspace 8
bindcode $mod+81 workspace 9
bindcode $mod+90 workspace 10

# switch to workspace with numlock numpad keys
bindcode $mod+Mod2+87 workspace $ws1
bindcode $mod+Mod2+88 workspace $ws2
bindcode $mod+Mod2+89 workspace $ws3
bindcode $mod+Mod2+83 workspace $ws4
bindcode $mod+Mod2+84 workspace $ws5
bindcode $mod+Mod2+85 workspace $ws6
bindcode $mod+Mod2+79 workspace $ws7
bindcode $mod+Mod2+80 workspace $ws8
bindcode $mod+Mod2+81 workspace $ws9
bindcode $mod+Mod2+90 workspace $ws10

# move focused container to workspace
bindsym $mod+Shift+1    move container to workspace  $ws1
bindsym $mod+Shift+2    move container to workspace  $ws2
bindsym $mod+Shift+3    move container to workspace  $ws3
bindsym $mod+Shift+4    move container to workspace  $ws4
bindsym $mod+Shift+5    move container to workspace  $ws5
bindsym $mod+Shift+6    move container to workspace  $ws6
bindsym $mod+Shift+7    move container to workspace  $ws7
bindsym $mod+Shift+8    move container to workspace  $ws8
bindsym $mod+Shift+9    move container to workspace  $ws9
bindsym $mod+Shift+0    move container to workspace  $ws10

# move focused container to workspace with numpad keys
bindcode $mod+Shift+Mod2+87 	move container to workspace  $ws1
bindcode $mod+Shift+Mod2+88 	move container to workspace  $ws2
bindcode $mod+Shift+Mod2+89 	move container to workspace  $ws3
bindcode $mod+Shift+Mod2+83 	move container to workspace  $ws4
bindcode $mod+Shift+Mod2+84 	move container to workspace  $ws5
bindcode $mod+Shift+Mod2+85 	move container to workspace  $ws6
bindcode $mod+Shift+Mod2+79 	move container to workspace  $ws7
bindcode $mod+Shift+Mod2+80 	move container to workspace  $ws8
bindcode $mod+Shift+Mod2+81 	move container to workspace  $ws9
bindcode $mod+Shift+Mod2+90 	move container to workspace  $ws10

# move focused container to workspace with numpad keys
bindcode $mod+Shift+87 	 move container to workspace  $ws1
bindcode $mod+Shift+88 	 move container to workspace  $ws2
bindcode $mod+Shift+89 	 move container to workspace  $ws3
bindcode $mod+Shift+83 	 move container to workspace  $ws4
bindcode $mod+Shift+84 	 move container to workspace  $ws5
bindcode $mod+Shift+85 	 move container to workspace  $ws6
bindcode $mod+Shift+79 	 move container to workspace  $ws7
bindcode $mod+Shift+80 	 move container to workspace  $ws8
bindcode $mod+Shift+81 	 move container to workspace  $ws9
bindcode $mod+Shift+90 	 move container to workspace  $ws10

# resize window (you can also use the mouse for that):
#mode "resize" {
# These bindings trigger as soon as you enter the resize mode
# Pressing left will shrink the window's width.
# Pressing right will grow the window's width.
# Pressing up will shrink the window's height.
# Pressing down will grow the window's height.
#        bindsym j resize shrink width 10 px or 10 ppt
#        bindsym k resize grow height 10 px or 10 ppt
#        bindsym l resize shrink height 10 px or 10 ppt
#        bindsym ntilde resize grow width 10 px or 10 ppt

# same bindings, but for the arrow keys
#	bindsym Left resize shrink width 10 px or 10 ppt
#        bindsym Down resize grow height 10 px or 10 ppt
#        bindsym Up resize shrink height 10 px or 10 ppt
#        bindsym Right resize grow width 10 px or 10 ppt

# back to normal: Enter or Escape
#	bindsym Return mode "default"
#        bindsym Escape mode "default"
#}

#bindsym $mod+r mode "resize"

######################################
# keybindings for different actions: #
######################################

# start a terminal
bindsym $mod+Return exec kitty

# kill focused window
bindsym $mod+q kill

# exit-menu
bindsym $mod+Shift+e exec ~/.config/i3/scripts/powermenu

# Lock the system
# lock with a picture:
#bindsym $mod+l exec i3lock -i  ~/.config/i3/i3-lock-screen.png -p default|win -t
# lock by blurring the screen:
bindsym $mod+l exec ~/.config/i3/scripts/blur-lock

# reload the configuration file
bindsym $mod+Shift+c reload

# restart i3 inplace (preserves your layout/session, can be used to update i3)
bindsym $mod+Shift+r restart

# keybinding in fancy rofi (automated):
# bindsym F1 exec ~/.config/i3/scripts/keyhint-2
# alternative
# keybinding list in editor:
# bindsym $mod+F1 exec xed ~/.config/i3/keybindings

# Backlight control
bindsym XF86MonBrightnessUp exec xbacklight +5 && notify-send "Brightness - $(xbacklight -get | cut -c1-2)%"
bindsym XF86MonBrightnessDown exec xbacklight -5 && notify-send "Brightness - $(xbacklight -get | cut -c1-2)%"

# change focus
bindsym $mod+j focus left
bindsym $mod+k focus down
bindsym $mod+b focus up
bindsym $mod+o focus right

# alternatively, you can use the cursor keys:
bindsym $mod+Left focus left
bindsym $mod+Down focus down
bindsym $mod+Up focus up
bindsym $mod+Right focus right

# move focused window
bindsym $mod+Shift+j move left
bindsym $mod+Shift+k move down
bindsym $mod+Shift+b move up
bindsym $mod+Shift+o move right

# alternatively, you can use the cursor keys:
bindsym $mod+Shift+Left move left
bindsym $mod+Shift+Down move down
bindsym $mod+Shift+Up move up
bindsym $mod+Shift+Right move right

# split in horizontal orientation
bindsym $mod+h split h

# split in vertical orientation
bindsym $mod+v split v

# enter fullscreen mode for the focused container
bindsym $mod+f fullscreen toggle

# change container layout (stacked, tabbed, toggle split)
bindsym $mod+s layout stacking
bindsym $mod+g layout tabbed
bindsym $mod+e layout toggle split

# toggle tiling / floating
bindsym $mod+Shift+space floating toggle

# change focus between tiling / floating windows
bindsym $mod+space focus mode_toggle

# focus the parent container
bindsym $mod+a focus parent

# open new empty workspace
bindsym $mod+Shift+n exec ~/.config/i3/scripts/empty_workspace

# Multimedia Keys

# volume
bindsym XF86AudioRaiseVolume exec amixer -D pulse sset Master 5%+ && pkill -RTMIN+1 i3blocks
bindsym XF86AudioLowerVolume exec amixer -D pulse sset Master 5%- && pkill -RTMIN+1 i3blocks

# gradular volume control
bindsym $mod+XF86AudioRaiseVolume exec amixer -D pulse sset Master 1%+ && pkill -RTMIN+1 i3blocks
bindsym $mod+XF86AudioLowerVolume exec amixer -D pulse sset Master 1%- && pkill -RTMIN+1 i3blocks

# mute
bindsym XF86AudioMute exec amixer sset Master toggle && killall -USR1 i3blocks

# audio control
bindsym XF86AudioPlay exec playerctl play
bindsym XF86AudioPause exec playerctl pause
bindsym XF86AudioNext exec playerctl next
bindsym XF86AudioPrev exec playerctl previous

# Redirect sound to headphones
bindsym $mod+p exec /usr/local/bin/switch-audio-port

## App shortcuts
bindsym $mod+w exec /usr/bin/microsoft-edge-dev
bindsym $mod+n exec /usr/bin/thunar
bindsym Print exec scrot ~/%Y-%m-%d-%T-screenshot.png && notify-send "Screenshot saved to ~/$(date +"%Y-%m-%d-%T")-screenshot.png"

# Power Profiles menu switcher (rofi)
bindsym $mod+Shift+p exec ~/.config/i3/scripts/power-profiles

##########################################
# configuration for workspace behaviour: #
##########################################

# Define names for default workspaces for which we configure key bindings later on.
# We use variables to avoid repeating the names in multiple places.
set $ws1 "1:"
set $ws2 "2:"
set $ws3 "3:"
set $ws4 "4:"
set $ws5 "5:"
set $ws6 "6"
set $ws7 "7"
set $ws8 "8"
set $ws9 "9"
set $ws10 "10"

# use workspaces on different displays:
# where you have to replace VGA-0/HDMI-0 with the names for your displays
# you can get from xrandr command
#workspace $ws1 output VGA-0
#workspace $ws2 output VGA-0
#workspace $ws3 output HDMI-0
#workspace $ws4 output HDMI-0
#workspace $ws5 output HDMI-0

# bind program to workspace and focus to them on startup:
assign [class="kitty"] $ws1
assign [class="(?i)microsoft-edge-dev"] $ws2
assign [class="Thunar"] $ws3
assign [class="Thunderbird"] $ws4
assign [class="TelegramDesktop"] $ws5

# automatic set focus new window if it opens on another workspace then the current:
for_window [class=kitty] focus
for_window [class=(?i)microsoft-edge-dev] focus
for_window [class=Thunar] focus
for_window [class=Thunderbird] focus
for_window [class=TelegramDesktop] focus

##############
# compositor #
##############

# transparency
# uncomment one of them to be used (picom package is installed per default)
# options could need changes, related to used GPU and drivers.
# to find the right setting consult the archwiki or ask at the forum.
#
# xcompmgr: https://wiki.archlinux.org/title/Xcompmgr
# manpage: https://man.archlinux.org/man/xcompmgr.1.en
#exec --no-startup-id xcompmgr -C -n &
# or an more specialized config like this:
#exec --no-startup-id xcompmgr -c -C -t-5 -l-5 -r4.2 -o.55 &
#
# or:
#
# picom: https://wiki.archlinux.org/title/Picom
# manpage: https://man.archlinux.org/man/picom.1.en
# The default configuration is available in /etc/xdg/picom.conf
# For modifications, it can be copied to ~/.config/picom/picom.conf or ~/.config/picom.conf
#
# using default config
#exec_always --no-startup-id picom -b
#
# for custom config:
#exec_always --no-startup-id picom --config  ~/.config/picom.conf

#############################################
# autostart applications/services on login: #
#############################################

#get auth work with polkit-gnome
exec --no-startup-id /usr/lib/polkit-gnome/polkit-gnome-authentication-agent-1

# dex execute .desktop files + apps using /etc/xdg/autostart.
# when second to i3 a DE is installed or mixed usage of i3 + xfce4 or GNOME
# in this cases better disable dex and use manual starting apps using xdg/autostart
# if enabled you should comment welcome app.
# https://github.com/jceb/dex
#exec --no-startup-id dex -a -s /etc/xdg/autostart/:~/.config/autostart/
exec --no-startup-id dex --autostart --environment i3

# start welcome app
#exec --no-startup-id sh /usr/share/endeavouros/scripts/welcome --startdelay=3

# num lock activated
#exec --no-startup-id numlockx on

# configure multiple keyboard layouts and hotkey to switch (Alt+CAPSLOCK in this example)
#exec --no-startup-id setxkbmap -layout 'us,sk' -variant altgr-intl,qwerty -option 'grp:alt_caps_toggle'

# start conky:
#exec_always --no-startup-id conky

# start a script to setup displays
# uncomment the next line, use arandr to setup displays and save the file as monitor:
exec --no-startup-id ~/.screenlayout/monitor.sh

# set wallpaper
exec --no-startup-id sleep 2 && nitrogen --restore
#exec --no-startup-id feh --bg-fill /usr/share/endeavouros/backgrounds/endeavouros_i3.png

# set powersavings for display:
exec --no-startup-id xset s 480 dpms 600 600 600

# disable power saving (for example if using xscreensaver)
#exec --no-startup-id xset -dpms

# use xautolock to use autosuspend rules for mobile devices
# https://wiki.archlinux.org/title/Session_lock#xautolock
#exec --no-startup-id xautolock -time 60 -locker "systemctl suspend"


# xscreensaver
# https://www.jwz.org/xscreensaver
#exec --no-startup-id xscreensaver --no-splash

# Desktop notifications
exec --no-startup-id dbus-launch dunst --config ~/.config/dunst/dunstrc
# alternative if you installed aside with XFCE4:
# exec --no-startup-id /usr/lib/xfce4/notifyd/xfce4-notifyd &

# autotiling script
# https://github.com/nwg-piotr/autotiling
# `yay -S autotiling ;) (it is in AUR)
#exec_always --no-startup-id autotiling

# Autostart apps as you like
#exec --no-startup-id sleep 2 && xfce4-terminal
exec --no-startup-id sleep 7 && megasync
exec --no-startup-id sleep 9 && goldendict
exec --no-startup-id sleep 12 && appimage-launcherd
# exec --no-startup-id sleep 13 && dunst
# exec --no-startup-id sleep 14 && dunst motrix

#exec --no-startup-id sleep 3 && thunar

###############
# system tray #
###############
# if you do not use dex: exec --no-startup-id dex --autostart --environment i3
# you need to have tray apps started manually one by one:

# start blueberry app for managing bluetooth devices from tray:
#exec --no-startup-id blueberry-tray

# networkmanager-applet
#exec --no-startup-id nm-applet

# clipman-applet
#exec --no-startup-id xfce4-clipman

##################
# floating rules #
##################

# set floating (nontiling) for apps needing it
for_window [class="Yad" instance="yad"] floating enable
for_window [class="Galculator" instance="galculator"] floating enable
for_window [class="Blueberry.py" instance="blueberry.py"] floating enable

# set floating (nontiling) for special apps
for_window [class="Xsane" instance="xsane"] floating enable
for_window [class="Pavucontrol" instance="pavucontrol"] floating enable
for_window [class="qt5ct" instance="qt5ct"] floating enable
for_window [class="Blueberry.py" instance="blueberry.py"] floating enable
for_window [class="Bluetooth-sendto" instance="bluetooth-sendto"] floating enable
for_window [class="Pamac-manager"] floating enable
for_window [window_role="About"] floating enable

# set border of floating window
for_window [class="urxvt"] border pixel 1

# set size of floating window
#for_window [window_role="(?i)GtkFileChooserDialog"] resize set 640 480 #to set size of file choose dialog
#for_window [class=".*"] resize set 640 480 #to change size of all floating windows

# set position of floating window
#for_window [class=".*"] move position center

######################################
# color settings for bar and windows #
######################################

# Define colors variables:
set $darkbluetrans	#08052be6
set $darkblue		#08052b
set $lightblue		#5294e2
set $urgentred		#e53935
set $white		#ffffff
set $black		#000000
set $purple		#e345ff
set $darkgrey		#383c4a
set $grey		#b0b5bd
set $mediumgrey		#8b8b8b
set $yellowbrown	#e1b700

# define colors for windows:
#class		        	border		bground		text		indicator	child_border
client.focused		    $lightblue	$darkblue	$white		$purple		$mediumgrey
client.unfocused	    $darkblue	$darkblue	$grey		$purple		$darkgrey
client.focused_inactive	$darkblue	$darkblue	$grey		$purple		$black
client.urgent		    $urgentred	$urgentred	$white		$purple		$yellowbrown

############################################
# bar settings (input comes from i3blocks) #
############################################

# Start i3bar to display a workspace bar
# (plus the system information i3status finds out, if available)
bar {
font pango: Noto Sans Regular 10
status_command i3blocks -c ~/.config/i3/i3blocks.conf
position bottom
#	    	i3bar_command i3bar --transparency
# it could be that you have no primary display set: set one (xrandr --output <output> --primary)
# reference: https://i3wm.org/docs/userguide.html#_tray_output
tray_output primary
tray_padding 0

# When strip_workspace_numbers is set to yes,
# any workspace that has a name of the form
# “[n][:][NAME]” will display only the name.
strip_workspace_numbers yes
##strip_workspace_name no

colors {
separator          $purple
background         $darkgrey
statusline         $white
#                          		border 		        bg		txt		indicator
focused_workspace	$mediumgrey	   	$grey		$darkgrey	$purple
active_workspace	$lightblue      	$mediumgrey	$darkgrey	$purple
inactive_workspace	$darkgrey   		$darkgrey	$grey		$purple
urgent_workspace	$urgentred	    	$urgentred	$white		$purple
}
}

# you can add different bars for multidisplay setups on each display:
# set output HDMI-0 to the display you want the bar, --transparency can be set.
# Transparency needs rgba color codes to be used where the last two letters are the transparency factor see here:
# https://gist.github.com/lopspower/03fb1cc0ac9f32ef38f4
# #08052be6 --> e6=90%

# bar {
#	font pango: Noto Sans Regular 10
#	status_command i3blocks -c ~/.config/i3/i3blocks-2.conf
#	i3bar_command i3bar --transparency
#	output HDMI-0
#	position bottom
#
# When strip_workspace_numbers is set to yes,
# any workspace that has a name of the form
# “[n][:][NAME]” will display only the name.
#strip_workspace_numbers yes
##strip_workspace_name no
#
#	colors {
#		separator          $purple
#		background         $darkbluetrans
#        	statusline         $white
#					border		bg		txt		indicator
#		focused_workspace	$lighterblue	$lighterblue	$darkblue	$purple
#		active_workspace	$lightdblue	$lightdblue	$darkblue	$purple
#		inactive_workspace	$darkblue	$darkblue	$lightdblue	$purple
#		urgent_workspace	$urgentred	$urgentred	$white		$purple
#	}
#}



bindsym $mod+d exec krunner
# bindsym F9 exec rofi -modi drun -show drun \
# 		-config ~/.config/rofi/rofidmenu.rasi


bindsym $mod+z exec rofi -show window \
-config ~/.config/rofi/rofidmenu.rasi

## rofi bindings to manage clipboard (install rofi-greenclip from the AUR)

exec --no-startup-id greenclip daemon>/dev/null
bindsym $mod+c exec --no-startup-id rofi -modi "clipboard:greenclip print" -show clipboard \
-config ~/.config/rofi/rofidmenu.rasi
for_window [class="^.*"] border pixel 1

1.11.1. i3block bottom

# i3blocks config file changed for EndeavourOS-i3 setup

# source is available here:
# https://raw.githubusercontent.com/endeavouros-team/endeavouros-i3wm-setup/main/.config/i3/i3blocks.conf
# Maintainer: joekamprad [joekamprad@endeavouros.com]
# Former Visual Designer: Florent Valetti [@FLVAL EndeavourOS]
# created for i3wm setup on EndeavourOS
# https://endeavouros.com

# cheatsheet for icon fonts used on the block-bar:
# https://fontawesome.com/v4.7/cheatsheet/

# --> to update this run the following command:
# wget --backups=1 https://raw.githubusercontent.com/endeavouros-team/endeavouros-i3wm-setup/main/.config/i3/i3blocks.conf -P ~/.config/i3/

# Please see man i3blocks for a complete reference!
# The man page is also hosted at http://vivien.github.io/i3blocks


# List of valid properties:
#
# align
# color
# command
# full_text
# instance
# interval
# label
# min_width
# name
# separator
# separator_block_width
# short_text
# signal
# urgent

# Global properties
#
# The top properties below are applied to every block, but can be overridden.
separator=false
markup=pango

#[Weather]
#command=~/.config/i3/scripts/openweather
# or:
#command=~/.config/i3/scripts/openweather-city
#interval=1800
#color=#7275b3

[terminal]
full_text= 
color=#807dfe
command=i3-msg -q exec kitty

[browser]
full_text= 
color=#2544bb
command=i3-msg -q exec microsoft-edge-dev

[files]
full_text= 
color=#7f3fbf
command=i3-msg -q exec thunar ~/

[mail]
full_text= 
color=#dbcb75
command=i3-msg -q exec thunderbird

[simple-2]
full_text=: :
color=#717171

# Disk usage
#
# The directory defaults to $HOME if the instance is not specified.
# The script may be called with a optional argument to set the alert
# (defaults to 10 for 10%).
[disk]
label=
instance=/
command=~/.config/i3/scripts/disk
interval=30

# Memory usage
#
# The type defaults to "mem" if the instance is not specified.
[memory]
label=
command=~/.config/i3/scripts/memory
interval=2

[cpu_usage]
label=
command=~/.config/i3/scripts/cpu_usage
#min_width=CPU: 100.00%
interval=2

[CPU-temperature]
label=
command=~/.config/i3/scripts/temperature
interval=30
#T_WARN=70
#T_CRIT=90
#SENSOR_CHIP=""
# where SENSOR_CHIP can be find with sensors output
# can be used also for GPU temperature or other temperature sensors lm-sensors detects.

# showing name of connected network (enable for wifi use)
#[net]
#label=
#command=echo "$(LANG=C nmcli d | grep connected  | awk '{print $4}')"
#interval=30

[bandwidth]
command=~/.config/i3/scripts/bandwidth2
interval=persist

# Battery indicator
[battery]
command=~/.config/i3/scripts/battery2
# for alternative battery script  change to battery1
# change this to battery-pinebook-pro if you are running on pinebook-pro
label=
interval=30

[simple-2]
full_text=: :
color=#717171

[pavucontrol]
full_text=
command=pavucontrol

[volume-pulseaudio]
command=~/.config/i3/scripts/volume
instance=Master
interval=1

# display keyboard layout name
# for keyboard layouts switcher
# see i3 config file
#[keyboard-layout]
#command=~/.config/i3/scripts/keyboard-layout
#interval=2

[keybindings]
full_text=
command=~/.config/i3/scripts/keyhint

#set power-profile
[ppd_menu]
full_text=
command=~/.config/i3/scripts/power-profiles
color=#407437

#Show the current power-profile
[ppd-status]
command=~/.config/i3/scripts/ppd-status
interval=5

[time]
label= 
command=date '+%a %d %b %H:%M:%S'
interval=1

[shutdown_menu]
full_text=
command=~/.config/i3/scripts/powermenu

[simple-2]
full_text=: :
color=#717171

1.12. Neo vim

God, I love vim hacker, they are so attractive in someway, but I rarely use Vim

"script to auto download and install vim plug{{{
if empty(glob('~/.local/share/nvim/site/autoload/plug.vim'))
silent !curl -fLo ~/.local/share/nvim/site/autoload/plug.vim --create-dirs
\ https://raw.githubusercontent.com/junegunn/vim-plug/master/plug.vim
autocmd VimEnter * PlugInstall --sync | source $MYVIMRC
endif"}}}
"Begin with fold{{{
augroup filetype_vim
autocmd!
autocmd FileType vim setlocal foldmethod=marker
autocmd FileType vim highlight Folded guibg=green
autocmd FileType vim highlight Folded ctermbg=green

" autocmd FileType vim set foldclose=all
" set foldopen=all
autocmd FileType vim set foldcolumn=1
augroup END
"}}}
" other setting {{{{
"default shell
" set shell=/bin/fish
"auto remove traitling space and line
" background
autocmd BufWritePre * %s/\s\+$//e
" command! TraitlingRemove :%s/\s\+$//e
set encoding=utf-8
set noendofline
" set binary
set fileencoding=utf-8
set guifont=hack:h13
" set guifont=DroidSansMono\ Nerd\ Font:h12
" set guifont=Source\ Code\ Pro\ for\ Powerline:h13:cANSI
set ignorecase
set wildmenu
" set nocom
"auto change tab to space, show show hidden character and change back space to
"tab
set tabstop=4 shiftwidth=4 expandtab
set number
set relativenumber
" Turn on syntax highlighting.
syntax on
" set statusline=%F%m%r%h%w\ [FORMAT=%{&ff}]\ [TYPE=%Y]\ [POS=%l,%v][%p%%]\ [BUFFER=%n]\ %{strftime('%c')}
set completeopt+=preview
set completeopt+=menuone,noselect
" set shortmess+=c   " Shut off completion messages

set hidden
" let g:racer_cmd = "~/.cargo/bin/racer"
" let g:racer_experimental_completer = 1
" let g:racer_insert_paren = 1
" Highlight vim regrex
set hlsearch | set incsearch

set mouse=a
set clipboard=unnamedplus

"quick calculate expression in vim
ino <C-A> <C-O>yiW<End>=<C-R>=<C-R>0<CR>

set timeoutlen=3000
" }}}
"All plugged in vim {{{
" for install plug.vim the best but minimalist vim plugin manager
" curl -fLo ~/.vim/autoload/plug.vim --create-dirs \
"    https://raw.githubusercontent.com/junegunn/vim-plug/master/plug.vim
call plug#begin(stdpath('data') . '/plugged')

" Plug 'ervandew/supertab'
" Gdb in vim
Plug 'cpiger/NeoDebug'
"Better repeat with dot key
Plug 'tpope/vim-repeat'
" Plug 'rhysd/vim-grammarous'
" A plugin make vim act like a blank page for focus writting
Plug 'junegunn/goyo.vim'
" Enchanted floaterm, it is core feature make neovim-tmux like a fully hacking evironment
Plug 'voldikss/vim-floaterm'
" Plug 'vimlab/split-term.vim'
" I dont like it too much, it just like denite or fzf
" Plug 'liuchengxu/vim-clap'
" Must have for any vim-hacker, it will better if it have auto wrap like
" paredit
Plug 'jiangmiao/auto-pairs'
" auto-pair for lisp filetype
Plug 'vim-scripts/paredit.vim'
"Fish shell plug
" Plug 'dag/vim-fish'
"Sudo in vim
Plug 'lambdalisue/suda.vim'
"Auto resize window in vim
Plug 'zhaocai/GoldenView.Vim'
"  slime lisp in vim{{{
" Plug 'kovisoft/slimv'
"Slimv config
" let g:slimv_swank_cmd = "!ros -e '(ql:quickload :swank) (swank:create-server)' wait &"
let g:slimv_lisp = '~/.roswell/impls/x86-64/linux/sbcl/2.0.6/bin/sbcl'
" let gLslimv_lisp = '~/impls/x86-64/linux/ccl-bin/1.12/scripts/ccl'
" let g:slimv_lisp = 'ros run'
" let g:slimv_impl = 'ccl'
" let g:slimv_echolines=-1
" let g:slimv_balloon=1
" let g:slimv_repl_split=4
" let g:lisp_rainbow=1
" let g:slimv_ctags ='ctags -R'

" function! Smart_TabComplete(){{{
"   let line = getline('.')                         " current line

"   let substr = strpart(line, -1, col('.')+1)      " from the start of the current
"                                                   " line to one character right
"                                                   " of the cursor
"   let substr = matchstr(substr, "[^ \t]*$")       " word till cursor
"   if (strlen(substr)==0)                          " nothing to match on empty string
"     return "\<tab>"
"   endif
"   let has_period = match(substr, '\.') != -1      " position of period, if any
"   let has_slash = match(substr, '\/') != -1       " position of slash, if any
"   if (!has_period && !has_slash)
"     return "\<C-X>\<C-P>"                         " existing text matching
"   elseif ( has_slash )
"     return "\<C-X>\<C-F>"                         " file matching
"   else
"     return "\<C-X>\<C-O>"                         " plugin matching
"   endif
" endfunction
" autocmd filetype lisp inoremap <tab> <c-r>=Smart_TabComplete()<CR>
" filetype plugin on
" set omnifunc=syntaxcomplete#Complete}}}
" let g:slimv_browser_cmd = "w3m"
"lisp mode Emacs
Plug 'eraserhd/parinfer-rust'
function LispInit()

set foldmethod=marker

endfunction
autocmd filetype lisp,ros call LispInit()
" autocmd BufReadPost *lisp,*ros call SlimvConnectServer()

"}}}
" Plug 'kien/rainbow_parentheses.vim'
" Most mordern rainbow parentheses
Plug 'luochen1990/rainbow'
"For ledger, counting plug
Plug 'ledger/vim-ledger'
"Go in vim{{{
Plug 'fatih/vim-go', { 'do': ':GoUpdateBinaries' }

let g:go_code_completion_enabled = 0
let g:go_play_browser_command = 'w3m %URL%'
let g:go_get_update = 0
"USe recursive map because <PLug>Go- is combine of serveral key
function GoMApping()
nmap <LocalLeader>R <Plug>(go-run)
nmap <LocalLeader>r :GoRun %<CR>
nmap <LocalLeader>b <Plug>(go-buid)
nmap <LocalLeader>i <Plug>(go-info)
nmap <LocalLeader>h <Plug>(go-doc)
nmap <LocalLeader>s <Plug>(go-describe)
nmap <LocalLeader>H <Plug>(go-doc-browser)
endfunction
autocmd FileType go call GoMApping()
autocmd BufNewFile,BufReadPost *.go let maplocalleader = ","

" Plug 'nsf/gocode', { 'rtp': 'nvim', 'do': '~/.local/share/nvim/plugged/gocode/nvim/symlink.sh' }}}}
" Plug 'ryanoasis/vim-devicons'
" A themes
Plug 'wadackel/vim-dogrun'
"Themes
Plug 'yassinebridi/vim-purpura'
"Undo trees
Plug 'mbbill/undotree'
"Themes
Plug 'rhysd/vim-color-spring-night'
"A hacking feature for fzf in vim{{{
Plug 'junegunn/fzf'
Plug 'junegunn/fzf.vim'
" [Buffers] Jump to the existing window if possible
let g:fzf_buffers_jump = 1

" [[B]Commits] Customize the options used by 'git log':
let g:fzf_commits_log_options = '--graph --color=always --format="%C(auto)%h%d %s %C(black)%C(bold)%cr"'

" [Tags] Command to generate tags file
" let g:fzf_tags_command = 'ctags -R'

" [Commands] --expect expression for directly executing the command
let g:fzf_commands_expect = 'alt-enter,ctrl-x'

nnoremap <leader>TB :BTags<CR>
"mean project -Recursive tags
noremap <leader>TR :Tags<CR>
"}}}
"  hacking auto complete and LCS in node for vim{{{
Plug 'neoclide/coc.nvim', {'branch': 'release'}
Plug 'SirVer/ultisnips'
" Plug 'Shougo/neosnippet.vim'
" Plug 'Shougo/neosnippet-snippets'
Plug 'honza/vim-snippets'
let g:UltiSnipsSnippetDirectories=["~/ultisnips/"]

"Coc-config

" TextEdit might fail if hidden is not set.
set hidden

" Some servers have issues with backup files, see #649.
set nobackup
set nowritebackup

" Give more space for displaying messages.
set cmdheight=2

" Having longer updatetime (default is 4000 ms = 4 s) leads to noticeable
" delays and poor user experience.
set updatetime=2000

" Don't pass messages to |ins-completion-menu|.
set shortmess+=c

" Always show the signcolumn, otherwise it would shift the text each time
" diagnostics appear/become resolved.
if has("patch-8.1.1564")
" Recently vim can merge signcolumn and number column into one
set signcolumn=number
else
set signcolumn=yes
endif



" Use tab for trigger completion with characters ahead and navigate.
" NOTE: Use command ':verbose imap <tab>' to make sure tab is not mapped by
" other plugin before putting this into your config.

" implementation
inoremap <silent><expr> <TAB>
\ pumvisible() ? "\<C-n>" :
\ <SID>check_back_space() ? "\<TAB>" :
\ coc#refresh()
inoremap <expr><S-TAB> pumvisible() ? "\<C-p>" : "\<C-h>"

function! s:check_back_space() abort
let col = col('.') - 1
return !col || getline('.')[col - 1]  =~# '\s'
endfunction

" Use <c-space> to trigger completion.
inoremap <silent><expr> <c-space> coc#refresh()

" Use <cr> to confirm completion, `<C-g>u` means break undo chain at current
" position. Coc only does snippet and additional edit on confirm.
" <cr> could be remapped by other vim plugin, try `:verbose imap <CR>`.
if exists('*complete_info')
inoremap <expr> <cr> complete_info()["selected"] != "-1" ? "\<C-y>" : "\<C-g>u\<CR>"
else
inoremap <expr> <cr> pumvisible() ? "\<C-y>" : "\<C-g>u\<CR>"
endif

" Use `[g` and `]g` to navigate diagnostics
" Use `:CocDiagnostics` to get all diagnostics of current buffer in location list.
nmap <silent> [g <Plug>(coc-diagnostic-prev)
nmap <silent> ]g <Plug>(coc-diagnostic-next)

" GoTo code navigation.
nmap <silent> <leader>cd <Plug>(coc-definition)
nmap <silent> <leader>ctd <Plug>(coc-type-definition)
nmap <silent> <leader>ci <Plug>(coc-implementation)
nmap <silent> <leader>cr <Plug>(coc-references)

" Use K to show documentation in preview window.
nnoremap <silent> <leader>s :call <SID>show_documentation()<CR>

function! s:show_documentation()
if (index(['vim','help'], &filetype) >= 0)
execute 'h '.expand('<cword>')
else
call CocAction('doHover')
endif
endfunction

" Highlight the symbol and its references when holding the cursor.
autocmd CursorHold * silent call CocActionAsync('highlight')

" Symbol renaming.
nmap <leader>crn <Plug>(coc-rename)

" Formatting selected code.
" vmap <leader>c=  <Plug>(coc-format-selected)
" nmap <leader>c=  <Plug>(coc-format-selected)

augroup ShitGroup
autocmd!
" Setup formatexpr specified filetype(s).
autocmd FileType typescript,json setl formatexpr=CocAction('formatSelected')
" Update signature help on jump placeholder.
autocmd User CocJumpPlaceholder call CocActionAsync('showSignatureHelp')
augroup end

" Applying codeAction to the selected region.
" Example: `<leader>aap` for current paragraph
xmap <leader>cas  <Plug>(coc-codeaction-selected)
nmap <leader>cas  <Plug>(coc-codeaction-selected)

" Remap keys for applying codeAction to the current buffer.
nmap <leader>cca  <Plug>(coc-codeaction)
" Apply AutoFix to problem on the current line.
nmap <leader>cfc  <Plug>(coc-fix-current)

" Map function and class text objects
" NOTE: Requires 'textDocument.documentSymbol' support from the language server.
xmap <leader>cfi <Plug>(coc-funcobj-i)
omap <leader>cfi <Plug>(coc-funcobj-i)
xmap <leader>cfa <Plug>(coc-funcobj-a)
omap <leader>cfa <Plug>(coc-funcobj-a)
xmap <leader>cci <Plug>(coc-classobj-i)
omap <leader>cci <Plug>(coc-classobj-i)
xmap <leader>cca <Plug>(coc-classobj-a)
omap <leader>cca <Plug>(coc-classobj-a)

" Use CTRL-S for selections ranges.
" Requires 'textDocument/selectionRange' support of LS, ex: coc-tsserver
nmap <silent> <C-s> <Plug>(coc-range-select)
xmap <silent> <C-s> <Plug>(coc-range-select)

" Add `:Format` command to format current buffer.
command! -nargs=0 Format :call CocAction('format')

" Add `:Fold` command to fold current buffer.
command! -nargs=? Fold :call     CocAction('fold', <f-args>)

" Add `:OR` command for organize imports of the current buffer.
command! -nargs=0 OR   :call     CocAction('runCommand', 'editor.action.organizeImport')

" Add (Neo)Vim's native statusline support.
" NOTE: Please see `:h coc-status` for integrations with external plugins that
" provide custom statusline: lightline.vim, vim-airline.
set statusline^=%{coc#status()}%{get(b:,'coc_current_function','')}

" Mappings for CoCList
" Show all diagnostics.
"
nnoremap <silent><nowait> <leader>cld  :<C-u>CocList diagnostics<cr>
" Manage extensions.
nnoremap <silent><nowait> <leader>cle  :<C-u>CocList extensions<cr>
" Show commands.
nnoremap <silent><nowait> <leader>clc  :<C-u>CocList commands<cr>
" Find symbol of current document.
nnoremap <silent><nowait> <leader>clo  :<C-u>CocList outline<cr>
" Search workspace symbols.
nnoremap <silent><nowait> <leader>cls  :<C-u>CocList -I symbols<cr>
" Do default action for next item.
nnoremap <silent><nowait> <leader>cj  :<C-u>CocNext<CR>
" Do default action for previous item.
nnoremap <silent><nowait> <leader>ck  :<C-u>CocPrev<CR>
" Resume latest coc list.
nnoremap <silent><nowait> <leader>p  :<C-u>CocListResume<CR>"}}}

"Cocsnip{{{
function g:CocSnip ()
" Use <C-l> for trigger snippet expand.
imap <C-l> <Plug>(coc-snippets-expand)

" Use <C-j> for select text for visual placeholder of snippet.
vmap <C-j> <Plug>(coc-snippets-select)

" Use <C-j> for jump to next placeholder, it's default of coc.nvim
let g:coc_snippet_next = '<c-j>'

" Use <C-k> for jump to previous placeholder, it's default of coc.nvim
let g:coc_snippet_prev = '<c-k>'

" Use <C-j> for both expand and jump (make expand higher priority.)

imap <C-j> <Plug>(coc-snippets-expand-jump)


inoremap <silent><expr> <TAB>
\ pumvisible() ? coc#_select_confirm() :
\ coc#expandableOrJumpable() ? "\<C-r>=coc#rpc#request('doKeymap', ['snippets-expand-jump',''])\<CR>" :
\ <SID>check_back_space() ? "\<TAB>" :
\ coc#refresh()

function! s:check_back_space() abort
let col = col('.') - 1
return !col || getline('.')[col - 1]  =~# '\s'
endfunction

let g:coc_snippet_next = '<tab>'
endfunction

augroup CocSnipGroup
autocmd!
"Must excute after all plugin, use vimenter
autocmd VimEnter * call CocSnip()
augroup"}}}

" Tmux!!!!!
Plug 'christoomey/vim-tmux-navigator'
" Plug 'chiel92/vim-autoformat'
" Plug 'terryma/vim-multiple-cursors'
" Plug 'dense-analysis/ale'
" Plug 'skywind3000/asyncrun.vim'
" Beautiful bottom-bar and tabar
Plug 'vim-airline/vim-airline'
" Statusbar-airline config {{{

" beautiful status bar

let g:airline_powerline_fonts = 1
let g:airline_extensions = ['branch', 'tabline']
let g:airline#extensions#tabline#fnamemod = ':p:.'
let g:airline#extensions#tabline#fnamecollapse = 1
" let g:airline_left_sep = "\ue0b4"
" let g:airline_right_sep = "\ue0b6"
" }}}
" Plug 'wlemuel/vim-tldr'
" Plug 'tpope/vim-liquid'
" Must have for  comentarry
Plug 'tpope/vim-commentary'
" Plug 'lifepillar/vim-mucomplete'
" Plug 'scrooloose/nerdtree' , { 'on':  'NERDTreeToggle' }
" Plug 'rhysd/vim-clang-format'
"Plug 'vim-scripts/c.vim'
"Plug 'rip-rip/clang_complete'
" Plug 'python-mode/python-mode', { 'for': 'python', 'branch': 'develop' }
Plug 'neomake/neomake'
" Plug 'pangloss/vim-javascript'
" Hacking tagbar{{{
Plug 'majutsushi/tagbar'
nnoremap <leader>TT :TagbarToggle<CR>
let g:tagbar_left = 1
let g:tagbar_autofocus = 1
" let g:tagbar_autopreview = 1
" let g:tagbar_previewwin_pos = "aboveleft"
"}}}
"Hacking surround
Plug 'tpope/vim-surround'
" Plug 'liuchengxu/vim-which-key'
" Vimwiki
Plug 'vimwiki/vimwiki'
Plug 'mattn/calendar-vim'
let g:vimwiki_folding='list'
let g:vimwiki_table_mappings = 0

"Vimwiki config {{{2
let g:vimwiki_use_calendar = 1
"}}}2
Plug 'godlygeek/tabular'
Plug 'plasticboy/vim-markdown'
"  html generator
Plug 'rstacruz/sparkup'
" Plug 'ap/vim-css-color'
" Rust in vim
Plug 'rust-lang/rust.vim'
" Plug 'phildawes/racer'
Plug 'racer-rust/vim-racer'
" Plug 'itchyny/calendar.vim'
" Plug 'davidhalter/jedi-vim'
Plug 'markonm/traces.vim'
" Themes
Plug 'vim-scripts/greenvision'
Plug 'tbabej/taskwiki'
Plug 'powerman/vim-plugin-AnsiEsc'
" Plug 'terryma/vim-multiple-cursors'
"Vim-mux  REPL{{{
Plug 'benmills/vimux'
" config for vimux
nnoremap <Leader>vr :call VimuxOpenRunner()<CR>
function! VimuxSend()
call VimuxSendText(@v)
call VimuxSendKeys("Enter")
endfunction

vnoremap <Leader>e "vy :call VimuxSend()<CR>
nnoremap <Leader>e ^v$h"vy :call VimuxSend()<CR>
nnoremap <Leader>v- :call VimuxInterruptRunner()<CR>
map <Leader>vp :VimuxPromptCommand<CR>
map <Leader>vi :VimuxInspectRunner<CR>
map <leader>vx :VimuxCloseRunner<CR>
let g:VimuxOrientation = "h"
let g:VimuxHeight = "40"
let g:VimuxUseNearest = 1
"}}}
"  session manager{{{
Plug 'xolox/vim-session'
let g:session_directory='.local/share/nvim/sessions'
let g:session_autosave='yes'
Plug 'xolox/vim-misc'
nnoremap <leader>OS :OpenSession
"}}}
""tag intelligent managerment
Plug 'ludovicchabant/vim-gutentags'
let g:gutentags_enabled=1
"Handmake plug
" Plug 'git@github.com:Kidman1670/io-lang.vim.git'
" For io a little but smart prog language
Plug '~/git/io.vim/io.vim/'
Plug 'dbeniamine/cheat.sh-vim'
"  text-obj for vim
Plug 'kana/vim-textobj-user'
Plug 'kana/vim-textobj-function'
Plug 'kana/vim-textobj-line'
Plug 'kana/vim-textobj-indent'
" Indent plugin
Plug 'yggdroot/indentline'

" let g:indentLine_setColors = 1
Plug 'Chiel92/vim-autoformat'
"
"" Vim

let g:indentLine_bgcolor_term = 000
let g:indentLine_bgcolor_gui = '#000000'
" Extend objecg movement in vim
Plug 'Kidman1670/targets.vim'
Plug 'easymotion/vim-easymotion'
nmap <leader>s <Plug>(easymotion-s)
vmap <leader>s <Plug>(easymotion-s)
nmap 2s <Plug>(easymotion-s2)
vmap 2s <Plug>(easymotion-s2)
"for keymap
Plug 'rlue/vim-barbaric'
" Plug 'justinmk/vim-sneak'
" Plug 'Kidman1670/vim-textobj-function'
" Template for all vim file, should use handmake fork repo
Plug 'https://github.com/Kidman1670/vim-template.git'

Plug 'vlime/vlime', {'rtp': 'vim/'}
autocmd FileType lisp inoremap <A-tab> <C-X><C-O>
let g:vlime_window_settings = {
\ "sldb": {
\ "pos": "botright",
\ "size": 60,
\ "vertical" : v:true
\ }
\ }
let g:vlime_overlay = "slimv"
" switch between window{{{
let i = 1
while i <= 9
execute 'nnoremap <Leader>' . i . ' :' . i . 'wincmd w<CR>'
let i = i + 1
endwhile
"}}}
" function Lisp_omni_complete()
"     if ft=lisp
"     inoremap <tab> <C-X><C-O>
" endfunction
" autocmd BufEnter

call plug#end()
"}}}
" Shell of floaterm{{{
let g:floaterm_shell="fish"
" }}}
"Rainbow{{{
let g:rainbow_active = 1 "set to 0 if you want to enable it later via :RainbowToggl}}}
"money management ledger{{{
let g:ledger_fillstring = '    -'
let g:ledger_detailed_first = 1
let g:ledger_fold_blanks = 1
let g:ledger_winpos = 'R'
"}}}



" set color syntax
autocmd BufNewFile,BufRead *.fish set syntax=fish

"Key map {{{
"
"remap escape to double leader
" imap <leader><leader> <Esc>
" map <leader>!!R :Repl<CR>
" map <leader>e :FloatermSend --name=repl<Cr>
" tnoremap <leader>WQ <C-\><C-n>:TmuxNavigatePrevious<CR>
" map <leader>!!T :Term<CR>
" let g:floaterm_keymap_prev   = '<leader>WE'
" " let g:floaterm_keymap_next   = '<F9>'
let g:floaterm_keymap_toggle = '<leader>WW'
let g:floaterm_keymap_kill = '<leader>WK'
" let g:floaterm_keymap_new = '<leader>WN'
" for paredit{{{
nmap ,LW <S-v>,W"}}}
let g:goldenview__enable_default_mapping = 0
nnoremap <leader>UT :UndotreeToggle<cr>
map <leader>hi :History<CR>
map <Leader>ft :Files<CR>
map <Leader>FT :Vifm<CR>
map <Leader>RG :Rg<CR>
map <Leader>/ :BLines<CR>
let g:tmux_navigator_no_mappings = 1
nnoremap <silent> <C-h> :TmuxNavigateLeft<cr>
nnoremap <silent> <C-j> :TmuxNavigateDown<cr>
nnoremap <silent>  <C-k> :TmuxNavigateUp<cr>
nnoremap <silent> <C-l> :TmuxNavigateRight<cr>
" USe leader 1,2,3,4 to move between window
nnoremap <silent> <leader>1 : TmuxNavigateLeft<cr>
nnoremap <silent> <leader>2 : TmuxNavigateDown<cr>
nnoremap <silent> <leader>3 : TmuxNavigateUp<cr>
nnoremap <silent> <leader>4 : TmuxNavigateRight<cr>
" noremap <F3> :Autoformat<CR>
inoremap <expr> <CR> pumvisible() ? "\<C-y>" : "\<C-g>u\<CR>"
" noremap <F4> :NERDTreeToggle<CR>
":nmap <M-+> <Plug>VimwikiIncrementListItem
":vmap <M-+> <Plug>VimwikiIncrementListItem
":nmap <M--> <Plug>VimwikiDecrementListItem
":vmap <M--> <Plug>VimwikiDecrementListItem
map <leader>da      :r !date<CR>A<space>
map! <leader>da <esc>:r !date<CR>A<space>
nnoremap <C-n> :bnext<CR>
nnoremap <C-p> :bprevious<CR>
nnoremap <A-j> :m .+1<CR>==
nnoremap <A-k> :m .-2<CR>==
inoremap <A-j> <Esc>:m .+1<CR>==gi
inoremap <A-k> <Esc>:m .-2<CR>==gi
vnoremap <A-j> :m '>+1<CR>gv=gv
vnoremap <A-k> :m '<-2<CR>gv=gv
" Define mappings
" nnoremap <silent><buffer><expr> <CR>
"             \ denite#do_map('do_action')
" nnoremap <silent><buffer><expr> d
"             \ denite#do_map('do_action', 'delete')
" nnoremap <silent><buffer><expr> p
"             \ denite#do_map('do_action', 'preview')
" nnoremap <silent><buffer><expr> q
"             \ denite#do_map('quit')
" nnoremap <silent><buffer><expr> i
"             \ denite#do_map('open_filter_buffer')
" nnoremap <silent><buffer><expr> <Space>
"             \ denite#do_map('toggle_select').'j'
nnoremap <F3> "=strftime("%Y/%m/%d")<CR>P
inoremap <F3> <C-R>=strftime("%Y/%m/%d")<CR>
"My handmake mapping
" map <leader>ft :NERDTreeToggle<CR>
map <leader>bt :Buffers<CR>
map <leader>cd :cd %:h<CR>
"list all register
noremap <leader>@r :registers<CR>

"golden dick
noremap <leader>z viw"xy:!goldendict <C-r>x<CR>
"}}}
"command {{{
"
command! ShowHiddenChar  set listchars=eol:$,tab:>-,trail:~,space:~ | set list
command! StopShowHidden set nolist
command! TabConvert     %s/\s\s\s\s/\t/g
command! Vifm FloatermNew vifm
command! Lazy FloatermNew lazygit
command! Repl FloatermNew  --wintype=normal --name=repl --position=right --width=0.5
command! Term FloatermNew --wintype=normal --name=bot-term --position=bottom --height=0.3
command! Sudo e suda://%

" too long didnot read in vim, but better use in commandline
"}}}
"Filytype {{{
"
filetype plugin on
filetype plugin indent on
au FileType lisp let b:AutoPairs = {'(':')', '[':']', '{':'}',"'":"",'"':'"', '`':''}
" autocmd FileType python set completeopt-=preview
autocmd FileType denite call s:denite_my_settings()
" Set the filetype based on the file's extension, overriding any
" 'filetype' that has already been set
au BufRead,BufNewFile *.fish set filetype=fish
"}}}
" source filez {{{
" source ~/.config/nvim/testing.vim
"}}}
"
"Colorscheme must load after all others {{{
colorscheme greenvision
set background=dark
set termguicolors
"}}}
"Testing{{{
"
" After vimenter script
hi CocCursorRange guibg=#b16286 guifg=#ebdbb2

nmap <C-x> <Plug>(coc-cursors-position)
nmap <C-w> <Plug>(coc-cursors-word)
xmap <C-x> <Plug>(coc-cursors-range)
" use normal command like `<leader>xi(`
nmap <leader>x  <Plug>(coc-cursors-operator)


augroup TaskwikiInit
autocmd!
autocmd FileType vimwiki noremap <leader>gt :VimwikiChangeSymbolTo * [ ]<CR>
autocmd FileType vimwiki vnoremap <leader>gt :VimwikiChangeSymbolTo * [ ]<CR>
augroup END
"Vim quick calculate 'zuper caculater'{{{
vnoremap <silent> <leader>zc c<C-O>"=<C-R>"<CR>P}}}
" split window{{{
noremap <silent> <leader>w- :split<CR>
inoremap <silent> <leader>w- <C-O>:split<CR>

noremap <silent> <leader>w= :vsplit<CR>
inoremap <silent> <leader>w= <C-O>:vsplit<CR>"}}}
"Keymap for ledger-cli{{{
function LedgerKeymap()
noremap <leader>lb :!ledger -f % balance<CR>
noremap <leader>
noremap { ?^\d<CR>
noremap } /^\d<CR>
noremap <leader>lr :call ledger#entry()<CR>
noremap <leader>la :%call ledger#align_commodity()<CR>
endfunction

autocmd FileType ledger,ldg call LedgerKeymap()"}}}
"
autocmd BufWritePre *.go :call CocAction('runCommand', 'editor.action.organizeImport')

augroup C_style
autocmd!
autocmd FileType c let g:surround_64 = "\1function: \1\{\n\r\n\}"
autocmd FileType c command! Run :!%:p:r
autocmd FileType c set makeprg=make\ %:p:r
augroup END
" }}}
"
" Handmake abbrev{{{
iabbrev mysign kidman1670@gmail.com
" iabbrev --- ------------------------------------------------------------------------------------------
iabbrev === ==========================================================================================
iabbrev intro_ <CR>
\==========================================================================================
\<CR>author:
\<CR>shit:
\<CR>==========================================================================================

"}}}
"

1.13. Tmux

1.13.1. Tmux.conf remote


# default shell on tmux
set -g default-shell /bin/fish

1.13.2. Tmux.conf.local

# https://github.com/gpakosz/.tmux
#         without any warranty.


# -- navigation ----------------------------------------------------------------

# if you're running tmux within iTerm2
#   - and tmux is 1.9 or 1.9a
#   - and iTerm2 is configured to let option key act as +Esc
#   - and iTerm2 is configured to send [1;9A -> [1;9D for option + arrow keys
# then uncomment the following line to make Meta + arrow keys mapping work
#set -ga terminal-overrides "*:kUP3=\e[1;9A,*:kDN3=\e[1;9B,*:kRIT3=\e[1;9C,*:kLFT3=\e[1;9D"


# -- windows & pane creation ---------------------------------------------------

# new window retains current path, possible values are:
#   - true
#   - false (default)
tmux_conf_new_window_retain_current_path=true

# new pane retains current path, possible values are:
#   - true (default)
#   - false
tmux_conf_new_pane_retain_current_path=true

# new pane tries to reconnect ssh sessions (experimental), possible values are:
#   - true
#   - false (default)
tmux_conf_new_pane_reconnect_ssh=false

# prompt for session name when creating a new session, possible values are:
#   - true
#   - false (default)
tmux_conf_new_session_prompt=false


# -- display -------------------------------------------------------------------

# RGB 24-bit colour support (tmux >= 2.2), possible values are:
#  - true
#  - false (default)
# tmux_conf_theme_24b_colour=true

# window style
tmux_conf_theme_window_fg='default'
tmux_conf_theme_window_bg='default'

# highlight focused pane (tmux >= 2.1), possible values are:
#   - true
#   - false (default)
tmux_conf_theme_highlight_focused_pane=false

# focused pane colours:
tmux_conf_theme_focused_pane_fg='default'
tmux_conf_theme_focused_pane_bg='#0087d7'               # light blue

# pane border style, possible values are:
#   - thin (default)
#   - fat
tmux_conf_theme_pane_border_style=thin

# pane borders colours:
tmux_conf_theme_pane_border='#444444'                   # gray
tmux_conf_theme_pane_active_border='#00afff'            # light blue

# pane indicator colours
tmux_conf_theme_pane_indicator='#00afff'                # light blue
tmux_conf_theme_pane_active_indicator='#00afff'         # light blue

# status line style
tmux_conf_theme_message_fg='#000000'                    # black
tmux_conf_theme_message_bg='#ffff00'                    # yellow
tmux_conf_theme_message_attr='bold'

# status line command style (<prefix> : Escape)
tmux_conf_theme_message_command_fg='#ffff00'            # yellow
tmux_conf_theme_message_command_bg='#000000'            # black
tmux_conf_theme_message_command_attr='bold'

# window modes style
tmux_conf_theme_mode_fg='#000000'                       # black
tmux_conf_theme_mode_bg='#ffff00'                       # yellow
tmux_conf_theme_mode_attr='bold'

# status line style
tmux_conf_theme_status_fg='#8a8a8a'                     # light gray
tmux_conf_theme_status_bg='#080808'                     # dark gray
tmux_conf_theme_status_attr='none'

# terminal title
#   - built-in variables are:
#     - #{circled_window_index}
#     - #{circled_session_name}
#     - #{hostname}
#     - #{hostname_ssh}
#     - #{username}
#     - #{username_ssh}

# window status style
#   - built-in variables are:
#     - #{circled_window_index}
#     - #{circled_session_name}
#     - #{hostname}
#     - #{hostname_ssh}
#     - #{username}
#     - #{username_ssh}
tmux_conf_theme_window_status_fg='#8a8a8a'              # light gray
tmux_conf_theme_window_status_bg='#080808'              # dark gray
tmux_conf_theme_window_status_attr='none'
tmux_conf_theme_window_status_format='#I #W'
#tmux_conf_theme_window_status_format='#{circled_window_index} #W'

# window current status style
#   - built-in variables are:
#     - #{circled_window_index}
#     - #{circled_session_name}
#     - #{hostname}
#     - #{hostname_ssh}
#     - #{username}
#     - #{username_ssh}
tmux_conf_theme_window_status_current_fg='#000000'      # black
tmux_conf_theme_window_status_current_bg='#00afff'      # light blue
tmux_conf_theme_window_status_current_attr='bold'
tmux_conf_theme_window_status_current_format='#I #W'
#tmux_conf_theme_window_status_current_format='#{circled_window_index} #W'

# window activity status style
tmux_conf_theme_window_status_activity_fg='default'
tmux_conf_theme_window_status_activity_bg='default'
tmux_conf_theme_window_status_activity_attr='underscore'

# window bell status style
tmux_conf_theme_window_status_bell_fg='#ffff00'         # yellow
tmux_conf_theme_window_status_bell_bg='default'
tmux_conf_theme_window_status_bell_attr='blink,bold'

# window last status style
tmux_conf_theme_window_status_last_fg='#00afff'         # light blue
tmux_conf_theme_window_status_last_bg='default'
tmux_conf_theme_window_status_last_attr='none'

# status left/right sections separators
tmux_conf_theme_left_separator_main=''
tmux_conf_theme_left_separator_sub='|'
tmux_conf_theme_right_separator_main=''
tmux_conf_theme_right_separator_sub='|'
#tmux_conf_theme_left_separator_main='\uE0B0'  # /!\ you don't need to install Powerline
#tmux_conf_theme_left_separator_sub='\uE0B1'   #   you only need fonts patched with
#tmux_conf_theme_right_separator_main='\uE0B2' #   Powerline symbols or the standalone
#tmux_conf_theme_right_separator_sub='\uE0B3'  #   PowerlineSymbols.otf font, see README.md

# status left/right content:
#   - separate main sections with '|'
#   - separate subsections with ','
#   - built-in variables are:
#     - #{battery_bar}
#     - #{battery_hbar}
#     - #{battery_percentage}
#     - #{battery_status}
#     - #{battery_vbar}
#     - #{circled_session_name}
#     - #{hostname_ssh}
#     - #{hostname}
#     - #{loadavg}
#     - #{pairing}
#     - #{prefix}
#     - #{root}
#     - #{synchronized}
#     - #{uptime_y}
#     - #{uptime_d} (modulo 365 when #{uptime_y} is used)
#     - #{uptime_h}
#     - #{uptime_m}
#     - #{uptime_s}
#     - #{username}
#     - #{username_ssh}
tmux_conf_theme_status_right='#{prefix}#{pairing}#{synchronized} #{?battery_status, #{battery_status},}#{?battery_bar, #{battery_bar},}#{?battery_percentage, #{battery_percentage},} , %R , %d %b | #{username}#{root} | #{hostname} '

# status left style
tmux_conf_theme_status_left_fg='#000000,#e4e4e4,#e4e4e4'  # black, white , white
tmux_conf_theme_status_left_bg='#ffff00,#ff00af,#00afff'  # yellow, pink, white blue
tmux_conf_theme_status_left_attr='bold,none,none'

# status right style
tmux_conf_theme_status_right_fg='#8a8a8a,#e4e4e4,#000000' # light gray, white, black
tmux_conf_theme_status_right_bg='#080808,#d70000,#e4e4e4' # dark gray, red, white
tmux_conf_theme_status_right_attr='none,none,bold'

# pairing indicator
tmux_conf_theme_pairing_fg='none'
tmux_conf_theme_pairing_bg='none'
tmux_conf_theme_pairing_attr='none'

# prefix indicator
tmux_conf_theme_prefix_fg='none'
tmux_conf_theme_prefix_bg='none'
tmux_conf_theme_prefix_attr='none'

# root indicator
tmux_conf_theme_root='!'
tmux_conf_theme_root_fg='none'
tmux_conf_theme_root_bg='none'
tmux_conf_theme_root_attr='bold,blink'

# synchronized indicator
tmux_conf_theme_synchronized_fg='none'
tmux_conf_theme_synchronized_bg='none'
tmux_conf_theme_synchronized_attr='none'

# battery bar symbols

# battery bar length (in number of symbols), possible values are:
#   - auto
#   - a number, e.g. 5
tmux_conf_battery_bar_length='auto'

# battery bar palette, possible values are:
#   - gradient (default)
#   - heat
#   - 'colour_full_fg,colour_empty_fg,colour_bg'
tmux_conf_battery_bar_palette='gradient'
#tmux_conf_battery_bar_palette='#d70000,#e4e4e4,#000000'   # red, white, black

# battery hbar palette, possible values are:
#   - gradient (default)
#   - heat
#   - 'colour_low,colour_half,colour_full'
tmux_conf_battery_hbar_palette='gradient'
#tmux_conf_battery_hbar_palette='#d70000,#ff5f00,#5fff00'  # red, orange, green

# battery vbar palette, possible values are:
#   - gradient (default)
#   - heat
#   - 'colour_low,colour_half,colour_full'
tmux_conf_battery_vbar_palette='gradient'
#tmux_conf_battery_vbar_palette='#d70000,#ff5f00,#5fff00'  # red, orange, green

# symbols used to indicate whether battery is charging or discharging

# clock style (when you hit <prefix> + t)
# you may want to use %I:%M %p in place of %R in tmux_conf_theme_status_right
tmux_conf_theme_clock_colour='#00afff'  # light blue
tmux_conf_theme_clock_style='24'


# -- clipboard -----------------------------------------------------------------

# in copy mode, copying selection also copies to the OS clipboard
#   - true
#   - false (default)
# on macOS, this requires installing reattach-to-user-namespace, see README.md
# on Linux, this requires xsel or xclip
tmux_conf_copy_to_os_clipboard=true


# -- user customizations -------------------------------------------------------
# this is the place to override or undo settings

# increase history size
set -g history-limit 10000

# start with mouse mode enabled
set -g mouse on

# force Vi mode
#   really you should export VISUAL or EDITOR environment variable, see manual
set -g status-keys vi
set -g mode-keys vi

# replace C-b by C-a instead of using both prefixes
# set -gu prefix2
# unbind C-a
# unbind C-b
# set -g prefix C-a
# bind C-a send-prefix

# move status line to top
#set -g status-position top

# tmux-pane-border
# set -g pane-border-status bottom
# set -g pane-border-format "#{pane_tty} #{pane-index} #{command} #{pane_current_path}   #{window_name}"


1.14. IdeaVimrc

"" Source your .vimrc
source ~/.vimrc
source ~/.config/nvim/init.vim
"source ~/.intellimacs/spacemacs.vim
"source ~/.intellimacs/extra.vim
" (Optional) Enable which-key plugin
"source ~/.intellimacs/which-key.vim

"" -- Suggested options --
" Show a few lines of context around the cursor. Note that this makes the
" text scroll if you mouse-click near the start or end of the window.
set scrolloff=5
imap fd <Esc>
nmap fd <Esc>
vmap fd <Esc>


" (Optional) Comma for major mode
"nmap , <leader>m
"vmap , <leader>m

" (Optional) Add/edit actions
"nnoremap <leader>gl    :action Vcs.Show.Log<CR>
"vnoremap <leader>gl    :action Vcs.Show.Log<CR>

" Do incrementa searching.
set incsearch

" Don't use Ex mode, use Q for formatting.
map Q gq


"" -- Map IDE actions to IdeaVim -- https://jb.gg/abva4t
"" Map \r to the Reformat Code action
"map \r <Action>(ReformatCode)

"" Map <leader>d to start debug
"map <leader>d <Action>(Debug)

"" Map \b to toggle the breakpoint on the current line
"map \b <Action>(ToggleLineBreakpoint)


" Find more examples here: https://jb.gg/share-ideavimrc
set commentary
set surround
" set which-key

set surround
set argtextobj
set textobj-entire
set matchitset ideajoin

1.15. w3m-setting

tabstop 8
indent_incr 4
pixel_per_char 14
pixel_per_line 16
frame 0
target_self 0
open_tab_blank 0
open_tab_dl_list 0
display_link 1
display_link_number 0
decode_url 0
display_lineinfo 0
ext_dirlist 1
dirlist_cmd file:///$LIB/dirlist.cgi
use_dictcommand 1
dictcommand file:///$LIB/w3mdict.cgi
multicol 1
alt_entity 0
graphic_char 0
display_borders 1
fold_textarea 0
display_ins_del 0
ignore_null_img_alt 1
view_unseenobject 0
display_image 1
pseudo_inlines 1
auto_image 1
max_load_image 4
ext_image_viewer 1
image_scale 100
imgdisplay w3mimgdisplay
image_map_list 1
fold_line 0
show_lnum 0
show_srch_str 1
label_topline 0
nextpage_topline 0
color 1
basic_color terminal
anchor_color blue
image_color green
form_color red
mark_color cyan
bg_color terminal
active_style 1
active_color cyan
visited_anchor 0
visited_color magenta
pagerline 10000
use_history 1
history 100
save_hist 1
confirm_qq 1
close_tab_back 0
mark 0
emacs_like_lineedit 0
vi_prec_num 0
mark_all_pages 0
wrap_search 1
ignorecase_search 1
use_mouse 0
reverse_mouse 0
relative_wheel_scroll 0
relative_wheel_scroll_ratio 30
fixed_wheel_scroll_count 5
clear_buffer 1
decode_cte 0
auto_uncompress 0
preserve_timestamp 1
keymap_file keymap
document_root
personal_document_root
cgi_bin
index_file
mime_types ~/.mime.types, /usr/etc/mime.types
mailcap ~/.w3m/mailcap, /usr/etc/w3m/mailcap
urimethodmap ~/.w3m/urimethodmap, /usr/etc/w3m/urimethodmap
editor /usr/bin/vi
mailto_options 1
mailer /usr/bin/mail
extbrowser /usr/bin/firefox
extbrowser2
extbrowser3
extbrowser4
extbrowser5
extbrowser6
extbrowser7
extbrowser8
extbrowser9
bgextviewer 1
use_lessopen 0
passwd_file ~/.w3m/passwd
disable_secret_security_check 0
ftppasswd
ftppass_hostnamegen 1
pre_form_file ~/.w3m/pre_form
siteconf_file ~/.w3m/siteconf
user_agent
no_referer 0
accept_language en;q=1.0
accept_encoding gzip, compress, bzip, bzip2, deflate
accept_media text/html, text/*;q=0.5, image/*
argv_is_url 1
retry_http 1
default_url 1
follow_redirection 10
meta_refresh 0
dns_order 0
nntpserver
nntpmode
max_news 50
use_proxy 1
http_proxy
https_proxy
ftp_proxy
no_proxy
noproxy_netaddr 1
no_cache 0
ssl_forbid_method 2, 3
ssl_verify_server 1
ssl_cert_file
ssl_key_file
ssl_ca_path
ssl_ca_file
use_cookie 1
show_cookie 0
accept_cookie 1
accept_bad_cookie 0
cookie_reject_domains
cookie_accept_domains
cookie_avoid_wrong_number_of_dots
display_charset UTF-8
document_charset UTF-8
auto_detect 2
system_charset UTF-8
follow_locale 1
ext_halfdump 0
use_wide 1
use_combining 1
east_asian_width 0
use_language_tag 1
ucs_conv 1
pre_conv 0
search_conv 1
fix_width_conv 1
use_gb12345_map 0
use_jisx0201 0
use_jisc6226 0
use_jisx0201k 0
use_jisx0212 0
use_jisx0213 0
strict_iso2022 1
gb18030_as_ucs 0
simple_preserve_space 0

1.16. Fisher

edc/bass
jethrokuan/z
danhper/fish-ssh-agent
jorgebucaran/autopair.fish
IlanCosman/tide
franciscolourenco/done

1.17. Zsh

eval "$(starship init zsh)"

export ZSH="$HOME/.oh-my-zsh"
export EDITOR="nvim"

ZSH_THEME=""

plugins=(vi-mode z gcloud git sudo docker  autojump zsh-autosuggestions  tmux tmuxinator ssh-agent urltools)

source $ZSH/oh-my-zsh.sh

export PATH="$PATH:$HOME/.cargo/bin:/home/vermin/bin/:$HOME/bin/:$HOME/go/bin/:/$HOME/.gem/ruby/2.7.0/bin/:$HOME/.local/bin/"
export BROWSER=/usr/bin/w3m
alias p="pier"
alias c="clear"
alias ls="exa"
alias ll="exa -al"
alias la="exa -a"
alias l="exa -l"
alias lt="exa --tree"
alias v="nvim"
alias vim="nvim"
alias myip='curl ipinfo.io'
alias t="task"
alias tl="task list"
alias tsa="task $1 start"
alias tsp="task $1 stop"

1.18. Script

All the script I had written

1.18.1. emacs-eshell-toggle.sh

emacsclient  -c -e "(call-interactively #'eshell)"

1.18.2. emacs-vterm-toggle.sh

emacsclient  -c -e "(call-interactively #'vterm)"

1.18.3. emacs-capture-code

~/.emacs.d/bin/org-capture -k "c"

1.18.4. emacs-capture-link.sh

~/.emacs.d/bin/org-capture -k "l"

1.18.5. emacs-caoture-markdown.sh

~/.emacs.d/bin/org-capture -k "m"
set -x
fullpath=$(realpath $1)
filename=$(basename "$fullpath")
base=$(basename "$filename" .jar)
ext="${filename/#$base}"

if [ ! "${ext}" == ".jar" ]; then
    echo "Only work with jar file"
    exit 1
fi


if [ ! "$(command "native-image")" ]; then
    echo "Install native-image please or graalvm not in your PATH"
    exit 1
fi

mkdir native

native-image --initialize-at-build-time  --no-server  --no-fallback  -jar "${fullpath}" -H:Name=native/"${base}"

1.18.6. log-notify-send.sh

logfile=$1

dbus-monitor "interface='org.freedesktop.Notifications'" |\
    grep --line-buffered "string" |\
    grep --line-buffered -e method -e ":" -e '""' -e urgency -e notify -v |\
    grep --line-buffered '.*(?=string)|(?<=string).*' -oPi |\
    grep --line-buffered -v '^\s*$' |\
    xargs -I '{}' \
    printf "---$( date )---\n"{}"\n" >> $logfile

1.18.7. join-two-double-lines.vim

:%!cat -s

1.19. Kitty config

# vim:fileencoding=utf-8:ft=conf:foldmethod=marker

#: Fonts {{{

#: kitty has very powerful font management. You can configure
#: individual font faces and even specify special fonts for particular
#: characters.

font_family      JetBrains Mono Medium
bold_font        JetBrains Mono Bold
italic_font      JetBrains Mono Italic
bold_italic_font JetBrains Mono Bold Italic

#: You can specify different fonts for the bold/italic/bold-italic
#: variants. To get a full list of supported fonts use the `kitty
#: list-fonts` command. By default they are derived automatically, by
#: the OSes font system. Setting them manually is useful for font
#: families that have many weight variants like Book, Medium, Thick,
#: etc. For example::

#:     font_family      Operator Mono Book
#:     bold_font        Operator Mono Medium
#:     italic_font      Operator Mono Book Italic
#:     bold_italic_font Operator Mono Medium Italic

font_size 12.0

#: Font size (in pts)

adjust_line_height  92%
# adjust_column_width 0

#: Change the size of each character cell kitty renders. You can use
#: either numbers, which are interpreted as pixels or percentages
#: (number followed by %), which are interpreted as percentages of the
#: unmodified values. You can use negative pixels or percentages less
#: than 100% to reduce sizes (but this might cause rendering
#: artifacts).

# symbol_map U+E0A0-U+E0A2,U+E0B0-U+E0B3 PowerlineSymbols

#: Map the specified unicode codepoints to a particular font. Useful
#: if you need special rendering for some symbols, such as for
#: Powerline. Avoids the need for patched fonts. Each unicode code
#: point is specified in the form U+<code point in hexadecimal>. You
#: can specify multiple code points, separated by commas and ranges
#: separated by hyphens. symbol_map itself can be specified multiple
#: times. Syntax is::

#:     symbol_map codepoints Font Family Name

# disable_ligatures never

#: Choose how you want to handle multi-character ligatures. The
#: default is to always render them.  You can tell kitty to not render
#: them when the cursor is over them by using cursor to make editing
#: easier, or have kitty never render them at all by using always, if
#: you don't like them. The ligature strategy can be set per-window
#: either using the kitty remote control facility or by defining
#: shortcuts for it in kitty.conf, for example::

#:     map alt+1 disable_ligatures_in active always
#:     map alt+2 disable_ligatures_in all never
#:     map alt+3 disable_ligatures_in tab cursor

# box_drawing_scale 0.001, 1, 1.5, 2

#: Change the sizes of the lines used for the box drawing unicode
#: characters These values are in pts. They will be scaled by the
#: monitor DPI to arrive at a pixel value. There must be four values
#: corresponding to thin, normal, thick, and very thick lines.

#: }}}

#: Cursor customization {{{

# cursor #ffd17f

#: Default cursor color

# cursor_text_color background

#: Choose the color of text under the cursor. If you want it rendered
#: with the background color of the cell underneath instead, use the
#: special keyword: background

# cursor_shape block

#: The cursor shape can be one of (block, beam, underline)

# cursor_blink_interval -1

#: The interval (in seconds) at which to blink the cursor. Set to zero
#: to disable blinking. Negative values mean use system default. Note
#: that numbers smaller than repaint_delay will be limited to
#: repaint_delay.

# cursor_stop_blinking_after 15.0

#: Stop blinking cursor after the specified number of seconds of
#: keyboard inactivity.  Set to zero to never stop blinking.

#: }}}

#: Scrollback {{{

# scrollback_lines 2000

#: Number of lines of history to keep in memory for scrolling back.
#: Memory is allocated on demand. Negative numbers are (effectively)
#: infinite scrollback. Note that using very large scrollback is not
#: recommended as it can slow down resizing of the terminal and also
#: use large amounts of RAM.

# scrollback_pager less --chop-long-lines --RAW-CONTROL-CHARS +INPUT_LINE_NUMBER

#: Program with which to view scrollback in a new window. The
#: scrollback buffer is passed as STDIN to this program. If you change
#: it, make sure the program you use can handle ANSI escape sequences
#: for colors and text formatting. INPUT_LINE_NUMBER in the command
#: line above will be replaced by an integer representing which line
#: should be at the top of the screen.

# scrollback_pager_history_size 0

#: Separate scrollback history size, used only for browsing the
#: scrollback buffer (in MB). This separate buffer is not available
#: for interactive scrolling but will be piped to the pager program
#: when viewing scrollback buffer in a separate window. The current
#: implementation stores one character in 4 bytes, so approximatively
#: 2500 lines per megabyte at 100 chars per line. A value of zero or
#: less disables this feature. The maximum allowed size is 4GB.

# wheel_scroll_multiplier 5.0

#: Modify the amount scrolled by the mouse wheel. Note this is only
#: used for low precision scrolling devices, not for high precision
#: scrolling on platforms such as macOS and Wayland. Use negative
#: numbers to change scroll direction.

# touch_scroll_multiplier 1.0

#: Modify the amount scrolled by a touchpad. Note this is only used
#: for high precision scrolling devices on platforms such as macOS and
#: Wayland. Use negative numbers to change scroll direction.

#: }}}

#: Mouse {{{

# mouse_hide_wait 0.0

#: Hide mouse cursor after the specified number of seconds of the
#: mouse not being used. Set to zero to disable mouse cursor hiding.
#: Set to a negative value to hide the mouse cursor immediately when
#: typing text. Disabled by default on macOS as getting it to work
#: robustly with the ever-changing sea of bugs that is Cocoa is too
#: much effort.

# url_color #0087bd
# url_style curly

#: The color and style for highlighting URLs on mouse-over. url_style
#: can be one of: none, single, double, curly

# open_url_modifiers kitty_mod

#: The modifier keys to press when clicking with the mouse on URLs to
#: open the URL

# open_url_with default

#: The program with which to open URLs that are clicked on. The
#: special value default means to use the operating system's default
#: URL handler.

# copy_on_select no

#: Copy to clipboard or a private buffer on select. With this set to
#: clipboard, simply selecting text with the mouse will cause the text
#: to be copied to clipboard. Useful on platforms such as macOS that
#: do not have the concept of primary selections. You can instead
#: specify a name such as a1 to copy to a private kitty buffer
#: instead. Map a shortcut with the paste_from_buffer action to paste
#: from this private buffer. For example::

#:     map cmd+shift+v paste_from_buffer a1

#: Note that copying to the clipboard is a security risk, as all
#: programs, including websites open in your browser can read the
#: contents of the system clipboard.

# strip_trailing_spaces never

#: Remove spaces at the end of lines when copying to clipboard. A
#: value of smart will do it when using normal selections, but not
#: rectangle selections. always will always do it.

# rectangle_select_modifiers ctrl+alt

#: The modifiers to use rectangular selection (i.e. to select text in
#: a rectangular block with the mouse)

# terminal_select_modifiers shift

#: The modifiers to override mouse selection even when a terminal
#: application has grabbed the mouse

# select_by_word_characters :@-./_~?&=%+#

#: Characters considered part of a word when double clicking. In
#: addition to these characters any character that is marked as an
#: alphanumeric character in the unicode database will be matched.

# click_interval -1.0

#: The interval between successive clicks to detect double/triple
#: clicks (in seconds). Negative numbers will use the system default
#: instead, if available, or fallback to 0.5.

# focus_follows_mouse no

#: Set the active window to the window under the mouse when moving the
#: mouse around

# pointer_shape_when_grabbed arrow

#: The shape of the mouse pointer when the program running in the
#: terminal grabs the mouse. Valid values are: arrow, beam and hand

#: }}}

#: Performance tuning {{{

# repaint_delay 10

#: Delay (in milliseconds) between screen updates. Decreasing it,
#: increases frames-per-second (FPS) at the cost of more CPU usage.
#: The default value yields ~100 FPS which is more than sufficient for
#: most uses. Note that to actually achieve 100 FPS you have to either
#: set sync_to_monitor to no or use a monitor with a high refresh
#: rate. Also, to minimize latency when there is pending input to be
#: processed, repaint_delay is ignored.

# input_delay 3

#: Delay (in milliseconds) before input from the program running in
#: the terminal is processed. Note that decreasing it will increase
#: responsiveness, but also increase CPU usage and might cause flicker
#: in full screen programs that redraw the entire screen on each loop,
#: because kitty is so fast that partial screen updates will be drawn.

# sync_to_monitor yes

#: Sync screen updates to the refresh rate of the monitor. This
#: prevents tearing (https://en.wikipedia.org/wiki/Screen_tearing)
#: when scrolling. However, it limits the rendering speed to the
#: refresh rate of your monitor. With a very high speed mouse/high
#: keyboard repeat rate, you may notice some slight input latency. If
#: so, set this to no.

#: }}}

#: Terminal bell {{{

# enable_audio_bell yes

#: Enable/disable the audio bell. Useful in environments that require
#: silence.

# visual_bell_duration 0.0

#: Visual bell duration. Flash the screen when a bell occurs for the
#: specified number of seconds. Set to zero to disable.

# window_alert_on_bell yes

#: Request window attention on bell. Makes the dock icon bounce on
#: macOS or the taskbar flash on linux.

# bell_on_tab yes

#: Show a bell symbol on the tab if a bell occurs in one of the
#: windows in the tab and the window is not the currently focused
#: window

# command_on_bell none

#: Program to run when a bell occurs.

#: }}}

#: Window layout {{{

# remember_window_size  yes
# initial_window_width  640
# initial_window_height 400

#: If enabled, the window size will be remembered so that new
#: instances of kitty will have the same size as the previous
#: instance. If disabled, the window will initially have size
#: configured by initial_window_width/height, in pixels. You can use a
#: suffix of "c" on the width/height values to have them interpreted
#: as number of cells instead of pixels.

# enabled_layouts *

#: The enabled window layouts. A comma separated list of layout names.
#: The special value all means all layouts. The first listed layout
#: will be used as the startup layout. For a list of available
#: layouts, see the
#: https://sw.kovidgoyal.net/kitty/index.html#layouts.

# window_resize_step_cells 2
# window_resize_step_lines 2

#: The step size (in units of cell width/cell height) to use when
#: resizing windows. The cells value is used for horizontal resizing
#: and the lines value for vertical resizing.

# window_border_width 1.0

#: The width (in pts) of window borders. Will be rounded to the
#: nearest number of pixels based on screen resolution. Note that
#: borders are displayed only when more than one window is visible.
#: They are meant to separate multiple windows.

# draw_minimal_borders yes

#: Draw only the minimum borders needed. This means that only the
#: minimum needed borders for inactive windows are drawn. That is only
#: the borders that separate the inactive window from a neighbor. Note
#: that setting a non-zero window margin overrides this and causes all
#: borders to be drawn.

# window_margin_width 0.0

#: The window margin (in pts) (blank area outside the border)

# single_window_margin_width -1000.0

#: The window margin (in pts) to use when only a single window is
#: visible. Negative values will cause the value of
#: window_margin_width to be used instead.

# window_padding_width 0.0

#: The window padding (in pts) (blank area between the text and the
#: window border)

# placement_strategy center

#: When the window size is not an exact multiple of the cell size, the
#: cell area of the terminal window will have some extra padding on
#: the sides. You can control how that padding is distributed with
#: this option. Using a value of center means the cell area will be
#: placed centrally. A value of top-left means the padding will be on
#: only the bottom and right edges.

# active_border_color #00ff00

#: The color for the border of the active window. Set this to none to
#: not draw borders around the active window.

# inactive_border_color #cccccc

#: The color for the border of inactive windows

# bell_border_color #ff5a00

#: The color for the border of inactive windows in which a bell has
#: occurred

# inactive_text_alpha 1.0

#: Fade the text in inactive windows by the specified amount (a number
#: between zero and one, with zero being fully faded).

# hide_window_decorations no

#: Hide the window decorations (title-bar and window borders). Whether
#: this works and exactly what effect it has depends on the window
#: manager/operating system.

# resize_debounce_time 0.1

#: The time (in seconds) to wait before redrawing the screen when a
#: resize event is received. On platforms such as macOS, where the
#: operating system sends events corresponding to the start and end of
#: a resize, this number is ignored.

# resize_draw_strategy static

#: Choose how kitty draws a window while a resize is in progress. A
#: value of static means draw the current window contents, mostly
#: unchanged. A value of scale means draw the current window contents
#: scaled. A value of blank means draw a blank window. A value of size
#: means show the window size in cells.

#: }}}

#: Tab bar {{{

# tab_bar_edge bottom

#: Which edge to show the tab bar on, top or bottom

# tab_bar_margin_width 0.0

#: The margin to the left and right of the tab bar (in pts)

# tab_bar_style fade

#: The tab bar style, can be one of: fade, separator, powerline, or
#: hidden. In the fade style, each tab's edges fade into the
#: background color, in the separator style, tabs are separated by a
#: configurable separator, and the powerline shows the tabs as a
#: continuous line.

# tab_bar_min_tabs 2

#: The minimum number of tabs that must exist before the tab bar is
#: shown

# tab_switch_strategy previous

#: The algorithm to use when switching to a tab when the current tab
#: is closed. The default of previous will switch to the last used
#: tab. A value of left will switch to the tab to the left of the
#: closed tab. A value of last will switch to the right-most tab.

# tab_fade 0.25 0.5 0.75 1

#: Control how each tab fades into the background when using fade for
#: the tab_bar_style. Each number is an alpha (between zero and one)
#: that controls how much the corresponding cell fades into the
#: background, with zero being no fade and one being full fade. You
#: can change the number of cells used by adding/removing entries to
#: this list.

# tab_separator " ┇"

#: The separator between tabs in the tab bar when using separator as
#: the tab_bar_style.

# tab_title_template {title}

#: A template to render the tab title. The default just renders the
#: title. If you wish to include the tab-index as well, use something
#: like: {index}: {title}. Useful if you have shortcuts mapped for
#: goto_tab N.

# active_tab_title_template none

#: Template to use for active tabs, if not specified falls back to
#: tab_title_template.

# active_tab_foreground   #000
# active_tab_background   #eee
# active_tab_font_style   bold-italic
# inactive_tab_foreground #444
# inactive_tab_background #999
# inactive_tab_font_style normal

#: Tab bar colors and styles

# tab_bar_background none

#: Background color for the tab bar. Defaults to using the terminal
#: background color.

#: }}}

#: Color scheme {{{

foreground #f0fdff
background #2a2e38

#: The foreground and background colors

# background_opacity 1.0

#: The opacity of the background. A number between 0 and 1, where 1 is
#: opaque and 0 is fully transparent.  This will only work if
#: supported by the OS (for instance, when using a compositor under
#: X11). Note that it only sets the default background color's
#: opacity. This is so that things like the status bar in vim,
#: powerline prompts, etc. still look good.  But it means that if you
#: use a color theme with a background color in your editor, it will
#: not be rendered as transparent.  Instead you should change the
#: default background color in your kitty config and not use a
#: background color in the editor color scheme. Or use the escape
#: codes to set the terminals default colors in a shell script to
#: launch your editor.  Be aware that using a value less than 1.0 is a
#: (possibly significant) performance hit.  If you want to dynamically
#: change transparency of windows set dynamic_background_opacity to
#: yes (this is off by default as it has a performance cost)

# dynamic_background_opacity no

#: Allow changing of the background_opacity dynamically, using either
#: keyboard shortcuts (increase_background_opacity and
#: decrease_background_opacity) or the remote control facility.

# dim_opacity 0.75

#: How much to dim text that has the DIM/FAINT attribute set. One
#: means no dimming and zero means fully dimmed (i.e. invisible).

# selection_foreground #000000

#: The foreground for text selected with the mouse. A value of none
#: means to leave the color unchanged.

# selection_background #fffacd

#: The background for text selected with the mouse.


#: The 16 terminal colors. There are 8 basic colors, each color has a
#: dull and bright version. You can also set the remaining colors from
#: the 256 color table as color16 to color255.


#: black
color0 #2a2e38
color8 #71798a

#: red
color1  #d08785
color9 #ff3334

#: green
color2  #6f98b3
color10 #9ec400

#: yellow

color3  #fdf8ce
color11 #e7c547

#: blue

color4  #a6b8cc
color12 #7aa6da

#: magenta

color5  #fcdbd9
color13 #b77ee0

#: cyan

color6  #ffd17f
color14 #54ced6

#: white

color7  #f0fdff
color15 #ffffff

#: }}}

#: Advanced {{{

shell fish

#: The shell program to execute. The default value of . means to use
#: whatever shell is set as the default shell for the current user.
#: Note that on macOS if you change this, you might need to add
#: --login to ensure that the shell starts in interactive mode and
#: reads its startup rc files.

# editor .

#: The console editor to use when editing the kitty config file or
#: similar tasks. A value of . means to use the environment variables
#: VISUAL and EDITOR in that order. Note that this environment
#: variable has to be set not just in your shell startup scripts but
#: system-wide, otherwise kitty will not see it.

# close_on_child_death no

#: Close the window when the child process (shell) exits. If no (the
#: default), the terminal will remain open when the child exits as
#: long as there are still processes outputting to the terminal (for
#: example disowned or backgrounded processes). If yes, the window
#: will close as soon as the child process exits. Note that setting it
#: to yes means that any background processes still using the terminal
#: can fail silently because their stdout/stderr/stdin no longer work.

# allow_remote_control no

#: Allow other programs to control kitty. If you turn this on other
#: programs can control all aspects of kitty, including sending text
#: to kitty windows, opening new windows, closing windows, reading the
#: content of windows, etc.  Note that this even works over ssh
#: connections. You can chose to either allow any program running
#: within kitty to control it, with yes or only programs that connect
#: to the socket specified with the kitty --listen-on command line
#: option, if you use the value socket-only. The latter is useful if
#: you want to prevent programs running on a remote computer over ssh
#: from controlling kitty.

# env

#: Specify environment variables to set in all child processes. Note
#: that environment variables are expanded recursively, so if you
#: use::

#:     env MYVAR1=a
#:     env MYVAR2=${MYVAR1}/${HOME}/b

#: The value of MYVAR2 will be a/<path to home directory>/b.

# update_check_interval 24

#: Periodically check if an update to kitty is available. If an update
#: is found a system notification is displayed informing you of the
#: available update. The default is to check every 24 hrs, set to zero
#: to disable.

# startup_session none

#: Path to a session file to use for all kitty instances. Can be
#: overridden by using the kitty --session command line option for
#: individual instances. See
#: https://sw.kovidgoyal.net/kitty/index.html#sessions in the kitty
#: documentation for details. Note that relative paths are interpreted
#: with respect to the kitty config directory. Environment variables
#: in the path are expanded.

# clipboard_control write-clipboard write-primary

#: Allow programs running in kitty to read and write from the
#: clipboard. You can control exactly which actions are allowed. The
#: set of possible actions is: write-clipboard read-clipboard write-
#: primary read-primary. You can additionally specify no-append to
#: disable kitty's protocol extension for clipboard concatenation. The
#: default is to allow writing to the clipboard and primary selection
#: with concatenation enabled. Note that enabling the read
#: functionality is a security risk as it means that any program, even
#: one running on a remote server via SSH can read your clipboard.

# term xterm-kitty

#: The value of the TERM environment variable to set. Changing this
#: can break many terminal programs, only change it if you know what
#: you are doing, not because you read some advice on Stack Overflow
#: to change it. The TERM variable is used by various programs to get
#: information about the capabilities and behavior of the terminal. If
#: you change it, depending on what programs you run, and how
#: different the terminal you are changing it to is, various things
#: from key-presses, to colors, to various advanced features may not
#: work.

#: }}}

#: OS specific tweaks {{{

# macos_titlebar_color system

#: Change the color of the kitty window's titlebar on macOS. A value
#: of system means to use the default system color, a value of
#: background means to use the background color of the currently
#: active window and finally you can use an arbitrary color, such as
#: #12af59 or red. WARNING: This option works by using a hack, as
#: there is no proper Cocoa API for it. It sets the background color
#: of the entire window and makes the titlebar transparent. As such it
#: is incompatible with background_opacity. If you want to use both,
#: you are probably better off just hiding the titlebar with
#: hide_window_decorations.

# macos_option_as_alt no

#: Use the option key as an alt key. With this set to no, kitty will
#: use the macOS native Option+Key = unicode character behavior. This
#: will break any Alt+key keyboard shortcuts in your terminal
#: programs, but you can use the macOS unicode input technique. You
#: can use the values: left, right, or both to use only the left,
#: right or both Option keys as Alt, instead.

# macos_hide_from_tasks no

#: Hide the kitty window from running tasks (Option+Tab) on macOS.

# macos_quit_when_last_window_closed no

#: Have kitty quit when all the top-level windows are closed. By
#: default, kitty will stay running, even with no open windows, as is
#: the expected behavior on macOS.

# macos_window_resizable yes

#: Disable this if you want kitty top-level (OS) windows to not be
#: resizable on macOS.

macos_thicken_font 0.3

#: Draw an extra border around the font with the given width, to
#: increase legibility at small font sizes. For example, a value of
#: 0.75 will result in rendering that looks similar to sub-pixel
#: antialiasing at common font sizes.

# macos_traditional_fullscreen no

#: Use the traditional full-screen transition, that is faster, but
#: less pretty.

# macos_show_window_title_in all

#: Show or hide the window title in the macOS window or menu-bar. A
#: value of window will show the title of the currently active window
#: at the top of the macOS window. A value of menubar will show the
#: title of the currently active window in the macOS menu-bar, making
#: use of otherwise wasted space. all will show the title everywhere
#: and none hides the title in the window and the menu-bar.

# macos_custom_beam_cursor no

#: Enable/disable custom mouse cursor for macOS that is easier to see
#: on both light and dark backgrounds. WARNING: this might make your
#: mouse cursor invisible on dual GPU machines.

# linux_display_server auto

#: Choose between Wayland and X11 backends. By default, an appropriate
#: backend based on the system state is chosen automatically. Set it
#: to x11 or wayland to force the choice.

#: }}}

#: Keyboard shortcuts {{{

#: For a list of key names, see: GLFW keys
#: <https://www.glfw.org/docs/latest/group__keys.html>. The name to
#: use is the part after the GLFW_KEY_ prefix. For a list of modifier
#: names, see: GLFW mods
#: <https://www.glfw.org/docs/latest/group__mods.html>

#: On Linux you can also use XKB key names to bind keys that are not
#: supported by GLFW. See XKB keys
#: <https://github.com/xkbcommon/libxkbcommon/blob/master/xkbcommon/xkbcommon-
#: keysyms.h> for a list of key names. The name to use is the part
#: after the XKB_KEY_ prefix. Note that you should only use an XKB key
#: name for keys that are not present in the list of GLFW keys.

#: Finally, you can use raw system key codes to map keys. To see the
#: system key code for a key, start kitty with the kitty --debug-
#: keyboard option. Then kitty will output some debug text for every
#: key event. In that text look for ``native_code`` the value of that
#: becomes the key name in the shortcut. For example:

#: .. code-block:: none

#:     on_key_input: glfw key: 65 native_code: 0x61 action: PRESS mods: 0x0 text: 'a'

#: Here, the key name for the A key is 0x61 and you can use it with::

#:     map ctrl+0x61 something

#: to map ctrl+a to something.

#: You can use the special action no_op to unmap a keyboard shortcut
#: that is assigned in the default configuration::

#:     map kitty_mod+space no_op

#: You can combine multiple actions to be triggered by a single
#: shortcut, using the syntax below::

#:     map key combine <separator> action1 <separator> action2 <separator> action3 ...

#: For example::

#:     map kitty_mod+e combine : new_window : next_layout

#: this will create a new window and switch to the next available
#: layout

#: You can use multi-key shortcuts using the syntax shown below::

#:     map key1>key2>key3 action

#: For example::

#:     map ctrl+f>2 set_font_size 20

# kitty_mod ctrl+shift

#: The value of kitty_mod is used as the modifier for all default
#: shortcuts, you can change it in your kitty.conf to change the
#: modifiers for all the default shortcuts.

# clear_all_shortcuts no

#: You can have kitty remove all shortcut definition seen up to this
#: point. Useful, for instance, to remove the default shortcuts.

# kitten_alias hints hints --hints-offset=0

#: You can create aliases for kitten names, this allows overriding the
#: defaults for kitten options and can also be used to shorten
#: repeated mappings of the same kitten with a specific group of
#: options. For example, the above alias changes the default value of
#: kitty +kitten hints --hints-offset to zero for all mappings,
#: including the builtin ones.

#: Clipboard {{{

# map kitty_mod+c copy_to_clipboard

#: There is also a copy_or_interrupt action that can be optionally
#: mapped to Ctrl+c. It will copy only if there is a selection and
#: send an interrupt otherwise.

# map cmd+c        copy_to_clipboard
# map kitty_mod+v  paste_from_clipboard
# map cmd+v        paste_from_clipboard
# map kitty_mod+s  paste_from_selection
# map shift+insert paste_from_selection
# map kitty_mod+o  pass_selection_to_program

#: You can also pass the contents of the current selection to any
#: program using pass_selection_to_program. By default, the system's
#: open program is used, but you can specify your own, the selection
#: will be passed as a command line argument to the program, for
#: example::

#:     map kitty_mod+o pass_selection_to_program firefox

#: You can pass the current selection to a terminal program running in
#: a new kitty window, by using the @selection placeholder::

#:     map kitty_mod+y new_window less @selection

#: }}}

#: Scrolling {{{

# map kitty_mod+up        scroll_line_up
# map alt+cmd+page_up     scroll_line_up
# map cmd+up              scroll_line_up
# map kitty_mod+k         scroll_line_up
# map kitty_mod+down      scroll_line_down
# map kitty_mod+j         scroll_line_down
# map alt+cmd+page_down   scroll_line_down
# map cmd+down            scroll_line_down
# map kitty_mod+page_up   scroll_page_up
# map cmd+page_up         scroll_page_up
# map kitty_mod+page_down scroll_page_down
# map cmd+page_down       scroll_page_down
# map kitty_mod+home      scroll_home
# map cmd+home            scroll_home
# map kitty_mod+end       scroll_end
# map cmd+end             scroll_end
# map kitty_mod+h         show_scrollback

#: You can pipe the contents of the current screen + history buffer as
#: STDIN to an arbitrary program using the ``launch`` function. For
#: example, the following opens the scrollback buffer in less in an
#: overlay window::

#:     map f1 launch --stdin-source=@screen_scrollback --stdin-add-formatting --type=overlay less +G -R

#: For more details on piping screen and buffer contents to external
#: programs, see launch.

#: }}}

#: Window management {{{

# map kitty_mod+enter new_window

#: You can open a new window running an arbitrary program, for
#: example::

#:     map kitty_mod+y      launch mutt

#: You can open a new window with the current working directory set to
#: the working directory of the current window using::

#:     map ctrl+alt+enter    launch --cwd=current

#: You can open a new window that is allowed to control kitty via the
#: kitty remote control facility by prefixing the command line with @.
#: Any programs running in that window will be allowed to control
#: kitty. For example::

#:     map ctrl+enter launch --allow-remote-control some_program

#: You can open a new window next to the currently active window or as
#: the first window, with::

#:     map ctrl+n launch --location=neighbor some_program
#:     map ctrl+f launch --location=first some_program

#: For more details, see launch.

# map cmd+enter   new_window
# map kitty_mod+n new_os_window

#: Works like new_window above, except that it opens a top level OS
#: kitty window. In particular you can use new_os_window_with_cwd to
#: open a window with the current working directory.

# map cmd+n       new_os_window
# map kitty_mod+w close_window
# map shift+cmd+d close_window
# map kitty_mod+] next_window
# map kitty_mod+[ previous_window
# map kitty_mod+f move_window_forward
# map kitty_mod+b move_window_backward
# map kitty_mod+` move_window_to_top
# map kitty_mod+r start_resizing_window
# map cmd+r       start_resizing_window
# map kitty_mod+1 first_window
# map cmd+1       first_window
# map kitty_mod+2 second_window
# map cmd+2       second_window
# map kitty_mod+3 third_window
# map cmd+3       third_window
# map kitty_mod+4 fourth_window
# map cmd+4       fourth_window
# map kitty_mod+5 fifth_window
# map cmd+5       fifth_window
# map kitty_mod+6 sixth_window
# map cmd+6       sixth_window
# map kitty_mod+7 seventh_window
# map cmd+7       seventh_window
# map kitty_mod+8 eighth_window
# map cmd+8       eighth_window
# map kitty_mod+9 ninth_window
# map cmd+9       ninth_window
# map kitty_mod+0 tenth_window
#: }}}

#: Tab management {{{

# map kitty_mod+right next_tab
# map ctrl+tab        next_tab
# map shift+cmd+]     next_tab
# map kitty_mod+left  previous_tab
# map shift+ctrl+tab  previous_tab
# map shift+cmd+[     previous_tab
# map kitty_mod+t     new_tab
# map cmd+t           new_tab
# map kitty_mod+q     close_tab
# map cmd+w           close_tab
# map kitty_mod+.     move_tab_forward
# map kitty_mod+,     move_tab_backward
# map kitty_mod+alt+t set_tab_title
# map shift+cmd+i     set_tab_title

#: You can also create shortcuts to go to specific tabs, with 1 being
#: the first tab, 2 the second tab and -1 being the previously active
#: tab::

#:     map ctrl+alt+1 goto_tab 1
#:     map ctrl+alt+2 goto_tab 2

#: Just as with new_window above, you can also pass the name of
#: arbitrary commands to run when using new_tab and use
#: new_tab_with_cwd. Finally, if you want the new tab to open next to
#: the current tab rather than at the end of the tabs list, use::

#:     map ctrl+t new_tab !neighbor [optional cmd to run]
#: }}}

#: Layout management {{{

# map kitty_mod+l next_layout

#: You can also create shortcuts to switch to specific layouts::

#:     map ctrl+alt+t goto_layout tall
#:     map ctrl+alt+s goto_layout stack

#: Similarly, to switch back to the previous layout::

#:    map ctrl+alt+p last_used_layout
#: }}}

#: Font sizes {{{

#: You can change the font size for all top-level kitty OS windows at
#: a time or only the current one.

# map kitty_mod+equal     change_font_size all +2.0
# map cmd+plus            change_font_size all +2.0
# map kitty_mod+minus     change_font_size all -2.0
# map cmd+minus           change_font_size all -2.0
# map kitty_mod+backspace change_font_size all 0
# map cmd+0               change_font_size all 0

#: To setup shortcuts for specific font sizes::

#:     map kitty_mod+f6 change_font_size all 10.0

#: To setup shortcuts to change only the current OS window's font
#: size::

#:     map kitty_mod+f6 change_font_size current 10.0
#: }}}

#: Select and act on visible text {{{

#: Use the hints kitten to select text and either pass it to an
#: external program or insert it into the terminal or copy it to the
#: clipboard.

# map kitty_mod+e kitten hints

#: Open a currently visible URL using the keyboard. The program used
#: to open the URL is specified in open_url_with.

# map kitty_mod+p>f kitten hints --type path --program -

#: Select a path/filename and insert it into the terminal. Useful, for
#: instance to run git commands on a filename output from a previous
#: git command.

# map kitty_mod+p>shift+f kitten hints --type path

#: Select a path/filename and open it with the default open program.

# map kitty_mod+p>l kitten hints --type line --program -

#: Select a line of text and insert it into the terminal. Use for the
#: output of things like: ls -1

# map kitty_mod+p>w kitten hints --type word --program -

#: Select words and insert into terminal.

# map kitty_mod+p>h kitten hints --type hash --program -

#: Select something that looks like a hash and insert it into the
#: terminal. Useful with git, which uses sha1 hashes to identify
#: commits


#: The hints kitten has many more modes of operation that you can map
#: to different shortcuts. For a full description see kittens/hints.
#: }}}

#: Miscellaneous {{{

# map kitty_mod+f11    toggle_fullscreen
# map kitty_mod+f10    toggle_maximized
# map kitty_mod+u      kitten unicode_input
# map kitty_mod+f2     edit_config_file
# map kitty_mod+escape kitty_shell window

#: Open the kitty shell in a new window/tab/overlay/os_window to
#: control kitty using commands.

# map kitty_mod+a>m    set_background_opacity +0.1
# map kitty_mod+a>l    set_background_opacity -0.1
# map kitty_mod+a>1    set_background_opacity 1
# map kitty_mod+a>d    set_background_opacity default
# map kitty_mod+delete clear_terminal reset active

#: You can create shortcuts to clear/reset the terminal. For example::

#:     # Reset the terminal
#:     map kitty_mod+f9 clear_terminal reset active
#:     # Clear the terminal screen by erasing all contents
#:     map kitty_mod+f10 clear_terminal clear active
#:     # Clear the terminal scrollback by erasing it
#:     map kitty_mod+f11 clear_terminal scrollback active
#:     # Scroll the contents of the screen into the scrollback
#:     map kitty_mod+f12 clear_terminal scroll active

#: If you want to operate on all windows instead of just the current
#: one, use all instead of active.

#: It is also possible to remap Ctrl+L to both scroll the current
#: screen contents into the scrollback buffer and clear the screen,
#: instead of just clearing the screen::

#:     map ctrl+l combine : clear_terminal scroll active : send_text normal,application \x0c


#: You can tell kitty to send arbitrary (UTF-8) encoded text to the
#: client program when pressing specified shortcut keys. For example::

#:     map ctrl+alt+a send_text all Special text

#: This will send "Special text" when you press the ctrl+alt+a key
#: combination.  The text to be sent is a python string literal so you
#: can use escapes like \x1b to send control codes or \u21fb to send
#: unicode characters (or you can just input the unicode characters
#: directly as UTF-8 text). The first argument to send_text is the
#: keyboard modes in which to activate the shortcut. The possible
#: values are normal or application or kitty or a comma separated
#: combination of them.  The special keyword all means all modes. The
#: modes normal and application refer to the DECCKM cursor key mode
#: for terminals, and kitty refers to the special kitty extended
#: keyboard protocol.

#: Another example, that outputs a word and then moves the cursor to
#: the start of the line (same as pressing the Home key)::

#:     map ctrl+alt+a send_text normal Word\x1b[H
#:     map ctrl+alt+a send_text application Word\x1bOH

#: }}}

# }}}



1.20. Go cheat

---
# The editor to use with 'cheat -e <sheet>'. Defaults to $EDITOR or $VISUAL.
editor: nvim

# Should 'cheat' always colorize output?
colorize: true

# Which 'chroma' colorscheme should be applied to the output?
# Options are available here:
#   https://github.com/alecthomas/chroma/tree/master/styles
style: monokai

# Which 'chroma' "formatter" should be applied?
# One of: "terminal", "terminal256", "terminal16m"
formatter: terminal16m

# Through which pager should output be piped? (Unset this key for no pager.)
pager: less -FRX

# The paths at which cheatsheets are available. Tags associated with a cheatpath
# are automatically attached to all cheatsheets residing on that path.
#
# Whenever cheatsheets share the same title (like 'tar'), the most local
# cheatsheets (those which come later in this file) take precedent over the
# less local sheets. This allows you to create your own "overides" for
# "upstream" cheatsheets.
#
# But what if you want to view the "upstream" cheatsheets instead of your own?
# Cheatsheets may be filtered via 'cheat -t <tag>' in combination with other
# commands. So, if you want to view the 'tar' cheatsheet that is tagged as
# 'community' rather than your own, you can use: cheat tar -t community
cheatpaths:

  # Paths that come earlier are considered to be the most "global", and will
  # thus be overridden by more local cheatsheets. That being the case, you
  # should probably list community cheatsheets first.
  #
  # Note that the paths and tags listed below are placeholders. You may freely
  # change them to suit your needs.
  #
  # Community cheatsheets must be installed separately, though you may have
  # downloaded them automatically when installing 'cheat'. If not, you may
  # download them here:
  #
  # https://github.com/cheat/cheatsheets
  #
  # Once downloaded, ensure that 'path' below points to the location at which
  # you downloaded the community cheatsheets.
  - name: community
    path: /home/vermin/.config/cheat/cheatsheets/community
    tags: [ community ]
    readonly: true

    # If you have personalized cheatsheets, list them last. They will take
    # precedence over the more global cheatsheets.
    - name: personal
      path: /home/vermin/org/cheat/
      tags: [ personal ]
      readonly: false

      # While it requires no configuration here, it's also worth noting that
      # 'cheat' will automatically append directories named '.cheat' within the
      # current working directory to the 'cheatpath'. This can be very useful if
      # you'd like to closely associate cheatsheets with, for example, a directory
      # containing source code.
      #
      # Such "directory-scoped" cheatsheets will be treated as the most "local"
      # cheatsheets, and will override less "local" cheatsheets. Likewise,
      # directory-scoped cheatsheets will always be editable ('readonly: false').

1.21. makem.sh

1.21.1. makem.sh

#!/usr/bin/env bash

# * makem.sh --- Script to aid building and testing Emacs Lisp packages

# URL: https://github.com/alphapapa/makem.sh
# Version: 0.6-pre

# * Commentary:

# makem.sh is a script that helps to build, lint, and test Emacs Lisp
# packages.  It aims to make linting and testing as simple as possible
# without requiring per-package configuration.

# It works similarly to a Makefile in that "rules" are called to
# perform actions such as byte-compiling, linting, testing, etc.

# Source and test files are discovered automatically from the
# project's Git repo, and package dependencies within them are parsed
# automatically.

# Output is simple: by default, there is no output unless errors
# occur.  With increasing verbosity levels, more detail gives positive
# feedback.  Output is colored by default to make reading easy.

# The script can run Emacs with the developer's local Emacs
# configuration, or with a clean, "sandbox" configuration that can be
# optionally removed afterward.  This is especially helpful when
# upstream dependencies may have released new versions that differ
# from those installed in the developer's personal configuration.

# * License:

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

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

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

# * Functions

function usage {
cat <<EOF
$0 [OPTIONS] RULES...

Linter- and test-specific rules will error when their linters or tests
are not found.  With -vv, rules that run multiple rules will show a
message for unavailable linters or tests.

Rules:
  all      Run all lints and tests.
  compile  Byte-compile source files.

  lint           Run all linters, ignoring unavailable ones.
  lint-checkdoc  Run checkdoc.
  lint-compile   Byte-compile source files with warnings as errors.
  lint-declare   Run check-declare.
  lint-elsa      Run Elsa (not included in "lint" rule).
  lint-indent    Lint indentation.
  lint-package   Run package-lint.
  lint-regexps   Run relint.

  test, tests           Run all tests, ignoring missing test types.
  test-buttercup        Run Buttercup tests.
  test-ert              Run ERT tests.
  test-ert-interactive  Run ERT tests interactively.

  batch        Run Emacs in batch mode, loading project source and test files
  automatically, with remaining args (after "--") passed to Emacs.
  interactive  Run Emacs interactively, loading project source and test files
  automatically, with remaining args (after "--") passed to Emacs.

  Options:
    -d, --debug    Print debug info.
    -h, --help     I need somebody!
    -v, --verbose  Increase verbosity, up to -vvv.
    --no-color     Disable color output.

    --debug-load-path  Print load-path from inside Emacs.

    -E, --emacs PATH  Run Emacs at PATH.

    -e, --exclude FILE  Exclude FILE from linting and testing.
    -f, --file FILE     Check FILE in addition to discovered files.

    -c, --compile-batch  Batch-compile files (instead of separately; quicker, but
    may hide problems).
    -C, --no-compile     Don't compile files automatically.

    Sandbox options:
      -s[DIR], --sandbox[=DIR]  Run Emacs with an empty config in a sandbox DIR.
      If DIR does not exist, make it.  If DIR is not
      specified, use a temporary sandbox directory and
      delete it afterward, implying --install-deps and
      --install-linters.
      --install-deps            Automatically install package dependencies.
      --install-linters         Automatically install linters.
      -i, --install PACKAGE     Install PACKAGE before running rules.

      An Emacs version-specific subdirectory is automatically made inside
      the sandbox, allowing testing with multiple Emacs versions.  When
      specifying a sandbox directory, use options --install-deps and
      --install-linters on first-run and omit them afterward to save time.

      Source files are automatically discovered from git, or may be
      specified with options.  Package dependencies are discovered from
      "Package-Requires" headers in source files, from -pkg.el files, and
      from a Cask file.
      EOF
      }

      # ** Elisp

      # These functions return a path to an elisp file which can be loaded
      # by Emacs on the command line with -l or --load.

      function elisp-buttercup-file {
      # The function buttercup-run, which is called by buttercup-run-discover,
      # signals an error if it can't find any Buttercup test suites.  We don't
      # want that to be an error, so we define advice which ignores that error.
      local file=$(mktemp)
      cat >$file <<EOF
      (defun makem-buttercup-run (oldfun &rest r)
      "Call buttercup-run only if \`buttercup-suites' is non-nil."
      (when buttercup-suites
      (apply oldfun r)))

      (advice-add #'buttercup-run :around #'makem-buttercup-run)
      EOF
      echo $file
      }

      function elisp-elint-file {
      local file=$(mktemp)
      cat >$file <<EOF
      (require 'cl-lib)
      (require 'elint)
      (defun makem-elint-file (file)
      (let ((errors 0))
      (cl-letf (((symbol-function 'orig-message) (symbol-function 'message))
      ((symbol-function 'message) (symbol-function 'ignore))
      ((symbol-function 'elint-output)
      (lambda (string)
      (cl-incf errors)
      (orig-message "%s" string))))
      (elint-file file)
      ;; NOTE: \`errors' is not actually the number of errors, because
      ;; it's incremented for non-error header strings as well.
      (kill-emacs errors))))
      EOF
      echo "$file"
      }

      function elisp-checkdoc-file {
      # Since checkdoc doesn't have a batch function that exits non-zero
      # when errors are found, we make one.
      local file=$(mktemp)

      cat >$file <<EOF
      (defvar makem-checkdoc-errors-p nil)

      (defun makem-checkdoc-files-and-exit ()
      "Run checkdoc-file on files remaining on command line, exiting non-zero if there are warnings."
      (let* ((files (mapcar #'expand-file-name command-line-args-left))
      (checkdoc-create-error-function
      (lambda (text start end &optional unfixable)
      (let ((msg (concat (checkdoc-buffer-label) ":"
      (int-to-string (count-lines (point-min) (or start (point-min))))
      ": " text)))
      (message msg)
      (setq makem-checkdoc-errors-p t)
      ;; Return nil because we *are* generating a buffered list of errors.
      nil))))
      (mapcar #'checkdoc-file files)
      (when makem-checkdoc-errors-p
      (kill-emacs 1))))

      (setq checkdoc-spellcheck-documentation-flag t)
      (makem-checkdoc-files-and-exit)
      EOF
      echo $file
      }

      function elisp-byte-compile-file {
      # This seems to be the only way to make byte-compilation signal
      # errors for warnings AND display all warnings rather than only
      # the first one.
      local file=$(mktemp)
      # TODO: Add file to $paths_temp in other elisp- functions.
      paths_temp+=("$file")

      cat >"$file" <<EOF
      (defun makem-batch-byte-compile (&rest args)
      ""
      (let ((num-errors 0))
      ;; NOTE: Only accepts files as args, not directories.
      (dolist (file command-line-args-left)
      (unless (makem-byte-compile-file file)
      (cl-incf num-errors)))
      (zerop num-errors)))

      (defun makem-byte-compile-file (filename &optional load)
      "Call \`byte-compile-warn', returning nil if there are any warnings."
      (let ((num-warnings 0))
      (cl-letf (((symbol-function 'byte-compile-warn)
      (lambda (format &rest args)
      ;; Copied from \`byte-compile-warn'.
      (cl-incf num-warnings)
      (setq format (apply #'format-message format args))
      (byte-compile-log-warning format t :warning))))
      (byte-compile-file filename load))
      (zerop num-warnings)))
      EOF
      echo "$file"
      }

      function elisp-check-declare-file {
      # Since check-declare doesn't have a batch function that exits
      # non-zero when errors are found, we make one.
      local file=$(mktemp)

      cat >$file <<EOF
      (require 'check-declare)

      (defun makem-check-declare-files-and-exit ()
      "Run check-declare-files on files remaining on command line, exiting non-zero if there are warnings."
      (let* ((files (mapcar #'expand-file-name command-line-args-left))
      (errors (apply #'check-declare-files files)))
      (when errors
      (with-current-buffer check-declare-warning-buffer
      (print (buffer-string)))
      (kill-emacs 1))))
      EOF
      echo $file
      }

      function elisp-lint-indent-file {
      # This function prints warnings for indentation errors and exits
      # non-zero when errors are found.
      local file=$(mktemp)

      cat >"$file" <<EOF
      (require 'cl-lib)

      (defun makem-lint-indent-batch-and-exit ()
      "Print warnings for files which are not indented properly, then exit.
      Exits non-zero if mis-indented lines are found.  Checks files in
      'command-line-args-left'."
      (let ((errors-p))
      (cl-labels ((lint-file (file)
      (find-file file)
      (let ((inhibit-message t))
      (indent-region (point-min) (point-max)))
      (when buffer-undo-list
      ;; Indentation changed: warn for each line.
      (dolist (line (undo-lines buffer-undo-list))
      (message "%s:%s: Indentation mismatch" (buffer-name) line))
      (setf errors-p t)))
      (undo-pos (entry)
      (cl-typecase (car entry)
      (number (car entry))
      (string (abs (cdr entry)))))
      (undo-lines (undo-list)
      ;; Return list of lines changed in UNDO-LIST.
      (nreverse (cl-loop for elt in undo-list
      for pos = (undo-pos elt)
      when pos
      collect (line-number-at-pos pos)))))
      (mapc #'lint-file (mapcar #'expand-file-name command-line-args-left))
      (when errors-p
      (kill-emacs 1)))))
      EOF

      echo "$file"
      }

      function elisp-package-initialize-file {
      local file=$(mktemp)

      cat >$file <<EOF
      (require 'package)
      (setq package-archives (list (cons "gnu" "https://elpa.gnu.org/packages/")
      (cons "melpa" "https://melpa.org/packages/")
      (cons "melpa-stable" "https://stable.melpa.org/packages/")))
      $elisp_org_package_archive
      (package-initialize)
      EOF
      echo $file
      }

      # ** Emacs

      function run_emacs {
      # NOTE: The sandbox args need to come before the package
      # initialization so Emacs will use the sandbox's packages.
      local emacs_command=(
      "${emacs_command[@]}"
      -Q
      --eval "(setq load-prefer-newer t)"
      "${args_debug[@]}"
      "${args_sandbox[@]}"
      -l $package_initialize_file
      $arg_batch
      "${args_load_paths[@]}"
      )

      # Show debug message with load-path from inside Emacs.
      [[ $debug_load_path ]] \
      && debug $("${emacs_command[@]}" \
      --batch \
      --eval "(message \"LOAD-PATH: %s\" load-path)" \
      2>&1)

      # Set output file.
      output_file=$(mktemp) || die "Unable to make output file."
      paths_temp+=("$output_file")

      # Run Emacs.
      debug "run_emacs: ${emacs_command[@]} $@ &>\"$output_file\""
      "${emacs_command[@]}" "$@" &>"$output_file"

      # Check exit code and output.
      exit=$?
      [[ $exit != 0 ]] \
      && debug "Emacs exited non-zero: $exit"

      [[ $verbose -gt 1 || $exit != 0 ]] \
      && cat $output_file

      return $exit
      }

      # ** Compilation

      function batch-byte-compile {
      debug "batch-byte-compile: ERROR-ON-WARN:$compile_error_on_warn"

      [[ $compile_error_on_warn ]] && local error_on_warn=(--eval "(setq byte-compile-error-on-warn t)")

      run_emacs \
      --load "$(elisp-byte-compile-file)" \
      "${error_on_warn[@]}" \
      --eval "(unless (makem-batch-byte-compile) (kill-emacs 1))" \
      "$@"
      }

      function byte-compile-file {
      debug "byte-compile: ERROR-ON-WARN:$compile_error_on_warn"
      local file="$1"

      [[ $compile_error_on_warn ]] && local error_on_warn=(--eval "(setq byte-compile-error-on-warn t)")

      # FIXME: Why is the line starting with "&& verbose 3" not indented properly?  Emacs insists on indenting it back a level.
      run_emacs \
      --load "$(elisp-byte-compile-file)" \
      "${error_on_warn[@]}" \
      --eval "(unless (makem-byte-compile-file \"$file\") (kill-emacs 1))" \
      && verbose 3 "Compiling $file finished without errors." \
      || { verbose 3 "Compiling file failed: $file"; return 1; }
      }

      # ** Files

      function dirs-project {
      # Echo list of directories to be used in load path.
      files-project-feature | dirnames
      files-project-test | dirnames
      }

      function files-project-elisp {
      # Echo list of Elisp files in project.
      git ls-files 2>/dev/null \
      | egrep "\.el$" \
      | filter-files-exclude-default \
      | filter-files-exclude-args
      }

      function files-project-feature {
      # Echo list of Elisp files that are not tests and provide a feature.
      files-project-elisp \
      | egrep -v "$test_files_regexp" \
      | filter-files-feature
      }

      function files-project-test {
      # Echo list of Elisp test files.
      files-project-elisp | egrep "$test_files_regexp"
      }

      function dirnames {
      # Echo directory names for files on STDIN.
      while read file
      do
      dirname "$file"
      done
      }

      function filter-files-exclude-default {
      # Filter out paths (STDIN) which should be excluded by default.
      egrep -v "(/\.cask/|-autoloads.el|.dir-locals)"
      }

      function filter-files-exclude-args {
      # Filter out paths (STDIN) which are excluded with --exclude.
      if [[ ${files_exclude[@]} ]]
      then
      (
      # We use a subshell to set IFS temporarily so we can send
      # the list of files to grep -F.  This is ugly but more
      # correct than replacing spaces with line breaks.  Note
      # that, for some reason, using IFS="\n" or IFS='\n' doesn't
      # work, and a literal line break seems to be required.
      IFS="
      "
      grep -Fv "${files_exclude[*]}"
      )
      else
      cat
      fi
      }

      function filter-files-feature {
      # Read paths on STDIN and echo ones that (provide 'a-feature).
      while read path
      do
      egrep "^\\(provide '" "$path" &>/dev/null \
      && echo "$path"
      done
      }

      function args-load-files {
      # For file in $@, echo "--load $file".
      for file in "$@"
      do
      sans_extension=${file%%.el}
      printf -- '--load %q ' "$sans_extension"
      done
      }

      function args-load-path {
      # Echo load-path arguments.
      for path in $(dirs-project | sort -u)
      do
      printf -- '-L %q ' "$path"
      done
      }

      function test-files-p {
      # Return 0 if $files_project_test is non-empty.
      [[ "${files_project_test[@]}" ]]
      }

      function buttercup-tests-p {
      # Return 0 if Buttercup tests are found.
      test-files-p || die "No tests found."
      debug "Checking for Buttercup tests..."

      grep "(require 'buttercup)" "${files_project_test[@]}" &>/dev/null
      }

      function ert-tests-p {
      # Return 0 if ERT tests are found.
      test-files-p || die "No tests found."
      debug "Checking for ERT tests..."

      # We check for this rather than "(require 'ert)", because ERT may
      # already be loaded in Emacs and might not be loaded with
      # "require" in a test file.
      grep "(ert-deftest" "${files_project_test[@]}" &>/dev/null
      }

      function package-main-file {
      # Echo the package's main file.
      file_pkg=$(git ls-files ./*-pkg.el 2>/dev/null)

      if [[ $file_pkg ]]
      then
      # Use *-pkg.el file if it exists.
      echo "$file_pkg"
      else
      # Use shortest filename (a sloppy heuristic that will do for now).
      for file in "${files_project_feature[@]}"
      do
      echo ${#file} "$file"
      done \
      | sort -h \
      | head -n1 \
      | sed -r 's/^[[:digit:]]+ //'
      fi
      }

      function dependencies {
      # Echo list of package dependencies.

      # Search package headers.  Use -a so grep won't think that an Elisp file containing
      # control characters (rare, but sometimes necessary) is binary and refuse to search it.
      egrep -a -i '^;; Package-Requires: ' $(files-project-feature) $(files-project-test) \
      | egrep -o '\([^([:space:]][^)]*\)' \
      | egrep -o '^[^[:space:])]+' \
      | sed -r 's/\(//g' \
      | egrep -v '^emacs$'  # Ignore Emacs version requirement.

      # Search Cask file.
      if [[ -r Cask ]]
      then
      egrep '\(depends-on "[^"]+"' Cask \
      | sed -r -e 's/\(depends-on "([^"]+)".*/\1/g'
      fi

      # Search -pkg.el file.
      if [[ $(git ls-files ./*-pkg.el 2>/dev/null) ]]
      then
      sed -nr 's/.*\(([-[:alnum:]]+)[[:blank:]]+"[.[:digit:]]+"\).*/\1/p' $(git ls-files ./*-pkg.el 2>/dev/null)
      fi
      }

      # ** Sandbox

      function sandbox {
      verbose 2 "Initializing sandbox..."

      # *** Sandbox arguments

      # MAYBE: Optionally use branch-specific sandbox?

      # Check or make user-emacs-directory.
      if [[ $sandbox_dir ]]
      then
      # Directory given as argument: ensure it exists.
      if ! [[ -d $sandbox_dir ]]
      then
      debug "Making sandbox directory: $sandbox_dir"
      mkdir -p "$sandbox_dir" || die "Unable to make sandbox dir."
      fi

      # Add Emacs version-specific subdirectory, creating if necessary.
      sandbox_dir="$sandbox_dir/$(emacs-version)"
      if ! [[ -d $sandbox_dir ]]
      then
      mkdir "$sandbox_dir" || die "Unable to make sandbox subdir: $sandbox_dir"
      fi
      else
      # Not given: make temp directory, and delete it on exit.
      local sandbox_dir=$(mktemp -d) || die "Unable to make sandbox dir."
      paths_temp+=("$sandbox_dir")
      fi

      # Make argument to load init file if it exists.
      init_file="$sandbox_dir/init.el"

      # Set sandbox args.  This is a global variable used by the run_emacs function.
      args_sandbox=(
      --title "makem.sh: $(basename $(pwd)) (sandbox: $sandbox_dir)"
      --eval "(setq user-emacs-directory (file-truename \"$sandbox_dir\"))"
      --load package
      --eval "(setq package-user-dir (expand-file-name \"elpa\" user-emacs-directory))"
      --eval "(setq user-init-file (file-truename \"$init_file\"))"
      )

      # Add package-install arguments for dependencies.
      if [[ $install_deps ]]
      then
      local deps=($(dependencies))
      debug "Installing dependencies: ${deps[@]}"

      for package in "${deps[@]}"
      do
      args_sandbox_package_install+=(--eval "(package-install '$package)")
      done
      fi

      # Add package-install arguments for linters.
      if [[ $install_linters ]]
      then
      debug "Installing linters: package-lint relint"

      args_sandbox_package_install+=(
      --eval "(package-install 'elsa)"
      --eval "(package-install 'package-lint)"
      --eval "(package-install 'relint)")
      fi

      # *** Install packages into sandbox

      if [[ ${args_sandbox_package_install[@]} ]]
      then
      # Initialize the sandbox (installs packages once rather than for every rule).
      verbose 1 "Installing packages into sandbox..."

      run_emacs \
      --eval "(package-refresh-contents)" \
      "${args_sandbox_package_install[@]}" \
      && success "Packages installed." \
      || die "Unable to initialize sandbox."
      fi

      verbose 2 "Sandbox initialized."
      }

      # ** Utility

      function cleanup {
      # Remove temporary paths (${paths_temp[@]}).

      for path in "${paths_temp[@]}"
      do
      if [[ $debug ]]
      then
      debug "Debugging enabled: not deleting temporary path: $path"
      elif [[ -r $path ]]
      then
      rm -rf "$path"
      else
      debug "Temporary path doesn't exist, not deleting: $path"
      fi
      done
      }

      function echo-unset-p {
      # Echo 0 if $1 is set, otherwise 1.  IOW, this returns the exit
      # code of [[ $1 ]] as STDOUT.
      [[ $1 ]]
      echo $?
      }

      function ensure-package-available {
      # If package $1 is available, return 0.  Otherwise, return 1, and
      # if $2 is set, give error otherwise verbose.  Outputting messages
      # here avoids repetition in callers.
      local package=$1
      local direct_p=$2

      if ! run_emacs --load $package &>/dev/null
      then
      if [[ $direct_p ]]
      then
      error "$package not available."
      else
      verbose 2 "$package not available."
      fi
      return 1
      fi
      }

      function ensure-tests-available {
      # If tests of type $1 (like "ERT") are available, return 0.  Otherwise, if
      # $2 is set, give an error and return 1; otherwise give verbose message.  $1
      # should have a corresponding predicate command, like ert-tests-p for ERT.
      local test_name=$1
      local test_command="${test_name,,}-tests-p"  # Converts name to lowercase.
      local direct_p=$2

      if ! $test_command
      then
      if [[ $direct_p ]]
      then
      error "$test_name tests not found."
      else
      verbose 2 "$test_name tests not found."
      fi
      return 1
      fi
      }

      function echo_color {
      # This allows bold, italic, etc. without needing a function for
      # each variation.
      local color_code="COLOR_$1"
      shift

      if [[ $color ]]
      then
      echo -e "${!color_code}${@}${COLOR_off}"
      else
      echo "$@"
      fi
      }
      function debug {
      if [[ $debug ]]
      then
      function debug {
      echo_color yellow "DEBUG ($(ts)): $@" >&2
      }
      debug "$@"
      else
      function debug {
      true
      }
      fi
      }
      function error {
      echo_color red "ERROR ($(ts)): $@" >&2
      ((errors++))
      return 1
      }
      function die {
      [[ $@ ]] && error "$@"
      exit $errors
      }
      function log {
      echo "LOG ($(ts)): $@" >&2
      }
      function log_color {
      local color_name=$1
      shift
      echo_color $color_name "LOG ($(ts)): $@" >&2
      }
      function success {
      if [[ $verbose -ge 2 ]]
      then
      log_color green "$@" >&2
      fi
      }
      function verbose {
      # $1 is the verbosity level, rest are echoed when appropriate.
      if [[ $verbose -ge $1 ]]
      then
      [[ $1 -eq 1 ]] && local color_name=blue
      [[ $1 -eq 2 ]] && local color_name=cyan
      [[ $1 -ge 3 ]] && local color_name=white

      shift
      log_color $color_name "$@" >&2
      fi
      }

      function ts {
      date "+%Y-%m-%d %H:%M:%S"
      }

      function emacs-version {
      # Echo Emacs version number.

      # Don't use run_emacs function, which does more than we need.
      "${emacs_command[@]}" -Q --batch --eval "(princ emacs-version)" \
      || die "Unable to get Emacs version."
      }

      function rule-p {
      # Return 0 if $1 is a rule.
      [[ $1 =~ ^(lint-?|tests?)$ ]] \
      || [[ $1 =~ ^(batch|interactive)$ ]] \
      || [[ $(type -t "$2" 2>/dev/null) =~ function ]]
      }

      # * Rules

      # These functions are intended to be called as rules, like a Makefile.
      # Some rules test $1 to determine whether the rule is being called
      # directly or from a meta-rule; if directly, an error is given if the
      # rule can't be run, otherwise it's skipped.

      function all {
      verbose 1 "Running all rules..."

      lint
      tests
      }

      function compile-batch {
      [[ $compile ]] || return 0
      unset compile  # Only compile once.

      verbose 1 "Compiling..."
      verbose 2 "Batch-compiling files..."
      debug "Byte-compile files: ${files_project_byte_compile[@]}"

      batch-byte-compile "${files_project_byte_compile[@]}"
      }

      function compile-each {
      [[ $compile ]] || return 0
      unset compile  # Only compile once.

      verbose 1 "Compiling..."
      debug "Byte-compile files: ${files_project_byte_compile[@]}"

      local compile_errors
      for file in "${files_project_byte_compile[@]}"
      do
      verbose 2 "Compiling file: $file..."
      byte-compile-file "$file" \
      || compile_errors=t
      done

      [[ ! $compile_errors ]]
      }

      function compile {
      if [[ $compile = batch ]]
      then
      compile-batch "$@"
      else
      compile-each "$@"
      fi
      local status=$?

      if [[ $compile_error_on_warn ]]
      then
      # Linting: just return status code, because lint rule will print messages.
      [[ $status = 0 ]]
      else
      # Not linting: print messages here.
      [[ $status = 0 ]] \
      && success "Compiling finished without errors." \
      || error "Compiling failed."
      fi
      }

      function batch {
      # Run Emacs in batch mode with ${args_batch_interactive[@]} and
      # with project source and test files loaded.
      verbose 1 "Executing Emacs with arguments: ${args_batch_interactive[@]}"

      run_emacs \
      $(args-load-files "${files_project_feature[@]}" "${files_project_test[@]}") \
      "${args_batch_interactive[@]}"
      }

      function interactive {
      # Run Emacs interactively.  Most useful with --sandbox and --install-deps.
      local load_file_args=$(args-load-files "${files_project_feature[@]}" "${files_project_test[@]}")
      verbose 1 "Running Emacs interactively..."
      verbose 2 "Loading files: ${load_file_args//--load /}"

      [[ $compile ]] && compile

      unset arg_batch
      run_emacs \
      $load_file_args \
      --eval "(load user-init-file)" \
      "${args_batch_interactive[@]}"
      arg_batch="--batch"
      }

      function lint {
      verbose 1 "Linting..."

      lint-checkdoc
      lint-compile
      lint-declare
      # NOTE: Elint doesn't seem very useful at the moment.  See comment
      # in lint-elint function.
      # lint-elint
      lint-indent
      lint-package
      lint-regexps
      }

      function lint-checkdoc {
      verbose 1 "Linting checkdoc..."

      local checkdoc_file="$(elisp-checkdoc-file)"
      paths_temp+=("$checkdoc_file")

      run_emacs \
      --load="$checkdoc_file" \
      "${files_project_feature[@]}" \
      && success "Linting checkdoc finished without errors." \
      || error "Linting checkdoc failed."
      }

      function lint-compile {
      verbose 1 "Linting compilation..."

      compile_error_on_warn=true
      compile "${files_project_byte_compile[@]}" \
      && success "Linting compilation finished without errors." \
      || error "Linting compilation failed."
      unset compile_error_on_warn
      }

      function lint-declare {
      verbose 1 "Linting declarations..."

      local check_declare_file="$(elisp-check-declare-file)"
      paths_temp+=("$check_declare_file")

      run_emacs \
      --load "$check_declare_file" \
      -f makem-check-declare-files-and-exit \
      "${files_project_feature[@]}" \
      && success "Linting declarations finished without errors." \
      || error "Linting declarations failed."
      }

      function lint-elsa {
      verbose 1 "Linting with Elsa..."

      # MAYBE: Install Elsa here rather than in sandbox init, to avoid installing
      # it when not needed.  However, we should be careful to be clear about when
      # packages are installed, because installing them does execute code.
      run_emacs \
      --load elsa \
      -f elsa-run-files-and-exit \
      "${files_project_feature[@]}" \
      && success "Linting with Elsa finished without errors." \
      || error "Linting with Elsa failed."
      }

      function lint-elint {
      # NOTE: Elint gives a lot of spurious warnings, apparently because it doesn't load files
      # that are `require'd, so its output isn't very useful.  But in case it's improved in
      # the future, and since this wrapper code already works, we might as well leave it in.
      verbose 1 "Linting with Elint..."

      local errors=0
      for file in "${files_project_feature[@]}"
      do
      verbose 2 "Linting with Elint: $file..."
      run_emacs \
      --load "$(elisp-elint-file)" \
      --eval "(makem-elint-file \"$file\")" \
      && verbose 3 "Linting with Elint found no errors." \
      || { error "Linting with Elint failed: $file"; ((errors++)) ; }
      done

      [[ $errors = 0 ]] \
      && success "Linting with Elint finished without errors." \
      || error "Linting with Elint failed."
      }

      function lint-indent {
      verbose 1 "Linting indentation..."

      # We load project source files as well, because they may contain
      # macros with (declare (indent)) rules which must be loaded to set
      # indentation.

      run_emacs \
      --load "$(elisp-lint-indent-file)" \
      $(args-load-files "${files_project_feature[@]}" "${files_project_test[@]}") \
      --funcall makem-lint-indent-batch-and-exit \
      "${files_project_feature[@]}" "${files_project_test[@]}" \
      && success "Linting indentation finished without errors." \
      || error "Linting indentation failed."
      }

      function lint-package {
      ensure-package-available package-lint $1 || return $(echo-unset-p $1)

      verbose 1 "Linting package..."

      run_emacs \
      --load package-lint \
      --eval "(setq package-lint-main-file \"$(package-main-file)\")" \
      --funcall package-lint-batch-and-exit \
      "${files_project_feature[@]}" \
      && success "Linting package finished without errors." \
      || error "Linting package failed."
      }

      function lint-regexps {
      ensure-package-available relint $1 || return $(echo-unset-p $1)

      verbose 1 "Linting regexps..."

      run_emacs \
      --load relint \
      --funcall relint-batch \
      "${files_project_source[@]}" \
      && success "Linting regexps finished without errors." \
      || error "Linting regexps failed."
      }

      function tests {
      verbose 1 "Running all tests..."

      test-ert
      test-buttercup
      }

      function test-ert-interactive {
      verbose 1 "Running ERT tests interactively..."

      unset arg_batch
      run_emacs \
      $(args-load-files "${files_project_test[@]}") \
      --eval "(ert-run-tests-interactively t)"
      arg_batch="--batch"
      }

      function test-buttercup {
      ensure-tests-available Buttercup $1 || return $(echo-unset-p $1)
      compile || die

      verbose 1 "Running Buttercup tests..."

      local buttercup_file="$(elisp-buttercup-file)"
      paths_temp+=("$buttercup_file")

      run_emacs \
      $(args-load-files "${files_project_test[@]}") \
      -f buttercup-run \
      && success "Buttercup tests finished without errors." \
      || error "Buttercup tests failed."
      }

      function test-ert {
      ensure-tests-available ERT $1 || return $(echo-unset-p $1)
      compile || die

      verbose 1 "Running ERT tests..."
      debug "Test files: ${files_project_test[@]}"

      run_emacs \
      $(args-load-files "${files_project_test[@]}") \
      -f ert-run-tests-batch-and-exit \
      && success "ERT tests finished without errors." \
      || error "ERT tests failed."
      }

      # * Defaults

      test_files_regexp='^((tests?|t)/)|-tests?.el$|^test-'

      emacs_command=("emacs")
      errors=0
      verbose=0
      compile=true
      arg_batch="--batch"
      compile=each

      # MAYBE: Disable color if not outputting to a terminal.  (OTOH, the
      # colorized output is helpful in CI logs, and I don't know if,
      # e.g. GitHub Actions logging pretends to be a terminal.)
      color=true

      # TODO: Using the current directory (i.e. a package's repo root directory) in
      # load-path can cause weird errors in case of--you guessed it--stale .ELC files,
      # the zombie problem that just won't die.  It's incredible how many different ways
      # this problem presents itself.  In this latest example, an old .ELC file, for a
      # .EL file that had since been renamed, was present on my local system, which meant
      # that an example .EL file that hadn't been updated was able to "require" that .ELC
      # file's feature without error.  But on another system (in this case, trying to
      # setup CI using GitHub Actions), the old .ELC was not present, so the example .EL
      # file was not able to load the feature, which caused a byte-compilation error.

      # In this case, I will prevent such example files from being compiled.  But in
      # general, this can cause weird problems that are tedious to debug.  I guess
      # the best way to fix it would be to actually install the repo's code as a
      # package into the sandbox, but doing that would require additional tooling,
      # pulling in something like Quelpa or package-build--and if the default recipe
      # weren't being used, the actual recipe would have to be fetched off MELPA or
      # something, which seems like getting too smart for our own good.

      # TODO: Emit a warning if .ELC files that don't match any .EL files are detected.

      # ** Colors

      COLOR_off='\e[0m'
      COLOR_black='\e[0;30m'
      COLOR_red='\e[0;31m'
      COLOR_green='\e[0;32m'
      COLOR_yellow='\e[0;33m'
      COLOR_blue='\e[0;34m'
      COLOR_purple='\e[0;35m'
      COLOR_cyan='\e[0;36m'
      COLOR_white='\e[0;37m'

      # ** Package system args

      args_package_archives=(
      --eval "(add-to-list 'package-archives '(\"gnu\" . \"https://elpa.gnu.org/packages/\") t)"
      --eval "(add-to-list 'package-archives '(\"melpa\" . \"https://melpa.org/packages/\") t)"
      )

      args_org_package_archives=(
      --eval "(add-to-list 'package-archives '(\"org\" . \"https://orgmode.org/elpa/\") t)"
      )

      args_package_init=(
      --eval "(package-initialize)"
      )

      elisp_org_package_archive="(add-to-list 'package-archives '(\"org\" . \"https://orgmode.org/elpa/\") t)"

      # * Args

      args=$(getopt -n "$0" \
      -o dhce:E:i:s::vf:CO \
      -l compile-batch,exclude:,emacs:,install-deps,install-linters,debug,debug-load-path,help,install:,verbose,file:,no-color,no-compile,no-org-repo,sandbox:: \
      -- "$@") \
      || { usage; exit 1; }
      eval set -- "$args"

      while true
      do
      case "$1" in
      --install-deps)
      install_deps=true
      ;;
      --install-linters)
      install_linters=true
      ;;
      -d|--debug)
      debug=true
      verbose=2
      args_debug=(--eval "(setq init-file-debug t)"
      --eval "(setq debug-on-error t)")
      ;;
      --debug-load-path)
      debug_load_path=true
      ;;
      -h|--help)
      usage
      exit
      ;;
      -c|--compile-batch)
      debug "Compiling files in batch mode"
      compile=batch
      ;;
      -E|--emacs)
      shift
      emacs_command=($1)
      ;;
      -i|--install)
      shift
      args_sandbox_package_install+=(--eval "(package-install '$1)")
      ;;
      -s|--sandbox)
      sandbox=true
      shift
      sandbox_dir="$1"

      if ! [[ $sandbox_dir ]]
      then
      debug "No sandbox dir: installing dependencies."
      install_deps=true
      else
      debug "Sandbox dir: $1"
      fi
      ;;
      -v|--verbose)
      ((verbose++))
      ;;
      -e|--exclude)
      shift
      debug "Excluding file: $1"
      files_exclude+=("$1")
      ;;
      -f|--file)
      shift
      args_files+=("$1")
      ;;
      -O|--no-org-repo)
      unset elisp_org_package_archive
      ;;
      --no-color)
      unset color
      ;;
      -C|--no-compile)
      unset compile
      ;;
      --)
      # Remaining args (required; do not remove)
      shift
      rest=("$@")
      break
      ;;
      esac

      shift
      done

      debug "ARGS: $args"
      debug "Remaining args: ${rest[@]}"

      # Set package elisp (which depends on --no-org-repo arg).
      package_initialize_file="$(elisp-package-initialize-file)"
      paths_temp+=("$package_initialize_file")

      # * Main

      trap cleanup EXIT INT TERM

      # Discover project files.
      files_project_feature=($(files-project-feature))
      files_project_test=($(files-project-test))
      files_project_byte_compile=("${files_project_feature[@]}" "${files_project_test[@]}")

      if [[ ${args_files[@]} ]]
      then
      # Add specified files.
      files_project_feature+=("${args_files[@]}")
      files_project_byte_compile+=("${args_files[@]}")
      fi

      debug "EXCLUDING FILES: ${files_exclude[@]}"
      debug "FEATURE FILES: ${files_project_feature[@]}"
      debug "TEST FILES: ${files_project_test[@]}"
      debug "BYTE-COMPILE FILES: ${files_project_byte_compile[@]}"
      debug "PACKAGE-MAIN-FILE: $(package-main-file)"

      if ! [[ ${files_project_feature[@]} ]]
      then
      error "No files specified and not in a git repo."
      exit 1
      fi

      # Set load path.
      args_load_paths=($(args-load-path))
      debug "LOAD PATH ARGS: ${args_load_paths[@]}"

      # If rules include linters and sandbox-dir is unspecified, install
      # linters automatically.
      if [[ $sandbox && ! $sandbox_dir ]] && [[ "${rest[@]}" =~ lint ]]
      then
      debug "Installing linters automatically."
      install_linters=true
      fi

      # Initialize sandbox.
      [[ $sandbox ]] && sandbox

      # Run rules.
      for rule in "${rest[@]}"
      do
      if [[ $batch || $interactive ]]
      then
      debug "Adding batch/interactive argument: $rule"
      args_batch_interactive+=("$rule")

      elif [[ $rule = batch ]]
      then
      # Remaining arguments are passed to Emacs.
      batch=true
      elif [[ $rule = interactive ]]
      then
      # Remaining arguments are passed to Emacs.
      interactive=true

      elif type -t "$rule" 2>/dev/null | grep function &>/dev/null
      then
      # Pass called-directly as $1 to indicate that the rule is
      # being called directly rather than from a meta-rule.
      $rule called-directly
      elif [[ $rule = test ]]
      then
      # Allow the "tests" rule to be called as "test".  Since "test"
      # is a shell builtin, this workaround is required.
      tests
      else
      error "Invalid rule: $rule"
      fi
      done

      # Batch/interactive rules.
      [[ $batch ]] && batch
      [[ $interactive ]] && interactive

      if [[ $errors -gt 0 ]]
      then
      log_color red "Finished with $errors errors."
      else
      success "Finished without errors."
      fi

      exit $errors

1.21.2. makefile

# * makem.sh/Makefile --- Script to aid building and testing Emacs Lisp packages

# URL: https://github.com/alphapapa/makem.sh
# Version: 0.5

# * Arguments

# For consistency, we use only var=val options, not hyphen-prefixed options.

# NOTE: I don't like duplicating the arguments here and in makem.sh,
# but I haven't been able to find a way to pass arguments which
# conflict with Make's own arguments through Make to the script.
# Using -- doesn't seem to do it.

ifdef install-deps
INSTALL_DEPS = "--install-deps"
endif
ifdef install-linters
INSTALL_LINTERS = "--install-linters"
endif

ifdef sandbox
ifeq ($(sandbox), t)
SANDBOX = --sandbox
else
SANDBOX = --sandbox=$(sandbox)
endif
endif

ifdef debug
DEBUG = "--debug"
endif

# ** Verbosity

# Since the "-v" in "make -v" gets intercepted by Make itself, we have
# to use a variable.

verbose = $(v)

ifneq (,$(findstring vvv,$(verbose)))
VERBOSE = "-vvv"
else ifneq (,$(findstring vv,$(verbose)))
VERBOSE = "-vv"
else ifneq (,$(findstring v,$(verbose)))
VERBOSE = "-v"
endif

# * Rules

# TODO: Handle cases in which "test" or "tests" are called and a
# directory by that name exists, which can confuse Make.

%:
  @./makem.sh $(DEBUG) $(VERBOSE) $(SANDBOX) $(INSTALL_DEPS) $(INSTALL_LINTERS) $(@)

  .DEFAULT: init
  init:
    @./makem.sh $(DEBUG) $(VERBOSE) $(SANDBOX) $(INSTALL_DEPS) $(INSTALL_LINTERS)

GET http://ipinfo.io

1.22. Emacs cheat


1.23. Vifm

" vim: filetype=vifm :
" Sample configuration file for vifm (last updated: 31 August, 2021)
" You can edit this file by hand.
" The " character at the beginning of a line comments out the line.
" Blank lines are ignored.
" The basic format for each item is shown with an example.

" ------------------------------------------------------------------------------

" Command used to edit files in various contexts.  The default is vim.
" If you would like to use another vi clone such as Elvis or Vile
" you will need to change this setting.

set vicmd=emacsclient\ -nw
" set vicmd=elvis\ -G\ termcap
" set vicmd=vile

" This makes vifm perform file operations on its own instead of relying on
" standard utilities like `cp`.  While using `cp` and alike is a more universal
" solution, it's also much slower when processing large amounts of files and
" doesn't support progress measuring.

set syscalls

" Trash Directory
" The default is to move files that are deleted with dd or :d to
" the trash directory.  If you change this you will not be able to move
" files by deleting them and then using p to put the file in the new location.
" I recommend not changing this until you are familiar with vifm.
" This probably shouldn't be an option.

set trash

" This is how many directories to store in the directory history.

set history=100

" Automatically resolve symbolic links on l or Enter.

set nofollowlinks

" Natural sort of (version) numbers within text.

set sortnumbers

" Maximum number of changes that can be undone.

set undolevels=100

" Use Vim's format of help file (has highlighting and "hyperlinks").
" If you would rather use a plain text help file set novimhelp.

set vimhelp

" If you would like to run an executable file when you
" press Enter, l or Right Arrow, set this.

set norunexec

" List of color schemes to try (picks the first one supported by the terminal)

colorscheme Default-256 Default

" Format for displaying time in file list. For example:
" TIME_STAMP_FORMAT=%m/%d-%H:%M
" See man date or man strftime for details.

set timefmt=%m/%d\ %H:%M

" Show list of matches on tab completion in command-line mode

set wildmenu

" Display completions in a form of popup with descriptions of the matches

set wildstyle=popup

" Display suggestions in normal, visual and view modes for keys, marks and
" registers (at most 5 files).  In other view, when available.

set suggestoptions=normal,visual,view,otherpane,keys,marks,registers

" Ignore case in search patterns unless it contains at least one uppercase
" letter

set ignorecase
set smartcase

" Don't highlight search results automatically

set nohlsearch

" Use increment searching (search while typing)
set incsearch

" Try to leave some space from cursor to upper/lower border in lists

set scrolloff=4

" Don't do too many requests to slow file systems

if !has('win')
set slowfs=curlftpfs
endif

" Set custom status line look

set statusline="  Hint: %z%= %A %10u:%-7g %15s %20d  "

" ------------------------------------------------------------------------------

" :mark mark /full/directory/path [filename]

mark b ~/bin/
mark h ~/

" ------------------------------------------------------------------------------

" :com[mand][!] command_name action
" The following macros can be used in a command
" %a is replaced with the user arguments.
" %c the current file under the cursor.
" %C the current file under the cursor in the other directory.
" %f the current selected file, or files.
" %F the current selected file, or files in the other directory.
" %b same as %f %F.
" %d the current directory name.
" %D the other window directory name.
" %m run the command in a menu window

command! df df -h %m 2> /dev/null
command! diff vim -d %f %F
command! zip zip -r %c.zip %f
command! run !! ./%f
command! make !!make %a
command! mkcd :mkdir %a | cd %a
command! vgrep vim "+grep %a"
command! reload :write | restart full

" ------------------------------------------------------------------------------

" The file type is for the default programs to be used with
" a file extension.
" :filetype pattern1,pattern2 defaultprogram,program2
" :fileviewer pattern1,pattern2 consoleviewer
" The other programs for the file type can be accessed with the :file command
" The command macros like %f, %F, %d, %D may be used in the commands.
" The %a macro is ignored.  To use a % you must put %%.

" For automated FUSE mounts, you must register an extension with :file[x]type
" in one of following formats:
"
" :filetype extensions FUSE_MOUNT|some_mount_command using %SOURCE_FILE and %DESTINATION_DIR variables
" %SOURCE_FILE and %DESTINATION_DIR are filled in by vifm at runtime.
" A sample line might look like this:
" :filetype *.zip,*.jar,*.war,*.ear FUSE_MOUNT|fuse-zip %SOURCE_FILE %DESTINATION_DIR
"
" :filetype extensions FUSE_MOUNT2|some_mount_command using %PARAM and %DESTINATION_DIR variables
" %PARAM and %DESTINATION_DIR are filled in by vifm at runtime.
" A sample line might look like this:
" :filetype *.ssh FUSE_MOUNT2|sshfs %PARAM %DESTINATION_DIR
" %PARAM value is filled from the first line of file (whole line).
" Example first line for SshMount filetype: root@127.0.0.1:/
"
" You can also add %CLEAR if you want to clear screen before running FUSE
" program.

" Pdf
filextype {*.pdf},<application/pdf> okular %c %i &, apvlv %c, xpdf %c
fileviewer {*.pdf},<application/pdf> pdftotext -nopgbrk %c -

" PostScript
filextype {*.ps,*.eps,*.ps.gz},<application/postscript>
\ {View in zathura}
\ zathura %f,
\ {View in gv}
\ gv %c %i &,

" Djvu
filextype {*.djvu},<image/vnd.djvu>
\ {View in zathura}
\ zathura %f,
\ {View in apvlv}
\ apvlv %f,

" Audio
filetype {*.wav,*.mp3,*.flac,*.m4a,*.wma,*.ape,*.ac3,*.og[agx],*.spx,*.opus},
\<audio/*>
\ {Play using ffplay}
\ ffplay -nodisp -autoexit %c,
\ {Play using MPlayer}
\ mplayer %f,
fileviewer {*.mp3},<audio/mpeg> mp3info
fileviewer {*.flac},<audio/flac> soxi

" Video
filextype {*.avi,*.mp4,*.wmv,*.dat,*.3gp,*.ogv,*.mkv,*.mpg,*.mpeg,*.vob,
\*.fl[icv],*.m2v,*.mov,*.webm,*.ts,*.mts,*.m4v,*.r[am],*.qt,*.divx,
\*.as[fx]},
\<video/*>
\ {View using ffplay}
\ ffplay -fs -autoexit %f,
\ {View using Dragon}
\ dragon %f:p,
\ {View using mplayer}
\ mplayer %f,
fileviewer {*.avi,*.mp4,*.wmv,*.dat,*.3gp,*.ogv,*.mkv,*.mpg,*.mpeg,*.vob,
\*.fl[icv],*.m2v,*.mov,*.webm,*.ts,*.mts,*.m4v,*.r[am],*.qt,*.divx,
\*.as[fx]},
\<video/*>
\ ffprobe -pretty %c 2>&1

" Web
filextype {*.html,*.htm},<text/html>
\ {Open with dwb}
\ dwb %f %i &,
\ {Open with firefox}
\ firefox %f &,
\ {Open with uzbl}
\ uzbl-browser %f %i &,
filetype {*.html,*.htm},<text/html> links, lynx

" Object
filetype {*.o},<application/x-object> nm %f | less

" Man page
filetype {*.[1-8]},<text/troff> man ./%c
fileviewer {*.[1-8]},<text/troff> man ./%c | col -b

" Images
filextype {*.bmp,*.jpg,*.jpeg,*.png,*.gif,*.xpm},<image/*>
\ {View in sxiv}
\ sxiv %f,
\ {View in gpicview}
\ gpicview %c,
\ {View in shotwell}
\ shotwell,
fileviewer {*.bmp,*.jpg,*.jpeg,*.png,*.gif,*.xpm},<image/*>
\ identify %f

" OpenRaster
filextype *.ora
\ {Edit in MyPaint}
\ mypaint %f,

" Mindmap
filextype *.vym
\ {Open with VYM}
\ vym %f &,

" MD5
filetype *.md5
\ {Check MD5 hash sum}
\ md5sum -c %f %S,

" SHA1
filetype *.sha1
\ {Check SHA1 hash sum}
\ sha1sum -c %f %S,

" SHA256
filetype *.sha256
\ {Check SHA256 hash sum}
\ sha256sum -c %f %S,

" SHA512
filetype *.sha512
\ {Check SHA512 hash sum}
\ sha512sum -c %f %S,

" GPG signature
filetype {*.asc},<application/pgp-signature>
\ {Check signature}
\ !!gpg --verify %c,

" Torrent
filetype {*.torrent},<application/x-bittorrent> ktorrent %f &
fileviewer {*.torrent},<application/x-bittorrent> dumptorrent -v %c

" FuseZipMount
filetype {*.zip,*.jar,*.war,*.ear,*.oxt,*.apkg},
\<application/zip,application/java-archive>
\ {Mount with fuse-zip}
\ FUSE_MOUNT|fuse-zip %SOURCE_FILE %DESTINATION_DIR,
\ {View contents}
\ zip -sf %c | less,
\ {Extract here}
\ tar -xf %c,
fileviewer *.zip,*.jar,*.war,*.ear,*.oxt zip -sf %c

" ArchiveMount
filetype {*.tar,*.tar.bz2,*.tbz2,*.tgz,*.tar.gz,*.tar.xz,*.txz,*.tar.zst,*.tzst},
\<application/x-tar>
\ {Mount with archivemount}
\ FUSE_MOUNT|archivemount %SOURCE_FILE %DESTINATION_DIR,
fileviewer *.tgz,*.tar.gz tar -tzf %c
fileviewer *.tar.bz2,*.tbz2 tar -tjf %c
fileviewer *.tar.xz,*.txz tar -tJf %c
fileviewer *.tar.zst,*.tzst tar -t --zstd -f %c
fileviewer {*.tar},<application/x-tar> tar -tf %c

" Rar2FsMount and rar archives
filetype {*.rar},<application/x-rar>
\ {Mount with rar2fs}
\ FUSE_MOUNT|rar2fs %SOURCE_FILE %DESTINATION_DIR,
fileviewer {*.rar},<application/x-rar> unrar v %c

" IsoMount
filetype {*.iso},<application/x-iso9660-image>
\ {Mount with fuseiso}
\ FUSE_MOUNT|fuseiso %SOURCE_FILE %DESTINATION_DIR,

" SshMount
filetype *.ssh
\ {Mount with sshfs}
\ FUSE_MOUNT2|sshfs %PARAM %DESTINATION_DIR %FOREGROUND,

" FtpMount
filetype *.ftp
\ {Mount with curlftpfs}
\ FUSE_MOUNT2|curlftpfs -o ftp_port=-,,disable_eprt %PARAM %DESTINATION_DIR %FOREGROUND,

" Fuse7z and 7z archives
filetype {*.7z},<application/x-7z-compressed>
\ {Mount with fuse-7z}
\ FUSE_MOUNT|fuse-7z %SOURCE_FILE %DESTINATION_DIR,
fileviewer {*.7z},<application/x-7z-compressed> 7z l %c

" Office files
filextype {*.odt,*.doc,*.docx,*.xls,*.xlsx,*.odp,*.pptx,*.ppt},
\<application/vnd.openxmlformats-officedocument.*,
\application/msword,
\application/vnd.ms-excel>
\ libreoffice %f &
fileviewer {*.doc},<application/msword> catdoc %c
fileviewer {*.docx},
\<application/
\vnd.openxmlformats-officedocument.wordprocessingml.document>
\ docx2txt.pl %f -

" TuDu files
filetype *.tudu tudu -f %c

" Qt projects
filextype *.pro qtcreator %f &

" Directories
filextype */
\ {View in thunar}
\ Thunar %f &,

" Syntax highlighting in preview
"
" Explicitly set highlight type for some extensions
"
" 256-color terminal
" fileviewer *.[ch],*.[ch]pp highlight -O xterm256 -s dante --syntax c %c
" fileviewer Makefile,Makefile.* highlight -O xterm256 -s dante --syntax make %c
"
" 16-color terminal
" fileviewer *.c,*.h highlight -O ansi -s dante %c
"
" Or leave it for automatic detection
"
" fileviewer *[^/] pygmentize -O style=monokai -f console256 -g

" Displaying pictures in terminal
"
" fileviewer *.jpg,*.png shellpic %c

" Open all other files with default system programs (you can also remove all
" :file[x]type commands above to ensure they don't interfere with system-wide
" settings).  By default all unknown files are opened with 'vi[x]cmd'
" uncommenting one of lines below will result in ignoring 'vi[x]cmd' option
" for unknown file types.
" For *nix:
" filetype * xdg-open
" For OS X:
" filetype * open
" For Windows:
" filetype * start, explorer %"f &

" ------------------------------------------------------------------------------

" What should be saved automatically between vifm sessions.  Drop "savedirs"
" value if you don't want vifm to remember last visited directories for you.
set vifminfo=dhistory,savedirs,chistory,state,tui,shistory,
\phistory,fhistory,dirstack,registers,bookmarks,bmarks

" ------------------------------------------------------------------------------

" Examples of configuring both panels

" Customize view columns a bit (enable ellipsis for truncated file names)
"
" set viewcolumns=-{name}..,6{}.

" Filter-out build and temporary files
"
" filter! {*.lo,*.o,*.d,*.class,*.pyc,*.pyo,.*~}

" ------------------------------------------------------------------------------

" Sample mappings

" Start shell in current directory
nnoremap s :shell<cr>

" Display sorting dialog
nnoremap S :sort<cr>

" Toggle visibility of preview window
nnoremap w :view<cr>
vnoremap w :view<cr>gv

" Open file in existing instance of gvim
nnoremap o :!gvim --remote-tab-silent %f<cr>
" Open file in new instance of gvim
nnoremap O :!gvim %f<cr>

" Open file in the background using its default program
nnoremap gb :file &<cr>l

" Interaction with system clipboard
if has('win')
" Yank current directory path to Windows clipboard with forward slashes
nnoremap yp :!echo %"d:gs!\!/! %i | clip<cr>
" Yank path to current file to Windows clipboard with forward slashes
nnoremap yf :!echo %"c:gs!\!/! %i | clip<cr>
elseif executable('xclip')
" Yank current directory path into the clipboard
nnoremap yd :!echo %d | xclip %i<cr>
" Yank current file path into the clipboard
nnoremap yf :!echo %c:p | xclip %i<cr>
elseif executable('xsel')
" Yank current directory path into primary and selection clipboards
nnoremap yd :!echo -n %d | xsel --input --primary %i &&
\ echo -n %d | xsel --clipboard --input %i<cr>
" Yank current file path into into primary and selection clipboards
nnoremap yf :!echo -n %c:p | xsel --input --primary %i &&
\ echo -n %c:p | xsel --clipboard --input %i<cr>
endif

" Mappings for faster renaming
nnoremap I cw<c-a>
nnoremap cc cw<c-u>
nnoremap A cw

" Open console in current directory
nnoremap ,t :!xterm &<cr>

" Open editor to edit vifmrc and apply settings after returning to vifm
nnoremap ,c :write | edit $MYVIFMRC | restart full<cr>
" Open gvim to edit vifmrc
nnoremap ,C :!gvim --remote-tab-silent $MYVIFMRC &<cr>

" Toggle wrap setting on ,w key
nnoremap ,w :set wrap!<cr>

" Example of standard two-panel file managers mappings
nnoremap <f3> :!less %f<cr>
nnoremap <f4> :edit<cr>
nnoremap <f5> :copy<cr>
nnoremap <f6> :move<cr>
nnoremap <f7> :mkdir<space>
nnoremap <f8> :delete<cr>

" Midnight commander alike mappings
" Open current directory in the other pane
nnoremap <a-i> :sync<cr>
" Open directory under cursor in the other pane
nnoremap <a-o> :sync %c<cr>
" Swap panes
nnoremap <c-u> <c-w>x

" ------------------------------------------------------------------------------

" Various customization examples

" Use ag (the silver searcher) instead of grep
"
" set grepprg='ag --line-numbers %i %a %s'

" Add additional place to look for executables
"
" let $PATH = $HOME.'/bin/fuse:'.$PATH

" Block particular shortcut
"
" nnoremap <left> <nop>

" Export IPC name of current instance as environment variable and use it to
" communicate with the instance later.
"
" It can be used in some shell script that gets run from inside vifm, for
" example, like this:
"     vifm --server-name "$VIFM_SERVER_NAME" --remote +"cd '$PWD'"
"
" let $VIFM_SERVER_NAME = v:servername


1.24. newsboat

Oh newsboat, I am not using you anymore, but I still love you.

https://hnrss.org/best

["https://hnrss.org/best" ,"https://hnrss.org/show?point=200"]

1.25. scratch

printnt
print("Hello world")
pr



1.26. Xonsh

# XONSH WEBCONFIG START
xontrib load bashisms
execx($(/usr/bin/starship init xonsh --print-full-init))
# XONSH WEBCONFIG END
xontrib load kitty
xontrib load z

1.27. Scratch.el

;;; scratch.el -*- lexical-binding: t; -*-
;;
;; Copyright (C) 2022 nhannht
;;
;; Author: nhannht <nhanclassroom@gmail.com>
;; Maintainer: nhannht <nhanclassroom@gmail.com>
;; Created: July 10, 2022
;; Modified: July 10, 2022
;; Version: 0.0.1
;; Keywords: abbrev bib c calendar comm convenience data docs emulations extensions faces files frames games hardware help hypermedia i18n internal languages lisp local maint mail matching mouse multimedia news outlines processes terminals tex tools unix vc wp
;; Homepage: https://github.com/vermin/scratch
;; Package-Requires: ((emacs "24.3"))
;;
;; This file is not part of GNU Emacs.
;;
;;; Commentary:
;;
;;
;;
;;; Code:
(require 'parse-csv)
(require 'jupyter)
(require 's)
(require 'mode-local)
(defconst ext-list (mapcar #'s-trim
                           (parse-csv->list (with-temp-buffer
                                              (insert-file-contents "~/org-one/ext-code.csv")
                                              (buffer-string)))))

(defun vermin/find-scratch-file ()
  "Ask for extension and create a scratch file."
  (interactive)
  (let* ((ext (completing-read "Choose extension or type your own "
                               ext-list nil nil))
         (file-name (file-name-concat (getenv "HOME")
                                      "org-one"
                                      (concat "scratch." ext))))
    (find-file-other-window file-name)
    (goto-char (point-max))))


;;; Scratch
(defun example-action-function (target)
  (message "The target was `%s'." target))

(map! :leader :prefix
      "w"
      ((:in "<left>" #'evil-window-left)
       (:in "<right>" #'evil-window-right)
       (:in "<up>" #'evil-window-up)
       (:in "<down>" #'evil-window-down)))



(jupyter-sha256 (current-time-string))



(defun vermin/jupyter-src-block-insert ()
  (interactive)
  (let* ((kernels (mapcar #'car
                          (jupyter-available-kernelspecs)))
         (kernel (completing-read "Choose your kernel" kernels
                                  nil nil)))
    (insert (format "#+BEGIN_SRC jupyter :kernel %s :session %s\n\n#+END_SRC"
                    kernel kernel))
    (forward-line -1)))

(defun vermin/find-scrum-file ()
  (interactive)
  (find-file "~/org/org-one/main-scrum.org"))

(defun vermin/org-scrum-insert-task ())

(map! :map prog-mode-map
      (:in "C-<return>" #'outshine-insert-heading))

(defun vermin/file-header-insert ()
  (interactive)
  (call-interactively #'add-file-local-variable-prop-line))

(defun vermin/org-scrum-add-task (task)
  (interactive "sName of your task: ")
  (insert (format "*** TODO %s" task))
  (org-set-property "OWNER" "nhannht")
  (org-set-property "ESTIMATED" "0")
  (org-set-property "ACTUAL" "0")
  (org-set-property "TASKID" "??"))

(map! :map prog-mode-map
      (:in "C-c C-n" #'jupyter-org-execute-and-next-block)
      (:in "C-c C-p" #'jupyter-org-previous-busy-src-block))

(defun vermin/parse-org-template-for-cli ()
  (let* ((li  (cl-map 'list (lambda (x)(list (nth 0 x) (nth 1 x))) org-capture-templates))
         (li-fil  (seq-filter (lambda (y)  (> (length (nth 0 y))
                                              1))
                              li)))
    (string-join  (cl-loop for i in li-fil
                           collect  (format "%s : %s" (nth 0 i) (nth 1 i)))
                  "\n")))

(message (vermin/parse-org-template-for-cli))

(map! :map org-mode-map ((:in "C-n" #'next-line)
                         (:in "C-p" #'previous-line)))

(use-package! org
  :defer t
  :config
  (setq! org-structure-template-alist  '(("S" . "src shell  :results html :eval t")
                                         ("p" . "src python :session python :async yes  ")
                                         ("a" . "export ascii")
                                         ("r" . "src jupyter :kernel ssh :session ssh :async yes")
                                         ("c" . "center")
                                         ("C" . "comment")
                                         ("e" . "example")
                                         ("E" . "export")
                                         ("h" . "export html")
                                         ("l" . "export latex")
                                         ("q" . "quote")
                                         ("s" . "src")
                                         ("v" . "verse"))))
;; (map! :map org-mode-map :leader :prefix "m" (:in "v" #'org-babel-demarcate-block)  )
(map!  :map pdf-view-mode-map "TAB" #'org-noter-insert-note-toggle-no-questions )

(map!    (:prefix "SPC" :map pdf-view-mode-map  :in "v" #'org-noter-create-skeleton ) )

(setq vermin/pwa '("https://excalidraw.com/"
                   "https://dbdiagram.io/d"))

(defun vermin/find-web-app ()
  (interactive)
  (let ((app (completing-read "Choose your PWA " vermin/pwa nil nil)))
    (if  (executable-find "chromium")
        (async-shell-command (format  "/usr/bin/env chromium --app=%s" app)))))

(add-hook!
 '(calibredb-show-mode calibre-search-mode calibredb-search-mode-hook) #'evil-emacs-state)

(map!  :map prog-mode-map
       :leader
       :prefix "m" ( (:in "r d"  #'srefactor-lisp-format-defun)
                     (:in "r s" #'srefactor-lisp-format-sexp)
                     ))

(map! :map org-mode-map "C-'" #'+fold/toggle)

;;;; Remap evil-open-below with my custom key

(defun vermin/get-src-blk-lang ()
  "get language of src block"
  (interactive)
  (nth 0 (org-babel-get-src-block-info)))

(defun vermin/get-buffer-file-name-ext ()
  "return empty string if buffer is scratch or non-file buffer"
  (let ((name (buffer-file-name)))
    (if name
        (file-name-extension name)
      "")
    ))

(defun vermin/evil-open-below ()
  "Fix the bug when enter new line in org babel bash block"
  (interactive)
  (let ((ext (vermin/get-buffer-file-name-ext)))
    (cond
     ((not (string-equal ext "org"))
      (evil-open-below 1))
     ((and (eq evil-state 'normal)
           (org-in-src-block-p)
           (member (vermin/get-src-blk-lang) '("bash" "shell")))
      (progn
        (evil-insert-newline-below)
        (evil-insert-state)))
     (t (evil-open-below 1)))))

(defun vermin/evil-open-above ()
  "Fix the bug when enter new above line in org babel bash block"
  (interactive)
  (let ((ext (vermin/get-buffer-file-name-ext)))
    (cond
     ((not (string-equal ext "org"))
      (evil-open-above 1))
     ((and (eq evil-state 'normal)
           (org-in-src-block-p)
           (member (vermin/get-src-blk-lang) '("bash" "shell")))
      (progn
        (evil-insert-newline-above )
        (evil-insert-state)))
     (t (evil-open-above 1)))))



;; Wtf, it pass sympol as a argument instead of function
(evil-define-key 'normal 'evil-org-mode-map (kbd "O") #'vermin/evil-open-above)

(evil-define-key 'normal 'evil-org-mode  (kbd "o") 'vermin/evil-open-below)
(defun vermin/org-return ()
  "replace org-return/evil-org-return which bug in org babel bash block"
  (interactive)
  (if (and  (member evil-state '(insert))
            (org-in-src-block-p )
            (member  (vermin/get-src-blk-lang) '("bash" "shell") ))
      (progn
        (org-return-and-maybe-indent )
        )
    (+org/return))
  )

(evil-define-key 'insert 'evil-org-mode (kbd "<return>") 'vermin/org-return)

(use-package! org
  :defer t
  :init
  (setq org-startup-with-inline-images t)
  (setq org-startup-with-latex-preview t)
  (setq +org-startup-with-animated-gifs t))
(use-package! python
  :defer t
  :init (defun vermin/python-describe-at-point (symbol process)
          (interactive (list (python-info-current-symbol)
                             (python-shell-get-process)))
          (comint-send-string process
                              (concat "?? " symbol "\n")))
  :config
  (setq python-section-delimiter "#%%")
  (setq python-section-highlight t))

(use-package! py-prof
  :defer t)
(use-package! python-x
  :defer t
  :config
  (python-x-setup))

(use-package! python
  :defer t
  :config
  (defun vermin/python-describe-at-point (symbol process)
    (interactive (list (python-info-current-symbol)
                       (python-shell-get-process)))
    (comint-send-string process (concat "?? " symbol "\n" )))

  (defun vermin/python-describe-at-point-mini (symbol process)
    (interactive (list (python-info-current-symbol)
                       (python-shell-get-process)))
    (comint-send-string process (concat "? " symbol "\n" )))
  (map! :map python-mode-map  ((:i "C-c g" #'+company/complete )
                               (:i "C-c C-g" #'+company/complete)
                               (:in "C-c M-d" #'vermin/python-describe-at-point-mini))))

(use-package! edraw
  :defer t
  :config
  (defun turn-on-edraw-org-link-image-mode ()
    "Turn on this edraw-org display inline image "
    (when (string-equal major-mode "org-mode")
      (edraw-org-link-image-mode 1))))

(define-globalized-minor-mode global-edraw-org-link-image-mode edraw-org-link-image-mode turn-on-edraw-org-link-image-mode
  :init-value t
  (if global-edraw-org-link-image-mode
      (add-hook 'org-mode-hook #'edraw-org-link-image-mode)
    (remove-hook 'org-mode-hook #'edraw-org-link-image-mode )))

(use-package! edraw
  :after org
  )
(use-package! edraw-org
  :after edraw
  :commands #'edraw-org-edit-link
  :config
  (edraw-org-setup-default)
  (setq global-edraw-org-link-image-mode t))

(use-package! ibuffer
  :defer t
  :init
  (add-hook 'ibuffer-hook #'evil-emacs-state))

(setq enable-local-variables :safe)



(setq safe-local-variable-values '(( find-file-hook . org-babel-execute-buffer)
                                   (find-file-hook . (lambda ()(interactive)
                                                       (message "hello ")))))
;; (use-package! poetry)
;; (defun vermin/dashboard-startup-hook ()
;;     (progn
;;         (poetry-venv-workon)
;;         (org-babel-execute-buffer)))

;; (setq debug-on-error 1)


(defun vermin/dashboard-edit ()
  (interactive)
  (let ((dashboard  "~/org-one/dashboard.org"))
    (if (file-exists-p
         dashboard)
        (find-file dashboard)
      (error (string  "No " dashboard  "file found"))))

  (defun vermin/vterm-org-babel-src-blk-dir (&optional blk-name)
    (interactive)
    (let ((dir (cdr (assoc :dir (nth 2
                                     (org-babel-get-src-block-info))))))
      (if dir
          (with-temp-buffer
            (setq default-directory  dir)
            (vterm))
        (progn
          (message "This src block dont have :dir header, so open current directory")
          (vterm)))
      )
    )
  (add-hook 'org-babel-after-execute-hook #'save-buffer)
  (setq! org-element-use-cache nil
         org-export-babel-evaluate nil))
(defun vermin/howdoi-query ()
  "Call howdoi shell command and return result other window, work on both symbol at point or region"
  (interactive)
  (let* (( in (read-string "Ask your answer: "))
         (query (format "%s" in  )))
    (with-current-buffer (get-buffer-create "*howdoi output*")
      (erase-buffer)

      (insert (format "%s " query))
      (insert (shell-command-to-string (format "howdoi %s -n 5" query) ))
      (pop-to-buffer (current-buffer))
      (helpful-mode)
      (setq buffer-read-only nil)
      (beginning-of-buffer ))))

(defun vermin/howdoi ()
  "Call howdoi shell command and return result other window, work on both symbol at point or region"
  (interactive)
  (let* (( in (if mark-active
                  (buffer-substring-no-properties (region-beginning) (region-end))
                (symbol-name (symbol-at-point))))
         (query (format  "howdoi -n 5 How to use %s in %s"
                         in (vermin/get-major-language-current-buffer) ))
         )
    (with-current-buffer (get-buffer-create "*howdoi output*")
      (erase-buffer)

      (insert (format "%s \n " query))
      (insert (shell-command-to-string query ))
      (pop-to-buffer (current-buffer))
      (helpful-mode)
      (setq buffer-read-only nil))))

(use-package! howdoyou
  :commands howdoyou-query
  :config
  (setq howdoyou-switch-to-answer-buffer t)
  (setq howdoyou-max-history 100)
  )
(use-package! wolfram
  :defer t
  :config
  (setq wolfram-alpha-app-id  "K8AKR2-62T7EH48V5"))
(use-package! point-history
  :defer t
  :config
  (point-history-mode 1)
  (setq point-history-save-timer 5)
  (map! :mode point-history-show-mode
        ((:inev "RET" #'point-history-preview-at-point)
         (:inev "q" #'point-history-quit))) )

(use-package! hnreader
  :defer t)
(use-package! helm-net
  :commands helm-google-suggest)

;; (add-to-list '+emacs-lisp-disable-flycheck-in-dirs "~/org-one")
(map! :leader  :prefix-map ( "r" . "vermin help map")
      (:ine "e" #'vermin/howdoi-query)
      (:ine "r" #'helm-google-suggest)
      (:ine  "a" #'+lookup/in-all-docsets)
      (:ine "s" #'+lookup/in-docsets)
      (:ine "g" #'devdocs-lookup)
      (:ine "l" #'devdocs-install)
      (:ine "k" #'dash-docs-install-docset)
      (:ine "K" #'dash-docs-install-user-docset)
      (:ine "w" #'wolfram-alpha)
      (:ine "c" #'cheat-sh-maybe-region)
      )
(map! :leader ((:ine "s h" #'ivy-point-history)))
(setq org-directory "~/org-one")
(defun vermin/todo-find-central-file ()
  (interactive)
  (find-file-other-frame (expand-file-name +org-capture-todo-file org-directory)))

(defun vermin/todo-find-local-file
    (interactive)
  (find-file-other-window (+org--capture-local-root +org-capture-todo-file) ))
(defcustom vermin/scratch-el-file "~/org-one/scratch.el"
  "The file to store the scratch elisp file  ."
  :type 'file
  :group 'vermin)
(defun vermin/scratch-el-find-file ()
  (interactive)
  (find-file-other-frame vermin/scratch-el-file))

(map! :leader  "SPC" #'counsel-ibuffer)
(map! :leader (("s w" #'counsel-wmctrl)
               ("s u" #'counsel-outline)
               ("s I" #'counsel-etags-list-tag-in-current-file)
               ("s q" #'counsel-locate)
               ))

(map! :leader (("f t" #'vermin/todo-find-file)
               ("f x" #'vermin/scratch-el-find-file)
               ("f a" #'vermin/dashboard-edit)))
(use-package company
  :defer t
  :config
  (setq company-idle-delay 1))

;; (use-package! poetry
;;   :config
;;   (poetry-tracking-mode -1)
;;   (setq poetry-tracking-strategy 'projectile))
(use-package! copilot
  :defer t
  :config
  (setq copilot-idle-delay 1))
;; (use-package! poetry
;;   :config
;;   (setq! poetry-tracking-mode nil
;;          poetry-tracking-strategy 'switch-buffer))


;; (setq! eval-expression-debug-on-error nil
;;        debug-on-error nil
;;        edebug-on-error nil)
(setq enable-local-variables :all)
;; (use-package! virtualenvwrapper
;;   :config
;;   (venv-initialize-interactive-shells)
;;   (venv-initialize-eshell))


(defvar vermin/org-capture-readme-file "README.org"
  "Default target for README file")
(defun vermin/org-capture-readme-file ()
  (expand-file-name vermin/org-capture-readme-file org-directory))

(defun vermin/org-capture-project-readme-file ()

  "Find the nearest README.org file in parent directory, otherwise, opens a blanks one at the project root. Throws an errors if not in a project"
  (+org--capture-local-root vermin/org-capture-readme-file))

(defun vermin/find-org-readme-local-project ()
  (interactive)
  (find-file (vermin/org-capture-project-readme-file)))

(use-package! semantic
  :defer t)

(defvar-mode-local emacs-lisp-mode imenu-create-index-function 'imenu-default-create-index-function)

(defun vermin-setup-imenu-elisp-mode ()
  (setq imenu-create-index-function #'imenu-default-create-index-function))
(add-hook 'emacs-lisp-mode-hook #'vermin-setup-imenu-elisp-mode)

(use-package! helm
  :defer t )

(use-package! helm-semantic
  :commands helm-semantic-or-imenu)

(use-package! helm-occur
  :commands (list helm-occur))

(use-package! inspector
  :defer t)


(defcustom vermin/evil-emacs-default-state-mode-alist nil
  "List of all mode that use emacs state as default"
  :type 'list )
(mapcar (lambda (mode)
          (evil-set-initial-state mode 'emacs)) vermin/evil-emacs-default-state-mode-alist)

(add-to-list 'vermin/evil-emacs-default-state-mode-alist 'inspector-mode)
(use-package! org
  :defer t
  :config
  (setq org-export-use-babel nil)
  (org-babel-do-load-languages
   'org-babel-load-languages
   '((http . t)
     (jupyter . t)
     )))

(defun vermin/load-jupyter ()
  (interactive)
  (use-package! jupyter)
  (use-package! jupyter-python
    :after jupyter)
  (use-package! ob-jupyter
    :after  jupyter))

(use-package! jupyter)
(use-package! ob-jupyter)

                                        ; (setq native-comp-always-compile t)
                                        ; (setq native-comp-speed 3)
;; (setq native-comp-deferred-compilation t)

                                        ; (defun vermin/dired-native-comp-mark-file ()
                                        ;   (interactive)
                                        ;   (mapc (lambda (mark-file)
                                        ;           (native-compile-async mark-file t t))
                                        ;         (dired-get-marked-files)))
;; (use-package! mixed-pitch
;;   :after org
;;   :config
;;   (add-hook 'org-mode-hook #'mixed-pitch-mode) )
(map! :map vterm-mode-map :in "C-b" #'vterm--self-insert)
(map! :map vterm-mode-map :in "w" #'vterm--self-insert)
(use-package! code-stats
  :after prog-mode
  :config
  (setq code-stats-token "xxxxxxx")
  (add-hook 'prog-mode-hook #'code-stats-mode)
  (run-with-idle-timer 30 t #'code-stats-sync)
  (add-hook 'kill-emacs-hook (lambda () (code-stats-sync :wait))))

(use-package! valign
  :disabled t
  :after org
  :config
  (setq valign-fancy-bar nil)
  (setq valign-max-table-size 100000))
(use-package! pollen-mode
  :init
  (add-to-list 'auto-minor-mode-alist '("\\.pp\\'" . pollen-minor-mode))
  :after racket-mode)

(with-eval-after-load "helm-net"
  (push (cons "How Do You"  (lambda (candidate) (howdoyou-query candidate)))
        helm-google-suggest-actions))
;; (use-package! grip-mode
;;   :commands ( grip-mode grip-browse-preview)
;;   :init
;;   (add-hook 'markdown-mode-hook #'grip-mode))

(use-package! pollen-mode
  :mode (("\\.pp\\'" . racket-mode)
         ("\\.pm\\'" . racket-mode)
         ("\\.html.p\\'" . web-mode))
  :hook (web-mode . emmet-mode)
  :config
  (add-to-list 'auto-minor-mode-alist '("\\.pp\\'" . pollen-minor-mode)
               )
  (add-to-list 'auto-minor-mode-alist '("\\.pm\\'" . pollen-minor-mode)
               )
  (add-to-list 'auto-minor-mode-alist '("\\.p\\'" . pollen-minor-mode)
               )
  )
(use-package! yaml-mode
  :mode (( "\\.yml\\'" . yaml-mode)
         ("\\.yaml\\'" . yaml-mode)))
(use-package! xonsh-mode :mode (( "\\.xsh\\'" . xonsh-mode)))
(use-package! counsel)
;;; scratch.el ends here

Author: Nhannht

Created: 2023-01-07 Sat 18:08

Validate