既に試した方もいらっしゃるようですね。
visual_studio.vimを入れてみた - ampmmnの日記
TaskList : タスクリストの項目をquickfixに表示する。動作未確認。
Output : アウトプットの内容をquickfixに表示。動作未確認。
Solutions : これはVisualStudioを複数走らせている時に、どれと通信するかを選択するものらしい。自分の環境で実行したら、何かエラーメッセージが出力された。でも機能はしているようだ。
Projects : どのプロジェクトをアクティブ(スタートアップ)にするかを選択する。動作未確認。
http://d.hatena.ne.jp/ampmmn/20080809/1218230946
visual_studio.vim,python,unicodeencodeerror - gnarl、技術メモ
visual_studio.vimを導入してみたものの同梱pythonスクリプトのstr(name)のあたりでunicodeencodeerrorが出て困りましたね。
...
projectsメニューの一部がなぜか文字化けしますが
http://d.hatena.ne.jp/gnarl/20071012/1192181729
さまざまな言語のコメントON/OFFに対応した便利プラグイン - Seasons.NET
ただし、日本語版は、日本語エンコードに不具合があるので、アウトプット文字列が表示できないです。
http://d.hatena.ne.jp/Seasons/20070613/1181629449
もったいないので、日本語版Visual Studioでも動作する様に修正してみました。
ポイントは、DDE通信を行ってウィンドウを取得した後、ウィンドウキャプションで目的のサブウィンドウを探している所。
英語版で想定されているので、"Output"は"出力"、"Find Result 1/Find Result 2"は"検索結果 1/検索結果 2"に、"Build"は"ビルド"に修正する必要があります。
せっかくなので、vimに表示されるメニューも修正しました。見栄えはこんな感じ。
一応、全てのメニューが動作する様にしてあります。
ちなみに、プロジェクト一覧の取得では
str(dict)
を使ってvimのDictionaryに引き渡している為、ダブルクォートでないと"\xXX\xXX"なマルチバイトを解釈出来ないvimでは正しく表示されていませんでした。
今回の修正では、simplejsonを使い
simplejson.dumps(obj, ensure_ascii=False).decode('utf-8').encode('mbcs')
を使うことでマルチバイトなvimのDictionary形式への変換を行っています。
ソース差分は以下の通り。
diff -cr plugin.orig/visual_studio.py plugin/visual_studio.py
*** plugin.orig/visual_studio.py Fri Sep 28 20:51:49 2007
--- plugin/visual_studio.py Mon Aug 18 22:59:17 2008
***************
*** 1,3 ****
--- 1,4 ----
+ # -*- coding: ms932 -*-
'''
Companion file to visual_studio.vim
Version 1.2
***************
*** 7,12 ****
--- 8,14 ----
'''
import os, re, sys, time, pywintypes, win32com.client
+ import simplejson
import logging
_logging_enabled = False
***************
*** 42,48 ****
return
# ExecuteCommand is not synchronous so we have to wait
_dte_wait_for_build (dte)
! dte_output (vs_pid, fn_quickfix, 'Output')
_vim_status ('Compile file complete')
_vim_activate ()
--- 44,50 ----
return
# ExecuteCommand is not synchronous so we have to wait
_dte_wait_for_build (dte)
! dte_output (vs_pid, fn_quickfix, '出力')
_vim_status ('Compile file complete')
_vim_activate ()
***************
*** 77,83 ****
_dte_exception (e)
_vim_activate ()
return
! dte_output (vs_pid, fn_quickfix, 'Output')
_vim_status ('Build solution complete')
_vim_activate ()
--- 79,85 ----
_dte_exception (e)
_vim_activate ()
return
! dte_output (vs_pid, fn_quickfix, '出力')
_vim_status ('Build solution complete')
_vim_activate ()
***************
*** 116,122 ****
_dte_exception (e)
_vim_activate ()
return
! dte_output (vs_pid, fn_quickfix, 'Output')
_vim_status ('Build project complete')
_vim_activate ()
--- 118,124 ----
_dte_exception (e)
_vim_activate ()
return
! dte_output (vs_pid, fn_quickfix, '出力')
_vim_status ('Build project complete')
_vim_activate ()
***************
*** 147,153 ****
if not dte: return
task_list = None
for window in dte.Windows:
! if str(window.Caption).startswith('Task List'):
task_list = window
if not task_list:
_vim_msg ('Error: Task List window not active')
--- 149,155 ----
if not dte: return
task_list = None
for window in dte.Windows:
! if window.Caption.encode('mbcs').startswith('タスク一覧'):
task_list = window
if not task_list:
_vim_msg ('Error: Task List window not active')
***************
*** 155,165 ****
TL = task_list.Object
for i in range (1, TL.TaskItems.Count+1):
TLItem = TL.TaskItems.Item(i)
! try: filename = TLItem.FileName
except: filename = '<no-filename>'
try: line = TLItem.Line
except: line = '<no-line>'
! try: description = TLItem.Description
except: description = '<no-description>'
print >>fp_task_list, '%s(%s) : %s' % (filename, line, description)
fp_task_list.close ()
--- 157,167 ----
TL = task_list.Object
for i in range (1, TL.TaskItems.Count+1):
TLItem = TL.TaskItems.Item(i)
! try: filename = TLItem.FileName.encode('mbcs')
except: filename = '<no-filename>'
try: line = TLItem.Line
except: line = '<no-line>'
! try: description = TLItem.Description.encode('mbcs')
except: description = '<no-description>'
print >>fp_task_list, '%s(%s) : %s' % (filename, line, description)
fp_task_list.close ()
***************
*** 170,176 ****
def dte_output (vs_pid, fn_output, window_caption, notify=None):
logging.info ('== dte_output %s' % vars())
! if window_caption not in ['Find Results 1', 'Find Results 2', 'Output']:
_vim_msg ('Error: unrecognized window (%s)' % window_caption)
return
dte = _get_dte(vs_pid)
--- 172,178 ----
def dte_output (vs_pid, fn_output, window_caption, notify=None):
logging.info ('== dte_output %s' % vars())
! if window_caption not in ['検索結果 1', '検索結果 2', '出力']:
_vim_msg ('Error: unrecognized window (%s)' % window_caption)
return
dte = _get_dte(vs_pid)
***************
*** 179,191 ****
if not window:
_vim_msg ('Error: window not active (%s)' % window_caption)
return
! if window_caption == 'Output':
! owp = window.Object.OutputWindowPanes.Item ('Build')
sel = owp.TextDocument.Selection
else:
sel = window.Selection
sel.SelectAll()
! lst_text = str(sel.Text).splitlines()
lst_text = _fix_filenames (os.path.dirname(dte.Solution.FullName), lst_text)
sel.Collapse()
fp_output = file (fn_output, 'w')
--- 181,193 ----
if not window:
_vim_msg ('Error: window not active (%s)' % window_caption)
return
! if window_caption == '出力':
! owp = window.Object.OutputWindowPanes.Item ('ビルド')
sel = owp.TextDocument.Selection
else:
sel = window.Selection
sel.SelectAll()
! lst_text = str(sel.Text.encode('mbcs')).splitlines()
lst_text = _fix_filenames (os.path.dirname(dte.Solution.FullName), lst_text)
sel.Collapse()
fp_output = file (fn_output, 'w')
***************
*** 280,286 ****
startup_project_index = index
lst_result.append (_dte_project_tree(project))
index += 1
! _vim_command ('let s:visual_studio_lst_project = %s' % lst_result)
_vim_command ('let s:visual_studio_startup_project_index = %s' % startup_project_index)
def _dte_project_tree (project):
--- 282,288 ----
startup_project_index = index
lst_result.append (_dte_project_tree(project))
index += 1
! _vim_command ('let s:visual_studio_lst_project = %s' % simplejson.dumps(lst_result, ensure_ascii=False).decode('utf-8').encode('mbcs'))
_vim_command ('let s:visual_studio_startup_project_index = %s' % startup_project_index)
def _dte_project_tree (project):
***************
*** 290,296 ****
name = _com_property (project, 'Name')
if not name:
return []
! name = str(name)
properties = _com_property(project, 'Properties')
if properties:
try: full_path = str(properties['FullPath'])
--- 292,298 ----
name = _com_property (project, 'Name')
if not name:
return []
! name = name.encode('utf-8')
properties = _com_property(project, 'Properties')
if properties:
try: full_path = str(properties['FullPath'])
***************
*** 441,447 ****
def _dte_output_activate (vs_pid):
dte = _get_dte(vs_pid)
if not dte: return
! window = _dte_get_window(dte, 'Output')
if not window: return
window.Activate()
--- 443,449 ----
def _dte_output_activate (vs_pid):
dte = _get_dte(vs_pid)
if not dte: return
! window = _dte_get_window(dte, '出力')
if not window: return
window.Activate()
diff -cr plugin.orig/visual_studio.vim plugin/visual_studio.vim
*** plugin.orig/visual_studio.vim Thu Sep 27 05:57:47 2007
--- plugin/visual_studio.vim Tue Aug 19 09:07:25 2008
***************
*** 226,232 ****
function! DTEOutput()
let &errorfile = g:visual_studio_output
! call <Sid>DTEExec ('dte_output', &errorfile, 'Output')
endfunction
"----------------------------------------------------------------------
--- 226,232 ----
function! DTEOutput()
let &errorfile = g:visual_studio_output
! call <Sid>DTEExec ('dte_output', &errorfile, '出力')
endfunction
"----------------------------------------------------------------------
***************
*** 234,243 ****
function! DTEFindResults(which)
if a:which == 1
let &errorfile = g:visual_studio_find_results_1
! let window_caption = 'Find Results 1'
else
let &errorfile = g:visual_studio_find_results_2
! let window_caption = 'Find Results 2'
endif
call <Sid>DTEExec ('dte_output', &errorfile, window_caption)
endfunction
--- 234,243 ----
function! DTEFindResults(which)
if a:which == 1
let &errorfile = g:visual_studio_find_results_1
! let window_caption = '検索結果 1'
else
let &errorfile = g:visual_studio_find_results_2
! let window_caption = '検索結果 2'
endif
call <Sid>DTEExec ('dte_output', &errorfile, window_caption)
endfunction
***************
*** 299,305 ****
endif
if gui_menu
echo 'Found '.len(s:visual_studio_lst_dte).' VisualStudio instance(s)'
! popup! VisualStudio.Solutions
else
call <Sid>DTESolutionTextMenu()
endif
--- 299,305 ----
endif
if gui_menu
echo 'Found '.len(s:visual_studio_lst_dte).' VisualStudio instance(s)'
! popup! VisualStudio.ソリューション(&S)
else
call <Sid>DTESolutionTextMenu()
endif
***************
*** 307,313 ****
function! <Sid>DTESolutionGuiMenuCreate()
try
! aunmenu VisualStudio.Solutions
catch
endtry
let menu_num = 0
--- 307,313 ----
function! <Sid>DTESolutionGuiMenuCreate()
try
! aunmenu VisualStudio.ソリューション(&S)
catch
endtry
let menu_num = 0
***************
*** 320,331 ****
else
let leader = '\ \ \ &'.menu_num
endif
! exe 'amenu <silent> .810 &VisualStudio.&Solutions.'.leader.'\ '.dte_sln.' :call <Sid>DTESolutionMenuChoice('.menu_num.')<cr>'
endfor
if len(s:visual_studio_lst_dte) > 0
! amenu <silent> &VisualStudio.&Solutions.-separator- :
endif
! amenu <silent> &VisualStudio.&Solutions.&Refresh :call DTEGetSolutions(1)<cr>
endfunction
function! <Sid>DTESolutionTextMenu()
--- 320,331 ----
else
let leader = '\ \ \ &'.menu_num
endif
! exe 'amenu <silent> .810 &VisualStudio.ソリューション(&S).'.leader.'\ '.dte_sln.' :call <Sid>DTESolutionMenuChoice('.menu_num.')<cr>'
endfor
if len(s:visual_studio_lst_dte) > 0
! amenu <silent> &VisualStudio.ソリューション(&S).-separator- :
endif
! amenu <silent> &VisualStudio.ソリューション(&S).更新(&R) :call DTEGetSolutions(1)<cr>
endfunction
function! <Sid>DTESolutionTextMenu()
***************
*** 393,399 ****
endif
if gui_menu
echo 'Found '.len(s:visual_studio_lst_project).' project(s)'
! popup! VisualStudio.Projects
else
call <Sid>DTEProjectTextMenu()
endif
--- 393,399 ----
endif
if gui_menu
echo 'Found '.len(s:visual_studio_lst_project).' project(s)'
! popup! VisualStudio.プロジェクト(&J)
else
call <Sid>DTEProjectTextMenu()
endif
***************
*** 401,407 ****
function! <Sid>DTEProjectGuiMenuCreate()
try
! aunmenu VisualStudio.Projects
catch
endtry
let menu_num = 0
--- 401,407 ----
function! <Sid>DTEProjectGuiMenuCreate()
try
! aunmenu VisualStudio.プロジェクト(&J)
catch
endtry
let menu_num = 0
***************
*** 414,422 ****
else
let leader = '\ \ \ &'.menu_num
endif
! let project_name_menu = '&VisualStudio.Pro&jects.'.leader.'\ '.escape(project_name, '\. ')
! exe 'amenu <silent> .820 '.project_name_menu.'.&Build\ Project :call <Sid>DTEProjectMenuBuildChoice('.menu_num.')<cr>'
! exe 'amenu <silent> .820 '.project_name_menu.'.Set\ Start&up\ Project :call <Sid>DTEProjectMenuStartupChoice('.menu_num.')<cr>'
exe 'amenu <silent> .820 '.project_name_menu.'.-separator- :<cr>'
if type(project_children) == type([])
for child in project_children
--- 414,422 ----
else
let leader = '\ \ \ &'.menu_num
endif
! let project_name_menu = '&VisualStudio.プロジェクト(&J).'.leader.'\ '.escape(project_name, '\. ')
! exe 'amenu <silent> .820 '.project_name_menu.'.プロジェクトをビルド(&B) :call <Sid>DTEProjectMenuBuildChoice('.menu_num.')<cr>'
! exe 'amenu <silent> .820 '.project_name_menu.'.スタートアッププロジェクトに設定(&U) :call <Sid>DTEProjectMenuStartupChoice('.menu_num.')<cr>'
exe 'amenu <silent> .820 '.project_name_menu.'.-separator- :<cr>'
if type(project_children) == type([])
for child in project_children
***************
*** 425,433 ****
endif
endfor
if len(s:visual_studio_lst_project) > 0
! amenu <silent> .820 &VisualStudio.Pro&jects.-separator- :
endif
! amenu <silent> .820 &VisualStudio.Pro&jects.&Refresh :call DTEGetProjects(1, 1)<cr>
endfunction
function! <Sid>DTEProjectGuiSubMenuCreate(menu, name, value)
--- 425,433 ----
endif
endfor
if len(s:visual_studio_lst_project) > 0
! amenu <silent> .820 &VisualStudio.プロジェクト(&J).-separator- :
endif
! amenu <silent> .820 &VisualStudio.プロジェクト(&J).更新(&R) :call DTEGetProjects(1, 1)<cr>
endfunction
function! <Sid>DTEProjectGuiSubMenuCreate(menu, name, value)
***************
*** 510,526 ****
" Menu setup
if has('gui') && ( ! exists('g:visual_studio_menu') || g:visual_studio_menu != 0 )
! amenu <silent> &VisualStudio.&Get\ File :call DTEGetFile()<cr>
! amenu <silent> &VisualStudio.&Put\ File :call DTEPutFile()<cr>
amenu <silent> &VisualStudio.-separator1- :
! amenu <silent> &VisualStudio.&Task\ List :call DTETaskList()<cr>
! amenu <silent> &VisualStudio.&Output :call DTEOutput()<cr>
! amenu <silent> &VisualStudio.&Find\ Results\ 1 :call DTEFindResults(1)<cr>
! amenu <silent> &VisualStudio.Find\ Results\ &2 :call DTEFindResults(2)<cr>
amenu <silent> &VisualStudio.-separator2- :
! amenu <silent> &VisualStudio.&Build\ Solution :call DTEBuildSolution()<cr>
! amenu <silent> &VisualStudio.Build\ Start&up\ Project :call DTEBuildStartupProject()<cr>
! amenu <silent> &VisualStudio.&Compile\ File :call DTECompileFile()<cr>
amenu <silent> &VisualStudio.-separator3- :
call <Sid>DTESolutionGuiMenuCreate()
call <Sid>DTEProjectGuiMenuCreate()
--- 510,526 ----
" Menu setup
if has('gui') && ( ! exists('g:visual_studio_menu') || g:visual_studio_menu != 0 )
! amenu <silent> &VisualStudio.ファイルを取得(&G) :call DTEGetFile()<cr>
! amenu <silent> &VisualStudio.ファイルを反映(&P) :call DTEPutFile()<cr>
amenu <silent> &VisualStudio.-separator1- :
! amenu <silent> &VisualStudio.タスクリスト(&T) :call DTETaskList()<cr>
! amenu <silent> &VisualStudio.出力(&O) :call DTEOutput()<cr>
! amenu <silent> &VisualStudio.検索結果\ 1(&F) :call DTEFindResults(1)<cr>
! amenu <silent> &VisualStudio.検索結果\ 2(&2) :call DTEFindResults(2)<cr>
amenu <silent> &VisualStudio.-separator2- :
! amenu <silent> &VisualStudio.ソリューションをビルド(&B) :call DTEBuildSolution()<cr>
! amenu <silent> &VisualStudio.スタートアッププロジェクトをビルド(&U) :call DTEBuildStartupProject()<cr>
! amenu <silent> &VisualStudio.ファイルをコンパイル(&C) :call DTECompileFile()<cr>
amenu <silent> &VisualStudio.-separator3- :
call <Sid>DTESolutionGuiMenuCreate()
call <Sid>DTEProjectGuiMenuCreate()
Visual StudioつまりWindows限定なのでファイルの文字コードはms932としました。
動作確認はVisual Studio 2005でしか行っていません。
visual_studio_ja-20080819.zip
よろしければどうぞ。