Quantcast
Channel: Vimタグが付けられた新着記事 - Qiita
Viewing all 5608 articles
Browse latest View live

プラグインなしのvimrc

$
0
0

新しく構築したサーバーに入ったとき、デフォルトのVimが起動。
でもちょっとしたテスト用で長くは使わないし、プラグインを記述したvimrcを展開させるのは面倒。
(一括設定スクリプトはあるけど、プラグインが多いとダウンロード時間が地味に遅い。数十秒ですが笑)
(あとは、ネットワークが外に繋がっていないなど…)

そして、シンタックスとか行番号とかをいちいちセットするのも面倒。
設定ファイルにチマチマ書こうか…そのまま使おうか…。

そんな時、私は下記のvimrcをコピペしてます。
(クリップボード管理アプリを使って保存してます)

if&compatiblesetnocompatibleendifsyntax enablecolorscheme desertnnoremap ; :sethlsearchsetnumbersetimdisablesetantialiassetnobackupsetvisualbellt_vb=setwrapscansetshowmatchsetgrepprg=internalsetclipboard=unnamedsetvirtualedit=blocksetignorecasesetsmartcasesetincsearchsetambiwidth=doublesetlaststatus=2setbackspace=eol,indent,startsetwildmenusetencoding=utf-8setcindentsettabstop=4setshiftwidth=4setshowtabline=2setlistsetlistchars=tab:>-,trail:-,extends:<,precedes:<" sorry, Ugandasetshortmess+=I

ちなみに、プラグイン設定を記述してる私のvimrcはこちら
一括設定スクリプトを用意してるので、だいたい$ makeでおけ!


モダンな開発環境をすこしずつ作ってみたい。(Neovim)

$
0
0

webエンジニアになって間もない。以前は物理的なインフラをいじったり、デスクトップアプリを作っていた。それぞれいろんな文化があると思うが、webエンジニアのいう「モダンな環境」を僕もつくりたい。
謎の勢力の「え、できるwebエンジニアはみんなこうだけど」という圧力に押されて、そしてなにより、そんな自分の手に馴染んたツールを使いこなしているエンジニアがかっこいいと思ったから、そんな環境を少しずつつくっていきます。
とりあえず以下の環境を整えたいんだけど、今日はNeovim
- Neovim
- fishシェル
- iTermの設定
- tmux

neovimのインストール

かんたん。macOSのコンソールで、以下のコマンド実行し完了。
# brew install neovim/neovim/neovim

これでとりあえずNeovim自体は使えるようになるので、以下のような感じでファイルが開けることを確認してみる。
# nvim test.rb

ちょっとした設定

  • ターミナル上でTrueColor(24bitカラー)が使えるようにしておきましょう。

早速nvim ~/.config/nvim/init.vimで設定ファイルを開いていただき・・・

~/.config/nvim/init.vim
set termguicolors
  • ターミナル上に行数が表示されるようにしておきましょう。
~/.config/nvim/init.vim
set number

操作の練習

ほとんどvimと同じだろうと思っている。
私も駆け出しvimmmerなので、基本的な操作しかできない。けど慣れると楽しい。
とりあえず以下のことはやってみた。
- コンソールからvimtutor実行して練習する。
- ドットインストールの「vim入門」を受けてみる。https://dotinstall.com/ 

 その他

web開発なら最低限これは必要だろ・・・というプラグインなどありましたらご教示ください。><

Vimのプラグインマネージャを乗り換えた

$
0
0

はじめに

今年の年末はやや慌ただしくなる事が想定されているので、早めにvimrcの大掃除をしようと思ったのがきっかけ。
IT企業に新卒でエンジニアとして入社して以降、ずっとNeoBundleを愛用させていただいていたが、後継であるdein.vimへの移行は昨年見送っていた。自分はミニマルな機能だけで十分かなと感じていたので、この機会に"A minimalist Vim plugin manager."と銘打っているvim-plugに乗り換えてみる事にした。

vim-plugの導入

vim-plugのREADME.mdを参考に。

インストール

plug.vimを~/.vim/autoload/に配置するだけ。

installation
curl -fLo ~/.vim/autoload/plug.vim --create-dirs \
    https://raw.githubusercontent.com/junegunn/vim-plug/master/plug.vim

使い方

.vimrcは、以下のようにcall plug#begin()call plug#end()の間に使いたいプラグインを羅列するだけ。

.vimrc
call plug#begin('~/.vim/plugged')
Plug 'Yggdroot/indentLine'
Plug 'bronson/vim-trailing-whitespace'call plug#end()

.vimrcを上書き保存して閉じたら、vimを起動して:PlugInstallと打てば記述したプラグインがインストールされる。
なお、vim-plugによれば、

Automatically executes filetype plugin indent on and syntax enable. You can revert the settings after the call. e.g. filetype indent off, syntax off, etc.

とのことなので、NeoBundleでは以下のように書いていたが、filetype plugin indent onsyntax enableの2行が不要になる。

.vimrc
call neobundle#begin(expand('~/.vim/bundle/'))
NeoBundle 'Yggdroot/indentLine'
NeoBundle 'bronson/vim-trailing-whitespace'call neobundle#end()filetype plugin indent onsyntax enable

その他

その他コマンドやオプションなど。
:PlugStatusプラグインの状態確認
:PlugUpdateプラグインの更新
:PlugUpgrade vim-plug自身の更新

プラグインの更新後に追加操作の必要なものは、下記のようにオプションを添えておけば良いとの事。ミニマルと銘打つ割にはケアが行き届いていて便利だ。

.vimrc
Plug 'Shougo/vimproc.vim', { 'do': 'make' }
Plug 'Valloric/YouCompleteMe', { 'do': './install.py' }
Plug 'fatih/vim-go', { 'do': ':GoInstallBinaries' }

ディストリビューションから始めたくない人向けのNeovimディストリビューション

$
0
0

begin-with-init.vimというNeovimディストリビューションを作りました。それが提供するのは一枚の小さな設定ファイルinit.vimのみです。そのまさかだ。

背景

Vimのディストリビューションは既に色々あります。

でもミニマリストの方々は、

  • 重いのきらい
  • 要らないプラグイン入れたくない
  • 設定ファイルは自分でカスタマイズしたい

といった理由からディストリビューションを避けるでしょう。そして、既存の環境に甘んじ、Vimを触らずに生涯を過ごすのです。

