Gedit」タグアーカイブ

Gedit 3.30 Auto Scroll is Bad!

Gedit 3.30 の仕様変更にまいった。

とりあえずカーソル位置からスクロールしてタブを切り換える。
そのタブをアクティブにするとカーソル位置まで勝手にスクロールしてしまう。
他のソースを参考にしながらコードを書いている時に超イライラする。

同じく Ctrl+Z で Undo するとその前の編集箇所に勝手にカーソル移動とスクロール。
これはありがたく思えるけど実際に使うと超迷惑。

それでいて gsettings のどこにも無効にする設定が見つからない。
ソースの参考は別ウインドウにする逃げ道があるけど Undo が困る。

タブを枠外にドラッグで別ウインドウにする時のアニメーションが無くなった。
相変わらず Wayland では Ctrl+F9 が使えない。

Xed にでも乗り換えようかな、と思ったらまったく同じ現象が。
どうやら GtkSourceView 自体の仕様変更のようだ、とっとと削除。
カーソル位置を見失なわないよう配慮したんだろうけど、困った。

、、、、、、、、、、

検索しまくったけど、海外すら誰もこれに気がついていないのか?
無効にする手段は見つからなかったけどこんな面白いのを見つけた。

GitHub – hardpixel/gedit-scroll-past: Gedit 3 plugin to allow scrolling past the end of file.

ファイルの終わりを過ぎてスクロールできるようにする Gedit プラグイン。
おぉ Visual Studio Code みたくできるんだ、作ってくれた人ありがとう!

、、、、、、、、、、

そんなこんなで自作アプリを更新、イライラしながら。

application.run([System.programInvocationName].concat(ARGV));

Y901x はこう書き替えただけで問題なく使えたのでとっとと出した。
gnome-mpv のサイズが完全固定できればこんなの作らなくてもいいのになぁ。

comipoli は何をやってもフルスクリーンがおかしい。
Y901x とまったく同じ処理に書き換えてさえおかしい、意味ワカラン。
早く動くようにしないとエロマンガが見られないジャン!

もう Clutter はあきらめて GtkDrawingArea に書き換えすることに。
macOS 版 comipoli のソースをコピペして cairo に書き換える。

このくらい同じなほうがお互いのメンテが楽でいいよね。
てゆーか滅茶苦茶軽くなったんだが、Clutter 遅かったのね。
作っていてよかった jxa 版。

Gedit RepeatLine Plugin

筆者は macOS で Visual Studio Code を使っている。
しかし Fedora では Gedit を使い続けている。
Fedora でも併用しようと考えたけど結局 Gedit しか使わない。

しかし Visual Studio Code には便利すぎる機能がある。
opthon(alt)+shift+down で行の複製ができる、これが超スバラシイ。

fn+left
shift+fn+right
command+c
fn+right
return
command+v

とやっていたことを一発だ、よく使うんだな行の複製って。
ちなみに fn の所は TextEdit.app 同様に command でもいい。
筆者は US 配列なので fn のほうが楽だということで。

てか mac の日本語キーボードは何故 fn が右なのか、マジで糞。
US 配列を店頭でも普通に買えるようにしてくれないかなぁ。
それは今は関係なくて。

Gedit でも同じことがやりたいぞ。
ということで Plugin を探し、、、じゃなくて作る!
何年ぶりの新規プラグイン作りだろう、ワクワク。

#-*- coding:utf-8 -*-

#    Gedit repeat plugin version 3.22.0
#    Copyright © 2018 sasakima-nao <sasakimanao@gmail.com>
#
#    This program is free software; you can redistribute it and/or modify
#    it under the terms of the GNU General Public License as published by
#    the Free Software Foundation; _endher version 2 of the License, or
#    (at your option) any later version.

import gi, os
gi.require_version("Gtk", "3.0")
gi.require_version("Gedit", "3.0")
gi.require_version("Peas", "1.0")

from gi.repository import GObject, Gedit, Gtk, Gio, GLib

class RepeatLineAppActivatable(GObject.Object, Gedit.AppActivatable):
    """
        Set GMenu and Accelerator
    """
    app = GObject.Property(type=Gedit.App)
 
    def __init__(self):
        GObject.Object.__init__(self)
 
    def do_activate(self):
        # "<Alt><Shift>Down" Not Work
        self.app.add_accelerator("<Alt><Shift>d", "win.repeatline", None)
        self.menu_ext = self.extend_menu("tools-section")
        item = Gio.MenuItem.new("Repeat Line",  "win.repeatline")
        self.menu_ext.append_menu_item(item)
 
    def do_deactivate(self):
        self.app.remove_accelerator("win.repeatline", None)

class RepeatLinePlugin(GObject.Object, Gedit.WindowActivatable):
    __gtype_name__ = "RepeatLinePlugin"
    window = GObject.Property(type=Gedit.Window)
    def __init__(self):
        GObject.Object.__init__(self)

    def do_activate(self):
        self.action = Gio.SimpleAction.new("repeatline", None)
        self.action.connect('activate', self.on_repeatline_activate)
        self.window.add_action(self.action)

    def do_deactivate(self):
        self.window.remove_action("repeatline")

    def do_update_state(self):
        self.action.set_enabled(self.window.get_active_document() != None)

    def on_repeatline_activate(self, action, param):
        view = self.window.get_active_view()
        buf = view.get_buffer()
        _start_ = buf.get_start_iter()
        _end_ = buf.get_end_iter()
        spos = buf.props.cursor_position
        epos = spos
        it = buf.get_iter_at_offset(spos - 1)
        line = None
        while 1:
            # search line start position
            if it.equal(_start_) or it.get_char() == "\n":
                line = it.copy()
                it = buf.get_iter_at_offset(epos)
                break
            spos -= 1
            it = buf.get_iter_at_offset(spos)
        while 1:
            # search line end position
            if it.equal(_end_) or it.get_char() == "\n":
                s = line.get_text(it)
                if line.equal(_start_):
                    s = "\n" + s
                buf.insert(it, s, -1)
                break;
            epos += 1
            it = buf.get_iter_at_offset(epos)

