Blogged by Ujihisa. Standard methods of programming and thoughts including Clojure, Vim, LLVM, Haskell, Ruby and Mathematics written by a Japanese programmer. github/ujihisa

Monday, December 31, 2012

Day 1 -- JavaScript in a week

https://github.com/ujihisa/jinaw

I'll make an implementation of a subset of programming language JavaScript within a week.

next post

Defining a subset of JavaScript

The implementation should execute the following JavaScript code.

var acc = 'dummy';
var f = function() {
  var acc = [];
  return function(x) {
    return x ? acc.push(x)&&f(x - 1) : acc;
  };
  console.log("this won't show up!");
}();

String.prototype.ujihisa = function() {
  var x = 10;
  return this + f(x);
}

console.log("hello".ujihisa());
console.log(acc == 'dummy');
console.log({'a': 2}.a == 2);

output:

hello10,9,8,7,6,5,4,3,2,1
true
true

That sample JS code covers the following important aspects.

  • statements and expressions
  • literals (String, Number, Function, Array and Object)
  • function call, method call, operators, and index/key access of Object
  • implicit convertion (String + Number)
  • lexical scope (see acc var)
  • method addition by prototype
  • return exits from the current function

The implementation consists of the following 2 parts.

  • parser (JS code to internal representation in S-expression)
  • runtime

I'll work on runtime first in Clojure, then work on parser in Haskell with parsec.

parsing

I don't implement the parser for now but I simply parse the sample code by hand. the first 2 statements will be like the below.

before:

var acc = 'dummy';
var f = function() {
    var acc = [];
    return function(x) {
        return x ? acc.push(x)&&f(x - 1) : acc;
    };
}();

after:

