ANN: HaRe 0.8 - The Haskell Refactorer

I'm pleased to announce the release of HaRe 0.8, available on hackage [1] What's new? =========== Everything, and nothing. Everything in the sense that it has been completely reworked internally to make use of the new API Annotations [2] in GHC 7.10.2, via the ghc-exactprint [3] library. Nothing in the sense that the functionality in this version is/should be identical to that in 0.7.2.8 Limitations =========== HaRe 0.8 will only work for projects using GHC 7.10.2 for compilation. Compiling HaRe with 7.10.2 and then using it against projects using an earlier compiler will not work, as HaRe needs to be able to invoke GHC to the type checker stage on the project using GHC 7.10.2. What is it? =========== HaRe makes changes to working code, so that it still works once the change is made. Refactorings it can do are * demote Take a declaration from the level where it is defined and move it down to the place where it is used. This only works if it is used in one place only. * dupdef Duplicate a definition with a new name. * iftocase Convert an if declaration to a case declaration. * liftOneLevel Move a declaration one level up, adding parameters as needed to pass in locally declared variables. * liftToTopLevel Move a declaration to the top level, adding parameters as needed to pass in locally declared variables. * rename Change a name throughout the project. This makes use of the GHC renamed source so will not change other names that just happen to be lexically identical, but are in fact different names. It currently has an emacs integration only, assistance in supporting other environnments welcome. [1] https://hackage.haskell.org/package/HaRe [2] https://ghc.haskell.org/trac/ghc/wiki/ApiAnnotations [3] https://hackage.haskell.org/package/ghc-exactprint Alan

Alan,
This is awesome. I can't express how excited I am to see this develop
further.
I'll gladly start working on Vim support.
Could you describe how it works with emacs?
-- Andrew
On Sun, Oct 4, 2015 at 1:18 PM, Alan & Kim Zimmerman
I'm pleased to announce the release of HaRe 0.8, available on hackage [1]
What's new? ===========
Everything, and nothing.
Everything in the sense that it has been completely reworked internally to make use of the new API Annotations [2] in GHC 7.10.2, via the ghc-exactprint [3] library.
Nothing in the sense that the functionality in this version is/should be identical to that in 0.7.2.8
Limitations ===========
HaRe 0.8 will only work for projects using GHC 7.10.2 for compilation. Compiling HaRe with 7.10.2 and then using it against projects using an earlier compiler will not work, as HaRe needs to be able to invoke GHC to the type checker stage on the project using GHC 7.10.2.
What is it? ===========
HaRe makes changes to working code, so that it still works once the change is made.
Refactorings it can do are
* demote
Take a declaration from the level where it is defined and move it down to the place where it is used. This only works if it is used in one place only.
* dupdef
Duplicate a definition with a new name.
* iftocase
Convert an if declaration to a case declaration.
* liftOneLevel
Move a declaration one level up, adding parameters as needed to pass in locally declared variables.
* liftToTopLevel
Move a declaration to the top level, adding parameters as needed to pass in locally declared variables.
* rename
Change a name throughout the project. This makes use of the GHC renamed source so will not change other names that just happen to be lexically identical, but are in fact different names.
It currently has an emacs integration only, assistance in supporting other environnments welcome.
[1] https://hackage.haskell.org/package/HaRe [2] https://ghc.haskell.org/trac/ghc/wiki/ApiAnnotations [3] https://hackage.haskell.org/package/ghc-exactprint
Alan
_______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe

Hi Andrew
Thanks for the offer, that will be awesome.
In emacs the process is to highlight in a buffer the point where a change
should happen, for example place the cursor on something that needs
renaming, and then press the key binding for the relevant refactoring. The
elisp uses the name of the buffer, location of the cursor and/or current
highlighted region to construct the parameters for a call to ghc-hare.
When it is done, ghc-hare returns either (ok [files]) to indicate success
and the names of the files that were changed, or (error "description of
error").
HaRe does not actually change any files, it just places a new version next
to to it with an extension of .refactored.hs. In emacs a (optional) series
of ediff buffers are presented to review the changes. If the user accepts
them the elisp copies the original files to the same name but with a
date-time string as a suffix, and renames the refactored file to be the
original. It should then reload the buffer, but I think that is missing
right now.
Alan
On Mon, Oct 5, 2015 at 8:07 AM, Andrew Gibiansky wrote: Alan, This is awesome. I can't express how excited I am to see this develop
further. I'll gladly start working on Vim support. Could you describe how it works with emacs? -- Andrew On Sun, Oct 4, 2015 at 1:18 PM, Alan & Kim Zimmerman I'm pleased to announce the release of HaRe 0.8, available on hackage [1] What's new?
=========== Everything, and nothing. Everything in the sense that it has been completely reworked internally
to make
use of the new API Annotations [2] in GHC 7.10.2, via the ghc-exactprint
[3]
library. Nothing in the sense that the functionality in this version is/should be
identical to that in 0.7.2.8 Limitations
=========== HaRe 0.8 will only work for projects using GHC 7.10.2 for compilation.
Compiling
HaRe with 7.10.2 and then using it against projects using an earlier
compiler
will not work, as HaRe needs to be able to invoke GHC to the type checker
stage
on the project using GHC 7.10.2. What is it?
=========== HaRe makes changes to working code, so that it still works once the
change is
made. Refactorings it can do are * demote Take a declaration from the level where it is defined and move it down
to the
place where it is used. This only works if it is used in one place only. * dupdef Duplicate a definition with a new name. * iftocase Convert an if declaration to a case declaration. * liftOneLevel Move a declaration one level up, adding parameters as needed to pass in
locally declared variables. * liftToTopLevel Move a declaration to the top level, adding parameters as needed to
pass in
locally declared variables. * rename Change a name throughout the project. This makes use of the GHC renamed
source
so will not change other names that just happen to be lexically
identical, but
are in fact different names. It currently has an emacs integration only, assistance in supporting other
environnments welcome. [1] https://hackage.haskell.org/package/HaRe
[2] https://ghc.haskell.org/trac/ghc/wiki/ApiAnnotations
[3] https://hackage.haskell.org/package/ghc-exactprint Alan _______________________________________________
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe

Alan, Andrew, The original version of HaRe did integrate with vim. This work was done more than 10 years ago, and it may well be that the mechanisms have changed. Still, the code should be in the HaRe repo. On the other hand, may be easier to start from scratch. Kind regards, and great to hear that you’re planning to do this! Simon T.
On 5 Oct 2015, at 07:19, Alan & Kim Zimmerman
wrote: Hi Andrew
Thanks for the offer, that will be awesome.
In emacs the process is to highlight in a buffer the point where a change should happen, for example place the cursor on something that needs renaming, and then press the key binding for the relevant refactoring. The elisp uses the name of the buffer, location of the cursor and/or current highlighted region to construct the parameters for a call to ghc-hare.
When it is done, ghc-hare returns either (ok [files]) to indicate success and the names of the files that were changed, or (error "description of error").
HaRe does not actually change any files, it just places a new version next to to it with an extension of .refactored.hs. In emacs a (optional) series of ediff buffers are presented to review the changes. If the user accepts them the elisp copies the original files to the same name but with a date-time string as a suffix, and renames the refactored file to be the original. It should then reload the buffer, but I think that is missing right now.
Alan
On Mon, Oct 5, 2015 at 8:07 AM, Andrew Gibiansky
mailto:andrew.gibiansky@gmail.com> wrote: Alan, This is awesome. I can't express how excited I am to see this develop further.
I'll gladly start working on Vim support.
Could you describe how it works with emacs?
-- Andrew
On Sun, Oct 4, 2015 at 1:18 PM, Alan & Kim Zimmerman
mailto:alan.zimm@gmail.com> wrote: I'm pleased to announce the release of HaRe 0.8, available on hackage [1] What's new? ===========
Everything, and nothing.
Everything in the sense that it has been completely reworked internally to make use of the new API Annotations [2] in GHC 7.10.2, via the ghc-exactprint [3] library.
Nothing in the sense that the functionality in this version is/should be identical to that in 0.7.2.8
Limitations ===========
HaRe 0.8 will only work for projects using GHC 7.10.2 for compilation. Compiling HaRe with 7.10.2 and then using it against projects using an earlier compiler will not work, as HaRe needs to be able to invoke GHC to the type checker stage on the project using GHC 7.10.2.
What is it? ===========
HaRe makes changes to working code, so that it still works once the change is made.
Refactorings it can do are
* demote
Take a declaration from the level where it is defined and move it down to the place where it is used. This only works if it is used in one place only.
* dupdef
Duplicate a definition with a new name.
* iftocase
Convert an if declaration to a case declaration.
* liftOneLevel
Move a declaration one level up, adding parameters as needed to pass in locally declared variables.
* liftToTopLevel
Move a declaration to the top level, adding parameters as needed to pass in locally declared variables.
* rename
Change a name throughout the project. This makes use of the GHC renamed source so will not change other names that just happen to be lexically identical, but are in fact different names.
It currently has an emacs integration only, assistance in supporting other environnments welcome.
[1] https://hackage.haskell.org/package/HaRe https://hackage.haskell.org/package/HaRe [2] https://ghc.haskell.org/trac/ghc/wiki/ApiAnnotations https://ghc.haskell.org/trac/ghc/wiki/ApiAnnotations [3] https://hackage.haskell.org/package/ghc-exactprint https://hackage.haskell.org/package/ghc-exactprint
Alan
_______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org mailto:Haskell-Cafe@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe
_______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe
Simon Thompson | Professor of Logic and Computation School of Computing | University of Kent | Canterbury, CT2 7NF, UK s.j.thompson@kent.ac.uk | M +44 7986 085754 | W www.cs.kent.ac.uk/~sjt

Hello, As for vim integration, neovim and https://github.com/neovimhaskell/nvim-hs might be the way to go. Best regards, Marcin Mrotek

It is here: https://github.com/alanz/HaRe/tree/master/old/editors/Vim
On Mon, Oct 5, 2015 at 10:47 AM, Simon Thompson
Alan, Andrew,
The original version of HaRe did integrate with vim. This work was done more than 10 years ago, and it may well be that the mechanisms have changed. Still, the code should be in the HaRe repo. On the other hand, may be easier to start from scratch.
Kind regards, and great to hear that you’re planning to do this!
Simon T.
On 5 Oct 2015, at 07:19, Alan & Kim Zimmerman
wrote: Hi Andrew
Thanks for the offer, that will be awesome.
In emacs the process is to highlight in a buffer the point where a change should happen, for example place the cursor on something that needs renaming, and then press the key binding for the relevant refactoring. The elisp uses the name of the buffer, location of the cursor and/or current highlighted region to construct the parameters for a call to ghc-hare.
When it is done, ghc-hare returns either (ok [files]) to indicate success and the names of the files that were changed, or (error "description of error").
HaRe does not actually change any files, it just places a new version next to to it with an extension of .refactored.hs. In emacs a (optional) series of ediff buffers are presented to review the changes. If the user accepts them the elisp copies the original files to the same name but with a date-time string as a suffix, and renames the refactored file to be the original. It should then reload the buffer, but I think that is missing right now.
Alan
On Mon, Oct 5, 2015 at 8:07 AM, Andrew Gibiansky < andrew.gibiansky@gmail.com> wrote:
Alan,
This is awesome. I can't express how excited I am to see this develop further.
I'll gladly start working on Vim support.
Could you describe how it works with emacs?
-- Andrew
On Sun, Oct 4, 2015 at 1:18 PM, Alan & Kim Zimmerman
wrote:
I'm pleased to announce the release of HaRe 0.8, available on hackage [1]
What's new? ===========
Everything, and nothing.
Everything in the sense that it has been completely reworked internally to make use of the new API Annotations [2] in GHC 7.10.2, via the ghc-exactprint [3] library.
Nothing in the sense that the functionality in this version is/should be identical to that in 0.7.2.8
Limitations ===========
HaRe 0.8 will only work for projects using GHC 7.10.2 for compilation. Compiling HaRe with 7.10.2 and then using it against projects using an earlier compiler will not work, as HaRe needs to be able to invoke GHC to the type checker stage on the project using GHC 7.10.2.
What is it? ===========
HaRe makes changes to working code, so that it still works once the change is made.
Refactorings it can do are
* demote
Take a declaration from the level where it is defined and move it down to the place where it is used. This only works if it is used in one place only.
* dupdef
Duplicate a definition with a new name.
* iftocase
Convert an if declaration to a case declaration.
* liftOneLevel
Move a declaration one level up, adding parameters as needed to pass in locally declared variables.
* liftToTopLevel
Move a declaration to the top level, adding parameters as needed to pass in locally declared variables.
* rename
Change a name throughout the project. This makes use of the GHC renamed source so will not change other names that just happen to be lexically identical, but are in fact different names.
It currently has an emacs integration only, assistance in supporting other environnments welcome.
[1] https://hackage.haskell.org/package/HaRe [2] https://ghc.haskell.org/trac/ghc/wiki/ApiAnnotations [3] https://hackage.haskell.org/package/ghc-exactprint
Alan
_______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe
_______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe
Simon Thompson | Professor of Logic and Computation School of Computing | University of Kent | Canterbury, CT2 7NF, UK s.j.thompson@kent.ac.uk | M +44 7986 085754 | W www.cs.kent.ac.uk/~sjt

Update: Version 0.8.1 is out, which fixes renaming that crosses module
boundaries and preserves CPP directives
On Sun, Oct 4, 2015 at 10:18 PM, Alan & Kim Zimmerman
I'm pleased to announce the release of HaRe 0.8, available on hackage [1]
What's new? ===========
Everything, and nothing.
Everything in the sense that it has been completely reworked internally to make use of the new API Annotations [2] in GHC 7.10.2, via the ghc-exactprint [3] library.
Nothing in the sense that the functionality in this version is/should be identical to that in 0.7.2.8
Limitations ===========
HaRe 0.8 will only work for projects using GHC 7.10.2 for compilation. Compiling HaRe with 7.10.2 and then using it against projects using an earlier compiler will not work, as HaRe needs to be able to invoke GHC to the type checker stage on the project using GHC 7.10.2.
What is it? ===========
HaRe makes changes to working code, so that it still works once the change is made.
Refactorings it can do are
* demote
Take a declaration from the level where it is defined and move it down to the place where it is used. This only works if it is used in one place only.
* dupdef
Duplicate a definition with a new name.
* iftocase
Convert an if declaration to a case declaration.
* liftOneLevel
Move a declaration one level up, adding parameters as needed to pass in locally declared variables.
* liftToTopLevel
Move a declaration to the top level, adding parameters as needed to pass in locally declared variables.
* rename
Change a name throughout the project. This makes use of the GHC renamed source so will not change other names that just happen to be lexically identical, but are in fact different names.
It currently has an emacs integration only, assistance in supporting other environnments welcome.
[1] https://hackage.haskell.org/package/HaRe [2] https://ghc.haskell.org/trac/ghc/wiki/ApiAnnotations [3] https://hackage.haskell.org/package/ghc-exactprint
Alan
participants (4)
-
Alan & Kim Zimmerman
-
Andrew Gibiansky
-
Marcin Mrotek
-
Simon Thompson