7d.nz

Init.org

[2019-02-27 Wed]

  emacs org elisp
emacs+org.png

This is my Emacs configuration, organized in an init.org file, with conditional section evaluations.

I'm working daily on emacs for 7 years now and this what I have now. There were many improvements when moving to Emacs 28. If you're still on 26 or 27, don't worry, it's only about a few changes in early-init.el and in the package manager to keep it compatible.

Here, only sections in a DONE state will be evaluated. However the HTML export of ox-webblog doesn't export TODO states (they're simply not visible) so you should refer to the original file to understand which sections are actually evaluated.

This configuration isn't tangled: the init.el is simply in charge of jumping to the legit source blocks and evaluate them.

It's structured like so:

    #+SEQ_TODO: ⵝ ? | ✓
  * init.org
  ✓ ← declared as a done state in the #+TODO directive
   ** ✓ section 1
    ALL elisp blocks in this section are evaluated
    even those falling under a subsection with any todo states
    ***  section 1
         will also be evaluated, this until init.org/depth is reached
   ** ⵝ section 2
       nothing evaluated
   ** section 3
       nothing evaluated

That file isn't in the org export down below neither (it's included from an other location).

Shortcuts:

init.el

  ;; Load bare minimal, then org-mode, then parse init.org
;; (find-file "~/.emacs.d/init.org")