嘆かわしい。

インストール

Neovimを事前にインストールしてください。

GitHubレポジトリをクローンして、シェルスクリプトを走らせれば完了です。

> git clone https://github.com/raviqqe/begin-with-init.vim>cd begin-with-init.vim> ./install.sh

なんでNeovim?

  • 非同期処理
  • プラガブルなフロントエンド
  • 多言語バインディング

未来を感じる。

まとめ

改宗するのは今からでも遅くはない。

一応、最小公倍数的なものを目指しています。フィードバックお待ちしております。

Vimでvim-lldbを使えるようにするまでの道のり

$
0
0

※特別な理由がないならneovim+lldb.nvimを使ったほうが絶対いいです。
neovim + clang + lldbでC++開発環境構築メモ(自動補完、文法チェック、デバッガフロントエンド)
どうしてもvimを使わないといけない人向けに一応書いときます。


vimでlldbを使いたいな~と思ってプラグインを探してみると、よさげなのがヒットしたので導入しようと思ったら泥沼にはまった。
再導入の時に絶対忘れる気がするので備忘録として導入方法を書いておく。

なお、該当のプラグインはこちら
https://github.com/gilligan/vim-lldb

まずは普通に導入してみる。自分はdeinを使っているので以下の一行を.vimrcに追加した。
.vimrc
call dein#add('gilligan/vim-lldb')

・起動すらしない(g:loaded_lldb = 0)
・has('python') = 0だからダメっぽい
・そういえばUbuntu版vimではpython2は切られていた
・2,3共存させるにはオリジナルビルドを作らないといけないらしい
参考:http://h-miyako.hatenablog.com/entry/2014/11/11/070536
・hg updateで切り替えるとなんかうまくいかなかったので別フォルダへのcheck outを推奨
・pip入れようと思ったらzlibがないといわれる
・zlib1g-dev入れて、Modules/Setupのzlibの行をコメントアウトしてみる
・ビルドしたけど今度はSSLがないらしい
・sslの行もコメントアウト、再ビルドしたらうまくいった
・ビルド完了、起動してみる
・pythonInitで失敗と出る
・import lldbに失敗しているらしい
・lldbというのはLLVM debugger本家のpythonバインディング
・なぜ失敗したかというと、オリジナルビルド版pythonにlldbが入っていなかったから
・python-lldb自体はインスコされているのでPYTHONPATHに追加すればOK
・パスを通して、起動してみるとまたもやエラー
・インタプリタでimport lldbをやってみる
・_lldbがロードできなかったらしい。なんじゃそりゃ
・soのsym linkが壊れているとかなんとか。
参考:http://stackoverflow.com/questions/30869945/how-to-import-lldb-in-a-python-script
・書いてある通りにやってみる、けどまたエラー(undefined PyUnicodeUCS4_AsUTF8String)
・どうやらpythonをucs4対応でビルドしないといけないらしい。やれやれ。
参考:http://stackoverflow.com/questions/33795982/undefined-symbol-pyunicodeucs4-fromstringandsize-with-tensorflow-on-heroku
・今度はsixモジュールがないそうだ。ここまで来るとなんでもできそうな気がしてくる
・正常にインポートされたようだ。vimを起動してみる
・エラーもなく起動。適当に「:Lshow」とか打ってもコマンドなしにはならないので大丈夫そうだ。

やれやれ。

:Ltargetでコンパイル済みファイルを選択。
ブレークポイント設定は仕掛けたい行で:Lbreakpoint。
実際使ってみると、まずrunが遅い。nextもかなりもっさりしている。
これならvimshellとかでlldb動かしたほうが速いような…

VIM教本(vimtutor v1.7) 内容の要約

$
0
0

本文中のチュートリアル分を削って自分用にまとめてみたものです。
ご参考までに。
vimrc(設定ファイル)は次の機会にでも。
・vim実行コマンド: vim
・バージョン確認: vim --versionもしくはvim -v
・vim教本実行コマンド: vimtutor
・導入: sudo apt-get install vim

処理該当キー動作説明
ノーマルモードescノーマルモードへ変更
上移動k (or ↑)上一行カーソル移動
下移動j (or ↓)下一行カーソル移動
右移動l(or →)右一文字カーソル移動
左移動h(or ←)上一文字カーソル移動
追記iもしくはa文字の追記
変更を保存せずにvimを終了:q!変更適用せずに終了
変更を保存してvimを終了:wq上書き保存,終了
行頭0行の頭へカーソル移動
行末$行の末尾へカーソル移動
各単語の一文字目へカーソル移動w-
各単語末尾へカーソル移動e-
deldelもしくはx-
単語削除(空白含む)dw一単語分+空白削除
単語削除(空白は残す)de一単語分削除
複数単語削除d+消したい単語の数+wあるいはe※数を頭においても同様の処理がなされる(例:d2w = 2dw)
カーソル以降削除(行末まで)d$カーソル以降の分を削除(一行分)
行ごと削除(+行情報保存)dd※頭に数をおけば、その数分削除処理される(例:2dd = 2行分削除)
貼り付けpdd後にpで行分コピペ可能
戻るu※ctrl + z のようなもの
複数一気に戻る数字+u文頭の数字分の処理が戻される
行分戻るU一行分の変更をすべて戻す
進むctrl+r※あんまり使わないからこのコマンド構成?
行追加(下)o-
行追加(上)O-
字の置換r+変更したい字※数を頭に指定するとその字数分同じ字に置換される(aaaa に 3r+oで oooa )
単語の置換cwカーソル位置から単語単位で削除され、挿入モードになる /末尾にw$を追記して実行すると削除コマンドと同様な処理*挿入モードが起動
指定置換:s/指定文字列/変更文字列:数字,数字s/~で指定行間一括置換 また、:%s/~で全体一括置換(さらに文末に/gcで一つ一つ確認しながら置換可能)
カーソル現在位置表示ctrl+g現在の行(全体の行数)
Homegg-
endG-
指定行へカーソル移動数字+G-
検索(下方向)/+探したい文字-
検索(上方向)?+探したい文字-
(検索後)次へn次の検索結果へ移動
(検索後)前へN前の検索結果へ移動
検索時に大文字小文字区別なし;set ic-
検索時部分マッチ表示is-
検索時強調表示hls-
各種括弧の先頭.末尾へ移動%(に対応する )にカーソルが移動
vimを起動しながら外部コマンドを使用:!コマンド-
選択v-
コピーy選択後のyでコピーされる
ペーストp-
外部ファイル内文章読み込み+ペースト:rファイル名:r !lsでls結果が本文中にペーストされる
ヘルプ:help-
コマンド確認:+(調べたいコマンドのイニシャル) 後にctrl+D:eならearlierやechoなどコマンド表が表示される

