Emacs Startup
The init file.

Table of Contents

Tags:

Elisp tags are: package, mode, variable, function, custom, interactive. Git and gitignore tags are: git.

1. Tasks to do

  1. TODO Counsel and ivy should be loaded before Nano

    There is a require nano-counsel. So, the Nano sections depends on Ivy and counsel!

2. Measure init time

I want to know how much time takes to start Emacs.

(defvar my-init-start-time (time-to-seconds)
  "The time when the init.org load starts.")
(defvar my-init-stop-time nil
  "The time when the init.org load ends")

3. Requirements

(require 'seq)

4. Which device? Cellphone or computer?

In cellphone, some packages should not be loaded to avoid problems with Termux. The same happens in Win.

Also, some variables are set differently depending on the Operative System. For instance, the bell is very annoying in Win, therefore it may be removed if am-i-on-win-p return true.

⚠️ This section should be at the begining: other sections uses it!

  1. am-i-on-cellphone-p   function
    (defun am-i-on-cellphone-p ()
      "True if this Emacs instance is on a cellphone"
      (numberp (string-search "android" system-configuration)))
    
  2. am-i-on-win-p   function
    (defun am-i-on-win-p ()
      "True if this Emacs instance is on a Win OS"
      (or (equal 'windows-nt system-type)
          (numberp (string-search "x86_64-w64-mingw32" system-configuration))))
    

5. Emacs-stuff path and definitions

Path definitions: where is the emacsstuff?

  1. Git: ignore some Emacs files   git
    1. Temporary files
      *~
      \#* 
      
    2. Compiled files
      *.elc
      
  2. emacsstuff-path   variable
    (defvar emacsstuff-path "~/emacs-stuff/"
      "Path where is the emacs_stuff directory. Add a \"/\" at the end!")
    
  3. emacsstuff-dir   function
    (defun emacsstuff-dir (dir)
      "Return a string with the complete path of a diectory DIR inside the 
    `emacsstuff-path'.
    DIR must be a string without initial \"/\".
    
    Example:
      (emacsstuff-dir \"dists/scripts/my-scritp.el\")
    "
      (concat emacsstuff-path dir))
    
  4. emacsstuff-packasubpath   variable

    Path definition for packages installed in dists/packs:

    (defvar emacsstuff-packsubpath "dists/packs/"
      "Where is the packs dir located inside the `emacsstuff-path'.
    
    See `emacsstuff-packsdir' and `emacsstuff-dir'.")
    
  5. emacsstuff-packsdir   function
    (defun emacsstuff-packsdir (pack-path)
      "Return the complete path of the PACK-PATH.
    
    Use `emacsstuff-packsubpath' variable for changing the packs subdir."
      (concat (emacsstuff-dir emacsstuff-packsubpath) pack-path))
    
  6. Setup the load-path
    1. Add emacsstuff-dirs

      Setup the load-path variable with the emacsstuff-dir. Add the scrip and other emacs-stuff directories.

      (add-to-list 'load-path (emacsstuff-dir "dists/scripts"))
      (add-to-list 'load-path (emacsstuff-dir "personal"))
      (add-to-list 'load-path (emacsstuff-dir "dists/linked-scripts"))
      
    2. Add system site-lisp path

      There is another load-path from the system. This is usually used by installed system packages which provides some Elisp code. For instance, the lilypond compiler provides some Elisp files for Emacs and they are installed in this directory.

      (push "/usr/share/emacs/site-lisp" load-path)
      
  7. Username

    Delete the login name to avoid writing it anywhere.

    (setq user-login-name "")
    
  8. Git repositories path
    1. Find the repository path
      1. my-repo-path   variable
        (defvar my-repo-path "~/repos/emacs"
          "Where is my Emacs repositories?
        The init.org file will load every path here!")
        
    2. Add repos/emacs/* to the load-path

      Except repos/emacs/emacs which is the Emacs source code!

      1. my-find-repo-paths   function
        (defun my-find-repo-paths ()
          "Return a list of repository directories
        Return a list of repositories in `my-repo-path'.  The repo path is
        not checked and an error will be raised if it does not exists."
          (mapcar (lambda (x)
                    (concat my-repo-path "/" x))
                  (seq-difference (directory-files my-repo-path)
                                  '("." ".." "emacs"))))
        
      2. my-update-repo-paths   function interactive

        How many times I have to update the repository paths because I have just added a new repo.

        So, here's the function (at last!) that updates the load-path with the new repositories only!

        (defun my-update-repo-paths ()
          "Update `load-path' with new repositories paths.
        Repositories paths should be ~/repos/emacs/* directories."
          (interactive)
          (let ((not-in-load-path (seq-filter (lambda (path)
                                                (not (member path load-path)))
                                                (my-find-repo-paths))))
            (setq load-path (append not-in-load-path load-path))
            (message "Added %s new paths: %s" (length not-in-load-path) not-in-load-path)))
        
        
      3. Add repos to load-path
        (if (file-exists-p my-repo-path)
            (setq load-path (append load-path (my-find-repo-paths)))
          (progn
            (message "Repository path does not exist! Creating it.")
            (make-directory my-repo-path t)))
        

6. My-Secrets - My personal information

My-Secrets are data that should not be published, such as usernames and passwords, personal folders, private configurations, tokens, or similar strings.

For this reason, the ./secrets/secrets-data.el.gpg file is an Elisp code encrypted (possibly with AES or a symmetric encription).

  1. Git: Ignore the secrets directory   git

    The git program should ignore all files in ./secrets/

    secrets/**
    
  2. Load my-secrets.el

    The my-secrets.el library is on ./dists/scripts/my-secrets.el. Provides a very basic secrets storage. We use it here to get information stored there, but not revealed to the public.

    (require 'my-secrets)
    

7. Packages and Scripts installation

;; (message"==> Packages and scripts installation")
  1. NOT-SUPPORTED Add Melpa repository

    Add the https://melpa.org repository.

    ⚠️ MELPA is added by emacs-spellbook.

    (require 'package) ;; You might already have this line
    
    (let* ((no-ssl (and (memq system-type '(windows-nt ms-dos))
                        (not (gnutls-available-p))))
           (url (concat (if no-ssl "http" "https") "://melpa.org/packages/")))
      (add-to-list 'package-archives (cons "melpa" url) t))
    
    (when (< emacs-major-version 24)
      ;; For important compatibility libraries like cl-lib
      (add-to-list 'package-archives '("gnu" . "http://elpa.gnu.org/packages/")))
    
  2. NOT-SUPPORTED Add NonGNU ELPA repository

    ⚠️ Is added by emacs-spellbook.

    (add-to-list 'package-archives
                 '("nongnu-dev" . "https://elpa.nongnu.org/nongnu-devel/"))
    
  3. NOT-SUPPORTED Initialize package repository

    ⚠️ Is added by emacs-spellbook.

    (package-initialize)
    
  4. use-package   package

    This package should be installed on emacs.

    ;; This is only needed once, near the top of the file
    (eval-when-compile (require 'use-package))
    

    Enable statistics to show the time of which package takes to load.

    (setq use-package-compute-statistics t)
    

    Install all packages by default.

    (require 'use-package-ensure)
    (setq use-package-always-ensure t)
    
  5. vc-use-package   package

    The vc-use-package can be found on Emacs 30+ by default. In other versions, it must be downloaded from Internet.

    (unless (package-installed-p 'vc-use-package)
      (package-vc-install "https://github.com/slotThe/vc-use-package"))
    (require 'vc-use-package)
    

8. Some bugfixes

  1. auth-info-password returns a function

    TRAMP did not work properly, and I found it was because auth-info-password returns a function… for instance:

    (auth-info-password
     (auth-source-search :max 1 :user "" :host "localhost" :port "sudo"
                         :require (cons :secret :user) :create t))
    

    Para evitar este problema, le incluimos un advice que chequea si retorna una funciĆ³n y la ejecuta si sucede este problema.

    (require 'auth-source)
    
    (defun my-auth-info-password (result)
      (if (functionp result)
          (funcall result)
        result))
    
    (advice-add 'auth-info-password :filter-return #'my-auth-info-password)
    

9. Convenience and Appearance

;; (message"==> Convenience and appearance")
  • Delete selection is useful.
  • Inverse video is better for its black background.
  • I don't want tabs in my code! indent with spaces!
  • The startup screen is not needed.

Inverse video on cellphone is not good: background is white!

(delete-selection-mode 1)
(setq inverse-video (not (am-i-on-cellphone-p))
      indent-tabs-mode nil)
  1. Theme

    Enable a beautiful theme.

    1. NOT-SUPPORTED doom-themes   package
      (use-package doom-themes
      :ensure t
      :config
      ;; Theme
      (load-theme 'doom-one t)
      (custom-set-faces
       '(font-lock-comment-face ((t (:foreground "dark gray"))))
       '(font-lock-doc-face
         ((t (:inherit font-lock-comment-face :foreground "dark gray"))))
       '(font-lock-function-name-face ((t (:foreground "#c678dd" :weight bold))))
       '(font-lock-keyword-face ((t (:foreground "#51afef" :weight bold))))
       '(font-lock-variable-name-face ((t (:foreground "#dcaeea" :weight bold))))))
      
    2. NOT-SUPPORTED nord theme   package

      ⚠️ Change the default theme. Now I use the dark theme from spellbook.

      I use the nord-theme in some cases. Homepage is https://nordtheme.com.

      (use-package nord-theme
        :ensure t)
      
    3. NOT-SUPPORTED NANO Emacs

      ⚠️ I'm using emacs-spellbook now.

      My repository is: https://github.com/cnngimenez/nano-emacs

      Original repository is: https://github.com/rougier/nano-emacs

      (unless (locate-library "nano")
        (message "Download nano with git from https://github.com/cnngimenez/nano-emacs.")
        (error "Nano library could not be loaded: download it from its repository!"))
      
      1. Requirements
        1. smex   package
          (use-package smex
            :ensure t)
          
      2. Customs

        Nano can be customised too. The following are personal customisations.

        1. nano-font-size should be 11

          The default font is with height 110 (see Fonts section). This settings tells nano to use that height by default (see nano-faces function).

          (setq nano-font-size 11)
          ;; (nano-faces) should be called later...
          
      3. Loading

        Load path…

        ⚠️ Themes and colour-schemes must be loaded before this section!

        (when (file-exists-p "~/repos/emacs/nano-emacs/nano.el")
          (push "~/repos/emacs/nano-emacs" load-path)
          (require 'nano-base-colors)
          (require 'nano-faces)
        
          (require 'nano-layout)
          (require 'nano-theme-dark)
          (unless (am-i-on-cellphone-p)
            (nano-theme-set-dark)
            (nano-faces))
        
          (require 'nano-theme)
          (nano-theme)
        
          ;; Nano default settings (optional)
          (require 'nano-defaults)
        
        
          ;; Nano session saving (optional)
          (require 'nano-session)
        
          ;; Nano header & mode lines (optional)
          (require 'nano-modeline)
        
          ;; Nano key bindings modification (optional)
          (require 'nano-bindings)
        
          ;; Compact layout (need to be loaded after nano-modeline)
          ;; (unless (member "-no-compact" command-line-args)
          ;;   (require 'nano-compact))
        
          ;; Nano counsel configuration (optional)
          ;; Needs "counsel" package to be installed (M-x: package-install)
          (require 'nano-counsel)
        
          ;; Welcome message (optional)
          (let ((inhibit-message t))
            (message "Welcome to GNU Emacs / N Λ N O edition")
            (message (format "Initialization time: %s" (emacs-init-time))))
        
          ;; Splash (optional)
          (unless (member "-no-splash" command-line-args)
            (require 'nano-splash))
        
          ;; Help (optional)
          (unless (member "-no-help" command-line-args)
            (require 'nano-help)))
        
      4. Some face fixes

        Fix italic: do not make it undelined! By default, Nano makes it underlined or with faded colour.

        Fix bold too!

        (set-face-attribute 'italic nil
                            :foreground 'unspecified :background 'unspecified
                            :family     'unspecified :slant      'oblique
                            :weight     'unspecified :height     'unspecified
                            :underline  'unspecified :overline   'unspecified
                            :box        'unspecified :inherit    'unspecified)
        (set-face-attribute 'bold nil
                            :foreground 'unspecified :background 'unspecified
                            :family     'unspecified :slant      'unspecified
                            :weight     'bold        :height     'unspecified
                            :underline  'unspecified :overline   'unspecified
                            :box        'unspecified :inherit    'unspecified)
        
      5. Show something at frame title
        (setq frame-title-format '(multiple-frames "%b"
                                                           ("" "%b - GNU Emacs at " system-name)))
        
      6. Font lock maximum decoration   doc

        Beware that font-lock-maximum-decoration and font-lock-maximum-size are disabled. This leads to far too less font-lock syntax highlighting with colours.

        This settings is modified at line ~58 in nano-default.el file.

      7. Show pop-up windows

        When using any function that creates pop-up windows, like org-goto, show it.

        If this is nil it would show the pop-up buffer in the same window which is not ment to be it.

        (setq pop-up-windows t)
        
      8. Fix bindings
        1. Removing bindings

          Some bindings are annoying!

          (global-unset-key (kbd "<M-return>"))
          (global-unset-key (kbd "C-x C-c"))
          (require 'org)
          (define-key org-mode-map (kbd "<M-return>") nil)
          
        2. Close binding
          (defun my-delete-frame-or-kill-emacs ()
            "Delete frame or kill Emacs if there is only one frame."
            (interactive)
            (if (> (length (seq-filter #'frame-visible-p (frame-list))) 1)
                (delete-frame)
              (save-buffers-kill-terminal)))
          
          (global-set-key (kbd "C-x C-c") 'my-delete-frame-or-kill-emacs)
          
      9. Titles faces for Org

        Nano is too minimal… I need something more LaTeX-like!

        (defun my-org-faces-fix ()
          "Fix the NANO faces that affects to org-mode faces.
        We want titles and tags more LaTeX-like! "
          (set-face-attribute 'org-level-1 nil
                              :height (* nano-font-size 14)
                              :weight 'bold)
          (set-face-attribute 'org-level-2 nil
                              :height (* nano-font-size 12)
                              :weight 'medium)
          (set-face-attribute 'org-level-3 nil
                              :height (* nano-font-size 10))
          (set-face-attribute 'org-tag nil
                              :height (* nano-font-size 10)
                              :weight 'medium))
        (my-org-faces-fix)
        
    4. NOT-SUPPORTED Programming vs reading appearance

      ⚠️ Requires more modifications!

      1. Programming appearance
        1. my-programming–fix-faces   function

          Fix some compatibility problems between nord theme and NANO Emacs.

          Fix window divider: it appears when loading nord.

          (defun my-programming--fix-faces ()
            "Fix some faces for `my-emacs-programming'."
            (set-face-attribute 'window-divider nil
                                :foreground nano-color-background)
            (set-face-attribute 'window-divider-first-pixel nil
                                :foreground nano-color-background)
            (set-face-attribute 'window-divider-last-pixel nil
                                :foreground nano-color-background))
          
        2. my-programming-set-font   function

          Hack font is better

          (defun my-programming-set-font ()
            "Set an appropiate font for programming."
            (set-face-attribute 'default nil :font "Hack" :height 110))
          
        3. my-emacs-programming   interactive function

          Enable nord theme to some programming languages.

          (defun my-emacs-programming ()
            "Set emacs appearance for programming."
            (interactive)
            (load-theme 'nord t)
            (setq font-lock-maximum-decoration t)
            (setq font-lock-maximum-size t)
            (my-programming--fix-faces)
            (my-programming-set-font)
            (nano-theme--mode-line))
          
      2. Reading appearance
        1. my-emacs-reading   interactive function
          (defun my-emacs-reading ()
            "Change the font to something more useful for reading."
            (interactive)
            (disable-theme 'nord)
            (nano-theme)
            (my-org-faces-fix)
            (my-programming--fix-faces)
            (nano-theme--mode-line)
            ;; (set-face-attribute 'default nil
            ;;                     :font "Fira Sans" :height 140))
            (set-face-attribute 'default nil
                                :font "Latin Modern Roman" :height 110))
          
          
  2. Convenience
    1. Dired customisations
      1. Hide details in cellphone
        (when (am-i-on-cellphone-p)
          (add-hook 'dired-mode-hook #'dired-hide-details-mode))
        
    2. NOT-SUPPORTED frame tabs

      List opened buffer as tabs.

      (use-package frame-tabs
        :ensure nil
        :config
      
      1. Filter tabs

        Filter out tabs with "*" in its name.

        (defun my-frame-tabs-default-filter (buffer frame)
          (let ((name (frame-tabs-default-filter buffer frame)))
            (when name
              (if (string-match-p "^[[:space:]]*[^\\*]" name)
                  name
                nil))))
        
          (setq frame-tabs-filter-function 'my-frame-tabs-default-filter)
        
      2. End
        ) ;; use-package
        
    3. Disable beep/bell

      On Win (and any Operative System!), the bell is very annoying! Let's just make it visible and not audible.

      (setq visible-bell t)
      
    4. Menu and tool bar

      Disable menu and tool bar. Set F10 to show the menubar as a text-mode one.

      ⚠️ Using menu-bar-mode and tool-bar-mode changes the font… maybe, is it a bug?

      ;; (let ((font-family (face-attribute 'default :family))
      ;;       (font-height (face-attribute 'default :height)))
      ;;   (menu-bar-mode -1)  ;; Managed by Emacs-Spellbook
      ;;   (tool-bar-mode -1) ;; Manager by Emacs-spellbook
      ;;   (set-face-attribute 'default nil
      ;;                       :font font-family
      ;;                       :height font-height))
      
      (defun menu-bar-open (&optional frame)
        "Show the menu bar as a text menu.
      FRAME is unused."
        (interactive)
        (tmm-menubar))
      
      (global-set-key [f10] 'menu-bar-open)  
      
    5. NOT-SUPPORTED Fonts

      ⚠️ I'm using emacs-spellbook now.

      Use Hack family as the default font. For unicode characters use a Symbola family by default if no other is used. If any of these are not found, message the user.

      This will override de Roboto font because it cannot show the italics properly. Hack can show these faces properly: italic bold Monospaced

      ;; set a default font
      ;; (when (member "FreeMono" (font-family-list))
      ;;   (set-face-attribute 'default nil :font "FreeMono"))
      (if (and (not (am-i-on-cellphone-p))
               (member "Hack" (font-family-list)))
          (set-face-attribute 'default nil
                              :font "Hack"
                              :height 110)
        (message "⚠ Hack font not loaded. Please, install it and run fc-cache -vf."))
      
      ;; specify font for all unicode characters
      (if (and (not (am-i-on-cellphone-p))
               (member "Noto Color Emoji" (font-family-list)))
          (set-fontset-font t 'unicode "Noto Color Emoji" nil 'prepend)
        (message "⚠ Noto Color Emoji font not loaded. Please install it and run fc-cache -vf."))
      
      (defun my-set-reading-font ()
        "Change the font to something more useful for reading."
        (interactive)
        (set-face-attribute 'default nil
                            :font "Fira Sans" :height 110))
      (defun my-set-mono-font ()
        "Change font to something useful for programming."
        (interactive)
        (set-face-attribute 'default nil :font "Hack" :height 110))
      
    6. NOT-SUPPORTED Cursor type and blinking

      ⚠️ I'm using emacs-spellbook now.

      (setq-default cursor-type 'box)
      (setq-default cursor-in-non-selected-windows nil)
      (setq-default cursor-in-echo-area nil)
      (blink-cursor-mode 0)
      
    7. NOT-SUPPORTED Startup buffers

      ⚠️ I'm using emacs-spellbook now.

      1. No emacs splash
        (setq-default inhibit-startup-screen t
                      inhibit-startup-message t
                      inhibit-startup-echo-area-message t)
        
      2. Scratch
        (setq-default initial-major-mode #'lisp-interaction-mode)
        
    8. NOT-SUPPORTED Emojify global mode

      This is the emojy-mode. Use it after initialization.

      (add-hook 'after-init-hook #'global-emojify-mode)
      
    9. NOT-SUPPORTED Load transparent.el

      Enable transparent frames. Useful when writing LaTeX code and using Okular or evince at the background.

      āš  Using KDE Application Special configuration. The active/inactive opacity can be set there. It conflicts with the Emacs transparency frame settings and sometimes it does not work.

      (load-library "transparent")
      
      1. KDE Settings

        This is the KDE Application settings for eamacs. This can be imported in the Configure - Edit Application-Specific Settings window.

        [Application settings for emacs]
        Description=Application settings for emacs
        clientmachine=localhost
        opacityactive=90
        opacityactiverule=2
        opacityinactive=55
        opacityinactiverule=2
        wmclass=emacs
        wmclassmatch=1
        
    10. NOT-SUPPORTED Line and number modes

      ⚠️ Is added by emacs-spellbook.

      Show the column number, and visual line frindges. Wrap lines at the edge with visual line, highlight the current line, and display the fill-column indicator.

      It is better to not highlight the current line… Depending on the theme colours and the device it may not show good.

      ;; line wrap and number modes
      (setq column-number-mode t
            visual-line-fringe-indicators t)
      (global-visual-line-mode)
      (global-hl-line-mode 0)
      ;; (global-visual-fill-column-mode)
      (global-display-fill-column-indicator-mode)
      
    11. NOT-SUPPORTED All the Icons

      ⚠️ I'm using emacs-spellbook now.

      Package for showing nice icons. Several packages may use this one, such as dired, ivy, and others.

      This snippet check if the icons exists, if not it downloads them.

      Only activate all-the-icons when not on cellphone!

      (unless (am-i-on-cellphone-p)
      
      1. all-the-icons   package
        ;; (message"==> all-the-icons")
        (use-package all-the-icons
          :if (not (am-i-on-cellphone-p))
          :ensure t
          :config
          ;; Install icons for all-the-icons if not founded
          (unless (or (file-exists-p "~/.local/share/fonts/all-the-icons.ttf")
                      (file-exists-p "~/.fonts/all-the-icons.ttf"))
            (all-the-icons-install-fonts) ) )
        
      2. All the Icons Dired   package

        Repairing icons : Apply this patch https://github.com/domtronn/all-the-icons.el/pull/106/files

        ;; (message"==> all-the-icons-dired")
        (use-package all-the-icons-dired
          :if (not (am-i-on-cellphone-p))
          :ensure t
          :after (all-the-icons)
          :config
          (add-hook 'dired-mode-hook 'all-the-icons-dired-mode t) ) ;; use-package
        
      3. All the icons in ibuffer   package
        (use-package all-the-icons-ibuffer
          :if (not (am-i-on-cellphone-p))
          :ensure t
          :after (all-the-icons)
          :hook (ibuffer-mode . all-the-icons-ibuffer-mode))
        
      4. NOT-SUPPORTED All the Icons Ivy   package

        Provide support to ivy for all-the-icons. āš  It is better to use all-the-icons for ivy-rich.

        (use-package all-the-icons-ivy
          :if (not (am-i-on-cellphone-p))
          :ensure t
          :after (all-the-icons ivy)
          :config
          (all-the-icons-ivy-setup) ) ;; use-package 
        
      5. All the Icons Ivy-Rich   package

        Provide icons to ivy-rich.

        ;; (message"==> all-the-icons-ivy-rich")
        (use-package all-the-icons-ivy-rich
                     :if (not (am-i-on-cellphone-p))
                     :ensure t
                     :after (all-the-icons ivy-rich)
                     :init (progn
                             (ivy-rich-mode 1)
                             (all-the-icons-ivy-rich-mode 1)))
        
      6. All the icons to completion candidates   package
        (use-package all-the-icons-completion
          :if (not (am-i-on-cellphone-p))
          :ensure t
          :after (all-the-icons))
        
      7. All the icons for gnus   package
        (use-package all-the-icons-gnus
          :if (not (am-i-on-cellphone-p))
          :after (all-the-icons))
        
      8. All the icons end
        ) ;; End  all-the-icons
        
    12. NOT-SUPPORTED Doom Modeline   package

      A nice modeline with cute icons.

      ;; (message"==> doom-modeline")
      (use-package doom-modeline
        :ensure t
        :config
        (doom-modeline-init)
        ;; (setq doom-modeline-height 10)
        ;; (set-face-attribute 'mode-line nil :height 100)
        ;; (set-face-attribute 'mode-line-inactive nil :height 100)
        ) ;; doom-modeline
      
    13. NOT-SUPPORTED which-key mode   package

      ⚠️ I'm using emacs-spellbook now.

      Show key references when pressing a partial key-binding.

      ;; (message"==> which-key")
      (use-package which-key
        :ensure t
        :config
        (which-key-mode) ) 
      
    14. NOT-SUPPORTED Ivy autocompletion ecosystem

      ⚠️ I'm using emacs-spellbook now.

      Ivy, Counsel and Swiper setup.

      1. Ivy   package

        Remove the S-SPC key which is annoying when using upcase letters.

        ;; (message"==> Ivy")
        (use-package ivy
          :ensure t
          :config
          (ivy-mode 1)
          (setq ivy-use-virtual-buffers t)
          (setq enable-recursive-minibuffers t)
          ;; (global-set-key (kbd "C-c C-r") 'ivy-resume)
          ;; (global-set-key (kbd "<f6>") 'ivy-resume)
          (define-key ivy-minibuffer-map (kbd "S-SPC") nil))
        
      2. Ivy-rich   package

        Richer experience with Ivy. Show more information in ivy buffers like Elisp function and variable descriptions, file data, etc.

        (use-package ivy-rich
          :ensure t
          :config  
        
        1. Transformer list

          The original trasformer list is huge and slow. By removing some uninteresting elements make it really faster.

          (unless (am-i-on-cellphone-p)
            (load-library (emacsstuff-dir "dists/scripts/ivy-rich-transformer-list.el")))
          
        2. End use-package

          Enable, disable and re-enable rich mode at startup. For some reason, Emacs 29 gives error when switching buffer and this restore it.

          (ivy-rich-mode 1)
          (ivy-rich-mode 0)
          (ivy-rich-mode 1)) ;; use-package ivy-rich
          
      3. Counsel   package

        Counsel package provide Ivy substitutes for common Emacs tasks: M-x, find-file, describe-*, etc. To enable it, just call the counsel-mode function.

        (use-package counsel
          :ensure t
          :config
          ;; (global-set-key (kbd "M-x") 'counsel-M-x)
          ;; (global-set-key (kbd "C-x C-f") 'counsel-find-file)
          ;; (global-set-key (kbd "<f1> f") 'counsel-describe-function)
          ;; (global-set-key (kbd "<f1> v") 'counsel-describe-variable)
          ;; (global-set-key (kbd "<f1> l") 'counsel-find-library)
          ;; (global-set-key (kbd "<f2> i") 'counsel-info-lookup-symbol)
          ;; (global-set-key (kbd "<f2> u") 'counsel-unicode-char)
          ;; (global-set-key (kbd "C-c g") 'counsel-git)
          ;; (global-set-key (kbd "C-c j") 'counsel-git-grep)
          ;; (global-set-key (kbd "C-c k") 'counsel-ag)
          ;; (global-set-key (kbd "C-x l") 'counsel-locate)
          ;; (global-set-key (kbd "C-S-o") 'counsel-rhythmbox)
          ;; (define-key minibuffer-local-map (kbd "C-r") 'counsel-minibuffer-history)
          (counsel-mode))
        
      4. NOT-SUPPORTED Swiper   package

        Swiper provides a better experience for searching strings. āš  It is too slow!!!

        (use-package swiper
        :ensure t
        :config
        ;; (global-set-key "\C-s" 'swiper)
        ) ;; use-package
        
      5. Prescient   package

        With prescient, Ivi can sort and filter candidates in a different way. Homepage: https://github.com/raxod502/prescient.el The order is: the last few candidates used, the most frequently used, and the shortests length first. The prescient-filter-method variable can be customised to change this filter method.

        (use-package ivy-prescient
          :ensure t
          :config
          (ivy-prescient-mode))
        
    15. NOT-SUPPORTED Helm   package

      Helm show candidates at the minibuffer. Helm is used as a library for other packages to show different options or selections.

      āš  Ivy and counsel are used as a replacement of helm. However, this is still required by scripts and other packages.

      (use-package helm
      :ensure t)
      
    16. NOT-SUPPORTED Savehist: Save History

      ⚠️ I'm using emacs-spellbook now.

      Savehist is a library installed on Emacs 29 by default. It saves the minibuffer history and restores it at startup.

      The objetive is to preserve all command history through different emacs instances. Using Ivy with savehist will restore the last history commands when emacs closes and runs again.

      (require 'savehist)
      (savehist-mode t)
      
    17. Prettify - ligatures

      Prettify or ligatures is the technique to change one or more characters into a visual symbol. For instance, a keyword like then may be changed into the unicode arrow →.

      Here is the documentation: http://www.modernemacs.com/post/prettify-mode/

      Problems: It counts the number of characters as one, reflecting a different number per line as it really is. However, it can be solved by disabling the prettify-symbols-mode.

      No package is required to install.

      ;; (message"==> Prettify")
      (global-prettify-symbols-mode 1)
      
      1. NOT-SUPPORTED Python

        Symbols for Python mode.

        (add-hook
         'python-mode-hook
         (lambda ()
           (mapc (lambda (pair) (push pair prettify-symbols-alist))
                 '(;; Syntax
                   ("def" .      #x2131)
                   ("not" .      #x2757)
                   ("in" .       #x2208)
                   ("not in" .   #x2209)
                   ("return" .   #x27fc)
                   ("yield" .    #x27fb)
                   ("for" .      #x2200)
                   ;; Base Types
                   ("int" .      #x2124)
                   ("float" .    #x211d)
                   ("str" .      #x1d54a)
                   ("True" .     #x1d54b)
                   ("False" .    #x1d53d)
                   ;; Mypy
                   ("Dict" .     #x1d507)
                   ("List" .     #x2112)
                   ("Tuple" .    #x2a02)
                   ("Set" .      #x2126)
                   ("Iterable" . #x1d50a)
                   ("Any" .      #x2754)
                   ("Union" .    #x22c3)))))
        
      2. NOT-SUPPORTED Web-mode
        (defun pretty-symbols--web-fnc ()
            (mapc (lambda (pair) (push pair prettify-symbols-alist))
                  '(;; Syntax
                    ("function" .      #x2131)
                    ("not" .      #x2757)
                    ("in" .       #x2208)
                    ("not in" .   #x2209)
                    ("return" .   #x27fc)
                    ("yield" .    #x27fb)
                    ("for" .      #x2200)
                    ;; ("<?php" . #xe938 )
                    ;; ("<?=" . #xe94f )
                    ;; ("->" . #x2192)
                    ;; ("=>" . #x21D2)
                    ;; ("::" . #Xe10a)
                    ;; Base Types
                    ("int" .      #x2124)
                    ("integer" .      #x2124)
                    ("float" .    #x211d)
                    ("str" .      #x1d54a)
                    ("string" .      #x1d54a)
                    ("True" .     #x1d54b)
                    ("true" .     #x1d54b)
                    ("False" .    #x1d53d)
                    ("false" .    #x1d53d)
                    ;;
                    ("=<" . ?≤)
                    (">=" . ?≥)
                    ("==" . ?⩵)
                    ("!=" . ?≠)
                    )))
        
        (add-hook 'web-mode-hook 'pretty-symbols--web-fnc) 
        
        (defconst pretty-fonts-fira-font-web
          '(;; OPERATORS
        
            ;; Equality
            ("\\(!=\\)" #Xe10e) ("\\(!==\\)"         #Xe10f) ("\\(=/=\\)" #Xe143)
            ("\\(/=\\)" #Xe12c) ("\\(/==\\)"         #Xe12d)
            ("\\(===\\)"#Xe13d) ("[^!/]\\(==\\)[^>]" #Xe13c)
        
            ;; Equality Special
            ("\\(||=\\)"  #Xe133) ("[^|]\\(|=\\)" #Xe134)
            ("\\(~=\\)"   #Xe166)
            ("\\(\\^=\\)" #Xe136)
            ("\\(=:=\\)"  #Xe13b)
        
            ;; Comparisons
            ("\\(<=\\)" #Xe141) ("\\(>=\\)" #Xe145)
        
            ;; Shifts
            ("[^-=]\\(>>\\)" #Xe147) ("\\(>>>\\)" #Xe14a)
            ("[^-=]\\(<<\\)" #Xe15c) ("\\(<<<\\)" #Xe15f)
        
            ;; REPEATED CHARACTERS
            ;; 2-Repeats
            ("\\(||\\)" #Xe132)
            ("\\(!!\\)" #Xe10d)
            ("\\(&&\\)" #Xe131)
        
            ;; 2+3-Repeats
            ("\\(##\\)"       #Xe11b) ("\\(###\\)"         #Xe11c) ("\\(####\\)" #Xe11d)
            ("\\(--\\)"       #Xe111) ("\\(---\\)"         #Xe112)
            ("\\(::\\)"       #Xe10a) ("\\(:::\\)"         #Xe10b)
        
            ;; ARROWS
            ;; Direct
            ("[^-]\\(->\\)" #Xe114) ("[^=]\\(=>\\)" #Xe13f)
        
            ;; MISC
            ("\\(www\\)"                   #Xe100)
            ("\\(<!--\\)"                  #Xe151)
            ("\\(~@\\)"                    #Xe164)
            ("[^<]\\(~~\\)"                #Xe168)
            ("\\(\\?=\\)"                  #Xe127)
            ("<\\(\\?php\\)"                 #Xe94f)
            ("[^=]\\(:=\\)"                #Xe10c)
            ("\\(/>\\)"                    #Xe12e)
            ("[^\\+<>]\\(\\+\\)[^\\+<>]"   #Xe16d)
            ("</?\\(a\\)" #Xe157)
            ("<\\(script\\)" #XF15C)
        
        )
          "Fira font ligatures and their regexes")
        
        
      3. NOT-SUPPORTED CoffeeScript
        (add-hook 'coffee-mode-hook 'pretty-symbols--coffee-fnc) 
        
      4. NOT-SUPPORTED Use Fira

        Warning: Org-mode looks bad, need more tweaking!

        Fira symbola font, needed: https://github.com/tonsky/FiraCode/files/412440/FiraCode-Regular-Symbol.zip

        Font install instructions: https://github.com/tonsky/FiraCode/wiki/Linux-instructions#installing-with-a-package-manager

        Manual Install script:

        #!/usr/bin/env bash
        
        fonts_dir="${HOME}/.local/share/fonts"
        if [ ! -d "${fonts_dir}" ]; then
            echo "mkdir -p $fonts_dir"
            mkdir -p "${fonts_dir}"
        else
            echo "Found fonts dir $fonts_dir"
        fi
        
        for type in Bold Light Medium Regular Retina; do
            file_path="${HOME}/.local/share/fonts/FiraCode-${type}.ttf"
            file_url="https://github.com/tonsky/FiraCode/blob/master/distr/ttf/FiraCode-${type}.ttf?raw=true"
            if [ ! -e "${file_path}" ]; then
                echo "wget -O $file_path $file_url"
                wget -O "${file_path} ${file_url}"
            else
                echo "Found existing file $file_path"
            fi;
        done
        
        echo "fc-cache -f"
        fc-cache -f
        
        (require 'pretty-fonts)
        (pretty-fonts-set-kwds '((pretty-fonts-fira-font-web
                                  ;; prog-mode-hook
                                  web-mode-hook)))
        

        For testing purposes, this reset the setted hooks:

        (setq web-mode-hook '(web-narrow-mode))
        (setq prog-mode-hook nil)
        (pretty-fonts-set-kwds
           '((pretty-fonts-fira-font-web
              ;; prog-mode-hook
              web-mode-hook)))
        
      5. Check if FiraCode is installed

        Warn the user about the FiraCode font if it is not installed.

        (unless (member "FiraCode" (font-family-list))
          (message "Warning: Fira code is needed for ligatures and it was not found!"))
        
      6. A working implementation

        https://github.com/karahobny/.emacs.d/blob/master/init/init-fira-code-ligatures.el

        This snippet uses font-lock to search for the symbol and the Fira Code Symbol font. The font can be downloaded from https://github.com/tonsky/FiraCode/files/412440/FiraCode-Regular-Symbol.zip (posted in an issue comment here), and then installed by copying it into /.fonts. To update the font-cache run fc-cache -v -f. Remember to restart emacs after any change.

        (unless (am-i-on-cellphone-p)
          (add-hook 'after-make-frame-functions
                    (lambda (frame) (set-fontset-font t
                                                      '(#Xe100 . #Xe16f)
                                                      "Fira Code Symbol")))
          (set-fontset-font t '(#Xe100 . #Xe16f) "Fira Code Symbol"))
        
          (defconst fira-code-font-lock-keywords-alist
            (mapcar (lambda (regex-char-pair)
                      `(,(car regex-char-pair)
                        (0 (prog1 ()
                             (compose-region (match-beginning 1)
                                             (match-end 1)
                                             ,(concat " "
                                                      (list
                                                       (decode-char 'ucs
                                                                    (cadr regex-char-pair)))))))))
        
                    '(("\\(www\\)"                   #Xe100)
                      ("[^/]\\(\\*\\*\\)[^/]"        #Xe101)
                      ("\\(\\*\\*\\*\\)"             #Xe102)
                      ("\\(\\*\\*/\\)"               #Xe103)
                      ("\\(\\*>\\)"                  #Xe104)
                      ("[^*]\\(\\*/\\)"              #Xe105)
                      ("\\(\\\\\\\\\\)"              #Xe106)
                      ("\\(\\\\\\\\\\\\\\)"          #Xe107)
                      ("\\({-\\)"                    #Xe108)
                      ;; box-looking character ([], aka list operator) looks
                      ;; too much like unicode missing-glyph icon. also the cons
                      ;; operator (::), along with the list ([]), both fuck up
                      ;; the alignment of sml and haskell-code far too goddamn
                      ;; often to be of any aesthetical use, rather an irritant
                      ;; if anything.
        
                      ;; TODO: FIXME: fix these by adding fake spaces to them?
        
                      ;; ("\\(\\[\\]\\)"                #Xe109)
                      ;; ("\\(::\\)"                    #Xe10a)
                      ("\\(:::\\)"                   #Xe10b)
                      ("[^=]\\(:=\\)"                #Xe10c)
                      ;; ("\\(!!\\)"                    #Xe10d)
                      ;; this should be hooked to sml-mode only
                      ("\\(<>\\)"                    #Xe10e)
                      ("\\(!=\\)"                    #Xe10e)
                      ("\\(!==\\)"                   #Xe10f)
                      ("\\(-}\\)"                    #Xe110)
                      ("\\(--\\)"                    #Xe111)
                      ("\\(---\\)"                   #Xe112)
                      ("\\(-->\\)"                   #Xe113)
                      ("[^-]\\(->\\)"                #Xe114)
                      ("\\(->>\\)"                   #Xe115)
                      ("\\(-<\\)"                    #Xe116)
                      ("\\(-<<\\)"                   #Xe117)
                      ("\\(-~\\)"                    #Xe118)
                      ("\\(#{\\)"                    #Xe119)
                      ("\\(#\\[\\)"                  #Xe11a)
                      ("\\(##\\)"                    #Xe11b)
                      ("\\(###\\)"                   #Xe11c)
                      ("\\(####\\)"                  #Xe11d)
                      ("\\(#(\\)"                    #Xe11e)
                      ("\\(#\\?\\)"                  #Xe11f)
                      ("\\(#_\\)"                    #Xe120)
                      ("\\(#_(\\)"                   #Xe121)
                      ("\\(\\.-\\)"                  #Xe122)
                      ("\\(\\.=\\)"                  #Xe123)
                      ("\\(\\.\\.\\)"                #Xe124)
                      ("\\(\\.\\.<\\)"               #Xe125)
                      ("\\(\\.\\.\\.\\)"             #Xe126)
                      ("\\(\\?=\\)"                  #Xe127)
                      ("\\(\\?\\?\\)"                #Xe128)
                      ("\\(;;\\)"                    #Xe129)
                      ("\\(/\\*\\)"                  #Xe12a)
                      ("\\(/\\*\\*\\)"               #Xe12b)
                      ("\\(/=\\)"                    #Xe12c)
                      ("\\(/==\\)"                   #Xe12d)
                      ("\\(/>\\)"                    #Xe12e)
                      ("\\(//\\)"                    #Xe12f)
                      ("\\(///\\)"                   #Xe130)
                      ("\\(&&\\)"                    #Xe131)
                      ("\\(||\\)"                    #Xe132)
                      ("\\(||=\\)"                   #Xe133)
                      ("[^|]\\(|=\\)"                #Xe134)
                      ("\\(|>\\)"                    #Xe135)
                      ("\\(\\^=\\)"                  #Xe136)
                      ("\\(\\$>\\)"                  #Xe137)
                      ("\\(\\+\\+\\)"                #Xe138)
                      ("\\(\\+\\+\\+\\)"             #Xe139)
                      ("\\(\\+>\\)"                  #Xe13a)
                      ("\\(=:=\\)"                   #Xe13b)
                      ("[^!/]\\(==\\)[^>]"           #Xe13c)
                      ("\\(===\\)"                   #Xe13d)
                      ("\\(==>\\)"                   #Xe13e)
                      ("[^=]\\(=>\\)"                #Xe13f)
                      ("\\(=>>\\)"                   #Xe140)
                      ("\\(<=\\)"                    #Xe141)
                      ("\\(=<<\\)"                   #Xe142)
                      ("\\(=/=\\)"                   #Xe143)
                      ("\\(>-\\)"                    #Xe144)
                      ("\\(>=\\)"                    #Xe145)
                      ("\\(>=>\\)"                   #Xe146)
                      ("[^-=]\\(>>\\)"               #Xe147)
                      ("\\(>>-\\)"                   #Xe148)
                      ("\\(>>=\\)"                   #Xe149)
                      ("\\(>>>\\)"                   #Xe14a)
                      ("\\(<\\*\\)"                  #Xe14b)
                      ("\\(<\\*>\\)"                 #Xe14c)
                      ("\\(<|\\)"                    #Xe14d)
                      ("\\(<|>\\)"                   #Xe14e)
                      ("\\(<\\$\\)"                  #Xe14f)
                      ("\\(<\\$>\\)"                 #Xe150)
                      ("\\(<!--\\)"                  #Xe151)
                      ("\\(<-\\)"                    #Xe152)
                      ("\\(<--\\)"                   #Xe153)
                      ("\\(<->\\)"                   #Xe154)
                      ("\\(<\\+\\)"                  #Xe155)
                      ("\\(<\\+>\\)"                 #Xe156)
                      ("\\(<=\\)"                    #Xe157)
                      ("\\(<==\\)"                   #Xe158)
                      ("\\(<=>\\)"                   #Xe159)
                      ("\\(<=<\\)"                   #Xe15a)
                      ;; ("\\(<>\\)"                    #Xe15b)
                      ("[^-=]\\(<<\\)"               #Xe15c)
                      ("\\(<<-\\)"                   #Xe15d)
                      ("\\(<<=\\)"                   #Xe15e)
                      ("\\(<<<\\)"                   #Xe15f)
                      ("\\(<~\\)"                    #Xe160)
                      ("\\(<~~\\)"                   #Xe161)
                      ("\\(</\\)"                    #Xe162)
                      ("\\(</>\\)"                   #Xe163)
                      ("\\(~@\\)"                    #Xe164)
                      ("\\(~-\\)"                    #Xe165)
                      ("\\(~=\\)"                    #Xe166)
                      ("\\(~>\\)"                    #Xe167)
                      ("[^<]\\(~~\\)"                #Xe168)
                      ("\\(~~>\\)"                   #Xe169)
                      ("\\(%%\\)"                    #Xe16a)
                      ("[^:=]\\(:\\)[^:=]"           #Xe16c)
                      ("[^\\+<>]\\(\\+\\)[^\\+<>]"   #Xe16d)
                      ("[^\\*/<>]\\(\\*\\)[^\\*/<>]" #Xe16f)
                      )))
        
          (defun add-fira-code-symbol-keywords ()
            "Add the Fira Code ligatures from Fira Code Symbol to selected keywords."
            (font-lock-add-keywords nil fira-code-font-lock-keywords-alist))
        
          ;; (provide 'init-fira-code-ligatures)
        
      7. PHP symbols

        PHP symbol replacement list.

        (defconst web-code-font-lock-keywords-alist
          (mapcar (lambda (regex-char-pair)
                    `(,(car regex-char-pair)
                      (0 (prog1 ()
                           (compose-region (match-beginning 1)
                                           (match-end 1)
                                           ,(concat "   "
                                                    (list
                                                     (decode-char 'ucs
                                                                  (cadr regex-char-pair)))))))))
        
        
                  '(
                  ("<\\(\\?php\\)"        #Xe94f)
                  ;; ("<?=" . #xe94f )
                    ("\\(function\\)"       #x2131)
                    ("\\(return\\)"         #x27fc)
                    ("\\(for\\) "           #x2200)
        
                    ;; Base Types
                    (" \\(int\\) "       #x2124)
                    (" \\(float\\) "     #x211d)
                    (" \\(str\\) "       #x1d54a)
                    ("[^[:alnum:]]\\(True\\)[^[:alnum:]]"      #x1d54b)
                    ("[^[:alnum:]]\\(true\\)[^[:alnum:]]"      #x1d54b)
                    ("[^[:alnum:]]\\(False\\)[^[:alnum:]]"     #x1d53d)
                    ("[^[:alnum:]]\\(false\\)[^[:alnum:]]"     #x1d53d)
                    ("\\(::\\)"             #Xe10a)
                    )))
        
        (defun add-web-code-symbol-keywords ()
          "Add the Fira Code ligatures from Fira Code Symbol to selected keywords."
          (font-lock-add-keywords nil web-code-font-lock-keywords-alist))
        
      8. Elisp symbols

        Elisp replacement symbol list

        (defconst elisp-code-font-lock-keywords-alist
          (mapcar (lambda (regex-char-pair)
                    `(,(car regex-char-pair)
                      (0 (prog1 ()
                           (compose-region (match-beginning 1)
                                           (match-end 1)
                                           ,(concat "   "
                                                    (list
                                                     (decode-char 'ucs
                                                                  (cadr regex-char-pair)))))))))
        
        
                  '(
                    ("\\(defvar\\)"     #x1d4b1) 
                    ("\\(defconst\\)"   #x1d49e) ;; otra: #x212d
                    ("\\(defun\\)"       #x2131)
                    ("\\(dolist\\) "           #x2200)
        
                    ;; Base Types
                    (" \\(int\\) "       #x2124)
                    (" \\(float\\) "     #x211d)
                    (" \\(str\\) "       #x1d54a)
                    ("[^[:alnum:]]\\(True\\)[^[:alnum:]]"      #x1d54b)
                    ("[^[:alnum:]]\\(true\\)[^[:alnum:]]"      #x1d54b)
                    ("[^[:alnum:]]\\(False\\)[^[:alnum:]]"     #x1d53d)
                    ("[^[:alnum:]]\\(false\\)[^[:alnum:]]"     #x1d53d)
                    )))
        
        (defun add-elisp-code-symbol-keywords ()
          "Add the Fira Code ligatures from Fira Code Symbol to selected keywords."
          (font-lock-add-keywords nil elisp-code-font-lock-keywords-alist))
        
      9. Adding hooks to affected modes

        Enabling symbol replacement into web-mode, prog-mode, and emacs-lisp-mode.

        (add-hook 'prog-mode-hook #'add-fira-code-symbol-keywords)
        ;; (add-hook 'scheme-mode-hook  #'add-fira-code-symbol-keywords)
        ;; (add-hook 'clojure-mode-hook #'add-fira-code-symbol-keywords)
        (add-hook 'web-mode-hook  #'add-web-code-symbol-keywords)
        (add-hook 'emacs-lisp-mode-hook #'add-elisp-code-symbol-keywords)
        
    18. NOT-SUPPORTED Origami   package
      (use-package origami
        :ensure t)
      (require 'origami)
      (require 'origami-parsers)
      (require 'dash)
      ;; (require 'cl)
      
      1. Conflicts!

        Origame has conflicts with the package installer. For some reason, possibly the hiding of text, it signals unbalanced parenthesis errors.

      2. KeyBindings
        (define-key origami-mode-map "\C-oo" 'origami-toggle-node)
        (define-key origami-mode-map "\C-or" 'origami-recursively-toggle-node)
        (define-key origami-mode-map "\C-oc" 'origami-toggle-all-nodes)
        (define-key origami-mode-map "\C-of" 'origami-show-only-node)
        
      3. NOT-SUPPORTED Elisp Parser
        ;; (defun origami-elisp-parser (create)
        ;;   (origami-lisp-parser create "\\(^[[:space:]]*;+[[:space:]]*\\(.*\\)$\\|(def\\w*\\s-*\\(\\s_\\|\\w\\|[:?!]\\)*\\([ \\t]*(.*?)\\)?\\)"))
        ;; (defun origami-elisp-parser (create)
        ;;   (origami-lisp-parser create "(def\\w*\\s-*\\(\\s_\\|\\w\\|[:?!]\\)*\\([ \\t]*(.*?)\\)?"))
        
        ;; (defun comment-parser (create beg end)
        ;;   (lambda (content)
        ;;     (funcall create beg end 1 nil)
        ;;     )
        ;;   )
        
        ;; (defun origami-elisp-parser (create)
        ;;   (let* ((beg (point-at-bol))
        ;;        (end (point-at-eol))
        ;;        (strline (buffer-substring-no-properties beg end))
        ;;        )
        ;;     (if (string-match "^[[:space:]]*;+.*$" strline)
        ;;       (comment-parser create beg end)
        ;;       (origami-lisp-parser create "(def\\w*\\s-*\\(\\s_\\|\\w\\|[:?!]\\)*\\([ \\t]*(.*?)\\)?")
        ;;       ) ;; if 
        ;;     ) ;; let    
        ;;   ) ;; defun
        
      4. BibTeX Parser
        (defun origami-bibtex-parser (create)
          (lambda (content)
            (let (lst-nodes beg end offset)
              (with-temp-buffer
                (insert content)
                (goto-char (point-min))
                (while (search-forward-regexp "\\(@[[:alpha:]]+{[^,]+\\),.*" nil t)
                  (setq beg (match-beginning 0))
                  (setq offset (length (match-string 1)))
                  ;; Search the next entry or the end of buffer, then go back up to "}"
                  (goto-char (+ 1 (point)))
                  (if (search-forward-regexp "@[[:alpha:]]+{" nil t)
                      (goto-char (match-beginning 0))
                    (goto-char (point-max)))
                  (search-backward "}" nil t)     
                  (setq end (point))
                  (add-to-list 'lst-nodes (funcall create beg end offset nil) )
                  ) ;; while
                ) ;; with-current-buffer
              (reverse lst-nodes)
              ) ;; let
            ) ;; lambda
          ) ;; defun
        
        (push '(bibtex-mode . origami-bibtex-parser) origami-parser-alist)
        
      5. SWI Parser
        (defvar origami-swi-regexps-alist
          '((pred . "^\\([[:alpha:]_]+\\)\\((.*)\\)?[[:space:]]*\\(:-\\|\\.\\|-->\\)")
            (comment . "^[[:space:]]*/\\*"))
          "List of regexps types used")
        
        (defun origami-swi-search (type)
          "Make a search using the previded regexp."
          (search-forward-regexp (alist-get type origami-swi-regexps-alist) nil t)
          ) ;; defun
        
        
        (defun origami-swi-search-comment ()
          "Search all the commets and return a list of origami nodes." 
          (let (beg end predname more-preds)
        
            (if (origami-swi-search 'comment)
                (progn
                  (setq beg (match-beginning 0))
                  (setq predname (match-string-no-properties 1))
                  (search-forward "*/" nil t)
                  (setq end (point))
        
                  (list beg end 2 predname)
                  ) ;; progn
              nil
              ) ;; if
            ) ;; let    
          )
        
        (defun origami-swi-search-pred ()
          "Search the following predicate region.
        
        Returns a list with this elements: 
          (begin-point end-point offset pred-name)
        Returns nil if no predicate found."
          (let (beg end offset predname more-preds)
        
            (if (origami-swi-search 'pred)
                (progn
                  (setq beg (match-beginning 0))
                  (setq offset (length (match-string 1)))
                  (setq predname (match-string-no-properties 1))
                  (setq more-preds t)
                  (while (and more-preds
                              (string-equal (match-string 1) predname))
                    (setq end (match-end 0))
                    (goto-char end)
                    (unless (origami-swi-search 'pred)
                      (setq more-preds nil))
                    ) ;; (while )
                  (goto-char end)
                  (search-forward "." nil t)      
                  (setq end (point))
        
                  (list beg end offset predname)
                  ) ;; progn
              nil
              ) ;; if
            ) ;; let
          )
        
        (defun origami-swi-all-searchs (search-fnc)
          "Return all preds node info from the current buffer.
        
        Parameters: 
        SEARCH-FNC is a function without parameters retrieving the next node as a list of (beg end offset)."
          (goto-char (point-min))
          (let (node lst-nodes)
            (setq node (funcall search-fnc))
            (while node
              (let ((beg (nth 0 node))
                    (end (nth 1 node))
                    (offset (nth 2 node)))
                (add-to-list 'lst-nodes (list beg end offset) t)
                (goto-char end)
                ) ;; let
              (setq node (funcall search-fnc))
              ) ;; while
            lst-nodes
            ) ;; let
          ) ;; defun
        
        (defun origami-node-less (n1 n2)
          "Return t if n1 points before than n2."
          (< (car n1) (car n2))
          )
        
        (defun origami-overlap-nodes (a b)
          "Return t if A overlaps B or B overlaps A."
          (or
           ;; Start of B is in A region
           (and (<= (car a) (car b))
                (<= (car b) (cadr a)))
                ;; End of B is in A region
           (and (<= (car a) (cadr b))
                (<= (cadr b) (cadr a)))
           ;; Start of A is in B region
           (and (<= (car b) (car a))
                (<= (car a) (cadr b)))
           ;; End of A is in B region
           (and (<= (car b) (cadr a))
                (<= (cadr a) (cadr b)))
           )
          )
        
        (defun origami-remove-overlaps (orig list)
          "Remove from LIST the elements that are overlaped with any element from ORIG.
        
        We expect that both list are sorted."
        
          (let ((lstres nil)
                (oind 0)
                (oelt (nth 0 orig))
                (lorig (1- (length orig)))
                )
            (dolist (elt list)
              ;; Advance oelt until we find a possible overlap candidates
              (while (and (< oind lorig)
                          (> (car elt) (cadr oelt)))
                ;; The elt is after oelt, cannot be overlaped
                (setq oind (1+ oind))
                (setq oelt (nth oind orig)))
        
              (unless (origami-overlap-nodes elt oelt)
                (add-to-list 'lstres elt)
                ) ;; unless
              ) ;; dolist
            lstres
            ) ;; let
          ) ;; defun
        
        (defun origami-append-no-overlap (lista listb)
          "Append LISTB into LISTA removing from LISTB all overlaped nodes."
          (append lista (origami-remove-overlaps lista listb))
          )
        
        (defun origami-swi-parser (create)
          (lambda (content)
            (let (lst-nodes node)
              (with-temp-buffer
                (insert content)
        
                (setq lst-nodes       
                      (origami-append-no-overlap (origami-swi-all-searchs 'origami-swi-search-comment)
                                                 (origami-swi-all-searchs 'origami-swi-search-pred)))
        
                (setq lst-nodes (cl-sort lst-nodes 'origami-node-less))
        
                (setq lst-nodes (mapcar (lambda (node)
                                          (let ((beg (car node))
                                                (end (nth 1 node))
                                                (offset (nth 2 node)))
                                            (funcall create beg end offset nil)) ;; let
                                          ) ;; lambda
                                        lst-nodes))
                lst-nodes             
                ) ;; with-current-buffer
              ) ;; let
            ) ;; lambda
          ) ;; defun
        
        (push '(prolog-mode . origami-swi-parser) origami-parser-alist)
        
      6. Ada parser
        (defun origami--ada-begin-parser ()
          "Search for \"begin\" and \"end\" words in the current buffer"
          (let ((lst-result '()))
            (save-excursion
              (goto-char (point-min))
              (while (search-forward-regexp "begin.*end" nil t)
                (add-to-list (funcall create
                                      (add-to-list
                                       (match-beginning 0)
                                       (match-end 0)))
                             )
                (goto-char (match-end))
                ) ;; while
              )
            ) ;; let  
          ) ;; defun
        
      7. Automatic load
        (defun origami--start-mode ()
          (origami-mode t)
          (origami-close-all-nodes (current-buffer))
        ) ;; defun
        (add-hook 'emacs-lisp-mode-hook 'origami--start-mode)
        ;; (add-hook 'web-mode-hook 'origami--start-mode) 
        

        āš  Warning! Don't set origami for using with prog-mode. It breaks other modules like yasnippet. This line should not be included:

        (add-hook 'prog-mode-hook 'origami--start-mode)
        
    19. Auto-fill

      Use 80 columns by default instead of 70.

      ;; (add-hook 'find-file-hooks 'auto-fill-mode)
      (setq fill-column 80)
      
    20. eldoc-mode

      Shows in the echo area the parameters of a function an other useful info of the symbol around the cursor.

      No need to add this snippet, because there is a global-eldoc-mode.

      ;; (add-hook 'emacs-lisp-mode-hook 'turn-on-eldoc-mode)
      ;; (add-hook 'lisp-interaction-mode-hook 'turn-on-eldoc-mode)
      ;; (add-hook 'ielm-mode-hook 'turn-on-eldoc-mode)  
      
      (global-eldoc-mode t)
      
    21. Finding prolog   package

      This is a personal project. It elaborate a subprogram signature database in any programming project. It support several languages: Prolog, Ada, Elisp, and others. Adding more languages are easy: add more DCG rules.

      Project homepage: https://gitlab.com/cnngimenez/finding-prolog

      (add-to-list 'load-path "~/repos/emacs/finding-prolog")
      
      (use-package fp
      :ensure nil
      :defer t)
      
    22. NOT-SUPPORTED Beacon   package

      šŸ’­ Disabled it because it is a little annoying.

      (use-package beacon
        :ensure nil
        :config 
        (setq beacon-color "#8fbcbb") ;; nord7 color
        (beacon-mode nil))
      
    23. Embark   package

      Provides a contextual menu by means of some keymaps. It is like a right-click contextual menu, but using a specific key strokes.

      The concepts used are:

      Target
      Where the text/region where Embark will act upon it.
      Actions
      The available actions that appears on the contextual menu.

      Marginalia and Consult packages are recommended.

      I should not use Marginalia with Ivy-rich, it may conflict…

      See this blog, it is awesome! https://karthinks.com/software/fifteen-ways-to-use-embark/

      (use-package embark
        :ensure t
        :bind (("C-." . embark-act)
               ("C-;" . embark-dwim)
               ("C-h B" . embark-bindings)))
      
    24. SachaC-news   package

      Yep, This is a package to be up-to-date with Sacha Chua's News. Here is the repository: https://github.com/cnngimenez/sachac-news

      Clone it with:

      cd ~/repos/emacs; git clone https://github.com/cnngimenez/sachac-news.git sachac
      
      (use-package sachac-news
        :if (locate-library "sachac-news")
        :ensure nil
        :config
        (sachac-news-activate-timer))
      
    25. Company completion framework
      1. company   package
        (use-package company)
        
      2. company-box   package

        Company box is a front end with explanations and colours. Is very useful for elisp programming.

        It does not work in tty or terminals.

        (use-package company-box
          :if (not (am-i-on-cellphone-p))
          :after company
          :hook (company-mode . company-box-mode))
        
    26. kdeconnect   package

      KDEConnect is an Android and a desktop application for the KDE environment. It can send files and many other things. Emacs kdeconnect package allows to connect to these applications and to use them to same files, messages, etc. It uses the kdeconnect-cli terminal program as a background subprocess: make sure it is installed!

      The configuration sets the kdeconnect-devices variable with the devices IDs found by kdeconnect-cl or by M-x kdeconnect-list-devices. The value is a strings with IDs separated by commas, for example: "def54321,abc12345".

      (use-package kdeconnect
        :if (not (am-i-on-cellphone-p))
        :ensure t
        :config
        (setq kdeconnect-devices (my-secrets-get "kdeconnect-devices")))
      
      (if (file-exists-p "~/repos/emacs/kdeconnect.el/kdeconnect.el")
          (load-library "kdeconnect")
        (message "kdeconnect.el couldn't be found. Please clone the repository from https://github.com/cnngimenez/kdeconnect.el.git"))
      
    27. Async shell command won't show the output buffer

      I want to run a lot of programs using M-& and, in dired mode with &. But is annoying to see the output buffer right away hiding your current work.

      This will avoid showing the output buffer, it just hides it.

      (unless (assoc shell-command-buffer-name-async display-buffer-alist)
        (push (cons shell-command-buffer-name-async '((display-buffer-no-window)))
              display-buffer-alist))
      

10. Text, Ploting and graphics programming

;; (message"==> Text, Ploting and graphics programming")
  1. Org-mode
    1. Agenda
      1. Agenda Icons org-agenda-category-icon-alist   custom

        When #+category: computers is used, an icon is shown on org-brain and org-agenda for it and its children.

        (unless (am-i-on-cellphone-p)
          (setq org-agenda-category-icon-alist
                `(("computers" ,(list (all-the-icons-material "computer"))
                   nil nil :ascent center)
                  ("books" ,(list (all-the-icons-faicon "book"))
                   nil nil :ascent center)
                  ("congresos" ,(list (all-the-icons-faicon "university"))
                   nil nil :ascent center)
                  ("teaching" ,(list (all-the-icons-faicon "graduation-cap"))
                   nil nil :ascent center)
                  ("master" ,(list (all-the-icons-faicon "book"))
                   nil nil :ascent center)
                  ("radio" ,(list (all-the-icons-material "radio"))
                   nil nil :ascent center)
                  ("home" ,(list (all-the-icons-faicon "home"))
                   nil nil :ascent center)
                  ("internals" ,(list (all-the-icons-faicon "cog"))
                   nil nil :ascent center)
                  ("google" ,(list (all-the-icons-faicon "google"))
                   nil nil :ascent center)
                  ("holidays" ,(list (all-the-icons-faicon "calendar-times-o"))
                   nil nil :ascent center)
                  ("efemérides" ,(list (all-the-icons-faicon "calendar-times-o"))
                   nil nil :ascent center)            
                  ("Diary" ,(list (all-the-icons-faicon "calendar-times-o"))
                   nil nil :ascent center))))
        
      2. Tags position in agenda   custom

        Put the tags at 80 maximum.

        (setq org-agenda-tags-column -80)
        
    2. Exporting to iCalendar

      I am using ICSx5 and Etar to see my calendar on my cellphone. If I export the Org-agenda files into ICS, and send the .ics files with syncthing, I can see it on the phone.

      This functions does this!

      1. Exporting iCalendar files to Syncthing directory
        (setq org-icalendar-combined-agenda-file "~/Sync/orgs/org.ics")
        
      2. Export all agenda files except specific ones

        The Google calendar is imported by the Cellphone from the ICS URL.

        1. my-do-not-export-to-ics
          (defvar my-do-not-export-to-ics '("/home/poo/Sync/orgs/google.org")
            "Exclude these paths from exporting them to the ics file.")
          
        2. my-export-org-agenda-to-ics   interactive function

          The org-icalendar-combine-agenda-files function creates a new Emacs subprocess when the async parameter is non-nil. This init file will be too slow and may generate conflicts as it requires user input and many other libraries.

          Therefore, a new temporary init file is created for the new subprocess. This init file has the output file (stored at org-icalendar-combined-agenda-file variable). The org-export-async-init-file is setted with the new init file path for the subprocess. When setted, the --batch -Q -l /tmp/org-export-init-fileXXXXXXXX -l /tmp/orgicsXXXXXXX parameters are used when calling the new Emacs.

          It is important that the asynchronous export works. Below, a timer is defined to run this function every hour, and Emacs should not be staggered.

          (defun my-export-org-agenda-to-ics (&optional sync)
            "Export the org-agenda files into ics files.
          If SYNC is t, then run synchronously."
            (interactive "P")
            (let ((org-export-async-init-file (make-temp-file "org-export-init-file"))
                  (org-agenda-files (cl-remove-if (lambda (path)
                                                    (member path my-do-not-export-to-ics))
                                                  (org-agenda-files t))))
              ;; Add the needed variable to generate the ICS file at the desired location.
              (with-temp-file org-export-async-init-file
                (insert (format "%S" `(setq org-icalendar-combined-agenda-file
                                            ,org-icalendar-combined-agenda-file))))
          
              ;; (message "Exporting %s files" org-agenda-files)
              (org-icalendar-combine-agenda-files (not sync))))
          
          
        3. Run once per hour

          To maintain consistency, run a timer to execute the function once per hour.

          (run-at-time t 3600 #'my-export-org-agenda-to-ics)
          
    3. Global Keys
      (global-set-key "\C-cl" 'org-store-link)
      (global-set-key "\C-cc" 'org-capture)
      (global-set-key "\C-ca" 'org-agenda)
      (global-set-key "\C-cb" 'org-iswitchb)
      
    4. Functions for convenience

      Some function created to easy editing.

      1. my-org-copy-begin-src   function interactive
        (defun my-org-copy-begin-src ()
          "Copy the last begin_src used."
          (interactive)
          (let ((tangle-text nil))
            (save-excursion
              (when (search-backward "#+begin_src" nil t)
                (setq tangle-text
                      (buffer-substring-no-properties (point-at-bol) (point-at-eol)))))
            (insert tangle-text)
            (insert "\n\n#+end_src\n")
            (previous-line 2)))
        
        1. Set key
          (define-key org-mode-map (kbd "C-c s") #'my-org-copy-begin-src)
          
    5. Personal Directories

      Syncthing runs under ~/Sync/orgs/ which has all agenda org.

      (if (file-exists-p "~/Sync/orgs")
          (progn
            (setq org-directory "~/Sync/orgs/")
            (setq org-agenda-files '("~/Sync/orgs/" "~/Sync/orgs/from-orgzly/a-agregar.org")))
        (message "Warning: Org agenda files could not be found at ~/Sync/orgs/"))
      
      1. Archive location
        (setq org-archive-location "~/docs/org/archive/%s::")
        
    6. Link support
      1. org-man - Manpage links   package

        Support for manpages links. org-man comes with org base package.

        (use-package org-man
          :ensure nil
          :after org)
        
      2. org-elisp-help - Elisp help links   package

        Links to emacs lisp documentation

        (use-package org-elisp-help
          :ensure t
          :after org)
        
      3. Tor-https

        See org-torlinks.org file.

        (load-library "org-torlinks")
        
      4. Gemini URLs

        See org-geminilinks.org file.

        (load-library "org-geminilinks")
        
    7. Org Brain
      1. ascii-art-to-unicode   package

        aa2u is ascii-art-to-unicode package, it is required by org-brain.

        (use-package ascii-art-to-unicode
          :defer t)
        
      2. NOT-SUPPORTED polymode   package

        Allows you to edit entries directly from org-brain-visualize

        (use-package polymode)
        
      3. my-org-brain-entry-path   function
          (defun my-org-brain-entry-path (entry)
          "Return the parent directory for Org-Brain titles.
        ENTRY should be the title string of the entry.
        
        Returns the parent directory as string, formatted for the Org-brain buffer."
          (org-with-point-at (org-brain-entry-marker entry)
            (concat (file-name-base
                     (string-trim (file-name-directory (buffer-file-name)) nil "/"))
                    ":")))
        
      4. org-brain   package
        (use-package org-brain
          :after (ascii-art-to-unicode polymode)
          :commands (org-brain-visualize)
          :config
          (setq org-brain-path "~/cloud/brain")
          (bind-key "C-c b" 'org-brain-prefix-map org-mode-map)
          (setq org-id-track-globally t)
          ;; (setq org-id-locations-file "~/.emacs.d/.org-id-locations")
          (add-hook 'before-save-hook #'org-brain-ensure-ids-in-buffer)
          (push '("b" "Brain" plain (function org-brain-goto-end)
                  "* %i%?" :empty-lines 1)
                org-capture-templates)
          (setq org-brain-visualize-default-choices 'all)
          (setq org-brain-title-max-length 12)
          (setq org-brain-include-file-entries t
                org-brain-file-entries-use-title t)
          ;; (add-hook 'org-brain-visualize-mode-hook #'org-brain-polymode)  ;; use with polymode package 
        
        1. Show the parent directory
          (add-hook 'org-brain-vis-title-prepend-functions #'my-org-brain-entry-path)
          
        2. End use-package
          )
          
      5. All-the-icons in org-brain

        Using all-the-icons in org-brain.

        1. org-brain-insert-resource-icon   function
          (unless (am-i-on-cellphone-p)
            (defun org-brain-insert-resource-icon (link)
              "Insert an icon, based on content of org-mode LINK."
              (insert (format "%s "
                            (cond ((string-prefix-p "http" link)
                                   (cond ((string-match "wikipedia\\.org" link)
                                          (all-the-icons-faicon "wikipedia-w"))
                                         ((string-match "github\\.com" link)
                                          (all-the-icons-octicon "mark-github"))
                                         ((string-match "vimeo\\.com" link)
                                          (all-the-icons-faicon "vimeo"))
                                         ((string-match "youtube\\.com" link)
                                          (all-the-icons-faicon "youtube"))
                                         (t
                                          (all-the-icons-faicon "globe"))))
                                  ((string-prefix-p "brain:" link)
                                   (all-the-icons-fileicon "brain"))
                                  (t
                                   (all-the-icons-icon-for-file link))))))
          
            (add-hook 'org-brain-after-resource-button-functions #'org-brain-insert-resource-icon))
          
      6. ASCII Art in org-brain

        Using ascii-art-to-unicode in org-brain.

        1. aa2u-buffer   function
          (defun aa2u-buffer ()
            (aa2u (point-min) (point-max)))
          
          (add-hook 'org-brain-after-visualize-hook #'aa2u-buffer)
          
    8. Beautifying Org-mode
      1. NOT-SUPPORTED Ellipsis (…) to other symbol

        ⚠️ I'm using emacs-spellbook now.

        Change the ellipsis used with a unicode character.

        (setq org-ellipsis "⤾")
        
      2. NOT-SUPPORTED Entities in Unicode Symbols

        ⚠️ I'm using emacs-spellbook now.

        Math symbols or latex macros that transforms to Unicode Symbols.

        (defun my-insert-html-codes (string)
          "Convert the STRING into HTML codes.
        Useful to convert emojis or any symbol character to HTML codes."
          (interactive "MString?")
          (insert 
           (mapconcat (lambda (char-num)
                        (format "&#%s" char-num))
                      (string-to-list string))))
        
        (setq org-entities-user        
              '(("sharp" "\\sharp" t "&#9839;" "♯" "" "♯")
                ("flat" "\\flat" t "&#9837;" "♭" "" "♭")
                ("triagright" "\\vartriangleright" nil "&#8883;" "⊳" "" "⊳")
                ("models" "\\models" t "&#8871;" "⊧" "" "⊧")
                ("vdash" "\\vdash" t "&#8870;" "⊦" "" "⊦")
                ("assertion" "\\vdash" t "&#8870;" "⊦" "" "⊦")
                ("assert" "\\vdash" t "&#8870;" "⊦" "" "⊦")
                ("nequiv" "\\not\\equiv" t "&#8802;" "≢" "" "≢")
                ("square" "\\square" nil "&#9723;" "◻" "" "◻")
                ("bot" "\\bot" t "&#8869;" "⊥" "" "⊥")
                ("top" "\\top" t "&#8868;" "⊤" "" "⊤")
                ;; ("diamond" "\\diamondsuit" nil "&#8900;" "" "" "♢")
                ;; Emojis
                ;; ("teacher" "\\emoji{teacher}" nil "&#129489;&#8205;&#127979;" "🧑‍🏫" "" "🧑‍🏫")
                ("pagefacingup" "\\emoji{page-facing-up}" nil "&#128196;" "📄" "" "📄")
                ("newspaper" "\\emoji{newspaper}" nil "&#128240;" "📰" "" "📰")
                ("barchart" "\\emoji{bar-chart}" nil "&#128202;" "📊" "" "📊")
                ("mate" "\\emoji{mate}" nil "&#129481;" "🧉" "" "🧉")
                ("grin" "\\emoji{grin}" nil "&#128513;" "😁" "" "😁")
                ("explodinghead" "\\emoji{exploding-head}" nil "&#129327;" "🤯" "" "🤯")
                ("tada" "\\emoji{tada}" nil "&#127881;" "🎉" "" "🎉")
                ("mouse" "\\emoji{computer-mouse}" nil "&#128433;&#65039;" "🖱️" "" "🖱")
                ("computer" "\\emoji{computer}" nil "&#128187;" "💻" "" "💻")
                ("telephone" "\\emoji{telephone}" nil "&#9742;&#65039;" "☎️" "" "☎")
                ("telephonereceiver" "\\emoji{telephonereceiver" nil "&#128222;" "📞" "" "📞")
                ("headphone" "\\emoji{headphone}" nil "&#127911;" "🎧" "" "🎧")
                ("glasses" "\\emoji{glasses}" nil "&#128083;" "👓" "" "👓")
                ("lightbulb" "\\emoji{light-bulb}" nil "&#128161;" "💡" "" "💡")
                ("bomb" "\\emoji{bomb}" nil "&#128163;" "💣" "" "💣")
                ("pausebutton" "\\emoji{pause-button}" nil "&#9208;&#65039;" "⏸️" "" "⏸") 
                ("musicalnotes" "\\emoji{musical-notes}" nil "&#127926;" "🎶" "" "🎶")
                ("musicalnote" "\\emoji{musical-note}" nil "&#127925;" "🎵" "" "🎵")
                ("new" "\\emoji{new}" nil "&#127381;" "🆕" "" "🆕")
                ("loudspeaker" "\\emoji{loudspeaker}" nil "" "📢" "" "📢")
                ("megaphone" "\\emoji{megaphone}" nil "" "📣" "" "📣")
                ("radio" "\\emoji{radio}" nil "&#128251;" "📻" "" "📻")
                ("microphone" "\\emoji{microphone}" nil "" "🎤" "" "🎤")
                ("studiomic" "\\emoji{studio-microphone}" nil "&#127897;" "🎙️" "" "🎙️")
                ("film" "\\emoji{film-frames}" nil "" "🎞️" "" "🎞️")
                ("moviecamera" "\\emoji{movie-camera}" nil "&#127909;" "🎥" "" "🎥")
                ("abacus" "\\emoji{abacus}" nil "&#129518;" "🧮" "" "🧮")
                ("raisinghands" "\\emoji{raising-hands}" nil "&#128588;" "🙌" "" "🙌")
                ("partyingface" "\\emoji{partying-face}" nil "&#129395;" "🥳" "" "🥳")
                ("confettiball" "\\emoji{confetti-ball}" nil "&#127882;" "🎊" "" "🎊")
                ("partypopper" "\\emoji{party-popper}" nil "&#127881;" "🎉" "" "🎉")
                ("warning"     "\\emoji{warning}"      nil "&#9888;&#65039;"   "⚠️" ""  "⚠")
        
                ("speechballoon" "\\emoji{right-anger-bubble}" nil "&#128172;" "💬" "" "💬")
                ("eyeinbubble" "\\emoji{eye-in-speech-buble}" nil
                 "&#128065;&#65039;&#8205;&#128488&#65039;" "👁️‍🗨️" "" "👁")
                ("speechbubble" "\\emoji{left-speech-bubble}" nil "&#128488;&#65039;" "🗨️" "" "🗨")
                ("angerbubble" "\\emoji{right-anger-bubble}" nil "&#128495;&#65039;" "🗯️" "" "🗯")
                ("thought" "\\emoji{thought-balloon}" nil "&#128173;" "💭" "" "💭")
                ("zzz" "\\emoji{zzz}" nil "&#128164;" "💤" "" "💤")
        
                ("books" "\\emoji{books}" nil "&#128218;" "📚" "" "📚")
                ("sigh" "\\emoji{face-exhaling}" nil "&#128168;" "💨" "" "💨")
                ("prohibited" "\\emoji{prohibited}" nil "&#128683;" "🚫" "" "🚫")
                ("angersymbol" "\\emoji{anger-symbol}" nil "&#128162;" "💢" "" "💢")
                ("pointright" "\\emoji{point-right}" nil "&#128073;" "👉" "" "👉")
                ("pointleft" "\\emoji{point-left}" nil "&#128072;" "👈" "" "👈")
                ("pointup" "\\emoji{point-up}" nil "&#9757;" "☝️" "" "☝️")
                ("backpointup" "\\emoji{point-up-2}" nil "&#128070;" "👆" "" "👆")
                ("backpointdown" "\\emoji{point-down}" nil "&#128071;" "👇" "" "👇")
                ("thumbsup" "\\emoji{thumbs-up}" nil "&#128077;" "👍" "" "👍")
                ("thumbsdown" "\\emoji{thumbs-down}" nil "&#128078;" "👎" "" "👎")
                ("technologist" "\\emoji{technologist}" nil "" "🧑" "" "🧑")
                ("openhands" "\\emoji{open-hands}" nil "" "👐" "" "👐")
                ("winkingface" "\\emoji{winking-face}" nil "&#128521;" "😉" "" "😉")
                ("nerdface" "\\emoji{nerd-face}" nil "" "🤓" "" "🤓")
                ("earthglobe" "\\emoji{globe-showing-americas}" nil "" "🌎" "" "🌎")
                ("globe" "\\emoji{globe-with-meridians}" nil "&#127760;" "🌐" "" "🌐")
                ("microscope" "\\emoji{microscope}" nil "" "🔬" "" "🔬")
                ("gear" "\\emoji{gear}" nil "" "⚙️" "" "⚙")
                ("busts" "\\emoji{busts-in-silhouette}" nil "" "👥" "" "👥")
                ("graduationcap" "\\emoji{graduation-cap}" nil "" "🎓" "" "🎓")
                ("laughing" "\\emoji{laughing}" nil "&#128518;" "😆" "" "😆")
                ("grinning" "\\emoji{grinning-face}" nil "" "😀" "" "😀")
                ("angry" "\\emoji{angry-face}" nil "" "😠" "" "😠")
                ("nogood" "\\emoji{person-gesturing-no}" nil "&#128581;" "🙅" "" "🙅")
                ("facepalm" "\\emoji{facepalm}" nil "" "🤦" "" "🤦")
                ("play" "\\emoji{play-button}" nil "&#9654;&#65039;" "▶️" "" "▶")
                ("glassright" "\\emoji{magnifying-glass-tilted-right}" nil "" "🔎" "" "🔎")
                ("recycle" "\\emoji{recycle}" nil "" "♻️" "" "♻")
                ("thinkingface" "\\emoji{thinking-face}" nil "&#129300;" "🤔" "" "🤔")
                ("writinghand" "\\emoji{writing-hand}" nil "" "✍️" "" "✍")
                ("soon" "\\emoji{soon-arrow}" nil "" "🔜" "" "🔜")
                ("shrug" "\\emoji{person-shrugging}" nil "" "🤷" "" "🤷")
                ("cammerawithflash" "\\emoji{camera-with-flash}" nil "" "📸" "" "📸")
                ("framedpicture" "\\emoji{framed-picture}" nil "&#128444;&#65039;" "🖼️" "" "🖼")
                ("art" "\\emoji{artist-palette}" nil "" "🎨" "" "🎨")
                ("video" "\\emoji{video-camera}" nil "" "📹" "" "📹")
                ("saxo" "\\emoji{saxophone}" nil "" "🎷" "" "🎷")
                ("moneyface" "\\emoji{money-mouth-face}" nil "" "🤑" "" "🤑")
                ("detective" "\\emoji{detective}" nil "" "🕵️‍" "" "🕵")
                ("coin" "\\emoji{coin}" nil "&#129689;" "🪙" "" "🪙")
                ("moneybag" "\\emoji{moneybag}" nil "&#128176;" "💰" "" "💰")
                ("moneywithwings" "\\emoji{money-with-wings}" nil "" "💸" "" "💸")
                ("bank" "\\emoji{bank}" nil "&#127974;" "🏦" ""  "🏦")
                ("handshake" "\\emoji{handshake}" nil "&#129309;" "🤝" "" "🤝")
                ("mechanicalarm" "\\emoji{mechanical-arm}" nil "" "🦾" "" "🦾")
                ("link" "\\emoji{link}" nil "" "🔗" "" "🔗")))
        
      3. NOT-SUPPORTED org-bullets - Bullets on titles   package

        ⚠️ I'm using emacs-spellbook now.

        Use bullets on headers.

        (use-package org-bullets
          :ensure t
          :config
          (add-hook 'org-mode-hook #'org-bullets-mode))
        
      4. Accept enumerations with letters

        Enumerations in Org are only with numbers. But with this variable, letters can be used up to one character only. See org#Plain Lists for more information.

        (setq org-list-allow-alphabetical t)  
        
    9. Babel

      Enable org-babel languages.

      1. ob-prolog   package
        (use-package ob-prolog
          :ensure t)
        
      2. Enable languages

        Org-babel (ob) execute code inside a source block ("#+beginsrc .. #+endsrc").

        Not all languages are enabled to execute freely. For instance, a Python code inside a source block would not be executed unless the user is asked first.

        In this example, any ditaa source block can be executed without prompting the user for any confirmation.

        (defun my-org-confirm-babel-evaluate (lang body)
           (not (string= lang "ditaa")))  ; don't ask for ditaa
        

        The following code defines a variable with a list of languages, a function to test if a specific language requires confirmation, and then it sets the proper variable to tell org-mode to use this function to test for confirmations.

        (defvar my-org-no-confirm-evaluation '("latex" "ditaa" "dot" "emacs-lisp" "elisp" "lilypond")
          "Languages that Org Babel can execute without user confirmation.")
        
        (defun my-org-confirm-babel-evaluate (lang _body)
          "Function to test if LANG should be confirmed for evaluation or not.
        Return t if it should be confirmed, nil otherwise.
        
        Intended for `org-confirm-babel-evaluate'." 
          (not (member lang my-org-no-confirm-evaluation)))
        
        (setq org-confirm-babel-evaluate 'my-org-confirm-babel-evaluate)
        

        These languages will be available directly from start. Org Babel will load any ob-* libraries required to enable these languages. If the user want to use any other language not listed here, it should load the library accordingly. For instance, to enable the Ruby language, the user should call M-x load-library ob-ruby or run (load-library "ob-ruby").

        (org-babel-do-load-languages 'org-babel-load-languages
                                     '((emacs-lisp . t)
                                       (dot . t)
                                       (latex . t)))
        
    10. NOT-SUPPORTED tangle-sync   package

      Is a module to sync tangled files with the org src blocks that create them.

      (use-package org-tanglesync
        :hook org-mode
        :bind (("C-c t" . org-tanglesync-minor-mode)))
      
    11. Other Configuration
      (setq org-hide-emphasis-markers nil
            org-preview-latex-default-process 'imagemagick)
      
    12. Open link configuration
      1. my-add-org-file-apps   function
        (defun my-add-org-file-apps (file-identifier command)
          "Function to ensure a unique association of file and commands.
        The `org-file-apps' variable use cons of FILE-IDENTIFIER and COMMANDS.
        But when adding, they can be duplicated.  This ensure to delete any
        possible association and to add the corret identifier and command.
        
        According to the variable documentation:
        - FILE-IDENTIFIER can be a symbol or string.
        - COMMANDS is a symbol."
          (delq (assoc file-identifier org-file-apps) org-file-apps)
          (push (cons file-identifier command) org-file-apps))
        
      2. Support for Mindmap and HTML files
        (my-add-org-file-apps "\\.mm\\'" 'default)
        (my-add-org-file-apps "\\.x?html?\\'" 'default)
        
      3. Open videos with mpv
        (my-add-org-file-apps "\\.mp4\\'" "mpv %s")
        (my-add-org-file-apps "\\.ogv\\'" "mpv %s")
        (my-add-org-file-apps "\\.ogg\\'" "mpv %s")
        
      4. Open in dired, not in Explorer   custom windows

        Configure file: links for dired and file+sys: links for Explorer.

        (when (eq system-type 'windows-nt)
          (my-add-org-file-apps 'directory 'emacs)
          (my-add-org-file-apps "file+sys" 'system))
        
    13. Inline images in white background

      Inline images have black background, which is terrible for dark themes and inverted colours. This changes the image background to a specific colour, in this case, white by default.

      ;; Background color in inlines images
      (defcustom org-inline-image-background "white"
        "The color used as the default background for inline images.
        When nil, use the default face background."
        :group 'org
        :type '(choice color (const nil)))
      
      (defun org-display-inline-images--with-color-theme-background-color (args)
        "Specify background color of Org-mode inline image through modify `ARGS'."
        (let* ((file (car args))
               (type (cadr args))
               (data-p (caddr args))
               (props (cdddr args)))
          ;; get this return result style from `create-image'
          (append (list file type data-p)
                  (list :background org-inline-image-background)
                  props)))
      
      (advice-add 'create-image :filter-args
                  #'org-display-inline-images--with-color-theme-background-color)
      
    14. Org-ref references and citation   package
      (use-package org-ref
        :if (not (am-i-on-cellphone-p))
        :commands (org-ref-insert-link
                   org-ref-insert-cite-link
                   org-ref-insert-label-link
                   org-ref-insert-ref-link
                   org-ref-citation-hydra/body
                   org-ref-help)    
        :init
        (setq org-ref-completion-library 'org-ref-ivy-cite) )
      
    15. Org mind map   package

      Creates a directed graph from org-mode files.

      (use-package org-mind-map
        :commands (org-mind-map-write 
                   org-mind-map-current-branch
                   org-mind-map-current-tree))
      
    16. Org Navigation   package

      orgnav is a navigation tool that uses helm.

      (use-package orgnav
        :defer t
        :commands (orgnav-search-ancestors
                   orgnav-search-subtree
                   orgnav-search-root
                   orgnav-search-nearby))
      
    17. Latex Compilation

      Add bibtex or biber to the compilation process. latexmk detects which of the two to execute automatically.

      (setq org-latex-pdf-process
            '("latexmk -g -pdf -pdflatex=\"%latex\" -shell-escape -outdir=%o %f"))
      

      Add babel or polyglossa depending on the compiler.

      (setq org-latex-packages-alist
            '(("AUTO" "polyglossia" nil ("xelatex" "lualatex"))
              ("AUTO" "babel" t ("pdflatex"))))
      
      1. Show compilation buffer in other window
        (unless (assoc "*tex-shell*" display-buffer-alist)
          (push (cons "*tex-shell*" '(display-buffer-in-direction . ((window . main)
                                                                     (direction . right))))
                display-buffer-alist))
        
    18. Capture templates

      See org-capture-templates and info:org#Capture templates for more info on how to create the template.

      (setq org-capture-templates '())
      
      1. my-add-capture-template   function
        (defun my-add-capture-template (key name &optional org-headline)
          "Add a predefined capture template."
          (let ((headline (if org-headline
                              org-headline
                            (concat name " Captures"))))
            (push `(,key ,name entry
                         (file+headline "~/Sync/orgs/todoes.org" ,headline)
                         "** %^{title} :capture:%^g:
        :CAPTUREINFO:
        - Date :: %U
        - Buffer :: %f
        - Annotation :: %a
        :END:
        %i
        %?")
                  org-capture-templates)))
        
      2. Research
        (my-add-capture-template "r" "Research")
        
      3. Teaching
        (my-add-capture-template "t" "Teaching")
        
      4. MCS Thesis
        (my-add-capture-template "m" "MCS")
        
      5. Emacs
        (my-add-capture-template "e" "Emacs")
        
      6. Home
        (my-add-capture-template "d" "Domestic")
        
      7. General
        (my-add-capture-template "g" "General")
        
      8. Extension
        (my-add-capture-template "E" "Extension")
        
    19. Presentation

      Packages and configuration needed to use org-mode to present.

      1. presentation   package

        Perfect font size for presentations.

        (use-package presentation
          :commands (presentation-mode)
          :ensure nil)
        
      2. moom   package

        Zooming and some other window features.

        (use-package moom
          :if (not (am-i-on-cellphone-p))
          :defer t)
        
      3. centered-window   package

        This package makes the windows to display at the center.

        (use-package centered-window
          :ensure t)
        
      4. org-tree-slide   package

        Animations and org-mode tree used as slides.

        (use-package org-tree-slide)
        
      5. org-tree-slide-pauses   package

        Pauses animation like beamer.

        (use-package org-tree-slide-pauses
          :after org-tree-slide)
        
      6. interaction-log   package

        To show what keys and commands I am pressing. The C-h l (M-x view-lossage) is good, but this is better!

        (use-package interaction-log
          :ensure t)
        
    20. Clocks

      Clock persists between Emacs sessions.

      (setq org-clock-persist 'history)
      (org-clock-persistence-insinuate)
      
    21. Literate programming
      1. my-org-lp-goto-error   function

        Function to move from any Elisp byte-compile Warnings to the original org file.

        Found in @contrapunctus init: https://codeberg.org/contrapunctus/dotemacs/src/branch/production/init.org#my-org-lp-goto-error

        (defun my-org-lp-goto-error (oldfn &optional prefix &rest args)
          "Make `compile-goto-error' lead to an Org literate program, if present.
        This is meant to be used as `:around' advice for `compile-goto-error'.
        OLDFN is `compile-goto-error'.
        With PREFIX arg, just run `compile-goto-error' as though unadvised.
        ARGS are ignored."
          (interactive "P")
          (if prefix
              (funcall oldfn)
            (let (buffer position column tangled-file-exists-p)
              (save-window-excursion
                (funcall oldfn)
                (setq column (- (point) (point-at-bol)))
                ;; `compile-goto-error' might be called from the output of
                ;; `literate-elisp-byte-compile-file', which means
                ;; `org-babel-tangle-jump-to-org' would error
                (when (ignore-errors (org-babel-tangle-jump-to-org))
                  (setq buffer         (current-buffer)
                        position       (point)
                        tangled-file-exists-p t)))
              ;; back to where we started - the `compilation-mode' buffer
              (if tangled-file-exists-p
                  (let ((org-window (get-buffer-window buffer)))
                    ;; if the Org buffer is visible, switch to its window
                    (if (window-live-p org-window)
                        (select-window org-window)
                      (switch-to-buffer buffer))
                    (goto-char (+ position column)))
                (funcall oldfn)))))
        
        (advice-add 'compile-goto-error :around #'my-org-lp-goto-error)
        ;; (advice-remove 'compile-goto-error #'my-org-lp-goto-error)
        
    22. Update syntax

      Some configurations require to execute this code. For instance org-list-allow-alphabetical.

      ⚠️ This must be at the end of all org-mode configurations.

      (org-element-update-syntax)
      
  2. graphviz-dot-mode   package mode
    (use-package graphviz-dot-mode
      :if (not (am-i-on-cellphone-p))
      :mode "\\.gv\\'" "\\.dot\\'")
    
  3. sparql-mode   package mode
    (use-package sparql-mode
      :if (not (am-i-on-cellphone-p))
      :mode "\\.sparql\\'"
      :config
    
    1. org-babel

      Enable babel for org mode evaluation.

      (org-babel-do-load-languages
       'org-babel-load-languages
       '((sparql . t)))
      
    2. End use-package
      ) ;; use-package
      
  4. gnuplot   package mode
    (use-package gnuplot-mode
      :if (not (am-i-on-cellphone-p))
      :mode "\\.gnuplot\\'" "\\.gp\\'")
    
  5. NOT-SUPPORTED Tex / LaTeX
    1. NOT-SUPPORTED auctex   package
      (use-package auctex
        :mode ".tex"
        :if (not (am-i-on-cellphone-p)))
      
    2. Folding

      There is a TeX-fold-mode ( C-c C-o C-f ) which fold/hides certain TeX element to read the tex file easily. It would be great to fold certain environments too.

      The following add more environments to the TeX-fold-mode.

      (setq TeX-fold-env-spec-list '(("[comment]" ("comment"))
                                     ("[figure]" ("figure"))
                                     ("[verbatim]" ("verbatim"))
                                     ("[table]" ("table"))
                                     ("[tabular]" ("tabular"))
                                     ("[tikz]" ("tikzpicture"))))
      
      (defadvice TeX-fold-buffer (after fold-all-comments activate)
        "Fold all comments."
        ;; (goto-point (point-min))
        ;; (while (search-forward-regexp "%\(.*\)$" nil t)
        ;; (goto-char (match-beginning 1))    
        (TeX-fold-region-comment (point-min) (point-max))
        ;; )
        )
      
      ;; (add-hook 'LaTeX-mode-hook 'TeX-fold-mode t)
      ;; (add-hook 'LaTeX-mode-hook 'TeX-fold-buffer t)
      
    3. View Results Programs

      The programs available for viewing the LaTeX output.

      The following snippet sets xdg-open as the default application to open a PDF file. Therefore, the system default application would be used.

      (setq TeX-view-program-selection (quote
                                        (((output-dvi has-no-display-manager)
                                          "dvi2tty")
                                         ((output-dvi style-pstricks)
                                          "dvips and gv")
                                         (output-dvi "xdvi")
                                         (output-pdf "xdg-open")
                                         (output-html "xdg-open"))))
      
  6. iRFC   package

    Reader for RFC standards.

    The use package does not work, it is not listed in the repositories.

    (use-package irfc
      :if (not (am-i-on-cellphone-p))
      :commands (irfc-reference-goto irfc-visit)
      :config
      (setq irfc-directory "~/.emacs.d/irfc")
      (when (not (file-exists-p irfc-directory))
        (make-directory irfc-directory))
      (setq irfc-assoc-mode t))  
    

    Load irfc from ./dists/scripts/irfc.el.

    (unless (am-i-on-cellphone-p)
      (require 'irfc)
      (setq irfc-directory "~/.emacs.d/irfc")
      (when (not (file-exists-p irfc-directory))
        (make-directory irfc-directory))
      (setq irfc-assoc-mode t))
    
  7. Yaoddmuse   package

    Yaoddmuse has no package in MELPA or ELPA.

    (use-package yaoddmuse
      :if (not (am-i-on-cellphone-p))
      :commands (yaoddmuse-browse-page
                 yaoddmuse-edit
                 yaoddmuse-edit-default)
      :config
      (setq yaoddmuse-username (my-secrets-get "yaoddmuse-username")))
    
    (unless (am-i-on-cellphone-p)
      (require 'yaoddmuse)
      (setq yaoddmuse-username (my-secrets-get "yaoddmuse-username")))
    
  8. Yasnippet   package
    (use-package yasnippet
      :if (not (am-i-on-cellphone-p))
      :config
      (add-to-list 'yas-snippet-dirs "~/emacs-stuff/snippets")
      (yas-reload-all)
      (yas-global-mode))
    
  9. Viewing and Annotates PDF
    1. pdf-tools   package

      The pdf-tools package supports viewing PDF files whose epdfinfo program is used as backend. Thus, the epdfinfo must be compiled before.

      Compiling the backend con be achieved by the following commands:

      ./autogen.sh
      ./configure
      make
      cp epdfinfo ../../
      
      (use-package pdf-tools
        :if (not (am-i-on-cellphone-p))
        :mode "\\.pdf\\'"
        :config 
        (pdf-loader-install t t))
      
    2. org-noter   package

      For annotations, org-noter can store notes in an org file next to the PDF as the default path.

      (use-package org-noter
        :if (not (am-i-on-cellphone-p))
        :mode "\\.pdf\\'"
        :after (pdf-tools))
      
  10. Markdown   mode package
    (use-package markdown-mode
      :mode "\\.md\\'" "\\.markdown\\'"
      :if (not (am-i-on-cellphone-p)))
    
  11. Emojify   package
    (use-package emojify
      :if (not (am-i-on-cellphone-p))
      :commands (emojify-insert-emoji emojify-apropos-emoji))
    
  12. emoji cheat sheet plus   package
    (use-package emoji-cheat-sheet-plus
      :if (not (am-i-on-cellphone-p))
      :commands (emoji-cheat-sheet-plus-insert emoji-cheat-sheet-plus-buffer))
    
  13. helm-bibtex   package

    Required by org-ref.

    (use-package helm-bibtex
      :if (not (am-i-on-cellphone-p))
      :commands (helm-bibtex)
      :after org-ref)
    
  14. Bibtex Ebib   package

    BibTeX manager.

    (use-package ebib
      :if (not (am-i-on-cellphone-p))
      :commands (ebib)
      :defer t
      :config
      (setq ebib-bib-search-dirs '("~/cloud/resources/bibtexs")
            ebib-file-associations '(("pdf")
                                     ("ps" . "gv"))
            ebib-file-search-dirs '("~/cloud/resources/")))
    

11. Music

  1. Lilypond
    1. Adding new compiling options
      (with-eval-after-load "lilypond-init"
        (add-to-list 'LilyPond-command-alist
                     '("PNG Cropped" "lilypond -dcrop %s")))
      

12. Programming modes

;; (message"==> Programming modes")
  1. Prolog
    1. NOT-SUPPORTED Support for switching between implementation

      Support for CIAO, GNU Prolog and SWI. Functions to change between these.

      I'll disable because I don't use all of them anymore, just SWI and CIAO.

      ;; (setq load-path (cons "/usr/lib/xemacs/site-lisp" load-path))
      (autoload 'run-prolog "prolog" "Start a Prolog sub-process." t)
      (autoload 'prolog-mode "prolog" "Major mode for editing Prolog programs." t)
      (autoload 'mercury-mode "prolog" "Major mode for editing Mercury programs." t)
      
      (defun toggle-ciao-gnu ()
        "Toggle between Ciao Prolog and GNU Prolog."
        (interactive)
        (if (equal prolog-system 'gnu)
            (use-ciao-prolog)
          (use-gnu-prolog)))
      
      (defun remove-all-ciao ()
        "Remove all ciao-mode from `auto-mode-alist'."
        (while (equal (cdr (assoc "\\.pl$" auto-mode-alist)) 'ciao-mode)
          (setq auto-mode-alist (remove '("\\.pl$" . ciao-mode) auto-mode-alist))))
      
      (defun remove-all-gnu-prolog ()
        "Remove all ciao-mode from `auto-mode-alist'."
        (while (equal (cdr (assoc "\\.pl$" auto-mode-alist)) 'prolog-mode)
          (setq auto-mode-alist (remove '("\\.pl$" . prolog-mode) auto-mode-alist))))
      
      (defun use-ciao-prolog ()
        (remove-all-gnu-prolog)
        (setq auto-mode-alist (append '(("\\.pl$" . ciao-mode))
                                      auto-mode-alist))
        (setq prolog-system 'ciao))
      
      (defun use-gnu-prolog ()
        (remove-all-ciao)
        (setq auto-mode-alist (append '(("\\.pl$" . prolog-mode))
                                      auto-mode-alist))  
        (setq prolog-system 'gnu))
      
      (setq
       auto-mode-alist (append '(("\\.pl$" . prolog-mode)
                                 ("\\.m$" . mercury-mode))
                               auto-mode-alist)
       prolog-system 'swi)
      
    2. prolog-mode   package
      1. Set SWI

        Set the SWI prolog and the pl file.

        (use-package prolog-mode
          :ensure nil
          :mode "\\.pl\\'"
          :config
          (setq auto-mode-alist (append '(("\\.pl$" . prolog-mode))
                                        auto-mode-alist)
                prolog-system 'swi))
        
    3. ediprolog   package

      Emacs does interactive Prolog.

      (use-package ediprolog
        :mode "\\.pl\\'"
        :after (prolog-mode))
      
    4. Support for Ciao

      A function to load the Ciao environment.

      1. my-ciao-load-site   function interactive

        Load the Ciao site.

        (defun my-ciao-load-site ()
          "Load the Ciao Prolog environment"
          (interactive)
          (if (file-exists-p
               "~/.ciaoroot/master/ciao_emacs/elisp/ciao-site-file.el")
              (load-file
               "~/.ciaoroot/master/ciao_emacs/elisp/ciao-site-file.el"))
          (when (not (member "~/.ciaoroot/master/build/doc" Info-directory-list))
            (add-to-list 'Info-directory-list "~/.ciaoroot/master/build/doc")))
        
  2. Python and Elpy

    Enable Elpy.

    1. python - Begin use-package   package
      (use-package python
        :ensure t
        :defer t
        :commands (python-mode)
        :mode ("\\.py\\'" . python-mode)
        :config
      
      1. Config

        Use flake8 and python3.

        (setq python-check-command "flake8"
              python-shell-interpreter "python3"
              elpy-rpc-python-command "python3")
        
        (elpy-enable)
        

        Add Elpy mode to the python mode.

        ;; (elpy-mode)
        (unless (member 'elpy-mode python-mode-hook)
          (add-hook 'python-mode-hook 'elpy-mode))
        
      2. End use-package
        ) ;; use-package
        
    2. Pydoc   package
      (use-package pydoc
        :if (not (am-i-on-cellphone-p))
        :commands (pydoc pydoc-browse)
        :after elpy)
      
    3. NOT-SUPPORTED Pydoc info   package
      (use-package pydoc-info
        :if (not (am-i-on-cellphone-p))
        :after elpy)
      
  3. Ada
    1. NOT-SUPPORTED ada-mode   package

      āš  After many times I tried different versions of ada-mode, I wanted a simpler mode with simpler things.

      I use a special version for ada-mode: 5.3.2.

      After that version, the dependency WISI (a parser) were rewrote in Ada and it does not compile well. Missing dependencies?

      ;; (push "~/repos/emacs/ada-mode-5.3.2" load-path)
      ;; (push "~/repos/emacs/wisi-1.1.6" load-path)
      
      (use-package ada-mode
        :ensure nil
        :mode "\\.ads\\'" "\\.adb\\'" "\\.gpr\\'"
      
      1. Configuration
        :config
        
        1. gnat-mode

          Load the gnat mode with all my personal functions.

          (require 'gnat)
          
        2. No tabs on indentations

          When indenting is not good to use tabs. If the developer checks for coding style (with gnat -gnatyS).

          The ada-tab function uses the indent-to basic function, which in turn use the indent-tabs-mode variable to direct which character use. See the Primitive Indent section of the Elisp info page.

          Remember, indent-tabs-mode is a buffer-local variable.

          (setq indent-tabs-mode nil)
          
        3. Indentation when using "when" keyword

          Ada complains when "when" is indented.

          (setq ada-indent-when 0)
          
      2. End ada-mode use-package
        ) ;; use-package
        
    2. Ada Ref Man   package

      Emacs info version of the Ada Reference Manual 2012.

      (use-package ada-ref-man
        :if (not (am-i-on-cellphone-p))
        :defer t
        :after (ada-mode))
      
  4. Emacs Lisp / ELisp

    Emacs has everything I need to edit ELisp!!!

    Maybe some Hydras? See Section Hydras. Also eldoc is enabled before, see Section eldoc-mode. For autocompletion, there is the Company completion framework.

    1. Creating MELPA package

      Packages required to create and test before submitting to MELPA or other repository.

      1. Do ispell checks on doc strings. See Section Ispell.
      2. Checkdoc must pass.
      1. package-lint-flymake   package
        (use-package package-lint-flymake
          :defer t
          :if (not (am-i-on-cellphone-p)))
        
  5. Ruby

    Ruby mode comes by default with Emacs. The following packages is needed for documentation (yari) and for running the interpreter (inf-ruby).

    1. yari   package

      View ri documentation in emacs.

      (use-package yari
        :commands (yari yari-helm)
        :config
        ;; (setq yari-ri-program-name "ri --doc-dir=/usr/share/ri/system")
        :if (not (am-i-on-cellphone-p)))
      
    2. inf-ruby   package

      Execute an IRB REPL process inside emacs.

      Also, fix the prompt for the IRB interpreter.

      (use-package inf-ruby
        :if (not (am-i-on-cellphone-p))
        :commands (inf-ruby)
        :config
        (setq inf-ruby-prompt-format "irb([^)]+):[0-9:]*> "))
      
    3. ruby-block   package

      The ruby-block has no package in MELPA or ELPA.

      (use-package ruby-block
        :if (not (am-i-on-cellphone-p))
        :commands (ruby-block-mode))
      
      (unless (am-i-on-cellphone-p)
        (require 'ruby-block))
      
    4. ruby-tools   package
      (use-package ruby-tools
        :if (not (am-i-on-cellphone-p))
        :commands (ruby-tools-mode))
      
    5. rvm   package

      RVM is a Ruby version and gems management.

      (use-package rvm
        :if (not (am-i-on-cellphone-p))
        :commands (rvm-use
                   rvm-use-default
                   rvm-open-gem
                   rvm-activate-corresponding-ruby))
      
    6. yard   package

      Another documentation tool aside from RDoc.

      (use-package yard-mode
        :if (not (am-i-on-cellphone-p))
        :defer t
        :config
        (add-hook 'ruby-mode-hook 'yard-mode)
        (add-hook 'ruby-mode-hook 'eldoc-mode))
      
  6. Crystal
    1. crystal-mode   package
      (use-package crystal-mode
        :if (not (am-i-on-cellphone-p))
        :defer t)
      
    2. ameba   package

      Ameba is a program to check the syntax of Crystal programs. It should be installed and available at the PATH.

      (use-package ameba
        :if (not (am-i-on-cellphone-p))
        :defer t)
      
    3. flycheck-crystal   package
      (use-package flycheck-crystal
        :if (not (am-i-on-cellphone-p))
        :defer t)
      
    4. flycheck-ameba   package
      (use-package flycheck-ameba
        :if (not (am-i-on-cellphone-p))
        :defer t)
      
  7. Haml   mode package

    Hook for make sure turn off tabs and auto-indent-mode can be enable.

    (use-package haml-mode
      :mode "\\.haml\\'"
      :config
      (add-hook 'haml-mode-hook
                (lambda ()
                  (setq indent-tabs-mode nil)
                  (define-key haml-mode-map "\C-m" 'newline-and-indent))))
    
  8. Web mode   package mode
    1. Begin use-package
      (use-package web-mode
        :if (not (am-i-on-cellphone-p))
        :mode (;;  "\\.php\\'"
               "\\.hbs\\'"
               "\\.[sx]?html?\\(\\.[a-zA-Z_]+\\)?\\'")
        :config
      
    2. Load the web-mode

      Load the a mode when reading a PHP script. Web-mode if HTML.

      ;;  (push '("\\.php$" . web-mode) auto-mode-alist)
      (push '("\\.hbs$" . web-mode) auto-mode-alist)
      
      (let ((elt (assoc "\\.[sx]?html?\\(\\.[a-zA-Z_]+\\)?\\'" auto-mode-alist)))
        (setq auto-mode-alist (remove elt auto-mode-alist)))
      
      (push '("\\.[sx]?html?\\(\\.[a-zA-Z_]+\\)?\\'" . web-mode) auto-mode-alist)
      
    3. Configure and personalizations

      Set indent to 2.

      (setq web-mode-markup-indent-offset 2
            web-mode-attr-value-indent-offset 2
            web-mode-code-indent-offset 4)
      
    4. End use-package
      ) ;; use-package
      
    5. NOT-SUPPORTED Web-mode edit element
      (require 'web-mode-edit-element)
      (add-hook 'web-mode-hook 'web-mode-edit-element-minor-mode)
      
      1. Keymap
        * Web mode edit element
        
        |---------------+-------------------------------------------------------|
        | Shortcut      | Command                                               |
        |---------------+-------------------------------------------------------|
        | *General*       |                                                       |
        |---------------+-------------------------------------------------------|
        | ~C-(~           | web-mode-element-wrap                                 |
        | ~M-(~           | web-mode-element-rename                               |
        |---------------+-------------------------------------------------------|
        | *Elements*      |                                                       |
        |---------------+-------------------------------------------------------|
        | ~C-<left>~      | web-mode-element-previous                             |
        | ~C-<right>~     | web-mode-element-next                                 |
        | ~M-<left>~      | web-mode-edit-element-elements-contract-over-border   |
        | ~M-<right>~     | web-mode-edit-element-elements-expand-over-border     |
        | ~C-M-<left>~    | web-mode-edit-element-elements-transpose-backward     |
        | ~C-M-<right>~   | web-mode-element-transpose                            |
        | ~C-<up>~        | web-mode-element-beginning                            |
        | ~C-<down>~      | web-mode-tag-match                                    |
        | ~C-S-<up>~      | web-mode-element-parent                               |
        | ~C-S-<down>~    | web-mode-element-next                                 |
        | ~M-<up>~        | web-mode-edit-element-elements-dissolve               |
        | ~M-<down>~      | web-mode-edit-element-elements-raise                  |
        | ~C-M-<up>~      | web-mode-element-content-select                       |
        | ~C-M-<down>~    | web-mode-element-vanish                               |
        | ~C-k~           | web-mode-element-kill                                 |
        | ~C-K~           | web-mode-edit-element-elements-kill-siblings          |
        | ~M-k~           | web-mode-edit-element-elements-kill-siblings-previous |
        | ~M-K~           | web-mode-edit-element-elements-kill-siblings-next     |
        |---------------+-------------------------------------------------------|
        | **Attributes**  |                                                       |
        |---------------+-------------------------------------------------------|
        | ~C-S-<left>~    | web-mode-attribute-previous                           |
        | ~C-S-<right>~   | web-mode-attribute-next                               |
        | ~C-M-S-<left>~  | web-mode-edit-element-attributes-transpose-backward   |
        | ~C-M-S-<right>~ | web-mode-attribute-transpose                          |
        | ~C-M-S-<up>~    | web-mode-attribute-beginning                          |
        | ~C-M-S-<down>~  | web-mode-edit-element-attributes-end-inside           |
        | ~C-M-K~         | web-mode-attribute-kill                               |
        |---------------+-------------------------------------------------------|
        
        
    6. Web-narrow-mode   package
      (use-package web-narrow-mode
        :if (not (am-i-on-cellphone-p))
        :commands (web-narrow-to-block web-narrow-to-region web-narrow-to-element)
        ;; :bind
        ;; ("C-c C-u j" . web-narrow-to-block)
        ;; ("C-c C-u l" . web-narrow-to-region)
        ;; ("C-c C-u u" . web-narrow-to-element)
        :after (:all web-mode)
        :config
        (add-hook 'web-mode-hook 'web-narrow-mode))
      
      1. Keymap   cheatsheet
        * Web Narrow Mode
        
        - ~C-c C-u u~ web-narrow-to-element : narrow a html element to buffer
        - ~C-c C-u j~ web-narrow-to-block : narrow content with in ~{...}~
        - ~C-c C-u l~ web-narrow-to-region : narrow region
        
        In narrowed-mode:
        
        ~C-c C-k~ quit current edit(narrowed), same as ~kill-buffer~
        
  9. PHP
    1. php-mode   package
      (use-package php-mode
        :if (not (am-i-on-cellphone-p))
        :defer t
        :commands (php-mode))
      
    2. php-eldoc   package
      (use-package php-eldoc
        :if (not (am-i-on-cellphone-p))
        :commands (php-eldoc-enable))
      
  10. SCSS
    1. scss-mode   package mode
      (use-package scss-mode
        :if (not (am-i-on-cellphone-p))
        :mode "\\.scss\\'") ;; use-package
      
  11. CUDA
    1. c-mode   package
      (use-package c-mode
        :if (not (am-i-on-cellphone-p))
        :ensure nil
        :mode "\\.cu\\'"
        :config
        (setq auto-mode-alist (append '(("\\.cu$" . c-mode))
                                      auto-mode-alist)))
      
  12. Vala
    1. vala-mode   package mode
      (use-package vala-mode
        :if (not (am-i-on-cellphone-p))
        :mode "\\.vala\\'" "\\.vapi\\'")
      
  13. brainfuck
    1. NOT-SUPPORTED brainfuck-mode   package mode

      ⚠️ For some reason, when installing some packages, this one gives parenthesis errors! And it propagates through the others!!!

      (use-package brainfuck-mode
        :if (not (am-i-on-cellphone-p))
        :defer t
        :mode "\\.bf\\'") 
      
    2. NOT-SUPPORTED bfbuilder   package

      Brainfuck development environment.

      (use-package bfbuilder
        :if (not (am-i-on-cellphone-p))
        :defer t
        :commands (bfbuilder-debug bfbuilder-mode)
        :after brainfuck-mode)
      
    3. NOT-SUPPORTED ebf   package

      Brainfuck transpiler to Emacs Lisp

      (use-package ebf
        :if (not (am-i-on-cellphone-p))
        :defer t
        :after brainfuck-mode) 
      
  14. Turtle RDF
    1. ttl-mode   package mode
      (use-package ttl-mode
        :mode "\\.ttl\\'")
      
  15. YAML
    1. yaml-mode   package mode
      (use-package yaml-mode
        :mode "\\.yaml\\'")
      
  16. Haskell
    1. haskell-mode   package mode
      (use-package haskell-mode
        :if (not (am-i-on-cellphone-p))
        :mode "\\.hl\\'"
        :init
        (add-hook 'haskell-mode-hook 'turn-on-haskell-indentation)
        (setq haskell-program-name "ghc --interactive")) 
      
  17. Fish shell
    1. fish-mode   package mode
      (use-package fish-mode
        :ensure t
        :mode "\\.fish\\'")
      
  18. CoffeeScript
    1. coffee-mode   package mode
      (use-package coffee-mode
        ;; :defer t
        :if (not (am-i-on-cellphone-p))
        :mode "\\.coffee\\'"
        :init 
        (setq coffee-tab-width 4))
      
  19. Nignx
    1. nginx-mode   package mode
      (use-package nignx-mode
        :if (not (am-i-on-cellphone-p))
        :ensure nil
        :mode "nginx\\.conf\\'" "\\.nginx")
      
  20. Apache
    1. apache-mode   mode package
      (use-package apache-mode
        :if (not (am-i-on-cellphone-p))
        :ensure nil
        :mode 
        "/apache2/sites-\\(?:available\\|enabled\\)/"
        "/httpd/conf/.+\\.conf\\'"
        "/apache2/.+\\.conf\\'"
        "/\\(?:access\\|httpd\\|srm\\)\\.conf\\'"
        "/\\.htaccess\\'")
      
  21. Lua
    1. lua-mode   package mode
      (use-package lua-mode
        :if (not (am-i-on-cellphone-p))
        :mode "\\.lua\\'")
      
  22. Conkeror
    1. Conkeror-minor-mode   mode package
      (use-package conkeror-minor-mode
        :if (not (am-i-on-cellphone-p))
        :ensure nil
        :commands (conkeror-minor-mode))
      
  23. Emacs Speaks Statistics
    1. ess   package
      (use-package ess
        :if (not (am-i-on-cellphone-p))
        :commands (ess-mode))
      
  24. Scheme and Racket
    1. racket-mode   package mode
      (use-package racket-mode
        :mode ".rkt"
        :hook
        ((racket-mode . geiser-mode)
         ;; (racket-mode . paredit-mode)
         (racket-mode . auto-complete-mode)))
      
  25. Common Lisp / Sly
    1. Completions is to narrow!

      The variable window-min-height should be 10 at least to read some completions.

      Sly uses completions in splited windows (uses the function display-buffer-at-bottom or display-buffer-below-selected, see elisp#Buffer Display Action Alists). Completions are after the fifth line more or less.

      Nano uses 1, which is a little too narrow, it should be modified!

      (defun my-large-splited-windows ()
        "Make splited windows larger!
      Modify the current min height to make splited windows larger.  This
      mean that using `display-buffer-at-bottom' or
      `display-buffer-below-selecte' will make buffers with larger windows.
      
      This only affects the local buffer only."
        (setq-local window-min-height 10))
      
      (add-hook 'sly-mrepl-mode-hook #'my-large-splited-windows)
      

13. Utilities

;; (message"==> Utilities")
  1. Projectile   package

    Organizing buffers and other Emacs things in projects.

    Setting the base modemap.

    (use-package projectile
      :defer t
      :bind-keymap
      ("s-p" . projectile-command-map)
      ("C-c p" . projectile-command-map)
      :config
      ;; (define-key projectile-mode-map (kbd "s-p") 'projectile-command-map)
      ;; (define-key projectile-mode-map (kbd "C-c p") 'projectile-command-map)
      (projectile-mode +1))
    
  2. NOT-SUPPORTED Execute
    (load-library "execute")
    
  3. Calendar
    1. my-calendar-nth-day   function
      (defun my-calendar-nth-day (nth-day)
        "Return the nth day from the current day.
      Calculate the NTH-DAY and return it in a calendar
      format: (month day year)."
        (let ((year (nth 5 (decode-time))))
          (calendar-gregorian-from-absolute
           (+ -1 nth-day (calendar-absolute-from-gregorian (list 1 1 year))))))
      
    2. Holidays
      (setq holiday-general-holidays nil)
      (setq holiday-other-holidays
            '(;; March
              (holiday-fixed 3 3 "Carnaval")
              (holiday-fixed 3 4 "Carnaval")
              (holiday-fixed 3 24 "Día de la memoria por la verdad y justicia")
              ;; April
              (holiday-fixed 4 2 "Día del veterano y de los caídos en la Guerra de Malvinas")
              (holiday-fixed 4 24
                             "Día por la tolerancia y el respeto entre los pueblos")
              ;; May
              (holiday-fixed 5 1 "Día del trabajador")
              (holiday-fixed 5 25 "Revolución de Mayo")
              ;; June
              (holiday-fixed 6 20 "Manuel Belgrano")
              ;; July
              (holiday-fixed 7 9 "Día de la independencia")
              ;; August
              (if (equal (calendar-day-of-week (list 8 17 (nth 5 (decode-time)))) 0)
                   ;; Cae un domingo, mover a lunes.
                   (holiday-fixed 8 18 "José de San Martín")
                 (holiday-fixed 8 17 "José de San Martín"))
              ;; September
              (holiday-fixed 9 17 "Día del profesor")
              (holiday-fixed 9 21 "Día de la primavera y del estudiante")
              ;; October
              (holiday-float 10 2 2 "Ada Lovelace Day")
              (if (equal (calendar-day-of-week (list 10 12 (nth 5 (decode-time)))) 0)
                   (holiday-fixed 10 13 "Día del respeto a la diversidad cultural")
                 (holiday-fixed 10 12 "Día del respeto a la diversidad cultural"))
              ;; November
              (if (equal (calendar-day-of-week (list 11 20 (nth 5 (decode-time)))) 0)
                  (holiday-fixed 11 21 "Día de la Soberanía Nacional")
                (holiday-fixed 11 20 "Día de la Soberanía Nacional"))
      
              (holiday-fixed 12 9 "Día internacional de la informática")
              (holiday-fixed 12 11 "Día nacional del profesional informático")
              ;; Último viernes de julio
              (holiday-float 7 5 -1 "Día del SysAdmin")
      
              ;; 256° día del año
              (holiday-sexp '(my-calendar-nth-day 256) "Día del programador")))
      
      (setq holiday-local-holidays nil)
      (setq holiday-hebrew-holidays nil)
      (setq holiday-bahai-holidays nil)
      (setq holiday-islamic-holidays nil)
      (setq holiday-oriental-holidays nil)
      
      ;; Show marks
      (setq calendar-mark-diary-entries-flag t)
      (setq calendar-mark-holidays-flag t)
      
  4. Dired
    1. Dired async call fix

      When calling dired-do-async-shell-command, will return error in non-POSIX shells like Fish. This is because the string &wait& is concatenated at the end of the command string without space or separator.

      However, the dired-shell-stuff-it is the function that process the command given by the user, and not dired-do-async-shell-command. The user gives a command according to the Dired manual, possibly with ? o * wildcard characters. The dired-shell-stuff-it function returns the real shell command to be executed. If the command is asynchronous, it will return a string ending in "&wait&".

      The following advice function will add a space, leaving " &wait&" at the end. It will add the space only if the real shell command has the asynchronous particular ending string.

      (defun my-dired-shell-stuff-it-add (x)
        "Add a space between the command and the wait.
      If the X command ends with \"&wait&\", then add a space before the ampersand."
        (replace-regexp-in-string "&wait&$" " &wait&" x))
      
      (advice-add #'dired-shell-stuff-it :filter-return #'my-dired-shell-stuff-it-add)
      
    2. Listing switches
      (setq dired-listing-switches "-alh")
      
    3. NOT-SUPPORTED image-dired+   package
      (use-package image-dired+
        :commands (image-diredx-async-mode imade-diredx-adjust-mode)) 
      
    4. NOT-SUPPORTED Dired+

      Dired+ enhance the dired to display more information and colours. Also provides more interactive commands.

      It is not in the Melpa repository, it is located at the emacs-stuff directory.

      (setq diredp-hide-details-initially-flag nil
            diredp-hide-details-propagate-flag nil)
      ;; (require 'dired+)
      

      For some reason, direp takes to long with this function every time find-dired is called. Remove from the hook.

      (remove-hook 'dired-mode-hook 'diredp-nb-marked-in-mode-name)
      
  5. Emms
    • Show the emms at the line-mode.

    Players are used in the following order:

    1. MPV
    2. mplayer
    3. VLC

    Use mplayer instead of mpg321.

    (use-package emms
      :if (not (am-i-on-cellphone-p))
      :commands (emms)
      :config
      (require 'emms-setup)
      (emms-all)
      (emms-default-players)
    
      (setq
       emms-mode-line-mode-line-function (quote emms-mode-line-icon-function)
       emms-player-list (quote
                         (emms-player-mpv
                          emms-player-mplayer-playlist
                          emms-player-mplayer
                          emms-player-vlc
                          emms-player-vlc-playlist))
       emms-player-mpg321-command-name "mplayer"))
    
  6. Gnus
    1. Move init file

      Move init file into emacs-stuff/gnus.

      (setq gnus-init-file (emacsstuff-dir "gnus/gnus-init.el"))
      
    2. Init file
      1. Support for Atom

        Extract from Emacswiki GnuRSS article.

        • Install xsltproc (Debian: apt-get install xsltproc)
        • Get the file atom2rss.xsl from http://atom.geekhood.net/ and save it in your home directory
        • Put the following code into your .gnus:
        ;; This will be the default .gnus.el. We change its location.
        
        ;; Usar Atom
        (require 'mm-url)
        (defadvice mm-url-insert (after DE-convert-atom-to-rss () )
          "Converts atom to RSS by calling xsltproc."
          (when (re-search-forward "xmlns=\"http://www.w3.org/.*/Atom\"" 
                                   nil t)
            (goto-char (point-min))
            (message "Converting Atom to RSS... ")
            (call-process-region (point-min) (point-max) 
                                 "xsltproc" 
                                 t t nil 
                                 (expand-file-name
                                  "~/emacs-stuff/gnus/atom2rss.xsl") "-")
            (goto-char (point-min))
            (message "Converting Atom to RSS... done")))
        
        (ad-activate 'mm-url-insert)
        
        ;; Para que no inicie de buenas a primeras cargando
        (setq gnus-select-method '(nnrss ""))
        
      2. Load Gnus my-secrets

        Groups and things I follow are in the secrets directory.

        (load-file (emacsstuff-dir "secrets/gnus/gnus-init.el"))
        
    3. Tree appearance on summary buffer

      This will show a tree-like appearance on the summary buffer.

      (setq gnus-thread-indent-level 4 ;; Not used really, you nee %I in line format
      
          ;; Make a false root per subject
          gnus-summary-make-false-root-always t
          gnus-summary-make-false-root 'dummy
      
          ;; Default... no idea what is the difference
          gnus-generate-tree-function #'gnus-generate-vertical-tree
      
          ;; Tree characters
          ;; gnus-sum-thread-tree-single-leaf "\\->"
          ;; gnus-sum-thread-tree-leaf-with-other "+->"
          ;; gnus-sum-thread-tree-vertical "|"
          ;; gnus-sum-thread-tree-indent "  "
          gnus-sum-thread-tree-single-leaf "└─→ "
          gnus-sum-thread-tree-leaf-with-other "├─→ "
          gnus-sum-thread-tree-vertical "|"
          gnus-sum-thread-tree-indent "  "
          gnus-thread-tree-root "> "
          gnus-sum-thread-tree-false-root "> "
      
          ;; Line formats...
          gnus-summary-dummy-line-format "_>> %S <<\n"
          gnus-summary-line-format "%B%U%R%z %(%[%4L: %n%]%) %s\n")
      
  7. TODO Jabber

    Resta chequear el path.

    (setq jabber-msg-sound (emacsstuff-dir "personal/receive.wav"))
    (setq jabber-default-priority 10)
    (setq jabber-default-show "dnd")
    (setq jabber-default-status (my-secrets-get "jabber-default-status"))
    (add-hook 'jabber-roster-mode-hook 'jabber-autoaway-start)
    
  8. Bibtex manager

    BibTeX manager.

    1. Ebib   package
      (use-package ebib
        :commands (ebib)
        :defer t
        :config
        (setq ebib-bib-search-dirs '("~/cloud/resources/bibtexs")
              ebib-file-associations '(("pdf")
                                       ("ps" . "gv"))
              ebib-file-search-dirs '("~/cloud/resources/")))
      
  9. Wanderlust

    Wanderlust x-faces requires the compface package installed with the uncompface program.

    1. my-wl-copy-href-link   function
      (defun my-wl-copy-href-link ()
        "Copy the URL from a message buffer."
        (interactive)
        (kill-new (get-text-property (point) 'w3m-href-anchor)))
      
    2. my-wl-browse-href-url   function
      (defun my-wl-browse-href-url (&optional copy)
        "Open browser the link from the current point in a MIME-view buffer.
      Get the link from the current point and open the browser.
      With C-u store it in the clipboard."  
        (interactive "P")
        (let ((url (get-text-property (point) 'w3m-href-anchor)))
          (if copy
              (kill-new url)
            (browse-url url))))
      
    3. wanderlust - use-package   package
      (use-package wanderlust
        :if (not (am-i-on-cellphone-p))
        :commands (wl)
        :config
        (setq wl-folders-file (emacsstuff-dir "secrets/wanderlust/folders"))
      
    4. Close use-package
      ) ;; use-package
      
    5. Warn the user about uncompface

      If the program does not exists, warn the user.

      (unless (executable-find "uncompface")
        (message "Warning: uncompface program was not found and is required by Wanderlust!"))
      
    6. Auto-fill configuration

      Auto-fill is configured to make the mail more readable for mobile devices.

      1. my/minimal-auto-fill   function
        (defun my/minimal-auto-fill ()
          "Set the auto-fill to a minimal number.
        This would be used on Wanderlust draft buffers."
          (setq fill-column 63))
        
        (add-hook 'wl-draft-mode-hook #'my/minimal-auto-fill)
        (add-hook 'wl-draft-mode-hook #'auto-fill-mode)
        
    7. Templates

      Templates have lots of personal information. It should not be here.

      (setq wl-template-alist '())
      (when (file-exists-p (emacsstuff-dir "secrets/wanderlust/templates.el"))
        (load-library (emacsstuff-dir "secrets/wanderlust/templates.el")))
      
    8. X-Face

      Enable the X-Face. Some clients can show it. The file x-face-e21.el is required and can be downloaded from http://jpl.org/ftp/pub/elisp/ (or ftp://jpl.org/pub/elisp/). However, the script is provided at dists/scripts/x-face-e21.el.gz.

      (autoload 'x-face-decode-message-header "x-face-e21")
      (setq wl-highlight-x-face-function 'x-face-decode-message-header)
      
    9. Common config

      wl-from need to be setted for wanderlust initialization

      (setq wl-from (my-secrets-get "wl-from")
            mime-edit-split-message nil)
      
  10. Ispell
    1. Use aspell
      (setq ispell-program-name "/usr/bin/aspell")
      
  11. Browse-url

    Use the default browser when clicking a link.

    (setq browse-url-browser-function 'browse-url-default-browser)
    
    1. Default browsers

      Set the default browser.

      1. NOT-SUPPORTED Nyxt support

        If nyxt, use the following:

        (setq browse-url-browser-function 'browse-url-generic)
        (setq browse-url-generic-program "nyxt")
        
      2. Firefox
        (setq browse-url-browser-function 'browse-url-firefox)  
        
  12. SQLi - SQL servers connection
    1. Recognize prompt in MariaDB
      1. sqli-add-hooks   function
        (defun sqli-add-hooks ()
          "My hooks for sql-interactive-mode"
          (sql-set-product-feature
           'mysql
           :prompt-regexp "^\\(?:mysql\\|MariaDB\\).*> "))
        
        (add-hook 'sql-interactive-mode-hook 'sqli-add-hooks)
        
  13. NOT-SUPPORTED Dashboard
    (require 'dashboard)
    (dashboard-setup-startup-hook)
    ;; Or if you use use-package
    ;; (use-package dashboard
    ;;   :ensure t
    ;;   :config
    ;;   (dashboard-setup-startup-hook))
    

    For using with emacs-server:

    (setq initial-buffer-choice (lambda () (get-buffer "*dashboard*")))
    
    1. Configuration
      ;; Set the title
      ;; (setq dashboard-banner-logo-title "Welcome to Emacs Dashboard")
      ;; Set the banner
      ;; (setq dashboard-startup-banner [VALUE])
      ;; Value can be
      ;; 'official which displays the official emacs logo
      ;; 'logo which displays an alternative emacs logo
      ;; 1, 2 or 3 which displays one of the text banners
      ;; "path/to/your/image.png" which displays whatever image you would prefer
      
      ;; Content is not centered by default. To center, set
      (setq dashboard-center-content t)
      

      Widgets:

      (setq dashboard-items '((recents  . 5)
                              (bookmarks . 5)
                              (projects . 5)
                              ;; (agenda . 5)
                              (registers . 5)))
      
  14. w3m   package
    (use-package w3m
      :commands (w3m))
    
  15. w3   package
    (use-package w3
      :ensure nil
      :commands (w3))
    
  16. Jabber-otr   package
    (use-package jabber-otr
      :ensure nil
      :defer t
      :commands (jabber-otr-encrypt))
    
  17. neotree   package

    Show the directory tree at the side of the window.

    (use-package neotree
      :ensure nil
      :commands (neotree
                 neotree-show
                 neotree-dir
                 neotree-find
                 neotree-projectile-action
                 neotree-toggle))
    
  18. Magit   package

    Git Manager.

    (use-package magit
      :commands (magit))
    
  19. Info
    1. How to add an info file

      Info concatenates dir files to create the main index. It uses the dir file as index of all the .info files founded in a specific directory. Thus, adding an info file requires to create or update a dir file too. So, adding the directory to the Info-additional-directory-list variable is not enough. To create or update the dir file in an info directory use the following command:

      install-info THE_INFO_FILE.info ./dir
      
    2. Add Ada info

      I use a personal directory for Ada language and their info.

      (add-to-list 'Info-additional-directory-list "~/Ada/share/doc/info/")
      
    3. Adding a .local info directory
      (add-to-list 'Info-additional-directory-list "~/.local/info")
      (add-to-list 'Info-additional-directory-list "~/.local/share/info")
      
    4. Add the latex2e info
      (add-to-list 'Info-additional-directory-list
                   "/usr/share/texmf-dist/doc/info")
      
  20. IRC (rcirc)
    1. Add default data
      (setq rcirc-default-nick (my-secrets-get "rcirc-default-nick")
            rcirc-default-user-name (my-secrets-get "rcirc-default-user-name")
            rcirc-default-full-name (my-secrets-get "rcirc-default-full-name"))
      
    2. Add the rcirc server
      (setq rcirc-server-alist '())
      
      1. FreeNode
        (setq rcirc-server-alist '(("irc.freenode.net"
                                    :port 6697
                                    :encryption tls
                                    :channels (my-secrets-get "rcirc-freenode-channels"))))
        
        
      2. Libera.chat
        (push '("irc.libera.chat"
                :port 6697
                :encryption tls
                :channels (my-secrets-get "rcirc-liberachat-channels"))
              rcirc-server-alist)
        
      3. Other personal servers
        (when (file-exists-p (emacsstuff-dir "secrets/rcirc/rcirc.el"))
          (load-library "secrets/rcirc/rcirc.el"))
        
  21. Mastodon client   package
    (use-package mastodon
      :if (not (am-i-on-cellphone-p))
      :commands (mastodon mastodon-toot)
      :config
      (setq mastodon-active-user (my-secrets-get "mastodon-active-user"))
      (setq mastodon-instance-url (my-secrets-get "mastodon-instance-url")))
    
  22. Shells and terminals
    1. default shell is fish
      (setq shell-file-name (executable-find "fish"))
      
    2. eat   package
      (use-package eat
        :commands (eat))
      
    3. eshell
      1. Load our own commands
        (when (file-exists-p (emacsstuff-dir "secrets/eshell/my-commands.el"))
          (load-library (emacsstuff-dir "secrets/eshell/my-commands.el")))
        
  23. World time list
    1. world-time-mode   package

      This package requires world-clock-list variable set.

      (use-package world-time-mode
        :ensure nil
        :commands (world-time-list list-world-time))
      

14. Gemini support

  1. elpher   package

    Elpher also sets up variables to support // URLs for browse-url function too.

    (use-package elpher
      :commands (elpher)
      :config (setq elpher-default-url-type "gemini"))
    
  2. Lagrange browse-url

    Why don't we use Lagrange as default browser too?

    (defcustom lagrange-program "lagrange"
      "The program path to Lagrange.")
    (defcustom lagrange-arguments nil
      "Extra arguments for Lagrange.")
    
    (defconst my-choose-gemini-browser-alist
      (list (cons "elpher" #'elpher-browse-url-elpher)
            (cons "lagrange" #'lagrange-browse-url-lagrange)))
    
    (defun my-choose-gemini-browser (url &rest _)
      "Choose between the Gemini browsers."
      (interactive (browse-url-interactive-arg "URL:"))
      (funcall (alist-get 
                (completing-read "Which browser"
                                 (mapcar #'car my-choose-gemini-browser-alist))
                my-choose-gemini-browser-alist
                nil nil #'equal)
               url))
    
    (defun lagrange-browse-url-lagrange (url &rest _)
      "Open Lagrange to browse the given URL."
      (interactive (browse-url-interactive-arg "URL: "))
      (setq url (browse-url-encode-url url))
      (let* ((process-environment (browse-url-process-environment)))
        (apply #'start-process
               (concat "lagrange " url) nil
               lagrange-program
               (append
                lagrange-arguments            
                (list url)))))
    
    (with-eval-after-load 'browse-url
      (add-to-list 'browse-url-handlers 
                   (cons "^\\(gopher\\|finger\\|gemini\\)://" 
                         #'my-choose-gemini-browser)))
    

15. Tor support

  1. org-links
    1. my-tor-switch-link-follow   function
      (defun my-tor-switch-link-follow (url &rest _)
        "Copy the link.
      Tor cannot be executed with an URL."
        (interactive (browse-url-interactive-arg "URL: "))
        (message url)
        (let ((urlcopy (replace-regexp-in-string "^tor\\(https?\\)" "\\1" url)))
          (kill-new urlcopy)
          (message "Copied to kill-ring: %s" urlcopy)))
      
      (org-link-set-parameters "torhttps" :follow
                               (lambda (url arg)
                                 (my-tor-switch-link-follow (concat "https:" url))))
      (org-link-set-parameters "torhttp" :follow
                               (lambda (url arg)
                                 (my-tor-switch-link-follow (concat "http:" url))))
      

16. Interesting functions

;; (message"==> Interesting functions")
  1. my-reset-buffers   interactive function
    (defun my-kill-if-non-common (buffer)
      "Kill the buffer provided if not modified and if it is not the initial ones" 
      (unless (member (buffer-name buffer)
                      '("*scratch*" "*Messages*"))
        (kill-buffer-if-not-modified buffer)))
    
    (defun my-reset-buffers ()
      "Kill all saved buffers except the initial ones."
      (interactive)
      (mapcar 'my-kill-if-non-common (buffer-list)))
    
  2. my-org-agenda

    To show my own agenda style: The current day, and the amount of work done.

    (defun my-search-clock-reports () 
      "Search #+begin: strings inside the current buffer.
    
    Return a list of positions where these strings can be found."
      (save-excursion
        (goto-char (point-min))
        (let ((lst-results nil))
          (while (re-search-forward "\\(#\\+begin:\\|#\\+BEGIN:\\)" nil t)
            (setq lst-results (push (match-beginning 0) lst-results))
            (goto-char (match-beginning 0))
          (next-line))
          lst-results)))
    
    (defun my-org-agenda ()
      "Show my own style of agenda.
    Display the agenda view in list day, and the current work."
      (interactive)
      ;; (with-current-buffer (find-file "~/Sync/orgs/init.org")
      ;;   (dolist (pos (my-search-clock-reports))
      ;;     (goto-char pos)
      ;;     (org-clock-report)))
      (org-agenda-list nil nil 1))
    
  3. Open the init.org file
    1. my-init-file   variable custom
      (defcustom my-init-file "~/emacs-stuff/init.org"
        "Where is my init.org file?"
        :type 'file)
      
    2. my-find-init-file   interactive function
      (defun my-find-init-file ()
        "Open the init.org file."
        (interactive)
        (find-file-other-frame my-init-file))
      
  4. Timezone functions
    (defun my-convert-timezone (hour from-timezone to-timezone)
      "Convert HOUR hours from the FROM-TIMEZONE to TO-TIMEZONE."
      (interactive "nHour: 
    MFrom timezone: 
    MTo timezone: ")
      (let ((dtime (decode-time)))
        (setf (decoded-time-zone dtime) from-timezone)
        (setf (decoded-time-hour dtime) hour)
        (message (format "%s <-> %s"
                         (format-time-string "%H:%M %d day %Z %z" (encode-time dtime) from-timezone)
                         (format-time-string "%H:%M %d day %Z %z" (encode-time dtime) to-timezone)))))
    
    (defun my-from-timezone (hour timezone)
      "What time is here whene at TIMEZONE is HOUR hours?
    Convert the given HOUR to the provided TIMEZONE.
    TIMEZONE should be a string such as \"UTC+10\", \"GMT\",
    or a tzdata string like \"America/New_York\"."
        (interactive "nHour:\nMTime-zone string:")
        (my-convert-timezone hour timezone (current-time-zone)))
    
    (defun my-to-timezone (hour timezone)
      "What time is at TIMEZONE when here is HOUR hours?
    Convert the given HOUR to the provided TIMEZONE.
    TIMEZONE should be a string such as \"UTC+10\", \"GMT\",
    or a tzdata string like \"America/New_York\".
    HOUR is a number hour."
      (interactive "nHour:\nMTo time-zone string:")
      (my-convert-timezone hour (current-time-zone) timezone))
    

17. Hydras

Load hydral.el file. See my-hydras.html.

(load-library (emacsstuff-dir "my-hydras.el"))

18. Other configurations

Some other configurations that are not supposed to be on every machine.

(when (file-exists-p (emacsstuff-dir "secrets/personal-configurations.el"))
  (load-library (emacsstuff-dir "secrets/personal-configurations.el")))

19. Emacs Server

Emacs server allows the user to use the same Emacs instance in multiple windows. When the user wants to open a new window, calling emacs my-file.txt would open a new window but also creates a new Emacs instance: any buffers opened in other instances would not be shared.

However, starting the Emacs server in an instance, enables creating new windows from the command line sharing all the features and buffers. The user should call emacsclient -c my-file.txt to create a new frame with the file opened.

More information at emacs#Emacs Server.

The following code enable the server, and thus emacsclient program would work.

(require 'server)
(unless (server-running-p)
  ;; (message"==> Emacs server")
  (setq server-window nil)
  (server-start))

20. NOT-SUPPORTED Enabling programing appearance

Depends on Section Programming vs reading appearance.

(my-emacs-programming)

21. Stop the measure of the init time

(setq my-init-stop-time (time-to-seconds))
(message (format "Init.org lasted %f seconds. See `use-package-report'."
                 (- my-init-stop-time my-init-start-time)))

22. Compile .el files

(unless (file-exists-p "~/emacs-stuff/init.elc")
  (native-compile-async "~/emacs-stuff/" t nil nil)
  (byte-recompile-directory "~/emacs-stuff/" 0 nil t)
  (message "emacs-stuff: all sources recompiled"))

23. Last but not least, open the main files

  1. my-cellphone-capture-buttons   function
    (defun my-cellphone-capture-buttons ()
      "Generate a list of button information from `org-capture-templates'.
    This button information is for `cptui-create-menu-buffer' or `cptui-insert-grid-buttons'."
      (mapcar (lambda (c)
                (list (nth 1 c)
                      `(lambda (x) (org-capture nil ,(car c)))))
              org-capture-templates))
    
  2. my-cellphone-startup-buttons   variable
    (defvar my-cellphone-startup-buttons
      (append
       (my-cellphone-capture-buttons)
       '("\n"
         ("Agenda" (lambda (x) (org-agenda-list nil nil 1)))))
      "Buttons for the cellphone menu.")
    
  3. my-run-cellphone-startup   function
    (require 'cptui)
    
    (defun my-run-cellphone-startup ()
      "This is the startup function for the cellphone."
      (cptui-create-menu-buffer "Startup" my-cellphone-startup-buttons)
      (my-org-agenda))
    
  4. Startup code
    (cond ((am-i-on-win-p)
           (find-file-read-only "~/startup.org"))
          ((am-i-on-cellphone-p)
           (my-run-cellphone-startup))
          (t 
           ;; (org-brain-visualize "main")
           (my-org-agenda)))
    

Date: 01 jun 2018

Author: Gimenez, Christian

Created: 2024-11-03 dom 17:31

Validate