Haskell-mode source navigation for dependencies - haskell

I am using haskell-mode for Emacs. I succeeded at creating etags for my haskell project on every save by hasktags, however, the cabal dependencies can not be navigated to this way. So I wonder: Is there a way to make this source code navigation work for cabal dependencies, too? (as it is easily possible for java-maven projects for example..)

You can try haskdogs, which provides a thin wrapper around hasktags and executes it for your imported modules as well as your own code. It maintains a repository of module sources in ~/.haskdogs and indexes into that.
I'm using it with vi and have been quite happy with it so far.

Related

Do build tools for Vimscript exist?

I'd like to build a small set of vimscript libraries, however, it seems that the only way to use them would be to load them all globally into vim.
Furthermore, it means that if i wanted to share a single script that depends on those, i'd have to share to them all, which sounds tiresome.
What i was hoping for is some common.js and webpack style approach to vimscript,
does such a thing exist. Something that:
Resolves dependencies
Allows for vimscript files to be "bundled" together into one file.
Everything that i found, winds up being a plugin manager, rather than a plugin build tool.
Do such things exist?
The situation so far, up to Vim 8.
There is no script isolation. When a script is loaded, it's globally. The script can hide variables and functions, but that's all.
Sharing/exporting a function is quite easy: we drop it in an autoload plugin, and we just have to use that function named dirrelatativeto_rtp#subdir#suddir...#scriptname#funcname(). If the script scriptname.vim is installed in dirrelatativeto_rtp/subdir/subdir somewhere in a directory registered in 'runtimepath', it'll get loaded automatically.
Regarding commands, abbreviations, mappings... they are meant to be defined in plugin files, or ftplugin files -- other approaches are possible when we want submodes. Also we cannot use them naively from an autoload plugin or when a script is being loaded -- we'll have to explicitly use :runtime to load the script where this command/mapping/... is defined (as we'd do an import in Python).
Yet, like with Python, scripts aren't installed automagically on our system. It's still up to us to trigger manually the installation of scripts.
We can decide to have library plugins and other plugins that depend on these libraries. But, we need either to tell the end-user everything that must be installed manually, or kindly tell him/her to stop using a plugin manager that don't understand dependencies.
This has been a personal rant of mine for years, the trendy plugin managers don't understand dependencies. There are so far only two plugin managers that do so:
Vim-Addon-Manager (aka VAM): it relies on a central repository (vim-pi) to install a plugin (and its dependencies) with just its name (e.g. :InstallAddon fugitive, :InstallAddon lh-cpp). Unfortunately the central repository is no longer maintained and we can't register new names. Fortunately, we can always install anything with :InstallAddon github:{N}/{repo}. Other functions are available for installing from the .vimrc.
and vim-flavor which is written in ruby, and which install plugins as Vim 8 packages.
Both have their own syntax to declare dependencies. Unlike VAM, we can specify constraints on plugin versions with vim-flavor.
Last thing, if we don't want to distribute all files, we can organize them as several "plugins". But beware of cyclic dependencies. And be kind to end users that are using these trendy plugins managers that don't understand dependencies as they'll need to explicitly install many "plugins"
Starting from Vim 9
We can start to isolate imported plugins in the sense that two plugins can define a function or a command with a same name. Again, this feature seems to mimic Python way of doing things.
However, I expect global stuff like autocommands to continue to operate globally. For instance: I don't see how we could have two template expander plugins running concurrently.
Vim 9 new scripting language won't change anything to the installation of plugins we depend on.
Disclaimer: It has been almost 2 decades now that I've been maintaining my plugins as a bunch of interdependent plugins, organized around a few library plugins, as I don't like to duplicate a same thing several times. In my rant about dependencies & co, I explore quickly other alternative approaches available to us.
Back to the bundling/packaging question (EDIT)
We have ways to package files together.
We can always manually define plugins: put files together in a directory tree, play with git and so on.
We can define tarballs.
We can also define vimballs. Vimballs are a quite old solution for installable archives: files are put in their right directory and documentation tags are produced. There are ways to produce vimballs. I continue to maintain scripts that help producing them for all my plugins. But in all honesty, this is not what people expect to have nowadays to install plugins. I just keep them around in case I release new versions of my plugins on vim.org.
In any case, neither of these solutions end up defining one single file we put somewhere in our ~/.vim/ directory. And I think we will never have something like that because:
Isolation is not perfect. Even with Vim 9 new scripting language: I don't see how we could correctly handle duplication of autocommands. If a same file, that defines autocommands, is duplicated in different versions in several distributed "plugins" I don't see how Vim could handle that correctly.
Vim expects different files in different places: ftplugins, plugins (the original meaning in vim context, not the set of files that could be installed together), syntax files, fold plugins, indent plugins, colorschemes, langmaps, and so on. Vim architecture does not expect everything in a single file.
For these reasons, I cannot see how we could have build systems that build single files ready to be distributed. It could work in some cases (pure collections of functions and "classes"), but not in the general case.

