mirror of
https://github.com/godotengine/emacs-gdscript-mode.git
synced 2026-01-05 22:10:05 +03:00
Compare commits
91 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
79739fc80f | ||
|
|
9822c8a921 | ||
|
|
e94dfd9dc7 | ||
|
|
e3b47496a3 | ||
|
|
bd0a741066 | ||
|
|
a0d25b46d8 | ||
|
|
2afbcecdd2 | ||
|
|
5136be407a | ||
|
|
1938aa7e2d | ||
|
|
3f3739dd88 | ||
|
|
17c270190b | ||
|
|
e18cf2cea3 | ||
|
|
f195ca86f8 | ||
|
|
703c776260 | ||
|
|
d83b971e20 | ||
|
|
208e231138 | ||
|
|
707e77ded3 | ||
|
|
c3d9988984 | ||
|
|
f320e02427 | ||
|
|
88f6bca508 | ||
|
|
686feebf2d | ||
|
|
f8fce3ad1a | ||
|
|
3052839d71 | ||
|
|
bee7f99c6f | ||
|
|
d1076e1b59 | ||
|
|
52b3637df8 | ||
|
|
21be7cd6d3 | ||
|
|
b03647b62e | ||
|
|
e0c8700d25 | ||
|
|
a89ae451d9 | ||
|
|
32086df833 | ||
|
|
4ae8760e19 | ||
|
|
ab6aae89aa | ||
|
|
2737f1c68c | ||
|
|
cd92e12084 | ||
|
|
becce1a4ba | ||
|
|
718267511f | ||
|
|
d25f778f02 | ||
|
|
b8a840448a | ||
|
|
e0a8dc9f0b | ||
|
|
8a28276daa | ||
|
|
a6efb8713d | ||
|
|
9b26d25aa3 | ||
|
|
bcb50cfe2c | ||
|
|
0938403561 | ||
|
|
3e2ae19f03 | ||
|
|
812da6aa3c | ||
|
|
4946aff35a | ||
|
|
0692056e95 | ||
|
|
b7188197a5 | ||
|
|
44fc361bd7 | ||
|
|
268abf778b | ||
|
|
13a3e00e6c | ||
|
|
45e05fd58b | ||
|
|
cee6d61591 | ||
|
|
3995a7b2ae | ||
|
|
70a243278a | ||
|
|
a5a25f07ac | ||
|
|
a48ad04502 | ||
|
|
73dac51758 | ||
|
|
68f18932a4 | ||
|
|
586d957650 | ||
|
|
72ddbec953 | ||
|
|
c8c22a6884 | ||
|
|
30c4d48f81 | ||
|
|
f071667776 | ||
|
|
d392e8aa7e | ||
|
|
d9e1f7f766 | ||
|
|
4badcf6a0c | ||
|
|
b7bfa6a3b2 | ||
|
|
9043e1a6b6 | ||
|
|
16c631cd6f | ||
|
|
4a1175f467 | ||
|
|
bdce2da794 | ||
|
|
fe59b77c3f | ||
|
|
e54edf94b8 | ||
|
|
d751ce6249 | ||
|
|
fa9ec1fead | ||
|
|
287acb7c76 | ||
|
|
b53d56e467 | ||
|
|
4e5bb877e3 | ||
|
|
4edc27ee7c | ||
|
|
9b1e313e2c | ||
|
|
f6c7bb5bb4 | ||
|
|
20fc7e4381 | ||
|
|
75fe658ab8 | ||
|
|
0aa2e8f52f | ||
|
|
95fdf3aa23 | ||
|
|
163a1340e5 | ||
|
|
1d6d707144 | ||
|
|
f87cc3e1c2 |
6
.github/dependabot.yml
vendored
Normal file
6
.github/dependabot.yml
vendored
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
version: 2
|
||||||
|
updates:
|
||||||
|
- package-ecosystem: github-actions
|
||||||
|
directory: /
|
||||||
|
schedule:
|
||||||
|
interval: daily
|
||||||
57
.github/workflows/test.yml
vendored
Normal file
57
.github/workflows/test.yml
vendored
Normal file
@@ -0,0 +1,57 @@
|
|||||||
|
name: CI
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches:
|
||||||
|
- master
|
||||||
|
pull_request:
|
||||||
|
|
||||||
|
concurrency:
|
||||||
|
group: ${{ github.workflow }}-${{ github.ref }}
|
||||||
|
cancel-in-progress: true
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
test:
|
||||||
|
runs-on: ${{ matrix.os }}
|
||||||
|
continue-on-error: ${{ matrix.experimental }}
|
||||||
|
strategy:
|
||||||
|
fail-fast: false
|
||||||
|
matrix:
|
||||||
|
os: [ubuntu-latest, macos-latest, windows-latest]
|
||||||
|
emacs-version:
|
||||||
|
- 26.3
|
||||||
|
- 27.2
|
||||||
|
- 28.2
|
||||||
|
- 29.4
|
||||||
|
- 30.2
|
||||||
|
experimental: [false]
|
||||||
|
include:
|
||||||
|
- os: ubuntu-latest
|
||||||
|
emacs-version: snapshot
|
||||||
|
experimental: true
|
||||||
|
- os: macos-latest
|
||||||
|
emacs-version: snapshot
|
||||||
|
experimental: true
|
||||||
|
- os: windows-latest
|
||||||
|
emacs-version: snapshot
|
||||||
|
experimental: true
|
||||||
|
exclude:
|
||||||
|
- os: macos-latest
|
||||||
|
emacs-version: 26.3
|
||||||
|
- os: macos-latest
|
||||||
|
emacs-version: 27.2
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v6
|
||||||
|
|
||||||
|
- uses: jcs090218/setup-emacs@master
|
||||||
|
with:
|
||||||
|
version: ${{ matrix.emacs-version }}
|
||||||
|
|
||||||
|
- uses: emacs-eask/setup-eask@master
|
||||||
|
with:
|
||||||
|
version: 'snapshot'
|
||||||
|
|
||||||
|
- name: Run tests
|
||||||
|
run:
|
||||||
|
make ci
|
||||||
3
.gitignore
vendored
3
.gitignore
vendored
@@ -2,7 +2,8 @@
|
|||||||
*.elc
|
*.elc
|
||||||
|
|
||||||
# Packaging
|
# Packaging
|
||||||
.cask
|
.eask
|
||||||
|
dist/
|
||||||
|
|
||||||
# Backup files
|
# Backup files
|
||||||
*~
|
*~
|
||||||
|
|||||||
23
CHANGELOG.md
23
CHANGELOG.md
@@ -2,6 +2,29 @@
|
|||||||
|
|
||||||
This document lists new features, improvements, changes, and bug fixes in each release of the package.
|
This document lists new features, improvements, changes, and bug fixes in each release of the package.
|
||||||
|
|
||||||
|
## GDScript mode 1.5.0
|
||||||
|
|
||||||
|
- Added the ability to toggle breakpoint on the current line instead of either adding or removing them.
|
||||||
|
- Added keybindings matching Godot to run the project (<kbd>f5</kbd>), current scene (<kbd>f6</kbd>), continue execution (<kbd>f7</kbd>), and toggle breakpoints <kbd>F9</kbd>.
|
||||||
|
|
||||||
|
## GDScript mode 1.4.1
|
||||||
|
|
||||||
|
Thanks to @clangdo for the contribution!
|
||||||
|
|
||||||
|
- Fixed indent functions preventing double hanging indent in parentheses or after a `\`.
|
||||||
|
|
||||||
|
## GDScript mode 1.4.0
|
||||||
|
|
||||||
|
Big thanks to @VlachJosef and @rileyrg for their work on this release.
|
||||||
|
|
||||||
|
### New features
|
||||||
|
|
||||||
|
- Debugger support with breakpoints, code stepping, stack frames, remote scene tree, and more. See the [README](https://github.com/godotengine/emacs-gdscript-mode/blob/master/README.md) for more information.
|
||||||
|
|
||||||
|
### Bug fixes
|
||||||
|
|
||||||
|
- Fix scene and script selection not aborting when pressing <kbd>C-g</kbd>.
|
||||||
|
|
||||||
## GDScript mode 1.3.0
|
## GDScript mode 1.3.0
|
||||||
|
|
||||||
This release brings many quality-of-life improvements to work more productively with Godot and Emacs.
|
This release brings many quality-of-life improvements to work more productively with Godot and Emacs.
|
||||||
|
|||||||
19
Eask
Normal file
19
Eask
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
;; -*- mode: eask; lexical-binding: t -*-
|
||||||
|
|
||||||
|
(package "gdscript-mode"
|
||||||
|
"0.1.0"
|
||||||
|
"Major mode for Godot's GDScript language")
|
||||||
|
|
||||||
|
(website-url "https://github.com/godotengine/emacs-gdscript-mode/")
|
||||||
|
(keywords "languages")
|
||||||
|
|
||||||
|
(package-file "gdscript-mode.el")
|
||||||
|
(files "*.el")
|
||||||
|
|
||||||
|
(script "test" "echo \"Error: no test specified\" && exit 1")
|
||||||
|
|
||||||
|
(source "gnu")
|
||||||
|
|
||||||
|
(depends-on "emacs" "26.3")
|
||||||
|
|
||||||
|
(setq network-security-level 'low) ; see https://github.com/jcs090218/setup-emacs-windows/issues/156#issuecomment-932956432
|
||||||
36
Makefile
Normal file
36
Makefile
Normal file
@@ -0,0 +1,36 @@
|
|||||||
|
SHELL := /usr/bin/env bash
|
||||||
|
|
||||||
|
EMACS ?= emacs
|
||||||
|
EASK ?= eask
|
||||||
|
|
||||||
|
.PHONY: clean checkdoc lint package install compile test
|
||||||
|
|
||||||
|
# TODO: add `lint` if we can?
|
||||||
|
ci: clean package install compile checkdoc
|
||||||
|
|
||||||
|
package:
|
||||||
|
@echo "Packaging..."
|
||||||
|
$(EASK) package
|
||||||
|
|
||||||
|
install:
|
||||||
|
@echo "Installing..."
|
||||||
|
$(EASK) install
|
||||||
|
|
||||||
|
compile:
|
||||||
|
@echo "Compiling..."
|
||||||
|
$(EASK) compile
|
||||||
|
|
||||||
|
test:
|
||||||
|
@echo "Testing..."
|
||||||
|
$(EASK) ert ./test/*.el
|
||||||
|
|
||||||
|
checkdoc:
|
||||||
|
@echo "Run checkdoc..."
|
||||||
|
$(EASK) lint checkdoc
|
||||||
|
|
||||||
|
lint:
|
||||||
|
@echo "Run package-lint..."
|
||||||
|
$(EASK) lint package
|
||||||
|
|
||||||
|
clean:
|
||||||
|
$(EASK) clean all
|
||||||
203
README.md
203
README.md
@@ -7,34 +7,46 @@ This package adds support for the GDScript programming language from the Godot
|
|||||||
game engine in Emacs. It gives syntax highlighting and indentations.
|
game engine in Emacs. It gives syntax highlighting and indentations.
|
||||||
[Contributors](#contributing) are welcome!
|
[Contributors](#contributing) are welcome!
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
<!-- markdown-toc start - Don't edit this section. Run M-x markdown-toc-refresh-toc -->
|
<!-- markdown-toc start - Don't edit this section. Run M-x markdown-toc-refresh-toc -->
|
||||||
**Table of Contents**
|
**Table of Contents**
|
||||||
|
|
||||||
- [Features](#features)
|
- [Features](#features)
|
||||||
- [Contributing](#contributing)
|
- [Contributing](#contributing)
|
||||||
- [How to install](#how-to-install)
|
- [How to install](#how-to-install)
|
||||||
|
- [Installing in Spacemacs](#installing-in-spacemacs)
|
||||||
|
- [Installing in Doom Emacs](#installing-in-doom-emacs)
|
||||||
|
- [Installing with `use-package` + `straight.el`](#installing-with-use-package--straightel)
|
||||||
|
- [Installing manually](#installing-manually)
|
||||||
|
- [Auto-completion with the Language Server Protocol (LSP)](#auto-completion-with-the-language-server-protocol-lsp)
|
||||||
|
- [Known issues](#known-issues)
|
||||||
|
- [Major mode with Treesit](#major-mode-with-treesit)
|
||||||
|
- [Install treesit](#install-treesit)
|
||||||
|
- [Install grammar](#install-grammar)
|
||||||
- [How to use](#how-to-use)
|
- [How to use](#how-to-use)
|
||||||
- [Opening the project in the editor](#opening-the-project-in-the-editor)
|
- [Opening the project in the editor](#opening-the-project-in-the-editor)
|
||||||
- [Running Godot with visual debug options](#running-godot-with-visual-debug-options)
|
- [Running Godot with visual debug options](#running-godot-with-visual-debug-options)
|
||||||
- [Using Hydra](#using-hydra)
|
- [Using Hydra](#using-hydra)
|
||||||
- [Formatting code with gdformat](#formatting-code-with-gdformat)
|
- [Formatting code with gdformat](#formatting-code-with-gdformat)
|
||||||
- [Browsing the Godot API with eww](#browsing-the-godot-api-with-eww)
|
- [Browsing the Godot API with eww](#browsing-the-godot-api-with-eww)
|
||||||
|
- [Using a local copy of the Godot docs](#using-a-local-copy-of-the-godot-docs)
|
||||||
- [Keyboard shortcuts](#keyboard-shortcuts)
|
- [Keyboard shortcuts](#keyboard-shortcuts)
|
||||||
- [Customization](#customization)
|
- [Customization](#customization)
|
||||||
- [Using the debugger](#using-the-debugger)
|
- [Using the debugger](#using-the-debugger)
|
||||||
- [Adding and removing breakpoints](#adding-and-removing-breakpoints)
|
- [Adding and removing breakpoints](#adding-and-removing-breakpoints)
|
||||||
- [Running the project with the debugger active](#running-the-project-with-the-debugger-active)
|
- [Running the project with the debugger active](#running-the-project-with-the-debugger-active)
|
||||||
- [Fetching an object's details](#fetching-an-objects-details)
|
- [Multi-line display](#multi-line-display)
|
||||||
- [Debug Hydra](#debug-hydra)
|
- [Fetching an object's details](#fetching-an-objects-details)
|
||||||
- [The `* Stack frame vars *` buffer](#the--stack-frame-vars--buffer)
|
- [Debug Hydra](#debug-hydra)
|
||||||
- [`* Inspector *` buffer](#-inspector--buffer)
|
- [The `* Stack frame vars *` buffer](#the--stack-frame-vars--buffer)
|
||||||
- [`* Stack dump *` buffer](#-stack-dump--buffer)
|
- [`* Inspector *` buffer](#-inspector--buffer)
|
||||||
- [`* Breakpoints *` buffer](#-breakpoints--buffer)
|
- [`* Stack dump *` buffer](#-stack-dump--buffer)
|
||||||
- [`* Scene tree *` buffer](#-scene-tree--buffer)
|
- [`* Breakpoints *` buffer](#-breakpoints--buffer)
|
||||||
|
- [`* Scene tree *` buffer](#-scene-tree--buffer)
|
||||||
|
|
||||||
<!-- markdown-toc end -->
|
<!-- markdown-toc end -->
|
||||||
|
|
||||||
|
|
||||||
## Features
|
## Features
|
||||||
|
|
||||||
This mode features all the essentials:
|
This mode features all the essentials:
|
||||||
@@ -52,12 +64,17 @@ This mode features all the essentials:
|
|||||||
- Auto-completion for all the keywords in the `gdscript-keywords.el` file.
|
- Auto-completion for all the keywords in the `gdscript-keywords.el` file.
|
||||||
- Run or open the project and files with Godot.
|
- Run or open the project and files with Godot.
|
||||||
- Browsing the API reference in Emacs.
|
- Browsing the API reference in Emacs.
|
||||||
|
- Add treesit major mode support `gdscript-ts-mode` .
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
_Code folding in action._
|
||||||
|
|
||||||
## Contributing
|
## Contributing
|
||||||
|
|
||||||
Contributors are welcome! Check the [issues tab](issues) for tasks to work on and open a PR anytime.
|
Contributors are welcome! Check the [issues tab](issues) for tasks to work on and open a PR anytime.
|
||||||
|
|
||||||
If you find a bug, or would like to suggest an improvement, [open a new
|
If you find a bug or would like to suggest an improvement, [open a new
|
||||||
issue](issues/new).
|
issue](issues/new).
|
||||||
|
|
||||||
For code style, we follow the [Emacs lisp style
|
For code style, we follow the [Emacs lisp style
|
||||||
@@ -66,29 +83,31 @@ and the [tips and
|
|||||||
conventions](https://www.gnu.org/software/emacs/manual/html_node/elisp/Tips.html)
|
conventions](https://www.gnu.org/software/emacs/manual/html_node/elisp/Tips.html)
|
||||||
from the Emacs manual.
|
from the Emacs manual.
|
||||||
|
|
||||||
You should also check for errors and linter warnings in your code. You can do so in Emacs with flymake or flycheck but we recommend running the tool `makem.sh` provided with the repository:
|
You should also check for errors and linter warnings in your code. You can do so in Emacs with flymake or flycheck, but we recommend running the tool `Eask` provided with the repository:
|
||||||
|
|
||||||
|
This assumes you have [Eask](https://github.com/emacs-eask/cli) installed.
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
./makem.sh lint-compile
|
eask compile
|
||||||
```
|
```
|
||||||
|
|
||||||
This program will tell you if there is any problem with your code. If there's no output, everything is fine. You can run all tests like so, but note it might give you spelling errors that aren't relevant in this project:
|
This program will tell you if there is any problem with your code. If there's no output, everything is fine. You can run all tests like so, but note it might give you spelling errors that aren't relevant in this project:
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
./makem.sh all
|
eask lint checkdoc && eask lint package
|
||||||
```
|
```
|
||||||
|
|
||||||
## How to install
|
## How to install
|
||||||
|
|
||||||
The package is available in the [MELPA](https://melpa.org/#/) package archive. Once you [set up MELPA](https://melpa.org/#/getting-started) you can install the package from Emacs:
|
The package is available in the [MELPA](https://melpa.org/#/) package archive. Once you [set up MELPA](https://melpa.org/#/getting-started) you can install the package from Emacs:
|
||||||
|
|
||||||
```lisp
|
```elisp
|
||||||
M-x package-install gdscript-mode
|
M-x package-install gdscript-mode
|
||||||
```
|
```
|
||||||
|
|
||||||
Then, in your init.el file, you can require the package:
|
Then, in your init.el file, you can require the package:
|
||||||
|
|
||||||
```lisp
|
```elisp
|
||||||
(require 'gdscript-mode)
|
(require 'gdscript-mode)
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -96,7 +115,7 @@ Then, in your init.el file, you can require the package:
|
|||||||
|
|
||||||
1. Add the package to the `dotspacemacs-additional-packages`. You can find it under the dotspacemacs/layers function:
|
1. Add the package to the `dotspacemacs-additional-packages`. You can find it under the dotspacemacs/layers function:
|
||||||
|
|
||||||
```lisp
|
```elisp
|
||||||
(defun dotspacemacs/layers ()
|
(defun dotspacemacs/layers ()
|
||||||
"Configuration Layers declaration..."
|
"Configuration Layers declaration..."
|
||||||
(setq-default
|
(setq-default
|
||||||
@@ -108,60 +127,132 @@ Then, in your init.el file, you can require the package:
|
|||||||
|
|
||||||
2. In your `dotspacemacs/user-config` function, require the package.
|
2. In your `dotspacemacs/user-config` function, require the package.
|
||||||
|
|
||||||
```lisp
|
```elisp
|
||||||
(defun dotspacemacs/user-config ()
|
(defun dotspacemacs/user-config ()
|
||||||
(require 'gdscript-mode))
|
(require 'gdscript-mode))
|
||||||
```
|
```
|
||||||
|
|
||||||
### Installing in Doom Emacs
|
### Installing in Doom Emacs
|
||||||
|
|
||||||
Add the following package definition to your `.doom.d/packages.el` file:
|
Doom Emacs comes with a Godot GDScript module.
|
||||||
|
|
||||||
```lisp
|
You just need to add the "lang: gdscript" keyword to your `.doom.d/init.el` file.
|
||||||
(package! gdscript-mode
|
|
||||||
:recipe (:host github
|
```elisp
|
||||||
:repo "GDQuest/emacs-gdscript-mode"))
|
:lang
|
||||||
|
(gdscript +lsp) ; the language you waited for
|
||||||
```
|
```
|
||||||
|
|
||||||
Require the package in your `.doom.d/config.el` file:
|
The `+lsp` flag adds language server support for game development with Godot.
|
||||||
|
|
||||||
```lisp
|
To see the module's documentation in Emacs, place your cursor over the word `gdscript` and press <kbd>k</kbd>.
|
||||||
(require 'gdscript-mode)
|
|
||||||
```
|
|
||||||
|
|
||||||
### Installing with `use-package` + `straight.el`
|
### Installing with `use-package` + `straight.el`
|
||||||
|
|
||||||
Add the call to use-package to your Emacs configuration:
|
Add the call to use-package to your Emacs configuration:
|
||||||
|
|
||||||
```lisp
|
```elisp
|
||||||
(use-package gdscript-mode
|
(use-package gdscript-mode
|
||||||
:straight (gdscript-mode
|
:straight (gdscript-mode
|
||||||
:type git
|
:type git
|
||||||
:host github
|
:host github
|
||||||
:repo "GDQuest/emacs-gdscript-mode"))
|
:repo "godotengine/emacs-gdscript-mode"))
|
||||||
```
|
```
|
||||||
|
|
||||||
### Installing manually
|
### Installing manually
|
||||||
|
|
||||||
1. Clone the repository or download a [stable release](https://github.com/GDQuest/emacs-gdscript-mode/releases) to your computer.
|
1. Clone the repository or download a [stable release](https://github.com/godotengine/emacs-gdscript-mode/releases) to your computer.
|
||||||
1. In your init.el file, add a call to load and require the package.
|
1. In your init.el file, add a call to load and require the package.
|
||||||
|
|
||||||
```lisp
|
```elisp
|
||||||
(add-to-list 'load-path "/path/to/gdscript-mode")
|
(add-to-list 'load-path "/path/to/gdscript-mode")
|
||||||
(require 'gdscript-mode)
|
(require 'gdscript-mode)
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## Auto-completion with the Language Server Protocol (LSP)
|
||||||
|
|
||||||
|
For auto-completion, we rely on either the [eglot](https://github.com/joaotavora/eglot) or [lsp-mode](https://emacs-lsp.github.io/lsp-mode/) packages, and the GDScript language server which is built into Godot.
|
||||||
|
|
||||||
|
To use the LSP with `eglot`, you need to install `eglot` on top of `gdscript-mode`, if using an Emacs version earlier than 29.
|
||||||
|
After installation, `eglot` can be connected on startup by adding `eglot-ensure` as a hook on `gdscript-mode-hook`.
|
||||||
|
|
||||||
|
Note that, due to language server changes made in Godot 4, usage with Godot 3 requires `gdscript-eglot-version` to be customized to 3.
|
||||||
|
|
||||||
|
An example configuration for Godot 3 usage with `use-package`:
|
||||||
|
|
||||||
|
```elisp
|
||||||
|
(use-package gdscript-mode
|
||||||
|
:hook (gdscript-mode . eglot-ensure)
|
||||||
|
:custom (gdscript-eglot-version 3))
|
||||||
|
```
|
||||||
|
|
||||||
|
To use the LSP with `lsp-mode`, you need to install `lsp-mode` on top of `gdscript-mode` and configure it. To install and configure `lsp-mode`, see the [lsp-mode documentation](https://emacs-lsp.github.io/lsp-mode/page/installation/).
|
||||||
|
|
||||||
|
### Known issues
|
||||||
|
|
||||||
|
There are some known issues with the GDScript language server in Godot 3.2 due to the server being a bit young and not following the specification strictly. This mainly causes some `unknown notification` errors in lsp-mode at the moment. You can suppress them by adding the following code to your Emacs configuration (thanks to Franco Garcia for sharing this workaround):
|
||||||
|
|
||||||
|
```elisp
|
||||||
|
(defun lsp--gdscript-ignore-errors (original-function &rest args)
|
||||||
|
"Ignore the error message resulting from Godot not replying to the `JSONRPC' request."
|
||||||
|
(if (string-equal major-mode "gdscript-mode")
|
||||||
|
(let ((json-data (nth 0 args)))
|
||||||
|
(if (and (string= (gethash "jsonrpc" json-data "") "2.0")
|
||||||
|
(not (gethash "id" json-data nil))
|
||||||
|
(not (gethash "method" json-data nil)))
|
||||||
|
nil ; (message "Method not found")
|
||||||
|
(apply original-function args)))
|
||||||
|
(apply original-function args)))
|
||||||
|
;; Runs the function `lsp--gdscript-ignore-errors` around `lsp--get-message-type` to suppress unknown notification errors.
|
||||||
|
(advice-add #'lsp--get-message-type :around #'lsp--gdscript-ignore-errors)
|
||||||
|
```
|
||||||
|
|
||||||
|
## Major mode with Treesit
|
||||||
|
|
||||||
|
[Treesit](https://github.com/tree-sitter/tree-sitter) is an incremental parsing system for programming tools.
|
||||||
|
|
||||||
|
This package has a major mode (gdscript-ts-mode). That supports the use tree-sitter for font-lock, imenu, indentation, and navigation of `gdscript` files.
|
||||||
|
|
||||||
|
Emacs version 29 or higher is required to use this mode.
|
||||||
|
|
||||||
|
### Install treesit
|
||||||
|
|
||||||
|
We need to install tree-sitter library, When under Arch Linux :
|
||||||
|
|
||||||
|
```sh
|
||||||
|
sudo pacman -S tree-sitter
|
||||||
|
```
|
||||||
|
|
||||||
|
### Install grammar
|
||||||
|
|
||||||
|
To support Gdscript, we must install [gdscript-grammar](https://github.com/PrestonKnopp/tree-sitter-gdscript.git):
|
||||||
|
|
||||||
|
```sh
|
||||||
|
git clone https://github.com/PrestonKnopp/tree-sitter-gdscript.git
|
||||||
|
cd tree-sitter-gdscript/src
|
||||||
|
cc -std=c99 -c parser.c
|
||||||
|
cc -c scanner.c -I./
|
||||||
|
cc -shared parser.o scanner.o -o libtree-sitter-gdscript.so
|
||||||
|
```
|
||||||
|
|
||||||
|
Additional directories to look for tree-sitter language definitions. ( DIR is your working path )
|
||||||
|
|
||||||
|
```emacs-lisp
|
||||||
|
(setq treesit-extra-load-path '("DIR/tree-sitter-gdscript/src/"))
|
||||||
|
```
|
||||||
|
enjoy.
|
||||||
|
|
||||||
## How to use
|
## How to use
|
||||||
|
|
||||||
### Opening the project in the editor
|
### Opening the project in the editor
|
||||||
|
|
||||||
You can open the project in the Godot editor with `M-x gdscript-godot-open-project-in-editor`, or open files and more in Godot with the `M-x gdscript-godot-*` commands.
|
You can open the Godot editor with `M-x gdscript-godot-open-project-in-editor`, or open files and more in Godot with the `M-x gdscript-godot-*` commands.
|
||||||
|
|
||||||
By default, these commands try to use an executable named `godot` on the system [PATH environment variable](<https://en.wikipedia.org/wiki/PATH_(variable)>).
|
By default, these commands try to use an executable named `godot` on the system [PATH environment variable](<https://en.wikipedia.org/wiki/PATH_(variable)>).
|
||||||
|
|
||||||
If you don't have `godot` available there, you can set a custom executable name or path to use instead:
|
If you don't have `godot` available there, you can set a custom executable name or path to use instead:
|
||||||
|
|
||||||
```lisp
|
```elisp
|
||||||
(setq gdscript-godot-executable "/path/to/godot")
|
(setq gdscript-godot-executable "/path/to/godot")
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -178,24 +269,20 @@ Here are the available options:
|
|||||||
3. `--debug-navigation`
|
3. `--debug-navigation`
|
||||||
4. `--debug-collisions --debug-navigation`
|
4. `--debug-collisions --debug-navigation`
|
||||||
|
|
||||||
The last selected option is saved for the next time you call `gdscript-godot-run-project-debug`. To remove debug options, you need to call the command with the universal argument again.
|
The last selected option is saved for the next time you call `gdscript-godot-run-project-debug`. To turn off debug options, you need to call the command with the universal argument again.
|
||||||
|
|
||||||
### Using Hydra
|
### Using Hydra
|
||||||
|
|
||||||
Running `gdscript-hydra-show` (<kbd>C-c r</kbd>) opens a [hydra](https://github.com/abo-abo/hydra) popup with options to open the editor or run the project, a scene, or a script, including with visual debug options.
|
Running `gdscript-hydra-show` (<kbd>C-c r</kbd>) opens a [hydra](https://github.com/abo-abo/hydra) popup with options to open the editor or run the project, a scene, or a script, including with visual debug options.
|
||||||
|
|
||||||
```
|

|
||||||
d ( ) Debug p run project t run script h run from history a format all q quit
|
|
||||||
e ( ) Editor s run scene r run last g switch to *godot* b format buffer
|
|
||||||
|
|
||||||
c [ ] Visible collisions shapes
|
_Hydra interactive menu to run the project and set debug options on the fly._
|
||||||
n [ ] Visible navigation
|
|
||||||
```
|
|
||||||
|
|
||||||
### Formatting code with gdformat
|
### Formatting code with gdformat
|
||||||
|
|
||||||
You can call the `gdscript-format` function to format the current buffer with
|
You can call the `gdscript-format` function to format the current buffer with
|
||||||
`gdformat`. Alternatively `gdscript-format-all` will reformat all gdscripts in
|
`gdformat`. Alternatively, `gdscript-format-all` will reformat all GDScript files in
|
||||||
the project. This feature requires the python package `gdtoolkit` to be installed
|
the project. This feature requires the python package `gdtoolkit` to be installed
|
||||||
and available on the system's PATH variable.
|
and available on the system's PATH variable.
|
||||||
|
|
||||||
@@ -208,7 +295,7 @@ pip3 install gdtoolkit
|
|||||||
|
|
||||||
### Browsing the Godot API with eww
|
### Browsing the Godot API with eww
|
||||||
|
|
||||||
With the point on a built-in class you can press `C-c C-b o` to open the code reference for that class in the text browser [eww](https://www.gnu.org/software/emacs/manual/html_node/emacs/EWW.html).
|
With the point on a built-in class, you can press `C-c C-b o` to open the code reference for that class in the text browser [eww](https://www.gnu.org/software/emacs/manual/html_node/emacs/EWW.html).
|
||||||
|
|
||||||
To open the main API reference page and browse it, press `C-c C-b a`.
|
To open the main API reference page and browse it, press `C-c C-b a`.
|
||||||
|
|
||||||
@@ -221,7 +308,7 @@ You can browse the API reference offline with `eww`. To do so:
|
|||||||
|
|
||||||
For example:
|
For example:
|
||||||
|
|
||||||
```lisp
|
```elisp
|
||||||
(setq gdscript-docs-local-path "/home/gdquest/Documents/docs/godot")
|
(setq gdscript-docs-local-path "/home/gdquest/Documents/docs/godot")
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -255,7 +342,7 @@ To find all GDScript-mode settings, press `M-x customize` and search for "gdscri
|
|||||||
|
|
||||||
Code example:
|
Code example:
|
||||||
|
|
||||||
```lisp
|
```elisp
|
||||||
(setq gdscript-use-tab-indents t) ;; If true, use tabs for indents. Default: t
|
(setq gdscript-use-tab-indents t) ;; If true, use tabs for indents. Default: t
|
||||||
(setq gdscript-indent-offset 4) ;; Controls the width of tab-based indents
|
(setq gdscript-indent-offset 4) ;; Controls the width of tab-based indents
|
||||||
(setq gdscript-godot-executable "/path/to/godot") ;; Use this executable instead of 'godot' to open the Godot editor.
|
(setq gdscript-godot-executable "/path/to/godot") ;; Use this executable instead of 'godot' to open the Godot editor.
|
||||||
@@ -264,13 +351,17 @@ Code example:
|
|||||||
|
|
||||||
## Using the debugger
|
## Using the debugger
|
||||||
|
|
||||||
Emacs GDScript mode includes support for the GDScript debugger. You can use breakpoints, use code stepping functions, see your nodes' state at runtime, and more.
|
Emacs GDScript mode includes support for the GDScript debugger.
|
||||||
|
|
||||||
|
*The debugger in this package is only for Godot 3. Godot 4 supports the Debugger Adapter Procol (DAP), which you can use with the [dap-mode](https://github.com/emacs-lsp/dap-mode) package.*
|
||||||
|
|
||||||
|
You can use the debugger tools to manage breakpoints, step through code, and more.
|
||||||
|
|
||||||
To get started with this feature, you need to add a least one breakpoint.
|
To get started with this feature, you need to add a least one breakpoint.
|
||||||
|
|
||||||
### Adding and removing breakpoints
|
### Adding and removing breakpoints
|
||||||
|
|
||||||
You can add a breakpoint on the current line with `gdscript-debug-add-breakpoint` (<kbd>C-c C-d b</kbd>). A red dot should appear in the left fringe. Use `gdscript-debug-remove-breakpoint` (<kbd>C-c C-d r</kbd>) to remove a breakpoint on the current line.
|
Like in Godot's editor, you can toggle a breakpoint on the current line with `gdscript-debug-toggle-breakpoint` (<kbd>F9</kbd>).
|
||||||
|
|
||||||
After adding at least one breakpoint to the project, a buffer named `* Breakpoints *` is created. This buffer displays all existing breakpoints in a project. In that buffer, pressing <kbd>D</kbd> on a breakpoint line deletes the breakpoint. Pressing <kbd>RET</kbd> opens the corresponding GDScript file in another buffer.
|
After adding at least one breakpoint to the project, a buffer named `* Breakpoints *` is created. This buffer displays all existing breakpoints in a project. In that buffer, pressing <kbd>D</kbd> on a breakpoint line deletes the breakpoint. Pressing <kbd>RET</kbd> opens the corresponding GDScript file in another buffer.
|
||||||
|
|
||||||
@@ -282,7 +373,7 @@ The debugger's server runs on `localhost` through port `6010` by default. You ca
|
|||||||
|
|
||||||
Once Godot hits a breakpoint, Emacs displays two new buffers:
|
Once Godot hits a breakpoint, Emacs displays two new buffers:
|
||||||
|
|
||||||
- `* Stack frame vars *` displays the locals, members, and globals variables for the current stack point. It show variable name, its type and its value.
|
- `* Stack frame vars *` displays the locals, members, and globals variables for the current stack point. It shows the variable name, its type, and its value.
|
||||||
- `* Inspector *` displays detailed information about the selected object. By default, it shows the properties of `self`.
|
- `* Inspector *` displays detailed information about the selected object. By default, it shows the properties of `self`.
|
||||||
|
|
||||||
You can inspect any object in those two buffers by pressing <kbd>RET</kbd> on the corresponding line.
|
You can inspect any object in those two buffers by pressing <kbd>RET</kbd> on the corresponding line.
|
||||||
@@ -323,7 +414,7 @@ o pin u unpin q quit
|
|||||||
|
|
||||||
### The `* Stack frame vars *` buffer
|
### The `* Stack frame vars *` buffer
|
||||||
|
|
||||||
The stack frame buffer displays the locals, members, and globals variables for the current stack point. Here are available keyboard shortcuts:
|
The stack frame buffer displays the locals, members, and global variables for the current stack point. Here are available keyboard shortcuts:
|
||||||
|
|
||||||
- <kbd>TAB</kbd> toggles multi-line display for selected types.
|
- <kbd>TAB</kbd> toggles multi-line display for selected types.
|
||||||
- <kbd>RET</kbd> on an object line to display its details in the `* Inspector *`buffer.
|
- <kbd>RET</kbd> on an object line to display its details in the `* Inspector *`buffer.
|
||||||
@@ -337,12 +428,12 @@ The stack frame buffer displays the locals, members, and globals variables for t
|
|||||||
|
|
||||||
### `* Inspector *` buffer
|
### `* Inspector *` buffer
|
||||||
|
|
||||||
Contains information about inspected object. By default `self` variable from `* Stack frame vars *` is displayed. Inspected object is kept to be focused until other object is inspected or until inspected object cease to exists, in which case current `self` is displayed instead.
|
Contains information about inspected object. By default `self` variable from `* Stack frame vars *` is displayed. The inspected object is kept in focus until you inspect another object or until the active object ceases to exists, in which case the current `self` is displayed instead.
|
||||||
|
|
||||||
- Press <kbd>TAB</kbd> to toggle multi-line display for selected typess.
|
- Press <kbd>TAB</kbd> to toggle multi-line display for selected typess.
|
||||||
- Press <kbd>RET</kbd> on object line to display its detailss.
|
- Press <kbd>RET</kbd> on object line to display its detailss.
|
||||||
- Press <kbd>RET</kbd> on `Node/path` line (second line from the top) to show given object in `* Scene Tree *` buffers.
|
- Press <kbd>RET</kbd> on `Node/path` line (second line from the top) to show given object in `* Scene Tree *` buffers.
|
||||||
- Press <kbd>l</kbd> deep in nested object to navigate one level up in the structure (ie. back). Pressing `l` while on top level object displays `* Stack frame vars *` buffers.
|
- Press <kbd>l</kbd> deep in nested object to navigate one level up in the structure (ie. back). Pressing `l` while on top-level object displays `* Stack frame vars *` buffers.
|
||||||
- Press <kbd>d</kbd> to display additional details for object variabless.
|
- Press <kbd>d</kbd> to display additional details for object variabless.
|
||||||
- Press <kbd>p</kbd> to go to the previous lines.
|
- Press <kbd>p</kbd> to go to the previous lines.
|
||||||
- Press <kbd>n</kbd> to go to the next lines.
|
- Press <kbd>n</kbd> to go to the next lines.
|
||||||
@@ -355,7 +446,7 @@ Contains information about inspected object. By default `self` variable from `*
|
|||||||
Contains stack dump information.
|
Contains stack dump information.
|
||||||
|
|
||||||
- Press <kbd>SPC</kbd> to jump to gdscript file where stack frame points to.
|
- Press <kbd>SPC</kbd> to jump to gdscript file where stack frame points to.
|
||||||
- Press <kbd>RET</kbd> to jump to gdscript file and to show `* Stack frame vars *`, `* Inspector *` buffers and a debug hydra.
|
- Press <kbd>RET</kbd> to jump to the gdscript file and show `* Stack frame vars *`, `* Inspector *` buffers, and a debug hydra.
|
||||||
- Press <kbd>l</kbd> to display the `* Stack frame vars *` buffer.
|
- Press <kbd>l</kbd> to display the `* Stack frame vars *` buffer.
|
||||||
- Press <kbd>p</kbd> to go to the previous line.
|
- Press <kbd>p</kbd> to go to the previous line.
|
||||||
- Press <kbd>n</kbd> to go to the next line.
|
- Press <kbd>n</kbd> to go to the next line.
|
||||||
|
|||||||
BIN
assets/emacs-gdscript-code-folding.png
Normal file
BIN
assets/emacs-gdscript-code-folding.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 23 KiB |
BIN
assets/emacs-gdscript-hydra.png
Normal file
BIN
assets/emacs-gdscript-hydra.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 15 KiB |
BIN
assets/emacs-gdscript-imenu.png
Normal file
BIN
assets/emacs-gdscript-imenu.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 87 KiB |
@@ -3,7 +3,7 @@
|
|||||||
;; Copyright (C) 2020 GDQuest and contributors
|
;; Copyright (C) 2020 GDQuest and contributors
|
||||||
;;
|
;;
|
||||||
;; Author: Josef Vlach <vlach.josef@gmail.com>
|
;; Author: Josef Vlach <vlach.josef@gmail.com>
|
||||||
;; URL: https://github.com/GDQuest/emacs-gdscript-mode/
|
;; URL: https://github.com/godotengine/emacs-gdscript-mode/
|
||||||
;; Version: 1.0.0
|
;; Version: 1.0.0
|
||||||
;; Package-Requires: ((emacs "26.3"))
|
;; Package-Requires: ((emacs "26.3"))
|
||||||
;; Maintainer: nathan@gdquest.com
|
;; Maintainer: nathan@gdquest.com
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
;; Copyright (C) 2020 GDQuest and contributors
|
;; Copyright (C) 2020 GDQuest and contributors
|
||||||
;;
|
;;
|
||||||
;; Author: Josef Vlach <vlach.josef@gmail.com>
|
;; Author: Josef Vlach <vlach.josef@gmail.com>
|
||||||
;; URL: https://github.com/GDQuest/emacs-gdscript-mode/
|
;; URL: https://github.com/godotengine/emacs-gdscript-mode/
|
||||||
;; Version: 1.0.0
|
;; Version: 1.0.0
|
||||||
;; Package-Requires: ((emacs "26.3"))
|
;; Package-Requires: ((emacs "26.3"))
|
||||||
;; Maintainer: nathan@gdquest.com
|
;; Maintainer: nathan@gdquest.com
|
||||||
@@ -58,8 +58,17 @@
|
|||||||
ARGUMENTS are command line arguments for godot executable.
|
ARGUMENTS are command line arguments for godot executable.
|
||||||
When run it will kill existing process if one exists."
|
When run it will kill existing process if one exists."
|
||||||
(let ((buffer-name (gdscript-util--get-godot-buffer-name (member "-e" arguments)))
|
(let ((buffer-name (gdscript-util--get-godot-buffer-name (member "-e" arguments)))
|
||||||
(inhibit-read-only t))
|
(inhibit-read-only t)
|
||||||
(if (not (or (file-executable-p gdscript-godot-executable) (executable-find gdscript-godot-executable)))
|
(godot-command gdscript-godot-executable))
|
||||||
|
|
||||||
|
;; support flatpak
|
||||||
|
(when (string-match-p (rx "run" (+ space) "org.godotengine.Godot") godot-command)
|
||||||
|
(let ((exec-split (split-string godot-command)))
|
||||||
|
(setq godot-command (car exec-split))
|
||||||
|
(setq arguments (append (cdr exec-split) arguments))))
|
||||||
|
|
||||||
|
(if (not (or (file-executable-p godot-command)
|
||||||
|
(executable-find godot-command)))
|
||||||
(error "Error: Could not execute '%s'. Please customize the `gdscript-godot-executable variable'" gdscript-godot-executable)
|
(error "Error: Could not execute '%s'. Please customize the `gdscript-godot-executable variable'" gdscript-godot-executable)
|
||||||
(with-current-buffer (get-buffer-create buffer-name)
|
(with-current-buffer (get-buffer-create buffer-name)
|
||||||
(when gdscript-gdformat-save-and-format
|
(when gdscript-gdformat-save-and-format
|
||||||
@@ -68,7 +77,7 @@ When run it will kill existing process if one exists."
|
|||||||
(godot-mode)
|
(godot-mode)
|
||||||
(buffer-disable-undo))
|
(buffer-disable-undo))
|
||||||
(erase-buffer)
|
(erase-buffer)
|
||||||
(comint-exec (current-buffer) buffer-name gdscript-godot-executable nil arguments)
|
(comint-exec (current-buffer) buffer-name godot-command nil arguments)
|
||||||
(set-process-sentinel (get-buffer-process (current-buffer)) 'gdscript-comint--sentinel)
|
(set-process-sentinel (get-buffer-process (current-buffer)) 'gdscript-comint--sentinel)
|
||||||
(pop-to-buffer (current-buffer))))))
|
(pop-to-buffer (current-buffer))))))
|
||||||
|
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
;; Copyright (C) 2020 GDQuest
|
;; Copyright (C) 2020 GDQuest
|
||||||
|
|
||||||
;; Author: Nathan Lovato <nathan@gdquest.com>, Fabián E. Gallina <fgallina@gnu.org>
|
;; Author: Nathan Lovato <nathan@gdquest.com>, Fabián E. Gallina <fgallina@gnu.org>
|
||||||
;; URL: https://github.com/GDQuest/emacs-gdscript-mode/
|
;; URL: https://github.com/godotengine/emacs-gdscript-mode/
|
||||||
;; Version: 0.1.0
|
;; Version: 0.1.0
|
||||||
;; Package-Requires: ((emacs "26.3"))
|
;; Package-Requires: ((emacs "26.3"))
|
||||||
;; Maintainer: nathan@gdquest.com
|
;; Maintainer: nathan@gdquest.com
|
||||||
@@ -63,23 +63,24 @@ first."
|
|||||||
(let ((has-projectile (featurep 'projectile)))
|
(let ((has-projectile (featurep 'projectile)))
|
||||||
(when has-projectile
|
(when has-projectile
|
||||||
(projectile-maybe-invalidate-cache arg))
|
(projectile-maybe-invalidate-cache arg))
|
||||||
(let* ((project-root
|
(when-let* ((project-root
|
||||||
(if has-projectile
|
(if has-projectile
|
||||||
(projectile-ensure-project (projectile-project-root))
|
(projectile-ensure-project (projectile-project-root))
|
||||||
(gdscript-util--find-project-configuration-file)))
|
(gdscript-util--find-project-configuration-file)))
|
||||||
(file
|
(file
|
||||||
(if has-projectile
|
(if has-projectile
|
||||||
(projectile-completing-read
|
(projectile-completing-read
|
||||||
"Find file: "
|
"Find file: "
|
||||||
(projectile-project-files project-root))
|
(projectile-project-files project-root))
|
||||||
(read-file-name
|
(read-file-name
|
||||||
"Find file: "
|
"Find file: "
|
||||||
project-root))))
|
project-root)))
|
||||||
(when file
|
(resource-path
|
||||||
(insert
|
(if has-projectile
|
||||||
(concat "\"res://"
|
file
|
||||||
(gdscript-util--get-godot-project-file-path-relative file)
|
(concat (gdscript-util--get-godot-project-file-path-relative file)
|
||||||
"." (file-name-extension file) "\""))))))
|
"." (file-name-extension file)))))
|
||||||
|
(insert (concat "\"res://" resource-path "\"")))))
|
||||||
|
|
||||||
|
|
||||||
(provide 'gdscript-completion)
|
(provide 'gdscript-completion)
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
;; Copyright (C) 2020 GDQuest
|
;; Copyright (C) 2020 GDQuest
|
||||||
|
|
||||||
;; Author: Nathan Lovato <nathan@gdquest.com>
|
;; Author: Nathan Lovato <nathan@gdquest.com>
|
||||||
;; URL: https://github.com/GDQuest/emacs-gdscript-mode/
|
;; URL: https://github.com/godotengine/emacs-gdscript-mode/
|
||||||
;; Version: 0.1.0
|
;; Version: 0.1.0
|
||||||
;; Package-Requires: ((emacs "26.3"))
|
;; Package-Requires: ((emacs "26.3"))
|
||||||
;; Maintainer: nathan@gdquest.com
|
;; Maintainer: nathan@gdquest.com
|
||||||
@@ -41,8 +41,8 @@
|
|||||||
|
|
||||||
(defcustom gdscript-use-type-hints t
|
(defcustom gdscript-use-type-hints t
|
||||||
"If t, inserted snippets contain type hints."
|
"If t, inserted snippets contain type hints."
|
||||||
:group 'gdscript
|
:type 'boolean
|
||||||
:type 'boolean)
|
:group 'gdscript)
|
||||||
|
|
||||||
;; gdscript-indent
|
;; gdscript-indent
|
||||||
(defcustom gdscript-use-tab-indents t "Use tabs (t) or spaces (nil)."
|
(defcustom gdscript-use-tab-indents t "Use tabs (t) or spaces (nil)."
|
||||||
@@ -54,30 +54,31 @@
|
|||||||
:group 'gdscript)
|
:group 'gdscript)
|
||||||
|
|
||||||
(defcustom gdscript-indent-offset 4 "Default indentation offset for Gdscript."
|
(defcustom gdscript-indent-offset 4 "Default indentation offset for Gdscript."
|
||||||
:group 'gdscript
|
|
||||||
:type 'integer
|
:type 'integer
|
||||||
:safe 'integerp)
|
:safe 'integerp
|
||||||
|
:group 'gdscript)
|
||||||
|
|
||||||
(defcustom gdscript-indent-trigger-commands '(indent-for-tab-command yas-expand yas/expand)
|
(defcustom gdscript-indent-trigger-commands '(indent-for-tab-command yas-expand yas/expand)
|
||||||
"Commands that might trigger a `gdscript-indent-line' call."
|
"Commands that might trigger a `gdscript-indent-line' call."
|
||||||
:type '(repeat symbol):group'gdscript)
|
:type '(repeat symbol)
|
||||||
|
:group'gdscript)
|
||||||
|
|
||||||
;; gdscript-fill-paragraph.el
|
;; gdscript-fill-paragraph.el
|
||||||
(defcustom gdscript-fill-comment-function 'gdscript-fill-paragraph-fill-comment
|
(defcustom gdscript-fill-comment-function 'gdscript-fill-paragraph-fill-comment
|
||||||
"Function to fill comments.
|
"Function to fill comments.
|
||||||
This is the function used by `gdscript-fill-paragraph' to
|
This is the function used by `gdscript-fill-paragraph' to
|
||||||
fill comments."
|
fill comments."
|
||||||
:type 'symbol
|
:type 'symbol
|
||||||
:group 'gdscript)
|
:group 'gdscript)
|
||||||
|
|
||||||
|
(defcustom gdscript-fill-string-function 'gdscript-fill-paragraph-fill-string
|
||||||
"Function to fill strings.
|
"Function to fill strings.
|
||||||
This is the function used by `gdscript-fill-paragraph' to
|
This is the function used by `gdscript-fill-paragraph' to
|
||||||
fill strings."
|
fill strings."
|
||||||
:type 'symbol
|
:type 'symbol
|
||||||
:group 'gdscript)
|
:group 'gdscript)
|
||||||
|
|
||||||
:group 'gdscript)
|
(defcustom gdscript-fill-paren-function 'gdscript-fill-paragraph-fill-paren
|
||||||
"Function to fill parens.
|
"Function to fill parens.
|
||||||
This is the function used by `gdscript-fill-paragraph' to
|
This is the function used by `gdscript-fill-paragraph' to
|
||||||
fill parens."
|
fill parens."
|
||||||
@@ -88,7 +89,15 @@ fill parens."
|
|||||||
"Multiplier applied to indentation inside multi-line def blocks."
|
"Multiplier applied to indentation inside multi-line def blocks."
|
||||||
:version "26.1"
|
:version "26.1"
|
||||||
:type 'integer
|
:type 'integer
|
||||||
"Multiplier applied to indentation inside multi-line def blocks."
|
:safe 'natnump
|
||||||
|
:group 'gdscript)
|
||||||
|
|
||||||
|
(defcustom gdscript-indent-line-continuation-scale 1
|
||||||
|
"Multiplier applied to indentation of line continuation in
|
||||||
|
general (inside parentheses and after backslash)."
|
||||||
|
:type 'integer
|
||||||
|
:options '(1 2)
|
||||||
|
:group 'gdscript)
|
||||||
|
|
||||||
(defcustom gdscript-godot-executable "godot"
|
(defcustom gdscript-godot-executable "godot"
|
||||||
"The godot executable which is either a full path such as '~/bin/godot2.2'
|
"The godot executable which is either a full path such as '~/bin/godot2.2'
|
||||||
@@ -116,12 +125,17 @@ so it is not slowing down Godot execution."
|
|||||||
:group 'gdscript)
|
:group 'gdscript)
|
||||||
|
|
||||||
(defcustom gdscript-docs-force-online-lookup nil
|
(defcustom gdscript-docs-force-online-lookup nil
|
||||||
:group 'gdscript)
|
"If true, calling commands like gdscript-docs-browse-api
|
||||||
|
browses the online API reference, even if a local copy is
|
||||||
|
available."
|
||||||
:type 'boolean
|
:type 'boolean
|
||||||
:group 'gdscript)
|
:group 'gdscript)
|
||||||
|
|
||||||
(defcustom gdscript-docs-use-eww t
|
(defcustom gdscript-docs-use-eww t
|
||||||
:group 'gdscript)
|
"If set to false use the emacs configurable `browse-url'
|
||||||
|
function rather than `eww' directly. `browse-url' can be
|
||||||
|
configured to open the desktop default GUI browser, for example,
|
||||||
|
via the variable `browse-url-browser-function'"
|
||||||
:type 'boolean
|
:type 'boolean
|
||||||
:group 'gdscript)
|
:group 'gdscript)
|
||||||
|
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
;; Copyright (C) 2020 GDQuest
|
;; Copyright (C) 2020 GDQuest
|
||||||
|
|
||||||
;; Author: Josef Vlach <vlach.josef@gmail.com>
|
;; Author: Josef Vlach <vlach.josef@gmail.com>
|
||||||
;; URL: https://github.com/GDQuest/emacs-gdscript-mode/
|
;; URL: https://github.com/godotengine/emacs-gdscript-mode/
|
||||||
;; Version: 0.0.1
|
;; Version: 0.0.1
|
||||||
;; Package-Requires: ((emacs "26.3"))
|
;; Package-Requires: ((emacs "26.3"))
|
||||||
;; Maintainer: vlach.josef@gmail.com
|
;; Maintainer: vlach.josef@gmail.com
|
||||||
@@ -1868,13 +1868,35 @@ calling `gdscript-debug--table-string'."
|
|||||||
(setq buffer-read-only t)
|
(setq buffer-read-only t)
|
||||||
(buffer-disable-undo))
|
(buffer-disable-undo))
|
||||||
|
|
||||||
(defun gdscript-debug-add-breakpoint ()
|
(defun gdscript-debug-toggle-breakpoint ()
|
||||||
|
"Add or remove a breakpoint on the line at POINT."
|
||||||
(interactive)
|
(interactive)
|
||||||
|
(let* ((breakpoint (gdscript-debug--construct-breakpoint-at-point)))
|
||||||
|
(if (gdscript-debug--is-existing-breakpoint-p breakpoint)
|
||||||
|
(gdscript-debug--remove-breakpoint breakpoint)
|
||||||
|
(gdscript-debug--add-breakpoint-to-line breakpoint))))
|
||||||
|
|
||||||
|
(defun gdscript-debug--construct-breakpoint-at-point ()
|
||||||
|
"Construct a breakpoint object for the line at POINT and return it.
|
||||||
|
May match an existing breakpoint."
|
||||||
(gdscript-debug--with-gdscript-file file-info
|
(gdscript-debug--with-gdscript-file file-info
|
||||||
(let* ((line (line-number-at-pos))
|
(let* ((start (line-beginning-position))
|
||||||
|
(end (line-end-position))
|
||||||
|
(line (line-number-at-pos))
|
||||||
(file (car file-info))
|
(file (car file-info))
|
||||||
(file-absolute (cdr file-info))
|
(file-absolute (cdr file-info))
|
||||||
(breakpoint (gdscript-breakpoint-create :file file :file-absolute file-absolute :line line)))
|
(breakpoint (gdscript-breakpoint-create :file file :file-absolute file-absolute :line line)))
|
||||||
|
breakpoint)))
|
||||||
|
|
||||||
|
(defun gdscript-debug--is-existing-breakpoint-p (breakpoint)
|
||||||
|
"Return t if `BREAKPOINT' is an existing breakpoint in the project."
|
||||||
|
(member breakpoint gdscript-debug--breakpoints))
|
||||||
|
|
||||||
|
(defun gdscript-debug--add-breakpoint-to-line (breakpoint)
|
||||||
|
"Register `BREAKPOINT' to the current line in a GDScript buffer."
|
||||||
|
(gdscript-debug--with-gdscript-file file-info
|
||||||
|
(let* ((line (line-number-at-pos))
|
||||||
|
(file (car file-info)))
|
||||||
(if (member breakpoint gdscript-debug--breakpoints)
|
(if (member breakpoint gdscript-debug--breakpoints)
|
||||||
(message "Breakpoint already present at %s:%s" file line)
|
(message "Breakpoint already present at %s:%s" file line)
|
||||||
(gdscript-debug--add-fringe (line-beginning-position) (not gdscript-debug--skip-breakpoints) 'gdb-bptno 1)
|
(gdscript-debug--add-fringe (line-beginning-position) (not gdscript-debug--skip-breakpoints) 'gdb-bptno 1)
|
||||||
@@ -1884,15 +1906,13 @@ calling `gdscript-debug--table-string'."
|
|||||||
(gdscript-debug--send-command
|
(gdscript-debug--send-command
|
||||||
(gdscript-debug--breakpoint-command file line t)))))))
|
(gdscript-debug--breakpoint-command file line t)))))))
|
||||||
|
|
||||||
(defun gdscript-debug-remove-breakpoint ()
|
(defun gdscript-debug--remove-breakpoint (breakpoint)
|
||||||
(interactive)
|
"Remove `BREAKPOINT' to the current line in a GDScript buffer."
|
||||||
(gdscript-debug--with-gdscript-file file-info
|
(gdscript-debug--with-gdscript-file file-info
|
||||||
(let* ((start (line-beginning-position))
|
(let* ((start (line-beginning-position))
|
||||||
(end (line-end-position))
|
(end (line-end-position))
|
||||||
(line (line-number-at-pos))
|
(line (line-number-at-pos))
|
||||||
(file (car file-info))
|
(file (car file-info)))
|
||||||
(file-absolute (cdr file-info))
|
|
||||||
(breakpoint (gdscript-breakpoint-create :file file :file-absolute file-absolute :line line)))
|
|
||||||
(if (not (member breakpoint gdscript-debug--breakpoints))
|
(if (not (member breakpoint gdscript-debug--breakpoints))
|
||||||
(message "No breakpoint at %s:%s" file line)
|
(message "No breakpoint at %s:%s" file line)
|
||||||
(gdscript-debug--remove-strings start end)
|
(gdscript-debug--remove-strings start end)
|
||||||
@@ -1920,7 +1940,9 @@ calling `gdscript-debug--table-string'."
|
|||||||
(prop `(left-fringe breakpoint ,(if (not enabled) 'breakpoint-enabled 'breakpoint-disabled))))
|
(prop `(left-fringe breakpoint ,(if (not enabled) 'breakpoint-enabled 'breakpoint-disabled))))
|
||||||
(put-text-property 0 1 'display prop string))))))))))))
|
(put-text-property 0 1 'display prop string))))))))))))
|
||||||
|
|
||||||
(defun gdscript-debug-toggle-breakpoint ()
|
(defun gdscript-debug-toggle-skip-breakpoints ()
|
||||||
|
"Toggle the execution of all breakpoints without removing them.
|
||||||
|
Like Godot's Skip Breakpoints button."
|
||||||
(interactive)
|
(interactive)
|
||||||
(setq gdscript-debug--skip-breakpoints (not gdscript-debug--skip-breakpoints))
|
(setq gdscript-debug--skip-breakpoints (not gdscript-debug--skip-breakpoints))
|
||||||
(gdscript-debug--set-left-fringe-breakpoints gdscript-debug--skip-breakpoints)
|
(gdscript-debug--set-left-fringe-breakpoints gdscript-debug--skip-breakpoints)
|
||||||
@@ -1937,7 +1959,7 @@ calling `gdscript-debug--table-string'."
|
|||||||
(with-current-buffer buffer
|
(with-current-buffer buffer
|
||||||
(goto-char (point-min))
|
(goto-char (point-min))
|
||||||
(forward-line (1- line))
|
(forward-line (1- line))
|
||||||
(gdscript-debug-remove-breakpoint)))))
|
(gdscript-debug--remove-breakpoint breakpoint)))))
|
||||||
(message "Not recognized as breakpoint line")))
|
(message "Not recognized as breakpoint line")))
|
||||||
|
|
||||||
(defun gdscript-debug-goto-breakpoint ()
|
(defun gdscript-debug-goto-breakpoint ()
|
||||||
@@ -2048,7 +2070,7 @@ calling `gdscript-debug--table-string'."
|
|||||||
(defvar gdscript-debug--breakpoints-mode-map
|
(defvar gdscript-debug--breakpoints-mode-map
|
||||||
(let ((map (make-sparse-keymap)))
|
(let ((map (make-sparse-keymap)))
|
||||||
(suppress-keymap map)
|
(suppress-keymap map)
|
||||||
(define-key map " " 'gdscript-debug-toggle-breakpoint)
|
(define-key map " " 'gdscript-debug-toggle-skip-breakpoints)
|
||||||
(define-key map "q" 'kill-current-buffer)
|
(define-key map "q" 'kill-current-buffer)
|
||||||
(define-key map "D" 'gdscript-debug-delete-breakpoint)
|
(define-key map "D" 'gdscript-debug-delete-breakpoint)
|
||||||
(define-key map "\r" 'gdscript-debug-goto-breakpoint)
|
(define-key map "\r" 'gdscript-debug-goto-breakpoint)
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
;; Copyright (C) 2020 GDQuest and contributors
|
;; Copyright (C) 2020 GDQuest and contributors
|
||||||
;;
|
;;
|
||||||
;; Author: Josef Vlach <vlach.josef@gmail.com>
|
;; Author: Josef Vlach <vlach.josef@gmail.com>
|
||||||
;; URL: https://github.com/GDQuest/emacs-gdscript-mode/
|
;; URL: https://github.com/godotengine/emacs-gdscript-mode/
|
||||||
;; Version: 1.0.0
|
;; Version: 1.0.0
|
||||||
;; Package-Requires: ((emacs "26.3"))
|
;; Package-Requires: ((emacs "26.3"))
|
||||||
;; Maintainer: nathan@gdquest.com
|
;; Maintainer: nathan@gdquest.com
|
||||||
@@ -34,7 +34,7 @@
|
|||||||
(require 'eww)
|
(require 'eww)
|
||||||
(require 'gdscript-customization)
|
(require 'gdscript-customization)
|
||||||
|
|
||||||
(defun gdscript-docs-open (url &optional)
|
(defun gdscript-docs-open (url &rest _)
|
||||||
"when `gdscript-docs-use-eww' is true use `eww' else use `browse-url'"
|
"when `gdscript-docs-use-eww' is true use `eww' else use `browse-url'"
|
||||||
(if gdscript-docs-use-eww
|
(if gdscript-docs-use-eww
|
||||||
(if (file-exists-p url) (eww-open-file url) (eww-browse-url url t))
|
(if (file-exists-p url) (eww-open-file url) (eww-browse-url url t))
|
||||||
@@ -44,7 +44,7 @@
|
|||||||
(defun gdscript-docs-browse-api (&optional force-online)
|
(defun gdscript-docs-browse-api (&optional force-online)
|
||||||
"Open the main page of Godot API. Use the universal prefix (C-u) to force browsing the online API."
|
"Open the main page of Godot API. Use the universal prefix (C-u) to force browsing the online API."
|
||||||
(interactive)
|
(interactive)
|
||||||
(if (and (or gdscript-docs-force-online-lookup current-prefix-arg force-online) (not (string= gdscript-docs-local-path "")))
|
(if (and (or gdscript-docs-force-online-lookup current-prefix-arg force-online) (string= gdscript-docs-local-path ""))
|
||||||
(gdscript-docs-open "https://docs.godotengine.org/en/stable/classes/index.html?#godot-api")
|
(gdscript-docs-open "https://docs.godotengine.org/en/stable/classes/index.html?#godot-api")
|
||||||
(let ((file (concat (file-name-as-directory gdscript-docs-local-path) "classes/index.html")))
|
(let ((file (concat (file-name-as-directory gdscript-docs-local-path) "classes/index.html")))
|
||||||
(if (file-exists-p file)
|
(if (file-exists-p file)
|
||||||
@@ -63,12 +63,12 @@ If a page is already open, switch to its buffer. Use local docs if gdscripts-doc
|
|||||||
(lambda (current-buffer)
|
(lambda (current-buffer)
|
||||||
(with-current-buffer current-buffer
|
(with-current-buffer current-buffer
|
||||||
(when (derived-mode-p 'eww-mode)
|
(when (derived-mode-p 'eww-mode)
|
||||||
(string-suffix-p symbol(string-remove-suffix ".html" (plist-get eww-data :url)) t)
|
(string-suffix-p symbol (string-remove-suffix ".html" (plist-get eww-data :url)) t))))
|
||||||
))) (buffer-list)))))
|
(buffer-list)))))
|
||||||
(if buffer (pop-to-buffer-same-window buffer)
|
(if buffer (pop-to-buffer-same-window buffer)
|
||||||
(if (string= "" symbol)
|
(if (string= "" symbol)
|
||||||
(message "No symbol at point or open API reference buffers.")
|
(message "No symbol at point or open API reference buffers.")
|
||||||
(if (and (not gdscript-docs-force-online-lookup)(not (or current-prefix-arg force-online)) (not (string= gdscript-docs-local-path "")))
|
(if (and (not gdscript-docs-force-online-lookup) (not (or current-prefix-arg force-online)) (not (string= gdscript-docs-local-path "")))
|
||||||
(let ((file (concat (file-name-as-directory gdscript-docs-local-path) (file-name-as-directory "classes") "class_" symbol ".html")))
|
(let ((file (concat (file-name-as-directory gdscript-docs-local-path) (file-name-as-directory "classes") "class_" symbol ".html")))
|
||||||
(if (file-exists-p file)
|
(if (file-exists-p file)
|
||||||
(gdscript-docs-open file)
|
(gdscript-docs-open file)
|
||||||
|
|||||||
95
gdscript-eglot.el
Normal file
95
gdscript-eglot.el
Normal file
@@ -0,0 +1,95 @@
|
|||||||
|
;;; gdscript-eglot.el --- Integration with eglot -*- lexical-binding: t; -*-
|
||||||
|
;;
|
||||||
|
;; Copyright (C) 2023 GDQuest and contributors
|
||||||
|
;;
|
||||||
|
;; Author: Ruijie Yu <ruijie@netyu.xyz>
|
||||||
|
;; URL: https://github.com/godotengine/emacs-gdscript-mode/
|
||||||
|
;; Version: 1.0.0
|
||||||
|
;; Package-Requires: ((emacs "26.3"))
|
||||||
|
;; Maintainer: nathan@gdquest.com
|
||||||
|
;; Created: June 2020
|
||||||
|
;; Keywords: languages
|
||||||
|
;;
|
||||||
|
;; This file is not part of GNU Emacs.
|
||||||
|
;;
|
||||||
|
;; This program is free software; you can redistribute it and/or modify
|
||||||
|
;; it under the terms of the GNU General Public License as published by
|
||||||
|
;; the Free Software Foundation, either version 3 of the License, or
|
||||||
|
;; (at your option) any later version.
|
||||||
|
|
||||||
|
;; This program is distributed in the hope that it will be useful,
|
||||||
|
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
;; GNU General Public License for more details.
|
||||||
|
|
||||||
|
;; You should have received a copy of the GNU General Public License
|
||||||
|
;; along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
;;
|
||||||
|
;;; Commentary:
|
||||||
|
;;
|
||||||
|
;; Handles the configuraiton of eglot.
|
||||||
|
;; This supports `gdscript-mode' using `eglot'.
|
||||||
|
;;
|
||||||
|
;;; Code:
|
||||||
|
|
||||||
|
;;;###autoload
|
||||||
|
(defgroup gdscript-eglot nil
|
||||||
|
"Configurations in gdscript related to `eglot'."
|
||||||
|
:group 'gdscript)
|
||||||
|
|
||||||
|
;;;###autoload
|
||||||
|
(defcustom gdscript-eglot-version "4.5"
|
||||||
|
"The version of godot in use."
|
||||||
|
:type 'string)
|
||||||
|
|
||||||
|
;;;###autoload
|
||||||
|
(defcustom gdscript-eglot-default-lsp-port 6005
|
||||||
|
"The default port for eglot to connect when extraction fails."
|
||||||
|
:type 'integer
|
||||||
|
:group 'gdscript-eglot)
|
||||||
|
|
||||||
|
(defun gdscript-eglot--get-config-dir ()
|
||||||
|
"Get system-specific directory with Godot configuration files."
|
||||||
|
(pcase system-type
|
||||||
|
('darwin (expand-file-name "~/Library/Application Support/Godot/"))
|
||||||
|
('windows-nt (file-name-concat (getenv "APPDATA") "Godot"))
|
||||||
|
('gnu/linux (file-name-concat
|
||||||
|
(or (getenv "XDG_CONFIG_HOME") (expand-file-name "~/.config"))
|
||||||
|
"godot"))))
|
||||||
|
|
||||||
|
(defun gdscript-eglot--extract-port (editor-settings-file)
|
||||||
|
"Extract LSP port from Godot EDITOR-SETTINGS-FILE.
|
||||||
|
If extraction fails, return `gdscript-eglot-default-port'.
|
||||||
|
NOTE: remote_port value only presents if it has been modified from the default value,
|
||||||
|
So this extract shall fail by default."
|
||||||
|
(or
|
||||||
|
(when (file-exists-p editor-settings-file)
|
||||||
|
(with-temp-buffer
|
||||||
|
(insert-file-contents editor-settings-file)
|
||||||
|
(when (re-search-forward
|
||||||
|
(rx "network/language_server/remote_port"
|
||||||
|
(* space) ?= (* space)
|
||||||
|
(group (+ digit)))
|
||||||
|
nil t)
|
||||||
|
(string-to-number (match-string 1)))))
|
||||||
|
gdscript-eglot-default-lsp-port))
|
||||||
|
|
||||||
|
;;;###autoload
|
||||||
|
(defun gdscript-eglot-contact (_interactive)
|
||||||
|
"Attempt to help `eglot' contact the running gdscript LSP.
|
||||||
|
Returns a list (HOST PORT) if successful, nil otherwise. See the
|
||||||
|
last definition of CONTACT in `eglot-server-programs' for
|
||||||
|
definitions of HOST, PORT, and INTERACTIVE.
|
||||||
|
|
||||||
|
For more context, see
|
||||||
|
https://lists.gnu.org/archive/html/bug-gnu-emacs/2023-04/msg01070.html."
|
||||||
|
(save-excursion
|
||||||
|
(let* ((config-dir (gdscript-eglot--get-config-dir))
|
||||||
|
(settings-file (file-name-concat
|
||||||
|
config-dir
|
||||||
|
(format "editor_settings-%s.tres" gdscript-eglot-version))))
|
||||||
|
(when-let* ((port (gdscript-eglot--extract-port settings-file)))
|
||||||
|
(list "localhost" port)))))
|
||||||
|
|
||||||
|
(provide 'gdscript-eglot)
|
||||||
|
;;; gdscript-eglot.el ends here.
|
||||||
@@ -3,7 +3,7 @@
|
|||||||
;; Copyright (C) 2020 GDQuest
|
;; Copyright (C) 2020 GDQuest
|
||||||
|
|
||||||
;; Author: Nathan Lovato <nathan@gdquest.com>
|
;; Author: Nathan Lovato <nathan@gdquest.com>
|
||||||
;; URL: https://github.com/GDQuest/emacs-gdscript-mode/
|
;; URL: https://github.com/godotengine/emacs-gdscript-mode/
|
||||||
;; Version: 0.1.0
|
;; Version: 0.1.0
|
||||||
;; Package-Requires: ((emacs "26.3"))
|
;; Package-Requires: ((emacs "26.3"))
|
||||||
;; Maintainer: nathan@gdquest.com
|
;; Maintainer: nathan@gdquest.com
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
;; Copyright (C) 2020 GDQuest, Pawel Lampe
|
;; Copyright (C) 2020 GDQuest, Pawel Lampe
|
||||||
|
|
||||||
;; Author: Pawel Lampe <pawel.lampe@gmail.com>, Nathan Lovato <nathan@gdquest.com>
|
;; Author: Pawel Lampe <pawel.lampe@gmail.com>, Nathan Lovato <nathan@gdquest.com>
|
||||||
;; URL: https://github.com/GDQuest/emacs-gdscript-mode/
|
;; URL: https://github.com/godotengine/emacs-gdscript-mode/
|
||||||
;; Version: 1.0.0
|
;; Version: 1.0.0
|
||||||
;; Package-Requires: ((emacs "26.3"))
|
;; Package-Requires: ((emacs "26.3"))
|
||||||
;; Maintainer: nathan@gdquest.com
|
;; Maintainer: nathan@gdquest.com
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
;; Copyright (C) 2020 GDQuest and contributors
|
;; Copyright (C) 2020 GDQuest and contributors
|
||||||
;;
|
;;
|
||||||
;; Author: Franco Eusébio Garcia <francoegarcia@outlook.com>, Nathan Lovato <nathan@gdquest.com>
|
;; Author: Franco Eusébio Garcia <francoegarcia@outlook.com>, Nathan Lovato <nathan@gdquest.com>
|
||||||
;; URL: https://github.com/GDQuest/emacs-gdscript-mode/
|
;; URL: https://github.com/godotengine/emacs-gdscript-mode/
|
||||||
;; Version: 1.0.0
|
;; Version: 1.0.0
|
||||||
;; Package-Requires: ((emacs "26.3"))
|
;; Package-Requires: ((emacs "26.3"))
|
||||||
;; Maintainer: nathan@gdquest.com
|
;; Maintainer: nathan@gdquest.com
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
;; Copyright (C) 2020 GDQuest and contributors
|
;; Copyright (C) 2020 GDQuest and contributors
|
||||||
;;
|
;;
|
||||||
;; Author: Josef Vlach <vlach.josef@gmail.com>
|
;; Author: Josef Vlach <vlach.josef@gmail.com>
|
||||||
;; URL: https://github.com/GDQuest/emacs-gdscript-mode/
|
;; URL: https://github.com/godotengine/emacs-gdscript-mode/
|
||||||
;; Version: 1.0.0
|
;; Version: 1.0.0
|
||||||
;; Package-Requires: ((emacs "26.3"))
|
;; Package-Requires: ((emacs "26.3"))
|
||||||
;; Maintainer: nathan@gdquest.com
|
;; Maintainer: nathan@gdquest.com
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
;; Copyright (C) 2020 GDQuest and contributors
|
;; Copyright (C) 2020 GDQuest and contributors
|
||||||
;;
|
;;
|
||||||
;; Author: Josef Vlach <vlach.josef@gmail.com>
|
;; Author: Josef Vlach <vlach.josef@gmail.com>
|
||||||
;; URL: https://github.com/GDQuest/emacs-gdscript-mode/
|
;; URL: https://github.com/godotengine/emacs-gdscript-mode/
|
||||||
;; Version: 1.0.0
|
;; Version: 1.0.0
|
||||||
;; Package-Requires: ((emacs "26.3"))
|
;; Package-Requires: ((emacs "26.3"))
|
||||||
;; Maintainer: nathan@gdquest.com
|
;; Maintainer: nathan@gdquest.com
|
||||||
@@ -47,11 +47,15 @@
|
|||||||
(defvar gdscript-hydra--editor nil)
|
(defvar gdscript-hydra--editor nil)
|
||||||
(defvar gdscript-hydra--debug-collisions nil)
|
(defvar gdscript-hydra--debug-collisions nil)
|
||||||
(defvar gdscript-hydra--debug-navigation nil)
|
(defvar gdscript-hydra--debug-navigation nil)
|
||||||
|
(defvar gdscript-hydra--hydra nil)
|
||||||
|
|
||||||
(defun gdscript-hydra-show ()
|
(defun gdscript-hydra-show ()
|
||||||
"Show gdcript hydra."
|
"Show gdcript hydra."
|
||||||
(interactive)
|
(interactive)
|
||||||
(gdscript-util--with-available-hydra (gdscript-hydra--menu/body)))
|
(gdscript-util--with-available-hydra
|
||||||
|
(unless gdscript-hydra--hydra
|
||||||
|
(setq gdscript-hydra--hydra (gdscript-hydra--create)))
|
||||||
|
(funcall gdscript-hydra--hydra)))
|
||||||
|
|
||||||
(defun gdscript-hydra--selected (selected)
|
(defun gdscript-hydra--selected (selected)
|
||||||
"Visual representation for (non)SELECTED checkboxes."
|
"Visual representation for (non)SELECTED checkboxes."
|
||||||
@@ -110,11 +114,10 @@ on hydra checkboxes."
|
|||||||
"Choose command to run from history of commands."
|
"Choose command to run from history of commands."
|
||||||
(gdscript-godot--run-command (gdscript-history--select-from-history)))
|
(gdscript-godot--run-command (gdscript-history--select-from-history)))
|
||||||
|
|
||||||
(ignore-errors
|
(defun gdscript-hydra--create ()
|
||||||
;; Don't signal an error when hydra.el is not present
|
|
||||||
(defhydra gdscript-hydra--menu (:hint none
|
(defhydra gdscript-hydra--menu (:hint none
|
||||||
:body-pre (setq gdscript-hydra--open t)
|
:body-pre (setq gdscript-hydra--open t)
|
||||||
:before-exit (setq gdscript-hydra--open nil))
|
:before-exit (setq gdscript-hydra--open nil))
|
||||||
"
|
"
|
||||||
_d_ (?d?) Debug _p_ run project _t_ run script _h_ run from history _a_ format all _q_ quit
|
_d_ (?d?) Debug _p_ run project _t_ run script _h_ run from history _a_ format all _q_ quit
|
||||||
_e_ (?e?) Editor _s_ run scene _r_ run last _g_ switch to *godot* _b_ format buffer
|
_e_ (?e?) Editor _s_ run scene _r_ run last _g_ switch to *godot* _b_ format buffer
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
;; Copyright (C) 2020 GDQuest
|
;; Copyright (C) 2020 GDQuest
|
||||||
|
|
||||||
;; Author: Nathan Lovato <nathan@gdquest.com>, Fabián E. Gallina <fgallina@gnu.org>
|
;; Author: Nathan Lovato <nathan@gdquest.com>, Fabián E. Gallina <fgallina@gnu.org>
|
||||||
;; URL: https://github.com/GDQuest/emacs-gdscript-mode/
|
;; URL: https://github.com/godotengine/emacs-gdscript-mode/
|
||||||
;; Version: 1.0.0
|
;; Version: 1.0.0
|
||||||
;; Package-Requires: ((emacs "26.3"))
|
;; Package-Requires: ((emacs "26.3"))
|
||||||
;; Maintainer: nathan@gdquest.com
|
;; Maintainer: nathan@gdquest.com
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
;; Copyright (C) 2020 GDQuest
|
;; Copyright (C) 2020 GDQuest
|
||||||
|
|
||||||
;; Author: Nathan Lovato <nathan@gdquest.com>, Fabián E. Gallina <fgallina@gnu.org>
|
;; Author: Nathan Lovato <nathan@gdquest.com>, Fabián E. Gallina <fgallina@gnu.org>
|
||||||
;; URL: https://github.com/GDQuest/emacs-gdscript-mode/
|
;; URL: https://github.com/godotengine/emacs-gdscript-mode/
|
||||||
;; Version: 1.0.0
|
;; Version: 1.0.0
|
||||||
;; Package-Requires: ((emacs "26.3"))
|
;; Package-Requires: ((emacs "26.3"))
|
||||||
;; Maintainer: nathan@gdquest.com
|
;; Maintainer: nathan@gdquest.com
|
||||||
@@ -273,17 +273,19 @@ possibilities can be narrowed to specific indentation points."
|
|||||||
(current-column)))
|
(current-column)))
|
||||||
(`(,(or :after-block-start
|
(`(,(or :after-block-start
|
||||||
:after-backslash-first-line
|
:after-backslash-first-line
|
||||||
:after-backslash-assignment-continuation
|
|
||||||
:inside-paren-newline-start) . ,start)
|
:inside-paren-newline-start) . ,start)
|
||||||
;; Add one indentation level.
|
;; Add one indentation level.
|
||||||
(goto-char start)
|
(goto-char start)
|
||||||
(+ (current-indentation) gdscript-indent-offset))
|
(+ (current-indentation) gdscript-indent-offset))
|
||||||
(`(,(or :inside-paren
|
(`(,(or :inside-paren
|
||||||
:after-backslash-block-continuation
|
:after-backslash-block-continuation
|
||||||
:after-backslash-dotted-continuation) . ,start)
|
:after-backslash-dotted-continuation
|
||||||
;; Use the column given by the context.
|
:after-backslash-assignment-continuation) . ,start)
|
||||||
|
;; Use (possibly extra) indentation given by the configuration
|
||||||
(goto-char start)
|
(goto-char start)
|
||||||
(current-column))
|
(+ (current-indentation)
|
||||||
|
(* gdscript-indent-offset
|
||||||
|
gdscript-indent-line-continuation-scale)))
|
||||||
(`(:after-block-end . ,start)
|
(`(:after-block-end . ,start)
|
||||||
;; Subtract one indentation level.
|
;; Subtract one indentation level.
|
||||||
(goto-char start)
|
(goto-char start)
|
||||||
@@ -345,11 +347,7 @@ to the maximum available level. When indentation is the minimum
|
|||||||
possible and PREVIOUS is non-nil, cycle back to the maximum
|
possible and PREVIOUS is non-nil, cycle back to the maximum
|
||||||
level."
|
level."
|
||||||
(let ((follow-indentation-p
|
(let ((follow-indentation-p
|
||||||
;; Check if point is within indentation.
|
(<= (current-column) (current-indentation))))
|
||||||
(and (<= (line-beginning-position) (point))
|
|
||||||
(>= (+ (line-beginning-position)
|
|
||||||
(current-indentation))
|
|
||||||
(point)))))
|
|
||||||
(save-excursion
|
(save-excursion
|
||||||
(indent-line-to
|
(indent-line-to
|
||||||
(gdscript-indent-calculate-indentation previous))
|
(gdscript-indent-calculate-indentation previous))
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
;; Copyright (C) 2020 GDQuest
|
;; Copyright (C) 2020 GDQuest
|
||||||
|
|
||||||
;; Author: Nathan Lovato <nathan@gdquest.com>
|
;; Author: Nathan Lovato <nathan@gdquest.com>
|
||||||
;; URL: https://github.com/GDQuest/emacs-gdscript-mode/
|
;; URL: https://github.com/godotengine/emacs-gdscript-mode/
|
||||||
;; Version: 0.1.0
|
;; Version: 0.1.0
|
||||||
;; Package-Requires: ((emacs "26.3"))
|
;; Package-Requires: ((emacs "26.3"))
|
||||||
;; Maintainer: nathan@gdquest.com
|
;; Maintainer: nathan@gdquest.com
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
;; Copyright (C) 2020 GDQuest
|
;; Copyright (C) 2020 GDQuest
|
||||||
|
|
||||||
;; Author: Nathan Lovato <nathan@gdquest.com>, Fabián E. Gallina <fgallina@gnu.org>
|
;; Author: Nathan Lovato <nathan@gdquest.com>, Fabián E. Gallina <fgallina@gnu.org>
|
||||||
;; URL: https://github.com/GDQuest/emacs-gdscript-mode/
|
;; URL: https://github.com/godotengine/emacs-gdscript-mode/
|
||||||
;; Version: 0.1.0
|
;; Version: 0.1.0
|
||||||
;; Package-Requires: ((emacs "26.3"))
|
;; Package-Requires: ((emacs "26.3"))
|
||||||
;; Maintainer: nathan@gdquest.com
|
;; Maintainer: nathan@gdquest.com
|
||||||
@@ -26,7 +26,7 @@
|
|||||||
;;; Commentary:
|
;;; Commentary:
|
||||||
|
|
||||||
;; Adds support for the GDScript programming language from the Godot game
|
;; Adds support for the GDScript programming language from the Godot game
|
||||||
;; engine. This is a domain-specific language dedicated to game programming.
|
;; engine. This is a domain-specific language dedicated to game programming.
|
||||||
|
|
||||||
;;; Code:
|
;;; Code:
|
||||||
|
|
||||||
@@ -42,6 +42,10 @@
|
|||||||
(require 'gdscript-godot)
|
(require 'gdscript-godot)
|
||||||
(require 'gdscript-hydra)
|
(require 'gdscript-hydra)
|
||||||
(require 'gdscript-debug)
|
(require 'gdscript-debug)
|
||||||
|
(require 'gdscript-eglot)
|
||||||
|
|
||||||
|
(when (version< "29" emacs-version)
|
||||||
|
(require 'gdscript-ts-mode))
|
||||||
|
|
||||||
;;;###autoload
|
;;;###autoload
|
||||||
(add-to-list 'auto-mode-alist '("\\.gd\\'" . gdscript-mode))
|
(add-to-list 'auto-mode-alist '("\\.gd\\'" . gdscript-mode))
|
||||||
@@ -49,6 +53,13 @@
|
|||||||
(add-to-list 'auto-mode-alist '("\\.tscn\\'" . conf-toml-mode))
|
(add-to-list 'auto-mode-alist '("\\.tscn\\'" . conf-toml-mode))
|
||||||
;;;###autoload
|
;;;###autoload
|
||||||
(add-to-list 'auto-mode-alist '("\\.tres\\'" . conf-toml-mode))
|
(add-to-list 'auto-mode-alist '("\\.tres\\'" . conf-toml-mode))
|
||||||
|
;;;###autoload
|
||||||
|
(with-eval-after-load 'eglot
|
||||||
|
(defvar eglot-server-programs)
|
||||||
|
(unless (equal (alist-get 'gdscript-mode eglot-server-programs)
|
||||||
|
#'gdscript-eglot-contact)
|
||||||
|
(push (cons 'gdscript-mode #'gdscript-eglot-contact)
|
||||||
|
eglot-server-programs)))
|
||||||
|
|
||||||
(defvar gdscript-mode-map (let ((map (make-sparse-keymap)))
|
(defvar gdscript-mode-map (let ((map (make-sparse-keymap)))
|
||||||
;; Movement
|
;; Movement
|
||||||
@@ -69,8 +80,10 @@
|
|||||||
;; Run in Godot.
|
;; Run in Godot.
|
||||||
(define-key map (kbd "C-c C-r p") 'gdscript-godot-open-project-in-editor)
|
(define-key map (kbd "C-c C-r p") 'gdscript-godot-open-project-in-editor)
|
||||||
(define-key map (kbd "C-c C-r r") 'gdscript-godot-run-project)
|
(define-key map (kbd "C-c C-r r") 'gdscript-godot-run-project)
|
||||||
|
(define-key map (kbd "<f5>") 'gdscript-godot-run-project)
|
||||||
(define-key map (kbd "C-c C-r d") 'gdscript-godot-run-project-debug)
|
(define-key map (kbd "C-c C-r d") 'gdscript-godot-run-project-debug)
|
||||||
(define-key map (kbd "C-c C-r s") 'gdscript-godot-run-current-scene)
|
(define-key map (kbd "C-c C-r s") 'gdscript-godot-run-current-scene)
|
||||||
|
(define-key map (kbd "<f6>") 'gdscript-godot-run-current-scene)
|
||||||
(define-key map (kbd "C-c C-r q") 'gdscript-godot-run-current-scene-debug)
|
(define-key map (kbd "C-c C-r q") 'gdscript-godot-run-current-scene-debug)
|
||||||
(define-key map (kbd "C-c C-r e") 'gdscript-godot-edit-current-scene)
|
(define-key map (kbd "C-c C-r e") 'gdscript-godot-edit-current-scene)
|
||||||
(define-key map (kbd "C-c C-r x") 'gdscript-godot-run-current-script)
|
(define-key map (kbd "C-c C-r x") 'gdscript-godot-run-current-script)
|
||||||
@@ -85,11 +98,11 @@
|
|||||||
(define-key map (kbd "C-c C-d C-d d") 'gdscript-debug-display-stack-dump-buffer)
|
(define-key map (kbd "C-c C-d C-d d") 'gdscript-debug-display-stack-dump-buffer)
|
||||||
(define-key map (kbd "C-c C-d C-d b") 'gdscript-debug-display-breakpoint-buffer)
|
(define-key map (kbd "C-c C-d C-d b") 'gdscript-debug-display-breakpoint-buffer)
|
||||||
(define-key map (kbd "C-c C-d C-d i") 'gdscript-debug-display-inspector-buffer)
|
(define-key map (kbd "C-c C-d C-d i") 'gdscript-debug-display-inspector-buffer)
|
||||||
(define-key map (kbd "C-c C-d b") 'gdscript-debug-add-breakpoint)
|
(define-key map (kbd "<f9>") 'gdscript-debug-toggle-breakpoint)
|
||||||
(define-key map (kbd "C-c C-d r") 'gdscript-debug-remove-breakpoint)
|
|
||||||
(define-key map (kbd "C-c C-d q") 'gdscript-debug-make-server)
|
(define-key map (kbd "C-c C-d q") 'gdscript-debug-make-server)
|
||||||
(define-key map (kbd "C-c C-d n") 'gdscript-debug-next)
|
(define-key map (kbd "C-c C-d n") 'gdscript-debug-next)
|
||||||
(define-key map (kbd "C-c C-d c") 'gdscript-debug-continue)
|
(define-key map (kbd "C-c C-d c") 'gdscript-debug-continue)
|
||||||
|
(define-key map (kbd "<f7>") 'gdscript-debug-continue)
|
||||||
(define-key map (kbd "C-c C-d s") 'gdscript-debug-step)
|
(define-key map (kbd "C-c C-d s") 'gdscript-debug-step)
|
||||||
;; Debugger Hydra
|
;; Debugger Hydra
|
||||||
(define-key map (kbd "C-c n") 'gdscript-debug-hydra)
|
(define-key map (kbd "C-c n") 'gdscript-debug-hydra)
|
||||||
@@ -119,6 +132,22 @@ the last command event was a string delimiter."
|
|||||||
(save-excursion
|
(save-excursion
|
||||||
(insert (make-string 2 last-command-event)))))
|
(insert (make-string 2 last-command-event)))))
|
||||||
|
|
||||||
|
(defun gdscript-mark-defun ()
|
||||||
|
"GDScript-specific version of `mark-defun'.
|
||||||
|
|
||||||
|
Put mark at end of this defun, point at beginning.
|
||||||
|
The defun marked is the one that contains point or follows point.
|
||||||
|
|
||||||
|
If the mark is active, it marks the next defun after the one
|
||||||
|
already marked."
|
||||||
|
(interactive)
|
||||||
|
(if (use-region-p)
|
||||||
|
(gdscript-nav-forward-defun)
|
||||||
|
(save-excursion
|
||||||
|
(gdscript-nav-backward-defun)
|
||||||
|
(set-mark (point))))
|
||||||
|
(gdscript-nav-end-of-defun))
|
||||||
|
|
||||||
;;;###autoload
|
;;;###autoload
|
||||||
(define-derived-mode gdscript-mode prog-mode "gdscript"
|
(define-derived-mode gdscript-mode prog-mode "gdscript"
|
||||||
"Major mode for editing Godot GDScript files."
|
"Major mode for editing Godot GDScript files."
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
;; Copyright (C) 2020 GDQuest and contributors
|
;; Copyright (C) 2020 GDQuest and contributors
|
||||||
;;
|
;;
|
||||||
;; Author: Josef Vlach <vlach.josef@gmail.com>
|
;; Author: Josef Vlach <vlach.josef@gmail.com>
|
||||||
;; URL: https://github.com/GDQuest/emacs-gdscript-mode/
|
;; URL: https://github.com/godotengine/emacs-gdscript-mode/
|
||||||
;; Version: 1.0.0
|
;; Version: 1.0.0
|
||||||
;; Package-Requires: ((emacs "26.3"))
|
;; Package-Requires: ((emacs "26.3"))
|
||||||
;; Maintainer: nathan@gdquest.com
|
;; Maintainer: nathan@gdquest.com
|
||||||
@@ -33,8 +33,6 @@
|
|||||||
|
|
||||||
(require 'gdscript-utils)
|
(require 'gdscript-utils)
|
||||||
|
|
||||||
(defvar gdscript-project--script-list nil)
|
|
||||||
|
|
||||||
(defun gdscript-project--current-buffer-scene ()
|
(defun gdscript-project--current-buffer-scene ()
|
||||||
"Return the name of current scene.
|
"Return the name of current scene.
|
||||||
|
|
||||||
@@ -64,51 +62,32 @@ If current buffer is not visiting script file return nil."
|
|||||||
(when (re-search-forward "^extends SceneTree\\|^extends MainLoop" nil t)
|
(when (re-search-forward "^extends SceneTree\\|^extends MainLoop" nil t)
|
||||||
(file-relative-name buffer-file-name (gdscript-util--find-project-configuration-file))))))
|
(file-relative-name buffer-file-name (gdscript-util--find-project-configuration-file))))))
|
||||||
|
|
||||||
(defun gdscript-project--select-script ()
|
(defun gdscript-project--select-script (script-list)
|
||||||
"Find all script files and let user choose one."
|
"Find all script files and let user choose one."
|
||||||
(let ((hydra-open gdscript-hydra--open))
|
(let ((hydra-open gdscript-hydra--open))
|
||||||
(when hydra-open (gdscript-hydra--menu/nil))
|
(when hydra-open (gdscript-hydra--menu/nil))
|
||||||
(unwind-protect
|
(unwind-protect
|
||||||
(let* ((prompt (format "Buffer %s is not script file, select script to run" (buffer-name)))
|
(let* ((prompt (format "Buffer %s is not script file, select script to run" (buffer-name)))
|
||||||
(script-name (gdscript-util--read gdscript-project--script-list prompt)))
|
(script-name (gdscript-util--read script-list prompt)))
|
||||||
(when script-name (gdscript-godot--run-script script-name)))
|
(when script-name
|
||||||
|
(string-match "^\\(.*.gd\\):" script-name)
|
||||||
|
(gdscript-godot--run-script (match-string 1 script-name))))
|
||||||
(when hydra-open (gdscript-hydra--menu/body)))))
|
(when hydra-open (gdscript-hydra--menu/body)))))
|
||||||
|
|
||||||
(defun gdscript-project--ag-cleanup ()
|
|
||||||
"Clean after ag search.
|
|
||||||
|
|
||||||
Try to leave Emacs as it was before ag search was launched."
|
|
||||||
(remove-hook 'ag-search-finished-hook #'gdscript-project--ag-find-next-script)
|
|
||||||
(let* ((ag-buffer (current-buffer))
|
|
||||||
(ag-window (get-buffer-window ag-buffer))
|
|
||||||
(prev-buffer (window-prev-buffers ag-window)))
|
|
||||||
(if prev-buffer (kill-buffer ag-buffer)
|
|
||||||
(delete-window ag-window)
|
|
||||||
(kill-buffer ag-buffer))))
|
|
||||||
|
|
||||||
(defun gdscript-project--ag-find-next-script ()
|
|
||||||
"Find next script file in ag buffer."
|
|
||||||
(let ((pos (next-single-property-change (point) 'compilation-message))
|
|
||||||
(comp-mes (get-text-property (point) 'compilation-message)))
|
|
||||||
(when comp-mes
|
|
||||||
(let ((file-name (caar (compilation--loc->file-struct (compilation--message->loc comp-mes)))))
|
|
||||||
(push file-name gdscript-project--script-list)))
|
|
||||||
(if pos (progn (goto-char pos)
|
|
||||||
(gdscript-project--ag-find-next-script))
|
|
||||||
(gdscript-project--ag-cleanup)
|
|
||||||
(with-current-buffer (window-buffer (selected-window))
|
|
||||||
(gdscript-project--select-script)))))
|
|
||||||
|
|
||||||
(defun gdscript-project--get-all-scripts ()
|
(defun gdscript-project--get-all-scripts ()
|
||||||
"Find all script files and let user choose one.
|
"Find all script files and let user choose one.
|
||||||
|
|
||||||
Since detection of script files require inspection of file contents,
|
Since detection of script files require inspection of file contents,
|
||||||
this use ag for performance."
|
this use ag for performance."
|
||||||
(if (not (featurep 'ag))
|
(if (executable-find "ag")
|
||||||
(error (format "Buffer %s is no script file. To see all available scripts in current project install package 'ag'." (buffer-name)))
|
(let ((default-directory (vc-git-root default-directory)))
|
||||||
(ag-project-regexp "^extends SceneTree|^extends MainLoop")
|
(with-temp-buffer
|
||||||
(setq gdscript-project--script-list nil)
|
(call-process "ag" nil (current-buffer) nil "--vimgrep" "-s" "^extends SceneTree|^extends MainLoop")
|
||||||
(add-hook 'ag-search-finished-hook #'gdscript-project--ag-find-next-script)))
|
(let ((available-standalone-scripts (split-string (buffer-string) "\n" t)))
|
||||||
|
(if (null available-standalone-scripts)
|
||||||
|
(message "No standalone script found. Look at https://docs.godotengine.org/en/stable/getting_started/editor/command_line_tutorial.html#running-a-script for details.")
|
||||||
|
(gdscript-project--select-script available-standalone-scripts)))))
|
||||||
|
(error (format "Buffer %s is no script file. To see all available scripts install 'ag' executable." (buffer-name)))))
|
||||||
|
|
||||||
(provide 'gdscript-project)
|
(provide 'gdscript-project)
|
||||||
|
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
;; Copyright (C) 2020 GDQuest
|
;; Copyright (C) 2020 GDQuest
|
||||||
|
|
||||||
;; Author: Nathan Lovato <nathan@gdquest.com>, Fabián E. Gallina <fgallina@gnu.org>
|
;; Author: Nathan Lovato <nathan@gdquest.com>, Fabián E. Gallina <fgallina@gnu.org>
|
||||||
;; URL: https://github.com/GDQuest/emacs-gdscript-mode/
|
;; URL: https://github.com/godotengine/emacs-gdscript-mode/
|
||||||
;; Version: 1.0.0
|
;; Version: 1.0.0
|
||||||
;; Package-Requires: ((emacs "26.3"))
|
;; Package-Requires: ((emacs "26.3"))
|
||||||
;; Maintainer: nathan@gdquest.com
|
;; Maintainer: nathan@gdquest.com
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
;; Copyright (C) 2020 GDQuest
|
;; Copyright (C) 2020 GDQuest
|
||||||
|
|
||||||
;; Author: Nathan Lovato <nathan@gdquest.com>, Fabián E. Gallina <fgallina@gnu.org>
|
;; Author: Nathan Lovato <nathan@gdquest.com>, Fabián E. Gallina <fgallina@gnu.org>
|
||||||
;; URL: https://github.com/GDQuest/emacs-gdscript-mode/
|
;; URL: https://github.com/godotengine/emacs-gdscript-mode/
|
||||||
;; Version: 1.0.0
|
;; Version: 1.0.0
|
||||||
;; Package-Requires: ((emacs "26.3"))
|
;; Package-Requires: ((emacs "26.3"))
|
||||||
;; Maintainer: nathan@gdquest.com
|
;; Maintainer: nathan@gdquest.com
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
;; Copyright (C) 2020 GDQuest and contributors
|
;; Copyright (C) 2020 GDQuest and contributors
|
||||||
;;
|
;;
|
||||||
;; Author: Josef Vlach <vlach.josef@gmail.com>
|
;; Author: Josef Vlach <vlach.josef@gmail.com>
|
||||||
;; URL: https://github.com/GDQuest/emacs-gdscript-mode/
|
;; URL: https://github.com/godotengine/emacs-gdscript-mode/
|
||||||
;; Version: 1.0.0
|
;; Version: 1.0.0
|
||||||
;; Package-Requires: ((emacs "26.3"))
|
;; Package-Requires: ((emacs "26.3"))
|
||||||
;; Maintainer: nathan@gdquest.com
|
;; Maintainer: nathan@gdquest.com
|
||||||
|
|||||||
298
gdscript-ts-mode.el
Normal file
298
gdscript-ts-mode.el
Normal file
@@ -0,0 +1,298 @@
|
|||||||
|
;;; gdscript-ts-mode.el --- Summary -*- lexical-binding: t -*-
|
||||||
|
|
||||||
|
;; Copyright (C) 2023 GDQuest and contributors
|
||||||
|
|
||||||
|
;; Author: xiliuya <xiliuya@aliyun.com>
|
||||||
|
;; URL: https://github.com/godotengine/emacs-gdscript-mode/
|
||||||
|
;; Version: 0.1.0
|
||||||
|
;; Maintainer: xiliuya <xiliuya@aliyun.com>
|
||||||
|
;; Created: 2023-05-22 19:14:43
|
||||||
|
|
||||||
|
;; Keywords: languages
|
||||||
|
;; Package-Requires: ((emacs "26.3"))
|
||||||
|
|
||||||
|
|
||||||
|
;; This program is free software; you can redistribute it and/or modify
|
||||||
|
;; it under the terms of the GNU General Public License as published by
|
||||||
|
;; the Free Software Foundation, either version 3 of the License, or
|
||||||
|
;; (at your option) any later version.
|
||||||
|
|
||||||
|
;; This program is distributed in the hope that it will be useful,
|
||||||
|
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
;; GNU General Public License for more details.
|
||||||
|
|
||||||
|
;; You should have received a copy of the GNU General Public License
|
||||||
|
;; along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
;;; Commentary:
|
||||||
|
;;
|
||||||
|
;; Tree-sitter mode for Gdscript.(Refer to python-ts-mode)
|
||||||
|
;; That supports the use tree-sitter for font-lock, imenu, indentation,
|
||||||
|
;; and navigation of Gdscript files.
|
||||||
|
|
||||||
|
;;
|
||||||
|
;;; Code:
|
||||||
|
|
||||||
|
(when (version< "29" emacs-version)
|
||||||
|
(require 'treesit))
|
||||||
|
|
||||||
|
|
||||||
|
;;; Imenu
|
||||||
|
|
||||||
|
(defvar gdscript-ts-imenu-format-item-label-function
|
||||||
|
'gdscript-ts-imenu-format-item-label
|
||||||
|
"Imenu function used to format an item label.
|
||||||
|
It must be a function with two arguments: TYPE and NAME.")
|
||||||
|
|
||||||
|
(defvar gdscript-ts-imenu-format-parent-item-label-function
|
||||||
|
'gdscript-ts-imenu-format-parent-item-label
|
||||||
|
"Imenu function used to format a parent item label.
|
||||||
|
It must be a function with two arguments: TYPE and NAME.")
|
||||||
|
|
||||||
|
(defvar gdscript-ts-imenu-format-parent-item-jump-label-function
|
||||||
|
'gdscript-ts-imenu-format-parent-item-jump-label
|
||||||
|
"Imenu function used to format a parent jump item label.
|
||||||
|
It must be a function with two arguments: TYPE and NAME.")
|
||||||
|
|
||||||
|
(defun gdscript-ts-imenu-format-item-label (type name)
|
||||||
|
"Return Imenu label for single node using TYPE and NAME."
|
||||||
|
(format "%s (%s)" name type))
|
||||||
|
|
||||||
|
(defun gdscript-ts-imenu-format-parent-item-label (type name)
|
||||||
|
"Return Imenu label for parent node using TYPE and NAME."
|
||||||
|
(format "%s..." (gdscript-ts-imenu-format-item-label type name)))
|
||||||
|
|
||||||
|
(defun gdscript-ts-imenu-format-parent-item-jump-label (type _name)
|
||||||
|
"Return Imenu label for parent node jump using TYPE and NAME."
|
||||||
|
(if (string= type "class")
|
||||||
|
"*class definition*"
|
||||||
|
"*function definition*"))
|
||||||
|
|
||||||
|
|
||||||
|
;;; Keywords
|
||||||
|
|
||||||
|
(defvar gdscript-ts--keyword-regex
|
||||||
|
(rx bot (| "func" "var" "const" "set" "get" "setget" "signal" "extends"
|
||||||
|
"match" "if" "elif" "else" "for" "in" "while" "break" "continue"
|
||||||
|
"pass" "return" "when" "yield" "await"
|
||||||
|
"class" "class_name" "abstract" "is" "onready" "tool" "static"
|
||||||
|
"export" "as" "void" "enum" "assert" "breakpoint"
|
||||||
|
"sync" "remote" "master" "puppet"
|
||||||
|
"remotesync" "mastersync" "puppetsync"
|
||||||
|
"trait" "namespace" "super"
|
||||||
|
"and" "or" "not"
|
||||||
|
"await" "yield" "self") eot))
|
||||||
|
|
||||||
|
;;; Types
|
||||||
|
|
||||||
|
(defvar gdscript-ts--builtin-type-regex
|
||||||
|
"\\`\\(int\\|bool\\|float\\|void\\|Vector2\\|Vector2i\\|Vector3\\|Vector3i\\|Vector4\\|Vector4i\\|Color\\|Rect2\\|Rect2i\\|Array\\|Basis\\|Dictionary\\|Plane\\|Quat\\|RID\\|Rect3\\|Transform\\|Transform2D\\|Transform3D\\|AABB\\|String\\|Color\\|NodePath\\|PoolByteArray\\|PoolIntArray\\|PoolRealArray\\|PoolStringArray\\|PoolVector2Array\\|PoolVector3Array\\|PoolColorArray\\|bool\\|int\\|float\\|Signal\\|Callable\\|StringName\\|Quaternion\\|Projection\\|PackedByteArray\\|PackedInt32Array\\|PackedInt64Array\\|PackedFloat32Array\\|PackedFloat64Array\\|PackedStringArray\\|PackedVector2Array\\|PackedVector2iArray\\|PackedVector3Array\\|PackedVector3iArray\\|PackedVector4Array\\|PackedColorArray\\|JSON\\|UPNP\\|OS\\|IP\\|JSONRPC\\|XRVRS\\)\\'")
|
||||||
|
|
||||||
|
(defvar gdscript-ts--type-regex
|
||||||
|
"\\`[A-Z][a-zA-Z0-9_]*[a-z][a-zA-Z0-9_]*\\'")
|
||||||
|
|
||||||
|
;;; Constants
|
||||||
|
|
||||||
|
(defvar gdscript-ts--constant-regex "\\`[A-Z_][A-Z0-9_]+\\'")
|
||||||
|
|
||||||
|
;;; Setting
|
||||||
|
|
||||||
|
(defvar gdscript-ts--feature-list
|
||||||
|
'(( comment definition)
|
||||||
|
( keyword string type annotation)
|
||||||
|
( number constant escape-sequence)
|
||||||
|
( bracket delimiter function operator property)))
|
||||||
|
|
||||||
|
(defvar gdscript-ts--treesit-settings
|
||||||
|
(treesit-font-lock-rules
|
||||||
|
:language 'gdscript
|
||||||
|
:feature 'comment
|
||||||
|
'((comment) @font-lock-comment-face)
|
||||||
|
|
||||||
|
:language 'gdscript
|
||||||
|
:feature 'constant
|
||||||
|
`(([(null) (false) (true)] @font-lock-constant-face)
|
||||||
|
(const_statement name: (name) @font-lock-constant-face)
|
||||||
|
(enumerator left: (identifier) @font-lock-constant-face)
|
||||||
|
((identifier) @font-lock-constant-face
|
||||||
|
(:match ,gdscript-ts--constant-regex @font-lock-constant-face))
|
||||||
|
(variable_statement
|
||||||
|
name: (name) @font-lock-constant-face
|
||||||
|
(:match ,gdscript-ts--constant-regex @font-lock-constant-face)))
|
||||||
|
|
||||||
|
:language 'gdscript
|
||||||
|
:feature 'bracket
|
||||||
|
`(["[" "]" "(" ")" "{" "}"] @font-lock-bracket-face)
|
||||||
|
|
||||||
|
:language 'gdscript
|
||||||
|
:feature 'delimiter
|
||||||
|
`(["," ":" "."] @font-lock-delimiter-face)
|
||||||
|
|
||||||
|
:language 'gdscript
|
||||||
|
:feature 'type
|
||||||
|
`(((identifier) @font-lock-builtin-face
|
||||||
|
(:match ,gdscript-ts--builtin-type-regex @font-lock-builtin-face))
|
||||||
|
(get_node) @font-lock-builtin-face
|
||||||
|
((identifier) @font-lock-type-face
|
||||||
|
(:match ,gdscript-ts--type-regex @font-lock-type-face))
|
||||||
|
(enum_definition name: (_) @font-lock-type-face)
|
||||||
|
(class_name_statement (name) @font-lock-type-face)
|
||||||
|
(class_definition (name) @font-lock-type-face))
|
||||||
|
|
||||||
|
:language 'gdscript
|
||||||
|
:feature 'definition
|
||||||
|
'((function_definition (name) @font-lock-function-name-face))
|
||||||
|
|
||||||
|
:language 'gdscript
|
||||||
|
:feature 'annotation
|
||||||
|
'((annotation "@" @font-lock-preprocessor-face
|
||||||
|
(identifier) @font-lock-preprocessor-face))
|
||||||
|
|
||||||
|
:language 'gdscript
|
||||||
|
:feature 'keyword
|
||||||
|
`((ERROR _ @font-lock-keyword-face (:match ,gdscript-ts--keyword-regex @font-lock-keyword-face))
|
||||||
|
(_ _ @font-lock-keyword-face (:match ,gdscript-ts--keyword-regex @font-lock-keyword-face)))
|
||||||
|
|
||||||
|
:language 'gdscript
|
||||||
|
:feature 'string
|
||||||
|
'((string) @font-lock-string-face)
|
||||||
|
|
||||||
|
:language 'gdscript
|
||||||
|
:feature 'function
|
||||||
|
'((call (identifier) @font-lock-builtin-face (:match "preload" @font-lock-builtin-face))
|
||||||
|
(call (identifier) @font-lock-function-call-face)
|
||||||
|
(attribute_call (identifier) @font-lock-function-call-face))
|
||||||
|
|
||||||
|
:language 'gdscript
|
||||||
|
:feature 'number
|
||||||
|
'(([(integer) (float)] @font-lock-number-face))
|
||||||
|
|
||||||
|
:language 'gdscript
|
||||||
|
:feature 'property
|
||||||
|
'((attribute (identifier) (identifier) @font-lock-property-use-face))
|
||||||
|
|
||||||
|
:feature 'operator
|
||||||
|
:language 'gdscript
|
||||||
|
`(["+" "+=" "-" "-=" "*" "*=" "/" "/=" "^" "^=" ">" ">="
|
||||||
|
"<" "<=" "|" "|=" "%" "%=" "&" "&=" ">>" ">>=" "<<" "<<="
|
||||||
|
"||" "&&" "==" "!=" "->" "~" "=" ":="]
|
||||||
|
@font-lock-operator-face)
|
||||||
|
|
||||||
|
:language 'gdscript
|
||||||
|
:override t
|
||||||
|
:feature 'escape-sequence
|
||||||
|
'((escape_sequence) @font-lock-escape-face)))
|
||||||
|
|
||||||
|
|
||||||
|
;;; Funtion
|
||||||
|
|
||||||
|
(defun gdscript-ts--treesit-defun-name (node)
|
||||||
|
"Return the defun name of NODE."
|
||||||
|
(treesit-node-text (treesit-search-subtree node "^name$" nil t) t))
|
||||||
|
|
||||||
|
(defun gdscript-ts--imenu-treesit-create-index-1 (node)
|
||||||
|
"Given a sparse tree, create an imenu alist.
|
||||||
|
|
||||||
|
NODE is the root node of the tree returned by
|
||||||
|
`treesit-induce-sparse-tree' (not a tree-sitter node, its car is
|
||||||
|
a tree-sitter node). Walk that tree and return an imenu alist.
|
||||||
|
|
||||||
|
Return a list of ENTRY where
|
||||||
|
|
||||||
|
ENTRY := (NAME . MARKER)
|
||||||
|
| (NAME . ((JUMP-LABEL . MARKER)
|
||||||
|
ENTRY
|
||||||
|
...)
|
||||||
|
|
||||||
|
NAME is the function/class's name, JUMP-LABEL is like \"*function
|
||||||
|
definition*\"."
|
||||||
|
(let* ((ts-node (car node))
|
||||||
|
(children (cdr node))
|
||||||
|
(subtrees (mapcan #'gdscript-ts--imenu-treesit-create-index-1
|
||||||
|
children))
|
||||||
|
(type (pcase (treesit-node-type ts-node)
|
||||||
|
("function_definition" 'def)
|
||||||
|
("export_variable_statement" 'e-var)
|
||||||
|
("onready_variable_statement" 'o-var)
|
||||||
|
("variable_statement" 'var)
|
||||||
|
("class_definition" 'class)))
|
||||||
|
;; The root of the tree could have a nil ts-node.
|
||||||
|
(name (when ts-node
|
||||||
|
(or (treesit-defun-name ts-node)
|
||||||
|
"Anonymous")))
|
||||||
|
(marker (when ts-node
|
||||||
|
(set-marker (make-marker)
|
||||||
|
(treesit-node-start ts-node)))))
|
||||||
|
(cond
|
||||||
|
((null ts-node)
|
||||||
|
subtrees)
|
||||||
|
(subtrees
|
||||||
|
(let ((parent-label
|
||||||
|
(funcall gdscript-ts-imenu-format-parent-item-label-function
|
||||||
|
type name))
|
||||||
|
(jump-label
|
||||||
|
(funcall
|
||||||
|
gdscript-ts-imenu-format-parent-item-jump-label-function
|
||||||
|
type name)))
|
||||||
|
`((,parent-label
|
||||||
|
,(cons jump-label marker)
|
||||||
|
,@subtrees))))
|
||||||
|
(t (let ((label
|
||||||
|
(funcall gdscript-ts-imenu-format-item-label-function
|
||||||
|
type name)))
|
||||||
|
(list (cons label marker)))))))
|
||||||
|
|
||||||
|
(defun gdscript-ts-imenu-treesit-create-index (&optional node)
|
||||||
|
"Return tree Imenu alist for the current Gdscript buffer.
|
||||||
|
|
||||||
|
Change `gdscript-ts-imenu-format-item-label-function',
|
||||||
|
`gdscript-ts-imenu-format-parent-item-label-function',
|
||||||
|
`gdscript-ts-imenu-format-parent-item-jump-label-function' to
|
||||||
|
customize how labels are formatted.
|
||||||
|
|
||||||
|
NODE is the root node of the subtree you want to build an index
|
||||||
|
of. If nil, use the root node of the whole parse tree.
|
||||||
|
|
||||||
|
Similar to `gdscript-imenu-create-index' but use tree-sitter."
|
||||||
|
(let* ((node (or node (treesit-buffer-root-node 'gdscript)))
|
||||||
|
(tree (treesit-induce-sparse-tree
|
||||||
|
node
|
||||||
|
(rx (or (seq bol
|
||||||
|
(or "onready_" "export_" "")
|
||||||
|
"variable_statement"
|
||||||
|
eol)
|
||||||
|
(seq bol
|
||||||
|
(or "function" "class")
|
||||||
|
"_definition"
|
||||||
|
eol)))
|
||||||
|
nil 1000)))
|
||||||
|
(gdscript-ts--imenu-treesit-create-index-1 tree)))
|
||||||
|
|
||||||
|
;;;###autoload
|
||||||
|
(define-derived-mode gdscript-ts-mode gdscript-mode "Gdscript"
|
||||||
|
"Major mode for editing gdscript files, using tree-sitter library.
|
||||||
|
|
||||||
|
\\{gdscript-ts-mode-map}"
|
||||||
|
:syntax-table gdscript-mode-syntax-table
|
||||||
|
(when (treesit-ready-p 'gdscript)
|
||||||
|
(treesit-parser-create 'gdscript)
|
||||||
|
(setq-local treesit-font-lock-feature-list gdscript-ts--feature-list)
|
||||||
|
(setq-local treesit-font-lock-settings gdscript-ts--treesit-settings)
|
||||||
|
;;; TODO: create-imenu
|
||||||
|
(setq-local imenu-create-index-function
|
||||||
|
#'gdscript-ts-imenu-treesit-create-index)
|
||||||
|
(setq-local treesit-defun-type-regexp (rx (seq bol
|
||||||
|
(or "function" "class")
|
||||||
|
"_definition"
|
||||||
|
eol)))
|
||||||
|
(setq-local treesit-defun-name-function
|
||||||
|
#'gdscript-ts--treesit-defun-name)
|
||||||
|
(treesit-major-mode-setup)
|
||||||
|
|
||||||
|
|
||||||
|
(add-to-list 'auto-mode-alist '("\\.gd\\'" . gdscript-ts-mode))
|
||||||
|
(add-to-list 'interpreter-mode-alist '("gdscript[0-9.]*" . gdscript-ts-mode))))
|
||||||
|
|
||||||
|
(provide 'gdscript-ts-mode)
|
||||||
|
;;; gdscript-ts-mode.el ends here
|
||||||
@@ -3,7 +3,7 @@
|
|||||||
;; Copyright (C) 2020 GDQuest
|
;; Copyright (C) 2020 GDQuest
|
||||||
|
|
||||||
;; Author: Nathan Lovato <nathan@gdquest.com>, Fabián E. Gallina <fgallina@gnu.org>
|
;; Author: Nathan Lovato <nathan@gdquest.com>, Fabián E. Gallina <fgallina@gnu.org>
|
||||||
;; URL: https://github.com/GDQuest/emacs-gdscript-mode/
|
;; URL: https://github.com/godotengine/emacs-gdscript-mode/
|
||||||
;; Version: 0.1.0
|
;; Version: 0.1.0
|
||||||
;; Package-Requires: ((emacs "26.3"))
|
;; Package-Requires: ((emacs "26.3"))
|
||||||
;; Maintainer: nathan@gdquest.com
|
;; Maintainer: nathan@gdquest.com
|
||||||
|
|||||||
Reference in New Issue
Block a user