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

Vim Bootstrap 基本プラグイン

$
0
0

Vim Bootstrapとは

vimrcに何を書いたらいいかわからない初中級vimmerの強い味方

Vim Bootstrap
使用したい言語を選択してgenerateするだけで便利なvimrcの出来上がり

この記事の趣旨

この記事は Vim Advent Calendar 2017四日目の記事です
初中級vimmerが何気なく使っているVim Bootstrapで基本生成されるプラグインを知るきっかけになるといい
自分のvimrcを見つける取っ掛かりとなるといい
プラグインの簡単な紹介を書いていきます

Vim Bootstrap基本プラグインリスト

vim-plug
vimのプラグインマネージャー

nerdtree
vimを開きながらディレクトリをツリー表示できる
上記GithubのREADMEを見てもらうと一目でわかると思います

vim-nerdtree-tabs
タブ間でnerdtreeを同期します

vim-commentary
コメントアウトを簡単に

vim-fugitive
vimからgitを呼べるようにするラッパープラグイン

vim-airline
vim-airline-themes
ステータスバーのデザインを変更する

vim-gitgutter
gitで管理しているファイル編集時に差分を左端に記号で表示できる

grep.vim
パターンに合致する箇所をファイルから検索する

CSApprox
ColorSchemeを256色に変換してくれるプラグイン

vim-trailing-whitespace
末尾の空白を強調表示する

delimitMate
括弧や引用符を自動で閉じる

tagbar
vimに関数定義や変数定義などのctag情報を表示するためのプラグイン vimのタグバー

syntastic
ファイルの構文エラーをチェックするためのプラグイン

indentLine
インデントを見やすくする

vim-bootstrap-updater
名前そのまま

vim-polyglot
vim用の言語パックのコレクション

fzf.vim
fzfとvimを連携するプラグイン

vimproc.vim
vimで非同期処理を実行するためのプラグイン

vim-misc
vimの拡張ライブラリ ほかのvimプラグインのためのプラグイン

vim-session
現在開いているバッファやウィンドウの状態を保存してくれる

vimshell.vim
vimからシェルを起動できる
vim8からデフォルトでこの機能が含まれている

ultisnips
スニペット機能を使うためのプラグイン

vim-snippets
さまざまな言語用のスニペットが含まれている

molokai
vimのカラースキーマ

間違っているところがあれば指摘お願いいたします
もう少しわかりやすくするために追記するかもしれません


軽量ディレクトリビューワ dirvish をカスタマイズする方法

$
0
0

Vim のファイラ選び

Vim には幾らかファイラがあります。

他にもいろいろあります。僕も昔は NERDTree を使っていたのですが、軽さを求めていたので dirvishにスイッチしました。

Big Sky :: Vim 上のファイラを NERDTree から dirvish に乗り換えた。

dirvish はとにかく何もしません。何もしないので機能が無いのですが、その分速いという訳です。README.md によると Netrw の2倍速いとのこと。

ただ、全てを気に入っているかというと、そういう訳ではなくて、幾らか不満もあります。

以下は僕がどうしても気に入らなかった2つの問題を解決する方法を紹介します。

-で起動してしまう

デフォルトではノーマルモードの -で dirvish が起動します。オペレータ等では反応しないので問題ないのですが、たまにキータイプをミスした時に画面を dirvish にすり替えられるのが許せませんでした。

ただしこの挙動は既にマッピングがあれば登録されない様になっているので以下を vimrc 入れておくことで回避出来ます。

nmap <Plug>(nomap-dirvish_up)<Plug>(dirvish_up)

検索プロンプトが独自

dirvish は独自で検索プロンプト /をハックしており、ファイル名のみマッチする様に作り込まれています。それはそれで便利なのですが、これの実装がムズムズする実装なのです。/をタイプすると

/\ze[^\/]*[\/]\=$

といった様に \ze[^\/]*[\/]\=$という文字を強制で入れられてしまいます。要は /を含まない後続部分にマッチしている訳ですが、こんなのが後ろに付いた状態で文字を入力したくない訳です。

運よく dirvish のバッファは dirvishというファイルタイプを設定してくれているので、カスタマイズする事が出来ます。

augroup DirVishau!
  autocmd FileType dirvish (何か)
augroup END

ここでキーを無効にする為に以下の様に書いても良いかもしれません。

function! s:setup_dirvish()
  nunmap <buffer> /
  nunmap <buffer> ?endfunction

augroup DirVish
  au!
  autocmd FileType dirvish :call s:setup_dirvish()
augroup END

もし「絶対にファイル名だけにマッチして欲しいけど、あの挙動だけは許せない」という人が居れば vim-prompterを使う事も出来ます。vim-prompter は Vim のコマンドラインを疑似するプラグインで、独自の補完やフックを行える様になっています。

function! s:on_enter(input)
  echo "YOU MAN!: " . join(a:input,'')endfunctionfunction! s:on_cancel(input)
  echo "WHY JAPANESE PEOPLE!"endfunctioncall prompter#input({
\ 'prompt': '# ',
\ 'on_enter':  function('s:on_enter'),
\ 'on_cancel': function('s:on_cancel'),
\})

この例を実行すると確定時に YOU WIN!を、キャンセル時に WHY JAPANESE PEOPLE!を表示します。

function! s:on_change(input)call clearmatches()
  exe "match Search /" . join(a:input,'') . "/"endfunctionfunction! s:on_enter(input)call clearmatches()
  echohl Warning | echo "WHY JAPANESE PEOPLE!: " . join(a:input,'')| echohl Noneendfunctionfunction! s:complete(input)return split(glob(a:input[0] . '*'),"\n")endfunctioncall prompter#input({
\ 'color': 'Normal',
\ 'prompt': '/',
\ 'on_complete': function('s:complete'),
\ 'on_enter':  function('s:on_enter'),
\ 'on_change':  function('s:on_change'),
\})

on_completeイベントや、on_changeイベントをフックする事でインクリメンタルサーチを実現する事も出来ます。

これを使って dirvish の /を置き換えてしまった物が以下になります。

nmap <Plug>(nomap-dirvish_up)<Plug>(dirvish_up)

augroup DirVish
  au!
  autocmd FileType dirvish :call s:setup_dirvish()
augroup ENDfunction! s:setup_dirvish()
  nunmap <buffer> /
  nunmap <buffer> ?call prompter#ready()nnoremap<buffer>/ :<c-u>call <SID>search('/')<CR>nnoremap<buffer> ? :<c-u>call<SID>search('?')<CR>endfunctionfunction! s:search(dir)let s:dir=a:dirlet s:pos = getpos('.')call prompter#input({
  \ 'prompt': a:dir,
  \ 'prompt_color': 'Normal',
  \ 'cursor': '_',
  \ 'cursor_color': 'StatusLine',
  \ 'histtype': '/',
  \ 'on_change': function('<SID>on_change'),
  \ 'on_enter': function('<SID>on_enter'),
  \ 'on_cancel': function('<SID>on_cancel'),
  \ })endfunctionfunction! s:on_cancel(input)call setpos('.', s:pos)endfunctionfunction! s:on_enter(input)let @/ = join(a:input, '') . '\ze[^\/]*[\/]\=$'endfunctionfunction! s:on_change(input)call setpos('.', s:pos)call search(join(a:input,'') . '\ze[^\/]*[\/]\=$', s:dir=='/' ? '' : 'bw')
  normal!0endfunction

あくまで疑似なので通常のプロンプトの動作とは異なります。これも嫌だという片は、おとなしく nunmapしたバージョンをお使い下さい。

VimにPythonコードの補完機能を追加して簡単に編集できるようにする

$
0
0

はじめに

vimのインストールから設定までを書いている記事がなかなか無かったので、
自分で書きます。
vim初心者がとりあえずPythonの補完機能を入れられるように書いています。
以下のサイトを参考にさせていただきました。

Vimインストール

sudo apt-get update
sudo apt-get install vim

Vimの設定

vimのプラグイン管理を行う dein.vimというものを使用してjedi-vimをインストールします。
今回は、 ~/.cache/deinにインストールします。

cd ~
mkdir ~/.cache
mkdir ~/.cache/deincd .cache/dein/
wget https://raw.githubusercontent.com/Shougo/dein.vim/master/bin/installer.sh
sh ./installer.sh ~/.cache/dein/

次に、プラグインの管理のファイル( plugin.tomlplugin_lazy.toml )を作成します。
plugin.tomlplugin_lazy.tomlの使い分けは以下の通りです。
特定の条件とは、Pythonの場合やマークダウンの場合などの開くファイルの種類に応じて
読み込むプラグインが指定できるようになっています。

  • plugin.toml    … 起動時に読み込むプラグインを指定する。
  • plugin_lazy.toml … 特定の条件でプラグインを指定する。