vim操作の基本

$
0
0

モードは3種類。
・コマンドモード(:)
・インサートモード(i)
・ビジュアルモード(v)

基本のコマンドは以下の通りです。
H← J↓ K↑ L→
^ 行の先頭に移動
$ 行の末尾に移動
ctrl + f 次の画面に移動
ctrl + b 前の画面に移動
w 次の単語に進む
b 前の単語に戻る
x 文字を削除
dd 1行切り取り
yy 現在行をコピー
p ペースト
/文字 Enterで検索開始。
u 前の操作を取り消す

[vim] 置換コマンド `:%s` の `g` オプションが効かない?

$
0
0

環境

  • PC : MacBook Air OS X EI Capitan バージョン 10.11.6
  • Vim : MacVim Custom Version 8.0.1272 (KaoriYa 20171105)

データ

aaa bbb aaa ccc
aaa bbb aaa ccc

やりたいこと

全ての aaa111に置換したい。

やったこと

:%s/aaa/111/g

結果

111 bbb aaa ccc
111 bbb aaa ccc

各行の最初の aaaしか置換されてなかった。
今までは gオプションをつければ、全部を置換してくれていたのに。

原因

いろいろと調べたところ、gdefault というコマンドで gオプションの動きを設定できるそうです。

:help gdefault

コマンド'gdefault' がオン'gdefault' がオフ
:s///全て置換最初だけ置換
:s///g最初だけ置換全て置換
:s///gg全て置換最初だけ置換

既定ではオフのはずなので、
:e ~/.vimrc vim設定ファイルを確認したら、
set gdefault という設定が混ざっていました。
削除することでデフォルト設定に戻りました。

参考になったリンク

http://vim.wikia.com/wiki/Search_and_replace


Vim patchダイジェスト [2017/11] (仮)

$
0
0

Vim patchダイジェスト [2017/11] (仮)
(8.0.12428.0.1260)

  • 8.0.1258: sgr mouseをサポートしていなくても'ttymouse'sgrがセットされてしまう件を修正しました。
  • runtimeファイル更新: gdbおよびNeoMutt設定ファイルのfiletypeプラグインの追加。documentの追記、誤記修正。等々。
  • 8.0.1250: 'hlsearch'のhighlightがincsearch後も残っている件を修正しました。(関連patch: 8.0.1238)
  • 8.0.1249: test用共通関数WaitFor()で式の評価時のエラーを無視しないようにしました。(関連patch: 8.0.1251)
  • 8.0.1247: :four_leaf_clover:Debianビルド情報のバッジをREADME.mdに追加しました。(関連patch: 8.0.1248)
  • 8.0.1242: 関数の引数がダッシュ(-)の場合に文字列-ではなく数字の0とみなされていた件を修正しました。

凡例

表記意味
:four_leaf_clover:新機能、大幅な仕様変更
'hoge'オプション (:h options参照)
:hogeExコマンド (:h :index参照)
hoge()組み込み関数 (:h functions参照)
v:hogeVim定義済変数 (:h v:参照)

方針

こちらを参照。


ひとこと

【バイナリファイル入門】Bitmapファイルを手書きで作って遊んでみる

$
0
0

みなさんバイナリファイルはお好きですか?僕は絶賛マイブーム中です。

バイナリファイルは人が見てもイマイチ理解しづらいために苦手意識を持つ方も少なくないのではと思います。

今回はそんな苦手意識を少しでも軽減すべく、簡単なBitmap画像を手作りしてみよう、という試みです。この記事を参考にバイナリデータを読んだり作ったりしてみることで、きっとバイナリデータの見方が変わるのではないかと思います。

では、どうぞ。

Bitmapとは

まずはBitmapというデータフォーマットについて説明しておきます。
Bitmapは、画像を表現するための(たぶん)一番単純なフォーマットです。

特に単純な白黒画像であれば、以下の参考リンクのようなフォーマット解説のページをざっと見ればなんとなく作れるような気がしてくるくらいの分かりやすさだったため、今回はこれを題材にしてみました。

参考

Bitmapファイルフォーマット

バイナリファイルの作り方

バイナリファイルはバイトデータの羅列でできたファイルです。1今回はBitmap形式のバイナリファイルをゼロから作ってみることで、バイナリファイルの扱いを体験します。
なお、バイナリファイルの内容を手作業で見たり修正したりする場合は通常バイナリエディタを使うのですが、今回は以前紹介したワンライナーを使って作成します。

【ワンライナー】バイナリファイルを手作業で作成する

これを使うと、まず16進数表記のバイト列をテキストファイルに記述・保存してからコマンドでバイナリファイルに変換するため、実際の記述作業は使い慣れたテキストエディタでできるメリットがあります。

また、バイナリファイルは「何バイト目から何バイト目にこの情報を記載する」というように仕様で定められた位置に、定められた桁数でデータを打ち込んでいく必要があります。上記のワンライナーを使えば、元となるテキストファイルは好きな位置で改行したりコメントを入れたりできるため、仕様に合わせて分かりやすく整形しつつ、効率的に編集することができます。

いざ、作成

今回は下の画像のように白地に黒で四角が描かれているだけの単純な画像ファイルを作成することを目指します。

スクリーンショット 2017-11-20 23.41.04.png

Bitmapファイルのフォーマットを確認する

まずは今回作成するBitmapファイルのフォーマットを確認します。

Bitmapファイルは大雑把に

  • ファイルヘッダ
  • 情報ヘッダ
  • パレットデータ
  • 画像データ

の4つの領域から成り立ちます。

細かな仕様は先述のリンク先を参照していただければと思いますが、今回はこれらの領域をファイルの先頭から順番に16進数のバイト列で記述していくことになります。

では、Vim等テキストエディタを開いて作業開始です。

$ vi square_bitmap.txt

ファイルヘッダ

ファイルヘッダには、ファイルサイズなどファイル全体の情報を記載します。
ひとまずできあがったものを以下に記載します。

