Programming」カテゴリーアーカイブ

(bash|zsh) read command 2

read コマンドをもう少し。
ファイルの読み込みなんかは bash と同じみたい。

bash: ‘\n’ in read file (part2) | PaePoi

while read -r line; do
    echo $line
done << __DOC__
aaa bbb
ccc\nddd
eee
__DOC__

うん、sh と同じく \n 文字は改行扱いになるってか。
それより、ついでと思い bash 直指定したら文字列扱いになってしまったんだけど。
Fedora では sh は単なる bash へのシンボリックリンクなんだけど。

macOS の sh は別コマンドなのか、でも [[ とかの bash 拡張は使えるし。
正直よくわからんぞ。
シバンは明確に #!/bin/bash とかを利用したほうが良さげ。

(bash|zsh) read command

zsh と bash の read コマンドは全然違うようだ。
bash, zshでyes/no判定をするワンライナー – Qiita

公式のビルトインコマンド man ページも見つけた。
zsh: 17 Shell Builtin Commands

早速試そうと思ったけど bash とソースを分けるのは色々と不便だ。
zsh にしても $SHELL は bash のままだし、readonly に何か無いかな?

あった、$ZSH_EVAL_CONTEXT が定義されているかで判別できそう。
プロンプトとライン入出力と Y|N 判定をひとまとめに書いてみた。

#!/bin/zsh

echo 'May I ask your name?'

if [[ $ZSH_EVAL_CONTEXT = toplevel ]]; then
    read name\?'> '
    echo "Hello $name san"
    printf 'Do you like zsh? (y|N): '
    read -q && echo '\nGreat!' || echo '\noh my god...'
else
    read -p '> ' name
    echo "Hello $name san!"
    read -n1 -p 'Do you like bash? (y|N): ' res
    [[ $res = [Yy] ]] && printf '\nGreat!\n' || printf '\noh my god...\n'
fi

マジで全然ちげえ、この手段でまとめページを作るのは無理があるみたい。
zsh の read -q でプロンプトは出せないのかな?

おまけで、zsh の echo はエスケープシーケンスが使えると解った。
macOS の bash は echo -e すら使えないのに。
組み込みコマンドは大体別物と思ったほうが良さげ。

Atom の script は bash|zsh のシバンも見分けしてくれる、助かる。
入力はできないけど、まあそれは Gedit も同じだ。

zsh

Catalinaでデフォルトシェルが「zsh」に変わる、bashとの違いは? – 新・OS X ハッキング!(241) | マイナビニュース

Catalina 以降は Python2 等がデフォルトで入らなくなるらしいのが話題だ。
筆者はコッチのほうが重要だ、だって bash の Tips ページを作っているんだもん。
今から少し慣れておいたほうが良さそうと思い早速使ってみる。

zsh に変更するとタイトルバーの表示も zsh に変わるのね。
しかしなんだこのシンプルすぎるプロンプトは。
いや bash のプロンプトは Fedora と同じ表示になるカスタムなんだけーがさ。
早々にカスタムだ。

zsh 設定 – プロンプト –

RPROMPT って何だ?
よく解らないことは自分で試してみるのが一番早い。
~/.zshenv を作って以下を書き込み。

# Fedora like Prompt for bash
#PS1='[\u@\h \W]\$ '
# zsh
PROMPT='[%n@%m]%# '
RPROMPT='[%~]'

右に出るんかい!
長いコマンドで上に被さると自動で消える、なるほどって感じ。
今となっては bash にも tcsh にも実装って書いてあるけど。。。
関数から自力で実装する方法しか見付からないんですけど。

一般ユーザーが # ってのも気になる所だけど。
そもそも sudo しか使えないんだからココを変える意味は今では無いんだけーが。
右出しを含めてどちらのシェルか解りやすいしコレでいくかなと。

ところで macOS の bash は cd doc から tab キーで documents になった。
zsh では cd Doc と大文字小文字を合わせないと tab キー補完ができないようだ。

シェルスクリプトの覚書色々 – L’Isola di Niente

read コマンドが微妙に違う。
for 文も微妙に違う。
細かいことはもう少し調べてから。

Hello Atom

PyObjC Tips の作成が全然進まない。
原因は解っている、Visual Studio Code がイライラするからだ!
無効にしても無効にしても意図しない補完を勝手にされるのはもうウンザリ。
でも mac のエディタってイマイチなものしか。。。

そういえば Atom って初期の超不安定な頃のしか試していないや、と。
最近のはどうなっているのかな、検索してみよう。

GitHub、無償コードエディター「Atom 1.31」を正式公開 ?ファイルツリーに多くの改善 – 窓の杜

シバンでファイルの見分けができるようになっているようだ。
何だよ、vscode よりコッチのほうが絶対にいいじゃん。

Atom

早速 macOS 版 1.38 をインストール。
触り始めでレビューしても無意味なので二週間ほど使い込む。
その間、徹底的に Gedit 風にカスタマイズ。

Atom を Gedit のように使う – L’Isola di Niente

こうなった。
何だこれ、vscode での不満が全部解決したぞ。

script というシンプルな名前のパッケージが本当に素敵!
モードラインが使える!
自作Geditプラグインの html_escape が関数追加だけで使える!
coffeescript を少し調べる必要があったけど JavaScript が解るなら簡単!
イライラするだけの余計な補完をしない(超重要!)

ということで乗り換え決定。
ただひとつ、拡張関数は js でよくね?

NSView Auto Layout

NSView のレイアウト方式いろいろ – ひ?to?り?go?と

こんなの見つけた。
windowDidResize に頼らず NSView を引き延ばす手段がこんなにあったんだ。

autoresizingMask の指定
addConstraints でアンカーの指定
layout のオーバーライド

一つづつ作って試すの面倒だから NSView の上に NSView を置いて。
上記三つを全部 PyObjC でやってみた。

#!/usr/bin/env python3

from AppKit import *

RECT = ((0, 0), (300, 100))
wins = []

class TopView(NSView):
    def initWithFrame_(self, rect):
        objc.super(TopView, self).initWithFrame_(rect)
        return self

    def drawRect_(self, rect):
        # 全体にバッテンを描く
        NSColor.darkGrayColor().set()
        path = NSBezierPath.bezierPath()
        path.setLineWidth_(10)
        path.moveToPoint_((0, 0))
        path.lineToPoint_(rect.size) # タプルなのでこれでいい
        path.moveToPoint_((0, rect.size.height))
        path.lineToPoint_((rect.size.width, 0))
        path.stroke()

class SecondView(NSView):
    def initWithFrame_(self, rect):
        objc.super(SecondView, self).initWithFrame_(rect)
        self.v = TopView.alloc().initWithFrame_(RECT)
        self.addSubview_(self.v)
        return self

    def layout(self):
        # Override
        objc.super(SecondView, self).layout()
        self.v.setFrameSize_(self.frame().size)

class ThirdView(NSView):
    def initWithFrame_(self, rect):
        objc.super(ThirdView, self).initWithFrame_(rect)
        self.v = SecondView.alloc().initWithFrame_(RECT)
        self.addSubview_(self.v)
        #
        # addConstraints
        #
        self.v.setTranslatesAutoresizingMaskIntoConstraints_(False)
        self.addConstraints_([
            self.v.leftAnchor().constraintEqualToAnchor_constant_(self.leftAnchor(), 0),
            self.v.rightAnchor().constraintEqualToAnchor_constant_(self.rightAnchor(), 0),
            self.v.topAnchor().constraintEqualToAnchor_constant_(self.topAnchor(), 0),
            self.v.bottomAnchor().constraintEqualToAnchor_constant_(self.bottomAnchor(), 0)
        ])
        return self

class MyWindow(NSWindow):
    def init(self):
        objc.super(MyWindow, self).initWithContentRect_styleMask_backing_defer_(
            RECT,
            NSTitledWindowMask | NSClosableWindowMask |
            NSResizableWindowMask | NSMiniaturizableWindowMask,
            NSBackingStoreBuffered, False)
        self.center()
        self.setTitle_('Auto Resize')
        #self.setDelegate_(self)
        # View
        self.v = ThirdView.alloc().initWithFrame_(RECT)
        self.contentView().addSubview_(self.v)
        #
        # autoresizingMask
        #
        self.v.setAutoresizingMask_(NSViewWidthSizable | NSViewHeightSizable) # 2+16
        #
        return self

    #def windowDidResize_(self, sender):
    #    self.v.setFrameSize_(self.contentView().frame().size)

class AppDelegate(NSObject):
    def applicationDidFinishLaunching_(self, notification):
        window = MyWindow.new()
        window.makeKeyAndOrderFront_(window)
        wins.append(window)

class AppMenu(NSMenu):
    def init(self):
        objc.super(AppMenu, self).init()
        item_app  = NSMenuItem.new()
        self.addItem_(item_app)
        menu_app = NSMenu.new()
        item_app.setSubmenu_(menu_app)
        # quit menu
        item_quit = NSMenuItem.new()
        item_quit.initWithTitle_action_keyEquivalent_('Quit App', 'terminate:', 'q')
        menu_app.addItem_(item_quit)
        return self

NSApplication.sharedApplication()
NSApp.setMainMenu_(AppMenu.new())
NSApp.setDelegate_(AppDelegate.new())
NSApp.activateIgnoringOtherApps_(True)
NSApp.run()

なるほど、全部 PyObjC からでも使えますね。
でも結局 windowDidResize が一番扱いやすいような。。。。。