Closed PMassicotte closed 3 months ago
Good job!
Do you plan to add other formatting features in the future? If yes, instead of RNumFormat
, perhaps the map label could be RFormatNum
and the map labels of future formatting features would also start with RFormat
too.
Where do the diagnostics in virtual text come from? Are they from the languageserver
? If yes, I imagine some people would expect to fix them by calling vim.lsp.buf.code_action()
.
Do you plan to add other formatting features in the future? If yes, instead of RNumFormat, perhaps the map label could be RFormatNum and the map labels of future formatting features would also start with RFormat too.
Good idea, I will change it, so it will be easier to add more features as you suggest.
Where do the diagnostics in virtual text come from? Are they from the languageserver?
Yes, from the LSP, using a .lintr file globally on in the project directory.
If yes, I imagine some people would expect to fix them by calling vim.lsp.buf.code_action().
This is a good suggestion. It looks like it is supported by languageserver
(https://github.com/REditorSupport/languageserver/tree/9b300181f2588462cb5a6f7ecd55fcbeb083d028?tab=readme-ov-file#services-implemented). I never tried to implement such service (https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#textDocument_codeAction), but I can try. If you have any idea where to start, please let me know.
Looks like the only option/action provided is to add nolint
(https://github.com/REditorSupport/languageserver/blob/9b300181f2588462cb5a6f7ecd55fcbeb083d028/R/code_action.R#L52). Can we implement an answer/action to take on our side or it must be implemented within r languageserver
?
I didn't investigate the possibilities, but I guess that we can use vim.lsp.buf.code_action()
only if the diagnostics come from a language server. The options, then, become: contribute to the existing R's languageserver
package, create our own language server, or forget about vim.lsp.buf.code_action()
.
The combination of nvimcom
and rnvimserver
already works like a language server (for completion of code, displaying documentation, formatting selected code), but it also has features that aren't in the language server protocol (Object Browser, opening the Examples section of documentation as a normal R script). The communication between nvimcom
+rnvimserver
and Neovim doesn't follow the language server protocol.
We use cache files to do completion with no noticeable delay and we can complete objects from the .GlobalEnv
. As far as I know, the languageserver
team doesn't want to use cache files, and completion of .GlobalEnv
objects isn't a goal.
In summary, I think that, ideally, we should avoid duplication of efforts in the free software community and collaborate with the languageserver
project when the goals overlap. However, it's more frequently easier to create something anew than adapt to an existing project.
Can we implement an answer/action to take on our side
It was a lot of work to convert Nvim-R
's VimScript into R.nvim
's Lua. I will not try to convert part of R.nvim
into a language server. So, my answer is: Yes, it's possible. But I can't work on this because it would require rewriting most of nvimcom
and nclientserver
and I don't have time for such a big change.
or it must be implemented within r languageserver ?
It would be more under users' expectations on how diagnostics are displayed and fixed, but you have already developed the feature to R.nvim
and it is ready to be merged. I think that we can simply merge your pull request. R.nvim
is free software and anyone can adapt the code to the languageserver
.
Maybe I should not have made my initial comment...
I agree with all you said. R.nvim
works just perfectly as it is now. We can add more goodies as we go ;)
I have made the changes. Maybe we could eventually document on how to have the lintr
working.
.Rprofile
: lintr.linter_file = "~/.lintr",
.lintr
file:linters: linters_with_defaults(
T_and_F_symbol_linter(),
absolute_path_linter(lax = TRUE),
any_duplicated_linter(),
any_is_na_linter(),
backport_linter(),
boolean_arithmetic_linter(),
class_equals_linter(),
commented_code_linter(),
condition_message_linter(),
conjunct_test_linter(),
consecutive_assertion_linter(),
cyclocomp_linter(),
cyclocomp_linter(50),
duplicate_argument_linter(),
empty_assignment_linter(),
expect_comparison_linter(),
expect_length_linter(),
expect_named_linter(),
expect_not_linter(),
expect_null_linter(),
expect_s3_class_linter(),
expect_s4_class_linter(),
expect_true_false_linter(),
expect_type_linter(),
extraction_operator_linter(),
fixed_regex_linter(),
for_loop_index_linter(),
function_argument_linter(),
function_return_linter(),
ifelse_censor_linter(),
implicit_assignment_linter(),
implicit_integer_linter(allow_colon = TRUE),
inner_combine_linter(),
is_numeric_linter(),
length_levels_linter(),
lengths_linter(),
library_call_linter(),
line_length_linter(150),
literal_coercion_linter(),
missing_argument_linter(),
missing_package_linter(),
namespace_linter(),
nested_ifelse_linter(),
nonportable_path_linter(),
nonportable_path_linter(lax = TRUE),
numeric_leading_zero_linter(),
object_length_linter(30),
object_usage_linter = NULL,
outer_negation_linter(),
package_hooks_linter(),
paste_linter(),
pipe_call_linter(),
redundant_equals_linter(),
redundant_ifelse_linter(),
regex_subset_linter(),
routine_registration_linter(),
scalar_in_linter(),
semicolon_linter(allow_compound = TRUE),
seq_linter(),
sort_linter(),
sprintf_linter(),
string_boundary_linter(),
strings_as_factors_linter(),
system_file_linter(),
undesirable_function_linter(all_undesirable_functions),
undesirable_operator_linter(all_undesirable_operators),
unnecessary_concatenation_linter(),
unnecessary_lambda_linter(),
unnecessary_nested_if_linter(),
unnecessary_placeholder_linter(),
unreachable_code_linter(),
vector_logic_linter(),
yoda_test_linter(),
undesirable_function_linter(
fun = c(
# Base messaging
"message" = "use cli::cli_inform()",
"warning" = "use cli::cli_warn()",
"stop" = "use cli::cli_abort()",
# rlang messaging
"inform" = "use cli::cli_inform()",
"warn" = "use cli::cli_warn()",
"abort" = "use cli::cli_abort()",
# older cli
"cli_alert_danger" = "use cli::cli_inform()",
"cli_alert_info" = "use cli::cli_inform()",
"cli_alert_success" = "use cli::cli_inform()",
"cli_alert_warning" = "use cli::cli_inform()",
# fs
"file.path" = "use path()",
"dir" = "use dir_ls()",
"dir.create" = "use dir_create()",
"file.copy" = "use file_copy()",
"file.create" = "use file_create()",
"file.exists" = "use file_exists()",
"file.info" = "use file_info()",
"normalizePath" = "use path_real()",
"unlink" = "use file_delete()",
"basename" = "use path_file()",
"dirname" = "use path_dir()",
# i/o
"readLines" = "use read_lines()",
"writeLines" = "use write_lines()"
),
symbol_is_undesirable = FALSE
)
)
neovim/nvim-lspconfig
:vim.g.LanguageClient_serverCommands = {
r = { "R", "--slave", "-e", "languageserver::run()" },
}
This PR introduces functionality for converting numbers to explicit integers in the current buffer. This feature is aimed at satisfying linters that recommend explicit integer usage, as detailed here: Implicit Integer Linter.
Key Features:
<localleader>cn
, for change number) has been added for quickly converting numbers.Configurable Option: An option to avoid converting numbers in ranges (e.g.,
1:10
) is available. By default, numbers within ranges are not converted, but this can be changed with the following configuration:Maybe the default should be to
true
?Documentation
The documentation has been updated to reflect these changes.