square_bitmap.txt
## ファイルヘッダ ##
42 4d           # ファイルタイプを2バイトで指定。Bitmapは必ず'BM' (16進数で 42 4d)
00 00 00 00     # ファイルサイズを4バイトで指定。TODO: あとで
00 00           # 予約領域1を2バイトで指定。常に0
00 00           # 予約領域2を2バイトで指定。常に0
00 00 00 00     # ファイルの先頭から画像データまでのバイト数を4バイトで指定。 TODO: あとで

上から順番に説明します。

ファイルタイプは、そのバイナリファイルが何の形式であるかを示すバイト列です。Bitmapの場合はASCII文字でBM、つまり16進数表記では42 4dとなります。

ファイルサイズは、今回作成するBitmapファイルのサイズを指定します。とはいえ今の段階では最終的に何バイトになるのかが分からないため、いったん0で埋めておきます。最後に測って修正します。

予約領域は特に使用しません。0 (16進数で00)で埋めておきます。

オフセットはファイルの先頭から画像データまでのバイト数です。こちらも後で測ります。

なんだかファイルタイプ以外は全部0で埋めるだけになりましたね、、、まあ気にせず次にいきましょう。

なお、ここで注意なのですが、ファイルタイプ以外のバイト列はすべてリトルエンディアンで記載します。詳しい説明は省略しますが、リトルエンディアンで記述する場合、下位バイトが左にくるよう記載します。

例えば、仮にファイルサイズが5000だった場合、16進数表記では13 88となります。なので上記のファイルサイズ部分は4バイトになるようゼロ埋めして00 00 13 88となるのですが、リトルエンディアンでは下の桁が左なので、88 13 00 00となる、というワケです。

なんでこんな逆の書き方するのかと言われるといろいろと理由があるみたいなのですが、そのあたりの説明は今回は省略します。とりあえずそういうものなんだ、と理解して先に進んでください。(ちなみにしばらく作業しているとリトルエンディアンの方が分かりやすく思えてきたりするから不思議です)

情報ヘッダ

次に、情報ヘッダです。
情報ヘッダには画像の色数やサイズなど、Bitmap画像自体の情報をいろいろと埋め込んでいきます。

今回は16ピクセル×16ピクセルの白黒画像という前提で指定していきます。

以下をsquare_bitmap.txtに追記してください。

square_bitmap.txt
## 情報ヘッダ ##
28 00 00 00     # 情報ヘッダサイズを4バイトで指定。
10 00 00 00     # 画像の横幅(単位はピクセル)を4バイトで指定。
10 00 00 00     # 画像の高さ(単位はピクセル)を4バイトで指定。
01 00           # プレーン数を2バイトで指定。常に1
01 00           # 色ビット数を2バイトで指定。今回は白黒2色なので1
00 00 00 00     # 圧縮形式を4バイトで指定。
00 00 00 00     # 画像データ部分のサイズを4バイトで指定。 TODO: あとで
10 00 00 00     # 横方向の解像度を4バイトで指定。
10 00 00 00     # 縦方向の解像度を4バイトで指定。
00 00 00 00     # パレット数を4バイトで指定。
00 00 00 00     # 重要色数を4バイトで指定。

記載の内容について、順番に説明します。

情報ヘッダサイズは、その名の通り情報ヘッダのサイズです。情報ヘッダはBitmapの種類によって変わるため、ここでどこまでが情報ヘッダなのかをデータを読み取るプログラムに教えてあげます。今回作成するWindows形式のBitmapファイルでは情報ヘッダは40バイトですので、4桁で0埋めして(そしてリトルエンディアンで)28 00 00 00となります。

画像の横幅・高さはそのままです。幅・高さそれぞれ何ピクセルかを指定します。

プレーン数は、よく理解できていないですが1(2桁の16進数で01 00)固定だそうです。その通り記載します。

色ビット数は画像を何ビットで表すか、という数値です。白黒など2色の場合は1ビット(0/1)で表せるため、1(2桁の16進数で01 00)を指定します。

圧縮形式は、今回は割愛します。無圧縮を表す0を指定します。

画像データサイズは後述する画像データ部分のサイズを指定します。まだ作ってみないと分からないため一旦保留です。

解像度は横、縦それぞれの1メートルあたりのドット数を指定します。なのですが、いろいろ変えてみても見た目が変わらなかったため、どのように指定するのが適切かは未調査です。とりあえず横幅、高さと同じ16(4桁の16進数で10 00 00 00)を指定しておきます。

パレット数はこの画像データで利用する色の数を指定します。ただし、今回のように色ビット数に指定した通り(今回は1bitで2色)の場合は省略して0を指定することができます。

重要色数についてもちょっと未調査です。今回は0で問題ないようなので、0を埋めておきます。

いろいろと理解不足な感は否めないですが、今回の目的はBitmapマスターになることではないため、一旦動けばいい作戦で次に進みたいと思います。

パレットデータ

次にパレットデータを作成します。
今回は色ビット数が1bitのため、2色分のパレットデータを指定する必要があります。白と黒で作成します。

square_bitmap.txt
## パレットデータ ##
ff ff ff 00     # RGB指定。4バイト目は常に0。
00 00 00 00     # RGB指定。4バイト目は常に0。

これだけです。1パレット4バイトで、左3バイトが16進数表記のRGB、4バイト目が予約領域で常に0だそうです。これを白黒それぞれ指定します。RGBの値を変えれば好きな色で画像が作れそうです。

なお、ここで先に指定した色がパレット番号0、後に指定した色がパレット番号1で登録されます。それぞれの番号は後述の画像データで利用します。

画像データ

最後に画像データです。今回は白地(パレット番号0)の上に、黒(パレット番号1)で四角形を描きます。

まず、今回のように色ビット数が1の場合、画像データは0と1の2進数で作成します。
1ピクセル1bitで、縦横16ピクセルずつですので、2進数表記の画像データは以下のようになります。(見やすさのため半角スペースを入れています)

0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0
0 1 0 0 0 0 0 0 0 0 0 0 0 0 1 0
0 1 0 0 0 0 0 0 0 0 0 0 0 0 1 0
0 1 0 0 0 0 0 0 0 0 0 0 0 0 1 0
0 1 0 0 0 0 0 0 0 0 0 0 0 0 1 0
0 1 0 0 0 0 0 0 0 0 0 0 0 0 1 0
0 1 0 0 0 0 0 0 0 0 0 0 0 0 1 0
0 1 0 0 0 0 0 0 0 0 0 0 0 0 1 0
0 1 0 0 0 0 0 0 0 0 0 0 0 0 1 0
0 1 0 0 0 0 0 0 0 0 0 0 0 0 1 0
0 1 0 0 0 0 0 0 0 0 0 0 0 0 1 0
0 1 0 0 0 0 0 0 0 0 0 0 0 0 1 0
0 1 0 0 0 0 0 0 0 0 0 0 0 0 1 0
0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0

