<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	xmlns:georss="http://www.georss.org/georss" xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#" xmlns:media="http://search.yahoo.com/mrss/"
	>

<channel>
	<title>Code that - Alex Yakushev&#039;s weblog</title>
	<atom:link href="http://codethat.wordpress.com/feed/" rel="self" type="application/rss+xml" />
	<link>http://codethat.wordpress.com</link>
	<description>Inventing, implementing, living a life</description>
	<lastBuildDate>Tue, 24 Jan 2012 08:03:23 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.com/</generator>
<cloud domain='codethat.wordpress.com' port='80' path='/?rsscloud=notify' registerProcedure='' protocol='http-post' />
<image>
		<url>http://s2.wp.com/i/buttonw-com.png</url>
		<title>Code that - Alex Yakushev&#039;s weblog</title>
		<link>http://codethat.wordpress.com</link>
	</image>
	<atom:link rel="search" type="application/opensearchdescription+xml" href="http://codethat.wordpress.com/osd.xml" title="Code that - Alex Yakushev&#039;s weblog" />
	<atom:link rel='hub' href='http://codethat.wordpress.com/?pushpress=hub'/>
		<item>
		<title>Writing Tetris in Clojure</title>
		<link>http://codethat.wordpress.com/2011/09/10/writing-tetris-in-clojure/</link>
		<comments>http://codethat.wordpress.com/2011/09/10/writing-tetris-in-clojure/#comments</comments>
		<pubDate>Sat, 10 Sep 2011 00:49:06 +0000</pubDate>
		<dc:creator>alexyakushev</dc:creator>
				<category><![CDATA[Clojure]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[clojure]]></category>
		<category><![CDATA[programming]]></category>
		<category><![CDATA[tetris]]></category>

		<guid isPermaLink="false">http://codethat.wordpress.com/?p=126</guid>
		<description><![CDATA[Good evening to everyone. Today I want to guide you step-by-step through the process of writing a game of Tetris in Clojure. My goal was not to write the shortest version possible but the concisest one and the one that would use idiomatic Clojure techniques (like relying on the sequence processing functions and making a [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=codethat.wordpress.com&amp;blog=11382405&amp;post=126&amp;subd=codethat&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>Good evening to everyone. Today I want to guide you step-by-step through the process of writing a game of Tetris in <a href="http://clojure.org/">Clojure</a>. My goal was not to write the shortest version possible but the concisest one and the one that would use idiomatic Clojure techniques (like relying on the sequence processing functions and making a clear distinction between purely functional and side-effect code). The result I got is about 300 lines of code in size but it is very comprehensible and simple. If you are interested then fire up your <em>editor_of_choice</em> and let&#8217;s get our hands dirty.<br />
<em>The whole code is available <a href="https://gist.github.com/1207703">here</a>.</em><br />
<span id="more-126"></span></p>
<h5>Briefing</h5>
<p>First let&#8217;s figure out how our tetris game model will be represented. The first idea that comes to mind is to represent the glass (and the blocks) as a two-dimensional array (array of rows to be more precise). The glass and the falling figure in our game will be stored in two different atoms, so we will also need an atom to store figure&#8217;s current coordinates. The glass will contain numbers that will mean a state of the cell &#8211; empty (0) or stationary filled (2). The filled cells in the moving figure will be represented by ones (1). Why this distinction is crucial we will see a bit later.<br />
<img class="aligncenter" src="http://codethat.files.wordpress.com/2011/09/screenshot.png?w=600" alt="Screenshot of the finished application" /></p>
<h5>Preparation</h5>
<p>We will use <a href="https://github.com/technomancy/leiningen">leiningen</a>, so open the <strong>project.clj</strong> of the newly created project and put these lines there:</p>
<p><pre class="brush: clojure;">
(defproject tetris &quot;1.0.0-SNAPSHOT&quot;
  :description &quot;Simple tetris written in Clojure&quot;
  :dependencies [[org.clojure/clojure &quot;1.2.0&quot;]
                 [org.clojure/clojure-contrib &quot;1.2.0&quot;]
                 [deflayout &quot;0.9.0-SNAPSHOT&quot;]]
  :dev-dependencies [[swank-clojure &quot;1.2.1&quot;]]
  :main tetris.core)
</pre></p>
<p><em>Note: deflayout is a small library (actually, a couple of macros) I once wrote to define Swing GUI more easily. I don&#8217;t maintain it anymore, so please consider using mature Clojure GUI frameworks like <a href="https://github.com/daveray/seesaw">Seesaw</a> or <a href="https://github.com/santamon/GUIFTW">GUIFTW</a> for larger projects.</em></p>
<p>Now open the <strong>src/tetris/core.clj</strong> file and start with this snippet:</p>
<p><pre class="brush: clojure;">
(ns tetris.core
  (:import (java.awt Color Dimension BorderLayout)
    (javax.swing JPanel JFrame JOptionPane JButton JLabel)
    (java.awt.event KeyListener))
  (:use clojure.contrib.import-static deflayout.core
        clojure.contrib.swing-utils)
  (:gen-class))

(import-static java.awt.event.KeyEvent VK_LEFT VK_RIGHT VK_DOWN VK_UP VK_SPACE)
</pre></p>
<p>We have just declared what we are going to use in our Tetris implementation.</p>
<p><pre class="brush: clojure; first-line: 11;">
(def empty-cell 0)
(def moving-cell 1)
(def filled-cell 2)
(def glass-width 10)
(def glass-height 20)
(def zero-coords [3 0])

(def stick [[0 0 0 0] 
            [1 1 1 1] 
            [0 0 0 0] 
            [0 0 0 0]])

(def square [[1 1]
             [1 1]])

(def tblock [[0 0 0]
             [1 1 1] 
             [0 1 0]])

(def sblock [[0 1 0] 
             [0 1 1] 
             [0 0 1]])

(def zblock [[0 0 1] 
             [0 1 1] 
             [0 1 0]])

(def lblock [[1 1 0] 
             [0 1 0] 
             [0 1 0]])

(def jblock [[0 1 1] 
             [0 1 0] 
             [0 1 0]])

(def figures [stick square tblock sblock zblock lblock jblock])
</pre></p>
<p>Everything was very simple so far. We have defined some constants and the main characters of our game.</p>
<h5>Functional code</h5>
<p>First we need to write a few helper functions to work with our data structures more in terms of the problem domain.</p>
<p><pre class="brush: clojure; first-line: 48;">
(def create-vector (comp vec repeat))
  
(defn create-glass[]
  (create-vector glass-height
                 (create-vector glass-width empty-cell)))
</pre></p>
<p>As we have stated earlier our glass would be an array of rows. In order to avoid the confusion of what coordinate to put first let&#8217;s write the following function:</p>
<p><pre class="brush: clojure; first-line: 54;">
(defn pick-cell [figure x y]
  (get-in figure [y x]))
</pre></p>
<p>Next we need a function that will work like map but for matrices. Here is its implementation:</p>
<p><pre class="brush: clojure; first-line: 57;">
(defn mapmatrix [func matrix]
  (into [] (map-indexed (fn[y vect]
                          (into [] (map-indexed (fn[x el]
                                                  (func el x y))
                                                vect)))
                        matrix)))
</pre></p>
<p>This code is fairly simple. We map through the list of rows using <strong>map-indexed</strong> (which consequently applies to a given function each element of the collection alongside with element&#8217;s number), and for each row we map through it replacing each cell value with the result of applying the function <strong>func</strong> to the current cell state and its coordinates.</p>
<p><pre class="brush: clojure; first-line: 64;">
(defn rotate-figure [fig]
  (let [fsize (count fig)]
    (mapmatrix #(pick-cell fig (- fsize %3 1) %2) fig)))
</pre></p>
<p>Note how we have defined the rotate function in the language of the problem domain. To rotate a figure of the size S we need to replace each cell with the coordinates (X,Y) by a cell with the coordinates (S-Y,X). This is exactly how the function is defined.</p>
<p><pre class="brush: clojure; first-line: 68;">
(defn apply-fig [glass fig [figx figy]]
  (let [fsize (count fig)]
    (mapmatrix (fn[el gx gy]
                 (if (and
                       (&lt;= figx gx (+ figx fsize -1))
                       (&lt;= figy gy (+ figy fsize -1)))
                   (+ el (pick-cell fig (- gx figx) (- gy figy)))
                   el))
      glass)))
</pre></p>
<p>This is the most important function in the whole program. It takes a glass, a figure and figure&#8217;s coordinates and puts the figure onto the glass. To do this it maps through entire glass and substitutes those cells on the glass that are covered by the figure with the sum of current glass&#8217; cell and the respective cell from the figure. So to say it <em>adds</em> the figure to the glass. As a result a new glass will be returned with zeros as empty cells, ones as figure&#8217;s cells, twos as fixed cells and threes being the cells where fixed cell and figure&#8217;s cell overlapped. This fact will be used later on to determine the correctness of the current glass.</p>
<p><pre class="brush: clojure; first-line: 78;">
(defn destroy-filled [glass]
  (let [clear-glass
        (remove (fn[vect] 
                  (not-any? #(= % empty-cell) vect)) glass)
        destroyed (- glass-height (count clear-glass))]
    [(into (vec (repeat 
                 destroyed
                 (create-vector glass-width empty-cell)))
           (vec clear-glass)) destroyed]))
</pre></p>
<p>This function removes the field rows from the glass and instead adds empty rows to the top of the glass. It is implemented just as the previous sentence stated: first it removes all rows that have no empty cells. Then it counts how many rows were removed by substituting the new number of rows from the initial one. Finally it creates the necessary number of empty rows and adds them to the top of the glass. Note that this function returns a vector of two values &#8211; a new glass and the number of destroyed rows. We&#8217;ll make use of it later.</p>
<p><pre class="brush: clojure; first-line: 88;">
(defn fix-figure [glass-with-fig]
  (mapmatrix (fn[el &amp; _]
               (if (= el moving-cell)
                  filled-cell
                  el))
    glass-with-fig))
</pre></p>
<p>This function given the glass with the figure applied to it replaces moving cells (represented by 1s) by fixed cells. We will call this function on the glass when the figure will fall to the bottom of the glass.</p>
<p><pre class="brush: clojure; first-line: 95;">
(defn count-cells [glass value]
  (reduce + (map (fn[vect]
                   (count (filter #(= % value) vect)))
                 glass)))
</pre></p>
<p>This simple function counts how many occurences of <strong>value</strong> is there in the glass.</p>
<p><pre class="brush: clojure; first-line: 100;">
(defn legal? [glass]
  (= (count-cells glass moving-cell) 4))
</pre></p>
<p>Now when we have the function <strong>count-cells</strong> we can define the function <strong>legal?</strong> very easily. The glass is legal if the number of moving cells equals four. Thus this function will instantly tell us that some part of the falling figure was lost (when rotated near the edge of the glass or near the fixed blocks or the figure was just moved out from the glass) and we won&#8217;t accept such player&#8217;s move.</p>
<p><pre class="brush: clojure; first-line: 103;">
(defn move 
  ([glass fig [figx figy] shiftx shifty]
    (let [newx (+ figx shiftx)
          newy (+ figy shifty)
          newglass (apply-fig glass fig [newx newy])]
      (when (legal? newglass) [newx newy])))
  ([glass fig coords direction]
    (cond
      (= direction :down) (move glass fig coords 0 1)
      (= direction :left) (move glass fig coords -1 0)
      (= direction :right) (move glass fig coords 1 0))))
</pre></p>
<p>This function acts the following way: given the glass, figure, figure&#8217;s coordinates and the direction of movement it tries to apply the figure to the glass with the new coordinates. If the glass stays legal after the move (the figure is not out of the glass&#8217; bounds and is not inside the fixed cells) then these new coordinates are returned, nil otherwise.</p>
<h5>Side-effects code</h5>
<p>Now when all the purely functional code is written (and its size is only about 100 hundred lines) we can get to the code that will change something. But first as always we need to define some constants:</p>
<p><pre class="brush: clojure; first-line: 115;">
(def score-per-line 10)
 
(defmacro defatoms [&amp; atoms]
  `(do
     ~@(map (fn[a#] `(def ~a# (atom nil))) atoms)))

(defatoms *glass* *fig-coords* *current-fig* *next-fig* *score*)
</pre></p>
<p>Here I used a tiny bit of metaprogramming to avoid writing <em>(def atomname (atom nil))</em> for each of the atoms I want to define. Not that it would be so cumbersome to do it for five atoms but I wanted to show an example how macros do the repetitive stuff for you.<br />
I mark all atoms with asterisks just to distinct them easier.</p>
<p><pre class="brush: clojure; first-line: 123;">
(defn complete-glass[]
  (apply-fig @*glass* @*current-fig* @*fig-coords*))

(defn done-callback [n]
  (swap! *score* #(+ % (* n score-per-line))))
</pre></p>
<p>The first function just applies our mutable figure to our mutable glass yielding a new glass. The second one is a callback function that we will call after calling <strong>destroy-filled</strong> on the glass in order to count the points scored.</p>
<p><pre class="brush: clojure; first-line: 129;">
(defn move-to-side [dir]
  (let [newcoords
        (move @*glass* @*current-fig* @*fig-coords* dir)]
    (if newcoords
      (reset! *fig-coords* newcoords))))
</pre></p>
<p>This function takes <strong>:left</strong> or <strong>:right</strong> as an argument. It tries to move the current figure to the given direction with the function <strong>move</strong>. If it returns a non-nil value (which means that the move is legal) then it sets the new coordinates for the current figure.</p>
<p><pre class="brush: clojure; first-line: 135;">
(defn move-down[]
  (let [newcoords
        (move @*glass* @*current-fig* @*fig-coords* :down)]
    (if newcoords
      (reset! *fig-coords* newcoords)
      (let [[newglass d-count] (-&gt; (complete-glass) 
                                   fix-figure
                                   destroy-filled)]
        (reset! *glass* newglass)
        (reset! *fig-coords* zero-coords)
        (reset! *current-fig* @*next-fig*)
        (reset! *next-fig* (rand-nth figures))
        (done-callback d-count)
        (when-not (legal? (complete-glass)) :lose)))))
</pre></p>
<p>This function works a bit differently from the previous one. It also tries to move the figure down and checks if the result position is legal. If it is not then it means that the figure has fallen all the way to the bottom. So we should fix it, destroy the filled rows in the new glass (if any), swap the current figure with the next one, randomly pick new next figure and set its coordinates to initial and call the <strong>done-callback</strong> function so it can update the score. Finally we have to check if the new current figure is positioned illegally from the start (this means that the glass is completely filled) and if so return <strong>:lose</strong>.</p>
<p><pre class="brush: clojure; first-line: 150;">
(defn move-all-down[]
  (move-down)
  (let [newcoords
        (move @*glass* @*current-fig* @*fig-coords* :down)]
    (when newcoords (recur))))
</pre></p>
<p>This function moves the figure down until it hits the floor.</p>
<p><pre class="brush: clojure; first-line: 150;">
(defn rotate-current[]
  (let [rotated (rotate-figure @*current-fig*)]
    (if (legal? (apply-fig @*glass* rotated @*fig-coords*))
      (swap! *current-fig* rotate-figure))))
</pre></p>
<p>The job of this function is to try rotating the current figure, see if the outcoming position is legal and if so replace the current figure with rotated one.</p>
<p><pre class="brush: clojure; first-line: 161;">
(defn new-game[]
  (reset! *glass* (create-glass))
  (reset! *fig-coords* zero-coords)
  (reset! *current-fig* (rand-nth figures))
  (reset! *next-fig* (rand-nth figures))
  (reset! *score* 0))
</pre></p>
<p>This function just sets the atoms to the initial values.</p>
<h5>GUI code</h5>
<p>In the final chapter we will write the code that will display and allow us to control our Tetris game.</p>
<p><pre class="brush: clojure; first-line: 168;">
(def cell-size 20)
(def border-size 3)
(def timer-interval 300)
(def game-running (atom false))
</pre></p>
<p>Some constants defining the size of the cell in pixels, the speed of the game and the flag that will tell the main loop if the game is in progress.</p>
<p><pre class="brush: clojure; first-line: 173;">
(defn fill-point [g [x y] color]
  (.setColor g color)
  (.fillRect g 
    (* x cell-size) (* y cell-size)
    cell-size cell-size)
  (when-not (= color (Color/gray))
    (.setColor g (.brighter color))
    (.fillRect g
      (* x cell-size) (* y cell-size)
      border-size cell-size)
    (.fillRect g
      (* x cell-size) (* y cell-size)
      cell-size border-size)
    (.setColor g (.darker color))
    (.fillRect g
      (- (* (inc x) cell-size) border-size) (* y cell-size)
      border-size cell-size)
    (.fillRect g
      (* x cell-size) (- (* (inc y) cell-size) border-size)
      cell-size border-size)))

(defn get-color [cell]
  (cond
    (= cell empty-cell) (Color/gray)
    (= cell filled-cell) (new Color 128 0 0)
    (= cell moving-cell) (new Color 0 128 0)
    :else (new Color 0 128 0)))
</pre></p>
<p>This scary function actually just draws a cell with the given coordinates and a color, and if the cell is not empty draws a border for the cell to give it some kind of 3D look. The second is a helper function which returns a color for every cell type.</p>
<p><pre class="brush: clojure; first-line: 201;">
(defn paint-glass [g glass]
  (mapmatrix (fn[cell x y]
               (fill-point g [x y] (get-color cell)))
    glass))
</pre></p>
<p>The function paints the whole glass on the given Graphics object by calling the function <strong>fill-point</strong> on every cell of the glass.</p>
<p><pre class="brush: clojure; first-line: 206;">
(defn game-panel []
  (proxy [JPanel KeyListener] []
    (paintComponent [g]
      (proxy-super paintComponent g)
      (doall (paint-glass g (complete-glass))))
    (keyPressed [e]
      (let [keycode (.getKeyCode e)]
        (do (cond
              (= keycode VK_LEFT) (move-to-side :left)
              (= keycode VK_RIGHT) (move-to-side :right)
              (= keycode VK_DOWN) (move-down)
              (= keycode VK_UP) (rotate-current)
              (= keycode VK_SPACE) (move-all-down))
          (.repaint this))))
    (getPreferredSize []
      (Dimension. (* glass-width cell-size)
        (* glass-height cell-size)))
    (keyReleased [e])
    (keyTyped [e])))
</pre></p>
<p>This function returns a JPanel instance with a few overridden methods. We override <strong>paintComponent</strong> method to make this panel draw the glass on itself and <strong>keyPressed</strong> to be able to control the game from the keyboard.</p>
<p><pre class="brush: clojure; first-line: 226;">
(defn next-panel []
  (proxy [JPanel] []
    (paintComponent [g]
      (proxy-super paintComponent g)
      (doall (paint-glass g @*next-fig*)))
    (getPreferredSize []
      (Dimension. (* 4 cell-size)
        (* 4 cell-size)))))
</pre></p>
<p>This panel will draw the next figure on itself.</p>
<p><pre class="brush: clojure; first-line: 235;">
(defn game[]
  (new-game)
  (reset! game-running true)
  (let [gamepanel (game-panel)
        sidepanel (new JPanel)
        nextpanel (next-panel)
        scorelabel (JLabel. &quot;Score: 0&quot;)
        exitbutton (JButton. &quot;Exit&quot;)
        frame (JFrame. &quot;Tetris&quot;)]
    (deflayout
      frame (:border)
      {:WEST gamepanel
       :EAST (deflayout (JPanel.) (:border)
               {:NORTH (deflayout sidepanel (:flow :TRAILING)
                         [nextpanel scorelabel])
                :SOUTH exitbutton})})
    (doto gamepanel
      (.setFocusable true)
      (.addKeyListener gamepanel)
      (.repaint))
    (doto frame
      (.pack)
      (.setVisible true))
    (doto exitbutton
      (add-action-listener (fn[_]
                             (do
                               (.setVisible frame false)
                               (reset! game-running false)))))
    (loop []
      (when @game-running
        (let [res (move-down)]    
          (if (= res :lose)
            (JOptionPane/showMessageDialog frame &quot;You lose!&quot; )
            (do               
              (.repaint gamepanel)
              (.repaint nextpanel)
              (.setText scorelabel (str &quot;Score: &quot; @*score*))
              (. Thread sleep timer-interval)
              (recur))))))))

(defn -main [&amp; args]
  (game))
</pre></p>
<p>Finally we define our main function that creates a frame, puts everything on it, finishes some GUI business and starts the main loop. The main loop ticks every <strong>timer-interval</strong> milliseconds, forces the current figure to move one cell down, checks if the player haven&#8217;t lost yet and updates the information on the screen.</p>
<p>And that&#8217;s all! We&#8217;ve managed to write a compact and concise Tetris implementation in Clojure. It is still pretty rough around the edges, especially its visual part but the code we came up with is extendable enough to fix it and add new features (like increasing the game speed) and so on.</p>
<p>I sincerely hope you liked this article and learned something while reading. If you have some questions or noticed some mistakes feel free to contact me here or any way you are comfortable with.<br />
Happy hacking!</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/codethat.wordpress.com/126/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/codethat.wordpress.com/126/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/codethat.wordpress.com/126/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/codethat.wordpress.com/126/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/codethat.wordpress.com/126/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/codethat.wordpress.com/126/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/codethat.wordpress.com/126/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/codethat.wordpress.com/126/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/codethat.wordpress.com/126/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/codethat.wordpress.com/126/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/codethat.wordpress.com/126/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/codethat.wordpress.com/126/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/codethat.wordpress.com/126/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/codethat.wordpress.com/126/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=codethat.wordpress.com&amp;blog=11382405&amp;post=126&amp;subd=codethat&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://codethat.wordpress.com/2011/09/10/writing-tetris-in-clojure/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/db0523c869c5311d95341801da7a69da?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">alexyakushev</media:title>
		</media:content>

		<media:content url="http://codethat.files.wordpress.com/2011/09/screenshot.png" medium="image">
			<media:title type="html">Screenshot of the finished application</media:title>
		</media:content>
	</item>
		<item>
		<title>Raidcall on Wine: problem with dnsapi.dll</title>
		<link>http://codethat.wordpress.com/2011/05/02/raidcall-on-wine-problem-with-dnsapi-dll/</link>
		<comments>http://codethat.wordpress.com/2011/05/02/raidcall-on-wine-problem-with-dnsapi-dll/#comments</comments>
		<pubDate>Mon, 02 May 2011 08:11:45 +0000</pubDate>
		<dc:creator>alexyakushev</dc:creator>
				<category><![CDATA[Linux]]></category>
		<category><![CDATA[Wine]]></category>
		<category><![CDATA[dnsapi.dll]]></category>
		<category><![CDATA[linux]]></category>
		<category><![CDATA[raidcall]]></category>
		<category><![CDATA[wine]]></category>

		<guid isPermaLink="false">http://codethat.wordpress.com/?p=118</guid>
		<description><![CDATA[Recently I stuck with a problem that had no solution around the Internet. Raidcall, a voice chat program exclusively for Windows, refused to start under Wine referring to the absent (or wrong) library dnsapi.dll. I found out that there is such library in ./wine/drive_c/windows/system32/ folder. Replacing this file with original dnsapi.dll taken from Windows distribution [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=codethat.wordpress.com&amp;blog=11382405&amp;post=118&amp;subd=codethat&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>Recently I stuck with a problem that had no solution around the Internet. Raidcall, a voice chat program exclusively for Windows, refused to start under Wine referring to the absent (or wrong) library dnsapi.dll. I found out that there is such library in ./wine/drive_c/windows/system32/ folder. Replacing this file with original dnsapi.dll taken from Windows distribution didn&#8217;t help. So after that I opened <strong>winecfg</strong>, switched to <strong>Libraries</strong>, found <strong>dnsapi.dll (native)</strong> in the list and just <strong>removed</strong> it (Remove button is on the right). Then, after applying the changes, Raidcall finally started.</p>
<p>Hope this would help somebody.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/codethat.wordpress.com/118/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/codethat.wordpress.com/118/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/codethat.wordpress.com/118/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/codethat.wordpress.com/118/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/codethat.wordpress.com/118/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/codethat.wordpress.com/118/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/codethat.wordpress.com/118/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/codethat.wordpress.com/118/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/codethat.wordpress.com/118/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/codethat.wordpress.com/118/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/codethat.wordpress.com/118/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/codethat.wordpress.com/118/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/codethat.wordpress.com/118/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/codethat.wordpress.com/118/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=codethat.wordpress.com&amp;blog=11382405&amp;post=118&amp;subd=codethat&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://codethat.wordpress.com/2011/05/02/raidcall-on-wine-problem-with-dnsapi-dll/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/db0523c869c5311d95341801da7a69da?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">alexyakushev</media:title>
		</media:content>
	</item>
		<item>
		<title>Browsers on WM8505 Linux</title>
		<link>http://codethat.wordpress.com/2011/02/21/browsers-on-wm8505-linux/</link>
		<comments>http://codethat.wordpress.com/2011/02/21/browsers-on-wm8505-linux/#comments</comments>
		<pubDate>Mon, 21 Feb 2011 13:21:45 +0000</pubDate>
		<dc:creator>alexyakushev</dc:creator>
				<category><![CDATA[Linux]]></category>
		<category><![CDATA[WM8505]]></category>
		<category><![CDATA[browsers]]></category>
		<category><![CDATA[debian]]></category>
		<category><![CDATA[linux]]></category>
		<category><![CDATA[wm8505]]></category>

		<guid isPermaLink="false">http://codethat.wordpress.com/?p=111</guid>
		<description><![CDATA[Being a proud owner of WM8505 mini netbook I spent a lot of time tinkering with it. This little noname machines ship with preinstalled WinCE that is very close to useless, so as soon as I got the netbook I installed this Debian distribution on it. And since I don&#8217;t want my time to be [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=codethat.wordpress.com&amp;blog=11382405&amp;post=111&amp;subd=codethat&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>Being a proud owner of WM8505 mini netbook I spent a lot of time tinkering with it. This little noname machines ship with preinstalled WinCE that is very close to useless, so as soon as I got the netbook I installed <a href="http://bento-linux.org/wiki/vt8505/wm8505/debian">this Debian distribution</a> on it. And since I don&#8217;t want my time to be utterly wasted I decided to start a series of post concering different aspects of using Linux on WM8505 netbooks. In this very entry I would talk about different browsers available for this installation, from the simplest to the most functional. So, let&#8217;s start.</p>
<p><em>Note: most of the information here should be also relevant for VT8500 netbooks.</em></p>
<p><em><span id="more-111"></span></em><strong>Links/Elinks/Lynx</strong></p>
<p>The family of text browsers that can work even without X Server. <strong>elinks </strong>is available in the Debian squeeze repository (I didn&#8217;t check others). You may consider using any of these browsers to quickly find and read some plain-text information without starting Xorg.</p>
<p>+ the fastest browser, can run in console</p>
<p>- text-only, does not support CSS, Javascript, images</p>
<p>Website:<a href="http://elinks.or.cz/"> http://elinks.or.cz/</a></p>
<p><strong>Dillo</strong></p>
<p>Unfortunatelly I didn&#8217;t manage to run Dillo on my WM8505. The reason is I couldn&#8217;t find any debian-arm ports it and failed to compile it myself. Maybe in future I would finally beat it and update this entry.</p>
<p><strong>Netsurf</strong></p>
<p>Fast and lightweight graphical browser standing somewhere near Dillo on our speed/functionality ladder. It is available in the repo by the name <strong>netsurf, </strong>it supports images and CSS, it has tabs. True candidate for the title of default browser for your mini netbook.</p>
<p>+ pretty fast, supports CSS and images</p>
<p>- doesn&#8217;t support JavaScript</p>
<p>Website: <a href="http://www.netsurf-browser.org/">http://www.netsurf-browser.org/</a></p>
<p><strong>Luakit</strong></p>
<p>This browser is not so popular as others and that is strange. Luakit is a Webkit-based browser written in C and Lua, configurable in Lua itself (it is even referred not as browser, but as a browser-framework), uses Vim-like user interaction, supports JavaScript and at the top of that is very fast, sometimes even faster than Netsurf! If you use Awesome WM, then configuring luakit by editing rc.lua file will be very familiar to you. So far luakit is the best browser for my netbook I tried so I ended up using it as my default browser.</p>
<p>Like all featured browsers on this list <strong>luakit</strong> is available at the repo.</p>
<p>+ very fast, very functional, highly configurable</p>
<p>- Vim-like hotkeys could be unusual for new users, doesn&#8217;t have many features (like password storage) out of the box</p>
<p>Website: <a href="http://luakit.org/projects/luakit/">http://luakit.org/projects/luakit/</a></p>
<p><strong>Arora</strong></p>
<p>Arora is considered to be one of the fastest &#8220;heavyweight&#8221; browsers. It can be installed from the repository, but uses Qt and I suppose because of that it fails to run on my netbook (actually, it shows up for a minute, doesn&#8217;t respond for anything and then closes). If anyone can run it on WM8505 write me how you did it:).</p>
<p><strong>Iceweasel(Firefox)/Iceape(Seamonkey)</strong></p>
<p>The heaviest browsers in the review. These two differs only in that Firefox is only a browser, but Iceape is an internet suite containing browser, mail client and some other modules. Though they both use the same engine for webpage rendering.</p>
<p>Firefox is indeed the most functional browser here, it is plugin-extendable and supports all modern standarts. Though with capabilities comes the price &#8211; Firefox is very slow when running on WM8505. Loading it takes about a minute and the browsing itself is much slower compared to above-mentioned browsers. You can still keep it as a reserve browser to open some complex website but day-to-day usage of Firefox is uncomfortable.</p>
<p>+ &#8220;adult&#8221; browser, supports everything, customizable with plugins</p>
<p>- slow, heavy, big loading time</p>
<p><strong>Conclusion</strong></p>
<p>After trying all these browsers I came up with keeping three of them: elinks, luakit and firefox. Elinks is good for fast browsing, luakit is the best daily browser and firefox is always capable of displaying some tricky page that luakit failed to do.</p>
<p>Hope this information helps someone.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/codethat.wordpress.com/111/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/codethat.wordpress.com/111/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/codethat.wordpress.com/111/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/codethat.wordpress.com/111/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/codethat.wordpress.com/111/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/codethat.wordpress.com/111/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/codethat.wordpress.com/111/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/codethat.wordpress.com/111/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/codethat.wordpress.com/111/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/codethat.wordpress.com/111/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/codethat.wordpress.com/111/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/codethat.wordpress.com/111/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/codethat.wordpress.com/111/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/codethat.wordpress.com/111/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=codethat.wordpress.com&amp;blog=11382405&amp;post=111&amp;subd=codethat&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://codethat.wordpress.com/2011/02/21/browsers-on-wm8505-linux/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/db0523c869c5311d95341801da7a69da?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">alexyakushev</media:title>
		</media:content>
	</item>
		<item>
		<title>Orglendar &#8211; calendar with org-mode schedule list for Awesome WM</title>
		<link>http://codethat.wordpress.com/2011/01/21/orglendar-calendar-with-org-mode-schedule-list-for-awesome-wm/</link>
		<comments>http://codethat.wordpress.com/2011/01/21/orglendar-calendar-with-org-mode-schedule-list-for-awesome-wm/#comments</comments>
		<pubDate>Fri, 21 Jan 2011 09:52:31 +0000</pubDate>
		<dc:creator>alexyakushev</dc:creator>
				<category><![CDATA[Awesome]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[awesome]]></category>
		<category><![CDATA[linux]]></category>
		<category><![CDATA[org-mode]]></category>
		<category><![CDATA[to-do]]></category>
		<category><![CDATA[widget]]></category>

		<guid isPermaLink="false">http://codethat.wordpress.com/?p=106</guid>
		<description><![CDATA[This is still another widget to make awesome users&#8217; life easier. This widget parses your Emacs org-mode files and shows you a pretty to-do list and a calendar. Here are listed its features: shows on-demand calendar with marked schedules and deadlines shows schedules and deadlines ordered by date supports multiple org-files If you are interested [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=codethat.wordpress.com&amp;blog=11382405&amp;post=106&amp;subd=codethat&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>This is still another widget to make awesome users&#8217; life easier. This widget parses your Emacs org-mode files and shows you a pretty to-do list and a calendar. Here are listed its features:</p>
<ul>
<li> shows on-demand calendar with marked schedules and deadlines</li>
</ul>
<ul>
<li> shows schedules and deadlines ordered by date</li>
</ul>
<ul>
<li> supports multiple org-files</li>
</ul>
<p>If you are interested visit <a title="Orglendar widget" href="https://awesome.naquadah.org/wiki/Orglendar_widget">this link</a> for further information about installation and usage.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/codethat.wordpress.com/106/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/codethat.wordpress.com/106/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/codethat.wordpress.com/106/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/codethat.wordpress.com/106/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/codethat.wordpress.com/106/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/codethat.wordpress.com/106/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/codethat.wordpress.com/106/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/codethat.wordpress.com/106/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/codethat.wordpress.com/106/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/codethat.wordpress.com/106/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/codethat.wordpress.com/106/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/codethat.wordpress.com/106/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/codethat.wordpress.com/106/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/codethat.wordpress.com/106/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=codethat.wordpress.com&amp;blog=11382405&amp;post=106&amp;subd=codethat&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://codethat.wordpress.com/2011/01/21/orglendar-calendar-with-org-mode-schedule-list-for-awesome-wm/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/db0523c869c5311d95341801da7a69da?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">alexyakushev</media:title>
		</media:content>
	</item>
		<item>
		<title>Quick launch bar for Awesome WM</title>
		<link>http://codethat.wordpress.com/2011/01/13/quick-launch-bar-for-awesome-wm/</link>
		<comments>http://codethat.wordpress.com/2011/01/13/quick-launch-bar-for-awesome-wm/#comments</comments>
		<pubDate>Thu, 13 Jan 2011 19:27:33 +0000</pubDate>
		<dc:creator>alexyakushev</dc:creator>
				<category><![CDATA[Awesome]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[awesome]]></category>
		<category><![CDATA[linux]]></category>
		<category><![CDATA[widget]]></category>

		<guid isPermaLink="false">http://codethat.wordpress.com/?p=103</guid>
		<description><![CDATA[After switching from Gnome\KDE many Awesome newcomers feel the lack of mouse-operated controls (like desktop icons or quick launch shortcuts). This widget tries to satisfy their needs providing an ability to put iconed shortcuts on the taskbar. Widget uses *.desktop files for specifying the shortcuts, so you don&#8217;t have to edit your configuration file in [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=codethat.wordpress.com&amp;blog=11382405&amp;post=103&amp;subd=codethat&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>After switching from Gnome\KDE many Awesome newcomers feel the lack of mouse-operated controls (like desktop icons or quick launch shortcuts). This widget tries to satisfy their needs providing an ability to put iconed shortcuts on the taskbar.</p>
<p>Widget uses *.desktop files for specifying the shortcuts, so you don&#8217;t have to edit your configuration file in order to add another shortcut. Also, you can just give the widget your Desktop folder as the folder for shortcuts, and they all will appear at the taskbar without any additional efforts.</p>
<p>For information about widget configuration and for the widget itself visit <a title="Quick launch bar widget" href="https://awesome.naquadah.org/wiki/Quick_launch_bar_widget">https://awesome.naquadah.org/wiki/Quick_launch_bar_widget</a></p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/codethat.wordpress.com/103/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/codethat.wordpress.com/103/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/codethat.wordpress.com/103/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/codethat.wordpress.com/103/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/codethat.wordpress.com/103/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/codethat.wordpress.com/103/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/codethat.wordpress.com/103/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/codethat.wordpress.com/103/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/codethat.wordpress.com/103/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/codethat.wordpress.com/103/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/codethat.wordpress.com/103/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/codethat.wordpress.com/103/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/codethat.wordpress.com/103/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/codethat.wordpress.com/103/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=codethat.wordpress.com&amp;blog=11382405&amp;post=103&amp;subd=codethat&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://codethat.wordpress.com/2011/01/13/quick-launch-bar-for-awesome-wm/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/db0523c869c5311d95341801da7a69da?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">alexyakushev</media:title>
		</media:content>
	</item>
		<item>
		<title>Coffee Time with Java &#8211; Part 1.5 &#8211; Sockets in Clojure</title>
		<link>http://codethat.wordpress.com/2011/01/05/coffee-time-with-java-part-1-and-a-half/</link>
		<comments>http://codethat.wordpress.com/2011/01/05/coffee-time-with-java-part-1-and-a-half/#comments</comments>
		<pubDate>Wed, 05 Jan 2011 12:58:27 +0000</pubDate>
		<dc:creator>alexyakushev</dc:creator>
				<category><![CDATA[Clojure]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[clojure]]></category>
		<category><![CDATA[programming]]></category>
		<category><![CDATA[sockets]]></category>

		<guid isPermaLink="false">http://codethat.wordpress.com/?p=81</guid>
		<description><![CDATA[It is almost a year now since I wrote the first part of meant-to-be series of topics concerning Java. I understood that there is no need to write the same stuff over and over again while there is plenty of it on the Net. But this time I&#8217;ve got an idea to rewrite that primitive [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=codethat.wordpress.com&amp;blog=11382405&amp;post=81&amp;subd=codethat&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>It is almost a year now since I wrote the first part of meant-to-be series of topics concerning Java. I understood that there is no need to write the same stuff over and over again while there is plenty of it on the Net. But this time I&#8217;ve got an idea to rewrite that primitive server-client demonstration into Clojure and see how it will look like.<span id="more-81"></span><br />
So all we need now is working Clojure REPL. You can just download the necessary jar-file, or use the Eclipse-plugin, actually there are a lot of ways to develop in Clojure as in any other language. I prefer <a title="Clojure development using Emacs and leiningen" href="http://blog.gaz-jones.com/post/2486737162/setting-up-clojure-development-on-osx-using-emacs-and" target="_blank">Emacs+SLIME</a> variant.<br />
So lets start with a server, just like the last time. The declaration begins with specifying the namespace and imports.</p>
<p><pre class="brush: clojure;">

(ns coffee-time.server)

(import '(java.util StringTokenizer)
        '(java.net ServerSocket Socket SocketException)
        '(java.io PrintWriter InputStreamReader BufferedReader))

</pre></p>
<p>Next we have to define the following global variables (presented as atoms):</p>
<p><pre class="brush: clojure;">

(def storage (atom {}))
(def exit? (atom false))

</pre></p>
<p>Variable <strong>storage</strong> will be our hashmap that stores key-value pairs. Variable <strong>exit?</strong> is just a flag indicating if server should keep running.</p>
<p><pre class="brush: clojure;">

(def parsing-re #&quot;([A-Z]+)\s*(\S+)\s*(\S*)&quot;)
</pre></p>
<p>Variable <strong>parsing-re</strong> is the regular expression that will break the request to our server into separate tokens &#8211; command, key (if exists) and value (if exists).</p>
<p><pre class="brush: clojure;">

(defn accept-connection [server-socket]
  (try (. server-socket accept)
       (catch SocketException e)))

</pre></p>
<p>This little function takes the ServerSocket as an argument, accepts the client connecting to it and returns the socket interacting with a client.<br />
<em> Note: in this entry I won&#8217;t explain the concepts of sockets and how they interact. For this information you can check the <a title="Coffee time with Java – Part 1 – Sockets" href="http://codethat.wordpress.com/2010/01/14/coffee-time-with-java-part-1-sockets/" target="_blank">original entry</a>.</em></p>
<p><pre class="brush: clojure;">

(defmulti operate (fn[command &amp; _]
                    (keyword command)))

</pre></p>
<p>Now this gets interesting. Here we define a <strong>multimethod</strong> &#8211; a method with an arbitrary dispatch function, which we define right here. The dispatch function does nothing but takes any number of arguments and returns the keyword from the first of arguments.</p>
<p><pre class="brush: clojure;">

(defmethod operate :GET [c key &amp; _]
           (if (contains? @storage key)
             (str key &quot; = &quot; (@storage key))
             &quot;No such key found&quot;))

(defmethod operate :PUT [c key value &amp; _]
           (do (swap! storage assoc key value)
               (str &quot;Value of &quot; key &quot; added&quot;)))

(defmethod operate :DELETE [c key &amp; _]
           (if (contains? @storage key)
             (do (swap! storage dissoc key)
                 (str &quot;Value of &quot; key &quot; deleted&quot;))
             &quot;No such key found&quot;))

(defmethod operate :EXIT [&amp; _]
           (reset! exit? true))

(defmethod operate :default [&amp; _]
           &quot;Wrong command&quot;)

</pre></p>
<p>Four functions above are the <strong>implementations</strong> for our multimethod. What you see next to the method name is a <strong>dispatch value</strong>. When we call the method <strong>operate</strong> on some arguments, Clojure applies the dispatch function<br />
on them, which as we now know, returns the keywordized first argument. Then Clojure seeks a multimethod implementation with this value in its definition.<br />
Multimethods are a beautiful technique for implementation decoupling. Whenever we decide to add more commands to our server we have just to add the appropriate methods. Actually the function overloading technique is just a multimethod with dispatch function that returns types of its arguments. Multimethods in general allow much more than that.<br />
Note the last method in the previous snippet. It has the dispatch value <strong>:default</strong>. This means that when the result of the dispatch function doesn&#8217;t match any of existing methods then this default method will be invoked.</p>
<p><pre class="brush: clojure;">

(defn parse-and-operate [s]
  (-&gt;&gt; s
       (re-find parsing-re)
       rest
       (apply operate)))

</pre></p>
<p>With multimethods the original <strong>parse-and-operate</strong> function is extremely short and concise. The operator <strong>-&gt;&gt;</strong> is actually a macro that takes a value as an argument and then consequently applies all the forms to it, placing the value at the tail of the form. So this expression should be read as: <em>Take the value s, then find the regular expression in it, drop the first item from the result and then apply the function operate to what has left.</em></p>
<p><pre class="brush: clojure;">

(defn start-server [port]
  (with-open [s-socket (new ServerSocket port)
              c-socket (accept-connection s-socket)
              in (new BufferedReader
                      (new InputStreamReader (. c-socket getInputStream)))
              out (new PrintWriter (. c-socket getOutputStream) true)]
    (do (reset! exit? false)
        (while (not @exit?)
          (-&gt;&gt; (. in readLine)
               parse-and-operate
               (. out println))))))

</pre></p>
<p>Here we introduce one more awesome macro &#8211; <strong>with-open</strong>. It takes a group of variables that are bound to some resources and at the end of the macro <strong>with-open</strong> automatically calls <strong>.close</strong> on this resources even if the exception was raised. So this macro completely replaces the <strong>try..finally</strong> block that is often used in such cases.<br />
What about the function itself? It is pretty self-explanatory. It creates a new ServerSocket, gets the client Socket from the function <strong>accept-connection</strong> that we defined above, binds input and output streams, and then repeatedly passes the incoming message from client to the function <strong>parse-and-operate</strong>.</p>
<p>So, that&#8217;s the whole server! Its size is only 53 lines of pretty &#8220;vertical&#8221; and extendable code. For sure, this code is rather proof of concept than the real code you would write, but the result is still impressive.</p>
<p>So now to the client part. This time I won&#8217;t use System.in stream for interaction with user, I decided to use the power of REPL instead. But first come the declarations:</p>
<p><pre class="brush: clojure;">

(ns coffee-time.client)

(import '(java.net Socket)
        '(java.io PrintWriter InputStreamReader BufferedReader))

(def socket (atom nil))
(def in (atom nil))
(def out (atom nil))

</pre></p>
<p>Nothing interesting here. <strong>socket</strong> is used to store Socket object, <strong>in</strong> and <strong>out</strong> speak for themselves.</p>
<p><pre class="brush: clojure;">

(defn start-client [port]
    (do
      (reset! socket (Socket. &quot;localhost&quot; port))
      (reset! out (PrintWriter. (. @socket getOutputStream) true))
      (reset! in (BufferedReader. (InputStreamReader. (. @socket getInputStream))))))

</pre></p>
<p>This function tries to connect to server (hardcoded localhost) on the specified port and gets necessary streams.</p>
<p><pre class="brush: clojure;">

(defn send-message [m]
  (do
    (. @out println m)
    (println (. @in readLine))))

</pre></p>
<p>Again pretty simple &#8211; the function gets the message as an argument, passes it to the output stream, gets response from input stream and prints it on the screen.</p>
<p><pre class="brush: clojure;">

(defn stop-client []
  (do (. @in close)
      (. @out close)
      (. @socket close)))

</pre></p>
<p>We should invoke this last function to tidy everything up after we did our work.</p>
<p>Once again, the client lacks a lot of try/catch cases because I didn&#8217;t want to bloat the code and since this is toy problem, clarity &gt; robustness.</p>
<p>Now, after both server and client are done, you can test them. First, in one repl, execute:</p>
<p><pre class="brush: clojure;">

coffee-time.server&gt; (start-server 1234)

</pre></p>
<p>In another repl, run:</p>
<p><pre class="brush: clojure;">

coffee-time.client&gt; (start-client 1234)

</pre></p>
<p>and then you can send messages to the server as following:</p>
<p><pre class="brush: clojure; gutter: false;">

coffee-time.client&gt; (send-message &quot;PAT message Hello world!&quot;)
Wrong command
nil
coffee-time.client&gt; (send-message &quot;PUT message Hello world!&quot;)
Value of message added
nil
coffee-time.client&gt; (send-message &quot;GET message&quot;)
message = Hello world!
nil
coffee-time.client&gt; (send-message &quot;DELETE message&quot;)
Value of message deleted
nil
coffee-time.client&gt; (send-message &quot;GET message&quot;)
No such key found
nil
</pre></p>
<p>Thus, we ported our Java simple client-server application to Clojure. The code has less noise in it, more expressive, understandable and accurately put together. There is still much left to be done &#8211; you can introduce a few macros to eliminate code duplication, break the code into few more functions, but it is now up to you what to do.<br />
I hope, this topic was somehow helpful to you. If you want to learn Clojure more, you can start with the book of Luke VanderHart and Stuart Sierra &#8220;Programming Clojure&#8221; or &#8220;The Pragmatic Bookshelf Programming Clojure&#8221; by Stuart Halloway. For deeper Clojure understanding I recommend reading an awesome book &#8220;The Joy of Clojure&#8221; by Michael Fogus and Chris Houser.<br />
Thank you for your attention.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/codethat.wordpress.com/81/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/codethat.wordpress.com/81/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/codethat.wordpress.com/81/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/codethat.wordpress.com/81/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/codethat.wordpress.com/81/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/codethat.wordpress.com/81/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/codethat.wordpress.com/81/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/codethat.wordpress.com/81/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/codethat.wordpress.com/81/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/codethat.wordpress.com/81/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/codethat.wordpress.com/81/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/codethat.wordpress.com/81/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/codethat.wordpress.com/81/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/codethat.wordpress.com/81/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=codethat.wordpress.com&amp;blog=11382405&amp;post=81&amp;subd=codethat&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://codethat.wordpress.com/2011/01/05/coffee-time-with-java-part-1-and-a-half/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/db0523c869c5311d95341801da7a69da?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">alexyakushev</media:title>
		</media:content>
	</item>
		<item>
		<title>Awesompd &#8211; half-widget/half-MPD-client for Awesome WM</title>
		<link>http://codethat.wordpress.com/2010/11/05/awesompd-half-widgethalf-mpd-client-for-awesome-wm/</link>
		<comments>http://codethat.wordpress.com/2010/11/05/awesompd-half-widgethalf-mpd-client-for-awesome-wm/#comments</comments>
		<pubDate>Fri, 05 Nov 2010 07:48:53 +0000</pubDate>
		<dc:creator>alexyakushev</dc:creator>
				<category><![CDATA[Awesome]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[awesome]]></category>
		<category><![CDATA[linux]]></category>
		<category><![CDATA[mpd]]></category>
		<category><![CDATA[widget]]></category>

		<guid isPermaLink="false">http://codethat.wordpress.com/?p=68</guid>
		<description><![CDATA[Awesompd is not just an ordinar MPD widget. Its aim is to provide awesome users a robust, functional and extendable MPD client in the form of widget. Here are main features of awesompd: Provides an ability to control playback, switch songs, playlists, change volume and other options. Displays information through a scrolling widget and naughty [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=codethat.wordpress.com&amp;blog=11382405&amp;post=68&amp;subd=codethat&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>Awesompd is not just an ordinar MPD widget. Its aim is to provide awesome users a robust, functional and extendable MPD client in the form of widget. Here are main features of awesompd:</p>
<ul>
<li> Provides an ability to control playback, switch songs, playlists, change volume and other options.</li>
</ul>
<ul>
<li> Displays information through a scrolling widget and naughty notifications.</li>
</ul>
<ul>
<li> Supports multiple servers and able to switch them on the fly.</li>
</ul>
<ul>
<li> Supports UTF encodings.</li>
</ul>
<p>For information where to download and how to setup it see <a href="http://awesome.naquadah.org/wiki/Awesompd_widget">http://awesome.naquadah.org/wiki/Awesompd_widget</a> .</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/codethat.wordpress.com/68/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/codethat.wordpress.com/68/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/codethat.wordpress.com/68/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/codethat.wordpress.com/68/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/codethat.wordpress.com/68/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/codethat.wordpress.com/68/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/codethat.wordpress.com/68/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/codethat.wordpress.com/68/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/codethat.wordpress.com/68/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/codethat.wordpress.com/68/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/codethat.wordpress.com/68/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/codethat.wordpress.com/68/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/codethat.wordpress.com/68/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/codethat.wordpress.com/68/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=codethat.wordpress.com&amp;blog=11382405&amp;post=68&amp;subd=codethat&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://codethat.wordpress.com/2010/11/05/awesompd-half-widgethalf-mpd-client-for-awesome-wm/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/db0523c869c5311d95341801da7a69da?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">alexyakushev</media:title>
		</media:content>
	</item>
		<item>
		<title>The Modern Programming Craftsmanship</title>
		<link>http://codethat.wordpress.com/2010/10/29/the-modern-programming-craftsmanship/</link>
		<comments>http://codethat.wordpress.com/2010/10/29/the-modern-programming-craftsmanship/#comments</comments>
		<pubDate>Fri, 29 Oct 2010 12:42:06 +0000</pubDate>
		<dc:creator>alexyakushev</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[craftsmanship]]></category>
		<category><![CDATA[interesting]]></category>
		<category><![CDATA[metaprogramming]]></category>
		<category><![CDATA[programming]]></category>
		<category><![CDATA[software]]></category>

		<guid isPermaLink="false">http://codethat.wordpress.com/?p=62</guid>
		<description><![CDATA[To make a start on the topic indirectly, I will state that one can view any kind of activity from different sides as different processes. Actually, there are different sides in any activity, but usually these sides are defined by people themselves. Chess, for example, were said to be an art by Wilhelm Steinitz, Emanuel [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=codethat.wordpress.com&amp;blog=11382405&amp;post=62&amp;subd=codethat&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>To make a start on the topic indirectly, I will state that one can view any kind of activity from different sides as different processes. Actually, there are different sides in any activity, but usually these sides are defined by people themselves. Chess, for example, were said to be an art by Wilhelm Steinitz, Emanuel Lasker considered them to be sport, Chigorin thought about chess as about science. But chess didn&#8217;t change because of these points of view, it&#8217;s the player who chooses the point for his own game of chess.<br />
Today we see that the software engineering transformed from being a magic thing into the kind of craftsmanship. Programming is no more considered a fun delightful action but a slow tedious process of typing in tons of code, testing, debugging and repeating the cycle again. How did it happen? The whole IT sphere was from the beginning some kind of wizardry. A small amount of people made the large lifeless machines work and perform complex operations that were impossible to do for a human. But time has passed and wizards are now replaced with lots of commoners with minimal (usually insufficient) knowledge about the profession itself. This fact is much more mysterious and astounding to be left unquestioned.<span id="more-62"></span><br />
To make it simple, lets draw the parallel to the woodcutting process. A thousand years ago there was a profession for it, and in order to make something of wood you had to ask a woodcutter &#8211; a person who specialized in that. But today we don&#8217;t need a woodcutter as a profession. Now the process of woodcutting is declarative &#8211; a professional of higher abstraction level defines a piece of wood he wants to have (in some kind of modeling software) and the machine does the rest. Perhaps, it needs some humans here and there (e.g. to carry the sample from one machine to another) but this can also be excluded soon.<br />
Why is there still such a buffer as human in software engineering? Why a higher-level specialist, a software architect or the person who specializes in the domain directly, cannot declaratively define what kind of software he wants? Why should he depend on a bunch of monkeys (developers) and a bit smaller bunch of inspectors (project managers)?<br />
There is more into it, that we can see at a glance. Software architect not only needs this buffer between him and a machine, but he has to know different things that these monkeys use. OOD, refactoring, TDD, various frameworks &#8211; a large amount of methods that don&#8217;t eliminate the human buffer but instead makes it useless though unavoidable. He (SA) doesn&#8217;t study computer science anymore, he learns the above-mentioned techniques to be able to communicate with the buffer. What a terrible waste of intellect.<br />
One may say it is about business. That business doesn&#8217;t need ten almighty hackers but a hundred expendable and replaceable coders. That&#8217;s incorrect. Business needs fast, robust and cheap solutions and it&#8217;s better for business not to have people at all. Machines are better in any way &#8211; they can work 24/7 without vacations, don&#8217;t require insurance policies, are predictable and easily controlled. Each industry prefers machines to humans, but software development does not. And it won&#8217;t until everybody realizes the problem about that.<br />
After all, what can we do to avoid this? The answer is simple and already known for a fifty years. The usage of DSL (Domain Specific Language) approach raises the level of abstraction by any height and lets a specialist of any sphere to operate the concepts and methods he used to. One pure example of this approach is SQL &#8211; a fine-grained DSL of its time. Another example is Wolfram Mathematica, the best computational software existing today. It was written in Mathematica language that was specially created for it.</p>
<p>Of course, you cannot so easily jump into writing DSLs and DSLs in DSLs and so on. This requires a host language capable of easy metaprogramming. Most of such languages are the Lisp derivatives that may ring you a bell. The mainstream languages come and go &#8211; ten years before the software companies were flooded with C++ coders, five years ago they all were replaced by Java/Python ones, now it seems like C# is the new cycle runner. But Lisp remains popular and useful for half a century now in any of its variations.</p>
<p>Code that writes code is a key. That is the natural way of development and not a rocket science as it is thought to be. Machines that build machines led to the scientific and technical revolution. Further research in the code-writing code industry can set up another one. Learn it, use it and you&#8217;ll see that programming is more magical than you ever thought.</p>
<p><em>If you want to learn more about metaprogramming and DSLs, you can start off with reading <a href="http://arxiv.org/pdf/cs/0409016v1">this article</a>.</em></p>
<p><em>Answer to the comment about &#8220;No silver bullet&#8221;: the metaprogramming implicitly states that there is no silver bullet. It provides an ability to write the language for the problem itself, hence eliminating the &#8220;silver bullet&#8221; principle. You can create a bullet for your very task and it would be better than any existing all-purpose languages.</em></p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/codethat.wordpress.com/62/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/codethat.wordpress.com/62/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/codethat.wordpress.com/62/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/codethat.wordpress.com/62/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/codethat.wordpress.com/62/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/codethat.wordpress.com/62/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/codethat.wordpress.com/62/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/codethat.wordpress.com/62/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/codethat.wordpress.com/62/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/codethat.wordpress.com/62/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/codethat.wordpress.com/62/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/codethat.wordpress.com/62/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/codethat.wordpress.com/62/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/codethat.wordpress.com/62/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=codethat.wordpress.com&amp;blog=11382405&amp;post=62&amp;subd=codethat&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://codethat.wordpress.com/2010/10/29/the-modern-programming-craftsmanship/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/db0523c869c5311d95341801da7a69da?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">alexyakushev</media:title>
		</media:content>
	</item>
		<item>
		<title>Show the TO-DO list from your Freemind in conky</title>
		<link>http://codethat.wordpress.com/2010/08/25/show-the-to-do-list-from-your-freemind-in-conky/</link>
		<comments>http://codethat.wordpress.com/2010/08/25/show-the-to-do-list-from-your-freemind-in-conky/#comments</comments>
		<pubDate>Wed, 25 Aug 2010 20:07:00 +0000</pubDate>
		<dc:creator>alexyakushev</dc:creator>
				<category><![CDATA[Linux]]></category>
		<category><![CDATA[Scripts]]></category>
		<category><![CDATA[conky]]></category>
		<category><![CDATA[freemind]]></category>
		<category><![CDATA[linux]]></category>
		<category><![CDATA[to-do]]></category>

		<guid isPermaLink="false">http://codethat.wordpress.com/?p=57</guid>
		<description><![CDATA[Introduction (if you look for instructions, skip this part) I tried a lot of software (offline and online) to help me with my tasks. I tried using specialized software, I tried different built-in things (like Firefox\Thunderbird plugins), I tried Rememberthemilk and similar services on the Web, but the same problem remained &#8211; the information was [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=codethat.wordpress.com&amp;blog=11382405&amp;post=57&amp;subd=codethat&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p><strong>Introduction (if you look for instructions, skip this part)</strong></p>
<p>I tried a lot of software (offline and online) to help me with my tasks. I tried using specialized software, I tried different built-in things (like Firefox\Thunderbird plugins), I tried Rememberthemilk and similar services on the Web, but the same problem remained &#8211; the information was too far from my eyes. It was either not noticeable, or stayed on my screen for not enough time, or I had to remember myself to view my to-do list.</p>
<p>Then conky came into my sight. I see it everyday, it stays on my desktop all the time, and I got an idea &#8211; why not show the to-do list in it? The idea isn&#8217;t new, one can say, but there is another problem &#8211; I&#8217;m too lazy to keep updated one more file for this list. But wait, I regularly work with Freemind, and it is fairly easy to create another branch directly for to-do management. Thus, I wrote this script that eased my life and may someday ease another one&#8217;s.<span id="more-57"></span></p>
<p><strong>Instructions</strong></p>
<p>To use this script, follow the next steps:</p>
<ol>
<li>Download the file <strong>conkytodo.sh</strong> from <a href="https://sourceforge.net/projects/fm-conky-todo/files/conkytodo.sh/download" target="_blank">here</a> and place it somewhere safe(e.g. into the <em>Scripts</em> folder).</li>
<li>Open <strong>conkytodo.sh</strong> in the text editor and change the following options:<br />
<strong>MINDMAP_FILE</strong> &#8211; the Freemind file where you keep your to-do list<br />
<strong>TODO_NODE</strong> &#8211; name of the root element of your to-do list. For example, you can  create a node in Freemind called &#8220;To-Do&#8221; and provide this name to this  option, and all child nodes of this branch will be shown in conky.</li>
<li>Allow the file <strong>conkytodo.sh</strong> to be executable. To do this, open the terminal window, go to the directory where the file lies and enter the following:<br />
<blockquote><p>chmod +x conkytodo.sh</p></blockquote>
</li>
<li>Open your conky configuration file and append there these lines:<br />
<blockquote><p>max_user_text 16384<br />
${execpi 10 <em>~/Scripts/conkytodo.sh</em>}</p></blockquote>
<p>The first option extends the limit for a text that a command can write.  The second one actually outputs the text and specifies the delay  between updates (here it is 10 seconds) and the path to the script (of  course, change it to where your script is).</li>
<li>That&#8217;s all, now if everything is right, your conky will print the name  of nodes from the to-do branch (which name you specified in step 2).</li>
</ol>
<div id="_mcePaste" style="position:absolute;left:-10000px;top:59px;width:1px;height:1px;overflow:hidden;">especially</div>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/codethat.wordpress.com/57/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/codethat.wordpress.com/57/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/codethat.wordpress.com/57/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/codethat.wordpress.com/57/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/codethat.wordpress.com/57/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/codethat.wordpress.com/57/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/codethat.wordpress.com/57/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/codethat.wordpress.com/57/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/codethat.wordpress.com/57/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/codethat.wordpress.com/57/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/codethat.wordpress.com/57/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/codethat.wordpress.com/57/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/codethat.wordpress.com/57/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/codethat.wordpress.com/57/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=codethat.wordpress.com&amp;blog=11382405&amp;post=57&amp;subd=codethat&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://codethat.wordpress.com/2010/08/25/show-the-to-do-list-from-your-freemind-in-conky/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/db0523c869c5311d95341801da7a69da?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">alexyakushev</media:title>
		</media:content>
	</item>
		<item>
		<title>Go console</title>
		<link>http://codethat.wordpress.com/2010/08/08/go-console/</link>
		<comments>http://codethat.wordpress.com/2010/08/08/go-console/#comments</comments>
		<pubDate>Sun, 08 Aug 2010 09:12:55 +0000</pubDate>
		<dc:creator>alexyakushev</dc:creator>
				<category><![CDATA[Linux]]></category>

		<guid isPermaLink="false">http://codethat.wordpress.com/?p=47</guid>
		<description><![CDATA[Sooner or later every user who got started using Linux with fancy Ubuntu windows has to get acquainted with big and scary Console. White letters on the black background, lots of typing and any sings of light in this long tunnel. But is it so bad? Console is an excellent solution which can help to [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=codethat.wordpress.com&amp;blog=11382405&amp;post=47&amp;subd=codethat&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p><!-- 		@page { margin: 0.79in } 		P { margin-bottom: 0.08in } -->Sooner or later every user who got started using <strong>Linux</strong> with fancy <strong>Ubuntu</strong> windows has to get acquainted with big and scary Console. White letters on the black background, lots of typing and any sings of light in this long tunnel. But is it so bad? Console is an excellent solution which can help to deal with lots of problems way faster than moving the mouse around.<span id="more-47"></span></p>
<p>Another option why you should like working in a console is if you use <strong>ssh</strong> a lot. Sure you can connect to a remote terminal with <strong>ssh</strong> using -X option, so it would transfer the windows directly from one <strong>X11</strong> server to another. But this can still be a bit slow and annoying.</p>
<p>Though, today we&#8217;ll try to modify our working environment for active console usage and maximal convenience for that. I won&#8217;t describe you common hot-keys or basic tips and tricks because there are loads of them on the Internet. I just want to share with some software that can make your migration to a console less hard and painful. So, here we go.</p>
<p>1. First of all, to use console effectively you have to have a good shell. You are probably equipped with <strong>bash</strong> or <strong>dash</strong>, but my choice is <a href="http://www.zsh.org/" target="_blank">zsh</a>. Why <strong>zsh</strong>? It&#8217;s command completion feature is really nice, it can complete arguments and parameters for most popular commands, it can correct your spelling mistakes, it shares the command history across all active shells. And above all that, <strong>zsh</strong> is very customizable.</p>
<p>2. After that, we need a terminal multiplexer, if we don&#8217;t want to spawn dozens of terminal windows (or we just cannot, as in <strong>ssh</strong> case). <a href="http://www.gnu.org/software/screen/" target="_blank">GNU Screen</a> is perfect for this. It can store multiple sessions in just one window, switch between them, operate them however you like. But the most toasty feature is sharable sessions, so that you can join remotely to a server, create a session, and then reconnect to the same session later (even from the other computer).</p>
<p>3. Now, file manager. For sure, you&#8217;d like to use <a href="http://www.midnight-commander.org/" target="_blank">mc</a>. It is a huge piece of software, very extensible and constantly evolving. It somehow resembles the well-known <strong>Norton Commander</strong>, so it will be easy for former <strong>nc</strong> users to get used to <strong>mc</strong>.</p>
<p>4. Talking. If you use <strong>Pidgin</strong>, you&#8217;ll be glad there is <a href="http://developer.pidgin.im/wiki/Using%20Finch" target="_blank">finch</a>. <strong>Finch</strong> is a console clone of <strong>pidgin</strong>, it has the same interface, it uses <strong>pidgin</strong> configuration, so you don&#8217;t have to configure it at all. Another nice program is <a href="http://mcabber.com/" target="_blank">mcabber</a> &#8211; a lightweight console XMPP client. It is highly configurable and has many handy features like external action triggers.</p>
<p>5. Music. You probably already heard about <a href="http://mpd.wikia.com/wiki/Music_Player_Daemon_Wiki" target="_blank">mpd</a>. <strong>Music Player Daemon</strong> is an fascinating software used all over the place where a network exists. It is a music server that can be controlled by any of the large amount of clients on the same computer or remotely. The simplest client for <strong>mpd</strong> is <a href="http://mpd.wikia.com/wiki/Client:Mpc" target="_self">mpc</a> &#8211; it has no interface at all, you just type commands to control the player. Hence, it requires no resources at all, neither does <strong>mpd</strong> &#8211; it is extremely lightweight. The list of most popular <strong>mpd</strong> clients you can find <a href="http://mpd.wikia.com/wiki/Clients" target="_blank">here</a>.</p>
<p>6. Torrents. If you use <strong>transmission</strong> then your choice would probably be <a href="http://linux.die.net/man/1/transmission-daemon" target="_blank">transmission-daemon</a> with <strong>transmission-cli</strong>. Daemon should be working on the server that would download torrents, and using client you can control the process, locally or remotely. Another option is a well-known <a href="http://libtorrent.rakshasa.no/" target="_blank">rtorrent</a>, even more client-server oriented and very extensible. There are clients for it that allow you manage your torrents via web interface from any computer which is really convenient.</p>
<p>So, as you see, console is full of programs that can easily replace their GUI counterparts. And although, you cannot do everything you want from the console (for instance, browsing. Times ago, there was links &#8211; text-based console browser, but it couldn&#8217;t catch up with the speed of web development), terminal window can become your sincere and beloved friend &#8211; always accessible, always fast, always there to execute your dreams.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/codethat.wordpress.com/47/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/codethat.wordpress.com/47/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/codethat.wordpress.com/47/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/codethat.wordpress.com/47/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/codethat.wordpress.com/47/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/codethat.wordpress.com/47/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/codethat.wordpress.com/47/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/codethat.wordpress.com/47/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/codethat.wordpress.com/47/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/codethat.wordpress.com/47/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/codethat.wordpress.com/47/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/codethat.wordpress.com/47/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/codethat.wordpress.com/47/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/codethat.wordpress.com/47/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=codethat.wordpress.com&amp;blog=11382405&amp;post=47&amp;subd=codethat&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://codethat.wordpress.com/2010/08/08/go-console/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/db0523c869c5311d95341801da7a69da?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">alexyakushev</media:title>
		</media:content>
	</item>
	</channel>
</rss>
