tech.kayac.com

Introduction

Je suis un utilisateur Linux depuis plus de 10 ans. Je fis mes premiers pas avec une distribution Slackware, à une époque ou les gestionnaires de fenêtres étaient encore hésitants. Après un retour sous Windows XP pendant 2 ans, je changeai a nouveau pour Fedora Core (devenu Fedora), puis Mandriva. Enfin, je passai à Ubuntu depuis mon arrivée au Japon, que j’utilise toujours à ce jour. Malgré multiple essais, je n’ai jamais vraiment réussi à utiliser Windows ou Mac OS pour le développement.

Que ce soit dans le cadre privé ou professionnel, l’installation est toujours l’étape laborieuse et répétitive; réinstallation des mêmes logiciels, réédition des mêmes fichiers de configuration sous /home/<user> … Le besoin de centralisation se faisant sentir de plus en plus, la sortie du service de cloud storage Canonical, “Ubuntu One”, fut l’occasion pour moi de m’atteler à cette tâche. Je vais donc présenter ici la façon dont je configure une installation tout fraîche en 3 étapes.

Je maintiens un répertoire home-env à la racine de mon compte Ubuntu One en dessous duquel je place tous les fichiers nécessaires.

I ) Installation de vim et des plugins

D’une manière générale, je suis partisan du minimalisme, que ce soit mon gestionnaire de fenêtre (bureau vierge, nombre d’icones de raccourcis réduit à 3-4 applications) ou les langages de programmation (Scheme & Python); il en va de même pour le choix de l’IDE. Excepté le développement pour Android, j’utilise exclusivement vim. Il est donc tout naturel que l’une des premières commandes soit :

$ sudo apt-get install vim

J’installe également certains plugins vi sur toutes mes machines servant au développement. Tous les plugins sont disponibles sur internet très facilement, mais pour ceux que j’installe systématiquement, je les ai sauvegardés sur Ubuntu One sous home-env, en gardant la même hiérarchie système :

$ home-env/vim/plugin , home-env/vim/doc , home-env/vim/after/ftplugin

Les plugins que je garde toujours sous le coude sont les suivants :

  • fugitive [1] : intégration de git dans vim
  • camelcasemotion [2] : Support de commandes permettant d’effacer/changer une partie du mot écrit en camel case, utilisant la majuscule comme séparateur.
  • pydiction [3] : auto completion pour Python.

II ) Création des fichiers de configuration vi , git et bash

Ja garde chaque fichier de configuration sous un nom différent du nom système, sous la forme conf-file.<username> (sans le [.] au début du fichier). E.g., .vimrc devient vimrc.<username>

Selon le type de fichier de conf., je rajoute une commande permettant d’exécuter les .<username> dans le fichier de conf. correspondant :

.vimrc

$ echo "source ~/Ubuntu\ One/home-env/vimrc.<username>" >> .vimrc

.bashrc

$ echo ". ~/Ubuntu\ One/home-env/bashrc.<username>" >> ~/.bashrc

.gitconfig

La version actuelle de git (1.7.9.x sur mon Ubuntu 12.04) ne permet malheureusement pas l’inclusion de fichiers de configuration externes via une syntaxe particulière. La solution que j’utilise actuellement est de créer un lien symbolique :

$ ln -s ~/Ubuntu\ One/home-env/gitconfig.<username> ~/.gitconfig

Note: 1.7.10 [4] devrait permettre ce type d’inclusion externe avec une définition du type :

[include]
    path = <path>/gitconfig.<username>

En procédant de cette manière, lorsque j’apporte une modification dans un fichier de configuration sur une machine, les changements sont automatiquement uploadés, puis mis à jour sur mes autres machines.

Voici le contenu de mes fichiers de configuration :

vimrc.<username>

syntax on
set sm
set nu
set sc
set is
set hlsearch
set nosi
set bs=2
set ts=4
set winminheight=0

let mapleader = ","
filetype plugin on

imap <Nul> <Space>
map  <Nul> <Nop>
vmap <Nul> <Nop>
cmap <Nul> <Nop>
nmap <Nul> <Nop>

highlight Error ctermbg=red
highlight LeadingTabs ctermfg=lightgrey ctermbg=darkgrey
highlight TrailingWS ctermbg=lightgrey ctermfg=darkgrey