cd ~/.cache/
mkdir userconfigcd userconfig/
vi plugin.toml
plugin.toml
[[plugins]]repo='Shougo/dein.vim'[[plugins]]repo='Shougo/vimproc.vim'

以下のファイルにPythonのプラグインの設定を行います。

vi plugin_lazy.toml
plugin_lazy.toml
[[plugins]]repo='Shougo/unite.vim'[[plugins]]repo='Shougo/neomru.vim'on_source=['unite.vim'][[plugins]]repo="davidhalter/jedi-vim"on_ft=['python']

最後に、vimの設定ファイルにプラグインの設定を書き込みます。

cd ~
vi ~/.vimrc
~/.vimrc
"dein Scripts-----------------------------
if &compatible
  set nocompatible               " Be iMproved
endif

let s:dein_path = expand('~/.cache/dein')
let s:dein_repo_path = s:dein_path . '/repos/github.com/Shougo/dein.vim'

if &runtimepath !~# '/dein.vim'
  if !isdirectory(s:dein_repo_path)
    execute '!git clone https://github.com/Shougo/dein.vim' s:dein_repo_path
  endif
  execute 'set runtimepath^=' . fnamemodify(s:dein_repo_path, ':p')
endif

if dein#load_state(s:dein_path)
  call dein#begin(s:dein_path)

  let g:config_dir  = expand('~/.cache/userconfig')
  let s:toml        = g:config_dir . '/plugin.toml'
  let s:lazy_toml   = g:config_dir . '/plugin_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


" Required:
filetype plugin indent on
syntax enable

" If you want to install not installed plugins on startup.
if dein#check_install()
  call dein#install()
endif
"End dein Scripts-------------------------

上記のファイルを保存して、再度vimを開くと、プラグインのダウンロードが始まります。
プラグインがダウンロードし終わった後に、適当なpythonファイルを開きます。

vi test.py

コマンドモードで、以下のコマンドを打つと、jediのヘルプ画面が表示されます。
これでプラグインが読み込まれていることが確認できます。

:help jedi

test.png

ヘルプ画面を閉じるときは、 :qで閉じます。

補完機能も確認します。

test2.png

ちゃんと機能していれば、ドットを打った時に一覧が表示されます。

まとめ

なるべくvim初心者でも設定できるように書いたつもりですが。
わからないところがあればコメントをお願いします
(僕自身が初心者なのでご容赦を・・・)。

また、jedi以外にも便利なプラグインがあれば追記していこうと考えています。

作って覚える Vim script

$
0
0

はじめに

Vimmerの皆さんこんにちは。
Vimに慣れてくると、色々カスタマイズしたくなりますよね。
でも、プラグインを作るのは大げさだし…と思っている人には
.vimrcでVim Scriptを書いてみるのがおすすめです。

Vim Scriptとは

Vim script は Vim に組み込まれたスクリプト言語です。
vimを開き、 :help vim-scriptと打ってみましょう。

はじめに

誰もが最初に触れる Vim script は vimrc ファイルです。Vim が起動するときに読
み込まれ、書かれているコマンドが実行されます。それにより好きなように設定を変更
できます。vimrc の中ではすべてのコロンコマンドが使えます (":" で始まるコマンド
のこと。Ex コマンドやコマンドラインコマンドと呼ばれることもある)。

(自分のVimはヘルプが日本語じゃないからやだ!という人はこちらをどうぞ→ Vimヘルプを日本語化!)

「誰もが最初に触れる Vim script は vimrc ファイルです。」ということで
実はVimを触っていれば自然とVim scriptにお世話になっているのです。
シンタックスハイライトに使うカラースキームも、もとを正せばVim script。
Vimが有りさえすれば、そこが実行環境。というわけで気軽に始めてみましょう。

こんな人向け

  • Vimを触っていて、プラグインも使っているけど、もっと痒いところに手が届く自動化をしてみたい人
  • もともと別のプログラム言語を触っているが、Vim scriptは触ったことがない人

今回やってみること

  1. Vim上でPHP lintを実行する
  2. lintでエラーが出た行数をハイライトしてみる
  3. 上記を保存時に実行できるようにする

環境

OS: Mac OS Sierra(10.12.6)
Vim: 8.0

1. Vim上でPHP lintを実行する

これはぶっちゃけいろんな人がやっていますので、
本能の赴くまま、無邪気に作って保存してみましょう。

~/.vimrc
function! PHPLint()
    let result = system('php -l ' . bufname(""))
    echo result
endfunction

→保存・コマンドモードで以下を実行
:source ~/.vimrc

test.php
<?php$hoge=1;aaa// 明らかなシンタックスエラーecho$hoge;

→保存

コマンドモードで
:call PHPLint()を実行

すると、こんな表示が出ます

スクリーンショット 2017-12-03 16.55.55.png

楽しい\(^o^)/

簡単な解説

関数はfunction ~ endfunctionで定義します。

コマンド・関数名動き
letコマンドlet (変数名) = (値)で変数定義できます。
system()関数(組み込み)シェルコマンドを実行し、実行結果の文字列を返します。
echoコマンド引数の値を表示

これらのコマンドや関数については、:help letなど、コマンド・関数名などの前に :helpをつけて実行すると詳細なマニュアルが見られます:yum:

スクリーンショット 2017-12-03 17.17.09.png

2. lintでエラーが出た行数をハイライトしてみる

では、今度はエラーが出た行数をハイライトしてみましょう。
(Syntaxチェックは必ずしも正しい行数を出してくれるわけではないが、今回はlineを信じて表示する)

~/.vimrc
function! PHPLint()
    let result = system('php -l ' . bufname(""))
    let error_list = matchlist(result, '\(line \)\(\d\+\)', 1)
    if empty(error_list)
        echo "エラーはありませんでした"
        return
    endif
    call matchaddpos("Error",[str2nr(error_list[2])])
    echo result
endfunction

→保存・コマンドモードで以下を実行
:source ~/.vimrc

コマンド・関数名動き
matchlist()関数(組み込み)正規表現でマッチした文字列のリストを返します。
str2nr()関数(組み込み)文字列を数値に変換した結果を返します。
matchaddpos()関数(組み込み)第二引数に指定された行数を強調表示する

同じく、詳細は:help (関数名)で確認!

matchstr()で PHPのSyntaxエラー

Parse error: parse error in test.php on line 6
Errors parsing test.php

line XXXXXXを正規表現で取得し、その行をハイライトしています。

おい、:sourceできないぞ

はい。こんな表示が出たかと思います

Error detected while processing /path/to/.vimrc:
line  (行数):
E122: Function PHPLint already exists, add ! to replace it

関数は、function!で宣言しないと
再度:sourceコマンドを実行する事ができません。
リローダブルなvimrcを書くには、

function! PHPLint()
...
endfunction

とする必要があります(後述のautocmdも同様)。

matchaddpos の第一引数について

:help matchaddposすると、以下のようなシグネチャになっています。

matchaddpos({group}, {pos}[, {priority}[, {id}[, {dict}]]])

matchaddと同じである、ということで、matchaddのマニュアルを読んでみると、

{group} = 構文グループ

だとわかりますが、構文グループとはなんぞや:question:
ということで、さらに :help groupと実行してみると、謎が解けます。

構文グループとは、同じ種類の構文アイテムをグループ化したものである。構文グルー
プから強調グループにリンクされ、強調グループに対して色が設定される。構文グルー
プそれ自体は、色や属性を指定するものではない。

なるほど。と、その下を読み進めていると、構文グループが列挙してありました。

スクリーンショット 2017-12-03 17.52.57.png
(つづく)

今回は下の方にあった、構文グループ ERRORを選択し、
指定した行数を ERRORと同じ強調色にしています。

こんな感じで、:helpを使いこなすにはちょっとしたコツが必要ですが
慣れてくるとスルメのようにいい味が出てくるマニュアルです。

気を取り直して

コマンドモードで
:call PHPLint()を実行

すると、こうなります。

スクリーンショット 2017-12-03 18.22.52.png

3. 上記を保存時に実行できるようにする

~/.vimrc
autocmd! BufWritePost *.php :call PHPLint()

→保存・コマンドモードで以下を実行
:source ~/.vimrc

例によって :help autocmdしてみると

:au[tocmd] [group] {event} {pat} [nested] {cmd}

コマンドの定義方法が出てきます。
(Vim script上でコロン(:)コマンドを書くときは、:は不要です。)
引数として必要なのは、{event}{pat}{cmd}だということがわかります。

autocmdはフックのようなものです。
{event}で指定されたイベントが発生したとき、{pat}で指定したファイルに対し、
{cmd}で指定したコマンド/関数を実行します。

{event}は、あらかじめVimに文字列で指定されています。
というわけで :help eventを見てみましょう。

