Virtual Terminal Emulator

VTE といってもホンダのバイクじゃありません。
Virtual Terminal Emulator の略であります。

Gedit 標準プラグインに Python コンソールがありますが全然違う。
gnome-terminal そのものみたいなエミュレーターです。

GNOME wiki の VTE Terminal Widget Library ページ。
Apps/Terminal/VTE – GNOME Wiki!

バージョンがややこいけど 2.91=0.39 のようだ。
例によって GNOME プロジェクト作だから合わせたかったのかな。
vte291-devel-0.39.90-1.fc22.armv7hl.rpm | RPM Info | koji

vte01

Fedora にはしっかり gir で入っていますね。
多分 gnome-terminal 採用のディストリなら大抵あると思う。
2.91 は見当たらないので 0.39 のドキュメントを見ればいいだろう。
VTE Reference Manual: VTE Reference Manual

参考が欲しいのでサンプルコードを探す。

c – gtk+ vte scrollback not working – Stack Overflow
python – How to add vte terminal widget in GTK3? – Ask Ubuntu

C や Python から使う方法は海外でアッサリ見つかった。
日本語情報は今のところ皆無、いつものことだ。

しかし古いようで vte_terminal_fork_command 関数は 2.91 で使えない。
どうやら現行は vte_terminal_spawn_sync 関数を使うようだ。

ということで。
早速 Python バインディングにて書いてみよう。

#!/usr/bin/env python3

from gi.repository import Gtk, Vte, GLib

class VteWindow(Gtk.Window):
    """
        Vte Sample (v2.91)
    """
    def __init__(self):
        Gtk.Window.__init__(self)
        # Create a virtual terminal 
        terminal = Vte.Terminal.new()
        # Exit of Ctrl+D
        terminal.connect("child-exited", self.on_terminal_child_exited)
        # Sync
        terminal.spawn_sync(
                Vte.PtyFlags.DEFAULT,
                GLib.get_home_dir(),
                #["/bin/sh"], @ List of Execute Command
                ["/usr/bin/python3"],
                None,
                GLib.SpawnFlags.DO_NOT_REAP_CHILD,
                None,
                None,
                None)
        self.add(terminal)
        self.set_title("Virtual Terminal")
        self.connect("delete-event", Gtk.main_quit)
        self.show_all()

    def on_terminal_child_exited(self, vteterminal, status):
        Gtk.main_quit()

VteWindow()
Gtk.main()

vte02

spawn_sync の引数については devhelp で詳しく。
三番目引数を sh や perl に変更すれば当然それらが起動する。
それと上記は起動したコマンドの終了を検知して自分も終了させている。
後はお好みで弄ってみてください。
今後バージョンで変わると思うので 2.91 と念を押して。

/bin/sh で起動してソコから Python を始めるとかも可能。
Ctrl+D で Python を終了すると sh に戻る、マジで普通の端末。

しかし自分で試して驚いた、こんなにアッサリ実装できるとは。
自分好みに拡張したオリジナル端末を作るだけでも面白そう。
ただ一言、日本語の情報がまったく無いのはキビシイze!

GtkSourceLanguageManager

テキストエディタの色分け表示については Gedit は超強力です。
実はコレ Gedit ではなく GtkSourceView 自体の機能だったりする。
下記ディレクトリに定義 XML ファイルがある時点で解るだろうけど。

/usr/share/gtksourceview-3.0/language-specs

プログラミングは基本や計算ばかりじゃ面白くないよね。
やはり GUI のほうが楽しいですよね。
今回は GtkSourceView でこの色分け機能を使う方法でも。

GtkLanguageManager を使います、驚くほど簡単です。
読み込むファイルを用意するのが面倒なので自分の Python コードを。

#!/usr/bin/env python3
  
import sys
from gi.repository import Gtk, GLib, Gio, GtkSource, Pango

# My src
FILENAME = __file__
  
