Vim Tips Wiki
Explore
Main Page
All Pages
Community
Interactive Maps
Community portal
To do
FANDOM
Fan Central
BETA
Games
Anime
Movies
TV
Video
Wikis
Explore Wikis
Community Central
Start a Wiki
Don't have an account?
Register
Sign In
Sign In
Register
Vim Tips Wiki
1,649
pages
Explore
Main Page
All Pages
Community
Interactive Maps
Community portal
To do
Editing
Vim as a refactoring tool and some examples in C sharp
Back to page
Edit
Edit source
View history
Talk (0)
Edit Page
Vim as a refactoring tool and some examples in C sharp
We recommend that you
log in
before editing. This will allow other users to leave you a message about your edit, and will let you track edits via your
Watchlist
.
Creating an account
is quick and free.
The edit appears to have already been undone.
Anti-spam check. Do
not
fill this in!
{{review}} {{TipImported |id=589 |previous=588 |next=590 |created=2003 |complexity=intermediate |author=Klaus Horsten |version=6.0 |rating=225/77 |category1=Automated Text Insertion |category2=C sharp |category3=LanguageSpecific }} You can use Vim as a refactoring tool. The advantages are: #You automate repetitive writing tasks. #You learn refactoring. You can expect much from a refactoring tool but if you have a look at the commercial refactoring tools there is much (not all!) Vim can do too. I give you three examples, all in C#. ===Example 1: The ''Extract Method'' refactoring=== Sphagetti code example: <pre> public string CreateMenu(string startMenu,string file) { string strOutput = ""; int i = 0; ArrayList startArray = new ArrayList(); string strVariable = ""; string strTemp = ""; XmlDocument XMLDoc = new XmlDocument(); try { XMLDoc.Load(file); } catch (Exception e) { strOutput = e.GetBaseException().ToString(); return strOutput; } XmlNodeList nodeList = XMLDoc.DocumentElement.ChildNodes; ... </pre> Imagine 50 lines of code here. Use the ''extract method refactoring'' to make a ''composed method''. I use a Vim function (see below) to build the extracted method. I highlight the code part I want to extract and press <code>\em</code> (for '''e'''xtract '''m'''ethod). A dialog appears and asks me how to name the new method. I type in "GetXmlDocumentFrom" and do get this: <pre> // = GetXmlDocumentFrom(); private GetXmlDocumentFrom() { XmlDocument XMLDoc = new XmlDocument(); try { XMLDoc.Load(file); } catch (Exception e) { strOutput = e.GetBaseException().ToString(); return strOutput; } // return ; } </pre> Now I have time to think what parameters the method needs and what to return. I end up with the following function and remove it from the original function: <pre> private XmlDocument GetXmlDocumentFrom(string XmlFile) { XmlDocument XMLDoc = new XmlDocument(); string strOutput = ""; try { XMLDoc.Load(XmlFile); } catch (Exception e) { strOutput = e.GetBaseException().ToString(); ErrorMessage(strOutput); } return XMLDoc; } </pre> In the original code I put two lines. <pre> XmlDocument XMLDoc = new XmlDocument(); XMLDoc = GetXmlDocumentFrom(XmlFile); </pre> So I reduced the original code for 8 lines and made it clearer what the code does. I do this with the rest of the code again and again. Since the class gets bloated because of the many new methods I later will use the ''Extract Class'' refactoring to put this method in an own XmlDocument-class. This has the advantage that our new function is also available for other similar purposes. I will create the new class also with the help of Vim, the actual extracting of the method into the new class is just a matter of copy & paste. Here is the Vim code: <pre> vmap \em :call ExtractMethod()<CR> function! ExtractMethod() range let name = inputdialog("Name of new method:") '< exe "normal! O\<BS>private " . name ."()\<CR>{\<Esc>" '> exe "normal! oreturn ;\<CR>}\<Esc>k" s/return/\/\/ return/ge normal! j% normal! kf( exe "normal! yyPi// = \<Esc>wdwA;\<Esc>" normal! == normal! j0w endfunction </pre> ===Example 2: The ''Self Encapsulate Field'' refactoring=== I have heard a programmer who just uses Visual Studio (nothing against Visual Studio, it's a great tool!) say: "I do not use properties. It's too much work." He just uses fields instead. With Vim it is no problem to write a property, that is, to use the ''Self Encapsulate Field'' refactoring. I write a name e.g. <code>Name</code> press <code>CTRL-C CTRL-P CTRL-S</code> ('''c'''reate '''p'''roperty with '''s'''tring). Voila, the new property appears in just a second: <pre> private string m_Name; public string Name { get { return m_Name; } set { m_Name = value; } } </pre> Here are the Vim mappings and the underlying function: <pre> "Create property imap <C-c><C-p><C-s> <Esc>:call CreateProperty("string")<CR>a imap <C-c><C-p><C-i> <Esc>:call CreateProperty("int")<CR>a function! CreateProperty(type) exe "normal bim_\<Esc>b\"yywiprivate ".a:type." \<Esc>A;\<CR>public ".a:type. \ " \<Esc>\"ypb2xea\<CR>{\<Esc>oget\<CR>{\<CR>return " . \ "\<Esc>\"ypa;\<CR>}\<CR>set\<CR>{\<CR>\<Tab>\<Esc>\"yPa = value;\<CR>}\<CR>}\<CR>\<Esc>" normal! 12k2wi endfunction </pre> You can combine Visual Studio and Vim. You can work in Visual Studio and load the file in Vim for refactoring. I have made a menu entry in Visual Studio that loads the actual file I am writing in Vim (cf. [[Integrate gvim with Visual Studio#Vim as an External Tool|Vim as an External Tool]]). ===Example 3: The ''Replace Conditional with Polymorphism'' refactoring=== Imagine a switch and you want to replace it with an abstract class and some concrete classes which inherit from this parent class. You may think "Why should I replace this switch? It's too much work. Writing all these classes ..." With Vim it's just a question of a few seconds. To build the abstract class I type, say <code>Fruit</code>. Then I press <code>CTRL-C CTRL-A CTRL-C</code> ('''c'''reate '''a'''bstract '''c'''lass) and get <pre> public abstract class Fruit { public abstract void |(); } | is the cursor position </pre> Now I fill in the methods. <pre> public abstract class Fruit { public abstract void Taste(); public abstract void Color(); public abstract string GetSize(); } </pre> Now I go on the first letter of <code>Fruit</code> and type <code>CTRL-C CTRL-C CTRL-C</code> ('''c'''reate '''c'''oncrete '''c'''lass). A dialog appears and asks me for the new name of the concrete class. I type in <code>Apple</code> and get <pre> public class Apple : Fruit { public override void Taste() { } public override void Color() { } public override string GetSize() { } } </pre> I continue doing so with all the child classes of the abstract class. In this way I get code templates that I can implement now. Here are my mappings and the underlying funtion. <pre> "Create abstract class imap <C-c><C-a><C-c> <Esc>bipublic abstract class <Esc>A<CR>{<CR>public abstract void X();<CR>}<Esc>:?X<CR>0fXs "Create concrete class map <C-c><C-c><C-c> :silent! call ImplementAbstractClass()<CR> function! ImplementAbstractClass() range exe "normal \<Esc>\"yyw" /{ normal "xy% normal %o exe "normal! \<Esc>o" let name = inputdialog("Name of new method:") exe "normal! ipublic class " .name." : \<Esc>\"yp\"xp" exe "normal! }O}\<Esc>==" normal %v% normal! gv '<,'>s/abstract/override/g normal! gv '<,'>s/;/\r{\r}\r/g normal! == normal %kdd%k endfunction </pre> ==Comments== These are amazing! I never thought of doing this, but I have to say your tips are quite amazing! I have begun to use hints 1 and 2 religiously, especially when I have to dig around through code that others have written! Thank you!! ---- Here is a variation <pre> imap <C-c><C-p> <Esc>:call CreateProperty()<CR>a function! CreateProperty() exe "normal bim_\<Esc>b\"yyybiprivate \<Esc>A;\<CR>\<Esc>\"ypw\"xyw\<Esc>2xbipublic \<Esc>$a\<CR>{\<Esc>oget\<CR>{\<CR>return \<Esc>\"xpa;\<CR>}\<CR>set\<CR>{\<CR>\<Tab>\<Esc>\"xPa = value;\<CR>}\<CR>}\<CR>\<Esc>" normal 12k2wi endfunction </pre> This will create a property from a ''<type> <Field Name>''. This alleviates the need for multiple mappings for each data type in the vimrc file So if you want to create a property from <code>Rectangle Box</code> just press <code><C-c><C-p></code> and you get <pre> private Rectangle m_Box; public Rectangle Box { get { return m_Box; } set { m_Box = value; } } </pre> I am still trying to get rid of some extra spaces in property name but I hope this helps. ----
Summary:
Please note that all contributions to the Vim Tips Wiki are considered to be released under the CC-BY-SA
Cancel
Editing help
(opens in new window)
Templates used on this page:
Template:Navigation
(
view source
)
Template:Review
(
view source
)
Template:TipImported
(
view source
)
Follow on IG
TikTok
Join Fan Lab