しかしバイナリデータは1バイト(8ビット)単位で表記する必要があるため、上記のビット列を8ビット1組のバイト列に変換します。

例えば3行目の0 1 0 0 0 0 0 0 0 0 0 0 0 0 1 0の場合、0100000000000010に分け、それぞれ16進数表記で4002になります。

同じ要領で上から順番に変換していくと、結果は以下のようになります。

00 00
7f fe
40 02
40 02
40 02
40 02
40 02
40 02
40 02
40 02
40 02
40 02
40 02
40 02
7f fe
00 00

さて、これで16ピクセル×16ピクセルの白黒データができたかと思いきや、もう1つ今回気にしなければならないルールがあります。

それは、行データはlong(4byte)の境界に揃えなければいけないというものです。
つまり、1行分のデータは4バイトでなければならず、それに満たない部分については00で埋める、というルールです。

上記の画像データも1行あたりが2バイト(16ビット)しかありませんので、2バイト分を00で埋める必要があります。結果は以下のようになります。

square_bitmap.txt
## 画像データ ##
00 00 00 00
7f fe 00 00
40 02 00 00
40 02 00 00
40 02 00 00
40 02 00 00
40 02 00 00
40 02 00 00
40 02 00 00
40 02 00 00
40 02 00 00
40 02 00 00
40 02 00 00
40 02 00 00
7f fe 00 00
00 00 00 00

画像データはこれで完成です。
ここで、1点だけ注意すべき点があります。Bitmapでは、画像データは左下から指定する、ということです。今回は上下線対称な画像だったため特に気にはしていませんが、実際の画像を作成する際は、下の列からデータを埋めていく必要があります。

このあたりは実際に作って表示しながら実験してみるとわかりやすいかと思いますので、詳しくは省略します。

「TODO: あとで」を埋める

さて、ここまでできれば先ほど「TODO: あとで」として飛ばした部分を埋めることができます。

まずはファイルサイズですが、これは現状のBitmapデータのバイト数を数えれば大丈夫です。一度紹介したワンライナーでバイナリファイルを作ってみましょう。

$ cat square_bitmap.txt | awk -F# '{print $1}' | tr -dc [0-9a-f] | xxd -r -p > square_bitmap.bmp

$ ls -l square_bitmap.bmp
-rw-r--r--@ 1 chooyan  wheel  126 11 20 23:40 square_bitmap.bmp

126バイトだそうです。126は16進数で7eですので、4桁で0埋めして7e 00 00 00を記載します。

次にオフセットです。これは全体のファイルサイズから画像データのサイズを引くことで得られます。つまり、今回は126 - (4バイト * 16行)で、62です。16進数にすると3eですね。4桁で0埋めして3e 00 00 00となります。

最後に画像データのサイズですが、これは先ほど出したとおり、4バイト * 16行で64バイトですね。16進数表記に直し、4桁で0埋めして40 00 00 00になります。

できあがったテキストファイル

これでテキストファイルの編集は終わりです。完成したファイルはこのようになっているはずです。

$ cat square_bitmap.txt

## ファイルヘッダ ##
42 4d           # ファイルタイプを2バイトで指定。Bitmapは必ず'BM' (16進数で 42 4d)
7e 00 00 00     # ファイルサイズを4バイトで指定。
00 00           # 予約領域1を2バイトで指定。常に0
00 00           # 予約領域2を2バイトで指定。常に0
3e 00 00 00     # ファイルの先頭から画像データまでのバイト数を4バイトで指定。

## 情報ヘッダ ##
28 00 00 00     # 情報ヘッダサイズを4バイトで指定。
10 00 00 00     # 画像の横幅(単位はピクセル)を4バイトで指定。
10 00 00 00     # 画像の高さ(単位はピクセル)を4バイトで指定。
01 00           # プレーン数を2バイトで指定。常に1
01 00           # 色ビット数を2バイトで指定。今回は白黒2色なので1
00 00 00 00     # 圧縮形式を4バイトで指定。
40 00 00 00     # 画像データ部分のサイズを4バイトで指定。
10 00 00 00     # 横方向の解像度を4バイトで指定。
10 00 00 00     # 縦方向の解像度を4バイトで指定。
00 00 00 00     # パレット数を4バイトで指定。
00 00 00 00     # 重要色数を4バイトで指定。

## パレットデータ ##
ff ff ff 00     # RGB指定。4バイト目は常に0。
00 00 00 00     # RGB指定。4バイト目は常に0。

## 画像データ ##
00 00 00 00
7f fe 00 00
40 02 00 00
40 02 00 00
40 02 00 00
40 02 00 00
40 02 00 00
40 02 00 00
40 02 00 00
40 02 00 00
40 02 00 00
40 02 00 00
40 02 00 00
40 02 00 00
7f fe 00 00
00 00 00 00

バイナリファイルに変換する

最後に、作成したテキストファイルを先ほどから使っているワンライナーでバイナリファイルに変換します。

$ cat square_bitmap.txt | awk -F# '{print $1}' | tr -dc [0-9a-f] | xxd -r -p > square_bitmap.bmp

生成されたバイナリファイルをodコマンドで見てみます。

$ od -Ad -tx1 -v square_bitmap.bmp
0000000 42 4d 7e 00 00 00 00 00 00 00 3e 00 00 00 28 00
0000016 00 00 10 00 00 00 10 00 00 00 01 00 01 00 00 00
0000032 00 00 40 00 00 00 10 00 00 00 10 00 00 00 00 00
0000048 00 00 00 00 00 00 ff ff ff 00 00 00 00 00 00 00
0000064 00 00 7f fe 00 00 40 02 00 00 40 02 00 00 40 02
0000080 00 00 40 02 00 00 40 02 00 00 40 02 00 00 40 02
0000096 00 00 40 02 00 00 40 02 00 00 40 02 00 00 40 02
0000112 00 00 40 02 00 00 7f fe 00 00 00 00 00 00
0000126

