Showing posts with label emacs. Show all posts
Showing posts with label emacs. Show all posts

2008-11-19

Emacs Tidbit #3

For those of you who have blogs hosted on blogger (like this one), and use emacs, I'm sure you've run into this - writing a post in emacs with auto-fill mode on leads to an ungodly amount of reformatting needed because of the insertion of hard line breaks.

If you weren't already aware of it,

longlines-mode
solves this problem.


longlines-mode is an interactive compiled Lisp function in `longlines.el'.
(longlines-mode &optional arg)

Toggle Long Lines mode.
In Long Lines mode, long lines are wrapped if they extend beyond
`fill-column'. The soft newlines used for line wrapping will not
show up when the text is yanked or saved to disk.

If the variable `longlines-auto-wrap' is non-nil, lines are automatically
wrapped whenever the buffer is changed. You can always call
`fill-paragraph' to fill individual paragraphs.

If the variable `longlines-show-hard-newlines' is non-nil, hard newlines
are indicated with a symbol.

This, in combination with the ability to post stuff to blogger through email, makes using emacs with your blogger account a bit easier.

One more thing - never, ever, while in the blogger "new post" editor, hit Ctrl-P, unless you really want to publish. It can be awfully frustrating.

2008-11-11

Emacs Tidbit #2

Ever make a throwaway buffer in some random directory that you didn't intend on saving, but then ended up wanting to save - but not in that directory?
M-x set-visited-file-name

Is what you want.

From the docs:

set-visited-file-name is an interactive compiled Lisp function in `files.el'.
(set-visited-file-name filename &optional no-query along-with-file)

Change name of file visited in current buffer to filename.
This also renames the buffer to correspond to the new file.
The next time the buffer is saved it will go in the newly specified file.
filename nil or an empty string means mark buffer as not visiting any file.
Remember to delete the initial contents of the minibuffer
if you wish to pass an empty string as the argument.

The optional second argument no-query, if non-nil, inhibits asking for
confirmation in the case where another buffer is already visiting filename.

The optional third argument along-with-file, if non-nil, means that
the old visited file has been renamed to the new name filename.


This just saved me a few commands, hope you find it useful, fellow emacs-learners. Don't forget to follow the link to files.el and read the code for the function.

2008-10-08

Creating a small addition of functionality to emacs behaviour.

I thought it might be a nice thing to illustrate what a lot of people really like about emacs with a small example of a little added functionality that I implemented earlier today.

There's a function called "kill-some-buffers", which steps through your buffer list (the list of open editing areas, most likely mainly files) and asks you if you want to kill them. This is useful when you find yourself with a whole bunch of buffers open, some of which you haven't touched for a while - and I've been using it lately.

I wanted to be able to mark certain buffers as "this is not getting killed by kill-some-buffers". Looking at its documentation, it doesn't say that it supports this functionality (C-h f kill-some-buffers). Looking at its code confirms this (click "files.el" in the output of C-h f). It's a short function, although if you're not familiar with a lisp, this may look like nonsense. If you're familiar with a lisp it'll be fairly obvious, and if you're passingly familiar with elisp you shouldn't have a problem reading it.

It just walks through the list of open buffers, performs some checks, lets you know whether they're modified or unmodified and asks if you want to kill them or not, taking the appropriate action.

Rather than modify the emacs source, I copied the body of kill-some-buffers, and added a variable and another utility function.

(defvar kept-buffers nil
"A list of buffers to never kill when running `limited-kill-some-buffers'")

(defun add-to-kept-buffers (buffername)
(interactive "bAdd to kept buffers list: ")
(setq kept-buffers
(append kept-buffers (list buffername))))

The line "bAdd...." tells interactive that it expects a buffername (which comes with autocompletion, and is just a taste of what you can do with interactive....). Interactive itself tells emacs that the function can be called by a keystroke, like M-x add-to-kept-buffers.

The only change to what used to be the body of kill-some-buffers is a single check after the others that it performs:
(not (member name kept-buffers))
The only thing I might change in the future is pruning of the kept-buffers list - which can be easily done by defining "advice" on the function kill-buffer to check to see if the buffer being killed is in the kept-buffers list, and if it is to remove it from it, but kill-buffer is a "primitive" function (written in C), and defining advice on those is generally frowned upon. I want to see if there's a more appropriate way to do that cleanup before doing that. I can always manually prune the list if it gets too large. Also, right now it seems like if I add a file to the kept-buffers list, I'm probably going to want to keep that file there for a while (if I kill the buffer, and then re-open the file, I want the restriction to stay).

If I had decided to modify the files.el source file, this would have been a 7 line change. Granted, this is a pretty trivial change - but the ease with which it was performed is amazing. A little bit of reading the provided (and high quality) documentation (through C-h i), and a little bit of reading through the source, and it's possible to totally bend the editor to your whim.

So a few minutes of coding, and something that was a minor annoyance to me about one functions performance is solved.