スクリーンショット 2017-12-03 18.11.06.png

いっぱい出てきました。
ここにあるイベント発生時に、任意のコマンドを実行できます。

BufWritePost

はバッファを保存した後のタイミングで実行するコマンドです。
test.php:wで保存してみましょう。PHPLint()が保存時に実行されているのがわかりますね。

おまけ:強調表示を消す方法

コマンド実行すると、強調表示されたままになってしまいます。
clearmatches()を実行すると強調表示がクリアされるので、以下のようにすると
シンタックスエラーがなくなれば表示も消えます。

function! PHPLint()
    let result = system( 'php -l ' . bufname(""))
    let error_list = matchlist(result, '\(line \)\(\d\+\)', 1)
    if empty(error_list)
        call clearmatches() ' ←こいつを追加
        echo "エラーはありませんでした"
        return
    endif
    call matchaddpos("Error",[str2nr(error_list[2])])
    echo result
endfunction

→保存・コマンドモードで以下を実行
:source ~/.vimrc

test.phpを正しく編集し、保存してみましょう。
強調表示が消えるはずです。

最後に

いかがでしたでしょうか?
今回は「作って覚える」ということで、細かい説明を省き
:helpを調べながら進めていきました。

Vim scriptと仲良くなるには、:helpと仲良くなるのが近道です。
楽しいVimライフを! & Merry Christmas!:christmas_tree:

エンジニアじゃない人がVimを学ぶメリット

$
0
0

こんにちは。
こちらはLIGのアドベントカレンダー3日目の記事です。 
謎の力によって3日目に移りました。
謎の力はすごいです。
株式会社LIGでWebディレクターをやっているともぞうといいます。
私はエンジニア出身でもなんでもないんですが使用するエディターはVimです。

本稿では下記の3つについて雑く書いていきます。

  1. 使えるようになってよかったこと
  2. なぜVimを使えるようなろうと思ったのか
  3. 使えようになるまでの道のりを

Vim自体の説明はしません。ここはQiitaですしおすし。

使えるようになってよかったこと

文字の一括編集が楽

矩形選択はいい機能ですね。
接頭辞、接尾辞を一気に入れるときに大変便利です。

番号リストつくるの楽

g + control + a

数字を矩形選択してこのコマンドをやってみましょう。
たしか最近のアップデートで追加された機能です。
Vimはいまだに進化をするエディタです。

他のアプリケーションのショートカットの肥やしになる

j , kを使えるアプリケーションは多いです。

  • ChatWork
  • Gmail
  • Google Drive

の上下選択は j , kが有効です。

エンジニアっぽくなれる

黒い画面を開いておくとエンジニアっぽさがでます。
そのおかげでしょうか。なんでか初見の人にエンジニアですか? と間違えられることも増えます。
新しく入ったエンジニアの人にいきなりSassの質問されたのはいい思い出です。

プレーンテキストを用意できる

+ Shift + vでスタイルを継承せずにコピペができるはずですが、
困ったことにKeynoteだと画像貼り付けのショートカットになります。
そこで一回Vimに貼っつけてからKeynoteへ挑むようにしています。

まあVimじゃなくてもできます。

とりあえずいきなりメモを書ける

ターミナル上でvimと打つだけでメモを書ける環境ができるのですごいです。
ゴミファイルが作成されないのでとてもエコです。
私はvにvimのaliasを割り当てています。

プレーンテキストを用意するときとかすっごい楽です。
なので、他のエディタでもできるんですがVimでプレーンテキストを用意することが多いです。

使えるようになりたいと思った理由

なんかカッコよさそう」の一言に尽きます。
カッコイイことは重要ですよね。 モチベーションがあがります。
なんとなくVimでメモとか書けたらカッコイイんじゃね? 
黒い画面触っている感じがカッコイイじゃね? という発想だけで覚えました。
モチベーションはすごいです。

使えるようになるまでの道のり

だいたいこんな感じでした。

  1. 秘伝のタレ(.vimrc)を誰かからもらう
  2. Vim矯正ギブス(メモはすべてVimで書くようにする)
  3. 師匠をみつける
  4. 本を読む

2週間ほどで最適化が完了します。

おわり

正直はじめてVimを使ったときは変態すぎて泣きました。
まず終了方法がわからないし、文字が入力できないとか意味がわからなかったです。
そして覚えてよかったと思っていますが、劇的に何かは変わっていないので、覚える必要はなかっただろうなというのも本音です。

ちなみのこの記事はIA WriterというMacのアプリで書きました。
IA Writerは便利ですね。

明日は誰かの何かです。
楽しみですね。

「E382: 'buftype'オプションが設定されているので書き込めません」の解決策

$
0
0

neovimを使ってterminalモードでgit commitすると、設定によっては以下エラーが出てcommitできないことがあります。

E382: 'buftype'オプションが設定されているので書き込めません

エラーの原因はこれみたいです。

tnoremap <silent> <ESC> <C-\><C-n>
tnoremap <silent> jj <C-\><C-n>

上記を削除するとエラーを回避できます。

Fablic.vimにて、凄腕vimmerに教えて頂きました。

VimからApexのLanguage Serverを使う

$
0
0

はじめに

この記事は チームスピリット Advent Calendar 2017の5日目です。
VimからApexのプロジェクトを扱う方法を探していたところ、ApexのLSP実装 1があるらしいです。わくてかわくてか。

forcedotcom/salesforcedx-vscode: Salesforce Extensions for VS Code
VSCode のプラグインに内包しちゃってますね。スタンドアロンじゃないのかよ。そんなわけで今回は言語サーバーを立ち上げているJARをプラグインから抜いてきてVimで使います。

サーバーJARを落としてくる

$ wget 'https://github.com/forcedotcom/salesforcedx-vscode/blob/develop/packages/salesforcedx-vscode-apex/out/apex-jorje-lsp.jar?raw=true'

JARをダウンロードし、呼び出しやすいファイル名にリネームしておきます。

起動確認

$ java -cp apex-jorje-lsp.jar -Ddebug.internal.errors=true -Ddebug.semantic.errors=false apex.jorje.lsp.ApexLanguageServerLauncher

一旦シェル上で起動することを確認してみます。引数はデバッグオプションがない場合にプラグイン内部で使われるコマンドをそのまま使っています。
標準入力でリクエストを受け付けるので、入力待ちの状態でプロセスが待機状態になれば成功。

Vim の下準備

まず、VimがApexファイルであることを判別するためにApexの言語プラグインが必要です。

  • ejholmes/vim-forcedotcom: Force.com syntax highlighting in vim.
    正規表現を使った構文ハイライトのみが含まれます。

  • neowit/vim-force.com: Vim plugin for force.com
    補完やデプロイ機能などApexのプロジェクト管理機能も豊富ですが、Language Serverと競合する場合があるかもしれません。
    正規表現を使った構文ハイライトを含み、オートインデントはJavaのものを流用しています。依存している channelのAPIの仕様がVimとNeovimで異なるため、Neovimでは一部の機能が利用できません。

次に、Vim側にLanguage Serverのクライアントとなるプラグインが必要です。Neovimであれば
* autozimu/LanguageClient-neovim: Language Server Protocol support for neovim and vim.
が実績もありおすすめです。(というか他をあまり知らない)

Vim の設定

先程のサーバー起動コマンドをVimのクライアントプラグインに設定して、Apexのファイルを開いた時にサーバーが起動されるようにします。
上記で上げたクライアントプラグインを前提としたサンプルコードです。

letg:LanguageClient_serverCommands = {
      \ 'apex': ['java','-cp', expand('/path/to/apex-jorje-lsp.jar'),'-Ddebug.internal.errors=true','-Ddebug.semantic.errors=false','apex.jorje.lsp.ApexLanguageServerLauncher'],
      \ }

/path/toはJARの保存場所に適宜書き換えておいてください。

じゃじゃーん!!

取っておいたスクリーンショットが会社製品のソースコードを丸々含んでいたのでupしませんでした。
後日upしますのでお手元で試して見てください。

使ってみた感想

  • VSCode版と比較もしたい(クライアントの実装状況に差があるため)が、VSCode版を使っていないので断念。
  • 補完の精度の検証もしたいが、そもそもApexの言語仕様をよく分かっていないので断念。
  • 正規表現ベースの構文ハイライトが時々おかしいのはLanguage Serverではどうしようもない。
  • テスト/デプロイなどの機能はない。これはLSPの仕様にないため、他のプラグインで補うしかない。
  • 途中まで文字を入力 -> 補完をした場合に、入力された文字を無視した補完候補を出すのだが、これはクライアント側の仕様? VSCode版使っている人がいたら教えてください。

  1. タグジャンプや補完、構文チェックなどの各種言語機能を提供するサーバーの通信プロトコルのこと。 Microsoft/language-server-protocol: Defines a common protocol for language servers. 

