-
Notifications
You must be signed in to change notification settings - Fork 5
/
Copy pathWorking-with-F-Projects-In-VSCode.html
374 lines (239 loc) · 19.7 KB
/
Working-with-F-Projects-In-VSCode.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Working with F# projects in VSCode</title>
<meta name="description" content="Working with F# projects in VSCode using Ionide extension">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="shortcut icon" href="/favicon/favicon.ico">
<link rel="apple-touch-icon-precomposed" href="/favicon/lattice-optic-illusion-152-204321.png" >
<meta name="msapplication-TileColor" content="#ffffff" />
<meta name="msapplication-TileImage" content="/favicon/lattice-optic-illusion-144-204321.png">
<link rel="stylesheet" type="text/css" href="//fonts.googleapis.com/css?family=Lato:400,400italic,700,700italic" />
<link rel="stylesheet" href="//cdnjs.cloudflare.com/ajax/libs/highlight.js/9.4.0/styles/default.min.css">
<link rel="stylesheet" href="/css/main.css" />
<link rel="stylesheet" href="/css/font-awesome.min.css" />
<link rel="canonical" href="http://localhost:4000/Working-with-F-Projects-In-VSCode">
<link rel="alternate" type="application/rss+xml" title="F# Reflections Feed" href="http://localhost:4000/feed.xml">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.2/jquery.min.js"></script>
</head>
<body>
<nav id="top" class="site-navigation">
<div class="inner">
<button id="menu-toggle" aria-expanded="false">Menu</button>
<div class="nav-menu">
<ul class="menu">
<li class="">
<a class="" href="/">Home</a>
</li>
<li class="">
<a class="" href="/about">About</a>
</li>
<li class="">
<a class="" href="/tags/">Archives</a>
</li>
<li class="">
<a class="" href="/2016">2016</a>
</li>
</ul>
</div><!-- .nav-menu -->
<div class="subscribe-button">
<a class="fa-feed square fill-horizontal" href="/feed.xml"><span class="screen-reader-text">RSS</span></a>
</div><!-- .social-links -->
</div><!-- .inner -->
</nav><!-- .site-navigation -->
<header class="site-header">
<div class="inner">
<h1 class="site-title"><a class="logo-text" href="/">F# Reflections</a></h1>
<p class="site-description">Thoughts, stories and ideas.</p>
</div><!-- .inner -->
</header>
<div class="site-content">
<div class="inner">
<main class="site-main">
<article class="post">
<header class="entry-header">
<div class="entry-header-wrap">
<div class="post-thumbnail">
<img src="/images/posts/landscape_5.jpg" alt="Working with F# projects in VSCode">
</div><!-- .post-thumbnail -->
<h1 class="entry-title">Working with F# projects in VSCode</h1>
</div><!-- .entry-header-wrap -->
<div class="entry-meta">
by <span class="post-author">Krzysztof Cieslak</span> on <time class="published" datetime="2016-07-27">July 27, 2016</time>
</div><!-- .entry-meta -->
</header><!-- .entry-header -->
<div class="entry-content">
<h1>Introduction</h1>
<p>Visual Studio Code is a lightweight but powerful source code editor which runs on your desktop and is available for Windows, OS X and Linux. It comes with built-in support for JavaScript, TypeScript and Node.js and has a rich ecosystem of extensions for other languages (C++, C#, Python, PHP) and runtimes. The F# support for VSCode is provided by <a href="http://ionide.io">Ionide</a> - set of extensions adding F# support, as well as Paket and FAKE.</p>
<blockquote>
<p>If you’re new VSCode user installing extensions is pretty easy - press extensions button on left panel, search for Ionide, press install for all Ionide extensions, wait untill all are installed and restart VSCode.</p>
</blockquote>
<p>Ionide-FSharp provides wide set of features useful for F# developer - from simple autocomplete and tooltips, through F# Interactive integration, to navigating to symbols or finding all usages of symbol.</p>
<p>It also comes with decent support for F# projects (defined using <code>.fsproj</code> file).</p>
<!--more-->
<h1>Working with existing projects</h1>
<p>Working with existing projects (created using Visual Studio or other IDE) should be pretty straightforward - opening root of your repository / solution will start Ionide. Plugin should find all project files in repository and parse them.</p>
<blockquote>
<p>Warning - this process can take some time, especially on huge solutions. You can still edit files without any problem, but it make take a while before are features are started - the priority is put on providing features like tooltips, autocomplete or error highlighting for currently opened files. Solution level features (finding all errors in solution, navigating to any symbol in solution, rename, etc ) take bit longer to start.</p>
</blockquote>
<h1>Creating new projects</h1>
<p>Ionide thanks to <a href="https://github.com/fsprojects/Forge">Forge</a> integration provides ability to create new F# projects without using full IDE. Creating new project is as simple as running <code>F#: New Project</code> command.</p>
<blockquote>
<p>All VSCode commands can be run using command palette, it can be started using <code>Ctrl(Cmd)+Shift+P</code> keybord shortcut.</p>
</blockquote>
<p>Ionide will ask about project name, directory where place new project, and project template. Currently there are about 15 different project templates, hopefully more will come in the future thanks to Community contributions to Forge.</p>
<blockquote>
<p>Warning - even if you just create new project, you should have VS Code open in empty directory. It does not create “solution” directory, and assumes that is run from repository root.</p>
</blockquote>
<p>Creating new project will also initialize Paket and FAKE, and create sample build script in repository root. This won’t happen if you’re just adding new project to existing solution with Paket and FAKE.</p>
<h1>Handling files in project</h1>
<p>As you probably know, <code>fsproj</code> files contain list of F# (<code>.fs</code>) files which will be compiled during build process. What’s important is that ordering of those files matters… and it’s huge F# feature. But this topic was already covered in amazing <a href="https://fsharpforfunandprofit.com/series/dependency-cycles.html">Scott Wlaschin’s blog</a>. So, back to the topic.</p>
<blockquote>
<p>Warning - Forge tends to do some additional changes to project file, so for first few times (unless you’re already comfortable with usual Forge changes) I recommend doing git commit before running Forge commands - it will make easier for you to check what changes Forge makes.</p>
</blockquote>
<p>There are few commands which makes handling files easier. First of all, you can add or remove currently open file from project using <code>F#: Add Current File To Project</code> and <code>F#: Remove Current File To Project</code>. Forge will try to find appropriate project file and add or remove file there.</p>
<p>Another important operation is file ordering - to control it <code>F#: Move File Up</code> and <code>F#: Move File Down</code> commands exist.</p>
<h1>Handling references</h1>
<p><code>fsproj</code> files contain also list of used references. Generally there are 3 types of those - external references from NuGet (this type is handled by Paket), project references and GAC references. To handle 2 later cases Ionide provides two commands.</p>
<p><code>F#: Add Project Reference</code> command will ask you which project you want to edit (there will be list of all projects found in current workspace), and after which project you want to reference. For GAC references Ionide provides <code>F#: Add Reference</code> command which works in very similar way.</p>
<h1>Solution-wide editor features</h1>
<p>Ionide’s editor features are probably good topic for another post, but let’s quickly go through some features which works on solution level:</p>
<ul>
<li>On file save, Ionide parse all projects and find all error in solution. They can be viewed in error panel (<code>Ctrl(Cmd) + Shift + M</code>).</li>
<li>Go-to-Definition (<code>F12</code>), Find all references (<code>Shift+F12</code>), Peek definition (<code>Alt + F12</code>) works across all projects in solution</li>
<li>Rename (<code>F2</code>) works across all projects in solution</li>
<li>Same for navigating to symbol (<code>Ctrl(Cmd)+T</code>)</li>
</ul>
<h1>Summary</h1>
<p>In this post, I’ve presented some Ionide’s features which makes supporting and handling F# projects in Visual Studio Code. There are still not as many project editing features as in Visual Studio or Xamarin Studio, but I belive that it’s good start point, and nice set of features for lightweight editor.</p>
</div><!-- .entry-content -->
<footer class="entry-footer">
<div class="share-post">
<span>Share</span>
<a class="fa-twitter" target="_blank" href="https://twitter.com/intent/tweet?text=Working%20with%20F#%20projects%20in%20VSCode&url=http://localhost:4000/Working-with-F-Projects-In-VSCode"><span class="screen-reader-text">Twitter</span></a>
<a class="fa-facebook" target="_blank" href="https://www.facebook.com/sharer/sharer.php?u=http://localhost:4000/Working-with-F-Projects-In-VSCode&t=Working%20with%20F#%20projects%20in%20VSCode"><span class="screen-reader-text">Facebook</span></a>
<a class="fa-google-plus" target="_blank" href="http://plus.google.com/share?url=http://localhost:4000/Working-with-F-Projects-In-VSCode"><span class="screen-reader-text">Google+</span></a>
</div><!-- .share-post -->
<div class="tag-links">
Tags: <a href="/tags/index.html#F%23" title="Pages tagged F#" rel="tag">F#</a><a href="/tags/index.html#VS+Code" title="Pages tagged VS Code" rel="tag">VS Code</a><a href="/tags/index.html#Tooling" title="Pages tagged Tooling" rel="tag">Tooling</a>
</div>
</footer><!-- .entry-footer -->
</article><!-- .post -->
<div class="author-box">
<div class="author-info">
<a href="http://kcieslak.io/about" target="_blank"> <div class="author-avatar" style="background-image: url(/images/authorimage.jpg)"><span class="screen-reader-text">Krzysztof Cieslak's Picture</span></div> </a>
<div class="author-details">
<h2 class="author-title">About Krzysztof Cieslak</h2>
<p class="author-bio">Krzysztof is a F# developer and consultant, open source contributor, conference speaker</p>
<span class="author-location"><i class="fa-map-marker" aria-hidden="true"></i> Lodz, Poland</span>
<span class="author-website"><i class="fa-chain" aria-hidden="true"></i> <a href="http://kcieslak.io" target="_blank"> http://kcieslak.io</a></span>
</div><!-- .author-details -->
</div><!-- .author-info -->
</div><!-- .author-box -->
<nav class="post-navigation">
<h2 class="screen-reader-text">Post navigation</h2>
<div class="nav-previous">
<div class="nav-inside">
<a href="/Creating-custom-project-file-for-F" class="nav-thumb" style="background-image: url(/images/posts/landscape_4.jpg)"></a>
<div class="nav-before">Previous</div>
<div class="nav-title"><a href="/Creating-custom-project-file-for-F">Creating custom project file for F#</a></div>
<div class="nav-date">June 23, 2016</div>
</div><!-- .nav-inside -->
</div><!-- .nav-previous -->
<div class="nav-next">
<div class="nav-inside">
<a href="/Dynamically-extending-F-applications" class="nav-thumb" style="background-image: url(/images/posts/landscape_6.jpg)"></a>
<div class="nav-before">Next</div>
<div class="nav-title"><a href="/Dynamically-extending-F-applications">Dynamically extending F# applications</a></div>
<div class="nav-date">October 3, 2016</div>
</div><!-- .nav-inside -->
</div><!-- .nav-next -->
</nav><!-- .post-navigation -->
</main><!-- .site-main -->
<aside class="sidebar">
<section class="widget widget-text">
<h2 class="widget-title">About Krzysztof Cieslak</h2>
<p>Krzysztof is a F# developer and consultant, open source contributor, conference speaker</p>
</section><!-- .widget-text -->
<section class="widget widget-text">
<p><a href="http://lambdafactory.io" target="_blank"><img src="/images/banner.png" alt="Optional Banner Ad" /></a></p>
</section><!-- .widget-text-->
<section class="widget widget-recent-posts">
<h2 class="widget-title">Latest Posts</h2>
<ul class="recent-posts">
<li class="recent-item"><a href="/F-Editor-Tooling-Part1">Behind the F# editor tootling. Part 1: introduction to compilers.</a> <span>August 27, 2019</span></li>
<li class="recent-item"><a href="/Ionide-Introducing-Info-Panel">Ionide — Introducing Info Panel</a> <span>May 6, 2019</span></li>
<li class="recent-item"><a href="/Ionide-New-Hope">Ionide — A New Hope</a> <span>March 24, 2019</span></li>
<li class="recent-item"><a href="/PureScript-on-Azure-Functions">PureScript on Azure Functions</a> <span>January 12, 2019</span></li>
<li class="recent-item"><a href="/Future-of-F-Cross-platform-editor-tooling">Future of F# cross-platform editor tooling</a> <span>December 31, 2018</span></li>
</ul><!-- .recent-posts -->
</section><!-- .widget-recent-posts -->
<!--Create a sorted array of tags-->
<section class="widget widget-tags">
<h2 class="widget-title">Tags</h2>
<div class="tagcloud">
<a href="/tags/#Azure">Azure</a>
<a href="/tags/#Azure+Functions">Azure Functions</a>
<a href="/tags/#Community">Community</a>
<a href="/tags/#Compiler">Compiler</a>
<a href="/tags/#F%23">F#</a>
<a href="/tags/#FAKE">FAKE</a>
<a href="/tags/#FSharp.Compiler.Services">FSharp.Compiler.Services</a>
<a href="/tags/#Fable">Fable</a>
<a href="/tags/#JS">JS</a>
<a href="/tags/#MVP">MVP</a>
<a href="/tags/#OAuth">OAuth</a>
<a href="/tags/#Open+Source">Open Source</a>
<a href="/tags/#Paket">Paket</a>
<a href="/tags/#PureScript">PureScript</a>
<a href="/tags/#Saturn">Saturn</a>
<a href="/tags/#Serverless">Serverless</a>
<a href="/tags/#Tooling">Tooling</a>
<a href="/tags/#VS+Code">VS Code</a>
<a href="/tags/#Web">Web</a>
<a href="/tags/#Webpack">Webpack</a>
</div><!-- .tagcloud -->
</section><!-- .widget -->
<section class="widget widget-text">
<h2 class="widget-title">Contact me</h2>
<a href="https://twitter.com/k_cieslak" class="fa-twitter square fill-horizontal"><span class="screen-reader-text">Twitter</span></a>
<a href="https://github.com/Krzysztof-Cieslak" class="fa-github-alt square fill-horizontal"><span class="screen-reader-text">GitHub</span></a>
<a href="https://gitlab.com/Krzysztof-Cieslak" class="fa-gitlab square fill-horizontal"><span class="screen-reader-text">GitHub</span></a>
<a href="mailto:[email protected]" class="fa-envelope square fill-horizontal"><span class="screen-reader-text">E-Mail</span></a>
</section><!-- .widget-text -->
</aside><!-- .sidebar -->
</div><!-- .inner -->
</div><!-- .site-content -->
<footer class="site-footer">
<div class="inner">
<div class="social-links">
<a href="https://twitter.com/k_cieslak" class="fa-twitter square fill-horizontal"><span class="screen-reader-text">Twitter</span></a>
<a href="https://github.com/Krzysztof-Cieslak" class="fa-github-alt square fill-horizontal"><span class="screen-reader-text">GitHub</span></a>
<a href="https://gitlab.com/Krzysztof-Cieslak" class="fa-gitlab square fill-horizontal"><span class="screen-reader-text">GitHub</span></a>
<a href="mailto:[email protected]" class="fa-envelope square fill-horizontal"><span class="screen-reader-text">E-Mail</span></a>
<a class="fa-feed square fill-horizontal" href="/feed.xml"><span class="screen-reader-text">RSS</span></a>
</div><!-- .social-links -->
<div class="site-info">
© <a href="/">Krzysztof Cieslak</a> all rights reserved. <br />Powered by <a target="_blank" href="https://jekyllrb.com/">Jekyll</a>. BlogInn theme by <a target="_blank" href="http://justgoodthemes.com/">JustGoodThemes</a>
<a href="#top" id="top-link" class="fa-chevron-up top-link square fill-horizontal"><span class="screen-reader-text">Back to the top</span></a>
</div><!-- .site-info -->
</div><!-- .inner -->
</footer><!-- .site-footer -->
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/9.4.0/highlight.min.js"></script>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/9.4.0/languages/fsharp.min.js"></script>
<script type="text/javascript" src="/js/plugins.js"></script>
<script type="text/javascript" src="/js/custom.js"></script>
<script>hljs.initHighlightingOnLoad();</script>
<!-- Asynchronous Google Analytics snippet -->
<script>
(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
})(window,document,'script','//www.google-analytics.com/analytics.js','ga');
ga('create', 'UA-74514389-1', 'auto');
ga('require', 'linkid', 'linkid.js');
ga('send', 'pageview');
</script>
</body>
</html>