class ColorLang(Gtk.Window):
    """
        GtkSourceLanguageManager Sample
    """
    def __init__(self):
        Gtk.Window.__init__(self)
        #
        # GtkSourceView
        self.view = GtkSource.View()
        self.view.set_show_line_numbers(True)
        # Set Monospace Font
        font_desc = Pango.font_description_from_string("Monospace 10")
        self.view.override_font(font_desc)
        #
        # LanguageManager
        manager = GtkSource.LanguageManager.new()
        lang = manager.guess_language(FILENAME)
        """ or ContentType
        contype, result = Gio.content_type_guess(FILENAME)
        lang = manager.guess_language(None, contype)
        """
        buf = self.view.get_buffer()
        buf.set_language(lang)
        # Read
        with open(FILENAME) as f:
            s = f.read()
            buf.set_text(s)
        sw = Gtk.ScrolledWindow()
        sw.add(self.view)
        # append the filename and ContentType
        hbar = Gtk.HeaderBar()
        hbar.set_title(GLib.path_get_basename(FILENAME))
        hbar.set_subtitle(Gio.content_type_guess(FILENAME)[0])
        hbar.set_show_close_button(True)
        self.set_titlebar(hbar)
        self.add(sw)
        self.resize(400, 400)
        self.connect("delete-event", Gtk.main_quit)
        self.show_all()

ColorLang()
Gtk.main()

languagemanager

ファイル名か ContentType を指定すると推測して定義ファイルから探し当てる。
ソレを set_language で突っ込む、マジでこれだけ。

でも g_content_type_guess だと ContentType は拡張子依存みたい。
本気で拡張子否依存にするなら自力で取得する必要有り、のようです。

で、まあ当然のように Gedit とまったく同じ色分けになりました。
これじゃつまんない、自分で定義したいという人は定義 XML を作って
gtk_source_language_manager_set_search_path でセットする。

GtkSourceView 3 Reference Manual: GtkSourceLanguageManager

しかし language という名ではつい gettext 関連と思ってしまいます。
いや、筆者が今までそう思い違いしていたというオチだyo!

GNOME Share

そろそろ四月、次の Ubuntu が出るが。

Ubuntu 15.04 (Vivid Vervet) Release Date Revealed – Softpedia

解っていたけど 15.04 の GNOME アプリは 3.10 のまま。
自アプリ動作チェックのために iso を落す必要は無さそう。
と思ったけど。

Ubuntu GNOME 15.04 – GNOME 3.14 desktop – YouTube

Ubuntu GNOME 15.04 は GNOME 3.14 らしい。
Nautilus はコッチなら 3.14 なんだね。
gnome-terminal, evince も、どういう風の吹き回しだろう。
しかし GtkNotebook が幅いっぱいに広がらないのは何故かな?

Totem が 3.10 って Clutter は使っていないのか?
Gedit も 3.10…
やっぱり必要無かった、もうすぐ 3.16 が出るというのにコレか。

で、ちと古いけどこんなのを見つけた。

LinuxQuestions.org – 2010 LinuxQuestions.org Members Choice Results
LinuxQuestions.org – 2014 LinuxQuestions.org Members Choice Results

GNOME のシェア落ちハンパネェ!
当時 GNOME2 だった Ubuntu が変えたので落ちて当然とはいえ唖然。
Slackware デフォルトが KDE だから凄く特殊な結果かもだけど。

しかし Mint は人気なのに Cinnamon がアンチの多い Gnome Shell とほぼ同じ。
うにてぃは更に低い、どういうことだってばよ。

Mint, Ubuntu 共に大半が XFCE 化しているってか。
XFCE は GNOME2 とだいたい同じだもんね、つーか GTK2 だもんね。
こんなもんです、プログラマー側以外は海外もあまり変わらない。
今でも XP がどうのと言っている Windows しか使えない輩を笑えない。

うにてぃ 8 が出てもみんな XFCE に変えてヨシだろう。
ついでに有名ゲームエンジンと紛らわしいんで名前を変更してほしい。