作ってみた。

残念ながら Alt+Shift+Down は無視された。
Alt+Shift+D でいいやもう。

os.getenv(GEDIT_CURRENT_LINE)
が使えると思ったけどこれはプラグインからは参照できないのね。
しかたがないので GtkTextIter で地味に \n 位置を探すことに。

先頭と最後は \n が無いけどこんな処理でイケた。
何をやっているかは GtkTextBuffer のドキュメントで。

とりあえずこれで Gedit でも同様なことができるぞい。
探せば既にあるかもだけど、プログラミングは経験値だよと一言。

Gedit External Tools CRLF

Gedit の External Tools が変だ。

何故コマンドが改行されているのだ?
head コマンドの挙動が変わってしまったのだろうか。

一時間くらいすったもんだしてやっと理由が判明。
何故か改行コードが CRLF になっていたからだった。

head -n1 は LF までを戻すので直前の CR は残ってしまうみたい。
てか bash が CR を改行と認識すると初めて知った。
CR を使うなですむ話だけど、一応対策。

#!/bin/sh

# Do shebang

#h=`head -n1 $GEDIT_CURRENT_DOCUMENT_PATH`
# Remove CR
h=`head -n1 $GEDIT_CURRENT_DOCUMENT_PATH | tr -d '\r'`
if [[ $h = \#\!* ]]; then
    app=${h#*\!}
    echo $app $GEDIT_CURRENT_DOCUMENT_PATH
    $app $GEDIT_CURRENT_DOCUMENT_PATH
fi

普段はまったく無意味な処理なんだけどね。

text/x-python3

Fedora 27 では ContentType に text/x-python3 が追加されていた。
…ことを昨日久々に Python ネタを書いてやっと気が付く筆者であった。
Gedit で python の所に登録したスニペットが流し込めなかったということで。

とうとう Python2 からの完全置き換えをあきらめたということかな。
ちなみに Gedit はモードラインが無いなら ContentType で見分けている。
どういう振り分けをしているのかしらべてみよう。

/usr/share/mime/magic
を Gedit で無理矢理開いて Ctrl+F から python3 を検索。

あぁシバンのみで判断しているってことね。
拡張子を py にしただけのファイルは text/x-python のままだ。

python3+15 って何だろと思ってアレコレ試してみた。
先頭から 15 文字目までにコレを見つけたら Python3 だと認識、でいいのかな。

#!!!!!!!!!!!/usr/bin/env python3

から ! を一文字増やし Ctrl+s で Gedit のステータスバー表記が Python に変わる。

いや実験です、この shebang は当然動作しません。
しかし 15 文字っていったいどんだけ変な場所に env があるんだよ。

とにかくこれで Python2/3 コードの振り分けが簡単になる。
いや現行の Fedora デフォルトに Python2 は含まれていませんけど。

JXA FileList

今回は JXA でディレクトリ内容列挙でも。
まあ Objective-c での手段は検索で山ほど見つかる、しかも日本語で。
Gjs だと英語しか見つからないのに、まあ macOS と比べてもね。

変換するだけとはいえ落とし穴は幾つかある。

#!/usr/bin/osascript

ObjC.import("Cocoa");

nil = $();

let path = $("~/Desktop").stringByExpandingTildeInPath;
let nsFiles = $.NSFileManager.defaultManager.contentsOfDirectoryAtPathError(path, nil);
//$.NSLog("%@", nsFiles);
let jsFiles = nsFiles.js; // NSArray to JS Array
for (let i=0; i<jsFiles.length; i++) {
    console.log(jsFiles[i].js);
}

nil は null ではない。
そういえばデルヒャァがそうだったなぁ、もう完全に忘れたけど。

NSArray のままではループできない。
こいつの変換も *.js メソッドでイケるのか、なるほど。

次は再起のように中身まで辿っていく手段。

#!/usr/bin/osascript

ObjC.import("Cocoa");

let path = $("~/Documents").stringByExpandingTildeInPath;
let nsDirEnum = $.NSFileManager.defaultManager.enumeratorAtPath(path);
//while (let name = nsDirEnum.nextObject) {
while (true) {
    let name = nsDirEnum.nextObject;
    if (name.isNil()) break;
    let fullPath = path.stringByAppendingPathComponent(name);   // Full Path
    console.log(fullPath.js);
}
console.log("done");

if (name == $()) では認識してくれない。
つまり検索でよく見つかるコメントアウト部分は使えない。
isNil() でなんとか JavaScript の boolean 値だと認識するようだ。

Gjs や PyGObject と違って型が明確に分離している。
ってもソレさえ理解できてしまえば日本語情報があるだけ簡単だね。

どうでもいいけど Gedit は日本語入力できないまま使っている。
開き直って日本語を使わなければいいのさ、ガッハッハ!
まあ JXA 専用だね。