autocmd BufNewFile,BufRead *.sql set filetype=mysql
autocmd BufNewFile,BufRead *.html set filetype=php
autocmd FileType php set et ts=4 sw=4
autocmd FileType python set setlocal expandtab tabstop=4 shiftwidth=4
autocmd BufNewFile,BufRead * let m=matchadd('LeadingTabs', '^\t\+', -1)
autocmd BufNewFile,BufRead * let m2=matchadd('Error', '\%>120v', -1)
autocmd InsertEnter * match TrailingWS /\s\+\%#\@<!$/
autocmd InsertLeave * match TrailingWS /\s\+$/

map <silent> W <Plug>CamelCaseMotion_w
map <silent> B <Plug>CamelCaseMotion_b
map <silent> E <Plug>CamelCaseMotion_e

"clearing highlighted search
nmap <silent> <leader>/ :nohlsearch<CR>

" visual shifting (does not exit Visual mode)
vnoremap < <gv
vnoremap > >gv

let g:pydiction_location = '~/.vim/after/ftplugin/.dict/complete-dict'
let g:pydiction_menu_height = 10

" Opening file only
match TrailingWS /\s\+$/

" backup to /tmp
set backup
set backupdir=~/tmp/vim/bak
set backupskip=~/tmp/vim/bak/*
set directory=~/tmp/vim/swap
set writebackup

set laststatus=2

" Broken down into easily includeable segments
set statusline=%<%f\   " Filename
set statusline+=%w%h%m%r " Options
set statusline+=%{fugitive#statusline()} "  Git Hotness
set statusline+=\ [%{&ff}/%Y]            " filetype
set statusline+=\ [%{getcwd()}]          " current dir
set statusline+=\ [A=\%03.3b/H=\%02.2B] " ASCII / Hexadecimal value of char
set statusline+=%=%-14.(%l,%c%V%)\ %p%%  " Right aligned file nav info

Quelques détails :

  • Je surbrille en gris les tabulations. Que ce soit PHP, Python ou n’importe quel autre langage, j’utilise toujours l’espace pour l’indentation. Cela me permet de déceler les endroits où mon code ne respecte pas cette convention. Cela permet accessoirement de détecter les lignes vides composées uniquement de tabulations.

    highlight LeadingTabs ctermfg=lightgrey ctermbg=darkgrey
    autocmd BufNewFile,BufRead * let m=matchadd('LeadingTabs', '^\t\+', -1)
    
  • Je colore en rouge toute ligne dépassant 120 caractères (j’avais mis 80 jusqu’à peu mais je me suis dit qu’on n’était plus en 1970). Bien qu’on ne soit plus à l’époque des cartes perforées, origine de la limite à 80 colonnes (et accessoirement une contrainte forte en Cobol), j’estime qu’il est préférable de limiter la longueur de chaque ligne de code afin de le garder lisible. Au pire, je divise le code en plusieurs lignes. Voici la commande associée :

    highlight Error ctermbg=red
    autocmd BufNewFile,BufRead * let m2=matchadd('Error', '\%>120v', -1)
    
  • Je surbrille en gris les espaces (ou tabulations) en fin de ligne; ceci est une raison purement esthétique et aussi pour garder une cohérence dans le code source. Je n’active la coloration qu’en sortant du mode édition ou après un retour à la ligne pour éviter que la subrillance aparaisse après chaque insertion d’un espace dans une ligne en cours d’édition :

    highlight TrailingWS ctermbg=lightgrey ctermfg=darkgrey
    autocmd InsertEnter * match TrailingWS /\s\+\%#\@<!$/
    autocmd InsertLeave * match TrailingWS /\s\+$/
    

Pour illustrer le tout, voici un échantillon d’un programme Python que j’ai délibérément modifié :

vim.png

  • La recherche d’un texte sous vim est très facile et puissante, mais en utilisant l’option hl on (highlightsearch on), les résultats de recherche sont surlignés en jaune, qui reste active jusqu’à la recherche suivante, ce qui peut devenir gênant. Avant, j’annulais la recherche en cours avec la commande plutôt maladroite

    /\\\\\\\\\\\\\\\\\\
    

    Ce qui, au lieu d’annuler le surlignage, effectue une nouvelle recherche sur le texte \\\\\\\\\, qui donc indirectement supprime le surlignage. J’ai récemment ajouté la macro suivante :

    let mapleader = ","
    nmap <silent> <leader>/ :nohlsearch<CR>
    

    Ce qui me permet dorénavant de réellement supprimer le surlignage automatique en utilisant la commande “,/”, ce qui est plus propre et rapide.

  • Par défaut, vim crée un fichier .swap dans le même répertoire que le fichier en cours d’édition. En cas de plantage de la console, ou pour diverses raisons, il arrive que le fichier swap ne soit pas effacé ce qui génère un warning lors de la réouverture du fichier sous vim. Tracer ces fichiers .swap est fastidieux; de plus, ils encombrent inutilement les répertoires projets. Je préfère une centralisation :

    set backup
    set backupdir=~/tmp/vim/bak
    set backupskip=~/tmp/vim/bak/*
    set directory=~/tmp/vim/swap
    set writebackup
    

    J’utilise un répertoire tmp local a home afin de ne pas créer de conflits avec un autre utilisateur. Plus embêtant (mais utile) sont les fichiers de backup que vim crée, avecun tilde (~) rajouté à la fin du nom de fichier (e.g. foofoo~, foo.phpfoo.php~). Embêtant car ces fichiers se retrouvent parfois malencontreusement archivés sous git ou svn, n’étant pas cachés par Linux faute de “.” en début de fichier. Je ne veux pas désactiver la création des fichiers de backup, c’est pourquoi ces derniers sont aussi centralisés a l’instar des fichiers swap.

bashrc.<username>

GIT_PS1_SHOWDIRTYSTATE=true
PS1='${debian_chroot:+($debian_chroot)}\[\033[01;32m\]\u@\h\[\033[00m\]:\[\033[01;34m\]\w\[\033[31m\]$(__git_ps1)\[\033[00m\]\$ '

Ces deux commandes permettent simplement d’activer l’intégration de git au sein de la console. Le prompt affiche la branche active du projet, et son état (clean, dirty…) si le répertoire actuel pwd est inclus dans un repository git.

gitconfig.<username>

[color]
  branch = auto
  diff = auto
  status = auto

[color "branch"]
  current = yellow reverse
  local = yellow
  remote = green

[color "diff"]
  meta = yellow bold
  frag = magenta bold
  old = red bold
  new = green bold

[color "status"]
  added = yellow
  changed = green
  untracked = cyan

[alias]
  ci = commit
  st = status -sb
  co = checkout
  b = branch
  l = log --graph --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)<%an>%Creset' --abbrev-commit --date=relative --decorate
  lc = log ORIG_HEAD.. --stat --no-merges
  undo = reset --hard

[core]
  editor = vim

En grosse partie, configure les couleurs lors de l’affichage dans la console, et les alias pour les commandes fréquemment utilisées. Pour git status et git log -alias st et l- je privilégie un affichage compact à celui par défaut :

$ git st
## dev
A  foo/src/main.py
 M foo/src/utils.py
?? foo/src/libs/rfc3339.py
?? bar/
^^__ Modifié mais non ajouté au stage
|___ Ajouté au stage (ce qui sera envoyé au prochain commit)

Affichage proche de celui de svn, à la sauce git.

Pour git log, voici un extrait d’un projet Android utilisant git en interne, et git-svn pour l’intégration avec svn :

$ git l
(...)
| *   0774882 - Merge branch 'build_03_01' of origin.local:myproject into build_03_01 (4 months ago) <Y M>
| |\
| | * af2188f - Updated demo samples (4 months ago) <Y M>
| | * 116ef0e - Fixed layout of sound tab header (4 months ago) <Y M>
| | * 317856f - Keep screen on (4 months ago) <Y M>
| | * 5fefbb8 - (PROTO_02_14, origin/dev, dev) Added ant build properties file Fixed fast tab switching issue! (try..catch) (4 months ago) <Y M>
| | * 02ee652 - Put car overlay over spot/traffic overlays (4 months ago) <Y M>
* | | f012bad - Updated R.java (4 months ago) <Y M>
* | | 7e63ae9 - Updated demo samples (4 months ago) <Y M>
* | | 91087cb - Fixed layout of sound tab header (4 months ago) <Y M>
* | | e1c2f8b - Focus on first spot/traffic during RadioAutomaton instead of Next Removed commented code from BottombannerAreaFragment (4 months ago) <Y M>
* | | bc2ef04 - Traffic level labels array resource used where needed. => Needed custom Application to allow Application Resources access from TrafficInfo (4 months ago)
* | | 8fb3e51 - Fixed merge (4 months ago) <Y M>
* | | 2fc921a - Tried to improve the fragment tab switching. Removing dependency on executePendingCommits(). Added delayed operations (4 months ago) <Y M>
|/ /
(...)

Cet affichage en plus d’être beaucoup plus compact que celui par défaut, rajoute en plus des informations visuelles sur les différents merge qui ont eu lieu et les branches qui en résultent.

III ) Import de mes clés GPG

J’utilise deux jeux de clés PGP : pour usage personnel et usage professionel. Note : Je ne met PAS mes clés sur mon compte UOne pour des raisons évidentes de sécurité!

J’utilise ma clé PGP pour encrypter les informations de connexion sur les divers serveurs utilisés pour les projets. Il s’agit d’un simple fichier texte qui est encrypté en utilisant l’option ascii-armored :

$ gpg --recipient xxx@yyy -a --encrypt server_info

Un fichier server_info.asc contenant le contenu encrypté. j’efface ensuite le fichier original :

$ rm server_info

Et je peux vérifier le contenu du fichier server_info.asc en fournissant mon passphrase :

$ gpg --decrypt -a server_info.asc

Afin de pouvoir décrypter les fichiers précédemment encryptés en cas de nouvelle installation, j’exporte ma clé privée GPG avant de réinstaller :

$ gpg --export-secret-key -a > my_private_key

Puis je la réimporte :

$ gpg --import my_private_key

J’utilise deux subkeys : une pour le cryptage, une pour la signature.

Au passage, idéalement j’aimerais avoir ma clé publique inscrite quelque part sur ma carte de visite :

Fingerprint : 0D67 DA34 9989 2211 7EE0  8FFF A7BA 11BA 7A0E A2B8

Conclusion

Je n’inclus pas dans ces étapes l’installation des logiciels restants (php, python, mysql, apache, nginx …), mais la configuration nécessaire afin de retrouver son petit chez soi en lançant le terminal est facilement automatisable et par conséquent mérite de l’être.

A propos du blogway 777

Cet article fait partie du blog-relai instauré par Kayac pour l’événement “777” relatif au festival Tanabata (七夕). D’ici le 7 Juillet, nous vous invitons à suivre les 4 blogs (ingénieur, designer, directeur, ingénieur front-end), mis à jour quotidiennement sous la forme d’un relai. Le thème est “Les 3 outils sacrés de la création” (San’shu no shin’gi - 三種の神器).

Pour le prochain article, je passe la main au blog designer.

777ブログウェイ「つくるための三種の神器」というテーマで、
本日はカヤック京都支社の技術部アルバイトで働いている高江洲(たかえす)がご紹介します。

エンジニアとして働く上で、大切だなぁと思う以下3つのことについて自分が利用している(利用し始めた、今後も継続したい)ことを3つ取り上げてみたいと思います。

1. 情報収集
2. タスク管理
3. テスト駆動開発

1.情報収集

情報収集手段といえば、はてブの人気エントリーやヤフーのトップニュース、RSSリーダーなど様々な手段がありますが、最近はもっぱらGunosy(グノシー)を使っています。

Gunosy.png

TwitterやFaceBookでログインすると、興味のある分野についてのおすすめ記事のまとめを1日1回メールで受け取る事ができます。大手のニュースサイトから個人のブログまでの幅広く、僕は朝の通勤中にひと通り目を通す感じで使っています。
使い始めて2ヶ月くらいですが、自分の中でホットな記事が結構な頻度で届き、とても精度がいいと実感しています。
登録してメールを見るだけの手軽さなので、おすすめで、継続もしやすいです。

2.タスク管理

タスク管理って大変ですよね。
やろうと思っていたことも数時間経つとなんだっけなぁーと忘れることが結構あります。。
本当に今すぐやる小さなことはノートにメモして終わったらチェックするなど管理することはできます。
しかし、すこし粒度が大きかったり、一度に複数のタスクを登録したいと思ったときはやはりツールを使うのが便利だと思います。

そこで最近は Trello という**無料のWebサービス**を利用しています。
アジャイルのカンバンのようなインターフェースで、カードにタスクを書くというスタイルです。
アナログで言うと、付箋にタスクをかいてボードに貼り付けるというイメージです。
表示はすべて英語ですが、日本語も問題無く入力できます。ドラッグアンドドロップでカードを移動することもでき直感的で使いやすいインターフェースだと思います。
また、レスポンシブデザインにも対応していて携帯端末で見ても違和感なく使用できます!

Trello-1-1.jpg

※左(PC)  右(Mobile)

僕は仕事での細かい粒度のタスクや、個人的にやりたいことなどを管理する用途で使っていますが、
コラボレーション機能(担当割当て機能、ファイル共有機能、チェックリスト機能、投票機能)が充実しているのでチームでのタスク管理にも向いていると思います。
次の記事もとても参考になります♪
オフィスのホワイトボードを止めて「Trello」を使うべき理由

3.テスト駆動開発

システムを開発する上でテストはとても重要なことだと最近になって悟り始めました。
テストと一口に言っても、単体テストから機能テスト、結合テストなど様々な分野がありますが、テスト意識してシステムをつくることがユーザ目線でつくるということに繋がるのではないかと思います。 先日参加した TDD Boot Camp Osaka でも、
単体テストを書いて実行することが、そのプログラムを初めて使うユーザである
ということを話されていました。
「テストについて考える ≒ ユーザ目線で考える」 ということなのかと思います。

最近よんだ関連する書籍3冊です。テストケースを考える参考になると思います。

マインドマップから始めるソフトウェアテスト
はじめて学ぶソフトウェアのテスト技法
レガシーコード改善ガイド

Groovy(Spock)によるBDDを試してみた

そこで前から気になっていたGroovy(Spock)を使ってBDDを試してみました。
GroovyはJavaのJVM上で動く言語で、SpockはGroovyで実装されたBDDのフレームワークです。
BDDとはBehavior Driven Developmentの略で振る舞い駆動開発と略されます。期待する振る舞いを定義し、テストコードそのものが仕様書の役割をはたすものです。
少しその動作環境をご紹介します。

Groovy(Spock)の環境構築

前提としてJavaの動作環境とIDEの設定(EclipseであればGroovy Eclipse Pluginなど)は済ませていること。 今回は最強のIDEを試して勉強してみようということでIntellij IDEAで書いてみました。

・Groovyのインストール(Mac , homebrew環境)

% brew install groovy

・Spockのインストール
Mavenを利用した方法、Grapeを利用した方法といくつもありますが、今回はここからJarファイルをダウンロードしてビルドパスに追加する形でインストールしました。

簡単な簡易文字コード処理を書いてみました。

1を入力したら「ONE」を出力、2を入力したら「TWO」を出力するというような、ちょー簡易的な文字コード処理みたいなものを書いてみました。
プロダクトコードはJavaで書き、テストコードはGroovy(Spock)で書いてみました。Javaとも何も問題なく連携できるのがいいですね。

プロダクトコード(Java)

public class CharacterCode {

    private HashMap charMap = new HashMap();

    //文字コードマップの初期化
    public CharacterCode() {
        charMap.put(1, "ONE");
        charMap.put(2, "TWO");
        charMap.put(3, "THREE");
        charMap.put(4, "FOUR");
        charMap.put(5, "FIVE");
    }

    //数値に対応する文字を返す
    public String getCharacter(int num) {
        if(!charMap.containsKey(num)) {
            throw new IllegalArgumentException("引数が不正です");
        }
        return charMap.get(num);
    }
}

テストコード(Groovy Spock)

class CharacterCodeTest extends Specification {

    CharacterCode cc = new CharacterCode()

    def "数字を入力して対応した文字を返す"() {
        expect:
        cc.getCharacter(NUM) == CHARACTER

        where:
        NUM     | CHARACTER
        1       | "ONE"
        2       | "TWO"
        3       | "THREE"
        4       | "FOUR"
        5       | "FIVE"
    }

    def "対応した数値以外(1~5以外)の場合は例外"() {
        when:
        cc.getCharacter(NUM)

        then:
        thrown(IllegalArgumentException)

        where:
        NUM << [0, -1, 6, 100]
    }
}

コードの見た目がとてもいいですよね!?
インプットとアウトプットがすっきり定義されていて、見ただけでどういった動作になるのかがわかると思います。
BDDでのシナリオを書くためのキーワード「when, then, where, expect」を使うことでなんとなく仕様書のように感じませんか。
まだ試してはいませんが、Android開発でもAndroidSDKがGroovyで使えれば、テストコードはGroovyということで使えるかもしれません。
テストコードは今まで殆ど書いたことがないのですが、これからは継続していきたいと思います。

今回書いたコードはGithub(Groovy-Practice)に公開しています。

最後に

この記事は面白法人カヤックの七夕のイベント「777」に向けたリレーブログです。 技術系のアドベントカレンダー(*)になぞり、777イベントが開催される7月7日までの期間に、4つの職能ブログ ( エンジニアデザイナーフロントエンドエンジニアディレクター ) を横断し、更新します。 テーマは「つくるための三種の神器」。 カヤック有志による、それぞれの切り口で記事を投稿していきます。

アドベントカレンダーについての記事 「師走を楽しもう。技術系アドベントカレンダーの魅力とは

引き続き、明日以降もよろしくお願いします。

はじめまして。技術部の中村です。 今日はRedmineチケットを作るための三種の神器ということでお送りします。

Google検索エンジン

Redmineのチケットを書く際には、調査のためにGoogleで検索することがよくあります。Chromeで検索するときによく使う小技を紹介します。

""で括る

例えば問題を調査していてサーバのログにエラーメッセージが出ていた時、エラーメッセージでググるわけですが、そのままだと関係ない結果がいっぱいヒットしてしまう場合があります。 そんなときは""で括ってググります。特定の環境に依存する文字列が含まれる場合はそれは除去して、その前後をそれぞれ""で括ってググります。

site:で特定のサイトに限定してググる

公式情報を探すため、本家のサイト内に限定してググりたい時などは、site:example.comのようにドメイン指定を追加してググります。 その他の検索のヘルプ - ウェブ検索 ヘルプ

英語のページに限定してググる

日本語のドキュメントが用意されていても古かったりするのはありがちなので、英語のページに限定してググるというのをよくやります。

Chrome search engine settings2.png

私は 検索エンジンの管理 - Google Chrome ヘルプ の手順に従って、 検索エンジン名: Google (en)、 キーワード: g、 URL: http://www.google.co.jp/search?hl=ja&source=hp&q=%s&lr=lang_en&aq=f&oq= というエンジンを追加しています。 すると、URL欄でgスペースと入力後検索ワードを入れれば英語ページ限定の検索ができます。

新しい情報に限定してググる

検索結果一覧に表示されている日付が古いものばかりが並んでいる場合は、左の「もっとツールを見る」をクリックして期間指定を「1年以内」とかにします。

Awesome Screenshot

Awesome Screenshot screenshot.png

Redmineのチケットを書く際には、スクリーンショットを作成して添付することがよくあります。

その際は Awesome Screenshot - Capture, Annotate and Share がお勧めです。Chrome版Firefox版Safari版 があります。

スクリーンショットをとってそこに赤丸をつけたりコメントを追記するのが、とっても手軽にできます。Awesome Screenshotを知る前はスクリーンショットをとった後GIMPなどの画像編集ソフトで開いて加工する必要があったのですが、Awesome Screenshotがあればブラウザ内で全て完結してしまいます。

ただし、Chromeの設定画面など一部の画面ではスクリーンショットがとれませんでした。 また、既存の画像ファイルを開いてコメント追記もそのままではできませんでした。でも、 <img src="画像ファイル名">という内容のHTMLファイルを作ってFirefoxで開けばAwesome Screenshotでコメント追記できました。

ChromeのFormat Linkエクステンション

Format Link screenshot.png

Redmineのチケットを書く際には、検索して見つけたページへのリンクを書くことがよくあります。

手前味噌ですが、私は拙作の Format Link を愛用しています。

これを作るまでは Create Link を重宝していました。

RedmineのWiki記法ではリンクは「"タイトル":URL」という形式になっているのですが、タイトル内の"は&quot;、[は&#91;と記述する必要があるというのに気づき、Format Linkエクステンションを自作しました。 ちなみに、Markdownのリンクは「[タイトル](URL)」という形式ですが、タイトル内の[と]はバックスラッシュでエスケープ、URL内の)は%29と記述する必要があります。こちらも対応済みです。

ソースはgithub.com/hnakamur/FormatLink-ChromeでMITライセンスで公開しています。

最後に

いかがでしたか。実は、Redmineチケットだけではなく、ブログ記事や自分用メモとかを書くときにも活用しています。ただ、タイトルを「ブログ記事やRedmineチケットを書くための三種の神器」にしたらまとまりがなかったのでRedmineチケットに限定したタイトルにしてみました。

777ブログウェイとは

この記事は面白法人カヤックの七夕のイベント「777」に向けたリレーブログです。 技術系のアドベントカレンダー(*)になぞり、777イベントが開催される7月7日までの期間に、4つの職能ブログ ( エンジニア、デザイナー、フロントエンドエンジニア、ディレクター ) を横断し、更新します。 テーマは「つくるための三種の神器」。 カヤック有志による、それぞれの切り口で記事を投稿していきます。

明日の777ブログウェイは意匠部からお送りします。ご期待ください。