Commit 9404c715 authored by Günther Wagner's avatar Günther Wagner

codespell: add codespell integration

Fixes #1237
parent b99fce21
Pipeline #191970 canceled with stage
in 35 minutes and 12 seconds
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
"name": "python3-jedi", "name": "python3-jedi",
"buildsystem": "simple", "buildsystem": "simple",
"build-commands": [ "build-commands": [
"pip3 install --no-index --find-links=\"file://${PWD}\" --prefix=${FLATPAK_DEST} jedi sphinx sphinx_rtd_theme lxml docutils" "pip3 install --no-index --find-links=\"file://${PWD}\" --prefix=${FLATPAK_DEST} jedi sphinx sphinx_rtd_theme lxml docutils codespell"
], ],
"sources": [ "sources": [
{ {
...@@ -119,6 +119,11 @@ ...@@ -119,6 +119,11 @@
"type": "file", "type": "file",
"url": "https://files.pythonhosted.org/packages/e4/83/4c05db437252694660c972b5374b35a68a8a0a8cd012dc95e5fd4d7e71b0/jedi-0.13.2.tar.gz", "url": "https://files.pythonhosted.org/packages/e4/83/4c05db437252694660c972b5374b35a68a8a0a8cd012dc95e5fd4d7e71b0/jedi-0.13.2.tar.gz",
"sha256": "571702b5bd167911fe9036e5039ba67f820d6502832285cde8c881ab2b2149fd" "sha256": "571702b5bd167911fe9036e5039ba67f820d6502832285cde8c881ab2b2149fd"
},
{
"type": "file",
"url": "https://files.pythonhosted.org/packages/7e/37/b15b4133e90bbef5acecfd2f3f3871c1352ee281c042fd64a22a72735fb8/codespell-1.17.1.tar.gz",
"sha256": "25a2ecd86b9cdc111dc40a30d0ed28c578e13a0ce158d1c383f9d47811bfcd23"
} }
] ]
} }
\ No newline at end of file
...@@ -23,6 +23,7 @@ option('plugin_c_pack', type: 'boolean') ...@@ -23,6 +23,7 @@ option('plugin_c_pack', type: 'boolean')
option('plugin_cargo', type: 'boolean') option('plugin_cargo', type: 'boolean')
option('plugin_clang', type: 'boolean') option('plugin_clang', type: 'boolean')
option('plugin_cmake', type: 'boolean') option('plugin_cmake', type: 'boolean')
option('plugin_codespell', type: 'boolean')
option('plugin_code_index', type: 'boolean') option('plugin_code_index', type: 'boolean')
option('plugin_color_picker', type: 'boolean') option('plugin_color_picker', type: 'boolean')
option('plugin_copyright', type: 'boolean') option('plugin_copyright', type: 'boolean')
......
/* codespell-plugin.c
*
* Copyright 2020 Günther Wagner <info@gunibert.de>
*
* 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/>.
*
* SPDX-License-Identifier: GPL-3.0-or-later
*/
#include "config.h"
#include <libpeas/peas.h>
#include <libide-code.h>
#include "ide-codespell-diagnostic-provider.h"
_IDE_EXTERN void
_ide_codespell_register_types (PeasObjectModule *module)
{
peas_object_module_register_extension_type (module,
IDE_TYPE_DIAGNOSTIC_PROVIDER,
IDE_TYPE_CODESPELL_DIAGNOSTIC_PROVIDER);
}
<?xml version="1.0" encoding="UTF-8"?>
<gresources>
<gresource prefix="/plugins/codespell">
<file>codespell.plugin</file>
</gresource>
</gresources>
[Plugin]
Authors=Günther Wagner <info@gunibert.de>
Builtin=true
Copyright=Copyright © 2020 Günther Wagner
Depends=editor;
Description=Provides integration with Codespell
Embedded=_ide_codespell_register_types
Module=codespell
Name=Codespell
X-Diagnostic-Provider-Languages-Priority=100
X-Diagnostic-Provider-Languages=c,chdr,cpp,js,python,vala
/* ide-codespell-diagnostic-provider.c
*
* Copyright 2020 Günther Wagner <info@gunibert.de>
*
* 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/>.
*
* SPDX-License-Identifier: GPL-3.0-or-later
*/
#include "ide-codespell-diagnostic-provider.h"
struct _IdeCodespellDiagnosticProvider
{
IdeObject parent_instance;
};
static void diagnostic_provider_iface_init (IdeDiagnosticProviderInterface *iface);
G_DEFINE_TYPE_WITH_CODE (IdeCodespellDiagnosticProvider,
ide_codespell_diagnostic_provider,
IDE_TYPE_OBJECT,
G_IMPLEMENT_INTERFACE (IDE_TYPE_DIAGNOSTIC_PROVIDER,
diagnostic_provider_iface_init))
IdeCodespellDiagnosticProvider *
ide_codespell_diagnostic_provider_new (void)
{
return g_object_new (IDE_TYPE_CODESPELL_DIAGNOSTIC_PROVIDER, NULL);
}
static void
ide_codespell_diagnostic_provider_class_init (IdeCodespellDiagnosticProviderClass *klass)
{
}
static void
ide_codespell_diagnostic_provider_init (IdeCodespellDiagnosticProvider *self)
{
}
static void
ide_codespell_diagnostic_provider_communicate_cb (GObject *object,
GAsyncResult *result,
gpointer user_data)
{
IdeSubprocess *subprocess = (IdeSubprocess *)object;
g_autoptr(IdeTask) task = user_data;
g_autoptr(IdeDiagnostics) ret = NULL;
g_autoptr(GError) error = NULL;
g_autofree gchar *stderr_buf = NULL;
g_autofree gchar *stdout_buf = NULL;
IdeLineReader reader;
GFile *file;
gchar *line;
gsize len;
g_assert (IDE_IS_SUBPROCESS (subprocess));
g_assert (G_IS_ASYNC_RESULT (result));
g_assert (IDE_IS_TASK (task));
if (!ide_subprocess_communicate_utf8_finish (subprocess, result, &stdout_buf, &stderr_buf, &error))
{
ide_task_return_error (task, g_steal_pointer (&error));
return;
}
file = ide_task_get_task_data (task);
g_assert (file != NULL);
g_assert (G_IS_FILE (file));
ret = ide_diagnostics_new ();
ide_line_reader_init (&reader, stdout_buf, -1);
while (NULL != (line = ide_line_reader_next (&reader, &len)))
{
g_autoptr(IdeDiagnostic) diag = NULL;
g_autoptr(IdeLocation) loc = NULL;
g_autoptr(IdeLocation) loc_end = NULL;
guint64 lineno;
/* Lines that we want to parse should look something like this:
* filename:42: misspelled word ==> correct word
*/
if (!g_str_has_prefix (line, g_file_get_path (file)))
continue;
line += strlen (g_file_get_path (file)) + 1;
if (!g_ascii_isdigit (*line))
continue;
lineno = g_ascii_strtoull (line, &line, 10);
if ((lineno == G_MAXUINT64 && errno == ERANGE) || ((lineno == 0) && errno == EINVAL))
continue;
if (lineno > 0)
lineno--;
if (!g_str_has_prefix (line, ": "))
continue;
line += strlen (": ");
/* As we don't get a column information out of codespell mark the full line */
loc = ide_location_new (file, lineno, -1);
loc_end = ide_location_new (file, lineno, G_MAXINT);
diag = ide_diagnostic_new (IDE_DIAGNOSTIC_NOTE, line, loc);
ide_diagnostic_add_range (diag, ide_range_new (loc, loc_end));
ide_diagnostics_add (ret, diag);
}
ide_task_return_pointer (task,
g_steal_pointer (&ret),
g_object_unref);
}
static void
ide_codespell_diagnostic_provider_diagnose_async (IdeDiagnosticProvider *provider,
GFile *file,
GBytes *contents,
const gchar *lang_id,
GCancellable *cancellable,
GAsyncReadyCallback callback,
gpointer user_data)
{
IdeCodespellDiagnosticProvider *self = (IdeCodespellDiagnosticProvider *)provider;
g_autoptr(IdeTask) task = NULL;
g_autoptr(IdeSubprocessLauncher) launcher = NULL;
g_autoptr(IdeSubprocess) subprocess = NULL;
g_autoptr(GError) error = NULL;
g_assert (IDE_IS_CODESPELL_DIAGNOSTIC_PROVIDER (self));
g_assert (G_IS_FILE (file));
g_assert (contents != NULL);
g_assert (!cancellable || G_IS_CANCELLABLE (cancellable));
task = ide_task_new (self, cancellable, callback, user_data);
ide_task_set_source_tag (task, ide_codespell_diagnostic_provider_diagnose_async);
ide_task_set_priority (task, G_PRIORITY_LOW);
ide_task_set_task_data (task, g_object_ref (file), g_object_unref);
launcher = ide_subprocess_launcher_new (G_SUBPROCESS_FLAGS_STDIN_PIPE |
G_SUBPROCESS_FLAGS_STDOUT_PIPE |
G_SUBPROCESS_FLAGS_STDERR_SILENCE);
ide_subprocess_launcher_push_argv (launcher, "codespell");
ide_subprocess_launcher_push_argv (launcher, "-d");
ide_subprocess_launcher_push_argv (launcher, g_file_get_path (file));
/* Spawn the process of fail immediately */
if (!(subprocess = ide_subprocess_launcher_spawn (launcher, cancellable, &error)))
{
ide_task_return_error (task, g_steal_pointer (&error));
return;
}
ide_subprocess_communicate_utf8_async (subprocess,
NULL,
cancellable,
ide_codespell_diagnostic_provider_communicate_cb,
g_steal_pointer (&task));
}
static IdeDiagnostics *
ide_codespell_diagnostic_provider_diagnose_finish (IdeDiagnosticProvider *provider,
GAsyncResult *result,
GError **error)
{
g_assert (IDE_IS_CODESPELL_DIAGNOSTIC_PROVIDER (provider));
g_assert (IDE_IS_TASK (result));
g_assert (ide_task_is_valid (IDE_TASK (result), provider));
return ide_task_propagate_pointer (IDE_TASK (result), error);
}
static void
diagnostic_provider_iface_init (IdeDiagnosticProviderInterface *iface)
{
iface->diagnose_async = ide_codespell_diagnostic_provider_diagnose_async;
iface->diagnose_finish = ide_codespell_diagnostic_provider_diagnose_finish;
}
/* ide-codespell-diagnostic-provider.h
*
* Copyright 2020 Günther Wagner <info@gunibert.de>
*
* 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/>.
*
* SPDX-License-Identifier: GPL-3.0-or-later
*/
#pragma once
#include <libide-code.h>
G_BEGIN_DECLS
#define IDE_TYPE_CODESPELL_DIAGNOSTIC_PROVIDER (ide_codespell_diagnostic_provider_get_type())
G_DECLARE_FINAL_TYPE (IdeCodespellDiagnosticProvider, ide_codespell_diagnostic_provider, IDE, CODESPELL_DIAGNOSTIC_PROVIDER, IdeObject)
G_END_DECLS
if get_option('plugin_codespell')
plugins_sources += files([
'codespell-plugin.c',
'ide-codespell-diagnostic-provider.c',
])
plugin_codespell_resources = gnome.compile_resources(
'codespell-resources',
'codespell.gresource.xml',
c_name: 'gbp_codespell',
)
plugins_sources += plugin_codespell_resources
endif
...@@ -43,6 +43,7 @@ subdir('buffer-monitor') ...@@ -43,6 +43,7 @@ subdir('buffer-monitor')
subdir('cargo') subdir('cargo')
subdir('clang') subdir('clang')
subdir('cmake') subdir('cmake')
subdir('codespell')
subdir('code-index') subdir('code-index')
subdir('codeui') subdir('codeui')
subdir('color-picker') subdir('color-picker')
...@@ -147,6 +148,7 @@ status += [ ...@@ -147,6 +148,7 @@ status += [
'Cargo ................. : @0@'.format(get_option('plugin_cargo')), 'Cargo ................. : @0@'.format(get_option('plugin_cargo')),
'Clang ................. : @0@'.format(get_option('plugin_clang')), 'Clang ................. : @0@'.format(get_option('plugin_clang')),
'CMake ................. : @0@'.format(get_option('plugin_cmake')), 'CMake ................. : @0@'.format(get_option('plugin_cmake')),
'Codespell ............. : @0@'.format(get_option('plugin_codespell')),
'Code Index ............ : @0@'.format(get_option('plugin_code_index')), 'Code Index ............ : @0@'.format(get_option('plugin_code_index')),
'Color Pickr ........... : @0@'.format(get_option('plugin_color_picker')), 'Color Pickr ........... : @0@'.format(get_option('plugin_color_picker')),
'CTags ................. : @0@'.format(get_option('plugin_ctags')), 'CTags ................. : @0@'.format(get_option('plugin_ctags')),
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment