Tag Archives: emacs

I’m making a note as I forgot which function was I using after not publishing  anything  for a while

In emacs the function is contained in the package htmlize. This guy made a function to directly have the output code with the css styles inline, as that is necessary when posting in wordpress blogs.

Using an interactive shell in Emacs for Windows you might enconter a bug that causes the shell process to terminate when you signal and eof (See point 7.6 here)
If, for example, you try:

/Program Files/Emacs/ cat >newfile
this is a test file
being created with the cat command
directly from the user input 
in shell.

Now, by pressing C-d (or C-c C-d) the input should finish here, and the prompt return, but what happens instead, is that the shell process terminates. Same thing occurs if you try to M-x comint-send-eof or if you pick an eof signal from the menu.

I had noticed that before (in my Windows emac, only not under Unix), but last night I found that an eof sign could be generated by typing C-q C-z.

I choose to set an alias and bind it to some keys in my .emacs to overcome the issue:

(defalias 'eof
  (read-kbd-macro "C-q C-z RET"))
(global-set-key [M-S-f8] 'eof)

Of course a better solution would be to advice the comint-send-eof to procede accordingly when in emacs for Windows. Anybody knows how to do it, or mind to share a stronger fix than this hack? Any feedback will be appreciated.

Update:
Actually there’s no need to set an alias, as I learned that this is also possible and more straight-forward:

(global-set-key [(meta shift f8)]
 '(lambda () (interactive) (execute-kbd-macro((read-kbd-macro "C-q C-z RET")))))

On how to delete a chunk of text contained in multiple lines: use sed to catch the range (/a/,/b/)

There were some javascript google ads calls from a page I downloaded via wget, doing:

 wget www.someSite.com/somePage.html > toCleanItUp.htlm

After highlighting all the page C-x h I did a M-x shell-command-on-region and used the following:

sed "/<script .*>/,/<\/script>/d" > nowItIsClean.html

If feeling lazy, (or if I don’t have the file opened already in an emacs buffer), there’s the straightforward way of using cat:

cat toCleanItUp.html | sed "/<script .*>/,/<\/script>/d" > nowItIsClean.html

Ah, the beauty of unix tools!

This was once the most important portion of elisp code I had put into my dot emacs.  Thanks to it I began to conciliate with the editor which I sort of resisted at first, by finding it foreign to my habits and liking. I was accustomed to the way Dreamveaver handled the indenting of selected text in blocks, so getting emacs to behave in such familiar and practical style was critical to ease the experience of using it in a daily basis -as I needed  a couple of years ago when entering a new position.

Pretty soon I saw why emacs was so superior in regard of its extensibility: with basic elisp knowledge and a few lines of code I was able to get indent/unindent function the way I wanted.  Now to select text as a block, I not longer needed to set the mark and point exactly from the beginning to the end of a line or group of lines. The code conveniently extended the highlighted area via the tab key, turning the sub-selection into a block containing all the text of the line(s) involved.

Besides, the selection was configured so to not disappear unless you click outside it, that is, while keeping  pressed the tab (or Shift-tab) key(s) you could get the text to shift continuously right (or left).

Having bound the tab key with the indentation functions required a few adjustment to make it context-sensitive. Here is how the tab key behaves after the changes:

  • First, to insert a real tab space, (when the cursor is before a word), you need to use Ctrl -q-tab.
  • If the text point is, at least, a space away from the end of a word, a standard tab-space is inserted.
  • If the text point is exactly at the end of a word, the tab uses the hippie-expand function to auto-complete the word. If Shift+tab are used instead, words are deleted backward one at a time up to the beginning of the line.
  • When editing in org-mode an exception was set to respect its visibility cycling function (org-mode cleverly uses the tab key to rotate the current state of tree and sub-trees).

Finally, Mac and PC users would probably appreciate the added function that makes Shift + click to end a selection of text, which is the default way on both platforms (I grabbed it here, from Dave Peck).

So, as you can see, the whole point of the code below is to ease the manual indentation of code. Not being comfortable with the automatic indentation in emacs, I like to avoid it at times, or for certain modes. Check the associated hack posted on how to deactivate it.

Please, have a look at the elisp lines. Remember that you could copy and paste all into the scratch buffer and do “M-x evaluate-buffer” to get them immediately working.

;; turn on transient mark mode
;;(that is, we highlight the selected text)
(transient-mark-mode t)

(setq my-tab-width 2)

(defun indent-block()
  (shift-region my-tab-width)
  (setq deactivate-mark nil))

(defun unindent-block()
  (shift-region (- my-tab-width))
  (setq deactivate-mark nil))

(defun shift-region(numcols)
" my trick to expand the region to the beginning and end of the area selected
 much in the handy way I liked in the Dreamweaver editor."
  (if (< (point)(mark))
    (if (not(bolp))    (progn (beginning-of-line)(exchange-point-and-mark) (end-of-line)))
    (progn (end-of-line)(exchange-point-and-mark)(beginning-of-line)))
  (setq region-start (region-beginning))
  (setq region-finish (region-end))
  (save-excursion
    (if (< (point) (mark)) (exchange-point-and-mark))
    (let ((save-mark (mark)))
      (indent-rigidly region-start region-finish numcols))))

(defun indent-or-complete ()
  "Indent region selected as a block; if no selection present either indent according to mode,
or expand the word preceding point. "
  (interactive)
  (if  mark-active
      (indent-block)
    (if (looking-at "\\>")
  (hippie-expand nil)
      (insert "\t"))))

(defun my-unindent()
  "Unindent line, or block if it's a region selected.
When pressing Shift+tab, erase words backward (one at a time) up to the beginning of line.
Now it correctly stops at the beginning of the line when the pointer is at the first char of an indented line. Before the command would (unconveniently)  kill all the white spaces, as well as the last word of the previous line."

  (interactive)
  (if mark-active
      (unindent-block)
    (progn
      (unless(bolp)
        (if (looking-back "^[ \t]*")
            (progn
              ;;"a" holds how many spaces are there to the beginning of the line
              (let ((a (length(buffer-substring-no-properties (point-at-bol) (point)))))
                (progn
                  ;; delete backwards progressively in my-tab-width steps, but without going further of the beginning of line.
                  (if (> a my-tab-width)
                      (delete-backward-char my-tab-width)
                    (backward-delete-char a)))))
          ;; delete tab and spaces first, if at least 2 exist, before removing words
          (progn
            (if(looking-back "[ \t]\\{2,\\}")
                (delete-horizontal-space)
              (backward-kill-word 1))))))))

(add-hook 'find-file-hooks (function (lambda ()
 (unless (eq major-mode 'org-mode)
(local-set-key (kbd "<tab>") 'indent-or-complete)))))

(if (not (eq  major-mode 'org-mode))
    (progn
      (define-key global-map "\t" 'indent-or-complete) ;; with this you have to force tab (C-q-tab) to insert a tab after a word
      (define-key global-map [S-tab] 'my-unindent)
      (define-key global-map [C-S-tab] 'my-unindent)))

;; mac and pc users would like selecting text this way
(defun dave-shift-mouse-select (event)
 “Set the mark and then move point to the position clicked on with
 the mouse. This should be bound to a mouse click event type.”
 (interactive “e”)
 (mouse-minibuffer-check event)
 (if mark-active (exchange-point-and-mark))
 (set-mark-command nil)
 ;; Use event-end in case called from mouse-drag-region.
 ;; If EVENT is a click, event-end and event-start give same value.
 (posn-set-point (event-end event)))

;; be aware that this overrides the function for picking a font. you can still call the command
;; directly from the minibufer doing: "M-x mouse-set-font"
(define-key global-map [S-down-mouse-1] 'dave-shift-mouse-select)

;; to use in into emacs for  unix I  needed this instead
; define-key global-map [S-mouse-1] 'dave-shift-mouse-select)

;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; this final line is only necessary to escape the *scratch* fundamental-mode
;; and let this demonstration work
(text-mode)

NOTE:
I revised the code and modified some things. Especially the function ‘my-unindent” in order to add some sophistication on how the shifting backwards now occurs. The main improvement is that deleting backwards will never lead to jumping to the previous line (and removing words from there) . Here’s how the movement to left is done when pressing Shift + tab:

  • killing word by word, if the insertion point is at the right of any text.
  • stepping back, in increments (set by the variable my-tab-width), BUT ALWAYS stopping at the beginning of the line when the cursor is at the left of any indented text.

You can see how much simpler the function looked before I decided to better it:

(defun my-unindent()
  "Unindent line, or block if it's a region selected"
  (interactive)
  (if mark-active
      (unindent-block)
    (if(not(bolp))(delete-backward-char 2 ))))

I know this is subjective, but it didn’t feel right being overridden by the editor rules on how the code should look. For quite a while until recently could only partially deactivate the mechanism that automatically handles indentation (there are dozens of functions and variables involved). Luckily I came across a hack that allows to turn off all syntactic indentation that happens within a mode.


; I don't want emacs making changes I can't control in regards of the indentation.
; This is a hairy issue but I want php to be just a major mode with syntax coloring and bracket balancing.

; to use PHP mode,
(autoload 'php-mode "php-mode" "PHP editing mode" t)
(add-to-list 'auto-mode-alist '("\\.php3\\'" . php-mode))
(add-to-list 'auto-mode-alist '("\\.php\\'" . php-mode))

(add-hook 'php-mode-hook
          '(lambda ()
             (define-key php-mode-map (kbd "C-c C-c") 'comment-or-uncomment-region)
             (setq tab-width 4)
             (highlight-regexp "&lt;\\?php" 'hi-blue)
             (highlight-regexp "\\?&gt;" 'hi-blue)))

(defun my-php-setup ()
  (local-set-key (kbd "TAB") 'tab-to-tab-stop)
  (local-set-key (kbd "{") 'self-insert-command) ; support for "{" needed
  (local-set-key (kbd "}") 'self-insert-command)
  (local-set-key (kbd ":") 'self-insert-command)
  (local-set-key (kbd ";") 'self-insert-command))

(add-hook 'php-mode-hook 'my-php-setup)

This is how I quickly pull and insert the subversion path within the emacs shell, as I often need the absolute URL when restoring to a file to previous version for example.

(defun svn-root ()
"get path to svn repository"
(interactive)
(insert (shell-command-to-string "svn info | awk -F ':' '/URL/' | cut -c 6- | tr -d '\n'")))

In emacs you use the function “occur” to find all occurrences of a string (or regexp) in a buffer. The matching lines are listed in another buffer named “*Occur*”, and you can click them there to navigate to the corresponding lines in the original buffer. That is, buffer ‘*Occur*’ acts as a hypertext index to your buffer.

Here’s a little bit of elisp that I wrote inside the dot emacs (the configuration to customize stuff) to re-define occur (well it’s actually a sort of wrapper of the function since itself isn’t touched and you can still call it with M-x occur ).

As the code is already commented, I’ll put it here without much explanation.

(defun my-occur (&optional arg)
 "Make sure to always put occur in a vertical split, into a narrower buffer at the side.
I didn't like the default horizontal split, nor the way it messes up the arrangement of windows in the frame or
the way in which the standard way uses a neighbor window."
  (interactive "P")
  (window-configuration-to-register ?y) ; store whatever frame configuratin we are currently in
  (occur (read-from-minibuffer "Regexp: "))
  (if (occur-check-existence)
      (progn
        (delete-other-windows)
        (split-window-horizontally)
        (enlarge-window-horizontally -10)
        (set-cursor-color "green")))
  (occur-procede-accordingly))

(defun occur-procede-accordingly ()
  "Switch to occur buffer or prevent opening of the occur window if no matches occured."
  (interactive "P")
  (if (not(get-buffer "*Occur*"))
      (message "There are no results.")
    (switch-to-buffer "*Occur*")))

(defun occur-check-existence()
  "Signal the existance of an occur buffer depending on the number of matches."
  (interactive)
  (if (not(get-buffer "*Occur*"))
      nil
    t))

(define-key global-map (kbd "C-S-o") 'my-occur)

(defun occur-mode-quit ()
  "Quit and close occur window. I want to press 'q' and leave things as they were before in regard of the split of windows in the frame.
This is the equivalent of pressing C-x 0 and reset windows in the frame, in whatever way they were,
plus jumping to the latest position of the cursor which might have been changed by using the links out
of any of the matches found in occur."
  (interactive)
  (switch-to-buffer "*Occur*")
  ;; in order to know where we put the cursor thay might have jumped from qoccur
  (other-window 1)                  ;; go to the main window
  (point-to-register ?1)            ;; store the latest cursor position
  (switch-to-buffer "*Occur*")      ;; go back to the occur window
  (kill-buffer "*Occur*")           ;; delete it
  (jump-to-register ?y)             ;; reset the original frame state
  (set-cursor-color "rgb:ff/fb/53") ;; reset cursor color
  (register-to-point ?1))           ;; re-position cursor

;; some key bindings defined below. Use "p" ans "n" as in dired mode (without Cntrl key) for previous and next line; just show occurrence without leaving the "occur" buffer; use RET to display the line of the given occurrence, instead of jumping to i,t which you do clicking instead;  also quit mode with Ctrl-g.
(define-key occur-mode-map (kbd "q") 'occur-mode-quit)
(define-key occur-mode-map (kbd "C-q") 'occur-mode-quit)
(define-key occur-mode-map (kbd "C-g") 'occur-mode-quit)
(define-key occur-mode-map (kbd "C-RET") 'occur-mode-goto-occurrence-other-window)
(define-key occur-mode-map (kbd "C-<up>") 'occur-mode-goto-occurrence-other-window)
(define-key occur-mode-map (kbd "RET") 'occur-mode-display-occurrence)
(define-key occur-mode-map (kbd "p") 'previous-line)
(define-key occur-mode-map (kbd "n") 'next-line)

I couldn’t get rid of the annoying beep when working in emacs in no-window mode. I tried various other things like
(set-message-beep 'silent), or (setq visible-bell t) which worked in a unix environment, but not when calling emacs with the ‘-nw’ option.
Finally I found that (setq ring-bell-function 'ignore)did the trick for me and saved me having to mute the speakers.

A quick note so I can remember the way to skip some fields at the beginning of a line printing the rest without further specifications (as it’d be tedious to have to write say: awk '{print $2,$3,$4,$5,$6,$7,$8,$9...$n}')
The solution found here explains a simple way: just to print the substring starting from the nth field.
In my example where I pull the history of commands filtering for “find” I skip the first field in order to output without the command number:
history | grep find | awk '{print substr($0, index($0,$2))}'
(for what it matters, turns to be convenient for me inside the emacs shell, as I can select the line I want doing fewer keystrokes:C-a SPC, activates the selection mark at the beginning, C-e extends selection to the end of the line and C-w copies it to customize and reuse it)

Later observation:
Actually, I found a simpler (hence, better) way using the cut command:

history | grep find | cut -d ' ' -f3-

where “-d ‘ ‘” is the separation field and -f3- means from the third field on. With cut you don’t need to know which is the last field, leaving the second part of the range empty implies “up to the end”.

The windows split capabilities of emacs is something I didn’t know before and became quite an important aspects of my editing work habits.

An emacs window is a viewport that looks into a buffer. The emacs screen begins by displaying a single window, but this screen space can later be divided among two or more windows. On the screen, the current window holds the cursor and views the current buffer.
A windows views one buffer at a time. Multiple windows can view one buffer, each window may view different parts of the same buffer, and each window carries its own value of Point. Any change to a buffer will be reflected in all the windows viewing that buffer.

Even with rudimentary knowledge of elisp I managed to hack a few functions to go into my dot file (the configuration file of the editor) to deal with them.

For instance, I depend a lot on this is one in my workflow as I happen to need several files open simultaneously, plus the shell, some folder in dired mode, etc. With it I can be sort of zooming in and out, maximizing any buffer and going back to the split as I please .

;; I want to be able to conmute between a split and a single window (sort of "C-x 1" for the one on focus)
(defun toggle-windows-split()
"Switch back and forth between one window and whatever split of windows we might have in the frame. The idea is to maximize the current buffer, while being able to go back to the previous split of windows in the frame simply by calling this command again."
(interactive)
(if (not(window-minibuffer-p (selected-window)))
(progn
(if (< 1 (count-windows))
(progn
(window-configuration-to-register ?u)
(delete-other-windows))
(jump-to-register ?u))))
(my-iswitchb-close))

Then, the convenient key binding:
(define-key global-map (kbd "C-`") 'toggle-windows-split)
(define-key global-map (kbd "C-~") 'toggle-windows-split)
(define-key global-map (kbd "C-|") 'toggle-windows-split) ; same key, on a spanish keyword mapping since I commute a lot between both

Below, a tweaking of the function other-window to go back and some key bindings to cycle through windows.

;; Window shifting. C-x-o lets us go forward a window (or several).
;; This one lets us go back one or more windows. From Glickstein.
(defun other-window-backward (&optional n)
"Select previous Nth window."
(interactive "P")
(other-window (- (prefix-numeric-value n))))

(define-key global-map (kbd “”) ‘other-window) ; [PgUp]
(define-key global-map (kbd “”) ‘other-window-backward) ; [PgDn]

(global-set-key [(control tab)] ‘other-window)
(global-set-key [(shift control tab)] ‘other-window-backward)

Also (stolen from someone else’s dot file) this is needed to shrink/expand windows without using the mouse.

(define-key global-map (kbd "C-M-<left>") 'shrink-window-horizontally)
(define-key global-map (kbd "C-M-<right>") 'enlarge-window-horizontally)
(define-key global-map (kbd "C-M-<top>") 'enlarge-window)
(define-key global-map (kbd "C-M-<down>") 'shrink-window)