まあ、よく分からないですね。とりあえず整形のための改行やコメントはきれいさっぱり消えて、126バイトのデータになっていることがわかります。

今回作成したのは画像ファイルですので、ちゃんとできているかの確認はエクスプローラーなどから確認します。フォルダを開いて、ダブルクリックしてみます。

ちゃんとできていれば、最初に掲載したキャプチャのような図が(ちっちゃく)表示されるはずです。

image.png

まとめ

というわけで、今回はBitmap画像ファイルを0から手打ちで作成してみました。

今までは手も足も出そうと思わなかったバイナリデータが、意外と仕様を見ながら手作業で作成できてしまう様子が体験できたのではないかと思います。

基本的にバイナリデータは、決まった仕様にしたがって作成されたデータを、同じ仕様にしたがって解釈・処理するプログラムが読み取ることによって役割を果たします。結局は共通の仕様が全てですので、その意味では「人間が読めればいいでしょ」的に曖昧に作られることの多いテキストファイルよりもある意味読みやすいと言えるんじゃないかと最近考えています。

おそらく他のファイルフォーマットでも要領は同じですので、ぜひいろいろと今回使ったワンライナーを使ってバイナリファイルを手書きしてみてください!



  1. ホントはファイルは全てバイトデータの塊なので「バイナリファイル」と言えるのですが、その中でもテキストとして解釈できるバイナリファイルは慣習的(?)に「テキストファイル」と呼んで区別します。 

WSL上のvimでクリップボードを共有する方法

$
0
0
  1. ここからwin32yankを落とす
  2. win32yankのPATHを通す
  3. 以下をvimrcに追記
vimrc
nnoremap <silent>y :.w !win32yank.exe -i<CR><CR>
vnoremap <silent>y :w !win32yank.exe -i<CR><CR>
nnoremap <silent>p :r !win32yank.exe -o<CR>
vnoremap <silent>p :r !win32yank.exe -o<CR>

WSL上のvimでcolorschemeの背景色を正しく表示する方法

$
0
0

WSL上のvimだとctermbgやguibgが正常に設定されない

WSLのvimだと、Linuxと同じ設定のままではhilightにおけるctermbgやguibgが行頭から行末までしか設定されないことがあります。
ということで、その解決方法をメモっておきます。

解決方法

  • set t_ut=を追記する

これだけです!

vimでCoqを使えるようにする

$
0
0

環境

OS: MacOS High Sierra
neovim: v0.2.0

deinを使ってインストールしています。

インストールするもの

インストール

dein_lazy.toml
[[plugins]]repo='let-def/vimbufsync'on_ft='coq'[[plugins]]repo='the-lambda-church/coquille'on_ft='coq'depends=['vimbufsync']hook_source='''nmap<silent><C-c><C-l>:CoqLaunch<CR>nmap<silent><C-c><C-n>:CoqNext<CR>nmap<silent><C-c><C-u>:CoqUndo<CR>nmap<silent><C-c><C-c>:CoqToCursor<CR>'''

coquilleをインストールしても動かなくてREADMEをみるとvimbufsyncと言うものが必要らしかった。
なのでdependsにvimbufsyncを指定してインストール
キーマッピングは各自の好みにおまかせします。

READMEに進められていたのは

" Maps Coquille commands to <F2> (Undo), <F3> (Next), <F4> (ToCursor)
au FileType coq call coquille#FNMapping()

だったけど、やってみるとF3とか押しにくいなあと思ったので変えてみたけど、今のも微妙かも
何かおすすめのキーマッピングがあれば教えてください

スクショはこんな感じです
スクリーンショット 2017-11-21 18.39.02.png

Windows環境にVimをインストールする方法

$
0
0

Vimの導入方法

Vim公式のダウンロードページにアクセスします。
導入先のOSに応じたダウンロードリンクをクリックします。
※現時点(2017年11月22日)での最近バージョンはVim8.0です。
今回は、「MS-Windows」なのでself-installing executableをクリックしてダウンロードします。
ダウンロードしてきたexeファイルを実行します。
Vimのインストールが完了するとデスクトップに「gvim」、「gvim Easy」、「gVim Read only」の3つのショートカットが作成されます
※インストール時のオプションをデフォルトから変更していない場合
インストールはこれで完了です。

環境変数の設定

ただVimをインストールしただけではコマンドプロンプトから起動することはできません。
それは、インストール時点ではVimの環境変数の設定がされていないからです。
vim-not-recognized.png

Windows10の場合、「Windowsキー+ i」と押すことでWindowsの設定画面が開きます。
そこから「システム」→「バージョン情報」→「システム情報」→「システム情報の詳細設定」→「環境変数」の順でクリックすると、環境変数の設定画面が開きます。

ユーザー環境変数のPathを選択した状態で「編集」をクリックしてPathの設定を行います。
すでに入っている値に、;(セミコロン)で繋げて「vim.exe」ファイルが存在するディレクトリ(例:C:\Program Files (x86)\Vim\vim80)を追加してください。

追加後には、PCの再起動を行うことで環境変数の変更が反映されます。
これでコマンドプロンプトでvimと入力するとVimエディタが開くようになりました。
もし開かない場合は環境変数の設定が上手くいってないと思われるのでVimのインストールディレクトリおよび環境変数の値を見直して再度チャレンジしてください。

おまけ

Cortanaが賢い。
環境変数の設定の際にCortanaの検索ウィンドウに環境変数と入れるとダイレクトに環境変数の設定画面に行くことができます。

cortana.png

これで本記事は終了です。
Let's enjoy Vim!

シェル書いててcan't cd to [directory]に出くわした

$
0
0

概要

シェル書いてて can't cd to [directory]というエラーが出たのでメモ。

環境

OS : debian 7.6

解決法

vim で新規にファイル作成した時に、改行コードをLFにする必要があるみたい。
tr 使って置換もありだけど、もはや思考停止したので、vimでLFとしてファイルを開く方法を採択してみた。

:edit ++fileformat=unix

これで解決。


【vim-go】便利なコマンド一覧

$
0
0

参考

公式vim-goドキュメント

一覧

個人的によく使うものを、まとめます。

