Bash prompt customizations

Some paths can be really long and annoying. Here's how you fix it.
NOTE: I am using 14.04. Your mileage may vary.

Reduce the size of the prompt

This simple trick checks if the length of the current directory path is greater than 30. In that case, it breaks it up into two chunks -- first 12 letters and the last 15.

__update_prompt1()                                                                                                                                                                     
{                                                                                                                                                                                     
   DIR=`pwd | sed -e "s!$HOME!~!"`                                                                                                                                                   
   if [ ${#DIR} -gt 30 ]; then                                                                                                                                                       
     CurDir=${DIR:0:12}....${DIR:${#DIR}-15}                                                                                                                                       
   else                                                                                                                                                                              
     CurDir=$DIR                                                                                                                                                                   
   fi                                                                                                                                                                                
} 

Before:
[user@hostname:/local/mnt/workspace/somefolder1/foldera/test]$
After:
[user@hostname:/local/mnt/w....a/test/]$


Personally, I like the one below. It replaces the folder names with a single letter.


__update_prompt2()                                                                                                                                                                    
{                                                                                                                                                                                     
    CurDir=`pwd | sed -e "s!$HOME!~!" | sed -re "s!([^/])[^/]+/!\1/!g"`                                                                                                               
} 

Before:
[user@hostname:/local/mnt/workspace/somefolder1/foldera/test]$
After:
[user@hostname:/l/m/w/s/f/test]$

All we need to do is update the PROMPT_COMMAND and PS1


PROMPT_COMMAND=__update_prompt2                                                                                                                                                       
export PROMPT_COMMAND=${PROMPT_COMMAND}                                                                                                                                                                                                                           
PS1='[\u@\h:${CurDir}]\$ '                                                                                                                                     
export PS1 

There is one other thing I like to do -- move the cursor to the newline
PS1='[\u@\h:${CurDir}]\n\$ '

The prompt looks like,

[user@hostname:/l/m/w/s/f/test]
$ ls


Adding git branch information to prompt along with git completion


First things first, download the git-completion.bash and git-prompt.sh files from https://github.com/git/git/tree/master/contrib/completion

Add these do the .bashrc


source ~/.git-completion.bash
source ~/.git-prompt.sh 

And finally, update the PS1

PS1='[\u@\h:${CurDir}]$(__git_ps1 " (%s)")\n\$ '

When the folder is a git repository it will automatically show the current git branch.

[user@hostname:/l/m/w/s/f/myrepo] (master)
$ ls -a
. .. .git hello 

You get git completion for free as well.

[user@hostname:/l/m/w/s/f/myrepo] (master)
$ git che [TAB]
check-mailmap   checkout        cherry          cherry-pick


Preserving the history across terminals



This can be done in three simple steps
  1. history -a : Append the new history lines (history lines entered since the beginning of the current Bash session) to the history file
  2. history -c : Clear the history list. This may be combined with the other options to replace the history list completely
  3. history -r : Read the history file and append its contents to the history list

Let's do this part of the PROMPT_COMMAND

PROMPT_COMMAND=__update_prompt2
export PROMPT_COMMAND="history -a; history -c; history -r; ${PROMPT_COMMAND}"

That's it!

[Vimdiff] cheat sheet

Sometimes I prefer using vimdiff especially when using it as a mergetool.  mattratleph has a handy cheatsheet.

git mergetool

In the middle file (future merged file), you can navigate between conflicts with ]c and [c.
Choose which version you want to keep with :diffget //2 or :diffget //3 (the //2 and //3 are unique identifiers for the target/master copy and the merge/branch copy file names).

:diffupdate (to remove leftover spacing issues)
:only (once you’re done reviewing all conflicts, this shows only the middle/merged file)
:wq (save and quit)
git add .
git commit -m “Merge resolved”

If you were trying to do a git pull when you ran into merge conflicts, type git rebase –continue.

vimdiff commands

]c :        - next difference
[c :        - previous difference
do          - diff obtain
dp          - diff put
zo          - open folded text
zc          - close folded text
:diffupdate - re-scan the files for differences
 

[Emacs] ediff marked files in dired

Found an awesome trick online to run ediff on marked files in dired.

(defun dired-ediff-marked-files ()
    "Run ediff on marked ediff files."
    (interactive)
    (set 'marked-files (dired-get-marked-files))
    (when (= (safe-length marked-files) 2)
        (ediff-files (nth 0 marked-files) (nth 1 marked-files)))

    (when (= (safe-length marked-files) 3)
        (ediff3 (buffer-file-name (nth 0 marked-files))
                (buffer-file-name (nth 1 marked-files))
                (buffer-file-name (nth 2 marked-files)))))


Another way (link)

(defun mkm/ediff-marked-pair ()
  "Run ediff-files on a pair of files marked in dired buffer"
  (interactive)
  (let* ((marked-files (dired-get-marked-files nil nil))
         (other-win (get-window-with-predicate
                     (lambda (window)
                       (with-current-buffer (window-buffer window)
                         (and (not (eq window (selected-window)))
                              (eq major-mode 'dired-mode))))))
         (other-marked-files (and other-win
                                  (with-current-buffer (window-buffer other-win)
                                    (dired-get-marked-files nil)))))
    (cond ((= (length marked-files) 2)
           (ediff-files (nth 0 marked-files)
                        (nth 1 marked-files)))
          ((and (= (length marked-files) 1)
                (= (length other-marked-files) 1))
           (ediff-files (nth 0 marked-files)
                        (nth 0 other-marked-files)))
          (t (error "mark exactly 2 files, at least 1 locally")))))

[Git] Remove files from last commit

You made a commit which has files that should not have been there. Worry not!

git reset --soft HEAD~1   // to soft reset (preserve changes)
git reset HEAD  /files/you/wish/to/unstage


You can now commit the staged files and checkout the unstaged files

git commit 
git checkout /files/you/wish/to/checkout


That's it!

[Emacs] Keyboard Macros!

Emacs keyboard macros are fun to use.

C-x ( to start recording
C-x ) to stop recording
C-x e to execute


If you want to repeat the macro N number of times,

C-u N C-x e

[Emacs] xterm mouse mode

Found another gem -- in order to use mouse in console mode (emacs -nw) use:

M-x xterm-mouse-mode

Provides basic functionality like scrolling and window selection. Best use when using gdb

[Emacs] Enable line numbers

Add the following to the .emacs file.

;; Show line numbers
(global-linum-mode t)
;; Separate text with space and |
(setq linum-format "%4d \u2502 ")

[Emacs] How to insert newline when replacing strings

To insert newline with replace-string use C-q C-j

e.g.

This;is;a;test

M-x replace-string <RET> ; <RET> C-q C-j

This
is
a
test

[emacs] Assign keyboard shortcuts to adjust buffer width and height

These are f*ucking handy!

(global-set-key (kbd "<f5>") 'balance-windows)
(global-set-key (kbd "<f6>") 'shrink-window)
(global-set-key (kbd "<f7<") 'enlarge-window)
(global-set-key (kbd "<f8>") 'enlarge-window-horizontally)
(global-set-key (kbd "<f9>") 'shrink-window-horizontally)

[emacs] Toggle read only mode

To ensure you don't accidentally change a file, enable the read-only mode.

M-x toggle-read-only

OR

C-x C-q

Very useful when using gdb

[emacs] Unwrap long line

To unwrap long lines

M-x toggle-truncate-lines

[emacs] search within a file

To search within a file

M-x occur
.. and it takes regular expressions as well.

[emacs] diff between buffers

To diff between buffers:

M-x ediff-buffers