集中線GIFメーカー in Golang

http://hitode909.hatenablog.com/entry/2015/09/13/205925

I wrote @hitode909's 集中線GIFメーカー(Awesome Web application) in Golang. This is command line application and you can use this as below.

Repository

https://github.com/syohex/speedline

Sample Output

f:id:syohex:20150915200436g:plain

f:id:syohex:20150915200446g:plain

Code

package main

import (
    "flag"
    "fmt"
    "math"
    "math/rand"

    "github.com/gographics/imagick/imagick"
)

var (
    output = flag.String("o", "output.gif", "output filename")
    color  = flag.String("color", "black", "background color")
)

func speedLine(mw *imagick.MagickWand, aw *imagick.MagickWand) error {
    cols, rows := mw.GetImageHeight(), mw.GetImageWidth()

    dw := imagick.NewDrawingWand()
    defer dw.Destroy()
    cw := imagick.NewPixelWand()
    cw.SetColor(*color)
    dw.SetFillColor(cw)

    center := []float64{float64(cols) / 2.0, float64(rows) / 2.0}
    const radiusCenter float64 = 0.75
    const step float64 = 0.02
    const bold float64 = 1.0
    var theeta float64

    for theeta < math.Pi*2 {
        stepNoise := rand.Float64() + 0.5
        theeta += step * stepNoise
        radiusCenterNoise := rand.Float64()*0.3 + 1.0
        boldNoise := rand.Float64() + 0.7 + 0.3

        point0 := imagick.PointInfo{
            X: math.Sin(theeta)*center[0]*radiusCenter*radiusCenterNoise + center[0],
            Y: math.Cos(theeta)*center[1]*radiusCenter*radiusCenterNoise + center[1],
        }
        point1 := imagick.PointInfo{
            X: math.Sin(theeta)*center[0]*2 + center[0],
            Y: math.Cos(theeta)*center[1]*2 + center[1],
        }
        point2 := imagick.PointInfo{
            X: math.Sin(theeta+step*bold*boldNoise)*center[0]*2 + center[0],
            Y: math.Cos(theeta+step*bold*boldNoise)*center[1]*2 + center[1],
        }

        dw.Polygon([]imagick.PointInfo{point0, point1, point2})
    }

    if err := aw.DrawImage(dw); err != nil {
        return err
    }

    return nil
}

func main() {
    flag.Parse()

    imagick.Initialize()
    defer imagick.Terminate()

    mw := imagick.NewMagickWand()
    defer mw.Destroy()
    aw := imagick.NewMagickWand()
    defer aw.Destroy()

    if err := mw.ReadImage(flag.Arg(0)); err != nil {
        panic(err)
    }

    if int(mw.GetNumberImages()) == 1 {
        mw.SetIteratorIndex(0)
        first := mw.GetImage()
        mw.ResetIterator()
        for i := 0; i < 3; i++ {
            mw.AddImage(first.Clone())
        }
    }

    for i := 0; i < int(mw.GetNumberImages()); i++ {
        mw.SetIteratorIndex(i)
        tw := mw.GetImage()
        aw.AddImage(tw)
        if err := speedLine(tw, aw); err != nil {
            fmt.Println(err)
            return
        }
        tw.Destroy()
    }
    mw.ResetIterator()

    aw.SetOption("loop", "0")
    if err := aw.WriteImages(*output, true); err != nil {
        panic(err)
    }
}

Emacs daemon memo

Run named daemon

Emacs --daemon command line option can accept name argument(like --daemon=server1).

% emacs --daemon=vim -Q
% emacs --daemon=atom -Q

Sending S-expression via emacsclient

And we can specify server by -s(--socket-name) option of emacsclient as below. (We can also specify socket file path instead of daemon name)

% emacsclient -s vim -e '(emacs-pid)'
% emacsclient -s atom -e '(shell-command-to-string "vim --version")'

Shutdown emacs daemon

We can stop daemon by sending kill-emacs

% emacsclient -s vim -e '(kill-emacs)'