2008-09-26

Emacs tidbit

I've been using emacs regularly for around one year now, and I am always running into reminders that I need to consistently learn more about what's available to you in emacs. It's frankly a bit hard to schedule getting stuff done in emacs with learning more about what's available through (or in) emacs, but the return value for learning a bit more about what you can do is very high - there are things that can make you magnitudes more productive just sitting around waiting to be found.

A small tidbit, from earlier today: kmacro-insert-counter inserts the number of times a macro has been called into the buffer.

I was debugging some methods, and had a bunch of similar calls that I wanted to log info about to files named in a sequential order (foo1.txt, foo2.txt). I just needed to do a diff of the output. I made a little macro that used kmacro-insert-counter. Wasn't the most robust debugging solution, but then again I wasn't in need of one at the time, just needed to see some data as quickly as possible.

There have been a few other times where I've wanted something like kmacro-insert-counter. It's not something that's useful (to me) on a very regular basis, but when it's handy, it's really handy. Emacs is chock-full of stuff like that, and if you're familiar with what's there, combining all the little convieniences into one big project-or-file-specific convienience is easy, and allows you to do non-trivial editing tasks much faster than I've been able to accomplish with other editors.

2008-01-02

Locking a section of text in emacs

Today, I was talking to a friend about things that would be useful for text editors. One feature that we thought was missing was the ability to select a region of text, and lock it so as to prevent accidental editing without unlocking it.

This was rather trivial to add to emacs:


