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

Reactで挨拶

$
0
0

この記事は社内勉強会用として作られました。
Pro Reactという本を読みながら進みます。

本の内容と異なる部分

  • 本のサンプルをESlintとAirbnbのスタイルガイドに合わせて直しました。
  • create-react-appを用いてプロジェクトを生成しました。

本のサンプルはここで確認してください。

目次

Vimの設定

Vimの環境設定は他の記事で扱う予定です。
ここではReactを学ぶことが目的なので、下記のファイルでVimの環境設定を行なってください。

% cd ~
% git clone https://gitlab.com/devtopia/dotfiles.git
% ln -sf dotfiles/.vim .vim
% ln -sf dotfiles/.vimrc .vimrc
% ln -sf dotfiles/.eslintrc .eslintrc
% ln -sf dotfiles/.tern-project .tern-project

# Vimの設定ファイルからフラグインをインストール
% vim .vimrc
:PlugInstall!

rubyとjavascriptの場合はrubocopeslintのスタイルガイドを適用しています。
rubocopとeslintが先に設置されている必要があります。
gemとnpm(またはyarn)でそれぞれ設置してください。
vimprocというpluginを使うためgcc(make)、macOSの場合はxcodeが必要です。
xcodeが設置されてない方は次のコマンドで設置してください。

% sudo xcode-select --install

第一歩、挨拶

  • 新規
    • src/components/Hello.js
  • 修正

    • src/index.js
  • src/components/Hello.js

diff --git a/src/components/Hello.js b/src/components/Hello.js
new file mode 100644
index 0000000..1dc66a9--- /dev/null+++ b/src/components/Hello.js@@ -0,0 +1,11 @@+import React from 'react';++class Hello extends React.Component {+  render() {+    return (+      <h1>Hello World</h1>+    );+  }+}++export default Hello;
  • src/index.js
diff --git a/src/index.js b/src/index.jsindex 53c7688..219b78a 100644--- a/src/index.js+++ b/src/index.js@@ -1,8 +1,8 @@
 import React from 'react';
 import ReactDOM from 'react-dom';
-import App from './App';+import Hello from './components/Hello';
 import registerServiceWorker from './registerServiceWorker';
 import './index.css';

-ReactDOM.render(<App />, document.getElementById('root'));+ReactDOM.render(<Hello />, document.getElementById('root'));
 registerServiceWorker();

💡 Check

  • stateless componentについて調べてください。
  • stateless componentで修正してみましょう。

分割代入(Destructuring assignment)

  • 修正
    • src/components/Hello.js