でもテキストエディタは vi/emacs でシェア九割だと思ったらあれ?
みんさん意外にコマンド万歳ではないようで。

Gedit Mode

GNOME アプリの C ソース先頭にある

/* -*- Mode: C; tab-width: 8; indent-tabs-mode: 8; c-basic-offset: 8 -*- */

って何?
多分 vim, emacs 等で使うんだろうと今迄思っていた。
けれどたまに「あれ?」と思うことがあったので実験してみた。

#!/bin/sh

cat << _EOS_ > test.java
#!/usr/bin/env python3
#! -*- Mode: C; indent-tabs-mode: 2; tab-width: 2 -*-

import sys
_EOS_

という中身は Python モードは C 拡張子は Java というファイルを作る。
Gedit で作らないように上記のようにシェルスクリプトで作った。
まあこのスクリプトを保存した時点で結果は解ってしまったけど。

筆者の Gedit では普段の設定は Python ガイドラインに合わせている。

ind01

先程のスクリプトで作ったファイルを開いたら結果はどうなった?

ind02

C モードになりタブ幅が変更され Tab ではなく空白指定が解除された。
知らなかった、Gedit はこの指定でファイル毎にインデントを指定できるんだ。
指定方法は emacs 形式でいいみたい。

更に、書き換えると保存毎にリアルタイムで変更になる。
モードを変更してタブ幅を変えても Ctrl+S を押した時点で切り替わる。
つまり先程のスクリプトは保存した時点で C に切り替わって焦った。

ということで。
筆者のような Python ガイドライン派は C を書く時に上記を先頭に書く。

C Coding Style にしている人は

#!/usr/bin/env python3
# -*- Mode: PYTHON; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-

と書いとけば Python を書く毎に設定を弄らないですむ。

PHP は言語としては統一されていないのでお好みでいいかな。
とにかくどこかに書いてコメントにすればいいみたい。

<!-- -*- Mode: PHP; indent-tabs-mode: 4; tab-width: 4 -*- -->

他のファイルを開くと普通にデフォルトが適用されます。

他の言語はガイドラインを知らないので各自で調べてください。
ただ某言語はワンライナーしか書かないからどうでもいいだろうな。

後 SyntaxHighlighter は Tab にしても半角スペースになってまうんで。
Web に貼り付けている奴は気に入らないなら \t で全置換してNE!

追記
一番肝心なことを書き忘れていた。
[モードライン]プラグインの機能なので有効にしてね。

Linux でファイル名に改行コードを入れる

今日は Linux のファイル名で遊ぶよ。

ファイル名に日本語を使う人は改行位置が気になることがあるよね。
英語ならワードラップで勝手にイイ感じになるのに不公平だ。

rename01

ここは「魔法少女」の所で改行してくれると綺麗に見えるのに…
みたいなことを思う変人がいるかどうかは知らないけれど。
実はファイル名に改行コードを普通に入れられるんだよ。

mv コマンドの変更先ファイル名をダブルクォーテーションで始める。
改行させたいところで Enter して改行する、クォーテーションを閉じる。

$ mv 魔法少女まどか☆マギカ.jpg "魔法少女
> まどか☆マギカ.jpg"

rename02

ls での表示が ? になった。
0x0A なので改行するかなと思ったけど ? を表示なんだ。
Nautilus ではどうなるんだろう。

rename03

見事狙った位置で改行されるようになりました。
いや、ファイル名に改行コードなんて入れて問題無いのか?

rename04

eog, Firefox でも問題なく表示できるけど Chrome は駄目でした。
少し調べるとサーバーアップロードとかにも一部引っ掛るみたい。
普通は文字列以外がファイル名にあるなんて思わないもん。

でも外付け HDD なんかにコピーするのは問題無し。
つまり自分のコレクションに使う分にはやってもよさそう。

というより。
端末でこうすると 0x0A が入ってしまうので注意しよう。
気が付かずにファイル名に入れてしまい「何か変」にならないようにNE!