vimrcの育て方

$
0
0

はじめに

この記事は,Vim Advent Calendar 2017(その2)の6日目の記事です.

みなさん,vimrcを育てていますか?

vimrcは我が子のようなもの.生まれてきたその日から,大切に育ててきたのではないかと思います.

たまに,最低限の設定しかvimrcには書かない!という信念を持っている人を見かけます.しかし,それは作業を効率化するための努力を放棄しているだけではないかと,個人的には思います.たかがvimrc,されどvimrc.少しずつでもいいので,自分に合ったvimrcを育てていきましょう.そして沼に嵌っていくのです…

vimrcを育てるためには,他人の色々な設定を見て,良いと思うものを取り込んでいくのが一番手っ取り早いと思います.この記事では,そのための参考になるものをいくつか紹介したいと思います.

Vim Advent Calendarを読む

最も簡単で,一番おすすめなのはVim Advent Calendarを読むことです.今まさに読んでるところだよ!と思うかもしれませんが,私が読んで欲しいのは過去のVim Advent Calendarです.

Vim Advent Calendarは2011年から始まっており,今年で7年目となっています.去年までの記事の合計数はなんと676件!あれ?Advent Calendarは毎年12月の1日~25日に行われるものだと記憶しているので,どう頑張っても数が合わないのですが…

それもそのはず.Vim Advent Calendarは毎年25件の記事だけでは終わりません.この記事が投稿されているAdvent Calendarも“その2”ですので,2つのカレンダーが埋められれば合計50件の記事が投稿される計算になります.

過去のカレンダーを見てみると,なんといっても一番すごいのは2012年のVim Advent Calendarでしょう.Advent Calendarなのに12月26日以降も続けられ,最後の記事が投稿されたのは翌年の11月30日でした.今年のカレンダーの説明に※1年間は続けません,なんて書いてあるのは,過去にこんなことがあったからなんですね.

さて,これだけたくさんある記事を全部読むのは流石に無理があるので,興味があったり,自分が読めるレベルの記事を適当に読んでいきましょう.自分が初めて過去のVim Advent Calendarを読んだときは,1週間くらいかけて全体の1~2割くらいの記事に目を通したような気がします.本当に初心者向けの記事から,上級者向けの記事まで幅広く,数多く揃っているので,誰が読んでも楽しめますし,新たな発見があることでしょう.

他人のvimrcを読む

他人のvimrcは,その人が蓄えてきたVim知識の宝庫です.参考にならないわけがありません.とはいえ,無数にいるVimmerのうち,誰のvimrcを読めばいいのでしょうか?

これに対する正しい回答があるわけではないのですが,有名なpluginの作者のvimrcを見てみると,色々な設定が書かれていて参考にする部分が多いように感じます.特に,あるpluginの設定方法について知りたい場合は,その人のvimrcを見れば大抵書いてあります.ちなみに,githubのdotfilesというレポジトリの中にvimrcを置いている人が多いです.

これは特殊な使い方かもしれまんせんが,自分の場合,他の人はこれについてどんな設定をしているのかな?と思ったときは,とりあえずdein.vimなどの作者として有名なShougoさんのレポジトリを見てみます.vimrcを設定の種類に応じて細かく分けているので少しわかりづらいですが,色々なノウハウが詰まっていて見ているだけでも楽しいです.

vimrc読書会に参加してみる

vimrc読書会とは

オンラインで集まり、毎回みんなで特定の誰かの vimrc を読んで、気になるところやわからないところ、感心するところなどを好き勝手に言いあう集まりです。

「vimrc読書会」というものが毎週土曜日の23時に,Gitter上で開催されています.アーカイブによると,vimrc読書会の初開催は2012年7月10日.こちらも5年以上に渡って,毎週行われてきたようです.

他人のvimrcはとても参考になるのですが,どうしても分からない設定が出てくることもあると思います.vimrc読書会では,毎回みんなで特定の誰かのvimrcを1時間ほどかけて読んでいます.Gitterではそのvimrcの良し悪しや分からないことについて話されており,vimrcを書く参考にもなりますし,Vimへの理解を深めることもできます.

チャットに参加せずとも,一緒にvimrcを読んで,他の人のチャットを眺めているだけでも得られるものはたくさんあります.Vim熟練者の常連の方がいるので,チャットに参加すれば誰でも満足のいく議論ができると思います.チャットに参加している人数はいつも10人に満たない程度なので,気軽に参加して欲しいと思います.かく言う私は時々しか参加していない上に,いつもROM専です.ごめんなさい.

helpを読む

helpはVimのマニュアルです.helpを読めばVimの全てがわかると言っても過言ではありません.とりあえずググる,その前にとりあえずhelpを引きましょう.

紙の辞書は前後の単語も目に入るので良い,なんて言ったりしますが,Vimのhelpも前後の設定が目に入るので,一度helpを引くだけで一石二鳥です.実際にhelpを引いていても,前後の項目が気になってついつい脱線してしまうことがよくあります.とはいえ,helpには詳しい使用方法までは書かれていないことも多いので,適宜ググりながら読むと良いと思います.

helpの難点はVimが使えない環境では見られないという点です.しかし,今はインターネットの普及した時代.Vimmerのための便利なサービスがあります.

Web版ヘルプです.いつでもどこでもhelpを引きましょう.Googleカスタム検索も使えるので,場合によってはVim上のhelpよりも便利に活用できるかもしれません.

おわりに

今回は4つの方法を挙げてみましたが,いかがだったでしょうか?どちらかというと初心者向けな記事となりましたが,vimrc読書会なんかは活用していない人も多いんじゃないかと思います.自分自身もまだまだ十分には活用できていないので,今後は積極的に利用していきたいです.


Vim初心者のためのコマンド備忘録

$
0
0

最初に

時間のある人はVimのチュートリアルができるのでそちらを利用することをおすすめします。
とりあえずVimtutorをやっておけばなんとかなる

Vimチュートリアルはvimtutorコマンドで実行できます

モード

コマンド機能
iカーソルのある位置で挿入モード
A行の末尾で挿入モード
o新規行を追加して挿入モード
R上書きモード
vビジュアルモード
Ctrl + vビジュアルモード(矩形選択)
Escノーマルモード

移動

コマンド機能
h左に1文字移動
j上に1行移動
k下に1行移動
l右に1文字移動
w1ワードごとに移動
^行頭に移動
$行末に移動
Gページ末尾移動
ggページ頭に移動
g<行番号>g特定の行へ移動

削除

削除された文字(文字列)は無名レジスタに上書き保存されます

コマンド機能
x1文字削除
dw1ワード削除
dd現在行を削除
d<行数>d特定の行数を削除
vd選択されている部分を削除
vxvdと同じ
vc選択されている部分を削除して挿入モード

ヤンク(コピー)&ペースト

ヤンクに関しては以下のサイト様に詳しく載っています
http://cohama.hateblo.jp/entry/20130108/1357664352

コマンド機能
<ビジュアルモード>yビジュアルモードで選択されている部分をコピー
yw1ワードをコピー
y<ワード数>w任意のワード数をコピー
yy現在行をコピー
y<行数>y任意の行数をコピー
p無名レジスタの内容をペースト(無名レジスタの状態によってはヤンクしたものがペーストできない)
"0p0レジスタの内容をペースト(ヤンクした内容が確実にペーストできる)

ウィンドウ

コマンド機能
:sp画面の水平分割
:vs画面の垂直分割
Ctrl + wh操作ウィンドウを左に切り替え
Ctrl + wj操作ウィンドウを下に切り替え
Ctrl + wk操作ウィンドウを上に切り替え
Ctrl + wl操作ウィンドウを右に切り替え
Ctrl + wc現在ウィンドウを閉じる
Ctrl + wo現在ウィンドウを以外を閉じる

検索

コマンド機能
/正規表現正規表現による検索を行う
n次の検索結果に移動
N前の検索結果に移動

置換

コマンド機能
:%s/置換前/置換後/一番初めにヒットした文字を置換
:%s/置換前/置換後/gヒットした文字を置換
:%s/置換前/置換後/c確認しながら置換

その他

コマンド機能
u最後に実行したコマンドを取り消す
U行全体で取り消す
Ctrl + r取り消したコマンドの再実行
:e <ファイルパス>現在のウィンドウでファイルを開く
:! <実行したいコマンド>外部コマンドの実行

最後に

間違い等あれば報告お願いします

単発繰り返し(ドット)を使って置換する

$
0
0

概要

この記事はVim Advent Calendar 2017の6日目の記事です。

vimの操作は覚えたけれど、上手く編集できない人に向けて、単発繰り返しを使っての置換について書きます。