diff --git a/src/components/Hello.js b/src/components/Hello.jsindex 1dc66a9..bae48e4 100644--- a/src/components/Hello.js+++ b/src/components/Hello.js@@ -1,6 +1,6 @@-import React from 'react';+import React, { Component } from 'react';-class Hello extends React.Component {+class Hello extends Component {
   render() {
     return (
       <h1>Hello World</h1>

Dynamic Values

  • 修正
    • src/components/Hello.js
diff --git a/src/components/Hello.js b/src/components/Hello.jsindex bae48e4..66b65fc 100644--- a/src/components/Hello.js+++ b/src/components/Hello.js@@ -2,8 +2,9 @@ import React, { Component } from 'react';

 class Hello extends Component {
   render() {
+    const place = 'World';
     return (
-      <h1>Hello World</h1>+      <h1>Hello {place}</h1>
     );
   }
 }

💡 Check

  • var, let, constについて調べてください。

Composing Components(props)

  • 新規
    • src/components/GroceryList.js
    • src/components/ListItem.js
  • 修正

    • src/index.js
  • src/components/GroceryList.js

diff --git a/src/components/GroceryList.js b/src/components/GroceryList.js
new file mode 100644
index 0000000..6fe4c05--- /dev/null+++ b/src/components/GroceryList.js@@ -0,0 +1,16 @@+import React, { Component } from 'react';+import ListItem from './ListItem';++class GroceryList extends Component {+  render() {+    return (+      <ul>+        <ListItem quantity="1" name="Bread" />+        <ListItem quantity="6" name="Eggs" />+        <ListItem quantity="2" name="Milk" />+      </ul>+    );+  }+}++export default GroceryList;
  • src/components/ListItem.js
diff --git a/src/components/ListItem.js b/src/components/ListItem.js
new file mode 100644
index 0000000..8285ebc--- /dev/null+++ b/src/components/ListItem.js@@ -0,0 +1,11 @@+import React, { Component } from 'react';++class ListItem extends Component {+  render() {+    return (+      <li>{this.props.quantity} x {this.props.name}</li>+    );+  }+}++export default ListItem;
  • src/index.js
diff --git a/src/index.js b/src/index.jsindex 219b78a..d690d95 100644--- a/src/index.js+++ b/src/index.js@@ -1,8 +1,8 @@
 import React from 'react';
 import ReactDOM from 'react-dom';
-import Hello from './components/Hello';+import GroceryList from './components/GroceryList';
 import registerServiceWorker from './registerServiceWorker';
 import './index.css';

-ReactDOM.render(<Hello />, document.getElementById('root'));+ReactDOM.render(<GroceryList />, document.getElementById('root'));
 registerServiceWorker();

💡 Check

  • コンポーネント間で情報の受け渡しについて調べてください。
  • single quotation('')とdouble quotation("")を変更しながら確認してみましょう。

Composing Components(props.children)

  • 修正

    • src/components/GroceryList.js
    • src/components/ListItem.js
  • src/components/GroceryList.js

diff --git a/src/components/GroceryList.js b/src/components/GroceryList.jsindex 6fe4c05..9a419b3 100644--- a/src/components/GroceryList.js+++ b/src/components/GroceryList.js@@ -5,9 +5,9 @@ class GroceryList extends Component {
   render() {
     return (
       <ul>
-        <ListItem quantity="1" name="Bread" />-        <ListItem quantity="6" name="Eggs" />-        <ListItem quantity="2" name="Milk" />+        <ListItem quantity="1">Bread</ListItem>+        <ListItem quantity="6">Eggs</ListItem>+        <ListItem quantity="2">Milk</ListItem></ul>
     );
   }
  • src/components/ListItem.js
diff --git a/src/components/ListItem.js b/src/components/ListItem.jsindex 8285ebc..f3904bb 100644--- a/src/components/ListItem.js+++ b/src/components/ListItem.js@@ -1,11 +1,17 @@
 import React, { Component } from 'react';

 class ListItem extends Component {
   render() {
     return (
-      <li>{this.props.quantity} x {this.props.name}</li>+      <li>{this.props.quantity} x {this.props.children}</li>
     );
   }
 }

 export default ListItem;

💡 Check

  • エラーを修正してください。
  • props validationについて調べてください。

最近めちゃくちゃ便利になった Vim の dot repeat の設定

$
0
0

ブログ記事からの転載です。

最近…というか asterisk.vim を使い始めた頃に(いまさら)dot repeat にはまっていたりします。

例えば、asterisk.vim を利用すると <Plug>(asterisk-z*)cgnというキー入力で

『カーソル下の単語を変更し、dot repeat で次の単語も同じ変更をする』

という事ができます。

dot repeat をうまく活用できなかった勢としては、これがかなり衝撃的でめちゃくちゃ便利でした。



が、これにも欠点があり(asterisk.vim を使う上でしょうがないんですが)『カーソル下の単語』しか対象にする事ができません。

textobj を多用する Vim でこれはちょっと不便だったので、operator-exec_commandにヘルパ関数を追加し、もう少し柔軟性を高くしてみました。

operator#exec_command#mapexpr_gn({operator}[, {noremap}])

このヘルパ関数は『{motion} のテキストを @/ に保存したあとに {operator}gn を行う operator のキーマッピング』を返します。

例えば cで dot repeat したい場合は以下のような設定になります。

" C{motion} で {motion} のテキストに対して dot repeat する事ができる
nmap <expr> C operator#exec_command#mapexpr_gn("c",1)

dotrepeat


これにより任意の textobj({motion})に対して dot repeat する事ができるようになります。

また、c以外のも <Plug>(operator-replace)などを適用することもできます。

nmap <expr> S operator#exec_command#mapexpr_gn("\<Plug>(operator-replace)")

これでかなり捗るようになった。

Vimの隠しコマンド

$
0
0

1.Vimを立ち上げる

$ vim

2.コマンドモードに入る

:

3.Ni!とタイプしエンター

:Ni!

4.結果は......

Do you demand a shrubbery?

なにこれ

モンティ・パイソン関連のジョークらしいです(参考:Wikipedia)。とは言っても私も元ネタを全く知らないのでよくわかりません。

検索してみるといくつかこのイースターエッグに言及した記事が見つかりました(他のイースターエッグも紹介されていて面白いです)。

詳細

この記事でやっていたVim scriptの高速化にあたってコードを眺めていると以下のような行を発見しました。

src/ex_docmd.c
/* Check for wrong commands. */if(*p=='!'&&ea.cmd[1]==0151&&ea.cmd[0]==78){errormsg=uc_fun_cmd();gotodoend;}

ea.cmdは実行するExコマンドを表す文字列(qwなど)なのですが、なぜか文字リテラルではなく数値リテラルと比較しています。しかもその一方は8進数で書かれています。コメントにはCheck for wrong commandsとそれっぽいことが書かれていますが、なんだか妙な感じです。そこで、エラーメッセージを返しているらしいuc_fun_cmd()を見てみます。

uc_fun_cmd()

src/ex_docmd.c
staticchar_u*uc_fun_cmd(void){staticchar_ufcmd[]={0x84,0xaf,0x60,0xb9,0xaf,0xb5,0x60,0xa4,0xa5,0xad,0xa1,0xae,0xa4,0x60,0xa1,0x60,0xb3,0xa8,0xb2,0xb5,0xa2,0xa2,0xa5,0xb2,0xb9,0x7f,0};inti;for(i=0;fcmd[i];++i)IObuff[i]=fcmd[i]-0x40;IObuff[i]=0;returnIObuff;}

!?
文字列をわざわざ""を使わずに、しかも16進数で書き、それからさらに各文字から0x40を引くというなんとも回りくどいことをしています。一体この文字列はなんなのでしょうか。せっかくなのでVimを使って確かめてみましょう。

まずfcmdの右辺の{}[]に置き換えます。surround系のプラグインを入れていれば一発です。
次に[]内の改行を取り除きます。Jコマンドを使うといいでしょう。
さらにya[とし、配列全体を無名レジスタにいれておきます。
最後にコマンドモードで:echo join(map(eval(@")[:-2], 'nr2char(v:val - 0x40)'), '')を実行します。

Do you demand a shrubbery?

冒頭のメッセージが復元できました。

メッセージの発生条件

さて、このエラーメッセージが表示されるのは、

src/ex_docmd.c
/* Check for wrong commands. */if(*p=='!'&&ea.cmd[1]==0151&&ea.cmd[0]==78){errormsg=uc_fun_cmd();gotodoend;}

このif文の条件式、*p == '!' && ea.cmd[1] == 0151 && ea.cmd[0] == 78が満たされた時です。ここでea.cmdはユーザーが入力したコマンドを表す文字列で、pはそのコマンドの次の文字を指しています。それでは015178を文字に直しましょう。

:echo nr2char(0151)" => i:echo nr2char(78)" => N

最初の文字がN、次がi、コマンドの次に来るのが!ですから、これはつまり:Ni!です。これで最初の現象が解明できました。なお、:Ni!以外にも:Niiiiiiiiiii!:Nippon!:'<,'>Ni! foobarなどにも反応します。コマンドの名前がNiで始まり、!が指定されていれば引数があろうと範囲指定があろうとこのメッセージが表示されます。

コマンド名に関する注意事項

ここで少し気になるのが、ユーザーがNiというコマンドを定義した場合です。

:command!-bang Ni echo 'User-defined Ni':Ni " => User-defined Ni:Ni!" => Do you demand a shrubbery?

あれ。定義されているかどうかは関係なくこうなるんですね。イースターエッグをhelpに書くわけにもいかないので(わざわざ難読化していることですし)全く知らない人が突然ハマりそうで怖いです。

引っかかりそうな単語

  • Niceなんとか
  • Nightなんとか
  • 9, 19, 90, ...
  • Nim language(奇しくもPython風の言語)
  • Nitroなんとか/Nickelなんとか(物質名はソフトウェアに結構ある気がする)
  • Ninja(ビルドツールのNinjaは大丈夫なんでしょうか)
  • その他多数(List all words starting with ni

Niceから始まるコマンドなんてもうすでにありそうで怖いですね。皆さんもコマンドを定義するときにはNiから始まっていないかどうかを確認しましょう。

【Windows向け】Vimのインストール方法について

$
0
0

はじめに

常に同じ環境でコードが書きたいということで、Vimを導入してみる。
今までも何度か導入しようとしたが、コマンド操作に慣れず、他のテキストエディタの方が
お洒落で使いやすいと感じていたので、あまり使う機会はなかった。

特に最近、複数のPC(異なるOS)上で作業する機会が増えてきており、
「インストールされているテキストエディタが違う」「インデントの深さが違う」等々、
PCによってテキストエディタの環境が違うということに非常にストレスを感じるようになった。

いろいろ調べた結果、「Vim」を導入してみることにした。

Vimとは?

Vimとは、コマンド操作 (CLI) が基本の黒い画面で有名なテキストエディタです。 (←僕の認識)

せっかくの機会なので、Wikipediaにて調べてみる。

(以下、Wikipediaより抜粋)

viから派生し、発展した高機能なテキストエディタである。
オランダ人のプログラマー Bram Moolenaar によってAmiga1向けに開発された。
のちに、Windowsを含むさまざまな環境に移植され、特にUnix系のOSでは、Emacsと並んで、
広く使用されているテキストエディタである。

Vimという名称は、オリジナルの「Viエディタ」に近づくことを目標として、
開発当初Vi IMitation(Viの模倣)の略とされていた。
しかし、やがてViを超えることを目指してVi IMproved(Viの改良)とされるようになり、
今日ではオリジナルのViを大きく上回る機能を持つに至っている。

ちなみに、「Vim」「GVim」は、また別物である。

Vimは、基本的にCUIで動作するが、GUIで動くVimのことを特に、GVim(gVim,gvim,ジービィム)と呼び、区別している。

Viとは? (Vimの前身)

(以下、Wikipediaより抜粋)
Emacsと共に、UNIX環境で人気があるテキストエディタ。ビル・ジョイによって開発された。
名前の由来は、VIsual editor」ないし、Visual Interface」とされている。

早速、インストールしてみる。

1.下記サイトよりインストール用のファイルをダウンロードする。

1.「 vim.org 」
vimの公式サイト。[※大きなアップデートのタイミングでしかリリースされない。]

2.「 KaoriYa - Vim 」
VimのWindows向けコンパイル済みバイナリを配布しています。
こちらで配布されているファイルは、1.「vim.org」で配布されているオリジナルに、日本語を扱う上で
便利な設定やスクリプトが追加されています。

今回は、「 KaoriYa」のVimをインストールしたいと思います。

お使いのPCスペックに合わせて、インストール用のファイルをダウンロードします。

ダウンロードをしたファイルを展開すると、すぐに「vim」を使うことができます。

展開したフォルダを開くと、下記のファイルがあると思います。

image.png

単純に、「gvim.eve」「vim.exe」ファイルを開くだけでも、
テキストエディタを開くことはできますが、、
コマンドプロンプトのどこからでも vimgvimが使用できるように設定を追加します。(ファイルパスを通す作業)

ファイルパスを通す(Windows編)

そもそもパスを通すとは?

僕も新人の頃、先輩にファイルパス通したと言われて、
インストールはしました。と答えていた時代がありました。

そんな人のために、ファイルパスを通すとはどういうことなのか、
手順とともに記載したいと思います。

と、書こうとしましたが、凄い良い記事を発見したので、
パスを通すということがどういうことなのか分からない方は、下記記事をご覧くださいw

「 Title : パスを通すとは?

mac osの記事ですが、Windowsの方にとっても非常にイメージが分かりやすいと思います。

僕が行った手順をメモ程度に記載します。

1. まず、解凍したフォルダ名を「Vim」に変更します。

image.png

2. ファイルを\c\Program Files配下、に移動させます。

image.png

3. 最後にファイルパスを登録します。

画面左下のwindowsボタンを左クリックし、「システム」を選択します。
image.png

コントロールパネル > システムとセキュリティ > システム に移動するので、システムの詳細設定を選択します。
image.png

「システムのプロパティ(環境変数)」> 「ユーザー環境変数(編集)」> 「環境変数名の編集」より「Vim」フォルダのパスを追加します。

image.png

以上で、ファイルパスを通す作業は終わりです。

Vimコマンドを叩いてみる。

$ vim

image.png

「Enter」を押す。

image.png

これでコマンドプロンプトからVimが使えるようになりました。


  1. 1985年にコモドールより発売されたパーソナルコンピューターのこと。 

gitでcommitしたファイルの一覧を表示、vi等で簡単に開く。

$
0
0

以下を.bashrcに追加

  • git log で出力したファイルの一覧をawkで成形しています。
.bashrc
function gls (){
    git log --name-status -n1 $1| awk -F' ''{print $2}';}
viで直前にcommitしたファイルを開く
$ vi gls
viで2つ前にcommitしたファイルを開く
$ vi gls HEAD^
  • ついでなので git status バージョン
.bashrc
function gs (){
    git status | grep "(modified:|new file:)"| awk -F':''{print $2}';}
viでcommit前のファイルを開く
$ vi gs

[Vim] プラグインなしでもデフォルトの機能で色々できるよ

$
0
0

はじめに

昔はvimのプラグインをよく使用していました。
しかし、プラグインを入れるたびにコマンドを学習するのが面倒になってきました。
プラグインがないとできないことは当然ありますが、プラグインを使えない環境で作業をすることがありますので、最近はプラグイン武装することよりもvim機能をもっと知ることに注力しています。
ファイル操作で便利な機能やプラグインに頼らなくてもできることなどをまとめていこうと思います。

コーディング中やコードを調査するときに便利な移動機能

個人的に便利だと思う移動機能。

キーバインド挙動
%対応する括弧に移動
[m(上方向に移動)関数を定義している箇所に移動する
]m(下方向に移動)関数を定義している箇所に移動する
m <任意のキー>
ex) ma
現在のカーソル箇所にマークをつける
` <マークをつけたキー>
ex) `a
マークをつけた場所に移動する
g,最後に修正した場所への移動

vimgrepで色んなものをgrep

普通のエディタと同じくvimにもvimgrepと呼ばれるgrep機能が備わっています。

私はtaglistプラグインが使えない環境でメソッドの一覧をみたい時に下記のようにvimgrepをよく使います。

:vimgrep /public function/ % | cw

ちなみに%は現在開いているファイル名のことを指します。
vimにはレジスタ編集中のファイル名やヤンク(コピー)した文字列の情報などをためこむ収納庫のようなものがあり、%はファイル名が保存されています。
興味のある方は:regで確認してみてください。

vimgrepに関しては下記の記事が参考になると思います。
vimgrepとQuickfix知らないVimmerはちょっとこっち来い

Tabを活用する

vimコマンドはパイプで組み合わせて使うことが出来るので、
:tabnew | edit /home/xxx/xxx.txt
とeditコマンドで新しいタブでファイルをしたり、
:tabnew | b 1
新しいタブにバッファーに展開されているファイルを流し込んだりできます。

Tabの切り替えコマンドは沢山存在しますが、下記のコマンドで大体のことが代用できると思います。

キーバインド挙動Link
gtTabを次のタブに切り替えるhttp://vim-jp.org/vimdoc-ja/tabpage.html
{Tab番号}gtTabを指定したTab番号のタブに切り替える

{Tab番号}gtを使うのならTab内にTab番号が表示されていたほうが分かりやすいかもしれませんね。
.vimrcファイルに下記のように設定するとTab番号が表示されます。
Tab番号 : [ファイル名] のフォーマットになるような設定です。

.vimrc
colo desert
" カレントタブをハイライトhi TabLineSel ctermbg=1" タブにフルパスでなく、ファイル名のみを表示する                                settabline=%!MyTabLine()" 常にタブラインを表示                                                          setshowtabline=2function! MyTabLine()let s =''foriin range(tabpagenr('$'))        " ラベルは MyTabLabel() で作成するlet my_tab_label ='%{MyTabLabel(' . (i+1) . ')}'        " 強調表示グループの選択ifi+1== tabpagenr()let s .='%#TabLineSel#'elselet s .='%#TabLine#'endif        " タブ番号 : [ファイル名] のフォーマットになるように設定let s .=(i+1) . ':[' . my_tab_label .'] 'endfor    " 最後のタブページの後は TabLineFill で埋め、タブページ番号をリセットするlet s .='%#TabLineFill#%T'return s
endfunctionfunction! MyTabLabel(n)let buflist = tabpagebuflist(a:n)let winnr = tabpagewinnr(a:n)return fnamemodify(bufname(buflist[winnr -1]),":t")endfunction

1847eb49-fab7-d2bd-70ed-5c1ecf6a92da.png

ファイルに書かれているファイルパスからそのファイルを開く

下記のようにファイルにパスが記載されているとします。

...
   $filepath = '/usr/local/log/error.log';
...

カーソルをパスの上に合わせて下記のコマンドを実行すると:e /usr/local/log/error.logなどしなくてもerror.logファイルを開くことができます。

キーバインド挙動Link
gfカレントウィンドウ上でファイルを開くhttp://vim-jp.org/vimdoc-ja/usr_22.html
<Ctrl>w gf新しくタブを開いてファイルを開くhttp://vim-jp.org/vimdoc-ja/windows.html#CTRL-W_gf

ファイルをあるときの状態に戻す

ファイルを編集している時にuを連打してファイルを元の状態に戻した経験はありませんか?
Undoブランチを理解すればuをひたすら連打するよりももっとスマートにファイルを戻せます。
http://vim-jp.org/vimdoc-ja/undo.html#undo-branches
http://vim-jp.org/vimdoc-ja/usr_32.html
ファイルの編集中は書いたり消したりという作業を繰り返するのでUndoブランチの分岐点がたくさん出来ます。
u連打でもいいですが、

{N}回前のファイルを保存したときのテキスト状態に移動する
:earlier {N}f

など様々な戻し方を知っていると便利なこともあるので知っておいて損はないと思います。
ちなみに戻しすぎた場合は、

{N}回後のファイルを保存したときのテキスト状態に移動する
:later {N}f

で調整してください。

ディレクトリをツリー表示

Windowsのエクスプローラーの様にディレクトリをツリー表示させるのに
Vimのプラグインnerdtreeを使用している方は多いのではないかと思います。
標準のvimでも同じようなことが:edit .で出来ます。ちなみにこのように表示されます。

" ============================================================================
" Netrw Directory Listing                                        (netrw v109)
"   Sorted by      name
"   Sort sequence: [\/]$,\.h$,\.c$,\.cpp$,*,\.info$,\.swp$,\.o$\.obj$,\.bak$
"   Quick Help: <F1>:help  -:go up dir  D:delete  R:rename  s:sort-by  x:exec
" ============================================================================
../
./
check/
Makefile
autocmd.txt
change.txt
eval.txt~
filetype.txt~
help.txt.info
キーバインド挙動
Enterディレクトリを開く
-(マイナス)親ディレクトリに移動
dディレクトリを作成する
Dファイル / ディレクトリを削除する
Rファイル / ディレクトリをリネームする

などなど他にも機能がたくさんあります。
詳しくは下記を参照してください。
キーバンドのリファレンス : http://vim-jp.org/vimdoc-ja/pi_netrw.html#netrw-quickmap

標準のvimでもnerdtreeのようにディレクトリにブックマークをつけることも出来るので結構便利。

最近開いたファイルの一覧を表示する

:ol[dfiles]で最近開いたファイルの一覧を表示することが出来ます。

ファイルの一覧を表示する
:ol[dfiles]

ただし、oldfilesコマンドは最近開いたファイルの一覧を表示するだけです。
VimプラグインのMRUのように
過去に開いたファイルの一覧を表示 → 開きたいファイルを選択し移動
という事がしたいのであれば、:bro[wse]と組み合わせて下さい。

ファイルの一覧を表示->開きたいファイルを選択し移動
:bro[wse] ol[dfiles]

仕組みに興味のある方はhelpのリンクを貼っておきますので、読んでみてください。
viminfo : http://vim-jp.org/vimdoc-ja/usr_21.html#21.3
v:oldfiles変数 : http://vim-jp.org/vimdoc-ja/eval.html#v:oldfiles

外部コマンドを実行する

vimはファイルを開いた状態でも:![コマンド]で外部(OS)コマンドを実行することが出来ます。
私はPHPのファイルを編集する際、編集の合間でちょこちょこプログラムを実行しながらデバッグします。

phpファイルのlint処理
:!php -l %

こんな感じ。

終わりに

今後もちょこちょこ編集していきます。

C/C++ で予約済み識別子をシンタックスハイライトする Vimプラグインつくった

$
0
0

ブログ記事からの転載です。

他人の書いた C/C++ のコードを見ているとあまりにも予約済み識別子を無視してコードを書いているものが多いので、ついカッとなってつくった。

プラグイン

NeoBundle 'osyo-manga/vim-cpp-syntax-reserved_identifiers'

また、デフォルトでは WarningMsgのハイライトを使用します。

任意のハイライト色にしたい場合は、

" ErrorMsg を任意のグループに置き換えるhighlight link cReservedIdentifiers ErrorMsg

みたいな設定で変更できます。

『グローバルスコープを持ち、_ で始まる名前』のハイライトを無効にする

予約済み識別子の条件の一つに

  • グローバルスコープを持ち、_ で始まる名前

というのがあるんですが Vim で『グローバルスコープ』という条件付けを行うのは無理なので単純に

  • _ で始まる名前

をハイライトするようにしています。

なので以下のようなコードもハイライトされます。

こういうコードをハイライトしてほしくない場合は、予め

letg:c_no_reserved_identifiers_start_underbar_lower_case=1

と、いうような設定をしておくことで

  • _ + 小文字で始まる名前

のハイライトを無効にできます。

何気に syntax 系のプラグインをつくったのは初めてなので問題や要望があれば Issues までお願いします。

[おまけ]

ちなみに当然ではありますが、予約済み識別子をガシガシ使ってる標準ライブラリのコードももちろんハイライトされます。

まぁこれはしょうがないか…。

vimキーバインドを利用するアプリをより使いやすくする方法(Macユーザ向け)

$
0
0

はじめに

vimキーバインドを利用するアプリケーションでは、エディットモード中に日本語入力を行った場合、
Escしても日本語入力モードのままの状態になりすぐにコマンドモードが利用できない。
その都度英数入力に切り替える必要のないように、特定アプリケーションのみEscを押下した際に、日本語入力がOFFになるように設定を行う。

設定にはキーバインドをカスタマイズするアプリKarabinerを利用する。

Karabinerの設定

実現したい動作

Escキーが押下されると、日本語入力をOFFにしつつ(英数キーを押下した挙動)、エディットモードから抜ける(Escキーを単体で押下した挙動)為の動作を定義する。

設定箇所

Karabinerには様々な挙動がデフォルトで用意されているが、独自の定義を行うためには個別にxmlで定義を行う必要がある。
この個別の設定はprivate.xmlファイルとして行う。private.xmlは以下で指定して読み込む。

Preference > Misc&Uninstall > Open private.xml

private.xmlの設定

例としてターミナルアプリ(Mac標準TerminalやiTermなど)MarkdownエディタのBoostnoteを対象として設定する。

<?xml version="1.0"?>
<root>
  <appdef>
    <appname>BOOSTNOTE</appname>
    <equal>com.maisin.boost</equal>
  </appdef>
  <item>
    <name>Escape to EISUU+Escape only terminal</name>
    <identifier>private.remap.jis_escape2eisuuAndEscape_terminal</identifier>
    <only>TERMINAL, BOOSTNOTE</only>
    <autogen>
      --KeyOverlaidModifier--
      KeyCode::ESCAPE,
      KeyCode::JIS_EISUU,
      KeyCode::ESCAPE
    </autogen>
  </item>
</root>

設定のポイントは以下の3つ

  1. 適用するアプリケーション名(アプリケーション群のまとまり)の定義
  2. 適用するアプリケーション名の指定
  3. 動作の定義

1. 適用するアプリケーション名(アプリケーション群のまとまり)の定義

アプリケーション名は <appdef>タグで定義する。
<appname>タグにアプリケーション名、 <equal>タグにアプリののBundle Identifierを指定する。
複数のBundle Identifireを指定する場合は <equal>タグを複数追記する。
Bundle Identifierの確認方法は以下を参照する。

http://harafuji0613.hatenablog.com/entry/2015/03/22/002953

該当のアプリケーションに対応するものがあれば、プリセットのアプリケーション名を利用できる。
プリセットのアプリケーション名は以下を参照。

https://github.com/tekezo/Karabiner/blob/version_10.22.0/src/core/server/Resources/appdef.xml

設定例においてターミナルアプリ(TERMINAL)をアプリケーション名として定義(<appdef>タグ内の設定)してないのはプリセットにリソース名が登録済みであるため。

参考までにTERMINALのプリセット定義は以下の通り。

<appdef>
    <appname>TERMINAL</appname>
    <equal>com.apple.Terminal</equal>
    <equal>iTerm</equal>
    <equal>net.sourceforge.iTerm</equal>
    <equal>com.googlecode.iterm2</equal>
    <equal>co.zeit.hyperterm</equal>
    <equal>co.zeit.hyper</equal>
  </appdef>

2. 適用するアプリケーション名の指定

<only>タグに適用したいアプリケーション名を指定する。
ここで述べるアプリケーション名は単一のアプリケーションではなく、カテゴライズした複数のアプリの総称として利用する。

3. 動作の定義

<autogen>タグの中にあるKeyCodeは上から、

  • 挙動変更するキー
  • 挙動変更した後のキー
  • 追加したい挙動のキー

を定義する。

補足

<name>タグで設定に名前をつける。Preference上ではこの名前で設定を確認できる。
<identifier>タグで設定に固有のIDをつける。システム内でユニークになるような命名規則を自分で考える。

参考

https://pqrs.org/osx/karabiner/xml.html.ja#prepared-appdef
https://pqrs.org/osx/karabiner/xml.html.ja#syntax-__KeyOverlaidModifier__


Windows環境でvimを利用するには

$
0
0

windows環境でvimをインストールしてみたので手順を書いてみました

Vimをダウンロードする

自マシンのビット数を確認し、以下のリンクからダウンロード
Vim-KaoriYa

※自マシンのビット数の確認方法

  • windows10の場合
  • [スタートメニュー]⇒[システム]
  • windows7の場合
  • [スタートメニュー]⇒[コンピューター]⇒[プロパティ]

Vimをインストールする

ダウンロードしたzipファイルを任意のフォルダに解凍し、vim.exeを起動
vim.png

image.png

参考

香り屋様(https://www.kaoriya.net/)

ターミナルのvimでctrl + spaceの挙動を無効にする

$
0
0

使用環境
- Ubuntu 16.04 LTS
- byobu/tmux
- vim

私はasciiキーボードを将来使う予定なので、ctrl-space と ctrl-: で入力切り替えをしているんですが、ターミナル内のvimのinsert modeで ctrl-space入力すると入力した文字がペーストされたり、エラー(E20: No inserted text yet)が起こったりしたので、その解決法を書きます。

まずターミナルのvimではctrl + spaceでnullが入力されるらしく、その際に上に書いたような挙動になるようです。なのでinsert mode時にnullのmappingを無効にするために.vimrcに

imap <Nul> <Nop>

という行を追加すると解決しました。

Vimに慣れるためのミニドリル

$
0
0

主にJavaScriptのコーディング用としてVimを使い始めたのですがなかなか操作に慣れなかったので、空き時間に練習するための題材を考えてみました。実際のコーディング時に役に立つかどうかは微妙ですが、とりあえず指の運動にはなりそうです。

なお、個人的に横移動は全て fでやるように矯正したかったので、それ以外の横移動はつぶしています。

nnoremaph<nop>nnoremapl<nop>nnoremapw<nop>nnoremapb<nop>nnoremape<nop>nnoremap ge <nop>vnoremapw<nop>vnoremapb<nop>vnoremape<nop>vnoremap ge <nop>

変数名を置換する(打ち直す)|cw{chars}<Esc>

ある変数名を変更したい、という場面です。

開始カーソル位置は、1行目の先頭です。
私は、fh*Ncwpiyo<Esc>n.で練習しています。

Before
consthoge=1;console.log(hoge);
After
constpiyo=1;console.log(piyo);

変数名を置換する(プットする)|cw<C-r>0<Esc>

ある変数名を変更したい、という場面です。
ただし、変更後の変数名は既にヤンク済みで、それをプットしたいという場合です。

開始カーソル位置は、1行目の先頭です。
私は、fpyejFh*Ncw<C-r>0<Esc>n.で練習しています。

Before
constpiyo=1;hoge+=1;console.log(hoge);
After
constpiyo=1;piyo+=1;console.log(piyo);

スネークケースからキャメルケースに|f_qmxgUlq

スネークケースにしていた変数をキャメルケースに変更したい、という場面です。

開始カーソル位置は、1行目の先頭です。
私は、fh*Nf_qmxgUlq;@myiwncw<C-r>0<Esc>n.で練習しています。
なお、gUl~としたほうが手っ取り早いですが、打ちにくいです(私の場合)。

Before
consthoge_piyo_fuga=1;hoge_piyo_fuga+=1;console.log(hoge_piyo_fuga);
After
consthogePiyoFuga=1;hogePiyoFuga+=1;console.log(hogePiyoFuga);

変数をなにかで囲う|cw{chars}<C-r><C-o>"{chars}<Esc>

変数を、記号や関数などで囲いたい、という場面です。

開始カーソル位置は、1行目の先頭です。
私は、fhcwparseInt(<C-r><C-o>", 10)<Esc>jFp.で練習しています。

Before
consta=hoge;constb=piyo;
After
consta=parseInt(hoge,10);constb=parseInt(piyo,10);

関数全体を選択する|vf{]}

関数定義の全体を選択したい、という場面です。

開始カーソル位置は、1行目の先頭です。
私は、fc*Nffvf{]}dnviwpNdjで練習しています。
なお、]}%としたほうが手っ取り早いですが、打ちにくいです(私の場合)。

Before
constcompare=function(a,b){returna-b;};array1.sort(compare);
After
array1.sort(function(a,b){returna-b;});

離れた2つの単語を入れ替える|demmf{char}viwp`mP

2つの「離れた」単語を入れ替えたい、という場面です。

開始カーソル位置は、行の先頭です。
私は、fhdemmfpviwp`mPで練習しています。

Before
consta=hoge-piyo;
After
consta=piyo-hoge;

複数行をブロックで囲う|V>O{chars}<Esc>`>o{chars}<Esc>

いくつかの行をif文などのブロックで囲いたい、という場面です。

開始カーソル位置は、行の先頭です。
私は、jVj>Oif (fuga) {<Esc>`>o}<Esc>で練習しています。
方法はいくつも考えられますが、個人的には、囲いたい部分をビジュアルモードで選択することから始める方法が視覚的に分かりやすいと思います。

Before
hoge=1;piyo=1;foo=1;bar=1;
After
hoge=1;if(fuga){piyo=1;foo=1;}bar=1;

ifブロックをコピーしたelseを追加する|f{yaBgPI else <Esc>

もともとif文があり、中身が似たようなelseを追加したい、という場面です。

開始カーソル位置は、行の先頭です。
私は、f{yaBgPI else <Esc>j<C-a>で練習しています。

Before
if(fuga){hoge=0;}
After
if(fuga){hoge=0;}else{hoge=1;}

オブジェクトリテラルを縦書き?にする|f,a<C-j><Esc>viBs<C-j><C-r>"<C-j><Esc>

正しい用語が分からないのですが、JavaScriptのオブジェクトリテラルの書き方を、

a={hoge:1,piyo:2};

から

a={hoge:1,piyo:2};

にしたい、という場面です。

開始カーソル位置は、行の先頭です。
私は、f,a<C-j><Esc>;.viBs<C-j><C-r>"<C-j><Esc>で練習しています。

Before
constuser={name:"hoge",age:20,address:"fuga"};
After
constuser={name:"hoge",age:20,address:"fuga"};

変数宣言を1行にまとめる|jdWVkJF;r,

複数行に書いていた変数宣言を1行にまとめたい、という場面です。

例えば

leta=1;letb=1;letc=1;

leta=1,b=1,c=1;

にします。

開始カーソル位置は、先頭行の最初の文字です。
私は、jjdd.j..kk"1P.u.dWj.VkkJF;r,;.で練習しています。

Before
leta=1;console.log(a);letb=1;console.log(b);letc=1;console.log(c);
After
leta=1,b=1,c=1;console.log(a);console.log(c);console.log(b);

Vimのキーマップに適したキー

$
0
0

はじめに

この記事はderisさんの「vimでキーマッピングする際に考えたほうがいいこと」やKoRoNさんの「スパルタンVim 5.0」等の影響を強く受けています
素晴らしい記事なので是非一読をおすすめします

関連のヘルプの引き方

この記事は大体ここに書いてある事をまとめただけ

全コマンド一覧
:help index.txt
マッピングについて
:help map.txt
キーの名前の対応表
:help key-notation
マップコマンドとモードの対応表
:help map-overview

ノーマルモード

機能が被っているキー

片方をマッピングして潰しても問題ないキー

key備考
<BS>hと同じ
<C-H>とは別にマップ可能
<C-H>hと同じ
<BS>とは別にマップ可能
<C-J>jと同じ
<C-N>jと同じ
<C-P>kと同じ
<Space>lと同じ
+<CR>と同じ

代用可能なキー

2キー以内で代用可能、{count}の操作も変わらないキー

key代用キー備考
Cc$$押しづらい マッピングは非推奨
Dd$$押しづらい マッピングは非推奨
Scc
Xdh
Yyy
scl
xdl

他にも <CR>j^-k^で代用可能
ただしオペレータと組み合わせた場合に動作が変わってしまう

未使用キー

key備考
<C-@>
<C-K>
<ESC>
<C-_>押すキーは<C-->(?)
\デフォルトの<Leader>

機能が似ているキー

key似ているキー
'`
`'
0^
_<CR>

プレフィックス系

組み合わせが空いているキーがある

key備考
<C-W>ウィンドウコマンド
<C-\>ほぼ未使用
'カーソルの移動
Z
[
]
`カーソル移動
g
mマーク
qマクロ
z

同一キー

マッピングすると同一のキーとして扱われるので注意が必要なキー

keykey
<Tab><C-I>
<CL><C-M>
<ESC><C-[>

個人的おすすめ設定

Yでカーソル位置から行末までヤンクする

C,Dc$,d$と等しいのに対してYはなぜかyyとなっている

nnoremap Y y$

x,Xでカーソル文字を削除する際レジスタを汚さない

ビジュアルモードで選択すればヤンクしないdとして使用できる

nnoremapx"_xvnoremapx"_xnnoremap X "_Xvnoremap X "_X

s,Sでカーソル文字を削除する際レジスタを汚さない設定

ビジュアルモードで選択すればヤンクしないcとして使用できる

nnoremap s "_svnoremap s "_snnoremap S "_Svnoremap S "_S

<C-p>,<C-n>でコマンドラインモードで入力したパターンに一致する履歴を補完する

cnoremap <C-p><Up>
cnoremap <C-n><Down>

さいごに

とりあえずノーマルモードの思いつくキーを書いてみました
間違いやその他おすすめのキーなどあればコメントお願いします

QFixHowmの全文検索にripgrepを使う設定

$
0
0

Vim用のQFixHowmの全文検索でGNU Grepの代わりに、ripgrepを使い、検索を高速化する設定方法。

" ripgrepを使う(PATHは通してある前提)let mygrepprg='rg'" 実行時のオプションをripgrep用に変更(GNU Grepと同じ出力になるように)let MyGrepcmd_useropt='-nH --no-heading --color never'let MyGrepcmd_regexp=''let MyGrepcmd_regexp_ignore='-i'let MyGrepcmd_fix='-F'let MyGrepcmd_fix_ignore='-F -i'let MyGrepcmd_recursive=''" gipgrepにファイルパターンとして「*」「*.*」を渡したらエラーになったのでその対策let MyGrep_GrepFilePattern='.'

参考

【Docker】コンテナ内でneovimを使ってIDEみたいな気分で開発したい【見た目IDE】

$
0
0

対象者

Dockerコンテナ内でvimでIDEみたいに開発したいという人

まとめ

  • Dockerでcentos6.9入れる
  • centos6.9にneovim入れる
  • neovimのプラグインNERDTreeを入れる
  • 最後にDockerfileを置いてありますので上記3つの話はわかってて速攻環境つくりたい人はDockerfileの章に飛んじゃってください

コンテナ内で開発するときも見た目はIDEはそっくり!
見た目以外の機能面の話は次回以降の記事で書こうと思っています。

自身の環境

項目内容
OSmacOS Sierra
OS version10.12.4
dockerDocker version 17.03.1-ce, build c6d412e
docker pullするOSCentOS:6.9

まずはcentOSをpull

$ docker pull centos:6.9

これでcentOS6.9のイメージを入手できます。
次に

$ docker run -it --name test centos:6.9

とするとtestという名前のコンテナが立ち上がり、

[root@7ed0424bd284 /]#

みたいな感じになってるかと思います!

ここで試しにviでphpのファイルを作ってみましょう!

[root@7ed0424bd284 /]# cd
[root@7ed0424bd284 ~]# mkdir qiita_php
[root@7ed0424bd284 ~]# vi test.php
test.php
<?php// greetingという名前をつけた関数functiongreeting($name){$message='Hello, '.$name.'!';// 処理return$message;// 結果を返す}$message=greeting('Tom');echo$message;// 'Hello, Tom!'

【PHP】関数というqiita記事からphpのプログラムをコピペいたしました。

IDEとの見た目の差

IDE(PhpStorm)

ローカルのmacでPhpStormでtest.phpを作って開いてみます。
スクリーンショット 2017-06-26 23.18.28.png

左にファイルエクスプローラがあって、下にはターミナルがあるって感じ。
コードにも色がついてて見やすいですね!

vi

スクリーンショット 2017-06-26 23.24.56.png

......
さすがにviはせこすぎました

neovim

centOS6にneovimいれるのちょっと大変です

[root@7ed0424bd284 ~]# cd /
[root@7ed0424bd284 /]# yum -y install libtool autoconf automake cmake gcc gcc-c++ make pkgconfig unzip
[root@7ed0424bd284 /]# yum -y install git
[root@7ed0424bd284 /]# git clone https://github.com/neovim/neovim
[root@7ed0424bd284 /]# cd neovim/
[root@7ed0424bd284 /]# make
[root@7ed0424bd284 /]# make install

makeのところがけっこう長かったです。

neovimがはいったところでtest.phpを開いてみましょう!

[root@7ed0424bd284 /]# nvim ~/qiita_test/test.php

スクリーンショット 2017-06-26 23.49.28.png

色的には随分良くなりました!(あたりまえ)

neovimの環境整備

まずは init.vimというvimでいうところの.vimrcにあたるファイルを編集します。

[root@7ed0424bd284 /]# mkdir -p ~/.config/nvim

[root@7ed0424bd284 /]# nvim ~/.config/nvim/init.vim
" プラグインが実際にインストールされるディレクトリ
let s:dein_dir = expand('~/.cache/dein')
" dein.vim 本体
let s:dein_repo_dir = s:dein_dir . '/repos/github.com/Shougo/dein.vim'

" dein.vim がなければ github から落としてくる
if &runtimepath !~# '/dein.vim'
  if !isdirectory(s:dein_repo_dir)
    execute '!git clone https://github.com/Shougo/dein.vim' s:dein_repo_dir
  endif
  execute 'set runtimepath^=' . fnamemodify(s:dein_repo_dir, ':p')
endif

" 設定開始
if dein#load_state(s:dein_dir)
  call dein#begin(s:dein_dir)

  " プラグインリストを収めた TOML ファイル
  " 予め TOML ファイル(後述)を用意しておく
  let g:rc_dir    = expand("~/.config/nvim")
  let s:toml      = g:rc_dir . '/dein.toml'
  let s:lazy_toml = g:rc_dir . '/dein_lazy.toml'
  " TOML を読み込み、キャッシュしておく
  call dein#load_toml(s:toml,      {'lazy': 0})
  call dein#load_toml(s:lazy_toml, {'lazy': 1})
  " 設定終了
  call dein#end()
  call dein#save_state()
endif

" もし、未インストールものものがあったらインストール
if dein#check_install()
  call dein#install()
endif

次にプラグインを管理するファイルであるdein.tomlを作成します

[root@7ed0424bd284 /]# nvim ~/.config/nvim/dein.toml

ちなみにこの段階でdein.vimのインストールが始まるはずです。インストールが終わったらファイル編集画面になります。

[[plugins]]
repo = 'scrooloose/nerdtree'
hook_add = '''
autocmd StdinReadPre * let s:std_in=1
autocmd VimEnter * if argc() == 0 && !exists("s:std_in") | NERDTree | endif
map <C-n> :NERDTreeToggle<CR>
'''

NERDTreeというプラグインを導入します。
このプラグインをいれるとneovimの画面左側にファイルエクスプローラが出現します!

hood_add以降の文は ファイル名を指定せずにneovimを起動するとファイルエクスプローラが開き、ファイル名を指定してneovimを起動するとファイルエクスプローラを開かないという設定を書いています。
また、ファイルエクスプローラが開いていない状態でも Ctl + nを押すとファイルエクスプローラを開くということも書かれています。

見た目勝負 第2戦

qiita_phpフォルダに移動して、neovimを起動します!

[root@7ed0424bd284 /]# cd ~/qiita_php
[root@7ed0424bd284 qiita_php]# nvim

スクリーンショット 2017-06-27 0.16.46.png

左側にファイルエクスプローラが出現しました!!
そこから十字キーでtest.phpにカーソルをあわせEnter!!

スクリーンショット 2017-06-27 0.18.06.png

だ、だいぶ近い
あとはIDEで下にでていたターミナルですね。

  1. test.phpにカーソルが置かれている状態のときに、 :split と入力
  2. 画面が分割され、下の画面にもtest.phpが表示
  3. Ctl-w + j で下の画面に移動
  4. :terminalと入力 (これがneovimじゃないとできない)(vimShellとかいれたらvimでも可能)

スクリーンショット 2017-06-27 0.21.31.png

見た目は完全に追いつきました!!

ついでに分割された画面を移動するコマンドまとめておきます。

コマンド移動先
Ctl-w + k上画面
Ctl-w + j下画面
Ctl-w + l右画面
Ctl-w + h左画面

エクスプローラが邪魔なときはCtl+nで消えて、欲しい時はCtl+nをもっかい押すとでてくるはずですので試してみてください。

neovimの環境設定をもっとやる

neovimをインストールしてプラグイン管理をdein.tomlでやってみたという自身の記事でdeopleteというさいっきょ補完プラグインなどをインストールしているdein.tomlなどがあるのでよろしかったらどうぞ。

Dockerfile

はじめから書けよ!!!!  っていうのは無しでお願いします。
githubにリポジトリを公開しました。

$ git clone https://github.com/ryo2851/neovim_ide.git
$ docker build -t test neovim_ide/.
$ docker run -it --name sample test

neovimをmakeする時間がかなりかかりますが、これで生成されるsampleコンテナではnvimが使え、NERDTreeも導入された状態になっています。

次回は機能面でもIDEに追いついて行く記事を書きます。

参考

neovimをインストールしてプラグイン管理をdein.tomlでやってみた

【Python環境整備】脱NeoBundle。超便利補完プラグインjedi-vimの環境をdeinで整えて快適になる設定までやる

Vimメモ : Neovimをインストールしてみる

Vimのキーストロークをどうやって覚えていったのかを人生を振り返ってみた。

$
0
0

私はHTMLコーディングにもプログラムの記述にも、Vimを使うことが当たり前になりました。
通常のエディタを使うこともありますが、開発においてはVimのキーストロークをよく使います。
(今はQiitaの投稿フォームで書いてますが・・・)

昔からVimを使いこなせたわけではなく、すぐには覚えられませんでした。
お決まり?ですが操作が全くできずイライラしていたのを覚えています。
「そういえば、どうやって覚えていったのか」とふと思ったので駄文を書いてみました。

俺の歴史

Lv.1: 大学時代、先生の説明が全く理解できずムカつく(笑)

OSが何なのか、PCかワークステーションかさえ忘れましたが、移動先の講義室に端末が置いてありました。
テキストにもviエディタの説明が載っていて、先生の説明からも「ノーマルモード」「コマンドモード」「挿入モード」という言葉が出てきました。
ただのワープロさえもろくに使えない時代にviのキーストロークなど、当然わけがわかりません。
そもそも打ったキーの文字が画面に出てこない時点で感情は限界に達していました。
多分、新規ファイルにノーマルモードで適当に打ってカーソルが何も変化しなかったのでしょう。

Lv.2: 取引先のエンジニアにキーストロークをほんのちょっと指示される

何を血迷ったか、会社でサーバーを建てようとかいう話になりました。
当時3万円ほどの安いデスクトップにLinuxを入れようと。(Fedora Coreだったと思います。)
本を読んで勉強するも、設定ファイルがまったくさわれません。
画面を見てもらって「dd」とか「p」とか言われてました。
「dd」で一行消えたのですが、なぜそうなるかはこの時は全くわかりませんでした。
カーソル移動はカーソルキーでやっていました。

Lv.3: ここからが本当の始まり。Viを覚えようと決意する。

ここまでは、Viを意図的に覚えようとはしていませんでした。
今の会社の社長がViを使いこなしているのを見て、これは覚えたら速いと思いました。
ここから覚えようと勉強を始めます。
Vimtutorを当時知りませんでした。
今は消えてしまったサイトですが、Viの基本の操作をわかりやすく解説しているサイトがあり、そこで書いている内容をViエディタで試していました。下記のような基本的なことが書かれていました。(原文は思い出せないので、原文ママではありません。)

「i」は現在のカーソルの前から挿入モードに入り、「a」は後ろから入ります。「i」と「a」は絶対に使い分けられた方がよいです。その他にも挿入モードに入る方法はたくさんあり、「I」で行の先頭、「A」で行の最後から挿入モードが開始されます。

こんな基本的なコマンドを少しずつ勉強していたのですが、まだ覚えているコマンドが少なく、普通のテキストエディタの方が効率がよい状態でした。
仕事で使いこなせるほどでもなかったのでDreamwerverや秀丸を使っていました。

  • 「O」「o」「A」「I」を使えず、「i」で挿入モードに入りカーソルキーや改行を使って一行上や一行下を編集していた。
  • ヤンクが思い通りに行えず、マウスで範囲選択してペーストしていた。
  • ビジュアル設定も全く使えない(秀丸の矩形選択は使えていたのに)
  • :%s(substitute)は知っていたが、特殊文字を反映できずDreamweaverに頼っていた
  • 「/」は使っていたが、移動手段としては積極的に使えなかった。

Lv.4: 検索の「/」、1単語の変更「cw」、最後の検索ワードに移動する「n」、繰り返しの「.」の活用で、便利さを初めて実感する

検索ワードの部分的な置換です。
一括置換をできないとき、今まではマウスで範囲選択してペーストすることで内容を置き換えていました。
これだと1文字余分に貼り付けてしまったり、クリップボードの範囲選択を間違ったりと、タイポの元になっていました。
これをViキーバインドで対処すると、正確で速かったのです。
スピードアップは期待していましたが、正確な編集ができることも知りました。

またこのとき、Eclipseを開発用エディタとして使用していました。
プラグインを入れてViキーバインドを使えるようにしていたのです。
このあたりから、開発用のメインエディタはViキーバインド必須と思うようになります。
開発効率も「Vimキーバインド > 通常のキーバインド」と逆転しました。

Lv.5: マクロ「qa」の威力に感動

Vimのキーストロークを記録して「@a」だけで再現するマクロです。
すべての変数に「$this->」をつけて、行末に「// 〜」とコメントを入れる。。1行1行やっていると時間がかかります。
プログラマーとしてはあらゆるものを自動化させたいと思うのは自然なことで、便利さを充分に実感できました。
キーストロークを間違って思いもよらない編集になることもありますが(今でもあります)、プログラマーとしての頭の使い所でもありますし、編集のスピードと正確性は数倍になることもあります。

ちなみにマクロを覚えた当初は「qa」で記録開始することが多かったのですが、今は「qq」で始めることが多いです。

Lv.6: Sublime Textの導入で、(Viキーバインドを持たない)Dreamweaverに別れを告げる

当時、開発用のメインエディタを探してさまよっていました。
ネットで調べてみると、特にデザイナーで人気急上昇なSublime Textに出会います。
私も操作性、デザイン、軽さ、そして一番大切な「Viキーバインド対応」が気に入り、しばらくハマりました。(ATOMがなかったら今でも使っているでしょう。)

純粋なVimの話ではなくなりますが、Sublime Textは複数箇所の範囲指定ができます。
複数箇所の範囲指定をした状態で、Viキーバインドで編集を始めることもよくやります。

今まではHTMLコーディングにDreamwerverを使っていました。
Sublime TextはHTMLの編集も非常にスムーズで、Viキーバインドが使えるようになったため、長らく愛用してきたDreamwerverに終止符を打ちました。

Lv.7: 「実践Vim」を読んでVim力が超絶UP!

「実践Vim」という書籍がネットで評判がよいので、買って読んでみました。
確かに超絶良書でした。
プラグインの説明ではなく、通常のコマンドの説明ですが、本当に勉強になったのは、書かれている「考え方」です。
「実践Vim」について得られた考えについては過去に投稿しています。

Lv.8: ビジュアル範囲設定を使えるようになる

Lv.9: グローバルコマンドを活用開始


[小ネタ] 最近使っているvimからdockerコンテナ内でテストする方法

$
0
0

最近はneovimを使っている。neovim-qtが割と安定していて良い。
neotermとvim-testでテストを実行する。
direnv等で、プロジェクト毎に環境変数を指定し環境変数でコンテナ名を引っ張ってくる。コンテナ名はプロジェクト毎で大体固定になるはず。
コンテナ名があればdocker psで取ってきてdocker execに渡す、というコマンドのトランスフォーマーを定義する。springの有無はお好みで。

nnoremap [space]tn :TestNearest<cr>nnoremap [space]tf :TestFile<cr>let test#strategy ='neoterm'let test#ruby#rspec#executable ='rspec'function! DockerTransformer(cmd) abort
  if $APP_CONTAINER_NAME !=''let container_id = system('docker ps --filter name=$APP_CONTAINER_NAME -q')return'docker exec -t ' . container_id . ' spring ' . a:cmd
  elsereturn'bundle exec ' . a:cmd
  endifendfunctionletg:test#custom_transformations = {'docker': function('DockerTransformer')}
letg:test#transformation ='docker'

基本的にdockerはコンテナ立ち上げっぱなしで、zshを起動する様にしている。サーバープロセスは一回中に入ってから起動する。
そうしておかないとサーバープロセス再起動時にコンテナごと落ちて面倒。

ある文字列をgrepで検索し返されたファイルをvimで編集

$
0
0

こういう状況のこういう作業

  • 一つのディレクトリ上にいくつかのファイルがある
  • とある文字列が入っているファイルがそのうちのいくつかある
  • (その文字列自体ではなく)その文字列付近を変更したい

具体的にこういう状況のこういう作業

例えば・・・

  • homeディレクトリ上に連番(0-99)のファイルがある
  • RSAという文字列がsample{素数}.txtに入っている
  • RSAという文字列の続きは、'RSA124'とか'aaaRSAbbb'とか、そもそも小文字で'rsahoge'だったり、ばらばらとしましょう
homeディレクトリ上のファイル
$ cd ~
$ ls

sample0.txt
sample1.txt
sample2.txt
sample3.txt
sample4.txt
sample5.txt
sample6.txt
...
sample98.txt
sample99.txt

愚直にやるのであれば、grepコマンドで'RSA'文字列を検索します。

RSA文字列の検索
$ cd ~
$ grep -i RSA *

-iオプションは大文字小文字の無視(ignore)です。
(よく使うと思うので説明不要かもしれませんが、念のため)

結果は以下

grepの結果
sample2.txt:ssh-rsa
sample3.txt:aaaRSAbbb
sample5.txt:RSA124
sample7.txt:RSA125
sample11.txt:rsarsaRSA
sample13.txt:RSA5a465465a
...
sample89.txt:hogehogeRSaaaaaa
sample97.txt:RSAってなんだ

この出力結果を見ながら、

編集したいファイルをvimで開く
vim sample2.txt
vim sample3.txt
vim sample5.txt
vim sample7.txt
vim sample11.txt
vim sample13.txt
...
vim sample89.txt
vim sample97.txt

といちいち打ちこんでいってエディタを起動し

  • /rsaで検索し、
  • 修正加えて
  • n, Nで次の単語に移動する

grep結果をvimにぶち込む

しかしスマートではないので、いちいちvimを起動しなくてもいいように

ファイル名だけを一度にvimにぶち込む
vim `grep -li RSA *`

-lはマッチしたファイル名のみ表示するオプションです。

こうすると

{n} 個のファイルが編集を控えています

みたいな標準出力が返されて、vimでn個のファイルを同時に開きます。
ファイルの移動は:nで次のファイル、:Nで前のファイル

書いた理由

別の人の作業を後ろから覗いているとき、「愚直な方法」で示したやり方をやっていました。
当初grepでファイル名のみを出力オプションがあることだけは頭にあったのですが、具体的に-lオプションだということがわからなかったので特に教えたりせず、黙って作業を見守っていました。

また、自分自身最初はパイプを使えばいいものと思っていて、帰ってから自分の環境で

grep -li RSA * | vim

としたところ

Vim: 警告: 端末からの入力ではありません
Vim: 入力を読込み中のエラーにより終了します...
Vim: preserving files...
Vim: Finished.

というエラーが返されてしまいました。

しばらくなんやかんやして、先にgrepを評価するバッククォート(`)を使用するのが正しい、と気づき、自戒の念もこめて書きました。

Mac向けのGUI neovim

$
0
0

概要

MacOSX向けにneovimのGUI環境を構築する

terminalのvimもいいけどアプリの切り替えをタブでシャカシャカやってる自分にとっては
GUIで別アプリとして立ち上がっているほうが扱いやすい

OSXのGUI vimはKaoriYaさんっていう印象だったけどneovimはやってないので探してみると
Githubで公開している人がいたので使ってみる

ただ使えればいいよって言う場合はbrewで入れればいい!

$ brew tap neovim/neovim
$ brew tap rogual/neovim-dot-app
$ brew install neovim-dot-app
$ brew linkapps neovim-dot-app

手順

  • githubからソースをクローンする

https://github.com/rogual/neovim-dot-app

$ git clone https://github.com/rogual/neovim-dot-app
  • makeする
$ cd neovim-dot-app/
$ make
VIM=/usr/local/Cellar/neovim/0.2.0/share/nvim NVIM=/usr/local/bin/nvim scons -Q
/bin/sh: scons: command not found
make: *** [all] Error 127
  • 通らない(^p^)

  • sconsコマンドをインストール

    • 調べると次世代のmake的な?知らなかった
$ brew install scons
  • その後、再度makeすると無事に通った

  • make installでインストール

$ sudo make install
  • make install後は普通にlaunch padにneovimという名称で追加されている

カスタマイズ

  • デフォルトでは ~/.config/nvim/init.vimが読み込まれるので普通にnvimの設定がしてあればおっけー
" 行番号表示setnumber" シンタックス有効syntax enable

" タブ、空行、改行、全角スペースの可視化setlistsetlistchars=tab:>.,trail:・,extends:>,precedes:<,nbsp:%
function! ZenkakuSpace()highlight ZenkakuSpace cterm=reverse ctermfg=DarkMagenta gui=reverse guifg=DarkMagenta
endfunction" インデント設定setautoindentsettabstop=4setshiftwidth=2setexpandtab" infoファイル設定setviminfo=" undoファイル設定setnoundofile" 入力補完inoremap jj <ESC>inoremap<C-j><ESC>" Escの2回押しでハイライト消去
nmap <ESC><ESC> ;nohlsearch<CR><ESC>" dein.vim設定letg:cache_home = $XDG_CACHE_HOME
letg:config_home = $XDG_CONFIG_HOME

" dein {{{let s:dein_cache_dir =g:cache_home . '/dein'" reset augroup
augroup MyAutoCmd
    autocmd!
augroup END

if&runtimepath!~# '/dein.vim'let s:dein_repo_dir = s:dein_cache_dir . '/repos/repos/github/'    " Auto Downloadif!isdirectory(s:dein_repo_dir)call system('git clone https://github.com/Shougo/dein.vim ' . shellescape(s:dein_repo_dir))endif    " dein.vim をプラグインとして読み込む
    execute 'set runtimepath^=' . s:dein_repo_dir
endif" dein.vim settingsletg:dein#install_max_processes =16letg:dein#install_progress_type ='title'letg:dein#install_message_type ='none'letg:dein#enable_notification =1if dein#load_state(s:dein_cache_dir)call dein#begin(s:dein_cache_dir)let s:toml_dir =g:config_home . '/nvim/dein'call dein#load_toml(s:toml_dir . '/plugins.toml', {'lazy': 0})call dein#load_toml(s:toml_dir . '/lazy.toml', {'lazy': 1})if has('nvim')call dein#load_toml(s:toml_dir . '/neovim.toml', {'lazy': 1})endifcall dein#end()call dein#save_state()endifif has('vim_starting')&& dein#check_install()call dein#install()endif" }}}" file type settingauBufRead,BufNewFile,BufReadPre *.coffee   setfiletype=coffee
auBufRead,BufNewFile,BufReadPre *.launch   setfiletype=xml
auBufRead,BufNewFile,BufReadPre *.test   setfiletype=xml
auBufRead,BufNewFile,BufReadPre *.xacro   setfiletype=xml
auBufRead,BufNewFile,BufReadPre *.world   setfiletype=xml
auBufRead,BufNewFile,BufReadPre *.urdf   setfiletype=xml

filetype plugin indent on

素のVimでgitのHEADとのdiff

$
0
0

ちょっとdiffを見たい時に。

単純な方法ですが、
新しいバッファに git show HEADを出力して、それを開いているファイルと比較します。

対象のファイルを表示している状態で :newなどで新しいバッファを作り、
:r !git show HEAD:#:.でそのバッファにHEADの内容を表示して、
:vert diffs #で先ほど開いたファイルとのdiffをとります。

ただ、:rした内容の先頭に空行が入るのが微妙ですが…。

なお、Windowsの場合はフォルダの区切りをスラッシュにしておく必要があります。

set shellslash

jedi-vimのポップアップの色設定

$
0
0

.vimrcの設定

Vim カラーチャートを参考に、ポップアップの背景をグレー、選択中背景をピンク、文字を黒にしてみた。

hi Pmenu ctermbg=8 ctermfg=0
hi PmenuSel ctermbg=13 ctermfg=0

文字どおり、

  • Pmenuがポップアップ
  • PmenuSelが選択中の候補
  • ctermbgが背景
  • ctermfgが文字色

参考

Completion List is Pink

Viewing all 5732 articles
Browse latest View live


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