キー内容
gd定義元にジャンプ(Ctrl-oで元のファイルへ戻る)
:GoFmtgo fmt実行(:wで保存時にも実行される)
:GoErrCheck現在のpackage内でエラーチェック
Ctrl-x Ctrl-oカーソル下のコード補完
:GoImports足りないpackageを追加、不要packageを削除
:GoRename [to]カーソル下にある識別子を[to]で指定した名前に一括変更
:GoDoc [word][word]のドキュメントを新たなウィンドウで開く。デフォルトの[word]はカーソル下
:GoDocBrowser [word]上記GoDocをブラウザで表示
:GoImplementsカーソル下の構造体やインターフェイスのリレーションを表示
:GoFillStructカーソル下の構造体にデフォルト値を与える

エイリアスをつけよう

コマンドが長いので、エイリアスを設定しましょう。
.vimrcに以下のように記述します。
エイリアスの最初の文字は大文字でないと怒られます。

.vimrc
" :command <エイリアス> <元のコマンド>:command Ge GoErrCheck:command Gii GoImports
.
.
.

新米のvimtutor勉強メモ

$
0
0
  • normal modeでのcursor移動

    • k 上
    • j 下
    • h 左
    • l 右
  • insert modeとnormal modeの切り替え

    • insert->normal : キーesc
    • normal->insert : キーi
    • normal->insert : キーa
    • normal->insert : キーA (行末にcursorが移動)
  • 保存なしで、vim閉じる:normal modeで :q!

  • 文字削除

    • 一文字(削除後、normal modeまま):normal modeでキーx
    • 一文字(削除後、insert modeまま):normal modeでキーs
    • 一単語(削除後、normal modeまま):normal modeでキーdw (delete word)
    • 一単語(削除後、insert modeまま):normal modeでキーcw (change word)

Vimで二分探索する

$
0
0

注意

実用性は無いです。

前提

vim -u NONE -i NONE -N -c 'put=range(1000)' -c '$ delete' -c 'set cul'
  • 初期状態ではバッファの各行が 0, 1, 2, ... 999 で埋まっている
  • 探索する値は何でもいいけど今回は42ということにしておく

手順

:let s=42^Mqqgs50%zzgsy$@=@0==''?"SNot found\<Esc>":@0<s?'dgg@q':@0>s?'dG@q':"IFound: \<Esc>"^Mq@q
  • ^Mはcarriage returnに置き換えること

結果

t.gif

解説

Step 1: 人間に読める形に分解する

:let s=42^Mqqgs50%zzgsy$@=@0==''?"SNot found\<Esc>":@0<s?'dgg@q':@0>s?'dG@q':"IFound: \<Esc>"^Mq@q

  1. :let s=42^M
    • 探す値を変数 sに代入
  2. qqgs50%zzgsy$@=@0==''?"SNot found\<Esc>":@0<s?'dgg@q':@0>s?'dG@q':"IFound: \<Esc>"^Mq
    • 何か凄そうだけど……全体は qq ... qなのでキーボードマクロの記録をしてるだけ
  3. @q
    • ...の操作をもう一度やる

Step 2: 記録された ...の正体

gs50%zzgsy$@=@0==''?"SNot found\<Esc>":@0<s?'dgg@q':@0>s?'dG@q':"IFound: \<Esc>"^M

  1. gs
    • 1秒sleep
    • 動きを人間の目でも認識できるよう仕込んでる(省略可)
  2. 50%
    • バッファ全体の大体50%くらいの位置に移動
  3. zz
    • カーソル行が画面の中央に表示されるようビューを調整
    • 動きを人間の目でも認識できるよう仕込んでる(省略可)
  4. gs
    • 1秒sleep(省略化)
  5. y$
    • カーソル行の内容をコピー
  6. @=@0==''?"SNot found\<Esc>":@0<s?'dgg@q':@0>s?'dG@q':"IFound: \<Esc>"^M
    • 何か凄い事をやってる

Step 3: 何か凄い事の正体

@=@0==''?"SNot found\<Esc>":@0<s?'dgg@q':@0>s?'dG@q':"IFound: \<Esc>"^M

  1. @=
    • レジスタ =の内容をキーボードマクロとして実行する
    • 実行する内容は「この後に書いた式の評価結果」なので……
  2. @0==''?"SNot found\<Esc>":@0<s?'dgg@q':@0>s?'dG@q':"IFound: \<Esc>"
    • これが何か凄い式
  3. ^M
    • 式の終わりを示すcarriage return

Step 4: 何か凄い式の正体

@0==''?"SNot found\<Esc>":@0<s?'dgg@q':@0>s?'dG@q':"IFound: \<Esc>"

  1. @0==''
    • 最後にコピーした内容(=カーソル行の内容)が空文字列か判定する
  2.  ?"SNot found\<Esc>"
    • 空文字列なら全要素探索し終えたので終了
  3.  :@0<s
    • カーソル行の内容が探索対象の値より小さいか判定する
  4.   ?'dgg@q'
    • 小さいならバッファの前半を消して二分探索を再実行
  5.   :@0>s
    • カーソル行の内容が探索対象の値より大きいか判定する
  6.    ?'dG@q'
    • 大きいならバッファの後半を消して二分探索を再実行
  7.    :"IFound: \<Esc>"
    • ここまで来たら探索対象の値が見つかったので終了

ポイント

qqgs50%zzgsy$@=@0==''?"SNot found\<Esc>":@0<s?'dgg@q':@0>s?'dG@q':"IFound: \<Esc>"^Mq@q

↓ (これの骨格だけを抽出すると)

qq...@=...''?'...@q':'...'^Mq@q

↓ (より本質的なところを抽出すると)

qq...@q...q@q
  • 1個目の @q: キーボードマクロ qの記録中なのに @qで実行してる
    • この段階ではレジスタ qの内容は空なので、 @qしても何も起きない
  • 2個目の @q: 先程レジスタ qに記録された内容が実行される
    • この段階ではレジスタ qの内容は沢山あるので、 @qの実行で更に @qが再帰的に実行される

vim 練習中

$
0
0

キー 動作
i カーソルの位置で挿入モードになります。iは「insert」の略として覚えます
I カーソル行の行頭(空白は除く)で挿入モードになります。
a カーソルの後ろの位置で挿入モードになります。aは「add」の略として覚えます
A カーソル行の行末で挿入モードになります。
o カーソルの次行の位置に行を追加して挿入モードになります。
O カーソルの前行の位置に行を追加して挿入モードになります。

