diff options
author | John Mercouris <john@mercouris.email> | 2017-11-17 15:35:00 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2017-11-17 15:35:00 +0100 |
commit | c5f8cc3175922a473ff4089677c7a0e8df1d6728 (patch) | |
tree | f9631af2ddd854d18239860f5ef21ac95c8c2af7 | |
parent | 0f583e8a9d5ca73cd00946bf20588687d928533f (diff) | |
parent | 6c69ce47f6ea9f9f3b2a9ff9d7c323db68a34ec7 (diff) |
Merge pull request #11 from nEXT-Browser/cocoa-backend0.04
Cocoa backend
-rw-r--r-- | .gitignore | 13 | ||||
-rw-r--r-- | assets/Info.plist | 26 | ||||
-rw-r--r-- | assets/logo.xcf | bin | 27117 -> 0 bytes | |||
-rw-r--r-- | documents/MANUAL.org | 18 | ||||
-rw-r--r-- | next/README.org | 190 | ||||
-rw-r--r-- | next/lisp/base.lisp | 33 | ||||
-rw-r--r-- | next/lisp/minibuffer.lisp | 46 | ||||
-rw-r--r-- | next/lisp/qt.lisp | 537 | ||||
-rw-r--r-- | next/main.cpp | 32 | ||||
-rw-r--r-- | next/make.lisp | 117 | ||||
-rw-r--r-- | next/next.asd | 10 | ||||
-rw-r--r-- | next/next.pro | 13 | ||||
-rw-r--r-- | next/run.lisp | 10 | ||||
-rw-r--r-- | next/source/base.lisp | 52 | ||||
-rw-r--r-- | next/source/bookmark.lisp (renamed from next/lisp/bookmark.lisp) | 0 | ||||
-rw-r--r-- | next/source/buffer.lisp (renamed from next/lisp/buffer.lisp) | 9 | ||||
-rw-r--r-- | next/source/cocoa/application.lisp | 89 | ||||
-rw-r--r-- | next/source/cocoa/cocoa.lisp | 224 | ||||
-rw-r--r-- | next/source/cocoa/utilities.lisp | 187 | ||||
-rw-r--r-- | next/source/completion.lisp (renamed from next/lisp/completion.lisp) | 0 | ||||
-rw-r--r-- | next/source/document-mode.lisp (renamed from next/lisp/document-mode.lisp) | 21 | ||||
-rw-r--r-- | next/source/global.lisp | 14 | ||||
-rw-r--r-- | next/source/keymap.lisp (renamed from next/lisp/keymap.lisp) | 3 | ||||
-rw-r--r-- | next/source/macro.lisp (renamed from next/lisp/macro.lisp) | 8 | ||||
-rw-r--r-- | next/source/minibuffer.lisp | 41 | ||||
-rw-r--r-- | next/source/mode.lisp (renamed from next/lisp/mode.lisp) | 0 | ||||
-rw-r--r-- | next/source/package.lisp (renamed from next/lisp/package.lisp) | 6 | ||||
-rw-r--r-- | next/source/tree-history.lisp (renamed from next/lisp/tree-history.lisp) | 0 |
28 files changed, 731 insertions, 968 deletions
diff --git a/.gitignore b/.gitignore index 1dab948c1..4c72fb2eb 100644 --- a/.gitignore +++ b/.gitignore @@ -1,23 +1,12 @@ -# C extensions -*.so - # Ignore folders archive/ offline/ -environment/ +online/ # Ignore info org files info.org info.org_archive -# Qmake Stash -*.qmake.stash - -# Ignore intermediary -*.a -*.o -Makefile - # Ignore App *.app diff --git a/assets/Info.plist b/assets/Info.plist new file mode 100644 index 000000000..7aa39c6a3 --- /dev/null +++ b/assets/Info.plist @@ -0,0 +1,26 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> +<plist version="1.0"> + <dict> + <key>NSPrincipalClass</key> + <string>next-application</string> + <key>CFBundleIconFile</key> + <string>next.icns</string> + <key>CFBundlePackageType</key> + <string>APPL</string> + <key>CFBundleGetInfoString</key> + <string>nEXT Browser</string> + <key>CFBundleSignature</key> + <string>????</string> + <key>CFBundleExecutable</key> + <string>next</string> + <key>CFBundleIdentifier</key> + <string>next.browser</string> + <key>NSAppTransportSecurity</key> + <dict> + <!--Include to allow all connections--> + <key>NSAllowsArbitraryLoads</key> + <true/> + </dict> + </dict> +</plist> diff --git a/assets/logo.xcf b/assets/logo.xcf Binary files differdeleted file mode 100644 index f3c9f5511..000000000 --- a/assets/logo.xcf +++ /dev/null diff --git a/documents/MANUAL.org b/documents/MANUAL.org index 3ac93d40a..950712745 100644 --- a/documents/MANUAL.org +++ b/documents/MANUAL.org @@ -106,21 +106,3 @@ The following keys exist as special keys: 1. ~C~: Control 2. ~S~: Super (Windows key, Command Key) 3. ~M~: Meta (Alt key, Option Key) - -*** Swapping the Modifier Keys -nEXT is built with QT, and on Mac OS, QT will automatically modify -what control, meta and caps lock as keycodes sent to the key-capturing -system. In order to maintain consistency with other programs that you -are familiar with, you may want to switch to the default emacs style -keybindings; to do so; simply copy the snippet below into your -init.lisp file. - -#+NAME: Emacs Style Modifier Keys -#+BEGIN_SRC lisp -(let ((original_control *control-key*) - (original_meta *meta-key*) - (original_alt *alt-key*)) - (setf *control-key* original_meta) - (setf *meta-key* original_alt) - (setf *super-key* original_control)) -#+END_SRC diff --git a/next/README.org b/next/README.org index 5b4d587e2..985d8829e 100644 --- a/next/README.org +++ b/next/README.org @@ -1,9 +1,9 @@ * Contents :TOC: - [[#developer-installation][Developer Installation]] - - [[#osx-instructions][OSX Instructions]] + - [[#macos-instructions][macOS Instructions]] - [[#linux-instructions][Linux Instructions]] - - [[#running-next][Running nEXT]] - - [[#compiling-next-under-active-development][Compiling nEXT (under active development)]] + - [[#running-next-from-source][Running nEXT from Source]] + - [[#compiling-next][Compiling nEXT]] - [[#release-timeline][Release Timeline]] - [[#005][0.05]] - [[#004][0.04]] @@ -13,51 +13,22 @@ - [[#contributing][Contributing]] * Developer Installation -nEXT browser is built with ECL and EQL, and is designed to be cross -platform compatible. To download a prebuilt-binary, please see the +nEXT browser is built with CCL, and is designed to be cross platform +compatible. Support for graphics is provided via Cocoa for macOS and +GTK for Linux. To download a prebuilt-binary, please see the "Releases" section of this repository. -** OSX Instructions -*** Installing Xcode Command Line Tools -Before installing anything, install the Xcode Comand line tools. To -install the Xcode Command Line tools on OSX execute the following in a -terminal: - -~xcode-select --install~ - -To verify that the command tools were successfully installed type: - -~xcode-select -p~ - -the output of this command should be the path at which the command -line tools are installed. - -*** Installing QT5 (Cross Platform GUI Toolkit) -QT5 is available from a number of sources, the easiest is to install -it via a package manager such as Macports or Brew. However you -install, ensure that you install it with webkit support. - -You can install QT5 via Macports with the following command: - -~port install qt5~ - -You can also install QT5 via the official qt installer: - -https://www.qt.io/download/ - -To test your installation/version of QT, execute ~qmake --version~. - -*** Installing ECL (Embeddable Common Lisp) -Compilable tarballs can be found on the ECL website: - -https://common-lisp.net/project/ecl/static/files/release/ - -To verify your installation of ECL: - -- Execute ~/usr/local/bin/ecl~, it should show an ECL Prompt -- Verify the contents of ~/usr/local/lib~ contain the ecl libraries. -- Verify the contents of ~/usr/local/include/ecl~ contain the header files - +** macOS Instructions +*** Installing CCL +- Download CCL: [[https://ccl.clozure.com/download.html]], full + installation instructions can be found here: + [[https://ccl.clozure.com/install.html]]. Brief installation + instructions can be found below: + +1. Copy the downloaded CCL directory to ~/usr/local/src/ccl~ +2. Copy the script located at ~ccl/scripts/ccl64~ somewhere into your + executable path +3. Optionally make an alias, or rename ~ccl64~ to ~ccl~ *** Installing Quicklisp The official quicklisp website can provide updated links to downloads, and instructions: @@ -67,127 +38,30 @@ https://www.quicklisp.org To install quicklisp: - Download https://beta.quicklisp.org/quicklisp.lisp -- Execute ~ecl --load quicklisp.lisp~ to load quicklisp +- Execute ~ccl --load quicklisp.lisp~ to load quicklisp - Evaluate in the REPL ~(quicklisp-quickstart:install)~ to install -- Evalute in the REPL ~(ql:add-to-init-file)~ to add quicklisp to your ecl init file +- Evalute in the REPL ~(ql:add-to-init-file)~ to add quicklisp to your ccl init file more detailed instructions and other resources are readily available on the quicklisp website. - -*** Installing EQL5 Library & Executable (Embedded QT Lisp) -The source for EQL5 is available here: - -https://gitlab.com/eql/EQL5 - -To build and install the EQL Library/Executable: - -1. Clone the Repository into a directory where you plan to keep the - installation, this cannot be moved after installation. -2. In ~src/~ exec: ~ecl -shell make.lisp~ This command generates - ~src/libini_eql5.a~. -3. Edit ~src/eql5.pro~ commenting out all QT modules you do not - require. - - - The webkit module is required for nEXT. - -4. In ~src/~ exec: ~qmake eql5.pro~. This command generates - the makefile. -5. In ~src/~ exec: ~make~ -6. In ~src/~ exec: ~sudo make install~ - -To test your installation exec ~eql5 -qgui~, you should presented -with a REPL and a GUI. - -After the installation, the following should be completed: - -- ~/usr/local/bin~ contains an ~eql5~ executable -- ~/usr/local/include~ contains a folder named ~eql5~ -- ~/usr/local/lib~ contains all built QT modules (selected in - ~src/eql5.pro~) and libeql \*.dylib files - ** Linux Instructions -Due to the large variances in Linux distributions: file locations, -package managers, and best practices, this installation guide attempts -to make as few decisions as possible- instead opting to list the -requirements necessary to build nEXT. - -*** Installing a compiler -Install a C/C++ Compiler -*** Installing QT5 -Install QT directly from QT: [[https://www.qt.io/download/][download QT]], or install via -third party package manager sources, apt-get etc. -*** Installing ECL (Embeddable Common Lisp) -Compilable tarballs can be found on the ECL website: [[https://common-lisp.net/project/ecl/static/files/release/][download ECL]] -*** Installing Quicklisp -The official quicklisp website can provide updated links -to downloads, and instructions: - -To install quicklisp: - -- Download https://beta.quicklisp.org/quicklisp.lisp -- Execute ~ecl --load quicklisp.lisp~ to load quicklisp -- Evaluate in the REPL ~(quicklisp-quickstart:install)~ to install -- Evalute in the REPL ~(ql:add-to-init-file)~ to add quicklisp to your ecl init file - -more detailed instructions and other resources are readily available -on the quicklisp website. -*** Installing EQL5 Library & Executable (Embedded QT Lisp) -The source for EQL5 is available here: - -https://gitlab.com/eql/EQL5 - -To build and install the EQL Library/Executable: - -1. Clone the Repository into a directory where you plan to keep the - installation, this cannot be moved after installation. -2. In ~src/~ exec: ~ecl -shell make.lisp~ This command generates - ~src/libini_eql5.a~. -3. Edit ~src/eql5.pro~ commenting out all QT modules you do not - require. - - - The webkit module is required for nEXT. - -4. In ~src/~ exec: ~qmake eql5.pro~. This command generates - the makefile. -5. In ~src/~ exec: ~make~ -6. In ~src/~ exec: ~sudo make install~ - -To test your installation exec ~eql5 -qgui~, you should presented -with a REPL and a GUI. - -After the installation, the following should be completed: - -- ~/usr/local/bin~ contains an ~eql5~ executable -- ~/usr/local/include~ contains a folder named ~eql5~ -- ~/usr/local/lib~ contains all built QT modules (selected in - ~src/eql5.pro~) and libeql \*.dylib files - -** Running nEXT -From the directory ~next/~ execute the following command to run: - -1. ~eql5 run~ - -You should be presented with a QT Window. To test that everything -is working execute the following commands: - -1. ~C-l~ -2. A minibuffer should pop-up in which you can enter text - -From the terminal that you launched nEXT you'll be able to see output -from the program. You can additionally create a REPL during runtime -in the following way: ~eql5 run -qgui~. +Instructions forthcoming pending GTK release. +** Running nEXT from Source +In a new Terminal execute the following: -If an exception or crash occurs, you'll be presented with a REPL that -you can use to debug the program. +1. ~ccl~ to create a new CCL Repl +2. Execute ~(require :asdf)~ if asdf is not already loaded +3. Execute ~(asdf:load-asd "/path/to/next.asd")~, this will load the + nEXT system into your Lisp image +4. Execute ~(next:start)~ to open your first nEXT Window. -** Compiling nEXT (under active development) -*** OSX Instructions -From the directory ~next/~ execute the following commands to compile: +** Compiling nEXT +*** macOS Instructions +From the CCL Source directory, execute -1. ~eql5 make~ +1. ~ccl --no-init --load make.lisp~ +2. The compiled binary will be present in build/nEXT -Now you should have a compiled next.app, simply execute this app to -start nEXT browser. * Release Timeline Major releases are issued by incrementing the first digit. That is, release 1.20, and 2.20 are one major release away from each other. Minor diff --git a/next/lisp/base.lisp b/next/lisp/base.lisp deleted file mode 100644 index b4e0c3308..000000000 --- a/next/lisp/base.lisp +++ /dev/null @@ -1,33 +0,0 @@ -;;;; base.lisp --- main entry point into nEXT - -(in-package :next) - -(defun start () - (ensure-directories-exist (uiop:physicalize-pathname #P"~/.next.d/")) - (interface:initialize) - (initialize-bookmark-db) - ;; define the default keybindings - (define-key global-map (kbd "C-x C-c") #'interface:quit) - (define-key minibuffer-mode-map (kbd "Return") #'return-input) - (define-key minibuffer-mode-map (kbd "C-g") #'cancel-input) - (define-key minibuffer-mode-map (kbd "Escape") #'cancel-input) - (define-key global-map (kbd "C-x b") (:input-complete switch-buffer buffer-complete)) - (define-key global-map (kbd "C-x k") (:input-complete delete-buffer buffer-complete)) - (define-key document-mode-map (kbd "S-f") (:input-complete history-forwards-query history-fowards-query-complete)) - (define-key document-mode-map (kbd "S-b") #'history-backwards) - (define-key document-mode-map (kbd "C-f") #'history-forwards) - (define-key document-mode-map (kbd "C-b") #'history-backwards) - (define-key document-mode-map (kbd "C-p") #'scroll-up) - (define-key document-mode-map (kbd "C-n") #'scroll-down) - (define-key document-mode-map (kbd "C-l") (:input set-url)) - (define-key global-map (kbd "C-o") (:input set-url-new-buffer)) - (define-key global-map (kbd "S-s k") (:input-complete bookmark-delete bookmark-complete)) - (define-key document-mode-map (kbd "S-s o") (:input-complete set-url bookmark-complete)) - (define-key document-mode-map (kbd "S-s s") #'bookmark-current-page) - ;; start the gui - (interface:start) - ;; create the default buffers - (setf *minibuffer* (generate-new-buffer "minibuffer" (minibuffer-mode) nil)) - (setf *active-buffer* (generate-new-buffer "default" (document-mode))) - ;; load the user configuration if it exists - (load "~/.next.d/init.lisp" :if-does-not-exist nil)) diff --git a/next/lisp/minibuffer.lisp b/next/lisp/minibuffer.lisp deleted file mode 100644 index 3c853d2f9..000000000 --- a/next/lisp/minibuffer.lisp +++ /dev/null @@ -1,46 +0,0 @@ -;;;; minibuffer.lisp --- major mode for input - -(in-package :next) - -(defvar minibuffer-mode-map (make-hash-table :test 'equalp)) - -(defclass minibuffer-mode (mode) ()) - -(defvar *minibuffer* nil - "A variable to store the mini-buffer") - -(defparameter *minibuffer-completion-function* nil - "A variable to store the function used to generate completion candidates") -(defparameter *minibuffer-callback* nil - "A variable to store the function upon completion of the minibuffer read") -(defparameter *minibuffer-callback-buffer* nil - "A variable to store the buffer which originally requested the minibuffer read") - -(defun input (callback-function &optional completion-function) - (setf *minibuffer-callback* callback-function) - (setf *minibuffer-completion-function* completion-function) - (interface:minibuffer-set-completion-function completion-function) - (setf *minibuffer-callback-buffer* *active-buffer*) - (set-active-buffer *minibuffer*) - (interface:minibuffer-show)) - -(defun return-input () - (set-active-buffer *minibuffer-callback-buffer*) - (if *minibuffer-completion-function* - (funcall *minibuffer-callback* - (nth 0 (funcall *minibuffer-completion-function* - (interface:minibuffer-get-input)))) - (funcall *minibuffer-callback* - (interface:minibuffer-get-input))) - (interface:minibuffer-hide)) - -(defun cancel-input () - (set-active-buffer *minibuffer-callback-buffer*) - (interface:minibuffer-hide)) - -(defun minibuffer-mode () - "Base mode for input" - (make-instance 'minibuffer-mode - :name "minibuffer" - :keymap minibuffer-mode-map - :view (interface:make-minibuffer))) diff --git a/next/lisp/qt.lisp b/next/lisp/qt.lisp deleted file mode 100644 index f47ec062a..000000000 --- a/next/lisp/qt.lisp +++ /dev/null @@ -1,537 +0,0 @@ -;;;; qt.lisp --- QT helper functions & data - -(in-package :interface) - -(defun initialize () - (eql:qrequire :webkit) - (initialize-keycodes) - (defvar *control-modifier* nil - "A variable to store the status of the control key") - (defvar *meta-modifier* nil - "A variable to store the status of the alt/meta key") - (defvar *super-modifier* nil - "A variable to store the status of the super/cmd key") - (eql:qadd-event-filter nil eql:|QEvent.KeyPress| 'key-press) - (eql:qadd-event-filter nil eql:|QEvent.KeyRelease| 'key-release)) - -(defun start () - (defparameter *window* (eql:qnew "QWidget" "windowTitle" "nEXT")) - (defparameter *root-layout* (eql:qnew "QGridLayout")) - (defparameter *stack-layout* (eql:qnew "QStackedLayout")) - (defparameter *minibuffer* nil "reference for widget containing all minibuffer views") - (defparameter *minibuffer-prompt* (eql:qnew "QLabel" "text" "input:")) - (defparameter *minibuffer-input* (eql:qnew "QLineEdit")) - (defparameter *minibuffer-completion* (eql:qnew "QListView")) - (defparameter *minibuffer-completion-model* (eql:qnew "QStringListModel")) - (defparameter *minibuffer-completion-function* nil) - ;; remove margins around root widgets - (eql:|setSpacing| *root-layout* 0) - (eql:|setContentsMargins| *root-layout* 0 0 0 0) - ;; arguments for grid layout: row, column, rowspan, colspan - (eql:|addLayout| *root-layout* *stack-layout* 0 0 1 1) - (eql:|setLayout| *window* *root-layout*) - (eql:|show| *window*)) - -(defun quit () - (eql:qquit)) - -(defun set-visible-view (view) - (eql:|setCurrentWidget| *stack-layout* view)) - -(defun add-to-stack-layout (view) - (eql:|addWidget| *stack-layout* view)) - -(defun delete-view (view) - (eql:qdelete view)) - -(defun make-web-view () - (eql:qnew "QWebView")) - -(defun web-view-scroll-down (view distance) - (eql:|scroll| (eql:|mainFrame| (eql:|page| view)) - 0 distance)) - -(defun web-view-scroll-up (view distance) - (eql:|scroll| (eql:|mainFrame| (eql:|page| view)) - 0 (- distance))) - -(defun web-view-set-url (view url) - (eql:qlet ((url (eql:qnew "QUrl(QString)" url))) - (eql:|setUrl| view url))) - -(defun web-view-set-url-loaded-callback (view function) - (eql:qconnect (eql:|mainFrame| (eql:|page| view)) "loadFinished(bool)" - function)) - -(defun web-view-get-url (view) - (eql:|toString| (eql:|url| view))) - -(defun make-minibuffer () - (let ((minibuffer (eql:qnew "QWidget")) (layout (eql:qnew "QGridLayout"))) - (eql:|addWidget| layout *minibuffer-prompt* 0 0 1 5) - (eql:|addWidget| layout *minibuffer-input* 0 1 1 15) - (eql:|addWidget| layout *minibuffer-completion* 1 1 1 15) - (eql:|setLayout| minibuffer layout) - (eql:|setModel| *minibuffer-completion* *minibuffer-completion-model*) - (eql:qadd-event-filter *minibuffer-input* eql:|QEvent.KeyRelease| 'update-candidates) - ;; add it to the main grid layout (*root-layout*) - ;; arguments for grid layout: row, column, rowspan, colspan - (eql:|addWidget| *root-layout* minibuffer 1 0 1 1) - (eql:|hide| minibuffer) - (setf *minibuffer* minibuffer) - ;; return the widget - *minibuffer*)) - -(defun update-candidates (obj event) - (declare (ignore obj)) ; supress unused warnings - (declare (ignore event)) ; supress unused warnings - (when *minibuffer-completion-function* - (let ((candidates (funcall *minibuffer-completion-function* (minibuffer-get-input)))) - (eql:|setStringList| *minibuffer-completion-model* candidates))) - nil) - -(defun minibuffer-set-completion-function (function) - (setf *minibuffer-completion-function* function)) - -(defun minibuffer-show () - (eql:|show| *minibuffer*) - (eql:|setFocus| *minibuffer-input*)) - -(defun minibuffer-hide () - (eql:|setText| *minibuffer-input* "") - (eql:|hide| *minibuffer*)) - -(defun minibuffer-get-input () - (eql:|text| *minibuffer-input*)) - -(defun key-press (obj event) - ;; Invoked upon key-press - (declare (ignore obj)) ; supress unused warnings - (let ((key (eql:|key| event))) - (cond - ((equalp key *control-key*) - (setf *control-modifier* t)) - ((equalp key *meta-key*) - (setf *meta-modifier* t)) - ((equalp key *super-key*) - (setf *super-modifier* t)) - (t (next:push-key-chord - *control-modifier* - *meta-modifier* - *super-modifier* - (gethash key *keycode->character*)))))) - -(defun key-release (obj event) - ;; Invoked upon key-release - (declare (ignore obj)) ; supress unused warnings - (let ((key (eql:|key| event))) - (cond - ((equalp key *control-key*) - (setf *control-modifier* nil)) - ((equalp key *meta-key*) - (setf *meta-modifier* nil)) - ((equalp key *super-key*) - (setf *super-modifier* nil)) - (t (return-from key-release))))) - -(defparameter *keycode->character* (make-hash-table :test 'equalp) - "A character -> keycode hashmap for associating the QT keycodes") - -(defun keycode (character keycode) - (setf (gethash character *keycode->character*) keycode)) - -(defun initialize-keycodes () - (defparameter *control-key* 16777249) ; OSX: command - (defparameter *meta-key* 16777250) ; OSX: control - (defparameter *alt-key* 16777251) ; OSX: option - (defparameter *super-key* 16777249) ; OSX: command - (when (equalp (eql:|platformName.QGuiApplication|) "cocoa") - (let ((original_control *control-key*) - (original_meta *meta-key*) - (original_alt *alt-key*)) - (setf *control-key* original_meta) - (setf *meta-key* original_alt) - (setf *super-key* original_control))) - (keycode 48 "0") - (keycode 49 "1") - (keycode 50 "2") - (keycode 51 "3") - (keycode 52 "4") - (keycode 53 "5") - (keycode 54 "6") - (keycode 55 "7") - (keycode 56 "8") - (keycode 57 "9") - (keycode 198 "AE") - (keycode 193 "Aacute") - (keycode 194 "Acircumflex") - (keycode 16777408 "AddFavorite") - (keycode 196 "Adiaeresis") - (keycode 192 "Agrave") - (keycode 16781571 "AltGr") - (keycode 16777251 "Alt") - (keycode 38 "Ampersand") - (keycode 32 "Any") - (keycode 39 "Apostrophe") - (keycode 16777415 "ApplicationLeft") - (keycode 16777416 "ApplicationRight") - (keycode 197 "Aring") - (keycode 94 "AsciiCircum") - (keycode 126 "AsciiTilde") - (keycode 42 "Asterisk") - (keycode 195 "Atilde") - (keycode 64 "At") - (keycode 16777478 "AudioCycleTrack") - (keycode 16777474 "AudioForward") - (keycode 16777476 "AudioRandomPlay") - (keycode 16777475 "AudioRepeat") - (keycode 16777413 "AudioRewind") - (keycode 16777464 "Away") - (keycode 65 "A") - (keycode 16777414 "BackForward") - (keycode 92 "Backslash") - (keycode 16777219 "Backspace") - (keycode 16777218 "Backtab") - (keycode 16777313 "Back") - (keycode 124 "Bar") - (keycode 16777331 "BassBoost") - (keycode 16777333 "BassDown") - (keycode 16777332 "BassUp") - (keycode 16777470 "Battery") - (keycode 16777471 "Bluetooth") - (keycode 16777495 "Blue") - (keycode 16777417 "Book") - (keycode 123 "BraceLeft") - (keycode 125 "BraceRight") - (keycode 91 "BracketLeft") - (keycode 93 "BracketRight") - (keycode 16777410 "BrightnessAdjust") - (keycode 66 "B") - (keycode 16777418 "CD") - (keycode 16777419 "Calculator") - (keycode 16777444 "Calendar") - (keycode 17825796 "Call") - (keycode 17825825 "CameraFocus") - (keycode 17825824 "Camera") - (keycode 16908289 "Cancel") - (keycode 16777252 "CapsLock") - (keycode 199 "Ccedilla") - (keycode 16777497 "ChannelDown") - (keycode 16777496 "ChannelUp") - (keycode 16777421 "ClearGrab") - (keycode 16777227 "Clear") - (keycode 16777422 "Close") - (keycode 16781623 "Codeinput") - (keycode 58 "Colon") - (keycode 44 "Comma") - (keycode 16777412 "Community") - (keycode 17825792 "Context1") - (keycode 17825793 "Context2") - (keycode 17825794 "Context3") - (keycode 17825795 "Context4") - (keycode 16777485 "ContrastAdjust") - (keycode 16777249 "Control") - (keycode 16777423 "Copy") - (keycode 16777424 "Cut") - (keycode 67 "C") - (keycode 16777426 "DOS") - (keycode 16777223 "Delete") - (keycode 36 "Dollar") - (keycode 16777237 "Down") - (keycode 68 "D") - (keycode 208 "ETH") - (keycode 201 "Eacute") - (keycode 202 "Ecircumflex") - (keycode 203 "Ediaeresis") - (keycode 200 "Egrave") - (keycode 16777401 "Eject") - (keycode 16777233 "End") - (keycode 16777221 "Enter") - (keycode 61 "Equal") - (keycode 16777216 "Escape") - (keycode 33 "Exclam") - (keycode 16908291 "Execute") - (keycode 16908298 "Exit") - (keycode 16777429 "Explorer") - (keycode 69 "E") - (keycode 16777273 "F10") - (keycode 16777274 "F11") - (keycode 16777275 "F12") - (keycode 16777276 "F13") - (keycode 16777277 "F14") - (keycode 16777278 "F15") - (keycode 16777279 "F16") - (keycode 16777280 "F17") - (keycode 16777281 "F18") - (keycode 16777282 "F19") - (keycode 16777264 "F1") - (keycode 16777283 "F20") - (keycode 16777284 "F21") - (keycode 16777285 "F22") - (keycode 16777286 "F23") - (keycode 16777287 "F24") - (keycode 16777288 "F25") - (keycode 16777289 "F26") - (keycode 16777290 "F27") - (keycode 16777291 "F28") - (keycode 16777292 "F29") - (keycode 16777265 "F2") - (keycode 16777293 "F30") - (keycode 16777294 "F31") - (keycode 16777295 "F32") - (keycode 16777296 "F33") - (keycode 16777297 "F34") - (keycode 16777298 "F35") - (keycode 16777266 "F3") - (keycode 16777267 "F4") - (keycode 16777268 "F5") - (keycode 16777269 "F6") - (keycode 16777270 "F7") - (keycode 16777271 "F8") - (keycode 16777272 "F9") - (keycode 16777361 "Favorites") - (keycode 16777411 "Finance") - (keycode 16777506 "Find") - (keycode 17825798 "Flip") - (keycode 16777314 "Forward") - (keycode 70 "F") - (keycode 16777430 "Game") - (keycode 16777431 "Go") - (keycode 62 "Greater") - (keycode 16777493 "Green") - (keycode 16777498 "Guide") - (keycode 71 "G") - (keycode 16777304 "Help") - (keycode 16781603 "Henkan") - (keycode 16777480 "Hibernate") - (keycode 16777407 "History") - (keycode 16777360 "HomePage") - (keycode 16777232 "Home") - (keycode 16777409 "HotLinks") - (keycode 16777302 "Hyper_L") - (keycode 16777303 "Hyper_R") - (keycode 72 "H") - (keycode 205 "Iacute") - (keycode 206 "Icircumflex") - (keycode 207 "Idiaeresis") - (keycode 204 "Igrave") - (keycode 16777499 "Info") - (keycode 16777222 "Insert") - (keycode 73 "I") - (keycode 74 "J") - (keycode 16777398 "KeyboardBrightnessDown") - (keycode 16777397 "KeyboardBrightnessUp") - (keycode 16777396 "KeyboardLightOnOff") - (keycode 75 "K") - (keycode 16777378 "Launch0") - (keycode 16777379 "Launch1") - (keycode 16777380 "Launch2") - (keycode 16777381 "Launch3") - (keycode 16777382 "Launch4") - (keycode 16777383 "Launch5") - (keycode 16777384 "Launch6") - (keycode 16777385 "Launch7") - (keycode 16777386 "Launch8") - (keycode 16777387 "Launch9") - (keycode 16777388 "LaunchA") - (keycode 16777389 "LaunchB") - (keycode 16777390 "LaunchC") - (keycode 16777391 "LaunchD") - (keycode 16777392 "LaunchE") - (keycode 16777393 "LaunchF") - (keycode 16777486 "LaunchG") - (keycode 16777487 "LaunchH") - (keycode 16777376 "LaunchMail") - (keycode 16777377 "LaunchMedia") - (keycode 16777234 "Left") - (keycode 60 "Less") - (keycode 16777405 "LightBulb") - (keycode 16777433 "LogOff") - (keycode 76 "L") - (keycode 16777467 "MailForward") - (keycode 16777434 "Market") - (keycode 16781612 "Massyo") - (keycode 16842751 "MediaLast") - (keycode 16777347 "MediaNext") - (keycode 16777349 "MediaPause") - (keycode 16777344 "MediaPlay") - (keycode 16777346 "MediaPrevious") - (keycode 16777348 "MediaRecord") - (keycode 16777345 "MediaStop") - (keycode 16777350 "MediaTogglePlayPause") - (keycode 16777435 "Meeting") - (keycode 16777404 "Memo") - (keycode 16777436 "MenuKB") - (keycode 16777437 "MenuPB") - (keycode 16777301 "Menu") - (keycode 16777465 "Messenger") - (keycode 16777250 "Meta") - (keycode 16777491 "MicMute") - (keycode 16777502 "MicVolumeDown") - (keycode 16777501 "MicVolumeUp") - (keycode 45 "Minus") - (keycode 77 "M") - (keycode 16777439 "News") - (keycode 16777504 "New") - (keycode 16842754 "No") - (keycode 209 "Ntilde") - (keycode 16777253 "NumLock") - (keycode 35 "NumberSign") - (keycode 78 "N") - (keycode 211 "Oacute") - (keycode 212 "Ocircumflex") - (keycode 214 "Odiaeresis") - (keycode 16777440 "OfficeHome") - (keycode 210 "Ograve") - (keycode 216 "Ooblique") - (keycode 16777364 "OpenUrl") - (keycode 16777505 "Open") - (keycode 16777441 "Option") - (keycode 213 "Otilde") - (keycode 79 "O") - (keycode 16777239 "PageDown") - (keycode 16777238 "PageUp") - (keycode 40 "ParenLeft") - (keycode 41 "ParenRight") - (keycode 16777442 "Paste") - (keycode 16777224 "Pause") - (keycode 37 "Percent") - (keycode 46 "Period") - (keycode 16777443 "Phone") - (keycode 16777468 "Pictures") - (keycode 16908293 "Play") - (keycode 43 "Plus") - (keycode 16777483 "PowerDown") - (keycode 16777399 "PowerOff") - (keycode 16781630 "PreviousCandidate") - (keycode 16908290 "Printer") - (keycode 16777225 "Print") - (keycode 80 "P") - (keycode 63 "Question") - (keycode 34 "QuoteDbl") - (keycode 96 "QuoteLeft") - (keycode 81 "Q") - (keycode 16777508 "Redo") - (keycode 16777492 "Red") - (keycode 16777316 "Refresh") - (keycode 16777446 "Reload") - (keycode 16777445 "Reply") - (keycode 16777220 "Return") - (keycode 16777236 "Right") - (keycode 16781604 "Romaji") - (keycode 16777447 "RotateWindows") - (keycode 16777449 "RotationKB") - (keycode 16777448 "RotationPB") - (keycode 82 "R") - (keycode 16777450 "Save") - (keycode 16777402 "ScreenSaver") - (keycode 16777254 "ScrollLock") - (keycode 16777362 "Search") - (keycode 16842752 "Select") - (keycode 59 "Semicolon") - (keycode 16777451 "Send") - (keycode 16777500 "Settings") - (keycode 16777248 "Shift") - (keycode 16777406 "Shop") - (keycode 16781628 "SingleCandidate") - (keycode 47 "Slash") - (keycode 16908292 "Sleep") - (keycode 32 "Space") - (keycode 16777452 "Spell") - (keycode 16777453 "SplitScreen") - (keycode 16777363 "Standby") - (keycode 16777315 "Stop") - (keycode 16777477 "Subtitle") - (keycode 16777299 "Super_L") - (keycode 16777300 "Super_R") - (keycode 16777454 "Support") - (keycode 16777484 "Suspend") - (keycode 16777226 "SysReq") - (keycode 83 "S") - (keycode 222 "THORN") - (keycode 16777217 "Tab") - (keycode 16777455 "TaskPane") - (keycode 16777456 "Terminal") - (keycode 16777479 "Time") - (keycode 16777420 "ToDoList") - (keycode 17825799 "ToggleCallHangup") - (keycode 16777457 "Tools") - (keycode 16777482 "TopMenu") - (keycode 16777490 "TouchpadOff") - (keycode 16777489 "TouchpadOn") - (keycode 16777488 "TouchpadToggle") - (keycode 16781611 "Touroku") - (keycode 16777458 "Travel") - (keycode 16777335 "TrebleDown") - (keycode 16777334 "TrebleUp") - (keycode 84 "T") - (keycode 16777473 "UWB") - (keycode 218 "Uacute") - (keycode 219 "Ucircumflex") - (keycode 220 "Udiaeresis") - (keycode 217 "Ugrave") - (keycode 95 "Underscore") - (keycode 16777507 "Undo") - (keycode 16777235 "Up") - (keycode 85 "U") - (keycode 16777459 "Video") - (keycode 16777481 "View") - (keycode 17825800 "VoiceDial") - (keycode 16777328 "VolumeDown") - (keycode 16777329 "VolumeMute") - (keycode 16777330 "VolumeUp") - (keycode 86 "V") - (keycode 16777472 "WLAN") - (keycode 16777403 "WWW") - (keycode 16777400 "WakeUp") - (keycode 16777466 "WebCam") - (keycode 16777460 "Word") - (keycode 87 "W") - (keycode 16777461 "Xfer") - (keycode 88 "X") - (keycode 221 "Yacute") - (keycode 16777494 "Yellow") - (keycode 16842753 "Yes") - (keycode 89 "Y") - (keycode 16777462 "ZoomIn") - (keycode 16777463 "ZoomOut") - (keycode 16908294 "Zoom") - (keycode 90 "Z") - (keycode 180 "acute") - (keycode 166 "brokenbar") - (keycode 184 "cedilla") - (keycode 162 "cent") - (keycode 169 "copyright") - (keycode 164 "currency") - (keycode 176 "degree") - (keycode 168 "diaeresis") - (keycode 247 "division") - (keycode 161 "exclamdown") - (keycode 171 "guillemotleft") - (keycode 187 "guillemotright") - (keycode 173 "hyphen") - (keycode 16777432 "iTouch") - (keycode 175 "macron") - (keycode 186 "masculine") - (keycode 215 "multiply") - (keycode 181 "mu") - (keycode 160 "nobreakspace") - (keycode 172 "notsign") - (keycode 189 "onehalf") - (keycode 188 "onequarter") - (keycode 185 "onesuperior") - (keycode 170 "ordfeminine") - (keycode 182 "paragraph") - (keycode 183 "periodcentered") - (keycode 177 "plusminus") - (keycode 191 "questiondown") - (keycode 174 "registered") - (keycode 167 "section") - (keycode 223 "ssharp") - (keycode 163 "sterling") - (keycode 190 "threequarters") - (keycode 179 "threesuperior") - (keycode 178 "twosuperior") - (keycode 33554431 "unknown") - (keycode 255 "ydiaeresis") - (keycode 165 "yen")) diff --git a/next/main.cpp b/next/main.cpp deleted file mode 100644 index 41761e8d9..000000000 --- a/next/main.cpp +++ /dev/null @@ -1,32 +0,0 @@ -#undef SLOT - -#include <ecl/ecl.h> -#include <eql5/eql.h> -#include <QApplication> -#include <QTextCodec> -#include <QSettings> -#include <QTranslator> - -extern "C" void init_lib_NEXT__ALL_SYSTEMS(cl_object); - -int catch_all_qexec() { - int ret = 0; - CL_CATCH_ALL_BEGIN(ecl_process_env()) { - ret = QApplication::exec(); } - CL_CATCH_ALL_END; - return ret; } - -int main(int argc, char** argv) { - - EQL::ini(argv); - - QApplication qapp(argc, argv); - - QTextCodec* utf8 = QTextCodec::codecForName("UTF-8"); - QTextCodec::setCodecForLocale(utf8); - - EQL eql; - - eql.exec(init_lib_NEXT__ALL_SYSTEMS); - - return catch_all_qexec(); } // closing the main/last window will quit the program diff --git a/next/make.lisp b/next/make.lisp index f66f0b58b..31c7b4a5d 100644 --- a/next/make.lisp +++ b/next/make.lisp @@ -1,87 +1,46 @@ ;;;; make.lisp --- create binary files for nEXT - -;;;; Pre-requisties: -;;;; - dylibbundler (available via ports) -;;;; - ecl (available at the official website) -;;;; - eql (available at the official repository) ;;;; ;;;; See Next/next/README.org for more information on installing the ;;;; dependencies necessary to build nEXT from source ;;;; ;;;; Please note that this script must be run from the directory -;;;; Next/next. It may be necessary to modify the paths or commands in -;;;; the "Bundle OSX Dependencies" List. - -#-eql5 -(error "Please use the EQL5 executable (see README)") -(require :cmp) -(push "./" asdf:*central-registry*) -(ql:quickload "next") - -;; build static library -(asdf:make-build "next" - :monolithic t - :type :static-library - :move-here "./") - -;; rename static library -(let ((lib-name #+msvc "next.lib" - #-msvc "libnext.a")) - (when (probe-file lib-name) - (delete-file lib-name)) - (rename-file (x:cc "next--all-systems" - #+msvc ".lib" - #-msvc ".a") - lib-name)) - -;; execute qmake -(ext:run-program "qmake" nil :output t) +;;;; Next/next. -;; execute make -(ext:run-program "make" nil :output t) +(let ((quicklisp-init (merge-pathnames ".quicklisp/setup.lisp" (user-homedir-pathname)))) + (when (probe-file quicklisp-init) + (load quicklisp-init))) +(require :asdf) - -;;;; Cleanup Operations ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;; delete tmp dir to force recompilation -(uiop:delete-directory-tree - (merge-pathnames (make-pathname - :directory '(:relative "tmp")) - (asdf:system-source-directory :next)) - :validate T - :if-does-not-exist :ignore) -;; delete libnext.a -(uiop:delete-file-if-exists - (format nil "~Alibnext.a" (asdf:system-source-directory :next))) -;; delete Makefile -(uiop:delete-file-if-exists - (format nil "~AMakefile" (asdf:system-source-directory :next))) - -;;;; Prompt the User to Bundle Dependencies ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -(format *query-io* "[0] Quit [1] Bundle OSX Dependencies: ") -(force-output *query-io*) -(let ((input (read-line *query-io*))) - (cond ((equalp input "0") ) - ((equalp input "1") - (progn - (ext:run-program - "dylibbundler" - '("-cd" - "-b" - "-x" - "./next.app/Contents/MacOS/next" - "-d" - "./next.app/Contents/libs") :input t :output t) - - (ext:run-program - "macdeployqt" - '("./next.app/" - "-libpath=/usr/local/lib") :output t) - - (ext:run-program - "install_name_tool" - '("-change" - "@libdir@/libecl.16.1.dylib" - "@executable_path/../libs/libecl.16.1.dylib" - "./next.app/Contents/MacOS/next") :output t))))) - -(qquit) +(push "./" asdf:*central-registry*) +(ql:quickload "next" :silent t) + +(defparameter *source-dir* (make-pathname :name nil :type nil + :defaults *load-truename*)) +(defparameter *build-dir* (merge-pathnames "build/" *source-dir*)) + +(defvar *bundle-dir*) +(defvar *contents-dir*) +(defvar *resources-dir*) +(defvar *macos-dir*) + +(defun build-next (&optional (build-dir *build-dir*)) + (let* ((*build-dir* build-dir) + (*bundle-dir* (merge-pathnames "nEXT.app/" *build-dir*)) + (*contents-dir* (merge-pathnames "Contents/" *bundle-dir*)) + (*resources-dir* (merge-pathnames "Resources/" *contents-dir*)) + (*macos-dir* (merge-pathnames "MacOS/" *contents-dir*)) + (*default-pathname-defaults* *source-dir*)) + (ccl::ensure-directories-exist *resources-dir*) + (ccl::ensure-directories-exist (merge-pathnames "ccl/" *resources-dir*)) + (ccl::ensure-directories-exist *macos-dir*) + (ccl::copy-file "../assets/Info.plist" (merge-pathnames "Info.plist" *contents-dir*) + :if-exists :supersede) + (ccl::copy-file "../assets/next.icns" (merge-pathnames "next.icns" *resources-dir*) + :if-exists :supersede) + (ccl::copy-file (ccl::kernel-path) (merge-pathnames "nEXT" *macos-dir*) + :if-exists :supersede + :preserve-attributes t) + (ccl::save-application (merge-pathnames "ccl/nEXT.image" *resources-dir*) + :application-class (find-symbol "COCOA-APPLICATION" "CCL")))) + +(build-next) diff --git a/next/next.asd b/next/next.asd index 2818c171f..30fc6b158 100644 --- a/next/next.asd +++ b/next/next.asd @@ -2,10 +2,14 @@ ;;;; next.asd (defsystem :next :serial t - :depends-on (:cl-strings :cl-string-match :puri :queues.simple-queue :sqlite) - :pathname "lisp/" + :depends-on (:cl-strings :cl-string-match :puri :queues.simple-queue :sqlite + (:require "cocoa") (:require "webkit")) + :pathname "source/" :components ((:file "package") - (:file "qt") + (:file "global") + (:file "cocoa/utilities") + (:file "cocoa/cocoa") + (:file "cocoa/application") (:file "macro") (:file "mode") (:file "keymap") diff --git a/next/next.pro b/next/next.pro deleted file mode 100644 index 7ccf58fed..000000000 --- a/next/next.pro +++ /dev/null @@ -1,13 +0,0 @@ -QT += widgets printsupport uitools -TEMPLATE = app -ICON = ../assets/next.icns -CONFIG += no_keywords release -INCLUDEPATH += /usr/local/include -INCLUDEPATH += /usr/local/include/eql -LIBS += -lecl -L. -lnext -L/usr/local/lib -leql5 -leql5_webkit -TARGET = next -DESTDIR = ./ -OBJECTS_DIR = ./tmp/ -MOC_DIR = ./tmp/ -QMAKE_MACOSX_DEPLOYMENT_TARGET = 10.12 -SOURCES += main.cpp diff --git a/next/run.lisp b/next/run.lisp deleted file mode 100644 index 32ca24d00..000000000 --- a/next/run.lisp +++ /dev/null @@ -1,10 +0,0 @@ -;;; run.lisp --- helper runner program to run from the command line -;;; to launch nEXT simply `eql5 run.lisp` -(push "./" asdf:*central-registry*) -(ql:quickload "next") -(asdf:load-system "next") - -(in-package #:next) - -;; start nEXT -(start) diff --git a/next/source/base.lisp b/next/source/base.lisp new file mode 100644 index 000000000..161efe6e1 --- /dev/null +++ b/next/source/base.lisp @@ -0,0 +1,52 @@ +;;;; base.lisp --- main entry point into nEXT + +(in-package :next) + +(defun start () + (ensure-directories-exist (uiop:physicalize-pathname #P"~/.next.d/")) + (initialize-bookmark-db) + (initialize-default-key-bindings) + (interface:initialize) + (interface:start) + ;; create the default buffers + (setf *minibuffer* + (make-instance 'buffer :name "minibuffer" :mode (minibuffer-mode))) + (set-visible-active-buffer (generate-new-buffer "default" (document-mode))) + ;; load the user configuration if it exists + (load "~/.next.d/init.lisp" :if-does-not-exist nil)) + +(defun initialize-default-key-bindings () + (define-key global-map (kbd "C-x C-c") + #'interface:kill) + (define-key global-map (kbd "C-x b") + (:input-complete *minibuffer* switch-buffer buffer-complete)) + (define-key global-map (kbd "C-x k") + (:input-complete *minibuffer* delete-buffer buffer-complete)) + (define-key global-map (kbd "M-l") + (:input *minibuffer* set-url-new-buffer)) + (define-key global-map (kbd "S-b k") + (:input-complete *minibuffer* bookmark-delete bookmark-complete)) + (define-key minibuffer-mode-map (kbd "
") + #'(lambda () (return-input (buffer-mode *minibuffer*)))) + (define-key minibuffer-mode-map (kbd "C-g") + #'(lambda () (cancel-input (buffer-mode *minibuffer*)))) + (define-key minibuffer-mode-map (kbd "Escape") + #'(lambda () (cancel-input (buffer-mode *minibuffer*)))) + (define-key document-mode-map (kbd "M-f") + (:input-complete *minibuffer* history-forwards-query history-fowards-query-complete)) + (define-key document-mode-map (kbd "M-b") + #'history-backwards) + (define-key document-mode-map (kbd "C-f") + #'history-forwards) + (define-key document-mode-map (kbd "C-b") + #'history-backwards) + (define-key document-mode-map (kbd "C-p") + #'scroll-up) + (define-key document-mode-map (kbd "C-n") + #'scroll-down) + (define-key document-mode-map (kbd "C-l") + (:input *minibuffer* set-url)) + (define-key document-mode-map (kbd "S-b o") + (:input-complete *minibuffer* set-url bookmark-complete)) + (define-key document-mode-map (kbd "S-b s") + #'bookmark-current-page)) diff --git a/next/lisp/bookmark.lisp b/next/source/bookmark.lisp index 7606cfb82..7606cfb82 100644 --- a/next/lisp/bookmark.lisp +++ b/next/source/bookmark.lisp diff --git a/next/lisp/buffer.lisp b/next/source/buffer.lisp index 9ac1683c3..88e9e13cf 100644 --- a/next/lisp/buffer.lisp +++ b/next/source/buffer.lisp @@ -2,25 +2,18 @@ (in-package :next) -(defvar *buffers* () - "A list of all existing buffers") -(defvar *active-buffer* () - "The currently active buffer") - (defclass buffer () ((name :accessor buffer-name :initarg :name) (mode :accessor buffer-mode :initarg :mode) (view :accessor buffer-view :initarg :view))) -(defun generate-new-buffer (name mode &optional (add-to-stack-layout t)) +(defun generate-new-buffer (name mode) (let ((new-buffer (make-instance 'buffer :name name :mode mode :view (mode-view mode)))) (push new-buffer *buffers*) - (when add-to-stack-layout - (interface:add-to-stack-layout (buffer-view new-buffer))) new-buffer)) (defun set-active-buffer (buffer) diff --git a/next/source/cocoa/application.lisp b/next/source/cocoa/application.lisp new file mode 100644 index 000000000..448ee2235 --- /dev/null +++ b/next/source/cocoa/application.lisp @@ -0,0 +1,89 @@ +(in-package "CCL") + +(defclass next-application (ns:ns-application) () + (:metaclass ns:+ns-application)) + +(objc:defmethod (#/sendEvent: :void) ((self next-application) event) + (if (eql #$NSKeyDown (#/type event)) + (unless (interface:process-event event) + (call-next-method event)) + (call-next-method event))) + +(defclass cocoa-ui-object (ui-object) ()) + +(defclass cocoa-application (application) + ((standalone-p :initform nil :accessor cocoa-application-standalone-p))) + +(defparameter *cocoa-application* + (make-instance 'cocoa-application + :ui-object (make-instance 'cocoa-ui-object))) + +(defmethod application-error ((self cocoa-application) condition error-pointer) + (break-loop-handle-error condition error-pointer)) + +(defmethod parse-application-arguments ((self cocoa-application)) + (values nil nil nil nil)) + +(defmethod toplevel-function ((self cocoa-application) init-file) + (declare (ignore init-file)) + (setf (cocoa-application-standalone-p self) t) + (prepare-cocoa-application self) + (start-cocoa-application self)) + +(defmethod prepare-cocoa-application ((self cocoa-application)) + (call-in-initial-process #'(lambda () + (setq *nsapp* (load-cocoa-application self)) + (next:start)))) + +(defmethod load-cocoa-application ((a cocoa-application)) + (with-autorelease-pool + (let* ((bundle (#/mainBundle ns:ns-bundle)) + (info (#/infoDictionary bundle)) + (progname (#/objectForKey: info #@"CFBundleName"))) + (unless (%null-ptr-p progname) + (#/setProcessName: (#/processInfo ns:ns-process-info) progname)) + (let* ((appclass next-application) + (app (#/sharedApplication appclass))) + (when (%null-ptr-p app) + (error "Could not create shared instance of ~s" + (%get-cfstring classname))) + app)))) + +(defun become-foreground-application () + (rlet ((psn #>ProcessSerialNumber)) + (#_GetCurrentProcess psn) + (#_TransformProcessType psn #$kProcessTransformToForegroundApplication))) + +(defun event-loop () + (loop + (with-simple-restart (abort "Process the next event") + (#/run *nsapp*)))) + +(defun run-event-loop () + (%set-toplevel nil) + (assert (eq *current-process* *initial-process*)) + (change-class *initial-process* 'cocoa-event-process) + (setf (process-name *initial-process*) "Cocoa event loop") + (with-process-whostate ("Active") + (event-loop))) + +;; After the lisp starts up, it creates a listener thread. The +;; initial thead then goes to sleep, waking up about 3 times a second +;; to do some housekeeping tasks. +;; +;; Because most of Cocoa needs to run on the initial thread, we +;; interrupt the initial thread, and use %set-toplevel and toplevel +;; (which are basically process-preset and process-reset for the +;; initial process) to make it start running the Cocoa event loop. We +;; create a new thread to do the housekeeping. + +(defmethod start-cocoa-application ((a cocoa-application)) + (flet ((startup () + (with-standard-initial-bindings + (process-run-function "housekeeping" #'housekeeping-loop) + (become-foreground-application) + (run-event-loop)))) + (process-interrupt *initial-process* + #'(lambda () + (%set-toplevel #'startup) + (toplevel))))) diff --git a/next/source/cocoa/cocoa.lisp b/next/source/cocoa/cocoa.lisp new file mode 100644 index 000000000..e66b4003f --- /dev/null +++ b/next/source/cocoa/cocoa.lisp @@ -0,0 +1,224 @@ +;;;; cocoa.lisp --- cocoa helper functions & data + +(in-package :interface) + +(defparameter *window* nil) +(defparameter *next-view* nil) + +(defclass minibuffer-view (ns:ns-view) + ((input-buffer :accessor input-buffer) + (completion-table :accessor completion-table) + (completion-controller :accessor completion-controller) + (completion-function :accessor completion-function)) + (:metaclass ns:+ns-object)) + +(defmethod initialize-instance :after ((self minibuffer-view) + &key &allow-other-keys) + (let* ((input-field (make-instance 'ns:ns-text-field)) + (completion-controller (make-instance 'controller + :data ())) + (completion-column (#/autorelease (make-instance ns:ns-table-column + :column-title "Completion" + :identifier "Completion" + :min-width 80 + :editable nil + :selectable t))) + (completion-table + (make-instance ns:ns-table-view + :allows-column-resizing nil + :column-autoresizing-style :uniform))) + (#/setDelegate: input-field self) + (#/addTableColumn: completion-table completion-column) + (#/setDataSource: completion-table completion-controller) + (setf (input-buffer self) input-field) + (setf (completion-table self) completion-table) + (setf (completion-controller self) completion-controller) + (#/addSubview: self input-field) + (#/addSubview: self completion-table) + (make-constraint :item1 input-field :att1 :center-x :relation := :item2 self :att2 :center-x) + (make-constraint :item1 input-field :att1 :width :relation := :item2 self :att2 :width) + (make-constraint :item1 input-field :att1 :top :relation := :item2 self :att2 :top) + (make-constraint :item1 input-field :att1 :height :relation := :const 20) + (make-constraint :item1 completion-table :att1 :top :relation := :item2 input-field :att2 :bottom) + (make-constraint :item1 completion-table :att1 :bottom :relation := :item2 self :att2 :bottom) + (make-constraint :item1 completion-table :att1 :width :relation := :item2 self :att2 :width))) + +(defmethod get-input ((self minibuffer-view)) + (ns-to-lisp-string (#/stringValue (input-buffer self)))) + +(defmethod process-set-completions ((self minibuffer-view)) + "Process and set completions for the minibuffer" + (with-slots (completion-function completion-controller completion-table) self + (when (completion-function self) + (setf (data completion-controller) (funcall completion-function (get-input self))) + (#/reloadData completion-table)))) + +(objc:defmethod (#/controlTextDidChange: :void) ((self minibuffer-view) notification) + (declare (ignore notification)) + (process-set-completions self)) + +(defclass next-web-view (ns:web-view) + ((load-finished-callback :accessor load-finished-callback)) + (:metaclass ns:+ns-object)) + +(objc:defmethod (#/webView:didFinishLoadForFrame: :void) + ((self next-web-view) + (wvs :id) + (fl :id)) + (declare (ignore wvs fl)) + (funcall (load-finished-callback self))) + +(defclass fill-container-view (ns:ns-view) + ((fill-view :accessor fill-view + :initarg :fill-view)) + (:default-initargs + :fill-view nil) + (:metaclass ns:+ns-object)) + +(defmethod initialize-instance :after ((self fill-container-view) + &key (fill-view nil) &allow-other-keys) + (when (and fill-view (view-p fill-view)) + (#/addSubview: self fill-view) + (constrain-size-relative-to fill-view self :rel :=))) + +(defmethod set-fill-view ((self fill-container-view) view) + (on-main-thread + (when (fill-view self) + (#/removeFromSuperview (fill-view self))) + (#/addSubview: self view) + (constrain-size-relative-to view self :rel :=)) + (setf (fill-view self) view)) + +(defclass next-view (ns:ns-view) + ((%fill-container-view :accessor fill-container-view) + (%minibuffer-view :accessor minibuffer-view) + (minibuffer-height-constraint :accessor minibuffer-height-constraint)) + (:metaclass ns:+ns-object)) + +(defmethod initialize-instance :after ((self next-view) + &key &allow-other-keys) + (let ((fvc (make-instance 'fill-container-view)) + (mb (make-instance 'minibuffer-view))) + (#/addSubview: self fvc) + (#/addSubview: self mb) + (setf (fill-container-view self) fvc) + (setf (minibuffer-view self) mb) + (make-constraint :item1 fvc :att1 :top :relation := :item2 self :att2 :top) + (make-constraint :item1 fvc :att1 :width :relation := :item2 self :att2 :width) + (make-constraint :item1 fvc :att1 :bottom :relation := :item2 mb :att2 :top) + (make-constraint :item1 mb :att1 :bottom :relation := :item2 self :att2 :bottom) + (make-constraint :item1 mb :att1 :width :relation := :item2 self :att2 :width) + (setf (minibuffer-height-constraint self) + (make-constraint :item1 mb :att1 :height :relation := :const 0)))) + +(defmethod hide-minibuffer ((self next-view)) + (on-main-thread + (#/setConstant: (minibuffer-height-constraint self) 0))) + +(defmethod show-minibuffer ((self next-view)) + (on-main-thread + (#/setConstant: (minibuffer-height-constraint self) 200))) + +(defclass next-window (ns:ns-window) () + (:metaclass ns:+ns-object)) + +(defun process-event (event) + (let* ((flags (#/modifierFlags event)) + (character (ns-to-lisp-string (#/charactersIgnoringModifiers event)))) + (next:push-key-chord + (> (logand flags #$NSControlKeyMask) 0) + (> (logand flags #$NSAlternateKeyMask) 0) + (> (logand flags #$NSCommandKeyMask) 0) + character))) + +(defun make-window () + (gui::assume-cocoa-thread) + (ns:with-ns-rect (r 100.0 100.0 1024.0 768.0) + (ccl::with-autorelease-pool + (let* ((.window. (make-instance + 'next-window + :with-content-rect r + :style-mask (logior #$NSTitledWindowMask + #$NSClosableWindowMask + #$NSMiniaturizableWindowMask + #$NSResizableWindowMask) + :backing #$NSBackingStoreBuffered + :title "nEXT" + :defer t)) + (.next-view. (make-instance 'next-view))) + (#/setContentView: .window. .next-view.) + (#/makeKeyAndOrderFront: .window. +null-ptr+) + (setf *window* .window.) + (setf *next-view* .next-view.) + *window*)))) + +(defun initialize ()) + +(defun start () + (on-main-thread + (make-window))) + +(defun kill () + (quit)) + +(defun set-visible-view (view) + (set-fill-view (fill-container-view *next-view*) view)) + +(defun make-web-view () + (on-main-thread + (ccl::with-autorelease-pool + (let ((view (#/retain + (make-instance + 'next-web-view + :frame-name #@"frame" + :group-name #@"group")))) + (#/setFrameLoadDelegate: view view) + view)))) + +(defun url-from-string (s) + (ccl::with-autorelease-pool + (#/retain (#/URLWithString: ns:ns-url (ccl::%make-nsstring (string s)))))) + +(defun web-view-set-url (view url) + (on-main-thread + (let* ((nsurl (url-from-string url)) + (webframe (#/mainFrame view)) + (request (#/requestWithURL: ns:ns-url-request nsurl))) + (#/loadRequest: webframe request)))) + +(defun delete-view (view) + (#/release view)) + +(defun web-view-scroll-down (view scroll-distance) + (declare (ignore scroll-distance)) + (on-main-thread + (#/stringByEvaluatingJavaScriptFromString: view #@"window.scrollBy(0, 100);"))) + +(defun web-view-scroll-up (view scroll-distance) + (declare (ignore scroll-distance)) + (on-main-thread + (#/stringByEvaluatingJavaScriptFromString: view #@"window.scrollBy(0, -100);"))) + +(defun web-view-set-url-loaded-callback (view function) + (setf (load-finished-callback view) function)) + +(defun web-view-get-url (view) + (ns-to-lisp-string (#/mainFrameURL view))) + +(defun make-minibuffer () + (minibuffer-view *next-view*)) + +(defun minibuffer-show () + (show-minibuffer *next-view*) + (#/makeFirstResponder: *window* (input-buffer (minibuffer-view *next-view*))) + (process-set-completions (minibuffer-view *next-view*))) + +(defun minibuffer-hide () + (hide-minibuffer *next-view*) + (#/makeFirstResponder: *window* (fill-container-view *next-view*))) + +(defun minibuffer-get-input () + (get-input (minibuffer-view *next-view*))) + +(defun minibuffer-set-completion-function (function) + (setf (completion-function (minibuffer-view *next-view*)) function)) diff --git a/next/source/cocoa/utilities.lisp b/next/source/cocoa/utilities.lisp new file mode 100644 index 000000000..04160424c --- /dev/null +++ b/next/source/cocoa/utilities.lisp @@ -0,0 +1,187 @@ +;;;; cocoa-utilities.lisp + + +#| +The MIT license. + +Copyright (c) 2013 Paul L. Krueger + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation +files (the "Software"), to deal in the Software without restriction, +including without limitation the rights to use, copy, modify, merge, +publish, distribute, sublicense, and/or sell copies of the Software, +and to permit persons to whom the Software is furnished to do so, +subject to the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +|# + +(in-package :interface) + +(defmacro on-main-thread (&rest actions) + `(ccl::call-in-event-process + #'(lambda () + ,@actions))) + +(defun ns-to-lisp-string (ns-str) + (if (and (not (eql (%null-ptr) ns-str)) (plusp (#/length ns-str))) + (ccl::%get-utf-8-cstring (#/UTF8String ns-str)) + "")) + +(defun lisp-to-ns-string (lisp-str) + (ccl::%make-nsstring lisp-str)) + +(defun view-p (thing) + (typep thing 'ns:ns-view)) + +(defun obj-if-not-null (ns-obj) + (if (eql ns-obj (%null-ptr)) + nil + ns-obj)) + +(defmethod superview ((v ns:ns-view)) + (obj-if-not-null (#/superview v))) + +(defmethod common-superview (v1 v2) + (cond ((and (view-p v1) (view-p v2)) + (if (eql v1 v2) + (superview v1) + (obj-if-not-null (#/ancestorSharedWithView: v1 v2)))) + ((view-p v1) + (superview v1)) + ((view-p v2) + (superview v2)) + (t + nil))) + +(defun relation-convert (rel-key) + (case rel-key + (:<= #$NSLayoutRelationLessThanOrEqual) + (:= #$NSLayoutRelationEqual) + (:>= #$NSLayoutRelationGreaterThanOrEqual) + (t #$NSLayoutRelationEqual))) + +(defun attribute-convert (att-key) + (case att-key + (:left #$NSLayoutAttributeLeft) + (:right #$NSLayoutAttributeRight) + (:top #$NSLayoutAttributeTop) + (:bottom #$NSLayoutAttributeBottom) + (:leading #$NSLayoutAttributeLeading) + (:trailing #$NSLayoutAttributeTrailing) + (:width #$NSLayoutAttributeWidth) + (:height #$NSLayoutAttributeHeight) + (:center-x #$NSLayoutAttributeCenterX) + (:center-y #$NSLayoutAttributeCenterY) + (:baseline #$NSLayoutAttributeBaseline) + (:none #$NSLayoutAttributeNotAnAttribute) + (t #$NSLayoutAttributeNotAnAttribute))) + +(defun make-constraint (&key + (install-view nil install-view-provided) + (priority nil) + item1 + (att1 :width) + (relation :=) + (item2 nil) + (att2 nil) ;; defaults to att1 if item2 is not null + (mult 1) + (const 0)) + (unless install-view-provided + (setf install-view (common-superview item1 item2))) + (when (and (view-p item1) + install-view + (not (eql item1 install-view)) + (#/translatesAutoresizingMaskIntoConstraints item1)) + ;; make sure no automatic constraints are used for this view + (#/setTranslatesAutoresizingMaskIntoConstraints: item1 #$NO)) + (when (and (view-p item2) + install-view + (not (eql item2 install-view)) + (#/translatesAutoresizingMaskIntoConstraints item2)) + ;; make sure no automatic constraints are used for this view + (#/setTranslatesAutoresizingMaskIntoConstraints: item2 #$NO)) + (let* ((rel (relation-convert relation)) + (a1 (attribute-convert att1)) + (a2 (cond (att2 (attribute-convert att2)) + ((or (null item2) (eql item2 (%null-ptr))) (attribute-convert :none)) + (t a1))) + (constraint (#/constraintWithItem:attribute:relatedBy:toItem:attribute:multiplier:constant: + ns:ns-layout-constraint + item1 + a1 + rel + (or item2 (%null-ptr)) + a2 + (gui::cgfloat mult) + (gui::cgfloat const)))) + (when (numberp priority) + (#/setPriority: constraint (float priority))) + (when (view-p install-view) + (on-main-thread + (#/addConstraint: install-view constraint))) + constraint)) + +(defmethod constrain-size-relative-to ((sized-view ns:ns-view) (relative-view ns:ns-view) + &key + (priority nil) + (install-view (common-superview sized-view relative-view)) + (rel :=) + (width t) + (height t)) + ;; constrains sized-view relative to the size of relative-view + ;; rel should be one of the keywords := :<= :>= + (let ((constraints nil)) + (when width + (push (make-constraint + :priority priority + :install-view install-view + :item1 sized-view + :att1 :width + :relation rel + :item2 relative-view + :att2 :width) + constraints)) + (when height + (push (make-constraint + :priority priority + :install-view install-view + :item1 sized-view + :att1 :height + :relation rel + :item2 relative-view + :att2 :height) + constraints)) + constraints)) + +(defclass controller (ns:ns-object) + ((data :accessor data + :initarg :data)) + (:metaclass ns:+ns-object)) + +(objc:defmethod (#/numberOfRowsInTableView: #>NSInteger) + ((self controller) (tab :id)) + ;; Assumes that objects is some type of sequence + ;; Subclass should override this method if that is not true. + (declare (ignore tab)) + (with-slots (data) self + (length data))) + +(objc:defmethod (#/tableView:objectValueForTableColumn:row: :id) + ((self controller) + (tab :id) + (col :id) + (row #>NSInteger)) + (declare (ignore tab col)) + (lisp-to-ns-string (nth row (data self)))) diff --git a/next/lisp/completion.lisp b/next/source/completion.lisp index 78382d689..78382d689 100644 --- a/next/lisp/completion.lisp +++ b/next/source/completion.lisp diff --git a/next/lisp/document-mode.lisp b/next/source/document-mode.lisp index 4dc696cfe..cbe7a81ce 100644 --- a/next/lisp/document-mode.lisp +++ b/next/source/document-mode.lisp @@ -3,17 +3,15 @@ (in-package :next) (defvar document-mode-map (make-hash-table :test 'equalp)) -(defvar scroll-distance 30 - "The distance scroll-down or scroll-up will scroll.") (defclass document-mode (mode) ((history-active-node :accessor mode-history-active-node :initarg :active-node))) (defun scroll-down () - (interface:web-view-scroll-down (buffer-view *active-buffer*) scroll-distance)) + (interface:web-view-scroll-down (buffer-view *active-buffer*) *scroll-distance*)) (defun scroll-up () - (interface:web-view-scroll-up (buffer-view *active-buffer*) scroll-distance)) + (interface:web-view-scroll-up (buffer-view *active-buffer*) *scroll-distance*)) (defun history-backwards () ;; move up to parent node to iterate backwards in history tree @@ -36,12 +34,17 @@ (defun history-fowards-query-complete (input) ;; provide completion candidates to the history-forwards-query function - (let ((children (node-children (mode-history-active-node (buffer-mode *minibuffer-callback-buffer*))))) + (let ((children + ;; Find children of active document-mode instance + (node-children (mode-history-active-node + ;; Find active document-mode instance from minibuffer callback + (buffer-mode (minibuffer-callback-buffer + (buffer-mode *minibuffer*))))))) (when children (fuzzy-match input (mapcar #'node-data children))))) (defun add-or-traverse-history (mode) - ;; get url from mode-view's qwebview + ;; get url from mode-view's webview (let ((url (interface:web-view-get-url (mode-view mode))) (active-node (mode-history-active-node mode))) ;; only add element to the history if it is different than the current @@ -79,11 +82,11 @@ (set-url-buffer url *active-buffer*))) (defun normalize-url (input-url) - "Will convert example.com to http://www.example.com" + "Will convert example.com to https://www.example.com" (let ((url (puri:parse-uri input-url))) (if (puri:uri-scheme url) input-url - (concatenate 'string "http://" input-url)))) + (concatenate 'string "https://" input-url)))) (defun document-mode () "Base mode for interacting with documents" @@ -95,6 +98,6 @@ :active-node root))) (interface:web-view-set-url-loaded-callback (mode-view mode) - (lambda (ok) (add-or-traverse-history mode))) + (lambda () (add-or-traverse-history mode))) ;; return instance of mode mode)) diff --git a/next/source/global.lisp b/next/source/global.lisp new file mode 100644 index 000000000..15b5e8ee9 --- /dev/null +++ b/next/source/global.lisp @@ -0,0 +1,14 @@ +;;;; global.lisp --- global variable and parameter declarations + +(in-package :next) + +(defvar global-map (make-hash-table :test 'equalp) + "A global key map, available in every mode/buffer") +(defvar *active-buffer* () + "The currently active buffer") +(defvar *minibuffer* nil + "A variable to store the mini-buffer") +(defvar *buffers* () + "A list of all existing buffers") +(defvar *scroll-distance* 15 + "The distance scroll-down or scroll-up will scroll.") diff --git a/next/lisp/keymap.lisp b/next/source/keymap.lisp index 0ed0a5123..3bd49c57e 100644 --- a/next/lisp/keymap.lisp +++ b/next/source/keymap.lisp @@ -11,9 +11,6 @@ (in-package :next) - -(defvar global-map (make-hash-table :test 'equalp) - "A global key map, available in every mode/buffer") (defvar *key-sequence-stack* () "A stack that keeps track of the key chords a user has inputted") diff --git a/next/lisp/macro.lisp b/next/source/macro.lisp index 1509b1551..ea75a6cd7 100644 --- a/next/lisp/macro.lisp +++ b/next/source/macro.lisp @@ -4,11 +4,11 @@ ;; used to provide input to buffers, "function" must accept input from ;; the minibuffer -(defmacro :input (function) - `#'(lambda () (input #',function))) +(defmacro :input (minibuffer function) + `#'(lambda () (input (buffer-mode ,minibuffer) #',function))) ;; used to provide input to buffers with an optional completion ;; function, the completion function must narrow a list of candidates ;; when given input -(defmacro :input-complete (function completion) - `#'(lambda () (input #',function #',completion))) +(defmacro :input-complete (minibuffer function completion) + `#'(lambda () (input (buffer-mode ,minibuffer) #',function #',completion))) diff --git a/next/source/minibuffer.lisp b/next/source/minibuffer.lisp new file mode 100644 index 000000000..2717bd36d --- /dev/null +++ b/next/source/minibuffer.lisp @@ -0,0 +1,41 @@ +;;;; minibuffer.lisp --- major mode for input + +(in-package :next) + +(defvar minibuffer-mode-map (make-hash-table :test 'equalp)) + +(defclass minibuffer-mode (mode) + ((minibuffer-completion-function :accessor minibuffer-completion-function) + (minibuffer-callback-function :accessor minibuffer-callback-function) + (minibuffer-callback-buffer :accessor minibuffer-callback-buffer))) + +(defmethod input ((self minibuffer-mode) callback-function &optional completion-function) + (with-slots (minibuffer-callback-function minibuffer-completion-function minibuffer-callback-buffer) self + (setf minibuffer-callback-function callback-function) + (setf minibuffer-completion-function completion-function) + (setf minibuffer-callback-buffer *active-buffer*) + (interface:minibuffer-set-completion-function completion-function)) + (set-active-buffer *minibuffer*) + (interface:minibuffer-show)) + +(defmethod return-input ((self minibuffer-mode)) + (set-active-buffer (minibuffer-callback-buffer self)) + (with-slots (minibuffer-completion-function minibuffer-callback-function) self + (if minibuffer-completion-function + (funcall minibuffer-callback-function + (nth 0 (funcall minibuffer-completion-function + (interface:minibuffer-get-input)))) + (funcall minibuffer-callback-function + (interface:minibuffer-get-input)))) + (interface:minibuffer-hide)) + +(defmethod cancel-input ((self minibuffer-mode)) + (set-active-buffer (minibuffer-callback-buffer self)) + (interface:minibuffer-hide)) + +(defun minibuffer-mode () + "Base mode for input" + (make-instance 'minibuffer-mode + :name "minibuffer" + :keymap minibuffer-mode-map + :view (interface:make-minibuffer))) diff --git a/next/lisp/mode.lisp b/next/source/mode.lisp index 43490a0f4..43490a0f4 100644 --- a/next/lisp/mode.lisp +++ b/next/source/mode.lisp diff --git a/next/lisp/package.lisp b/next/source/package.lisp index 233608a04..a99dcabfa 100644 --- a/next/lisp/package.lisp +++ b/next/source/package.lisp @@ -9,13 +9,13 @@ #:push-key-chord)) (defpackage :interface - (:use :common-lisp) + (:use :common-lisp :ccl) (:export #:initialize #:start - #:quit + #:kill + #:process-event #:set-visible-view - #:add-to-stack-layout #:delete-view #:make-web-view #:web-view-scroll-down diff --git a/next/lisp/tree-history.lisp b/next/source/tree-history.lisp index 24019bdf1..24019bdf1 100644 --- a/next/lisp/tree-history.lisp +++ b/next/source/tree-history.lisp |