;; (add-to-list 'load-path (expand-file-name "lisp" user-emacs-directory))
;;(defconst *spell-check-support-enabled* nil) ;; Enable with t if you prefer
;;(defconst *is-a-mac* (eq system-type 'darwin))

;; https://github.com/raxod502/straight.el/issues/757#issuecomment-840123748
;;(setq straight-repository-branch "develop")
;;(setq comp-deferred-compilation-deny-list nil)

;; Bootstrapping straight.el
(defvar bootstrap-version)
(let ((bootstrap-file
       (expand-file-name "straight/repos/straight.el/bootstrap.el" user-emacs-directory))
      (bootstrap-version 5))
  (unless (file-exists-p bootstrap-file)
    (with-current-buffer
        (url-retrieve-synchronously
         "https://raw.githubusercontent.com/raxod502/straight.el/develop/install.el"
         'silent 'inhibit-cookies)
      (goto-char (point-max))
      (eval-print-last-sexp)))
  (load bootstrap-file nil 'nomessage))

;;- if you use use-package, then this makes each use-package form also
;;- invoke straight.el to install the package, unless otherwise
;;- specified.
(setq straight-use-package-by-default t)

;; Use straight.el for use-package expressions
(straight-use-package 'use-package)
;;(use-package el-patch  :straight t)

;; Load the helper package for commands like `straight-x-clean-unused-repos'
(require 'straight-x)

;;(require 'package)
;;(if (< (string-to-number emacs-version) 27)
;;    (package-initialize)  ; no longer needed in emacs 27
;;  )

;;(let* ((no-ssl (and (memq system-type '(windows-nt ms-dos))
;;					(not (gnutls-available-p))))
;;       (proto (if no-ssl "http" "https")))
;; Comment/uncomment these two lines to enable/disable MELPA and MELPA Stable as desired
;;  (add-to-list 'package-archives (cons "melpa" (concat proto "://melpa.org/packages/")) t)
;; (add-to-list 'package-archives (cons "melpa-stable" (concat proto "://stable.melpa.org/packages/")) t)
;;  )

;;      ;; Evaluate Code Blocks alternative
;;      ((looking-at "^#\\+BEGIN_SRC +emacs-lisp *$")
;;       (let ((l (match-end 0)))
;;         (search-forward "\n#+END_SRC")
;;         (eval-region l (match-beginning 0))))
;;      ;; Finish on the next level-1 header
;;      ((looking-at "^\\* ")
;;       (goto-char (point-max)))
					;     )
;;   )
;; )


(defun org-next-block-if-any ()
  " Jump to next block, return nil
    when a user-error is thrown
    which traditionnaly is : (user-error No further code blocks).
    Good care is advised to handle that nil output inside a loop."
  (condition-case err (org-next-block 1) (user-error () nil)))

(defun try--ignore-user-error(f)
  " Execute function f and handle any user-error thrown
    by ignoring it. Example : (user-error No further code blocks).
    return nil "
  (condition-case err (funcall f) (user-error () nil)))


(defvar init.org/depth 3
  "What depth of init.org headers to go to at startup.")

;; https://stackoverflow.com/questions/3139970/open-a-file-at-line-with-filenameline-syntax
;; Open files and goto lines like we see from g++ etc. i.e. file:line#
;; (to-do "make `find-file-line-number' work for emacsclient as well")
;; (to-do "make `find-file-line-number' check if the file exists")
(defadvice find-file (around find-file-line-number
                             (filename &optional wildcards)
                             activate)
  "Turn files like file.cpp:14 into file.cpp and going to the 14-th line."
  (save-match-data
    (let* ((matched (string-match "^\\(.*\\):\\([0-9]+\\):?$" filename))
           (line-number (and matched
                             (match-string 2 filename)
                             (string-to-number (match-string 2 filename))))
           (filename (if matched (match-string 1 filename) filename)))
      ad-do-it
      (when line-number
        ;; goto-line is for interactive use
        (goto-char (point-min))
        (forward-line (1- line-number))))))

(defun path-with-line-number()
  (concat (dired-replace-in-string (getenv "HOME") "~" (buffer-file-name)) "::"
	  (number-to-string (line-number-at-pos))))


(defun init.org(file headline prefix)
  "Evaluate the source blocks of an org-mode file,
   starting at a level 1 section named HEADLINE
   every subsection starting with PREFIX"
  (with-temp-buffer
    (insert-file file)
    (goto-char (point-min))
    (search-forward (concat "\n* " headline))
    (org-mode)
    ;; line number here
    (org-narrow-to-subtree)
    (org-down-element)
    (while (not (eobp))
      (cond
       ((looking-at (format "\\*\\{2,%s\\} %s +.*$"
			    init.org/depth prefix))
	(princ (concat "\n" (match-string 0) " "))
	(setq init-org-block 0)
	;; add to prev line number here (minus previous)
	(org-narrow-to-subtree)
	(while (org-next-block-if-any)
	  (cond (
		 (looking-at "^[\t ] *#\\+begin_src +\\(emacs-lisp\\|elisp\\)\\([\t ]+.*\\)?$")
		 (let ((l (match-end 0)))
		   (search-forward "#+end_src")
		   (setq init-org-block (+ 1 init-org-block))
		   ;;(princ init-org-block) (princ (line-number-at-pos))
		   ;;(princ "[ ") (princ init-org-block) (princ " ")
		   (princ (line-number-at-pos)) (princ " ]") ;; < [2021-12-28 Tue] need to keep the pos before narrowing
		   ;;(princ(path-with-line-number))
		   ;;(message (path-with-line-number))
		   (eval-region l (match-beginning 0))
		   ))))
	(widen)
	)
       ((looking-at "^\\* ")
	(message "%s complete" headline)
	(goto-char (point-max))))
      (try--ignore-user-error 'org-forward-element)
      )))

(message (format-time-string "%Y-%m-%d %H:%M:%S"))
(init.org (concat user-emacs-directory "init.org") "init.org" "✓")
(message "init.el loaded")

Package manager

Straight. Those two § are from https://github.com/raxod502/straight.el

Install packages

Out of the box, you can install any package listed on MELPA, GNU ELPA, or Emacsmirror, which is to say any package in existence. (Although MELPA is used as a package listing, packages are installed by cloning their Git repositories rather than by downloading tarballs like package.el does.) To install a package temporarily (until you restart Emacs), run M-x straight-use-package and select the package you want. To install a package permanently, place a call to straight-use-package in your init-file, like:

(straight-use-package 'el-patch)

Note that installing a package will activate all of its autoloads, but it will not actually require the features provided by the package. This means that you might need to use require or autoload for some antiquated packages that do not properly declare their autoloads.

Configuration reproducibility

To save the currently checked out revisions of all of your packages, run M-x straight-freeze-versions. The resulting file (~/.emacs.d/straight/versions/default.el), together with your init-file, perfectly define your package configuration. Keep your version lockfile checked into version control; when you install your Emacs configuration on another machine, the versions of packages specified in your lockfile will automatically be checked out after the packages are installed. You can manually revert all packages to the revisions specified in the lockfile by running M-x straight-thaw-versions. To learn more, see the documentation on version lockfiles.

init.org

Explanations

All blocks in section L2 marked with tick ( ) are evaluated. The tick mark works only at Level 2. This Means that ALL blocks after a level 2 headline with a tick mark and below are evaluated, whatever the nesting they are in. This is intended to evaluate only visible sections and no hidden nested ones.

start

    (message "%s %s\n%s"
	   (format-time-string
	    "%Y-%m-%d %H:%M:%S")
	   "init.org starts" (emacs-version))
  (setq init.org-start-time (current-time))

user name

  (setq user-full-name "Phil. Estival")

debugging

(debug-on-entry nil) (setq debug-on-error t)

    (defun reload-dotemacs ()
    (interactive)
    (load-file "~/.emacs.d/init.el"))

Native Compiled Emacs Lisp (.eln)

emacs-nat or gcc-emacs is integrated into master branch starting from 28.0.50

    (defvar comp-deferred-compilation)
  (setq comp-deferred-compilation t)

The emacs process will sometimes take up 100% when loading a new package (list-processes) or (proced) will show what's going on under the hood, that is, compiling to native binary.

elpa, melpa, gnu

elpa & melpa & gnu. For list-packages to read packages description, no longer to install them.

    (setq package-archives
        '(("melpa" . "https://melpa.org/packages/")
          ("nongnu" . "https://elpa.nongnu.org/nongnu/")
          ("gnu" . "https://elpa.gnu.org/packages/")))

  (add-to-list 'load-path (expand-file-name "lisp" user-emacs-directory))
  ;; ( let* ((no-ssl (and (memq system-type '(windows-nt ms-dos))
  ;;                  (not (gnutls-available-p))))
  ;;     (proto (if no-ssl "http" "https")))

  ;; Comment/uncomment these two lines to enable/disable MELPA and MELPA
  ;; Stable as desired

  ;;(add-to-list 'package-archives (cons "melpa" (concat proto "://melpa.org/packages/")) t)
  ;;(add-to-list 'package-archives (cons "melpa-stable" (concatproto "://stable.melpa.org/packages/")) t)

spell check

  (defconst *spell-check-support-enabled* nil) ;;

generics

  
  (global-font-lock-mode t) ; We need syntax coloring
  (tool-bar-mode -1)
  (tooltip-mode -1)         ; Disable tooltips
  (menu-bar-mode -1)
                                          ; (menu-bar-mode 1)
                                          ; bring it back.
                                          ; May require a window move depending on the Gui kit and window manager.
                                          ; There are things to discover in it
                                          ; C-Mouse2 will bring it as contextual popup when menu-bar is of

  (scroll-bar-mode -1) ;; no scrollbar, more space;;
  (setq inhibit-startup-message t) ;; we know the startup screen
  (line-number-mode) ;; but the modeline may redefine that
  (column-number-mode)

  ;;(set-fringe-mode 20)       ; Give some breathing room
  ;; turn off the visible bell
  (setq visible-bell nil)

  (setq font-lock-maximum-size nil) ;; maximum colors (nil : obsolete and irrelevant)

  ;; all backup files goes in one directory
  (setq backup-directory-alist '((".*" . "~/.emacs.d/backup-files/")))
  (setq default-directory "/f/") ;; shorter than ~
  ;;(mouse-wheel-mode t) ;; mouse wheel scroll. Is already on
  ;; (setq mouse-wheel-scroll-amount '(3
  ;; ((shift) . 5)  ;; with shift : move sideways
  ;; ((control))))  ;; with control : zoom in and out
  ;;(setq  x-meta-keysym 'meta x-super-keysym 'meta) ;; unknown


  (fset #'yes-or-no-p #'y-or-n-p)     ; y/n instead of yes/no, yes please.
  ;; (setq mouse-drag-copy-region t) ;; don't

  ;; line-wrap
  (set-display-table-slot standard-display-table 'wrap ?\ )
  (toggle-truncate-lines)

  (setq show-paren-delay 0)  ; show matching pairs of parenthesis
  (show-paren-mode 1)

                                          ; chmod +x if it's a script #!/bin/bash
  (add-hook 'after-save-hook 'executable-make-buffer-file-executable-if-script-p)

                                          ; display images and compressed files
  (setq auto-image-file-mode t)
  (setq auto-compression-mode t)

  (and (bufferp "*scratch*") (kill-buffer "*scratch*"))   ;; no need


  (setq-default fill-column 70)  ;; 50 character is 1/4 of my screen

  ;; rest taken from doom.d


  ;; Get rid of "For information about GNU Emacs..." message at startup, unless
  ;; we're in a daemon session where it'll say "Starting Emacs daemon." instead,
  ;; which isn't so bad.
  (unless (daemonp)
    (advice-add #'display-startup-echo-area-message :override #'ignore))


  ;; Favor vertical splits over horizontal ones. Monitors are trending toward
  ;; wide, rather than tall.
  (setq split-width-threshold 160
        split-height-threshold nil)

                ;;; Minibuffer

  ;; Allow for minibuffer-ception. Sometimes we need another minibuffer command
  ;; while we're in the minibuffer.
  ;;(setq enable-recursive-minibuffers t)
  ;;(minibuffer-depth-indicate-mode 1)
  ;; not in helm anymore (but T.Volpato says otherwise)
  ;; https://github.com/emacs-helm/helm/issues/2159

  ;; Try to keep the cursor out of the read-only portions of the minibuffer.
  (setq minibuffer-prompt-properties
        '(read-only t intangible t cursor-intangible t face minibuffer-prompt))
  (add-hook 'minibuffer-setup-hook #'cursor-intangible-mode)


  ;; middle-click paste at point, not at click
  (setq mouse-yank-at-point t)

                                          ; Larger column width for function name in profiler reports
  ;;(after! profiler
  ;; (setf (caar profiler-report-cpu-line-format) 80
  ;;         (caar profiler-report-memory-line-format) 80))

  ;; Scrolling

  (setq hscroll-margin 2
        hscroll-step 1
        ;; Emacs spends too much effort recentering the screen if you scroll the
        ;; cursor more than N lines past window edges (where N is the settings of
        ;; `scroll-conservatively'). This is especially slow in larger files
        ;; during large-scale scrolling commands. If kept over 100, the window is
        ;; never automatically recentered.
        scroll-conservatively 101
        scroll-margin 0
        scroll-preserve-screen-position t
        ;; Reduce cursor lag by a tiny bit by not auto-adjusting `window-vscroll'
        ;; for tall lines.
        auto-window-vscroll nil
        ;; mouse
        ;;mouse-wheel-scroll-amount '(2 ((shift) . hscroll))
        ;;mouse-wheel-scroll-amount-horizontal 2)


        mouse-wheel-scroll-amount '(1 ((shift) . 1))
        mouse-wheel-progressive-speed nil ;; don't accelerate scrolling
        mouse-wheel-follow-mouse 't ;; scroll window under mouse
        scroll-step 1 ;; keyboard scroll one line at a time
        use-dialog-box nil) ;; Disable dialog boxes (none seen in lucid)

  (blink-cursor-mode 0)

  (set-window-margins nil 1)


  (save-place-mode 1) ;; save location inside files
  (setq
   save-place-file (locate-user-emacs-file "places" "~/.emacs.d/places")
                                          ; If emacs is slow to exit after enabling saveplace, you may be
                                          ; running afoul of save-place-forget-unreadable-files. On exit, it
                                          ; checks that every loaded file is readable before saving its buffer
                                          ; position - potentially very slow if you use NFS.
   save-place-forget-unreadable-files nil)
                                          ;will restores emacs exit to nearly instantaneous.)""""))

  (recentf-mode 1)
  (global-auto-revert-mode 1) ;; will do when there's no unsaved changes.
  (setq global-auto-revert-non-file-buffers t) ;; will update dired (without g update)

whitespaces

      ;; automatically clean up "bad" whitespace
    ;; (setq whitespace-action '(auto-cleanup))
    ;; (setq whitespace-action '(nil))

    ;; usefull for Python Pep but not 100% safe
    ;; (add-hook 'before-save-hook 'delete-trailing-whitespace)
    ;; (remove-hook 'before-save-hook 'delete-trailing-whitespace)
    (use-package whitespace)
    ;; only show bad whitespace
    (setq whitespace-style '(trailing space-before-tab indentation empty space-after-tab))

move lines

  
  (defun move-line-up ()
    "Move up the current line."
    (interactive)
    (transpose-lines 1)
    (forward-line -2)
    (indent-according-to-mode))

  (defun move-line-down ()
    "Move down the current line."
    (interactive)
    (forward-line 1)
    (transpose-lines 1)
    (forward-line -1)
    (indent-according-to-mode))

   ;;(define-key global-map (kbd "<M-down>") #'move-line-down)
   (global-set-key (kbd "<M-down>")  'move-line-down)
   (global-set-key (kbd "<M-up>")  'move-line-up)

  ;; (add-hook 'c-mode-hook 'line-move-keys)
  ;; (add-hook 'go-mode-hook 'line-move-keys)
  ;; (add-hook 'emacs-lisp-mode-hook 'line-move-keys)
  ;; (add-hook 'sh-mode-hook 'line-move-keys)
  ;; (add-hook 'html-mode-hook 'line-move-keys)
  ;; (add-hook 'python-mode-hook 'line-move-keys)
  ; html autoclose
  ;;(setq sgml-quick-keys 'close)

move region

https://www.emacswiki.org/emacs/MoveRegion

  (defun move-region (start end n)
  "Move the current region up or down by N lines."
  (interactive "r\np")
  (let ((line-text (delete-and-extract-region start end)))
    (forward-line n)
    (let ((start (point)))
      (insert line-text)
      (setq deactivate-mark nil)
      (set-mark start))))

(defun move-region-up (start end n)
  "Move the current line up by N lines."
  (interactive "r\np")
  (move-region start end (if (null n) -1 (- n))))

(defun move-region-down (start end n)
  "Move the current line down by N lines."
  (interactive "r\np")
  (move-region start end (if (null n) 1 n)))

(global-set-key (kbd "M-<up>") 'move-region-up)
(global-set-key (kbd "M-<down>") 'move-region-down)

move region

  (defun move-text-internal (arg)
   (cond
    ((and mark-active transient-mark-mode)
     (if (> (point) (mark))
            (exchange-point-and-mark))
     (let ((column (current-column))
              (text (delete-and-extract-region (point) (mark))))
       (forward-line arg)
       (move-to-column column t)
       (set-mark (point))
       (insert text)
       (exchange-point-and-mark)
       (setq deactivate-mark nil)))
    (t
     (beginning-of-line)
     (when (or (> arg 0) (not (bobp)))
       (forward-line)
       (when (or (< arg 0) (not (eobp)))
            (transpose-lines arg))
       (forward-line -1)))))

(defun move-text-down (arg)
   "Move region (transient-mark-mode active) or current line
  arg lines down."
   (interactive "*p")
   (move-text-internal arg))

(defun move-text-up (arg)
   "Move region (transient-mark-mode active) or current line
  arg lines up."
   (interactive "*p")
   (move-text-internal (- arg)))

(global-set-key [\M-\S-up] 'move-text-up)
(global-set-key [\M-\S-down] 'move-text-down)

Unfill paragraph

      ;;; Stefan Monnier <foo at acm.org>. It is the opposite of fill-paragraph
    (defun unfill-paragraph (&optional region)
      "Takes a multi-line paragraph and makes it into a single line of text."
      (interactive (progn (barf-if-buffer-read-only) '(t)))
      (let ((fill-column (point-max))
            ;; This would override `fill-column' if it's an integer.
            (emacs-lisp-docstring-fill-column t))
        (fill-paragraph nil region)))

    ;; Handy key definition
    (define-key global-map "\M-Q" 'unfill-paragraph)

anzu

       (use-package anzu) ;; highlight search results n/N
     (global-anzu-mode +1)

bar cursor

it's fine with the blue on grey one

  (use-package bar-cursor)
(bar-cursor-mode 1)

(set-cursor-color "green") (bar-cursor-mode 0) (blink-cursor-mode 1)

multiple cursor

Still can't get something as efficient as IntelliJ or Sublime.

  ;; (require 'multiple-cursors)
(global-set-key (kbd "C-S-c C-S-c") 'mc/edit-lines)

smart-mode-powerline

    (use-package smart-mode-line)
  (use-package smart-mode-line-powerline-theme)
  (setq sml/theme 'powerline)
  (sml/setup)
   '(sml/mode-width
   (if
       (eq
	(powerline-current-separator)
	(quote arrow))
       (quote right)
     (quote full)))
 '(sml/pos-id-separator
   (quote
    (""
     (:propertize " " face powerline-active1)
     (:eval
      (propertize " "
		  (quote display)
		  (funcall
		   (intern
		    (format "powerline-%s-%s"
			    (powerline-current-separator)
			    (car powerline-default-separator-dir)))
		   (quote powerline-active1)
		   (quote powerline-active2))))
     (:propertize " " face powerline-active2))))
 '(sml/pos-minor-modes-separator
   (quote
    (""
     (:propertize " " face powerline-active1)
     (:eval
      (propertize " "
		  (quote display)
		  (funcall
		   (intern
		    (format "powerline-%s-%s"
			    (powerline-current-separator)
			    (cdr powerline-default-separator-dir)))
		   (quote powerline-active1)
		   (quote sml/global))))
     (:propertize " " face sml/global))))
 '(sml/pre-id-separator
   (quote
    (""
     (:propertize " " face sml/global)
     (:eval
      (propertize " "
		  (quote display)
		  (funcall
		   (intern
		    (format "powerline-%s-%s"
			    (powerline-current-separator)
			    (car powerline-default-separator-dir)))
		   (quote sml/global)
		   (quote powerline-active1))))
     (:propertize " " face powerline-active1))))
 '(sml/pre-minor-modes-separator
   (quote
    (""
     (:propertize " " face powerline-active2)
     (:eval
      (propertize " "
		  (quote display)
		  (funcall
		   (intern
		    (format "powerline-%s-%s"
			    (powerline-current-separator)
			    (cdr powerline-default-separator-dir)))
		   (quote powerline-active2)
		   (quote powerline-active1))))
     (:propertize " " face powerline-active1))))
 '(sml/pre-modes-separator (propertize " " (quote face) (quote sml/modes)))

htop : fix it on emacs

https://emacs.stackexchange.com/a/28088/13477

  (defun htop ()
  (interactive)
  (if (get-buffer "*htop*")
      (switch-to-buffer "*htop*")
    (term "htop")))
    ;;(comint-sen d-string "*htop*" "htop\n")))

ispell

   (let ((langs '("english" "francais")))
      (setq lang-ring (make-ring (length langs)))
      (dolist (elem langs) (ring-insert lang-ring elem)))

 (defun cycle-ispell-languages ()
      (interactive)
      (let ((lang (ring-ref lang-ring -1)))
        (ring-insert lang-ring lang)
        (ispell-change-dictionary lang)))

(defun fd-switch-dictionary() (interactive) (let* ((dic ispell-current-dictionary) (change (if (string= dic "deutsch8") "english" "frencxh"))) (ispell-change-dictionary change) (message "Dictionary switched from %s to %s" dic change) ))

bash

    (setq shell-file-name "bash")
  (setq shell-command-switch "-c") ;; non interactive or else

with -i (interactive) will tell : "bash: cannot set terminal process group (-1): Inappropriate ioctl for device"

is this needed anymore ?

(setenv "BASH_ENV" "~/.bashrc")

also see

shopt -s expand_aliases

path from bash

(setenv "PATH" "~/bin:/usr/local/bin:/usr/bin:/bin:/usr/local/games:/usr/games:/usr/local/plan9/bin:.:~/sh/:/etc/init.d/::~/.nvm/versions/node/v8.11.1/bin/:/usr/local/inferno/Linux/386/bin/:/usr/local/pgsql/bin/:/usr/local/cuda-7.5/bin/:/usr/local/go/bin:~/.cargo/bin:~/.node_modules/.bin:~/.deno/bin:/usr/local/go/bin:~/go/bin:/usr/local/plan9/bin:/usr/local/plan9/bin/venti:~/bin:~/.cargo/bin:~/sh:~/go/bin")
(setenv "PATH" "/f/opt/nim")

(getenv "PATH") (exec-path-from-shell-initialize) (shell-command "echo $PATH") https://www.emacswiki.org/emacs/ExecPath

needs at least /usr/bin to be able to run /etc/profile

    (defun set-exec-path-from-shell-PATH ()
    "Set up Emacs' `exec-path' and PATH environment variable to match
  that used by the user's shell.

  This is particularly useful under Mac OS X and macOS, where GUI
  apps are not started from a shell."
    (interactive)
    (let ((path-from-shell
	   (replace-regexp-in-string
	    "[ \t\n]*$" ""
	    (shell-command-to-string
	     "$SHELL --login -c 'echo $PATH'"))))
      (setenv "PATH" path-from-shell)
      (setq exec-path (split-string path-from-shell path-separator))))

  (set-exec-path-from-shell-PATH)

which python

eshell switch

  (defun command-to-eshell (command)
   (with-current-buffer "*eshell*"
     (eshell-return-to-prompt)
     (eshell-bol)
     ;(kill-line)
     (insert command)
     (eshell-send-input)))
    (defun switch-to-eshell ()
    " switch to eshell, start if it has not,
      and to the directory of the buffer this is called from,
      or get back to the previous buffer if we are already on *eshell*
    "
    (interactive)

    (if (string= (buffer-name) eshell-buffer-name);;*eshell*
        (previous-buffer)
      ;;else
      (let((current-dir default-directory ));;  (file-name-directory (or (buffer-file-name) "nil"))))
        (message ">%s" default-directory)
        (eshell)
        (message ")%s" default-directory)
        (let ((eshell-current-dir
               (dired-replace-in-string (getenv "HOME") "~" (concat (eshell/pwd) "/"))
               ))
          (message "%s %s" current-dir eshell-current-dir)
          (when ;;(or (eq current-dir nil)
              (not(string-equal eshell-current-dir current-dir))
            (command-to-eshell current-dir)
            )
          (end-of-buffer)
          (recenter nil t)
          ))))

;(defun switch-to-buffer-list () ; (interactive) ; (list-buffers) ;(other-window 1) ;) (command-to-eshell "ls")

insert-character-pair

Something that certainly exists somewhere else, but the elisp universe is too vast.

    (add-to-list 'insert-pair-alist '(171 187)) ;; « »
  (add-to-list 'insert-pair-alist '(8220 8221)) ;; “ ”
  (setq insert-non-breakable-space-with-pair-list '(171 8220)) ;; « ... »

  (defun insert-character-pair (&optional arg)

   "Interactively calls insert-pair, with the next
   (not last) typed character.
   If `parens-require-spaces' is non-nil, this
   command also inserts a space before and after,
   depending on the surrounding characters.
   Look into `insert-non-breakable-space-with-pair-list'
   for  the opening character of a pair wich needs the
   insertion of a non-breakable space in-between.
   Typically « quotes ».
   If region is active, insert enclosing characters
   at region boundaries.

  [2022-01-02 Sun] did something changed with the
   point position after insert-pair ?  "

    (interactive "c")
    (let ((pair (assq arg insert-pair-alist))
          (open arg)
          (close arg)
          (space-required parens-require-spaces)
          (n (prefix-numeric-value current-prefix-arg))
          )
      (when pair
        (setq open (car pair)
              close (car(cdr pair))))

      (save-mark-and-excursion
        (if (memq open insert-non-breakable-space-with-pair-list)
            (if (and transient-mark-mode mark-active)
                (save-mark-and-excursion
                  (when (> (point) (mark)) (exchange-point-and-mark))
                  (insert-pair 1 open close)
                  (save-mark-and-excursion
                    (goto-char (mark))
                    (insert 160)) ;; insert nbsp
                  (goto-char (point))
                  (insert 160))
              (progn
                (save-excursion (insert-pair 1 open close))
                (setq parens-require-spaces nil)
                (insert-pair 1 160 160)
                (setq parens-require-spaces space-required)))
          (progn
            (when (and transient-mark-mode mark-active (> (point) (mark))) (exchange-point-and-mark))

            (save-mark-and-excursion
              (dotimes (i n) (insert-pair 1 open close))))
          ))))

  (global-set-key (kbd "C-=") 'insert-character-pair)

Example:

C-u 2 C-= [

surrounds the next word or region with double brackets

org

generic

    ;;  (use-package org-contrib) ;;
  (require 'org-tempo) ;; <s <q
  (require 'org-mouse) ;; clickable entries & checkboxes
  (require 'org-clock)
  (use-package org-ref)
  ;;(require 'org-man)
  (setq org-use-speed-commands t)
  (setq org-fontify-done-headline nil) ;; don't want a single face for DONE headline

org-man

  (org-link-set-parameters "man"
			 :follow #'org-man-open
			 :export #'org-man-export
			 :store #'org-man-store-link)

(defcustom org-man-command 'man
  "The Emacs command to be used to display a man page."
  :group 'org-link
  :type '(choice (const man) (const woman)))

(defun org-man-open (path)
  "Visit the manpage on PATH.
PATH should be a topic that can be thrown at the man command."
  (funcall org-man-command path))

(defun org-man-store-link ()
  "Store a link to a README file."
  (when (memq major-mode '(Man-mode woman-mode))
    ;; This is a man page, we do make this link
    (let* ((page (org-man-get-page-name))
           (link (concat "man:" page))
           (description (format "Manpage for %s" page)))
      (org-store-link-props
       :type "man"
       :link link
       :description description))))

(defun org-man-get-page-name ()
  "Extract the page name from the buffer name."
  ;; This works for both `Man-mode' and `woman-mode'.
  (if (string-match " \\(\\S-+\\)\\*" (buffer-name))
      (match-string 1 (buffer-name))
    (error "Cannot create link to this man page")))

(defun org-man-export (link description format)
  "Export a man page link from Org files."
  (let ((path (format "http://man.he.net/?topic=%s&section=all" link))
	(desc (or description link)))
    (cond
     ((eq format 'html) (format "<a target=\"_blank\" href=\"%s\">%s</a>" path desc))
     ((eq format 'latex) (format "\\href{%s}{%s}" path desc))
     ((eq format 'texinfo) (format "@uref{%s,%s}" path desc))
     ((eq format 'ascii) (format "%s (%s)" desc path))
     (t path))))

crypt

   ;; (require 'org-crypt)
  (org-crypt-use-before-save-magic)
  (setq org-tags-exclude-from-inheritance (quote ("crypt")))

  (setq org-crypt-key nil)
    ;; GPG key to use for encryption
    ;; Either the Key ID or set to nil to use symmetric encryption.

  ;;(setq auto-save-default nil)
    ;; Auto-saving does not cooperate with org-crypt.el: so you need
    ;; to turn it off if you plan to use org-crypt.el quite often.
    ;; Otherwise, you'll get an (annoying) message each time you
    ;; start Org.

    ;; To turn it off only locally, you can insert this:
    ;;
    ;; # -*- buffer-auto-save-file-name: nil; -*-

line numbering on org code blocks

By john kitchin https://kitchingroup.cheme.cmu.edu/blog/2015/10/13/Line-numbers-in-org-mode-code-blocks/ He named it just number-line-src-block.

     ;; (require 's)
   ;; line numbers
   (defvar number-line-overlays '()
     "List of overlays for line numbers.")

   (make-variable-buffer-local 'number-line-overlays)

   (defun read-key-to-clear(arg) nil)


   (defun org-number-line-src-block ()
     (interactive)
     (save-excursion
       (let* ((src-block (org-element-context))
              (nlines (- (length
                          (s-split
                           "\n"
                           (org-element-property :value src-block)))
                         1)))
         (goto-char (org-element-property :begin src-block))
         (re-search-forward (regexp-quote (org-element-property :value src-block)))
         (goto-char (match-beginning 0))

         (cl-loop for i from 1 to nlines
                  do
                  (beginning-of-line)
                  (let (ov)
                    (setq ov (make-overlay (point) (point)))
                    (overlay-put ov 'before-string (format "%3s" (number-to-string i)))
                    (add-to-list 'number-line-overlays ov))
                  (next-line))))

     ;; now read a char to clear them
     (read-key-to-clear
      "Press a key to clear numbers.")
     (mapc 'delete-overlay number-line-overlays)
     (setq number-line-overlays '()))

   ;;(org-number-line-src-block)


   (defun org-mode-extra-bindings() )
   ;; C-c n was ... bound or not ?
   (global-set-key (kbd "C-c n") 'org-number-line-src-block)
;; (global-set-key (kbd "C-M-x") 'eval-defun)) ;;

   (add-hook

    'org-mode-hook
    'org-mode-extra-bindings)
   ;; (custom-set-faces
   ;;  '(org-block ((t (:extend t :background "#081020" :foreground "white"))))
   ;;  '(org-block-begin-line ((t (:extend nil :foreground "orange red" :underline t :slant italic :weight semi-bold :height 1.0))))
   ;;  '(org-block-end-line ((t (:foreground "orange red" :overline t :slant oblique :weight semi-bold :extend nil :height 0.8)))))
   ;; (electric-indent-mode nil)))

   ;; [2021-09-28 Tue 04:53] couldn't find an alternatived with that bug in
   ;; 28.0.5.1 (or is it in doom-themes ?)
   ;;  (add-hook 'org-mode
   ;; 		(custom-set-faces
   ;; '(org-block ((t (:extend t :background "#080919" :foreground "white"))))
   ;; '(org-block-begin-line ((t (:foreground "orange red" :underline t :slant italic :weight semi-bold :extend nil :height 1.0))))
   ;; '(org-block-end-line ((t (:foreground "#0C1021" :overline "orange red" :slant oblique :weight semi-bold :extend nil :height 0.8))))
   ;; )) ;; doesn't work either

   (defun read-key-to-clear(arg)
     " defined after the 1st evaluation of number-line-src-line
          since it's asking for a key press we skip when emacs init

        "
     (read-key "Press a key to clear numbers."))

org-(de)-tangle-block

Is the counting of blocks correct ? Shouldn't they be relative to the number of blocks in the file rather than the number of detangled ones ?

There are such packages for automatic "detanglement" with a link comment: Files gets modified, and block gets accordingly updated.

     (defun org-babel-tangle-block()
         (interactive)
         (let ((current-prefix-arg '(4)))
                (call-interactively 'org-babel-tangle)
   ))

  (defun org-babel-detangle-block ()
        (interactive)
        (save-excursion
          (let ((source-code-file (cdr (assoc :tangle (nth 2 (org-babel-get-src-block-info))))))
                (when source-code-file
                  (org-babel-update-block-body
                   (with-temp-buffer
                         (insert-file-contents source-code-file)
                         (buffer-string)))))))

  (define-key org-mode-map (kbd "C-c b") 'org-babel-tangle-block)
  (define-key org-mode-map (kbd "C-c u b") 'org-babel-detangle-block)

org superstar custom bullets

    (use-package org-superstar)
  (setq org-superstar-headline-bullets-list
        '(  ;; Original ones nicked from org-bullets
          ?▪
          ?•
          ))

  (add-hook 'org-mode-hook
            (lambda()
              org-superstar-mode))

(setq org-superstar-headline-bullets-list '( ;; Original ones nicked from org-bullets ?🞛 ?◉ ?▷ ?✸))

(setq org-superstar-headline-bullets-list '(?◼ ?● ?◆ ?★ ?▶ ?◉ ?✿ ?◇ ?✚ ?✜ ?♦ ?☢)) ;; ♥ ● ✚ ✜ ☯ ◆ ♠ ♣ ♦ ☢ ❀ ◆ ◖ ▶ ;;; Small ;; ► • ★ ▸ see : org-superstar

org-json

     ;; answer given by John Kitchin on stackx
   (require 'json)
   (defun org-export-json-buffer ()
     (interactive)
     (let* ((tree (org-element-parse-buffer 'object nil)))
       (org-element-map tree (append org-element-all-elements
                                     org-element-all-objects '(plain-text))
         (lambda (x)
           (if (org-element-property :parent x)
               (org-element-put-property x :parent "none"))
           (if (org-element-property :structure x)
               (org-element-put-property x :structure "none")))
         )
       (with-current-buffer (get-buffer-create "*ox-json*")
         (erase-buffer)
         (insert (json-encode tree))
         (json-pretty-print-buffer))
       (switch-to-buffer (get-buffer-create "*ox-json*"))))

   (defun org-to-json (query)
     "Export headings that match QUERY to json."
     (org-map-entries
      (lambda ()
        (org-copy-subtree)
        (with-current-buffer (get-buffer-create "-t-")
          (yank)))
      query)
     (with-current-buffer "-t-" (org-export-json-buffer))
     (kill-buffer "-t-"))

   (defun org-export-published-to-json ()
     (org-map-entries
      (lambda ()
        (org-copy-subtree)
        (with-current-buffer (get-buffer-create "-t-")
          (yank)))
      "TODO=\"PUBLISHED\"")
     (with-current-buffer "-t-" (org-export-json-buffer))
     (kill-buffer "-t-"))

exemple : (org-to-json "TODO=\"DONE\"") ; filter out headings marked DONE (org-to-json "important") ; filter out headings tagged important

  
   (require 'json)
   (defun org-export-json-buffer ()
     (interactive)
     (let* ((tree (org-element-parse-buffer 'object nil)))
       (org-element-map tree (append org-element-all-elements
                                     org-element-all-objects '(plain-text))
         (lambda (x)
           (message "> %s" (type-of (org-element-class x)))
           (if (org-element-property :parent x)
               (org-element-put-property x :parent nil)) ;; or infinite recursion
           (if (org-element-property :structure x)
               (org-element-put-property x :structure nil)) ;; or Bad JSON key object
           )
         ;;(org-element-extract-element(:begin))
         )
       (with-current-buffer (get-buffer-create "*ox-json*")
         (erase-buffer)
         (insert (json-encode tree))
         (json-pretty-print-buffer))
       (switch-to-buffer (get-buffer-create "*ox-json*"))))

   (defun org-to-json (query)
     "Export headings that match QUERY to json."
     (org-map-entries
      (lambda ()
        (org-copy-subtree)
        (with-current-buffer (get-buffer-create "-t-")
          (yank)))
      query)
     (with-current-buffer "-t-" (org-export-json-buffer))
     (kill-buffer "-t-"))


   (defun org-json ()
     (interactive)
     (org-to-json "TODO=\"READY\"")
     )
  
(defun json-from-org(datum)
  (interactive)
  (let* ((tree (org-element-copy datum)))
    (org-element-map tree (append org-element-all-elements
                                  org-element-all-objects '(plain-text))
      (lambda (x)
        (if (org-element-property :parent x)
            (org-element-put-property x :parent "none"))
        (if (org-element-property :structure x)
            (org-element-put-property x :structure "none"))))
    (json-encode tree)))

apply function to all section

(typically remove the properties inserted by pandoc)

    (defun org-apply-to-all-subsection (f &rest args)
    (org-show-all)
    (while (org-forward-element)
      (funcall f args)))

hideshow mode

hs-minor-mode C-c @ C-c: fold code default keybinding C-c @ C-M-h to trigger the folding (hs-hide-all)

    ;;  hideshow-org.el provides an org-mode like interface to the
  ;; hideshow.el file. ;; En clair, on plie et déplie avec TAB aux endroits
  ;; adéquats, et S-TAB, partout. (add-to-list 'load-path ;;"~/srces/hideshow-org")
  (use-package 'hideshow-org)
  ;;  (require 'hideshow-org)
  ; Keymaps (global key)
  (global-set-key "\C-ch" 'hs-org/minor-mode)
  ; [2013-04-24 mer. 08:17]
  ; Je n'aurai qu'à l'enlever si par improbable, ça me gênait.
  ; Je l'arrime à hs, pas à C, pour faire une cascade ordonnée.
  (add-hook 'hs-minor-mode-hook '(lambda ()
		   (hs-org/minor-mode)))

  (add-hook 'elisp-mode-hook '(lambda ()
		   (hs-org/minor-mode)))

  ; [2013-04-19 ven. 12:14]
  ;(add-hook 'C-mode-hook 'hs-minor-mode) ; already mentioinned in C mode

  ;(add-hook 'elisp-mode-hook 'hs-minor-mode)

eye-candy

keywords and tag faces

  (setq org-todo-keyword-faces
      '(("✓" . (:foreground "Green" :weight bold))
        ("NEXT" . (:foreground "IndianRed1" :weight bold))
        ("STARTED" . (:foreground "OrangeRed" :weight bold))
        ("WAITING" . (:foreground "coral" :weight bold))
        ("CANCELED" . (:foreground "LimeGreen" :weight bold))
        ("DELEGATED" . (:foreground "LimeGreen" :weight bold))
        ("SOMEDAY" . (:foreground "LimeGreen" :weight bold))
        ))
  (setq org-tag-faces
      '(
        ("TEST" . (:foreground "GoldenRod" :weight bold))
        ("RESEARCH" . (:foreground "GoldenRod" :weight bold))
	("noexport" . (:foreground "LimeGreen" :weight bold))
))

openwith

      ;;  (require 'openwith)
      (use-package openwith)
      (openwith-mode t)
      (setq openwith-associations '
	    (("\\.xlsx\\'" "libreoffice" (file))
	     ("\\.docx\\'" "libreoffice" (file))
	     ("\\.pdf\\'" "okular" (file))
	     ("\\.html\\'" "chromium" (file))
	     ("\\.1\\'" "man" (file))
	     ("\\.2\\'" "man" (file))
	     ("\\.odt\\'" "libreoffice" (file))
	     ("\\.ods\\'" "libreoffice" (file))
	     ("\\.pdf\\'" "okular" (file))
	     ;;("\\.svg\\'" "inkscape" (file))
	     ("\\.ogg\\'" "mpv" (file))
	     ("\\.ogv\\'" "mpv" (file))
	     ("\\.mp3\\'" "mpv" (file))))

      (setq openwith-associations '
	    (("\\.rtf\\'" "libreoffice" (file))))

mu-open external

https://emacs.stackexchange.com/questions/21796/dired-alternative-to-openwith-how-to-open-file-per-extension

  
      (defun mu-open-in-external-app ()
	"Open the file where point is or the marked files in Dired in external
      app. The app is chosen from your OS's preference."
	(interactive)
	(let* ((file-list
		(dired-get-marked-files)))
	  (mapc
	   (lambda (file-path)
	     (let ((process-connection-type nil))
	       (start-process "" nil "xdg-open" file-path))) file-list)))

      (define-key dired-mode-map (kbd "1") #'mu-open-in-external-app)

duplicate line

  (defun duplicate-line-or-region (&optional n)
  "Duplicate current line, or region if active.
With argument N, make N copies.
With negative N, comment out original line and use the absolute value."
  (interactive "*p")
  (let ((use-region (use-region-p)))
    (save-excursion
      (let ((text (if use-region        ;Get region if active, otherwise line
                      (buffer-substring (region-beginning) (region-end))
                    (prog1 (thing-at-point 'line)
                      (end-of-line)
                      (if (< 0 (forward-line 1)) ;Go to beginning of next line, or make a new one
                          (newline))))))
        (dotimes (i (abs (or n 1)))     ;Insert N times, or once if not specified
          (insert text))))
    (if use-region nil                  ;Only if we're working with a line (not a region)
      (let ((pos (- (point) (line-beginning-position)))) ;Save column
        (if (> 0 n)                             ;Comment out original with negative arg
            (comment-region (line-beginning-position) (line-end-position)))
        (forward-line 1)
        (forward-char pos)))))

(global-set-key [?\C-c ?d] 'duplicate-line-or-region)

which key

Keybinding Panel (which-key)

which-key is great for getting an overview of what keybindings are available based on the prefix keys you entered. Learned about this one from Spacemacs.

  (use-package which-key
  :init (which-key-mode)
  :diminish which-key-mode
  :config
  (setq which-key-idle-delay 0.3))

smartparen

auto insert parens pairs ()

   (use-package smartparens)

Tramp

  (use-package tramp)

programming

Important for preserving code structure,

  (setq org-src--preserve-indentation t)
(setq org-src--preserve-blank-line t)

may also need to untabify before export

highlight indentation

    (use-package highlight-indent-guides)

  (defun my-highlighter (level responsive display)
    ;; highlight normally, except that it will
    ;; not highlight the first two levels of indentation:
    (if (> 2 level)
        nil
      (highlight-indent-guides--highlighter-default level responsive display)))

  (setq highlight-indent-guides-highlighter-function 'my-highlighter)

ggtags

  (use-package ggtags)

nlinum-mode

  (use-package nlinum)

rust

  (use-package rustic
  :ensure
  :bind (:map rustic-mode-map
              ("M-j" . lsp-ui-imenu)
              ("M-?" . lsp-find-references)
              ("C-c C-c l" . flycheck-list-errors)
              ("C-c C-c a" . lsp-execute-code-action)
              ("C-c C-c r" . lsp-rename)
              ("C-c C-c q" . lsp-workspace-restart)
              ("C-c C-c Q" . lsp-workspace-shutdown)
              ("C-c C-c s" . lsp-rust-analyzer-status))
  :config
  ;; uncomment for less flashiness
  ;; (setq lsp-eldoc-hook nil)
  ;; (setq lsp-enable-symbol-highlighting nil)
  ;; (setq lsp-signature-auto-activate nil)

  ;; comment to disable rustfmt on save
  (setq rustic-format-on-save t)
  (add-hook 'rustic-mode-hook 'rk/rustic-mode-hook))

(defun rk/rustic-mode-hook ()
  ;; so that run C-c C-c C-r works without having to confirm
  (setq-local buffer-save-without-query t))

LSP

    (use-package lsp-mode
    :ensure t
    :defer t
    :commands lsp
    ;;    :init
    ;; (setq lsp-keep-workspace-alive nil
    ;;       lsp-signature-doc-lines 5
    ;;       lsp-idle-delay 0.5
    ;;       lsp-prefer-capf t
    ;;       lsp-client-packages nil)
    :custom
    ;; what to use when checking on-save. "check" is default, I prefer clippy
    ;;(lsp-rust-analyzer-cargo-watch-command "clippy")
    ;;(lsp-rust-analyzer-server-display-inlay-hints t)
    (lsp-eldoc-render-all t)
    (lsp-idle-delay 0.6)
    :config
    (add-hook 'lsp-mode-hook 'lsp-ui-mode))

  (use-package lsp-ui
    :ensure
    :commands lsp-ui-mode
    :custom
    (lsp-ui-peek-always-show t)
    (lsp-ui-sideline-show-hover t)
    (lsp-ui-doc-enable nil)
    ;; (define-key lsp-ui-mode-map [remap xref-find-definitions] #'lsp-ui-peek-find-definitions)
    ;; (define-key lsp-ui-mode-map [remap xref-find-references] #'lsp-ui-peek-find-references)
    )

("M-j" . lsp-ui-imenu) ("M-?" . lsp-find-references) ("C-c C-c l" . flycheck-list-errors) ("C-c C-c a" . lsp-execute-code-action) ("C-c C-c r" . lsp-rename) ("C-c C-c q" . lsp-workspace-restart) ("C-c C-c Q" . lsp-workspace-shutdown) ("C-c C-c s" . lsp-rust-analyzer-status))

(use-package lsp-mode :ensure t :defer t :hook (lsp-mode . (lambda ()

(let ((lsp-keymap-prefix "s-q"))))))

:bind (:map ("M-j" . lsp-ui-imenu) ("M-?" . lsp-find-references) ("C-c C-c l" . flycheck-list-errors) ("C-c C-c a" . lsp-execute-code-action) ("C-c C-c r" . lsp-rename) ("C-c C-c q" . lsp-workspace-restart) ("C-c C-c Q" . lsp-workspace-shutdown) ("C-c C-c s" . lsp-rust-analyzer-status))

lsp-ui is optional. It provides inline overlays over the symbol at point and enables code fixes at point. If you find it to flashy and prefer not activating it just remove :config (add-hook 'lsp-mode-hook 'lsp-ui-mode).

The config shown above already disables the documentation normally shown inline by lsp-ui. This is too much for my taste as it often covers up source code. If you want to also deactivate the documentation shown in the minibuffer you can add (setq lsp-eldoc-hook nil). To do less when your cursor moves consider (setq lsp-signature-auto-activate nil) and (setq lsp-enable-symbol-highlighting nil).

Code navigation Having setup lsp-mode, you can use M-. to jump to the definition of function, structs, packages etc. when your cursor is over a symbol. M-, to jump back. With M-? you can list all references of a symbol. A little demo:

With M-j you can open up an outline of the current module that allows you to quickly navigate between functions and other definitions.

Code actions Refactorings are possible using M-x lsp-rename and lsp-execute-code-action. Code actions are basically code transformation and fixes. For example the linter may find a way to express code more idiomatically:

Code completion and snippets

lsp-mode directly integrates with company-mode, a completion framework for emacs. It will display a list of possible symbols that could be inserted at the cursor. It is very helpful when working with unknown libraries (or the std lib) and reduces the need for looking up documentation. Rust’s type system is used as a source for the completions and thus what you can insert makes (mostly) sense.

By default the code completion popup will appear after company-idle-delay which is set to 0.5 seconds by default. You can modify that value or disable the auto popup completely by setting company-begin-commands to nil.

  (use-package company
  :ensure
  :custom
  (company-idle-delay 0.5) ;; how long to wait until popup
  ;; (company-begin-commands nil) ;; uncomment to disable popup
  :bind
  (:map company-active-map
	      ("C-n". company-select-next)
	      ("C-p". company-select-previous)
	      ("M-<". company-select-first)
	      ("M->". company-select-last)))

(use-package yasnippet :ensure :config (yas-reload-all) (add-hook 'prog-mode-hook 'yas-minor-mode) (add-hook 'text-mode-hook 'yas-minor-mode)) #+endsrc

  (use-package flycheck :ensure)

You can display a list of errors and warnings using M-x flycheck-list-errors or by pressing C-c C-c l.

Inline type hints

Rust-analyzer and lsp-mode are able to show inline type annotations. Normally, those would appear via eldoc when placing the cursor over the defined variable, with the annotations you will always see the inferred types. Use (setq lsp-rust-analyzer-server-display-inlay-hints t) to enable them. To actually insert an inferred type into the source code you can move your cursor over the defined variable and run M-x lsp-execute-code-action or C-c C-c a.

Note that they might not interact well with lsp-ui-sideline-mode. If you prefer the hints but want to disable sideline mode, you can add (lsp-ui-sideline-enable nil) to a rustic-mode-hook.

C/C++ mode

  					    ;(load-file "~/.emacs.d/lisp/hideshowvis.el")
    ;; C/C++ Config
    (semantic-mode 1)            ;; CEDET holdover
    (global-ede-mode 1)          ;; CEDET holdover
    (setq c-default-style "bsd") ;; BSD/Allman brackets
    (setq c-basic-offset 4)      ;; 4-space indent
    ;;  (add-hook 'c-mode-common-hook 'fci-mode)
    (add-hook 'c-mode-common-hook 'company-mode)
    (add-hook 'c-mode-common-hook 'flycheck-mode)
    (add-hook 'c-mode-common-hook 'flycheck-color-mode-line-mode)
    (add-hook 'c-mode-common-hook 'linum-mode)
    ;; (add-hook 'c-mode-common-hook 'hideshowvis-minor-mode)
    (add-hook 'c-mode-common-hook 'hideshowvis-enable)
    (add-hook 'c-mode-common-hook 'hs-minor-mode)

CEDET is the Collection of Emacs Development Environment Tools http://cedet.sourceforge.net

  
    ;; (Conditional) C/C++ Keybinds
    (add-hook 'c-mode-common-hook
	      (lambda () (local-set-key (kbd "<C-tab>") 'company-complete)))
    (add-hook 'c-mode-common-hook
			  (lambda () (local-set-key (kbd "C-c j") 'find-tag)))

racket

ob racket :

  (load-file "~/.emacs.d/lisp/ob-racket.el")

slime

    ;;(require 'slime)
  ;;(add-to-list 'load-path "/.emacs.d/lisp/slime/")
  (load (expand-file-name
         "~/quicklisp/slime-helper.el"))
  (setq inferior-lisp-program "/usr/bin/sbcl")
  (require 'slime)
  (slime-setup '(slime-fancy slime-tramp slime-asdf))
  ;;(slime-require :swank-listener-hooks)
  ;;(slime-require :swank-listener-hooks)

  ;;(global-set-key (kbd "C-c s s") 'sly-describe-symbol)
  ;;(global-set-key (kbd "C-c s f") 'sly-describe-function)
  ;;(global-set-key (kbd "C-x C-q") 'slime-close-all-parens-in-sexp) ; Was save-buffers-kill-emacs

Scss

(add-to-list 'load-path (expand-file-name "~/.emacs.d/elpa/scss-mode-20180123.1708")) (autoload 'scss-mode "scss-mode") (add-to-list 'auto-mode-alist '("\\.scss\\'" . scss-mode))

go golang

see https://legends2k.github.io/note/go_setup/ and http://tleyden.github.io/blog/2014/05/22/configure-emacs-as-a-go-editor-from-scratch/

    (use-package go-mode)

;;(use-package ob-go)

  
(add-to-list 'load-path "~/go/src/github.com/dougm/goflymake")
(require 'go-flymake)
(use-package go-errcheck)

(setq gofmt-command "goimports")

(add-hook 'go-mode-hook (lambda ()
        (local-set-key (kbd "C-c C-r") 'go-remove-unused-imports)
        (local-set-key (kbd "C-c C-g") 'godoc-at-point)
))

(use-package go-eldoc) ;; Don't need to require, if you install by package.el
(add-hook 'go-mode-hook 'go-eldoc-setup)
; shows type information for variable, functions and current argument position of function.

(use-package go-guru)
(add-hook 'go-mode-hook #'go-guru-hl-identifier-mode)

Company-go is an alternative emacs plugin for autocompletion. It uses company-mode. Completion will start automatically whenever the current symbol is preceded by a ., or after you type company-minimum-prefix-length letters.

  (setq company-tooltip-limit 20)                      ; bigger popup window
(setq company-idle-delay .3)                         ; decrease delay before autocompletion popup shows
(setq company-echo-delay 0)                          ; remove annoying blinking
(setq company-begin-commands '(self-insert-command)) ; start autocompletion only after typing

Only use company-mode with company-go in go-mode By default company-mode loads every backend it has. If you want to only have company-mode enabled in go-mode add the following to your emacs-config:

  (add-hook 'go-mode-hook (lambda ()
                          (set (make-local-variable 'company-backends) '(company-go))
                          (company-mode)
			  (local-set-key (kbd "M-.") 'godef-jump)
			  (go-eldoc-setup)

			  (if (not (string-match "go" compile-command))
 			      (set (make-local-variable 'compile-command)
			  "go build -v && go test -v && go vet"))
                          ; call Gofmt before saving
                          (add-hook 'before-save-hook 'gofmt-before-save)
			  ; (remove-hook 'before-save-hook 'gofmt-before-save)
			  ; can get buggy here
			  )
)

(eval-after-load 'go-mode
  '(substitute-key-definition 'go-import-add 'helm-go-package go-mode-map))

Periodically go get -u all to keep the downloaded tools updated.

python

  (use-package python)
   ;;; (add-hook 'python-mode-common-hook 'flycheck-mode)
 ;;(require 'flymake-python-pyflakes)
 ;;(add-hook 'python-mode-hook 'flymake-python-pyflakes-load)
 ;; (global-flycheck-mode 1)
 (with-eval-after-load 'flycheck
   (add-hook 'flycheck-mode-hook #'flycheck-pycheckers-setup))
 (add-hook 'before-save-hook 'delete-trailing-whitespace)

lua

  (use-package lua-mode)

mongo

  (use-package ob-mongo)
(add-to-list 'org-babel-load-languages '(mongo . t))
(org-babel-do-load-languages 'org-babel-load-languages org-babel-load-languages)

deno

  (use-package ob-deno)
(add-to-list 'org-babel-load-languages '(deno . t))
(org-babel-do-load-languages 'org-babel-load-languages org-babel-load-languages)
;; optional (required the typescript.el)
(add-to-list 'org-src-lang-modes '("deno" . typescript))
(add-to-list 'org-src-lang-modes '("ts" . typescript))

[2021-10-21 Thu 12:36] problem with result output

    return {foo, baz};
  console.log("hello world")
    const response = await fetch("https://httpbin.org/get?hello=world");
  const json = await response.json();

  console.log(json.args);
  import { DOMParser, Element } from "https://deno.land/x/deno_dom/deno-dom-wasm.ts";
const doc = new DOMParser().parseFromString(`
  <h1>Hello World!</h1>
  <p>Hello from <a href="https://deno.land/">Deno!</a></p>
`, "text/html")!;

const p = doc.querySelector("p")!;

console.log(p.textContent); // "Hello from Deno!"
console.log(p.childNodes[1].textContent); // "Deno!"

p.innerHTML = "DOM in <b>Deno</b> is pretty cool";
console.log(p.children[0].outerHTML); // "<b>Deno</b>"

nim (nimrod) nim-lang

Great langages, still immature but promising. The documentation and the source code are all you need to start rolling.

    (defface blackboard '((t :background "#0C1021")) "blackboard")

  (defun nim-hooks ()
    (lsp)
    (nlinum-mode)
    (face-remap-add-relative 'default 'blackboard)
    (highlight-indent-guides-mode))

   (use-package nim-mode
     :ensure t
     :bind (:map nim-mode-map
                 ("M-j" . lsp-ui-imenu)
                 ("C-x E" . next-error))
     :config (add-hook 'nim-mode-hook 'nim-hooks))

     (use-package ob-nim)

lsp-ui-mode-map

    (define-key lsp-ui-mode-map [remap xref-find-definitions] #'lsp-ui-peek-find-definitions)
  (define-key lsp-ui-mode-map [remap xref-find-references] #'lsp-ui-peek-find-references)

tcl

  (use-package tcl

org-babel

    (use-package ob-rust)
  (use-package typescript-mode)
  (use-package ob-graphql)
  (use-package ob-go)
  (org-babel-do-load-languages
   'org-babel-load-languages
   '(
     (shell . t)
     (C . t)
     (lisp . t)
     (shell . t)
     (go . t)
    ;; (php . t)
     (rust . t)
     (python . t)
     (ditaa . t)
     (calc . t)
     ;(deno . t)
     (js . t)
     (graphql . t)
     ))

  (add-to-list 'org-src-lang-modes '("gql" . graphql))
  (add-to-list 'org-src-lang-modes '("py" . python))

confirmation

bypass confirmations

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

  (defun do-org-confirm-babel-evaluations (lang body)
    (not
     (or
      (string= lang "nim")
      (string= lang "elisp"))))
  (setq org-confirm-babel-evaluate 'do-org-confirm-babel-evaluations)

(defun do-org-confirm-babel-evaluations (lang body) (not (or (string= lang "python") (string= lang "calc")))) (setq org-confirm-babel-evaluate 'do-org-confirm-babel-evaluations)

dashboard

to start it :

(get-buffer-create "*dashboard*")
(dashboard-refresh-buffer)
  
  (use-package dashboard
    :ensure t
    :config

    (dashboard-setup-startup-hook)

    (setq dashboard-startup-banner "~/.emacs.d/emacs.svg")
    (setq initial-buffer-choice (lambda () (get-buffer "*dashboard*")))
    ;(require 'dashboard-hackernews)

    (setq dashboard-items '((recents  . 35)
			    (bookmarks . 5)
			    (agenda . 5)
			    ;;(projects . 5) ;; req. projectile
		  ;(hackernews . 20)
		  ;(registers . 5)
			    ))

    (setq dashboard-show-shortcuts t)
    (setq dashboard-set-heading-icons t)
    (setq dashboard-set-file-icons t)
    (setq dashboard-set-navigator t)
  ;(setq dashboard-set-init-info t)
  ;(setq dashboard-init-info (fortune))
  ;(setq dashboard-init-info (fortune-message))
  ;(setq dashboard-init-info nil)

    (setq dashboard-set-footer nil)
 ;(switch-to-buffer "*dashboard*")
 ;(dashboard-mode)
 ;(setq dashboard-banner-logo-title (fortune-message))
 ;(dashboard-modify-heading-icons '((recents . "file-text") (bookmarks . "book")))
  )
  (defun dashboard-insert-custom () (insert "Custom text"))
(add-to-list 'dashboard-item-generators  '(custom . dashboard-insert-custom))
(add-to-list 'dashboard-items '(custom) t)

add your own custom widget is pretty easy, define your widget’s callback function and add it to `dashboard-items` as such:

(defun dashboard-insert-custom () (insert "Custom text")) (add-to-list 'dashboard-item-generators '(custom . dashboard-insert-custom)) (add-to-list 'dashboard-items '(custom) t)

;To modify heading icons with another icon from all-the-icons octicons: (dashboard-modify-heading-icons '((recents . "file-text") (bookmarks . "book")))

;; Format: "(icon title help action face prefix suffix)" (setq dashboard-navigator-buttons `(;; line1 ((,(all-the-icons-octicon "mark-github" :height 1.1 :v-adjust 0.0) "Homepage" "Browse homepage" (lambda (&rest _) (browse-url "homepage"))) ("★" "Star" "Show stars" (lambda (&rest _) (show-stars)) warning) ("?" "" "?/h" #'show-help nil "<" ">")) ;; line 2 ((,(all-the-icons-faicon "linkedin" :height 1.1 :v-adjust 0.0) "Linkedin" "" (lambda (&rest _) (browse-url "homepage"))) ("⚑" nil "Show flags" (lambda (&rest _) (message "flag")) error))))

ibuffer

nicer than (buffer-menu)

    (defalias 'list-buffers 'ibuffer) ; make ibuffer default-directory

  (setq ibuffer-saved-filter-groups
        '(("home"
           ("Org" (or (mode . org-mode)))
           ("Nims" (or (mode . nim-mode)))
           ("Dirs" (or (mode . dired-mode)
                       (mode . dired-sidebar-mode)
                       ))
           ("Custom" (or (mode . Custom-mode)))
           ("Magit" (name . "magit"))
           ("Help" (or
                       (mode . help-mode)
                       (mode . "*Apropos\*")
                       (name . "\*info\*")))
           ("elisp" (or (mode . emacs-lisp-mode)))
           ("Helms" (mode . helm-major-mode))
           ("Html" (mode . mhtml-mode))
           ("Babel temp" (filename . "/tmp/babel-"))
           ("Images" (mode . image-mode))
           ("sys" (name . "\*"))
           )))

emacs server

    (server-start)

env

  (setenv "PLAN9" "/usr/local/plan9")
(setq PLAN9  "/usr/local/plan9")
  echo $PLAN9

org#Link abbreviations

    (setq org-link-abbrev-alist
     '(("cnrtl"  . "http://www.cnrtl.fr/definition/%s")
       ("yt"  . "https://yewtu.be/%s")
       ("github"  . "https://github.com/%s")
       ("wiki-fr"  . "https://fr.wikipedia.org/wiki/%s")
       ("wiki-en"  . "https://en.wikipedia.org/wiki/%s")
      )
  )

("sci-hub" . "https://sci-hub.se/%s#") ("rfc" . "~/doc/rfc/Org/rfc%s.org") ("RFC" . "~/doc/rfc/Org/rfc%s.org")

shell

How to display completion-at-point into a popup ?

(describe-package 'native-complete)

    (use-package native-complete)
  (with-eval-after-load 'shell
      (native-complete-setup-bash))

readline completion

(describe-package 'readline-complete) (add-hook 'completion-at-point-functions 'pcomplete-completions-at-point) (add-hook 'completion-in-region-functions 'popup-complete-in-region)

    (setq explicit-shell-file-name "bash")
  (setq explicit-bash-args '("-c" "export EMACS=; stty echo; bash"))
  (setq comint-process-echoes t)
    (use-package readline-complete)
    (use-package auto-complete)
  (add-to-list 'ac-modes 'shell-mode)
    (add-hook 'shell-mode-hook 'ac-rlc-setup-sources)
    (push 'company-readline company-backends)
    (add-hook 'rlc-no-readline-hook (lambda () (company-mode -1)))

eshell

(eshell-smart-initialize) (setq eshell-path-env (concat "Users/bat.nodebrew/current/bin" ":" eshell-path-env))

  
     ;(getenv "SHELL")
     ;(getenv "PATH")
     ;(setenv "SHELL" "/bin/zsh/")

     ;;(setenv "PATH" (concat (getenv "PATH") ":/f/sh:/f/go/bin:."))
     ;;(setenv "PATH" "/usr/local/bin:/usr/bin:/bin:/f/sh:/f/go/bin:.")

see in 3.111

https://github.com/emacs-helm/helm/wiki/Eshell Thierry Volpiatto edited this page on 29 Feb 2016· 3 revisions

Eshell is a shell-like command interpreter implemented in Emacs Lisp. It invokes no external processes except for those requested by the user.

shortcuts

ff and vi for find file it also works in eshell

  (defalias 'ff 'find-file)
(defalias 'vi 'find-file)
(defalias 'd 'dired)
(defsubst eshell/ll (&rest args)
  "An alias version of `eshell/ls -l'."
(eshell/ls "-l" args))

(eshell/alias "lx" "ls -l $*") exits only once eshell is started see file://~/.emacs.d/eshell/alias

  (defvar eshell/trash "~/.local/share/Trash/files/")

(defsubst eshell/rm (&rest args)
  "move into $trash"
  (eshell/mv args eshell/trash))

Completion & history

  • pcomplete is already enabled in Eshell, we add Helm support.
  • To search Eshell history with Helm, use the helm-eshell-history command.
     (defun eshell-hooks ()
     (eshell-cmpl-initialize)
     (define-key eshell-mode-map [remap eshell-pcomplete] 'helm-esh-pcomplete)
     (define-key eshell-mode-map (kbd "M-p") 'helm-eshell-history))

   (add-hook 'eshell-mode-hook 'eshell-hooks)

Now, the TAB key should provide Helm support for pcomplete.

Fix SUDO completion

When you use sudo in Eshell, there is no completion on the command you enter after sudo. This is true regardless of whether Helm is enabled.

To fix this problem, you can define a pcomplete/sudo function and add it to your configuration.

  
 (defun pcomplete/sudo ()
   (let ((prec (pcomplete-arg 'last -1)))
     (cond ((string= "sudo" prec)
            (while (pcomplete-here*
                    (funcall pcomplete-command-completion-function)
                    (pcomplete-arg 'last) t))))))

However, the above example of pcomplete/sudo will not work in some cases without modifications to some Emacs functions due to unresolved Emacs bugs. To fix this, you can use my pcomplete-extension, which will provide more Helm completions like apt-get and find.

Custom pcomplete functions

You can enhance Emacs pcomplete by writing your own pcomplete functions. See my pcomplete-extension for enhanced completions.

Here an example with find command:

  
 (defun pcomplete/find ()
   (let ((prec (pcomplete-arg 'last -1)))
     (cond ((and (pcomplete-match "^-" 'last)
                 (string= "find" prec))
            (pcomplete-opt "HLPDO"))
           ((pcomplete-match "^-" 'last)
            (while (pcomplete-here
                    '("-amin" "-anewer" "-atime" "-cmin" "-cnewer" "-context"
		      "-ctime" "-daystart" "-delete" "-depth" "-empty" "-exec"
		      "-execdir" "-executable" "-false" "-fls" "-follow" "-fprint"
		      "-fprint0" "-fprintf" "-fstype" "-gid" "-group"
		      "-help" "-ignore_readdir_race" "-ilname" "-iname"
		      "-inum" "-ipath" "-iregex" "-iwholename"
		      "-links" "-lname" "-ls" "-maxdepth"
		      "-mindepth" "-mmin" "-mount" "-mtime"
		      "-name" "-newer" "-nogroup" "-noignore_readdir_race"
		      "-noleaf" "-nouser" "-nowarn" "-ok"
		      "-okdir" "-path" "-perm" "-print"
		      "-print0" "-printf" "-prune" "-quit"
		      "-readable" "-regex" "-regextype" "-samefile"
		      "-size" "-true" "-type" "-uid"
		      "-used" "-user" "-version" "-warn"
		      "-wholename" "-writable" "-xdev" "-xtype"))))
           ((string= "-type" prec)
            (while (pcomplete-here (list "b" "c" "d" "p" "f" "l" "s" "D"))))
           ((string= "-xtype" prec)
            (while (pcomplete-here (list "b" "c" "d" "p" "f" "l" "s"))))
           ((or (string= prec "-exec")
		(string= prec "-execdir"))
            (while (pcomplete-here* (funcall pcomplete-command-completion-function)
                                    (pcomplete-arg 'last) t))))
     (while (pcomplete-here (pcomplete-entries) nil 'identity))))

eshell-new

   (defun eshell-new()
   "Open a new instance of eshell."
   (interactive)
   (eshell 'N))

shortcuts function

  (defalias 'fifi 'find-file)

start it

  (eshell)

note that key-binding can be set in the :bind attribute of use-package

  
  (global-unset-key (kbd "C-x c")) ;; preempt exit
  (global-unset-key (kbd "C-z")) ;; preempt background
                                          ; C-h h is (view-hello-file)
  ;; (global-unset-key (kbd "C-h C-s"))

  (global-set-key (kbd "<f2>")   'switch-to-buffer) ;; I hit this one many *many* times a day
  (global-set-key (kbd "C-<f2>") 'helm-multi-files) ;; need to find a way to sort by recentb
  ;;(global-set-key (kbd "<S-f2>") 'list-buffers) ;;switch-to-buffer-list)
  (global-set-key (kbd "C-S-r") 'replace-string)
  (global-set-key (kbd "C-M-S-r") 'replace-regexp)
  (global-set-key (kbd "C-h C-k v") 'customize-variable)
  (global-set-key (kbd "C-c N") 'linum-mode)
  (global-set-key (kbd "C-h C-k g") 'customize-group)
  (global-set-key (kbd "C-h C-k f") 'customize-face)
  (global-set-key (kbd "C-h C-k t") 'customize-themes)
  (global-set-key (kbd "C-h C-w") 'woman)
  (global-set-key (kbd "<f5>")   'ranger)
  (global-set-key (kbd "<f6>")   'switch-to-eshell)
  (global-set-key (kbd "<f7>")   'flyspell-mode)
  (global-set-key (kbd "<C-f7>") 'cycle-ispell-languages)
                                          ;(global-set-key (kbd "<S-f6>")'switch-to-eshell)
                                          ;(global-set-key (kbd "<f9>")  'reload-dotemacs)
                                          ;(global-set-key (kbd "<f12>") 'org-export-json)
  (global-set-key (kbd "<f12>")  'company-complete)
                                          ;(global-set-key (kbd "<f12>") 'dumb-jump-go)
                                          ;(global-set-key (kbd "<C-f12>") 'dumb-jump-back)

  ;;(global-set-key (kbd "M-é")   'sr-speedbar-toggle); already boud to S-2 (é)
  ;;  (global-set-key (kbd "M-é")    'speedbar); already boud to S-2 (é)
  ;; [2021-09-02 Thu 14:28] > dired-sidebar (C-x C-n)
  (global-set-key (kbd "C-x C-c") 'nil) ; Was save-buffers-kill-emacs
  (global-set-key (kbd "C-x w") 'kill-yank)
  (global-set-key (kbd "C-c p") 'fill-paragraph-entire-buffer)
                                          ;(global-set-key "\C-w" 'backward-kill-word)
  (global-set-key "\C-w"  'kill-region)
                                          ;(global-set-key "\C-x\C-k" 'kill-region)
                                          ; (global-set-key "\C-c\C-k" 'kill-region)  (org-kill-note-or-show-branches)

  (define-prefix-command 'helm-addons-map)
  (global-set-key (kbd "C-h C-s") 'helm-addons-map)
  (define-key 'helm-addons-map "p" 'helm-system-packages)
  (define-key 'helm-addons-map "s" 'helm-DES)
  (define-key 'helm-addons-map "d" 'helm-tlfi)
  (define-key 'helm-addons-map "D" 'helm-dictionary-word-at-point)
  (define-key 'helm-addons-map "t" 'helm-rg-tlf) ;; broken, fixme
  (define-key 'helm-addons-map "r" 'helm-rg)
  (global-set-key (kbd "C-S-f") 'helm-rg)
  (global-set-key (kbd "C-x F") 'helm-recentf)
  (global-set-key (kbd "C-S-a") 'helm-ag) ; silversearcher
  (global-set-key (kbd "C-S-l") 'helm-locate)

  (global-set-key (kbd "C-c l") 'org-store-link)
  (global-set-key (kbd "C-c ! .") 'org-time-stamp-inactive) ;; C-c ! are flychecks prefix in some mode, but inserting timestamp anywhere is usefull
  (global-set-key (kbd "C-x M-l") 'list-packages)
                                          ;(define-prefix-command 'perly-sense-map)
                                          ;(global-set-key (kbd "C-p") 'perly-sense-map)
                                          ;(define-key perly-sense-map (kbd "C-d") 'perly-sense-smart-docs-at-point)
                                          ;(define-key perly-sense-map (kbd "C-g") 'perly-sense-smart-go-to-at-point)
                                          ;(define-prefix-command '"C-h C-s" 'helm-addons)
                                          ;(define-prefix-command 'helm-system 'help-map)
                                          ;(local-set-key (kbd "C-h") helm-addons)
                                          ;(defvaralias 'helm-addons 'help-map)
                                          ;(local-key help-map (kbd "C-s") 'nil)
                                          ;(global-set-key (kbd "C-h C-s") 'nil) undefine a symbol
                                          ;(global-set-key help-map (kbd "C-s p") 'helm-system-packages)
                                          ;(global-set-key (kbd "C-h C-s d") 'helm-tlfi)
                                          ;(global-set-key (kbd "C-h C-s s") 'helm-DES)

                                          ;(global-set-key (kbd "C-c (") 's-wrap)
                                          ;(global-set-key (kbd "C-c e") 'sly-eval-last-expression)
                                          ;(global-set-key (kbd "C-h C-s p") 'helm-system-packages)
                                          ;(global-set-key (kbd "C-h C-s d") 'helm-tlfi)

  (global-set-key (kbd "M-x") 'helm-M-x)

  (global-set-key (kbd "M-n") 'org-next-item)
  (global-set-key (kbd "M-p") 'org-previous-item)

  (global-set-key [mouse-8] (lambda () (interactive) (scroll-up-command)))
  (global-set-key [mouse-9] (lambda () (interactive) (scroll-down-command)))

  (define-key org-mode-map (kbd "C-c i") 'org-format-src-block)
  ;;(global-set-key (kbd "C-c t") 'org-format-src-block)
  (global-set-key (kbd "<C-tab>") 'hs-toggle-hiding)
  ;;(global-set-key (kbd "M-O") 'occur) ; was bound to M-s
    (defun org-format-src-block()
    (interactive)
    (org-edit-src-code)
    (indent-region (point-min) (point-max))
    (org-edit-src-exit))

rss elfeed

see (it's by default)

file://~/.emacs.d/elfeed.html

(info "(org) RSS Feeds")

(setq org-feed-alist '(("France culture" "http://radiofrance-podcast.net/podcast09/rss_11921.xml" "~/org/feeds.org" "franceculture")))

file://~/org/feeds.html

(setq org-feed-alist '(("7dnz" "http://forge.net/www/feed" "/tmp/feed.org" "7dnz")))

  


;; Load elfeed-org
(use-package elfeed-org)

;; Initialize elfeed-org
;; This hooks up elfeed-org to read the configuration when elfeed
;; is started with =M-x elfeed=
; (elfeed-org)

;; Optionally specify a number of files containing elfeed
;; configuration. If not set then the location below is used.
;; Note: The customize interface is also supported.
(setq rmh-elfeed-org-files (list "~/.emacs.d/elfeed.org"))

expand region

https://github.com/magnars/expand-region.el/blob/master/the-org-mode-expansions.el

     (require 'expand-region)
    (global-set-key (kbd "C-@") 'er/expand-region)

helm

file://~/github.com/emacs/helm.wiki

The default "C-x c" is quite close to "C-x C-c", which quits Emacs. Changed to "C-c h". Note: We must set "C-c h" globally, because we cannot change `helm-command-prefix-key' once `helm-config' is loaded.

global-set-key (kbd "C-c h") 'helm-command-prefix)

or (customize-variable 'helm-command-prefix-key) see also (customize-variable 'helm-command-prefix)

    (use-package helm)
  (use-package helm-ag) ;; the silversearcher
  (use-package helm-rg) ;; interactive async results with ripgrep
  (use-package helm-system-packages) ;; juggle with the apt packages
  (use-package helm-unicode)
  ;;(use-package helm-config)

  (define-key helm-map (kbd "<tab>") 'helm-execute-persistent-action) ; rebind tab to run persistent action
  (define-key helm-map (kbd "C-i") 'helm-execute-persistent-action) ; make TAB work in terminal
  (define-key helm-map (kbd "C-z") 'helm-select-action) ; list actions using C-z
  (define-key global-map (kbd "C-x C-f") 'helm-find-files)

                                          ;(when (executable-find "curl")
                                          ;  (setq helm-google-suggest-use-curl-p t))

  (setq helm-split-window-in-side-p           t ; open helm buffer inside current window, not occupy whole other window
        helm-move-to-line-cycle-in-source     t ; move to end or beginning of source when reaching top or bottom of source.
        helm-ff-search-library-in-sexp        t ; search for library in `require' and `declare-function' sexp.
        helm-scroll-amount                    8 ; scroll 8 lines other window using M-<next>/M-<prior>
        helm-ff-file-name-history-use-recentf t
        helm-echo-input-in-header-line t)

                                          ;(defun spacemacs//helm-hide-minibuffer-maybe ()
                                          ;  "Hide minibuffer in Helm session if we use the header line as input field."
                                          ;  (when (with-helm-buffer helm-echo-input-in-header-line)
                                          ;    (let ((ov (make-overlay (point-min) (point-max) nil nil t)))
                                          ;      (overlay-put ov 'window (selected-window))
                                          ;      (overlay-put ov 'face
                                          ;                   (let ((bg-color (face-background 'default nil)))
                                          ;                     `(:background ,bg-color :foreground ,bg-color)))
                                          ;      (setq-local cursor-type nil))))


                                          ;(add-hook 'helm-minibuffer-set-up-hook
                                          ;          'spacemacs//helm-hide-minibuffer-maybe)

; (helm-mode 1)

da TODO : find how to prevent ~ expand-filename

helm frame

displays in it's own frame

    (setq helm-autoresize-min-height 20)
  (setq helm-autoresize-max-height 0)
  (helm-autoresize-mode 1)
  (setq helm-display-function #'helm-display-buffer-in-own-frame)

it's fine, but needs improvement.

  • when the frame reaches the window border, it's sent back to the top right corner
  • it doesn't play well with multiple client windows
  • between the display of the frame and the keystroke is a rabbit hole that invert frames (meta-x stays, the caller vanishes)
  • 0:00:00 Error running timer ‘helm-M-x–notify-prefix-arg’: (wrong-type-argument window-live-p nil) [364 times]
  (defun helm-display-buffer-in-own-frame (buffer &optional resume)
  "Display Helm buffer BUFFER in a separate frame.

Function suitable for `helm-display-function',
`helm-completion-in-region-display-function' and/or
`helm-show-completion-default-display-function'.

See `helm-display-buffer-height' and `helm-display-buffer-width'
to configure frame size.

Note that this feature is available only with emacs-25+."
  (cl-assert (and (fboundp 'window-absolute-pixel-edges)
                  (fboundp 'frame-geometry))
             nil "Helm buffer in own frame is only available starting at emacs-25+")
  (if (not (display-graphic-p))
      ;; Fallback to default when frames are not usable.
      (helm-default-display-buffer buffer)
    (setq helm--buffer-in-new-frame-p t)
    (let* ((pos (window-absolute-pixel-position))
           (half-screen-size (/ (display-pixel-height x-display-name) 2))
           (frame-info (frame-geometry))
           (prmt-size (length helm--prompt))
           (line-height (frame-char-height))
           tab-bar-mode
           (default-frame-alist
             (if resume
                 (buffer-local-value 'helm--last-frame-parameters
                                     (get-buffer buffer))
               `((width . ,helm-display-buffer-width)
                 (height . ,helm-display-buffer-height)
                 (tool-bar-lines . 0)
                 (left . ,(- (car pos)
                             (* (frame-char-width)
                                (if (< (- (point) (point-at-bol)) prmt-size)
                                    (- (point) (point-at-bol))
                                  prmt-size))))
                 ;; Try to put frame at the best possible place.
                 ;; Frame should be below point if enough
                 ;; place, otherwise above point and
                 ;; current line should not be hidden
                 ;; by helm frame.
                 (top . ,(if (> (cdr pos) half-screen-size)
                             ;; Above point
                             (- (cdr pos)
                                ;; add 2 lines to make sure there is always a gap
                                (* (+ helm-display-buffer-height 1) line-height)
                                ;; account for title bar height too
                                (cddr (assq 'title-bar-size frame-info)))
                           ;; Below point
                           (+ (cdr pos) line-height)))
                 (title . "Helm")
                 (undecorated . ,helm-use-undecorated-frame-option)
                 (background-color . ,(or helm-frame-background-color
                                          (face-attribute 'default :background)))
                 (foreground-color . ,(or helm-frame-foreground-color
                                          (face-attribute 'default :foreground)))
                 (alpha . ,(or helm-frame-alpha 100))
                 (font . ,(assoc-default 'font (frame-parameters)))
                 (vertical-scroll-bars . nil)
                 (menu-bar-lines . 0)
                 (fullscreen . nil)
                 (visibility . ,(null helm-display-buffer-reuse-frame))
                 (minibuffer . t))))
           display-buffer-alist)
      ;; Display minibuffer above or below only in initial session,
      ;; not on a session triggered by action, this way if user have
      ;; toggled minibuffer and header-line manually she keeps this
      ;; setting in next action.
      (unless (or helm--executing-helm-action resume)
        ;; Add the hook inconditionally, if
        ;; helm-echo-input-in-header-line is nil helm-hide-minibuffer-maybe
        ;; will have anyway no effect so no need to remove the hook.
        (add-hook 'helm-minibuffer-set-up-hook 'helm-hide-minibuffer-maybe)
        (with-helm-buffer
          (setq-local helm-echo-input-in-header-line
                      (not (> (cdr pos) half-screen-size)))))
      (helm-display-buffer-popup-frame buffer default-frame-alist)
      ;; When frame size have been modified manually by user restore
      ;; it to default value unless resuming or not using
      ;; `helm-display-buffer-reuse-frame'.
      ;; This have to be done AFTER raising the frame otherwise
      ;; minibuffer visibility is lost until next session.
      (unless (or resume (not helm-display-buffer-reuse-frame))
        (set-frame-size helm-popup-frame
                        helm-display-buffer-width
                        helm-display-buffer-height)))
    (helm-log-run-hook 'helm-window-configuration-hook)))

helm frame position

https://www.reddit.com/r/emacs/comments/jj269n/display_helm_frames_in_the_center_of_emacs/

  (defun my-helm-display-frame-center (buffer &optional resume)
  "Display `helm-buffer' in a separate frame which centered in
parent frame."
  (if (not (display-graphic-p))
      ;; Fallback to default when frames are not usable.
      (helm-default-display-buffer buffer)
    (setq helm--buffer-in-new-frame-p t)
    (let* ((parent (selected-frame))
           (frame-pos (frame-position parent))
           (parent-left (car frame-pos))
           (parent-top (cdr frame-pos))
           (width (/ (frame-width parent) 2))
           (height (/ (frame-height parent) 3))
           tab-bar-mode
           (default-frame-alist
             (if resume
                 (buffer-local-value 'helm--last-frame-parameters
                                     (get-buffer buffer))
               `((parent . ,parent)
                 (width . ,width)
                 (height . ,height)
                 (undecorated . ,helm-use-undecorated-frame-option)
                 (left-fringe . 0)
                 (right-fringe . 0)
                 (tool-bar-lines . 0)
                 (line-spacing . 0)
                 (desktop-dont-save . t)
                 (no-special-glyphs . t)
                 (inhibit-double-buffering . t)
                 (tool-bar-lines . 0)
                 (left . ,(+ parent-left (/ (* (frame-char-width parent) (frame-width parent)) 4)))
                 (top . ,(+ parent-top (/ (* (frame-char-width parent) (frame-height parent)) 6)))
                 (title . "Helm")
                 (vertical-scroll-bars . nil)
                 (menu-bar-lines . 0)
                 (fullscreen . nil)
                 (visible . ,(null helm-display-buffer-reuse-frame))
                 ;; (internal-border-width . ,(if IS-MAC 1 0))
                )))
           display-buffer-alist)
      (set-face-background 'internal-border (face-foreground 'default))
      (Helm-display-buffer-popup-frame buffer default-frame-alist))
    (helm-log-run-hook 'helm-window-configuration-hook)))

(setq helm-display-function 'my-helm-display-frame-center)

helm frame position 2

Make Helm window at the bottom WITHOUT using any extra package

Simply add this to your config:

  (add-to-list 'display-buffer-alist
                    `(,(rx bos "*helm" (* not-newline) "*" eos)
                         (display-buffer-in-side-window)
                         (inhibit-same-window . t)
                         (window-height . 0.4)))

helm gtags

  
(setq
 helm-gtags-ignore-case t
 helm-gtags-auto-update t
 helm-gtags-use-input-at-cursor t
 helm-gtags-pulse-at-cursor t
 helm-gtags-prefix-key "\C-cg"
 helm-gtags-suggested-key-mapping t
 )

(use-package 'helm-gtags)
;; Enable helm-gtags-mode
(add-hook 'dired-mode-hook 'helm-gtags-mode)
(add-hook 'eshell-mode-hook 'helm-gtags-mode)
(add-hook 'c-mode-hook 'helm-gtags-mode)
(add-hook 'c++-mode-hook 'helm-gtags-mode)
(add-hook 'asm-mode-hook 'helm-gtags-mode)


;; Set key bindings
 (eval-after-load "helm-gtags"
 '(progn
  (define-key helm-gtags-mode-map (kbd "M-t") 'helm-gtags-find-tag)
  (define-key helm-gtags-mode-map (kbd "M-r") 'helm-gtags-find-rtag)
  (define-key helm-gtags-mode-map (kbd "M-s") 'helm-gtags-find-symbol)
  (define-key helm-gtags-mode-map (kbd "M-g M-p") 'helm-gtags-parse-file)
  (define-key helm-gtags-mode-map (kbd "C-c <") 'helm-gtags-previous-history)
  (define-key helm-gtags-mode-map (kbd "C-c >") 'helm-gtags-next-history)
  (define-key helm-gtags-mode-map (kbd "<M-left>") 'helm-gtags-previous-history)
  (define-key helm-gtags-mode-map (kbd "<M-right>") 'helm-gtags-next-history)

 (define-key helm-gtags-mode-map (kbd "C-c g a") 'helm-gtags-tags-in-this-function)
 (define-key helm-gtags-mode-map (kbd "C-j") 'helm-gtags-select)
 (define-key helm-gtags-mode-map (kbd "M-.") 'helm-gtags-dwim) ; references
 (define-key helm-gtags-mode-map (kbd "M-,") 'helm-gtags-pop-stack)
 (define-key helm-gtags-mode-map (kbd "C-c <") 'helm-gtags-previous-history)
 (define-key helm-gtags-mode-map (kbd "C-c >") 'helm-gtags-next-history)))

helm-examples

  
   (setq data '(("John" . "john@email.com")
				("Jim" . "jim@email.com")
				("Jane" . "jane@email.com")
				("Jill" . "jill@email.com")))

   (setq some-helm-source
		 `((name . "HELM at the Emacs")
		   (candidates . ,(mapcar 'car data))
		   (action . (lambda (candidate)
					   (message "%s" (cdr (assoc candidate data)))))))

   (helm :sources '(some-helm-source))



   (setq data '(("John" . "john@email.com")
				("Jim" . "jim@email.com")
				("Jane" . "jane@email.com")
				("Jill" . "jill@email.com")))

   (setq some-helm-source
		 `((name . "HELM at the Emacs")
		   (candidates . ,data)
		   (action . (lambda (candidate)
					   (helm-marked-candidates)))))

   (defun helm-select-and-insert-emails ()
	 (interactive)
	 (insert
	  (mapconcat 'identity
				 (helm :sources '(some-helm-source))
				 ",")))

#+endsrc

TLFI & DES

Trésor de la Langue Française Informatisé

    (defgroup tlfi nil "Customize TLFi integration into emacs" :version 26.1)
  (defcustom tlfi-path "~/doc/TLF/TLFi/tlfi.org/"
    "set tlfi directory"
    :group 'tlfi
    )
  ;;
  ;;
  ;; Fonctions de recherche dans les dictionnaires
  ;; - organisés en fichiers dans un dossier
  ;; - en liste de mot dans un fichier
  ;; - en liste de synonyme
  ;;   avec à chaque ligne
  ;;   mot : synonyme1, synonyme2, etc.


  (defcustom DES-file-path "~/doc/TLF/TLFi/DES"
    "répértoire du DES")

  (defun read-lines (filePath)
    "Return a list of lines of a file at filePath."
    (with-temp-buffer
      (insert-file-contents filePath)
      (split-string (buffer-string) "\n" t)))

  (setq helm-synonyms-source
	'((name . "définition")
	  (candidates . (lambda() (read-lines DES-file-path)))
	  (action . (lambda (candidate)
		      (open-dictionary "%s" candidate)))))

  (setq helm-DES-source
	'((name . "Synonymes")
	  (candidates . (lambda() (read-lines  DES-file-path)))
	  (action . (lambda (candidate)
		      (helm :sources
			    '((name . "definition")
			      (candidates . (lambda() (split-string (car (last (split-string candidate " : "))) ", ")))
			      (action . (lambda(c) (helm-tlfi c)))
			      ;; action 2 : insérer le mot
			      ))))))

  (defun helm-DES()
    "search terms in the DES"
    (interactive)
    (helm :sources '(helm-DES-source))
    :buffer "*helm-DES*"
    :resume t ) ; does not resume anymore ?


  (defcustom tlfi-index-path "~/doc/TLF/TLFi/index"
    "path to the article list"
    :group 'tlfi
    )


  (defun helm-tlfi--action-open-article(candidate)
    (dictionary-word candidate))

  (defun helm-tlfi--action-open-file-article(candidate)
    (dictionary-word candidate t))

  (defun helm-tlfi--persistent-action (candidate)
    "Not documented."
    (dictionary-word candidate))

  (defvar helm-tlfi--actions
    (helm-make-actions
     ;;   "Do nothing " #'nil ; won't lure helm in follow mode
     "View article" #'helm-tlfi--action-open-article
     "Open file" #'helm-tlfi--action-open-file-article
     "Not documented."))

  (defun helm-tlfi-sync-source () ;; helm-tlfi-source is in use instead
    "Return a `helm' source for tlfi."
    (setq helm-tlfi-started t)
    (helm-build-sync-source "TLFi.org"
      :candidates (lambda () (read-lines  tlfi-index-path))
      :candidate-number-limit 999
      :requires-pattern 1
      ;;:candidate-transformer  (lambda (candidates) (sort candidates #'string-lessp))
      :nomark t  ;; markind disabled
      :persistent-action  'dictionary-word
      :nohighlight t
      ;;:action 'helm-tlfi--actions
      :follow (and helm-follow-mode-persistent 1)
      :action 'helm-tlfi--actions ))

  ;;(("view" . dictionary-word))))

  (setq helm-tlfi-source
	'((name . "TLFi")
	  (candidates . (lambda() (read-lines  tlfi-index-path)))
	  (action . (lambda (candidate)
		      (dictionary-word candidate)))))

  ;;(dictionary-word "ouatte" t)
  (defvar helm-tlfi-started nil)

  (defun helm-tlfi(&optional input)
    "Rechercher dans le TLF"
    (interactive)
    (helm
     :sources (helm-tlfi-sync-source) ;;ou '(helm-tlfi-source)
     :resume nil
     :buffer "*helm-TLF*"
     :input input
     ))

  (defun helm-rg-tlf(&optional pat)
    "Recherche interactive dans le TLF.
	 give him the absolute path please"
    (interactive)
    (helm-rg pat nil '(tlfi-path)))

  (defcustom lexic-file-extension ""
    "file extensions in the dictionary folders")
  
  (defcustom lexic-file-extension  nil ;; ".gz"
    "file extensions in the dictionary folders")

  (defun open-dictionary-file-in-buffer (file)
    (switch-to-buffer (get-buffer-create "*tlfi-page*"))
    (erase-buffer)
    ;(org-mode)
    ;(setq org-hide-emphasis-markers t)
    (insert-file-contents file))


  (defun open-dictionary-file (file &optional in-buffer-p )
     (find-file file))
     ;;(org-mode)
     ;;(view-mode))


  ;(if in-buffer-p
  ;	(find-file file)
  ;     (open-dictionary-file-in-buffer file)))
  ;; else
					  ; (open-dictionary-file "~/tlfi.org/ivre")

  (defun dictionary-word (word &optional in-buffer-p)
    "open the dictionary file for this word"
    (let*( (article (downcase word))
           ;; (article (car (last(split-string (downcase word) "'")))) ;; ???
	   (file (concat "/:" tlfi-path "/" article lexic-file-extension))
	   )

      (if (file-readable-p file)
	  ;;(find-file file)
	  (open-dictionary-file file in-buffer-p)
	;;else try to depluralize
	(if (string= (substring article -1) "s")
	    (let*( (article (substring article 0 -1))
		   (file (concat tlfi-path article lexic-file-extension)) )
	      (if (file-readable-p file)
		  (find-file file)
		(open-dictionary-file file in-buffer-p)
		;;else
		(message "%s or %ss %s" file file "not found")
		)))
	(message "%s %s" file "not found")
	)))


  (defun dictionary-word-at-point ()
    "open dictionary for word at point"
    (interactive)
    (dictionary-word (word-at-point)))


  (defun helm-dictionary-word (word &optional in-buffer-p)
    "open the dictionary file for this word"
    (let*( (article (car (last(split-string (downcase word) "'")))))
       (helm-tlfi article)))

  (defun helm-dictionary-word-at-point ()
    "open dictionary for word at point"
    (interactive)
    (helm-dictionary-word (word-at-point)))

revoirs

   (defun wikipedia/word-at-point ()
    (interactive)
    (org-open-link-from-string
       (concat "[[wiki:" (downcase (word-at-point))":]]")
         ))

modeline

  
  (use-package doom-modeline
    :ensure t
    :hook (after-init . doom-modeline-mode))

  (doom-modeline-mode)

treemacs

       (use-package treemacs :ensure t)
     (use-package lsp-treemacs :ensure t)
     (setq treemacs-text-scale 0.9)
     (treemacs-resize-icons 16)

magit

[2022-01-06 Thu] magit-diff complains with-editor is missing file://~/.emacs.d/straight/repos/with-editor

    (load-file "~/.emacs.d/straight/repos/with-editor/with-editor.el")

  (use-package magit
      :ensure with-editor
      )

(use-package with-editor) Error (use-package): magit/:catch: Cannot open load file: No such file or directory, with-editor Disable showing Disable logging Error (use-package): Cannot load with-editor Disable showing Disable logging

mpv

       (use-package mpv)
     (global-set-key (kbd "<X86AudioStop>") 'mpv-kill)

dired

      (use-package diredfl)
    (diredfl-global-mode)
    (use-package dired-du)
    (use-package dired-atool)
    (use-package dired-launch)
    (dired-launch-enable)
    (use-package dired-sidebar
      :bind (("C-x C-n" . dired-sidebar-toggle-sidebar))
      :ensure nil
    )
     ;; :init
     ;; (dired-sidebar-toggle-sidebar))

    (defface dired-sidebar-customized-face
    '((t :height 0.9))
    "Default face for highlighting the current line in Hl-Line mode."
    :version "22.1"
    :group 'hl-line)
    (setq dired-sidebar-use-custom-font t)
    (setq dired-sidebar-mode-line-formamt
     '(""))
         ; '("%e" mode-line-front-space mode-line-buffer-identification " " mode-line-end-spaces))

    ;(setq dired-sidebar-face dired-sidebar-customized-face)
    ;; '(dired-sidebar-face nil)
     ;;   '(dired-sidebar-face dired-sidebar-customized-face)

(push 'toggle-window-split dired-sidebar-toggle-hidden-commands) (push 'rotate-windows dired-sidebar-toggle-hidden-commands)

(setq dired-sidebar-subtree-line-prefix nil) (setq dired-sidebar-use-term-integration nil) (setq dired-sidebar-use-custom-font nil))

all the icons dired

  (use-package all-the-icons-dired)

dired-fi nd-alternate

https://www.emacswiki.org/emacs/DiredPower A small customization to use your [mouse-2] button (middle button) to “find-alternate” on what you click on. It avoids opening a lot of dired buffer when navigating using the mouse. Simply paste this to your .emacs :

  (defun dired-mouse-find-alternate-file (event)
  "In dired, visit the file or directory you click on instead of the dired buffer."
  (interactive "e")
  (let (file)
    (save-excursion
      (set-buffer (window-buffer (posn-window (event-end event))))
      (save-excursion
	(goto-char (posn-point (event-end event)))
	(setq file (dired-get-filename nil t))))
    (select-window (posn-window (event-end event)))
    (find-alternate-file (file-name-sans-versions file t))))

(define-key dired-mode-map [mouse-2] 'dired-mouse-find-alternate-file)

dired auto refresh

  ; Auto-refresh dired on file change
(add-hook 'dired-mode-hook 'auto-revert-mode)

will keep telling "reverting dir…" however it's not displayed when pressing C-g would keep it if it was silenced despite critics on reddit saying that they don't like when the system perform changes in their back. (remove-hook 'dired-mode-hook 'auto-revert-mode)

eros

Evaluation Result OverlayS for Emacs Lisp https://github.com/xiongtx/eros https://endlessparentheses.com/eval-result-overlays-in-emacs-lisp.html

    (use-package eros)
  (eros-mode 1)

aa2e

   (use-package ascii-art-to-unicode)

no break space

  (customize-face 'nobreak-space)

non breakable space / whitespace < evaluated ?

U+0020 SPACE foo bar Depends on font, typically 1/4 em, often adjusted
U+00A0 NO-BREAK SPACE foo bar As a space, but often not adjusted
U+1680 OGHAM SPACE MARK foo bar Unspecified usually not really a space but a dash
U+2000 EN QUAD foo bar 1 en (= 1/2 em)
U+2001 EM QUAD foo bar 1 em (nominally, the height of the font)
U+2002 EN SPACE (nut) foo bar 1 en (= 1/2 em)
U+2003 EM SPACE (mutton) foo bar 1 em
U+2004 THREE-PER-EM SPACE (thick) foo bar 1/3 em
U+2005 FOUR-PER-EM SPACE (mid) foo bar 1/4 em
U+2006 SIX-PER-EM SPACE foo bar 1/6 em
U+2007 FIGURE SPACE foo bar “Tabular width”, the width of digits
U+2008 PUNCTUATION SPACE foo bar The width of a period “.”
U+2009 THIN SPACE foo bar 1/5em (or sometimes 1/6 em)
U+200A HAIR SPACE foo bar Narrower than THIN SPACE
U+200B ZERO WIDTH SPACE foo​bar 0
U+202F NARROW NO-BREAK SPACE foo bar Narrower than NO-BREAK SPACE (or SPACE), “typically the width of a thin space or a mid space”
U+205F MEDIUM MATHEMATICAL SPACE foo bar 4/18 em
U+3000 IDEOGRAPHIC SPACE foo bar The width of ideographic (CJK) characters.
U+FEFF ZERO WIDTH NO-BREAK SPACE foobar 0
0x23B5 BOTTOM SQUARE BRACKE  

simple : (customize-face 'nobreak-space) or :

     (require 'highlight-chars)
   (hc-toggle-highlight-hard-spaces)

mu4e

https://config.daviwil.com/mail

       (use-package mu4e
       :defer 20 ; Wait until 20 seconds after startup
       :config

       ;; Load org-mode integration
       (require 'org-mu4e)

       ;; Refresh mail using isync every 10 minutes
       (setq mu4e-update-interval (* 10 60))
       (setq mu4e-get-mail-command "mbsync -a")
       (setq mu4e-maildir "~/Mail")

       ;; Use Ivy for mu4e completions (maildir folders, etc)
       (setq mu4e-completing-read-function #'ivy-completing-read)

       ;; Make sure that moving a message (like to Trash) causes the
       ;; message to get a new file name.  This helps to avoid the
       ;; dreaded "UID is N beyond highest assigned" error.
       ;; See this link for more info: https://stackoverflow.com/a/43461973
       (setq mu4e-change-filenames-when-moving t)

       ;; Set up contexts for email accounts
       (setq mu4e-contexts
	     `(,(make-mu4e-context
		 :name "crtdb"
		 :match-func (lambda (msg) (when msg
					     (string-prefix-p "/crtdb" (mu4e-message-field msg :maildir))))
		 :vars '(
			 (user-full-name . "Philippe Estival")
			 (user-mail-address . "estival@cartodebat.com")
			 (mu4e-sent-folder . "/crtdb/Sent Items")
			 (mu4e-trash-folder . "/crtdb/Trash")
			 (mu4e-drafts-folder . "/crtdb/Drafts")
			 (mu4e-refile-folder . "/crtdb/Archive")
			 (mu4e-sent-messages-behavior . sent)
			 ))
	       ,(make-mu4e-context
		 :name "Personal"
		 :match-func (lambda (msg) (when msg
					     (string-prefix-p "/Personal" (mu4e-message-field msg :maildir))))
		 :vars '(
			 (mu4e-sent-folder . "/Personal/Sent")
			 (mu4e-trash-folder . "/Personal/Deleted")
			 (mu4e-refile-folder . "/Personal/Archive")
			 ))
	       ))
       (setq mu4e-context-policy 'pick-first)

       ;; Prevent mu4e from permanently deleting trashed items
       ;; This snippet was taken from the following article:
       ;; http://cachestocaches.com/2017/3/complete-guide-email-emacs-using-mu-and-/
       (defun remove-nth-element (nth list)
	 (if (zerop nth) (cdr list)
	   (let ((last (nthcdr (1- nth) list)))
	     (setcdr last (cddr last))
	     list)))
       (setq mu4e-marks (remove-nth-element 5 mu4e-marks))
       (add-to-list 'mu4e-marks
		    '(trash
		      :char ("d" . "▼")
		      :prompt "dtrash"
		      :dyn-target (lambda (target msg) (mu4e-get-trash-folder msg))
		      :action (lambda (docid msg target)
				(mu4e~proc-move docid
						(mu4e~mark-check-target target) "-N"))))

       ;; Display options
       (setq mu4e-view-show-images t)
       (setq mu4e-view-show-addresses 't)

       ;; Composing mail
       (setq mu4e-compose-dont-reply-to-self t)

       ;; Use mu4e for sending e-mail
       (setq mail-user-agent 'mu4e-user-agent
	     message-send-mail-function 'smtpmail-send-it
	     smtpmail-smtp-server "mail.gandi.net"
	     smtpmail-smtp-service 465
	     smtpmail-stream-type  'ssl)

       ;; Signing messages (use mml-secure-sign-pgpmime)

       ;;  (setq mml-secure-openpgp-signers '("53C41E6E41AAFE55335ACA5E446A2ED4D940BF14"))

       ;; (See the documentation for `mu4e-sent-messages-behavior' if you have
       ;; additional non-Gmail addresses and want assign them different
       ;; behavior.)

       ;; setup some handy shortcuts
       ;; you can quickly switch to your Inbox -- press ``ji''
       ;; then, when you want archive some messages, move them to
       ;; the 'All Mail' folder by pressing ``ma''.
       (setq mu4e-maildir-shortcuts
	     '(("/crtdb/INBOX"       . ?i)
	       ("/crtdb/Lists/*"     . ?l)
	       ("/crtdb/Sent Mail"   . ?s)
	       ("/crtdb/Trash"       . ?t)))

       (add-to-list 'mu4e-bookmarks
		    (make-mu4e-bookmark
		     :name "All Inboxes"
		     :query "maildir:/crtdb/INBOX OR maildir:/Personal/Inbox"
		     :key ?i))

       ;; don't keep message buffers around
       (setq message-kill-buffer-on-exit t)

       (setq dw/mu4e-inbox-query
	     "(maildir:/Personal/Inbox OR maildir:/crtdb/INBOX) AND flag:unread")

       (defun dw/go-to-inbox ()
	 (interactive)
	 (mu4e-headers-search dw/mu4e-inbox-query))

       (dw/leader-key-def
	"m"  '(:ignore t :which-key "mail")
	"mm" 'mu4e
	"mc" 'mu4e-compose-new
	"mi" 'dw/go-to-inbox
	"ms" 'mu4e-update-mail-and-index)

       ;; Start mu4e in the background so that it syncs mail periodically
       (mu4e t))

Use mu4e-alert to show notifications when e-mail comes in github:iqbalansari/mu4e-alert

  (use-package mu4e-alert
  :after mu4e
  :config
  ;; Show unread emails from all inboxes
  (setq mu4e-alert-interesting-mail-query dw/mu4e-inbox-query)

  ;; Show notifications for mails already notified
  (setq mu4e-alert-notify-repeated-mails nil)

  (mu4e-alert-enable-notifications))

dequote

    (fset 'dequote
	 [?\C-s ?\" ?\C-m ?\C-? ?« ?\C-s ?\C-s ?\C-m ?\C-? ?»])

hn reader

  (use-package hnreader)

edraw

(straight-use-package '(edraw :type git :host github :repo "misohena/el-easydraw"))

find file in project

(describe-package 'find-file-in-project)

    (use-package find-file-in-project
    :init
    (setq ffip-use-rust-fd t ))
  (global-set-key (kbd "C-x M-f") 'find-file-in-project)

align string

no need any more, there's align.el (and bibtex-mode does it too) which contains align-regexp

  (load "~/.emacs.d/lisp/align-string.el")

uuid

      (let ((myStr (md5 (format "%s%s%s%s%s%s%s%s%s"
                              (user-uid)
                              (emacs-pid)
                              (system-name)
                              (user-full-name)
                              (current-time)
                              (emacs-uptime)
                              (garbage-collect)
                              ;;(buffer-string)
                              (random)
                              (recent-keys)))))
      (insert (format "%s-%s-4%s-%s%s-%s"
                      (substring myStr 0 8)
                      (substring myStr 8 12)
                      (substring myStr 13 16)
                      (format "%x" (+ 8 (random 4)))
                      (substring myStr 17 20)
                      (substring myStr 20 32)))))))

tabline

  (use-package tab-line
;u  :straight nil
  :unless (version< emacs-version "27")
  :hook ((after-init . global-tab-line-mode)
         ((aorst--load-theme
           aorst--disable-theme
           aorst--solaire-swap-bg) . aorst/tabline-setup-faces))
  :config
  (defun tab-line-close-tab (&optional e)
    "Close the selected tab.

If tab is presented in another window, close the tab by using
`bury-buffer` function.  If tab is unique to all existing
windows, kill the buffer with `kill-buffer` function.  Lastly, if
no tabs left in the window, it is deleted with `delete-window`
function."
    (interactive "e")
    (let* ((posnp (event-start e))
           (window (posn-window posnp))
           (buffer (get-pos-property 1 'tab (car (posn-string posnp)))))
      (with-selected-window window
        (let ((tab-list (tab-line-tabs-window-buffers))
              (buffer-list (flatten-list
                            (seq-reduce (lambda (list window)
                                          (select-window window t)
                                          (cons (tab-line-tabs-window-buffers) list))
                                        (window-list) nil))))
          (select-window window)
          (if (> (seq-count (lambda (b) (eq b buffer)) buffer-list) 1)
              (progn
                (if (eq buffer (current-buffer))
                    (bury-buffer)
                  (set-window-prev-buffers window (assq-delete-all buffer (window-prev-buffers)))
                  (set-window-next-buffers window (delq buffer (window-next-buffers))))
                (unless (cdr tab-list)
                  (ignore-errors (delete-window window))))
            (and (kill-buffer buffer)
                 (unless (cdr tab-list)
                   (ignore-errors (delete-window window)))))))))


  (defcustom tab-line-tab-min-width 10
    "Minimum width of a tab in characters."
    :type 'integer
    :group 'tab-line)


  (defcustom tab-line-tab-max-width 33
    "Maximum width of a tab in characters."
    :type 'integer
    :group 'tab-line)

  (defcustom tab-line-ellipsis-string "…"
    "String for indicating truncated names"
    :type 'string
    :group 'tab-line)

  (defun aorst/tab-line--tab-width (window-width tab-amount)
    "Calculate width of single tab dividing WINDOW-WIDTH by TAB-AMOUNT."
    (let* ((close-button-size
            (if tab-line-close-button-show
                (length (substring-no-properties tab-line-close-button)) 0))
           (tab-width (/ window-width tab-amount)))
      (- (cond ((< window-width 0)
                tab-line-tab-min-width)
               ((>= tab-width tab-line-tab-max-width)
                tab-line-tab-max-width)
               ((< tab-width tab-line-tab-min-width)
                tab-line-tab-min-width)
               (t tab-width))
         close-button-size)))

  (defun aorst/tab-line--max-width (window)
    "Calculate free width of the WINDOW.

Free width means amount of space we can use to display tabs
without truncation."
    (- (window-width window)
       (length (substring-no-properties tab-line-left-button))
       (length (substring-no-properties tab-line-right-button))
       (if tab-line-new-button-show
           (length (substring-no-properties tab-line-new-button))
         0)))


  (defun aorst/tab-line--make-pad (tab-width name-width)
    "Generate padding string based on TAB-WIDTH and NAME-WIDTH."
    (let* ((width (- tab-width name-width))
           (padding (/ (if (oddp width) (+ width 1) width) 2)))
      (make-string padding ?\s)))


  (defun aorst/tab-line-name-buffer (buffer &rest _buffers)
    "Create name for tab with padding and truncation.

If buffer name is shorter than `tab-line-tab-max-width' it gets
centered with spaces, otherwise it is truncated, to preserve
equal width for all tabs.  This function also tries to fit as
many tabs in window as possible, so if there are no room for tabs
with maximum width, it calculates new width for each tab and
truncates text if needed.  Minimal width can be set with
`tab-line-tab-min-width' variable."
    (with-current-buffer buffer
      (let* ((amount (length (tab-line-tabs-window-buffers)))
             (width (aorst/tab-line--tab-width
                     (aorst/tab-line--max-width (get-buffer-window buffer))
                     amount))
             (buffer (string-trim (buffer-name)))
             (name-width (length buffer))
             (right-pad (if tab-line-close-button-show "" " "))
             (truncate-width (- width
                                (length tab-line-ellipsis-string)
                                (length right-pad)
                                1)))
        (if (>= name-width truncate-width)
            (propertize (concat  " " (truncate-string-to-width buffer truncate-width) tab-line-ellipsis-string right-pad)
                        'help-echo (if-let ((name (buffer-file-name)))
                                       (abbreviate-file-name name)
                                     (buffer-name)))
          (let* ((padding (aorst/tab-line--make-pad width name-width))
                 (tab-text (concat padding buffer))
                 (text-width (length tab-text)))
            (propertize (concat tab-text (make-string (- width text-width) ?\s))
                        'help-echo (when-let ((name (buffer-file-name)))
                                    (abbreviate-file-name name))))))))



  (setq tab-line-close-button-show t
        tab-line-new-button-show nil
        tab-line-separator ""
        tab-line-tab-name-function #'aorst/tab-line-name-buffer
        tab-line-right-button (propertize (if (char-displayable-p ?▶) " ▶ " " > ")
                                          'keymap tab-line-right-map
                                          'mouse-face 'tab-line-highlight
                                          'help-echo "Click to scroll right")
        tab-line-left-button (propertize (if (char-displayable-p ?◀) " ◀ " " < ")
                                         'keymap tab-line-left-map
                                         'mouse-face 'tab-line-highlight
                                         'help-echo "Click to scroll left")
        tab-line-close-button (propertize (if (char-displayable-p ?×) " × " " x ")
                                          'keymap tab-line-tab-close-map
                                          'mouse-face 'tab-line-close-highlight
                                          'help-echo "Click to close tab")
        tab-line-exclude-modes '(ediff-mode
                                 process-menu-mode
                                 term-mode
                                 vterm-mode))


  (defun aorst/tabline-setup-faces ()
    (let ((bg (if (and (facep 'solaire-default-face)
                       (not (eq (face-attribute 'solaire-default-face :background)
                                'unspecified)))
                  (face-attribute 'solaire-default-face :background)
                (face-attribute 'default :background)))
          (fg (face-attribute 'default :foreground))
          (dark-fg (face-attribute 'shadow :foreground))
          (base (if (and (facep 'solaire-default-face)
                         (not (eq (face-attribute 'solaire-default-face :background)
                                  'unspecified)))
                    (face-attribute 'default :background)
                  (face-attribute 'mode-line :background)))
          (box-width (/ aorst--line-pixel-height 2)))
      (set-face-attribute 'tab-line nil
                          :background base
                          :foreground dark-fg
                          :height 1.0
                          :inherit nil
                          :box (when (> box-width 0) (list :line-width -1 :color base)))
      (set-face-attribute 'tab-line-tab nil
                          :foreground dark-fg
                          :background bg
                          :weight 'normal
                          :inherit nil
                          :box (when (> box-width 0) (list :line-width box-width :color bg)))
      (set-face-attribute 'tab-line-tab-inactive nil
                          :foreground dark-fg
                          :background base
                          :weight 'normal
                          :inherit nil
                          :box (when (> box-width 0) (list :line-width box-width :color base)))
      (set-face-attribute 'tab-line-tab-current nil
                          :foreground fg
                          :background bg
                          :weight 'normal
                          :inherit nil
                          :box (when (> box-width 0) (list :line-width box-width :color bg)))))

  (aorst/tabline-setup-faces)

  (defun aorst/tab-line-drop-caches ()
    "Drops `tab-line' cache in every window."
    (dolist (window (window-list))
      (set-window-parameter window 'tab-line-cache nil)))

  (add-hook 'window-configuration-change-hook #'aorst/tab-line-drop-caches)

  (define-advice tab-line-select-tab (:after (&optional e) aorst:tab-line-select-tab)
    (select-window (posn-window (event-start e)))))

tabbar

    (use-package tabbar
  :ensure t
  :bind)
      (custom-set-faces
     '(tabbar-button ((t (:inherit tabbar-default :background "#5a5d68" :box nil))))
     '(tabbar-button-highlight ((t (:inherit tabbar-default :background "#0C1021"))))
     '(tabbar-default ((t (:background "#2a2d3c" :foreground "gray58" :height 0.8))))
     '(tabbar-modified ((t (:inherit tabbar-default :foreground "dark orange" :box nil))))
     '(tabbar-selected ((t (:inherit tabbar-default :background "#0C1021" :foreground "white" :box nil :overline "cyan"))))
     '(tabbar-selected-modified ((t (:inherit tabbar-default :foreground "orange" :overline "deep sky blue"))))
     '(tabbar-separator ((t (:inherit tabbar-default))))
     '(tabbar-unselected ((t (:inherit tabbar-default)))))

smart mode line

    (require 'smart-mode-line)
  (setq sml/theme 'powerline)
  (sml/setup)
   '(sml/mode-width
   (if
       (eq
	(powerline-current-separator)
	(quote arrow))
       (quote right)
     (quote full)))
 '(sml/pos-id-separator
   (quote
    (""
     (:propertize " " face powerline-active1)
     (:eval
      (propertize " "
		  (quote display)
		  (funcall
		   (intern
		    (format "powerline-%s-%s"
			    (powerline-current-separator)
			    (car powerline-default-separator-dir)))
		   (quote powerline-active1)
		   (quote powerline-active2))))
     (:propertize " " face powerline-active2))))
 '(sml/pos-minor-modes-separator
   (quote
    (""
     (:propertize " " face powerline-active1)
     (:eval
      (propertize " "
		  (quote display)
		  (funcall
		   (intern
		    (format "powerline-%s-%s"
			    (powerline-current-separator)
			    (cdr powerline-default-separator-dir)))
		   (quote powerline-active1)
		   (quote sml/global))))
     (:propertize " " face sml/global))))
 '(sml/pre-id-separator
   (quote
    (""
     (:propertize " " face sml/global)
     (:eval
      (propertize " "
		  (quote display)
		  (funcall
		   (intern
		    (format "powerline-%s-%s"
			    (powerline-current-separator)
			    (car powerline-default-separator-dir)))
		   (quote sml/global)
		   (quote powerline-active1))))
     (:propertize " " face powerline-active1))))
 '(sml/pre-minor-modes-separator
   (quote
    (""
     (:propertize " " face powerline-active2)
     (:eval
      (propertize " "
		  (quote display)
		  (funcall
		   (intern
		    (format "powerline-%s-%s"
			    (powerline-current-separator)
			    (cdr powerline-default-separator-dir)))
		   (quote powerline-active2)
		   (quote powerline-active1))))
     (:propertize " " face powerline-active1))))
 '(sml/pre-modes-separator (propertize " " (quote face) (quote sml/modes)))

minimap

  ;;  (use-package minimap)
;;  (use-package perfect-margin)  ;; will hung after a code block evaluation

adapt background to mode

  (defvar chosig-alist
  '((Info-mode . "#ddd")
    ("scratch" . "#fee")
    (go-mode . "#eee"))
  "Alist matching major modes or buffer names with background colors.
Every cons cell on the alist has the form (CHECK . COLOR) where CHECK
is either a symbol matching the `major-mode' or a regular expression
matching the `buffer-name' of the current buffer. COLOR is a string
representing a valid color, eg. \"red\" or \"f00\".")

(defun chosig-choose-background ()
  "Pick background-color according to `chosig-alist'.
The overlay used is stored in `chosig-background'."
  (let ((alist chosig-alist)
	background)
    (while (and (not background) alist)
      (if (or (and (stringp (caar alist))
		   (string-match (caar alist) (buffer-name)))
	      (eq major-mode (caar alist)))
	  (setq background (cdar alist))
	(setq alist (cdr alist))))
    ;; cleanup
    (mapc (lambda (o)
	    (when (overlay-get o 'chosig)
	      (delete-overlay o)))
	  (overlays-in (point-min) (point-max)))
    ;; new one
    (when background
      (let ((o (make-overlay (point-min) (point-max)
			     (current-buffer) nil t)))
	(overlay-put o 'face `(:background ,background))
	(overlay-put o 'chosig t)))))

(add-hook'after-change-major-mode-hook 'chosig-choose-background)

fringe, margins, gutter

A double line for the vertical border would make emacs even nicer

      (set-face-attribute 'fringe nil
                        :background "blackboard"
                        :foreground "black") ;;<- indicate the line return
    (set-face-background 'vertical-border (face-background 'default))
    (set-face-foreground 'vertical-border "blue")
    (defun my-set-margins ()
      "Set margins in current buffer."
      (setq left-margin-width 5)
      (setq right-margin-width 5))

    (add-hook 'org-mode-hook 'my-set-margins)


    ;; Reverse colors for the border to have nicer line
    (set-face-inverse-video-p 'vertical-border nil) ;; this is for tty
    (set-face-background 'vertical-border (face-background 'default))

    ;; Set symbol for the border
    (set-display-table-slot standard-display-table
                            'vertical-border
                            (make-glyph-code ?┃))

scroll bar

  (scroll-bar-mode -1)

current file and line number

(store link) https://gist.github.com/kristianhellquist/3082383#gistcomment-2804834

    (defun copy-current-line-position-to-clipboard ()
      "Copy current line in file to clipboard as '</path/to/file>:<line-number>'."
      (interactive)
      (let ((path-with-line-number
	     (concat (dired-replace-in-string (getenv "HOME") "~" (buffer-file-name)) "::" (number-to-string (line-number-at-pos)))))
	(kill-new path-with-line-number)
	(message (concat path-with-line-number " copied to clipboard"))))

  (define-key global-map (kbd "C-c M-l") 'copy-current-line-position-to-clipboard)

all the icons

      (use-package all-the-icons)
    (require 'helm-all-the-icons)

ring-bell

    (setq ring-bell-function nil ;; #'doom-themes-visual-bell-fn
	visible-bell nil)

theme

  
  (add-to-list 'custom-theme-load-path (expand-file-name "themes" user-emacs-directory))

  (use-package doom-themes)
  ;; Global settings (defaults)
  (setq doom-themes-enable-bold t    ; if nil, bold is universally disabled
	doom-themes-enable-italic t) ; if nil, italics is universally disabled

  ;; Load the theme (doom-one, doom-molokai, etc); keep in mind that each
  ;; theme may have their own settings.
  (load-theme 'doom-one t)

  ;; Enable flashing mode-line on errors
  ;;  (doom-themes-visual-bell-config)

  ;;(use-package neotree)
  ;; Enable custom neotree theme
  ;;(doom-themes-neotree-config)  ; all-the-icons fonts must be installed!


  ;;(toggle-frame-fullscreen)
  ;;(custom-enabled-themes (quote (smart-mode-line-powerline)))

this should go in the doom-one derivation

    (custom-set-faces
   '(default ((t (:inherit nil :extend nil :stipple nil :foreground "white smoke" :inverse-video nil :box nil :strike-through nil :overline nil :underline nil :slant normal :weight normal :height 113 :width normal :foundry "unknown" :family "DejaVu Sans Mono"))))
   '(blog-auto-export-enabled ((t (:inherit default :foreground "chartreuse" :weight semi-bold))))
   '(dired-sidebar-customized-face ((t (:height 0.9))))
   '(font-lock-comment-face ((t (:foreground "cadet blue"))))
   '(fringe ((t (:inherit default))))
   '(hc-hard-space ((t (:underline "cyan"))))
   '(linum ((t (:inherit default :foreground "dim gray" :strike-through nil :underline nil :slant normal :weight normal))))
   '(nobreak-space ((t (:inherit default :underline "cyan"))))
   '(org-block ((t (:extend t :background "#081020" :foreground "white"))))
   '(org-block-begin-line ((t (:foreground "orange red" :underline t :slant italic :weight semi-bold :height 1.0))))
   '(org-block-end-line ((t (:inherit org-block-begin-line :extend nil :foreground "#081020" :overline "orange red" :underline nil :slant oblique :weight semi-bold :height 0.9))))
   '(org-checkbox ((t (:inherit default :weight semi-bold))))
   '(org-code ((t (:inherit org-block :foreground "yellow"))))
   '(org-document-info ((t (:foreground "light blue"))))
   '(org-document-title ((t (:foreground "light blue" :weight bold :height 1.2))))
   '(org-done ((t (:foreground "green" :strike-through nil :weight bold))))
   '(org-drawer ((t (:foreground "steel blue"))))
   '(org-footnote ((t (:foreground "#da8548" :height 0.9))))
   '(org-headline-done ((t nil)))
   '(org-level-2 ((t (:foreground "#edd400" :weight normal :height 1.1))))
   '(org-link ((t (:foreground "chartreuse" :underline t :weight normal))))
   '(org-todo ((t (:foreground "red" :weight bold))))
   '(org-verbatim ((t (:foreground "wheat" :weight bold))))
   '(secondary-selection ((t (:extend t :background "#3f444a" :inverse-video t))))
   '(vertical-border ((t (:foreground "black")))))

themes reserve

darcula

    ;;(use-package jetbrains-darcula-theme
  ;;  :config
  ;;  (load-theme 'jetbrains-darcula t))

blackboard2

    (load-theme 'blackboard-2 t)
  ;;(setq blackboard-bg-color  "#0C1021")

nano

  (use-package nano-theme
  :ensure nil)

buttonize-buffer

buttonize the entire buffer

    (define-button-type 'find-file-button
    'follow-link t
    'action #'find-file-button)

  (defun find-file-button (button)
    (find-file (buffer-substring (button-start button) (button-end button))))


  (defun buttonize-buffer ()
    "Turn all file paths and URLs into buttons."
    (interactive)
    (require 'ffap)
    (deactivate-mark)
    (let (token guess beg end reached bound len)
      (save-excursion
	(setq reached (point-min))
	(goto-char (point-min))
	(while (re-search-forward   ;;(concat
		ffap-next-regexp
		;;"(:[:digit:]*)?")
		nil t)
	  ;; There seems to be a bug in ffap, Emacs 23.3.1: `ffap-file-at-point'
	  ;; enters endless loop when the string at point is "//".
	  (setq token (ffap-string-at-point))
	  (unless (string= "//" (substring token 0 2))
	    ;; Note that `ffap-next-regexp' only finds some "indicator string" for a
	    ;; file or URL. `ffap-string-at-point' blows this up into a token.
	    (save-excursion
	      (beginning-of-line)
	      (when (search-forward token (point-at-eol) t)
		(setq beg (match-beginning 0)
		      end (match-end 0)
		      reached end))
	      )
	    ;;(message "Found token %s at (%d-%d)" token beg (- end 1))
	    ;;(message "at point %s" (ffap-file-at-point))
	    ;; Now let `ffap-guesser' identify the actual file path or URL at
	    ;; point.
	    (when (setq guess token) ;;(ffap-guesser))
	      ;;(message "  Guessing %s" guess)
	      (save-excursion
		(beginning-of-line)
		(when (search-forward guess (point-at-eol) t)
		  (setq len (length guess) end (point) beg (- end len))
		  ;; Finally we found something worth buttonizing. It shall have
		  ;; at least 2 chars, however.
		  ;;(message "    Matched at (%d-%d]" beg (- end 1))
		  (unless (or (< (length guess) 2))
		    ;;(message "      Buttonize!")
		    (make-button beg end :type 'find-file-button))
		  )
		)
	      )
	    ;; Continue one character after the guess, or the original token.
	    (goto-char (max reached end))
	    ;;(message "Continuing at %d" (point))
	    )
	  )
	)
      )
    )

comint filter buttonize buffer

Turn relative file names + line to buttons this is a comint filter, scrutinizing the areas as the output occurs

Possible improvements

  • filter on files with complete path turning the button to a short name relative to a directory, while keeping the full name in the button property.

check ffap-next-regexp for filenames with a path.

      (define-button-type 'find-file-button
      'follow-link t
      'action #'find-file-button)

    (defun find-file-button (button)
      (find-file-other-window (buffer-substring (button-start button) (button-end button)))
      (recenter-top-bottom)
      )

    (defun  comint-output-buttonize-filenames(string)
          (output-buttonize-filenames))

    (defun  output-buttonize-filenames()
      (let*((start-marker (if (and (markerp comint-last-output-start)
                                   (eq (marker-buffer comint-last-output-start)
                                       (current-buffer))
                                   (marker-position comint-last-output-start))
                              comint-last-output-start
                            (point-min-marker))))
        ;;(end-marker (process-mark (get-buffer-process (current-buffer)))))
        (goto-char  (marker-position start-marker))
        (while (re-search-forward "~?[-~\./:[:alnum:]]*[[:alnum:]]*:[[:digit:]]+" nil t)
          (let((end (match-end 0))
               (beg (match-beginning 0)))
            (make-button beg end :type 'find-file-button)
            ))
        ))

    (defun test-comint(str)
      (message " ?" ))

    ;; could call add-to-list instead, however
    ;; debugging init.org loads it several times
    (setq comint-output-filter-functions
          '(
            comint-output-buttonize-filenames
            ;; test-comint
            ansi-color-process-output
            comint-postoutput-scroll-to-bottom
            comint-watch-for-password-prompt
            ))

    (setq comint-preoutput-filter-functions
          '())

  ;; see also  (eshell-output-filter-functions

[2022-01-29 Sat 21:25] hmm not working anymore

trying different approach

    (defun buttonize-file-names()
    (interactive)
    (while (re-search-forward "[/:.~[:alpha:]]+\.[-[:alnum:]]+:[[:digit:]]+" nil t)
      (let((end (match-end 0))
           (beg (match-beginning 0)))
        (make-button beg end :type 'find-file-button)
        )))

(setq comint-output-filter-functions '( ansi-color-process-output comint-postoutput-scroll-to-bottom comint-watch-for-password-prompt comint-output-buttonize-files-names ))

the following substitution might help to sanitize the buffer

      | sed -e "    \
 s%$(pwd)/%%;      \
 s%\.nim(%\.nim:%;  \
 s%$HOME%~%;         \
 s%Warning%\x1b[1;33mWarning\x1b[0m%;\
 s%Error%\x1b[1;31mError\x1b[0m%;\
 "

marker

Question is now, how to do so on the message area ?

    (org-narrow-to-subtree)
  (let ((m1 (make-marker)))
    (set-marker m1 (point))
    (message "%s %s" (marker-position m1) (point)))

does this recurse to max recursion depth ?

 (setq comint-output-filter-functions
       '( (lambda(x) (message "ok") )))
(message "init.org:30")
    (defun buttonize-short-file-names+lines ()
    (interactive)
    (cd user-emacs-directory)
    (goto-char (point-min))
    (while (re-search-forward "[/:.~[:alnum:]]+\.[:alnum:]+:[[:digit:]]+" nil t)
;; assume there's an extension
;;    (while (re-search-forward "[/:.~[:alpha:]]*[-[:alnum:]]*:[[:digit:]]+" nil t)
      (let((end (match-end 0))
           (beg (match-beginning 0)))
        (make-button beg end :type 'find-file-button)
        ))
    )
  (defun init.org(file block prefix)
  "evaluate and org-mode file,
   starting at a level 1 section named BLOCK
   every subsection starting with PREFIX"
  (with-temp-buffer
    (insert-file file)
    (goto-char (point-min))
    (search-forward (concat "\n* " block))
    (org-mode)
    ;; line number here
    (org-narrow-to-subtree)
    (org-down-element)
    (while (not (eobp))
      (cond
       ((looking-at (format "\\*\\{2,%s\\} %s +.*$"
			    init.org/depth prefix))
	(princ (concat "\n" (match-string 0) " "))
	(setq init-org-block 0)
	;; add to prev line number here (minus previous)
	(org-narrow-to-subtree)
	(while (org-next-block-if-any)
	  (cond (
		 (looking-at "^[\t ]*#\\+begin_src +\\(emacs-lisp\\|elisp\\)\\([\t ]+.*\\)?$")
		 (let ((l (match-end 0)))
		   (search-forward "#+end_src")
		   (setq init-org-block (+ 1 init-org-block))
		   (princ init-org-block) (princ (line-number-at-pos))
		   ;;(eval-region l (match-beginning 0))
		   (princ init-org-block)
		   ;; (princ (line-number-at-pos))
		   ;; < [2021-12-28 Tue] need to keep the pos before narrowing
		   ;;(princ(path-with-line-number))
		   ;;(message (path-with-line-number))
		   ))))
	(widen)
	)
       ((looking-at "^\\* ")
	(message "%s complete" block)
	(goto-char (point-max))))
      (try--ignore-user-error 'org-forward-element)
      )))

markers

(what-line) (marker-position (point-marker)) (line-number-at-pos (point) t)

binding super

s-l is already bound to increase master width factor under awesomeWM (see with s-s)

  (define-key global-map (kbd "s-l") 'magit-status)

(add-hook 'find-function-search-for-symbol 'recenter-top-bottom) (remove-hook 'find-function-search-for-symbol 'recenter-top-bottom)

ws-trim

  ;;(use-package ws-trim-mode

custom.el

custom variables and custom faces are saved in custom.el load them after the themes

    ; custom-set faces and custom-variables goes here
  (setq custom-file (expand-file-name "custom.el" user-emacs-directory))
  (load-file custom-file)
  (set-cursor-color "light goldenrod")
  (set-mouse-color "goldenrod")

desktop restore

emacs#Saving Emacs Sessions

  (desktop-save-mode 1)

emacs run launcher

https://www.reddit.com/r/unixporn/comments/s7p7pr/so_which_run_launcher_do_you_use_rofi_or_dmenu/

    (defun emacs-run-launcher () "Create and select a frame called
    emacs-run-launcher which consists only of a minibuffer and has
    specific dimensions. Run counsel-linux-app on that frame, which is
    an emacs command that prompts you to select an app and open it in
    a dmenu like behaviour. Delete the frame after that command has exited"
         (interactive)
         (with-selected-frame
             (make-frame
              '(
                (name . "emacs-run-launcher")
                (minibuffer . only) (width . 120)
                (height . 11)))
           (unwind-protect (counsel-linux-app) (delete-frame))))

path

Sat here because it seems something is resetting it somewhere along the way

  (setenv "PATH"
".\
:/bin\
:/usr/bin\
:/usr/local/bin\
:~/opt/nim/bin\
:/f/sh\
")
(setq exec-path (split-string (getenv "PATH") path-separator))

tip

(shell-command-to-string "echo $PATH" ) (setq shell-command-switch "-ic")

pdf-tools

et org-pdftools

dired rsync

  (use-package dired-rsync
  :config
  (bind-key "C-c C-r" 'dired-rsync dired-mode-map))

super-save

    (use-package super-save
    :ensure t
    :config
    (super-save-mode +1))
  (setq super-save-remote-files nil)
  (setq super-save-auto-save-when-idle nil)

  (defcustom super-save-hook-triggers
    '(mouse-leave-buffer-hook focus-out-hook)
    "A list of hooks which would trigger `super-save-command'."
    :group 'super-save
    :type '(repeat symbol)
    )

Add the following to your Emacs config to enable super-save:

(super-save-mode +1) (super-save-mode nil)

If you want to enable the additional feature of auto-saving buffers when Emacs is idle, add the following as well:

(setq super-save-auto-save-when-idle t)

At this point you can probably switch off the built-in auto-save-mode (unless you really care about its backups):

(setq auto-save-default nil)

Configuration

super-save will save files on command (e.g. switch-to-buffer) and hook triggers (e.g. focus-out-hook).

Both of those are configurable via super-save-triggers and super-save-hook-triggers. Here's a couple of examples:

;; add integration with ace-window (add-to-list 'super-save-triggers 'ace-window)

;; save on find-file (add-to-list 'super-save-hook-triggers 'find-file-hook)

Sometimes you might want to exclude specific files from super-save. You can achieve this via super-save-exclude, for example:

(setq super-save-exclude '(".gpg"))

blimp

    (use-package blimp)
  (add-hook 'image-mode-hook 'blimp-mode)

end message

    (minibuffer-message
   "init.org complete %ss"
   (time-to-seconds (time-subtract (current-time) init.org-start-time )))

(dired-sidebar-toggle-sidebar)

early-init.el

info:emacs#Early Init File

  
  ;; Temporarily reduce garbage collection during startup
  (defconst sanityinc/initial-gc-cons-threshold gc-cons-threshold
    "Initial value of `gc-cons-threshold' at start-up time.")
  (setq gc-cons-threshold (* 128 1024 1024))
  (add-hook 'after-init-hook
     (lambda () (setq gc-cons-threshold sanityinc/initial-gc-cons-threshold)))

  (setq package-enable-at-startup nil)

emacs 27 early-init.el

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

;; Emacs 27.1 introduced early-init.el, which is run before init.el, before
;; package and UI initialization happens, and before site files are loaded.

;; A big contributor to startup times is garbage collection. We up the gc
;; threshold to temporarily prevent it from running, then reset it later by
;; enabling `gcmh-mode'. Not resetting it will cause stuttering/freezes.
(setq gc-cons-threshold most-positive-fixnum)

;; Prevent unwanted runtime compilation for gccemacs (native-comp) users;
;; packages are compiled ahead-of-time when they are installed and site files
;; are compiled when gccemacs is installed.
;; REVIEW Remove after a month
(setq comp-deferred-compilation nil
      native-comp-deferred-compilation nil)

;; In noninteractive sessions, prioritize non-byte-compiled source files to
;; prevent the use of stale byte-code. Otherwise, it saves us a little IO time
;; to skip the mtime checks on every *.elc file.
(setq load-prefer-newer noninteractive)

;; In Emacs 27+, package initialization occurs before `user-init-file' is
;; loaded, but after `early-init-file'. Doom handles package initialization, so
;; we must prevent Emacs from doing it early!
(setq package-enable-at-startup nil)
(fset #'package--ensure-init-file #'ignore)  ; DEPRECATED Removed in 28