How to setup with vim YCM

i want to move from using CMake to Premake for my current project, but im usig vim and the YCM plugin which is really great for making my setup like an IDE. However, the plugin needs compilation flags file which is produced when running CMake. Is there something for Premake to generate a file like that as well?
Premake does not do this in its current state (alpha 13). If you have some insights as to what is necessary for getting it to work, the best thing to do would be to submit a ticket in the issue tracker.
I'm afraid, if your new build system does not generate that compilation flags file (yet), you'll need to maintain your own (hand-crafted) one. You can find an example at https://github.com/Valloric/ycmd/blob/0e999dbee209ea79a522259816ce3a68b7d6cddc/examples/.ycm_extra_conf.py.
I would advice to have (at least) one per project rather than one generic one in your $HOME.
Although I have to admit, that it would be beneficial to get it created and in sync with the actual build system, I don't find it too troublesome to maintain it manually. At the end of the day it only contains the C++ standard you want to use, a set of preprocessor symbols and a set of both system and user include directories.

Is it possible to get "paths" functionality with tsify similar to what vanilla browserify has?

In vanilla browserify you can specify "paths" option to set directories where browserify looks for "required" files.
browserify({paths: ["./source/App"]})
When using tsify to compile TypeScript, this option seems to be ignored. The reason for using paths in the first place, is to avoid having every require statement start with "../../../etc".
I know an alternative option is to place the code in node_modules, but firstly that does seem pretty odd (you wouldn't normally keep you application code with your dependencies) but it also requires you to commit node_modules to your repositories and make sure no one ever clears that directory to reinstall dependencies.
The other alternative; symlinks don't work on windows, and also seems like quite a "hacky" solution.
I am quite new to browserify (coming from RequireJS), so it is possible that I overlooked something. But at this point I really would appreciate some input. If it makes any difference I am also using gulp.
Well, given that Path mappings based module resolution feature is proposed for TypeScript 1.8 and tsify is a thin wrapper of the TypeScript compiler, I can't imagine a way how it can work nowadays.
I expect that TypeScript 1.8 will be ready in a few months.

How to get source code for all build-depends using cabal?

I generated a new project using Yesod and am trying to go through the source to see how the pieces fit together. I am still a bit unfamiliar with most of the types so I have to keep a browser open where I hoogle/hayoo for types of things.
When I use Intellij for Java development I can usually just jump in to the source code of most of my dependencies. I wanted to try to replicate this for Haskell.
Since I am using vim for Haskell I thought I would just get the source for everything listed in build-depends and then generate a specific cabal_tags file and add that to vim's tags option.
My cabal skills are very rudimentary though. I noticed there is cabal get which can get the source for a package but it seems you need to explicitly specify the package and there doesn't seem to be an option for getting everything specified under build-depends in the .cabal file.

Package versioning clashes in Cabal

Forgive me if this is a FAQ but I'm a bit puzzled about how to get around this problem properly.
I recently downloaded the package TagSoup which installed fine with the latest version 0.12.2
Then I installed the package download-curl which installed fine with the latest version. What I failed to realise was, download-curl depends on TagSoup with a version =< 0.11, so as part of the installation process Cabal downloaded an older version of TagSoup too.
This is a problem because I want to use both libraries (the latest version of TagSoup AND download-curl) - and when you do for some reason GHCI gets in a bit of a mess.
My question is, is there a way of specifying versions in your import statements, i.e.
import Text.Html.TagSoup-0.12.2
or is this a no go? I'm thinking not.
The only way I got around this was to download the download-curl source, modify the .cabal file to use TagSoup-0.12.2 and reinstalled the package with my little "hack" in place which works as I would expect it to - but I don't think this is the solution
Any help would be appreciated
Normally one specifies the required version in the .cabal file. There is an extension syntax for specific package imports (-XPackageImports) but it's usually better to let Cabal deal.
That said, yes, if you need to use both then you enter the dark realm of diamond dependencies. Yours is pretty much the only solution available currently. -XPackageImports is not a good idea here, as trying to use two versions of the same library in the same program probably won't link and almost certainly will dump core at runtime if it does manage to link without duplicate symbols.

Resources