「単発繰り返し」について

直前の動作を繰り返すことができるので便利です。※詳しくは、ヘルプ参照 h .

サンプル

説明で使用するテキストになります。

<form><divclass="form-group"><labelfor="exampleInputEmail1">Email address</label><inputtype="email"class="form-control"id="exampleInputEmail1"aria-describedby="emailHelp"placeholder="Enter email"><smallid="emailHelp"class="form-text text-muted">We'll never share your email with anyone else.</small></div><divclass="form-group"><labelfor="exampleInputPassword1">Password</label><inputtype="password"class="form-control"id="exampleInputPassword1"placeholder="Password"></div><divclass="form-check"><labelclass="form-check-label"><inputtype="checkbox"class="form-check-input">
      Check me out</label></div><buttontype="submit"class="btn btn-primary">Submit</button></form>

https://getbootstrap.com/docs/4.0/components/forms/より

置換の手順

  1. /ex検索
  2. ciw入力へ
  3. sample<esc>置換
  4. n.繰り返し

n.は、よく使うのでmapにすると便利です。

私は、次で登録しています。

nnoremap <c-k> n.

検索について

単語検索は、*を使います。*を使うとカーソル下の単語を単語で検索することができます。カーソル下に単語がない場合は、移動して*を実行します。*で入力ミスを確認できるので便利です。また、単語以外の場合は、vi"y/<c-r>"などカッコを利用して検索もできます。

exampleInputEmail1の検索

手順

  1. /ex短い単語で、exampleInputEmail1を探します。
  2. n到達するまで繰り返します。
  3. *で単語検索を開始します。

入力について

単語を入れ替える場合

exampleInputEmail1 → sample

ciwsample<esc>n.

cを使って削除後に入力モードにし、入力しています。

ciw<c-r>0<esc>n.

ソース上に単語が存在する場合は、あらかじめヤンクしておけばペーストするだけで修正できます。入力モードでは、<c-r>0でペーストできます。

単語以外を入れ替える場合

form-control → sample

ci"samle<esc>n.

""で括られている場合は、ci"を使って置換します。

12ssample<esc>n.
""などで指定できない場合は、文字数を使います。

ct"sample<esc>n.
検索を使う方法もあります。数がわからない場合に使います。

先頭に追加する場合

exampleInputEmail1 → sample-exampleInputEmail1

isaple-<esc>n.

末尾に追加する場合

exampleInputEmail1 → exampleInputEmail1-sample

ciw<c-r>"-saple<esc>n.

削除してから入力します。

先頭を修正する場合

exampleInputEmail1 → form-InputEmail1

7sform-<esc>n.

途中に文字を入れたい場合

exampleInputEmail1 → example-InputEmail1

7sexample-<esc>n.

先頭部分は、打ち直します。打った方が早いことは、よくあります。

最後に

vimは色々なコマンドがあるので、色々探してみるのも面白いです。ドットでは難しいことは、マクロや正規表現を使うことで解決できるのでまたの機会に。

ありがとうございました。

KaoriYa Vim にMigemoを導入する

$
0
0

Migemoとは

KoRoNさんが配布しているKaoriYaパッチを適用したWindows版Vimでは、C/Migemoを導入することでMigemoを利用できます。

Migemoとは、漢字や平仮名の検索をローマ字で素早くできるしくみです。
例えば「検索」という単語を検索したいとき、Migemoを導入していないと「kensaku」を入力して「スペース」で変換開始、「エンター」で候補を確定という手間がかかります。
加えて、検索前後で日本語入力の切り替えも必要です。
一方Migemoを用いると、日本語入力の切り替えをせずに「kensaku」と入力するだけでよいのです。

無題.png

このアイデアは以下の文献で詳しく説明してあります。

  • 高林 哲: 横着プログラミング 第2回: Migemo: 日本語のインクリメンタル検索, UNIX MAGAZINE, Vol. 17, No. 2, pp. 129-136, February, 2002.
  • 高林 哲, 小松 弘幸, 増井 俊之: Migemo: 日本語のインクリメンタル検索, 情報処理学会論文誌, Vol. 43, No. 12, pp. 3698-3705, December, 2002.

ドキュメント通りでは導入できない

さて、この便利なMigemoを導入しようとしても、C/Migemoに同梱のドキュメント通りにしたがってもうまくできません。
C/Migemoのドキュメントは3年以上更新されておらず、おそらくVimの仕様の変化に追従していないのでしょう。
Vimスクリプトを勉強し試行錯誤して、やっと解決できたので忘備録として残しておきます。

現在のインストール方法

Windows版Vimをダウンロードし起動できる状態にした直後を想定して説明していきます。

1. C/Migemoをダウンロード

KoRoNさんのサイトでC/Migemoをダウンロードしてください。
32bit版と64bit版がありますが、あらかじめ導入済みのVimと同じ版を選んでください。

ダウンロードしたらアーカイブを展開してください。

2. migemo.dllをコピー

C/Migemoに含まれているmigemo.dllをgvim.exeがあるディレクトリにコピーします。

3. migemo.vimをコピー

同梱のドキュメントには、migemo.vimを $VIM/runtime/plugin/にコピーと書いてありますが、これではスクリプトが読み込まれません。
Vim上で :set runtimepath?コマンドを実行すると、現在有効なランタイムパスが表示され、このディレクトリ上のスクリプトが読み込まれます。
表示されたランタイムパスの中には $VIM/runtime/plugin/が含まれていないため、上記の方法では失敗するのです。

というわけで、gvim.exeがあるディレクトリを $VIM$とすると、 $VIM/vimfiles/plugin/にmigemo.vimをコピーするのが正解です。

4. 辞書ファイルをコピー

ドキュメントには $VIM/dictディレクトリに4つのファイルをコピーするように書かれていますが、C/Migemoのdictディレクトリにはcp932とutf-8の2つの辞書ファイルが含まれており、どちらをコピーしたらよいのか迷います。

実際はdictディレクトリをそのまま $VIMにコピーすれば大丈夫です。

インストール完了

以上でインストールは完了です。

Migemoを使ってみる

_vimrcには以下の設定を追記しておいてください。

_vimrc
setincsearchif has("migemo")set migemoendif

Migemoはデフォルトで g/に割り当てられています。
ノーマルモードで g/を入力することで、Migemoによる前方検索が開始できます。

Enjoy Migemo!!

僕とVimの1年間

$
0
0

はじめに

この記事はVim Advent Calendar 2017の7日目の記事です。

この記事では、筆者とVimの出会いと日々、そしてこれからについて記しています。
まだ1年と少しという短いVimとの日々を振り返りながら、読者の皆さんにVimの魅力を伝えることをゴールとします。

ただの年末のテンションから生じた叙事詩的なテキストなので、お気軽にお楽しみください。

筆者

筆者のプロフィールはざっくりと以下の通りです。

  • ソフトウェアエンジニア暦は1年3ヶ月
  • 組み込みの業界で開発者として勤務
  • 文系卒(歴史学)
  • 前職ではアパレルの販売職を5年ほど務めた

Vimとの出会い

僕とVimの出会いは、ソフトウェアエンジニアとしてデビューする、数ヶ月前(2016年、8月頃)でした。

ソフトウェアエンジニアへ転職するべく、半年弱の組み込みの開発の教育を受けていた時のことでした。
当時は、時間もたくさんあったので、Raspberry Piに電子部品を組み合わせてよく遊んでいました。
その手の手順書には、「vim xxxで設定ファイルを開く」といった、内容のものが時々あり、
それが最初にVimを開いた瞬間だったと記憶しています。

そしてその時は、やはりというか、お決まりの、

「なんだこれ!!!!!!!!!!!!」
「入力できひん!!!!!!!!!!」
「終了できひん!!!!!!!!!!」

という状態へ陥り、第一印象は最悪でした。

「こんなんnanoで開いたらええやんけ」
当時はそう思ったりしていました。

Vimとの再開

Vimの洗礼を受けてから2ヶ月後、教育のカリキュラムはLinux(CentOS, 組み込みLinux)を使用したものとなっていました。
そこでVimと再開することとなります。

そのカリキュラムのテキストでは、様々な編集は全てVimで行うようになっていました。
今思えばなかなか「いい」テキストだったと思います。

そこで筆者は幸いにも、じわじわとVimに馴れていくことができました。
ググると出てくる様々なコマンド。(ddで行削除とか、置換コマンドsubstituteとか)
偶然ながら、僕に「テキストエディタ」というものの強力さをはじめに教えてくれたのは、Vimでした。

Vimとの意気投合

そして、その2ヶ月後、いよいよソフトウェアエンジニアとしてデビューを果たします。

その現場の上司は、エクストリームなVimmerでした。
これも僕にとっては幸運なことでした。

そして、その現場に入って、Vimを使う上でとんでもない誤りをしていたことをその上司に指摘されます。

「カーソル移動を十字キーで行っていた」 のです。
Vimにはノーマルモードとhjklキーによる移動という、素晴らしいカーソル移動手段があることの、
その重要性をないがしろにしていたのです。

これの修正には大いに苦労をしました。
そもそも、タッチタイプも満足にできなかったヒヨッコプログラマだった僕は、
必死でVim経由でタイピングの特訓を行いました。

その甲斐もあって、エンジニアになって一月が経つ頃には、
Vimでタイプすることが、とてもとても気持ちのいいことになっていました。

それにより、Vimといよいよ意気投合ができたと感じました。
そして、Vimと僕との毎日が始まっていきました。

Vimとの1年

そして、Vimと働きだしてからの1年は、いつでもVim共にあったと振り返っています。

ソースコードを書くとき。
簡単なテキスト処理をするとき。
社内のイントラネットへ書き込む内容を編集するとき。
バイナリを開くとき。
ソースの差分をとるとき。
Gitのコマンドを実行するとき。
IDEのテキストオープンをリモートでジャックするとき
……

実質的にVimは僕にとってはIDEとして働いていてくれたと考えています。

そして、ソフトウェアの中でも、テキストエディタというものへ特別な興味を抱かせてくれたと感じています。

ちなみに、Vimの一番好きなところは、「小さなコマンドの組み合わせで多彩な機能を実現している」ことです。
Unix的で素敵。

Vimとのこれから

僕はVimは世のテキストエディタ群において、文化的に以下のような位置づけと考えています。

「文化の黎明期から隆盛期にかけて登場する、最も文化的で格式性に富んだものごと」

まあ、スターウォーズでいう、ライトセーバーみたいなイメージです。笑

だから、今後Vimのような思想をもったエディタはきっと現れないと考えています。
そして、人間がテキストベースのインターフェースでコンピュータとコミュニケーションができる限り、
その思想は不変であり続けると考えています。

というわけで、今後は自分もVimが好きで、テキストエディタが好きな人間として、
微力ながらVimのコミュニティに貢献していきたいと考えています。

まとめ

そんなこんなでダラダラと筆者とVimのあれこれをご紹介しました。
最後までお読みいただき、誠にありがとうございます。

この記事も、edited by Vim 100%でお送りしました。

MacBook Pro で esc が打ちづらい人のための、挿入モードからノーマルモードへの戻り方

$
0
0

この記事は?

MacBook Pro は、esc がタッチバーに存在するため、打ったかどうかの判定が難しいです。
最初のうちは慣れればなんとかなるかと思いましたが、さすがに厳しい。
そこで、esc を使う以外で挿入モードからノーマルモードに戻る方法をまとめました。

解決案

1. ctrl + 3を使う

これは正統派ですね。元々 esc 使わなくてもこのコマンドでいけますので。

2. .vimrc に inoremap jj <esc>を追加する

私はこれを使っています。
挿入モードの時に jjと押したらノーマルモードに戻ります。
何がいいって完全にホームポジションから手を動かさずに実行できるところですね。
二回キー入力をするので若干遅いかもしれませんが、それを補って余りある楽さがあります。

VSCode の Vim プラグインにコントリビュートした!

$
0
0

この記事は、VisualStudioCode AdventCalendar 2017 8日目の記事です。

はじめに

2017 年は私にとって Vim を使い始めた年になりました。
しかし普段は IDE などにある Vim のプラグインを使っています。

そして VSCode にも Vim のプラグインがあります!

Vim for Visual Studio Code

Vim for Visual Studio Code

目からウロコ、Vim の EasyMotion プラグイン

Vim には沢山のプラグインがあり、その中に EasyMotion というカーソル移動を爆速で行えるプラグインがあります。イメージで言うと、目線の先にカーソルを移動することができるスグレモノです。

EasyMotion の機能についは、現在保守を行っている方のブログ記事に詳しく説明されています。

Vimのカーソル移動はもっともっと爆速になる! Vim-EasyMotion v3.0 をリリースしました

Imgur

(たとえば "wo" から始まる箇所へ一瞬でジャンプすることが出来ます)

勢いでコントリビュート

人気プラグインのため VSCodeVim でも EasyMotion がサポートされていたのですが、やや機能が足りていなかったので思い切って機能追加をしてコントリビュートすることにしました。

VSCode の拡張機能は TS もしくは JS で簡単開発

VSCodeVim は TypeScript で作られていたので、TypeScript (もしくは JavaScript) が分かる人なら機能追加もそう難しくありません。

EasyMotion ではカーソル移動先を強調表示するという挙動がありますが、VSCodeの拡張機能用 API に Decoration APIというものがあるので再現可能です。

VSCode の登場時は拡張機能がそもそもサポートされていませんでしたが、現在はかなり細かい所にも手が届きます。拡張機能の作りやすさ、自由度の高さは VSCode の非常に良いところだと思います。

VSCode の拡張機能用 API 一覧 (英語)

さいごに

VSCode の話なんだか Vim の話なんだかよく分からなくなってしまいました...。

VSCodeを含め、たいていのプラグインは GitHub でホストされている OSS なので、お気に入りのプラグインがあったら思い切ってコントリビュートすると良いと思います。

VSCode と VSCode のプラグインを盛り上げていきましょう!

vim,emacsそしてevilへ

$
0
0

vim,emacsそしてevilへ

evilとは

emacsのpluginの一つでemacs上でvimの操作が可能になるものです。
少し説明すると、emacsにステート(vimのモードのようなもの)が追加され、emacsステート、vimステートの2つに分かれます。
emacsステートは、emacsのキーバインド操作が可能です。
vimステートは、vimのキーバインド操作と、vimのモード(ノーマル、インサート、ヴィジュアル)も存在します。
どうでしょうか?少し 興味が出てきた方はインストールしてみてはいかがでしょうか?

インストール方法

evilはemacsのversionが24以上出ないと動作しません。
macの標準で入っているemacsはversionが24未満なのでupdateしましょう。
(versionの確認方法 $ emacs --version)

emacsのversionが24未満の方

$ brew upgrade emacs

$ emacs --versionGNU Emacs 25.3.1と表示されれば大丈夫です。

emacsが入っていない方

$ brew install emacs(オプションに--with-cocoaをつけるとGUI版も一緒にinstallされるらしいが、CUI派のため、つけない)

init.elに以下を追加