macproではescが物理ボタンではない
物理ボタンで打ち込む場合はcontrol+[

Deniteの使い方メモ

$
0
0

準備

  • rgを導入しておく

設定

Shougoさんのコードをかなり参考にしました。

vimrc
nnoremap [Window] <Nop>
nmap s [Window]
nmap <Space> [Space]
hook_source
"---------------------------------------------------------------------------
" denite.nvim
"

if executable('rg')
  call denite#custom#var('file_rec', 'command',
        \ ['rg', '--files', '--glob', '!.git'])
  call denite#custom#var('grep', 'command', ['rg', '--threads', '1'])
  call denite#custom#var('grep', 'recursive_opts', [])
  call denite#custom#var('grep', 'final_opts', [])
  call denite#custom#var('grep', 'separator', ['--'])
  call denite#custom#var('grep', 'default_opts',
        \ ['--vimgrep', '--no-heading'])
else
  call denite#custom#var('file_rec', 'command',
        \ ['ag', '--follow', '--nocolor', '--nogroup', '-g', ''])
endif

call denite#custom#source('file_old', 'matchers',
      \ ['matcher_fuzzy', 'matcher_project_files'])
call denite#custom#source('tag', 'matchers', ['matcher_substring'])
if has('nvim')
  call denite#custom#source('file_rec,grep', 'matchers',
        \ ['matcher_cpsm'])
endif
call denite#custom#source('file_old', 'converters',
      \ ['converter_relative_word'])

call denite#custom#map('insert', '<C-r>',
      \ '<denite:toggle_matchers:matcher_substring>', 'noremap')
call denite#custom#map('insert', '<C-s>',
      \ '<denite:toggle_sorters:sorter_reverse>', 'noremap')
call denite#custom#map('insert', '<C-j>',
      \ '<denite:move_to_next_line>', 'noremap')
call denite#custom#map('insert', '<C-k>',
      \ '<denite:move_to_previous_line>', 'noremap')
call denite#custom#map('insert', "'",
      \ '<denite:move_to_next_line>', 'noremap')
call denite#custom#map('normal', 'r',
      \ '<denite:do_action:quickfix>', 'noremap')
call denite#custom#map('insert', ';',
      \ 'vimrc#sticky_func()', 'expr')

call denite#custom#alias('source', 'file_rec/git', 'file_rec')
call denite#custom#var('file_rec/git', 'command',
      \ ['git', 'ls-files', '-co', '--exclude-standard'])

" call denite#custom#option('default', 'prompt', '>')
" call denite#custom#option('default', 'short_source_names', v:true)
call denite#custom#option('default', {
      \ 'auto_accel': v:true,
      \ 'prompt': '>',
      \ 'source_names': 'short',
      \ })

let s:menus = {}
let s:menus.vim = {
    \ 'description': 'Vim',
    \ }
let s:menus.vim.file_candidates = [
    \ ['    > Edit configuation file (init.vim)', '~/.config/nvim/init.vim']
    \ ]
call denite#custom#var('menu', 'menus', s:menus)

call denite#custom#filter('matcher_ignore_globs', 'ignore_globs',
      \ [ '.git/', '.ropeproject/', '__pycache__/',
      \   'venv/', 'images/', '*.min.*', 'img/', 'fonts/'])

call denite#custom#action('file', 'test',
      \ {context -> execute('let g:foo = 1')})

call denite#custom#action('file', 'test2',
      \ {context -> denite#do_action(context, 'open', context['targets'])})
hook_add
  nnoremap <silent> ;r
        \ :<C-u>Denite -buffer-name=register
        \ register neoyank<CR>
  xnoremap <silent> ;r
        \ :<C-u>Denite -default-action=replace -buffer-name=register
        \ register neoyank<CR>
  nnoremap <silent> [Window]<Space>
        \ :<C-u>Denite file_rec:~/.vim/rc<CR>
  nnoremap <silent> / :<C-u>Denite -buffer-name=search -auto-highlight
        \ line<CR>
  nnoremap <silent> * :<C-u>DeniteCursorWord -buffer-name=search
        \ -auto-highlight -mode=normal line<CR>
  nnoremap <silent> [Window]s :<C-u>Denite file_point file_old
        \ -sorters=sorter_rank
        \ `finddir('.git', ';') != '' ? 'file_rec/git' : 'file_rec'`<CR>
  nnoremap <silent> [Window]f :<C-u>Denite file_rec -path=
  nnoremap <silent><expr> tt  &filetype == 'help' ?  "g\<C-]>" :
        \ ":\<C-u>DeniteCursorWord -buffer-name=tag -immediately
        \  tag:include\<CR>"
  nnoremap <silent><expr> tp  &filetype == 'help' ?
        \ ":\<C-u>pop\<CR>" : ":\<C-u>Denite -mode=normal jump\<CR>"
  nnoremap <silent> [Window]n :<C-u>Denite dein<CR>
  nnoremap <silent> [Window]g :<C-u>Denite ghq<CR>
  nnoremap <silent> ;g :<C-u>Denite -buffer-name=search
        \ -no-empty -mode=normal grep<CR>
  nnoremap <silent> n :<C-u>Denite -buffer-name=search
        \ -resume -mode=normal -refresh<CR>
  nnoremap <silent> ft :<C-u>Denite filetype<CR>
  nnoremap <silent> <C-t> :<C-u>Denite
        \ -select=`tabpagenr()-1` -mode=normal deol<CR>
  nnoremap <silent> <C-k> :<C-u>Denite -mode=normal change jump<CR>
  nnoremap <silent> [Space]gs :<C-u>Denite gitstatus<CR>
  nnoremap <silent> ;;
        \ :<C-u>Denite command command_history<CR>

使い方

検索
/
カーソル上の単語で検索
*
貼り付け
;r
不明
s<space>
変更順のファイルリストを展開
ss
カレントディレクトリをfind
sf<Enter>
カレントディレクトリ以外をfind
sf<Path>
buffer的なやつかな?
tp
プラグイン一覧が見れる
sn
カレントバッファ以外のファイルの中身を検索
;g
n #前回の検索パターンを使用して再検索
filetype変更
ft
よくわからんけどタブとかshellとか関係ありそう
<C-t> # deol.nvimを入れる必要がある
変更した箇所のジャンプリストを展開
<C-k>
gitstatus
<Space>gs # Denite-gitを入れる必要がある
vim上で実行したコマンドの履歴
;;
Viewing all 5608 articles
Browse latest View live


<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>