'[(var 'acc "dummy")
  (var 'f
       (call
         (function []
                   [[(var 'acc (array))
                     (return
                       (function ['x]
                                 [[(return (if 'x
                                             (and (mcall 'push 'acc ['x])
                                                  (call 'f [(minus 'x 1)]))
                                             'acc))]]))]])
         []))]

Day 1 progress

https://github.com/ujihisa/jinaw/commit/6902cd4e9382e2da58fb9d43f8069256e8fe1ded

  • just finished implementing var and console.log

    (run '[(var x "hello")
           (fcall 'console.log ['x])])
  • currently console.log is just a single name of built-in function

https://github.com/ujihisa/jinaw/commit/30ad8c898a1c806735eaa990656258537b65a34c

  • changed the structure a little bit.. to separate run to handle statements and evaluate to handle an expression
  • now it supports nested function calls

    (run '[(var x 1)
           (fcall 'console.log [(fcall '+ ['x 2])])])

Sunday, October 21, 2012

I'll be in Japan and Taiwan for a while

  • Taiwan: Oct 28
  • Japan: Oct 28 to Nov 21
  • Taiwan: Nov 21 to Nov 23

I have no particular plans in Taiwan yet besides having awesome 小籠包s there.

小籠包 from wikipedia

小籠包 from wikipedia

Whereas I have plans in Japan -- I'll be organizing 4 conferences/meetups there.

If you are interested in either some of the topics above or me, and have plan to visit Kanto or Kansai area, you should check it out and give a presentation there.

Saturday, October 13, 2012

Mergesort in Haskell, Clojure and Scheme

In Haskell

Mergesort requires O(1) index access so I used Data.Vector instead of List.

import qualified Data.Vector as V

-- length (sort2 x y) == 2
-- sorted (sort2 x y) is true
sort2 :: Ord a => a -> a -> V.Vector a
sort2 x y = if x < y then V.fromList [x, y] else V.fromList [y, x]

-- contract: sorted xs && sorted ys
-- length (merge xs ys) == length xs + length ys
-- sorted (merge xs ys) is true
merge :: Ord a => V.Vector a -> V.Vector a -> V.Vector a
merge xs ys = case (xs V.!? 0, ys V.!? 0) of
  (Nothing, _) -> ys
  (_, Nothing) -> xs
  (Just x, Just y) -> if x < y
    then x `V.cons` merge (V.tail xs) ys
    else y `V.cons` merge xs (V.tail ys)

-- length (mergeSort xs) == length xs
-- sorted (mergeSort xs) is true
mergeSort' :: Ord a => V.Vector a -> V.Vector a
mergeSort' xs = case V.length xs of
  0 -> xs
  1 -> xs
  2 -> sort2 (V.head xs) (V.last xs)
  otherwise -> let (a, b) = split2 xs in
               merge (mergeSort' a) (mergeSort' b)

mergeSort :: Ord a => [a] -> [a]
mergeSort = V.toList . mergeSort' . V.fromList


-- contract: length xs > 2
-- (a, b) = split2 xs => length a + length b == length xs
split2 :: Ord a => V.Vector a -> (V.Vector a, V.Vector a)
split2 xs = (V.take (V.length xs `div` 2) xs, V.drop (V.length xs `div` 2) xs)

main = do
  print $ mergeSort [3, 1, 4, 1, 5, 9, 2]

In Clojure

(defn sort2 [x y]
  (if (< x y) [x y] [y x]))

(defn merge2 [xs ys]
  (cond
    (empty? xs) ys
    (empty? ys) xs
    :else
    (let [x (first xs) y (first ys)]
      (if (< x y)
        (cons x (merge2 (rest xs) ys))
        (cons y (merge2 (rest ys) xs))))))

(defn merge-sort [xs]
  (cond
    (> 2 (count xs)) xs
    (= 2 (count xs)) (apply sort2 xs)
    :else (let [[a b] (split-at (/ (count xs) 2) xs)]
            (merge2 (merge-sort a) (merge-sort b)))))

(prn (merge-sort [3 1 4 1 5 9 2]))

Scheme (Gauche)

With List (slow)

(use srfi-1)

(define (sort2 x y)
  (if (< x y) (list x y) (list y x)))

(define (nil? xs)
  (eq? xs '()))

(define (merge2 xs ys)
  (cond
    ((nil? xs) ys)
    ((nil? ys) xs)
    ((let ((x (car xs))
           (y (car ys)))
       (if (< x y)
         (cons x (merge2 (cdr xs) ys))
         (cons y (merge2 xs (cdr ys))))))))

(define (merge-sort xs)
  (cond
    ((> 2 (length xs)) xs)
    ((= 2 (length xs)) (apply sort2 xs))
    ((receive (a b) (split-at xs (/ (length xs) 2))
       (merge2 (merge-sort a) (merge-sort b))))))

(print (merge-sort '(3 1 4 1 5 9 2 6)))

With Vector (fast)

(use srfi-43)

(define (sort2 x y)
  (if (< x y) (vector x y) (vector y x)))

(define (merge2 xs ys)
  (cond
    ((vector-empty? xs) ys)
    ((vector-empty? ys) xs)
    ((let ((x (~ xs 0))
           (y (~ ys 0)))
       (if (< x y)
         (vector-append (vector x) (merge2 (vector-copy xs 1 -1) ys))
         (vector-append (vector y) (merge2 xs (vector-copy ys 1 -1))))))))

(define (merge-sort xs)
  (cond
    ((> 2 (vector-length xs)) xs)
    ((= 2 (vector-length xs)) (sort2 (~ xs 0) (~ xs 1)))
    ((let ((a (vector-copy xs 0 (div (vector-length xs) 2)))
           (b (vector-copy xs (div (vector-length xs) 2) -1)))
       (merge2 (merge-sort a) (merge-sort b))))))

(print (merge-sort #(3 1 4 1 5 9 2 6)))

Tuesday, September 18, 2012

Quicksort in Lua

function rest(xs)
  local ys = {}
  for i = 2, #xs do
    table.insert(ys, xs[i])
  end
  return ys
end

function concat(xs, ys)
  local zs = {}
  for _, v in ipairs(xs) do
    table.insert(zs, v)
  end
  for _, v in ipairs(ys) do
    table.insert(zs, v)
  end
  return zs
end

function qsort(xs)
  if (#xs < 2) then
    return xs
  end
  local p, xs = xs[1], rest(xs)
  local lesser, greater = {}, {}
  for _, x in ipairs(xs) do
    if x < p then
      table.insert(lesser, x)
    else
      table.insert(greater, x)
    end
  end
  return concat(qsort(lesser), concat({p}, qsort(greater)))
end

xs = {3, 1, 4, 1, 5, 9}
for _, x in ipairs(qsort(xs)) do
  io.write(x .. ' ')
end
print()
-- to check if the original xs isn't destroyed
for _, x in ipairs(xs) do
  io.write(x .. ' ')
end

This works, but the code looks more complicated than it should be.

I rewrote it with using Underscore.lua and it made the code much easier to read.

_ = require 'underscore'

function concat(xs, ys)
  return _(ys):reduce(xs, function(m, x)
    return _(m):push(x)
  end)
end

function qsort(xs)
  if (#xs < 2) then
    return xs
  end
  local p, xs = xs[1], _(xs):rest()
  return concat(
    _(qsort(_(xs):select(function(x) return x < p end))):push(p),
    qsort(_(xs):select(function(x) return x >= p end)))
end

xs = {3, 1, 4, 1, 5, 9}
_(qsort(xs)):each(function(x)
  io.write(x .. ' ')
end)
print()
_(xs):each(function(x)
  io.write(x .. ' ')
end)

Sunday, September 16, 2012

Eval in Lua

assert(loadstring(string.format('return %s', something)))()

The call of assert is only for debug-friendly.

Freeciv on Mac OS X

If you haven't play Freeciv, it's a good opportunity to try it. It's a freesoftware which is based on Civilization™. I've been playing Freeciv recently.

It's very easy to install Freeciv on Gentoo Linux: just emerge it. It's not very easy to install it on Mac OS X Snow Leopard.

There are 3 ways to install Freeciv on Mac OS X Snow Leopard. (1) 2.1.9 binary package for Snow Leopard, (2) 2.3.1 with sdl on Homebrew's Homebrew-games, or (3) jinhao's patched version of Homebrew formula. Dont choose (1) or (2).

Freeciv has 2 ways to provide GUI interface; sdl and gtk2. sdl interface is very inconvenient. gtk2 interface is much much better but it needs lots of compiling. Still I recommend gtk2 version for everybody.

Note that don't start Freeciv server on Mac OS X. I don't know why but it consumes all the CPU power. Singleplay in Freeciv simply means it starts server and connects itself. Start a server on a Gentoo machine and connect there to play.

Enjoy!

Sunday, September 9, 2012

English Words Lookup/Completion on Gentoo

When I used Mac OS X, I used look command a lot.

$ look standa
standage
standard
standardbred
standardizable
standardization
standardize
standardized
standardizer
standardwise

A Vim plugin neco-look makes your Vim auto-complete English words, using look command internally.

I had been looking for how to use the look command on Gentoo Linux. I finally found that how to do that today.. just install the following packages.

  • sys-apps/util-linux
  • sys-apps/miscfiles

I used e-file command to find portage packages which depend on look command and its dependency /usr/share/dict/words. Install app-portage/pfl to use e-file.

Friday, September 7, 2012

DNS Lookup in Scala

import javax.naming.directory.{InitialDirContext, Attribute}
import javax.naming.NamingException
import scala.collection.JavaConversions._

object L {
    def main(args: Array[String]) {
        println('ip, lookupIp(args.head))
    }

    def lookupIp(host: String): List[String] = {
        val attributes = try {
            new InitialDirContext getAttributes ("dns:/%s" format host)
        } catch {
            case _: NamingException => return Nil
        }
        val list = {
            val attributeEnumeration = attributes.getAll
            var list = List[Attribute]()
            while (attributeEnumeration.hasMore)
                list = attributeEnumeration.next :: list
            attributeEnumeration.close
            list.reverse
        }
        list map (x => x.getID -> x.get.toString) flatMap {
            case ("A", x) => List(x)
            case ("CNAME", x) => lookupIp(x)
            case (_, x) => Nil
        }
    }
}

Sunday, September 2, 2012

Minecraft MOD in Clojure

http://github.com/ujihisa/cloft

I've been writing Clojure for this Minecraft server MOD. This MOD, cloft, uses Bukkit API and is compatible with Minecraft client version 1.3.1+, including the latest stable version 1.3.2.

This MOD was originally based on clj-minecraft made by Deon Moolman.

I'm also running my own minecraft server with using cloft. If you are interested in playing, feel free to ask me on Twitter.

Wednesday, July 4, 2012

ZeroMQ Versions and Bindings

ZeroMQ has two major versions; 2.x.y and 3.x.y. Even though the latter is still release candidate, people are already using it. The problem is that these two versions don't have compatibility. If one system uses version 3.x.y, whole other systems which talk to the system have to use 3.x.y.

There are some binding libraries for each programming languages. Note that some of them don't support one of the versions. The below is the list as of today.

  • Haskell
    • zeromq-haskell: 2.1.x
    • zeromq-haskell3: 3.1.x
    • just use cabal to install them
  • Clojure
    • (Not directly for Clojure but for JVM languages in general)
    • jzmq: both 2.x.y and 3.x.y
    • there are no official clojar/maven/apt/portage packages. one for gentoo is here
  • Scala
    • zeromq-scala-binding: 2.1.x
      • (akka-zeromq uses it)
    • jzmq: both 2.x.y and 3.x.y
      • (ditto in Clojure)
  • Ruby
    • rbzmq: 2.x.y
  • Python
    • pyzmq: 2.x.x (experimentally 3.x.x)

Use Haskell, Clojure, Scala or Python to use ZeroMQ even if you use zeromq version 2 just in case at least one system uses version 3. If you need to use Ruby, just use JRuby to use jzmq. It's not very easy to install jzmq, but if you are using Gentoo, it's easy.

Wednesday, May 9, 2012

Octal or not Octal

A number literal with begins with 0 differs between programming languages. For example, a programming language considers 015 as 13, or as 15 just by ignoring the first 0, or even throws an error.

I categorized some programming languages by the view.

  • 015 == 13
    • Clojure
    • Scala
    • Java
    • Ruby
    • C
    • Vim script
    • JavaScript
  • 015 == 15
    • Haskell
    • Scheme
    • Emacs Lisp
    • Lua
    • Common Lisp
  • Exception
    • Python
    • CoffeeScript

Monday, April 2, 2012

Concurrent PI-Calculator in Clojure

Inspired by a tutorial about akka tutorial in Scala about making a concurrent PI calculator, I made similar on in Clojure without actor model but just with thread and atom.

(ns pi.core
  (:import [java.util.concurrent Executors])
  (:gen-class))

(def sum (partial reduce +))

(defn f [n]
  (/ (if (even? n) 1 -1) (inc (* 2 n))))

(defn solver1 [n]
  (double (* 4 (sum (map f (range 0 n))))))

(defn solver2 [n]
  (def a (atom 0))
  (def tasks
    (let [unit (/ n 4)]
      (for [m (range 0 4)]
        (fn []
          (swap! a (partial + (sum (map f (range (* unit m) (* unit (inc m)))))))))))

  (let [pool (Executors/newFixedThreadPool (count tasks))]
    (doseq [f (.invokeAll pool tasks)]
      (.get f))
    (.shutdown pool))
  (double (* 4 @a)))

(defn -main []
  (let [n 2000]
    (prn (solver1 n))
    (prn (solver2 n))))

Commenting out the line of solver1/solver2, I got the following results on my 2-core with hyper-threading machine; virtually it's 4 core machine.

solver1

real 3.80
user 4.66
sys 0.09
3.141092653621043

solver2

real 2.01
user 3.44
sys 0.05
3.141092653621043

Comparing to the sequential version, the concurrent version was almost 2 times faster.

Sunday, February 5, 2012

IBus-Mozc for Kana Input on US Keyboard Layout

There are two major input methods in Japanese language; roma-input and kana-input (*1). Roma-input layouts in popular implementations are same while kana-input layouts are different among implementations for some reason when it's on US Keyboard layout.

I'm a kana typer and a user of US Keyboard Layout. Kana layout of Mac OS X Kotoeri layout and kana layout of ibus-mozc are very different. I had used Kotoeri for a long time, so I decided to change the layout of mozc, but mozc doesn't have an interface to change the layout.

I wrote a patch to make mozc same to Kotoeri's.

kana-layout.patch:

Index: unix/ibus/key_translator.cc
===================================================================
--- unix/ibus/key_translator.cc (revision 94)
+++ unix/ibus/key_translator.cc (working copy)
@@ -254,100 +254,100 @@
   // to Right Shift).
   { '\\', "", "" },
 }, kana_map_us[] = {
-  { '`' , "\xe3\x82\x8d", "\xe3\x82\x8d" },  // "ろ", "ろ"
-  { '~' , "\xe3\x82\x8d", "\xe3\x82\x8d" },  // "ろ", "ろ"
-  { '1' , "\xe3\x81\xac", "\xe3\x81\xac" },  // "ぬ", "ぬ"
-  { '!' , "\xe3\x81\xac", "\xe3\x81\xac" },  // "ぬ", "ぬ"
-  { '2' , "\xe3\x81\xb5", "\xe3\x81\xb5" },  // "ふ", "ふ"
+  { '$' , "\xe3\x81\x85", "\xe3\x81\x85" },  // "ぅ", "ぅ"
+  { '(' , "\xe3\x82\x87", "\xe3\x82\x87" },  // "ょ", "ょ"
+  { ',' , "\xe3\x81\xad", "\xe3\x81\xad" },  // "ね", "ね"
+  { '0' , "\xe3\x82\x8f", "\xe3\x82\x8f" },  // "わ", "わ"
+  { '4' , "\xe3\x81\x86", "\xe3\x81\x86" },  // "う", "う"
+  { '8' , "\xe3\x82\x86", "\xe3\x82\x86" },  // "ゆ", "ゆ"
+  { '<' , "\xe3\x80\x81", "\xe3\x80\x81" },  // "、", "、"
   { '@' , "\xe3\x81\xb5", "\xe3\x81\xb5" },  // "ふ", "ふ"
-  { '3' , "\xe3\x81\x82", "\xe3\x81\x81" },  // "あ", "ぁ"
-  { '#' , "\xe3\x81\x82", "\xe3\x81\x81" },  // "あ", "ぁ"
-  { '4' , "\xe3\x81\x86", "\xe3\x81\x85" },  // "う", "ぅ"
-  { '$' , "\xe3\x81\x86", "\xe3\x81\x85" },  // "う", "ぅ"
-  { '5' , "\xe3\x81\x88", "\xe3\x81\x87" },  // "え", "ぇ"
-  { '%' , "\xe3\x81\x88", "\xe3\x81\x87" },  // "え", "ぇ"
-  { '6' , "\xe3\x81\x8a", "\xe3\x81\x89" },  // "お", "ぉ"
-  { '^' , "\xe3\x81\x8a", "\xe3\x81\x89" },  // "お", "ぉ"
-  { '7' , "\xe3\x82\x84", "\xe3\x82\x83" },  // "や", "ゃ"
-  { '&' , "\xe3\x82\x84", "\xe3\x82\x83" },  // "や", "ゃ"
-  { '8' , "\xe3\x82\x86", "\xe3\x82\x85" },  // "ゆ", "ゅ"
-  { '*' , "\xe3\x82\x86", "\xe3\x82\x85" },  // "ゆ", "ゅ"
-  { '9' , "\xe3\x82\x88", "\xe3\x82\x87" },  // "よ", "ょ"
-  { '(' , "\xe3\x82\x88", "\xe3\x82\x87" },  // "よ", "ょ"
-  { '0' , "\xe3\x82\x8f", "\xe3\x82\x92" },  // "わ", "を"
-  { ')' , "\xe3\x82\x8f", "\xe3\x82\x92" },  // "わ", "を"
-  { '-' , "\xe3\x81\xbb", "\xe3\x83\xbc" },  // "ほ", "ー"
-  { '_' , "\xe3\x81\xbb", "\xe3\x83\xbc" },  // "ほ", "ー"
-  { '=' , "\xe3\x81\xb8", "\xe3\x81\xb8" },  // "へ", "へ"
-  { '+' , "\xe3\x81\xb8", "\xe3\x81\xb8" },  // "へ", "へ"
-  { 'q' , "\xe3\x81\x9f", "\xe3\x81\x9f" },  // "た", "た"
-  { 'Q' , "\xe3\x81\x9f", "\xe3\x81\x9f" },  // "た", "た"
-  { 'w' , "\xe3\x81\xa6", "\xe3\x81\xa6" },  // "て", "て"
-  { 'W' , "\xe3\x81\xa6", "\xe3\x81\xa6" },  // "て", "て"
-  { 'e' , "\xe3\x81\x84", "\xe3\x81\x83" },  // "い", "ぃ"
-  { 'E' , "\xe3\x81\x84", "\xe3\x81\x83" },  // "い", "ぃ"
-  { 'r' , "\xe3\x81\x99", "\xe3\x81\x99" },  // "す", "す"
-  { 'R' , "\xe3\x81\x99", "\xe3\x81\x99" },  // "す", "す"
+  { 'D' , "\xe3\x81\x97", "\xe3\x81\x97" },  // "し", "し"
+  { 'H' , "\xe3\x81\x8f", "\xe3\x81\x8f" },  // "く", "く"
+  { 'L' , "\xe3\x82\x8a", "\xe3\x82\x8a" },  // "り", "り"
+  { 'P' , "\xe3\x81\x9b", "\xe3\x81\x9b" },  // "せ", "せ"
+  { 'T' , "\xe3\x81\x8b", "\xe3\x81\x8b" },  // "か", "か"
+  { 'X' , "\xe3\x81\x95", "\xe3\x81\x95" },  // "さ", "さ"
+  { '\\' , "\xe3\x81\xb8", "\xe3\x81\xb8" },  // "へ", "へ"
+  { '`' , "\xef\xbd\x80", "\xef\xbd\x80" },  // "`", "`"
+  { 'd' , "\xe3\x81\x97", "\xe3\x81\x97" },  // "し", "し"
+  { 'h' , "\xe3\x81\x8f", "\xe3\x81\x8f" },  // "く", "く"
+  { 'l' , "\xe3\x82\x8a", "\xe3\x82\x8a" },  // "り", "り"
+  { 'p' , "\xe3\x81\x9b", "\xe3\x81\x9b" },  // "せ", "せ"
   { 't' , "\xe3\x81\x8b", "\xe3\x81\x8b" },  // "か", "か"
-  { 'T' , "\xe3\x81\x8b", "\xe3\x81\x8b" },  // "か", "か"
-  { 'y' , "\xe3\x82\x93", "\xe3\x82\x93" },  // "ん", "ん"
-  { 'Y' , "\xe3\x82\x93", "\xe3\x82\x93" },  // "ん", "ん"
-  { 'u' , "\xe3\x81\xaa", "\xe3\x81\xaa" },  // "な", "な"
-  { 'U' , "\xe3\x81\xaa", "\xe3\x81\xaa" },  // "な", "な"
-  { 'i' , "\xe3\x81\xab", "\xe3\x81\xab" },  // "に", "に"
-  { 'I' , "\xe3\x81\xab", "\xe3\x81\xab" },  // "に", "に"
-  { 'o' , "\xe3\x82\x89", "\xe3\x82\x89" },  // "ら", "ら"
+  { 'x' , "\xe3\x81\x95", "\xe3\x81\x95" },  // "さ", "さ"
+  { '|' , "\xe3\x82\x8d", "\xe3\x82\x8d" },  // "ろ", "ろ"
+  { '#' , "\xe3\x81\x81", "\xe3\x81\x81" },  // "ぁ", "ぁ"
+  { '\'' , "\xe3\x81\x91", "\xe3\x81\x91" },  // "け", "け"
+  { '+' , "\xe3\x80\x8c", "\xe3\x80\x8c" },  // "「", "「"
+  { '/' , "\xe3\x82\x81", "\xe3\x82\x81" },  // "め", "め"
+  { '3' , "\xe3\x81\x82", "\xe3\x81\x82" },  // "あ", "あ"
+  { '7' , "\xe3\x82\x84", "\xe3\x82\x84" },  // "や", "や"
+  { ';' , "\xe3\x82\x8c", "\xe3\x82\x8c" },  // "れ", "れ"
+  { '?' , "\xe3\x83\xbb", "\xe3\x83\xbb" },  // "・", "・"
+  { 'C' , "\xe3\x81\x9d", "\xe3\x81\x9d" },  // "そ", "そ"
+  { 'G' , "\xe3\x81\x8d", "\xe3\x81\x8d" },  // "き", "き"
+  { 'K' , "\xe3\x81\xae", "\xe3\x81\xae" },  // "の", "の"
   { 'O' , "\xe3\x82\x89", "\xe3\x82\x89" },  // "ら", "ら"
-  { 'p' , "\xe3\x81\x9b", "\xe3\x81\x9b" },  // "せ", "せ"
-  { 'P' , "\xe3\x81\x9b", "\xe3\x81\x9b" },  // "せ", "せ"
+  { 'S' , "\xe3\x81\xa8", "\xe3\x81\xa8" },  // "と", "と"
+  { 'W' , "\xe3\x81\xa6", "\xe3\x81\xa6" },  // "て", "て"
   { '[' , "\xe3\x82\x9b", "\xe3\x82\x9b" },  // "゛", "゛"
-  { '{' , "\xe3\x82\x9b", "\xe3\x82\x9b" },  // "゛", "゛"
-  { ']' , "\xe3\x82\x9c", "\xe3\x80\x8c" },  // "゜", "「"
-  { '}' , "\xe3\x82\x9c", "\xe3\x80\x8c" },  // "゜", "「"
-  { '\\', "\xe3\x82\x80", "\xe3\x80\x8d" },  // "む", "」"
-  { '|' , "\xe3\x82\x80", "\xe3\x80\x8d" },  // "む", "」"
-  { 'a' , "\xe3\x81\xa1", "\xe3\x81\xa1" },  // "ち", "ち"
-  { 'A' , "\xe3\x81\xa1", "\xe3\x81\xa1" },  // "ち", "ち"
+  { '_' , "\xe3\x81\xbb", "\xe3\x81\xbb" },  // "ほ", "ほ"
+  { 'c' , "\xe3\x81\x9d", "\xe3\x81\x9d" },  // "そ", "そ"
+  { 'g' , "\xe3\x81\x8d", "\xe3\x81\x8d" },  // "き", "き"
+  { 'k' , "\xe3\x81\xae", "\xe3\x81\xae" },  // "の", "の"
+  { 'o' , "\xe3\x82\x89", "\xe3\x82\x89" },  // "ら", "ら"
   { 's' , "\xe3\x81\xa8", "\xe3\x81\xa8" },  // "と", "と"
-  { 'S' , "\xe3\x81\xa8", "\xe3\x81\xa8" },  // "と", "と"
-  { 'd' , "\xe3\x81\x97", "\xe3\x81\x97" },  // "し", "し"
-  { 'D' , "\xe3\x81\x97", "\xe3\x81\x97" },  // "し", "し"
-  { 'f' , "\xe3\x81\xaf", "\xe3\x81\xaf" },  // "は", "は"
+  { 'w' , "\xe3\x81\xa6", "\xe3\x81\xa6" },  // "て", "て"
+  { '{' , "\xe3\x80\x8d", "\xe3\x80\x8d" },  // "」", "」"
+  { '"' , "\xe3\x82\x8d", "\xe3\x82\x8d" },  // "ろ", "ろ"
+  { '&' , "\xe3\x82\x83", "\xe3\x82\x83" },  // "ゃ", "ゃ"
+  { '*' , "\xe3\x82\x85", "\xe3\x82\x85" },  // "ゅ", "ゅ"
+  { '.' , "\xe3\x82\x8b", "\xe3\x82\x8b" },  // "る", "る"
+  { '2' , "\xe3\x81\xb5", "\xe3\x81\xb5" },  // "ふ", "ふ"
+  { '6' , "\xe3\x81\x8a", "\xe3\x81\x8a" },  // "お", "お"
+  { ':' , "\xe3\x82\x8c", "\xe3\x82\x8c" },  // "れ", "れ"
+  { '>' , "\xe3\x80\x82", "\xe3\x80\x82" },  // "。", "。"
+  { 'B' , "\xe3\x81\x93", "\xe3\x81\x93" },  // "こ", "こ"
   { 'F' , "\xe3\x81\xaf", "\xe3\x81\xaf" },  // "は", "は"
-  { 'g' , "\xe3\x81\x8d", "\xe3\x81\x8d" },  // "き", "き"
-  { 'G' , "\xe3\x81\x8d", "\xe3\x81\x8d" },  // "き", "き"
-  { 'h' , "\xe3\x81\x8f", "\xe3\x81\x8f" },  // "く", "く"
-  { 'H' , "\xe3\x81\x8f", "\xe3\x81\x8f" },  // "く", "く"
-  { 'j' , "\xe3\x81\xbe", "\xe3\x81\xbe" },  // "ま", "ま"
   { 'J' , "\xe3\x81\xbe", "\xe3\x81\xbe" },  // "ま", "ま"
-  { 'k' , "\xe3\x81\xae", "\xe3\x81\xae" },  // "の", "の"
-  { 'K' , "\xe3\x81\xae", "\xe3\x81\xae" },  // "の", "の"
-  { 'l' , "\xe3\x82\x8a", "\xe3\x82\x8a" },  // "り", "り"
-  { 'L' , "\xe3\x82\x8a", "\xe3\x82\x8a" },  // "り", "り"
-  { ';' , "\xe3\x82\x8c", "\xe3\x82\x8c" },  // "れ", "れ"
-  { ':' , "\xe3\x82\x8c", "\xe3\x82\x8c" },  // "れ", "れ"
-  { '\'', "\xe3\x81\x91", "\xe3\x81\x91" },  // "け", "け"
-  { '\"', "\xe3\x81\x91", "\xe3\x81\x91" },  // "け", "け"
-  { 'z' , "\xe3\x81\xa4", "\xe3\x81\xa3" },  // "つ", "っ"
-  { 'Z' , "\xe3\x81\xa4", "\xe3\x81\xa3" },  // "つ", "っ"
-  { 'x' , "\xe3\x81\x95", "\xe3\x81\x95" },  // "さ", "さ"
-  { 'X' , "\xe3\x81\x95", "\xe3\x81\x95" },  // "さ", "さ"
-  { 'c' , "\xe3\x81\x9d", "\xe3\x81\x9d" },  // "そ", "そ"
-  { 'C' , "\xe3\x81\x9d", "\xe3\x81\x9d" },  // "そ", "そ"
-  { 'v' , "\xe3\x81\xb2", "\xe3\x81\xb2" },  // "ひ", "ひ"
+  { 'N' , "\xe3\x81\xbf", "\xe3\x81\xbf" },  // "み", "み"
+  { 'R' , "\xe3\x81\x99", "\xe3\x81\x99" },  // "す", "す"
   { 'V' , "\xe3\x81\xb2", "\xe3\x81\xb2" },  // "ひ", "ひ"
+  { 'Z' , "\xe3\x81\xa3", "\xe3\x81\xa3" },  // "っ", "っ"
+  { '^' , "\xe3\x81\x89", "\xe3\x81\x89" },  // "ぉ", "ぉ"
   { 'b' , "\xe3\x81\x93", "\xe3\x81\x93" },  // "こ", "こ"
-  { 'B' , "\xe3\x81\x93", "\xe3\x81\x93" },  // "こ", "こ"
+  { 'f' , "\xe3\x81\xaf", "\xe3\x81\xaf" },  // "は", "は"
+  { 'j' , "\xe3\x81\xbe", "\xe3\x81\xbe" },  // "ま", "ま"
   { 'n' , "\xe3\x81\xbf", "\xe3\x81\xbf" },  // "み", "み"
-  { 'N' , "\xe3\x81\xbf", "\xe3\x81\xbf" },  // "み", "み"
+  { 'r' , "\xe3\x81\x99", "\xe3\x81\x99" },  // "す", "す"
+  { 'v' , "\xe3\x81\xb2", "\xe3\x81\xb2" },  // "ひ", "ひ"
+  { 'z' , "\xe3\x81\xa4", "\xe3\x81\xa4" },  // "つ", "つ"
+  { '~' , "\xe3\x80\x9c", "\xe3\x80\x9c" },  // "〜", "〜"
+  { '!' , "\xe3\x81\xac", "\xe3\x81\xac" },  // "ぬ", "ぬ"
+  { '%' , "\xe3\x81\x87", "\xe3\x81\x87" },  // "ぇ", "ぇ"
+  { ')' , "\xe3\x82\x92", "\xe3\x82\x92" },  // "を", "を"
+  { '-' , "\xe3\x81\xbb", "\xe3\x81\xbb" },  // "ほ", "ほ"
+  { '1' , "\xe3\x81\xac", "\xe3\x81\xac" },  // "ぬ", "ぬ"
+  { '5' , "\xe3\x81\x88", "\xe3\x81\x88" },  // "え", "え"
+  { '9' , "\xe3\x82\x88", "\xe3\x82\x88" },  // "よ", "よ"
+  { '=' , "\xe3\x82\x9c", "\xe3\x82\x9c" },  // "゜", "゜"
+  { 'A' , "\xe3\x81\xa1", "\xe3\x81\xa1" },  // "ち", "ち"
+  { 'E' , "\xe3\x81\x83", "\xe3\x81\x83" },  // "ぃ", "ぃ"
+  { 'I' , "\xe3\x81\xab", "\xe3\x81\xab" },  // "に", "に"
+  { 'M' , "\xe3\x82\x82", "\xe3\x82\x82" },  // "も", "も"
+  { 'Q' , "\xe3\x81\x9f", "\xe3\x81\x9f" },  // "た", "た"
+  { 'U' , "\xe3\x81\xaa", "\xe3\x81\xaa" },  // "な", "な"
+  { 'Y' , "\xe3\x82\x93", "\xe3\x82\x93" },  // "ん", "ん"
+  { ']' , "\xe3\x82\x80", "\xe3\x82\x80" },  // "む", "む"
+  { 'a' , "\xe3\x81\xa1", "\xe3\x81\xa1" },  // "ち", "ち"
+  { 'e' , "\xe3\x81\x84", "\xe3\x81\x84" },  // "い", "い"
+  { 'i' , "\xe3\x81\xab", "\xe3\x81\xab" },  // "に", "に"
   { 'm' , "\xe3\x82\x82", "\xe3\x82\x82" },  // "も", "も"
-  { 'M' , "\xe3\x82\x82", "\xe3\x82\x82" },  // "も", "も"
-  { ',' , "\xe3\x81\xad", "\xe3\x80\x81" },  // "ね", "、"
-  { '<' , "\xe3\x81\xad", "\xe3\x80\x81" },  // "ね", "、"
-  { '.' , "\xe3\x82\x8b", "\xe3\x80\x82" },  // "る", "。"
-  { '>' , "\xe3\x82\x8b", "\xe3\x80\x82" },  // "る", "。"
-  { '/' , "\xe3\x82\x81", "\xe3\x83\xbb" },  // "め", "・"
-  { '?' , "\xe3\x82\x81", "\xe3\x83\xbb" },  // "め", "・"
+  { 'q' , "\xe3\x81\x9f", "\xe3\x81\x9f" },  // "た", "た"
+  { 'u' , "\xe3\x81\xaa", "\xe3\x81\xaa" },  // "な", "な"
+  { 'y' , "\xe3\x82\x93", "\xe3\x82\x93" },  // "ん", "ん"
+  { '}' , "\xe3\x83\xbc", "\xe3\x83\xbc" },  // "ー", "ー"
 };

 }  // namespace
Index: unix/ibus/mozc_engine.cc
===================================================================
--- unix/ibus/mozc_engine.cc    (revision 94)
+++ unix/ibus/mozc_engine.cc    (working copy)
@@ -542,8 +542,7 @@
 #endif

   // TODO(yusukes): use |layout| in IBusEngineDesc if possible.
-  const bool layout_is_jp =
-      !g_strcmp0(ibus_engine_get_name(engine), "mozc-jp");
+  const bool layout_is_jp = 0;

   commands::KeyEvent key;
   if (!key_translator_->Translate(

Here I also made an ebuild for the latest ibus-mozc on gentoo portage. You can just use it if you are a Gentoo user.

http://ujihisa.shiracha.net/static/ibus-mozc-1.3.975.102.tgz

  • *1 There are more variety of other input methods like thumb-shift or kyuuri-kai.

Realtek RTL8191S WLAN Adapter on Gentoo

I bought a wireless network adapter for my Gentoo desktop computer. It's a usb dongle and it says it's Linux-compatible.

RealTek 8191SU

RealTek 8191SU

How to use:

Device Drivers ->
  Staging drivers ->
    RealTek RTL8712U (RTL8192SU) Wireless LAN NIC driver

In the menuconfig.

Sunday, January 22, 2012

AutoKey Rocks

Mac OS X has a built-in keyboard shortcut configuration tool in Preferences. You can set both global key bindings and application-specific key bindings.

I had used this to use Cmd key more often than Ctrl key. For example Google Chrome has default key mappings to go to the next tab by <ctrl-tab> and to the previous tab by <shift-ctrl-tab>. They break your left pinky easily. I mapped them ad <Cmd-j> and <Cmd-k>. That helped the finger.

But there is no such great built-in tool in the Linux world neither in Gnome nor KDE. There is a Keyboard Shortcuts in Preference of Gnome, but it's only for Gnome apps.

AutoKey

AutoKey is a similar tool to the Mac OS X built-in keybinding configuration tool. The differences are (1) AutoKey doesn't map a key to a function in the application's menu and (2) AutoKey enables you to run arbitrary scripts.

It's very easy to install on Debian family distributions such as Ubuntu. Gentoo, on the other hand, has an overlay that has autokey-gtk package, but it's broken. You have to get the source code and build it. It also requires you to install some dependencies manually, but it works.

autokey-gtk on gentoo

autokey-gtk on gentoo

(Added on Jan 24 2012)

There is an issue in autokey that you cannot exclude a window easily. See the end of this discussion to solve it. http://groups.google.com/group/autokey-users/browse_thread/thread/658ad02cfbde8788

Followers