init.el
(whenload-file-name(setquser-emacs-directory(file-name-directoryload-file-name)))(require'package)(add-to-list'package-archives'("marmalade"."http://marmalade-repo.org/packages/"))(package-initialize)(defunpackage-install-with-refresh(package)(unless(assqpackagepackage-alist)(package-refresh-contents))(unless(package-installed-ppackage)(package-installpackage)))(package-install-with-refresh'evil)(require'evil)(evil-mode1)

この設定は、忘れてしまいましたが、どこかのサイトを参考にしました。
emacsを再起動すれば、設定が反映されます。

操作方法

evilを導入すると、emacsステート、vimステートが存在し、前述でも説明した通り対応した操作が
可能になります。
ステートに切り替え方法ですが、C-zで切り替え可能です。
現在のステートの確認方法は、モードラインの行数の隣に表示されています。

emacsステート

emacs操作が可能なステートです。
モードラインに<E>と表示されます。

vimステート

vim操作が可能なステートです。
モードラインに<N>と表示されているときはノーマルモード、<I>のときはインサートモード、<V>のときはヴィジュアルモードに相当します。
<N>(ノーマルモード)から<I>(インサートモード)への切り替えはvimと同様です。

emacsでvim操作ができるなんと面白いですよね。
すでにemacsの方は導入の検討を、vimmerな方はぜひ一度試されてはいかかでしょうか?

終わりに

vimを使っている方はvimmer,emacsを使っている人はemacserと呼ぶのでしょうか?emacserは少し、言いにくい気がしますね。


補完プラグイン用 source の asyncomplete-omni.vim を作りました

$
0
0

はじめに

この記事は Vim Advent Calendar 2017 9日目の記事です。
昨年は タブページ数に応じて幅が変わる tabline プラグインを作成しました - Qiitaという記事を Advent Calender で書きました。
今年は yami-beta/asyncomplete-omni.vimというプラグインを作ったので、こちらを Advent Calener で掲載します。

asyncomplete-omni.vim

asyncomplete-omni.vim は prabirshrestha/asyncomplete.vim用の source でオムニ補完候補を渡すプラグインとなっています。

asyncomplete.vim とは

prabirshrestha 氏による Vim 8, Neovim 用の補完プラグインです。
Language Server Protocol 用のプラグインである prabirshrestha/vim-lspの作者でもあります。

作った経緯

補完プラグインの乗り換え先を探していたときに偶然 asyncomplete.vim を発見しました。
asyncomplete.vim 自体は補完プラグインというより、補完ポップアップを表示するためのライブラリみたいな実装です。

中身を見たときに、オムニ補完用 source を作れば filetype ごとに source を入れなくても良いのではないだろうか、という 思いつきで作り始めました。

asyncomplete-omni.vim の仕組み

asyncomplete-omni.vim は以下の流れで補完候補を取得しています。
基本的には omnifuncを実行し、補完候補を asyncomplete.vim に渡しているだけです。

  1. 現在のバッファの omnifuncを Funcref で取得
  2. asyncomplete#sources#omni#completorの引数でカーソル位置と入力中のテキストが取得
  3. オムニ補完の Funcref を第一引数を 1にして呼び出す(1回目)
    • omnifuncは第一引数の値で、補完テキストの始点を返す or 補完候補を返す
    • omnifuncによっては、第一引数を 1にした状態で1度呼び出さないと補完候補を用意しないものがある
    • :h complete-functions
  4. カーソル位置と入力中のテキストををオムニ補完の Funcref に渡して呼び出す(2回目)
  5. 取得した補完候補を asyncomplete.vim に合わせて整形し返す

Github に公開してみると

自分がよく使う filetype で補完候補が出ることを確認した後、Github に公開したのが 2017年5月27日です。
それから2週間ほどで以下の issue が出来ていました。
send PR to asyncomplete.vim to be included in README.md · Issue #1 · yami-beta/asyncomplete-omni.vim

asyncomplete.vim の作者である prabirshrestha 氏から README に載せるから Pull Request を送ってくれという内容でした。
思いつきで作ったプラグインが、まさか作者本人に試してもらえるとは思いもよりませんでした。

こうして asyncomplete-omni.vim は asyncomplete.vim の README に、作者以外で最初に載った source になりました :tada:
(コミットログで確認)

asyncomplete-omni.vim を自分で使ってみて

ノリと勢いで作った感があるプラグインですが、しばらく試した後完全に乗り換えました。
強力な補完や高速な補完が欲しいというよりは、とりあえず補完候補が自動で出ればラッキーなくらいのものを自分は求めており asyncomplete.vim が程よく条件を満たしていたので、乗り換え出来ました。

asyncomplete-omni.vim を使っていて一番驚いたのが fatih/vim-goを入れて Go のコードを書き始めたときです。
vim-go は omnifuncを設定するため asyncomplete-omni.vim で自動で補完候補が表示でき、これが思っていた以上に快適でした。
gocode が高速なこともあり asyncomplete.vim, asyncomplete-omni.vim, vim-go の組み合わせで、それなりに快適な Go を書く環境が出来ました。

asyncomplete-omni.vim の欠点

  • 非同期では無い
  • omnifuncによっては上手く動かない

asyncomplete-omni.vim という名前にも関わらず、非同期処理ではありません。
以下のような処理を jobかなにかで出来れば、非同期化も可能かもしれないと思いつつ、中身が複雑になりそうなので手をつけていません…

  1. 現在のバッファを一時ファイルとして保存し、別バッファで開く
  2. 別バッファで omnifuncを実行し補完候補を取得
  3. 元のバッファで補完候補を受け取り、asyncomplete.vim で表示

また omnifuncによって、動かない場合があることも把握しています。
下記の issue では、カーソルを移動させる omnifuncがあることが分かりました。
Cursor jumps around with completions · Issue #4 · yami-beta/asyncomplete-omni.vim

おわりに(asyncomplete-omni.vim の今後)

昨今、Language Server Protocol (LSP) の普及により、様々な言語で Language Server が用意されるようになりました。
asyncomplete.vim にも LSP 用の source である prabirshrestha/asyncomplete-lsp.vimがあるため、いずれこの source だけであらゆる言語の補完が可能になる未来がやってくるかもしれません。
もしそうなれば asyncomplete-omni.vim は役割を失いますが、それはむしろ喜ばしいことではないかと個人的には考えています。

様々な言語で、開発環境を問わず同じ支援が受けられるようになる日まで、緩やかに asycomplete-omni.vim の開発を続けていこうと思います。

GoでVimを開いて編集内容をパースする方法

$
0
0

動機

私の現在働いている会社では、GitLabを使用して開発を行っています。
その中でIssueやMRを作成するたびにWeb画面がもっさり表示され、本来するべきである
書く。という作業にたどり着くまでに非常に多くのステップや時間が費やされることに不満を感じていました。

私は現在labコマンドというGitLabのCLIクライアントを作成しており、
上記不満を解消するため新規投稿コマンドを実行するとテキストエディタを開いてIssueやMR内容を記載し、
ファイルを保存することで、編集内容がそのままリクエストされるという機能を思いつきました。

要するにgit commitした瞬間に発動するアレです。

アレな動作の動画

本日はGoでアレな機能を作る過程でできたマイクロコードを用いて、アレの実現方法をご紹介致します。

なおCLIで細々オプションを指定して書いていっても良いのですが、
改行が含まれたりする長文を考えながら記載する場合、
ワンラインで編集するのはなかなかにストレスが貯まる作業かと思います。
今回の目的以外にも、幅広い用途で使えるのではと思います。CLIの梯子の力...ヤバイ。

なお今回使用するコードはhubコマンドからちょろっと拝借したコードを分析するため、
バリバリ構造化された内容を解きほぐして1ファイルに収めたものとなっております。
なので、こんな泥臭いコードでなくてもっと構造化されたものを見たいという方は、
hubコマンドの以下ファイルを眺めてみると良いかと思います。

https://github.com/github/hub/blob/master/github/editor.go

ゴール

最終的なゴールは以下の機能の実装です。

  1. コマンドを実行するとVimが起動する
  2. 起動したVimには、どのように記載すれば目的どおりの編集が可能であるかのガイドラインをコメントとして表示する
  3. Vimで編集/保存した内容をGoで読み取りし目的となる結果を得る

まずは結論から

うだうだ言ってないでコード出せ。という方は以下のリポジトリをご参照ください。

lighttiger2505/launch-vim

実装内容

幾つかのステップに分けてご紹介していこうと思います。

ステップ1: とりあえずGoからVimを開く

とりあえずVimを開かなければお話になりません。
何も考えずにos/execパッケージでVimを実行してみましょう。

packagemainimport("fmt""os""os/exec")funcmain(){exitStatus:=launchVim()os.Exit(exitStatus)}funclaunchVim()int{// Open text editorerr:=openEditor("vim")iferr!=nil{fmt.Fprint(os.Stdout,fmt.Sprintf("failed open text editor. %s\n",err.Error()))return1}return0}funcopenEditor(programstring)error{c:=exec.Command(program)c.Stdin=os.Stdinc.Stdout=os.Stdoutc.Stderr=os.Stderrreturnc.Run()}

実行してみると...やったーVimが開いたよー。

とりあえずGoからVimを開く動画

ステップ2: tmpファイルを用意してVimで編集する

ステップ1のコードを見て気がついた人もいらっしゃるでしょうが
なんと。ステップ1のままではVimが起動するだけで編集した内容を受け取ることができません。
これではまるで意味がありません。

なので次は以下の機能を実装します。

  • プログラム起動時にVimで開くためのtmpファイルを作成する(今回は~/tmpにご用意しました。)
  • Vimで該当のファイルを開く
  • 編集後のファイルを読み取りして、内容を取得する
packagemainimport("fmt""io/ioutil""os""os/exec""path/filepath""runtime")funcmain(){exitStatus:=launchVim()os.Exit(exitStatus)}funclaunchVim()int{// Make temp editing filefPath:=getFilePath("ISSUE")err:=makeFile(fPath)iferr!=nil{fmt.Fprint(os.Stdout,fmt.Sprintf("failed make edit file. %s\n",err.Error()))return1}deferdeleteFile(fPath)// Open text editorerr=openEditor("vim",fPath)iferr!=nil{fmt.Fprint(os.Stdout,fmt.Sprintf("failed open text editor. %s\n",err.Error()))return1}// Read edit filecontent,err:=ioutil.ReadFile(fPath)iferr!=nil{fmt.Fprint(os.Stdout,fmt.Sprintf("failed read content. %s\n",err.Error()))return1}fmt.Fprint(os.Stdout,string(content))return0}funcgetFilePath(aboutstring)string{home:=os.Getenv("HOME")ifhome==""&&runtime.GOOS=="windows"{home=os.Getenv("APPDATA")}fname:=filepath.Join(home,"tmp",fmt.Sprintf("%s_EDITMSG",about))returnfname}funcmakeFile(fPathstring)(errerror){if!isFileExist(fPath){err=ioutil.WriteFile(fPath,[]byte(""),0644)iferr!=nil{return}}return}funcisFileExist(fPathstring)bool{_,err:=os.Stat(fPath)returnerr==nil||!os.IsNotExist(err)}funcdeleteFile(fPathstring)error{returnos.Remove(fPath)}funcopenEditor(programstring,args...string)error{c:=exec.Command(program,args...)c.Stdin=os.Stdinc.Stdout=os.Stdoutc.Stderr=os.Stderrreturnc.Run()}

実行してみると...こいつ。読めるぞっ

tmpファイルを用意してVimで編集する動画

というわけでなんとなくそれっぽい感じになってきました。

ステップ3: コメントとかでガイドしたとおりVimで編集されたファイルをパースする

ステップ2ではプログラムにおけるI/Oが出来上がりました。
あとプログラムに必要な要素は何でしょうか?

そう。インプットされた内容を加工し、適切に整形した内容をアウトプットすること。
要するにデータのフィルターや加工です。
これができればプログラムはもはや完成したといっても過言ではないでしょう。

今回はGitLabのIssueやMRが書きたいので、その目的に則した内容にします。
なので次は以下の機能を実装します。

  • ファイル作成時にガイドラインとして活用するコメント行をファイルに書き込む
  • Vimをファイルタイプgitcommitで起動し、コメント行を解釈できるようにする
  • 編集後のファイルからコメント行を除外し、タイトルと内容を個別に取得する
packagemainimport("bufio""bytes""fmt""io""io/ioutil""os""os/exec""path/filepath""regexp""runtime""strings")funcmain(){exitStatus:=launchVim()os.Exit(exitStatus)}funclaunchVim()int{message:=`# |<----  Opened the file with your favorite editor. The first block of text is the title.  ---->|# |<----  The following blocks are explanations  ---->|`// Make temp editing filefPath:=getFilePath("ISSUE")err:=makeFile(fPath,message)iferr!=nil{fmt.Fprint(os.Stdout,fmt.Sprintf("failed make edit file. %s\n",err.Error()))return1}deferdeleteFile(fPath)// Open text editorerr=openEditor("vim","--cmd","set ft=gitcommit tw=0 wrap lbr",fPath)iferr!=nil{fmt.Fprint(os.Stdout,fmt.Sprintf("failed open text editor. %s\n",err.Error()))return1}// Read edit filecontent,err:=ioutil.ReadFile(fPath)iferr!=nil{fmt.Fprint(os.Stdout,fmt.Sprintf("failed read content. %s\n",err.Error()))return1}// Parce read contentreader:=bytes.NewReader(content)title,body,err:=perseTitleAndBody(reader,"#")iferr!=nil{fmt.Fprint(os.Stdout,fmt.Sprintf("failed parce content. %s\n",err.Error()))return1}fmt.Fprint(os.Stdout,fmt.Sprintf("title=%s, body=%s\n",title,body))return0}funcgetFilePath(aboutstring)string{home:=os.Getenv("HOME")ifhome==""&&runtime.GOOS=="windows"{home=os.Getenv("APPDATA")}fname:=filepath.Join(home,"tmp",fmt.Sprintf("%s_EDITMSG",about))returnfname}funcmakeFile(fPath,messagestring)(errerror){// only write message if file doesn't existif!isFileExist(fPath)&&message!=""{err=ioutil.WriteFile(fPath,[]byte(message),0644)iferr!=nil{return}}return}funcisFileExist(fPathstring)bool{_,err:=os.Stat(fPath)returnerr==nil||!os.IsNotExist(err)}funcdeleteFile(fPathstring)error{returnos.Remove(fPath)}funcopenEditor(programstring,args...string)error{c:=exec.Command(program,args...)c.Stdin=os.Stdinc.Stdout=os.Stdoutc.Stderr=os.Stderrreturnc.Run()}funcperseTitleAndBody(readerio.Reader,csstring)(title,bodystring,errerror){vartitleParts,bodyParts[]stringr:=regexp.MustCompile("\\S")scanner:=bufio.NewScanner(reader)forscanner.Scan(){line:=scanner.Text()ifstrings.HasPrefix(line,cs){continue}iflen(bodyParts)==0&&r.MatchString(line){titleParts=append(titleParts,line)}else{bodyParts=append(bodyParts,line)}}iferr=scanner.Err();err!=nil{return}title=strings.Join(titleParts," ")title=strings.TrimSpace(title)body=strings.Join(bodyParts,"\n")body=strings.TrimSpace(body)return}

実行してみると...これや。これが欲しかったんや!

コメントとかでガイドしたとおりVimで編集されたファイルをパースする動画

最後に

もちろん起動方法やパース方法を工夫することでVim以外のテキストエディタにも適用可能です。
Emacsな貴方もnanoな貴方も、そしてviなあなたにも。

しかし、コードが無駄に長くなってしまった。精進せねば。

あと、gifアニメを簡単につくれるツールを誰かおしえて。

vimでバッファやレジスタをコマンドラインに貼り付け

$
0
0

無名レジスタの内容をコマンドラインに貼り付け

:<C-r>"
で無名レジスタの内容をコマンドラインに貼り付け

また,挿入モードやコマンドラインモードで
<C-r>"
とするとカーソル位置に無名レジスタの内容を貼り付け.
"
の部分はレジスタ名.

バッファの内容が
1 abc def ghi
dの位置にカーソルがあり,ノーマルモードとする.
yw:<C-r>"
とタイプするとコマンドラインモードで以下となる.
:def_ (_はスペース)
(カーソル位置はスペースの1つ後ろ.)

上の例の解説

(レジスタについての解説はしません.)
yw
"(無名レジスタ) に def_をコピー.
:<C-r>
とタイプするとコマンドラインモードで以下の状態になる.
:"
(カーソルは"の位置)
この状態でレジスタ名をタイプするとそのレジスタの内容をカーソル位置に貼り付け.
つまり"(無名レジスタ)を張り付けたい場合は"(ダブルクォーテーション)をタイプ.

おまけ

:
でコマンドを打ち込める状態は
Command-line mode
と言うそうです.
:help command-line-mode

vim-airlineでステータスバーにgitのブランチを出力させるのに苦労した

$
0
0

vim-airline

カッコいい。
カタチだけなのはダメだけど、やっぱりカタチも大事です。

GitHubに事細かに書いてくれているので、説明は割愛。
https://github.com/vim-airline/vim-airline

環境

OS:Ubuntu 16.04 LTS
VIM: 8.0

問題発生

vim-airlineを使ってカッコいいVim生活を送っていたつもりになっていたのに、ある日違和感に気付いた。
範囲を選択_022.png

あれ?コレが出てない???
範囲を選択_021.png


vim-airlineの上記ページで大量にアップされている画像たちにもしっかりブランチ名表示されてる。
自分も表示させたい!!!

解決方法

プラグインマネージャにdeinを使っているんですが、
fugitiveの設定がメインのTOMLと遅延ロード用のTOMLの両方に書かれてました。

dein.toml
[[plugins]]repo='tpope/vim-fugitive'

遅延ロード用のTOMLにも記述があるのは誤りなので削除。
だいぶハマってしまって一回諦めかけたけど、無事解決してよかった!
範囲を選択_023.png

VSCodeのVimでVSCode本体のUndo/Redoを使う

$
0
0

はじめに

VSCodeVimのデフォルトのUndo/Redoは、拡張機能側の独自実装なので、本来のVSCodeのUndo/Redo機能とは挙動が多少異なることがある。

  • Undoで変更前の状態に戻しても変更されたファイルとして扱われる
  • 外部 (Git等) でファイルの内容が変更された場合、全く戻すことができない

大きな問題にはならないが、違和感を感じたので、ユーザ設定を変更しVSCodeVimでVSCode本体のUndo/Redoを呼ぶように変更する。具体的には、vim.otherModesKeyBindingsを変更する。

keybindings.jsonで変更することも考えたが、uが見つからなかったため断念した。
(Ctrl+Rはできる)

ユーザ設定

以下の内容を、ユーザ設定ファイルに追加する。

settings.json
{"vim.otherModesKeyBindingsNonRecursive":[{"before":["u"],"after":[],"commands":[{"command":"undo"}]},{"before":["<C-r>"],"after":[],"commands":[{"command":"redo"}]}]}

説明

vim.otherModesKeyBindingsは、挿入モード以外でのキーバインドを上書きするために用意されている設定である。上記ではuundoを、Ctrl+Rredoを実行させている。

まとめ

VSCodeVimのUndo/Redoに対する違和感が解消できた。他にも、vim.handleKeysで一部のキーを無効にしたり、vim.insertModeKeybindingsで挿入モード時のキーバインドを変更したりできる。詳細はVSCodeVimを参照のこと。

Viewing all 5608 articles
Browse latest View live


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