chore(src/emacs): move lean-mode to https://github.com/leanprover/lean-mode

Closes #410
This commit is contained in:
Sebastian Ullrich 2017-10-03 16:11:35 +02:00 committed by Leonardo de Moura
parent bcad5309d9
commit 5efa1b829c
37 changed files with 3 additions and 3806 deletions

View file

@ -18,7 +18,6 @@ About
- [Homepage](http://leanprover.github.io)
- [Theorem Proving in Lean](https://leanprover.github.io/theorem_proving_in_lean/index.html)
- [Core library](library/library.md)
- [Emacs Mode](src/emacs/README.md)
- [Change Log](doc/changes.md)
- For HoTT mode, please use [Lean2](https://github.com/leanprover/lean2).

2
bin/.gitignore vendored
View file

@ -1,4 +1,2 @@
lean
lean.exe
leanemacs
leanemacs.bat

View file

@ -1,4 +0,0 @@
SET MY_PATH=%~dp0
SET LEAN_ROOTDIR=%MY_PATH%/..
SET LEAN_EMACS_PATH=%MY_PATH%/../@EMACS_LISP_DIR@
emacs -load %LEAN_EMACS_PATH%/load-lean.el

View file

@ -1,8 +0,0 @@
#!/usr/bin/env bash
MY_PATH="`dirname \"$0\"`" # relative
MY_PATH="`( cd \"$MY_PATH\" && pwd )`" # absolutized and normalized
export LEAN_ROOTDIR="$MY_PATH/.."
export LEAN_EMACS_PATH="$MY_PATH/../@EMACS_LISP_DIR@"
emacs -load $LEAN_EMACS_PATH/load-lean.el $*

View file

@ -1,8 +0,0 @@
#!/usr/bin/env bash
MY_PATH="`dirname \"$0\"`" # relative
MY_PATH="`( cd \"$MY_PATH\" && pwd )`" # absolutized and normalized
export LEAN_ROOTDIR="$MY_PATH/.."
export LEAN_EMACS_PATH="$LEAN_ROOTDIR/src/emacs"
emacs -load $LEAN_EMACS_PATH/load-lean.el $*

View file

@ -1,4 +0,0 @@
SET MY_PATH=%~dp0
SET LEAN_ROOTDIR=%MY_PATH%/..
SET LEAN_EMACS_PATH=%MY_PATH%/../src/emacs
emacs -load %LEAN_EMACS_PATH%/load-lean.el

View file

@ -1,9 +0,0 @@
#!/usr/bin/env bash
# Script for testing load-lean.el without installing Lean
MY_PATH="`dirname \"$0\"`" # relative
MY_PATH="`( cd \"$MY_PATH\" && pwd )`" # absolutized and normalized
export LEAN_ROOTDIR="$MY_PATH/.."
export LEAN_EMACS_PATH="$MY_PATH/../src/emacs"
emacs -load $LEAN_EMACS_PATH/load-lean.el -debug-init $*

View file

@ -5,21 +5,10 @@ The binary distribution package contains:
- Lean executable (located in the sub-directory bin)
- Standard library (located in the sub-directory lib/lean/library)
- Emacs modes (located in the sub-directory share/emacs/site-list/lean)
Assuming you are in the same directory this file is located,
the following command executes a simple set of examples
% bin/lean examples/ex.lean
The Emacs mode is the ideal way to use Lean. It requires at
least Emacs version 24.3
Documentation
-------------
The tutorial "Theorem Proving in Lean" describes Lean main features,
and provides many examples. The tutorial is available in two different forms:
- Interactive HTML: http://leanprover.github.io/tutorial/index.html
- PDF: http://leanprover.github.io/tutorial/tutorial.pdf
For more information on Lean and supported editors, please see https://leanprover.github.io/documentation/.

View file

@ -150,6 +150,8 @@ For more details, see discussion [here](https://github.com/leanprover/lean/pull/
* User attributes can no longer be set with `set_basic_attribute`. You need to use `user_attribute.set` now.
* The Emacs mode has been moved into its own repository and MELPA packages: https://github.com/leanprover/lean-mode
*API name changes*
* `list.dropn` => `list.drop`

View file

@ -50,8 +50,6 @@ option(CUSTOM_ALLOCATORS "CUSTOM_ALLOCATORS" ON)
option(SAVE_SNAPSHOT "SAVE_SNAPSHOT" ON)
option(SAVE_INFO "SAVE_INFO" ON)
# emacs site-lisp dir
set(EMACS_LISP_DIR "share/emacs/site-lisp/lean" CACHE STRING "emacs site-lisp dir")
# library dir
set(LIBRARY_DIR "lib/lean" CACHE STRING "library dir")
set(LEAN_EXT_INCLUDE_DIR "include/lean_ext" CACHE STRING "include dir for building Lean extensions")
@ -102,8 +100,6 @@ if (NOT("${SAVE_INFO}" MATCHES "ON"))
set(LEAN_EXTRA_CXX_FLAGS "${LEAN_EXTRA_CXX_FLAGS} -D LEAN_NO_INFO")
endif()
message(STATUS "Lean emacs-mode will be installed at "
"${CMAKE_INSTALL_PREFIX}/${EMACS_LISP_DIR}")
message(STATUS "Lean library will be installed at "
"${CMAKE_INSTALL_PREFIX}/${LIBRARY_DIR}")
@ -192,7 +188,6 @@ set(CMAKE_CXX_FLAGS_GPROF "-O2 -g -pg")
set(CPACK_DMG_BACKGROUND_IMAGE "${LEAN_SOURCE_DIR}/../images/lean.png")
set(CPACK_DMG_VOLUME_NAME "Lean-${LEAN_VERSION_STRING}")
set(CPACK_BUNDLE_NAME "Lean-${LEAN_VERSION_STRING}")
set(CPACK_BUNDLE_STARTUP_COMMAND "bin/leanemacs")
set(CPACK_PACKAGE_ICON "${LEAN_SOURCE_DIR}/../images/lean.png")
##################
@ -352,10 +347,6 @@ configure_file("${LEAN_SOURCE_DIR}/githash.h.in" "${LEAN_BINARY_DIR}/githash.h")
# Version
configure_file("${LEAN_SOURCE_DIR}/version.h.in" "${LEAN_BINARY_DIR}/version.h")
# leanemacs file
configure_file("${LEAN_SOURCE_DIR}/../bin/leanemacs.in" "${LEAN_SOURCE_DIR}/../bin/leanemacs")
configure_file("${LEAN_SOURCE_DIR}/../bin/leanemacs.bat.in" "${LEAN_SOURCE_DIR}/../bin/leanemacs.bat")
include_directories("${LEAN_BINARY_DIR}")
add_subdirectory(util)
set(LEAN_OBJS ${LEAN_OBJS} $<TARGET_OBJECTS:util>)
@ -419,7 +410,6 @@ if (NOT("${CROSS_COMPILE}" MATCHES "ON"))
endif()
add_subdirectory(shell)
add_subdirectory(emacs)
function(add_exec_test name tgt)
if(${EMSCRIPTEN})
@ -494,16 +484,6 @@ install(FILES "${CMAKE_SOURCE_DIR}/../bin/leanpkg"
DESTINATION bin
PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE)
if(${CMAKE_SYSTEM_NAME} MATCHES "Windows")
install(FILES "${CMAKE_SOURCE_DIR}/../bin/leanemacs.bat" "${CMAKE_SOURCE_DIR}/../bin/leanemacs.bat"
DESTINATION bin
PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE)
else()
install(FILES "${CMAKE_SOURCE_DIR}/../bin/leanemacs" "${CMAKE_SOURCE_DIR}/../bin/leanemacs"
DESTINATION bin
PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE)
endif()
install(DIRECTORY "${CMAKE_SOURCE_DIR}/../library" DESTINATION "${LIBRARY_DIR}"
FILES_MATCHING
PATTERN "*.lean"
@ -522,9 +502,6 @@ install(DIRECTORY "${CMAKE_SOURCE_DIR}/" DESTINATION "${LEAN_EXT_INCLUDE_DIR}"
FILES_MATCHING
PATTERN "*.h")
install(FILES "${CMAKE_SOURCE_DIR}/../src/emacs/lean.pgm"
DESTINATION "${EMACS_LISP_DIR}")
if("${INCLUDE_MSYS2_DLLS}" MATCHES "ON")
# TODO(Leo): do not use hardlinks to required DLLs.
# For example, we can try to use ldd to retrieve the list of required DLLs.

View file

@ -1,2 +0,0 @@
.cask
*.elc

View file

@ -1,2 +0,0 @@
FILE(GLOB LEAN_MODE_FILES *.el)
install(FILES ${LEAN_MODE_FILES} DESTINATION "${EMACS_LISP_DIR}")

View file

@ -1,14 +0,0 @@
(source gnu)
(source melpa)
(package-file "lean-mode.el")
(development
(depends-on "cl-lib")
(depends-on "company")
(depends-on "dash" 2.8.0)
(depends-on "dash-functional" "1.1.0")
(depends-on "ert-runner")
(depends-on "ecukes")
(depends-on "f")
(depends-on "flycheck")
(depends-on "flymake")
(depends-on "s"))

View file

@ -1,17 +0,0 @@
CASK ?= cask
EMACS ?= emacs
all: test
test: unit ecukes
unit:
${CASK} exec ert-runner
ecukes:
${CASK} exec ecukes
install:
${CASK} install
.PHONY: all test unit ecukes install

View file

@ -1,165 +0,0 @@
This is the emacs mode for the [Lean theorem prover][lean].
[lean]: https://github.com/leanprover/lean
Quick-start
===========
If you have built lean from source, all that is necessary is to call the
`leanemacs_build` script which automatically installs all the dependencies and
opens up emacs with lean-mode loaded:
```
~/projects/lean/bin/leanemacs_build
```
If you have installed lean from a binary package, you can run `leanemacs`.
Trying It Out
=============
If things are working correctly, you should see the word ``Lean`` in the
Emacs mode line when you open a file with extension `.lean`. If you type
```lean
#check id
```
the word ``#check`` will be underlined, and hovering over it will show
you the type of ``id``. The mode line will show ``FlyC:0/1``, indicating
that there are no errors and one piece of information displayed.
Key Bindings and Commands
=========================
| Key | Function |
|--------------------|---------------------------------------------------------------------------------|
| <kbd>M-.</kbd> | jump to definition in source file (`lean-find-definition`) |
| <kbd>S-SPC</kbd> | auto complete identifiers, options, imports, etc. (`company-complete`) |
| <kbd>C-c C-k</kbd> | shows the keystroke needed to input the symbol under the cursor |
| <kbd>C-c C-x</kbd> | execute lean in stand-alone mode (`lean-std-exe`) |
| <kbd>C-c SPC</kbd> | run a command on the hole at point (`lean-hole`)
| <kbd>C-c C-g</kbd> | toggle showing current tactic proof goal (`lean-toggle-show-goal`) |
| <kbd>C-c C-n</kbd> | toggle showing next error in dedicated buffer (`lean-toggle-next-error`) |
| <kbd>C-c C-b</kbd> | toggle showing output in inline boxes (`lean-message-boxes-toggle`) |
| <kbd>C-c C-r</kbd> | restart the lean server (`lean-server-restart`) |
| <kbd>C-c ! n</kbd> | flycheck: go to next error |
| <kbd>C-c ! p</kbd> | flycheck: go to previous error |
| <kbd>C-c ! l</kbd> | flycheck: show list of errors |
In the default configuration, the Flycheck annotation `FlyC:n/n` indicates the
number of errors / responses from Lean; clicking on `FlyC` opens the Flycheck menu.
Message Boxes
================
To view the output of commands such as `check` and `print` in boxes in the buffer, enable the feature using <kbd>C-c C-b</kbd>.
If you then type
```lean
#check id
```
a box appears after the line showing the type of `id`. Customize `lean-message-boxes-enabled-captions` to choose categories of boxes.
In particular, add `"trace output"` to the list to see proof states and other traces in the buffer.
Requirements
============
``lean-mode`` requires [Emacs 24][emacs24] or later and the following
packages, which can be installed via <kbd>M-x package-install</kbd>:
[dash][dash], [dash-functional][dash], [f][f], [s][s], [company][company],
and [flycheck][flycheck]
[emacs24]: http://www.gnu.org/software/emacs
[dash]: https://github.com/magnars/dash.el
[f]: https://github.com/rejeep/f.el
[s]: https://github.com/magnars/s.el
[company]: http://company-mode.github.io/
[flycheck]: http://www.flycheck.org/manual/latest/index.html
Installation
============
You can also include lean-mode permanently in your emacs init file. In this
case, just put the following code in your Emacs init file (typically `~/.emacs.d/init.el`):
```elisp
;; You need to modify the following two lines:
(setq lean-rootdir "~/projects/lean")
(setq lean-emacs-path "~/projects/lean/src/emacs")
(setq lean-mode-required-packages '(company dash dash-functional f
flycheck let-alist s seq))
(require 'package)
(add-to-list 'package-archives '("melpa" . "http://melpa.org/packages/"))
(package-initialize)
(let ((need-to-refresh t))
(dolist (p lean-mode-required-packages)
(when (not (package-installed-p p))
(when need-to-refresh
(package-refresh-contents)
(setq need-to-refresh nil))
(package-install p))))
(setq load-path (cons lean-emacs-path load-path))
(require 'lean-mode)
```
If you already have the dependencies installed, the following three lines suffice:
```elisp
;; You need to modify the following two lines:
(setq lean-rootdir "~/projects/lean")
(setq load-path (cons "~/projects/lean/src/emacs" load-path))
(require 'lean-mode)
```
Known Issues and Possible Solutions
===================================
Unicode
-------
If you experience a problem rendering unicode symbols on emacs,
please download the following fonts and install them on your machine:
- [Quivira.ttf](http://www.quivira-font.com/files/Quivira.ttf)
- [Dejavu Fonts](http://sourceforge.net/projects/dejavu/files/dejavu/2.35/dejavu-fonts-ttf-2.35.tar.bz2)
- [NotoSans](https://github.com/googlei18n/noto-fonts/blob/master/hinted/NotoSans-Regular.ttc?raw=true)
- [NotoSansSymbols](https://github.com/googlei18n/noto-fonts/blob/master/unhinted/NotoSansSymbols-Regular.ttf?raw=true)
Then, have the following lines in your emacs setup to use `DejaVu Sans Mono` font:
```elisp
(when (member "DejaVu Sans Mono" (font-family-list))
(set-face-attribute 'default nil :font "DejaVu Sans Mono-11"))
```
You may also need to install [emacs-unicode-fonts](https://github.com/rolandwalker/unicode-fonts) package.
- Run `M-x package-refresh-contents`, `M-x package-install`, and type `unicode-fonts`.
- Add the following lines in your emacs setup:
```lisp
(require 'unicode-fonts)
(unicode-fonts-setup)
```
"Variable binding depth exceeds max-specpdl-size" Error
---------------------------------------------------------
See [Issue 906](https://github.com/leanprover/lean/issues/906) for details.
[Moritz Kiefer](https://github.com/cocreature) reported that `proofgeneral`
comes with an old version of `mmm-mode` (0.4.8, released in 2004) on ArchLinux
and it caused this problem. Either removing `proofgeneral` or upgrading
`mmm-mode` to the latest version (0.5.1 as of 2015 Dec) resolves this issue.
Contributions
=============
Contributions are welcome!
Install [Cask](https://github.com/cask/cask) if you haven't already, then:
$ cd /path/to/lean/src/emacs
$ cask
Run all tests with:
$ make

View file

@ -1,206 +0,0 @@
;;; eri.el --- Enhanced relative indentation (eri)
;;; Commentary:
;;; Code:
(require 'cl)
(defun eri-current-line-length nil
"Calculate length of current line."
(- (line-end-position) (line-beginning-position)))
(defun eri-current-line-empty nil
"Return non-nil if the current line is empty (not counting white space)."
(equal (current-indentation)
(eri-current-line-length)))
(defun eri-maximum (xs)
"Calculate maximum element in XS.
Returns nil if the list is empty."
(if xs (apply 'max xs)))
(defun eri-take (n xs)
"Return the first N elements of XS."
(butlast xs (- (length xs) n)))
(defun eri-split (x xs)
"Return a pair of lists (XS1 . XS2).
If XS is sorted, then XS = (append XS1 XS2), and all elements in
XS1 are <= X, whereas all elements in XS2 are > X."
(let* ((pos (or (position-if (lambda (y) (> y x)) xs) (length xs)))
(xs1 (eri-take pos xs))
(xs2 (nthcdr pos xs)))
(cons xs1 xs2)))
(defun eri-calculate-indentation-points-on-line (max)
"Calculate indentation points on current line.
Only points left of column number MAX are included. If MAX is
nil, then all points are included. Points are returned in
ascending order.
Example (positions marked with ^ are returned):
f x y = g 3 (Just y) 5 4
^ ^ ^ ^ ^ ^ ^ ^ |
|
MAX"
(let ((result))
(save-excursion
(save-restriction
(beginning-of-line)
; To make \\` work in the regexp below:
(narrow-to-region (line-beginning-position) (line-end-position))
(while
(progn
(let ((pos (and (search-forward-regexp
"\\(?:\\s-\\|\\`\\)\\(\\S-\\)" nil t)
(match-beginning 1))))
(when (not (null pos))
(let ((pos1 (- pos (line-beginning-position))))
(when (or (null max) (< pos1 max))
(add-to-list 'result pos1))))
(and pos
(< (point) (line-end-position))
(or (null max) (< (current-column) max))))))
(nreverse result) ; Destructive operation.
))))
(defun eri-new-indentation-points ()
"Calculate new indentation points.
Returns a singleton list containing the column number two steps
in from the indentation of the first non-empty line (white space
excluded) above the current line. If there is no such line,
then the empty list is returned."
(let ((start (line-beginning-position)))
(save-excursion
; Find a non-empty line above the current one, if any.
(while
(progn
(forward-line -1)
(not (or (bobp)
(not (eri-current-line-empty))))))
(if (or (equal (point) start)
(eri-current-line-empty))
nil
(list (+ 2 (current-indentation)))))))
(defun eri-calculate-indentation-points (reverse)
"Calculate points used to indent the current line.
The points are given in reverse order if REVERSE is non-nil. See
`eri-indent' for a description of how the indentation points are
calculated; note that the current indentation is not included in
the returned list."
;; First find a bunch of indentations used above the current line.
(let ((points)
(max)
(start (line-beginning-position)))
(save-excursion
(while
(progn
(forward-line -1)
; Skip the line we started from and lines with nothing but
; white space.
(unless (or (equal (point) start)
(eri-current-line-empty))
(setq points
(append
(eri-calculate-indentation-points-on-line max)
points))
(setq max (car points)))
;; Stop after hitting the beginning of the buffer or a
;; non-empty, non-indented line.
(not (or (bobp)
(and (equal (current-indentation) 0)
(> (eri-current-line-length) 0)))))))
;; Add new indentation points, but remove the current indentation.
;; Sort the indentations. Rearrange the points so that the next
;; point is the one after the current one. Reverse if necessary.
;;
;; Note: sort and nreverse are destructive.
(let* ((ps0 (remove (current-indentation)
(append (eri-new-indentation-points) points)))
(ps1 (eri-split (current-indentation) (sort ps0 '<)))
(ps2 (append (cdr ps1) (car ps1))))
(if reverse
(nreverse ps2)
ps2))))
(defun eri-indent (&optional reverse)
"Cycle between some possible indentation points.
With prefix argument REVERSE, cycle in reverse order.
Assume that a file contains the following lines of code, with
point on the line with three dots:
frob = loooooooooooooooooooooooooong identifier
foo = f a b
where
f (Foo x) y = let bar = x
baz = 3 + 5
...
^ ^ ^ ^ ^ ^ ^ ^ ^ * ^ ^ ^ ^
Then the ^'s and the * mark the indentation points that this
function cycles through. The indentation points are selected as
follows:
* All lines before the current one, up to and including the
first non-indented line (or the beginning of the buffer) are
considered.
foo = f a b
where
f (Foo x) y = let bar = x
baz = 3 + 5
* On these lines, erase all characters that stand to the right
of some non-white space character on a lower line.
foo
whe
f (Foo x) y = let b
baz = 3 + 5
* Also erase all characters not immediately preceded by white
space.
f
w
f ( x y = l b
b = 3 + 5
* The columns of all remaining characters are indentation
points.
f w f ( x y = l b = 3 + 5
^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^
* A new indentation point is also added, two steps in from the
indentation of the first non-empty line (white space
excluded) above the current line (if there is such a line).
f w f ( x y = l b = 3 + 5
^ ^ ^ ^ ^ ^ ^ ^ ^ * ^ ^ ^ ^"
(interactive "P")
(let* ((points (eri-calculate-indentation-points reverse))
(remaining-points (cdr (member (current-indentation) points)))
(indentation (if remaining-points
(car remaining-points)
(car points))))
(when indentation
(save-excursion (indent-line-to indentation))
(if (< (current-column) indentation)
(indent-line-to indentation)))))
(defun eri-indent-reverse nil
"Cycle between some possible indentation points (in reverse order).
See `eri-indent' for a description of how the indentation points
are calculated."
(interactive)
(eri-indent t))
(provide 'eri)
;;; eri.el ends here

View file

@ -1,11 +0,0 @@
Feature: Do Some things
In order to do something
As a user
I want to do something
Scenario: Do Something
Given I have "something"
When I have "something"
Then I should have "something"
And I should have "something"
But I should not have "something"

View file

@ -1,28 +0,0 @@
;; This file contains your project specific step definitions. All
;; files in this directory whose names end with "-steps.el" will be
;; loaded automatically by Ecukes.
(Given "^I have \"\\(.+\\)\"$"
(lambda (something)
;; ...
))
(When "^I have \"\\(.+\\)\"$"
(lambda (something)
;; ...
))
(Then "^I should have \"\\(.+\\)\"$"
(lambda (something)
;; ...
))
(And "^I have \"\\(.+\\)\"$"
(lambda (something)
;; ...
))
(But "^I should not have \"\\(.+\\)\"$"
(lambda (something)
;; ...
))

View file

@ -1,32 +0,0 @@
(require 'f)
(defvar emacs-support-path
(f-dirname load-file-name))
(defvar emacs-features-path
(f-parent emacs-support-path))
(defvar emacs-root-path
(f-parent emacs-features-path))
(add-to-list 'load-path emacs-root-path)
(require 'emacs)
(require 'espuds)
(require 'ert)
(Setup
;; Before anything has run
)
(Before
;; Before each scenario is run
)
(After
;; After each scenario is run
)
(Teardown
;; After when everything has been run
)

View file

@ -1,187 +0,0 @@
;; -*- lexical-binding: t; -*-
;; Copyright (c) 2014 Microsoft Corporation. All rights reserved.
;; Released under Apache 2.0 license as described in the file LICENSE.
;;
;; Authors: Soonho Kong, Sebastian Ullrich
;;
(require 'company)
(require 'company-etags)
(require 'dash)
(require 'dash-functional)
(require 'f)
(require 's)
(require 'cl-lib)
(require 'lean-util)
(require 'lean-server)
(defun company-lean-hook ()
(set (make-local-variable 'company-backends) '(company-lean))
(setq-local company-tooltip-limit 20) ; bigger popup window
(setq-local company-minimum-prefix-length 5)
(setq-local company-idle-delay nil) ; decrease delay before autocompletion popup shows
;(setq-local company-echo-delay 0) ; remove annoying blinking
(setq-local company-begin-commands '(self-insert-command)) ; start autocompletion only after typing
(company-mode t))
(cl-defun company-lean--make-candidate (prefix &key text type (tactic_params 'empty) doc source &allow-other-keys)
(destructuring-bind (&key file line column) source
(let ((source (cond
(file (cons file line))
(line (cons (current-buffer) (lean-pos-at-line-col line 0))))))
(propertize text
'type type
'tactic_params tactic_params
'doc doc
'source source
'prefix prefix))))
(defun company-lean--handle-singleton-candidate (prefix candidates)
"Handle singleton candidate. If the candidate does not start
with prefix, we add prefix itself as a candidate to prevent
from auto-completion."
(let ((candidate (car candidates)))
(cond ((s-prefix? prefix candidate) candidates)
(t `(,candidate ,prefix)))))
(cl-defun company-lean--exec (&key skip-completions)
"Synchronously queries completions for the current point from server and returns a plist with keys :prefix and :candidates., or nil if no completion should be triggered."
(lean-server-sync)
(let* ((col (lean-line-offset))
(response (lean-server-send-synchronous-command
'complete (list :file_name (buffer-file-name)
:line (line-number-at-pos)
:column col
:skip_completions (or skip-completions :json-false))))
(candidates (plist-get response :completions))
(prefix (plist-get response :prefix)))
(when candidates
(setq candidates
(--map (apply 'company-lean--make-candidate prefix it)
candidates))
(when (= (length candidates) 1)
(setq candidates
(company-lean--handle-singleton-candidate prefix candidates))))
(when (plist-member response :prefix)
(list :prefix prefix :candidates candidates))))
(defun company-lean--annotation (candidate)
(let ((type (get-text-property 0 'type candidate))
(tactic_params (get-text-property 0 'tactic_params candidate)))
(when type
(let* ((annotation-str (if (not (eq tactic_params 'empty))
(format " %s" (mapconcat 'identity tactic_params " "))
(format " : %s" type)))
(annotation-len (length annotation-str))
(candidate-len (length candidate))
(entry-width (+ candidate-len
annotation-len))
(allowed-width (truncate (* 0.90 (window-body-width)))))
(when (> entry-width allowed-width)
(setq annotation-str
(concat
(substring-no-properties annotation-str
0
(- allowed-width candidate-len 3))
"...")))
annotation-str))))
(defun company-lean--location (arg)
(get-text-property 0 'source arg))
(defun company-lean--match (arg)
"Return the end of matched region"
(let ((prefix (get-text-property 0 'prefix arg)))
(when (and prefix (eq (s-index-of prefix arg) 0))
(length prefix))))
(defun company-lean--meta (arg)
(get-text-property 0 'doc arg))
(defun company-lean (command &optional arg &rest ignored)
(cl-case command
(prefix (plist-get (company-lean--exec :skip-completions t) :prefix))
(candidates (plist-get (company-lean--exec) :candidates))
(annotation (company-lean--annotation arg))
(location (company-lean--location arg))
(match (company-lean--match arg))
(meta (company-lean--meta arg))
(no-cache t)
(require-match 'never)
(sorted t)))
;; ADVICES
;; =======
(defadvice company--window-width
(after lean-company--window-width activate)
(when (eq major-mode 'lean-mode)
(setq ad-return-value (truncate (* 0.95 (window-body-width))))))
(defun replace-regex-return-position (regex rep string &optional start)
"Find regex and replace with rep on string.
Return replaced string and start and end positions of replacement."
(let* ((start (or start 0))
(len (length string))
(m-start (string-match regex string start))
(m-end (match-end 0))
pre-string post-string matched-string replaced-string result)
(cond (m-start
(setq pre-string (substring string 0 m-start))
(setq matched-string (substring string m-start m-end))
(setq post-string (substring string m-end))
(string-match regex matched-string)
(setq replaced-string
(replace-match rep nil nil matched-string))
(setq result (concat pre-string
replaced-string
post-string))
`(,result ,m-start ,(+ m-start (length replaced-string)))
))))
(defun replace-regex-add-properties-all (regex rep string properties)
"Find all occurrences of regex in string, and replace them with
rep. Then, add text-properties on the replaced region."
(let ((replace-result-items (replace-regex-return-position regex rep string))
(result string))
(while replace-result-items
(pcase replace-result-items
(`(,replaced-string ,m-start ,m-end)
(setq result replaced-string)
(add-text-properties m-start m-end properties result)
(setq replace-result-items
(replace-regex-return-position regex rep result m-end)))))
result))
(eval-after-load 'company
'(defadvice company-fill-propertize
(after lean-company-fill-propertize activate)
(when (eq major-mode 'lean-mode)
(let* ((selected (ad-get-arg 3))
(foreground-color lean-company-type-foreground)
(background-color (if selected (face-background 'company-tooltip-selection)
(face-background 'company-tooltip)))
(face-attrs
(cond (background-color `(:foreground ,foreground-color
:background ,background-color))
(t `(:foreground ,foreground-color))))
(properties `(face ,face-attrs
mouse-face company-tooltip))
(old-return ad-return-value)
(old-len (length old-return))
new-return new-len)
(setq new-return
(replace-regex-add-properties-all
(rx "?" word-start (group (+ (not white))) word-end)
"\\1"
ad-return-value
properties))
(setq new-len (length new-return))
(while (< (length new-return) old-len)
(setq new-return
(concat new-return " ")))
(when background-color
(add-text-properties new-len old-len properties new-return))
(setq ad-return-value new-return)))))
(provide 'lean-company)

View file

@ -1,47 +0,0 @@
;; Copyright (c) 2014 Microsoft Corporation. All rights reserved.
;; Released under Apache 2.0 license as described in the file LICENSE.
;;
;; Author: Soonho Kong
;;
(require 'cl-lib)
(defvar lean-debug-mode nil)
(defvar lean-debug-buffer-name "*lean-debug*")
(defun lean-turn-on-debug-mode (&optional print-msg)
(interactive)
(when (or (called-interactively-p 'any) print-msg)
(message "lean: turn on debug mode"))
(get-buffer-create lean-debug-buffer-name)
(buffer-disable-undo lean-debug-buffer-name)
(display-buffer lean-debug-buffer-name 'display-buffer-reuse-window
'((reusable-frames . t)))
(setq lean-debug-mode t))
(defun lean-turn-off-debug-mode (&optional print-msg)
(interactive)
(when (eq major-mode 'lean-mode)
(when (or (called-interactively-p 'any) print-msg)
(message "lean: turn off debug mode"))
(setq lean-debug-mode nil)))
(defun lean-output-to-buffer (buffer-name format-string args)
(with-current-buffer
(get-buffer-create buffer-name)
(save-selected-window
(ignore-errors
(select-window (get-buffer-window buffer-name t)))
(goto-char (point-max))
(insert (apply 'format format-string args)))))
(defun lean-debug (format-string &rest args)
"Display a message at the bottom of the *lean-debug* buffer."
(when lean-debug-mode
(let ((time-str (format-time-string "%H:%M:%S.%3N" (current-time))))
(lean-output-to-buffer lean-debug-buffer-name
(concat "%s -- " format-string "\n")
(cons (propertize time-str 'face 'font-lock-keyword-face)
args)))))
(provide 'lean-debug)

View file

@ -1,16 +0,0 @@
;; -*- lexical-binding: t -*-
;;
;; Copyright (c) 2017 Microsoft Corporation. All rights reserved.
;; Released under Apache 2.0 license as described in the file LICENSE.
;;
;; Author: Sebastian Ullrich
;;
(defun lean-diff-test-file ()
"Use interactive ./test_input.sh on file of current buffer"
(interactive)
(message (shell-command-to-string (format "yes | ./test_single.sh \"%s\" \"%s\" yes"
(lean-get-executable "lean")
(f-filename (buffer-file-name))))))
(provide 'lean-dev)

View file

@ -1,151 +0,0 @@
;; -*- lexical-binding: t -*-
;;
;; Copyright (c) 2017 David Christiansen.
;; Released under Apache 2.0 license as described in the file LICENSE.
;;
;; Author: David Christiansen
;;
;;; Commentary:
;; This is an interface to Lean's support for holes.
;;
;; The interface consists of two components: the hole command, which
;; collects the list of completions and the message, and a handler,
;; which selects a completion.
;;
;; For now, the only handler uses completing-read, but handlers using
;; helm or company's interface would be a good addition.
;;
;;; Code:
(require 'lean-server)
(defun lean-hole-handler-completing-read (alternatives)
"Pick a hole replacement from ALTERNATIVES with `completing-read'."
(let* ((choices (cl-loop for alt in alternatives
collect (cons (concat (plist-get alt :code)
""
(plist-get alt :description))
(plist-get alt :code))))
(selection (let ((this-command 'lean-hole))
(completing-read
"Response: "
choices
nil t nil nil nil t)))
(code (assoc selection choices)))
(if code
(cdr code)
(error "Didn't select a hole completion"))))
(defvar lean-hole-handler-function 'lean-hole-handler-completing-read)
(defun lean-hole--line-col->pos (line col)
"Compute the position corresponding to LINE and COL."
(save-restriction
(widen)
(save-excursion
(goto-char (point-min))
(forward-line (1- line))
(forward-char col)
(point))))
(defun lean-hole ()
"Ask Lean for a list of holes, then ask the user which to use."
(interactive)
(with-demoted-errors "lean hole: %s"
(lean-server-send-command
'hole_commands (list :file_name (buffer-file-name)
:line (line-number-at-pos)
:column (lean-line-offset))
(cl-function
(lambda (&key start end results)
(let ((start-pos (lean-hole--line-col->pos (plist-get start :line)
(plist-get start :column)))
(end-pos (lean-hole--line-col->pos (plist-get end :line)
(plist-get end :column))))
(let ((start-marker (make-marker))
(end-marker (make-marker)))
(set-marker start-marker start-pos (current-buffer))
(set-marker end-marker end-pos (current-buffer))
(let* ((choices
(cl-loop for res in results
collect (cons (concat (plist-get res :name)
""
(plist-get res :description))
(plist-get res :name))))
(selection (let ((this-command 'lean-hole))
(completing-read
"Hole command: "
choices
nil t nil nil nil t)))
(code (assoc selection choices)))
(if code
(lean-hole--command (cdr code) start-marker end-marker)
(error "Didn't select a hole completion"))))))))))
;; This uses markers to ensure that if the hole moves while the
;; command is running, it is still updated.
(defun lean-hole--command (command start-marker end-marker)
"Execute COMMAND in the hole between START-MARKER and END-MARKER."
(interactive)
(with-demoted-errors "lean hole: %s"
(lean-server-send-command
'hole (list :action command
:file_name (buffer-file-name)
:line (line-number-at-pos start-marker)
:column (lean-line-offset start-marker))
(cl-function
(lambda (&key message replacements)
(let ((replacement-count (length (plist-get replacements :alternatives))))
(let ((selected-code
(cond ((= replacement-count 0)
nil)
((= replacement-count 1)
(plist-get (car (plist-get replacements :alternatives)) :code))
(t
(lean-hole-handler-completing-read
(plist-get replacements :alternatives))))))
(when selected-code
(save-excursion
(goto-char start-marker)
(delete-region start-marker end-marker)
(insert selected-code)))))
(when message
(message "%s" (s-trim message)))
(set-marker start-marker nil)
(set-marker end-marker nil))))))
(defun lean-hole-right-click ()
"Ask Lean for a list of hole commands, then ask the user which to use."
(interactive)
(let ((buf (current-buffer)))
(ignore-errors
(list
'hole_commands
(list :file_name (buffer-file-name)
:line (line-number-at-pos)
:column (lean-line-offset))
(cl-function
(lambda (&key start end results)
(when (and start end)
(with-current-buffer buf
(let ((start-pos (lean-hole--line-col->pos (plist-get start :line)
(plist-get start :column)))
(end-pos (lean-hole--line-col->pos (plist-get end :line)
(plist-get end :column))))
(let ((start-marker (make-marker))
(end-marker (make-marker)))
(set-marker start-marker start-pos (current-buffer))
(set-marker end-marker (1+ end-pos) (current-buffer))
(mapcar (lambda (res)
(let ((item-name (plist-get res :name))
(item-desc (plist-get res :description)))
(list :name
(concat item-name "" item-desc)
:action
(lambda ()
(lean-hole--command
item-name
start-marker end-marker)))))
results)))))))))))
(provide 'lean-hole)
;;; lean-hole.el ends here

View file

@ -1,118 +0,0 @@
;; -*- lexical-binding: t -*-
;;
;;; lean-info.el --- Emacs mode for Lean theorem prover
;;
;; Copyright (c) 2016 Gabriel Ebner. All rights reserved.
;;
;; Author: Gabriel Ebner <gebner@gebner.org>
;; Maintainer: Gabriel Ebner <gebner@gebner.org>
;; Created: Oct 29, 2016
;; Keywords: languages
;; Version: 0.1
;; URL: https://github.com/leanprover/lean/blob/master/src/emacs
;;
;; Released under Apache 2.0 license as described in the file LICENSE.
;;
;; Lean Info Mode (for "*lean-info*" buffer)
;; Automode List
;;;###autoload
(define-derived-mode lean-info-mode prog-mode "Lean-Info"
"Major mode for Lean Info Buffer"
:syntax-table lean-syntax-table
:group 'lean
(set (make-local-variable 'font-lock-defaults) lean-info-font-lock-defaults)
(set (make-local-variable 'indent-tabs-mode) nil)
(set 'compilation-mode-font-lock-keywords '())
(set-input-method "Lean")
(set (make-local-variable 'lisp-indent-function)
'common-lisp-indent-function))
(defmacro lean-with-info-output-to-buffer (buffer &rest body)
`(let ((buf (get-buffer ,buffer)))
(with-current-buffer buf
(setq buffer-read-only nil)
(erase-buffer)
(setq standard-output buf)
. ,body)))
(defun lean-ensure-info-buffer (buffer)
(unless (get-buffer buffer)
(with-current-buffer (get-buffer-create buffer)
(buffer-disable-undo)
(lean-info-mode))))
(defun lean-toggle-info-buffer (buffer)
(-if-let (window (get-buffer-window buffer))
(quit-window nil window)
(lean-ensure-info-buffer buffer)
(display-buffer buffer)))
(defun lean-info-buffer-active (buffer)
"Checks whether the given info buffer should show info for the current buffer"
(and
;; info buffer visible
(get-buffer-window buffer)
;; current window of current buffer is selected (i.e., in focus)
(eq (current-buffer) (window-buffer))))
(defun lean-highlight-string (str)
"Returns 'str' highlighted in lean-info-mode"
(lean-ensure-info-buffer " Lean tmp buffer")
(lean-with-info-output-to-buffer (get-buffer " Lean tmp buffer")
(princ str)
(font-lock-fontify-buffer)
(buffer-string)))
(defun lean-get-info-record-at-point (cont)
"Get info-record at the current point"
(with-demoted-errors "lean get info: %s"
(lean-server-send-command
'info (list :file_name (buffer-file-name)
:line (line-number-at-pos)
:column (lean-line-offset))
(cl-function
(lambda (&key record)
(funcall cont record))))))
(defun lean-info-right-click-find-definition ()
"Offer to jump to definition of right-click target."
(interactive)
(list 'info
(list :file_name (buffer-file-name)
:line (line-number-at-pos)
:column (lean-line-offset))
(cl-function
(lambda (&key record)
(let ((source-record (plist-get record :source)))
(if source-record
(let ((full-name (plist-get record :full-id)))
(list
(list :name (if full-name
(concat "Find definition of " full-name)
"Find definition")
:action (lambda ()
(apply #'lean-find-definition-cont source-record)))))
(list)))))))
(cl-defun lean-find-definition-cont (&key file line column)
(when (fboundp 'xref-push-marker-stack) (xref-push-marker-stack))
(when file
(find-file file))
(goto-char (point-min))
(forward-line (1- line))
(forward-char column))
(defun lean-find-definition ()
"Jump to definition of thing at point"
(interactive)
(lean-get-info-record-at-point
(lambda (info-record)
(-if-let (source-record (plist-get info-record :source))
(apply #'lean-find-definition-cont source-record)
(-if-let (id (plist-get info-record :full-id))
(message "no source location available for %s" id)
(message "unknown thing at point"))))))
(provide 'lean-info)

File diff suppressed because it is too large Load diff

View file

@ -1,124 +0,0 @@
;; -*- lexical-binding: t -*-
;;
;; Copyright (c) 2016 David Christiansen.
;; Released under Apache 2.0 license as described in the file LICENSE.
;;
;; Author: David Christiansen
;;
;;; Code:
(require 's)
(require 'lean-server)
(defface lean-message-boxes-content-face
'((t :inherit font-lock-doc-face))
"Face for Lean message box contents."
:group 'lean)
(defcustom lean-message-boxes-enabled-captions '("check result" "print result")
"Which captions should result in boxes?"
:group 'lean
:type '(repeat (choice (const "check result")
(const "print result")
(const "trace output"))))
(defvar lean-message-boxes-enabledp nil
"Whether or not to display message boxes.")
(make-variable-buffer-local 'lean-message-boxes-enabledp)
(defun lean-message-boxes--ask-for-messages ()
"Get the current messages out of the Lean server session."
(let ((buf (current-buffer)))
(if lean-server-session
(remove-if-not (lambda (msg)
(equal (buffer-file-name buf)
(plist-get msg :file_name)))
(lean-server-session-messages lean-server-session))
'())))
(defun lean-message-boxes--set-enabledp (enabledp)
"Enable the boxes if ENABLEDP is non-nil."
(setq lean-message-boxes-enabledp enabledp)
(lean-message-boxes-display (lean-message-boxes--ask-for-messages)))
(defun lean-message-boxes-toggle ()
"Toggle the display of message boxes."
(interactive)
(lean-message-boxes--set-enabledp (not lean-message-boxes-enabledp)))
(defun lean-message-boxes-enable ()
"Enable the display of message boxes."
(interactive)
(setq lean-message-boxes--set-enabledp t))
(defun lean-message-boxes-disable ()
"Disable the display of message boxes."
(interactive)
(setq lean-message-boxes--set-enabledp t))
(defvar lean-message-boxes--overlays '()
"The overlays in the current buffer from Lean messages.")
(make-variable-buffer-local 'lean-message-boxes--overlays)
(defun lean-message-boxes--kill-overlays ()
"Delete all Lean message overlays in the current buffer."
(dolist (o lean-message-boxes--overlays)
(delete-overlay o))
(setq lean-message-boxes--overlays '()))
(defun lean-message-boxes--pad-to (str width)
"Pad the string STR to a particular WIDTH."
(concat str (make-string (max 0 (- width (length str))) ?\ )))
(defun lean-message-boxes-display (msgs)
"Show the messages MSGS in the Lean buffer as boxes when `lean-message-boxes-enabledp' is non-nil."
(lean-message-boxes--kill-overlays)
(when lean-message-boxes-enabledp
(dolist (msg msgs)
(let ((end-line (plist-get msg :end_pos_line))
(end-col (plist-get msg :end_pos_col))
(caption (plist-get msg :caption))
(text (plist-get msg :text)))
(when (member caption lean-message-boxes-enabled-captions)
(let ((overlay (lean-message-boxes--make-overlay
end-line end-col
caption text)))
(push overlay lean-message-boxes--overlays)))))))
(defun lean-message-boxes--as-string (caption str)
"Construct a propertized string representing CAPTION and STR."
(let* ((caption-copy (concat caption))
(str-copy (s-trim str)))
(put-text-property 0 (length str-copy)
'face 'lean-message-boxes-content-face
str-copy)
(let* ((lines (s-lines str-copy))
(w (apply #'max (mapcar #'length (cons caption lines)))))
(apply #'concat
(mapcar
(lambda (l)
(concat ""
(lean-message-boxes--pad-to l w)
"\n"))
lines)))))
(defun lean-message-boxes--make-overlay (end-line end-col caption text)
"Construct a message box overlay at LINE and COL with CAPTION and TEXT."
(let* ((end-pos (save-excursion (goto-char (point-min))
(forward-line (1- end-line))
(forward-char (1- end-col))
(while (looking-at-p "[\t\r\n ]")
(forward-char -1))
(end-of-line)
(1+ (point))))
(overlay (make-overlay end-pos (1+ end-pos)))
(as-box (lean-message-boxes--as-string caption text)))
(put-text-property 0 1 'cursor t as-box)
(overlay-put overlay 'before-string as-box)
(overlay-put overlay 'help-echo caption)
(overlay-put overlay 'lean-is-output-overlay t)
(overlay-put overlay 'evaporate t)
overlay))
(add-hook 'lean-server-show-message-hook 'lean-message-boxes-display)
(provide 'lean-message-boxes)

View file

@ -1,233 +0,0 @@
;; -*- lexical-binding: t -*-
;;
;;; lean-mode.el --- Emacs mode for Lean theorem prover
;;
;; Copyright (c) 2013, 2014 Microsoft Corporation. All rights reserved.
;; Copyright (c) 2014, 2015 Soonho Kong. All rights reserved.
;;
;; Author: Leonardo de Moura <leonardo@microsoft.com>
;; Soonho Kong <soonhok@cs.cmu.edu>
;; Maintainer: Soonho Kong <soonhok@cs.cmu.edu>
;; Created: Jan 09, 2014
;; Keywords: languages
;; Version: 0.1
;; URL: https://github.com/leanprover/lean/blob/master/src/emacs
;;
;; Released under Apache 2.0 license as described in the file LICENSE.
;;
(require 'cl-lib)
(require 'pcase)
(require 'lean-require)
(require 'eri)
(require 'flycheck)
(require 'lean-util)
(require 'lean-settings)
(require 'lean-input)
(require 'lean-syntax)
(require 'lean-pkg)
(require 'lean-company)
(require 'lean-server)
(require 'lean-flycheck)
(require 'lean-info)
(require 'lean-hole)
(require 'lean-type)
(require 'lean-message-boxes)
(require 'lean-right-click)
(require 'lean-dev)
(defun lean-compile-string (exe-name args file-name)
"Concatenate exe-name, args, and file-name"
(format "%s %s %s" exe-name args file-name))
(defun lean-create-temp-in-system-tempdir (file-name prefix)
"Create a temp lean file and return its name"
(make-temp-file (or prefix "flymake") nil (f-ext file-name)))
(defun lean-execute (&optional arg)
"Execute Lean in the current buffer"
(interactive)
(when (called-interactively-p 'any)
(setq arg (read-string "arg: " arg)))
(let ((cc compile-command)
(target-file-name
(or
(buffer-file-name)
(flymake-init-create-temp-buffer-copy 'lean-create-temp-in-system-tempdir))))
(compile (lean-compile-string
(shell-quote-argument (f-full (lean-get-executable lean-executable-name)))
(or arg "")
(shell-quote-argument (f-full target-file-name))))
;; restore old value
(setq compile-command cc)))
(defun lean-std-exe ()
(interactive)
(lean-execute))
(defun lean-check-expansion ()
(interactive)
(save-excursion
(if (looking-at (rx symbol-start "_")) t
(if (looking-at "\\_>") t
(backward-char 1)
(if (looking-at "\\.") t
(backward-char 1)
(if (looking-at "->") t nil))))))
(defun lean-tab-indent ()
(interactive)
(cond ((looking-back (rx line-start (* white)) nil)
(eri-indent))
(t (indent-for-tab-command))))
(defun lean-set-keys ()
(local-set-key lean-keybinding-std-exe1 'lean-std-exe)
(local-set-key lean-keybinding-std-exe2 'lean-std-exe)
(local-set-key lean-keybinding-show-key 'quail-show-key)
(local-set-key lean-keybinding-server-restart 'lean-server-restart)
(local-set-key lean-keybinding-find-definition 'lean-find-definition)
(local-set-key lean-keybinding-tab-indent 'lean-tab-indent)
(local-set-key lean-keybinding-auto-complete 'company-complete)
(local-set-key lean-keybinding-hole 'lean-hole)
(local-set-key lean-keybinding-lean-toggle-show-goal 'lean-toggle-show-goal)
(local-set-key lean-keybinding-lean-toggle-next-error 'lean-toggle-next-error)
(local-set-key lean-keybinding-lean-message-boxes-toggle 'lean-message-boxes-toggle)
(local-set-key lean-keybinding-leanpkg-configure 'leanpkg-configure)
(local-set-key lean-keybinding-leanpkg-build 'leanpkg-build)
(local-set-key lean-keybinding-leanpkg-test 'leanpkg-test)
(local-set-key lean-keybinding-lean-helm-definitions 'lean-helm-definitions)
;; This only works as a mouse binding due to the event, so it is not abstracted
;; to avoid user confusion.
(local-set-key (kbd "<mouse-3>") 'lean-right-click-show-menu)
)
(define-abbrev-table 'lean-abbrev-table
'())
(defvar lean-mode-map (make-sparse-keymap)
"Keymap used in Lean mode")
(defun lean-mk-check-menu-option (text sym)
`[,text (lean-set-check-mode ',sym)
:style radio :selected (eq lean-server-check-mode ',sym)])
(easy-menu-define lean-mode-menu lean-mode-map
"Menu for the Lean major mode"
`("Lean"
["Execute lean" lean-execute t]
;; ["Create a new project" (call-interactively 'lean-project-create) (not (lean-project-inside-p))]
"-----------------"
["Show type info" lean-show-type (and lean-eldoc-use eldoc-mode)]
["Toggle goal display" lean-toggle-show-goal t]
["Toggle next error display" lean-toggle-next-error t]
["Toggle message boxes" lean-message-boxes-toggle t]
["Highlight pending tasks" lean-server-toggle-show-pending-tasks
:active t :style toggle :selected lean-server-show-pending-tasks]
["Find definition at point" lean-find-definition t]
"-----------------"
["List of errors" flycheck-list-errors flycheck-mode]
"-----------------"
["Restart lean process" lean-server-restart t]
"-----------------"
,(lean-mk-check-menu-option "Check nothing" 'nothing)
,(lean-mk-check-menu-option "Check visible lines" 'visible-lines)
,(lean-mk-check-menu-option "Check visible lines and above" 'visible-lines-and-above)
,(lean-mk-check-menu-option "Check visible files" 'visible-files)
,(lean-mk-check-menu-option "Check open files" 'open-files)
"-----------------"
("Configuration"
["Show type at point"
lean-toggle-eldoc-mode :active t :style toggle :selected eldoc-mode])
"-----------------"
["Customize lean-mode" (customize-group 'lean) t]))
(defconst lean-hooks-alist
'(
;; server
;; (kill-buffer-hook . lean-server-stop)
(after-change-functions . lean-server-change-hook)
(focus-in-hook . lean-server-show-messages)
(window-scroll-functions . lean-server-window-scroll-function-hook)
;; Handle events that may start automatic syntax checks
(before-save-hook . lean-whitespace-cleanup)
;; info windows
(post-command-hook . lean-show-goal--handler)
(post-command-hook . lean-next-error--handler)
(flycheck-after-syntax-check-hook . lean-show-goal--handler)
(flycheck-after-syntax-check-hook . lean-next-error--handler)
)
"Hooks which lean-mode needs to hook in.
The `car' of each pair is a hook variable, the `cdr' a function
to be added or removed from the hook variable if Flycheck mode is
enabled and disabled respectively.")
(defun lean-mode-setup ()
"Default lean-mode setup"
;; server
(ignore-errors (lean-server-ensure-alive))
(setq mode-name '("Lean" (:eval (lean-server-status-string))))
;; Right click menu sources
(setq lean-right-click-item-functions '(lean-info-right-click-find-definition
lean-hole-right-click))
;; Flycheck
(lean-flycheck-turn-on)
(setq-local flycheck-disabled-checkers '())
;; info buffers
(lean-ensure-info-buffer lean-next-error-buffer-name)
(lean-ensure-info-buffer lean-show-goal-buffer-name)
;; company-mode
(when lean-company-use
(company-lean-hook))
;; eldoc
(when lean-eldoc-use
(set (make-local-variable 'eldoc-documentation-function)
'lean-eldoc-documentation-function)
(eldoc-mode t)))
;; Automode List
;;;###autoload
(define-derived-mode lean-mode prog-mode "Lean"
"Major mode for Lean
\\{lean-mode-map}
Invokes `lean-mode-hook'.
"
:syntax-table lean-syntax-table
:abbrev-table lean-abbrev-table
:group 'lean
(set (make-local-variable 'comment-start) "--")
(set (make-local-variable 'comment-start-skip) "[-/]-[ \t]*")
(set (make-local-variable 'comment-end) "")
(set (make-local-variable 'comment-end-skip) "[ \t]*\\(-/\\|\\s>\\)")
(set (make-local-variable 'comment-padding) 1)
(set (make-local-variable 'comment-use-syntax) t)
(set (make-local-variable 'font-lock-defaults) lean-font-lock-defaults)
(set (make-local-variable 'indent-tabs-mode) nil)
(set 'compilation-mode-font-lock-keywords '())
(set-input-method "Lean")
(set (make-local-variable 'lisp-indent-function)
'common-lisp-indent-function)
(lean-set-keys)
(if (fboundp 'electric-indent-local-mode)
(electric-indent-local-mode -1))
;; (abbrev-mode 1)
(pcase-dolist (`(,hook . ,fn) lean-hooks-alist)
(add-hook hook fn nil 'local))
(lean-mode-setup))
;; Automatically use lean-mode for .lean files.
;;;###autoload
(push '("\\.lean$" . lean-mode) auto-mode-alist)
(push '("\\.hlean$" . lean-mode) auto-mode-alist)
;; Use utf-8 encoding
;;;### autoload
(modify-coding-system-alist 'file "\\.lean\\'" 'utf-8)
(modify-coding-system-alist 'file "\\.hlean\\'" 'utf-8)
;; Flycheck init
(eval-after-load 'flycheck
'(lean-flycheck-init))
(provide 'lean-mode)
;;; lean-mode.el ends here

View file

@ -1,93 +0,0 @@
;; -*- lexical-binding: t -*-
;;
;; Copyright (c) 2017 Microsoft Corporation. All rights reserved.
;; Released under Apache 2.0 license as described in the file LICENSE.
;;
;; Author: Gabriel Ebner
;;
(require 's)
(require 'json)
(require 'lean-util)
(defun leanpkg-find-dir-in (dir)
(when dir
(or (leanpkg-find-dir-in (f-parent dir))
(when (f-exists? (f-join dir "leanpkg.toml")) dir))))
(defun leanpkg-find-dir ()
(and (buffer-file-name)
(leanpkg-find-dir-in (f-dirname (buffer-file-name)))))
(defun leanpkg-find-dir-safe ()
(or (leanpkg-find-dir)
(error (format "cannot find leanpkg.toml for %s" (buffer-file-name)))))
(defun leanpkg-executable ()
(lean-get-executable "leanpkg"))
(defvar leanpkg-running nil)
(defvar-local leanpkg-configure-prompt-shown nil)
(defun leanpkg-run (cmd &optional restart-lean-server)
"Call `leanpkg $cmd`"
(let ((dir (file-name-as-directory (leanpkg-find-dir-safe)))
(orig-buf (current-buffer)))
(with-current-buffer (get-buffer-create "*leanpkg*")
(setq buffer-read-only nil)
(erase-buffer)
(switch-to-buffer-other-window (current-buffer))
(redisplay)
(insert (format "> leanpkg %s\n" cmd))
(setq leanpkg-running t)
(let* ((default-directory dir)
(out-buf (current-buffer))
(proc (start-process "leanpkg" (current-buffer)
(leanpkg-executable) cmd)))
(set-process-sentinel
proc (lambda (p e)
(setq leanpkg-running nil)
(when restart-lean-server
(with-current-buffer out-buf
(insert "; restarting lean server\n"))
(with-current-buffer orig-buf
(lean-server-restart)))))))))
(defun leanpkg-configure ()
"Call leanpkg configure"
(interactive)
(leanpkg-run "configure" 't))
(defun leanpkg-build ()
"Call leanpkg build"
(interactive)
(leanpkg-run "build"))
(defun leanpkg-test ()
"Call leanpkg test"
(interactive)
(leanpkg-run "test"))
(defun leanpkg-find-path-file ()
(let* ((json-object-type 'plist) (json-array-type 'list) (json-false nil)
(path-json (shell-command-to-string
(concat (shell-quote-argument (lean-get-executable lean-executable-name))
" -p")))
(path-out (json-read-from-string path-json)))
(when (and (eq major-mode 'lean-mode)
(plist-get path-out :is_user_leanpkg_path)
(not leanpkg-running)
(not leanpkg-configure-prompt-shown)
(setq leanpkg-configure-prompt-shown t)
(leanpkg-find-dir)
(y-or-n-p (format "Found leanpkg.toml in %s, call leanpkg configure?" (leanpkg-find-dir))))
(save-match-data ; running in timer so that we don't mess up the window layout
(run-at-time nil nil
(lambda (buf)
(with-current-buffer buf
(leanpkg-configure)))
(current-buffer))))
(setq leanpkg-configure-prompt-shown t)
(plist-get path-out :leanpkg_path_file)))
(provide 'lean-pkg)

View file

@ -1,32 +0,0 @@
;; Copyright (c) 2014 Microsoft Corporation. All rights reserved.
;; Released under Apache 2.0 license as described in the file LICENSE.
;;
;; Author: Soonho Kong
;;
(defun lean-mode-require-package (pkg)
"Check whether pkg is available or not."
(unless (featurep pkg)
(if (not (require pkg (symbol-name pkg) t))
(error "lean-mode: required package '%s' is not found." (symbol-name pkg))
(message "lean-mode: package %S loaded." pkg))))
(defun lean-mode-check-package (pkg)
"Check whether pkg is available or not."
(unless (featurep pkg)
(if (not (require pkg (symbol-name pkg) t))
(message "lean-mode: optional package '%s' is not found." (symbol-name pkg))
(message "lean-mode: optional package %S loaded." pkg))))
(defun lean-mode-check-requirements ()
"Check lean-mode requirements"
(if (not (>= emacs-major-version 24))
(error "Emacs version >= 24 is required to use lean-mode"))
(lean-mode-check-package 'package)
(lean-mode-check-package 'dash)
(let ((required-packages '(cl-lib compile dash dash-functional f flymake s))
(optional-packages '(flycheck)))
(-each required-packages 'lean-mode-require-package)
(-each optional-packages 'lean-mode-check-package)))
(lean-mode-check-requirements)
(provide 'lean-require)

View file

@ -1,84 +0,0 @@
;; -*- lexical-binding: t -*-
;;
;;; lean-right-click.el
;;
;; Copyright (c) 2017 David Christiansen. All rights reserved.
;;
;; Author: David Christiansen
;; Released under Apache 2.0 license as described in the file LICENSE.
;;
;;; Code:
(defvar lean-right-click-item-functions nil
"A list of functions to compute menu items from source locations.
The functions take no arguments. They will be run in a context
where `current-buffer' gives the buffer in which the click
occurred. The function should return a three-element list, where
the first is a Lean server command, the second is its parameter
list, and the third is a continuation that will compute a list of
menu items.
Each menu item is a plist that maps the key :name to the string
to show in the menu and the key :action to a zero-argument
function that implements the action.")
(make-variable-buffer-local 'lean-right-click-item-functions)
(defvar lean-right-click--unique-val-counter 0
"A global counter for unique values for lean-right-click.")
(defun lean-right-click--unique-val ()
"Get a unique value for internal tagging."
(cl-incf lean-right-click--unique-val-counter))
(defun lean-right-click--items-for-location ()
"Return the menu items for point in the current buffer."
(let ((commands (cl-loop for fun in lean-right-click-item-functions
collecting (funcall fun))))
(let ((timeout 0.15)
(items '())
(start-time (time-to-seconds))
(command-count (length commands))
(commands-returned 0))
(cl-loop for (cmd args cont) in commands
do (progn (lean-server-send-command
cmd args
(lambda (&rest result)
(setq items (append items (apply cont result)))
(cl-incf commands-returned))
(lambda (&rest _whatever)
(cl-incf commands-returned)))
;; This is necessary to ensure that async IO happens.
(sit-for 0.02)))
(while (and (< (time-to-seconds) (+ timeout start-time))
(< commands-returned command-count))
(sit-for 0.02))
items)))
(defun lean-right-click-show-menu (click)
"Show a menu based on the location of CLICK, computed from the `lean-right-click-functions'."
(interactive "e")
(let* ((window (posn-window (event-end click)))
(buffer (window-buffer window))
(where (posn-point (event-end click)))
(menu-items (with-current-buffer buffer
(save-excursion
(goto-char where)
(lean-right-click--items-for-location)))))
(when menu-items
(let* ((menu (make-sparse-keymap))
(todo (cl-loop for item in menu-items
collecting (let ((sym (lean-right-click--unique-val)))
(define-key-after menu `[,sym]
`(menu-item ,(plist-get item :name)
(lambda () (interactive)))
t)
(cons sym (plist-get item :action)))))
(selection (x-popup-menu click menu)))
(when selection
(funcall (cdr (assoc (car selection) todo))))))))
(provide 'lean-right-click)
;;; lean-right-click.el ends here

View file

@ -1,487 +0,0 @@
;; -*- lexical-binding: t -*-
;;
;; Copyright (c) 2016 Microsoft Corporation. All rights reserved.
;; Released under Apache 2.0 license as described in the file LICENSE.
;;
;; Author: Gabriel Ebner
;;
(require 'json)
(require 'lean-debug)
(require 'lean-pkg)
(require 'dash)
(defcustom lean-server-show-message-hook '(lean-message-boxes-display)
"Hook run on messages from Lean, allowing custom display.
Each hook is a function that receives a list of message objects
for the current buffer. Each message object is a plist with at
least the following keys:
- :pos_line is the line number of the message, a number
- :pos_col is the column of the start of the message, a number
- :caption is a category of message, a string
- :text is the text to display, a string."
:group 'lean
:type 'hook
:options '(lean-message-boxes-display))
(defstruct lean-server-session
path-file ; the leanpkg.path file of this lean server
process ; process object of lean --server
seq-num ; sequence number
callbacks ; alist of (seq_num . (success_cb . error_cb))
current-roi ; alist of (file_name (begin_line . end_line) ...)
tasks ; last deserialized current_tasks message
messages) ; list of messages in deserialized json
(defun lean-server-session-proc-buffer (sess)
(process-buffer (lean-server-session-process sess)))
(defun lean-server-session-pop-callback (sess seq-num)
(let ((cbp (assoc seq-num (lean-server-session-callbacks sess))))
(setf (lean-server-session-callbacks sess)
(delete cbp (lean-server-session-callbacks sess)))
(if cbp (cdr cbp) (cons nil nil))))
(defun lean-server-process-response (sess res)
(pcase (plist-get res :response)
("additional_message"
(setf (lean-server-session-messages sess)
(cons (plist-get res :msg) (lean-server-session-messages sess)))
(lean-server-notify-messages-changed sess))
("all_messages"
(setf (lean-server-session-messages sess)
(plist-get res :msgs))
(lean-server-notify-messages-changed sess))
("current_tasks"
(let ((old-tasks (lean-server-session-tasks sess)))
(setf (lean-server-session-tasks sess) res)
(lean-server-notify-tasks-changed sess old-tasks)))
("error"
(message "error: %s" (plist-get res :message))
;; TODO(gabriel): maybe even add the error as a message
(when (plist-get res :seq_num)
(let ((cb (lean-server-session-pop-callback sess (plist-get res :seq_num))))
(when (cdr cb) (funcall (cdr cb) res)))))
("ok"
(let ((cb (lean-server-session-pop-callback sess (plist-get res :seq_num))))
(when (car cb) (funcall (car cb) res))))))
(defun lean-server-process-line (sess line)
(condition-case-unless-debug err
(progn
(lean-debug "server=> %s" line)
(let* ((json-array-type 'list)
(json-object-type 'plist)
(json-false nil)
(response (json-read-from-string line)))
(lean-server-process-response sess response)))
(error (message "error in lean-server command handler: %s\nServer response was:\n%s" err (buffer-string)))))
(defun lean-server-process-buffer (sess)
(goto-char (point-min))
(when (search-forward "\n" nil t)
(let ((line (buffer-substring (point-min) (point))))
(delete-region (point-min) (point))
(lean-server-process-line sess line)
(lean-server-process-buffer sess))))
(defun lean-server-filter (sess string)
(when (buffer-live-p (lean-server-session-proc-buffer sess))
(with-current-buffer (lean-server-session-proc-buffer sess)
(goto-char (point-max))
(insert string)
(lean-server-process-buffer sess))))
(defun lean-server-handle-signal (process event)
"Handle signals for lean-server-process"
(force-mode-line-update)
(let ((event-string (s-trim event)))
(lean-debug "lean-server-handle-signal: %s"
(propertize event-string 'face '(:foreground "red")))
(if (s-contains? "abnormally" event)
(message (concat "Lean server died. See lean-server stderr buffer for details; "
"use lean-server-restart to restart it")))))
(defun lean-server-session-create (path-file)
"Creates a new server session"
(let* ((default-directory (f--traverse-upwards (f-dir? it) path-file))
; Setting process-connection-type is necessary, otherwise
; emacs truncates lines with >4096 bytes:
; https://debbugs.gnu.org/cgi/bugreport.cgi?bug=24531
(process-connection-type nil)
(cmd `(,(lean-get-executable lean-executable-name)
"--server"
,(format "-M%i" lean-memory-limit)
,(format "-T%i" lean-timeout-limit)
,@lean-extra-arguments
,(format "*%s*" path-file)))
(proc (if (fboundp 'make-process)
(make-process ;; emacs >= 25 lets us redirect stderr
:name "lean-server"
:buffer (format " *lean-server (%s)*" path-file)
:command cmd
:coding 'utf-8
:noquery t
:sentinel #'lean-server-handle-signal
:stderr (make-pipe-process
:name "lean-server stderr"
:buffer (format "*lean-server stderr (%s)*" path-file)
:noquery t))
(progn
; emacs 24 loves directory separators, without it
; the server gets started in the parent directory....
(setq default-directory (format "%s/" default-directory))
(apply #'start-process "lean-server"
(format " *lean-server (%s)*" (buffer-name))
cmd))))
(sess (make-lean-server-session
:path-file path-file
:process proc
:seq-num 0
:current-roi 'not-yet-sent
:callbacks nil
:messages nil)))
(set-process-filter proc (lambda (proc string) (lean-server-filter sess string)))
(set-process-coding-system proc 'utf-8 'utf-8)
(set-process-query-on-exit-flag proc nil)
sess))
(defun lean-server-session-send-command (sess cmd-name params &optional cb error-cb)
(let* ((seq-num (lean-server-session-seq-num sess))
(req `(:seq_num ,seq-num :command ,cmd-name . ,params))
(json-array-type 'list)
(json-object-type 'plist)
(json-false :json-false)
(json-req (json-encode req))
(cur-buf (current-buffer))
(wrapped-cb (and cb
(lambda (res)
(and cur-buf
(with-current-buffer cur-buf
(apply cb :allow-other-keys t res))))))
(wrapped-err-cb (and error-cb
(lambda (res)
(and cur-buf
(with-current-buffer cur-buf
(apply error-cb :allow-other-keys t res)))))))
(setf (lean-server-session-seq-num sess) (1+ seq-num))
(if (or cb error-cb)
(setf (lean-server-session-callbacks sess)
(cons (cons seq-num (cons wrapped-cb wrapped-err-cb)) (lean-server-session-callbacks sess))))
(lean-debug "server<= %s" json-req)
(process-send-string (lean-server-session-process sess)
(concat json-req "\n"))))
(defvar lean-server-sessions nil
"list of all running lean-server-sessions")
(defun lean-server-session-alive-p (sess)
(and sess
(lean-server-session-process sess)
(equal 'run (process-status (lean-server-session-process sess)))))
(defun lean-server-session-kill (sess)
(ignore-errors (delete-process (lean-server-session-process sess)))
(ignore-errors (kill-buffer (lean-server-session-proc-buffer sess)))
(setf (lean-server-session-process sess) nil)
(setq lean-server-sessions (delete sess lean-server-sessions)))
(defun lean-server-session-get (path-file)
(setq lean-server-sessions
(remove-if-not #'lean-server-session-alive-p
lean-server-sessions))
(or (find path-file lean-server-sessions
:test (lambda (d s) (equal d (lean-server-session-path-file s))))
(let ((sess (lean-server-session-create path-file)))
(setq lean-server-sessions (cons sess lean-server-sessions))
sess)))
(defvar-local lean-server-session nil
"Lean server session for the current buffer")
(defun lean-server-session-running-p (sess)
(and sess (plist-get (lean-server-session-tasks sess) :is_running)))
(defun lean-server-status-string ()
(if (not (lean-server-session-alive-p lean-server-session)) ""
(if (lean-server-session-running-p lean-server-session) ""
"")))
(defvar-local lean-server-flycheck-delay-timer nil)
(defvar-local lean-server-task-overlays nil)
(defun lean-server-task-region (task)
(let ((bl (1- (plist-get task :pos_line)))
(bc (plist-get task :pos_col))
(el (1- (plist-get task :end_pos_line)))
(ec (plist-get task :end_pos_col)))
(save-excursion
(widen)
(goto-char (point-min))
(forward-line bl)
(if (equal (cons bl bc) (cons el ec))
(progn
(let ((beg (point)))
(forward-line 1)
(cons beg (point))))
(ignore-errors (forward-char bc))
(let ((beg (point)))
(goto-char (point-min))
(forward-line el)
(ignore-errors (forward-char ec))
(cons beg (point)))))))
(defface lean-server-task-face
nil
"Face to highlight pending Lean tasks."
:group 'lean)
(if (fboundp 'define-fringe-bitmap)
(define-fringe-bitmap 'lean-server-fringe-bitmap
(vector) 16 8))
(defface lean-server-task-fringe-face
'((((class color) (background light))
:background "chocolate1")
(((class color) (background dark))
:background "navajo white")
(t :inverse-video t))
"Face to highlight the fringe of pending Lean tasks."
:group 'lean)
(defun lean-server-update-task-overlays ()
(dolist (ov lean-server-task-overlays) (delete-overlay ov))
(setq lean-server-task-overlays nil)
(when (and lean-server-show-pending-tasks lean-server-session)
(let* ((tasks (lean-server-session-tasks lean-server-session))
(cur-fn (buffer-file-name))
(roi (cdr (assq cur-fn (lean-server-session-current-roi lean-server-session)))))
(dolist (task (plist-get tasks :tasks))
(if (and (equal (plist-get task :file_name) cur-fn)
(--any? (<= (max (car it) (plist-get task :pos_line))
(min (cdr it) (plist-get task :end_pos_line)))
roi))
(let* ((reg (lean-server-task-region task))
(ov (make-overlay (car reg) (cdr reg))))
(setq lean-server-task-overlays (cons ov lean-server-task-overlays))
(overlay-put ov 'face 'lean-server-task-face)
(overlay-put ov 'line-prefix
(propertize " " 'display
'(left-fringe lean-server-fringe-bitmap lean-server-task-fringe-face)))
(overlay-put ov 'help-echo (format "%s..." (plist-get task :desc)))))))))
(defun lean-server-toggle-show-pending-tasks ()
"Toggles highlighting of pending tasks"
(interactive)
(setq lean-server-show-pending-tasks (not lean-server-show-pending-tasks))
(dolist (sess lean-server-sessions)
(lean-server-notify-tasks-changed sess nil)))
(defvar-local lean-server-flycheck-delay-timer nil)
(defvar-local lean-server-flycheck-delayed-update nil)
(defun lean-server-show-messages (&optional buf)
(with-current-buffer (or buf (current-buffer))
(save-match-data
(when (and (eq buf flycheck-error-list-source-buffer)
(get-buffer-window buf))
(if (memq lean-server-flycheck-delay-timer timer-list)
(setq lean-server-flycheck-delayed-update t) ; arm timer
(flycheck-buffer)
(setq lean-server-flycheck-delay-timer
(run-at-time "100 milliseconds" nil
(lambda (buf)
(with-current-buffer buf
(when lean-server-flycheck-delayed-update
(setq lean-server-flycheck-delayed-update nil)
(flycheck-buffer))))
(current-buffer))))))
(when lean-server-session
(let ((relevant-msgs
(remove-if-not (lambda (msg)
(equal (buffer-file-name buf)
(plist-get msg :file_name)))
(lean-server-session-messages lean-server-session))))
(dolist (hook lean-server-show-message-hook)
(funcall hook relevant-msgs))))))
(defvar-local lean-server-show-tasks-delay-timer nil)
(defun lean-server-show-tasks (&optional buf)
(with-current-buffer (or buf (current-buffer))
(save-match-data
(when (not (memq lean-server-show-tasks-delay-timer timer-list))
(setq lean-server-show-tasks-delay-timer
(run-at-time "300 milliseconds" nil
(lambda (buf)
(with-current-buffer buf
(lean-server-update-task-overlays)))
(current-buffer)))))))
(defun lean-server-notify-messages-changed (sess)
(dolist (buf (buffer-list))
(with-current-buffer buf
(when (and lean-server-session
(eq sess lean-server-session))
(lean-server-show-messages)))))
(defun lean-server-notify-tasks-changed (sess old-tasks)
(force-mode-line-update)
(when (and (not lean-server-show-pending-tasks)
(or (plist-get old-tasks :tasks)
(plist-get (lean-server-session-tasks sess) :tasks)))
; update task flycheck messages only if the task list is non-empty
(lean-server-notify-messages-changed sess))
(dolist (buf (buffer-list))
(with-current-buffer buf
(when (eq sess lean-server-session)
(lean-server-show-tasks)))))
(defun lean-server-stop ()
"Stops the lean server associated with the current buffer"
(interactive)
(when lean-server-session
(lean-server-session-kill lean-server-session)))
(defun lean-server-ensure-alive ()
"Ensures that the current buffer has a lean server"
(when (not (lean-server-session-alive-p lean-server-session))
(setq lean-server-session (lean-server-session-get (leanpkg-find-path-file)))
(lean-server-show-tasks)
(lean-server-show-messages)
(lean-server-sync)))
(defun lean-server-restart ()
"Restarts the lean server for the current buffer"
(interactive)
(lean-server-stop)
(lean-server-ensure-alive)
(flycheck-stop)
(flycheck-buffer))
(defun lean-server-send-command (cmd params &optional cb error-cb)
"Sends a command to the lean server for the current buffer, with a callback to be called upon completion"
(lean-server-ensure-alive)
(lean-server-session-send-command lean-server-session cmd params cb error-cb))
(defun lean-server-send-synchronous-command (cmd params)
"Sends a command to the lean server for the current buffer, waiting for and returning the response"
;; inspired by company--force-sync
(let ((res 'trash)
(ok t)
(start (time-to-seconds)))
(lean-server-send-command cmd params
(lambda (&rest result) (setq res result))
(cl-function
(lambda (&key message)
(setq ok nil)
(setq res message))))
(while (eq res 'trash)
(if (> (- (time-to-seconds) start) company-async-timeout)
(error "Lean server timed out")
(sleep-for company-async-wait)))
(if ok
res
(error res))))
(defun lean-server-sync (&optional buf)
"Synchronizes the state of BUF (or the current buffer, if nil) with the lean server"
(with-demoted-errors "lean server sync: %s"
(with-current-buffer (or buf (current-buffer))
(lean-server-sync-roi)
(lean-server-send-command
'sync (list :file_name (buffer-file-name)
:content (buffer-string))))))
(defvar-local lean-server-sync-timer nil)
(defun lean-server-change-hook (begin end len)
(save-match-data
(when lean-server-sync-timer (cancel-timer lean-server-sync-timer))
(setq lean-server-sync-timer
(run-at-time "50 milliseconds" nil #'lean-server-sync (current-buffer)))))
(defun lean-server-compute-roi (sess)
"Compute the region of interest for the session SESS."
(--mapcat (with-current-buffer it
(when (eq lean-server-session sess)
(list (cons (buffer-file-name)
(--map (cons (line-number-at-pos (window-start it))
(line-number-at-pos (window-end it t)))
(get-buffer-window-list))))))
(buffer-list)))
(defun lean-server-session-send-roi (sess roi)
(setf (lean-server-session-current-roi sess) roi)
(lean-server-send-command
'roi (list :mode lean-server-check-mode
:files (--map (list (cons :file_name (car it))
(cons :ranges (--map (list (cons :begin_line (car it))
(cons :end_line (cdr it)))
(cdr it))))
roi))))
(defun lean-server-roi-subset-p (as bs)
(--all? (let ((b (cdr (assq (car it) bs))))
(and b (-all? (lambda (ar) (--any? (and (<= (car it) (car ar))
(<= (cdr ar) (cdr it)))
b))
(cdr it))))
as))
(defun lean-server-roi-extend (roi delta)
(--map `(,(car it) .
,(--map `(,(max 1 (- (car it) delta)) . ,(+ (cdr it) delta)) (cdr it)))
roi))
(defun lean-server-roi-ok (old-roi new-roi)
(and (lean-server-roi-subset-p new-roi old-roi)
(lean-server-roi-subset-p old-roi (lean-server-roi-extend new-roi 10))))
(defun lean-server-sync-roi (&optional force)
(when lean-server-session
(let ((old-roi (lean-server-session-current-roi lean-server-session))
(new-roi (lean-server-compute-roi lean-server-session)))
(when (or force (eq old-roi 'not-yet-sent) (not (lean-server-roi-ok old-roi new-roi)))
(lean-server-session-send-roi lean-server-session
(lean-server-roi-extend new-roi 5))))))
(defun lean-server-window-scroll-function-hook (wnd new-start-pos)
(let ((buf (window-buffer wnd)))
(with-demoted-errors "lean scroll hook: %s"
(with-current-buffer buf
(lean-server-ensure-alive)
(lean-server-sync-roi)))))
(defun lean-set-check-mode (mode)
(setq lean-server-check-mode mode)
(lean-server-sync-roi t))
(defun lean-check-nothing ()
"Check nothing"
(interactive)
(lean-set-check-mode 'nothing))
(defun lean-check-visible-lines ()
"Check visible lines"
(interactive)
(lean-set-check-mode 'visible-lines))
(defun lean-check-visible-lines-and-above ()
"Check visible lines and above"
(interactive)
(lean-set-check-mode 'visible-lines-and-above))
(defun lean-check-visible-files ()
"Check visible files"
(interactive)
(lean-set-check-mode 'visible-files))
(defun lean-check-open-files ()
"Check visible files"
(interactive)
(lean-set-check-mode 'open-files))
(provide 'lean-server)

View file

@ -1,147 +0,0 @@
;; Copyright (c) 2014 Microsoft Corporation. All rights reserved.
;; Released under Apache 2.0 license as described in the file LICENSE.
;;
;; Author: Soonho Kong
;;
(require 'cl-lib)
(defgroup lean nil
"Lean Theorem Prover"
:prefix "lean-"
:group 'languages
:link '(url-link :tag "Website" "http://leanprover.github.io")
:link '(url-link :tag "Github" "https://github.com/leanprover/lean"))
(defgroup lean-keybinding nil
"Keybindings for lean-mode."
:prefix "lean-"
:group 'lean)
(defvar-local lean-default-executable-name
(cl-case system-type
('gnu "lean")
('gnu/linux "lean")
('gnu/kfreebsd "lean")
('darwin "lean")
('ms-dos "lean")
('windows-nt "lean.exe")
('cygwin "lean.exe"))
"Default executable name of Lean")
(defcustom lean-rootdir nil
"Full pathname of lean root directory. It should be defined by user."
:group 'lean
:type 'string)
(defcustom lean-executable-name lean-default-executable-name
"Name of lean executable"
:group 'lean
:type 'string)
(defcustom lean-memory-limit 1024
"Memory limit for lean process in megabytes"
:group 'lean
:type 'number)
(defcustom lean-timeout-limit 100000
"Deterministic timeout limit (it is approximately the maximum number of memory allocations in thousands)"
:group 'lean
:type 'number)
(defcustom lean-extra-arguments nil
"Extra command-line arguments to the lean process"
:group 'lean
:type '(list string))
(defcustom lean-company-use t
"Use company mode for lean."
:group 'lean
:type 'boolean)
(defcustom lean-company-type-foreground (face-foreground 'font-lock-keyword-face)
"Color of type parameter in auto-complete candidates"
:group 'lean
:type 'color)
(defcustom lean-eldoc-use t
"Use eldoc mode for lean."
:group 'lean
:type 'boolean)
(defcustom lean-eldoc-nay-retry-time 0.3
"When eldoc-function had nay, try again after this amount of time."
:group 'lean
:type 'number)
(defcustom lean-delete-trailing-whitespace nil
"Set this variable to true to automatically delete trailing
whitespace when a buffer is loaded from a file or when it is
written."
:group 'lean
:type 'boolean)
(defcustom lean-show-type-add-to-kill-ring nil
"If it is non-nil, add the type information to the kill-ring so
that user can yank(paste) it later. By default, it's
false (nil)."
:group 'lean
:type 'boolean)
(defcustom lean-server-show-pending-tasks t
"Highlights pending tasks in the current buffer."
:group 'lean
:type 'boolean)
(defcustom lean-server-check-mode 'visible-lines-and-above
"What parts of the open files the Lean server should check"
:group 'lean
:type 'symbol
:options '(nothing visible-lines visible-lines-and-above visible-files open-files))
(defcustom lean-keybinding-std-exe1 (kbd "C-c C-x")
"Lean Keybinding for std-exe #1"
:group 'lean-keybinding :type 'key-sequence)
(defcustom lean-keybinding-std-exe2 (kbd "C-c C-l")
"Lean Keybinding for std-exe #2"
:group 'lean-keybinding :type 'key-sequence)
(defcustom lean-keybinding-show-key (kbd "C-c C-k")
"Lean Keybinding for show-key"
:group 'lean-keybinding :type 'key-sequence)
(defcustom lean-keybinding-server-restart (kbd "C-c C-r")
"Lean Keybinding for server-restart"
:group 'lean-keybinding :type 'key-sequence)
(defcustom lean-keybinding-find-definition (kbd "M-.")
"Lean Keybinding for find-definition"
:group 'lean-keybinding :type 'key-sequence)
(defcustom lean-keybinding-tab-indent (kbd "TAB")
"Lean Keybinding for tab-indent"
:group 'lean-keybinding :type 'key-sequence)
(defcustom lean-keybinding-auto-complete (kbd "S-SPC")
"Lean Keybinding for auto completion"
:group 'lean-keybinding :type 'key-sequence)
(defcustom lean-keybinding-hole (kbd "C-c SPC")
"Lean Keybinding for hole manipulation"
:group 'lean-keybinding :type 'key-sequence)
(defcustom lean-keybinding-lean-toggle-show-goal (kbd "C-c C-g")
"Lean Keybinding for show-goal-at-pos"
:group 'lean-keybinding :type 'key-sequence)
(defcustom lean-keybinding-lean-toggle-next-error (kbd "C-c C-n")
"Lean Keybinding for lean-toggle-next-error"
:group 'lean-keybinding :type 'key-sequence)
(defcustom lean-keybinding-lean-message-boxes-toggle (kbd "C-c C-b")
"Lean Keybinding for lean-message-boxes-toggle"
:group 'lean-keybinding :type 'key-sequence)
(defcustom lean-keybinding-leanpkg-configure (kbd "C-c C-p C-c")
"Lean Keybinding for lean-pkg-configure"
:group 'lean-keybinding :type 'key-sequence)
(defcustom lean-keybinding-leanpkg-build (kbd "C-c C-p C-b")
"Lean Keybinding for lean-pkg-build"
:group 'lean-keybinding :type 'key-sequence)
(defcustom lean-keybinding-leanpkg-test (kbd "C-c C-p C-t")
"Lean Keybinding for lean-pkg-test"
:group 'lean-keybinding :type 'key-sequence)
(defcustom lean-keybinding-lean-helm-definitions (kbd "C-c C-d")
"Lean Keybinding for lean-helm-definitions"
:group 'lean-keybinding :type 'key-sequence)
(provide 'lean-settings)

View file

@ -1,194 +0,0 @@
;; Copyright (c) 2013, 2014 Microsoft Corporation. All rights reserved.
;; Released under Apache 2.0 license as described in the file LICENSE.
;;
;; Author: Leonardo de Moura
;; Soonho Kong
;;
(require 'rx)
(defconst lean-keywords1
'("import" "prelude" "protected" "private" "noncomputable" "definition" "meta" "renaming"
"hiding" "exposing" "parameter" "parameters" "begin" "constant" "constants"
"lemma" "variable" "variables" "theorem" "example"
"open" "export" "axiom" "axioms" "inductive" "coinductive" "with" "without" "inout"
"structure" "universe" "universes"
"precedence" "reserve" "declare_trace" "add_key_equivalence"
"match" "infix" "infixl" "infixr" "notation" "postfix" "prefix" "instance"
"end" "this" "using" "using_well_founded" "namespace" "section"
"attribute" "local" "set_option" "extends" "include" "omit" "classes" "class"
"attributes" "raw" "replacing"
"calc" "have" "show" "suffices" "by" "in" "at" "do" "let" "forall" "Pi" "fun"
"exists" "if" "then" "else" "assume" "from"
"mutual" "def" "run_cmd")
"lean keywords ending with 'word' (not symbol)")
(defconst lean-keywords1-regexp
(eval `(rx word-start (or ,@lean-keywords1) word-end)))
(defconst lean-constants
'("#" "@" "!" "->" "" "" "/" "==" "=" ":=" "<->" "/\\" "\\/" "" ""
"" "<" ">" "" "" "¬" "<=" ">=" "⁻¹" "" "" "+" "*" "-" "/" "λ"
"" "" "" "" "×" "Σ" "Π" "~" "||" "&&" "" "" ""
"" "" "" "" "" "𝔸"
"⬝e" "⬝i" "⬝o" "⬝op" "⬝po" "⬝h" "⬝v" "⬝hp" "⬝vp" "⬝ph" "⬝pv" "⬝r" "" "◾o"
"∘n" "∘f" "∘fi" "∘nf" "∘fn" "∘n1f" "∘1nf" "∘f1n" "∘fn1"
"^c" "≃c" "≅c" "×c" "×f" "×n" "+c" "+f" "+n" "ℕ₋₂")
"lean constants")
(defconst lean-constants-regexp (regexp-opt lean-constants))
(defconst lean-numerals-regexp
(eval `(rx word-start
(one-or-more digit) (optional (and "." (zero-or-more digit)))
word-end)))
(defconst lean-warnings '("sorry" "exit") "lean warnings")
(defconst lean-warnings-regexp
(eval `(rx word-start (or ,@lean-warnings) word-end)))
(defconst lean-syntax-table
(let ((st (make-syntax-table)))
;; Matching parens
(modify-syntax-entry ?\[ "(]" st)
(modify-syntax-entry ?\] ")[" st)
(modify-syntax-entry ?\{ "(}" st)
(modify-syntax-entry ?\} "){" st)
;; comment
(modify-syntax-entry ?/ ". 14nb" st)
(modify-syntax-entry ?- ". 123" st)
(modify-syntax-entry ?\n ">" st)
(modify-syntax-entry "<" st)
(modify-syntax-entry ">" st)
;; Word constituent
(--map (modify-syntax-entry it "w" st)
(list ?a ?b ?c ?d ?e ?f ?g ?h ?i ?j ?k ?l ?m
?n ?o ?p ?q ?r ?s ?t ?u ?v ?w ?x ?y ?z
?A ?B ?C ?D ?E ?F ?G ?H ?I ?J ?K ?L ?M
?N ?O ?P ?Q ?R ?S ?T ?U ?V ?W ?X ?Y ?Z))
(--map (modify-syntax-entry it "w" st)
(list ?0 ?1 ?2 ?3 ?4 ?5 ?6 ?7 ?8 ?9))
(--map (modify-syntax-entry it "w" st)
(list ?α ?γ ?ι ;;?λ
?ν ?ο ?ρ ?σ ?υ
))
(--map (modify-syntax-entry it "w" st)
(list ?ϒ
?Ϝ
?Ϩ
?ϱ ?ϲ ?ϳ ?Ϲ ?Ϻ ))
(--map (modify-syntax-entry it "w" st)
(list ?ἀ ?ἁ ?ἂ ?ἃ ?ἄ ?ἅ ?ἆ ?ἇ ?Ἀ ?Ἁ ?Ἂ ?Ἃ ?Ἄ
?Ἅ ?Ἆ ?Ἇ ?ἐ ?ἑ ?ἒ ?ἓ ?ἔ ?ἕ ?἖ ?἗ ?Ἐ ?Ἑ
?Ἒ ?Ἓ ?Ἔ ?Ἕ ?἞ ?἟ ?ἠ ?ἡ ?ἢ ?ἣ ?ἤ ?ἥ
?ἦ ?ἧ ?Ἠ ?Ἡ ?Ἢ ?Ἣ ?Ἤ ?Ἥ ?Ἦ ?Ἧ ?ἰ ?ἱ
?ἲ ?ἳ ?ἴ ?ἵ ?ἶ ?ἷ ?Ἰ ?Ἱ ?Ἲ ?Ἳ ?Ἴ ?Ἵ ?Ἶ ?Ἷ
?ὀ ?ὁ ?ὂ ?ὃ ?ὄ ?ὅ ?὆ ?὇ ?Ὀ ?Ὁ ?Ὂ ?Ὃ
?Ὄ ?Ὅ ?὎ ?὏ ?ὐ ?ὑ ?ὒ ?ὓ ?ὔ ?ὕ ?ὖ ?ὗ
?὘ ?Ὑ ?὚ ?Ὓ ?὜ ?Ὕ ?὞ ?Ὗ ?ὠ ?ὡ ?ὢ
?ὣ ?ὤ ?ὥ ?ὦ ?ὧ ?Ὠ ?Ὡ ?Ὢ ?Ὣ ?Ὤ ?Ὥ ?Ὦ
?Ὧ ?ὰ ?ά ?ὲ ?έ ?ὴ ?ή ?ὶ ?ί ?ὸ ?ό ?ὺ ?ύ ?ὼ
?ώ ?὾ ?὿ ?ᾀ ?ᾁ ?ᾂ ?ᾃ ?ᾄ ?ᾅ ?ᾆ ?ᾇ ?ᾈ
?ᾉ ?ᾊ ?ᾋ ?ᾌ ?ᾍ ?ᾎ ?ᾏ ?ᾐ ?ᾑ ?ᾒ ?ᾓ ?ᾔ
?ᾕ ?ᾖ ?ᾗ ?ᾘ ?ᾙ ?ᾚ ?ᾛ ?ᾜ ?ᾝ ?ᾞ ?ᾟ ?ᾠ ?ᾡ ?ᾢ
?ᾣ ?ᾤ ?ᾥ ?ᾦ ?ᾧ ?ᾨ ?ᾩ ?ᾪ ?ᾫ ?ᾬ ?ᾭ ?ᾮ ?ᾯ ?ᾰ
?ᾱ ?ᾲ ?ᾳ ?ᾴ ?᾵ ?ᾶ ?ᾷ ?Ᾰ ?Ᾱ ?Ὰ ?Ά ?ᾼ ?
? ?᾿ ? ?῁ ?ῂ ?ῃ ?ῄ ?῅ ?ῆ ?ῇ ?Ὲ ?Έ ?Ὴ
?Ή ?ῌ ?῍ ?῎ ?῏ ?ῐ ?ῑ ?ῒ ?ΐ ?῔ ?῕ ?ῖ ?ῗ
?Ῐ ?Ῑ ?Ὶ ?Ί ?῜ ?῝ ?῞ ?῟ ?ῠ ?ῡ ?ῢ ?ΰ ?ῤ ?ῥ
?ῦ ?ῧ ?Ῠ ?Ῡ ?Ὺ ?Ύ ?Ῥ ?῭ ?΅ ? ?῰ ?῱ ?ῲ ?ῳ
?ῴ ?῵ ?ῶ ?ῷ ?Ὸ ?Ό ?Ὼ ?Ώ ?ῼ ? ?))
(--map (modify-syntax-entry it "w" st)
(list ?℀ ?℁ ? ?℃ ?℄ ?℅ ?℆ ?ℇ ?℈ ?℉ ? ? ? ? ?
?ℏ ? ? ? ? ?℔ ? ?№ ?℗ ?℘ ? ? ? ? ?
?℞ ?℟ ?℠ ?℡ ?™ ?℣ ? ?℥ ?Ω ?℧ ? ?℩ ? ?Å ?
? ? ? ? ? ?Ⅎ ? ? ?ℵ ?ℶ ?ℷ ?ℸ ? ?℺ ?℻
?ℼ ? ?ℾ ?ℿ ?⅀ ?⅁ ?⅂ ?⅃ ?⅄ ? ? ? ? ? ?⅊
?⅋ ?⅌ ?⅍ ?ⅎ ?⅏))
(modify-syntax-entry ?' "w" st)
(modify-syntax-entry ?_ "w" st)
(modify-syntax-entry ?\. "w" st)
;; Lean operator chars
(mapc #'(lambda (ch) (modify-syntax-entry ch "_" st))
"!#$%&*+<=>@^|~:")
;; Whitespace is whitespace
(modify-syntax-entry ?\ " " st)
(modify-syntax-entry ?\t " " st)
;; Strings
(modify-syntax-entry ?\" "\"" st)
(modify-syntax-entry ?\\ "/" st)
st))
(defconst lean-font-lock-defaults
`((;; attributes
(,(rx word-start "attribute" word-end (zero-or-more whitespace) (group (one-or-more "[" (zero-or-more (not (any "]"))) "]" (zero-or-more whitespace))))
(1 'font-lock-doc-face))
(,(rx (group "@[" (zero-or-more (not (any "]"))) "]"))
(1 'font-lock-doc-face))
(,(rx (group "#" (or "eval" "print" "reduce" "help" "check")))
(1 'font-lock-keyword-face))
;; mutual definitions "names"
(,(rx word-start
"mutual"
word-end
(zero-or-more whitespace)
word-start
(or "inductive" "definition" "def")
word-end
(group (zero-or-more (not (any " \t\n\r{([,"))) (zero-or-more (zero-or-more whitespace) "," (zero-or-more whitespace) (not (any " \t\n\r{([,")))))
(1 'font-lock-function-name-face))
;; declarations
(,(rx word-start
(group (or "inductive" (group "class" (zero-or-more whitespace) "inductive") "instance" "structure" "class" "theorem" "axiom" "axioms" "lemma" "definition" "def" "constant"))
word-end (zero-or-more whitespace)
(group (zero-or-more "{" (zero-or-more (not (any "}"))) "}" (zero-or-more whitespace)))
(zero-or-more whitespace)
(group (zero-or-more (not (any " \t\n\r{([")))))
(4 'font-lock-function-name-face))
;; Constants which have a keyword as subterm
(,(rx (or "∘if")) . 'font-lock-constant-face)
;; Keywords
("\\(set_option\\)[ \t]*\\([^ \t\n]*\\)" (2 'font-lock-constant-face))
(,lean-keywords1-regexp . 'font-lock-keyword-face)
(,(rx word-start (group "example") ".") (1 'font-lock-keyword-face))
(,(rx (or "")) . 'font-lock-keyword-face)
;; Types
(,(rx word-start (or "Prop" "Type" "Type*" "Sort" "Sort*") symbol-end) . 'font-lock-type-face)
(,(rx word-start (group (or "Prop" "Type" "Sort")) ".") (1 'font-lock-type-face))
;; String
("\"[^\"]*\"" . 'font-lock-string-face)
;; ;; Constants
(,lean-constants-regexp . 'font-lock-constant-face)
(,lean-numerals-regexp . 'font-lock-constant-face)
;; place holder
(,(rx symbol-start "_" symbol-end) . 'font-lock-preprocessor-face)
;; warnings
(,lean-warnings-regexp . 'font-lock-warning-face)
;; escaped identifiers
(,(rx (and (group "«") (group (one-or-more (not (any "»")))) (group "»")))
(1 font-lock-comment-face t)
(2 nil t)
(3 font-lock-comment-face t))
)))
;; Syntax Highlighting for Lean Info Mode
(defconst lean-info-font-lock-defaults
(let ((new-entries
`(;; Please add more after this:
(,(rx (group (+ symbol-start (+ (or word (char ?₁ ?₂ ?₃ ?₄ ?₅ ?₆ ?₇ ?₈ ?₉ ?₀))) symbol-end (* white))) ":")
(1 'font-lock-variable-name-face))
(,(rx white ":" white)
. 'font-lock-keyword-face)
(,(rx "" white)
. 'font-lock-keyword-face)
(,(rx "[" (group "stale") "]")
(1 'font-lock-warning-face))
(,(rx line-start "No Goal" line-end)
. 'font-lock-constant-face)))
(inherited-entries (car lean-font-lock-defaults)))
`(,(-concat new-entries inherited-entries))))
(provide 'lean-syntax)

View file

@ -1,96 +0,0 @@
;; Copyright (c) 2014 Microsoft Corporation. All rights reserved.
;; Released under Apache 2.0 license as described in the file LICENSE.
;;
;; Author: Soonho Kong
;;
(require 'cl-lib)
(require 'f)
(require 's)
(require 'dash)
(require 'dash-functional)
(defun lean-get-rootdir ()
(or
lean-rootdir
(error
(concat "'lean-rootdir' is not defined."
"Please have (customize-set-variable 'lean-rootdir \"~/work/lean\") "
"in your emacs configuration. "
"Also make sure that your (custom-set-variable ...) "
" comes before (require 'lean-mode)"))))
(defun lean-get-executable (exe-name)
"Return fullpath of lean executable"
(let ((lean-bin-dir-name "bin"))
(f-full (f-join (lean-get-rootdir) lean-bin-dir-name exe-name))))
(defun lean-line-offset (&optional pos)
"Return the byte-offset of `pos` or current position, counting from the
beginning of the line"
(interactive)
(let* ((pos (or pos (point)))
(bol-pos
(save-excursion
(goto-char pos)
(beginning-of-line)
(point))))
(- pos bol-pos)))
(defun lean-pos-at-line-col (l c)
"Return the point of the given line and column."
;; http://emacs.stackexchange.com/a/8083
(save-excursion
(goto-char (point-min))
(forward-line (- l 1))
(move-to-column c)
(point)))
(defun lean-whitespace-cleanup ()
(when lean-delete-trailing-whitespace
(delete-trailing-whitespace)))
(defun lean-in-comment-p ()
"t if a current point is inside of comment block
nil otherwise"
(nth 4 (syntax-ppss)))
;; The following function is a slightly modified version of
;; f--collect-entries written by Johan Andersson
;; The URL is at https://github.com/rejeep/f.el/blob/master/f.el#L416-L435
(defun lean--collect-entries (path recursive)
(let (result
(entries
(-reject
(lambda (file)
(or
(equal (f-filename file) ".")
(equal (f-filename file) "..")))
(directory-files path t))))
;; The following line is the only modification that I made
;; It waits 0.0001 second for an event. This wait allows
;; wait-timeout function to check the timer and kill the execution
;; of this function.
(sit-for 0.0001)
(cond (recursive
(-map
(lambda (entry)
(if (f-file? entry)
(setq result (cons entry result))
(when (f-directory? entry)
(setq result (cons entry result))
(setq result (append result (lean--collect-entries entry recursive))))))
entries))
(t (setq result entries)))
result))
;; The following function is a slightly modified version of
;; f-files function written by Johan Andersson The URL is at
;; https://github.com/rejeep/f.el/blob/master/f.el#L478-L481
(defun lean-find-files (path &optional fn recursive)
"Find all files in PATH."
;; It calls lean--collect-entries instead of f--collect-entries
(let ((files (-select 'f-file? (lean--collect-entries path recursive))))
(if fn (-select fn files) files)))
(provide 'lean-util)

Binary file not shown.

View file

@ -1,64 +0,0 @@
(setq inhibit-startup-screen t)
(if (getenv "LEAN_ROOTDIR")
(setq lean-rootdir (getenv "LEAN_ROOTDIR"))
(error "LEAN_ROOTDIR environment variable must be set"))
(if (getenv "LEAN_EMACS_PATH")
(setq-local lean-emacs-path (getenv "LEAN_EMACS_PATH"))
(error "LEAN_EMACS_PATH environment variable must be set"))
(setq lean-logo
(condition-case nil
(create-image (format "%s/lean.pgm" lean-emacs-path))
(error nil)))
(setq lean-required-packages '(company dash dash-functional f
flycheck let-alist s seq unicode-fonts))
(require 'package)
(add-to-list 'package-archives '("melpa" . "http://melpa.org/packages/"))
(package-initialize)
(let ((need-to-refresh t))
(dolist (p lean-required-packages)
(when (not (package-installed-p p))
(when need-to-refresh
(package-refresh-contents)
(setq need-to-refresh nil))
(package-install p))))
; This enables out-of-the-box support for characters such as at least on Windows.
(require 'unicode-fonts)
(unicode-fonts-setup)
(setq load-path (cons lean-emacs-path load-path))
(require 'lean-mode)
(defun lean-welcome ()
(let ((cbuf (current-buffer))
(buf (get-buffer-create "Lean Welcome"))
(cpoint (point-min)))
(set-buffer buf)
(setq fill-column (window-width))
(if buffer-read-only (toggle-read-only))
(erase-buffer)
(insert "\n\n")
(insert " ")
(when lean-logo (insert-image lean-logo))
(setq cpoint (1+ (point)))
(insert "\n")
(insert "\n\nPlease check our website periodically for news of later versions")
(insert "\nat http://leanprover.github.io")
(insert "\n\nBug reports and suggestions for improvement should be posted at")
(insert "\nhttps://github.com/leanprover/lean/issues")
(insert "\n\nTo start using Lean, open a .lean file")
(set-buffer-modified-p nil)
(text-mode)
(toggle-read-only)
(goto-char (point-min))
(switch-to-buffer buf)
(set-buffer cbuf)
buf))
(lean-welcome)

View file

@ -1,18 +0,0 @@
;; Copyright (c) 2014 Microsoft Corporation. All rights reserved.
;; Released under Apache 2.0 license as described in the file LICENSE.
;;
;; Author: Soonho Kong
;;
(defconst lean-test/test-path
(f-parent (f-this-file)))
(defconst lean-test/root-path
(f-parent lean-test/test-path))
(add-to-list 'load-path lean-test/root-path)
;; Avoid Emacs 23 interupting the tests with:
;; File bar-autoloads.el changed on disk. Reread from disk? (yes or no)
(fset 'y-or-n-p (lambda (_) t))
(fset 'yes-or-no-p (lambda (_) t))