With a little side of applesauce...

Thursday, October 27, 2011

EMACS - TRAMP remote file access over SSH

TRAMP is the main reason that I left Eclipse and returned to EMACS. The Eclipse remote file access over SSH was clunky, (or possibly non-existent at the time). TRAMP is simple, (once I give you some tips), and is much faster than Eclipse. It also works on all platforms, (though you will need to use Cygwin on Windows).

First, I add the following to my .emacs:
;; tramp
(require 'tramp)
(setq tramp-default-method "scp")

This makes sure it is available to EMACS, (though it may not be necessary now that TRAMP is bundled in newer versions of EMACS), and sets the default method to SCP.

Second, you will want to set up key-based authentication as described in my post, "ssh authentication through public/private keypairs". This is not necessary, (and may be prohibited by your security policies), but it makes your remote file interaction seamless. If you don't setup key-based authentication, TRAMP will prompt you everytime that you login to the remote machine, so no worries.

Now, start EMACS, and hit C-x C-f and type the following and hit :

TRAMP will negotiate the SSH handshake, and prompt you for a password if you didn't setup key-based authentication. You should now see a listing of contents in your remote directory, (Dired). At this point, navigate and open/close and edit files just as if you were on your local machine. Very cool!

Don't forget to bookmark oft-used locations, (C-x r m)!


1. I always leave a local file open in EMACS, (usually .emacs), as sql-mode will try to search for psql on the remote machine when your current buffer is remote. Therefore, I switch to my local file before I start a new SQL-mode buffer.

2. There can be a short delay before the remote file is written if there are network issues, or if the SSH handshake takes longer than normal. Try reloading your web browser again if your changes didn't show. (Or, make sure that you saved your changes :) ).

3. I reload any buffer that is edited via a different program. For instance, I am working in EMACS, but visit the remote file using VIM in a regular shell session. Remember that the buffer is local and will overwrite any changes made locally to the file, if you save the buffer without reloading.

4. Some commands in Eshell don't work correctly with TRAMP, (ie grep). Therefore, I usually don't use Eshell for 'real' shell interaction with remote files. (Hence point #3).

EMACS - bookmarks

I can't live without bookmarks in EMACS. They allow you to bookmark local AND remote files. It's pretty sweet to use a bookmark to automatically activate TRAMP and edit files over SSH!

Here are the two keyboard shortcuts that I use:
C-x r l = list bookmarks
C-x r m = bookmark with current buffer

Here is my .emacs configuration:
;; bookmarks

(require 'bookmark)
;(bookmark-load "~/.emacs.bmk")

(defun bookmark-to-abbrevs ()
"Create abbrevs based on `bookmark-alist'."
(dolist (bookmark bookmark-alist)
(let* ((name (car bookmark))
(file (bookmark-get-filename name)))
(define-abbrev global-abbrev-table name file))))

(defadvice bookmark-jump (after bookmark-jump activate)
(let ((latest (bookmark-get-bookmark bookmark)))
(setq bookmark-alist (delq latest bookmark-alist))
(add-to-list 'bookmark-alist latest)))


EMACS - sql-mode connect to multiple databases

I just wanted to show my setup for connecting to multiple databases on multiple hosts via sql-mode in EMACS:

;; sql
(setq sql-connection-alist
(sql-name "host1_db1")
(sql-product 'postgres)
(sql-server "host1.example.com")
(sql-user "db1user")
(sql-password "")
(sql-database "db1")
(sql-port 5432))
(sql-name "host2_db1")
(sql-product 'postgres)
(sql-server "host2.example.com")
(sql-user "db2user")
(sql-password "")
(sql-database "db2")
(sql-port 5432))
(sql-name "local_mydb")
(sql-product 'postgres)
(sql-server "localhost")
(sql-user "myuser")
(sql-password "")
(sql-database "mydb")
(sql-port 5432))))

(defun sql-pool-host1_db1 ()
(sql-connect-preset 'pool-host1_db1))
(defun sql-pool-host2_db1 ()
(sql-connect-preset 'host2_db1))
(defun sql-pool-local_mydb ()
(sql-connect-preset 'pool-local_mydb))

;; this makes all it all happen via M-x sql-pool-host1_db1, etc.
(defun sql-connect-preset (name)
"Connect to a predefined SQL connection listed in `sql-connection-alist'"
(eval `(let ,(cdr (assoc name sql-connection-alist))
(flet ((sql-get-login (&rest what)))
(sql-product-interactive sql-product)))))

;; names the buffer *SQL: <host>_<db>, which is easier to
;; find when you M-x list-buffers, or C-x C-b
(defun sql-make-smart-buffer-name ()
"Return a string that can be used to rename a SQLi buffer.
This is used to set `sql-alternate-buffer-name' within
(or (and (boundp 'sql-name) sql-name)
(concat (if (not(string= "" sql-server))
(or (and (string-match "[0-9.]+" sql-server) sql-server)
(car (split-string sql-server "\\.")))

(add-hook 'sql-interactive-mode-hook
(lambda ()
(setq sql-alternate-buffer-name (sql-make-smart-buffer-name))

sql-make-smart-buffer-name () is added to make it easier to find the buffer when you have twenty-thirty buffers open.

EMACS - reload .emacs made easy

I use the following function to simplify reloading my .emacs:

;; Reload .emacs file by typing: Mx reload.
(defun reload () "Reloads .emacs interactively."
(load "~/.emacs"))

EMACS - Coldfusion keyboard shortcuts

Here are some Coldfusion keyboard shortcuts that I use in EMACS to speed up my development. Throw these in your .emacs and M-x load-file:

;; coldfusion

(defun insert-cfdump-tag ()
"Insert cf markup <cfdump var='' />."
(insert "<cfdump var='##' />")
(backward-char 5)
(defun insert-cfabort-tag ()
"Insert cf markup <cfabort />."
(insert "<cfabort />")
(defun insert-cfcomment-tag ()
"Insert CF comment."
(insert "<!--- --->")
(backward-char 5)
(defun insert-cfoutput-tag ()
"Insert CFoutput."
(insert "<cfoutput>##</cfoutput>")
(backward-char 12)
(defun insert-cfparam-tag ()
"Insert CFparam."
(insert "<cfparam name='' default='' />")
(backward-char 15)
(defun insert-cfset-tag ()
"Insert CFset."
(insert "<cfset />")
(backward-char 3)
(defun insert-cflocation-tag ()
"Insert CFlocation."
(insert "<cflocation url='' addtoken='no' />")
(backward-char 17)
(defun insert-cftry-tag ()
"Insert CFtry."
(insert "<cftry>\n\n<cfcatch type="Any">\n\n</cfcatch>\n</cftry>")
(backward-char 42)
(defun insert-cfbreak-tag ()
"Insert cf markup <cfbreak />."
(insert "<cfbreak />")
(defun insert-cfobject-tag ()
"Insert CFobject."
(insert "<cfobject name='' component='' />")
(backward-char 17)
(defun insert-cfquery-tag ()
"Insert CFquery."
(insert "<cfquery datasource='' name=''>\n\n</cfquery>")
(backward-char 24)
(defun insert-cfqueryparam-tag ()
"Insert CFqueryparam."
(insert "<cfqueryparam value='##' cfsqltype='cf_sql_varchar'>,")
(backward-char 31)
(defun insert-cfvariable-tag ()
"Insert CF ##."
(insert "##")
(backward-char 1)
(defun insert-cfargument-tag ()
"Insert cfargument."
(insert "<cfargument name='' type='string' required='true' />")
(backward-char 34)
(defun insert-cffunction-tag ()
"Insert cffunction."
(insert "<cffunction name=''\nreturntype=''\naccess='public'\nhint=''\n>\n\n</cffunction>")
(backward-char 56)
(defun insert-cfcomponent-tag ()
"Insert cfcomponent."
(insert "<cfcomponent name=''\ndisplayname=''\nhint=''\n>\n\n</cfcomponent>")
(backward-char 42)
(defun insert-cfloop-tag ()
"Insert cfloop list."
(insert "<cfloop >\n\n</cfloop>")
(backward-char 12)
(defun insert-cfinclude-tag ()
"Insert cfinclude."
(insert "<cfinclude template='' />")
(backward-char 4)
; define some keys only when the major mode html-mode is active
(add-hook 'nxhtml-mode-hook
(lambda ()
(local-set-key (kbd "C-S-d") 'insert-cfdump-tag)
(local-set-key (kbd "C-S-a") 'insert-cfabort-tag)
(local-set-key (kbd "C-S-t") 'insert-cftry-tag)
(local-set-key (kbd "C-S-m") 'insert-cfcomment-tag)
(local-set-key (kbd "C-S-o") 'insert-cfoutput-tag)
(local-set-key (kbd "C-S-p") 'insert-cfparam-tag)
(local-set-key (kbd "C-S-s") 'insert-cfset-tag)
;(local-set-key (kbd "C-S-n") 'insert-cflocation-tag)
(local-set-key (kbd "C-S-b") 'insert-cfbreak-tag)
(local-set-key (kbd "C-S-i") 'insert-cfinclude-tag)
(local-set-key (kbd "C-S-q") 'insert-cfquery-tag)
(local-set-key (kbd "C-S-u") 'insert-cfqueryparam-tag)
(local-set-key (kbd "C-S-v") 'insert-cfvariable-tag)
(local-set-key (kbd "C-S-g") 'insert-cfargument-tag)
(local-set-key (kbd "C-S-f") 'insert-cffunction-tag)
(local-set-key (kbd "C-S-c") 'insert-cfcomponent-tag)
(local-set-key (kbd "C-S-l") 'insert-cfloop-tag)

This relies on nxhtml mode, which I download into ~/Documents/emacs and load with the following in my .emacs:

(load "~/Documents/emacs/nxhtml/autostart.el")

Also, you can tell EMACS to use nxhtml-mode for cfm and cfc files with this:
    (add-to-list 'auto-mode-alist '("\\.cfm\\'" . nxhtml-mode))
(add-to-list 'auto-mode-alist '("\\.cfc\\'" . nxhtml-mode))

Tuesday, October 18, 2011

BASH - aliases to modify and reload your .bashrc

Here are some quicky aliases to open my .bashrc with vi, and to source it after I modify it:
alias vibashrc='vi ~/.bashrc'

alias reload='. ~/.bashrc'

BASH - useful recursive chmod aliases

I am always performing chmod operations on folders and files, and wrote a couple of quick BASH functions (.bashrc) to help me:
function recursivechmoddir() { for d in $(sudo find ${2} -type d); do sudo chmod -R ${1} ${d} ; done; }

function recursivechmodfile() { for f in $(sudo find ${2} -type f); do sudo chmod -R ${1} ${f} ; done; }

VMware - resize LVM partitions on guest

Resizing LVM Volumes in Linux:
By David Maphis 4/29/2008


Wednesday, October 5, 2011

Windows 7 / Apache 2.2 - (OS 5)Access is denied. : file permissions deny server access:

If Apache is throwing a strange Access Denied message for a single directory on Windows 7, open up Windows Explorer, and browse to the problem folder. If it displays in green, then the contents are encrypted, and Windows 7 won't serve the file. Cool stuff!

Here is the browser error:
You don't have permission to access /simplejquerydropdown/index.html on this server.

Here is the error.log:
(OS 5)Access is denied. : file permissions deny server access:

The fix is to unencrypt the contents by:

1. right-click on the folder and choose properties.
2. General->Advanced
3. Uncheck 'Encrypt contents to secure data'
4. Click OK
5. Click OK to close the Properties dialogue box
6. Choose to apply these changes to subfolders and files, and click OK

Sunday, October 2, 2011

Windows 7 - remove GRUB and restore windows bootloader

The easiest way to restore the Windows bootloader on Windows 7 is to do the following:

1. Download 32-bit bootsect.exe
2. Unzip it into C:\Windows\system32
3. Open cmd.exe
4. run: bootsect /nt60 all /mbr
5. reboot

Beats having to track down a Windows 7 installation DVD :)