If you stop emacs daemon by kill command, you should also remove socket file at ${temporary-file-directory}/emacs${pid}/${servername} such as /tmp/emacs1000/vim.

f:id:syohex:20150912001428g:plain

Better space handling in helm-do-ag

I have implemented better space handling in helm-ag. If you want to input pattern which contains space, you can use escaped space like pattern1\ pattern2. Such pattern matches lines which have pattern1 pattern2. (While pattern1 pattern2 matches lines which have both pattern1 and pattern2.

Example

f:id:syohex:20150906105615g:plain

First I input apple orange. This pattern matches all lines because all line have both apple and orange. Second I input apple\ orange, first and third line are matched but second line is not matches because second line does not have apple orange

ac-emoji for Linux users

We can use emoji fonts other than MacOSX platform. (However MacOSX fonts is good looking :-()

Installing Symbola font

http://zhm.github.io/symbola/

Download Symbola.ttf and put it into fonts directory such as ~/.fonts.

% cd ~/.fonts
% curl -LO http://zhm.github.io/symbola/fonts/Symbola.ttf

NOTE

Debian/Ubuntu provides Symbola font as package, ttf-ancient-fonts or ttf-ancient-fonts-symbola. And some other distributions provide too. Please check your package system before installing Symbola font manually.

Configuration

Add following configuration in your init.el

(set-fontset-font
 t 'symbol
 (font-spec :family "Symbola") nil 'prepend)

Screenshot

We can use emoji on Linux now.

ac-emoji-linux

auto-complete source for Rust

ac-racer

Repository

https://github.com/syohex/emacs-ac-racer

How to use

(defun my/racer-mode-hook ()
  (ac-racer-setup))
(add-hook 'racer-mode-hook 'my/racer-mode-hook)

(custom-set-variables
 '(racer-cmd (expand-file-name "~/src/racer/target/release/racer"))
 '(racer-rust-src-path (expand-file-name "~/src/rustc/src")))

You must set racer-cmd and racer-rust-src-path. (racer-cmd is path of racer command. racer-rust-src-path is path of rustc source code)

Summary

ac-racer is alpha quality. Please report me via github issues or twitter if you have any suggestions or issues.

Text::Xslate 3.3.6 released

https://metacpan.org/release/SYOHEX/Text-Xslate-3.3.6

I released Text::Xslate 3.3.6. This version fixed include issue.

Include Issue

Perl VM stack pointer goes wrong by each include call. For example.

#!perl
use strict;
use warnings;
use Text::Xslate;

my $tx = Text::Xslate->new(
    path => {
        'body.tx' => ': block body | reverse -> { include text }',
        'text.tx' => 'foo',
    },
    function => {
        reverse => sub { scalar reverse $_[0] },
    },
);

print $tx->render('body.tx');

reverse function takes foo as first argument but it is undefined value.

% perl test.pl
Text::Xslate: Use of uninitialized value $_[0] in reverse at test.pl line 12.
 (<string>:1) at test.pl line 12.
    main::__ANON__(undef, foo) called at test.pl line 16
    eval {...} called at test.pl line 1

Why this behavior ? Because foo is 2nd argument. Following code works well.

#!perl
use strict;
use warnings;
use Text::Xslate;

my $tx = Text::Xslate->new(
    path => {
        'body.tx' => ': block body | reverse -> { include text }',
        'text.tx' => 'foo',
    },
    function => {
        reverse => sub { scalar reverse $_[1] },
    },
);

print $tx->render('body.tx');

oof is printed. If include is called two times, foobar is 3rd argument. 1st and 2nd arguments are undef.

#!perl
use strict;
use warnings;
use Text::Xslate;

my $tx = Text::Xslate->new(
    path => {
        'body.tx' => ': block body | reverse -> { include text; include text2 }',
        'text.tx' => 'foo',
        'text2.tx' => 'bar',
    },
    function => {
        reverse => sub { scalar reverse $_[2] },
    },
);

print $tx->render('body.tx');

Conclusion

I released Text::Xslate 3.3.6. Please report us via github issues if you have any problems.