Mar 5 10

Cheap Ubuntu screencast tutorial

by Stephen Mann

Here’s the cheapest, easiest way I know of to make a visual-only screencast in Ubuntu.

Install recordMyDesktop: sudo apt-get install recordmydesktop

If you want to record only a specific window, get the window ID with xwininfo, a pre-install utilitiy.

Start recording with recordMyDesktop --windowId [id], where [id] is the window id.

CTRL-C in the window will stop the recording, and automatically produce the video in .ogg format.

Share and Enjoy:
  • Digg
  • del.icio.us
  • Facebook
  • LinkedIn
  • Reddit
  • Slashdot
  • Twitter
  • RSS
  • email
  • Print
Feb 19 10

Improved Vim IDE

by Stephen Mann

I spent some time today learning about vim scripting basics. (Did you you know that you can script Vim with vimscript, python, perl, ruby, mzscheme, and others?! There goes the last possible reason for learning emacs.)

Putting that new knowledge to work, I set to improving my haskell and python workflow. The goal: hit R to run whatever it is I’m working on.

The .vimrc code is below, but first I want to explain the interface.

Prerequisite: I’m running GNU Screen with windows titled “main”, “ghci”, and “python”. Not surprisingly, “ghci” is running ghci, and “python” is running the python interpreter — this happens automatically, based on the .screenrc file below.

Interface

If I’m working on a haskell file, hitting R runs the project in the “main” window of the terminal with runghc. Selecting text and R runs the selected text in ghci, in the “ghci” window. F5 fully compiles and runs the program in “main”.

If I’m working on a python file, it’s basically the same thing. R runs the project in “main”. Select text and R runs the selected text in the interactive python interpreter in the “python” window.

It’s simple enough to extend the code to compile/run any format (lilypond, groovy, povray, …), and always with just R.

Running the :SendToScreen command sends whatever text follows to the currently active window in the terminal. %p expands to the fully qualified path of the current file. %r to the same, less the extension.

The :SetRunTimeOptions command lets you set options to pass to the compiler. The setting is specific to the current buffer, so your haskell and python buffer can maintain different settings.

The gory details

I send text to the terminal through GNU Screen’s -X stuff command.

autocmd! BufEnter,BufNew lets me run configuration functions when I enter a file of the specified type. Those functions redefine vim shortcuts, which can be specific to the current mode.

command lets me write my own vim command.

Solving the problem like this lets me dump the whole mess into my .vimrc.

.vimrc

" interacting with screen
" =======================

" sending function; user does not call directly
" - window can be ""
" - %p = full path
" - %r = root of file name, no extension
function! SendToScreenWindow(window, text)
 let pArg = a:window == "" ? "" : "-p " . a:window
 let toStuff = substitute(a:text,  "%p", fnamemodify(@%, ":p"), "g")
 let toStuff = substitute(toStuff, "%r", fnamemodify(@%, ":p:r"), "g")
 call system("screen " . pArg . " -X stuff '" . toStuff . "\n'")
endfunction

" commands to set run-time options
command! -nargs=+ SetRunTimeOptions   let b:runTimeOpts=<q-args>
command!          ClearRunTimeOptions let b:runTimeOpts=""

" command to send text to active window
command! -nargs=+ SendToScreen call SendToScreenWindow("", <q-args>)

" automatically change settings based on filetype
autocmd! BufEnter,BufNew *.hs call ConfigureHaskell()
autocmd! BufEnter,BufNew *.py call ConfigurePython()

