質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.49%
Git

Gitはオープンソースの分散バージョン管理システム(DVCS)です。

Go

Go(golang)は、Googleで開発されたオープンソースのプログラミング言語です。

Q&A

解決済

2回答

437閲覧

Go言語で外部プログラムの標準出力・入力を扱う方法について

kamontia

総合スコア7

Git

Gitはオープンソースの分散バージョン管理システム(DVCS)です。

Go

Go(golang)は、Googleで開発されたオープンソースのプログラミング言語です。

0グッド

0クリップ

投稿2018/08/15 01:53

編集2018/08/15 02:02

実現したいこと

Go言語を使って外部プログラムを起動して、ファイルを修正する方法はありますか?
具体的には、Vimで指定されたファイルを読み取り、Vim上に表示されている文字列を置換したいです。

例えば、text.txtが以下のような場合

txt

1Hello

Go言語からVimを使って読み込まれたファイルを修正したいです。

現状で試したこと

Qiitaなどで調査して、ソースコード書いてみましたが意図した動作になりません。

go

1 vimCmd := exec.Command("vim", "text.txt") 2 vimStdout, _ := vimCmd.StdoutPipe() 3 vimStderr, _ := vimCmd.StderrPipe() 4 vimCmd.Start() 5 /* 以下3行は有効にするとvimエディタが起動(例外で落ちる) */ 6 //vimCmd.Stdin = os.Stdin 7 //vimCmd.Stdout = os.Stdout 8 //vimCmd.Stderr = os.Stderr 9 go func() { 10 scannerOut := bufio.NewScanner(vimStdout) 11 scannerErr := bufio.NewScanner(vimStderr) 12 for scannerOut.Scan() { 13 for scannerErr.Scan() { 14 lineErr := scannerErr.Text() 15 fmt.Println("[stdErr] ", lineErr) 16 } 17 lineOut := scannerOut.Text() 18 fmt.Println("[output] ", lineOut) 19 } 20 }() 21 vimCmd.Wait() 22

bash

1[stdErr] Vim: 警告: 端末への出力ではありません 2[stdErr] Vim: 警告: 端末からの入力ではありません

聞きたいこと

  • Go言語を使って書きたいという要望がありますが、そもそも不可能なことですか?
  • 実現する方法があればヒントだけでもいいのでアドバイスを頂きたいです

結局何をしたいのかというと

Gitのリベース処理を自動化するコマンドを作りたいです。
細かいコミットが重なったために、リベースでSquashしようとすると以下のようなコマンドを実行して、

bash

1git rebase -i HEAD~3

すると、git-rebase-todoがエディタで立ち上がると思います。
しかし、その都度エディタが立ち上がり対象のコミットに対してsquashに書き換えるのが面倒です。
そこをコマンドでサクっと修正できるようにしたいと考えています。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

一時的に、環境変数 EDITOR にエディターではなく、「自分で作ったプログラム」を登録すれば、git はそちらを呼び出すはずです。

そのコールバックされるプログラムで、エディターに行わせたかった動作をさせる方が簡単かと思いますが、いかがでしょうか?

問題は、git が間に入るので、大元のプログラムからコールバックされるプログラムへパラメーターが渡しにくいという点ですが、そちらは「別の名前の環境変数」とか一時ファイルなどを使うなどの方法があると思います。

投稿2018/09/02 02:59

zetamatta

総合スコア23

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

kamontia

2018/10/04 06:14

返信が遅くなり申し訳ございません。 ご指摘されている通り、間にGitが入るためGitの細かなバージョンの違いによっても影響が出てくるかもしれません。 Gitのマニュアルを読み、autosquash機能を使うことで実現したいことが実現できました。 Githubに公開させて頂いております。 https://github.com/kamontia/qs
guest

0

ベストアンサー

vimはキー入力を標準入力でなく端末から取るので、パイプでの制御は無理です。
vimのコマンドラインモードであるexを使えばパイプでの制御ができるかと思います。

vimで、:の後に入力するのがexのコマンドです。%s/foo/bar/とかqとか。

Bash

1echo -e '%s/foo/bar/g\n%l\nwq' | ex test.txt

どうしてもvimということだと、擬似端末(pty)のAPIを使って動かすのでしょうか。

投稿2018/08/15 02:30

編集2018/08/15 03:23
otn

総合スコア84491

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

kamontia

2018/08/15 05:14

ご回答ありがとうございます。 ptyを使用すると色々出来そうですが費用対効果があまり無さそうですね。 コミットメッセージに"squash! 統合したい過去のコミットメッセージ"とし(Go等のプログラムから出来そうです)、rebaesのautosquashオプションと組み合わせて実現できそうです。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.49%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問