(defun lock ()
"Make a section of text read-only, and add an overlay so
it's apparent"
(interactive)
(let ((start (region-beginning))
(end (region-end)))
(overlay-put (make-overlay start (+ 1 end)) 'face
'(:background "light slate gray"))
(put-text-property start end 'read-only t)))

(defun unlock ()
"Unlock a region of text, and remove its overlay"
(interactive)
(let ((inhibit-read-only t)
(start (region-beginning))
(end (region-end)))
(remove-overlays start (+ 1 end))
(remove-text-properties start end '(read-only))))


Just bind lock and unlock to some keys, and there you go - makes a region of text uneditable, and adds an overlay to it.

2007-12-18

Automating the insertion of keybinding code in .el files, surrounded by a bunch of explanatory blabber.

Recently, I have been learning my way around the lisp family
of languages. Naturally, that led me to learning my way around emacs -
the editor-of-choice for most of those languages - and it turns out
that I like using emacs. A lot.

Emacs, as I'm sure most people reading this are already well
aware of, is extensible in a dialect of lisp called elisp - and it's
more extensible than any other editor I've used as of yet. Everything
it does is open to you, and not only because it is an open source
program, although the politics behind that are a large reason for its
extensibility.

Emacs was written to be extended - and it shows. Things like
being able to load changes into the editor on the fly, being able to
hit C-h f and bring up the docstring for a function as
well as a link straight to its source code make developing in it a
breeze - not to mention the loads of documentation and other things
that make editing much more powerful like C-x ( which starts the
definition of a one-off keyboard macro.

I could ramble on about features of emacs that make it nice -
but I don't really want to talk about that right now. What I want to
talk about is the process of writing code in lisp family languages,
especially with emacs - so far I have found it to be much nicer than
in other languages.

Now, I am not a seasond lisper. I've only been messing around
with these languages (mostly Common Lisp, elisp, and Scheme) for a
month or so now. However, that has been more than enough time to
realize that they are powerful. Very, very powerful. I'm not going to
talk about specific features of the lisps that make them powerful
though - partly because I don't fully understand them as of yet, and
partly because at the moment, I feel that the process that one goes
through while writing code in them is far more important - and I feel
that it's best to illustrate by example.

Earlier today, I was reading through some of the emacs
documentation, specifically the FAQ entry on keybindings. It mentions
that you can add or modify keybindings to modes (assuming that the
author of the mode wrote it correctly - and I don't think that there
are any that come with emacs that aren't) by placing code like this in
your .emacs, or in some other file, or the scratch buffer (or
wherever) and loading it:

(add-hook 'lisp-interaction-mode-hook
(lambda ()
(local-set-key (^M) (newline-and-indent))))

This would bind ^M, which is or , to the function
newline-and-indent under lisp-interaction mode. (By the way, you can
type C-q to ouput the control character for a key, which is
handy)

You could also call local-set-key (or it's big brother
global-set-key) interactively by typing M-x local-set-key and get
prompted for the values of key and command.

The FAQ also mentioned a useful "trick" for getting the code
to put in the add-hook form - bind the key by calling it
interactively, then type C-x C-a C-k C-g . This runs redo,
which puts the code in the message buffer at the bottom, goes to the
beginning of it, kills it, and quits. Then you can just yank it into
your .emacs, or wherever you want it. Convienient.

Even more convienient than that is that a string or a vector
can be bound to a key, and as such treated as a macro. You could do
something like this:

(global-set-key [f10] "\C-x\e\e\C-a\C-k\C-g")

and from then on, whenever you hit f10, the last command you entered
will be put in the kill ring, ready to be copied.

This got me thinking - could I just tack a "\C-y" on the end
of that and have it auto-yank for me? Unfortunately no, because C-g is
quitting the command loop. Now I just wanted to automate the process
of entering keybinding (re)definitions into my .emacs - it's not
something I do that often, but I need something to do to practice my
emacs-customizing skills, and off I went, hacking away.

Here's where the process comes into play. The code I wrote
went through several iterations. I started off just trying to automate
the process of entering those keybindings - I ended up doing that, and
writing a few general purpose utilities that may or may not end up
being useful - but I have them now, regardless, and the code doesn't
feel right unless things that can be are generalized out (especially
in lisps).

I had some trouble at first figuring out how to get emacs to
print a string representation of a list - until I found princ, prin1,
and pp-to-string. I had managed to hack together a working solution
without building a list, but it was ugly, and I had lost the ability
to have auto-completion in the message buffer because I couldn't
figure out how to get a string representation of something gotten
through interactives flag C or v.

So yes, first workable solution was ugly, and looked a lot
like PHP-style templating code. Stuff like

(insert "(add-hook '" hook)
(newline-and-indent)
(insert "(lambda ()")
(newline-and-indent)
. . .

and so on. Not standing for that, nope. Ugly, and broken to boot.

After searching the documentation for a while, I came upon the
previously mentioned pp-to-string. I looked at the source for it, saw
that it called prin1, followed the chain around, and eventually I
found this variable called print-level - which is used by such
pretty-printing functions to signal when they should stop printing and
start abbreviating.

I can't just assume that it's going to be nil, which is what I
need, and I can't assume that there aren't any more variables like
this that people may have set, have nil as a default, and that I would
like to do something with at some point in time - but what I can do is
set the value of the symbol print-level to nil within the scope of
what I'm doing with a "let".

Once I got the ability to output the code to the
current-buffer working, it was just a matter of making it
interactive. I originally had one function for inserting these
keybindings, but after realizing that I didn't want to to an
"add-hook" every single time (not for hooks that already had one
defined anyhow), I split it into three functions - one for inserting a
new hook and keybinding, one for either returning the list
representation for a keybinding or inserting it depending on how it
was called, and one that handles the interaction and re-indentation.

Here's the code:

(defun insert-new-hook-and-keybinding (hook key command)
"Outputs the code needed to make a new key binding on KEY to COMMAND under HOOK.
HOOK should be the name of a mode-hook (e.g. lisp-interaction-mode-hook).
KEY should be the key to bind (e.g. ^T )
COMMAND should be the command to bind the key to.

Is meant to be run through insert-keybinding, but could be called directly."
(interactive "vHook: \nKKey: \nCCommand: ")
(let ((print-level nil))
(let ((result `(add-hook ',hook
,(create-local-keybinding key command))))
(insert (strip-quotes (pp-to-string result))))))


(defun create-local-keybinding (key command)
"Do the appropriate action to create the output for a local keybinding of KEY to COMMAND.
If called interactively, output the keybinding to the current buffer.
If called non-interactively, return the list for use in other output."
(interactive "KKey: \nCCommand: ")
(let ((result `(lambda ()
(local-unset-key (,key))
(local-set-key (,key) (',command)))))
(cond ((interactive-p)
(let ((print-level nil))
(insert (strip-quotes (pp-to-string result)))))
(t result))))


(defun insert-keybindings ()
"Insert keybinding code into the current buffer, prompting the user for values.
If cursor is at the beginning of the line from which insert-keybindings is invoked,
also prompt for hook name and create the appropriate form.

Insert keybindings re-indents and moves point to the bottom of the current keybinding-form
when it is finished in an attempt to act sane and make the code look decent."
(interactive)
(let ((line-no (line-number-at-pos (point))))
(if (equal (point-at-bol) (point))
(call-interactively #'insert-new-hook-and-keybinding)
(call-interactively #'create-local-keybinding))
(while (y-or-n-p "Insert another keybinding? ")
(goto-line line-no)
(goto-char (point-at-eol))
(newline)
(call-interactively #'create-local-keybinding))
(goto-line line-no)
(goto-char (point-at-bol))
(indent-sexp)
(end-of-defun)))



(global-set-key [f10] 'insert-keybinding)

It's rather simple.

The thing that struck me as I was writing this, and the thing
that I've been failing rather horribly at articulating is that this
code evolved as I was writing it. I didn't have much of a plan - I did
know what I needed to do, but I didn't put very much thought into how
I would accomplish it. As I wrote it, the form above came about on
it's own - a result of wanting to avoid duplication, and wanting to
express things a certain way.

Not that that doesn't happen in other languages, but it seems
to happen more in the lisp family. At least it's more in-your-face.