Vim | vim -v is beautiful
How to cancel Git | commit --amend prematurely (cancel while entering commit message)
problem
Amend it!
$ git commit --amend
I want to quit after all!
Fix you brain # Please enter the commit message for your changes. Lines starting # with '#' will be ignored, and an empty message aborts the commit. # ...
Get out without saving!
:q!
(The vim command)
Wow ah, it has been committed ah!
Date: Fri Dec 18 13:38:52 2015 +0900 2 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 you-need-amend.rb create mode 100644 but-i-walk-my-way.sh
Solution 1
commit --amend
1. Delete all commit messages.
Make no commit message. (Comments may be included)
# Please enter the commit message for your changes. Lines starting # with '#' will be ignored, and an empty message aborts the commit. # # Date: Fri Dec 18 13:38:52 2015 +0900
However. Because it will be committed if there is only one blank line / comment line. It would be safer to delete all the file contents. (If you keep pressing the d
key as well)
2. End saving
:x
(the vim command)
3. Results
Not committed (Return to the original)
Aborting commit due to empty commit message.
Solution 2
How is it usually?
In a normal commit that is not amend. It just seems OK if you exit without saving. ( :q!
)
environment
- git version 2.3.8 (Apple Git-58)
- vim 7.3
Aside
I noticed later that it was clearly explained in the commit editing message.
an empty message aborts the commit.
Original by
Git | commit --amend を途中で取り消しする方法 (コミットメッセージ入力中のキャンセル)
About
vim | How to open file from last line
Vim script でアヤメの品種を分類する
はじめに
以前、Vim script で機械学習という記事を書いた事で、「Vim script で機械学習は可能」という事を皆さんにもご理解頂けたはずなので、今回は Vim script を使ってアヤメの品種分類をしたいと思います。
出典: https://ja.wikipedia.org/wiki/%E3%82%A2%E3%83%A4%E3%83%A1
iris.csv とは
アヤメは温帯に生息するおよそ150種類からなるアヤメ科の植物で、その多くは、がく片の長さ、がく片の幅、花弁の長さ、花弁の幅でその品種が分類できるそうです。この研究結果を UCI(カリフォルニア大学アーバイン校)がデータマイニングの検証用データとして iris.csv
というファイル名で配布していて機械学習をやる方の間では有名なデータセットになっています1。iris.csv
に含まれるのは、setosa、versicolor、virginica の3種で、150個のサンプルが含まれています。
出典: https://en.wikipedia.org/wiki/Iris_flower_data_set#cite_ref-fisher36_1-0
これは、がく片の長さ、がく片の幅、花弁の長さ、花弁の幅、それぞれをペアで図にした物ですが、これを見るだけでも個々の形容の属性値と品種に相関があるのが分かります。iris.csv
は以下の内容で定義されています。
1. sepal length in cm
2. sepal width in cm
3. petal length in cm
4. petal width in cm
5. class:
-- Iris Setosa
-- Iris Versicolour
-- Iris Virginica
SepalLength,SepalWidth,PetalLength,PetalWidth,Name
5.1,3.5,1.4,0.2,Iris-setosa
4.9,3.0,1.4,0.2,Iris-setosa
4.7,3.2,1.3,0.2,Iris-setosa
4.6,3.1,1.5,0.2,Iris-setosa
Vim script で分類しましょう
さっそく Vim script から CSV を読み込んでみます。Vim script にも浮動小数型があるのでファイルから文字列を読み込み、カンマで分割、数字で構成させているのであれば文字列評価で数値化します。
function!s:token(line) abort
return map(split(a:line,','),'v:val =~# "^[-+]\\?[0-9][.]\\?[0-9]*$" ? str2float(v:val) : v:val')endfunctionfunction!s:main() abort
letl:data = map(readfile('iris.csv'),'s:token(v:val)')[1:]endfunction
CSV の1~4カラム目が属性値、5カラム目が品種になるので分割します。
let[l:X,l:y]=[[],[]]forl:row inl:data
call add(l:X,l:row[:3])call add(l:y,l:row[4])endfor
Bag of Words
品種名の一覧から品種名の一覧を作り、数値化(Bag of Words)します。
function!s:make_vocab(names) abort
letl:ns ={}forl:name ina:namesif!has_key(l:ns,l:name)letl:ns[l:name]=0.0+ len(l:ns)endifendforreturnl:ns
endfunctionfunction!s:bag_of_words(names, vocab) abort
return map(a:names,'(0.0 + a:vocab[v:val]) / len(a:vocab)')endfunction
letl:vocab =s:make_vocab(l:y)calls:bag_of_words(l:y,l:vocab)
これで l:y
が名称の一覧ではなく、品種名を示す値になった訳です。ロジスティック回帰を使うのですが、残念ながら Vim script には乱数を生成する機能がありません。Xorshift を扱う為の pull-requst を送ってはいますが、未だマージされていません2。
そこで疑似乱数生成機を作ります。以下は V8 で使われている George Marsaglia 氏の MWC アルゴリズムです。
" Random number generator using George Marsaglia's MWC algorithm.lets:hi=0lets:lo=0function!s:srand(seed)ifa:seed<0lets:hi=(a:seed-0x80000000) / 0x10000 +0x8000
lets:lo=(a:seed-0x80000000) % 0x10000
elselets:hi=a:seed / 0x10000 +0x8000
lets:lo=a:seed % 0x10000
endifendfunctionfunction!s:rand()ifs:hi==0lets:hi=s:random_seed()endififs:lo==0lets:lo=s:random_seed()endififs:hi<0lethi=s:hi-0x80000000
lethi=36969 * (hi % 0x10000)+(hi / 0x10000 +0x8000)elselethi=s:hilethi=36969 * (hi % 0x10000)+(hi / 0x10000)endififs:lo<0letlo=s:lo-0x80000000
letlo=18273 * (lo % 0x10000)+(lo / 0x10000 +0x8000)elseletlo=s:loletlo=18273 * (lo % 0x10000)+(lo / 0x10000)endiflets:hi=hilets:lo=loreturn(hi * 0x10000)+((lo<0 ? lo-0x80000000 :lo) % 0x10000)endfunctionfunction!s:random()letn=s:rand()ifn<0return(n-0x80000000)/ 4294967295.0 + (0x40000000 /(4294967295.0 / 2.0))elsereturnn / 4294967295.0endifendfunction" V8 uses C runtime random function for seed and initialize it with time.lets:seed= float2nr(fmod(str2float(reltimestr(reltime())) * 256,2147483648.0))function!s:random_seed()lets:seed=s:seed * 214013+2531011return(s:seed<0 ? s:seed-0x80000000 :s:seed) / 0x10000 % 0x8000
endfunction
属性値が示す勾配を補正していく為に1をゲインとするシグモイド関数を用意します。よく見るこういう奴ですね。
h(x) = \frac{1}{1+e^{-x}}\\
function!s:add(x,y) abort
returnjoin(map(a:x,'v:val + a:y[v:key]'),'+')endfunctionfunction!s:scale(x,f) abort
return map(deepcopy(a:x),'v:val * a:f')endfunctionfunction!s:dot(x,y) abort
return eval(join(map(deepcopy(a:x),'v:val * a:y[v:key]'),'+'))endfunctionfunction!s:softmax(w,x) abort
letl:v=s:dot(a:w,a:x)return1.0 / (1.0+ exp(-l:v))endfunctionfunction!s:predict(w,x) abort
returns:softmax(a:w,a:x)endfunction
function!s:logistic_regression(X,y, rate, ntrains) abort
letl:w= map(repeat([[]], len(a:X[0])),'s:random()')letl:w=[0.1,0.2,0.3,0.4]letl:rate =a:rateforl:nin range(a:ntrains)forl:iin range(len(a:X))letl:x=a:X[l:i]letl:t= deepcopy(l:x)letl:pred =s:softmax(l:t,l:w)letl:perr =a:y[l:i]-l:pred
letl:scale =l:rate * l:perr * l:pred * (1.0-l:pred)calls:add(l:w,s:scale(l:x,l:scale))endforendforreturnl:wendfunction
l:perr * l:pred * (1.0 - l:pred)
の部分でオッズ比を得て学習率(l:rate
) からどの程度を次回の学習にデータを持ち越すかを決めます。なのでこの l:rate
が大きいと予測結果が安定しない事になります。これを以下の様に実行すると、入力データに対するパラメータ w
が得られます。
letl:w=s:logistic_regression(l:X,l:y,0.3,500)
乱数を使っているので常に同じ値にはなりません。
[-0.346271, -0.52895, 0.600594, 0.724118]
Intel Core i5、16GB の PC で4秒程度です。試しに入力データの1行目を使ってこの w
がどの様に働くかを確認します。
5.1,3.5,1.4,0.2,Iris-setosa
学習した内容と同じ事をすれば良いので w
とこのベクトルの内積の和から得られる値のゲイン(上の predict)を得れば良い事になります。以下の様に実行します。
:echo s:softmax([-0.346271,-0.52895,0.600594,0.724118],[5.1,3.5,1.4,0.2])
0.067129
これが上記で得た品種名の添え字(およそ 0 つまり iris-setosa
)になる訳です。以下の様にすれば元の品種名に戻せます。
letl:ni = map(sort(map(keys(l:vocab),'[v:val, float2nr(l:vocab[v:val])]'),{a,b->a[1]-b[1]}),'v:val[0]')forl:xinl:X
letl:r=s:predict(l:w,l:x)
echo l:ni[min([float2nr(l:r * len(l:vocab)+0.1), len(l:vocab)-1])]endfor
正解率を調べます。
letl:ni = map(sort(map(keys(l:vocab),'[v:val, float2nr(l:vocab[v:val])]'),{a,b->a[1]-b[1]}),'v:val[0]')letl:count =0forl:iin range(len(l:X))letl:x=l:X[l:i]letl:r=s:predict(l:w,l:x)ifl:ni[min([float2nr(l:r * len(l:vocab)+0.1), len(l:vocab)-1])]==l:data[l:i][4]letl:count +=1endifendfor
echo l:count
141と出たので、およそ 94% という所です。
学習データと検証データ
全てのデータを学習用に使ってしまうと「そりゃ正解率高いだろ」という結果になってしまうのでデータを学習用とテスト用に分けます。
function!s:shuffle(arr)letl:arr =a:arrletl:i= len(l:arr)whilel:iletl:i-=1letl:j=s:rand() * l:i % len(l:arr)ifl:i==l:j
continue
endiflet[l:arr[l:i],l:arr[l:j]]=[l:arr[l:j],l:arr[l:i]]endwhilereturnl:arr
endfunction
データをシャッフルして120件を学習に、残り30件をテストとなる様に分割します。
letl:data = map(readfile('iris.csv'),'s:token(v:val)')[1:]calls:shuffle(l:data)let[l:train,l:test]=[l:data[:119],l:data[119:]]
学習用の件数が減ったので学習率と学習回数も調整が必要です。
let l:w = s:logistic_regression(l:X, l:y, 0.1, 3000)
※要はまぁ、学習する為の入力データの1件1件をどれくらい大事にするかという話です。
0.967742
という、まぁまぁな正解率が得られました。
まとめ
Vim script で機械学習を扱いアヤメの品種を分類しました。Vim script は使えるけど Python をうまく扱えない人、宗教上の理由で Python が書けない人、色々いらっしゃるかと思います。Vim script なら分かるぞという方でもデータサイエンスが出来る事を伝えられたのではと思います。Vim script はエディタ上で動作するスクリプト言語です。実行しつつ編集したり、編集しつつ実行できる統合開発環境なのです。Vim script からデータサイエンスの世界に入ってみるのも良いかもしれません。
最後にソースコード全体を Gist に載せておきます。遊びたい方はどうぞ。
https://gist.github.com/mattn/920779ca764b777174958db0430964ae
Neovimのデフォルト設定
はじめに
Neovimでは、今までvimrcに当たり前のように書いていたオプションがデフォルトで設定されています。:h vim_diff.txt
の出だしに載っているものを紹介します。
機能
Syntax highlighting
デフォルトで有効。
:filetype plugin indent on
デフォルトで有効。
オプション
autoindent
改行時にインデントが保持される。
autoread
vimで開いているファイルが外部で変更されたときに自動で読み直す。
background
デフォルトでdark
。
backspace
デフォルトでindent,eol,start
。バックスペースの挙動をよくあるように。
backupdir
デフォルトは~/.local/share/nvim/backup
。'backup'
がオンの場合、ファイルを上書きする前にバックアップが作られる。
belloff
デフォルトでall
。全てのイベントでベルが鳴らない。
complete
vimのデフォルトである.,w,b,u,t,i
からi
を除いた.,w,b,u,t
がNeovimのデフォルト。
キーワード補完の対象から、インクルードされるファイルが除かれている。
残った対象はバッファとタグ。
cscopeverbose
デフォルトでオン。cscopeのデータベースに情報を追加するときメッセージが表示される。
cscopeはctagsのようなツール。
directory
デフォルトは~/.local/share/nvim/swap//
。スワップファイル用のディレクトリ。
display
デフォルトはlastline,msgsep
。
lastline | ウィンドウの最後の行ができるだけ多く表示される。謎。 |
msgsep | メッセージが'cmdheight' より長いとき、画面全体ではなくメッセージ行だけスクロールする。 |
encoding
デフォルトはUTF-8
。Neovim内部とRPC通信に使われるエンコーディング。
RPCはリモートプラグインで使われる。
fillchars
デフォルトはvert:│,fold:·
。垂直分割の区切り文字と畳込んだ所の文字。
formatoptions
デフォルトはtcqj
。自動整形の方法を決める。vimに対してj
が追加されている。
t | 'textwidth'を使ってテキストを自動折返しする |
c | 同上。コメントだったらコメント開始文字を自動挿入する |
q | gq でコメントを整形する |
j | 複数行のコメントを連結する際に、余計なコメント開始文字を消す |
fsync
デフォルトでオフ。vimではオンになっている。
オンになっていると:write
の後などにOSのfsync()が呼ばれ、メモリからストレージに書き込まれる。
Neovimの場合、CursorHold
イベントやNeovimが異常終了したときなどに書き込まれるためオフになっている。
history
デフォルトで10000。EXコマンドと検索パターンの履歴数。
hlsearch
デフォルトでオン。検索文字がハイライトされる。
incsearch
デフォルトでオン。インクリメンタルサーチ。
langnoremap
デフォルトでオン。Neovimではdeprecated。気にする必要なし。
langremap
デフォルトでオフ。'langmap'
を無効にする。'langmap'
は、キー入力をギリシャ語等の言語に切り替えることができるオプション。
laststatus
デフォルトで2。ステータスラインを常に表示。
listchars
デフォルトはtab:> ,trail:-,nbsp:+
。nbsp。nbspはnon-breakable spaceで0xA0やU+202F等。
モード時の表示文字で、
'list''list'
はタブ文字や行末を文字で表示するオプション。
compatible
デフォルトでオフ。vi互換を無くす。
vimはvimrcがあればオフになっていたが、Neovimでは常にオフ。
nrformats
デフォルトはbin,hex
。i_CTRL-A
,i_CTRL_X
を使うときの進数。
vimからoctal
が除かれており、0始まりを8進数とみなさない。
0x,0bから始まる数をそれぞれ16進数、2進数と認識する。
ruler
デフォルトでオン。カーソルの位置を表示する。
sessionoptions
vimに対して、"options"
が除かれている。:mksession
にオプションとマッピングが含まれない。
その場限りのオプションの変更やマッピングは保存しないということ。
shortmess
デフォルトは"F"
。Neovimの様々な表示を短くするオプション。"F"
はコマンドに対する:silent
のように、ファイル編集中にファイル情報を表示しない。
showcmd
デフォルトでオン。右下にコマンドが表示される。
sidescroll
デフォルトで1。水平スクロールの刻み幅。vimでは0。
smarttab
デフォルトでオン。'shiftwidth'
,'tabstop'
,'softtabstop'
,'expandtab'
をみてタブを快適に扱える。
tabpagemax
デフォルトで50。タブページの最大数。vimでは10。
tags
デフォルトは./tags;,tags
。tagコマンドで使うファイル名。
ttimeoutlen
デフォルトで50。キーコードの完了を待つ時間。ミリ秒。
vimとは違いマッピングとは関係がない。
ttyfast
常にオン。Neovimでは削除されている。
undodir
デフォルトは~/.local/share/nvim/undo
。アンドゥファイル用のディレクトリ。
viminfo
デフォルトで"!"
が含まれている。アルファベットの大文字で始まり、小文字を含まないグローバル変数を保存・復元する。
wildmenu
デフォルトでオン。コマンドライン補完で候補が表示される。
XVim2をinstallする
Pythonを使ってVimからQiitaへ投稿。
Pythonを使ってVimからQiitaへ投稿。
※この記事は個人的なメモです。
こんにちは。
最近とても興味深い記事を見つけて、Vimをもっと使ってやろうと意気込んで、作ってみたものです。1
Vimで書いた*.mdファイルを簡単に投稿したかったので最近ハマっているPyhtonを使ってみました。
既存のVimプラグインも探したらありそうなものですが、別に投稿と更新さえできればいいので、作った方が早いかもと思った次第です。
機能の多すぎるプラグイン入れて起動速度落ちるのが嫌なのが主な理由...
そして、この記事書き終わった後に素晴らしいプラグインを発見しました...笑↓
https://github.com/mattn/qiita-vim
NeoBandleをはじめとしたプラグインになるべく頼りたくない、素のVim使いたいとかいう人には参考になるかもです?
ちなみに、NeoBandleに比べて圧倒的に軽いvim-plugを普段から使っていますが、非常におすすめです。
ミニマリストの方は試してみると良いかもしれません。↓
https://github.com/junegunn/vim-plug
Qiita API
Qiita APIをPythonで叩くにはTokenを取得せねばなりません。
Token取得には「curl コマンドで Qiita API を試す方法」2がとても参考になりました!
Tokenが取得できたら
次は、Pythonから叩きます。
まずは、ディレクトリ構成を、
qiita-book --- qiita.py
|
-- content.md
とってもシンプルです。
また、同一ディレクトリに記事を貯めていく形です。
では、とりあえずqiita.pyをのぞいてみましょう。
importrequestsimportsysif__name__=="__main__":tags=[]print('please input title:')title=input()iftitle=="q":sys.exit()foriinrange(5):print('Do you have any other tags?:y,n')ans=input()ifans=="q":sys.exit()ifansin'y':print('please input tags. if you need any other tags, you can set next input: ')tagadd=input()tags.append(tagadd)else:breakprint('please input filepath:')filepath=input()f=open(filepath,"r")id=f.readline()ifidin"ID:":id=f.readline().replace('ID:','')else:id=''item={'title':title,"coediting":False,'tags':[{"name":tag}fortagintags],'private':True,'tweet':False,'id':id}item['body']=f.read()f.closeurl='https://qiita.com/api/v2/items'token=!YOURACTOKENheaders={'Authorization':'Bearer {}'.format(token),'Content-Type':'application/json',}print(item)print(headers)res=requests.post(url,headers=headers,json=item)result=res.json()['id']iook="ID:"+resultf.close()fw=open(filepath,"w")fw.write(iook)fw.close()fw1=open(filepath,"a")body="\n"+item['body']fw1.write(body)fw1.close
思い立って数時間で書いたクオリティーです、、、笑
今度時間がある時もう少し書き直したいと思います。
ちなみに、コードの解説をすると。
importrequestsimportsys
requestsでjsonをpostしています。
sysは終了処理のためにインポートしています。
if__name__=="__main__":
これはPythonのお決まりですね。
print('please input title:')title=input()iftitle=="q":sys.exit()
ここでは、記事のタイトルを決めてtitle変数にinputしています。
foriinrange(5):print('Do you have any other tags?:y,n')ans=input()ifans=="q":sys.exit()ifansin'y':print('please input tags. if you need any other tags, you can set next input: ')tagadd=input()tags.append(tagadd)else:break
上記処理は、Qiitaのタグをtags変数にinputしています。
ちなみに、タグは最大5つまでなので、Do you have any other tags?:y,n でNoと答えるまで繰り返して、配列に格納しています。
print('please input filepath:')filepath=input()f=open(filepath,"r")id=f.readline()ifidin"ID:":id=f.readline().replace('ID:','')else:id=''
これは、同一ディレクトリ内にあるfile名、あるいは、そのほかのディレクトリにあるファイルパスをfilepath変数にinputして、一行目を読み込んでいます。
ここで、なぜ一行目だけ読み込むのかというと、更新する際、すでに投稿した記事と紐づけるため、IDをファイルの先頭に置いておく仕様にしているからです。
これで、変更の際にも、そのまま更新できます。
あと、未実装なのですが、tagsも引き継げるような仕組みを時間がある時加えたいと思っています。
item={'title':title,"coediting":False,'tags':[{"name":tag}fortagintags],'private':True,'tweet':False,'id':id}
jsonの形にしています。
ここで、tagsを繰り返して最大5つまで格納できるようにしています。
item['body']=f.read()f.closeurl='https://qiita.com/api/v2/items'token=アクセストークンheaders={'Authorization':'Bearer {}'.format(token),'Content-Type':'application/json',}
tokenには取得したアクセストークンをそれぞれ使いましょう。
直書きはよくないので、工夫した方が良いと思います。
res=requests.post(url,headers=headers,json=item)result=res.json()['id']iook="ID:"+resultf.close()fw=open(filepath,"w")fw.write(iook)fw.close()fw1=open(filepath,"a")body="\n"+item['body']fw1.write(body)fw1.close
最後に、requestsでpostしましょう。
result変数には更新の際に必要になってくるidを代入しています。
そのidをファイルの先頭に持ってくるため、一旦idだけを上書きして、その後投稿後の記事を追加しています。
ここまでできたら、あとはプレビュー機能が欲しくなってきます。
プレビュー機能はvim-plugの力を借りて、以下のように.vimrcに素晴らしいプラグインを加えます。
"vimプラグイン https://github.com/junegunn/vim-plug
" Specify a directory for plugins
" - For Neovim: ~/.local/share/nvim/plugged
" - Avoid using standard Vim directory names like 'plugin'
call plug#begin('~/.vim/plugged')
Plug 'plasticboy/vim-markdown'
Plug 'kannokanno/previm'
Plug 'tyru/open-browser.vim'
call plug#end()""" markdown {{{
autocmd BufRead,BufNewFile *.mkd set filetype=markdown
autocmd BufRead,BufNewFile *.md set filetype=markdown
" Need: kannokanno/previm
nnoremap <silent> <C-p> :PrevimOpen<CR> "
let g:vim_markdown_folding_disabled=1
"}}}
ここではCtrl+Pでプレビューできるようにしています。
あとはPythonの実行です。
Vimにはコマンドモードで!をつけてあげる事によってshellscriptを実行したりできる機能があり、その機能を借りてpythonスクリプトを実行します。
:!python qiita.py
これでVimでQiitaを投稿できるようになりました。
色々と問題ありですが、ゆっくり更新していきたいなと思います。
最後にVimで記事を編集している様子をあげておきます。↓
Link.
「vimって極めればvscode並のIDEになるんじゃないの? - 最強のvimrcを晒す。」 https://qiita.com/ryuta69/items/98901f4c4f0683e7aa57?utm_source=Qiitaニュース&utm_campaign=d26eeec1b5-Qiita_newsletter_356_04_17_2019&utm_medium=email&utm_term=0_e44feaa081-d26eeec1b5-33219769 ↩
「curl コマンドで Qiita API を試す方法」https://qiita.com/itooww/items/ea6f197ef50bf8b252ce ↩
Pythonを使ってVimからQiitaへ投稿。
※この記事は個人的なメモです。
こんにちは。
最近とても興味深い記事を見つけて、Vimをもっと使ってやろうと意気込んで、作ってみたものです。1
Vimで書いた*.mdファイルを簡単に投稿したかったので最近ハマっているPyhtonを使ってみました。
既存のVimプラグインも探したらありそうなものですが、別に投稿と更新さえできればいいので、作った方が早いかもと思った次第です。
機能の多すぎるプラグイン入れて起動速度落ちるのが嫌なのが主な理由...
そして、この記事書き終わった後に素晴らしいプラグインを発見しました...笑↓
https://github.com/mattn/qiita-vim
NeoBandleをはじめとしたプラグインになるべく頼りたくない、素のVim使いたいとかいう人には参考になるかもです?
ちなみに、NeoBandleに比べて圧倒的に軽いvim-plugを普段から使っていますが、非常におすすめです。
ミニマリストの方は試してみると良いかもしれません。↓
https://github.com/junegunn/vim-plug
Qiita API
Qiita APIをPythonで叩くにはTokenを取得せねばなりません。
Token取得には「curl コマンドで Qiita API を試す方法」2がとても参考になりました!
Tokenが取得できたら
次は、Pythonから叩きます。
まずは、ディレクトリ構成を、
qiita-book --- qiita.py
|
-- content.md
とってもシンプルです。
また、同一ディレクトリに記事を貯めていく形です。
では、とりあえずqiita.pyをのぞいてみましょう。
importrequestsimportsysif__name__=="__main__":tags=[]print('please input title:')title=input()iftitle=="q":sys.exit()foriinrange(5):print('Do you have any other tags?:y,n')ans=input()ifans=="q":sys.exit()ifansin'y':print('please input tags. if you need any other tags, you can set next input: ')tagadd=input()tags.append(tagadd)else:breakprint('please input filepath:')filepath=input()f=open(filepath,"r")id=f.readline()ifidin"ID:":id=f.readline().replace('ID:','')else:id=''item={'title':title,"coediting":False,'tags':[{"name":tag}fortagintags],'private':True,'tweet':False,'id':id}item['body']=f.read()f.closeurl='https://qiita.com/api/v2/items'token=!YOURACTOKENheaders={'Authorization':'Bearer {}'.format(token),'Content-Type':'application/json',}print(item)print(headers)res=requests.post(url,headers=headers,json=item)result=res.json()['id']iook="ID:"+resultf.close()fw=open(filepath,"w")fw.write(iook)fw.close()fw1=open(filepath,"a")body="\n"+item['body']fw1.write(body)fw1.close
思い立って数時間で書いたクオリティーです、、、笑
今度時間がある時もう少し書き直したいと思います。
ちなみに、コードの解説をすると。
importrequestsimportsys
requestsでjsonをpostしています。
sysは終了処理のためにインポートしています。
if__name__=="__main__":
これはPythonのお決まりですね。
print('please input title:')title=input()iftitle=="q":sys.exit()
ここでは、記事のタイトルを決めてtitle変数にinputしています。
foriinrange(5):print('Do you have any other tags?:y,n')ans=input()ifans=="q":sys.exit()ifansin'y':print('please input tags. if you need any other tags, you can set next input: ')tagadd=input()tags.append(tagadd)else:break
上記処理は、Qiitaのタグをtags変数にinputしています。
ちなみに、タグは最大5つまでなので、Do you have any other tags?:y,n でNoと答えるまで繰り返して、配列に格納しています。
print('please input filepath:')filepath=input()f=open(filepath,"r")id=f.readline()ifidin"ID:":id=f.readline().replace('ID:','')else:id=''
これは、同一ディレクトリ内にあるfile名、あるいは、そのほかのディレクトリにあるファイルパスをfilepath変数にinputして、一行目を読み込んでいます。
ここで、なぜ一行目だけ読み込むのかというと、更新する際、すでに投稿した記事と紐づけるため、IDをファイルの先頭に置いておく仕様にしているからです。
これで、変更の際にも、そのまま更新できます。
あと、未実装なのですが、tagsも引き継げるような仕組みを時間がある時加えたいと思っています。
item={'title':title,"coediting":False,'tags':[{"name":tag}fortagintags],'private':True,'tweet':False,'id':id}
jsonの形にしています。
ここで、tagsを繰り返して最大5つまで格納できるようにしています。
item['body']=f.read()f.closeurl='https://qiita.com/api/v2/items'token=アクセストークンheaders={'Authorization':'Bearer {}'.format(token),'Content-Type':'application/json',}
tokenには取得したアクセストークンをそれぞれ使いましょう。
直書きはよくないので、工夫した方が良いと思います。
res=requests.post(url,headers=headers,json=item)result=res.json()['id']iook="ID:"+resultf.close()fw=open(filepath,"w")fw.write(iook)fw.close()fw1=open(filepath,"a")body="\n"+item['body']fw1.write(body)fw1.close
最後に、requestsでpostしましょう。
result変数には更新の際に必要になってくるidを代入しています。
そのidをファイルの先頭に持ってくるため、一旦idだけを上書きして、その後投稿後の記事を追加しています。
ここまでできたら、あとはプレビュー機能が欲しくなってきます。
プレビュー機能はvim-plugの力を借りて、以下のように.vimrcに素晴らしいプラグインを加えます。
"vimプラグイン https://github.com/junegunn/vim-plug
" Specify a directory for plugins
" - For Neovim: ~/.local/share/nvim/plugged
" - Avoid using standard Vim directory names like 'plugin'
call plug#begin('~/.vim/plugged')
Plug 'plasticboy/vim-markdown'
Plug 'kannokanno/previm'
Plug 'tyru/open-browser.vim'
call plug#end()""" markdown {{{
autocmd BufRead,BufNewFile *.mkd set filetype=markdown
autocmd BufRead,BufNewFile *.md set filetype=markdown
" Need: kannokanno/previm
nnoremap <silent> <C-p> :PrevimOpen<CR> "
let g:vim_markdown_folding_disabled=1
"}}}
ここではCtrl+Pでプレビューできるようにしています。
あとはPythonの実行です。
Vimにはコマンドモードで!をつけてあげる事によってshellscriptを実行したりできる機能があり、その機能を借りてpythonスクリプトを実行します。
:!python qiita.py
これでVimでQiitaを投稿できるようになりました。
色々と問題ありですが、ゆっくり更新していきたいなと思います。
最後にVimで記事を編集している様子をあげておきます。↓
Link.
「vimって極めればvscode並のIDEになるんじゃないの? - 最強のvimrcを晒す。」 https://qiita.com/ryuta69/items/98901f4c4f0683e7aa57?utm_source=Qiitaニュース&utm_campaign=d26eeec1b5-Qiita_newsletter_356_04_17_2019&utm_medium=email&utm_term=0_e44feaa081-d26eeec1b5-33219769 ↩
「curl コマンドで Qiita API を試す方法」https://qiita.com/itooww/items/ea6f197ef50bf8b252ce ↩
よく使われているvimrcの設定ランキング
背景
世の中のエンジニアのalias設定
こんな記事を書いたついでに、vimrcについても気になったので調べてみました。
せっかくなので、こちらは解説(主にvimdoc-jaの引用)付きで紹介していきます。
プラグイン版はこちら。
よく使われているvimのプラグイン top20
対象
- GitHub上のdotfilesトピックがついたリポジトリ
- スター数順に上位1000リポジトリ
- 対象ファイルは
*vimrc
とinit.vim
.vimrc
やnvimrc
、hoge.vimrc
等も含む
- 総ファイル数644ファイル
例によって、このリポジトリを使いました。
reireias/dotseeker
集計方法
- 対象のファイルをローカルにダウンロード
- 先頭の空白は除去
- 末尾のコメントと空白も除去
- 下記に合致するものは除外
if
,else
,endif
,function
,endfunction
等の制御構文autocmd!
(自動コマンドの除去、クリーンナップ的な用途なので)
コマンドは下記になります。
# ちょっと最初のgrepは非効率かもgrep-r-h-E"^" files --color=none --include="*vimrc" | sed-e's/^[ \t]*//g'-e's/[ \t]*$//g' | grep-v-E"^$" | grep-v-E"^\\\\"> rc.txt
grep-r-h-E"^" files --color=none --include="*init.vim" | sed-e's/^[ \t]*//g'-e's/[ \t]*$//g' | grep-v-E"^$" | grep-v-E"^\\\\"> init.txt
# 自作のフィルターで末尾のコメントを除去しているwc-l< *.txt | cat - *.txt | ./comment_remove.py | sed-e's/[ \t]*$//g' | grep-v-E"^(if|endif|endfunction|autogroup|else|autocmd\!|au\!|augroup|endfor)" | sort | uniq-c | sort-nr | head-n 30
設定を入れた際との比較用に何も設定していない場合の表示も置いておきます。
(ファイルはなんとなくでrubyのテキトーなサンプルです)
備考
vimのバージョンは下記です。(普段はneovimなので、vim8が手元にありませんでした)
VIM - Vi IMproved 7.4 (2013 Aug 10, compiled Nov 24 2016 16:44:48)
また、ターミナルアプリのカラーを少しいじっているので、シンタックスの色は読者の手元の環境と異なると思います。
登場数ランキング
1位 set number
(489回/644ファイル)
毎行の前に行番号を表示する。
やはり第1位はこれ!!!
そのまんまですね。行番号が表示されます。
vimはコマンドで行数を使ったりするので、必須ですね。
2位 set expandtab
(474回/644ファイル)
挿入モードで を挿入するとき、代わりに適切な数の空白を使う。
また、コマンド '>' や '<' によるインデントや、オプション 'autoindent' がオンのときのインデントでも空白を使う。
'expandtab' がオンのときに本当のタブを挿入するには、CTRL-V を使うこと。
タブキーで入力した際に、代わりにスペース2つとか4つを入力してくれる設定です。autocmd FileType
と組み合わせてファイルタイプごとに設定することが多いです。
例:goはタブ、jsはスペース2つ、pythonはスペース4つ等
3位 set hlsearch
(461回/644ファイル)
前回の検索パターンが存在するとき、それにマッチするテキストを全て強調表示する。
検索結果のハイライトです。
下記の画像は/def
で検索しています。
4位 set ignorecase
(458回/644ファイル)
検索パターンにおいて大文字と小文字を区別しない。
/hello
と検索すると、hello
にもHello
にもHELLO
にもヒットします。
5位 set incsearch
(457回/644ファイル)
検索コマンドを打ち込んでいる間にも、打ち込んだところまでのパターンがマッチするテキストを、すぐに表示する。
マッチした文字列は強調表示される。
いわゆるインクリメンタルサーチです。
下記画像は/d
まで入力した場合です。(エンターはまだ押していません)
6位 set smartcase
(412回/644ファイル)
検索パターンが大文字を含んでいたらオプション 'ignorecase' を上書きする。
小文字で検索した場合は、大文字小文字の違いは無視、大文字を含む文字列で検索した場合は無視しない、といった検索になります。
7位 set laststatus=2
(402回/644ファイル)
最下ウィンドウにいつステータス行が表示されるかを設定する。
0: 全く表示しない
1: ウィンドウの数が2以上のときのみ表示
2: 常に表示
画像のようにファイル名等の情報を表示するステータスバーが追加されます。
カスタマイズ次第ではこんなにいろいろ表示できます。
8位 set nocompatible
(399回/644ファイル)
VimをなるべくVi互換にするか、便利な機能を使えるようにするかを決定する。
これは、特別な種類のオプションである。
このオプションの値が変更されると、それに伴って他のオプションも変更されるからだ。
実はもうおまじないと化してる模様
set nocompatibleはもういらない
9位 syntax on
(372回/644ファイル)
次のコマンドで構文ハイライトが有効になる:
:syntax enableコマンド
:syntax enable
は現在の色設定を変更しない。
そのため、このコマンドを使用する前後にコマンド:highlight
で好みの色を設定することができる。
現在の設定を破棄して、デフォルトの色を設定させたい場合は次のコマンドを使用する:
:syntax on
シンタックスハイライトを有効にします。
シンタックスハイライトなしのエディタでコーディングする人とか、現代にいるのでしょうか?
10位 set autoindent
(363回/644ファイル)
新しい行を開始したとき (挿入モードで を打ち込むか、コマンド "o"や "O" を使ったとき)、新しい行のインデントを現在行と同じくする。
要は改行した時に、同じレベルのインデントにしてくれます。
タブでもスペースでもよきに計らってくれます。
これなしでコーディングはきついですね。
11位-20位
- 11位
filetype plugin indent on
(360回/644ファイル)
:filetype plugin on と :filetype indent on を行った状態になる。
ファイルタイプの自動検出、ファイルタイプ用の プラグインとインデント設定 を自動読み込みするようになる。
- 12位
set showcmd
(344回/644ファイル)
コマンド (の一部) を画面の最下行に表示する。
ノーマルモードで入力したコマンドが右下に表示されるようになります。
- 13位
set background=dark
(341回/644ファイル)
値が "dark" のときは、Vimは暗い背景によく合う色を使おうとする。
値が "light" のときは、Vimは明るい背景によく合う色を使おうとする。
その他の値は無効である。
- 14位
set wildmenu
(335回/644ファイル)
オンのとき、コマンドライン補完が拡張モードで行われる。
15位
call plug#end()
(329回/644ファイル)- 最も利用されているプラグイン管理はvim-plugのようです
plug#begin
がランクインしてないのは、引数にとるパスが各々異なるためでしょう- なお、パスを無視してgrepしたところ、
plug#begin
は363回、dein#begin
は26回の登場でした
16位
set hidden
(320回/644ファイル)
オフのときは、バッファは放棄 |abandon| されるときに解放される。
オンのときは、バッファは放棄 |abandon| されるときに隠れ (hidden) 状態になる。
そのバッファが別のウィンドウでまだ表示されているなら、もちろん隠れ状態にはならない。
- 17位
set backspace=indent,eol,start
(307回/644ファイル)
挿入モードでの
<BS>
,<Del>
,CTRL-W
,CTRL-U
の働きに影響する。
値はキーワードのコンマ区切りのリストである。
それぞれのキーワードがバックスペースの働く対象を定めている。
値 効果
indent autoindent を超えてバックスペースを働かせる
eol 改行を超えてバックスペースを働かせる (行を連結する)
start 挿入区間の始めでバックスペースを働かせるが CTRL-W と CTRL-U は挿入区間の始めでいったん止まる
- 18位
set ruler
(301回/644ファイル)
カーソルが何行目の何列目に置かれているかを表示する {訳注: これをルーラーと呼ぶ}。
- 19位
set showmatch
(294回/644ファイル)
閉じ括弧が入力されたとき、対応する開き括弧にわずかの間ジャンプする。
- 20位
set cursorline
(278回/644ファイル)
カーソルがある画面上の行をCursorLineで強調する。
カーソルを目立たせるのに便利。スクリーンの再描画が遅くなる。
ランキング全体
とりあえず上位50位と登場回数を下記に載せておきます。
あとでgistに全体を上げる予定です。
489 set number
474 set expandtab
461 set hlsearch
458 set ignorecase
457 set incsearch
412 set smartcase
402 set laststatus=2
399 set nocompatible
372 syntax on
363 set autoindent
360 filetype plugin indent on
344 set showcmd
341 set background=dark
335 set wildmenu
329 call plug#end()
320 set hidden
307 set backspace=indent,eol,start
301 set ruler
294 set showmatch
278 set cursorline
266 set mouse=a
254 set noswapfile
254 set encoding=utf-8
251 set shiftwidth=4
247 set autoread
244 set shiftwidth=2
238 set undofile
236 set tabstop=4
230 set nobackup
220 set splitright
218 set t_Co=256
215 set splitbelow
215 Plug 'tpope/vim-fugitive'
212 set tabstop=2
211 set list
211 Plug 'tpope/vim-surround'
206 set lazyredraw
204 syntax enable
203 set smarttab
191 set nowrap
190 set smartindent
188 set noshowmode
171 set title
171 set relativenumber
170 set ttyfast
165 Plug 'airblade/vim-gitgutter'
159 set showmode
153 set noerrorbells
151 set softtabstop=4
151 return
まとめ
春は新たなvimmerが多く誕生する季節ですね。
そんな方々の参考になれば幸いです。
Pythonを使ってVimからQiitaへ投稿。
※この記事は個人的なメモです。
こんにちは。
最近とても興味深い記事を見つけて、Vimをもっと使ってやろうと意気込んで、作ってみたものです。1
Vimで書いた*.mdファイルを簡単に投稿したかったので最近ハマっているPyhtonを使ってみました。
既存のVimプラグインも探したらありそうなものですが、別に投稿と更新さえできればいいので、作った方が早いかもと思った次第です。
機能の多すぎるプラグイン入れて起動速度落ちるのが嫌なのが主な理由...
NeoBandleをはじめとしたプラグインになるべく頼りたくない、素のVim使いたいとかいう人には参考になるかもです?
追記:
非常に完成度の高いvimプラグインがすでにありました↓
素晴らしいですね...
https://github.com/mattn/qiita-vim
普通にこれ使った方が良いです。
ちなみに、NeoBandleに比べて圧倒的に軽いvim-plugを普段から使っていますが、非常におすすめです。
ミニマリストの方は試してみると良いかもしれません。↓
https://github.com/junegunn/vim-plug
Qiita API
Qiita APIをPythonで叩くにはTokenを取得せねばなりません。
Token取得には「curl コマンドで Qiita API を試す方法」2がとても参考になりました!
Tokenが取得できたら
次は、Pythonから叩きます。
まずは、ディレクトリ構成を、
qiita-book --- qiita.py
|-- content.md
とってもシンプルです。
また、同一ディレクトリに記事を貯めていく形です。
では、とりあえずqiita.pyをのぞいてみましょう。
importrequestsimportsysif__name__=="__main__":tags=[]print('please input title:')title=input()iftitle=="q":sys.exit()foriinrange(5):print('Do you have any other tags?:y,n')ans=input()ifans=="q":sys.exit()ifansin'y':print('please input tags. if you need any other tags, you can set next input: ')tagadd=input()tags.append(tagadd)else:breakprint('please input filepath:')filepath=input()f=open(filepath,"r")id=f.readline()ifidin"ID:":id=f.readline().replace('ID:','')else:id=''item={'title':title,"coediting":False,'tags':[{"name":tag}fortagintags],'private':True,'tweet':False,'id':id}item['body']=f.read()f.closeurl='https://qiita.com/api/v2/items'token=!YOURACTOKENheaders={'Authorization':'Bearer {}'.format(token),'Content-Type':'application/json',}print(item)print(headers)res=requests.post(url,headers=headers,json=item)result=res.json()['id']iook="ID:"+resultf.close()fw=open(filepath,"w")fw.write(iook)fw.close()fw1=open(filepath,"a")body="\n"+item['body']fw1.write(body)fw1.close
思い立って数時間で書いたクオリティーです...笑
今度時間がある時もう少し書き直したいと思います。
ちなみに、コードの解説をすると。
importrequestsimportsys
requestsでjsonをpostしています。
sysは終了処理のためにインポートしています。
if__name__=="__main__":
これはPythonのお決まりですね。
print('please input title:')title=input()iftitle=="q":sys.exit()
ここでは、記事のタイトルを決めてtitle変数にinputしています。
foriinrange(5):print('Do you have any other tags?:y,n')ans=input()ifans=="q":sys.exit()ifansin'y':print('please input tags. if you need any other tags, you can set next input: ')tagadd=input()tags.append(tagadd)else:break
上記処理は、Qiitaのタグをtags変数にinputしています。
ちなみに、タグは最大5つまでなので、Do you have any other tags?:y,n でNoと答えるまで繰り返して、配列に格納しています。
print('please input filepath:')filepath=input()f=open(filepath,"r")id=f.readline()ifidin"ID:":id=f.readline().replace('ID:','')else:id=''
これは、同一ディレクトリ内にあるfile名、あるいは、そのほかのディレクトリにあるファイルパスをfilepath変数にinputして、一行目を読み込んでいます。
ここで、なぜ一行目だけ読み込むのかというと、更新する際、すでに投稿した記事と紐づけるため、IDをファイルの先頭に置いておく仕様にしているからです。
これで、変更の際にも、そのまま更新できます。
あと、未実装なのですが、tagsも引き継げるような仕組みを時間がある時加えたいと思っています。
item={'title':title,"coediting":False,'tags':[{"name":tag}fortagintags],'private':True,'tweet':False,'id':id}
jsonの形にしています。
ここで、tagsを繰り返して最大5つまで格納できるようにしています。
item['body']=f.read()f.closeurl='https://qiita.com/api/v2/items'token=アクセストークンheaders={'Authorization':'Bearer {}'.format(token),'Content-Type':'application/json',}
tokenには取得したアクセストークンをそれぞれ使いましょう。
直書きはよくないので、工夫した方が良いと思います。
res=requests.post(url,headers=headers,json=item)result=res.json()['id']iook="ID:"+resultf.close()fw=open(filepath,"w")fw.write(iook)fw.close()fw1=open(filepath,"a")body="\n"+item['body']fw1.write(body)fw1.close
最後に、requestsでpostしましょう。
result変数には更新の際に必要になってくるidを代入しています。
そのidをファイルの先頭に持ってくるため、一旦idだけを上書きして、その後投稿後の記事を追加しています。
ここまでできたら、あとはプレビュー機能が欲しくなってきます。
プレビュー機能はvim-plugの力を借りて、以下のように.vimrcに素晴らしいプラグインを加えます。
"vimプラグイン https://github.com/junegunn/vim-plug
" Specify a directory for plugins
" - For Neovim: ~/.local/share/nvim/plugged
" - Avoid using standard Vim directory names like 'plugin'
call plug#begin('~/.vim/plugged')
Plug 'plasticboy/vim-markdown'
Plug 'kannokanno/previm'
Plug 'tyru/open-browser.vim'
call plug#end()""" markdown {{{
autocmd BufRead,BufNewFile *.mkd set filetype=markdown
autocmd BufRead,BufNewFile *.md set filetype=markdown
" Need: kannokanno/previm
nnoremap <silent> <C-p> :PrevimOpen<CR> "
let g:vim_markdown_folding_disabled=1
"}}}
ここではCtrl+Pでプレビューできるようにしています。
あとはPythonの実行です。
Vimにはコマンドモードで!をつけてあげる事によってshellscriptを実行したりできる機能があり、その機能を借りてpythonスクリプトを実行します。
:!python qiita.py
これでVimでQiitaを投稿できるようになりました。
色々と問題ありですが、ゆっくり更新していきたいなと思います。
最後にVimで記事を編集している様子をあげておきます。↓
参考.
「vimって極めればvscode並のIDEになるんじゃないの? - 最強のvimrcを晒す。」 https://qiita.com/ryuta69/items/98901f4c4f0683e7aa57?utm_source=Qiitaニュース&utm_campaign=d26eeec1b5-Qiita_newsletter_356_04_17_2019&utm_medium=email&utm_term=0_e44feaa081-d26eeec1b5-33219769 ↩
「curl コマンドで Qiita API を試す方法」https://qiita.com/itooww/items/ea6f197ef50bf8b252ce ↩
【Vim】必要な時だけカーソル行をハイライトする
Vim には 'cursorline'
という機能があります。これは名前の通り、カーソルのある行を強調し、目立たせてくれるものです。
便利な機能なのですが、常時有効にしていると以下のような問題がありました。
- 有効のまま画面をスクロールすると動作が重い。
- (カラースキームによっては)文字が背景と同化して見づらい。
そもそもこれはカーソルの位置を見失わないようにするための機能ですから、必要な時だけ有効になってくれると便利です。具体的には、以下のように切り替わって欲しいです。
- カーソルを動かすと無効にする。
- ウィンドウを開いたり、移動したりした時に有効にする。
- しばらくカーソルが止まっている時も有効にする。
……と、ここまでは以下のエントリーに書いてあることの要約です。
エントリー内のスクリプトでまさにこれが実現できるのですが、後述の理由により一つのプラグインとしてまとめました。
インストール方法などは README を読んでみてください。以下は、どうしてこのプラグインを作ったのかについて書いています。
CursorHold
イベントの功罪
従来の Vim では、他の言語にはよくある「タイマー機能」というものがありませんでした。例えば JavaScript の setTimeout()
のような、「一定時間が経ったら〇〇を実行する」ということができなかったのです。
その不便をある程度解消するために使われていたのが CursorHold
イベントです。
これはカーソルを移動させた後、'updatetime'
に指定した時間が過ぎた時に発動するイベントです。おそらくユーザーはカーソルを留めて何か考え中のはずですから、多少重たい動作をさせても構わないだろう、というわけです。このため、なるべくユーザーの操作をブロックしたくないプラグインは、みんなこの CursorHold
イベントで関数を呼び出していました。
ただこの 'updatetime'
の値は、Vim 全体で一つしか設定できません。例えば vim-gitgutterのようなプラグインではこの値を小さく(100ms)設定することが推奨されています。
しかし今回の要件のためには 100ms という時間は短すぎます。上述の thinca 氏のエントリー内のスクリプトでは CursorHold
を使っているのですが、vim-gitgutter のために、頻繁に cursorline が on/off されるのが悩みのタネでした。
CursorHold
の代わりにタイマー機能を使う
Vim8.0 ではまさにこのために、タイマー機能が実装されました。
使い方は簡単で、timer_start()
の引数に時間と関数を指定するだけです。
function! EchoHoge(timer_id) abort
echo 'hoge'endfunction" 1秒後に hoge と表示するlet timer_id = timer_start(1000,'EchoHoge')" 関数リファレンスも使えるlet timer_id = timer_start(1000,function('EchoHoge'))" Lambda も OKlet timer_id = timer_start(1000,{-> execute('echo "hoge"','')})
今回はこれを使って、以下のような処理を実装しています。
autocmd CursorMoved,CursorMovedI * calls:cursor_moved()function!s:cursor_moved() abort
" cursorline を消すsetlocal nocursorline
" すでに起動しているタイマーを止めるcall timer_stop(s:timer_id)" 新しいタイマーを起動lets:timer_id= timer_start(1000,function('s:enable_cursorline'))endfunctionfunction!s:enable_cursorline(timer_id) abort
setlocal cursorline
endfunction
基本的にはこれだけです。ただ、このままだとカーソルを動かすたびに setlocal nocursorline
していて無駄ですし、他にもいろんなエッジケースがあったのでもう少し複雑なことをやっています。詳しくはソースを読んでみてください。
まとめ
これからは CursorHold
じゃなくてタイマー機能を使おうぜ!という話でした。
自分のVim環境を整理してみる(個人的な見解です)
私のvimrcを公開してみる。
※個人的な見解ですのでご注意ください。
こんにちは、
最近真面目にVimを使い出したので、一度自分の中のVimについて整理したいと思い、この記事を書き始めました。
私は、たいして使いこなしてませんが、かれこれVimと付き合って6、7年目でしょうか。
私とVimとの出会いは衝撃的で、初めて手にした、故障したPCを祖父から譲ってもらったのがきっかけ。あの頃は若かった。
苦労して動かす方法を探して、そんな中、Linuxに出会う。
CUIぐらいしかまともに動かせないスペックだったのでとりあえず何か書こうとViに出会い困惑し、その後Vimに出会いました。
Viを使えばファイルが扱えるという当時右も左もわからない初心者がViなど使えるわけもなく。
そのような状況下で、Vimの存在を知ってようやくまともにファイル編集ができた感動が今でも忘れられません。
そのボロボロのPCを頑張って2年ほど使ったのちにMacBookAirを買った。
GUIの素晴らしさを体感したと同時にVimとしばらくお別れしました笑
sublime textというエディターに出会ってしまったのです。
でも、時を重ね、だんだんとSSHでの作業が多くなってゆき、再びVimに戻ってきました。
そんな私は、いくつかVimプラグインを使ってきました。
Vimプラグインに出会った時は本当に感動しましたが、プラグインを導入しすぎて、Vimの起動が非常に重くなってしまった時は絶望でした。笑
NeoBandleにはお世話になりましたが、最近ではすっかりvim-plugに移行してしまいましたね。
また、論文を書くときもVimを使うようになりました。
LaTexとの出会いです。
それまでの私は、Microsoft OfficeのWordにお世話になりまくってましたが、結局Vimに還っていくのだなと、改めてVimが自分とコンピュータとの原点だなと感じました。
そして、最近実現したのですが、このQiitaの記事もVimで書く事になるとは夢にも思っていませんでしたね。
とりあえず、vimrcをあげてみたいと思います。↓
" TeX Setting Start.
filetype plugin on
let tex_flavor = 'latex'
set grepprg=grep\ -nH\ $*
set shellslash
let g:Tex_DefaultTargetFormat = 'pdf'
let g:Tex_ViewRule_pdf = 'open -a Skim.app'
let g:Tex_CompileRule_dvi = 'platex --interaction=nonstopmode $*'
let g:Tex_CompileRule_pdf = 'dvipdfmx $*.dvi'
let g:Tex_FormatDependency_pdf = 'dvi,pdf'
let g:latex_fold_enabled = 0
" TeX Setting Fin.
"vim-plug Start. https://github.com/junegunn/vim-plug
" Specify a directory for plugins
" - For Neovim: ~/.local/share/nvim/plugged
" - Avoid using standard Vim directory names like 'plugin'
call plug#begin('~/.vim/plugged')" Make sure you use single quotes
" vimtex https://github.com/lervag/vimtex
Plug 'lervag/vimtex'" ruby https://vimawesome.com/plugin/vim-ruby
Plug 'vim-ruby/vim-ruby'
" python https://vimawesome.com/plugin/python-mode
Plug 'klen/python-mode'" post web.
Plug 'plasticboy/vim-markdown'
Plug 'kannokanno/previm'
Plug 'tyru/open-browser.vim'
Plug 'mattn/qiita-vim'
Plug 'mattn/webapi-vim'
call plug#end()
" vim-plug Fin.
" colorscheme murphy
" NERDTree Start.
autocmd StdinReadPre *let s:std_in=1
autocmd VimEnter *if argc()== 0 &&!exists("s:std_in") | NERDTree | endif
map <S-e> :NERDTreeToggle<CR>
let g:NERDTreeDirArrows = 1
let g:NERDTreeDirArrowExpandable ='▶'let g:NERDTreeDirArrowCollapsible ='▼'" NERDTree Fin.
" esc
noremap <C-f> <esc>
noremap! <C-f> <esc>
" clipboard enable
set clipboard+=unnamed
""" markdown {{{
autocmd BufRead,BufNewFile *.mkd set filetype=markdown
autocmd BufRead,BufNewFile *.md set filetype=markdown
" Need: kannokanno/previm
nnoremap <silent> <C-p> :PrevimOpen<CR> " Ctrl-p Preview.
let g:vim_markdown_folding_disabled=1
" }}}
これが今の私の最適解です。
起動処理は遅すぎず、最低限の機能を保つvimrcです。
今日はここまで、また、時間ができたとき詳しく解説していきたいと思います。
Vimにプロジェクトツリーを追加する。(mac)
vimってプロジェクトツリーを見ることできないのかなーと思って調べていたんですが、できるみたいなので早速導入。
今回はNERDTreeというプラグインを使用しました。
基本的にはこちらの方の記事を参考にさせて頂きました。
https://qiita.com/zwirky/items/0209579a635b4f9c95ee
1, NEOBUNDLEのインストール
$ curl https://raw.githubusercontent.com/Shougo/neobundle.vim/master/bin/install.sh | sh
2, ~/.vimrcに以下を記述。
set nocompatible
filetype off
if has('vim_starting')
set runtimepath+=~/.vim/bundle/neobundle.vim
call neobundle#rc(expand('~/.vim/bundle/'))
endif
"insert here your Neobundle plugins"
NeoBundle 'scrooloose/nerdtree'
filetype plugin indent on
3, バンドルインストール
:NeoBundleInstall
ここまでやっていけると思ったんですが、vimを開こうと思ったら以下のようなメッセージが表示されました。
[neobundle] neobundle#rc() is removed function.
[neobundle] Please use neobundle#begin()/neobundle#end() instead.
[neobundle] neobundle directory is empty.
[neobundle] `NeoBundle` commands must be executed within a neobundle#begin/end block. Please check your usage.
要は
「neobundle#rc()って書き方は止めたから、代わりに#begin()/neobundle#end()って書き方でやってくれよ。あと、NeoBundleコマンドはその中に記述してね」
ってことらしい。
なので、2の記述を以下に変更
set nocompatible
filetype off
if has('vim_starting')
set runtimepath+=~/.vim/bundle/neobundle.vim
call neobundle#begin(expand('~/.vim/bundle/'))
NeoBundle 'scrooloose/nerdtree'
call neobundle#end()
endif
filetype plugin indent on
これで再度vimを開き、:NERDTreeToggleと入力したら表示されるようになりました。
vimでカレントファイルパスを素早くヤンクしたい
<C-g>
で表示はすぐできるのに、ヤンクはすぐできないもどかしさを解消したかった。
function! ClipText(data)let @0=a:datalet @"=a:datalet @*=a:dataendfunction
nnoremap <C-g>:call ClipText(expand('%'))<CR><C-g>
エンジニア目指したい新入生のみんなにオススメのエディタ
はじめに
エンジニア志望の新入生のみんな!入学おめでとう!
やっぴー(@yanashi_masa)です。
詳細なプロフィールはこちら↓
https://scrapbox.io/yanashi/%E3%82%84%E3%81%A3%E3%81%B4%E3%83%BC%E3%81%AB%E3%81%A4%E3%81%84%E3%81%A6
今日はエンジニアを目指して、色々な学校に入学した新入生のみんなにオススメのエディタを教えてあげるぞ!
※当記事は、あくまでも、弊学をベースに話しています。各々の事情で他エディタを使う場合は、以下スルーしても構いません。
本題
さて、1年生は様々なエディタを使うかもしれないが、僕は、このエディタをオススメしたい。
それは、
Vimだ!異論は認めぬ。
インストール
- Windowsの場合
詳しくはこちらを参照してほしい→https://qiita.com/go12lim/items/0644f262cff619934e10
- MacOSの場合
Macの場合、もっともお手軽なのが、Homebrewを使ってインストールする事だ。
このHomebrewは、かなり重宝するので入れたほうがいい。
まずは、AppStoreからXcodeをインストールする。
次に、Homebrewのインストールコマンドをここからコピー。
そして、ターミナルを開いて、コピーしたコマンドをペーストして実行する。
$ /usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"
これで、Homebrewのインストールが完了した。
続いて、以下のコマンドを実行。
$ brew doctor
$ brew update
これで、準備が整った。
さぁ、Vimをインストールしてみよう。
以下のコマンドを実行してみよう。
$ brew install vim
これで、Vimのインストールは完了した。
では、Vimを立ち上げてみよう。以下のコマンドを実行。
$ vim
問題がなければ、Vimが立ち上がるはずだ。
もっとも多く使う超重要キーコマンド
とりあえず、めちゃくちゃ使う超基本的コマンドを記載しておく。(異論が出るのはわかるが、ちょっとそこのVimmer黙ってて。)
i
: 編集モード。これで、ファイルの編集が出来る。v
: ビジュアルモード。ファイルの文字をコピー&ペーストしたり出来る。Esc
: ノーマルモードに戻る。
ノーマルモードでのキーコマンド
:q
: vimを終了。:w
: 編集したファイルを保存。:wq
: 編集したファイルを保存し、Vimを終了させる。ビジュアルモードでのキーコマンド
yy
: 選択した文字列をコピー。p
: コピーした文をペースト。d
: 選択した文を削除。
とりあえず、これだけ覚えれば、Vimはある程度扱える。
どうしても使えそうにない人たちへの救済措置
最悪、上記のコマンドが使えそうになかったら、
Visual Studio Codeをインストールして、Vimプラグインを実装する事だ。
しばらくは、それで慣れておいた方がいいかも。
【上級者向け】vimrcを作成して、魔改造
vimrcとは、Vimの設定ファイルである。
このファイルを作成する事で、Vimを自分流に改造することができる。
- Windowsの場合
↓Windowsの場合、この記事を参照した方がいいかもしれない↓
https://vim.jp.net/setup_windows_setting.html
- MacOSの場合(以下、Macで説明)
vimrcの作成方法は、以下のコマンドを実行すれば良い。
touch ~/.vimrc
後は、以下のコマンドでVimを立ち上げて編集する。
vim ~/.vimrc
とりあえず、以下のように記入して、保存してみよう。
vnoremap <C-c> yy
vnoremap <C-p> p
ノーマルモードで保存&終了する。
:wq
もう一度、Vimを立ち上げると、vimrcの設定が反映される。
ちなみに、上記の設定で以下のように変更した。Ctrl + c
: 選択した文字列をコピー。Ctrl + p
: コピーした文字列をペースト。
詳しいことは、以下の記事を参照してほしい。
・mapとnoremapの違いについて
https://cocopon.me/blog/2013/10/vim-map-noremap/
・キーマッピングで使う表記一覧
http://kannokanno.hatenablog.com/entry/2013/05/05/130219
Vimを好きになってほしい
最後に。
僕としては、Vimを好きになってほしい。
もう他のエディタなんていらないぜ!という状態にしてほしい。
ちなみに、僕は用途によって、Visual Studio Codeと併用している。
え?Visual Studio Code最強だって?気持ちはわかるが、
魔改造して、自分流のエディタにする楽しみは、純粋なVimでしか味わえないよ...
是非、試してほしい。
エンジニア目指したい新入生のみんなにオススメのエディタ
はじめに
エンジニア志望の新入生のみんな!入学おめでとう!
やっぴー(@yanashi_masa)です。
詳細なプロフィールはこちら↓
https://scrapbox.io/yanashi/%E3%82%84%E3%81%A3%E3%81%B4%E3%83%BC%E3%81%AB%E3%81%A4%E3%81%84%E3%81%A6
今日はエンジニアを目指して、色々な学校に入学した新入生のみんなにオススメのエディタを教えてあげるぞ!
※当記事は、あくまでも、弊学をベースに話しています。各々の事情で他エディタを使う場合は、以下スルーしても構いません。
本題
さて、1年生は様々なエディタを使うかもしれないが、僕は、このエディタをオススメしたい。
それは、
Vimだ!異論は認めぬ。
インストール
- Windowsの場合
詳しくはこちらを参照してほしい→https://qiita.com/go12lim/items/0644f262cff619934e10
- MacOSの場合
Macの場合、もっともお手軽なのが、Homebrewを使ってインストールする事だ。
このHomebrewは、かなり重宝するので入れたほうがいい。
まずは、AppStoreからXcodeをインストールする。
次に、Homebrewのインストールコマンドをここからコピー。
そして、ターミナルを開いて、コピーしたコマンドをペーストして実行する。
$ /usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"
これで、Homebrewのインストールが完了した。
続いて、以下のコマンドを実行。
$ brew doctor
$ brew update
これで、準備が整った。
さぁ、Vimをインストールしてみよう。
以下のコマンドを実行してみよう。
$ brew install vim
これで、Vimのインストールは完了した。
では、Vimを立ち上げてみよう。以下のコマンドを実行。
$ vim
問題がなければ、Vimが立ち上がるはずだ。
もっとも多く使う超重要キーコマンド
とりあえず、めちゃくちゃ使う超基本的コマンドを記載しておく。(異論が出るのはわかるが、ちょっとそこのVimmer黙ってて。)
i
: 編集モード。これで、ファイルの編集が出来る。v
: ビジュアルモード。ファイルの文字をコピー&ペーストしたり出来る。Esc
: ノーマルモードに戻る。
ノーマルモードでのキーコマンド
:q
: vimを終了。:q!
: vimを強制終了。:w
: 編集したファイルを保存。:wq
: 編集したファイルを保存し、Vimを終了させる。ビジュアルモードでのキーコマンド
yy
: 選択した文字列をコピー。p
: コピーした文をペースト。d
: 選択した文を削除。
とりあえず、これだけ覚えれば、Vimはある程度扱える。
どうしても使えそうにない人たちへの救済措置
最悪、上記のコマンドが使えそうになかったら、
Visual Studio Codeをインストールして、Vimプラグインを実装する事だ。
しばらくは、それで慣れておいた方がいいかも。
【上級者向け】vimrcを作成して、魔改造
vimrcとは、Vimの設定ファイルである。
このファイルを作成する事で、Vimを自分流に改造することができる。
- Windowsの場合
↓Windowsの場合、この記事を参照した方がいいかもしれない↓
https://vim.jp.net/setup_windows_setting.html
- MacOSの場合(以下、Macで説明)
vimrcの作成方法は、以下のコマンドを実行すれば良い。
touch ~/.vimrc
後は、以下のコマンドでVimを立ち上げて編集する。
vim ~/.vimrc
とりあえず、以下のように記入して、保存してみよう。
vnoremap <C-c> yy
vnoremap <C-p> p
ノーマルモードで保存&終了する。
:wq
もう一度、Vimを立ち上げると、vimrcの設定が反映される。
ちなみに、上記の設定で以下のように変更した。Ctrl + c
: 選択した文字列をコピー。Ctrl + p
: コピーした文字列をペースト。
詳しいことは、以下の記事を参照してほしい。
・mapとnoremapの違いについて
https://cocopon.me/blog/2013/10/vim-map-noremap/
・キーマッピングで使う表記一覧
http://kannokanno.hatenablog.com/entry/2013/05/05/130219
Vimを好きになってほしい
最後に。
僕としては、Vimを好きになってほしい。
もう他のエディタなんていらないぜ!という状態にしてほしい。
ちなみに、僕は用途によって、Visual Studio Codeと併用している。
え?Visual Studio Code最強だって?気持ちはわかるが、
魔改造して、自分流のエディタにする楽しみは、純粋なVimでしか味わえないよ...
是非、試してほしい。
.vimrc晒す。
僕の.vimrc晒します。
参考までに。
NERDTreeというプラグインが必要なので、
以下のコマンドでインストールしてから、以下のvimrcを導入してください。
git clone https://github.com/scrooloose/nerdtree.git ~/.vim/bundle/nerdtree
.vimrc晒す。
syntax onset mouse=aset ttymouse=xterm2
autocmd QuickFixCmdPost *grep* cwindowcolorscheme molokai
letg:molokai_original=1letg:rehash256=1set background=dark
execute pathogen#infect()let NERDTreeShowHidden =1
map n:NERDTreeToggle<CR>
map rn :NERDTreeToggle<CR>r
tnoremap <C-x><C-w><C-w>
tnoremap <C-e><C-w>N
nnoremap <C-a><C-w><C-w>
tnoremap <C-z><C-w><C-c>
nnoremap w:w<kenter>
nnoremap qa:qa<kenter>
nnoremap cs:close<kenter>
nnoremap <C-t>:terminal<kenter>
inoremap <C-t><esc>:terminal<kenter>
nnoremap z :tabNext<kenter>
nnoremap x:tabnext<kenter>
nnoremap t:tabnew<kenter>
nnoremap co:compiler
nnoremap ma:make<kenter>
vnoremap <C-c> yy<esc>i
vnoremap <C-x> dd<esc>i
vnoremap <Backspace>di
inoremap <C-p><esc>vpi
nnoremap <C-b>:vs<kenter>
nnoremap +<C-w>>
nnoremap -<C-w><set backspace=indent,eol,startset splitbelow
set termwinsize=15x0
setnumberset title
set tabstop=2set expandtab
set virtualedit=block
set list
set listchars=tab:»-,trail:-,eol:↲,extends:»,precedes:«,nbsp:%
set smartindent
set shiftwidth=2set ambiwidth=double
setnoswapfileset whichwrap=b,s,[,],<,>set showmatch
set laststatus=2set wildmode=list:longest
set visualbell
set incsearch
function!s:open(args) abort
if empty(term_list())
execute "terminal"a:argselselet bufnr = term_list()[0]
execute term_getsize(bufnr)[0]."new"
execute "buffer + " bufnr
endifendfunction
command!-nargs=*
\ Terminal calls:open(<q-args>)
VSCodeで始めるVim
※本記事で言う「Vim」とは「Vimキーマップ」のことです。
Vim、使ってますか?
Vimって使ったことのない人からすると何がいいのかよくわからないですよね。特に「移動はhjklで行う」あたりが最高に意味不明でした。
私もつい最近まではなんで皆vimにこだわるんだと思っていた口です。別に無くてもいいじゃないかと。
しかし、物は試しということで1週間ほど使ってみたら……びっくりするほど手に馴染みました。
まだ2か月程度しかVimを使っていない小学生ですが、それでも以前と変わらない速度で編集できています。また、マウスやカーソルキーに手を伸ばす機会が減り、他のマウス必須な操作をキーボードで行えるようにカスタマイズするきっかけにもなりました。
そんなわけでVimが思ったより良かったこと、そしてVim入門にはVSCodeが向いているんじゃないかと感じたことから、何番煎じかわからないですがこの記事を書いています。
Vimプラグインの導入
まずはVimのプラグインを導入しましょう。これが無ければ始まりません。
プラグインが導入できたら、何も言わずにsettings.json
を開いて以下の項目を追加してください。
"vim.insertModeKeyBindings":["before":["j","j"],"after":["<Esc>"]}],"vim.hlsearch":true
個人的に上記2つの設定は必須だと思っています。特にjj
。
Vimの基本
モード
Vimにはモード
と呼ばれる概念があります。とりあえず下記の4つがあるということだけ覚えておいてください。
- 通常モード
- 挿入モード
- ビジュアルモード
- コマンドモード
基本のキ
ごく基本的な操作からです。
カーソル移動の基本
コマンド | 説明 |
---|---|
h | 左にカーソル移動 |
j | 下にカーソル移動 |
k | 上にカーソル移動 |
l | 右にカーソル移動 |
出ました。Vimをキモいと言わしめる最初にして最大の難関。
ですがこれ、最初は無理に覚えなくていいです。カーソルキーに慣れている人は最初はカーソルキーぽちぽちの方が早いでしょうし。
なぜ覚えなくていいかというと、すぐ覚えたくなるからです。Vimは移動系のキーマップが頭おかしくなるくらい存在するので、ホームポジションからほとんど手を動かさずにあっちこっちへ移動できます。Vimの移動に慣れ始めるとすぐにカーソルキーなんて遠いものを使うのが馬鹿馬鹿しくなります。いやホントに。
挿入モードの基本
コマンド | 説明 |
---|---|
i | カーソルの左から挿入モードへ |
a | カーソルの右から挿入モードへ |
I | 行の先頭から挿入モードへ |
A | 行の終端から挿入モードへ |
Esc | 通常モードへ戻る |
Ctrl-c | 通常モードへ戻る |
挿入モードは普段見慣れたテキスト編集だと思ってください。通常モードではカーソルは常に文字を選択しているため、右か左かを選ぶ必要があります。最初はi
とa
の使い分けが厄介ですが慣れましょう。
Vimはモードがわかりにくいとよく聞きます。VScodeのプラグインでは画面下部にモードが表示されているので、困ったら画面下を見ればいいのですが、それでもよくわからなければEsc
連打で通常モードへ戻れます。
挿入モードから通常モードにもどるにはEsc
かCtrl-c
をコマンドする、若干押しにくいです。嫌ですね。
でも大丈夫、この記事通りに進んでいるならjj
で挿入モードから通常モードに戻れます。settings.json
でキーバインドを追加しましたから。
通常モードで移動、編集したい場所にたどり着いたら挿入モードへ、編集が終わったら通常モードへ、という流れがVimの基本のようなので慣れていきましょう。
編集の基本
コマンド | 説明 |
---|---|
u | アンドゥ |
Ctrl-r | リドゥ |
x | 一文字削除 |
dd | 一行削除 |
yy | 一行コピー |
p | カーソルの右に貼り付け |
P | カーソル行を改行して貼り付け |
アンドゥとリドゥが無ければ生きていけない。dd
とyy
はよく使います。なお、ここでコピーしたものはクリップボードではなくレジスタに登録されます。加えて、削除したものはすべてレジスタに登録されるので、一行コピー → 一行削除 → 貼り付け のように操作すると、削除した行が挿入されるので注意してください。
なお、VimではCtrl-c
もCtrl-v
もキーバインドされているので、コピーペーストがしたければCtrl-Insert
、Shift-Insert
の利用をお勧めします。
コマンドの基本
コマンド | 説明 |
---|---|
:q | ファイルを閉じる |
:q! | 保存せずに閉じる |
:w | 上書き |
:w! | 強制的に上書き |
:wq | 上書きして閉じる |
:wq! | 強制的に上書きして閉じる |
頭に:
を付けるとコマンドモードになります。抜けたいときは挿入モードと同じくEsc
、もしくはCtrl-c
ですね。jj
は登録していないので使えません。!
を付けると問答無用で実行します。
基本のホ
これまでのコマンドだけでは「ただ面倒になっただけじゃねーか!」と言われそうですね。ですが、面白いコマンドはこれからですよ。
横移動いろいろ
コマンド | 説明 |
---|---|
w | 次の単語の頭へジャンプ |
e | 次の単語の末尾へジャンプ |
b | 前の単語の頭へジャンプ |
ge | 前の単語の末尾へジャンプ |
W | 記号を無視して次の単語の頭へジャンプ |
E | 記号を無視して次の単語の末尾へジャンプ |
B | 記号を無視して前の単語の頭へジャンプ |
gE | 記号を無視して前の単語の末尾へジャンプ |
単語ジャンプです。ポンポン横移動できるのでカーソルキーをポチポチするより断然早いです。
大文字になると記号を無視します。記号を多く含む行の場合はサクッとジャンプして微調整が便利ですね。
コマンド | 説明 |
---|---|
f{文字} | 右方向で最初の{文字}にジャンプ |
t{文字} | 右方向で最初の{文字}の手前にジャンプ |
F{文字} | 左方向で最初の{文字}にジャンプ |
T{文字} | 左方向で最初の{文字}の手前にジャンプ |
今度は文字ジャンプですね。単語のど真ん中に移動したいとき等に便利です。
大文字になると逆方向になります。Vimは大文字になると大げさになるか逆の効果になるコマンドが多いそうです。
コマンド | 説明 |
---|---|
0 | 行の先頭へジャンプ |
^ | 空白を除く行の先頭へジャンプ |
$ | 行の末尾へジャンプ |
行の先頭と末尾へのジャンプですね。$
が押しにくく感じるかもしれませんが、文末へ移動して編集を行う場合はA
を使えばいいので、あまり使う機会はありません。
縦移動いろいろ
コマンド | 説明 |
---|---|
Ctrl-u | 上に画面半分だけ移動 |
Ctrl-d | 下に画面半分だけ移動 |
{数字}G | {数字}行へ移動 |
gg | ファイルの始端まで移動 |
G | ファイルの末端まで移動 |
ここからは縦移動です。Ctrl-u
とCtrl-d
は画面を見ながらガッツリ移動したいときに便利ですね。これとは別に1画面分移動するCtrl-f
、Ctrl-b
コマンドもありますが、VScodeの検索コマンドと被っていることと、移動が速すぎて扱いにくく感じるので載せていません。g
移動もよく使います。最近のエディターやIDEには行番号表示がデフォルトでついているかと思いますが、VScodeも例に漏れずついているのでガッツリ利用してやりましょう。
コマンド | 説明 |
---|---|
H | 画面に表示されている一番上の行へ移動 |
M | 画面に表示されている中央の行へ移動 |
L | 画面に表示されている一番下の行へ移動 |
画面を見ながらパッと移動するのに便利です。他のコマンドで不便ながらも代用できるときが多いので、なかなか覚えられないのですが……
ビジュアルモードの操作
コマンド | 説明 |
---|---|
v | ビジュアルモードへ/通常モードへ |
V | カーソル行を全選択してビジュアルモードへ |
(ビジュアルモードで)d | 選択範囲を削除して通常モードへ |
(ビジュアルモードで)c | 選択範囲を削除して挿入モードへ |
(ビジュアルモードで)y | 選択範囲をコピーして通常モードへ |
ビジュアルモードでは特定の範囲を選択し、様々な処理を行うことができます。
ファイル全体を選択したい場合はggVG
です。Ctrl-a
もキーバインドされているため、よくお世話になるので覚えてしまいましょう。
便利な編集コマンド
コマンド | 説明 |
---|---|
o | カーソルの下に空行を挿入して挿入モードへ |
O | カーソル行に空行を挿入して挿入モードへ |
s | カーソルの下の文字を削除して挿入モードへ |
S | カーソル行を削除して挿入モードへ |
D | カーソルから右側を削除 |
C | カーソルから右側を削除して挿入モードへ |
ci" | カーソルがいる""の中身を削除して挿入モードへ |
cw | カーソルの下の文字から次の単語の手前まで削除して挿入モードへ |
r{文字} | カーソルの下の文字を書き換え |
どれもめっちゃ使います。o
、O
はカーソルが行のどこにいても空行を挿入してくれます。VScodeならCtrl-Enter
でカーソル行の下に空行を挿入できるため、挿入モードに入りたいかどうかで使い分けています。ci"
はとても便利です。ci"
だけでなく、ci'
、ci<
、ci{
、ci(
、ci[
とコマンドすればそれぞれ対応した範囲で削除してくれます。無ければ生きていけない。
繰り返しコマンド
コマンド | 説明 |
---|---|
{数字}{コマンド} | {コマンド}を{数字}回繰り返す |
. | 直前の編集系操作を繰り返す |
; | 直前の検索系操作を繰り返す |
繰り返しですね。これもめっちゃ使います。
コマンドの頭に数字を付けると繰り返しになります。例えばこんな感じ。
- 5dd …… 5行削除
- 22j …… 22行下へ移動
- 3w …… 3つ先の単語の頭にジャンプ
.
と;
はどちらも繰り返しですが、繰り返す対象のコマンドが異なります。どっちのコマンドが何を繰り返すのかよくわかっていませんが、キー一発で繰り返してくれるので便利ですね。
可視領域の操作
コマンド | 説明 |
---|---|
zt | カーソル行が画面最上部になるようにスクロール |
zz | カーソル行が画面中央になるようにスクロール |
zb | カーソル行が画面最下部になるようにスクロール |
Ctrl-y | 画面を下方向にスクロール |
Ctrl-e | 画面を上方向にスクロール |
カーソルを動かさずに見える範囲を変えるコマンドです。個人的にzzはよく使います。
文字列検索
コマンド | 説明 |
---|---|
/{文字列} | {文字列}の検索 |
* | カーソルの下の文字列で検索 |
n | 次の検索結果へ |
N | 前の検索結果へ |
:noh | 検索ハイライトを消す |
検索機能です。正規表現検索が可能なので、うまく使うと便利になると思います。VScodeの検索機能も便利だと思うので、使い分けるといいかもしれません。
基本のン
ここからはVimコマンドの雑な理解を紹介していきます。
削除、修正、コピー、選択
一部のコマンドは{編集コマンド}{移動コマンド}
という規則性を持ちます。このコマンドでは、カーソルの位置から{移動コマンド}での移動先まで{編集コマンド}を実行します。
削除のd
、修正のc
、コピーのy
、選択のv
と覚えましょう。例えばこんな感じです。
- d5G …… カーソル行から5行目まで削除
- c0 …… カーソル位置から行の先頭まで削除して挿入モードへ
- yfX …… カーソル位置から
X
までの文字列をコピー - vG …… カーソル位置からファイル終端まで選択してビジュアルモードへ
この4種類のコマンドについて、他にも一部のコマンドで互換性があるようです。
例えばci"
はカーソルがいる""の中身を削除して編集
というコマンドですが、以下の通りに応用が利きます。
コマンド | 説明 |
---|---|
di" | ""の中身を削除 |
ci" | ""の中身を削除して編集 |
yi" | ""の中身をコピー |
vi" | ""の中身を選択してビジュアルモードへ |
オペレータ
とモーション
の組み合わせがコマンドの基本らしく、ここで行っていることも同じのようです。詳しい仕組みについては把握していないのでここでは説明しません。
一括編集
コマンド | 説明 |
---|---|
Ctrl-v | 矩形選択 |
(矩形選択状態で)I | 選択範囲の左側から一括編集 |
(矩形選択状態で)A | 選択範囲の右側から一括編集 |
:%s/{置換前の文字列}/{置換後の文字列}/ | ファイル内の文字列を一括置換 |
Vimには矩形(くけい)選択があります。複数行をまとめてコメントアウト……はCtrl-/
で行えますが、同じ編集を複数行に行いたい場合は便利です。
置換機能についてはVScodeの検索からでも行えるので、好みで利用するといいかと思います。Vimではもっと柔軟な置換が行えるようですが、把握していないためここでは載せません。
コマンドいろいろ
ここでは分類しにくいコマンドを紹介します。
<
、>
はインデントです。<l
でカーソル行を左にインデントする、といった使い方をします。
もちろん、ビジュアルモードで選択していれば選択範囲をすべてインデントしてくれます。
VScodeなら補完候補が出てくると思いますが、Ctrl-n
で下の候補へ、Ctrl-P
で上の候補へ移動できます。無ければ生きていけない。
なお、VScodeではCtrl-n
が新規タブを開くキーバインドと重複していたと思うので、利用したい場合はどちらかのキーバインドを変更しましょう。
q{a~z}
でコマンドの記録ができます。記録を止めるにはq
、実行するには@{a~z}
です。
同じ処理を数か所に行いたい場合はqa
で記録を始め、コマンドを一通り行い、q
で記録終了、次の編集箇所まで移動してから@a
といった形で利用します。
カーソル下の数字をCtrl-a
でインクリメント、Ctrl-x
でデクリメントできます。あんまり使う機会はないですが、数字が増えたり減ったりする様子を見るのは楽しいです。
不要な人はCtrl-a
のキーバインドを解除して全選択が行えるようにした方がいいかもしれません。
挿入モードでCtrl-x, Ctrl-l
をコマンドすると行補完ができます。単語の補完候補と違ってCtrl-n
で選べないので少々面倒ですが、調べれば多分キーバインドできると思います。多分。
参考
さっさと帰りたい怠け者エンジニアは vim をマスターしましょう
Vimの各種コマンドについて、覚え方も含めて説明してくれている非常にわかりやすい記事。ここに出会わなければいまだにVimを触ってなかったと思います。Vim幼稚園からVim小学校へ
古い記事ですが、初心者がVimを始めるのに近い目線でコマンドの紹介がされているので、チラチラ見てると勉強になります。
優柔不断VimmerのVSCodeVim
優柔不断VimmerのVSCodeVim
ターミナルVim
↓
VSCode Vim
↓
ターミナルVim
↓
他のエンジニアもVSCodeだし合わせないとなんか気持ち悪い←今ここ。
そんなVimmerです。
「気持ち悪い」というのも、弊社では「モブプログラミング」を週1で開催しており、環境が異なると僕がドライバーになった際に困るのです。
というわけで、久々にVSCodeを立ち上げてみるも、一部のプラグインが正常に動作しない。
非推奨の「背景表示」プラグインが原因だったり、PHPCSの動作不良で警告が吐かれたり、そもそもめっちゃ動作が重たい。
そんなこんなでアンインストール & インストール・プラグイン導入 までやってみました。
既に同じような記事がいくつも上がってますが、アンインストール時・導入時にハマるポイントなども解説していきます。
*MacBookPro使用してます。
アンインストール
今回はプラグインごと綺麗さっぱり削除したいので、いくつかコマンドを実行します。
## 本体削除rm-rf /Applications/Visual\ Studio\ Code.app/
## プラグイン削除rm-rf ~/Library/Application\ Support/Code/
rm-rf ~/.vscode/
僕の場合はプラグインがうまく動作していない様子だったので、プラグインなどのフォルダごと削除しました。
インストール
## Homebrewで導入
brew update
brew cask install visual-studio-code
プラグイン導入
以下、導入したプラグインたちです。
- VSCodeVim
- 僕にとっては必須アイテム。VSCodeでVimを利用するためのプラグイン
- vscode-icons
- 有名ですよね。オシャレ男子必須アイテム。アイコンをオシャレにします
- hoovercj.vscode-power-mode
- pwoer modeです
- monokai.theme-monokai-pro-vscode
- VSCodeの見た目を変更
- alefragnani.project-manager
- プロジェクトを切り替えるサイドバーを追加
- gizak.shortcuts
- ステータスバーにショートカットを追加
- Compulim.vscode-clock
- ステータスバーに時間表示
- spywhere.guides
- インデントガイドラインを追加
- sgryjp.japanese-word-handler
- 日本語のカーソル移動をサポート
- 日本語化
- 日本語化しちゃう
- vscode-duplicate
- ファイル複製を楽にする
- shardulm94.trailing-spaces
- 末尾スペースの可視化
- githistory
- 差分表示とか
- gitlens
git blame
が楽にできる
- pull-request-github
- プルリクをVSCode上で確認
- vscode-icons-team.vscode-icons
- gitignoreを自動で追加してくれる
- IBM.output-colorizer - ログファイルの色付け
- emilast.LogFileHighlighter
- これもログの色付け
- rogalmic.bash-debug
- bashを組む時に使う
- chrmarti.regex
- 正規表現のプレビュー
- bracket-pair-colorizer
- 括弧に色付けしてくれる
- rainbow-csv
- CSVファイルを色付けしてくれる。割と重宝してます
- prettier
- 自動フォーマッター
- felixfbecker.php-intellisense
- PHPインテリセンス
- bmewburn.vscode-intelephense-client
- PHPインテリセンス
- ikappas.phpcs
- phpcsです
## phpcsについて、php-code-snifferを導入しないとエラーになる
brew install php-code-sniffer
高速化
VSCodeの設定で高速化ができるらしい。
{"editor.cursorBlinking":"solid","editor.fontSize":9,"editor.highlightActiveIndentGuide":true,"editor.wordWrap":"on","editor.minimap.enabled":false,"editor.renderIndentGuides":false,"files.trimTrailingWhitespace":true,"files.watcherExclude":{"**/画像/**":true,"**/.git/objects/**":true,"**/.git/subtree-cache/**":true,"**/node_modules/*/**":true},"breadcrumbs.enabled":true,"terminal.integrated.fontSize":9,"emmet.includeLanguages":{"twig":"html","vue-html":"html"},"workbench.useExperimentalGridLayout":true,"workbench.colorTheme":"Monokai Pro (Filter Machine)","workbench.iconTheme":"Monokai Pro (Filter Machine) Icons","fabric.runtime":{"ports":{"orderer":17050,"peerRequest":17051,"peerChaincode":17052,"peerEventHub":17053,"certificateAuthority":17054,"couchDB":17055,"logs":17056},"developmentMode":false},"window.zoomLevel":2,"powermode.enabled":true,"powermode.presets":"exploding-rift"}
上記設定の中で、file.watcherExclude
という項目があります。
これは「監視から除外するファイル」を列挙でき、これにより読み込み時に余計なリソースを喰わなくなります。
画像ファイルが監視対象となるのかは定かではないですが、設定するのはタダなのでやっておきました。
"files.watcherExclude":{"**/画像/**":true,"**/.git/objects/**":true,"**/.git/subtree-cache/**":true,"**/node_modules/*/**":true},
その他の設定は良しなに変更してください。
感想
ショートカットや設定によってさらに使いやすくなるので、やはりVSCodeは素晴らしいですね。
ターミナルのVimは確かに軽量で多機能ではあるのですが、機能拡張やカスタマイズにかかる時間を考えるとVScodeにVimを導入して周りと開発環境を合わせた方が良いなと感じました。
おまけ
コマンドパレットを開き、「zen」と入力すると「zen modeへの切り替え」という項目が表示される。
僕も上司から聞いて初めて知ったのですが、UIなどを非表示にしてコーデディングに集中できるようにするためのモードだとか。
「zen(禅) mode」ぜひ利用してみてください。(僕は10分触って満足したのでそれ以降利用してない)
Reversed Client ID をVimでつくる
Google Firebase を使っていたら、Client ID(1234567890-abcdefg.apps.googleusercontent.comみたいなやつ)を逆順にしたもの(com.googleusercontent.apps.1234567890-abcdefg)を入力することがあったので、それをVimからつくるメモ。
Client IDが書かれたバッファで、以下のコマンドを実行。
:%!cat | ruby -ane 'puts $F.first.split(".").reverse.join(".")'
%!
: フィルタ処理(詳しくは :help range! )cat |
: Vimバッファの内容をrubyにパイプで渡すruby -ane
: ワンライナーを実行する。$Fからパイプで渡された情報が配列で取れるようになる。'puts $F.first.split(".").reverse.join(".")'
: Rubyスクリプトで文字列を加工する。putsした内容でVimバッファの内容を置き換える。
以上です。