投稿者「sasakima-nao」のアーカイブ

file ext

前々回。
「g_content_type_guess だと ContentType は拡張子依存みたい」
と書いた手前、筆者的には当然の結果だけど一応試してみた。

#!/usr/bin/env python3

from gi.repository import Gio

# Doesn't exist a File.

ans = Gio.content_type_guess("Not Found.txt")
print(ans)
#=> ('text/plain', False)

# File Create (No Ext).

with open("found", "w") as f:
    f.write("#!/usr/bin/env python3\n")

# g_content_type_guess

ans = Gio.content_type_guess("found")
print(ans)
#=> ('application/octet-stream', False)

# Gio Query

obj = Gio.file_new_for_path("found")
info = obj.query_info(
    Gio.FILE_ATTRIBUTE_STANDARD_CONTENT_TYPE,
    Gio.FileQueryInfoFlags.NONE )
ans = info.get_content_type()
print(ans)
#=> text/x-python

やっぱり拡張子の有無で関数の違いが出るんですね。
Gtk, GLib と付き合いが長いので結果は解っていたけどこういうこと。

つまり面倒臭い手段を使えば予定通りな結果が得られる。
GNOME プロジェクトは計画的にやっているんだろうな、と思ってしまう。
何故こうなるかは割愛、これは GNOME 関連では単純なほうだyo!

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!

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