function! ConfigureHaskell()

 call InitBuffer()

 nmap R :wa<CR> :call SendToScreenWindow("main", "runghc %p " . b:runTimeOpts)<CR>
 vmap R y:silent call SendToScreenWindow("ghci", @")<CR>

 let b:runHs =
 \ "clear;
 \ hlint %p;
 \ ghc --make %p;
 \ time %r " . b:runTimeOpts
 nmap <F5> :wa<CR> :call SendToScreenWindow("main", b:runHs)<CR>
endfunction

function! ConfigurePython()

 call InitBuffer()

 nmap R :wa<CR> :call SendToScreenWindow("main", "python %p " . b:runTimeOpts)<CR>
 vmap R y:silent call SendToScreenWindow("python", @")<CR>
endfunction

" utilities
function! InitBuffer()
 if !exists("b:runTimeOpts")
 let b:runTimeOpts = ""
 endif
endfunction

.screenrc

defscrollback 1024
startup_message off

caption always

screen -t "python" 2 python
screen -t "ghci"   1 ghci
screen -t "main"   0
Share and Enjoy:
  • Digg
  • del.icio.us
  • Facebook
  • LinkedIn
  • Reddit
  • Slashdot
  • Twitter
  • RSS
  • email
  • Print
Feb 11 10

Tiny haskell code with high feature density

by Stephen Mann

Trying to get a handle on monads in haskell, I found myself punching out this cute one-liner. It neatly demonstrates many of haskell’s cooler features in a remarkably tiny space.

[1..5] >>= return . (+5)

-- outputs: [6,7,8,9,10]

And it works something like this:

[1..5] builds the list [1, 2, 3, 4, 5]

>>= is one of those crazy monad operators. Generally: a monad is a kind of container. The >>= operator extracts a value from that container, and passes it to the function on the right. The function on the right has to be somewhat special: it must take that value, operate on it, and then insert it back into the original type of container.

In this example, the monad/container is a list. So, the >>= operator takes a value from the list, applies that function on the right to it, and inserts the result back into a list (at the end, all those little lists are concatenated back into a single list).

Right.

Reading the function on the right from right to left. (+5) is a partially applied addition function. It takes a value, and returns that value plus 5. That function is composed with the return function, which in haskell inserts a value back into its monad container — basically inserting, say, 6 back into the list.

A haskell expert might quibble with bits of my description, but that’s generally what’s going on. Quite the assortment of features: a list building syntatical form, monads, function composition, point-free style, and partially applied functions.

One last thing. For your viewing pleasure, each of the following lines of code have the exact same effect as the above. I do this last because it’s interesting, but also because I want to stress that nobody would actually write code like the above. It’s just an interesting exercise — one that helped me understand monads a little bit better.

[1..5] >>= \n -> return (n + 5)
[1..5] >>= \n -> [n + 5]
 map (\n -> n + 5) [1..5]
 map (+5) [1..5]
fmap (+5) [1..5]
Share and Enjoy:
  • Digg
  • del.icio.us
  • Facebook
  • LinkedIn
  • Reddit
  • Slashdot
  • Twitter
  • RSS
  • email
  • Print
Jan 30 10

Haskell vs. Scheme: learning the syntax

by Stephen Mann

I think scheme would be a more eye-opening experience if I hadn’t already spent time learning haskell. I’m not into the advanced features of scheme yet (though I suspect there aren’t many), but I have noticed something about basic syntax differences: haskell uses more syntactical constructs and relies on more symbols, whereas scheme uses only a single syntactial construct, and uses almost no symbols.

I apprciate scheme for its purity, and haskell for its conciseness. Ultimately, I think the more concise language is the one I’d prefer to work in.

Here’s a concrete example: the functions below are functionally identical.

Scheme:

(define (my-map f lst)
    (cond
     [(empty? lst) empty]
     [else (cons (f (first lst))
                 (my-map f (rest lst)))]))

Haskell:

map f []     = []
map f (x:xs) = f x : map f xs

Not only are these functions functionally identical (they do the same thing), they’re functionally identical (they do it in exactly the same way). The tokens line up almost one-to-one. The only differences are:

  • haskell doesn’t require a keyword to define a function or value
  • haskell uses pattern matching instead of “cond”
  • haskell uses pattern matching (x:xs) to separate out the first element of the list and the rest

That, I think, should give you an idea of why I don’t think it’s going to be a problem to move from one to the other.

Share and Enjoy:
  • Digg
  • del.icio.us
  • Facebook
  • LinkedIn
  • Reddit
  • Slashdot
  • Twitter
  • RSS
  • email
  • Print
Dec 17 09

Simple timer

by Stephen Mann

While working on my Rubik’s cube, I came up with a simple timer for your average unix-like system. Try putting the following in your ~/.bashrc:

alias timer="echo 'begin timer';time sleep 1d"

Then source it (. ~/.bashrc) and enter timer to run it. It prints a start message, starts the time command-line utility, and then waits (sleeps 1 day). Hit ctrl-c to stop, and it prints the elapsed time. Dead simple, but effective enough.

For those wanting an even more simple solution, just type time sleep 1d into the command-line.

For those wanting more, I’d recommend creating a bash function that takes a message, so you can comment on what the timer’s timing.

Share and Enjoy:
  • Digg
  • del.icio.us
  • Facebook
  • LinkedIn
  • Reddit
  • Slashdot
  • Twitter
  • RSS
  • email
  • Print
Dec 14 09

uniq: useful linux command-line utility

by Stephen Mann

uniq, from the man page: “report or omit repeated lines”

Which is just what I needed today. To remove duplicate lines from a file in vi, it’s just :%!uniq. Or you could do it from the terminal, but working in vi is more fun.

Share and Enjoy:
  • Digg
  • del.icio.us
  • Facebook
  • LinkedIn
  • Reddit
  • Slashdot
  • Twitter
  • RSS
  • email
  • Print
Dec 14 09

Helpful .screenrc binding

by Stephen Mann

This makes ctrl+a space do what ctrl+a " normally does: bring up a selectable list of the currently active windows.

bind ' ' windowlist -b

While I’m at it, here’s the rest of my .screenrc file.

defscrollback 10000
bind q stuff "cleverPassword^M"
bind g stuff "cleverPassword2^M"
bind ' ' windowlist -b

screen -t "windowName1" 1
screen -t "windowName2" 2
Share and Enjoy:
  • Digg
  • del.icio.us
  • Facebook
  • LinkedIn
  • Reddit
  • Slashdot
  • Twitter
  • RSS
  • email
  • Print
Dec 8 09

Shout-out to my own vimrc

by Stephen Mann

Here’s a shout-out to my own .vimrc. It’s been updated quite a bit since I first posted it.

Share and Enjoy:
  • Digg
  • del.icio.us
  • Facebook
  • LinkedIn
  • Reddit
  • Slashdot
  • Twitter
  • RSS
  • email
  • Print
Dec 6 09

More screen magic, now with povray

by Stephen Mann

The goal: hit F5 to rerender scene.

The line in .vimrc:

nmap <F5> :update<CR>:call system("screen -X stuff 'clear; povray ".@%."; open $(basename ".@%." .pov).png; open ".@%."; \n'")<CR>

And how it works:

  • nmap <F5> to set shortcut key
  • :update<CR> to save the current file
  • :call system("screen -X stuff '...'")<CR> This combination makes a call to the system (a terminal). That call runs the screen -X stuff '...' command, which inserts '...' into the current screen session.
  • Looking at the "..." piece by piece:
  • clear clears the terminal
  • povray ".@%." feeds the current file into the povray command-line utility. % is the current file. @% accesses the current file. The "’s escape from the string, and the . is concatenation.
  • open $(basename ".@%." .pov).png Opens (refreshes the view of) the new .png. basename is a function that strips a filename’s extension. $() evaluations an expression in bash.
  • open ".@%." Opens the file back up in vim — serves to return focus to the file I’m editing.
  • \n enter, makes the command go

The result of all this trickery is ease. I hit F5, and all my windows auto-update — terminal, image viewer, and vim. The only thing left to do is locate some artistic talent.

Share and Enjoy:
  • Digg
  • del.icio.us
  • Facebook
  • LinkedIn
  • Reddit
  • Slashdot
  • Twitter
  • RSS
  • email
  • Print
Nov 25 09

Abusing security with screen

by Stephen Mann

I hate typing passwords. Today’s fix: because I’m always using screen in the terminal anyway, I can create bindings in .screenrc. For example:

bind q stuff "myCleverPassword^M"

Now I just type CTRL-a q, and my password is typed for me, anywhere in a terminal. Great for ssh.

By the way, The ^M represented a carriage return.

Share and Enjoy:
  • Digg
  • del.icio.us
  • Facebook
  • LinkedIn
  • Reddit
  • Slashdot
  • Twitter
  • RSS
  • email
  • Print