[GHC] #15887: It would be very nice to have a better GHCi editing experience
GHC
ghc-devs at haskell.org
Sun Nov 11 07:01:48 UTC 2018
#15887: It would be very nice to have a better GHCi editing experience
-------------------------------------+-------------------------------------
Reporter: Anchpop | Owner: (none)
Type: feature | Status: new
request |
Priority: high | Milestone: Research needed
Component: Compiler | Version: 8.6.2
Keywords: QoL | Operating System: Unknown/Multiple
Architecture: | Type of failure: None/Unknown
Unknown/Multiple |
Test Case: | Blocked By:
Blocking: | Related Tickets:
Differential Rev(s): | Wiki Page:
-------------------------------------+-------------------------------------
I have a two annoyances when writing Haskell code in GHCi which I will
enumerate here. While minor, I think if these were fixed there would be a
marked improvement of the GHCi editing experience.
1) Syntax/Keyword Highlighting.
Haskell has some very common keywords. Simply writing `if`, `then`,
`else`, `where`, `do`, etc. in some color other than the default when not
inside a string literal would be a huge improvement in my opinion, and
might not be very difficult.
2) Multiline editing
Writing multiline expressions in Haskell is somewhat difficult for
four reasons. Firstly, to even start a multiline expression you must enter
`:{` end end it with `:}`. Secondly, GHCi does not attempt to
automatically indent your code, which is usually (always?) required when
writing a multiline expression. Thirdly, you cannot navigate the curor to
previous lines to edit them. Lastly, pressing the up arrow on the keyboard
shows the last line of the multiline expression which is useless because
it's almost always `:}`.
My proposal is as follows.
1) The issue of how to enter multiline mode without needing to enter
`:{` and exit it without needing `:}`.
Instead of entering multiline mode only when the user enters
`:{`, we add the following additional criteria. When I discuss haskell
keywords in here, assume I mean "while not in a string literal".
a) When the input code contains an odd number of unescaped
quotation marks and ends in a backslash.
b) When the input code ends with `where`, `let`, `in`, `if`,
`then`, `else`, `do`, `of`, `case`, or `->` preceeded by and in the same
level of parenthetical nesting of `case`.
c) When the input code contains a `let` that is not eventually
followed by `in`, an `if` not followed by `then`, or a `then` not followed
by `else`.
d) When the input code contains a `case` followed by `of`, not
enclosed by parentheses.
e) When the input code contains a `[` that is not followed by
a `]`, or an `(` that is not followed by a `)`.
f) When the input starts with two or more consecutive space-
seperated tokens that do not contain haskell keywords (other than the
backtick) followed by `=`.
g)
i) When the input contains a single token that is not a
haskell keyword, followed by `::`, ending in `=>` or `->`.
ii) When the input contains a single token that is not a
haskell keyword, followed by `::`, not ending in `=>` or `->`.
e) When the user hits `shift-return` instead of simply
`return`, or hits `return` when there are non-whitespace characters after
the cursor.
This should cover the majority of cases where it can be safely
assumed one would want to enter multiline mode. Criterion f is intended to
enter multiline mode when defining any function, to make it simple to
define functions that use pattern matching. Criterion g is to make it
simple to place a function signature right above a function definition.
In situations where multiline mode was not entered with `:{`,
you should be able to exit it and submit your code to GHCi for execution
by pressing `return` twice, or `meta-return`.
2) The issue of GHCi not attempting to indent your code.
How to indent depends on the reason GHCi entered multiline
mode. If GHCi entered multiline mode because the user entered `:{`, no
indentation should take place. If the user is in multiline mode but their
code does not match criteria a-f, the default indentation should be the
same as the indentation on the previous line. If the line is just
whitespace and the user presses enter, indentation should be the same as
the previous line. For criteria a-f, here is how to respond (I've ordered
these from greatest to least precedence I think they should take, but I
could be entirely wrong here).
a) Indent to the same column as the last unescaped
quotation mark. For bonus points add a backslash too.
b) Indent to two columns as the token that caused the
activation of multiline mode.
c) Indent to the same column as the token that caused the
activation of multiline mode.
d) Indent to the character after the final `of` not
contained in parentheses
e) Indent to the column of the next non-whitespace
character after `(` or `[`, if one exists. Otherwise, indent one column
farther than the `(`/`[`.
f) No indentation.
g)
i) Indent to the column of the first non-
whitespace character after the `::`
ii) No indentation.
e) No indentation
If the user is not editing the last line, use the code up
to the point of their cursor for advice on how to indent.
3) The issue of not being able to navigate the curor to previous
lines in order to edit them when in multiline editing mode.
I think this would require a complete rewrite of the user
interface for multiline editing, and I anticipate it would be the hardest
part of this whole endevor. I don't have the knowledge to suggest how one
might go about implementing it, though. If possible, pressing ctrl-c
should cancel the current code and make a new `Prelude> ` prompt.
4) The issue of pressing `up` only displaying one line at a time.
See above.
I would be happy to try to implement some of these, but I have never
contributed to GHC or GHCi before and would need some pointers on where to
start (Either in here or in the #ghc irc channel).
--
Ticket URL: <http://ghc.haskell.org/trac/ghc/ticket/15887>
GHC <http://www.haskell.org/ghc/>
The Glasgow Haskell Compiler
More information about the ghc-tickets
mailing list