Default Operations

  • Moving the Cursor and Screen
  • Make/kill/move windows frames buffers
  • Projectile, Helm and Smex
  • Parentheses
  • Directories
  • Clip board (kill ring)
  • PDF tools and command line history

Parentheses

Skeleton pairs are included in Emacs. Configure them and you get two brackets of the types you specify with cursor in between when you insert one. Code below. The Smart Parentheses package follows. This hydra configuration is a little different than the others as the hydra is configured within the Smart Parens package. The :commands argument for the use-package implementation defers the loading of everything within the use-package declaration until those commands are called. So you only initialize the Smart Parens stuff after you call web-mode, smartparens-mode, or the parens hydra (Parentheses_/body). This is good because I don't use the parens hydra a lot. It's for moving quickly between expressions, parentheses. The slurp and barf grab characters and words and pull them into the brackets or spit them out of it. I just move around, mark the stuff, then cut and paste. It's faster for me. The juggling part is also for me largely uselesss. What I do use sometimes are the sp-wrap-round and sp-change inner. The wrap round puts quotes, or brackets around your marked region, and the change inner removes everything within the brackets and lets you paste something else. I have a region marking hydra that allows for a kind of hippy expand, which expands the region to everything within the brackets and I use that more often.



	;insert pairs
(setq skeleton-pair t)
(setq skeleton-pair-on-word t)
(bind-key "\("   'skeleton-pair-insert-maybe)
(bind-key "\["  'skeleton-pair-insert-maybe)
(bind-key "\{"  'skeleton-pair-insert-maybe)
 (bind-key "\"" 'skeleton-pair-insert-maybe)
(bind-key  "\'" 'skeleton-pair-insert-maybe)
(bind-key "\<"  'skeleton-pair-insert-maybe)

;Smart Parentheses
(use-package smartparens
:diminish smartparens-mode
:diminish smartparens-strict-mode
:after hydra
:commands (web-mode Parentheses_/body smartparens-mode)
:init
;define title generator function
(defun with-material (icon str &rest height v-adjust)
      (s-concat (all-the-icons-material icon :v-adjust (or v-adjust 0) :height (or height 1)) " " str))
;generate hydra title
(defvar parens-title (with-material "code" "Parentheses"))
:config
(require 'smartparens-config)
(smartparens-global-mode)
(setq smartparens-global-strict-mode 0)
(show-smartparens-global-mode)
;generate hydra
:pretty-hydra
;pretty-hydra-define _Parentheses
( Parentheses_ (:color pink :quit-key "q" :title parens-title);end heads
("Moving"
         (("a" sp-beginning-of-sexp "Beginning")
	      ("e" sp-end-of-sexp  "End"   )
	      ("f" sp-forward-sexp "Forward")
	      ("b" sp-backward-sexp "Backward")
	      ("n" sp-down-sexp "Down")
	      ("N" sp-backward-down-sexp "Bw Down")
	      ("p" sp-up-sexp "Up" )
	      ("P" sp-backward-up-sexp "Bw Up"))
"Slurping & barfing"
              (("h" sp-backward-slurp-sexp "Bw Slurp")
	      ("H" sp-backward-barf-sexp "Bw Barf")
	      ("l" sp-forward-slurp-sexp "Slurp")
	      ("L" sp-forward-barf-sexp "Barf"))
"Wrapping"
	      (("R" sp-rewrap-sexp "Rewrap")
	      ("u" sp-unwrap-sexp "Unwrap")
	      ("U" sp-backward-unwrap-sexp "Bw Unwrap")
	      ("(" sp-wrap-round "Wrap")
	      ("{" sp-wrap-curly "Wrap")
	      ("[" sp-wrap-square "Wrap"))
"Sexp juggling"
	      (("S" sp-split-sexp "Split")
	      ("s" sp-splice-sexp "Splice")
	      ("r" sp-raise-sexp "Raise")
	      ("j" sp-join-sexp "Join")
	      ("t" sp-transpose-sexp "Transpose")
	      ("A" sp-absorb-sexp "Absorb")
	      ("E" sp-emit-sexp "Emit")
	      ("o" sp-convolute-sexp "Convolute"))
"Editing"
	      (("c" sp-change-inner "Change" :color blue)
	      ("C" sp-change-enclosing "Change" :color blue )
	      ("k" sp-kill-sexp "Kill")
	      ("K" sp-backward-kill-sexp "Bw Kill")
	      ("w" sp-copy-sexp "Copy" )
          ("h" hydra-helm/body "Return To Helm" :color blue )
          ("<SPC>" nil "Quit" :color blue )
);end section
);end heads
);end hydra
:bind
("<C-m> p" . Parentheses_/body)
);end smartparens

image of emacs posiedon configuration parentheses hydra code


Directories Defaults

Most of this code sets up good defaults for emacs directories management. Hiding details by default makes the screen legible. Configuring C-a to move the cursor back to the start of the directory files. Making the directory if it doesn't exist. The function to create a directory. Getting dired mode role over to the first file when you get to the end. All of these things in emacs require default configuration. Here it is.



;dired movement defaults
(require 'dired)

;hide dir details
(add-hook 'dired-mode-hook 'dired-hide-details-mode t)

;; Make dired less verbose
(setq-default dired-details-hidden-string "")

; Move files between split panes
(setq dired-dwim-target t)

;; C-a is nicer in dired if it moves back to start of files
(defun dired-back-to-start-of-files ()
(interactive)
(backward-char (- (current-column) 2)))
(define-key dired-mode-map (kbd "C-a") 'dired-back-to-start-of-files)
(define-key dired-mode-map (kbd "k") 'dired-do-delete)

;; M-up is nicer in dired if it moves to the fourth line - the first file
(defun dired-back-to-top ()
(interactive)
(beginning-of-buffer)
(dired-next-line 4))
(define-key dired-mode-map (vector 'remap 'beginning-of-buffer) 'dired-back-to-top)
(define-key dired-mode-map (vector 'remap 'smart-up) 'dired-back-to-top)

;; M-down is nicer in dired if it moves to the last file
(defun dired-jump-to-bottom ()
(interactive)
(end-of-buffer)
(dired-next-line -1))
(define-key dired-mode-map (vector 'remap 'end-of-buffer) 'dired-jump-to-bottom)
(define-key dired-mode-map (vector 'remap 'smart-down) 'dired-jump-to-bottom)

;; Delete with C-x C-k to match file buffers and magit
(define-key dired-mode-map (kbd "C-x C-k") 'dired-do-delete)
(eval-after-load "wdired"
'(progn
(define-key wdired-mode-map (kbd "C-a") 'dired-back-to-start-of-files)
(define-key wdired-mode-map (vector 'remap 'beginning-of-buffer) 'dired-back-to-top)
(define-key wdired-mode-map (vector 'remap 'end-of-buffer) 'dired-jump-to-bottom)))
;my-dired-create-file
(eval-after-load 'dired
  '(progn
     (define-key dired-mode-map (kbd "c") 'my-dired-create-file)
     (defun create-new-file (file-list)
       (defun exsitp-untitled-x (file-list cnt)
         (while (and (car file-list) (not (string= (car file-list) (concat "untitled" (number-to-string cnt) ".txt"))))
           (setq file-list (cdr file-list)))
         (car file-list))
(defun exsitp-untitled (file-list)
         (while (and (car file-list) (not (string= (car file-list) "untitled.txt")))
           (setq file-list (cdr file-list)))
         (car file-list))
(if (not (exsitp-untitled file-list))
           "untitled.txt"
         (let ((cnt 2))
           (while (exsitp-untitled-x file-list cnt)
             (setq cnt (1+ cnt)))
           (concat "untitled" (number-to-string cnt) ".txt"))))
(defun my-dired-create-file (file)
       (interactive
        (list (read-file-name "Create file: " (concat (dired-current-directory) (create-new-file (directory-files (dired-current-directory))))))
        )
       (write-region "" nil (expand-file-name file) t)
       (dired-add-file file)
       (revert-buffer)
       (dired-goto-file (expand-file-name file)))
)
 ) ;end my dired create file

;backup directory
(setq backup-directory-alist '(("." . "~/backups")))

;if directory doesn't exist make it
(defun my-create-non-existent-directory ()
(let ((parent-directory (file-name-directory buffer-file-name)))
		  (when (and (not (file-exists-p parent-directory))
				 (y-or-n-p (format "Directory `%s does not exist! Create it?" parent-directory)))
		(make-directory parent-directory t))))
(add-to-list 'find-file-not-found-functions 'my-create-non-existent-directory)

Neo Tree is Cool

But I don't use it. I have a function that toggles on/off icons in dired buffers and don't need to open up and navigate directories in side window. I just use dired mode. But here it is anyway.



;neotree
(use-package neotree
:config
(setq neo-theme (if (display-graphic-p) 'icons 'arrow))
(require 'all-the-icons)
(require 'neotree)
(setq-default neo-smart-open t)
;only 'icons' works with all-the-icons
(setq neo-theme 'icons) ; 'classic, 'nerd, 'ascii, 'arrow
(setq neo-vc-integration '(face char))
(setq neo-show-hidden-files t)
(setq neo-toggle-window-keep-p t)
(setq neo-force-change-root t)
(setq neo-window-width 35)
;; face customizations
(set-face-attribute 'neo-vc-edited-face nil :foreground "#E2C08D")
(set-face-attribute 'neo-vc-added-face nil :foreground "green4")
(setq all-the-icons-color-icons t)
 (add-hook 'neotree-mode-hook
(lambda ()
 		(setq-local mode-line-format nil)
 		(setq-local display-line-numbers nil)
 		(local-set-key (kbd "C-s") 'isearch-forward)
 		(local-set-key (kbd "C-M-s") 'isearch-forward-regexp)
 		(local-set-key (kbd "C-r") 'isearch-backward)
 		(local-set-key (kbd "C-M-r") 'isearch-backward-regexp)))
:bind
("<f9>" . neotree-toggle)
);end neotree

image of emacs posiedon configuration neo tree code


Image-dired

This is a cool set up. Image-dired I think you need to download from the net. It's not on Melpa. The same with dired+, and image+. These guys together with image-magick enable image viewing and resizing in buffers. You can rotate and delete the images as well. Image-dired (or maybe it's image+) makes thumbnails in a directory you specify below. You will need to install image-magick and for that on windows you will need an emacs version compiled for windows with image-magick and pdf-tools support. Of course the image action here is just a convenience, internet explorer works fine (and honestly I only use emacs for images 20% of the time), and for any serious work you would use the shell or another program. I use Inkscape, Gimp, and Faststone Image Viewer. Btw, everything below with a -p on the end of it is a path to a library or executable defined earlier. See earlier emacs posts.



;dired+
(add-to-list 'load-path dired+-p)
(require 'dired+)

;image-dired
;image-mode (image[jpg]-mode)
(setq image-magick-enabled t)

;image-dired
(require 'image-dired)
(add-to-list 'load-path image-magick-p)
(setq  image-dired-dir   image-dired-p)

;image+
(use-package image+
:defer t
:load-path image+-p
;:disabled
:config
(require 'image)
(eval-after-load 'image '(require 'image+))
(require 'image-file)
(setq imagex-quiet-error t)
(eval-after-load 'image+ '(imagex-auto-adjust-mode 1))
(eval-after-load 'image+ '(imagex-global-sticky-mode 1))

:bind (:map image-mode-map
              ("=" . imagex-sticky-zoom-in)
              ("-" . imagex-sticky-zoom-out)
              ("m" . imagex-sticky-maximize)
              ("g" . imagex-sticky-restore-original)
              ("S" . imagex-sticky-save-image)
              ("r" . imagex-sticky-rotate-right)
              ("l" . imagex-sticky-rotate-left)
              ("/" . imagex-sticky-binding/body))
);end image+


Directories Hydra

This directories hydra is super useful. Remember, hydras simply consolidate functions you can call from the mini-buffer or with shortcuts defined in their respective packages. The functions I use the most in the hydra are create a directory and create a file. I also often will rename files. Rename is copy, and if you call it with two different directories open in adjacent windows it pre-fills the directory path to the path in the adjacent window so you easily move files from one directory to another. Yes, you can do all this from the shell or internet explorer, and I do usually use internet explorer for this. But when I need to do a lot of specific clean up and renaming in a directory I always use emacs. I'll toggle on and off the details as needed and enable often also icons just for kicks.



;define material icon function
(defun with-material (icon str &rest height v-adjust)
      (s-concat (all-the-icons-material icon :v-adjust (or v-adjust 0) :height (or height 1)) " " str))

;define dired-modes hydra title
(defvar dired-title (with-material "folder_open" "Directories"))

;define dired-modes hydra
(pretty-hydra-define  Directories_ ( :title dired-title :quit-key "q" :color pink )
("Mode"
   (("d" dired "Directory Choose")
    ("+" dired-create-directory "Create A Directory" )
    ("f" my-dired-create-file "Create A File")
    ("P" image-dired              "View All Images In Directory" )
    ("x" xah-open-in-external-app "Open In External Program")
    ("g" revert-buffer              "Refresh Directory" )
    ("~" dired-hide-details-mode "Show Details" :toggle t )
    ("i" all-the-icons-dired-mode "Directory With Icons" :toggle t )
    ("h" hydra-helm/body "Go To Hydra Helm" :color blue )
 );end mode

"Mark"
   (

    ("m" dired-mark "Mark Selection At Point" )
    ("u" dired-unmark "Unmark Selection At Point" )
    ("a" dired-toggle-marks "Mark Or Unmark All In Directory" :toggle t )
    ("A" dired-unmark-all-files "Unmark All Files")
    ("-" dired-change-marks "Change Marks")
    ("o" dired-find-file-other-window "Open File In Other Window" )
    ("C" dired-copy-filename-as-kill "Copy Selection Name")
    ("<SPC>" nil "Quit" :color blue )
);end mark

"Action"
   (

    ("D" dired-do-delete  "Delete Marked Sections")
    ("r" dired-do-rename "Rename Selection At Point" )
    ("c" dired-do-copy "Copy Marked Selections")
    ("M" dired-do-rename "Move Marked Selections")
    ("=" imagex-sticky-zoom-in "Zoom In On Image" )
    ("-" imagex-sticky-zoom-out "Zoom Out On Image" )
    ("R" imagex-sticky-rotate-right "Rotate Image Right" )
    ("L" imagex-sticky-rotate-left "Rotate Image Left" )
);end action
);end hydra body
);end pretty-hydra-dired
(bind-key "<C-m> d"  'Directories_/body)

image of emacs posiedon configuration directories code


Some Kill Ring Settings and Functions

Before they had clipboards they had kill-rings. I'm not asking. :smile: "Kill" is copy and "Yank" is paste. In Emacs myself (and most people) use M-w and C-y. I've never liked the M-w for cutting, but I use it anyway. I also have M-y to show the kill-ring in the helm buffer, which I use a lot.

Below is code to browse the kill-ring with C-c 9, which I rarely use. There's also some code to ensure you get the ents of the windows clipboard in your kill ring, which is really important.



; Remove text in active region if inserting text
(delete-selection-mode 1)
;clipboard is saved to kill-ring
(defun clipboard-to-kill-ring()
   "save the external clipboard contents to the kill ring"
   (interactive)
     (let ((clip (funcall interprogram-paste-function)))
       (when clip
         (kill-new clip)))
(defadvice yank (before maybe-copy-windows-clipboard (arg))
     (clipboard-to-kill-ring))
(ad-activate 'yank))
;Browse Kill Ring
 (use-package browse-kill-ring
:defer t
:config
(setq browse-kill-ring-highlight-current-entry t)
:bind
("C-c 9" . browse-kill-ring))

Easy Kill

Easy Kill gives an option to add a letter after M-w and save specific items, as follows:

M-w w: save word at point
M-w s: save sexp at point
M-w l: save list at point (enclosing sexp)
M-w d: save defun at point
M-w D: save current defun name
M-w f: save file at point
M-w b: save buffer-file-name or default-directory. - changes the kill to the directory name, + to full name and 0 to basename. The following keys modify the selection:

@: append selection to previous kill and exit. For example, M-w d @ will append current function to last kill.
C-w: kill selection and exit
+, - and 1..9: expand/shrink selection
0 shrink the selection to the initial size i.e. before any expansion
SPC: cycle through things in easy-kill-alist
C-SPC: turn selection into an active region
C-g: abort

Hungry delete follows that, and it's cool. You use C-d to delete, as usual, but all the empty space is deleted in one shot. So it pulls all the gaps out of the code. It also automatically deletes the entire line if you are at the left margin and the space is gone. So double C-d will delete all trailing white space between two paragraphs and then the next line of the next paragraph. Sanity kill back to indent works backwards. I just highlight the line and delete it.




(use-package easy-kill
:config
(global-set-key [remap kill-ring-save] #'easy-kill)
(global-set-key [remap mark-sexp] #'easy-mark))
;hungry delete
(use-package hungry-delete
:diminish
:config
(global-hungry-delete-mode))
;sanity delete
(defun sanityinc/kill-back-to-indentation ()
 "Kill from point back to the first non-whitespace character on the line."
 (interactive)
 (let ((prev-pos (point)))
   (back-to-indentation)
   (kill-region (point) prev-pos)))
(bind-key "C-M-<backspace>" 'sanityinc/kill-back-to-indentation)

Pdf Tools and Command Line history

PDF Tools of course require an emacs compiled with pdf tools support. See earlier blog posts for installing emacs (search for emacs or install)

paste/substring is a custom function you can use to copy a string, run this function, paste the string into the minibuffer, then paste the last 11 characters of the string anywhere you like (it's on the kill ring). This is useful to copy a youtube URL from the browser with C-c, run this function, paste the youtube URL into the minibuffer, Enter, then paste the Youtube ID anywhere you like (Youtube ID is last 11 ch of URL).



;start server so pdf-tools autostart when pdf is selected can use emacsclient to open in same instance
(server-start)
(add-hook 'TeX-after-compilation-finished-functions #'TeX-revert-document-buffer)
;command line history
(use-package command-log-mode
:commands (global-command-log-mode clm/toggle-command-log-buffer)
:config
(require 'command-log-mode)
(global-command-log-mode)
);end command-log mode
;substring
(defun paste/substring (astring)
  "Copy a string to clipboard"
(interactive "sAstring: ")
(with-temp-buffer
    (insert (substring astring -11))
    (clipboard-kill-region (point-min) (point-max))))

That’s all for now…